Backed out changeset c417fb206f6c (bug 1308056)
authorSebastian Hengst <archaeopteryx@coole-files.de>
Tue, 11 Oct 2016 14:25:13 +0200
changeset 360375 ced9e3a01e45e1595cae4133993be10114260c55
parent 360374 f9b61cc39e92fb28f7d5d946c4a78123db56970a
child 360376 d77072059582f13fe62477717836cec397dbc70b
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-beta@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1308056
milestone52.0a1
backs outc417fb206f6cb7fb6c4059f437f8f59f9c18b46e
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
Backed out changeset c417fb206f6c (bug 1308056)
js/src/asmjs/WasmTextToBinary.cpp
js/src/jit-test/tests/wasm/table-gc.js
js/src/jit-test/tests/wasm/tables.js
js/src/jit-test/tests/wasm/text.js
--- a/js/src/asmjs/WasmTextToBinary.cpp
+++ b/js/src/asmjs/WasmTextToBinary.cpp
@@ -2489,59 +2489,110 @@ ParseLocalOrParam(WasmParseContext& c, A
         return locals->append(AstName()) && ParseValueTypeList(c, localTypes);
 
     WasmToken token;
     return locals->append(c.ts.get().name()) &&
            c.ts.match(WasmToken::ValueType, &token, c.error) &&
            localTypes->append(token.valueType());
 }
 
-static bool
-ParseInlineImport(WasmParseContext& c, InlineImport* import)
-{
-    return c.ts.match(WasmToken::Text, &import->module, c.error) &&
-           c.ts.match(WasmToken::Text, &import->field, c.error);
-}
-
-static bool
-ParseInlineExport(WasmParseContext& c, DefinitionKind kind, AstModule* module,
-                  AstRef ref = AstRef())
+static AstFunc*
+ParseFunc(WasmParseContext& c, AstModule* module)
 {
-    WasmToken name;
-    if (!c.ts.match(WasmToken::Text, &name, c.error))
-        return false;
-
-    AstExport* exp = nullptr;
-    if (!ref.isInvalid())
-        exp = new(c.lifo) AstExport(name.text(), kind, ref);
-    else
-        exp = new(c.lifo) AstExport(name.text(), kind);
-
-    return exp && module->append(exp);
-}
-
-static bool
-MaybeParseTypeUse(WasmParseContext& c, AstRef* sig)
-{
+    AstValTypeVector vars(c.lifo);
+    AstValTypeVector args(c.lifo);
+    AstNameVector locals(c.lifo);
+
+    AstName exportName = c.ts.getIfText();
+    AstName funcName = c.ts.getIfName();
+
+    AstRef sig;
+
     WasmToken openParen;
+    if (exportName.empty() && c.ts.getIf(WasmToken::OpenParen, &openParen)) {
+        if (c.ts.getIf(WasmToken::Export)) {
+            WasmToken text;
+            if (!c.ts.match(WasmToken::Text, &text, c.error))
+                return nullptr;
+            if (!c.ts.match(WasmToken::CloseParen, c.error))
+                return nullptr;
+            exportName = text.text();
+        } else {
+            c.ts.unget(openParen);
+        }
+    }
+
+    if (!exportName.empty()) {
+        if (funcName.empty())
+            funcName = exportName;
+        AstExport* exp = new(c.lifo) AstExport(exportName, DefinitionKind::Function,
+                                               AstRef(funcName, AstNoIndex));
+        if (!exp || !module->append(exp))
+            return nullptr;
+    }
+
     if (c.ts.getIf(WasmToken::OpenParen, &openParen)) {
         if (c.ts.getIf(WasmToken::Type)) {
-            if (!c.ts.matchRef(sig, c.error))
-                return false;
+            if (!c.ts.matchRef(&sig, c.error))
+                return nullptr;
             if (!c.ts.match(WasmToken::CloseParen, c.error))
-                return false;
+                return nullptr;
         } else {
             c.ts.unget(openParen);
         }
     }
-    return true;
+
+    AstExprVector body(c.lifo);
+    ExprType result = ExprType::Void;
+
+    while (c.ts.getIf(WasmToken::OpenParen)) {
+        WasmToken token = c.ts.get();
+        switch (token.kind()) {
+          case WasmToken::Local:
+            if (!ParseLocalOrParam(c, &locals, &vars))
+                return nullptr;
+            break;
+          case WasmToken::Param:
+            if (!vars.empty()) {
+                c.ts.generateError(token, c.error);
+                return nullptr;
+            }
+            if (!ParseLocalOrParam(c, &locals, &args))
+                return nullptr;
+            break;
+          case WasmToken::Result:
+            if (!ParseResult(c, &result))
+                return nullptr;
+            break;
+          default:
+            c.ts.unget(token);
+            AstExpr* expr = ParseExprInsideParens(c);
+            if (!expr || !body.append(expr))
+                return nullptr;
+            break;
+        }
+        if (!c.ts.match(WasmToken::CloseParen, c.error))
+            return nullptr;
+    }
+
+    if (!ParseExprList(c, &body, true))
+        return nullptr;
+
+    if (sig.isInvalid()) {
+        uint32_t sigIndex;
+        if (!module->declare(AstSig(Move(args), result), &sigIndex))
+            return nullptr;
+        sig.setIndex(sigIndex);
+    }
+
+    return new(c.lifo) AstFunc(funcName, sig, Move(vars), Move(locals), Move(body));
 }
 
 static bool
