Bug 952306: Allow global const literals as variable initializers; r=luke
authorBenjamin Bouvier <benj@benj.me>
Wed, 29 Jan 2014 14:27:01 +0100
changeset 181764 191ba4345c963f47d7a09803fd8aacfdc909dd32
parent 181763 bd3a04b82246745223ce5694e347127b68caa88e
child 181765 192c0bc86b01c007b775d4dbf59082d5194b9200
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-beta@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs952306
milestone29.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 952306: Allow global const literals as variable initializers; r=luke
js/src/jit-test/tests/asm.js/testGlobals.js
js/src/jit/AsmJS.cpp
--- a/js/src/jit-test/tests/asm.js/testGlobals.js
+++ b/js/src/jit-test/tests/asm.js/testGlobals.js
@@ -25,16 +25,38 @@ assertAsmTypeFail(USE_ASM + "const c=0, 
 assertEq(asmLink(asmCompile(USE_ASM + "var i=13; function f(i, j) { i=i|0; j=j|0; i=j; return i|0 } return f"))(42,43), 43);
 assertEq(asmLink(asmCompile(USE_ASM + "var i=13; function f(j) { j=j|0; var i=0; i=j; return i|0 } return f"))(42), 42);
 
 var f = asmLink(asmCompile(USE_ASM + "var i=13; function f(j) { j=j|0; if ((j|0) != -1) { i=j } else { return i|0 } return 0 } return f"));
 assertEq(f(-1), 13);
 assertEq(f(42), 0);
 assertEq(f(-1), 42);
 
+assertAsmTypeFail(USE_ASM + "var i=13; function f() { var j=i; return j|0 } return f");
+assertAsmTypeFail(USE_ASM + "var i=13.37; function f() { var j=i; return +j } return f");
+assertAsmTypeFail('global', USE_ASM + "var f32 = global.Math.fround; var i=f32(13.37); function f() { var j=i; return f32(j) } return f");
+
+assertEq(asmLink(asmCompile('global', USE_ASM + 'var i=global.Infinity; function f() { var j=i; return +j } return f'), {Infinity:Infinity})(), Infinity);
+assertEq(asmLink(asmCompile('global', USE_ASM + 'var i=global.NaN; function f() { var j=i; return +j } return f'), {NaN:NaN})(), NaN);
+
+assertEq(asmLink(asmCompile(USE_ASM + "const i=13; function f() { var j=i; return j|0 } return f"))(), 13);
+assertEq(asmLink(asmCompile(USE_ASM + "const i=13.37; function f() { var j=i; return +j } return f"))(), 13.37);
+assertEq(asmLink(asmCompile('global', USE_ASM + "var f32 = global.Math.fround; const i=f32(13.37); function f() { var j=i; return f32(j) } return f"), this)(), Math.fround(13.37));
+
+assertAsmTypeFail(USE_ASM + "function f() { var j=i; return j|0 } return f");
+assertAsmTypeFail(USE_ASM + "function i(){} function f() { var j=i; return j|0 } return f");
+assertAsmTypeFail(USE_ASM + "function f() { var j=i; return j|0 } var i = [f]; return f");
+assertAsmTypeFail('global', USE_ASM + "var i=global.Math.fround; function f() { var j=i; return j|0 } return f");
+assertAsmTypeFail('global', 'imp', USE_ASM + "var i=imp.f; function f() { var j=i; return j|0 } return f");
+assertAsmTypeFail('global', 'imp', USE_ASM + "var i=imp.i|0; function f() { var j=i; return j|0 } return f");
+assertAsmTypeFail('global', 'imp', USE_ASM + "var i=+imp.i; function f() { var j=i; return +j } return f");
+assertAsmTypeFail('global', 'imp', USE_ASM + "const i=imp.i|0; function f() { var j=i; return j|0 } return f");
+assertAsmTypeFail('global', 'imp', USE_ASM + "const i=+imp.i; function f() { var j=i; return +j } return f");
+assertAsmTypeFail('global', 'imp', 'heap', USE_ASM + "var i=new global.Float32Array(heap); function f() { var j=i; return +j } return f");
+
 assertAsmTypeFail('global', USE_ASM + "var i=global; function f() { return i|0 } return f");
 assertAsmTypeFail('global', USE_ASM + "const i=global; function f() { return i|0 } return f");
 assertAsmTypeFail('global', USE_ASM + "var i=global|0; function f() { return i|0 } return f");
 assertAsmTypeFail('global', USE_ASM + "const i=global|0; function f() { return i|0 } return f");
 assertAsmTypeFail('global', USE_ASM + "var j=0;var i=j.i|0; function f() { return i|0 } return f");
 assertAsmTypeFail('global', USE_ASM + "var i=global.i|0; function f() { return i|0 } return f");
 assertAsmTypeFail('global', USE_ASM + "const i=global.i|0; function f() { return i|0 } return f");
 assertAsmTypeFail('global', USE_ASM + "var i=global.i|0; function f() { return i|0 } return f");
--- a/js/src/jit/AsmJS.cpp
+++ b/js/src/jit/AsmJS.cpp
@@ -3285,18 +3285,29 @@ CheckVariable(FunctionCompiler &f, Parse
 
     if (!CheckIdentifier(f.m(), var, name))
         return false;
 
     ParseNode *initNode = MaybeDefinitionInitializer(var);
     if (!initNode)
         return f.failName(var, "var '%s' needs explicit type declaration via an initial value", name);
 
+    if (initNode->isKind(PNK_NAME)) {
+        PropertyName *initName = initNode->name();
+        if (const ModuleCompiler::Global *global = f.lookupGlobal(initName)) {
+            if (global->which() != ModuleCompiler::Global::ConstantLiteral)
+                return f.failName(initNode, "'%s' isn't a possible global variable initializer, "
+                                            "needs to be a const numeric literal", initName);
+            return f.addVariable(var, name, global->varOrConstType(), global->constLiteralValue());
+        }
+        return f.failName(initNode, "'%s' needs to be a global name", initName);
+    }
+
     if (!IsNumericLiteral(f.m(), initNode))
-        return f.failName(initNode, "initializer for '%s' needs to be a numeric literal", name);
+        return f.failName(initNode, "initializer for '%s' needs to be a numeric literal or a global const literal", name);
 
     NumLit literal = ExtractNumericLiteral(f.m(), initNode);
     if (!literal.hasType())
         return f.failName(initNode, "initializer for '%s' is out of range", name);
 
     return f.addVariable(var, name, literal.varType(), literal.value());
 }