]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #31653 - tomaka:emscripten-abi, r=eddyb
authorbors <bors@rust-lang.org>
Mon, 15 Feb 2016 11:07:02 +0000 (11:07 +0000)
committerbors <bors@rust-lang.org>
Mon, 15 Feb 2016 11:07:02 +0000 (11:07 +0000)
Needs a correct review because I'm not too confident with how this works.
All tests related to the C ABI are now passing.

References:
- https://github.com/kripken/emscripten-fastcomp-clang/blob/dbe68fecd03d6f646bd075963c3cc0e7130e5767/lib/CodeGen/TargetInfo.cpp#L479-L489
- https://github.com/kripken/emscripten-fastcomp-clang/blob/dbe68fecd03d6f646bd075963c3cc0e7130e5767/lib/CodeGen/TargetInfo.cpp#L466-L477

The `classifyArgumentType` function has two different paths depending on `RAA == CGCXXABI::RAA_DirectInMemory`, but I don't really know what's the corresponding option in Rust.

cc @brson @eddyb

src/librustc_trans/trans/cabi_asmjs.rs

index 823f333f3317b77469f242958dd0088ceb62796c..3a4a6b9960e9cea6bd62cb3260b08423def164b6 100644 (file)
@@ -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,
+    };
 }