about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_trans/trans/cabi_asmjs.rs58
1 files changed, 54 insertions, 4 deletions
diff --git a/src/librustc_trans/trans/cabi_asmjs.rs b/src/librustc_trans/trans/cabi_asmjs.rs
index 823f333f331..3a4a6b9960e 100644
--- a/src/librustc_trans/trans/cabi_asmjs.rs
+++ b/src/librustc_trans/trans/cabi_asmjs.rs
@@ -8,15 +8,65 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use trans::cabi::FnType;
-use trans::cabi_arm;
+#![allow(non_upper_case_globals)]
+
+use llvm::{Struct, Array, Attribute};
+use trans::cabi::{FnType, ArgType};
 use trans::context::CrateContext;
 use trans::type_::Type;
 
+// Data layout: e-p:32:32-i64:64-v128:32:128-n32-S128
+
+// See the https://github.com/kripken/emscripten-fastcomp-clang repository.
+// The class `EmscriptenABIInfo` in `/lib/CodeGen/TargetInfo.cpp` contains the ABI definitions.
+
+fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
+    match ty.kind() {
+        Struct => {
+            let field_types = ty.field_types();
+            if field_types.len() == 1 {
+                ArgType::direct(ty, Some(field_types[0]), None, None)
+            } else {
+                ArgType::indirect(ty, Some(Attribute::StructRet))
+            }
+        },
+        Array => {
+            ArgType::indirect(ty, Some(Attribute::StructRet))
+        },
+        _ => {
+            let attr = if ty == Type::i1(ccx) { Some(Attribute::ZExt) } else { None };
+            ArgType::direct(ty, None, None, attr)
+        }
+    }
+}
+
+fn classify_arg_ty(ccx: &CrateContext, ty: Type) -> ArgType {
+    if ty.is_aggregate() {
+        ArgType::indirect(ty, Some(Attribute::ByVal))
+    } else {
+        let attr = if ty == Type::i1(ccx) { Some(Attribute::ZExt) } else { None };
+        ArgType::direct(ty, None, None, attr)
+    }
+}
+
 pub fn compute_abi_info(ccx: &CrateContext,
                         atys: &[Type],
                         rty: Type,
                         ret_def: bool) -> FnType {
-    cabi_arm::compute_abi_info(ccx, atys, rty, ret_def,
-                               cabi_arm::Flavor::General)
+    let mut arg_tys = Vec::new();
+    for &aty in atys {
+        let ty = classify_arg_ty(ccx, aty);
+        arg_tys.push(ty);
+    }
+
+    let ret_ty = if ret_def {
+        classify_ret_ty(ccx, rty)
+    } else {
+        ArgType::direct(Type::void(ccx), None, None, None)
+    };
+
+    return FnType {
+        arg_tys: arg_tys,
+        ret_ty: ret_ty,
+    };
 }