Bug 878526 - OdinMonkey: handle 'unknown' type properly for FFI functions with unused results (r=bbouvier)
authorLuke Wagner <luke@mozilla.com>
Mon, 10 Jun 2013 16:21:21 -0700
changeset 134580 9ce9c145e07238c62803c509c6f7d0db1b366402
parent 134579 92b758cba0f17448b274a6fab3061b11adf20b44
child 134581 8e30d56cf29d43ed0a43d905767ed96987254df2
push id29283
push userlwagner@mozilla.com
push dateMon, 10 Jun 2013 23:42:33 +0000
treeherdermozilla-inbound@1eff67ffe6b9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier
bugs878526
milestone24.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 878526 - OdinMonkey: handle 'unknown' type properly for FFI functions with unused results (r=bbouvier)
js/src/ion/AsmJS.cpp
js/src/jit-test/tests/asm.js/testFFI.js
--- a/js/src/ion/AsmJS.cpp
+++ b/js/src/ion/AsmJS.cpp
@@ -354,17 +354,18 @@ class Type
     enum Which {
         Double,
         Doublish,
         Fixnum,
         Int,
         Signed,
         Unsigned,
         Intish,
-        Void
+        Void,
+        Unknown
     };
 
   private:
     Which which_;
 
   public:
     Type() : which_(Which(-1)) {}
     Type(Which w) : which_(w) {}
@@ -411,32 +412,34 @@ class Type
             return MIRType_Double;
           case Fixnum:
           case Int:
           case Signed:
           case Unsigned:
           case Intish:
             return MIRType_Int32;
           case Void:
+          case Unknown:
             return MIRType_None;
         }
         JS_NOT_REACHED("Invalid Type");
         return MIRType_None;
     }
 
     const char *toChars() const {
         switch (which_) {
           case Double:    return "double";
           case Doublish:  return "doublish";
           case Fixnum:    return "fixnum";
           case Int:       return "int";
           case Signed:    return "signed";
           case Unsigned:  return "unsigned";
           case Intish:    return "intish";
           case Void:      return "void";
+          case Unknown:   return "unknown";
         }
         JS_NOT_REACHED("Invalid Type");
         return "";
     }
 };
 
 // Represents the subset of Type that can be used as the return type of a
 // function.
@@ -622,16 +625,26 @@ class Use
           case NoCoercion: return Type::Void;
           case ToInt32: return Type::Intish;
           case ToNumber: return Type::Doublish;
           case AddOrSub: return Type::Void;
         }
         JS_NOT_REACHED("unexpected use type");
         return Type::Void;
     }
+    Type toFFIReturnType() const {
+        switch (which_) {
+          case NoCoercion: return Type::Unknown;
+          case ToInt32: return Type::Intish;
+          case ToNumber: return Type::Doublish;
+          case AddOrSub: return Type::Unknown;
+        }
+        JS_NOT_REACHED("unexpected use type");
+        return Type::Unknown;
+    }
     MIRType toMIRType() const {
         switch (which_) {
           case NoCoercion: return MIRType_None;
           case ToInt32: return MIRType_Int32;
           case ToNumber: return MIRType_Double;
           case AddOrSub: return MIRType_None;
         }
         JS_NOT_REACHED("unexpected use type");
@@ -3537,17 +3550,17 @@ CheckFFICall(FunctionCompiler &f, ParseN
 
     unsigned exitIndex;
     if (!f.m().addExit(ffiIndex, CallCallee(callNode)->name(), Move(argMIRTypes), use, &exitIndex))
         return false;
 
     if (!f.ffiCall(exitIndex, args, use.toMIRType(), def))
         return false;
 
-    *type = use.toReturnType();
+    *type = use.toFFIReturnType();
     return true;
 }
 
 static inline void *
 UnaryMathFunCast(double (*pf)(double))
 {
     return JS_FUNC_TO_DATA_PTR(void*, pf);
 }
--- a/js/src/jit-test/tests/asm.js/testFFI.js
+++ b/js/src/jit-test/tests/asm.js/testFFI.js
@@ -24,16 +24,17 @@ var imp = { inc:inc, add1:add1, add2:add
 assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { incc() } return f');
 assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { var i = 0; return (i + inc)|0 } return f');
 assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { inc = 0 } return f');
 assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return (inc() + 1)|0 } return f');
 assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return +((inc()|0) + 1.1) } return f');
 assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return +(inc() + 1.1) } return f');
 assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return (+inc() + 1)|0 } return f');
 assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { var i = 0; inc(i>>>0) } return f');
+assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return inc(); return } return f');
 
 assertAsmLinkFail(asmCompile('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return inc()|0 } return f'), null, {});
 assertAsmLinkFail(asmCompile('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return inc()|0 } return f'), null, {inc:0});
 assertAsmLinkFail(asmCompile('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return inc()|0 } return f'), null, {inc:{}});
 
 assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + 'var inc=imp.inc; function g() { inc() } return g'), null, imp)(), undefined);
 assertEq(counter, 1);