diff --git a/.gitignore b/.gitignore index b2a4b763..cc420697 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ !.gitkeep +.DS_Store # temporary files diff --git a/.npmignore b/.npmignore index 2659cf0b..cd855f14 100644 --- a/.npmignore +++ b/.npmignore @@ -11,10 +11,12 @@ bootstrap/ .jsx tmp/ + # products try/ doc/ +example/ # npm-related files @@ -37,3 +39,27 @@ linux-* # git stuff .git* + +# only for JSX compiler developer + +t/ +src/ +.travis.yml +.npmignore +.proverc +extlib/ +gruntfile.js +submodules/ +xt/ +release-engineering.md +idl2jsx/ +tool/bootstrap-compiler.js +tool/git-hooks-pre-push +tool/form +tool/Util.pm +tool/jsx.pl +tool/make-meta +tool/postpublish.jsx +tool/setup.pl +tool/toggle-todo +web/ diff --git a/src/doc/style.css b/etc/doc-template/style.css similarity index 100% rename from src/doc/style.css rename to etc/doc-template/style.css diff --git a/src/doc/template.html b/etc/doc-template/template.html similarity index 100% rename from src/doc/template.html rename to etc/doc-template/template.html diff --git a/src/js/bootstrap.js b/lib/js-startup/bootstrap.js similarity index 100% rename from src/js/bootstrap.js rename to lib/js-startup/bootstrap.js diff --git a/src/js/launcher.js b/lib/js-startup/launcher.js similarity index 100% rename from src/js/launcher.js rename to lib/js-startup/launcher.js diff --git a/src/js/profiler.js b/lib/js-startup/profiler.js similarity index 100% rename from src/js/profiler.js rename to lib/js-startup/profiler.js diff --git a/src/js/web-launcher.js b/lib/js-startup/web-launcher.js similarity index 100% rename from src/js/web-launcher.js rename to lib/js-startup/web-launcher.js diff --git a/src/jsemitter.jsx b/src/jsemitter.jsx index dc679edb..d1e27458 100644 --- a/src/jsemitter.jsx +++ b/src/jsemitter.jsx @@ -3027,7 +3027,7 @@ abstract class _BootstrapBuilder { } function addBootstrap(code : string) : string { - code += this._emitter._platform.load(this._emitter._platform.getRoot() + "/src/js/launcher.js"); + code += this._emitter._platform.load(this._emitter._platform.getRoot() + "/lib/js-startup/launcher.js"); var args; switch (this._executableFor) { @@ -3054,7 +3054,7 @@ abstract class _BootstrapBuilder { abstract function _getLauncher() : string; function _wrapOnLoad(code : string) : string { - var wrapper = this._emitter._platform.load(this._emitter._platform.getRoot() + "/src/js/web-launcher.js"); + var wrapper = this._emitter._platform.load(this._emitter._platform.getRoot() + "/lib/js-startup/web-launcher.js"); return wrapper.replace(/\/\/--CODE--\/\//, code); } @@ -3268,7 +3268,7 @@ class JavaScriptEmitter implements Emitter { // headers this._output += "// generatedy by JSX compiler " + Meta.IDENTIFIER + "\n"; this._output += this._fileHeader; - this._output += this._platform.load(this._platform.getRoot() + "/src/js/bootstrap.js"); + this._output += this._platform.load(this._platform.getRoot() + "/lib/js-startup/bootstrap.js"); var stash = (this.getStash(_NoDebugCommand.IDENTIFIER) as _NoDebugCommand.Stash); this._emit("JSX.DEBUG = "+(stash == null || stash.debugValue ? "true" : "false")+";\n", null); @@ -3529,7 +3529,7 @@ class JavaScriptEmitter implements Emitter { } output += this._output + "\n"; if (this._enableProfiler) { - output += this._platform.load(this._platform.getRoot() + "/src/js/profiler.js"); + output += this._platform.load(this._platform.getRoot() + "/lib/js-startup/profiler.js"); } if (this._bootstrapBuilder != null) { output = this._bootstrapBuilder.addBootstrap(output); diff --git a/src/jsx-command.jsx b/src/jsx-command.jsx index 77de9ac1..5bba1826 100644 --- a/src/jsx-command.jsx +++ b/src/jsx-command.jsx @@ -426,7 +426,7 @@ class JSXCommand { return 1; } if (compiler.compile()) { - new DocumentGenerator(compiler, platform.getRoot() + "/src/doc", outputFile) + new DocumentGenerator(compiler, platform.getRoot() + "/etc/doc-template", outputFile) .setResourceFiles(["style.css"]) .setPathFilter(function (sourcePath) { if (sourcePath.indexOf("system:") == 0) { diff --git a/tool/bootstrap-compiler.js b/tool/bootstrap-compiler.js index 00cb9d02..3ece70d1 100755 --- a/tool/bootstrap-compiler.js +++ b/tool/bootstrap-compiler.js @@ -1,5 +1,5 @@ #!/usr/bin/env node -// generatedy by JSX compiler 0.9.83 (2014-03-07 19:06:44 +0900; bf8546af13dba4c1a7f25a164301606e02ac301e) +// generatedy by JSX compiler 0.9.84 (2014-04-03 00:05:13 -0700; 6d7f8eb9fe9485eed11d294c6a08bbc8fab53fac) var JSX = {}; (function (JSX) { /** @@ -147,8 +147,7 @@ JSX.DEBUG = true; var GeneratorFunction$0 = (function () { try { - eval('import {GeneratorFunction} from "std:iteration"'); - return GeneratorFunction; + return Function('import {GeneratorFunction} from "std:iteration"; return GeneratorFunction')(); } catch (e) { return function GeneratorFunction () {}; } @@ -579,7 +578,7 @@ function Util$_isBuiltInObjectType$LType$HB(type, classeSet) { Util._isBuiltInObjectType$LType$HB = Util$_isBuiltInObjectType$LType$HB; -function Util$isNativeClass$LType$(type) { +function Util$rootIsNativeClass$LType$(type) { var classDef; if (type instanceof ObjectType) { classDef = type.getClassDef$(); @@ -593,35 +592,7 @@ function Util$isNativeClass$LType$(type) { return false; }; -Util.isNativeClass$LType$ = Util$isNativeClass$LType$; - -function Util$lhsHasSideEffects$LExpression$(lhsExpr) { - var holderExpr; - var arrayExpr; - if (lhsExpr instanceof LocalExpression) { - return false; - } - if (lhsExpr instanceof PropertyExpression) { - holderExpr = lhsExpr.getExpr$(); - if (Util$isNativeClass$LType$(holderExpr.getType$()) && ! Util$isBuiltInClass$LType$(holderExpr.getType$())) { - return true; - } - if (holderExpr instanceof ThisExpression || holderExpr instanceof LocalExpression || holderExpr.isClassSpecifier$()) { - return false; - } - } else if (lhsExpr instanceof ArrayExpression) { - arrayExpr = lhsExpr; - if (Util$isNativeClass$LType$(arrayExpr.getFirstExpr$().getType$()) && ! Util$isBuiltInClass$LType$(arrayExpr.getFirstExpr$().getType$())) { - return true; - } - if (arrayExpr.getFirstExpr$() instanceof LocalExpression && arrayExpr.getSecondExpr$() instanceof LeafExpression) { - return false; - } - } - return true; -}; - -Util.lhsHasSideEffects$LExpression$ = Util$lhsHasSideEffects$LExpression$; +Util.rootIsNativeClass$LType$ = Util$rootIsNativeClass$LType$; function Util$instantiateTemplate$LAnalysisContext$LToken$SALType$(context, token, className, typeArguments) { return context.parser.lookupTemplate$ALCompileError$LTemplateInstantiationRequest$F$LParser$LClassDefinition$LClassDefinition$$(context.errors, new TemplateInstantiationRequest(token, className, typeArguments), context.postInstantiationCallback); @@ -2211,6 +2182,22 @@ function _Util$emitFusedIntOpWithSideEffects$LJavaScriptEmitter$SLExpression$F$N _Util.emitFusedIntOpWithSideEffects$LJavaScriptEmitter$SLExpression$F$NV$N = _Util$emitFusedIntOpWithSideEffects$LJavaScriptEmitter$SLExpression$F$NV$N; +function _Util$getNewExpressionInliner$LNewExpression$(expr) { + var classDef; + var ctor; + var argTypes; + var callingFuncDef; + var stash; + classDef = expr.getType$().getClassDef$(); + ctor = expr.getConstructor$(); + argTypes = ctor.getArgumentTypes$(); + callingFuncDef = Util$findFunctionInClass$LClassDefinition$SALType$B(classDef, "constructor", argTypes, false); + stash = callingFuncDef.getStash$S("unclassify"); + return (stash ? stash.inliner : null); +}; + +_Util.getNewExpressionInliner$LNewExpression$ = _Util$getNewExpressionInliner$LNewExpression$; + function _TempVarLister() { this._varNameMap = {}; }; @@ -3707,7 +3694,7 @@ _PreIncrementExpressionEmitter.prototype.emit$N = function (outerOpPrecedence) { var opToken; opToken = this._expr.getToken$(); if (this._expr.getType$().resolveIfNullable$().equals$LType$(Type.integerType)) { - if (Util$lhsHasSideEffects$LExpression$(this._expr.getExpr$())) { + if (this._expr.getExpr$().hasSideEffects$()) { _Util$emitFusedIntOpWithSideEffects$LJavaScriptEmitter$SLExpression$F$NV$N(this._emitter, (opToken.getValue$() === "++" ? "$__jsx_ipadd" : "$__jsx_ipdec"), this._expr.getExpr$(), (function (outerPred) { $this._emitter._emit$SLToken$("1", opToken); }), 0); @@ -3749,7 +3736,7 @@ _PostIncrementExpressionEmitter.prototype.emit$N = function (outerOpPrecedence) var opToken; opToken = this._expr.getToken$(); if (this._expr.getType$().resolveIfNullable$().equals$LType$(Type.integerType)) { - if (Util$lhsHasSideEffects$LExpression$(this._expr.getExpr$())) { + if (this._expr.getExpr$().hasSideEffects$()) { _Util$emitFusedIntOpWithSideEffects$LJavaScriptEmitter$SLExpression$F$NV$N(this._emitter, (opToken.getValue$() === "++" ? "$__jsx_ippostinc" : "$__jsx_ippostdec"), this._expr.getExpr$(), (function (outerPred) { $this._emitter._emit$SLToken$("1", opToken); }), 0); @@ -3781,7 +3768,7 @@ function _PostIncrementExpressionEmitter$_setOperatorPrecedence$SN(op, precedenc _PostIncrementExpressionEmitter._setOperatorPrecedence$SN = _PostIncrementExpressionEmitter$_setOperatorPrecedence$SN; function _PostIncrementExpressionEmitter$needsTempVarFor$LPostIncrementExpression$(expr) { - return expr.getType$().resolveIfNullable$().equals$LType$(Type.integerType) && ! Util$lhsHasSideEffects$LExpression$(expr.getExpr$()); + return expr.getType$().resolveIfNullable$().equals$LType$(Type.integerType) && ! expr.getExpr$().hasSideEffects$(); }; _PostIncrementExpressionEmitter.needsTempVarFor$LPostIncrementExpression$ = _PostIncrementExpressionEmitter$needsTempVarFor$LPostIncrementExpression$; @@ -4024,7 +4011,7 @@ _FusedAssignmentExpressionEmitter.prototype.emit$N = function (outerOpPrecedence var coreOp; coreOp = this._expr.getToken$().getValue$().charAt(0); if (_FusedAssignmentExpressionEmitter._fusedIntHelpers[coreOp] != null && this._expr.getFirstExpr$().getType$().resolveIfNullable$().equals$LType$(Type.integerType)) { - if (Util$lhsHasSideEffects$LExpression$(this._expr.getFirstExpr$())) { + if (this._expr.getFirstExpr$().hasSideEffects$()) { _Util$emitFusedIntOpWithSideEffects$LJavaScriptEmitter$SLExpression$F$NV$N(this._emitter, _FusedAssignmentExpressionEmitter._fusedIntHelpers[coreOp], this._expr.getFirstExpr$(), (function (outerPred) { $this._emitter._emitWithNullableGuard$LExpression$N($this._expr.getSecondExpr$(), outerPred); }), outerOpPrecedence); @@ -4529,30 +4516,19 @@ function _NewExpressionEmitter(emitter, expr) { $__jsx_extend([_NewExpressionEmitter], _OperatorExpressionEmitter); _NewExpressionEmitter.prototype.emit$N = function (outerOpPrecedence) { - var $this = this; - var getInliner; + var inliner; var classDef; - var ctor; var argTypes; - var callingFuncDef; - var inliner; - function getInliner(funcDef) { - var stash; - stash = funcDef.getStash$S("unclassify"); - return (stash ? stash.inliner : null); - } + inliner = _Util$getNewExpressionInliner$LNewExpression$(this._expr); classDef = this._expr.getType$().getClassDef$(); - ctor = this._expr.getConstructor$(); - argTypes = ctor.getArgumentTypes$(); - callingFuncDef = Util$findFunctionInClass$LClassDefinition$SALType$B(classDef, "constructor", argTypes, false); - inliner = getInliner(callingFuncDef); if (inliner) { this._emitAsObjectLiteral$LClassDefinition$ALExpression$(classDef, inliner(this._expr)); - } else if (_Util$isArrayType$LType$(this._expr.getType$()) && argTypes.length === 0) { + } else if (_Util$isArrayType$LType$(this._expr.getType$()) && this._expr.getArguments$().length === 0) { this._emitter._emit$SLToken$("[]", this._expr.getToken$()); } else if (classDef instanceof InstantiatedClassDefinition && classDef.getTemplateClassName$() === "Map") { this._emitter._emit$SLToken$("{}", this._expr.getToken$()); } else { + argTypes = this._expr.getConstructor$().getArgumentTypes$(); this._emitter._emitCallArguments$LToken$SALExpression$ALType$(this._expr.getToken$(), "new " + this._emitter.getNamer$().getNameOfConstructor$LClassDefinition$ALType$(classDef, argTypes) + "(", this._expr.getArguments$(), argTypes); } }; @@ -4632,7 +4608,7 @@ _BootstrapBuilder.prototype.init$LJavaScriptEmitter$SS = function (emitter, entr _BootstrapBuilder.prototype.addBootstrap$S = function (code) { var args; var callEntryPoint; - code += this._emitter._platform.load$S(this._emitter._platform.getRoot$() + "/src/js/launcher.js"); + code += this._emitter._platform.load$S(this._emitter._platform.getRoot$() + "/lib/js-startup/launcher.js"); switch (this._executableFor) { case "node": args = "process.argv.slice(2)"; @@ -4654,7 +4630,7 @@ _BootstrapBuilder.prototype.addBootstrap$S = function (code) { _BootstrapBuilder.prototype._wrapOnLoad$S = function (code) { var wrapper; - wrapper = this._emitter._platform.load$S(this._emitter._platform.getRoot$() + "/src/js/web-launcher.js"); + wrapper = this._emitter._platform.load$S(this._emitter._platform.getRoot$() + "/lib/js-startup/web-launcher.js"); return wrapper.replace(/\/\/--CODE--\/\//, code); }; @@ -5338,7 +5314,7 @@ function JSXCommand$main$LPlatform$AS(platform, args) { return 1; } if (compiler.compile$()) { - new DocumentGenerator(compiler, platform.getRoot$() + "/src/doc", outputFile).setResourceFiles$AS([ "style.css" ]).setPathFilter$F$SB$((function (sourcePath) { + new DocumentGenerator(compiler, platform.getRoot$() + "/etc/doc-template", outputFile).setResourceFiles$AS([ "style.css" ]).setPathFilter$F$SB$((function (sourcePath) { if (sourcePath.indexOf("system:") === 0) { return false; } @@ -7406,7 +7382,7 @@ ConstructorInvocationStatement.prototype.instantiate$LInstantiationContext$ = fu if (this._ctorFunctionType != null) { throw new Error("instantiation after analysis?"); } - return new ConstructorInvocationStatement$0(this._token, this._ctorClassType.instantiate$LInstantiationContext$(instantiationContext), Util$cloneArray$ALExpression$(this._args), null); + return new ConstructorInvocationStatement$0(this._token, this._ctorClassType.instantiate$LInstantiationContext$B(instantiationContext, false), Util$cloneArray$ALExpression$(this._args), null); }; @@ -7495,55 +7471,55 @@ Expression.prototype.instantiate$LInstantiationContext$ = function (instantiatio if (expr instanceof NullExpression) { srcType = expr.getType$(); if (srcType != null) { - expr.setType$LType$(srcType.instantiate$LInstantiationContext$(instantiationContext)); + expr.setType$LType$(srcType.instantiate$LInstantiationContext$B(instantiationContext, false)); } } else if (expr instanceof NewExpression) { srcType = expr.getType$(); if (srcType != null) { - expr.setType$LType$(srcType.instantiate$LInstantiationContext$(instantiationContext)); + expr.setType$LType$(srcType.instantiate$LInstantiationContext$B(instantiationContext, false)); } } else if (expr instanceof PropertyExpression) { propertyExpr = expr; srcType = expr.getType$(); if (srcType != null) { - propertyExpr.setType$LType$(srcType.instantiate$LInstantiationContext$(instantiationContext)); + propertyExpr.setType$LType$(srcType.instantiate$LInstantiationContext$B(instantiationContext, false)); } srcTypes = propertyExpr.getTypeArguments$(); if (srcTypes != null) { propertyExpr.setTypeArguments$ALType$(srcTypes.map((function (type) { - return type.instantiate$LInstantiationContext$(instantiationContext); + return type.instantiate$LInstantiationContext$B(instantiationContext, false); }))); } } else if (expr instanceof ArrayLiteralExpression) { srcType = expr.getType$(); if (srcType != null) { - expr.setType$LType$(srcType.instantiate$LInstantiationContext$(instantiationContext)); + expr.setType$LType$(srcType.instantiate$LInstantiationContext$B(instantiationContext, false)); } } else if (expr instanceof MapLiteralExpression) { srcType = expr.getType$(); if (srcType != null) { - expr.setType$LType$(srcType.instantiate$LInstantiationContext$(instantiationContext)); + expr.setType$LType$(srcType.instantiate$LInstantiationContext$B(instantiationContext, false)); } } else if (expr instanceof AsExpression) { srcType = expr.getType$(); if (srcType != null) { - expr.setType$LType$(srcType.instantiate$LInstantiationContext$(instantiationContext)); + expr.setType$LType$(srcType.instantiate$LInstantiationContext$B(instantiationContext, false)); } } else if (expr instanceof AsNoConvertExpression) { srcType = expr.getType$(); if (srcType != null) { - expr.setType$LType$(srcType.instantiate$LInstantiationContext$(instantiationContext)); + expr.setType$LType$(srcType.instantiate$LInstantiationContext$B(instantiationContext, false)); } } else if (expr instanceof ClassExpression) { srcType = expr.getType$(); if (srcType != null) { - expr.setType$LType$(srcType.instantiate$LInstantiationContext$(instantiationContext)); + expr.setType$LType$(srcType.instantiate$LInstantiationContext$B(instantiationContext, false)); } } else if (expr instanceof LocalExpression) { expr.setLocal$LLocalVariable$(expr.getLocal$().getInstantiated$()); } else if (expr instanceof InstanceofExpression) { instanceofExpr = expr; - instanceofExpr.setExpectedType$LType$(instanceofExpr.getExpectedType$().instantiate$LInstantiationContext$(instantiationContext)); + instanceofExpr.setExpectedType$LType$(instanceofExpr.getExpectedType$().instantiate$LInstantiationContext$B(instantiationContext, false)); } return expr.forEachExpression$F$LExpression$B$(onExpr); } @@ -7594,6 +7570,32 @@ function Expression$assertIsAssignable$LAnalysisContext$LToken$LType$LType$(cont Expression.assertIsAssignable$LAnalysisContext$LToken$LType$LType$ = Expression$assertIsAssignable$LAnalysisContext$LToken$LType$LType$; +Expression.prototype.hasSideEffects$ = function () { + var $this = this; + return this.hasSideEffects$F$LExpression$UB$((function (expr) { + return null; + })); +}; + + +Expression.prototype.hasSideEffects$F$LExpression$UB$ = function (preCheckCb) { + var r; + r = preCheckCb(this); + if (r != null) { + return r; + } + return this._doHasSideEffects$F$LExpression$UB$(preCheckCb); +}; + + +Expression.prototype._doHasSideEffects$F$LExpression$UB$ = function (preCheckCb) { + var $this = this; + return ! this.forEachExpression$F$LExpression$B$((function (expr) { + return ! expr.hasSideEffects$F$LExpression$UB$(preCheckCb); + })); +}; + + function Expression$getDefaultValueExpressionOf$LType$(type) { if (type.equals$LType$(Type.booleanType)) { return new BooleanLiteralExpression(new Token$2("false", false)); @@ -8058,6 +8060,22 @@ NewExpression.prototype.forEachExpression$F$LExpression$F$LExpression$V$B$ = fun }; +NewExpression.prototype._doHasSideEffects$F$LExpression$UB$ = function (preCheckCb) { + var classDef; + var className; + classDef = this._type.getClassDef$(); + className = classDef.className$().replace(/\.<.*/, ""); + switch (className) { + case "Object": + case "Map": + return false; + case "Array": + return false; + } + return true; +}; + + function SuperExpression(token, name, args) { OperatorExpression.call(this, token); this._name = name; @@ -8137,6 +8155,11 @@ SuperExpression.prototype.forEachExpression$F$LExpression$F$LExpression$V$B$ = f }; +SuperExpression.prototype._doHasSideEffects$F$LExpression$UB$ = function (preCheckCb) { + return true; +}; + + function CallExpression(token, expr, args) { OperatorExpression.call(this, token); this._expr = expr; @@ -8231,6 +8254,11 @@ CallExpression.prototype.forEachExpression$F$LExpression$F$LExpression$V$B$ = fu }; +CallExpression.prototype._doHasSideEffects$F$LExpression$UB$ = function (preCheckCb) { + return true; +}; + + function ConditionalExpression(operatorToken, condExpr, ifTrueExpr, ifFalseExpr) { ConditionalExpression$0.call(this, operatorToken, condExpr, ifTrueExpr, ifFalseExpr, null); }; @@ -8627,6 +8655,11 @@ FusedAssignmentExpression.prototype.getType$ = function () { }; +FusedAssignmentExpression.prototype._doHasSideEffects$F$LExpression$UB$ = function (preCheckCb) { + return true; +}; + + function AssignmentExpression(operatorToken, expr1, expr2) { BinaryExpression.call(this, operatorToken, expr1, expr2); }; @@ -8761,6 +8794,11 @@ AssignmentExpression.prototype.getType$ = function () { }; +AssignmentExpression.prototype._doHasSideEffects$F$LExpression$UB$ = function (preCheckCb) { + return true; +}; + + function ArrayExpression(operatorToken, expr1, expr2) { BinaryExpression.call(this, operatorToken, expr1, expr2); this._type = null; @@ -8836,6 +8874,14 @@ ArrayExpression.prototype.assertIsAssignable$LAnalysisContext$LToken$LType$ = fu }; +ArrayExpression.prototype._doHasSideEffects$F$LExpression$UB$ = function (preCheckCb) { + if (! Util$isBuiltInClass$LType$(this._expr1.getType$()) && Util$rootIsNativeClass$LType$(this._expr1.getType$())) { + return true; + } + return Expression.prototype._doHasSideEffects$F$LExpression$UB$.call(this, preCheckCb); +}; + + function AdditiveExpression(operatorToken, expr1, expr2) { BinaryExpression.call(this, operatorToken, expr1, expr2); this._type = null; @@ -9163,6 +9209,17 @@ PropertyExpression.prototype.assertIsAssignable$LAnalysisContext$LToken$LType$ = }; +PropertyExpression.prototype._doHasSideEffects$F$LExpression$UB$ = function (preCheckCb) { + if (this.isClassSpecifier$()) { + return false; + } + if (! Util$isBuiltInClass$LType$(this._expr.getType$()) && Util$rootIsNativeClass$LType$(this._expr.getType$())) { + return true; + } + return Expression.prototype._doHasSideEffects$F$LExpression$UB$.call(this, preCheckCb); +}; + + PropertyExpression.prototype.deduceByArgumentTypes$LAnalysisContext$LToken$ALType$B = function (context, operatorToken, argTypes, isStatic) { var i; var rhsType; @@ -9214,6 +9271,11 @@ IncrementExpression.prototype.getType$ = function () { }; +IncrementExpression.prototype._doHasSideEffects$F$LExpression$UB$ = function (preCheckCb) { + return true; +}; + + function PreIncrementExpression(operatorToken, expr) { IncrementExpression.call(this, operatorToken, expr); }; @@ -10116,7 +10178,7 @@ JavaScriptEmitter.prototype._emitInit$ = function () { this._emittingFunction = null; this._output += "// generatedy by JSX compiler " + Meta.IDENTIFIER + "\n"; this._output += this._fileHeader; - this._output += this._platform.load$S(this._platform.getRoot$() + "/src/js/bootstrap.js"); + this._output += this._platform.load$S(this._platform.getRoot$() + "/lib/js-startup/bootstrap.js"); stash = this.getStash$S(_NoDebugCommand.IDENTIFIER); this._emit$SLToken$("JSX.DEBUG = " + (stash == null || stash.debugValue ? "true" : "false") + ";\n", null); }; @@ -10393,7 +10455,7 @@ JavaScriptEmitter.prototype.getOutput$ = function () { } output += this._output + "\n"; if (this._enableProfiler) { - output += this._platform.load$S(this._platform.getRoot$() + "/src/js/profiler.js"); + output += this._platform.load$S(this._platform.getRoot$() + "/lib/js-startup/profiler.js"); } if (this._bootstrapBuilder != null) { output = this._bootstrapBuilder.addBootstrap$S(output); @@ -10583,11 +10645,25 @@ JavaScriptEmitter.prototype._emitFunctionBody$LMemberFunctionDefinition$ = funct JavaScriptEmitter.prototype._emitStaticMemberVariable$LMemberVariableDefinition$ = function (variable) { + var $this = this; var initialValue; var tempVars; var i; initialValue = variable.getInitialValue$(); - if (initialValue != null && ! (initialValue instanceof NullExpression || initialValue instanceof BooleanLiteralExpression || initialValue instanceof IntegerLiteralExpression || initialValue instanceof NumberLiteralExpression || initialValue instanceof StringLiteralExpression || initialValue instanceof RegExpLiteralExpression)) { + if (initialValue != null && initialValue.hasSideEffects$F$LExpression$UB$((function (expr) { + var holderExpr; + if (expr instanceof PropertyExpression) { + holderExpr = expr.getExpr$(); + if (holderExpr instanceof ClassExpression || holderExpr instanceof PropertyExpression && holderExpr.isClassSpecifier$()) { + return true; + } + } else if (expr instanceof NewExpression) { + if (_Util$getNewExpressionInliner$LNewExpression$(expr) != null) { + return false; + } + } + return null; + }))) { this._emit$SLToken$("$__jsx_lazy_init(", variable.getNameToken$()); this._emit$SLToken$(this._namer.getNameOfClass$LClassDefinition$(variable.getClassDef$()) + ", \"" + this._namer.getNameOfStaticVariable$LClassDefinition$S(variable.getClassDef$(), variable.name$()) + "\", function () {\n", variable.getNameToken$()); this._advanceIndent$(); @@ -11071,7 +11147,7 @@ LocalVariable.prototype.instantiateAndPush$LInstantiationContext$ = function (in LocalVariable.prototype._instantiate$LInstantiationContext$ = function (instantiationContext) { var type; - type = (this._type != null ? this._type.instantiate$LInstantiationContext$(instantiationContext) : null); + type = (this._type != null ? this._type.instantiate$LInstantiationContext$B(instantiationContext, false) : null); return new LocalVariable(this._name, type, this._isConstant); }; @@ -11092,7 +11168,7 @@ CaughtVariable.prototype.touchVariable$LAnalysisContext$LToken$B = function (con CaughtVariable.prototype._instantiate$LInstantiationContext$ = function (instantiationContext) { - return new CaughtVariable(this._name, this._type.instantiate$LInstantiationContext$(instantiationContext)); + return new CaughtVariable(this._name, this._type.instantiate$LInstantiationContext$B(instantiationContext, false)); }; @@ -11124,7 +11200,7 @@ ArgumentDeclaration.prototype.getDefaultValue$ = function () { ArgumentDeclaration.prototype._instantiate$LInstantiationContext$ = function (instantiationContext) { var type; - type = (this._type != null ? this._type.instantiate$LInstantiationContext$(instantiationContext) : null); + type = (this._type != null ? this._type.instantiate$LInstantiationContext$B(instantiationContext, false) : null); return new ArgumentDeclaration$0(this._name, type, this._defaultValue); }; @@ -11850,7 +11926,7 @@ ClassDefinition.prototype.instantiate$LInstantiationContext$ = function (instant } extendType = null; if (this._extendType != null) { - type = this._extendType.instantiate$LInstantiationContext$(instantiationContext); + type = this._extendType.instantiate$LInstantiationContext$B(instantiationContext, false); if (! (type instanceof ParsedObjectType)) { instantiationContext.errors.push(new CompileError(this._extendType.getToken$(), "non-object type is not extensible")); return null; @@ -11859,7 +11935,7 @@ ClassDefinition.prototype.instantiate$LInstantiationContext$ = function (instant } implementTypes = []; for (i = 0; i < this._implementTypes.length; ++i) { - type = this._implementTypes[i].instantiate$LInstantiationContext$(instantiationContext); + type = this._implementTypes[i].instantiate$LInstantiationContext$B(instantiationContext, false); if (! (type instanceof ParsedObjectType)) { instantiationContext.errors.push(new CompileError(this._implementTypes[i].getToken$(), "non-object type is not extensible")); return null; @@ -12577,7 +12653,7 @@ MemberVariableDefinition.prototype.instantiate$LInstantiationContext$ = function var type; var initialValue; var closures; - type = (this._type != null ? this._type.instantiate$LInstantiationContext$(instantiationContext) : null); + type = (this._type != null ? this._type.instantiate$LInstantiationContext$B(instantiationContext, false) : null); initialValue = null; if (this._initialValue != null) { initialValue = this._initialValue.clone$(); @@ -12982,7 +13058,7 @@ MemberFunctionDefinition.prototype._instantiateCore$LInstantiationContext$F$LTok this._args[i].popInstantiated$(); } if (this._returnType != null) { - returnType = this._returnType.instantiate$LInstantiationContext$(instantiationContext); + returnType = this._returnType.instantiate$LInstantiationContext$B(instantiationContext, true); if (returnType == null) { return null; } @@ -13720,7 +13796,7 @@ TemplateClassDefinition.prototype.instantiate$LInstantiationContext$ = function } extendType = null; if (this._extendType != null) { - type = this._extendType.instantiate$LInstantiationContext$(instantiationContext); + type = this._extendType.instantiate$LInstantiationContext$B(instantiationContext, false); if (! (type instanceof ParsedObjectType)) { instantiationContext.errors.push(new CompileError(this._extendType.getToken$(), "non-object type is not extensible")); return null; @@ -13729,7 +13805,7 @@ TemplateClassDefinition.prototype.instantiate$LInstantiationContext$ = function } implementTypes = []; for (i = 0; i < this._implementTypes.length; ++i) { - type = this._implementTypes[i].instantiate$LInstantiationContext$(instantiationContext); + type = this._implementTypes[i].instantiate$LInstantiationContext$B(instantiationContext, false); if (! (type instanceof ParsedObjectType)) { instantiationContext.errors.push(new CompileError(this._implementTypes[i].getToken$(), "non-object type is not extensible")); return null; @@ -13788,7 +13864,7 @@ TemplateClassDefinition.prototype.instantiateTemplateClass$ALCompileError$LTempl } extendType = null; if (this._extendType != null) { - type = this._extendType.instantiate$LInstantiationContext$(instantiationContext); + type = this._extendType.instantiate$LInstantiationContext$B(instantiationContext, false); if (! (type instanceof ParsedObjectType)) { instantiationContext.errors.push(new CompileError(this._extendType.getToken$(), "non-object type is not extensible")); return null; @@ -13797,7 +13873,7 @@ TemplateClassDefinition.prototype.instantiateTemplateClass$ALCompileError$LTempl } implementTypes = []; for (i = 0; i < this._implementTypes.length; ++i) { - type = this._implementTypes[i].instantiate$LInstantiationContext$(instantiationContext); + type = this._implementTypes[i].instantiate$LInstantiationContext$B(instantiationContext, false); if (! (type instanceof ParsedObjectType)) { instantiationContext.errors.push(new CompileError(this._implementTypes[i].getToken$(), "non-object type is not extensible")); return null; @@ -13883,7 +13959,7 @@ Type.prototype.toNullableType$ = function () { Type.prototype.toNullableType$B = function (force) { - if (force || this instanceof PrimitiveType) { + if (force || this instanceof PrimitiveType || this.equals$LType$(Type.voidType)) { return new NullableType(this); } return this; @@ -14047,7 +14123,7 @@ function VoidType() { }; $__jsx_extend([VoidType], Type); -VoidType.prototype.instantiate$LInstantiationContext$ = function (instantiationContext) { +VoidType.prototype.instantiate$LInstantiationContext$B = function (instantiationContext, allowVoid) { return this; }; @@ -14058,7 +14134,7 @@ VoidType.prototype.isAssignable$ = function () { VoidType.prototype.isConvertibleTo$LType$ = function (type) { - return false; + return type.equals$LType$(Type.voidType); }; @@ -14077,7 +14153,7 @@ function NullType() { }; $__jsx_extend([NullType], Type); -NullType.prototype.instantiate$LInstantiationContext$ = function (instantiationContext) { +NullType.prototype.instantiate$LInstantiationContext$B = function (instantiationContext, allowVoid) { return this; }; @@ -14107,7 +14183,7 @@ function PrimitiveType() { }; $__jsx_extend([PrimitiveType], Type); -PrimitiveType.prototype.instantiate$LInstantiationContext$ = function (instantiationContext) { +PrimitiveType.prototype.instantiate$LInstantiationContext$B = function (instantiationContext, allowVoid) { return this; }; @@ -14206,7 +14282,7 @@ function VariantType() { }; $__jsx_extend([VariantType], Type); -VariantType.prototype.instantiate$LInstantiationContext$ = function (instantiationContext) { +VariantType.prototype.instantiate$LInstantiationContext$B = function (instantiationContext, allowVoid) { return this; }; @@ -14242,9 +14318,9 @@ function NullableType(type) { }; $__jsx_extend([NullableType], Type); -NullableType.prototype.instantiate$LInstantiationContext$ = function (instantiationContext) { +NullableType.prototype.instantiate$LInstantiationContext$B = function (instantiationContext, allowVoid) { var baseType; - baseType = this._baseType.resolveIfNullable$().instantiate$LInstantiationContext$(instantiationContext); + baseType = this._baseType.resolveIfNullable$().instantiate$LInstantiationContext$B(instantiationContext, true); return baseType.toNullableType$(); }; @@ -14297,9 +14373,9 @@ function VariableLengthArgumentType(type) { }; $__jsx_extend([VariableLengthArgumentType], Type); -VariableLengthArgumentType.prototype.instantiate$LInstantiationContext$ = function (instantiationContext) { +VariableLengthArgumentType.prototype.instantiate$LInstantiationContext$B = function (instantiationContext, allowVoid) { var baseType; - baseType = this._baseType.instantiate$LInstantiationContext$(instantiationContext); + baseType = this._baseType.instantiate$LInstantiationContext$B(instantiationContext, allowVoid); return new VariableLengthArgumentType(baseType); }; @@ -14348,7 +14424,7 @@ function ObjectType(classDef) { }; $__jsx_extend([ObjectType], Type); -ObjectType.prototype.instantiate$LInstantiationContext$ = function (instantiationContext) { +ObjectType.prototype.instantiate$LInstantiationContext$B = function (instantiationContext, allowVoid) { throw new Error("logic flaw; ObjectType is created during semantic analysis, after template instantiation"); }; @@ -14437,7 +14513,7 @@ ParsedObjectType.prototype.getTypeArguments$ = function () { }; -ParsedObjectType.prototype.instantiate$LInstantiationContext$ = function (instantiationContext) { +ParsedObjectType.prototype.instantiate$LInstantiationContext$B = function (instantiationContext, allowVoid) { var enclosingType; var actualType; var qualifiedName; @@ -14450,6 +14526,9 @@ ParsedObjectType.prototype.instantiate$LInstantiationContext$ = function (instan if (enclosingType == null && this._typeArguments.length === 0) { actualType = instantiationContext.typemap[this._qualifiedName.getToken$().getValue$()]; if (actualType != null) { + if (! allowVoid && actualType.equals$LType$(Type.voidType)) { + instantiationContext.errors.push(new CompileError(this.getToken$(), "the type cannot be instantiated as void in this context")); + } return actualType; } if (this._classDef == null) { @@ -14459,7 +14538,7 @@ ParsedObjectType.prototype.instantiate$LInstantiationContext$ = function (instan } qualifiedName = this._qualifiedName; if (enclosingType != null) { - actualEnclosingType = this._qualifiedName.getEnclosingType$().instantiate$LInstantiationContext$(instantiationContext); + actualEnclosingType = this._qualifiedName.getEnclosingType$().instantiate$LInstantiationContext$B(instantiationContext, true); if (! this._qualifiedName.getEnclosingType$().equals$LType$(actualEnclosingType)) { qualifiedName = new QualifiedName$1(this._qualifiedName.getToken$(), actualEnclosingType); } @@ -14467,15 +14546,17 @@ ParsedObjectType.prototype.instantiate$LInstantiationContext$ = function (instan typeArgs = []; for (i = 0; i < this._typeArguments.length; ++i) { if (this._typeArguments[i] instanceof ParsedObjectType && this._typeArguments[i].getTypeArguments$().length !== 0) { - actualType = this._typeArguments[i].instantiate$LInstantiationContext$(instantiationContext); + actualType = this._typeArguments[i].instantiate$LInstantiationContext$B(instantiationContext, true); } else { actualType = instantiationContext.typemap[this._typeArguments[i].toString()]; } typeArgs[i] = (actualType != null ? actualType : this._typeArguments[i]); - if (typeArgs[i] instanceof NullableType) { - templateClassName = qualifiedName.getToken$().getValue$(); - if (templateClassName === "Array" || templateClassName === "Map") { + templateClassName = qualifiedName.getToken$().getValue$(); + if (templateClassName === "Array" || templateClassName === "Map") { + if (typeArgs[i] instanceof NullableType) { typeArgs[i] = typeArgs[i].getBaseType$(); + } else if (typeArgs[i].equals$LType$(Type.voidType)) { + instantiationContext.errors.push(new CompileError(this.getToken$(), "cannot instantiate " + templateClassName + ". with T=void")); } } } @@ -14526,7 +14607,7 @@ FunctionType.prototype.getClassDef$ = function () { }; -FunctionType.prototype.instantiate$LInstantiationContext$ = function (instantiationContext) { +FunctionType.prototype.instantiate$LInstantiationContext$B = function (instantiationContext, allowVoid) { throw new Error("logic flaw"); }; @@ -14820,17 +14901,17 @@ function StaticFunctionType(token, returnType, argTypes, isAssignable) { }; $__jsx_extend([StaticFunctionType], ResolvedFunctionType); -StaticFunctionType.prototype.instantiate$LInstantiationContext$ = function (instantiationContext) { +StaticFunctionType.prototype.instantiate$LInstantiationContext$B = function (instantiationContext, allowVoid) { var returnType; var argTypes; var i; - returnType = this._returnType.instantiate$LInstantiationContext$(instantiationContext); + returnType = this._returnType.instantiate$LInstantiationContext$B(instantiationContext, true); if (returnType == null) { return null; } argTypes = []; for (i = 0; i < this._argTypes.length; ++i) { - if ((argTypes[i] = this._argTypes[i].instantiate$LInstantiationContext$(instantiationContext)) == null) { + if ((argTypes[i] = this._argTypes[i].instantiate$LInstantiationContext$B(instantiationContext, true)) == null) { return null; } } @@ -14982,7 +15063,7 @@ TemplateFunctionType.prototype._getExpectedTypes$ALUtil$x2EArgumentTypeRequest$N } instantiationContext = new InstantiationContext([ ], this._funcDef.getResolvedTypemap$()); for (i = 0; i < numberOfArgs; ++i) { - argTypes[i] = argTypes[i].instantiate$LInstantiationContext$(instantiationContext); + argTypes[i] = argTypes[i].instantiate$LInstantiationContext$B(instantiationContext, true); } hasCallback = false; callbackArgTypes = argTypes.map((function (argType) { @@ -16570,7 +16651,7 @@ Parser.prototype._classDefinition$ = function () { } for (i = 0; i < this._outerClass.templateInners.length; ++i) { if (this._outerClass.templateInners[i].className$() === className.getValue$()) { - this._errors.push(new CompileError(className, "a non-template inner class with the same name has been already declared")); + this._errors.push(new CompileError(className, "a template inner class with the same name has been already declared")); success = false; break; } @@ -16935,7 +17016,7 @@ Parser.prototype._actualTypeArguments$ = function () { return types; } do { - type = this._typeDeclaration$B(false); + type = this._typeDeclaration$B(true); if (type == null) { return null; } @@ -17002,7 +17083,7 @@ Parser.prototype._nullableTypeDeclaration$ = function () { if (this._expect$S(".") == null || this._expect$S("<") == null) { return null; } - baseType = this._typeDeclaration$B(false); + baseType = this._typeDeclaration$B(true); if (baseType == null) { return null; } @@ -17136,9 +17217,15 @@ Parser.prototype._templateTypeDeclaration$LQualifiedName$ALType$ = function (qua var className; var objectType; className = qualifiedName.getToken$().getValue$(); - if ((className === "Array" || className === "Map") && typeArgs[0] instanceof NullableType) { - this._newError$S("cannot declare " + className + ".>, should be " + className + "."); - return null; + if (className === "Array" || className === "Map") { + if (typeArgs[0] instanceof NullableType) { + this._newError$S("cannot declare " + className + ".>, should be " + className + "."); + return null; + } + if (typeArgs[0].equals$LType$(Type.voidType)) { + this._newError$S("cannot declare " + className + ". with T=void"); + return null; + } } objectType = new ParsedObjectType(qualifiedName, typeArgs); this._objectTypesUsed.push(objectType); @@ -18997,30 +19084,18 @@ function _Util$0$exprIsAssignment$LExpression$(expr) { _Util$0.exprIsAssignment$LExpression$ = _Util$0$exprIsAssignment$LExpression$; function _Util$0$exprHasSideEffects$LExpression$(expr) { - return ! (function onExpr(expr) { + return expr.hasSideEffects$F$LExpression$UB$((function precheck(expr) { var callingFuncDef; - var type; - if (_Util$0$exprIsAssignment$LExpression$(expr) || expr instanceof NewExpression || expr instanceof SuperExpression) { - return false; - } else if (expr instanceof CallExpression) { + if (expr instanceof CallExpression) { callingFuncDef = _DetermineCalleeCommand$getCallingFuncDef$LStashable$(expr); if (callingFuncDef != null && (callingFuncDef.flags$() & ClassDefinition.IS_PURE) !== 0) { - } else { - return false; - } - } else if (expr instanceof PropertyExpression) { - type = expr.getExpr$().getType$(); - if (! (Util$isBuiltInClass$LType$(type) || ! Util$isNativeClass$LType$(type))) { - return false; - } - } else if (expr instanceof ArrayExpression) { - type = expr.getFirstExpr$().getType$(); - if (! (Util$isBuiltInClass$LType$(type) || ! Util$isNativeClass$LType$(type))) { - return false; + return ! expr.forEachExpression$F$LExpression$B$((function (expr) { + return ! expr.hasSideEffects$F$LExpression$UB$(precheck); + })); } } - return expr.forEachExpression$F$LExpression$B$(onExpr); - })(expr); + return null; + })); }; _Util$0.exprHasSideEffects$LExpression$ = _Util$0$exprHasSideEffects$LExpression$; @@ -19300,26 +19375,6 @@ _OptimizeCommand.prototype.getCompiler$ = function () { }; -_OptimizeCommand.prototype.getStash$LStashable$ = function (stashable) { - var stash; - stash = stashable.getStash$S(this._identifier); - if (stash == null) { - stash = stashable.setStash$SLStash$(this._identifier, this._createStash$()); - } - return stash; -}; - - -_OptimizeCommand.prototype._createStash$ = function () { - throw new Error("if you are going to use the stash, you need to override this function"); -}; - - -_OptimizeCommand.prototype.resetStash$LStashable$ = function (stashable) { - stashable.setStash$SLStash$(this._identifier, null); -}; - - _OptimizeCommand.prototype.createVar$LMemberFunctionDefinition$LType$S = function (funcDef, type, baseName) { var $this = this; var locals; @@ -19393,2076 +19448,2749 @@ _FunctionOptimizeCommand.prototype.performOptimization$ = function () { }; -function _LinkTimeOptimizationCommand() { - _OptimizeCommand.call(this, _LinkTimeOptimizationCommand.IDENTIFIER); +function _NoAssertCommand() { + _FunctionOptimizeCommand.call(this, _NoAssertCommand.IDENTIFIER); }; -$__jsx_extend([_LinkTimeOptimizationCommand], _OptimizeCommand); -_LinkTimeOptimizationCommand.prototype._createStash$ = function () { - return new _LinkTimeOptimizationCommand$x2EStash(); +$__jsx_extend([_NoAssertCommand], _FunctionOptimizeCommand); +_NoAssertCommand.prototype.optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { + this._optimizeStatements$ALStatement$(funcDef.getStatements$()); + return true; }; -_LinkTimeOptimizationCommand.prototype.performOptimization$ = function () { +_NoAssertCommand.prototype._optimizeStatements$ALStatement$ = function (statements) { var $this = this; - this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { + var optimize; + function optimize(statements) { var i; - if (classDef.extendType$() != null) { - $this.getStash$LStashable$(classDef.extendType$().getClassDef$()).extendedBy.push(classDef); - } - for (i = 0; i < classDef.implementTypes$().length; ++i) { - $this.getStash$LStashable$(classDef.implementTypes$()[i].getClassDef$()).extendedBy.push(classDef); - } - return true; - })); - this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { - if ((classDef.flags$() & (ClassDefinition.IS_INTERFACE | ClassDefinition.IS_MIXIN | ClassDefinition.IS_NATIVE | ClassDefinition.IS_FINAL | ClassDefinition.IS_EXPORT)) === 0 && $this.getStash$LStashable$(classDef).extendedBy.length === 0) { - $this.log$S("marking class as final: " + classDef.className$()); - classDef.setFlags$N(classDef.flags$() | ClassDefinition.IS_FINAL); - classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$((function (funcDef) { - if ((funcDef.flags$() & (ClassDefinition.IS_STATIC | ClassDefinition.IS_FINAL)) === 0) { - funcDef.setFlags$N(funcDef.flags$() | ClassDefinition.IS_FINAL); - } - return true; - })); - } else if ((classDef.flags$() & (ClassDefinition.IS_NATIVE | ClassDefinition.IS_FINAL)) === 0) { - classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$((function (funcDef) { - var overrides; - if ((funcDef.flags$() & (ClassDefinition.IS_STATIC | ClassDefinition.IS_NATIVE | ClassDefinition.IS_FINAL)) !== 0) { - } else if ((funcDef.flags$() & ClassDefinition.IS_ABSTRACT) === 0) { - if (funcDef.getStatements$() == null) { - throw new Error("a non-native, non-abstract function with out function body?"); - } - overrides = $this._getOverrides$LClassDefinition$ALClassDefinition$SALType$(classDef, $this.getStash$LStashable$(classDef).extendedBy, funcDef.name$(), funcDef.getArgumentTypes$()); - if (overrides.length === 0) { - $this.log$S("marking function as final: " + funcDef.getNotation$()); - funcDef.setFlags$N(funcDef.flags$() | ClassDefinition.IS_FINAL); - } else { - $this.log$S("function has overrides, not marking as final: " + funcDef.getNotation$()); - } - } else if ((funcDef.flags$() & ClassDefinition.IS_ABSTRACT) !== 0) { - } - return true; - })); + for (i = 0; i < statements.length; ) { + if (statements[i] instanceof AssertStatement) { + statements.splice(i, 1); + } else { + _Util$0$handleSubStatements$F$ALStatement$B$LStatement$(optimize, statements[i]); + ++i; + } } - return true; - })); + return false; + } + optimize(statements); }; -_LinkTimeOptimizationCommand.prototype._getOverrides$LClassDefinition$ALClassDefinition$SALType$ = function (srcClassDef, classDefs, name, argTypes) { - var overrides; - var i; - overrides = []; - for (i = 0; i < classDefs.length; ++i) { - overrides = overrides.concat(this._getOverridesByClass$LClassDefinition$LClassDefinition$SALType$(srcClassDef, classDefs[i], name, argTypes)); - } - return overrides; +function _NoLogCommand() { + _FunctionOptimizeCommand.call(this, _NoLogCommand.IDENTIFIER); +}; + +$__jsx_extend([_NoLogCommand], _FunctionOptimizeCommand); +_NoLogCommand.prototype.optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { + this._optimizeStatements$ALStatement$(funcDef.getStatements$()); + return true; }; -_LinkTimeOptimizationCommand.prototype._getOverridesByClass$LClassDefinition$LClassDefinition$SALType$ = function (srcClassDef, classDef, name, argTypes) { +_NoLogCommand.prototype._optimizeStatements$ALStatement$ = function (statements) { var $this = this; - var overrides; - var addOverride; - var implementClassDefs; - var i; - overrides = this._getOverrides$LClassDefinition$ALClassDefinition$SALType$(srcClassDef, this.getStash$LStashable$(classDef).extendedBy, name, argTypes); - function addOverride(funcDef) { - if (funcDef.name$() === name && (funcDef.flags$() & ClassDefinition.IS_ABSTRACT) === 0 && Util$typesAreEqual$ALType$ALType$(funcDef.getArgumentTypes$(), argTypes)) { - overrides.push(funcDef); - return false; - } - return true; - } - classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$(addOverride); - implementClassDefs = classDef.implementTypes$().map((function (type) { - return type.getClassDef$(); - })); - for (i = 0; i < implementClassDefs.length; ++i) { - if (srcClassDef != implementClassDefs[i]) { - implementClassDefs[i].forEachClassToBase$F$LClassDefinition$B$((function (classDef) { - return classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$(addOverride); - })); + var optimize; + function optimize(statements) { + var i; + for (i = 0; i < statements.length; ) { + if (statements[i] instanceof LogStatement) { + statements.splice(i, 1); + } else { + _Util$0$handleSubStatements$F$ALStatement$B$LStatement$(optimize, statements[i]); + ++i; + } } + return false; } - return overrides; + optimize(statements); }; -function _StripOptimizeCommand() { - _OptimizeCommand.call(this, _StripOptimizeCommand.IDENTIFIER); - this._classesInstantiated = []; - this._methodsAlive = {}; - this._membersToWalk = []; -}; - -$__jsx_extend([_StripOptimizeCommand], _OptimizeCommand); -_StripOptimizeCommand.prototype._createStash$ = function () { - return new _StripOptimizeCommand$x2E_Stash(); +function _DeadCodeEliminationOptimizeCommand() { + _FunctionOptimizeCommand.call(this, _DeadCodeEliminationOptimizeCommand.IDENTIFIER); }; - -_StripOptimizeCommand.prototype._touchStatic$LMemberDefinition$ = function (member) { - var stash; - stash = this.getStash$LStashable$(member); - if (stash.touched) { - return; +$__jsx_extend([_DeadCodeEliminationOptimizeCommand], _FunctionOptimizeCommand); +_DeadCodeEliminationOptimizeCommand.prototype.optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { + if (funcDef.getStatements$() == null) { + return true; } - this.log$S("touched " + member.getNotation$()); - stash.touched = true; - this._membersToWalk.push(member); + while (this._optimizeFunction$LMemberFunctionDefinition$(funcDef) || this._removeExpressionStatementsWithoutSideEffects$LMemberFunctionDefinition$(funcDef)) { + } + return true; }; -_StripOptimizeCommand.prototype._touchInstance$LClassDefinition$ = function (classDef) { +_DeadCodeEliminationOptimizeCommand.prototype._removeExpressionStatementsWithoutSideEffects$LMemberFunctionDefinition$ = function (funcDef) { var $this = this; - var stash; - var name; - var listOfArgTypes; - var i; - var funcDef; - stash = this.getStash$LStashable$(classDef); - if (stash.touched) { - return; - } - this.log$S("touched " + classDef.className$()); - stash.touched = true; - this._classesInstantiated.push(classDef); - for (name in this._methodsAlive) { - listOfArgTypes = this._methodsAlive[name]; - for (i = 0; i !== listOfArgTypes.length; ++i) { - funcDef = Util$findFunctionInClass$LClassDefinition$SALType$B(classDef, name, listOfArgTypes[i], false); - if (funcDef != null) { - this._membersToWalk.push(funcDef); + var shouldRetry; + shouldRetry = false; + (function onStatements(statements) { + var i; + for (i = 0; i < statements.length; ) { + if (statements[i] instanceof ExpressionStatement && ! _Util$0$exprHasSideEffects$LExpression$(statements[i].getExpr$())) { + shouldRetry = true; + statements.splice(i, 1); + } else { + if (statements[i] instanceof ExpressionStatement) { + $this._optimizeExprInVoid$LExpression$F$LExpression$V$(statements[i].getExpr$(), (function (expr) { + statements[i] = new ExpressionStatement(expr); + })); + } + statements[i++].handleStatements$F$ALStatement$B$(onStatements); } } - } - classDef.forEachMemberVariable$F$LMemberVariableDefinition$B$((function (varDef) { - if ((varDef.flags$() & ClassDefinition.IS_STATIC) === 0) { - $this._membersToWalk.push(varDef); - } return true; - })); - if (classDef.extendType$() != null) { - this._touchInstance$LClassDefinition$(classDef.extendType$().getClassDef$()); - } - classDef.implementTypes$().forEach((function (implementType) { - $this._touchInstance$LClassDefinition$(implementType.getClassDef$()); - })); - if (classDef.getOuterClassDef$() != null) { - this._touchInstance$LClassDefinition$(classDef.getOuterClassDef$()); - } + })(funcDef.getStatements$()); + return shouldRetry; }; -_StripOptimizeCommand.prototype._touchConstructor$LMemberFunctionDefinition$ = function (funcDef) { - var stash; - stash = this.getStash$LStashable$(funcDef); - if (stash.touched) { - return; +_DeadCodeEliminationOptimizeCommand.prototype._optimizeExprInVoid$LExpression$F$LExpression$V$ = function (expr, replaceCb) { + var condExpr; + var ifTrueHasSideEffect; + var ifFalseHasSideEffect; + var condAndIfTrue; + var condOrIfFalse; + if (expr instanceof ConditionalExpression) { + condExpr = expr; + ifTrueHasSideEffect = _Util$0$exprHasSideEffects$LExpression$(condExpr.getIfTrueExpr$()); + ifFalseHasSideEffect = _Util$0$exprHasSideEffects$LExpression$(condExpr.getIfFalseExpr$()); + if (ifTrueHasSideEffect && ifFalseHasSideEffect) { + } else if (ifTrueHasSideEffect && ! ifFalseHasSideEffect) { + condAndIfTrue = new LogicalExpression(new Token$3("&&"), condExpr.getCondExpr$(), condExpr.getIfTrueExpr$()); + replaceCb(condAndIfTrue); + } else if (! ifTrueHasSideEffect && ifFalseHasSideEffect) { + condOrIfFalse = new LogicalExpression(new Token$3("||"), condExpr.getCondExpr$(), condExpr.getIfFalseExpr$()); + replaceCb(condOrIfFalse); + } else { + replaceCb(condExpr.getCondExpr$()); + } + } else if (expr instanceof LogicalNotExpression) { + replaceCb(expr.getExpr$()); } - this.log$S("touched " + funcDef.getNotation$()); - stash.touched = true; - this._membersToWalk.push(funcDef); - this._touchInstance$LClassDefinition$(funcDef.getClassDef$()); }; -_StripOptimizeCommand.prototype._touchMethod$SALType$ = function (name, argTypes) { - var listOfArgTypes; - var i; - var funcDef; - if ($__jsx_ObjectHasOwnProperty.call(this._methodsAlive, name)) { - listOfArgTypes = this._methodsAlive[name]; - } else { - listOfArgTypes = this._methodsAlive[name] = []; - } - for (i = 0; i < listOfArgTypes.length; ++i) { - if (Util$typesAreEqual$ALType$ALType$(listOfArgTypes[i], argTypes)) { - return; - } - } - this.log$S("touched #" + name); - listOfArgTypes.push(argTypes.concat()); - for (i = 0; i < this._classesInstantiated.length; ++i) { - funcDef = Util$findFunctionInClass$LClassDefinition$SALType$B(this._classesInstantiated[i], name, argTypes, false); - if (funcDef != null) { - this._membersToWalk.push(funcDef); - } - } +_DeadCodeEliminationOptimizeCommand.prototype._optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { + var $this = this; + _Util$0$optimizeBasicBlock$LMemberFunctionDefinition$F$ALExpression$V$(funcDef, (function (exprs) { + $this._eliminateDeadStoresToProperties$LMemberFunctionDefinition$ALExpression$(funcDef, exprs); + $this._delayAssignmentsBetweenLocals$LMemberFunctionDefinition$ALExpression$(funcDef, exprs); + $this._eliminateDeadStores$LMemberFunctionDefinition$ALExpression$(funcDef, exprs); + $this._eliminateDeadConditions$LMemberFunctionDefinition$ALExpression$(funcDef, exprs); + })); + return this._eliminateUnusedVariables$LMemberFunctionDefinition$(funcDef); }; -_StripOptimizeCommand.prototype.performOptimization$ = function () { +_DeadCodeEliminationOptimizeCommand.prototype._eliminateUnusedVariables$LMemberFunctionDefinition$ = function (funcDef) { var $this = this; - var isEmittedClass; - var member; - var memberShouldPreserve; - function isEmittedClass(classDef) { - if (classDef instanceof TemplateClassDefinition) { - return false; - } - if ((classDef.flags$() & ClassDefinition.IS_NATIVE) !== 0) { - return false; - } - return true; - } - this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { - $this.resetStash$LStashable$(classDef); - return classDef.forEachMember$F$LMemberDefinition$B$((function (member) { - $this.resetStash$LStashable$(member); - return true; - })); - })); - this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { - if (! (classDef instanceof TemplateClassDefinition) && (classDef.flags$() & ClassDefinition.IS_NATIVE) !== 0) { - classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$((function (funcDef) { - if (funcDef.name$() === "constructor") { - } else if ((funcDef.flags$() & ClassDefinition.IS_FINAL) !== 0) { - } else { - $this._touchMethod$SALType$(funcDef.name$(), funcDef.getArgumentTypes$()); - } - return true; - })); + var shouldRetry; + var locals; + var localsUsed; + var localIndex; + shouldRetry = false; + locals = funcDef.getLocals$(); + localsUsed = new Array(locals.length); + funcDef.forEachStatement$F$LStatement$B$((function onStatement(statement) { + if (statement instanceof FunctionStatement) { + statement.getFuncDef$().forEachStatement$F$LStatement$B$(onStatement); } - return true; - })); - this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { - if (isEmittedClass(classDef)) { - if ((classDef.flags$() & ClassDefinition.IS_EXPORT) !== 0) { - $this._touchInstance$LClassDefinition$(classDef); - } - classDef.forEachMember$F$LMemberDefinition$B$((function (member) { - var funcDef; - if ((member.flags$() & ClassDefinition.IS_EXPORT) !== 0) { - if ((member.flags$() & ClassDefinition.IS_STATIC) !== 0) { - $this._touchStatic$LMemberDefinition$(member); - } else if (member instanceof MemberFunctionDefinition) { - funcDef = member; - if (funcDef.name$() === "constructor") { - $this._touchConstructor$LMemberFunctionDefinition$(funcDef); - } else { - $this._touchMethod$SALType$(funcDef.name$(), funcDef.getArgumentTypes$()); - } + statement.forEachExpression$F$LExpression$B$((function onExpr(expr) { + var i; + if (expr instanceof AssignmentExpression && expr.getFirstExpr$() instanceof LocalExpression && expr.getFirstExpr$().getType$().equals$LType$(expr.getSecondExpr$().getType$())) { + return onExpr(expr.getSecondExpr$()); + } else if (expr instanceof LocalExpression) { + for (i = 0; i < locals.length; ++i) { + if (locals[i] == expr.getLocal$()) { + break; } } - return true; - })); - } - return true; - })); - while (this._membersToWalk.length !== 0) { - member = this._membersToWalk.shift(); - this.log$S("walking " + member.getNotation$()); - if (member instanceof MemberFunctionDefinition) { - this._walkFunctionDefinition$LMemberFunctionDefinition$(member); - } else { - this._walkVariableDefinition$LMemberVariableDefinition$(member); - } - } - function memberShouldPreserve(member) { - var isTouched; - var listOfArgTypes; - var i; - if ((member.flags$() & ClassDefinition.IS_EXPORT) !== 0) { - return true; - } - isTouched = $this.getStash$LStashable$(member).touched; - if ((member.flags$() & ClassDefinition.IS_STATIC) !== 0) { - return isTouched; - } else if (member instanceof MemberFunctionDefinition) { - if (member.name$() === "constructor") { - return isTouched; - } else { - if ($this.getStash$LStashable$(member.getClassDef$()).touched && $__jsx_ObjectHasOwnProperty.call($this._methodsAlive, member.name$())) { - listOfArgTypes = $this._methodsAlive[member.name$()]; - for (i = 0; i !== listOfArgTypes.length; ++i) { - if (Util$typesAreEqual$ALType$ALType$(listOfArgTypes[i], member.getArgumentTypes$())) { - return true; - } - } + if (i !== locals.length) { + localsUsed[i] = true; } - return false; + } else if (expr instanceof FunctionExpression) { + expr.getFuncDef$().forEachStatement$F$LStatement$B$(onStatement); } + return expr.forEachExpression$F$LExpression$B$(onExpr); + })); + return statement.forEachStatement$F$LStatement$B$(onStatement); + })); + for (localIndex = localsUsed.length - 1; localIndex >= 0; --localIndex) { + if (localsUsed[localIndex]) { + continue; } - return true; - } - this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { - var numConstructors; - var members; - var memberIndex; - var member; - var ctor; - if (isEmittedClass(classDef)) { - numConstructors = 0; - members = classDef.members$(); - for (memberIndex = 0; memberIndex !== members.length; ) { - member = members[memberIndex]; - if (memberShouldPreserve(member)) { - if (member instanceof MemberFunctionDefinition && (member.flags$() & ClassDefinition.IS_STATIC) === 0 && member.name$() === "constructor") { - ++numConstructors; + (function onStatements(statements) { + var i; + var statement; + var localFuncDef; + for (i = 0; i < statements.length; ) { + statement = statements[i]; + if (statement instanceof FunctionStatement) { + localFuncDef = statement.getFuncDef$(); + onStatements(localFuncDef.getStatements$()); + if (localFuncDef.getFuncLocal$() == locals[localIndex]) { + $this.log$S("removing definition of " + locals[localIndex].getName$().getNotation$()); + funcDef.getClosures$().splice(funcDef.getClosures$().indexOf(localFuncDef), 1); + statements.splice(i, 1); + } else { + i++; } - ++memberIndex; - $this.log$S("preserving used: " + member.getNotation$()); } else { - $this.log$S("removing unused: " + member.getNotation$()); - members.splice(memberIndex, 1); + i++; } + statement.forEachExpression$F$LExpression$F$LExpression$V$B$((function onExpr(expr, replaceCb) { + var rhsExpr; + if (expr instanceof AssignmentExpression && expr.getFirstExpr$() instanceof LocalExpression && expr.getFirstExpr$().getLocal$() == locals[localIndex]) { + $this.log$S("removing assignment to " + locals[localIndex].getName$().getNotation$()); + rhsExpr = expr.getSecondExpr$(); + replaceCb(rhsExpr); + shouldRetry = true; + return rhsExpr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); + } else if (expr instanceof LocalExpression && expr.getLocal$() == locals[localIndex]) { + throw new Error("logic flaw, found a variable going to be removed being used"); + } else if (expr instanceof FunctionExpression) { + onStatements(expr.getFuncDef$().getStatements$()); + } + return expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); + })); + _Util$0$handleSubStatements$F$ALStatement$B$LStatement$(onStatements, statement); } - if (numConstructors === 0) { - $this.log$S("substituting fake constructor for class: " + classDef.className$()); - ctor = new MemberFunctionDefinition(null, new Token$2("constructor", true), ClassDefinition.IS_FINAL | classDef.flags$() & ClassDefinition.IS_EXPORT, Type.voidType, [], [], [], [], classDef.getToken$(), null); - ctor.setClassDef$LClassDefinition$(classDef); - members.push(ctor); - } + return true; + })(funcDef.getStatements$()); + locals.splice(localIndex, 1); + } + return shouldRetry; +}; + + +_DeadCodeEliminationOptimizeCommand.prototype._delayAssignmentsBetweenLocals$LMemberFunctionDefinition$ALExpression$ = function (funcDef, exprs) { + var $this = this; + var localsUntouchable; + var locals; + localsUntouchable = new TypedMap$x2E$x3CLocalVariable$x2Cboolean$x3E(); + locals = new TypedMap$x2E$x3CLocalVariable$x2CExpression$x3E(); + Util$forEachExpression$F$LExpression$B$ALExpression$((function onExpr(expr) { + var local; + if (expr instanceof FusedAssignmentExpression && expr.getFirstExpr$() instanceof LocalExpression) { + local = expr.getFirstExpr$().getLocal$(); + $this.log$S("local variable " + local.getName$().getValue$() + " cannot be rewritten (has fused assignment)"); + localsUntouchable.set$LLocalVariable$B(local, true); + } else if (expr instanceof IncrementExpression && expr.getExpr$() instanceof LocalExpression) { + local = expr.getExpr$().getLocal$(); + $this.log$S("local variable " + local.getName$().getValue$() + " cannot be rewritten (has increment)"); + localsUntouchable.set$LLocalVariable$B(local, true); } - return true; - })); - this.getCompiler$().getParsers$().forEach((function (parser) { - var classDefs; - var i; - var preserve; - classDefs = parser.getClassDefs$(); - for (i = 0; i !== classDefs.length; ) { - preserve = true; - if ((classDefs[i].flags$() & ClassDefinition.IS_NATIVE) !== 0 && classDefs[i].getNativeSource$() != null && ! $this.getStash$LStashable$(classDefs[i]).touched && classDefs[i].forEachMember$F$LMemberDefinition$B$((function (member) { - if ((member.flags$() & ClassDefinition.IS_STATIC) === 0) { - return true; + return expr.forEachExpression$F$LExpression$B$(onExpr); + }), exprs); + Util$forEachExpression$F$LExpression$F$LExpression$V$B$ALExpression$((function onExpr(expr, replaceCb) { + var assignmentExpr; + var lhsLocal; + var rhsExpr; + var rhsLocal; + var cachedExpr; + var callingFuncDef; + if (expr instanceof AssignmentExpression) { + assignmentExpr = expr; + if (assignmentExpr.getFirstExpr$() instanceof LocalExpression) { + onExpr(assignmentExpr.getSecondExpr$(), (function (expr) { + assignmentExpr.setSecondExpr$LExpression$(expr); + })); + if (! localsUntouchable.get$LLocalVariable$(assignmentExpr.getFirstExpr$().getLocal$()) && assignmentExpr.getFirstExpr$().getType$().equals$LType$(assignmentExpr.getSecondExpr$().getType$())) { + lhsLocal = assignmentExpr.getFirstExpr$().getLocal$(); + $this.log$S("resetting cache for: " + lhsLocal.getName$().getNotation$()); + locals.reversedForEach$F$LLocalVariable$LExpression$B$((function (local, expr) { + if (local == lhsLocal) { + $this.log$S(" clearing itself"); + locals.delete$LLocalVariable$(local); + } else if (expr instanceof LocalExpression && expr.getLocal$() == lhsLocal) { + $this.log$S(" clearing " + local.getName$().getNotation$()); + locals.delete$LLocalVariable$(local); + } + return true; + })); + if (assignmentExpr.getToken$().getValue$() === "=") { + rhsExpr = assignmentExpr.getSecondExpr$(); + if (rhsExpr instanceof LocalExpression) { + rhsLocal = rhsExpr.getLocal$(); + if (lhsLocal != rhsLocal && ! localsUntouchable.get$LLocalVariable$(rhsLocal)) { + $this.log$S(" set to: " + rhsLocal.getName$().getNotation$()); + locals.set$LLocalVariable$LExpression$(lhsLocal, rhsExpr); + } + } else if (rhsExpr instanceof LeafExpression) { + $this.log$S(" set to: " + rhsExpr.getToken$().getNotation$()); + locals.set$LLocalVariable$LExpression$(lhsLocal, rhsExpr); + } + } } - return ! $this.getStash$LStashable$(member).touched; - }))) { - preserve = false; + return true; } - if (preserve) { - ++i; + } else if (expr instanceof LocalExpression) { + cachedExpr = locals.get$LLocalVariable$(expr.getLocal$()); + if (cachedExpr) { + replaceCb(cachedExpr.clone$()); + return true; + } + } else if (expr instanceof CallExpression) { + callingFuncDef = _DetermineCalleeCommand$getCallingFuncDef$LStashable$(expr); + if (callingFuncDef != null && (callingFuncDef.flags$() & ClassDefinition.IS_PURE) !== 0) { } else { - $this.log$S("removing unused native class: " + classDefs[i].className$()); - classDefs.splice(i, 1); + expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); + if (funcDef.getParent$() != null || funcDef.getClosures$().length !== 0) { + locals.clear$(); + } + return true; } + } else if (expr instanceof NewExpression) { + expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); + locals.clear$(); + return true; } - })); + return expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); + }), exprs); }; -_StripOptimizeCommand.prototype._walkExpression$LExpression$ = function (expr) { +_DeadCodeEliminationOptimizeCommand.prototype._eliminateDeadStores$LMemberFunctionDefinition$ALExpression$ = function (funcDef, exprs) { var $this = this; + var lastAssignExpr; var onExpr; - function onExpr(expr) { - var callee; - var propertyExpr; - var holderClassDef; - var name; - var member; - var superExpr; - if (expr instanceof NewExpression) { - callee = Util$findFunctionInClass$LClassDefinition$SALType$B(expr.getType$().getClassDef$(), "constructor", expr.getConstructor$().getArgumentTypes$(), false); - $this._touchConstructor$LMemberFunctionDefinition$(callee); - } else if (expr instanceof InstanceofExpression) { - $this._touchInstance$LClassDefinition$(expr.getExpectedType$().getClassDef$()); - } else if (expr instanceof AsExpression) { - if (expr.getType$() instanceof ObjectType) { - $this._touchInstance$LClassDefinition$(expr.getType$().getClassDef$()); - } - } else if (expr instanceof AsNoConvertExpression) { - if (expr.getType$() instanceof ObjectType) { - $this._touchInstance$LClassDefinition$(expr.getType$().getClassDef$()); - } - } else if (expr instanceof PropertyExpression) { - propertyExpr = expr; - holderClassDef = propertyExpr.getHolderType$().getClassDef$(); - if (propertyExpr.isClassSpecifier$()) { - if ((holderClassDef.flags$() & ClassDefinition.IS_NATIVE) !== 0) { - $this._touchInstance$LClassDefinition$(holderClassDef); - } - } else { - name = propertyExpr.getIdentifierToken$().getValue$(); - if (propertyExpr.getExpr$().isClassSpecifier$()) { - if (Util$isReferringToFunctionDefinition$LPropertyExpression$(propertyExpr)) { - member = Util$findFunctionInClass$LClassDefinition$SALType$B(holderClassDef, name, expr.getType$().getArgumentTypes$(), true); - } else { - member = Util$findVariableInClass$LClassDefinition$SB(holderClassDef, name, true); - } - $this._touchStatic$LMemberDefinition$(member); - } else if (Util$isReferringToFunctionDefinition$LPropertyExpression$(propertyExpr)) { - $this._touchMethod$SALType$(name, expr.getType$().getArgumentTypes$()); + lastAssignExpr = new TypedMap$x2E$x3CLocalVariable$x2CPair$x2E$x3CAssignmentExpression$x2Cfunction$x20$x28$x3A$x20Expression$x29$x20$x3A$x20void$x3E$x3E(); + function onExpr(expr, rewriteCb) { + var assignExpr; + var lhsLocal; + var lastAssign; + if (expr instanceof AssignmentExpression) { + assignExpr = expr; + if (assignExpr.getFirstExpr$() instanceof LocalExpression) { + onExpr(assignExpr.getSecondExpr$(), (function (assignExpr) { + return (function (expr) { + assignExpr.setSecondExpr$LExpression$(expr); + }); + })(assignExpr)); + lhsLocal = assignExpr.getFirstExpr$().getLocal$(); + lastAssign = lastAssignExpr.get$LLocalVariable$(lhsLocal); + if (lastAssign) { + $this.log$S("eliminating dead store to: " + lhsLocal.getName$().getValue$()); + lastAssign.second(lastAssign.first.getSecondExpr$()); } + lastAssignExpr.set$LLocalVariable$LPair$x2E$x3CAssignmentExpression$x2Cfunction$x20$x28$x3A$x20Expression$x29$x20$x3A$x20void$x3E$(lhsLocal, Util$makePair$LAssignmentExpression$F$LExpression$V$(assignExpr, rewriteCb)); + return true; } - } else if (expr instanceof SuperExpression) { - superExpr = expr; - $this._touchMethod$SALType$(superExpr.getName$().getValue$(), superExpr.getFunctionType$().getArgumentTypes$()); + } else if (expr instanceof LocalExpression) { + lastAssignExpr.delete$LLocalVariable$(expr.getLocal$()); + } else if (expr instanceof LogicalExpression || expr instanceof ConditionalExpression) { + expr.forEachExpression$F$LExpression$F$LExpression$V$B$((function (expr, rewriteCb) { + var result; + result = onExpr(expr, rewriteCb); + lastAssignExpr.clear$(); + return result; + })); + return true; + } else if (_Util$0$exprHasSideEffects$LExpression$(expr)) { + expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); + lastAssignExpr.clear$(); + return true; } - return expr.forEachExpression$F$LExpression$B$(onExpr); + return expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); } - return onExpr(expr); + Util$forEachExpression$F$LExpression$F$LExpression$V$B$ALExpression$(onExpr, exprs); }; -_StripOptimizeCommand.prototype._walkStatement$LStatement$ = function (statement) { +_DeadCodeEliminationOptimizeCommand.prototype._eliminateDeadStoresToProperties$LMemberFunctionDefinition$ALExpression$ = function (funcDef, exprs) { var $this = this; - var onStatement; - function onStatement(statement) { - var ctorStatement; - var callee; - if (statement instanceof ConstructorInvocationStatement) { - ctorStatement = statement; - callee = Util$findFunctionInClass$LClassDefinition$SALType$B(ctorStatement.getConstructingClassDef$(), "constructor", ctorStatement.getConstructorType$().getArgumentTypes$(), false); - $this._touchConstructor$LMemberFunctionDefinition$(callee); - } - statement.forEachExpression$F$LExpression$B$((function (expr) { - return $this._walkExpression$LExpression$(expr); - })); - return statement.forEachStatement$F$LStatement$B$(onStatement); + var isFirstLevelPropertyAccess; + var baseExprsAreEqual; + var lastAssignExpr; + var onExpr; + function isFirstLevelPropertyAccess(expr) { + var baseExpr; + if (! (expr instanceof PropertyExpression)) { + return false; + } + baseExpr = expr.getExpr$(); + if (baseExpr instanceof LocalExpression || baseExpr instanceof ThisExpression || baseExpr.isClassSpecifier$()) { + return true; + } else { + return false; + } } - return onStatement(statement); -}; - - -_StripOptimizeCommand.prototype._walkFunctionDefinition$LMemberFunctionDefinition$ = function (funcDef) { - var $this = this; - if (funcDef.getStatements$() != null) { - funcDef.forEachStatement$F$LStatement$B$((function onStatement(statement) { - return $this._walkStatement$LStatement$(statement); - })); + function baseExprsAreEqual(x, y) { + if (x instanceof LocalExpression && y instanceof LocalExpression) { + return x.getLocal$() == y.getLocal$(); + } else if (x instanceof ThisExpression && y instanceof ThisExpression) { + return true; + } else if (x.isClassSpecifier$() && y.isClassSpecifier$()) { + return x.getType$().equals$LType$(y.getType$()); + } + return false; } - return funcDef.forEachClosure$F$LMemberFunctionDefinition$B$((function (funcDef) { - return $this._walkFunctionDefinition$LMemberFunctionDefinition$(funcDef); - })); + lastAssignExpr = {}; + onExpr = (function (expr, rewriteCb) { + var assignmentExpr; + var firstExpr; + var propertyName; + var k; + var baseExpr; + if (expr instanceof AssignmentExpression) { + assignmentExpr = expr; + firstExpr = assignmentExpr.getFirstExpr$(); + if (isFirstLevelPropertyAccess(firstExpr) && ! Util$rootIsNativeClass$LType$(firstExpr.getExpr$().getType$())) { + propertyName = firstExpr.getIdentifierToken$().getValue$(); + onExpr(assignmentExpr.getSecondExpr$(), null); + if (lastAssignExpr[propertyName] && lastAssignExpr[propertyName].second != null && baseExprsAreEqual(firstExpr.getExpr$(), lastAssignExpr[propertyName].first.getFirstExpr$().getExpr$())) { + lastAssignExpr[propertyName].second(lastAssignExpr[propertyName].first.getSecondExpr$()); + } + lastAssignExpr[propertyName] = Util$makePair$LAssignmentExpression$F$LExpression$V$(assignmentExpr, rewriteCb); + return true; + } else if (assignmentExpr.getFirstExpr$() instanceof LocalExpression) { + onExpr(assignmentExpr.getSecondExpr$(), null); + for (k in lastAssignExpr) { + baseExpr = lastAssignExpr[k].first.getFirstExpr$().getExpr$(); + if (baseExpr instanceof LocalExpression && baseExpr.getLocal$() == expr.getFirstExpr$().getLocal$()) { + delete lastAssignExpr[k]; + } + } + return true; + } + } else if (isFirstLevelPropertyAccess(expr)) { + propertyName = expr.getIdentifierToken$().getValue$(); + delete lastAssignExpr[propertyName]; + } else if (expr instanceof CallExpression) { + onExpr(expr.getExpr$(), null); + Util$forEachExpression$F$LExpression$F$LExpression$V$B$ALExpression$(onExpr, expr.getArguments$()); + lastAssignExpr = {}; + return true; + } else if (expr instanceof NewExpression) { + Util$forEachExpression$F$LExpression$F$LExpression$V$B$ALExpression$(onExpr, expr.getArguments$()); + lastAssignExpr = {}; + return true; + } + return expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); + }); + Util$forEachExpression$F$LExpression$F$LExpression$V$B$ALExpression$(onExpr, exprs); }; -_StripOptimizeCommand.prototype._walkVariableDefinition$LMemberVariableDefinition$ = function (varDef) { +_DeadCodeEliminationOptimizeCommand.prototype._eliminateDeadConditions$LMemberFunctionDefinition$ALExpression$ = function (funcDef, exprs) { var $this = this; - var initialValue; - initialValue = varDef.getInitialValue$(); - if (initialValue != null) { - this._walkExpression$LExpression$(initialValue); + var spliceStatements; + function spliceStatements(dest, index, src) { + var i; + dest.splice(index, 1); + for (i = 0; i < src.length; ++i) { + dest.splice(index + i, 0, src[i]); + } } - return varDef.forEachClosure$F$LMemberFunctionDefinition$B$((function (funcDef) { - return $this._walkFunctionDefinition$LMemberFunctionDefinition$(funcDef); - })); + (function onStatements(statements) { + var i; + var statement; + var ifStatement; + var cond; + for (i = statements.length - 1; i >= 0; --i) { + statement = statements[i]; + if (statement instanceof IfStatement) { + ifStatement = statement; + cond = _Util$0$conditionIsConstant$LExpression$(ifStatement.getExpr$()); + if (cond == null) { + } else if (cond === false && ifStatement.getOnFalseStatements$().length === 0) { + statements.splice(i, 1); + } else if (cond === false) { + spliceStatements(statements, i, ifStatement.getOnFalseStatements$()); + } else if (cond === true) { + spliceStatements(statements, i, ifStatement.getOnTrueStatements$()); + } + } + statement.handleStatements$F$ALStatement$B$(onStatements); + } + return true; + })(funcDef.getStatements$()); }; -function _NoAssertCommand() { - _FunctionOptimizeCommand.call(this, _NoAssertCommand.IDENTIFIER); +function _ReturnIfOptimizeCommand() { + _FunctionOptimizeCommand.call(this, _ReturnIfOptimizeCommand.IDENTIFIER); + this._altered = false; }; -$__jsx_extend([_NoAssertCommand], _FunctionOptimizeCommand); -_NoAssertCommand.prototype.optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { +$__jsx_extend([_ReturnIfOptimizeCommand], _FunctionOptimizeCommand); +_ReturnIfOptimizeCommand.prototype.optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { + if (funcDef.getReturnType$() == null || funcDef.getReturnType$().equals$LType$(Type.voidType)) { + return false; + } + this._altered = false; this._optimizeStatements$ALStatement$(funcDef.getStatements$()); - return true; + this.log$S(funcDef.getNotation$() + " " + (this._altered ? "Y" : "N")); + return this._altered; }; -_NoAssertCommand.prototype._optimizeStatements$ALStatement$ = function (statements) { - var $this = this; - var optimize; - function optimize(statements) { - var i; - for (i = 0; i < statements.length; ) { - if (statements[i] instanceof AssertStatement) { - statements.splice(i, 1); - } else { - _Util$0$handleSubStatements$F$ALStatement$B$LStatement$(optimize, statements[i]); - ++i; +_ReturnIfOptimizeCommand.prototype._statementsCanBeReturnExpr$ALStatement$ = function (statements) { + if (statements.length === 1 && statements[0] instanceof ReturnStatement) { + return true; + } + this._optimizeStatements$ALStatement$(statements); + if (statements.length === 1 && statements[0] instanceof ReturnStatement) { + return true; + } + return false; +}; + + +_ReturnIfOptimizeCommand.prototype._optimizeStatements$ALStatement$ = function (statements) { + var ifStatement; + var onFalseStatements; + if (statements.length >= 1 && statements[statements.length - 1] instanceof IfStatement) { + ifStatement = statements[statements.length - 1]; + if (this._statementsCanBeReturnExpr$ALStatement$(ifStatement.getOnTrueStatements$()) && this._statementsCanBeReturnExpr$ALStatement$(ifStatement.getOnFalseStatements$())) { + statements[statements.length - 1] = this._createReturnStatement$LToken$LExpression$LExpression$LExpression$(ifStatement.getToken$(), ifStatement.getExpr$(), ifStatement.getOnTrueStatements$()[0].getExpr$(), ifStatement.getOnFalseStatements$()[0].getExpr$()); + this._altered = true; + this._optimizeStatements$ALStatement$(statements); + } + } else if (statements.length >= 2 && statements[statements.length - 1] instanceof ReturnStatement && statements[statements.length - 2] instanceof IfStatement) { + ifStatement = statements[statements.length - 2]; + if (this._statementsCanBeReturnExpr$ALStatement$(ifStatement.getOnTrueStatements$())) { + onFalseStatements = ifStatement.getOnFalseStatements$(); + if (onFalseStatements.length === 0) { + statements.splice(statements.length - 2, 2, this._createReturnStatement$LToken$LExpression$LExpression$LExpression$(ifStatement.getToken$(), ifStatement.getExpr$(), ifStatement.getOnTrueStatements$()[0].getExpr$(), statements[statements.length - 1].getExpr$())); + this._altered = true; + this._optimizeStatements$ALStatement$(statements); + } else if (onFalseStatements.length === 1 && onFalseStatements[0] instanceof IfStatement && onFalseStatements[0].getOnFalseStatements$().length === 0) { + onFalseStatements[0].getOnFalseStatements$().push(statements[statements.length - 1]); + statements.pop(); + this._altered = true; + this._optimizeStatements$ALStatement$(statements); } } - return false; } - optimize(statements); }; -function _NoLogCommand() { - _FunctionOptimizeCommand.call(this, _NoLogCommand.IDENTIFIER); +_ReturnIfOptimizeCommand.prototype._createReturnStatement$LToken$LExpression$LExpression$LExpression$ = function (token, condExpr, trueExpr, falseExpr) { + return new ReturnStatement(token, new ConditionalExpression$0(new Token$2("?", false), condExpr, trueExpr, falseExpr, falseExpr.getType$())); }; -$__jsx_extend([_NoLogCommand], _FunctionOptimizeCommand); -_NoLogCommand.prototype.optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { - this._optimizeStatements$ALStatement$(funcDef.getStatements$()); - return true; + +function _LCSECachedExpression(origExpr, replaceCb) { + this._origExpr = origExpr; + this._replaceCb = replaceCb; + this._localExpr = null; }; +$__jsx_extend([_LCSECachedExpression], Object); +_LCSECachedExpression.prototype.getOrigExpr$ = function () { + return this._origExpr; +}; -_NoLogCommand.prototype._optimizeStatements$ALStatement$ = function (statements) { - var $this = this; - var optimize; - function optimize(statements) { - var i; - for (i = 0; i < statements.length; ) { - if (statements[i] instanceof LogStatement) { - statements.splice(i, 1); - } else { - _Util$0$handleSubStatements$F$ALStatement$B$LStatement$(optimize, statements[i]); - ++i; - } - } - return false; + +_LCSECachedExpression.prototype.getLocalExpr$F$LType$SLLocalExpression$$ = function (createVarCb) { + if (this._localExpr == null) { + this._localExpr = createVarCb(this._origExpr.getType$(), this._origExpr.getIdentifierToken$().getValue$()); + this._replaceCb(new AssignmentExpression(new Token$2("=", false), this._localExpr, this._origExpr)); } - optimize(statements); + return this._localExpr; }; -function _DetermineCalleeCommand() { - _FunctionOptimizeCommand.call(this, _DetermineCalleeCommand.IDENTIFIER); +function _LCSEOptimizeCommand() { + _FunctionOptimizeCommand.call(this, _LCSEOptimizeCommand.IDENTIFIER); }; -$__jsx_extend([_DetermineCalleeCommand], _FunctionOptimizeCommand); -_DetermineCalleeCommand.prototype._createStash$ = function () { - return new _DetermineCalleeCommand$x2EStash(); +$__jsx_extend([_LCSEOptimizeCommand], _FunctionOptimizeCommand); +_LCSEOptimizeCommand.prototype.optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { + var $this = this; + _Util$0$optimizeBasicBlock$LMemberFunctionDefinition$F$ALExpression$V$(funcDef, (function (exprs) { + $this._optimizeExpressions$LMemberFunctionDefinition$ALExpression$(funcDef, exprs); + })); + return true; }; -_DetermineCalleeCommand.prototype.optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { +_LCSEOptimizeCommand.prototype._optimizeExpressions$LMemberFunctionDefinition$ALExpression$ = function (funcDef, exprs) { var $this = this; - funcDef.forEachStatement$F$LStatement$B$((function onStatement(statement) { - var callingFuncDef; - if (statement instanceof ConstructorInvocationStatement) { - callingFuncDef = _DetermineCalleeCommand$findCallingFunctionInClass$LClassDefinition$SALType$B(statement.getConstructingClassDef$(), "constructor", statement.getConstructorType$().getArgumentTypes$(), false); - if (callingFuncDef == null) { - throw new Error("could not determine the associated parent ctor"); - } - $this._setCallingFuncDef$LStashable$LMemberFunctionDefinition$(statement, callingFuncDef); - } else if (statement instanceof FunctionStatement) { - statement.getFuncDef$().forEachStatement$F$LStatement$B$(onStatement); - } - statement.forEachExpression$F$LExpression$B$((function onExpr(expr) { - var calleeExpr; - var propertyExpr; - var holderType; - var callingFuncDef; - var newExpr; - if (expr instanceof CallExpression) { - calleeExpr = expr.getExpr$(); - if (calleeExpr instanceof PropertyExpression && ! calleeExpr.getType$().isAssignable$()) { - propertyExpr = calleeExpr; - holderType = propertyExpr.getHolderType$(); - callingFuncDef = _DetermineCalleeCommand$findCallingFunction$LClassDefinition$SALType$B(holderType.getClassDef$(), propertyExpr.getIdentifierToken$().getValue$(), propertyExpr.getType$().getArgumentTypes$(), propertyExpr.getExpr$().isClassSpecifier$()); - $this._setCallingFuncDef$LStashable$LMemberFunctionDefinition$(expr, callingFuncDef); - } else if (calleeExpr instanceof FunctionExpression) { - $this._setCallingFuncDef$LStashable$LMemberFunctionDefinition$(expr, calleeExpr.getFuncDef$()); + var cachedExprs; + var getCacheKey; + var registerCacheable; + var clearCacheByLocalName; + var clearCache; + this.log$S("optimizing expressions starting"); + cachedExprs = {}; + getCacheKey = (function (expr) { + var propertyExpr; + var receiverType; + var base; + if (expr instanceof PropertyExpression) { + propertyExpr = expr; + receiverType = propertyExpr.getExpr$().getType$(); + if (Util$rootIsNativeClass$LType$(receiverType)) { + return null; + } + base = getCacheKey(propertyExpr.getExpr$()); + if (base == null) { + return null; + } + return base + "." + propertyExpr.getIdentifierToken$().getValue$(); + } else if (expr instanceof LocalExpression) { + return expr.getLocal$().getName$().getValue$(); + } else if (expr instanceof ThisExpression) { + return "this"; + } + return null; + }); + registerCacheable = (function (key, expr, replaceCb) { + $this.log$S("registering lcse entry for: " + key); + cachedExprs[key] = new _LCSECachedExpression(expr, replaceCb); + }); + clearCacheByLocalName = (function (name) { + var k; + $this.log$S("clearing lcse entry for local name: " + name); + for (k in cachedExprs) { + if (k.substring(0, name.length + 1) === name + ".") { + $this.log$S(" removing: " + k); + delete cachedExprs[k]; + } + } + }); + clearCache = (function () { + $this.log$S("clearing lcse cache"); + cachedExprs = {}; + }); + Util$forEachExpression$F$LExpression$F$LExpression$V$B$ALExpression$((function onExpr(expr, replaceCb) { + var assignmentExpr; + var lhsExpr; + var lhsPropertyExpr; + var cacheKey; + var incrementExpr; + var propertyExpr; + var conditionalExpr; + var funcExpr; + var args; + var i; + if (expr instanceof AssignmentExpression || expr instanceof FusedAssignmentExpression) { + assignmentExpr = expr; + lhsExpr = assignmentExpr.getFirstExpr$(); + if (lhsExpr instanceof LocalExpression) { + onExpr(assignmentExpr.getSecondExpr$(), (function (expr) { + assignmentExpr.setSecondExpr$LExpression$(expr); + })); + clearCacheByLocalName(lhsExpr.getLocal$().getName$().getValue$()); + } else if (lhsExpr instanceof PropertyExpression) { + lhsPropertyExpr = lhsExpr; + onExpr(lhsExpr.getExpr$(), (function (expr) { + lhsPropertyExpr.setExpr$LExpression$(expr); + })); + onExpr(assignmentExpr.getSecondExpr$(), (function (expr) { + assignmentExpr.setSecondExpr$LExpression$(expr); + })); + if (lhsPropertyExpr.getIdentifierToken$().getValue$() === "length") { } else { - $this._setCallingFuncDef$LStashable$LMemberFunctionDefinition$(expr, null); - } - } else if (expr instanceof NewExpression) { - newExpr = expr; - if (! (newExpr.getType$().getClassDef$() != null)) { - debugger; - throw new Error("[src/optimizer.jsx:1062:59] assertion failure\n assert newExpr.getType().getClassDef() != null;\n ^^\n"); - } - if (! (newExpr.getConstructor$() != null)) { - debugger; - throw new Error("[src/optimizer.jsx:1063:52] assertion failure\n assert newExpr.getConstructor() != null;\n ^^\n"); - } - callingFuncDef = _DetermineCalleeCommand$findCallingFunctionInClass$LClassDefinition$SALType$B(newExpr.getType$().getClassDef$(), "constructor", newExpr.getConstructor$().getArgumentTypes$(), false); - if (callingFuncDef == null) { - throw new Error("could not find matching constructor for " + newExpr.getConstructor$().toString()); + cacheKey = getCacheKey(lhsExpr); + if (cacheKey) { + registerCacheable(cacheKey, lhsExpr, (function (expr) { + assignmentExpr.setFirstExpr$LExpression$(expr); + })); + } } - $this._setCallingFuncDef$LStashable$LMemberFunctionDefinition$(newExpr, callingFuncDef); + } else { + clearCache(); } - if (expr instanceof FunctionExpression) { - return expr.getFuncDef$().forEachStatement$F$LStatement$B$(onStatement); + return true; + } else if (expr instanceof IncrementExpression) { + incrementExpr = expr; + if (incrementExpr.getExpr$() instanceof PropertyExpression) { + propertyExpr = incrementExpr.getExpr$(); + onExpr(propertyExpr.getExpr$(), (function (expr) { + propertyExpr.setExpr$LExpression$(expr); + })); + } + clearCache(); + return true; + } else if (expr instanceof ConditionalExpression) { + conditionalExpr = expr; + onExpr(conditionalExpr.getCondExpr$(), (function (expr) { + conditionalExpr.setCondExpr$LExpression$(expr); + })); + clearCache(); + return true; + } else if (expr instanceof LogicalExpression) { + if (! expr.forEachExpression$F$LExpression$B$((function (expr) { + return ! _Util$0$exprHasSideEffects$LExpression$(expr); + }))) { + clearCache(); + return true; + } + } else if (expr instanceof FunctionExpression) { + clearCache(); + return true; + } else if (expr instanceof CallExpression) { + funcExpr = expr.getExpr$(); + if (funcExpr instanceof LocalExpression) { + } else if (funcExpr instanceof PropertyExpression) { + propertyExpr = funcExpr; + onExpr(propertyExpr.getExpr$(), (function (expr) { + propertyExpr.setExpr$LExpression$(expr); + })); } else { - return expr.forEachExpression$F$LExpression$B$(onExpr); + clearCache(); } - })); - return statement.forEachStatement$F$LStatement$B$(onStatement); - })); - return true; -}; - - -_DetermineCalleeCommand.prototype._setCallingFuncDef$LStashable$LMemberFunctionDefinition$ = function (stashable, funcDef) { - this.getStash$LStashable$(stashable).callingFuncDef = funcDef; + args = expr.getArguments$(); + for (i = 0; i < args.length; ++i) { + onExpr(args[i], (function (args, index) { + return (function (expr) { + args[index] = expr; + }); + })(args, i)); + } + clearCache(); + return true; + } else if (expr instanceof NewExpression) { + $this.log$S("new expression"); + args = expr.getArguments$(); + for (i = 0; i < args.length; ++i) { + onExpr(args[i], (function (args, index) { + return (function (expr) { + args[index] = expr; + }); + })(args, i)); + } + clearCache(); + return true; + } + if (expr instanceof PropertyExpression) { + if (expr.getIdentifierToken$().getValue$() === "length") { + } else { + cacheKey = getCacheKey(expr); + if (cacheKey) { + $this.log$S("rewriting cse for: " + cacheKey); + if (cachedExprs[cacheKey]) { + replaceCb(cachedExprs[cacheKey].getLocalExpr$F$LType$SLLocalExpression$$((function (type, baseName) { + var localVar; + localVar = $this.createVar$LMemberFunctionDefinition$LType$S(funcDef, type, baseName); + return new LocalExpression(localVar.getName$(), localVar); + })).clone$()); + } else { + registerCacheable(cacheKey, expr, replaceCb); + } + } + } + } + return expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); + }), exprs); }; -function _DetermineCalleeCommand$findCallingFunctionInClass$LClassDefinition$SALType$B(classDef, funcName, argTypes, isStatic) { - var found; - found = Util$findFunctionInClass$LClassDefinition$SALType$B(classDef, funcName, argTypes, isStatic); - if (found != null) { - if ((found.flags$() & (ClassDefinition.IS_STATIC | ClassDefinition.IS_FINAL)) === 0) { - found = null; - } - } - return found; +function _ArrayLengthOptimizeCommand() { + _FunctionOptimizeCommand.call(this, _ArrayLengthOptimizeCommand.IDENTIFIER); }; -_DetermineCalleeCommand.findCallingFunctionInClass$LClassDefinition$SALType$B = _DetermineCalleeCommand$findCallingFunctionInClass$LClassDefinition$SALType$B; - -function _DetermineCalleeCommand$findCallingFunction$LClassDefinition$SALType$B(classDef, funcName, argTypes, isStatic) { - var found; - found = null; - classDef.forEachClassToBase$F$LClassDefinition$B$((function (classDef) { - if ((found = _DetermineCalleeCommand$findCallingFunctionInClass$LClassDefinition$SALType$B(classDef, funcName, argTypes, isStatic)) != null) { - return false; +$__jsx_extend([_ArrayLengthOptimizeCommand], _FunctionOptimizeCommand); +_ArrayLengthOptimizeCommand.prototype.optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { + var $this = this; + funcDef.forEachStatement$F$LStatement$B$((function onStatement(statement) { + var condExpr; + var arrayLocal; + statement.forEachStatement$F$LStatement$B$(onStatement); + if (statement instanceof ForStatement) { + condExpr = statement.getCondExpr$(); + arrayLocal = (condExpr != null ? $this._hasLengthExprOfLocalArray$LExpression$(condExpr) : null); + if (arrayLocal != null) { + $this._optimizeArrayLength$LMemberFunctionDefinition$LForStatement$LLocalVariable$(funcDef, statement, arrayLocal); + } } return true; })); - return found; -}; - -_DetermineCalleeCommand.findCallingFunction$LClassDefinition$SALType$B = _DetermineCalleeCommand$findCallingFunction$LClassDefinition$SALType$B; - -function _DetermineCalleeCommand$getCallingFuncDef$LStashable$(stashable) { - var stash; - stash = stashable.getStash$S(_DetermineCalleeCommand.IDENTIFIER); - if (stash == null) { - throw new Error("callee not searched"); - } - return stash.callingFuncDef; -}; - -_DetermineCalleeCommand.getCallingFuncDef$LStashable$ = _DetermineCalleeCommand$getCallingFuncDef$LStashable$; - -function _StaticizeOptimizeCommand() { - _OptimizeCommand.call(this, _StaticizeOptimizeCommand.IDENTIFIER); -}; - -$__jsx_extend([_StaticizeOptimizeCommand], _OptimizeCommand); -_StaticizeOptimizeCommand.prototype._createStash$ = function () { - return new _StaticizeOptimizeCommand$x2EStash(); + return true; }; -_StaticizeOptimizeCommand.prototype.performOptimization$ = function () { +_ArrayLengthOptimizeCommand.prototype._optimizeArrayLength$LMemberFunctionDefinition$LForStatement$LLocalVariable$ = function (funcDef, statement, arrayLocal) { var $this = this; - var memberCanBeStaticized; - function memberCanBeStaticized(funcDef) { - var onStatement; - if ((funcDef.flags$() & (ClassDefinition.IS_OVERRIDE | ClassDefinition.IS_ABSTRACT | ClassDefinition.IS_FINAL | ClassDefinition.IS_STATIC | ClassDefinition.IS_NATIVE)) !== ClassDefinition.IS_FINAL) { - return false; - } - if (funcDef.name$() === "constructor") { - return false; - } - function onStatement(statement) { - if (statement instanceof FunctionStatement) { - return statement.getFuncDef$().forEachStatement$F$LStatement$B$(onStatement); - } - return statement.forEachExpression$F$LExpression$B$((function onExpression(expr) { - if (expr instanceof FunctionExpression) { - return expr.getFuncDef$().forEachStatement$F$LStatement$B$(onStatement); - } else if (expr instanceof SuperExpression) { - return false; - } - return expr.forEachExpression$F$LExpression$B$(onExpression); - })) && statement.forEachStatement$F$LStatement$B$(onStatement); - } - if (! funcDef.forEachStatement$F$LStatement$B$(onStatement)) { - return false; - } - return true; - } - this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { - if ((classDef.flags$() & (ClassDefinition.IS_INTERFACE | ClassDefinition.IS_MIXIN)) !== 0) { - return true; + var lengthLocal; + var assignToLocal; + var onExpr; + if (this._lengthIsUnmodifiedInExpr$LExpression$(statement.getCondExpr$()) && this._lengthIsUnmodifiedInExpr$LExpression$(statement.getPostExpr$()) && statement.forEachStatement$F$LStatement$B$((function (statement) { + return $this._lengthIsUnmodifiedInStatement$LStatement$(statement); + }))) { + this.log$S(funcDef.getNotation$() + " optimizing " + statement.getToken$().getNotation$()); + lengthLocal = this.createVar$LMemberFunctionDefinition$LType$S(funcDef, Type.integerType, arrayLocal.getName$().getValue$() + "$len"); + assignToLocal = new AssignmentExpression(new Token$3("="), new LocalExpression(new Token$2(lengthLocal.getName$().getValue$(), true), lengthLocal), new PropertyExpression$0(new Token$3("."), new LocalExpression(new Token$2(arrayLocal.getName$().getValue$(), true), arrayLocal), new Token$3("length"), [], lengthLocal.getType$())); + if (statement.getInitExpr$() != null) { + statement.setInitExpr$LExpression$(new CommaExpression(new Token$3(","), statement.getInitExpr$(), assignToLocal)); + } else { + statement.setInitExpr$LExpression$(assignToLocal); } - classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$((function onFunction(funcDef) { - if (memberCanBeStaticized(funcDef)) { - $this.log$S("staticizing method: " + funcDef.name$()); - $this._staticizeMethod$LMemberFunctionDefinition$(funcDef); + onExpr = (function (expr, replaceCb) { + if (expr instanceof PropertyExpression && expr.getIdentifierToken$().getValue$() === "length" && expr.getExpr$() instanceof LocalExpression && expr.getExpr$().getLocal$() == arrayLocal) { + replaceCb(new LocalExpression(new Token$2(lengthLocal.getName$().getValue$(), true), lengthLocal)); + } else { + expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); } return true; - })); - return true; - })); - this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { - var onFunction; - $this.log$S("rewriting member method calls in class: " + classDef.className$()); - classDef.forEachMemberVariable$F$LMemberVariableDefinition$B$((function (varDef) { - if (varDef.getInitialValue$() == null) { - return true; - } - $this._rewriteMethodCallsToStatic$LExpression$F$LExpression$V$LMemberFunctionDefinition$(varDef.getInitialValue$(), (function (expr) { - varDef.setInitialValue$LExpression$(expr); - }), null); + }); + statement.getCondExpr$().forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); + statement.getPostExpr$().forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); + statement.forEachStatement$F$LStatement$B$((function onStatement2(statement) { + statement.forEachStatement$F$LStatement$B$(onStatement2); + statement.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); return true; })); - function onFunction(funcDef) { - var onStatement; - function onStatement(statement) { - statement.forEachExpression$F$LExpression$F$LExpression$V$B$((function (expr, replaceCb) { - $this._rewriteMethodCallsToStatic$LExpression$F$LExpression$V$LMemberFunctionDefinition$(expr, replaceCb, funcDef); - return true; - })); - return statement.forEachStatement$F$LStatement$B$(onStatement); - } - funcDef.forEachStatement$F$LStatement$B$(onStatement); - return funcDef.forEachClosure$F$LMemberFunctionDefinition$B$(onFunction); - } - classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$(onFunction); - return true; - })); + } }; -_StaticizeOptimizeCommand.prototype._staticizeMethod$LMemberFunctionDefinition$ = function (funcDef) { +_ArrayLengthOptimizeCommand.prototype._hasLengthExprOfLocalArray$LExpression$ = function (expr) { var $this = this; - var staticFuncDef; - var classDef; - var newName; - var thisArg; - staticFuncDef = funcDef.clone$(); - classDef = staticFuncDef.getClassDef$(); - newName = this._newStaticFunctionName$LClassDefinition$SALType$B(classDef, funcDef.name$(), [ new ObjectType(classDef) ].concat(funcDef.getType$().getArgumentTypes$()), true); - this.getStash$LStashable$(funcDef).altName = newName; - staticFuncDef._nameToken = new Token$2(newName, true); - staticFuncDef.setFlags$N(funcDef.flags$() & ~ ClassDefinition.IS_EXPORT | ClassDefinition.IS_STATIC); - thisArg = new ArgumentDeclaration(new Token$2("$this", false), new ObjectType(classDef)); - staticFuncDef.getArguments$().unshift(thisArg); - staticFuncDef.forEachStatement$F$LStatement$B$((function onStatement(statement) { - if (statement instanceof FunctionStatement) { - statement.getFuncDef$().forEachStatement$F$LStatement$B$(onStatement); + var local; + local = null; + expr.forEachExpression$F$LExpression$B$((function onExpr(expr) { + if (expr instanceof PropertyExpression && expr.getIdentifierToken$().getValue$() === "length" && expr.getExpr$() instanceof LocalExpression && $this._typeIsArray$LType$(expr.getExpr$().getType$().resolveIfNullable$())) { + local = expr.getExpr$().getLocal$(); + return false; } - return statement.forEachExpression$F$LExpression$F$LExpression$V$B$((function onExpr(expr, replaceCb) { - if (expr instanceof ThisExpression) { - replaceCb(new LocalExpression(thisArg.getName$(), thisArg)); - } else if (expr instanceof FunctionExpression) { - return expr.getFuncDef$().forEachStatement$F$LStatement$B$(onStatement); - } - return expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); - })) && statement.forEachStatement$F$LStatement$B$(onStatement); + return expr.forEachExpression$F$LExpression$B$(onExpr); })); + return local; }; -_StaticizeOptimizeCommand.prototype._newStaticFunctionName$LClassDefinition$SALType$B = function (classDef, baseName, argTypes, isStatic) { - var index; - var newName; - index = 0; - newName = baseName; - while (Util$findFunctionInClass$LClassDefinition$SALType$B(classDef, newName, argTypes, isStatic) != null) { - newName = Util$format$SAS("%1_%2", [ baseName, index + "" ]); - ++index; +_ArrayLengthOptimizeCommand.prototype._lengthIsUnmodifiedInStatement$LStatement$ = function (statement) { + var $this = this; + if (! statement.forEachStatement$F$LStatement$B$((function (statement) { + return $this._lengthIsUnmodifiedInStatement$LStatement$(statement); + }))) { + return false; } - return newName; + return statement.forEachExpression$F$LExpression$B$((function (expr) { + return $this._lengthIsUnmodifiedInExpr$LExpression$(expr); + })); }; -_StaticizeOptimizeCommand.prototype._rewriteMethodCallsToStatic$LExpression$F$LExpression$V$LMemberFunctionDefinition$ = function (expr, replaceCb, rewritingFuncDef) { - var $this = this; - var onExpr; - function onExpr(expr, replaceCb) { - var calleeExpr; - var propertyExpr; - var receiverType; - var funcDef; - var newName; - var superExpr; - var classDef; - var thisVar; - var thisArg; - if (expr instanceof CallExpression) { - calleeExpr = expr.getExpr$(); - if (calleeExpr instanceof PropertyExpression && ! calleeExpr.getExpr$().isClassSpecifier$() && ! calleeExpr.getType$().isAssignable$()) { - propertyExpr = calleeExpr; - receiverType = propertyExpr.getExpr$().getType$().resolveIfNullable$(); - if ((receiverType.getClassDef$().flags$() & (ClassDefinition.IS_INTERFACE | ClassDefinition.IS_MIXIN)) === 0) { - funcDef = $this._findFunctionInClassTree$LClassDefinition$SALType$B(receiverType.getClassDef$(), propertyExpr.getIdentifierToken$().getValue$(), propertyExpr.getType$().getArgumentTypes$(), false); - if (funcDef != null && (newName = $this.getStash$LStashable$(funcDef).altName) != null) { - onExpr(propertyExpr.getExpr$(), (function (expr) { - propertyExpr.setExpr$LExpression$(expr); - })); - Util$forEachExpression$F$LExpression$F$LExpression$V$B$ALExpression$(onExpr, expr.getArguments$()); - replaceCb(new CallExpression(expr.getToken$(), new PropertyExpression$0(propertyExpr.getToken$(), new ClassExpression(new Token$2(funcDef.getClassDef$().className$(), true), new ObjectType(funcDef.getClassDef$())), new Token$2(newName, true), propertyExpr.getTypeArguments$(), new StaticFunctionType(null, funcDef.getType$().getReturnType$(), [ new ObjectType(funcDef.getClassDef$()) ].concat(funcDef.getType$().getArgumentTypes$()), false)), [ propertyExpr.getExpr$() ].concat(expr.getArguments$()))); - return true; - } - } - } - } else if (expr instanceof SuperExpression) { - superExpr = expr; - classDef = superExpr.getFunctionType$().getObjectType$().getClassDef$(); - funcDef = $this._findFunctionInClassTree$LClassDefinition$SALType$B(classDef, superExpr.getName$().getValue$(), superExpr.getFunctionType$().getArgumentTypes$(), false); - if (funcDef != null && (newName = $this.getStash$LStashable$(funcDef).altName) != null) { - Util$forEachExpression$F$LExpression$F$LExpression$V$B$ALExpression$(onExpr, superExpr.getArguments$()); - if ((rewritingFuncDef.flags$() & ClassDefinition.IS_STATIC) !== 0) { - thisArg = rewritingFuncDef.getArguments$()[0]; - thisVar = new LocalExpression(thisArg.getName$(), thisArg); - } else { - thisVar = new ThisExpression(new Token$2("this", false), funcDef.getClassDef$()); - } - replaceCb(new CallExpression(expr.getToken$(), new PropertyExpression$0(superExpr.getToken$(), new ClassExpression(new Token$2(funcDef.getClassDef$().className$(), true), new ObjectType(funcDef.getClassDef$())), new Token$2(newName, true), [ ], new StaticFunctionType(null, funcDef.getType$().getReturnType$(), [ new ObjectType(funcDef.getClassDef$()) ].concat(funcDef.getType$().getArgumentTypes$()), false)), [ thisVar ].concat(superExpr.getArguments$()))); - return true; - } +_ArrayLengthOptimizeCommand.prototype._lengthIsUnmodifiedInExpr$LExpression$ = function (expr) { + if (expr instanceof AssignmentExpression) { + if (this._lhsMayModifyLength$LExpression$(expr.getFirstExpr$())) { + return false; + } + } else if (expr instanceof CallExpression || expr instanceof SuperExpression) { + return false; + } else if (expr instanceof IncrementExpression) { + if (this._lhsMayModifyLength$LExpression$(expr.getExpr$())) { + return false; } - return expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); } - onExpr(expr, replaceCb); + return true; }; -_StaticizeOptimizeCommand.prototype._findFunctionInClassTree$LClassDefinition$SALType$B = function (classDef, name, argTypes, isStatic) { - var funcDef; - while (classDef.className$() !== "Object") { - if ((funcDef = Util$findFunctionInClass$LClassDefinition$SALType$B(classDef, name, argTypes, isStatic)) != null) { - return funcDef; - } - classDef = classDef.extendType$().getClassDef$(); +_ArrayLengthOptimizeCommand.prototype._lhsMayModifyLength$LExpression$ = function (expr) { + var exprType; + if (expr instanceof PropertyExpression && expr.getIdentifierToken$().getValue$() === "length") { + return true; } - return Util$findFunctionInClass$LClassDefinition$SALType$B(classDef, name, argTypes, isStatic); + if (expr instanceof ArrayExpression) { + return true; + } + exprType = expr.getType$().resolveIfNullable$(); + if (exprType.equals$LType$(Type.variantType)) { + return true; + } + if (this._typeIsArray$LType$(exprType)) { + return true; + } + return false; }; -function _UnclassifyOptimizationCommand() { - _OptimizeCommand.call(this, _UnclassifyOptimizationCommand.IDENTIFIER); +_ArrayLengthOptimizeCommand.prototype._typeIsArray$LType$ = function (type) { + var classDef; + if (! (type instanceof ObjectType)) { + return false; + } + classDef = type.getClassDef$(); + if (! (classDef instanceof InstantiatedClassDefinition)) { + return false; + } + return classDef.getTemplateClassName$() === "Array"; }; -$__jsx_extend([_UnclassifyOptimizationCommand], _OptimizeCommand); -_UnclassifyOptimizationCommand.prototype._createStash$ = function () { - return new _UnclassifyOptimizationCommand$x2EStash(); -}; +function _TailRecursionOptimizeCommand() { + _FunctionOptimizeCommand.call(this, _TailRecursionOptimizeCommand.IDENTIFIER); +}; -_UnclassifyOptimizationCommand.prototype.performOptimization$ = function () { +$__jsx_extend([_TailRecursionOptimizeCommand], _FunctionOptimizeCommand); +_TailRecursionOptimizeCommand.prototype.optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { var $this = this; - var classDefs; - classDefs = this._getClassesToUnclassify$(); - classDefs.forEach((function (classDef) { - $this.log$S("unclassifying class: " + classDef.className$()); - classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$((function onFunction(funcDef) { - if ((funcDef.flags$() & ClassDefinition.IS_STATIC) === 0 && funcDef.name$() !== "constructor") { - $this.log$S("rewriting method to static function: " + funcDef.name$()); - $this._rewriteFunctionAsStatic$LMemberFunctionDefinition$(funcDef); - } - return true; - })); - })); - this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { - var onFunction; - $this.log$S("rewriting member method calls in class: " + classDef.className$()); - function onFunction(funcDef) { - var onStatement; - function onStatement(statement) { - statement.forEachExpression$F$LExpression$F$LExpression$V$B$((function (expr, replaceCb) { - $this._rewriteMethodCallsToStatic$LExpression$F$LExpression$V$ALClassDefinition$(expr, replaceCb, classDefs); - return true; - })); - return statement.forEachStatement$F$LStatement$B$(onStatement); + var altered; + var statements; + var body; + if ((funcDef.flags$() & (ClassDefinition.IS_OVERRIDE | ClassDefinition.IS_ABSTRACT | ClassDefinition.IS_NATIVE)) !== 0 || (funcDef.flags$() & (ClassDefinition.IS_STATIC | ClassDefinition.IS_FINAL)) === 0) { + return false; + } + altered = false; + statements = funcDef.getStatements$(); + (function onStatements(statements) { + var i; + for (i = 0; i < statements.length; ++i) { + if ($this._isTailCall$LMemberFunctionDefinition$LStatement$(funcDef, statements[i])) { + $this._replaceTailCallStatement$LMemberFunctionDefinition$ALStatement$N(funcDef, statements, i); + altered = true; } - funcDef.forEachStatement$F$LStatement$B$(onStatement); - return funcDef.forEachClosure$F$LMemberFunctionDefinition$B$(onFunction); + statements[i].handleStatements$F$ALStatement$B$(onStatements); } - classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$(onFunction); - classDef.forEachMemberVariable$F$LMemberVariableDefinition$B$((function (varDef) { - if ((varDef.flags$() & ClassDefinition.IS_STATIC) !== 0) { - if (varDef.getInitialValue$() != null) { - $this._rewriteMethodCallsToStatic$LExpression$F$LExpression$V$ALClassDefinition$(varDef.getInitialValue$(), (function (expr) { - varDef.setInitialValue$LExpression$(expr); - }), classDefs); - } - } - return varDef.forEachClosure$F$LMemberFunctionDefinition$B$(onFunction); - })); return true; + })(statements); + if (altered) { + this.log$S("transform " + funcDef.getNotation$()); + body = new WhileStatement(new Token$3("while"), new Token$3(_TailRecursionOptimizeCommand.LABEL), new BooleanLiteralExpression(new Token$3("true")), statements); + funcDef.setStatements$ALStatement$([ body ]); + } + return true; +}; + + +_TailRecursionOptimizeCommand.prototype._isTailCall$LMemberFunctionDefinition$LStatement$ = function (funcDef, statement) { + var returnStatement; + if (statement instanceof ReturnStatement) { + returnStatement = statement; + if (returnStatement.getExpr$() != null && returnStatement.getExpr$() instanceof CallExpression) { + return funcDef == _DetermineCalleeCommand$getCallingFuncDef$LStashable$(returnStatement.getExpr$()); + } + } + return false; +}; + + +_TailRecursionOptimizeCommand.prototype._replaceTailCallStatement$LMemberFunctionDefinition$ALStatement$N = function (funcDef, statements, idx) { + var $this = this; + var callExpression; + var locals; + var setupArgs; + var retry; + var localsToArgs; + callExpression = statements[idx].getExpr$(); + locals = funcDef.getArguments$().map((function (argDecl) { + return $this.createVar$LMemberFunctionDefinition$LType$S(funcDef, argDecl.getType$(), argDecl.getName$().getValue$()); })); + setupArgs = callExpression.getArguments$().reduce((function (prevExpr, arg, i) { + var assignToArg; + assignToArg = new AssignmentExpression(new Token$3("="), new LocalExpression(locals[i].getName$(), locals[i]), arg); + return (prevExpr == null ? assignToArg : new CommaExpression(new Token$3(","), prevExpr, assignToArg)); + }), null); + retry = new ContinueStatement(new Token$3("continue"), new Token$3(_TailRecursionOptimizeCommand.LABEL)); + if (setupArgs == null) { + statements.splice(idx, 1, retry); + } else { + localsToArgs = locals.reduce((function (prevExpr, local, i) { + var assignToArg; + assignToArg = new AssignmentExpression(new Token$3("="), new LocalExpression(funcDef.getArguments$()[i].getName$(), funcDef.getArguments$()[i]), new LocalExpression(local.getName$(), local)); + return (prevExpr == null ? assignToArg : new CommaExpression(new Token$3(","), prevExpr, assignToArg)); + }), null); + statements.splice(idx, 1, new ExpressionStatement(setupArgs), new ExpressionStatement(localsToArgs), retry); + } }; -_UnclassifyOptimizationCommand.prototype._getClassesToUnclassify$ = function () { +function _StructuredStashAccessor$x2E$x3CStash$x3E() { +}; + +$__jsx_extend([_StructuredStashAccessor$x2E$x3CStash$x3E], Object); +_StructuredStashAccessor$x2E$x3CStash$x3E.prototype.$__jsx_implements__StructuredStashAccessor$x2E$x3CStash$x3E = true; + +_StructuredStashAccessor$x2E$x3CStash$x3E.prototype.getStash$LStashable$ = function (stashable) { + var identifier; + var stash; + identifier = this._identifier; + stash = stashable.getStash$S(identifier); + if (stash == null) { + stash = new _LinkTimeOptimizationCommand$x2EStash(); + stashable.setStash$SLStash$(identifier, stash); + } + return stash; +}; + + +_StructuredStashAccessor$x2E$x3CStash$x3E.prototype.resetStash$LStashable$ = function (stashable) { + var identifier; + identifier = this._identifier; + stashable.setStash$SLStash$(identifier, null); +}; + + +function _LinkTimeOptimizationCommand() { + _OptimizeCommand.call(this, _LinkTimeOptimizationCommand.IDENTIFIER); + _StructuredStashAccessor$x2E$x3CStash$x3E.call(this); +}; + +$__jsx_extend([_LinkTimeOptimizationCommand], _OptimizeCommand); +$__jsx_merge_interface(_LinkTimeOptimizationCommand, _StructuredStashAccessor$x2E$x3CStash$x3E); + +_LinkTimeOptimizationCommand.prototype.performOptimization$ = function () { var $this = this; - var candidates; - var candidateIndex; - var hasInlineableCtor; - candidates = []; this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { - if ((classDef.flags$() & (ClassDefinition.IS_FINAL | ClassDefinition.IS_NATIVE | ClassDefinition.IS_EXPORT)) === ClassDefinition.IS_FINAL && classDef.extendType$().getClassDef$().className$() === "Object" && classDef.implementTypes$().length === 0 && classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$((function (funcDef) { - return (funcDef.flags$() & (ClassDefinition.IS_OVERRIDE | ClassDefinition.IS_EXPORT)) === 0; - }))) { - candidates.push(classDef); + var i; + if (classDef.extendType$() != null) { + $this.getStash$LStashable$(classDef.extendType$().getClassDef$()).extendedBy.push(classDef); + } + for (i = 0; i < classDef.implementTypes$().length; ++i) { + $this.getStash$LStashable$(classDef.implementTypes$()[i].getClassDef$()).extendedBy.push(classDef); } return true; })); this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { - var onExpr; - var onFunction; - if (candidates.length === 0) { - return false; - } - function onExpr(expr) { - var foundClassDefIndex; - if (! (expr != null)) { - debugger; - throw new Error("[src/optimizer.jsx:1451:28] assertion failure\n assert expr != null;\n ^^\n"); - } - if (expr instanceof InstanceofExpression) { - foundClassDefIndex = candidates.indexOf(expr.getExpectedType$().getClassDef$()); - if (foundClassDefIndex !== - 1) { - candidates.splice(foundClassDefIndex, 1); - if (candidates.length === 0) { - return false; - } + if ((classDef.flags$() & (ClassDefinition.IS_INTERFACE | ClassDefinition.IS_MIXIN | ClassDefinition.IS_NATIVE | ClassDefinition.IS_FINAL | ClassDefinition.IS_EXPORT)) === 0 && $this.getStash$LStashable$(classDef).extendedBy.length === 0) { + $this.log$S("marking class as final: " + classDef.className$()); + classDef.setFlags$N(classDef.flags$() | ClassDefinition.IS_FINAL); + classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$((function (funcDef) { + if ((funcDef.flags$() & (ClassDefinition.IS_STATIC | ClassDefinition.IS_FINAL)) === 0) { + funcDef.setFlags$N(funcDef.flags$() | ClassDefinition.IS_FINAL); } - } else if (expr instanceof AsExpression && expr.getType$() instanceof ObjectType) { - foundClassDefIndex = candidates.indexOf(expr.getType$().getClassDef$()); - if (foundClassDefIndex !== - 1) { - candidates.splice(foundClassDefIndex, 1); - if (candidates.length === 0) { - return false; + return true; + })); + } else if ((classDef.flags$() & (ClassDefinition.IS_NATIVE | ClassDefinition.IS_FINAL)) === 0) { + classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$((function (funcDef) { + var overrides; + if ((funcDef.flags$() & (ClassDefinition.IS_STATIC | ClassDefinition.IS_NATIVE | ClassDefinition.IS_FINAL)) !== 0) { + } else if ((funcDef.flags$() & ClassDefinition.IS_ABSTRACT) === 0) { + if (funcDef.getStatements$() == null) { + throw new Error("a non-native, non-abstract function with out function body?"); + } + overrides = $this._getOverrides$LClassDefinition$ALClassDefinition$SALType$(classDef, $this.getStash$LStashable$(classDef).extendedBy, funcDef.name$(), funcDef.getArgumentTypes$()); + if (overrides.length === 0) { + $this.log$S("marking function as final: " + funcDef.getNotation$()); + funcDef.setFlags$N(funcDef.flags$() | ClassDefinition.IS_FINAL); + } else { + $this.log$S("function has overrides, not marking as final: " + funcDef.getNotation$()); } + } else if ((funcDef.flags$() & ClassDefinition.IS_ABSTRACT) !== 0) { } - } - return expr.forEachExpression$F$LExpression$B$(onExpr); - } - function onFunction(funcDef) { - funcDef.forEachStatement$F$LStatement$B$((function onStatement(statement) { - statement.forEachExpression$F$LExpression$B$(onExpr); - return statement.forEachStatement$F$LStatement$B$(onStatement); + return true; })); - return funcDef.forEachClosure$F$LMemberFunctionDefinition$B$(onFunction); } - classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$(onFunction); - classDef.forEachMemberVariable$F$LMemberVariableDefinition$B$((function (varDef) { - if ((varDef.flags$() & ClassDefinition.IS_STATIC) !== 0) { - if (varDef.getInitialValue$() != null) { - onExpr(varDef.getInitialValue$()); - } - } - return varDef.forEachClosure$F$LMemberFunctionDefinition$B$(onFunction); - })); return true; })); - for (candidateIndex = candidates.length - 1; candidateIndex >= 0; --candidateIndex) { - hasInlineableCtor = false; - candidates[candidateIndex].forEachMemberFunction$F$LMemberFunctionDefinition$B$((function (funcDef) { - var inliner; - if ((funcDef.flags$() & ClassDefinition.IS_STATIC) === 0 && funcDef.name$() === "constructor") { - inliner = $this._createInliner$LMemberFunctionDefinition$(funcDef); - $this.log$S(funcDef.getNotation$() + " is" + (inliner ? "" : " not") + " inlineable"); - if (inliner) { - $this.getStash$LStashable$(funcDef).inliner = inliner; - hasInlineableCtor = true; - } - } - return true; - })); - if (! hasInlineableCtor) { - candidates.splice(candidateIndex, 1); - } - } - if (candidates.length === 0) { - return candidates; +}; + + +_LinkTimeOptimizationCommand.prototype._getOverrides$LClassDefinition$ALClassDefinition$SALType$ = function (srcClassDef, classDefs, name, argTypes) { + var overrides; + var i; + overrides = []; + for (i = 0; i < classDefs.length; ++i) { + overrides = overrides.concat(this._getOverridesByClass$LClassDefinition$LClassDefinition$SALType$(srcClassDef, classDefs[i], name, argTypes)); } - return candidates; + return overrides; }; -_UnclassifyOptimizationCommand.prototype._createInliner$LMemberFunctionDefinition$ = function (funcDef) { +_LinkTimeOptimizationCommand.prototype._getOverridesByClass$LClassDefinition$LClassDefinition$SALType$ = function (srcClassDef, classDef, name, argTypes) { var $this = this; - var propertyNames; - var propertyExprs; - var expectedArgIndex; - var statements; - var statementIndex; - var statementExpr; - var lhsExpr; - var onRHSExpr; - var propertyIndex; + var overrides; + var addOverride; + var implementClassDefs; var i; - if (funcDef.getLocals$().length !== 0) { - return null; - } - propertyNames = []; - funcDef.getClassDef$().forEachMemberVariable$F$LMemberVariableDefinition$B$((function (member) { - if ((member.flags$() & ClassDefinition.IS_STATIC) === 0) { - propertyNames.push(member.name$()); + overrides = this._getOverrides$LClassDefinition$ALClassDefinition$SALType$(srcClassDef, this.getStash$LStashable$(classDef).extendedBy, name, argTypes); + function addOverride(funcDef) { + if (funcDef.name$() === name && (funcDef.flags$() & ClassDefinition.IS_ABSTRACT) === 0 && Util$typesAreEqual$ALType$ALType$(funcDef.getArgumentTypes$(), argTypes)) { + overrides.push(funcDef); + return false; } return true; - })); - propertyExprs = []; - expectedArgIndex = 0; - statements = funcDef.getStatements$(); - if (statements.length !== propertyNames.length) { - return null; } - for (statementIndex = 0; statementIndex < statements.length; ++statementIndex) { - if (! (statements[statementIndex] instanceof ExpressionStatement)) { - return null; + classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$(addOverride); + implementClassDefs = classDef.implementTypes$().map((function (type) { + return type.getClassDef$(); + })); + for (i = 0; i < implementClassDefs.length; ++i) { + if (srcClassDef != implementClassDefs[i]) { + implementClassDefs[i].forEachClassToBase$F$LClassDefinition$B$((function (classDef) { + return classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$(addOverride); + })); } - statementExpr = statements[statementIndex].getExpr$(); - if (! (statementExpr instanceof AssignmentExpression)) { - return null; - } - lhsExpr = statementExpr.getFirstExpr$(); - if (! (lhsExpr instanceof PropertyExpression && lhsExpr.getExpr$() instanceof ThisExpression)) { - return null; - } - function onRHSExpr(expr) { - var argIndex; - if (_Util$0$exprIsAssignment$LExpression$(expr)) { - return false; - } else if (expr instanceof FunctionExpression) { - return false; - } else if (expr instanceof ThisExpression) { - return false; - } else if (expr instanceof LocalExpression) { - argIndex = funcDef.getArguments$().map((function (i) { - return i; - })).indexOf(expr.getLocal$()); - if (argIndex === - 1) { - throw new Error("logic flaw; could not find argument: " + expr.getLocal$().getName$().getValue$()); - } - if (expectedArgIndex !== argIndex) { - return false; - } - ++expectedArgIndex; - } - return expr.forEachExpression$F$LExpression$B$(onRHSExpr); - } - if (! onRHSExpr(statementExpr.getSecondExpr$())) { - return null; - } - propertyIndex = propertyNames.indexOf(lhsExpr.getIdentifierToken$().getValue$()); - if (propertyIndex === - 1) { - throw new Error("logic flaw; could not find property: " + lhsExpr.getIdentifierToken$().getValue$()); - } - if (propertyExprs[propertyIndex]) { - return null; - } - for (i = propertyIndex + 1; i < propertyNames.length; ++i) { - if (propertyExprs[i] != null && _Util$0$exprHasSideEffects$LExpression$(propertyExprs[i])) { - return null; - } - } - propertyExprs[propertyIndex] = statementExpr.getSecondExpr$().clone$(); } - return (function (newExpr) { - return propertyExprs.map((function (expr) { - var onExpr; - function onExpr(expr, replaceCb) { - var args; - var argIndex; - var i; - if (expr instanceof LocalExpression) { - (args = funcDef.getArguments$(), argIndex = - 1); - for (i in args) { i |= 0; - if (args[i] == expr.getLocal$()) { - argIndex = i; - break; - } - } - if (argIndex === - 1) { - throw new Error("logic flaw"); - } - replaceCb(newExpr.getArguments$()[argIndex]); - return true; - } - return expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); - } - expr = expr.clone$(); - onExpr(expr, (function (newExpr) { - expr = newExpr; - })); - return expr; - })); - }); + return overrides; }; -_UnclassifyOptimizationCommand.prototype._rewriteFunctionAsStatic$LMemberFunctionDefinition$ = function (funcDef) { - var $this = this; - var thisArg; - thisArg = new ArgumentDeclaration(new Token$2("$this", false), new ObjectType(funcDef.getClassDef$())); - funcDef.getArguments$().unshift(thisArg); - funcDef.forEachStatement$F$LStatement$B$((function onStatement(statement) { - if (statement instanceof FunctionStatement) { - statement.getFuncDef$().forEachStatement$F$LStatement$B$(onStatement); - } - return statement.forEachExpression$F$LExpression$F$LExpression$V$B$((function onExpr(expr, replaceCb) { - if (expr instanceof ThisExpression) { - replaceCb(new LocalExpression(thisArg.getName$(), thisArg)); - } else if (expr instanceof FunctionExpression) { - return expr.getFuncDef$().forEachStatement$F$LStatement$B$(onStatement); - } - return expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); - })) && statement.forEachStatement$F$LStatement$B$(onStatement); - })); - funcDef.setFlags$N(funcDef.flags$() | ClassDefinition.IS_STATIC); +function _StructuredStashAccessor$x2E$x3C_Stash$x3E() { }; +$__jsx_extend([_StructuredStashAccessor$x2E$x3C_Stash$x3E], Object); +_StructuredStashAccessor$x2E$x3C_Stash$x3E.prototype.$__jsx_implements__StructuredStashAccessor$x2E$x3C_Stash$x3E = true; -_UnclassifyOptimizationCommand.prototype._rewriteMethodCallsToStatic$LExpression$F$LExpression$V$ALClassDefinition$ = function (expr, replaceCb, unclassifyingClassDefs) { - var $this = this; - var onExpr; - onExpr = (function (expr, replaceCb) { - var calleeExpr; - var propertyExpr; - var receiverType; - var receiverClassDef; - var funcType; - if (expr instanceof CallExpression) { - calleeExpr = expr.getExpr$(); - if (calleeExpr instanceof PropertyExpression && ! calleeExpr.getExpr$().isClassSpecifier$() && ! calleeExpr.getType$().isAssignable$() && ! (calleeExpr.getIdentifierToken$().getValue$() === "toString" && expr.getArguments$().length === 0)) { - propertyExpr = calleeExpr; - receiverType = propertyExpr.getExpr$().getType$().resolveIfNullable$(); - receiverClassDef = receiverType.getClassDef$(); - if (unclassifyingClassDefs.indexOf(receiverClassDef) !== - 1) { - onExpr(propertyExpr.getExpr$(), (function (expr) { - propertyExpr.setExpr$LExpression$(expr); - })); - Util$forEachExpression$F$LExpression$F$LExpression$V$B$ALExpression$(onExpr, expr.getArguments$()); - funcType = propertyExpr.getType$(); - replaceCb(new CallExpression(expr.getToken$(), new PropertyExpression$0(propertyExpr.getToken$(), new ClassExpression(new Token$2(receiverClassDef.className$(), true), receiverType), propertyExpr.getIdentifierToken$(), propertyExpr.getTypeArguments$(), new StaticFunctionType(null, funcType.getReturnType$(), [ receiverType ].concat(funcType.getArgumentTypes$()), false)), [ propertyExpr.getExpr$() ].concat(expr.getArguments$()))); - return true; - } - } - } - return expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); - }); - onExpr(expr, replaceCb); +_StructuredStashAccessor$x2E$x3C_Stash$x3E.prototype.getStash$LStashable$ = function (stashable) { + var identifier; + var stash; + identifier = this._identifier; + stash = stashable.getStash$S(identifier); + if (stash == null) { + stash = new _StripOptimizeCommand$x2E_Stash(); + stashable.setStash$SLStash$(identifier, stash); + } + return stash; }; -function _FoldConstantCommand() { - _FunctionOptimizeCommand.call(this, _FoldConstantCommand.IDENTIFIER); +_StructuredStashAccessor$x2E$x3C_Stash$x3E.prototype.resetStash$LStashable$ = function (stashable) { + var identifier; + identifier = this._identifier; + stashable.setStash$SLStash$(identifier, null); }; -$__jsx_extend([_FoldConstantCommand], _FunctionOptimizeCommand); -_FoldConstantCommand.prototype._createStash$ = function () { - return new _FoldConstantCommand$x2EStash(); + +function _StripOptimizeCommand() { + _OptimizeCommand.call(this, _StripOptimizeCommand.IDENTIFIER); + _StructuredStashAccessor$x2E$x3C_Stash$x3E.call(this); + this._classesInstantiated = []; + this._methodsAlive = {}; + this._membersToWalk = []; }; +$__jsx_extend([_StripOptimizeCommand], _OptimizeCommand); +$__jsx_merge_interface(_StripOptimizeCommand, _StructuredStashAccessor$x2E$x3C_Stash$x3E); -_FoldConstantCommand.prototype.optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { +_StripOptimizeCommand.prototype._touchStatic$LMemberDefinition$ = function (member) { + var stash; + stash = this.getStash$LStashable$(member); + if (stash.touched) { + return; + } + this.log$S("touched " + member.getNotation$()); + stash.touched = true; + this._membersToWalk.push(member); +}; + + +_StripOptimizeCommand.prototype._touchInstance$LClassDefinition$ = function (classDef) { var $this = this; - funcDef.forEachStatement$F$LStatement$B$((function onStatement(statement) { - statement.forEachStatement$F$LStatement$B$(onStatement); - statement.forEachExpression$F$LExpression$F$LExpression$V$B$((function (expr, replaceCb) { - return $this._optimizeExpression$LExpression$F$LExpression$V$(expr, replaceCb); - })); + var stash; + var name; + var listOfArgTypes; + var i; + var funcDef; + stash = this.getStash$LStashable$(classDef); + if (stash.touched) { + return; + } + this.log$S("touched " + classDef.className$()); + stash.touched = true; + this._classesInstantiated.push(classDef); + for (name in this._methodsAlive) { + listOfArgTypes = this._methodsAlive[name]; + for (i = 0; i !== listOfArgTypes.length; ++i) { + funcDef = Util$findFunctionInClass$LClassDefinition$SALType$B(classDef, name, listOfArgTypes[i], false); + if (funcDef != null) { + this._membersToWalk.push(funcDef); + } + } + } + classDef.forEachMemberVariable$F$LMemberVariableDefinition$B$((function (varDef) { + if ((varDef.flags$() & ClassDefinition.IS_STATIC) === 0) { + $this._membersToWalk.push(varDef); + } return true; })); - return true; + if (classDef.extendType$() != null) { + this._touchInstance$LClassDefinition$(classDef.extendType$().getClassDef$()); + } + classDef.implementTypes$().forEach((function (implementType) { + $this._touchInstance$LClassDefinition$(implementType.getClassDef$()); + })); + if (classDef.getOuterClassDef$() != null) { + this._touchInstance$LClassDefinition$(classDef.getOuterClassDef$()); + } }; -_FoldConstantCommand.prototype._optimizeExpression$LExpression$F$LExpression$V$ = function (expr, replaceCb) { +_StripOptimizeCommand.prototype._touchConstructor$LMemberFunctionDefinition$ = function (funcDef) { + var stash; + stash = this.getStash$LStashable$(funcDef); + if (stash.touched) { + return; + } + this.log$S("touched " + funcDef.getNotation$()); + stash.touched = true; + this._membersToWalk.push(funcDef); + this._touchInstance$LClassDefinition$(funcDef.getClassDef$()); +}; + + +_StripOptimizeCommand.prototype._touchMethod$SALType$ = function (name, argTypes) { + var listOfArgTypes; + var i; + var funcDef; + if ($__jsx_ObjectHasOwnProperty.call(this._methodsAlive, name)) { + listOfArgTypes = this._methodsAlive[name]; + } else { + listOfArgTypes = this._methodsAlive[name] = []; + } + for (i = 0; i < listOfArgTypes.length; ++i) { + if (Util$typesAreEqual$ALType$ALType$(listOfArgTypes[i], argTypes)) { + return; + } + } + this.log$S("touched #" + name); + listOfArgTypes.push(argTypes.concat()); + for (i = 0; i < this._classesInstantiated.length; ++i) { + funcDef = Util$findFunctionInClass$LClassDefinition$SALType$B(this._classesInstantiated[i], name, argTypes, false); + if (funcDef != null) { + this._membersToWalk.push(funcDef); + } + } +}; + + +_StripOptimizeCommand.prototype.performOptimization$ = function () { var $this = this; - var propertyExpr; - var holderType; + var isEmittedClass; var member; - var foldedExpr; - var calculateCb; - var baseExpr; - var firstExpr; - var secondExpr; - var innerExpr; - var condition; - var op; - var conditionalExpr; - var condExpr; - var ifTrueExpr; - var ifFalseExpr; - var callExpr; - var allArgsAreConstants; - expr.forEachExpression$F$LExpression$F$LExpression$V$B$((function (expr, replaceCb) { - return $this._optimizeExpression$LExpression$F$LExpression$V$(expr, replaceCb); - })); - if (expr instanceof PropertyExpression) { - propertyExpr = expr; - holderType = propertyExpr.getHolderType$(); - if (propertyExpr.getExpr$().isClassSpecifier$()) { - member = null; - holderType.getClassDef$().forEachMemberVariable$F$LMemberVariableDefinition$B$((function (m) { - if (m.name$() === propertyExpr.getIdentifierToken$().getValue$()) { - member = m; - } - return member == null; - })); - if (member != null && (member.flags$() & ClassDefinition.IS_CONST) !== 0) { - this._foldStaticConst$LMemberVariableDefinition$(member); - foldedExpr = this._toFoldedExpr$LExpression$LType$(member.getInitialValue$(), member.getType$()); - if (foldedExpr != null) { - foldedExpr = this._toFoldedExpr$LExpression$LType$(foldedExpr, propertyExpr.getType$()); - if (foldedExpr != null && ! (foldedExpr instanceof StringLiteralExpression && foldedExpr.getDecoded$().length > _FoldConstantCommand.LONG_STRING_LITERAL)) { - this.log$S("folding property " + member.getNotation$() + " at " + propertyExpr.getToken$().getFilename$() + ":" + (propertyExpr.getToken$().getLineNumber$() + "")); - replaceCb(foldedExpr); - } - } - } - } else if (propertyExpr.getExpr$() instanceof StringLiteralExpression) { - if (propertyExpr.getIdentifierToken$().getValue$() === "length") { - replaceCb(new NumberLiteralExpression(new Token$3(propertyExpr.getExpr$().getDecoded$().length + ""))); - } + var memberShouldPreserve; + function isEmittedClass(classDef) { + if (classDef instanceof TemplateClassDefinition) { + return false; } - } else if (expr instanceof SignExpression) { - switch (expr.getToken$().getValue$()) { - case "+": - calculateCb = (function (x) { - return + x; - }); - break; - case "-": - calculateCb = (function (x) { - return - x; - }); - break; - default: + if ((classDef.flags$() & ClassDefinition.IS_NATIVE) !== 0) { return false; } - baseExpr = expr.getExpr$(); - if (baseExpr instanceof IntegerLiteralExpression) { - this.log$S("folding operator (number) " + expr.getToken$().getNotation$()); - replaceCb(new IntegerLiteralExpression(new Token$3(calculateCb(_Util$0$decodeNumericLiteral$LExpression$(baseExpr)) + ""))); - } else if (baseExpr instanceof NumberLiteralExpression) { - this.log$S("folding operator (number) " + expr.getToken$().getNotation$()); - replaceCb(new NumberLiteralExpression(new Token$3(calculateCb(_Util$0$decodeNumericLiteral$LExpression$(baseExpr)) + ""))); + return true; + } + this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { + $this.resetStash$LStashable$(classDef); + return classDef.forEachMember$F$LMemberDefinition$B$((function (member) { + $this.resetStash$LStashable$(member); + return true; + })); + })); + this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { + if (! (classDef instanceof TemplateClassDefinition) && (classDef.flags$() & ClassDefinition.IS_NATIVE) !== 0) { + classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$((function (funcDef) { + if (funcDef.name$() === "constructor") { + } else if ((funcDef.flags$() & ClassDefinition.IS_FINAL) !== 0) { + } else { + $this._touchMethod$SALType$(funcDef.name$(), funcDef.getArgumentTypes$()); + } + return true; + })); } - } else if (expr instanceof BitwiseNotExpression) { - baseExpr = expr.getExpr$(); - if (this._isIntegerOrNumberLiteralExpression$LExpression$(baseExpr)) { - this.log$S("folding operator " + expr.getToken$().getNotation$()); - replaceCb(new IntegerLiteralExpression(new Token$3(~ _Util$0$decodeNumericLiteral$LExpression$(baseExpr) + ""))); + return true; + })); + this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { + if (isEmittedClass(classDef)) { + if ((classDef.flags$() & ClassDefinition.IS_EXPORT) !== 0) { + $this._touchInstance$LClassDefinition$(classDef); + } + classDef.forEachMember$F$LMemberDefinition$B$((function (member) { + var funcDef; + if ((member.flags$() & ClassDefinition.IS_EXPORT) !== 0) { + if ((member.flags$() & ClassDefinition.IS_STATIC) !== 0) { + $this._touchStatic$LMemberDefinition$(member); + } else if (member instanceof MemberFunctionDefinition) { + funcDef = member; + if (funcDef.name$() === "constructor") { + $this._touchConstructor$LMemberFunctionDefinition$(funcDef); + } else { + $this._touchMethod$SALType$(funcDef.name$(), funcDef.getArgumentTypes$()); + } + } + } + return true; + })); } - } else if (expr instanceof AdditiveExpression) { - firstExpr = expr.getFirstExpr$(); - secondExpr = expr.getSecondExpr$(); - if (this._foldNumericBinaryExpression$LBinaryExpression$F$LExpression$V$(expr, replaceCb)) { - } else if (firstExpr instanceof StringLiteralExpression && secondExpr instanceof StringLiteralExpression) { - replaceCb(new StringLiteralExpression(new Token$2(Util$encodeStringLiteral$S(firstExpr.getDecoded$() + secondExpr.getDecoded$()), false))); + return true; + })); + while (this._membersToWalk.length !== 0) { + member = this._membersToWalk.shift(); + this.log$S("walking " + member.getNotation$()); + if (member instanceof MemberFunctionDefinition) { + this._walkFunctionDefinition$LMemberFunctionDefinition$(member); + } else { + this._walkVariableDefinition$LMemberVariableDefinition$(member); } - } else if (expr instanceof EqualityExpression) { - this._foldEqualityExpression$LEqualityExpression$F$LExpression$V$(expr, replaceCb); - } else if (expr instanceof BinaryNumberExpression || expr instanceof ShiftExpression) { - this._foldNumericBinaryExpression$LBinaryExpression$F$LExpression$V$(expr, replaceCb); - } else if (expr instanceof AsExpression) { - this._foldAsExpression$LAsExpression$F$LExpression$V$(expr, replaceCb); - } else if (expr instanceof LogicalNotExpression) { - innerExpr = expr.getExpr$(); - if ((condition = _Util$0$conditionIsConstant$LExpression$(innerExpr)) != null) { - replaceCb(new BooleanLiteralExpression(new Token$2((condition ? "false" : "true"), false))); + } + function memberShouldPreserve(member) { + var isTouched; + var listOfArgTypes; + var i; + if ((member.flags$() & ClassDefinition.IS_EXPORT) !== 0) { + return true; } - } else if (expr instanceof LogicalExpression) { - firstExpr = expr.getFirstExpr$(); - secondExpr = expr.getSecondExpr$(); - if ((condition = _Util$0$conditionIsConstant$LExpression$(firstExpr)) != null) { - op = expr.getToken$().getValue$(); - if (op === "||" && condition) { - replaceCb(new AsExpression(firstExpr.getToken$(), firstExpr, Type.booleanType)); - } else if (op === "||" && ! condition) { - replaceCb(new AsExpression(secondExpr.getToken$(), secondExpr, Type.booleanType)); - } else if (op === "&&" && condition) { - replaceCb(new AsExpression(secondExpr.getToken$(), secondExpr, Type.booleanType)); - } else if (op === "&&" && ! condition) { - replaceCb(new AsExpression(firstExpr.getToken$(), firstExpr, Type.booleanType)); + isTouched = $this.getStash$LStashable$(member).touched; + if ((member.flags$() & ClassDefinition.IS_STATIC) !== 0) { + return isTouched; + } else if (member instanceof MemberFunctionDefinition) { + if (member.name$() === "constructor") { + return isTouched; } else { - throw new Error("logic flaw"); + if ($this.getStash$LStashable$(member.getClassDef$()).touched && $__jsx_ObjectHasOwnProperty.call($this._methodsAlive, member.name$())) { + listOfArgTypes = $this._methodsAlive[member.name$()]; + for (i = 0; i !== listOfArgTypes.length; ++i) { + if (Util$typesAreEqual$ALType$ALType$(listOfArgTypes[i], member.getArgumentTypes$())) { + return true; + } + } + } + return false; } } - } else if (expr instanceof ConditionalExpression) { - conditionalExpr = expr; - condExpr = conditionalExpr.getCondExpr$(); - if ((condition = _Util$0$conditionIsConstant$LExpression$(condExpr)) != null) { - ifTrueExpr = conditionalExpr.getIfTrueExpr$() || condExpr; - ifFalseExpr = conditionalExpr.getIfFalseExpr$(); - replaceCb(condition ? ifTrueExpr : ifFalseExpr); + return true; + } + this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { + var numConstructors; + var members; + var memberIndex; + var member; + var ctor; + if (isEmittedClass(classDef)) { + numConstructors = 0; + members = classDef.members$(); + for (memberIndex = 0; memberIndex !== members.length; ) { + member = members[memberIndex]; + if (memberShouldPreserve(member)) { + if (member instanceof MemberFunctionDefinition && (member.flags$() & ClassDefinition.IS_STATIC) === 0 && member.name$() === "constructor") { + ++numConstructors; + } + ++memberIndex; + $this.log$S("preserving used: " + member.getNotation$()); + } else { + $this.log$S("removing unused: " + member.getNotation$()); + members.splice(memberIndex, 1); + } + } + if (numConstructors === 0) { + $this.log$S("substituting fake constructor for class: " + classDef.className$()); + ctor = new MemberFunctionDefinition(null, new Token$2("constructor", true), ClassDefinition.IS_FINAL | classDef.flags$() & ClassDefinition.IS_EXPORT, Type.voidType, [], [], [], [], classDef.getToken$(), null); + ctor.setClassDef$LClassDefinition$(classDef); + members.push(ctor); + } } - } else if (expr instanceof CallExpression) { - callExpr = expr; - if (callExpr.getExpr$() instanceof PropertyExpression) { - allArgsAreConstants = true; - callExpr.getArguments$().forEach((function (expr) { - if (! (expr instanceof IntegerLiteralExpression || expr instanceof NumberLiteralExpression || expr instanceof BooleanLiteralExpression || expr instanceof StringLiteralExpression)) { - allArgsAreConstants = false; + return true; + })); + this.getCompiler$().getParsers$().forEach((function (parser) { + var classDefs; + var i; + var preserve; + classDefs = parser.getClassDefs$(); + for (i = 0; i !== classDefs.length; ) { + preserve = true; + if ((classDefs[i].flags$() & ClassDefinition.IS_NATIVE) !== 0 && classDefs[i].getNativeSource$() != null && ! $this.getStash$LStashable$(classDefs[i]).touched && classDefs[i].forEachMember$F$LMemberDefinition$B$((function (member) { + if ((member.flags$() & ClassDefinition.IS_STATIC) === 0) { + return true; } - })); - if (allArgsAreConstants) { - this._foldCallExpression$LCallExpression$F$LExpression$V$(callExpr, replaceCb); + return ! $this.getStash$LStashable$(member).touched; + }))) { + preserve = false; + } + if (preserve) { + ++i; + } else { + $this.log$S("removing unused native class: " + classDefs[i].className$()); + classDefs.splice(i, 1); } } - } - return true; + })); }; -_FoldConstantCommand.prototype._foldCallExpression$LCallExpression$F$LExpression$V$ = function (callExpr, replaceCb) { +_StripOptimizeCommand.prototype._walkExpression$LExpression$ = function (expr) { var $this = this; - var propertyExpr; - var holderType; - var argExprs; - var member; - var s; - var recvStr; - propertyExpr = callExpr.getExpr$(); - holderType = propertyExpr.getHolderType$(); - if ((holderType.getClassDef$().flags$() & ClassDefinition.IS_NATIVE) === 0) { - return; - } - argExprs = callExpr.getArguments$(); - member = null; - holderType.getClassDef$().forEachMemberFunction$F$LMemberFunctionDefinition$B$((function (m) { - if (m.name$() === propertyExpr.getIdentifierToken$().getValue$()) { - member = m; - } - return member == null; - })); - if (member != null && (member.flags$() & ClassDefinition.IS_PURE) === 0) { - return; - } - if (propertyExpr.getExpr$().isClassSpecifier$()) { - if (holderType.getClassDef$().classFullName$() === "Math") { - switch (propertyExpr.getIdentifierToken$().getValue$()) { - case "sqrt": - this.log$S("folding " + member.getNotation$()); - replaceCb(new NumberLiteralExpression(new Token$3(Math.sqrt(_Util$0$decodeNumericLiteral$LExpression$(argExprs[0])) + ""))); - break; - case "log": - this.log$S("folding " + member.getNotation$()); - replaceCb(new NumberLiteralExpression(new Token$3(Math.log(_Util$0$decodeNumericLiteral$LExpression$(argExprs[0])) + ""))); - break; - case "pow": - this.log$S("folding " + member.getNotation$()); - replaceCb(new NumberLiteralExpression(new Token$3(Math.pow(_Util$0$decodeNumericLiteral$LExpression$(argExprs[0]), _Util$0$decodeNumericLiteral$LExpression$(argExprs[1])) + ""))); - break; - case "sin": - this.log$S("folding " + member.getNotation$()); - replaceCb(new NumberLiteralExpression(new Token$3(Math.sin(_Util$0$decodeNumericLiteral$LExpression$(argExprs[0])) + ""))); - break; - case "cos": - this.log$S("folding " + member.getNotation$()); - replaceCb(new NumberLiteralExpression(new Token$3(Math.cos(_Util$0$decodeNumericLiteral$LExpression$(argExprs[0])) + ""))); - break; + var onExpr; + function onExpr(expr) { + var callee; + var propertyExpr; + var holderClassDef; + var name; + var member; + var superExpr; + if (expr instanceof NewExpression) { + callee = Util$findFunctionInClass$LClassDefinition$SALType$B(expr.getType$().getClassDef$(), "constructor", expr.getConstructor$().getArgumentTypes$(), false); + $this._touchConstructor$LMemberFunctionDefinition$(callee); + } else if (expr instanceof InstanceofExpression) { + $this._touchInstance$LClassDefinition$(expr.getExpectedType$().getClassDef$()); + } else if (expr instanceof AsExpression) { + if (expr.getType$() instanceof ObjectType) { + $this._touchInstance$LClassDefinition$(expr.getType$().getClassDef$()); } - } - if (holderType.getClassDef$().classFullName$() === "String") { - switch (propertyExpr.getIdentifierToken$().getValue$()) { - case "fromCharCode": - this.log$S("folding " + member.getNotation$()); - s = ""; - argExprs.forEach((function (arg) { - s += String.fromCharCode(_Util$0$decodeNumericLiteral$LExpression$(arg)); - })); - replaceCb(new StringLiteralExpression(new Token$3(Util$encodeStringLiteral$S(s)))); - break; + } else if (expr instanceof AsNoConvertExpression) { + if (expr.getType$() instanceof ObjectType) { + $this._touchInstance$LClassDefinition$(expr.getType$().getClassDef$()); } + } else if (expr instanceof PropertyExpression) { + propertyExpr = expr; + holderClassDef = propertyExpr.getHolderType$().getClassDef$(); + if (propertyExpr.isClassSpecifier$()) { + if ((holderClassDef.flags$() & ClassDefinition.IS_NATIVE) !== 0) { + $this._touchInstance$LClassDefinition$(holderClassDef); + } + } else { + name = propertyExpr.getIdentifierToken$().getValue$(); + if (propertyExpr.getExpr$().isClassSpecifier$()) { + if (Util$isReferringToFunctionDefinition$LPropertyExpression$(propertyExpr)) { + member = Util$findFunctionInClass$LClassDefinition$SALType$B(holderClassDef, name, expr.getType$().getArgumentTypes$(), true); + } else { + member = Util$findVariableInClass$LClassDefinition$SB(holderClassDef, name, true); + } + $this._touchStatic$LMemberDefinition$(member); + } else if (Util$isReferringToFunctionDefinition$LPropertyExpression$(propertyExpr)) { + $this._touchMethod$SALType$(name, expr.getType$().getArgumentTypes$()); + } + } + } else if (expr instanceof SuperExpression) { + superExpr = expr; + $this._touchMethod$SALType$(superExpr.getName$().getValue$(), superExpr.getFunctionType$().getArgumentTypes$()); } - } else if (propertyExpr.getExpr$() instanceof StringLiteralExpression) { - switch (propertyExpr.getIdentifierToken$().getValue$()) { - case "charCodeAt": - this.log$S("folding " + member.getNotation$()); - recvStr = propertyExpr.getExpr$().getDecoded$(); - replaceCb(new NumberLiteralExpression(new Token$3(recvStr.charCodeAt(_Util$0$decodeNumericLiteral$LExpression$(argExprs[0])) + ""))); - break; - } + return expr.forEachExpression$F$LExpression$B$(onExpr); } + return onExpr(expr); }; -_FoldConstantCommand.prototype._foldEqualityExpression$LEqualityExpression$F$LExpression$V$ = function (expr, replaceCb) { +_StripOptimizeCommand.prototype._walkStatement$LStatement$ = function (statement) { var $this = this; - var firstExpr; - var secondExpr; - var isEqual; - var isNullVsPrimitiveLiteral; - var result; - firstExpr = expr.getFirstExpr$(); - secondExpr = expr.getSecondExpr$(); - isEqual = null; - function isNullVsPrimitiveLiteral(x, y) { - return x instanceof NullExpression && y instanceof PrimitiveLiteralExpression; - } - if (firstExpr instanceof NullExpression && secondExpr instanceof NullExpression) { - isEqual = true; - } else if (isNullVsPrimitiveLiteral(firstExpr, secondExpr) || isNullVsPrimitiveLiteral(secondExpr, firstExpr)) { - isEqual = false; - } else if (firstExpr instanceof StringLiteralExpression && secondExpr instanceof StringLiteralExpression) { - isEqual = firstExpr.getDecoded$() === secondExpr.getDecoded$(); - } else if (this._isIntegerOrNumberLiteralExpression$LExpression$(firstExpr) && this._isIntegerOrNumberLiteralExpression$LExpression$(secondExpr)) { - isEqual = _Util$0$decodeNumericLiteral$LExpression$(firstExpr) === _Util$0$decodeNumericLiteral$LExpression$(secondExpr); - } - if (isEqual != null) { - result = (expr.getToken$().getValue$() === "==" ? isEqual : ! isEqual); - replaceCb(new BooleanLiteralExpression(new Token$2((result ? "true" : "false"), true))); + var onStatement; + function onStatement(statement) { + var ctorStatement; + var callee; + if (statement instanceof ConstructorInvocationStatement) { + ctorStatement = statement; + callee = Util$findFunctionInClass$LClassDefinition$SALType$B(ctorStatement.getConstructingClassDef$(), "constructor", ctorStatement.getConstructorType$().getArgumentTypes$(), false); + $this._touchConstructor$LMemberFunctionDefinition$(callee); + } + statement.forEachExpression$F$LExpression$B$((function (expr) { + return $this._walkExpression$LExpression$(expr); + })); + return statement.forEachStatement$F$LStatement$B$(onStatement); } + return onStatement(statement); }; -_FoldConstantCommand.prototype._foldNumericBinaryExpression$LBinaryExpression$F$LExpression$V$ = function (expr, replaceCb) { +_StripOptimizeCommand.prototype._walkFunctionDefinition$LMemberFunctionDefinition$ = function (funcDef) { var $this = this; - var exprIsZero; - var exprIsOne; - if (this._isIntegerOrNumberLiteralExpression$LExpression$(expr.getFirstExpr$()) && this._isIntegerOrNumberLiteralExpression$LExpression$(expr.getSecondExpr$())) { - return this._foldNumericBinaryExpressionOfConstants$LBinaryExpression$F$LExpression$V$(expr, replaceCb); - } - function exprIsZero(expr) { - return expr instanceof NumberLiteralExpression && expr.getDecoded$() === 0; + if (funcDef.getStatements$() != null) { + funcDef.forEachStatement$F$LStatement$B$((function onStatement(statement) { + return $this._walkStatement$LStatement$(statement); + })); } - function exprIsOne(expr) { - return expr instanceof NumberLiteralExpression && expr.getDecoded$() === 1; + return funcDef.forEachClosure$F$LMemberFunctionDefinition$B$((function (funcDef) { + return $this._walkFunctionDefinition$LMemberFunctionDefinition$(funcDef); + })); +}; + + +_StripOptimizeCommand.prototype._walkVariableDefinition$LMemberVariableDefinition$ = function (varDef) { + var $this = this; + var initialValue; + initialValue = varDef.getInitialValue$(); + if (initialValue != null) { + this._walkExpression$LExpression$(initialValue); } - switch (expr.getToken$().getValue$()) { - case "+": - if (exprIsZero(expr.getFirstExpr$())) { - replaceCb(expr.getSecondExpr$()); - return true; - } else if (exprIsZero(expr.getSecondExpr$())) { - replaceCb(expr.getFirstExpr$()); - return true; - } - break; - case "-": - if (exprIsZero(expr.getFirstExpr$())) { - replaceCb(new SignExpression(new Token$2("-", false), expr.getSecondExpr$())); - return true; - } else if (exprIsZero(expr.getSecondExpr$())) { - replaceCb(expr.getFirstExpr$()); - return true; - } - break; - case "*": - if (exprIsOne(expr.getFirstExpr$())) { - replaceCb(expr.getSecondExpr$()); - return true; - } else if (exprIsOne(expr.getSecondExpr$())) { - replaceCb(expr.getFirstExpr$()); - return true; - } - break; - case "/": - if (exprIsOne(expr.getSecondExpr$())) { - replaceCb(expr.getFirstExpr$()); - return true; - } - break; + return varDef.forEachClosure$F$LMemberFunctionDefinition$B$((function (funcDef) { + return $this._walkFunctionDefinition$LMemberFunctionDefinition$(funcDef); + })); +}; + + +function _StructuredStashAccessor$x2E$x3CStash$x3E$0() { +}; + +$__jsx_extend([_StructuredStashAccessor$x2E$x3CStash$x3E$0], Object); +_StructuredStashAccessor$x2E$x3CStash$x3E$0.prototype.$__jsx_implements__StructuredStashAccessor$x2E$x3CStash$x3E$0 = true; + +_StructuredStashAccessor$x2E$x3CStash$x3E$0.prototype.getStash$LStashable$ = function (stashable) { + var identifier; + var stash; + identifier = this._identifier; + stash = stashable.getStash$S(identifier); + if (stash == null) { + stash = new _DetermineCalleeCommand$x2EStash(); + stashable.setStash$SLStash$(identifier, stash); } - return false; + return stash; }; -_FoldConstantCommand.prototype._foldNumericBinaryExpressionOfConstants$LBinaryExpression$F$LExpression$V$ = function (expr, replaceCb) { +_StructuredStashAccessor$x2E$x3CStash$x3E$0.prototype.resetStash$LStashable$ = function (stashable) { + var identifier; + identifier = this._identifier; + stashable.setStash$SLStash$(identifier, null); +}; + + +function _DetermineCalleeCommand() { + _FunctionOptimizeCommand.call(this, _DetermineCalleeCommand.IDENTIFIER); + _StructuredStashAccessor$x2E$x3CStash$x3E$0.call(this); +}; + +$__jsx_extend([_DetermineCalleeCommand], _FunctionOptimizeCommand); +$__jsx_merge_interface(_DetermineCalleeCommand, _StructuredStashAccessor$x2E$x3CStash$x3E$0); + +_DetermineCalleeCommand.prototype.optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { var $this = this; - switch (expr.getToken$().getValue$()) { - case "+": - this._foldNumericBinaryExpressionAsNumeric$LBinaryExpression$F$LExpression$V$F$III$F$NNN$(expr, replaceCb, (function (x, y) { - return ((x + y) | 0); - }), (function (x, y) { - return x + y; - })); - break; - case "-": - this._foldNumericBinaryExpressionAsNumeric$LBinaryExpression$F$LExpression$V$F$III$F$NNN$(expr, replaceCb, (function (x, y) { - return ((x - y) | 0); - }), (function (x, y) { - return x - y; - })); - break; - case "*": - this._foldNumericBinaryExpressionAsNumeric$LBinaryExpression$F$LExpression$V$F$III$F$NNN$(expr, replaceCb, (function (x, y) { - return $__jsx_imul(x, y); - }), (function (x, y) { - return x * y; - })); - break; - case "/": - this._foldNumericBinaryExpressionAsNumber$LBinaryExpression$F$LExpression$V$F$NNN$(expr, replaceCb, (function (x, y) { - return x / y; - })); - break; - case "%": - this._foldNumericBinaryExpressionAsNumber$LBinaryExpression$F$LExpression$V$F$NNN$(expr, replaceCb, (function (x, y) { - return x % y; - })); - break; - case ">>>": - this._foldNumericBinaryExpressionAsInteger$LBinaryExpression$F$LExpression$V$F$III$(expr, replaceCb, (function (x, y) { - return x >>> y; - })); - break; - case ">>": - this._foldNumericBinaryExpressionAsInteger$LBinaryExpression$F$LExpression$V$F$III$(expr, replaceCb, (function (x, y) { - return x >> y; - })); - break; - case "<<": - this._foldNumericBinaryExpressionAsInteger$LBinaryExpression$F$LExpression$V$F$III$(expr, replaceCb, (function (x, y) { - return x << y; - })); - break; - case "&": - this._foldNumericBinaryExpressionAsInteger$LBinaryExpression$F$LExpression$V$F$III$(expr, replaceCb, (function (x, y) { - return x & y; - })); - break; - case "|": - this._foldNumericBinaryExpressionAsInteger$LBinaryExpression$F$LExpression$V$F$III$(expr, replaceCb, (function (x, y) { - return x | y; - })); - break; - case "^": - this._foldNumericBinaryExpressionAsInteger$LBinaryExpression$F$LExpression$V$F$III$(expr, replaceCb, (function (x, y) { - return x ^ y; - })); - break; - case "<": - this._foldNumericBinaryExpressionAsBoolean$LBinaryExpression$F$LExpression$V$F$NNB$(expr, replaceCb, (function (x, y) { - return x < y; - })); - break; - case "<=": - this._foldNumericBinaryExpressionAsBoolean$LBinaryExpression$F$LExpression$V$F$NNB$(expr, replaceCb, (function (x, y) { - return x <= y; - })); - break; - case ">": - this._foldNumericBinaryExpressionAsBoolean$LBinaryExpression$F$LExpression$V$F$NNB$(expr, replaceCb, (function (x, y) { - return x > y; - })); - break; - case ">=": - this._foldNumericBinaryExpressionAsBoolean$LBinaryExpression$F$LExpression$V$F$NNB$(expr, replaceCb, (function (x, y) { - return x >= y; + funcDef.forEachStatement$F$LStatement$B$((function onStatement(statement) { + var callingFuncDef; + if (statement instanceof ConstructorInvocationStatement) { + callingFuncDef = _DetermineCalleeCommand$findCallingFunctionInClass$LClassDefinition$SALType$B(statement.getConstructingClassDef$(), "constructor", statement.getConstructorType$().getArgumentTypes$(), false); + if (callingFuncDef == null) { + throw new Error("could not determine the associated parent ctor"); + } + $this._setCallingFuncDef$LStashable$LMemberFunctionDefinition$(statement, callingFuncDef); + } else if (statement instanceof FunctionStatement) { + statement.getFuncDef$().forEachStatement$F$LStatement$B$(onStatement); + } + statement.forEachExpression$F$LExpression$B$((function onExpr(expr) { + var calleeExpr; + var propertyExpr; + var holderType; + var callingFuncDef; + var newExpr; + if (expr instanceof CallExpression) { + calleeExpr = expr.getExpr$(); + if (calleeExpr instanceof PropertyExpression && ! calleeExpr.getType$().isAssignable$()) { + propertyExpr = calleeExpr; + holderType = propertyExpr.getHolderType$(); + callingFuncDef = _DetermineCalleeCommand$findCallingFunction$LClassDefinition$SALType$B(holderType.getClassDef$(), propertyExpr.getIdentifierToken$().getValue$(), propertyExpr.getType$().getArgumentTypes$(), propertyExpr.getExpr$().isClassSpecifier$()); + $this._setCallingFuncDef$LStashable$LMemberFunctionDefinition$(expr, callingFuncDef); + } else if (calleeExpr instanceof FunctionExpression) { + $this._setCallingFuncDef$LStashable$LMemberFunctionDefinition$(expr, calleeExpr.getFuncDef$()); + } else { + $this._setCallingFuncDef$LStashable$LMemberFunctionDefinition$(expr, null); + } + } else if (expr instanceof NewExpression) { + newExpr = expr; + if (! (newExpr.getType$().getClassDef$() != null)) { + debugger; + throw new Error("[src/optimizer.jsx:1039:59] assertion failure\n assert newExpr.getType().getClassDef() != null;\n ^^\n"); + } + if (! (newExpr.getConstructor$() != null)) { + debugger; + throw new Error("[src/optimizer.jsx:1040:52] assertion failure\n assert newExpr.getConstructor() != null;\n ^^\n"); + } + callingFuncDef = _DetermineCalleeCommand$findCallingFunctionInClass$LClassDefinition$SALType$B(newExpr.getType$().getClassDef$(), "constructor", newExpr.getConstructor$().getArgumentTypes$(), false); + if (callingFuncDef == null) { + throw new Error("could not find matching constructor for " + newExpr.getConstructor$().toString()); + } + $this._setCallingFuncDef$LStashable$LMemberFunctionDefinition$(newExpr, callingFuncDef); + } + if (expr instanceof FunctionExpression) { + return expr.getFuncDef$().forEachStatement$F$LStatement$B$(onStatement); + } else { + return expr.forEachExpression$F$LExpression$B$(onExpr); + } })); - break; - default: - return false; - } + return statement.forEachStatement$F$LStatement$B$(onStatement); + })); return true; }; -_FoldConstantCommand.prototype._foldNumericBinaryExpressionAsNumeric$LBinaryExpression$F$LExpression$V$F$III$F$NNN$ = function (expr, replaceCb, calcCbInt, calcCbNumber) { - if (expr.getFirstExpr$() instanceof IntegerLiteralExpression && expr.getSecondExpr$() instanceof IntegerLiteralExpression) { - this._foldNumericBinaryExpressionAsInteger$LBinaryExpression$F$LExpression$V$F$III$(expr, replaceCb, calcCbInt); - } else { - this._foldNumericBinaryExpressionAsNumber$LBinaryExpression$F$LExpression$V$F$NNN$(expr, replaceCb, calcCbNumber); - } +_DetermineCalleeCommand.prototype._setCallingFuncDef$LStashable$LMemberFunctionDefinition$ = function (stashable, funcDef) { + this.getStash$LStashable$(stashable).callingFuncDef = funcDef; }; -_FoldConstantCommand.prototype._foldNumericBinaryExpressionAsInteger$LBinaryExpression$F$LExpression$V$F$III$ = function (expr, replaceCb, calcCb) { - var value; - value = calcCb((_Util$0$decodeNumericLiteral$LExpression$(expr.getFirstExpr$()) | 0), (_Util$0$decodeNumericLiteral$LExpression$(expr.getSecondExpr$()) | 0)); - this.log$S("folding operator " + expr.getToken$().getNotation$() + " to int: " + (value + "")); - if (value !== (value | 0)) { - throw new Error("value is not an integer"); +function _DetermineCalleeCommand$findCallingFunctionInClass$LClassDefinition$SALType$B(classDef, funcName, argTypes, isStatic) { + var found; + found = Util$findFunctionInClass$LClassDefinition$SALType$B(classDef, funcName, argTypes, isStatic); + if (found != null) { + if ((found.flags$() & (ClassDefinition.IS_STATIC | ClassDefinition.IS_FINAL)) === 0) { + found = null; + } } - replaceCb(new IntegerLiteralExpression(new Token$3(value + ""))); + return found; }; +_DetermineCalleeCommand.findCallingFunctionInClass$LClassDefinition$SALType$B = _DetermineCalleeCommand$findCallingFunctionInClass$LClassDefinition$SALType$B; -_FoldConstantCommand.prototype._foldNumericBinaryExpressionAsNumber$LBinaryExpression$F$LExpression$V$F$NNN$ = function (expr, replaceCb, calcCb) { - var value; - value = calcCb(_Util$0$decodeNumericLiteral$LExpression$(expr.getFirstExpr$()), _Util$0$decodeNumericLiteral$LExpression$(expr.getSecondExpr$())); - this.log$S("folding operator " + expr.getToken$().getNotation$() + " to number: " + (value + "")); - replaceCb(new NumberLiteralExpression(new Token$3(value + ""))); +function _DetermineCalleeCommand$findCallingFunction$LClassDefinition$SALType$B(classDef, funcName, argTypes, isStatic) { + var found; + found = null; + classDef.forEachClassToBase$F$LClassDefinition$B$((function (classDef) { + if ((found = _DetermineCalleeCommand$findCallingFunctionInClass$LClassDefinition$SALType$B(classDef, funcName, argTypes, isStatic)) != null) { + return false; + } + return true; + })); + return found; }; +_DetermineCalleeCommand.findCallingFunction$LClassDefinition$SALType$B = _DetermineCalleeCommand$findCallingFunction$LClassDefinition$SALType$B; -_FoldConstantCommand.prototype._foldNumericBinaryExpressionAsBoolean$LBinaryExpression$F$LExpression$V$F$NNB$ = function (expr, replaceCb, calcCb) { - var value; - value = calcCb(_Util$0$decodeNumericLiteral$LExpression$(expr.getFirstExpr$()), _Util$0$decodeNumericLiteral$LExpression$(expr.getSecondExpr$())); - this.log$S("folding operator " + expr.getToken$().getNotation$() + " to boolean: " + (value + "")); - replaceCb(new BooleanLiteralExpression(new Token$3(value + ""))); +function _DetermineCalleeCommand$getCallingFuncDef$LStashable$(stashable) { + var stash; + stash = stashable.getStash$S(_DetermineCalleeCommand.IDENTIFIER); + if (stash == null) { + throw new Error("callee not searched"); + } + return stash.callingFuncDef; }; +_DetermineCalleeCommand.getCallingFuncDef$LStashable$ = _DetermineCalleeCommand$getCallingFuncDef$LStashable$; -_FoldConstantCommand.prototype._isIntegerOrNumberLiteralExpression$LExpression$ = function (expr) { - return expr instanceof NumberLiteralExpression || expr instanceof IntegerLiteralExpression; +function _StructuredStashAccessor$x2E$x3CStash$x3E$1() { }; +$__jsx_extend([_StructuredStashAccessor$x2E$x3CStash$x3E$1], Object); +_StructuredStashAccessor$x2E$x3CStash$x3E$1.prototype.$__jsx_implements__StructuredStashAccessor$x2E$x3CStash$x3E$1 = true; -_FoldConstantCommand.prototype._foldStaticConst$LMemberVariableDefinition$ = function (member) { - var $this = this; +_StructuredStashAccessor$x2E$x3CStash$x3E$1.prototype.getStash$LStashable$ = function (stashable) { + var identifier; var stash; - var initialValue; - stash = this.getStash$LStashable$(member); - if (stash.isOptimized) { - return; - } - stash.isOptimized = true; - initialValue = member.getInitialValue$(); - if (initialValue != null) { - this._optimizeExpression$LExpression$F$LExpression$V$(initialValue, (function (expr) { - member.setInitialValue$LExpression$(expr); - })); + identifier = this._identifier; + stash = stashable.getStash$S(identifier); + if (stash == null) { + stash = new _StaticizeOptimizeCommand$x2EStash(); + stashable.setStash$SLStash$(identifier, stash); } + return stash; }; -_FoldConstantCommand.prototype._toFoldedExpr$LExpression$LType$ = function (expr, type) { - if (expr instanceof NullExpression) { - return expr; - } else if (expr instanceof BooleanLiteralExpression) { - return expr; - } else if (expr instanceof IntegerLiteralExpression) { - return expr; - } else if (expr instanceof NumberLiteralExpression) { - if (type.resolveIfNullable$().equals$LType$(Type.integerType)) { - return new IntegerLiteralExpression(new Token$3((expr.getDecoded$() | 0) + "")); - } - return expr; - } else if (expr instanceof StringLiteralExpression) { - return expr; - } - return null; +_StructuredStashAccessor$x2E$x3CStash$x3E$1.prototype.resetStash$LStashable$ = function (stashable) { + var identifier; + identifier = this._identifier; + stashable.setStash$SLStash$(identifier, null); }; -_FoldConstantCommand.prototype._foldAsExpression$LAsExpression$F$LExpression$V$ = function (expr, replaceCb) { - var baseExpr; - baseExpr = expr.getExpr$(); - if (expr.getType$().equals$LType$(Type.stringType)) { - if (baseExpr.getType$().equals$LType$(Type.stringType)) { - this.log$S("folding type cast: string as string"); - replaceCb(baseExpr); - } else if (baseExpr instanceof PrimitiveLiteralExpression) { - this.log$S("folding type cast: primitive literal as string"); - replaceCb(new StringLiteralExpression(new Token$2(Util$encodeStringLiteral$S(baseExpr.toNormalizedString$()), false))); +function _StaticizeOptimizeCommand() { + _OptimizeCommand.call(this, _StaticizeOptimizeCommand.IDENTIFIER); + _StructuredStashAccessor$x2E$x3CStash$x3E$1.call(this); +}; + +$__jsx_extend([_StaticizeOptimizeCommand], _OptimizeCommand); +$__jsx_merge_interface(_StaticizeOptimizeCommand, _StructuredStashAccessor$x2E$x3CStash$x3E$1); + +_StaticizeOptimizeCommand.prototype.performOptimization$ = function () { + var $this = this; + var memberCanBeStaticized; + function memberCanBeStaticized(funcDef) { + var onStatement; + if ((funcDef.flags$() & (ClassDefinition.IS_OVERRIDE | ClassDefinition.IS_ABSTRACT | ClassDefinition.IS_FINAL | ClassDefinition.IS_STATIC | ClassDefinition.IS_NATIVE)) !== ClassDefinition.IS_FINAL) { + return false; } - } else if (expr.getType$().equals$LType$(Type.numberType)) { - if (baseExpr.getType$().equals$LType$(Type.numberType)) { - this.log$S("folding type cast: number as number"); - replaceCb(baseExpr); - } else if (baseExpr instanceof StringLiteralExpression) { - this.log$S("folding type cast: string literal as number"); - replaceCb(new NumberLiteralExpression(new Token$2(+baseExpr.getDecoded$() + "", false))); - } else if (baseExpr instanceof IntegerLiteralExpression) { - this.log$S("folding type cast: int literal as number"); - replaceCb(new NumberLiteralExpression(new Token$2(+baseExpr.getDecoded$() + "", false))); + if (funcDef.name$() === "constructor") { + return false; } - } else if (expr.getType$().equals$LType$(Type.integerType)) { - if (baseExpr.getType$().equals$LType$(Type.integerType)) { - this.log$S("folding type cast: int as int"); - replaceCb(baseExpr); - } else if (baseExpr instanceof StringLiteralExpression) { - this.log$S("folding type cast: string literal as int"); - replaceCb(new IntegerLiteralExpression(new Token$2((baseExpr.getDecoded$() | 0) + "", false))); - } else if (baseExpr instanceof NumberLiteralExpression) { - this.log$S("folding type cast: number literal as int"); - replaceCb(new IntegerLiteralExpression(new Token$2((baseExpr.getDecoded$() | 0) + "", false))); + function onStatement(statement) { + if (statement instanceof FunctionStatement) { + return statement.getFuncDef$().forEachStatement$F$LStatement$B$(onStatement); + } + return statement.forEachExpression$F$LExpression$B$((function onExpression(expr) { + if (expr instanceof FunctionExpression) { + return expr.getFuncDef$().forEachStatement$F$LStatement$B$(onStatement); + } else if (expr instanceof SuperExpression) { + return false; + } + return expr.forEachExpression$F$LExpression$B$(onExpression); + })) && statement.forEachStatement$F$LStatement$B$(onStatement); } - } else if (expr.getType$().equals$LType$(Type.booleanType)) { - if (baseExpr.getType$().equals$LType$(Type.booleanType)) { - this.log$S("folding type cast: boolean as boolean"); - replaceCb(baseExpr); - } else if (baseExpr instanceof StringLiteralExpression) { - this.log$S("folding type cast: string literal as boolean"); - replaceCb(new BooleanLiteralExpression(new Token$2(!! baseExpr.getDecoded$() + "", false))); - } else if (baseExpr instanceof NumberLiteralExpression) { - this.log$S("folding type cast: number literal as boolean"); - replaceCb(new BooleanLiteralExpression(new Token$2((baseExpr.getDecoded$() ? "true" : "false"), false))); - } else if (baseExpr instanceof IntegerLiteralExpression) { - this.log$S("folding type cast: integer literal as boolean"); - replaceCb(new BooleanLiteralExpression(new Token$2((baseExpr.getDecoded$() ? "true" : "false"), false))); + if (! funcDef.forEachStatement$F$LStatement$B$(onStatement)) { + return false; } - } -}; - - -function _DeadCodeEliminationOptimizeCommand() { - _FunctionOptimizeCommand.call(this, _DeadCodeEliminationOptimizeCommand.IDENTIFIER); -}; - -$__jsx_extend([_DeadCodeEliminationOptimizeCommand], _FunctionOptimizeCommand); -_DeadCodeEliminationOptimizeCommand.prototype.optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { - if (funcDef.getStatements$() == null) { return true; } - while (this._optimizeFunction$LMemberFunctionDefinition$(funcDef) || this._removeExpressionStatementsWithoutSideEffects$LMemberFunctionDefinition$(funcDef)) { - } - return true; -}; - - -_DeadCodeEliminationOptimizeCommand.prototype._removeExpressionStatementsWithoutSideEffects$LMemberFunctionDefinition$ = function (funcDef) { - var $this = this; - var shouldRetry; - shouldRetry = false; - (function onStatements(statements) { - var i; - for (i = 0; i < statements.length; ) { - if (statements[i] instanceof ExpressionStatement && ! _Util$0$exprHasSideEffects$LExpression$(statements[i].getExpr$())) { - shouldRetry = true; - statements.splice(i, 1); - } else { - if (statements[i] instanceof ExpressionStatement) { - $this._optimizeExprInVoid$LExpression$F$LExpression$V$(statements[i].getExpr$(), (function (expr) { - statements[i] = new ExpressionStatement(expr); - })); - } - statements[i++].handleStatements$F$ALStatement$B$(onStatements); + this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { + if ((classDef.flags$() & (ClassDefinition.IS_INTERFACE | ClassDefinition.IS_MIXIN)) !== 0) { + return true; + } + classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$((function onFunction(funcDef) { + if (memberCanBeStaticized(funcDef)) { + $this.log$S("staticizing method: " + funcDef.name$()); + $this._staticizeMethod$LMemberFunctionDefinition$(funcDef); + } + return true; + })); + return true; + })); + this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { + var onFunction; + $this.log$S("rewriting member method calls in class: " + classDef.className$()); + classDef.forEachMemberVariable$F$LMemberVariableDefinition$B$((function (varDef) { + if (varDef.getInitialValue$() == null) { + return true; + } + $this._rewriteMethodCallsToStatic$LExpression$F$LExpression$V$LMemberFunctionDefinition$(varDef.getInitialValue$(), (function (expr) { + varDef.setInitialValue$LExpression$(expr); + }), null); + return true; + })); + function onFunction(funcDef) { + var onStatement; + function onStatement(statement) { + statement.forEachExpression$F$LExpression$F$LExpression$V$B$((function (expr, replaceCb) { + $this._rewriteMethodCallsToStatic$LExpression$F$LExpression$V$LMemberFunctionDefinition$(expr, replaceCb, funcDef); + return true; + })); + return statement.forEachStatement$F$LStatement$B$(onStatement); } + funcDef.forEachStatement$F$LStatement$B$(onStatement); + return funcDef.forEachClosure$F$LMemberFunctionDefinition$B$(onFunction); } + classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$(onFunction); return true; - })(funcDef.getStatements$()); - return shouldRetry; + })); }; -_DeadCodeEliminationOptimizeCommand.prototype._optimizeExprInVoid$LExpression$F$LExpression$V$ = function (expr, replaceCb) { - var condExpr; - var ifTrueHasSideEffect; - var ifFalseHasSideEffect; - var condAndIfTrue; - var condOrIfFalse; - if (expr instanceof ConditionalExpression) { - condExpr = expr; - ifTrueHasSideEffect = _Util$0$exprHasSideEffects$LExpression$(condExpr.getIfTrueExpr$()); - ifFalseHasSideEffect = _Util$0$exprHasSideEffects$LExpression$(condExpr.getIfFalseExpr$()); - if (ifTrueHasSideEffect && ifFalseHasSideEffect) { - } else if (ifTrueHasSideEffect && ! ifFalseHasSideEffect) { - condAndIfTrue = new LogicalExpression(new Token$3("&&"), condExpr.getCondExpr$(), condExpr.getIfTrueExpr$()); - replaceCb(condAndIfTrue); - } else if (! ifTrueHasSideEffect && ifFalseHasSideEffect) { - condOrIfFalse = new LogicalExpression(new Token$3("||"), condExpr.getCondExpr$(), condExpr.getIfFalseExpr$()); - replaceCb(condOrIfFalse); - } else { - replaceCb(condExpr.getCondExpr$()); +_StaticizeOptimizeCommand.prototype._staticizeMethod$LMemberFunctionDefinition$ = function (funcDef) { + var $this = this; + var staticFuncDef; + var classDef; + var newName; + var thisArg; + staticFuncDef = funcDef.clone$(); + classDef = staticFuncDef.getClassDef$(); + newName = this._newStaticFunctionName$LClassDefinition$SALType$B(classDef, funcDef.name$(), [ new ObjectType(classDef) ].concat(funcDef.getType$().getArgumentTypes$()), true); + this.getStash$LStashable$(funcDef).altName = newName; + staticFuncDef._nameToken = new Token$2(newName, true); + staticFuncDef.setFlags$N(funcDef.flags$() & ~ ClassDefinition.IS_EXPORT | ClassDefinition.IS_STATIC); + thisArg = new ArgumentDeclaration(new Token$2("$this", false), new ObjectType(classDef)); + staticFuncDef.getArguments$().unshift(thisArg); + staticFuncDef.forEachStatement$F$LStatement$B$((function onStatement(statement) { + if (statement instanceof FunctionStatement) { + statement.getFuncDef$().forEachStatement$F$LStatement$B$(onStatement); } - } else if (expr instanceof LogicalNotExpression) { - replaceCb(expr.getExpr$()); - } + return statement.forEachExpression$F$LExpression$F$LExpression$V$B$((function onExpr(expr, replaceCb) { + if (expr instanceof ThisExpression) { + replaceCb(new LocalExpression(thisArg.getName$(), thisArg)); + } else if (expr instanceof FunctionExpression) { + return expr.getFuncDef$().forEachStatement$F$LStatement$B$(onStatement); + } + return expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); + })) && statement.forEachStatement$F$LStatement$B$(onStatement); + })); }; -_DeadCodeEliminationOptimizeCommand.prototype._optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { - var $this = this; - _Util$0$optimizeBasicBlock$LMemberFunctionDefinition$F$ALExpression$V$(funcDef, (function (exprs) { - $this._eliminateDeadStoresToProperties$LMemberFunctionDefinition$ALExpression$(funcDef, exprs); - $this._delayAssignmentsBetweenLocals$LMemberFunctionDefinition$ALExpression$(funcDef, exprs); - $this._eliminateDeadStores$LMemberFunctionDefinition$ALExpression$(funcDef, exprs); - $this._eliminateDeadConditions$LMemberFunctionDefinition$ALExpression$(funcDef, exprs); - })); - return this._eliminateUnusedVariables$LMemberFunctionDefinition$(funcDef); +_StaticizeOptimizeCommand.prototype._newStaticFunctionName$LClassDefinition$SALType$B = function (classDef, baseName, argTypes, isStatic) { + var index; + var newName; + index = 0; + newName = baseName; + while (Util$findFunctionInClass$LClassDefinition$SALType$B(classDef, newName, argTypes, isStatic) != null) { + newName = Util$format$SAS("%1_%2", [ baseName, index + "" ]); + ++index; + } + return newName; }; -_DeadCodeEliminationOptimizeCommand.prototype._eliminateUnusedVariables$LMemberFunctionDefinition$ = function (funcDef) { +_StaticizeOptimizeCommand.prototype._rewriteMethodCallsToStatic$LExpression$F$LExpression$V$LMemberFunctionDefinition$ = function (expr, replaceCb, rewritingFuncDef) { var $this = this; - var shouldRetry; - var locals; - var localsUsed; - var localIndex; - shouldRetry = false; - locals = funcDef.getLocals$(); - localsUsed = new Array(locals.length); - funcDef.forEachStatement$F$LStatement$B$((function onStatement(statement) { - if (statement instanceof FunctionStatement) { - statement.getFuncDef$().forEachStatement$F$LStatement$B$(onStatement); - } - statement.forEachExpression$F$LExpression$B$((function onExpr(expr) { - var i; - if (expr instanceof AssignmentExpression && expr.getFirstExpr$() instanceof LocalExpression && expr.getFirstExpr$().getType$().equals$LType$(expr.getSecondExpr$().getType$())) { - return onExpr(expr.getSecondExpr$()); - } else if (expr instanceof LocalExpression) { - for (i = 0; i < locals.length; ++i) { - if (locals[i] == expr.getLocal$()) { - break; + var onExpr; + function onExpr(expr, replaceCb) { + var calleeExpr; + var propertyExpr; + var receiverType; + var funcDef; + var newName; + var superExpr; + var classDef; + var thisVar; + var thisArg; + if (expr instanceof CallExpression) { + calleeExpr = expr.getExpr$(); + if (calleeExpr instanceof PropertyExpression && ! calleeExpr.getExpr$().isClassSpecifier$() && ! calleeExpr.getType$().isAssignable$()) { + propertyExpr = calleeExpr; + receiverType = propertyExpr.getExpr$().getType$().resolveIfNullable$(); + if ((receiverType.getClassDef$().flags$() & (ClassDefinition.IS_INTERFACE | ClassDefinition.IS_MIXIN)) === 0) { + funcDef = $this._findFunctionInClassTree$LClassDefinition$SALType$B(receiverType.getClassDef$(), propertyExpr.getIdentifierToken$().getValue$(), propertyExpr.getType$().getArgumentTypes$(), false); + if (funcDef != null && (newName = $this.getStash$LStashable$(funcDef).altName) != null) { + onExpr(propertyExpr.getExpr$(), (function (expr) { + propertyExpr.setExpr$LExpression$(expr); + })); + Util$forEachExpression$F$LExpression$F$LExpression$V$B$ALExpression$(onExpr, expr.getArguments$()); + replaceCb(new CallExpression(expr.getToken$(), new PropertyExpression$0(propertyExpr.getToken$(), new ClassExpression(new Token$2(funcDef.getClassDef$().className$(), true), new ObjectType(funcDef.getClassDef$())), new Token$2(newName, true), propertyExpr.getTypeArguments$(), new StaticFunctionType(null, funcDef.getType$().getReturnType$(), [ new ObjectType(funcDef.getClassDef$()) ].concat(funcDef.getType$().getArgumentTypes$()), false)), [ propertyExpr.getExpr$() ].concat(expr.getArguments$()))); + return true; } } - if (i !== locals.length) { - localsUsed[i] = true; - } - } else if (expr instanceof FunctionExpression) { - expr.getFuncDef$().forEachStatement$F$LStatement$B$(onStatement); } - return expr.forEachExpression$F$LExpression$B$(onExpr); - })); - return statement.forEachStatement$F$LStatement$B$(onStatement); - })); - for (localIndex = localsUsed.length - 1; localIndex >= 0; --localIndex) { - if (localsUsed[localIndex]) { - continue; - } - (function onStatements(statements) { - var i; - var statement; - var localFuncDef; - for (i = 0; i < statements.length; ) { - statement = statements[i]; - if (statement instanceof FunctionStatement) { - localFuncDef = statement.getFuncDef$(); - onStatements(localFuncDef.getStatements$()); - if (localFuncDef.getFuncLocal$() == locals[localIndex]) { - $this.log$S("removing definition of " + locals[localIndex].getName$().getNotation$()); - funcDef.getClosures$().splice(funcDef.getClosures$().indexOf(localFuncDef), 1); - statements.splice(i, 1); - } else { - i++; - } + } else if (expr instanceof SuperExpression) { + superExpr = expr; + classDef = superExpr.getFunctionType$().getObjectType$().getClassDef$(); + funcDef = $this._findFunctionInClassTree$LClassDefinition$SALType$B(classDef, superExpr.getName$().getValue$(), superExpr.getFunctionType$().getArgumentTypes$(), false); + if (funcDef != null && (newName = $this.getStash$LStashable$(funcDef).altName) != null) { + Util$forEachExpression$F$LExpression$F$LExpression$V$B$ALExpression$(onExpr, superExpr.getArguments$()); + if ((rewritingFuncDef.flags$() & ClassDefinition.IS_STATIC) !== 0) { + thisArg = rewritingFuncDef.getArguments$()[0]; + thisVar = new LocalExpression(thisArg.getName$(), thisArg); } else { - i++; + thisVar = new ThisExpression(new Token$2("this", false), funcDef.getClassDef$()); } - statement.forEachExpression$F$LExpression$F$LExpression$V$B$((function onExpr(expr, replaceCb) { - var rhsExpr; - if (expr instanceof AssignmentExpression && expr.getFirstExpr$() instanceof LocalExpression && expr.getFirstExpr$().getLocal$() == locals[localIndex]) { - $this.log$S("removing assignment to " + locals[localIndex].getName$().getNotation$()); - rhsExpr = expr.getSecondExpr$(); - replaceCb(rhsExpr); - shouldRetry = true; - return rhsExpr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); - } else if (expr instanceof LocalExpression && expr.getLocal$() == locals[localIndex]) { - throw new Error("logic flaw, found a variable going to be removed being used"); - } else if (expr instanceof FunctionExpression) { - onStatements(expr.getFuncDef$().getStatements$()); - } - return expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); - })); - _Util$0$handleSubStatements$F$ALStatement$B$LStatement$(onStatements, statement); + replaceCb(new CallExpression(expr.getToken$(), new PropertyExpression$0(superExpr.getToken$(), new ClassExpression(new Token$2(funcDef.getClassDef$().className$(), true), new ObjectType(funcDef.getClassDef$())), new Token$2(newName, true), [ ], new StaticFunctionType(null, funcDef.getType$().getReturnType$(), [ new ObjectType(funcDef.getClassDef$()) ].concat(funcDef.getType$().getArgumentTypes$()), false)), [ thisVar ].concat(superExpr.getArguments$()))); + return true; } - return true; - })(funcDef.getStatements$()); - locals.splice(localIndex, 1); + } + return expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); } - return shouldRetry; + onExpr(expr, replaceCb); }; -_DeadCodeEliminationOptimizeCommand.prototype._delayAssignmentsBetweenLocals$LMemberFunctionDefinition$ALExpression$ = function (funcDef, exprs) { - var $this = this; - var localsUntouchable; - var locals; - localsUntouchable = new TypedMap$x2E$x3CLocalVariable$x2Cboolean$x3E(); - locals = new TypedMap$x2E$x3CLocalVariable$x2CExpression$x3E(); - Util$forEachExpression$F$LExpression$B$ALExpression$((function onExpr(expr) { - var local; - if (expr instanceof FusedAssignmentExpression && expr.getFirstExpr$() instanceof LocalExpression) { - local = expr.getFirstExpr$().getLocal$(); - $this.log$S("local variable " + local.getName$().getValue$() + " cannot be rewritten (has fused assignment)"); - localsUntouchable.set$LLocalVariable$B(local, true); - } else if (expr instanceof IncrementExpression && expr.getExpr$() instanceof LocalExpression) { - local = expr.getExpr$().getLocal$(); - $this.log$S("local variable " + local.getName$().getValue$() + " cannot be rewritten (has increment)"); - localsUntouchable.set$LLocalVariable$B(local, true); - } - return expr.forEachExpression$F$LExpression$B$(onExpr); - }), exprs); - Util$forEachExpression$F$LExpression$F$LExpression$V$B$ALExpression$((function onExpr(expr, replaceCb) { - var assignmentExpr; - var lhsLocal; - var rhsExpr; - var rhsLocal; - var cachedExpr; - var callingFuncDef; - if (expr instanceof AssignmentExpression) { - assignmentExpr = expr; - if (assignmentExpr.getFirstExpr$() instanceof LocalExpression) { - onExpr(assignmentExpr.getSecondExpr$(), (function (expr) { - assignmentExpr.setSecondExpr$LExpression$(expr); - })); - if (! localsUntouchable.get$LLocalVariable$(assignmentExpr.getFirstExpr$().getLocal$()) && assignmentExpr.getFirstExpr$().getType$().equals$LType$(assignmentExpr.getSecondExpr$().getType$())) { - lhsLocal = assignmentExpr.getFirstExpr$().getLocal$(); - $this.log$S("resetting cache for: " + lhsLocal.getName$().getNotation$()); - locals.reversedForEach$F$LLocalVariable$LExpression$B$((function (local, expr) { - if (local == lhsLocal) { - $this.log$S(" clearing itself"); - locals.delete$LLocalVariable$(local); - } else if (expr instanceof LocalExpression && expr.getLocal$() == lhsLocal) { - $this.log$S(" clearing " + local.getName$().getNotation$()); - locals.delete$LLocalVariable$(local); - } - return true; - })); - if (assignmentExpr.getToken$().getValue$() === "=") { - rhsExpr = assignmentExpr.getSecondExpr$(); - if (rhsExpr instanceof LocalExpression) { - rhsLocal = rhsExpr.getLocal$(); - if (lhsLocal != rhsLocal && ! localsUntouchable.get$LLocalVariable$(rhsLocal)) { - $this.log$S(" set to: " + rhsLocal.getName$().getNotation$()); - locals.set$LLocalVariable$LExpression$(lhsLocal, rhsExpr); - } - } else if (rhsExpr instanceof LeafExpression) { - $this.log$S(" set to: " + rhsExpr.getToken$().getNotation$()); - locals.set$LLocalVariable$LExpression$(lhsLocal, rhsExpr); - } - } - } - return true; - } - } else if (expr instanceof LocalExpression) { - cachedExpr = locals.get$LLocalVariable$(expr.getLocal$()); - if (cachedExpr) { - replaceCb(cachedExpr.clone$()); - return true; - } - } else if (expr instanceof CallExpression) { - callingFuncDef = _DetermineCalleeCommand$getCallingFuncDef$LStashable$(expr); - if (callingFuncDef != null && (callingFuncDef.flags$() & ClassDefinition.IS_PURE) !== 0) { - } else { - expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); - if (funcDef.getParent$() != null || funcDef.getClosures$().length !== 0) { - locals.clear$(); - } - return true; - } - } else if (expr instanceof NewExpression) { - expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); - locals.clear$(); - return true; +_StaticizeOptimizeCommand.prototype._findFunctionInClassTree$LClassDefinition$SALType$B = function (classDef, name, argTypes, isStatic) { + var funcDef; + while (classDef.className$() !== "Object") { + if ((funcDef = Util$findFunctionInClass$LClassDefinition$SALType$B(classDef, name, argTypes, isStatic)) != null) { + return funcDef; } - return expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); - }), exprs); + classDef = classDef.extendType$().getClassDef$(); + } + return Util$findFunctionInClass$LClassDefinition$SALType$B(classDef, name, argTypes, isStatic); }; -_DeadCodeEliminationOptimizeCommand.prototype._eliminateDeadStores$LMemberFunctionDefinition$ALExpression$ = function (funcDef, exprs) { +function _StructuredStashAccessor$x2E$x3CStash$x3E$2() { +}; + +$__jsx_extend([_StructuredStashAccessor$x2E$x3CStash$x3E$2], Object); +_StructuredStashAccessor$x2E$x3CStash$x3E$2.prototype.$__jsx_implements__StructuredStashAccessor$x2E$x3CStash$x3E$2 = true; + +_StructuredStashAccessor$x2E$x3CStash$x3E$2.prototype.getStash$LStashable$ = function (stashable) { + var identifier; + var stash; + identifier = this._identifier; + stash = stashable.getStash$S(identifier); + if (stash == null) { + stash = new _UnclassifyOptimizationCommand$x2EStash(); + stashable.setStash$SLStash$(identifier, stash); + } + return stash; +}; + + +_StructuredStashAccessor$x2E$x3CStash$x3E$2.prototype.resetStash$LStashable$ = function (stashable) { + var identifier; + identifier = this._identifier; + stashable.setStash$SLStash$(identifier, null); +}; + + +function _UnclassifyOptimizationCommand() { + _OptimizeCommand.call(this, _UnclassifyOptimizationCommand.IDENTIFIER); + _StructuredStashAccessor$x2E$x3CStash$x3E$2.call(this); +}; + +$__jsx_extend([_UnclassifyOptimizationCommand], _OptimizeCommand); +$__jsx_merge_interface(_UnclassifyOptimizationCommand, _StructuredStashAccessor$x2E$x3CStash$x3E$2); + +_UnclassifyOptimizationCommand.prototype.performOptimization$ = function () { var $this = this; - var lastAssignExpr; - var onExpr; - lastAssignExpr = new TypedMap$x2E$x3CLocalVariable$x2CPair$x2E$x3CAssignmentExpression$x2Cfunction$x20$x28$x3A$x20Expression$x29$x20$x3A$x20void$x3E$x3E(); - function onExpr(expr, rewriteCb) { - var assignExpr; - var lhsLocal; - var lastAssign; - if (expr instanceof AssignmentExpression) { - assignExpr = expr; - if (assignExpr.getFirstExpr$() instanceof LocalExpression) { - onExpr(assignExpr.getSecondExpr$(), (function (assignExpr) { - return (function (expr) { - assignExpr.setSecondExpr$LExpression$(expr); - }); - })(assignExpr)); - lhsLocal = assignExpr.getFirstExpr$().getLocal$(); - lastAssign = lastAssignExpr.get$LLocalVariable$(lhsLocal); - if (lastAssign) { - $this.log$S("eliminating dead store to: " + lhsLocal.getName$().getValue$()); - lastAssign.second(lastAssign.first.getSecondExpr$()); - } - lastAssignExpr.set$LLocalVariable$LPair$x2E$x3CAssignmentExpression$x2Cfunction$x20$x28$x3A$x20Expression$x29$x20$x3A$x20void$x3E$(lhsLocal, Util$makePair$LAssignmentExpression$F$LExpression$V$(assignExpr, rewriteCb)); - return true; + var classDefs; + classDefs = this._getClassesToUnclassify$(); + classDefs.forEach((function (classDef) { + $this.log$S("unclassifying class: " + classDef.className$()); + classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$((function onFunction(funcDef) { + if ((funcDef.flags$() & ClassDefinition.IS_STATIC) === 0 && funcDef.name$() !== "constructor") { + $this.log$S("rewriting method to static function: " + funcDef.name$()); + $this._rewriteFunctionAsStatic$LMemberFunctionDefinition$(funcDef); } - } else if (expr instanceof LocalExpression) { - lastAssignExpr.delete$LLocalVariable$(expr.getLocal$()); - } else if (expr instanceof LogicalExpression || expr instanceof ConditionalExpression) { - expr.forEachExpression$F$LExpression$F$LExpression$V$B$((function (expr, rewriteCb) { - var result; - result = onExpr(expr, rewriteCb); - lastAssignExpr.clear$(); - return result; - })); - return true; - } else if (_Util$0$exprHasSideEffects$LExpression$(expr)) { - expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); - lastAssignExpr.clear$(); return true; + })); + })); + this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { + var onFunction; + $this.log$S("rewriting member method calls in class: " + classDef.className$()); + function onFunction(funcDef) { + var onStatement; + function onStatement(statement) { + statement.forEachExpression$F$LExpression$F$LExpression$V$B$((function (expr, replaceCb) { + $this._rewriteMethodCallsToStatic$LExpression$F$LExpression$V$ALClassDefinition$(expr, replaceCb, classDefs); + return true; + })); + return statement.forEachStatement$F$LStatement$B$(onStatement); + } + funcDef.forEachStatement$F$LStatement$B$(onStatement); + return funcDef.forEachClosure$F$LMemberFunctionDefinition$B$(onFunction); } - return expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); - } - Util$forEachExpression$F$LExpression$F$LExpression$V$B$ALExpression$(onExpr, exprs); + classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$(onFunction); + classDef.forEachMemberVariable$F$LMemberVariableDefinition$B$((function (varDef) { + if ((varDef.flags$() & ClassDefinition.IS_STATIC) !== 0) { + if (varDef.getInitialValue$() != null) { + $this._rewriteMethodCallsToStatic$LExpression$F$LExpression$V$ALClassDefinition$(varDef.getInitialValue$(), (function (expr) { + varDef.setInitialValue$LExpression$(expr); + }), classDefs); + } + } + return varDef.forEachClosure$F$LMemberFunctionDefinition$B$(onFunction); + })); + return true; + })); }; -_DeadCodeEliminationOptimizeCommand.prototype._eliminateDeadStoresToProperties$LMemberFunctionDefinition$ALExpression$ = function (funcDef, exprs) { +_UnclassifyOptimizationCommand.prototype._getClassesToUnclassify$ = function () { var $this = this; - var isFirstLevelPropertyAccess; - var baseExprsAreEqual; - var lastAssignExpr; - var onExpr; - function isFirstLevelPropertyAccess(expr) { - var baseExpr; - if (! (expr instanceof PropertyExpression)) { - return false; + var candidates; + var candidateIndex; + var hasInlineableCtor; + candidates = []; + this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { + if ((classDef.flags$() & (ClassDefinition.IS_FINAL | ClassDefinition.IS_NATIVE | ClassDefinition.IS_EXPORT)) === ClassDefinition.IS_FINAL && classDef.extendType$().getClassDef$().className$() === "Object" && classDef.implementTypes$().length === 0 && classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$((function (funcDef) { + return (funcDef.flags$() & (ClassDefinition.IS_OVERRIDE | ClassDefinition.IS_EXPORT)) === 0; + }))) { + candidates.push(classDef); } - baseExpr = expr.getExpr$(); - if (baseExpr instanceof LocalExpression || baseExpr instanceof ThisExpression || baseExpr.isClassSpecifier$()) { - return true; - } else { + return true; + })); + this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { + var onExpr; + var onFunction; + if (candidates.length === 0) { return false; } - } - function baseExprsAreEqual(x, y) { - if (x instanceof LocalExpression && y instanceof LocalExpression) { - return x.getLocal$() == y.getLocal$(); - } else if (x instanceof ThisExpression && y instanceof ThisExpression) { - return true; - } else if (x.isClassSpecifier$() && y.isClassSpecifier$()) { - return x.getType$().equals$LType$(y.getType$()); - } - return false; - } - lastAssignExpr = {}; - onExpr = (function (expr, rewriteCb) { - var assignmentExpr; - var firstExpr; - var propertyName; - var k; - var baseExpr; - if (expr instanceof AssignmentExpression) { - assignmentExpr = expr; - firstExpr = assignmentExpr.getFirstExpr$(); - if (isFirstLevelPropertyAccess(firstExpr) && ! Util$isNativeClass$LType$(firstExpr.getExpr$().getType$())) { - propertyName = firstExpr.getIdentifierToken$().getValue$(); - onExpr(assignmentExpr.getSecondExpr$(), null); - if (lastAssignExpr[propertyName] && lastAssignExpr[propertyName].second != null && baseExprsAreEqual(firstExpr.getExpr$(), lastAssignExpr[propertyName].first.getFirstExpr$().getExpr$())) { - lastAssignExpr[propertyName].second(lastAssignExpr[propertyName].first.getSecondExpr$()); + function onExpr(expr) { + var foundClassDefIndex; + if (! (expr != null)) { + debugger; + throw new Error("[src/optimizer.jsx:1420:28] assertion failure\n assert expr != null;\n ^^\n"); + } + if (expr instanceof InstanceofExpression) { + foundClassDefIndex = candidates.indexOf(expr.getExpectedType$().getClassDef$()); + if (foundClassDefIndex !== - 1) { + candidates.splice(foundClassDefIndex, 1); + if (candidates.length === 0) { + return false; + } } - lastAssignExpr[propertyName] = Util$makePair$LAssignmentExpression$F$LExpression$V$(assignmentExpr, rewriteCb); - return true; - } else if (assignmentExpr.getFirstExpr$() instanceof LocalExpression) { - onExpr(assignmentExpr.getSecondExpr$(), null); - for (k in lastAssignExpr) { - baseExpr = lastAssignExpr[k].first.getFirstExpr$().getExpr$(); - if (baseExpr instanceof LocalExpression && baseExpr.getLocal$() == expr.getFirstExpr$().getLocal$()) { - delete lastAssignExpr[k]; + } else if (expr instanceof AsExpression && expr.getType$() instanceof ObjectType) { + foundClassDefIndex = candidates.indexOf(expr.getType$().getClassDef$()); + if (foundClassDefIndex !== - 1) { + candidates.splice(foundClassDefIndex, 1); + if (candidates.length === 0) { + return false; } } - return true; } - } else if (isFirstLevelPropertyAccess(expr)) { - propertyName = expr.getIdentifierToken$().getValue$(); - delete lastAssignExpr[propertyName]; - } else if (expr instanceof CallExpression) { - onExpr(expr.getExpr$(), null); - Util$forEachExpression$F$LExpression$F$LExpression$V$B$ALExpression$(onExpr, expr.getArguments$()); - lastAssignExpr = {}; + return expr.forEachExpression$F$LExpression$B$(onExpr); + } + function onFunction(funcDef) { + funcDef.forEachStatement$F$LStatement$B$((function onStatement(statement) { + statement.forEachExpression$F$LExpression$B$(onExpr); + return statement.forEachStatement$F$LStatement$B$(onStatement); + })); + return funcDef.forEachClosure$F$LMemberFunctionDefinition$B$(onFunction); + } + classDef.forEachMemberFunction$F$LMemberFunctionDefinition$B$(onFunction); + classDef.forEachMemberVariable$F$LMemberVariableDefinition$B$((function (varDef) { + if ((varDef.flags$() & ClassDefinition.IS_STATIC) !== 0) { + if (varDef.getInitialValue$() != null) { + onExpr(varDef.getInitialValue$()); + } + } + return varDef.forEachClosure$F$LMemberFunctionDefinition$B$(onFunction); + })); + return true; + })); + for (candidateIndex = candidates.length - 1; candidateIndex >= 0; --candidateIndex) { + hasInlineableCtor = false; + candidates[candidateIndex].forEachMemberFunction$F$LMemberFunctionDefinition$B$((function (funcDef) { + var inliner; + if ((funcDef.flags$() & ClassDefinition.IS_STATIC) === 0 && funcDef.name$() === "constructor") { + inliner = $this._createInliner$LMemberFunctionDefinition$(funcDef); + $this.log$S(funcDef.getNotation$() + " is" + (inliner ? "" : " not") + " inlineable"); + if (inliner) { + $this.getStash$LStashable$(funcDef).inliner = inliner; + hasInlineableCtor = true; + } + } + return true; + })); + if (! hasInlineableCtor) { + candidates.splice(candidateIndex, 1); + } + } + if (candidates.length === 0) { + return candidates; + } + return candidates; +}; + + +_UnclassifyOptimizationCommand.prototype._createInliner$LMemberFunctionDefinition$ = function (funcDef) { + var $this = this; + var propertyNames; + var propertyExprs; + var expectedArgIndex; + var statements; + var statementIndex; + var statementExpr; + var lhsExpr; + var onRHSExpr; + var propertyIndex; + var i; + if (funcDef.getLocals$().length !== 0) { + return null; + } + propertyNames = []; + funcDef.getClassDef$().forEachMemberVariable$F$LMemberVariableDefinition$B$((function (member) { + if ((member.flags$() & ClassDefinition.IS_STATIC) === 0) { + propertyNames.push(member.name$()); + } + return true; + })); + propertyExprs = []; + expectedArgIndex = 0; + statements = funcDef.getStatements$(); + if (statements.length !== propertyNames.length) { + return null; + } + for (statementIndex = 0; statementIndex < statements.length; ++statementIndex) { + if (! (statements[statementIndex] instanceof ExpressionStatement)) { + return null; + } + statementExpr = statements[statementIndex].getExpr$(); + if (! (statementExpr instanceof AssignmentExpression)) { + return null; + } + lhsExpr = statementExpr.getFirstExpr$(); + if (! (lhsExpr instanceof PropertyExpression && lhsExpr.getExpr$() instanceof ThisExpression)) { + return null; + } + function onRHSExpr(expr) { + var argIndex; + if (_Util$0$exprIsAssignment$LExpression$(expr)) { + return false; + } else if (expr instanceof FunctionExpression) { + return false; + } else if (expr instanceof ThisExpression) { + return false; + } else if (expr instanceof LocalExpression) { + argIndex = funcDef.getArguments$().map((function (i) { + return i; + })).indexOf(expr.getLocal$()); + if (argIndex === - 1) { + throw new Error("logic flaw; could not find argument: " + expr.getLocal$().getName$().getValue$()); + } + if (expectedArgIndex !== argIndex) { + return false; + } + ++expectedArgIndex; + } + return expr.forEachExpression$F$LExpression$B$(onRHSExpr); + } + if (! onRHSExpr(statementExpr.getSecondExpr$())) { + return null; + } + propertyIndex = propertyNames.indexOf(lhsExpr.getIdentifierToken$().getValue$()); + if (propertyIndex === - 1) { + throw new Error("logic flaw; could not find property: " + lhsExpr.getIdentifierToken$().getValue$()); + } + if (propertyExprs[propertyIndex]) { + return null; + } + for (i = propertyIndex + 1; i < propertyNames.length; ++i) { + if (propertyExprs[i] != null && _Util$0$exprHasSideEffects$LExpression$(propertyExprs[i])) { + return null; + } + } + propertyExprs[propertyIndex] = statementExpr.getSecondExpr$().clone$(); + } + return (function (newExpr) { + return propertyExprs.map((function (expr) { + var onExpr; + function onExpr(expr, replaceCb) { + var args; + var argIndex; + var i; + if (expr instanceof LocalExpression) { + (args = funcDef.getArguments$(), argIndex = - 1); + for (i in args) { i |= 0; + if (args[i] == expr.getLocal$()) { + argIndex = i; + break; + } + } + if (argIndex === - 1) { + throw new Error("logic flaw"); + } + replaceCb(newExpr.getArguments$()[argIndex]); + return true; + } + return expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); + } + expr = expr.clone$(); + onExpr(expr, (function (newExpr) { + expr = newExpr; + })); + return expr; + })); + }); +}; + + +_UnclassifyOptimizationCommand.prototype._rewriteFunctionAsStatic$LMemberFunctionDefinition$ = function (funcDef) { + var $this = this; + var thisArg; + thisArg = new ArgumentDeclaration(new Token$2("$this", false), new ObjectType(funcDef.getClassDef$())); + funcDef.getArguments$().unshift(thisArg); + funcDef.forEachStatement$F$LStatement$B$((function onStatement(statement) { + if (statement instanceof FunctionStatement) { + statement.getFuncDef$().forEachStatement$F$LStatement$B$(onStatement); + } + return statement.forEachExpression$F$LExpression$F$LExpression$V$B$((function onExpr(expr, replaceCb) { + if (expr instanceof ThisExpression) { + replaceCb(new LocalExpression(thisArg.getName$(), thisArg)); + } else if (expr instanceof FunctionExpression) { + return expr.getFuncDef$().forEachStatement$F$LStatement$B$(onStatement); + } + return expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); + })) && statement.forEachStatement$F$LStatement$B$(onStatement); + })); + funcDef.setFlags$N(funcDef.flags$() | ClassDefinition.IS_STATIC); +}; + + +_UnclassifyOptimizationCommand.prototype._rewriteMethodCallsToStatic$LExpression$F$LExpression$V$ALClassDefinition$ = function (expr, replaceCb, unclassifyingClassDefs) { + var $this = this; + var onExpr; + onExpr = (function (expr, replaceCb) { + var calleeExpr; + var propertyExpr; + var receiverType; + var receiverClassDef; + var funcType; + if (expr instanceof CallExpression) { + calleeExpr = expr.getExpr$(); + if (calleeExpr instanceof PropertyExpression && ! calleeExpr.getExpr$().isClassSpecifier$() && ! calleeExpr.getType$().isAssignable$() && ! (calleeExpr.getIdentifierToken$().getValue$() === "toString" && expr.getArguments$().length === 0)) { + propertyExpr = calleeExpr; + receiverType = propertyExpr.getExpr$().getType$().resolveIfNullable$(); + receiverClassDef = receiverType.getClassDef$(); + if (unclassifyingClassDefs.indexOf(receiverClassDef) !== - 1) { + onExpr(propertyExpr.getExpr$(), (function (expr) { + propertyExpr.setExpr$LExpression$(expr); + })); + Util$forEachExpression$F$LExpression$F$LExpression$V$B$ALExpression$(onExpr, expr.getArguments$()); + funcType = propertyExpr.getType$(); + replaceCb(new CallExpression(expr.getToken$(), new PropertyExpression$0(propertyExpr.getToken$(), new ClassExpression(new Token$2(receiverClassDef.className$(), true), receiverType), propertyExpr.getIdentifierToken$(), propertyExpr.getTypeArguments$(), new StaticFunctionType(null, funcType.getReturnType$(), [ receiverType ].concat(funcType.getArgumentTypes$()), false)), [ propertyExpr.getExpr$() ].concat(expr.getArguments$()))); + return true; + } + } + } + return expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); + }); + onExpr(expr, replaceCb); +}; + + +function _StructuredStashAccessor$x2E$x3CStash$x3E$3() { +}; + +$__jsx_extend([_StructuredStashAccessor$x2E$x3CStash$x3E$3], Object); +_StructuredStashAccessor$x2E$x3CStash$x3E$3.prototype.$__jsx_implements__StructuredStashAccessor$x2E$x3CStash$x3E$3 = true; + +_StructuredStashAccessor$x2E$x3CStash$x3E$3.prototype.getStash$LStashable$ = function (stashable) { + var identifier; + var stash; + identifier = this._identifier; + stash = stashable.getStash$S(identifier); + if (stash == null) { + stash = new _FoldConstantCommand$x2EStash(); + stashable.setStash$SLStash$(identifier, stash); + } + return stash; +}; + + +_StructuredStashAccessor$x2E$x3CStash$x3E$3.prototype.resetStash$LStashable$ = function (stashable) { + var identifier; + identifier = this._identifier; + stashable.setStash$SLStash$(identifier, null); +}; + + +function _FoldConstantCommand() { + _FunctionOptimizeCommand.call(this, _FoldConstantCommand.IDENTIFIER); + _StructuredStashAccessor$x2E$x3CStash$x3E$3.call(this); +}; + +$__jsx_extend([_FoldConstantCommand], _FunctionOptimizeCommand); +$__jsx_merge_interface(_FoldConstantCommand, _StructuredStashAccessor$x2E$x3CStash$x3E$3); + +_FoldConstantCommand.prototype.performOptimization$ = function () { + var $this = this; + _FunctionOptimizeCommand.prototype.performOptimization$.call(this); + this.getCompiler$().forEachClassDef$F$LParser$LClassDefinition$B$((function (parser, classDef) { + if (classDef instanceof TemplateClassDefinition || (classDef.flags$() & ClassDefinition.IS_NATIVE) !== 0) { + return true; + } + classDef.forEachMemberVariable$F$LMemberVariableDefinition$B$((function (varDef) { + if ((varDef.flags$() & ClassDefinition.IS_STATIC) !== 0 && varDef.getInitialValue$() != null) { + $this.log$S("starting optimization of " + varDef.getNotation$()); + $this._optimizeExpression$LExpression$F$LExpression$V$(varDef.getInitialValue$(), (function (expr) { + varDef.setInitialValue$LExpression$(expr); + })); + $this.log$S("finished optimization of " + varDef.getNotation$()); + } + return true; + })); + return true; + })); +}; + + +_FoldConstantCommand.prototype.optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { + var $this = this; + funcDef.forEachStatement$F$LStatement$B$((function onStatement(statement) { + statement.forEachStatement$F$LStatement$B$(onStatement); + statement.forEachExpression$F$LExpression$F$LExpression$V$B$((function (expr, replaceCb) { + return $this._optimizeExpression$LExpression$F$LExpression$V$(expr, replaceCb); + })); + return true; + })); + return true; +}; + + +_FoldConstantCommand.prototype._optimizeExpression$LExpression$F$LExpression$V$ = function (expr, replaceCb) { + var $this = this; + var propertyExpr; + var holderType; + var member; + var foldedExpr; + var calculateCb; + var baseExpr; + var firstExpr; + var secondExpr; + var innerExpr; + var condition; + var op; + var conditionalExpr; + var condExpr; + var ifTrueExpr; + var ifFalseExpr; + var callExpr; + var allArgsAreConstants; + expr.forEachExpression$F$LExpression$F$LExpression$V$B$((function (expr, replaceCb) { + return $this._optimizeExpression$LExpression$F$LExpression$V$(expr, replaceCb); + })); + if (expr instanceof PropertyExpression) { + propertyExpr = expr; + holderType = propertyExpr.getHolderType$(); + if (propertyExpr.getExpr$().isClassSpecifier$()) { + member = null; + holderType.getClassDef$().forEachMemberVariable$F$LMemberVariableDefinition$B$((function (m) { + if (m.name$() === propertyExpr.getIdentifierToken$().getValue$()) { + member = m; + } + return member == null; + })); + if (member != null && (member.flags$() & ClassDefinition.IS_CONST) !== 0) { + this._foldStaticConst$LMemberVariableDefinition$(member); + foldedExpr = this._toFoldedExpr$LExpression$LType$(member.getInitialValue$(), member.getType$()); + if (foldedExpr != null) { + foldedExpr = this._toFoldedExpr$LExpression$LType$(foldedExpr, propertyExpr.getType$()); + if (foldedExpr != null && ! (foldedExpr instanceof StringLiteralExpression && foldedExpr.getDecoded$().length > _FoldConstantCommand.LONG_STRING_LITERAL)) { + this.log$S("folding property " + member.getNotation$() + " at " + propertyExpr.getToken$().getFilename$() + ":" + (propertyExpr.getToken$().getLineNumber$() + "")); + replaceCb(foldedExpr); + } + } + } + } else if (propertyExpr.getExpr$() instanceof StringLiteralExpression) { + if (propertyExpr.getIdentifierToken$().getValue$() === "length") { + replaceCb(new NumberLiteralExpression(new Token$3(propertyExpr.getExpr$().getDecoded$().length + ""))); + } + } + } else if (expr instanceof SignExpression) { + switch (expr.getToken$().getValue$()) { + case "+": + calculateCb = (function (x) { + return + x; + }); + break; + case "-": + calculateCb = (function (x) { + return - x; + }); + break; + default: + return false; + } + baseExpr = expr.getExpr$(); + if (baseExpr instanceof IntegerLiteralExpression) { + this.log$S("folding operator (number) " + expr.getToken$().getNotation$()); + replaceCb(new IntegerLiteralExpression(new Token$3(calculateCb(_Util$0$decodeNumericLiteral$LExpression$(baseExpr)) + ""))); + } else if (baseExpr instanceof NumberLiteralExpression) { + this.log$S("folding operator (number) " + expr.getToken$().getNotation$()); + replaceCb(new NumberLiteralExpression(new Token$3(calculateCb(_Util$0$decodeNumericLiteral$LExpression$(baseExpr)) + ""))); + } + } else if (expr instanceof BitwiseNotExpression) { + baseExpr = expr.getExpr$(); + if (this._isIntegerOrNumberLiteralExpression$LExpression$(baseExpr)) { + this.log$S("folding operator " + expr.getToken$().getNotation$()); + replaceCb(new IntegerLiteralExpression(new Token$3(~ _Util$0$decodeNumericLiteral$LExpression$(baseExpr) + ""))); + } + } else if (expr instanceof AdditiveExpression) { + firstExpr = expr.getFirstExpr$(); + secondExpr = expr.getSecondExpr$(); + if (this._foldNumericBinaryExpression$LBinaryExpression$F$LExpression$V$(expr, replaceCb)) { + } else if (firstExpr instanceof StringLiteralExpression && secondExpr instanceof StringLiteralExpression) { + replaceCb(new StringLiteralExpression(new Token$2(Util$encodeStringLiteral$S(firstExpr.getDecoded$() + secondExpr.getDecoded$()), false))); + } + } else if (expr instanceof EqualityExpression) { + this._foldEqualityExpression$LEqualityExpression$F$LExpression$V$(expr, replaceCb); + } else if (expr instanceof BinaryNumberExpression || expr instanceof ShiftExpression) { + this._foldNumericBinaryExpression$LBinaryExpression$F$LExpression$V$(expr, replaceCb); + } else if (expr instanceof AsExpression) { + this._foldAsExpression$LAsExpression$F$LExpression$V$(expr, replaceCb); + } else if (expr instanceof LogicalNotExpression) { + innerExpr = expr.getExpr$(); + if ((condition = _Util$0$conditionIsConstant$LExpression$(innerExpr)) != null) { + replaceCb(new BooleanLiteralExpression(new Token$2((condition ? "false" : "true"), false))); + } + } else if (expr instanceof LogicalExpression) { + firstExpr = expr.getFirstExpr$(); + secondExpr = expr.getSecondExpr$(); + if ((condition = _Util$0$conditionIsConstant$LExpression$(firstExpr)) != null) { + op = expr.getToken$().getValue$(); + if (op === "||" && condition) { + replaceCb(new AsExpression(firstExpr.getToken$(), firstExpr, Type.booleanType)); + } else if (op === "||" && ! condition) { + replaceCb(new AsExpression(secondExpr.getToken$(), secondExpr, Type.booleanType)); + } else if (op === "&&" && condition) { + replaceCb(new AsExpression(secondExpr.getToken$(), secondExpr, Type.booleanType)); + } else if (op === "&&" && ! condition) { + replaceCb(new AsExpression(firstExpr.getToken$(), firstExpr, Type.booleanType)); + } else { + throw new Error("logic flaw"); + } + } + } else if (expr instanceof ConditionalExpression) { + conditionalExpr = expr; + condExpr = conditionalExpr.getCondExpr$(); + if ((condition = _Util$0$conditionIsConstant$LExpression$(condExpr)) != null) { + ifTrueExpr = conditionalExpr.getIfTrueExpr$() || condExpr; + ifFalseExpr = conditionalExpr.getIfFalseExpr$(); + replaceCb(condition ? ifTrueExpr : ifFalseExpr); + } + } else if (expr instanceof CallExpression) { + callExpr = expr; + if (callExpr.getExpr$() instanceof PropertyExpression) { + allArgsAreConstants = true; + callExpr.getArguments$().forEach((function (expr) { + if (! (expr instanceof IntegerLiteralExpression || expr instanceof NumberLiteralExpression || expr instanceof BooleanLiteralExpression || expr instanceof StringLiteralExpression)) { + allArgsAreConstants = false; + } + })); + if (allArgsAreConstants) { + this._foldCallExpression$LCallExpression$F$LExpression$V$(callExpr, replaceCb); + } + } + } + return true; +}; + + +_FoldConstantCommand.prototype._foldCallExpression$LCallExpression$F$LExpression$V$ = function (callExpr, replaceCb) { + var $this = this; + var propertyExpr; + var holderType; + var argExprs; + var member; + var s; + var recvStr; + propertyExpr = callExpr.getExpr$(); + holderType = propertyExpr.getHolderType$(); + if ((holderType.getClassDef$().flags$() & ClassDefinition.IS_NATIVE) === 0) { + return; + } + argExprs = callExpr.getArguments$(); + member = null; + holderType.getClassDef$().forEachMemberFunction$F$LMemberFunctionDefinition$B$((function (m) { + if (m.name$() === propertyExpr.getIdentifierToken$().getValue$()) { + member = m; + } + return member == null; + })); + if (member != null && (member.flags$() & ClassDefinition.IS_PURE) === 0) { + return; + } + if (propertyExpr.getExpr$().isClassSpecifier$()) { + if (holderType.getClassDef$().classFullName$() === "Math") { + switch (propertyExpr.getIdentifierToken$().getValue$()) { + case "sqrt": + this.log$S("folding " + member.getNotation$()); + replaceCb(new NumberLiteralExpression(new Token$3(Math.sqrt(_Util$0$decodeNumericLiteral$LExpression$(argExprs[0])) + ""))); + break; + case "log": + this.log$S("folding " + member.getNotation$()); + replaceCb(new NumberLiteralExpression(new Token$3(Math.log(_Util$0$decodeNumericLiteral$LExpression$(argExprs[0])) + ""))); + break; + case "pow": + this.log$S("folding " + member.getNotation$()); + replaceCb(new NumberLiteralExpression(new Token$3(Math.pow(_Util$0$decodeNumericLiteral$LExpression$(argExprs[0]), _Util$0$decodeNumericLiteral$LExpression$(argExprs[1])) + ""))); + break; + case "sin": + this.log$S("folding " + member.getNotation$()); + replaceCb(new NumberLiteralExpression(new Token$3(Math.sin(_Util$0$decodeNumericLiteral$LExpression$(argExprs[0])) + ""))); + break; + case "cos": + this.log$S("folding " + member.getNotation$()); + replaceCb(new NumberLiteralExpression(new Token$3(Math.cos(_Util$0$decodeNumericLiteral$LExpression$(argExprs[0])) + ""))); + break; + } + } + if (holderType.getClassDef$().classFullName$() === "String") { + switch (propertyExpr.getIdentifierToken$().getValue$()) { + case "fromCharCode": + this.log$S("folding " + member.getNotation$()); + s = ""; + argExprs.forEach((function (arg) { + s += String.fromCharCode(_Util$0$decodeNumericLiteral$LExpression$(arg)); + })); + replaceCb(new StringLiteralExpression(new Token$3(Util$encodeStringLiteral$S(s)))); + break; + } + } + } else if (propertyExpr.getExpr$() instanceof StringLiteralExpression) { + switch (propertyExpr.getIdentifierToken$().getValue$()) { + case "charCodeAt": + this.log$S("folding " + member.getNotation$()); + recvStr = propertyExpr.getExpr$().getDecoded$(); + replaceCb(new NumberLiteralExpression(new Token$3(recvStr.charCodeAt(_Util$0$decodeNumericLiteral$LExpression$(argExprs[0])) + ""))); + break; + } + } +}; + + +_FoldConstantCommand.prototype._foldEqualityExpression$LEqualityExpression$F$LExpression$V$ = function (expr, replaceCb) { + var $this = this; + var firstExpr; + var secondExpr; + var isEqual; + var isNullVsPrimitiveLiteral; + var result; + firstExpr = expr.getFirstExpr$(); + secondExpr = expr.getSecondExpr$(); + isEqual = null; + function isNullVsPrimitiveLiteral(x, y) { + return x instanceof NullExpression && y instanceof PrimitiveLiteralExpression; + } + if (firstExpr instanceof NullExpression && secondExpr instanceof NullExpression) { + isEqual = true; + } else if (isNullVsPrimitiveLiteral(firstExpr, secondExpr) || isNullVsPrimitiveLiteral(secondExpr, firstExpr)) { + isEqual = false; + } else if (firstExpr instanceof StringLiteralExpression && secondExpr instanceof StringLiteralExpression) { + isEqual = firstExpr.getDecoded$() === secondExpr.getDecoded$(); + } else if (this._isIntegerOrNumberLiteralExpression$LExpression$(firstExpr) && this._isIntegerOrNumberLiteralExpression$LExpression$(secondExpr)) { + isEqual = _Util$0$decodeNumericLiteral$LExpression$(firstExpr) === _Util$0$decodeNumericLiteral$LExpression$(secondExpr); + } + if (isEqual != null) { + result = (expr.getToken$().getValue$() === "==" ? isEqual : ! isEqual); + replaceCb(new BooleanLiteralExpression(new Token$2((result ? "true" : "false"), true))); + } +}; + + +_FoldConstantCommand.prototype._foldNumericBinaryExpression$LBinaryExpression$F$LExpression$V$ = function (expr, replaceCb) { + var $this = this; + var exprIsZero; + var exprIsOne; + if (this._isIntegerOrNumberLiteralExpression$LExpression$(expr.getFirstExpr$()) && this._isIntegerOrNumberLiteralExpression$LExpression$(expr.getSecondExpr$())) { + return this._foldNumericBinaryExpressionOfConstants$LBinaryExpression$F$LExpression$V$(expr, replaceCb); + } + function exprIsZero(expr) { + return expr instanceof NumberLiteralExpression && expr.getDecoded$() === 0; + } + function exprIsOne(expr) { + return expr instanceof NumberLiteralExpression && expr.getDecoded$() === 1; + } + switch (expr.getToken$().getValue$()) { + case "+": + if (exprIsZero(expr.getFirstExpr$())) { + replaceCb(expr.getSecondExpr$()); return true; - } else if (expr instanceof NewExpression) { - Util$forEachExpression$F$LExpression$F$LExpression$V$B$ALExpression$(onExpr, expr.getArguments$()); - lastAssignExpr = {}; + } else if (exprIsZero(expr.getSecondExpr$())) { + replaceCb(expr.getFirstExpr$()); + return true; + } + break; + case "-": + if (exprIsZero(expr.getFirstExpr$())) { + replaceCb(new SignExpression(new Token$2("-", false), expr.getSecondExpr$())); + return true; + } else if (exprIsZero(expr.getSecondExpr$())) { + replaceCb(expr.getFirstExpr$()); + return true; + } + break; + case "*": + if (exprIsOne(expr.getFirstExpr$())) { + replaceCb(expr.getSecondExpr$()); + return true; + } else if (exprIsOne(expr.getSecondExpr$())) { + replaceCb(expr.getFirstExpr$()); + return true; + } + break; + case "/": + if (exprIsOne(expr.getSecondExpr$())) { + replaceCb(expr.getFirstExpr$()); return true; } - return expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); - }); - Util$forEachExpression$F$LExpression$F$LExpression$V$B$ALExpression$(onExpr, exprs); + break; + } + return false; +}; + + +_FoldConstantCommand.prototype._foldNumericBinaryExpressionOfConstants$LBinaryExpression$F$LExpression$V$ = function (expr, replaceCb) { + var $this = this; + switch (expr.getToken$().getValue$()) { + case "+": + this._foldNumericBinaryExpressionAsNumeric$LBinaryExpression$F$LExpression$V$F$III$F$NNN$(expr, replaceCb, (function (x, y) { + return ((x + y) | 0); + }), (function (x, y) { + return x + y; + })); + break; + case "-": + this._foldNumericBinaryExpressionAsNumeric$LBinaryExpression$F$LExpression$V$F$III$F$NNN$(expr, replaceCb, (function (x, y) { + return ((x - y) | 0); + }), (function (x, y) { + return x - y; + })); + break; + case "*": + this._foldNumericBinaryExpressionAsNumeric$LBinaryExpression$F$LExpression$V$F$III$F$NNN$(expr, replaceCb, (function (x, y) { + return $__jsx_imul(x, y); + }), (function (x, y) { + return x * y; + })); + break; + case "/": + this._foldNumericBinaryExpressionAsNumber$LBinaryExpression$F$LExpression$V$F$NNN$(expr, replaceCb, (function (x, y) { + return x / y; + })); + break; + case "%": + this._foldNumericBinaryExpressionAsNumber$LBinaryExpression$F$LExpression$V$F$NNN$(expr, replaceCb, (function (x, y) { + return x % y; + })); + break; + case ">>>": + this._foldNumericBinaryExpressionAsInteger$LBinaryExpression$F$LExpression$V$F$III$(expr, replaceCb, (function (x, y) { + return x >>> y; + })); + break; + case ">>": + this._foldNumericBinaryExpressionAsInteger$LBinaryExpression$F$LExpression$V$F$III$(expr, replaceCb, (function (x, y) { + return x >> y; + })); + break; + case "<<": + this._foldNumericBinaryExpressionAsInteger$LBinaryExpression$F$LExpression$V$F$III$(expr, replaceCb, (function (x, y) { + return x << y; + })); + break; + case "&": + this._foldNumericBinaryExpressionAsInteger$LBinaryExpression$F$LExpression$V$F$III$(expr, replaceCb, (function (x, y) { + return x & y; + })); + break; + case "|": + this._foldNumericBinaryExpressionAsInteger$LBinaryExpression$F$LExpression$V$F$III$(expr, replaceCb, (function (x, y) { + return x | y; + })); + break; + case "^": + this._foldNumericBinaryExpressionAsInteger$LBinaryExpression$F$LExpression$V$F$III$(expr, replaceCb, (function (x, y) { + return x ^ y; + })); + break; + case "<": + this._foldNumericBinaryExpressionAsBoolean$LBinaryExpression$F$LExpression$V$F$NNB$(expr, replaceCb, (function (x, y) { + return x < y; + })); + break; + case "<=": + this._foldNumericBinaryExpressionAsBoolean$LBinaryExpression$F$LExpression$V$F$NNB$(expr, replaceCb, (function (x, y) { + return x <= y; + })); + break; + case ">": + this._foldNumericBinaryExpressionAsBoolean$LBinaryExpression$F$LExpression$V$F$NNB$(expr, replaceCb, (function (x, y) { + return x > y; + })); + break; + case ">=": + this._foldNumericBinaryExpressionAsBoolean$LBinaryExpression$F$LExpression$V$F$NNB$(expr, replaceCb, (function (x, y) { + return x >= y; + })); + break; + default: + return false; + } + return true; +}; + + +_FoldConstantCommand.prototype._foldNumericBinaryExpressionAsNumeric$LBinaryExpression$F$LExpression$V$F$III$F$NNN$ = function (expr, replaceCb, calcCbInt, calcCbNumber) { + if (expr.getFirstExpr$() instanceof IntegerLiteralExpression && expr.getSecondExpr$() instanceof IntegerLiteralExpression) { + this._foldNumericBinaryExpressionAsInteger$LBinaryExpression$F$LExpression$V$F$III$(expr, replaceCb, calcCbInt); + } else { + this._foldNumericBinaryExpressionAsNumber$LBinaryExpression$F$LExpression$V$F$NNN$(expr, replaceCb, calcCbNumber); + } +}; + + +_FoldConstantCommand.prototype._foldNumericBinaryExpressionAsInteger$LBinaryExpression$F$LExpression$V$F$III$ = function (expr, replaceCb, calcCb) { + var value; + value = calcCb((_Util$0$decodeNumericLiteral$LExpression$(expr.getFirstExpr$()) | 0), (_Util$0$decodeNumericLiteral$LExpression$(expr.getSecondExpr$()) | 0)); + this.log$S("folding operator " + expr.getToken$().getNotation$() + " to int: " + (value + "")); + if (value !== (value | 0)) { + throw new Error("value is not an integer"); + } + replaceCb(new IntegerLiteralExpression(new Token$3(value + ""))); +}; + + +_FoldConstantCommand.prototype._foldNumericBinaryExpressionAsNumber$LBinaryExpression$F$LExpression$V$F$NNN$ = function (expr, replaceCb, calcCb) { + var value; + value = calcCb(_Util$0$decodeNumericLiteral$LExpression$(expr.getFirstExpr$()), _Util$0$decodeNumericLiteral$LExpression$(expr.getSecondExpr$())); + this.log$S("folding operator " + expr.getToken$().getNotation$() + " to number: " + (value + "")); + replaceCb(new NumberLiteralExpression(new Token$3(value + ""))); +}; + + +_FoldConstantCommand.prototype._foldNumericBinaryExpressionAsBoolean$LBinaryExpression$F$LExpression$V$F$NNB$ = function (expr, replaceCb, calcCb) { + var value; + value = calcCb(_Util$0$decodeNumericLiteral$LExpression$(expr.getFirstExpr$()), _Util$0$decodeNumericLiteral$LExpression$(expr.getSecondExpr$())); + this.log$S("folding operator " + expr.getToken$().getNotation$() + " to boolean: " + (value + "")); + replaceCb(new BooleanLiteralExpression(new Token$3(value + ""))); +}; + + +_FoldConstantCommand.prototype._isIntegerOrNumberLiteralExpression$LExpression$ = function (expr) { + return expr instanceof NumberLiteralExpression || expr instanceof IntegerLiteralExpression; +}; + + +_FoldConstantCommand.prototype._foldStaticConst$LMemberVariableDefinition$ = function (member) { + var $this = this; + var stash; + var initialValue; + stash = this.getStash$LStashable$(member); + if (stash.isOptimized) { + return; + } + stash.isOptimized = true; + initialValue = member.getInitialValue$(); + if (initialValue != null) { + this._optimizeExpression$LExpression$F$LExpression$V$(initialValue, (function (expr) { + member.setInitialValue$LExpression$(expr); + })); + } +}; + + +_FoldConstantCommand.prototype._toFoldedExpr$LExpression$LType$ = function (expr, type) { + if (expr instanceof NullExpression) { + return expr; + } else if (expr instanceof BooleanLiteralExpression) { + return expr; + } else if (expr instanceof IntegerLiteralExpression) { + return expr; + } else if (expr instanceof NumberLiteralExpression) { + if (type.resolveIfNullable$().equals$LType$(Type.integerType)) { + return new IntegerLiteralExpression(new Token$3((expr.getDecoded$() | 0) + "")); + } + return expr; + } else if (expr instanceof StringLiteralExpression) { + return expr; + } + return null; +}; + + +_FoldConstantCommand.prototype._foldAsExpression$LAsExpression$F$LExpression$V$ = function (expr, replaceCb) { + var baseExpr; + baseExpr = expr.getExpr$(); + if (expr.getType$().equals$LType$(Type.stringType)) { + if (baseExpr.getType$().equals$LType$(Type.stringType)) { + this.log$S("folding type cast: string as string"); + replaceCb(baseExpr); + } else if (baseExpr instanceof PrimitiveLiteralExpression) { + this.log$S("folding type cast: primitive literal as string"); + replaceCb(new StringLiteralExpression(new Token$2(Util$encodeStringLiteral$S(baseExpr.toNormalizedString$()), false))); + } + } else if (expr.getType$().equals$LType$(Type.numberType)) { + if (baseExpr.getType$().equals$LType$(Type.numberType)) { + this.log$S("folding type cast: number as number"); + replaceCb(baseExpr); + } else if (baseExpr instanceof StringLiteralExpression) { + this.log$S("folding type cast: string literal as number"); + replaceCb(new NumberLiteralExpression(new Token$2(+baseExpr.getDecoded$() + "", false))); + } else if (baseExpr instanceof IntegerLiteralExpression) { + this.log$S("folding type cast: int literal as number"); + replaceCb(new NumberLiteralExpression(new Token$2(+baseExpr.getDecoded$() + "", false))); + } + } else if (expr.getType$().equals$LType$(Type.integerType)) { + if (baseExpr.getType$().equals$LType$(Type.integerType)) { + this.log$S("folding type cast: int as int"); + replaceCb(baseExpr); + } else if (baseExpr instanceof StringLiteralExpression) { + this.log$S("folding type cast: string literal as int"); + replaceCb(new IntegerLiteralExpression(new Token$2((baseExpr.getDecoded$() | 0) + "", false))); + } else if (baseExpr instanceof NumberLiteralExpression) { + this.log$S("folding type cast: number literal as int"); + replaceCb(new IntegerLiteralExpression(new Token$2((baseExpr.getDecoded$() | 0) + "", false))); + } + } else if (expr.getType$().equals$LType$(Type.booleanType)) { + if (baseExpr.getType$().equals$LType$(Type.booleanType)) { + this.log$S("folding type cast: boolean as boolean"); + replaceCb(baseExpr); + } else if (baseExpr instanceof StringLiteralExpression) { + this.log$S("folding type cast: string literal as boolean"); + replaceCb(new BooleanLiteralExpression(new Token$2(!! baseExpr.getDecoded$() + "", false))); + } else if (baseExpr instanceof NumberLiteralExpression) { + this.log$S("folding type cast: number literal as boolean"); + replaceCb(new BooleanLiteralExpression(new Token$2((baseExpr.getDecoded$() ? "true" : "false"), false))); + } else if (baseExpr instanceof IntegerLiteralExpression) { + this.log$S("folding type cast: integer literal as boolean"); + replaceCb(new BooleanLiteralExpression(new Token$2((baseExpr.getDecoded$() ? "true" : "false"), false))); + } + } }; -_DeadCodeEliminationOptimizeCommand.prototype._eliminateDeadConditions$LMemberFunctionDefinition$ALExpression$ = function (funcDef, exprs) { - var $this = this; - var spliceStatements; - function spliceStatements(dest, index, src) { - var i; - dest.splice(index, 1); - for (i = 0; i < src.length; ++i) { - dest.splice(index + i, 0, src[i]); - } +function _StructuredStashAccessor$x2E$x3CStash$x3E$4() { +}; + +$__jsx_extend([_StructuredStashAccessor$x2E$x3CStash$x3E$4], Object); +_StructuredStashAccessor$x2E$x3CStash$x3E$4.prototype.$__jsx_implements__StructuredStashAccessor$x2E$x3CStash$x3E$4 = true; + +_StructuredStashAccessor$x2E$x3CStash$x3E$4.prototype.getStash$LStashable$ = function (stashable) { + var identifier; + var stash; + identifier = this._identifier; + stash = stashable.getStash$S(identifier); + if (stash == null) { + stash = new _InlineOptimizeCommand$x2EStash(); + stashable.setStash$SLStash$(identifier, stash); } - (function onStatements(statements) { - var i; - var statement; - var ifStatement; - var cond; - for (i = statements.length - 1; i >= 0; --i) { - statement = statements[i]; - if (statement instanceof IfStatement) { - ifStatement = statement; - cond = _Util$0$conditionIsConstant$LExpression$(ifStatement.getExpr$()); - if (cond == null) { - } else if (cond === false && ifStatement.getOnFalseStatements$().length === 0) { - statements.splice(i, 1); - } else if (cond === false) { - spliceStatements(statements, i, ifStatement.getOnFalseStatements$()); - } else if (cond === true) { - spliceStatements(statements, i, ifStatement.getOnTrueStatements$()); - } - } - statement.handleStatements$F$ALStatement$B$(onStatements); - } - return true; - })(funcDef.getStatements$()); + return stash; +}; + + +_StructuredStashAccessor$x2E$x3CStash$x3E$4.prototype.resetStash$LStashable$ = function (stashable) { + var identifier; + identifier = this._identifier; + stashable.setStash$SLStash$(identifier, null); }; function _InlineOptimizeCommand() { _FunctionOptimizeCommand.call(this, _InlineOptimizeCommand.IDENTIFIER); + _StructuredStashAccessor$x2E$x3CStash$x3E$4.call(this); }; $__jsx_extend([_InlineOptimizeCommand], _FunctionOptimizeCommand); -_InlineOptimizeCommand.prototype._createStash$ = function () { - return new _InlineOptimizeCommand$x2EStash(); -}; - +$__jsx_merge_interface(_InlineOptimizeCommand, _StructuredStashAccessor$x2E$x3CStash$x3E$4); _InlineOptimizeCommand.prototype.optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { var stash; @@ -21619,7 +22347,7 @@ _InlineOptimizeCommand.prototype._expandStatementExpression$LMemberFunctionDefin cb(stmtIndex); return true; } - } else if (expr instanceof AssignmentExpression && ! Util$lhsHasSideEffects$LExpression$(expr.getFirstExpr$()) && expr.getSecondExpr$() instanceof CallExpression) { + } else if (expr instanceof AssignmentExpression && ! expr.getFirstExpr$().hasSideEffects$() && expr.getSecondExpr$() instanceof CallExpression) { args = this._getArgsAndThisIfCallExprIsInlineable$LCallExpression$(expr.getSecondExpr$()); if (args != null) { stmtIndex = this._expandCallingFunction$LMemberFunctionDefinition$ALStatement$NLMemberFunctionDefinition$ALExpression$(funcDef, statements, stmtIndex, _DetermineCalleeCommand$getCallingFuncDef$LStashable$(expr.getSecondExpr$()), args); @@ -21962,329 +22690,82 @@ _InlineOptimizeCommand.prototype._rewriteExpression$LExpression$LExpression$F$LE localExpr = expr; for (j = 0; j < formalArgs.length; ++j) { if (formalArgs[j].getName$().getValue$() === localExpr.getLocal$().getName$().getValue$()) { - break; - } - } - if (j === formalArgs.length) { - ++j; - locals = calleeFuncDef.getLocals$(); - for (k = 0; k < locals.length; (++k, ++j)) { - if (locals[k].getName$().getValue$() === localExpr.getLocal$().getName$().getValue$()) { - break; - } - } - } - if (j !== argsAndThisAndLocals.length) { - if (argsAndThisAndLocals[j] instanceof FunctionExpression) { - replaceCb(argsAndThisAndLocals[j]); - argsAndThisAndLocals[j] = null; - } else { - if (parentExpr != null && parentExpr instanceof AssignmentExpression && parentExpr.getFirstExpr$() == expr && ! (argsAndThisAndLocals[j] instanceof LocalExpression)) { - return true; - } - replaceCb(argsAndThisAndLocals[j].clone$()); - } - } - } else if (expr instanceof ThisExpression) { - replaceCb(argsAndThisAndLocals[formalArgs.length].clone$()); - } - expr.forEachExpression$F$LExpression$F$LExpression$V$B$((function (childExpr, replaceCb) { - return $this._rewriteExpression$LExpression$LExpression$F$LExpression$V$ALExpression$LMemberFunctionDefinition$(childExpr, expr, replaceCb, argsAndThisAndLocals, calleeFuncDef); - })); - return true; -}; - - -_InlineOptimizeCommand.prototype._functionHasThis$LMemberFunctionDefinition$ = function (funcDef) { - do { - if ((funcDef.flags$() & ClassDefinition.IS_STATIC) === 0) { - return true; - } - } while ((funcDef = funcDef.getParent$()) != null); - return false; -}; - - -function _ReturnIfOptimizeCommand() { - _FunctionOptimizeCommand.call(this, _ReturnIfOptimizeCommand.IDENTIFIER); - this._altered = false; -}; - -$__jsx_extend([_ReturnIfOptimizeCommand], _FunctionOptimizeCommand); -_ReturnIfOptimizeCommand.prototype.optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { - if (funcDef.getReturnType$() == null || funcDef.getReturnType$().equals$LType$(Type.voidType)) { - return false; - } - this._altered = false; - this._optimizeStatements$ALStatement$(funcDef.getStatements$()); - this.log$S(funcDef.getNotation$() + " " + (this._altered ? "Y" : "N")); - return this._altered; -}; - - -_ReturnIfOptimizeCommand.prototype._statementsCanBeReturnExpr$ALStatement$ = function (statements) { - if (statements.length === 1 && statements[0] instanceof ReturnStatement) { - return true; - } - this._optimizeStatements$ALStatement$(statements); - if (statements.length === 1 && statements[0] instanceof ReturnStatement) { - return true; - } - return false; -}; - - -_ReturnIfOptimizeCommand.prototype._optimizeStatements$ALStatement$ = function (statements) { - var ifStatement; - var onFalseStatements; - if (statements.length >= 1 && statements[statements.length - 1] instanceof IfStatement) { - ifStatement = statements[statements.length - 1]; - if (this._statementsCanBeReturnExpr$ALStatement$(ifStatement.getOnTrueStatements$()) && this._statementsCanBeReturnExpr$ALStatement$(ifStatement.getOnFalseStatements$())) { - statements[statements.length - 1] = this._createReturnStatement$LToken$LExpression$LExpression$LExpression$(ifStatement.getToken$(), ifStatement.getExpr$(), ifStatement.getOnTrueStatements$()[0].getExpr$(), ifStatement.getOnFalseStatements$()[0].getExpr$()); - this._altered = true; - this._optimizeStatements$ALStatement$(statements); - } - } else if (statements.length >= 2 && statements[statements.length - 1] instanceof ReturnStatement && statements[statements.length - 2] instanceof IfStatement) { - ifStatement = statements[statements.length - 2]; - if (this._statementsCanBeReturnExpr$ALStatement$(ifStatement.getOnTrueStatements$())) { - onFalseStatements = ifStatement.getOnFalseStatements$(); - if (onFalseStatements.length === 0) { - statements.splice(statements.length - 2, 2, this._createReturnStatement$LToken$LExpression$LExpression$LExpression$(ifStatement.getToken$(), ifStatement.getExpr$(), ifStatement.getOnTrueStatements$()[0].getExpr$(), statements[statements.length - 1].getExpr$())); - this._altered = true; - this._optimizeStatements$ALStatement$(statements); - } else if (onFalseStatements.length === 1 && onFalseStatements[0] instanceof IfStatement && onFalseStatements[0].getOnFalseStatements$().length === 0) { - onFalseStatements[0].getOnFalseStatements$().push(statements[statements.length - 1]); - statements.pop(); - this._altered = true; - this._optimizeStatements$ALStatement$(statements); - } - } - } -}; - - -_ReturnIfOptimizeCommand.prototype._createReturnStatement$LToken$LExpression$LExpression$LExpression$ = function (token, condExpr, trueExpr, falseExpr) { - return new ReturnStatement(token, new ConditionalExpression$0(new Token$2("?", false), condExpr, trueExpr, falseExpr, falseExpr.getType$())); -}; - - -function _LCSECachedExpression(origExpr, replaceCb) { - this._origExpr = origExpr; - this._replaceCb = replaceCb; - this._localExpr = null; -}; - -$__jsx_extend([_LCSECachedExpression], Object); -_LCSECachedExpression.prototype.getOrigExpr$ = function () { - return this._origExpr; -}; - - -_LCSECachedExpression.prototype.getLocalExpr$F$LType$SLLocalExpression$$ = function (createVarCb) { - if (this._localExpr == null) { - this._localExpr = createVarCb(this._origExpr.getType$(), this._origExpr.getIdentifierToken$().getValue$()); - this._replaceCb(new AssignmentExpression(new Token$2("=", false), this._localExpr, this._origExpr)); - } - return this._localExpr; -}; - - -function _LCSEOptimizeCommand() { - _FunctionOptimizeCommand.call(this, _LCSEOptimizeCommand.IDENTIFIER); -}; - -$__jsx_extend([_LCSEOptimizeCommand], _FunctionOptimizeCommand); -_LCSEOptimizeCommand.prototype.optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { - var $this = this; - _Util$0$optimizeBasicBlock$LMemberFunctionDefinition$F$ALExpression$V$(funcDef, (function (exprs) { - $this._optimizeExpressions$LMemberFunctionDefinition$ALExpression$(funcDef, exprs); - })); - return true; -}; - - -_LCSEOptimizeCommand.prototype._optimizeExpressions$LMemberFunctionDefinition$ALExpression$ = function (funcDef, exprs) { - var $this = this; - var cachedExprs; - var getCacheKey; - var registerCacheable; - var clearCacheByLocalName; - var clearCache; - this.log$S("optimizing expressions starting"); - cachedExprs = {}; - getCacheKey = (function (expr) { - var propertyExpr; - var receiverType; - var base; - if (expr instanceof PropertyExpression) { - propertyExpr = expr; - receiverType = propertyExpr.getExpr$().getType$(); - if (Util$isNativeClass$LType$(receiverType)) { - return null; - } - base = getCacheKey(propertyExpr.getExpr$()); - if (base == null) { - return null; - } - return base + "." + propertyExpr.getIdentifierToken$().getValue$(); - } else if (expr instanceof LocalExpression) { - return expr.getLocal$().getName$().getValue$(); - } else if (expr instanceof ThisExpression) { - return "this"; - } - return null; - }); - registerCacheable = (function (key, expr, replaceCb) { - $this.log$S("registering lcse entry for: " + key); - cachedExprs[key] = new _LCSECachedExpression(expr, replaceCb); - }); - clearCacheByLocalName = (function (name) { - var k; - $this.log$S("clearing lcse entry for local name: " + name); - for (k in cachedExprs) { - if (k.substring(0, name.length + 1) === name + ".") { - $this.log$S(" removing: " + k); - delete cachedExprs[k]; + break; } } - }); - clearCache = (function () { - $this.log$S("clearing lcse cache"); - cachedExprs = {}; - }); - Util$forEachExpression$F$LExpression$F$LExpression$V$B$ALExpression$((function onExpr(expr, replaceCb) { - var assignmentExpr; - var lhsExpr; - var lhsPropertyExpr; - var cacheKey; - var incrementExpr; - var propertyExpr; - var conditionalExpr; - var funcExpr; - var args; - var i; - if (expr instanceof AssignmentExpression || expr instanceof FusedAssignmentExpression) { - assignmentExpr = expr; - lhsExpr = assignmentExpr.getFirstExpr$(); - if (lhsExpr instanceof LocalExpression) { - onExpr(assignmentExpr.getSecondExpr$(), (function (expr) { - assignmentExpr.setSecondExpr$LExpression$(expr); - })); - clearCacheByLocalName(lhsExpr.getLocal$().getName$().getValue$()); - } else if (lhsExpr instanceof PropertyExpression) { - lhsPropertyExpr = lhsExpr; - onExpr(lhsExpr.getExpr$(), (function (expr) { - lhsPropertyExpr.setExpr$LExpression$(expr); - })); - onExpr(assignmentExpr.getSecondExpr$(), (function (expr) { - assignmentExpr.setSecondExpr$LExpression$(expr); - })); - if (lhsPropertyExpr.getIdentifierToken$().getValue$() === "length") { - } else { - cacheKey = getCacheKey(lhsExpr); - if (cacheKey) { - registerCacheable(cacheKey, lhsExpr, (function (expr) { - assignmentExpr.setFirstExpr$LExpression$(expr); - })); - } + if (j === formalArgs.length) { + ++j; + locals = calleeFuncDef.getLocals$(); + for (k = 0; k < locals.length; (++k, ++j)) { + if (locals[k].getName$().getValue$() === localExpr.getLocal$().getName$().getValue$()) { + break; } - } else { - clearCache(); - } - return true; - } else if (expr instanceof IncrementExpression) { - incrementExpr = expr; - if (incrementExpr.getExpr$() instanceof PropertyExpression) { - propertyExpr = incrementExpr.getExpr$(); - onExpr(propertyExpr.getExpr$(), (function (expr) { - propertyExpr.setExpr$LExpression$(expr); - })); - } - clearCache(); - return true; - } else if (expr instanceof ConditionalExpression) { - conditionalExpr = expr; - onExpr(conditionalExpr.getCondExpr$(), (function (expr) { - conditionalExpr.setCondExpr$LExpression$(expr); - })); - clearCache(); - return true; - } else if (expr instanceof LogicalExpression) { - if (! expr.forEachExpression$F$LExpression$B$((function (expr) { - return ! _Util$0$exprHasSideEffects$LExpression$(expr); - }))) { - clearCache(); - return true; - } - } else if (expr instanceof FunctionExpression) { - clearCache(); - return true; - } else if (expr instanceof CallExpression) { - funcExpr = expr.getExpr$(); - if (funcExpr instanceof LocalExpression) { - } else if (funcExpr instanceof PropertyExpression) { - propertyExpr = funcExpr; - onExpr(propertyExpr.getExpr$(), (function (expr) { - propertyExpr.setExpr$LExpression$(expr); - })); - } else { - clearCache(); - } - args = expr.getArguments$(); - for (i = 0; i < args.length; ++i) { - onExpr(args[i], (function (args, index) { - return (function (expr) { - args[index] = expr; - }); - })(args, i)); } - clearCache(); - return true; - } else if (expr instanceof NewExpression) { - $this.log$S("new expression"); - args = expr.getArguments$(); - for (i = 0; i < args.length; ++i) { - onExpr(args[i], (function (args, index) { - return (function (expr) { - args[index] = expr; - }); - })(args, i)); - } - clearCache(); - return true; } - if (expr instanceof PropertyExpression) { - if (expr.getIdentifierToken$().getValue$() === "length") { + if (j !== argsAndThisAndLocals.length) { + if (argsAndThisAndLocals[j] instanceof FunctionExpression) { + replaceCb(argsAndThisAndLocals[j]); + argsAndThisAndLocals[j] = null; } else { - cacheKey = getCacheKey(expr); - if (cacheKey) { - $this.log$S("rewriting cse for: " + cacheKey); - if (cachedExprs[cacheKey]) { - replaceCb(cachedExprs[cacheKey].getLocalExpr$F$LType$SLLocalExpression$$((function (type, baseName) { - var localVar; - localVar = $this.createVar$LMemberFunctionDefinition$LType$S(funcDef, type, baseName); - return new LocalExpression(localVar.getName$(), localVar); - })).clone$()); - } else { - registerCacheable(cacheKey, expr, replaceCb); - } + if (parentExpr != null && parentExpr instanceof AssignmentExpression && parentExpr.getFirstExpr$() == expr && ! (argsAndThisAndLocals[j] instanceof LocalExpression)) { + return true; } + replaceCb(argsAndThisAndLocals[j].clone$()); } } - return expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); - }), exprs); + } else if (expr instanceof ThisExpression) { + replaceCb(argsAndThisAndLocals[formalArgs.length].clone$()); + } + expr.forEachExpression$F$LExpression$F$LExpression$V$B$((function (childExpr, replaceCb) { + return $this._rewriteExpression$LExpression$LExpression$F$LExpression$V$ALExpression$LMemberFunctionDefinition$(childExpr, expr, replaceCb, argsAndThisAndLocals, calleeFuncDef); + })); + return true; +}; + + +_InlineOptimizeCommand.prototype._functionHasThis$LMemberFunctionDefinition$ = function (funcDef) { + do { + if ((funcDef.flags$() & ClassDefinition.IS_STATIC) === 0) { + return true; + } + } while ((funcDef = funcDef.getParent$()) != null); + return false; +}; + + +function _StructuredStashAccessor$x2E$x3CStash$x3E$5() { +}; + +$__jsx_extend([_StructuredStashAccessor$x2E$x3CStash$x3E$5], Object); +_StructuredStashAccessor$x2E$x3CStash$x3E$5.prototype.$__jsx_implements__StructuredStashAccessor$x2E$x3CStash$x3E$5 = true; + +_StructuredStashAccessor$x2E$x3CStash$x3E$5.prototype.getStash$LStashable$ = function (stashable) { + var identifier; + var stash; + identifier = this._identifier; + stash = stashable.getStash$S(identifier); + if (stash == null) { + stash = new _UnboxOptimizeCommand$x2EStash(); + stashable.setStash$SLStash$(identifier, stash); + } + return stash; +}; + + +_StructuredStashAccessor$x2E$x3CStash$x3E$5.prototype.resetStash$LStashable$ = function (stashable) { + var identifier; + identifier = this._identifier; + stashable.setStash$SLStash$(identifier, null); }; function _UnboxOptimizeCommand() { _FunctionOptimizeCommand.call(this, _UnboxOptimizeCommand.IDENTIFIER); + _StructuredStashAccessor$x2E$x3CStash$x3E$5.call(this); }; $__jsx_extend([_UnboxOptimizeCommand], _FunctionOptimizeCommand); -_UnboxOptimizeCommand.prototype._createStash$ = function () { - return new _UnboxOptimizeCommand$x2EStash(); -}; - +$__jsx_merge_interface(_UnboxOptimizeCommand, _StructuredStashAccessor$x2E$x3CStash$x3E$5); _UnboxOptimizeCommand.prototype.optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { var locals; @@ -22313,7 +22794,7 @@ _UnboxOptimizeCommand.prototype._optimizeLocal$LMemberFunctionDefinition$LLocalV if (! (local.getType$() instanceof ObjectType)) { return false; } - if (Util$isNativeClass$LType$(local.getType$())) { + if (Util$rootIsNativeClass$LType$(local.getType$())) { return false; } foundNew = false; @@ -22494,196 +22975,85 @@ _UnboxOptimizeCommand.prototype._unboxVariable$LMemberFunctionDefinition$LLocalV return true; }); if (statements[statementIndex] instanceof FunctionStatement) { - onStatements(statements[statementIndex].getFuncDef$().getStatements$()); - ++statementIndex; - } else { - newExpr = $this._statementIsConstructingTheLocal$LStatement$LLocalVariable$(statements[statementIndex], local); - if (newExpr != null) { - statements.splice(statementIndex, 1); - statementIndex = buildConstructingStatements(statements, statementIndex, newExpr); - } else { - statements[statementIndex].forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); - statements[statementIndex].handleStatements$F$ALStatement$B$(onStatements); - ++statementIndex; - } - } - } - return true; - }); - onStatements(funcDef.getStatements$()); -}; - - -_UnboxOptimizeCommand.prototype._statementIsConstructingTheLocal$LStatement$LLocalVariable$ = function (statement, local) { - var expr; - var lhsExpr; - var rhsExpr; - if (! (statement instanceof ExpressionStatement)) { - return null; - } - expr = statement.getExpr$(); - if (! (expr instanceof AssignmentExpression)) { - return null; - } - lhsExpr = expr.getFirstExpr$(); - if (! (lhsExpr instanceof LocalExpression)) { - return null; - } - if (lhsExpr.getLocal$() != local) { - return null; - } - rhsExpr = expr.getSecondExpr$(); - if (! (rhsExpr instanceof NewExpression)) { - return null; - } - return rhsExpr; -}; - - -function _ArrayLengthOptimizeCommand() { - _FunctionOptimizeCommand.call(this, _ArrayLengthOptimizeCommand.IDENTIFIER); -}; - -$__jsx_extend([_ArrayLengthOptimizeCommand], _FunctionOptimizeCommand); -_ArrayLengthOptimizeCommand.prototype.optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { - var $this = this; - funcDef.forEachStatement$F$LStatement$B$((function onStatement(statement) { - var condExpr; - var arrayLocal; - statement.forEachStatement$F$LStatement$B$(onStatement); - if (statement instanceof ForStatement) { - condExpr = statement.getCondExpr$(); - arrayLocal = (condExpr != null ? $this._hasLengthExprOfLocalArray$LExpression$(condExpr) : null); - if (arrayLocal != null) { - $this._optimizeArrayLength$LMemberFunctionDefinition$LForStatement$LLocalVariable$(funcDef, statement, arrayLocal); - } - } - return true; - })); - return true; -}; - - -_ArrayLengthOptimizeCommand.prototype._optimizeArrayLength$LMemberFunctionDefinition$LForStatement$LLocalVariable$ = function (funcDef, statement, arrayLocal) { - var $this = this; - var lengthLocal; - var assignToLocal; - var onExpr; - if (this._lengthIsUnmodifiedInExpr$LExpression$(statement.getCondExpr$()) && this._lengthIsUnmodifiedInExpr$LExpression$(statement.getPostExpr$()) && statement.forEachStatement$F$LStatement$B$((function (statement) { - return $this._lengthIsUnmodifiedInStatement$LStatement$(statement); - }))) { - this.log$S(funcDef.getNotation$() + " optimizing " + statement.getToken$().getNotation$()); - lengthLocal = this.createVar$LMemberFunctionDefinition$LType$S(funcDef, Type.integerType, arrayLocal.getName$().getValue$() + "$len"); - assignToLocal = new AssignmentExpression(new Token$3("="), new LocalExpression(new Token$2(lengthLocal.getName$().getValue$(), true), lengthLocal), new PropertyExpression$0(new Token$3("."), new LocalExpression(new Token$2(arrayLocal.getName$().getValue$(), true), arrayLocal), new Token$3("length"), [], lengthLocal.getType$())); - if (statement.getInitExpr$() != null) { - statement.setInitExpr$LExpression$(new CommaExpression(new Token$3(","), statement.getInitExpr$(), assignToLocal)); - } else { - statement.setInitExpr$LExpression$(assignToLocal); - } - onExpr = (function (expr, replaceCb) { - if (expr instanceof PropertyExpression && expr.getIdentifierToken$().getValue$() === "length" && expr.getExpr$() instanceof LocalExpression && expr.getExpr$().getLocal$() == arrayLocal) { - replaceCb(new LocalExpression(new Token$2(lengthLocal.getName$().getValue$(), true), lengthLocal)); + onStatements(statements[statementIndex].getFuncDef$().getStatements$()); + ++statementIndex; } else { - expr.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); + newExpr = $this._statementIsConstructingTheLocal$LStatement$LLocalVariable$(statements[statementIndex], local); + if (newExpr != null) { + statements.splice(statementIndex, 1); + statementIndex = buildConstructingStatements(statements, statementIndex, newExpr); + } else { + statements[statementIndex].forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); + statements[statementIndex].handleStatements$F$ALStatement$B$(onStatements); + ++statementIndex; + } } - return true; - }); - statement.getCondExpr$().forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); - statement.getPostExpr$().forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); - statement.forEachStatement$F$LStatement$B$((function onStatement2(statement) { - statement.forEachStatement$F$LStatement$B$(onStatement2); - statement.forEachExpression$F$LExpression$F$LExpression$V$B$(onExpr); - return true; - })); - } -}; - - -_ArrayLengthOptimizeCommand.prototype._hasLengthExprOfLocalArray$LExpression$ = function (expr) { - var $this = this; - var local; - local = null; - expr.forEachExpression$F$LExpression$B$((function onExpr(expr) { - if (expr instanceof PropertyExpression && expr.getIdentifierToken$().getValue$() === "length" && expr.getExpr$() instanceof LocalExpression && $this._typeIsArray$LType$(expr.getExpr$().getType$().resolveIfNullable$())) { - local = expr.getExpr$().getLocal$(); - return false; } - return expr.forEachExpression$F$LExpression$B$(onExpr); - })); - return local; + return true; + }); + onStatements(funcDef.getStatements$()); }; -_ArrayLengthOptimizeCommand.prototype._lengthIsUnmodifiedInStatement$LStatement$ = function (statement) { - var $this = this; - if (! statement.forEachStatement$F$LStatement$B$((function (statement) { - return $this._lengthIsUnmodifiedInStatement$LStatement$(statement); - }))) { - return false; +_UnboxOptimizeCommand.prototype._statementIsConstructingTheLocal$LStatement$LLocalVariable$ = function (statement, local) { + var expr; + var lhsExpr; + var rhsExpr; + if (! (statement instanceof ExpressionStatement)) { + return null; } - return statement.forEachExpression$F$LExpression$B$((function (expr) { - return $this._lengthIsUnmodifiedInExpr$LExpression$(expr); - })); + expr = statement.getExpr$(); + if (! (expr instanceof AssignmentExpression)) { + return null; + } + lhsExpr = expr.getFirstExpr$(); + if (! (lhsExpr instanceof LocalExpression)) { + return null; + } + if (lhsExpr.getLocal$() != local) { + return null; + } + rhsExpr = expr.getSecondExpr$(); + if (! (rhsExpr instanceof NewExpression)) { + return null; + } + return rhsExpr; }; -_ArrayLengthOptimizeCommand.prototype._lengthIsUnmodifiedInExpr$LExpression$ = function (expr) { - if (expr instanceof AssignmentExpression) { - if (this._lhsMayModifyLength$LExpression$(expr.getFirstExpr$())) { - return false; - } - } else if (expr instanceof CallExpression || expr instanceof SuperExpression) { - return false; - } else if (expr instanceof IncrementExpression) { - if (this._lhsMayModifyLength$LExpression$(expr.getExpr$())) { - return false; - } - } - return true; +function _StructuredStashAccessor$x2E$x3CStash$x3E$6() { }; +$__jsx_extend([_StructuredStashAccessor$x2E$x3CStash$x3E$6], Object); +_StructuredStashAccessor$x2E$x3CStash$x3E$6.prototype.$__jsx_implements__StructuredStashAccessor$x2E$x3CStash$x3E$6 = true; -_ArrayLengthOptimizeCommand.prototype._lhsMayModifyLength$LExpression$ = function (expr) { - var exprType; - if (expr instanceof PropertyExpression && expr.getIdentifierToken$().getValue$() === "length") { - return true; - } - if (expr instanceof ArrayExpression) { - return true; - } - exprType = expr.getType$().resolveIfNullable$(); - if (exprType.equals$LType$(Type.variantType)) { - return true; - } - if (this._typeIsArray$LType$(exprType)) { - return true; +_StructuredStashAccessor$x2E$x3CStash$x3E$6.prototype.getStash$LStashable$ = function (stashable) { + var identifier; + var stash; + identifier = this._identifier; + stash = stashable.getStash$S(identifier); + if (stash == null) { + stash = new _NoDebugCommand$x2EStash(); + stashable.setStash$SLStash$(identifier, stash); } - return false; + return stash; }; -_ArrayLengthOptimizeCommand.prototype._typeIsArray$LType$ = function (type) { - var classDef; - if (! (type instanceof ObjectType)) { - return false; - } - classDef = type.getClassDef$(); - if (! (classDef instanceof InstantiatedClassDefinition)) { - return false; - } - return classDef.getTemplateClassName$() === "Array"; +_StructuredStashAccessor$x2E$x3CStash$x3E$6.prototype.resetStash$LStashable$ = function (stashable) { + var identifier; + identifier = this._identifier; + stashable.setStash$SLStash$(identifier, null); }; function _NoDebugCommand() { _OptimizeCommand.call(this, _NoDebugCommand.IDENTIFIER); + _StructuredStashAccessor$x2E$x3CStash$x3E$6.call(this); }; $__jsx_extend([_NoDebugCommand], _OptimizeCommand); -_NoDebugCommand.prototype._createStash$ = function () { - return new _NoDebugCommand$x2EStash(); -}; - +$__jsx_merge_interface(_NoDebugCommand, _StructuredStashAccessor$x2E$x3CStash$x3E$6); _NoDebugCommand.prototype.performOptimization$ = function () { var $this = this; @@ -22709,83 +23079,6 @@ _NoDebugCommand.prototype.performOptimization$ = function () { }; -function _TailRecursionOptimizeCommand() { - _FunctionOptimizeCommand.call(this, _TailRecursionOptimizeCommand.IDENTIFIER); -}; - -$__jsx_extend([_TailRecursionOptimizeCommand], _FunctionOptimizeCommand); -_TailRecursionOptimizeCommand.prototype.optimizeFunction$LMemberFunctionDefinition$ = function (funcDef) { - var $this = this; - var altered; - var statements; - var body; - if ((funcDef.flags$() & (ClassDefinition.IS_OVERRIDE | ClassDefinition.IS_ABSTRACT | ClassDefinition.IS_NATIVE)) !== 0 || (funcDef.flags$() & (ClassDefinition.IS_STATIC | ClassDefinition.IS_FINAL)) === 0) { - return false; - } - altered = false; - statements = funcDef.getStatements$(); - (function onStatements(statements) { - var i; - for (i = 0; i < statements.length; ++i) { - if ($this._isTailCall$LMemberFunctionDefinition$LStatement$(funcDef, statements[i])) { - $this._replaceTailCallStatement$LMemberFunctionDefinition$ALStatement$N(funcDef, statements, i); - altered = true; - } - statements[i].handleStatements$F$ALStatement$B$(onStatements); - } - return true; - })(statements); - if (altered) { - this.log$S("transform " + funcDef.getNotation$()); - body = new WhileStatement(new Token$3("while"), new Token$3(_TailRecursionOptimizeCommand.LABEL), new BooleanLiteralExpression(new Token$3("true")), statements); - funcDef.setStatements$ALStatement$([ body ]); - } - return true; -}; - - -_TailRecursionOptimizeCommand.prototype._isTailCall$LMemberFunctionDefinition$LStatement$ = function (funcDef, statement) { - var returnStatement; - if (statement instanceof ReturnStatement) { - returnStatement = statement; - if (returnStatement.getExpr$() != null && returnStatement.getExpr$() instanceof CallExpression) { - return funcDef == _DetermineCalleeCommand$getCallingFuncDef$LStashable$(returnStatement.getExpr$()); - } - } - return false; -}; - - -_TailRecursionOptimizeCommand.prototype._replaceTailCallStatement$LMemberFunctionDefinition$ALStatement$N = function (funcDef, statements, idx) { - var $this = this; - var callExpression; - var locals; - var setupArgs; - var retry; - var localsToArgs; - callExpression = statements[idx].getExpr$(); - locals = funcDef.getArguments$().map((function (argDecl) { - return $this.createVar$LMemberFunctionDefinition$LType$S(funcDef, argDecl.getType$(), argDecl.getName$().getValue$()); - })); - setupArgs = callExpression.getArguments$().reduce((function (prevExpr, arg, i) { - var assignToArg; - assignToArg = new AssignmentExpression(new Token$3("="), new LocalExpression(locals[i].getName$(), locals[i]), arg); - return (prevExpr == null ? assignToArg : new CommaExpression(new Token$3(","), prevExpr, assignToArg)); - }), null); - retry = new ContinueStatement(new Token$3("continue"), new Token$3(_TailRecursionOptimizeCommand.LABEL)); - if (setupArgs == null) { - statements.splice(idx, 1, retry); - } else { - localsToArgs = locals.reduce((function (prevExpr, local, i) { - var assignToArg; - assignToArg = new AssignmentExpression(new Token$3("="), new LocalExpression(funcDef.getArguments$()[i].getName$(), funcDef.getArguments$()[i]), new LocalExpression(local.getName$(), local)); - return (prevExpr == null ? assignToArg : new CommaExpression(new Token$3(","), prevExpr, assignToArg)); - }), null); - statements.splice(idx, 1, new ExpressionStatement(setupArgs), new ExpressionStatement(localsToArgs), retry); - } -}; - - function Compiler(platform) { this._searchPaths = null; this._builtinParsers = null; @@ -26190,9 +26483,7 @@ _SwitchStatementTransformer$x2ECaseStash.prototype.clone$ = function () { $__jsx_lazy_init(CompilationServer, "AUTO_SHUTDOWN", function () { return ! process.env.JSX_NO_AUTO_SHUTDOWN; }); -$__jsx_lazy_init(CompilationServer, "LIFE", function () { - return 10 * 60 * 1000; -}); +CompilationServer.LIFE = 10 * 60 * 1000; $__jsx_lazy_init(node, "__dirname", function () { return eval("__dirname") + ""; }); @@ -26235,9 +26526,7 @@ $__jsx_lazy_init(Util, "_builtInClass", function () { $__jsx_lazy_init(Util, "_builtInContainer", function () { return Util$asSet$AS([ "Array", "Map", "Int8Array", "Uint8Array", "Uint8ClampedArray", "Int16Array", "Uint16Array", "Int32Array", "Uint32Array", "Float32Array", "Float64Array" ]); }); -$__jsx_lazy_init(Util, "_stringLiteralEncodingMap", function () { - return ({ "\0": "\\0", "\r": "\\r", "\n": "\\n", "\t": "\\t", "\"": "\\\"", "\'": "\\\'", "\\": "\\\\" }); -}); +Util._stringLiteralEncodingMap = ({ "\0": "\\0", "\r": "\\r", "\n": "\\n", "\t": "\\t", "\"": "\\\"", "\'": "\\\'", "\\": "\\\\" }); _Util.OUTPUTNAME_IDENTIFIER = "emitter.outputname"; $__jsx_lazy_init(_Util, "_ecma262reserved", function () { return Util$asSet$AS([ "break", "do", "instanceof", "typeof", "case", "else", "new", "var", "catch", "finally", "return", "void", "continue", "for", "switch", "while", "debugger", "function", "this", "with", "default", "if", "throw", "delete", "in", "try", "class", "enum", "extends", "super", "const", "export", "import", "implements", "let", "private", "public", "yield", "interface", "package", "protected", "static", "null", "true", "false" ]); @@ -26250,45 +26539,23 @@ $__jsx_lazy_init(_MinifiedNameGenerator, "GLOBALS", function () { _Minifier.CLASSSTASH_IDENTIFIER = "minifier.class"; _Minifier.SCOPESTASH_IDENTIFIER = "minifier.scope"; _Minifier.LOCALSTASH_IDENTIFIER = "minifier.local"; -$__jsx_lazy_init(_UnaryExpressionEmitter, "_operatorPrecedence", function () { - return {}; -}); -$__jsx_lazy_init(_PreIncrementExpressionEmitter, "_operatorPrecedence", function () { - return {}; -}); -$__jsx_lazy_init(_PostIncrementExpressionEmitter, "_operatorPrecedence", function () { - return {}; -}); +_UnaryExpressionEmitter._operatorPrecedence = {}; +_PreIncrementExpressionEmitter._operatorPrecedence = {}; +_PostIncrementExpressionEmitter._operatorPrecedence = {}; _PostIncrementExpressionEmitter.TEMP_VAR_NAME = "$__jsx_postinc_t"; _InstanceofExpressionEmitter._operatorPrecedence = 0; _PropertyExpressionEmitter._operatorPrecedence = 0; _FunctionExpressionEmitter._operatorPrecedence = 0; _AdditiveExpressionEmitter._operatorPrecedence = 0; -$__jsx_lazy_init(_AssignmentExpressionEmitter, "_operatorPrecedence", function () { - return {}; -}); -$__jsx_lazy_init(_FusedAssignmentExpressionEmitter, "_fusedIntHelpers", function () { - return ({ "+": "$__jsx_ipadd", "-": "$__jsx_ipsub", "*": "$__jsx_ipmul", "/": "$__jsx_ipdiv", "%": "$__jsx_ipmod" }); -}); -$__jsx_lazy_init(_FusedAssignmentExpressionEmitter, "_operatorPrecedence", function () { - return {}; -}); -$__jsx_lazy_init(_EqualityExpressionEmitter, "_operatorPrecedence", function () { - return {}; -}); +_AssignmentExpressionEmitter._operatorPrecedence = {}; +_FusedAssignmentExpressionEmitter._fusedIntHelpers = ({ "+": "$__jsx_ipadd", "-": "$__jsx_ipsub", "*": "$__jsx_ipmul", "/": "$__jsx_ipdiv", "%": "$__jsx_ipmod" }); +_FusedAssignmentExpressionEmitter._operatorPrecedence = {}; +_EqualityExpressionEmitter._operatorPrecedence = {}; _InExpressionEmitter._operatorPrecedence = 0; -$__jsx_lazy_init(_LogicalExpressionEmitter, "_operatorPrecedence", function () { - return {}; -}); -$__jsx_lazy_init(_ShiftExpressionEmitter, "_operatorPrecedence", function () { - return {}; -}); -$__jsx_lazy_init(_BinaryNumberExpressionEmitter, "_OPS_RETURNING_INT", function () { - return ({ '&': true, '|': true, '^': true }); -}); -$__jsx_lazy_init(_BinaryNumberExpressionEmitter, "_operatorPrecedence", function () { - return {}; -}); +_LogicalExpressionEmitter._operatorPrecedence = {}; +_ShiftExpressionEmitter._operatorPrecedence = {}; +_BinaryNumberExpressionEmitter._OPS_RETURNING_INT = ({ '&': true, '|': true, '^': true }); +_BinaryNumberExpressionEmitter._operatorPrecedence = {}; _ArrayExpressionEmitter._operatorPrecedence = 0; _ConditionalExpressionEmitter._operatorPrecedence = 0; _CallExpressionEmitter._operatorPrecedence = 0; @@ -26310,10 +26577,10 @@ $__jsx_lazy_init(NodePlatform, "_isColorSupported", function () { return false; })(); }); -Meta.VERSION_STRING = "0.9.83"; -Meta.VERSION_NUMBER = 0.009083; -Meta.LAST_COMMIT_HASH = "bf8546af13dba4c1a7f25a164301606e02ac301e"; -Meta.LAST_COMMIT_DATE = "2014-03-07 19:06:44 +0900"; +Meta.VERSION_STRING = "0.9.84"; +Meta.VERSION_NUMBER = 0.009084; +Meta.LAST_COMMIT_HASH = "6d7f8eb9fe9485eed11d294c6a08bbc8fab53fac"; +Meta.LAST_COMMIT_DATE = "2014-04-03 00:05:13 -0700"; $__jsx_lazy_init(Meta, "IDENTIFIER", function () { return Meta.VERSION_STRING + " (" + Meta.LAST_COMMIT_DATE + "; " + Meta.LAST_COMMIT_HASH + ")"; }); @@ -26321,9 +26588,7 @@ JavaScriptEmitter.BOOTSTRAP_NONE = 0; JavaScriptEmitter.BOOTSTRAP_EXECUTABLE = 1; JavaScriptEmitter.BOOTSTRAP_TEST = 2; JavaScriptEmitter._initialized = false; -$__jsx_lazy_init(LocalVariableStatuses, "UNTYPED_RECURSIVE_FUNCTION", function () { - return - 1; -}); +LocalVariableStatuses.UNTYPED_RECURSIVE_FUNCTION = - 1; LocalVariableStatuses.UNSET = 0; LocalVariableStatuses.ISSET = 1; LocalVariableStatuses.MAYBESET = 2; @@ -26434,33 +26699,31 @@ $__jsx_lazy_init(_Lexer, "reserved", function () { }); SourceMapper.NODE_SOURCE_MAP_HEADER = "require('source-map-support').install();\n\n"; SourceMapper.WEB_SOURCE_MAP_HEADER = ""; -_LinkTimeOptimizationCommand.IDENTIFIER = "lto"; -_StripOptimizeCommand.IDENTIFIER = "strip"; _NoAssertCommand.IDENTIFIER = "no-assert"; _NoLogCommand.IDENTIFIER = "no-log"; +_DeadCodeEliminationOptimizeCommand.IDENTIFIER = "dce"; +_ReturnIfOptimizeCommand.IDENTIFIER = "return-if"; +_LCSEOptimizeCommand.IDENTIFIER = "lcse"; +_ArrayLengthOptimizeCommand.IDENTIFIER = "array-length"; +_TailRecursionOptimizeCommand.IDENTIFIER = "tail-rec"; +_TailRecursionOptimizeCommand.LABEL = "$TAIL_REC"; +_LinkTimeOptimizationCommand.IDENTIFIER = "lto"; +_StripOptimizeCommand.IDENTIFIER = "strip"; _DetermineCalleeCommand.IDENTIFIER = "determine-callee"; _StaticizeOptimizeCommand.IDENTIFIER = "staticize"; _UnclassifyOptimizationCommand.IDENTIFIER = "unclassify"; _FoldConstantCommand.IDENTIFIER = "fold-const"; _FoldConstantCommand.LONG_STRING_LITERAL = 64; -_DeadCodeEliminationOptimizeCommand.IDENTIFIER = "dce"; _InlineOptimizeCommand.IDENTIFIER = "inline"; _InlineOptimizeCommand.INLINE_THRESHOLD = 30; -_ReturnIfOptimizeCommand.IDENTIFIER = "return-if"; -_LCSEOptimizeCommand.IDENTIFIER = "lcse"; _UnboxOptimizeCommand.IDENTIFIER = "unbox"; -_ArrayLengthOptimizeCommand.IDENTIFIER = "array-length"; _NoDebugCommand.IDENTIFIER = "no-debug"; -_TailRecursionOptimizeCommand.IDENTIFIER = "tail-rec"; -_TailRecursionOptimizeCommand.LABEL = "$TAIL_REC"; Compiler.MODE_COMPILE = 0; Compiler.MODE_PARSE = 1; Compiler.MODE_COMPLETE = 2; Compiler.MODE_DOC = 3; _Util$1._numUniqVar = 0; -$__jsx_lazy_init(_StatementTransformer, "_statementCountMap", function () { - return {}; -}); +_StatementTransformer._statementCountMap = {}; GeneratorTransformCommand.IDENTIFIER = "generator"; CPSTransformCommand.IDENTIFIER = "cps"; FixedExpressionTransformCommand.IDENTIFIER = "fixed"; @@ -26978,14 +27241,26 @@ var $__jsx_classMap = { _OptimizeCommand$S: _OptimizeCommand, _FunctionOptimizeCommand: _FunctionOptimizeCommand, _FunctionOptimizeCommand$S: _FunctionOptimizeCommand, - _LinkTimeOptimizationCommand: _LinkTimeOptimizationCommand, - _LinkTimeOptimizationCommand$: _LinkTimeOptimizationCommand, - _StripOptimizeCommand: _StripOptimizeCommand, - _StripOptimizeCommand$: _StripOptimizeCommand, _NoAssertCommand: _NoAssertCommand, _NoAssertCommand$: _NoAssertCommand, _NoLogCommand: _NoLogCommand, _NoLogCommand$: _NoLogCommand, + _DeadCodeEliminationOptimizeCommand: _DeadCodeEliminationOptimizeCommand, + _DeadCodeEliminationOptimizeCommand$: _DeadCodeEliminationOptimizeCommand, + _ReturnIfOptimizeCommand: _ReturnIfOptimizeCommand, + _ReturnIfOptimizeCommand$: _ReturnIfOptimizeCommand, + _LCSECachedExpression: _LCSECachedExpression, + _LCSECachedExpression$LExpression$F$LExpression$V$: _LCSECachedExpression, + _LCSEOptimizeCommand: _LCSEOptimizeCommand, + _LCSEOptimizeCommand$: _LCSEOptimizeCommand, + _ArrayLengthOptimizeCommand: _ArrayLengthOptimizeCommand, + _ArrayLengthOptimizeCommand$: _ArrayLengthOptimizeCommand, + _TailRecursionOptimizeCommand: _TailRecursionOptimizeCommand, + _TailRecursionOptimizeCommand$: _TailRecursionOptimizeCommand, + _LinkTimeOptimizationCommand: _LinkTimeOptimizationCommand, + _LinkTimeOptimizationCommand$: _LinkTimeOptimizationCommand, + _StripOptimizeCommand: _StripOptimizeCommand, + _StripOptimizeCommand$: _StripOptimizeCommand, _DetermineCalleeCommand: _DetermineCalleeCommand, _DetermineCalleeCommand$: _DetermineCalleeCommand, _StaticizeOptimizeCommand: _StaticizeOptimizeCommand, @@ -26994,24 +27269,12 @@ var $__jsx_classMap = { _UnclassifyOptimizationCommand$: _UnclassifyOptimizationCommand, _FoldConstantCommand: _FoldConstantCommand, _FoldConstantCommand$: _FoldConstantCommand, - _DeadCodeEliminationOptimizeCommand: _DeadCodeEliminationOptimizeCommand, - _DeadCodeEliminationOptimizeCommand$: _DeadCodeEliminationOptimizeCommand, _InlineOptimizeCommand: _InlineOptimizeCommand, _InlineOptimizeCommand$: _InlineOptimizeCommand, - _ReturnIfOptimizeCommand: _ReturnIfOptimizeCommand, - _ReturnIfOptimizeCommand$: _ReturnIfOptimizeCommand, - _LCSECachedExpression: _LCSECachedExpression, - _LCSECachedExpression$LExpression$F$LExpression$V$: _LCSECachedExpression, - _LCSEOptimizeCommand: _LCSEOptimizeCommand, - _LCSEOptimizeCommand$: _LCSEOptimizeCommand, _UnboxOptimizeCommand: _UnboxOptimizeCommand, _UnboxOptimizeCommand$: _UnboxOptimizeCommand, - _ArrayLengthOptimizeCommand: _ArrayLengthOptimizeCommand, - _ArrayLengthOptimizeCommand$: _ArrayLengthOptimizeCommand, _NoDebugCommand: _NoDebugCommand, _NoDebugCommand$: _NoDebugCommand, - _TailRecursionOptimizeCommand: _TailRecursionOptimizeCommand, - _TailRecursionOptimizeCommand$: _TailRecursionOptimizeCommand, "_LinkTimeOptimizationCommand.Stash": _LinkTimeOptimizationCommand$x2EStash, "_LinkTimeOptimizationCommand.Stash$": _LinkTimeOptimizationCommand$x2EStash, "_StripOptimizeCommand._Stash": _StripOptimizeCommand$x2E_Stash,