mirror of https://github.com/webpack/webpack.git
Merge pull request #10288 from ngg/asmjs
do not evaluate constants in asm.js, fix IIFE mode detection
This commit is contained in:
commit
a302e6e208
|
|
@ -131,6 +131,7 @@ class ConstPlugin {
|
||||||
|
|
||||||
const handler = parser => {
|
const handler = parser => {
|
||||||
parser.hooks.statementIf.tap("ConstPlugin", statement => {
|
parser.hooks.statementIf.tap("ConstPlugin", statement => {
|
||||||
|
if (parser.scope.isAsmJs) return;
|
||||||
const param = parser.evaluateExpression(statement.test);
|
const param = parser.evaluateExpression(statement.test);
|
||||||
const bool = param.asBool();
|
const bool = param.asBool();
|
||||||
if (typeof bool === "boolean") {
|
if (typeof bool === "boolean") {
|
||||||
|
|
@ -201,6 +202,7 @@ class ConstPlugin {
|
||||||
parser.hooks.expressionConditionalOperator.tap(
|
parser.hooks.expressionConditionalOperator.tap(
|
||||||
"ConstPlugin",
|
"ConstPlugin",
|
||||||
expression => {
|
expression => {
|
||||||
|
if (parser.scope.isAsmJs) return;
|
||||||
const param = parser.evaluateExpression(expression.test);
|
const param = parser.evaluateExpression(expression.test);
|
||||||
const bool = param.asBool();
|
const bool = param.asBool();
|
||||||
if (typeof bool === "boolean") {
|
if (typeof bool === "boolean") {
|
||||||
|
|
@ -236,6 +238,7 @@ class ConstPlugin {
|
||||||
parser.hooks.expressionLogicalOperator.tap(
|
parser.hooks.expressionLogicalOperator.tap(
|
||||||
"ConstPlugin",
|
"ConstPlugin",
|
||||||
expression => {
|
expression => {
|
||||||
|
if (parser.scope.isAsmJs) return;
|
||||||
if (
|
if (
|
||||||
expression.operator === "&&" ||
|
expression.operator === "&&" ||
|
||||||
expression.operator === "||"
|
expression.operator === "||"
|
||||||
|
|
@ -321,6 +324,7 @@ class ConstPlugin {
|
||||||
parser.hooks.evaluateIdentifier
|
parser.hooks.evaluateIdentifier
|
||||||
.for("__resourceQuery")
|
.for("__resourceQuery")
|
||||||
.tap("ConstPlugin", expr => {
|
.tap("ConstPlugin", expr => {
|
||||||
|
if (parser.scope.isAsmJs) return;
|
||||||
if (!parser.state.module) return;
|
if (!parser.state.module) return;
|
||||||
return evaluateToString(getQuery(parser.state.module.resource))(
|
return evaluateToString(getQuery(parser.state.module.resource))(
|
||||||
expr
|
expr
|
||||||
|
|
@ -329,6 +333,7 @@ class ConstPlugin {
|
||||||
parser.hooks.expression
|
parser.hooks.expression
|
||||||
.for("__resourceQuery")
|
.for("__resourceQuery")
|
||||||
.tap("ConstPlugin", expr => {
|
.tap("ConstPlugin", expr => {
|
||||||
|
if (parser.scope.isAsmJs) return;
|
||||||
if (!parser.state.module) return;
|
if (!parser.state.module) return;
|
||||||
const dep = new CachedConstDependency(
|
const dep = new CachedConstDependency(
|
||||||
JSON.stringify(getQuery(parser.state.module.resource)),
|
JSON.stringify(getQuery(parser.state.module.resource)),
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ class VariableInfo {
|
||||||
* @property {boolean | "arrow"} topLevelScope
|
* @property {boolean | "arrow"} topLevelScope
|
||||||
* @property {boolean} inShorthand
|
* @property {boolean} inShorthand
|
||||||
* @property {boolean} isStrict
|
* @property {boolean} isStrict
|
||||||
|
* @property {boolean} isAsmJs
|
||||||
* @property {boolean} inTry
|
* @property {boolean} inTry
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1455,7 +1456,7 @@ class JavascriptParser extends Parser {
|
||||||
this.walkPattern(param);
|
this.walkPattern(param);
|
||||||
}
|
}
|
||||||
if (statement.body.type === "BlockStatement") {
|
if (statement.body.type === "BlockStatement") {
|
||||||
this.detectStrictMode(statement.body.body);
|
this.detectMode(statement.body.body);
|
||||||
this.prewalkStatement(statement.body);
|
this.prewalkStatement(statement.body);
|
||||||
this.walkStatement(statement.body);
|
this.walkStatement(statement.body);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1935,7 +1936,7 @@ class JavascriptParser extends Parser {
|
||||||
this.walkPattern(param);
|
this.walkPattern(param);
|
||||||
}
|
}
|
||||||
if (expression.body.type === "BlockStatement") {
|
if (expression.body.type === "BlockStatement") {
|
||||||
this.detectStrictMode(expression.body.body);
|
this.detectMode(expression.body.body);
|
||||||
this.prewalkStatement(expression.body);
|
this.prewalkStatement(expression.body);
|
||||||
this.walkStatement(expression.body);
|
this.walkStatement(expression.body);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1953,7 +1954,7 @@ class JavascriptParser extends Parser {
|
||||||
this.walkPattern(param);
|
this.walkPattern(param);
|
||||||
}
|
}
|
||||||
if (expression.body.type === "BlockStatement") {
|
if (expression.body.type === "BlockStatement") {
|
||||||
this.detectStrictMode(expression.body.body);
|
this.detectMode(expression.body.body);
|
||||||
this.prewalkStatement(expression.body);
|
this.prewalkStatement(expression.body);
|
||||||
this.walkStatement(expression.body);
|
this.walkStatement(expression.body);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2172,6 +2173,7 @@ class JavascriptParser extends Parser {
|
||||||
this.setVariable(params[i].name, varInfo);
|
this.setVariable(params[i].name, varInfo);
|
||||||
}
|
}
|
||||||
if (functionExpression.body.type === "BlockStatement") {
|
if (functionExpression.body.type === "BlockStatement") {
|
||||||
|
this.detectMode(functionExpression.body.body);
|
||||||
this.prewalkStatement(functionExpression.body);
|
this.prewalkStatement(functionExpression.body);
|
||||||
this.walkStatement(functionExpression.body);
|
this.walkStatement(functionExpression.body);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2495,6 +2497,7 @@ class JavascriptParser extends Parser {
|
||||||
inTry: false,
|
inTry: false,
|
||||||
inShorthand: false,
|
inShorthand: false,
|
||||||
isStrict: oldScope.isStrict,
|
isStrict: oldScope.isStrict,
|
||||||
|
isAsmJs: oldScope.isAsmJs,
|
||||||
definitions: oldScope.definitions.createChild()
|
definitions: oldScope.definitions.createChild()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -2516,6 +2519,7 @@ class JavascriptParser extends Parser {
|
||||||
inTry: false,
|
inTry: false,
|
||||||
inShorthand: false,
|
inShorthand: false,
|
||||||
isStrict: oldScope.isStrict,
|
isStrict: oldScope.isStrict,
|
||||||
|
isAsmJs: oldScope.isAsmJs,
|
||||||
definitions: oldScope.definitions.createChild()
|
definitions: oldScope.definitions.createChild()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -2539,6 +2543,7 @@ class JavascriptParser extends Parser {
|
||||||
inTry: oldScope.inTry,
|
inTry: oldScope.inTry,
|
||||||
inShorthand: false,
|
inShorthand: false,
|
||||||
isStrict: oldScope.isStrict,
|
isStrict: oldScope.isStrict,
|
||||||
|
isAsmJs: oldScope.isAsmJs,
|
||||||
definitions: oldScope.definitions.createChild()
|
definitions: oldScope.definitions.createChild()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -2547,15 +2552,17 @@ class JavascriptParser extends Parser {
|
||||||
this.scope = oldScope;
|
this.scope = oldScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
detectStrictMode(statements) {
|
detectMode(statements) {
|
||||||
const isStrict =
|
const isLiteral =
|
||||||
statements.length >= 1 &&
|
statements.length >= 1 &&
|
||||||
statements[0].type === "ExpressionStatement" &&
|
statements[0].type === "ExpressionStatement" &&
|
||||||
statements[0].expression.type === "Literal" &&
|
statements[0].expression.type === "Literal";
|
||||||
statements[0].expression.value === "use strict";
|
if (isLiteral && statements[0].expression.value === "use strict") {
|
||||||
if (isStrict) {
|
|
||||||
this.scope.isStrict = true;
|
this.scope.isStrict = true;
|
||||||
}
|
}
|
||||||
|
if (isLiteral && statements[0].expression.value === "use asm") {
|
||||||
|
this.scope.isAsmJs = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enterPatterns(patterns, onIdent) {
|
enterPatterns(patterns, onIdent) {
|
||||||
|
|
@ -2790,6 +2797,7 @@ class JavascriptParser extends Parser {
|
||||||
inTry: false,
|
inTry: false,
|
||||||
inShorthand: false,
|
inShorthand: false,
|
||||||
isStrict: false,
|
isStrict: false,
|
||||||
|
isAsmJs: false,
|
||||||
definitions: new StackedMap()
|
definitions: new StackedMap()
|
||||||
};
|
};
|
||||||
/** @type {ParserState} */
|
/** @type {ParserState} */
|
||||||
|
|
@ -2800,7 +2808,7 @@ class JavascriptParser extends Parser {
|
||||||
this.lastStatementEndPos = NaN;
|
this.lastStatementEndPos = NaN;
|
||||||
this.statementStartPos = NaN;
|
this.statementStartPos = NaN;
|
||||||
if (this.hooks.program.call(ast, comments) === undefined) {
|
if (this.hooks.program.call(ast, comments) === undefined) {
|
||||||
this.detectStrictMode(ast.body);
|
this.detectMode(ast.body);
|
||||||
this.prewalkStatements(ast.body);
|
this.prewalkStatements(ast.body);
|
||||||
this.blockPrewalkStatements(ast.body);
|
this.blockPrewalkStatements(ast.body);
|
||||||
this.walkStatements(ast.body);
|
this.walkStatements(ast.body);
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,26 @@ describe("Compiler", () => {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should not evaluate constants in asm.js", done => {
|
||||||
|
compile("./asmjs", {}, (stats, files) => {
|
||||||
|
expect(Object.keys(files)).toEqual(["/main.js"]);
|
||||||
|
const bundle = files["/main.js"];
|
||||||
|
expect(bundle).toMatch('"use asm";');
|
||||||
|
expect(bundle).toMatch("101");
|
||||||
|
expect(bundle).toMatch("102");
|
||||||
|
expect(bundle).toMatch("103");
|
||||||
|
expect(bundle).toMatch("104");
|
||||||
|
expect(bundle).toMatch("105");
|
||||||
|
expect(bundle).not.toMatch("106");
|
||||||
|
expect(bundle).not.toMatch("107");
|
||||||
|
expect(bundle).not.toMatch("108");
|
||||||
|
expect(bundle).toMatch("109");
|
||||||
|
expect(bundle).toMatch("110");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("methods", () => {
|
describe("methods", () => {
|
||||||
let compiler;
|
let compiler;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
module.exports = function a() {
|
||||||
|
function b() {
|
||||||
|
"use asm";
|
||||||
|
if (0 == 0) {
|
||||||
|
return 1 == 1 ? 101 : 102;
|
||||||
|
} else {
|
||||||
|
return 0 == 1 ? 103 : 104;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function c() {
|
||||||
|
if (0 == 0) {
|
||||||
|
return 1 == 1 ? 105 : 106;
|
||||||
|
} else {
|
||||||
|
return 0 == 1 ? 107 : 108;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var d = (function() {
|
||||||
|
"use asm";
|
||||||
|
return 1 == 1 ? 109 : 110;
|
||||||
|
})();
|
||||||
|
return b() + c() + d;
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue