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