]> git.lizzy.rs Git - rust.git/commitdiff
Fix the asmjs ABI
authorPierre Krieger <pierre.krieger1708@gmail.com>
Sun, 14 Feb 2016 16:07:44 +0000 (17:07 +0100)
committerPierre Krieger <pierre.krieger1708@gmail.com>
Sun, 14 Feb 2016 16:25:49 +0000 (17:25 +0100)
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,
+    };
 }