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 => { | ||||
| 					parser.hooks.statementIf.tap("ConstPlugin", statement => { | ||||
| 						if (parser.scope.isAsmJs) return; | ||||
| 						const param = parser.evaluateExpression(statement.test); | ||||
| 						const bool = param.asBool(); | ||||
| 						if (typeof bool === "boolean") { | ||||
|  | @ -201,6 +202,7 @@ class ConstPlugin { | |||
| 					parser.hooks.expressionConditionalOperator.tap( | ||||
| 						"ConstPlugin", | ||||
| 						expression => { | ||||
| 							if (parser.scope.isAsmJs) return; | ||||
| 							const param = parser.evaluateExpression(expression.test); | ||||
| 							const bool = param.asBool(); | ||||
| 							if (typeof bool === "boolean") { | ||||
|  | @ -236,6 +238,7 @@ class ConstPlugin { | |||
| 					parser.hooks.expressionLogicalOperator.tap( | ||||
| 						"ConstPlugin", | ||||
| 						expression => { | ||||
| 							if (parser.scope.isAsmJs) return; | ||||
| 							if ( | ||||
| 								expression.operator === "&&" || | ||||
| 								expression.operator === "||" | ||||
|  | @ -321,6 +324,7 @@ class ConstPlugin { | |||
| 					parser.hooks.evaluateIdentifier | ||||
| 						.for("__resourceQuery") | ||||
| 						.tap("ConstPlugin", expr => { | ||||
| 							if (parser.scope.isAsmJs) return; | ||||
| 							if (!parser.state.module) return; | ||||
| 							return evaluateToString(getQuery(parser.state.module.resource))( | ||||
| 								expr | ||||
|  | @ -329,6 +333,7 @@ class ConstPlugin { | |||
| 					parser.hooks.expression | ||||
| 						.for("__resourceQuery") | ||||
| 						.tap("ConstPlugin", expr => { | ||||
| 							if (parser.scope.isAsmJs) return; | ||||
| 							if (!parser.state.module) return; | ||||
| 							const dep = new CachedConstDependency( | ||||
| 								JSON.stringify(getQuery(parser.state.module.resource)), | ||||
|  |  | |||
|  | @ -78,6 +78,7 @@ class VariableInfo { | |||
|  * @property {boolean | "arrow"} topLevelScope | ||||
|  * @property {boolean} inShorthand | ||||
|  * @property {boolean} isStrict | ||||
|  * @property {boolean} isAsmJs | ||||
|  * @property {boolean} inTry | ||||
|  */ | ||||
| 
 | ||||
|  | @ -1455,7 +1456,7 @@ class JavascriptParser extends Parser { | |||
| 				this.walkPattern(param); | ||||
| 			} | ||||
| 			if (statement.body.type === "BlockStatement") { | ||||
| 				this.detectStrictMode(statement.body.body); | ||||
| 				this.detectMode(statement.body.body); | ||||
| 				this.prewalkStatement(statement.body); | ||||
| 				this.walkStatement(statement.body); | ||||
| 			} else { | ||||
|  | @ -1935,7 +1936,7 @@ class JavascriptParser extends Parser { | |||
| 				this.walkPattern(param); | ||||
| 			} | ||||
| 			if (expression.body.type === "BlockStatement") { | ||||
| 				this.detectStrictMode(expression.body.body); | ||||
| 				this.detectMode(expression.body.body); | ||||
| 				this.prewalkStatement(expression.body); | ||||
| 				this.walkStatement(expression.body); | ||||
| 			} else { | ||||
|  | @ -1953,7 +1954,7 @@ class JavascriptParser extends Parser { | |||
| 				this.walkPattern(param); | ||||
| 			} | ||||
| 			if (expression.body.type === "BlockStatement") { | ||||
| 				this.detectStrictMode(expression.body.body); | ||||
| 				this.detectMode(expression.body.body); | ||||
| 				this.prewalkStatement(expression.body); | ||||
| 				this.walkStatement(expression.body); | ||||
| 			} else { | ||||
|  | @ -2172,6 +2173,7 @@ class JavascriptParser extends Parser { | |||
| 				this.setVariable(params[i].name, varInfo); | ||||
| 			} | ||||
| 			if (functionExpression.body.type === "BlockStatement") { | ||||
| 				this.detectMode(functionExpression.body.body); | ||||
| 				this.prewalkStatement(functionExpression.body); | ||||
| 				this.walkStatement(functionExpression.body); | ||||
| 			} else { | ||||
|  | @ -2495,6 +2497,7 @@ class JavascriptParser extends Parser { | |||
| 			inTry: false, | ||||
| 			inShorthand: false, | ||||
| 			isStrict: oldScope.isStrict, | ||||
| 			isAsmJs: oldScope.isAsmJs, | ||||
| 			definitions: oldScope.definitions.createChild() | ||||
| 		}; | ||||
| 
 | ||||
|  | @ -2516,6 +2519,7 @@ class JavascriptParser extends Parser { | |||
| 			inTry: false, | ||||
| 			inShorthand: false, | ||||
| 			isStrict: oldScope.isStrict, | ||||
| 			isAsmJs: oldScope.isAsmJs, | ||||
| 			definitions: oldScope.definitions.createChild() | ||||
| 		}; | ||||
| 
 | ||||
|  | @ -2539,6 +2543,7 @@ class JavascriptParser extends Parser { | |||
| 			inTry: oldScope.inTry, | ||||
| 			inShorthand: false, | ||||
| 			isStrict: oldScope.isStrict, | ||||
| 			isAsmJs: oldScope.isAsmJs, | ||||
| 			definitions: oldScope.definitions.createChild() | ||||
| 		}; | ||||
| 
 | ||||
|  | @ -2547,15 +2552,17 @@ class JavascriptParser extends Parser { | |||
| 		this.scope = oldScope; | ||||
| 	} | ||||
| 
 | ||||
| 	detectStrictMode(statements) { | ||||
| 		const isStrict = | ||||
| 	detectMode(statements) { | ||||
| 		const isLiteral = | ||||
| 			statements.length >= 1 && | ||||
| 			statements[0].type === "ExpressionStatement" && | ||||
| 			statements[0].expression.type === "Literal" && | ||||
| 			statements[0].expression.value === "use strict"; | ||||
| 		if (isStrict) { | ||||
| 			statements[0].expression.type === "Literal"; | ||||
| 		if (isLiteral && statements[0].expression.value === "use strict") { | ||||
| 			this.scope.isStrict = true; | ||||
| 		} | ||||
| 		if (isLiteral && statements[0].expression.value === "use asm") { | ||||
| 			this.scope.isAsmJs = true; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	enterPatterns(patterns, onIdent) { | ||||
|  | @ -2790,6 +2797,7 @@ class JavascriptParser extends Parser { | |||
| 			inTry: false, | ||||
| 			inShorthand: false, | ||||
| 			isStrict: false, | ||||
| 			isAsmJs: false, | ||||
| 			definitions: new StackedMap() | ||||
| 		}; | ||||
| 		/** @type {ParserState} */ | ||||
|  | @ -2800,7 +2808,7 @@ class JavascriptParser extends Parser { | |||
| 		this.lastStatementEndPos = NaN; | ||||
| 		this.statementStartPos = NaN; | ||||
| 		if (this.hooks.program.call(ast, comments) === undefined) { | ||||
| 			this.detectStrictMode(ast.body); | ||||
| 			this.detectMode(ast.body); | ||||
| 			this.prewalkStatements(ast.body); | ||||
| 			this.blockPrewalkStatements(ast.body); | ||||
| 			this.walkStatements(ast.body); | ||||
|  |  | |||
|  | @ -170,6 +170,26 @@ describe("Compiler", () => { | |||
| 			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", () => { | ||||
| 		let compiler; | ||||
| 		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