-ParseFuncSig(WasmParseContext& c, AstSig* sig)
+ParseFuncType(WasmParseContext& c, AstSig* sig)
 {
     AstValTypeVector args(c.lifo);
     ExprType result = ExprType::Void;
 
     while (c.ts.getIf(WasmToken::OpenParen)) {
         WasmToken token = c.ts.get();
         switch (token.kind()) {
           case WasmToken::Param:
@@ -2559,143 +2610,28 @@ ParseFuncSig(WasmParseContext& c, AstSig
         if (!c.ts.match(WasmToken::CloseParen, c.error))
             return false;
     }
 
     *sig = AstSig(Move(args), result);
     return true;
 }
 
-static bool
-ParseFuncType(WasmParseContext& c, AstRef* ref, AstModule* module)
-{
-    if (!MaybeParseTypeUse(c, ref))
-        return false;
-
-    if (ref->isInvalid()) {
-        AstSig sig(c.lifo);
-        if (!ParseFuncSig(c, &sig))
-            return false;
-        uint32_t sigIndex;
-        if (!module->declare(Move(sig), &sigIndex))
-            return false;
-        ref->setIndex(sigIndex);
-    }
-
-    return true;
-}
-
-static bool
-ParseFunc(WasmParseContext& c, AstModule* module)
-{
-    AstValTypeVector vars(c.lifo);
-    AstValTypeVector args(c.lifo);
-    AstNameVector locals(c.lifo);
-
-    AstName funcName = c.ts.getIfName();
-
-    // Inline imports and exports.
-    WasmToken openParen;
-    if (c.ts.getIf(WasmToken::OpenParen, &openParen)) {
-        if (c.ts.getIf(WasmToken::Import)) {
-            if (module->funcs().length()) {
-                c.ts.generateError(openParen, "import after function definition", c.error);
-                return false;
-            }
-
-            InlineImport names;
-            if (!ParseInlineImport(c, &names))
-                return false;
-            if (!c.ts.match(WasmToken::CloseParen, c.error))
-                return false;
-
-            AstRef sig;
-            if (!ParseFuncType(c, &sig, module))
-                return false;
-
-            auto* imp = new(c.lifo) AstImport(funcName, names.module.text(), names.field.text(), sig);
-            return imp && module->append(imp);
-        }
-
-        if (c.ts.getIf(WasmToken::Export)) {
-            AstRef ref = funcName.empty()
-                         ? AstRef(AstName(), module->funcImportNames().length() + module->funcs().length())
-                         : AstRef(funcName, AstNoIndex);
-            if (!ParseInlineExport(c, DefinitionKind::Function, module, ref))
-                return false;
-            if (!c.ts.match(WasmToken::CloseParen, c.error))
-                return false;
-        } else {
-            c.ts.unget(openParen);
-        }
-    }
-
-    AstRef sigRef;
-    if (!MaybeParseTypeUse(c, &sigRef))
-        return false;
-
-    AstExprVector body(c.lifo);
-
-    ExprType result = ExprType::Void;
-    while (c.ts.getIf(WasmToken::OpenParen)) {
-        WasmToken token = c.ts.get();
-        switch (token.kind()) {
-          case WasmToken::Local:
-            if (!ParseLocalOrParam(c, &locals, &vars))
-                return false;
-            break;
-          case WasmToken::Param:
-            if (!vars.empty()) {
-                c.ts.generateError(token, c.error);
-                return false;
-            }
-            if (!ParseLocalOrParam(c, &locals, &args))
-                return false;
-            break;
-          case WasmToken::Result:
-            if (!ParseResult(c, &result))
-                return false;
-            break;
-          default:
-            c.ts.unget(token);
-            AstExpr* expr = ParseExprInsideParens(c);
-            if (!expr || !body.append(expr))
-                return false;
-            break;
-        }
-        if (!c.ts.match(WasmToken::CloseParen, c.error))
-            return false;
-    }
-
-    if (!ParseExprList(c, &body, true))
-        return false;
-
-    if (sigRef.isInvalid()) {
-        uint32_t sigIndex;
-        if (!module->declare(AstSig(Move(args), result), &sigIndex))
-            return false;
-        sigRef.setIndex(sigIndex);
-    }
-
-    auto* func = new(c.lifo) AstFunc(funcName, sigRef, Move(vars), Move(locals), Move(body));
-    return func && module->append(func);
-}
-
 static AstSig*
 ParseTypeDef(WasmParseContext& c)
 {
     AstName name = c.ts.getIfName();
 
     if (!c.ts.match(WasmToken::OpenParen, c.error))
         return nullptr;
     if (!c.ts.match(WasmToken::Func, c.error))
         return nullptr;
 
     AstSig sig(c.lifo);
-    if (!ParseFuncSig(c, &sig))
+    if (!ParseFuncType(c, &sig))
         return nullptr;
 
     if (!c.ts.match(WasmToken::CloseParen, c.error))
         return nullptr;
 
     return new(c.lifo) AstSig(name, Move(sig));
 }
 
@@ -2868,38 +2804,51 @@ ParseImport(WasmParseContext& c, AstModu
             if (!c.ts.match(WasmToken::CloseParen, c.error))
                 return nullptr;
             return new(c.lifo) AstImport(name, moduleName.text(), fieldName.text(),
                                          AstGlobal(AstName(), typeToken.valueType(), flags));
         }
         if (c.ts.getIf(WasmToken::Func)) {
             AstName name = c.ts.getIfName();
 
-            AstRef sigRef;
-            if (!ParseFuncType(c, &sigRef, module))
-                return nullptr;
+            WasmToken token;
+            if (c.ts.getIf(WasmToken::Type, &token)) {
+                if (!c.ts.matchRef(&sigRef, c.error))
+                    return nullptr;
+            } else {
+                AstSig sig(c.lifo);
+                if (!ParseFuncType(c, &sig))
+                    return nullptr;
+
+                uint32_t sigIndex;
+                if (!module->declare(Move(sig), &sigIndex))
+                    return nullptr;
+
+                sigRef.setIndex(sigIndex);
+            }
             if (!c.ts.match(WasmToken::CloseParen, c.error))
                 return nullptr;
 
-            return new(c.lifo) AstImport(name, moduleName.text(), fieldName.text(), sigRef);
+            return new(c.lifo) AstImport(name, moduleName.text(), fieldName.text(),
+                                         sigRef);
         }
 
         if (c.ts.getIf(WasmToken::Type)) {
             if (!c.ts.matchRef(&sigRef, c.error))
                 return nullptr;
             if (!c.ts.match(WasmToken::CloseParen, c.error))
                 return nullptr;
         } else {
             c.ts.unget(openParen);
         }
     }
 
     if (sigRef.isInvalid()) {
         AstSig sig(c.lifo);
-        if (!ParseFuncSig(c, &sig))
+        if (!ParseFuncType(c, &sig))
             return nullptr;
 
         uint32_t sigIndex;
         if (!module->declare(Move(sig), &sigIndex))
             return nullptr;
         sigRef.setIndex(sigIndex);
     }
 
@@ -2977,16 +2926,35 @@ ParseExport(WasmParseContext& c)
         break;
     }
 
     c.ts.generateError(exportee, c.error);
     return nullptr;
 }
 
 static bool
+ParseInlineImport(WasmParseContext& c, InlineImport* import)
+{
+    return c.ts.match(WasmToken::Text, &import->module, c.error) &&
+           c.ts.match(WasmToken::Text, &import->field, c.error);
+}
+
+static bool
+ParseInlineExport(WasmParseContext& c, DefinitionKind kind, AstModule* module)
+{
+    WasmToken name;
+    if (!c.ts.match(WasmToken::Text, &name, c.error))
+        return false;
+    auto* exp = new(c.lifo) AstExport(name.text(), kind);
+    if (!exp || !module->append(exp))
+        return false;
+    return true;
+}
+
+static bool
 ParseTable(WasmParseContext& c, WasmToken token, AstModule* module)
 {
     AstName name = c.ts.getIfName();
 
     if (c.ts.getIf(WasmToken::OpenParen)) {
         // Either an import and we're done, or an export and continue.
         if (c.ts.getIf(WasmToken::Import)) {
             InlineImport names;
@@ -3166,17 +3134,18 @@ ParseModule(const char16_t* text, LifoAl
           }
           case WasmToken::Elem: {
             AstElemSegment* segment = ParseElemSegment(c);
             if (!segment || !module->append(segment))
                 return nullptr;
             break;
           }
           case WasmToken::Func: {
-            if (!ParseFunc(c, module))
+            AstFunc* func = ParseFunc(c, module);
+            if (!func || !module->append(func))
                 return nullptr;
             break;
           }
           default:
             c.ts.generateError(section, c.error);
             return nullptr;
         }
 
--- a/js/src/jit-test/tests/wasm/table-gc.js
+++ b/js/src/jit-test/tests/wasm/table-gc.js
@@ -4,17 +4,17 @@
 
 load(libdir + 'wasm.js');
 
 const Module = WebAssembly.Module;
 const Instance = WebAssembly.Instance;
 const Table = WebAssembly.Table;
 
 var caller = `(type $v2i (func (result i32))) (func $call (param $i i32) (result i32) (call_indirect $v2i (get_local $i))) (export "call" $call)`
-var callee = i => `(func $f${i} (type $v2i) (i32.const ${i}))`;
+var callee = i => `(func $f${i} (type $v2i) (result i32) (i32.const ${i}))`;
 
 // A table should not hold exported functions alive and exported functions
 // should not hold their originating table alive. Live exported functions should
 // hold instances alive and instances hold imported tables alive. Nothing
 // should hold the export object alive.
 resetFinalizeCount();
 var i = wasmEvalText(`(module (table 2 anyfunc) (export "tbl" table) (elem (i32.const 0) $f0) ${callee(0)} ${caller})`);
 var e = i.exports;
--- a/js/src/jit-test/tests/wasm/tables.js
+++ b/js/src/jit-test/tests/wasm/tables.js
@@ -31,17 +31,17 @@ var m = new Module(wasmTextToBinary(`
         (elem (get_global 0) $f0 $f0)
         ${callee(0)})
 `));
 var tbl = new Table({initial:50, element:"anyfunc"});
 assertEq(new Instance(m, {globals:{a:20, table:tbl}}) instanceof Instance, true);
 assertErrorMessage(() => new Instance(m, {globals:{a:50, table:tbl}}), RangeError, /elem segment does not fit/);
 
 var caller = `(type $v2i (func (result i32))) (func $call (param $i i32) (result i32) (call_indirect $v2i (get_local $i))) (export "call" $call)`
-var callee = i => `(func $f${i} (type $v2i) (i32.const ${i}))`;
+var callee = i => `(func $f${i} (type $v2i) (result i32) (i32.const ${i}))`;
 
 var call = wasmEvalText(`(module (table 10 anyfunc) ${callee(0)} ${caller})`).exports.call;
 assertErrorMessage(() => call(0), Error, /indirect call to null/);
 assertErrorMessage(() => call(10), Error, /out-of-range/);
 
 var call = wasmEvalText(`(module (table 10 anyfunc) (elem (i32.const 0)) ${callee(0)} ${caller})`).exports.call;
 assertErrorMessage(() => call(0), Error, /indirect call to null/);
 assertErrorMessage(() => call(10), Error, /out-of-range/);
@@ -150,19 +150,19 @@ assertErrorMessage(() => e3.call(2), Err
 
 // Call signatures are matched structurally:
 
 var call = wasmEvalText(`(module
     (type $v2i1 (func (result i32)))
     (type $v2i2 (func (result i32)))
     (type $i2v (func (param i32)))
     (table anyfunc (elem $a $b $c))
-    (func $a (type $v2i1) (i32.const 0))
-    (func $b (type $v2i2) (i32.const 1))
-    (func $c (type $i2v))
+    (func $a (type $v2i1) (result i32) (i32.const 0))
+    (func $b (type $v2i2) (result i32) (i32.const 1))
+    (func $c (type $i2v) (param i32))
     (func $call (param i32) (result i32) (call_indirect $v2i1 (get_local 0)))
     (export "call" $call)
 )`).exports.call;
 assertEq(call(0), 0);
 assertEq(call(1), 1);
 assertErrorMessage(() => call(2), Error, /indirect call signature mismatch/);
 
 var call = wasmEvalText(`(module
--- a/js/src/jit-test/tests/wasm/text.js
+++ b/js/src/jit-test/tests/wasm/text.js
@@ -56,41 +56,10 @@ assertErrorMessage(() => wasmEvalText('(
 wasmEvalText('(module (table $t (import "mod" "field") 1 anyfunc))', {mod: {field: table}});
 
 assertErrorMessage(() => wasmEvalText('(module (table $t (export "mod") 1))'), SyntaxError, parsingError);
 assertErrorMessage(() => wasmEvalText('(module (table $t (export "mod") anyfunc))'), SyntaxError, parsingError);
 assertErrorMessage(() => wasmEvalText('(module (table $t (export "mod") anyfunc 1 2 3))'), SyntaxError, parsingError);
 assertEq(wasmEvalText('(module (table $t (export "tbl") anyfunc (elem)))').exports.tbl instanceof Table, true);
 assertEq(wasmEvalText('(module (func) (table $t (export "tbl") anyfunc (elem 0 0 0)))').exports.tbl instanceof Table, true);
 
-// Functions.
-assertErrorMessage(() => wasmEvalText('(module (func $t import))'), SyntaxError, parsingError);
-assertErrorMessage(() => wasmEvalText('(module (func $t (import)))'), SyntaxError, parsingError);
-assertErrorMessage(() => wasmEvalText('(module (func $t (import "mod")))'), SyntaxError, parsingError);
-assertErrorMessage(() => wasmEvalText('(module (func $t (import "mod" "func" (local i32))))'), SyntaxError, parsingError);
-
-const func = i => 42 + i;
-wasmEvalText('(module (func $t (import "mod" "func")))', { mod: {func} });
-wasmEvalText('(module (func $t (import "mod" "func")(param i32)))', { mod: {func} });
-wasmEvalText('(module (func $t (import "mod" "func")(result i32)))', { mod: {func} });
-wasmEvalText('(module (func $t (import "mod" "func")(param i32) (result i32)))', { mod: {func} });
-wasmEvalText('(module (func $t (import "mod" "func")(result i32) (param i32)))', { mod: {func} });
-
-assertErrorMessage(() => wasmEvalText('(module (func $t (import "mod" "func") (type)))', { mod: {func} }), SyntaxError, parsingError);
-wasmEvalText('(module (type $t (func)) (func $t (import "mod" "func") (type $t)))', { mod: {func} });
-
-assertErrorMessage(() => wasmEvalText('(module (func $t (export))))'), SyntaxError, parsingError);
-wasmEvalText('(module (func (export "f")))');
-wasmEvalText('(module (func $f (export "f")))');
-wasmEvalText('(module (func $f (export "f") (result i32) (param i32) (i32.add (get_local 0) (i32.const 42))))');
-
-assertErrorMessage(() => wasmEvalText(`
-    (module
-        (type $tf (func (param i32) (result i32)))
-        (func (import "mod" "a") (type $tf))
-        (func (export "f1"))
-        (func (import "mod" "b") (type $tf))
-        (func (export "f2"))
-    )
-`), SyntaxError, /import after function definition/);
-
 // Note: the s-expression text format is temporary, this file is mostly just to
 // hold basic error smoke tests.