Prohibit from eliminating non-local temporary variables
This commit is contained in:
+5
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.js.inline.clean
|
||||
import com.google.dart.compiler.backend.js.ast.*
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.synthetic
|
||||
import org.jetbrains.kotlin.js.inline.util.canHaveSideEffect
|
||||
import org.jetbrains.kotlin.js.inline.util.collectDefinedNames
|
||||
import org.jetbrains.kotlin.js.inline.util.collectFreeVariables
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||
|
||||
@@ -29,6 +30,7 @@ internal class TemporaryAssignmentElimination(private val root: JsBlock) {
|
||||
private val mappedUsages = mutableMapOf<JsName, Usage>()
|
||||
private val syntheticNames = mutableSetOf<JsName>()
|
||||
private var hasChanges = false
|
||||
private val namesToProcess = mutableSetOf<JsName>()
|
||||
|
||||
fun apply(): Boolean {
|
||||
analyze()
|
||||
@@ -39,6 +41,8 @@ internal class TemporaryAssignmentElimination(private val root: JsBlock) {
|
||||
}
|
||||
|
||||
private fun analyze() {
|
||||
namesToProcess.addAll(collectDefinedNames(root))
|
||||
|
||||
object : JsVisitorWithContextImpl() {
|
||||
override fun visit(x: JsReturn, ctx: JsContext<*>): Boolean {
|
||||
val returnExpr = x.expression
|
||||
@@ -253,6 +257,7 @@ internal class TemporaryAssignmentElimination(private val root: JsBlock) {
|
||||
private fun tryRecord(expr: JsExpression, usage: Usage): Boolean {
|
||||
if (expr !is JsNameRef) return false
|
||||
val name = expr.name ?: return false
|
||||
if (name !in namesToProcess) return false
|
||||
|
||||
usages[name] = usage
|
||||
return true
|
||||
|
||||
+6
-2
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.js.inline.clean
|
||||
import com.google.dart.compiler.backend.js.ast.*
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.synthetic
|
||||
import org.jetbrains.kotlin.js.inline.util.canHaveSideEffect
|
||||
import org.jetbrains.kotlin.js.inline.util.collectDefinedNames
|
||||
import org.jetbrains.kotlin.js.inline.util.collectFreeVariables
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||
|
||||
@@ -28,6 +29,7 @@ internal class TemporaryVariableElimination(private val root: JsStatement) {
|
||||
private val definedValues = mutableMapOf<JsName, JsExpression>()
|
||||
private val temporary = mutableSetOf<JsName>()
|
||||
private var hasChanges = false
|
||||
private val namesToProcess = mutableSetOf<JsName>()
|
||||
|
||||
fun apply(): Boolean {
|
||||
analyze()
|
||||
@@ -36,6 +38,8 @@ internal class TemporaryVariableElimination(private val root: JsStatement) {
|
||||
}
|
||||
|
||||
private fun analyze() {
|
||||
namesToProcess.addAll(collectDefinedNames(root))
|
||||
|
||||
object : JsVisitorWithContextImpl() {
|
||||
val lastAssignedVars = mutableListOf<JsName>()
|
||||
|
||||
@@ -44,7 +48,7 @@ internal class TemporaryVariableElimination(private val root: JsStatement) {
|
||||
if (name != null && x.qualifier == null) {
|
||||
val expr = definedValues[name]
|
||||
useVariable(name)
|
||||
if (lastAssignedVars.lastOrNull() == name) {
|
||||
if (lastAssignedVars.lastOrNull() == name && name in namesToProcess) {
|
||||
lastAssignedVars.removeAt(lastAssignedVars.lastIndex)
|
||||
}
|
||||
else if (expr == null || expr.canHaveSideEffect()) {
|
||||
@@ -95,7 +99,7 @@ internal class TemporaryVariableElimination(private val root: JsStatement) {
|
||||
val (name, value) = assignment
|
||||
assignVariable(name, value)
|
||||
accept(value)
|
||||
if (x.synthetic) {
|
||||
if (x.synthetic && name in namesToProcess) {
|
||||
temporary += name
|
||||
}
|
||||
else if (value.canHaveSideEffect()) {
|
||||
|
||||
+2
@@ -24,4 +24,6 @@ class TemporaryAssignmentEliminationTest : BasicOptimizerTest("temporary-assignm
|
||||
@Test fun returnStatement() = box()
|
||||
|
||||
@Test fun declaration() = box()
|
||||
|
||||
@Test fun skipsGlobalDeclarations() = box()
|
||||
}
|
||||
+2
@@ -22,4 +22,6 @@ class TemporaryVariableEliminationTest : BasicOptimizerTest("temporary-variable"
|
||||
@Test fun declaration() = box()
|
||||
|
||||
@Test fun assignment() = box()
|
||||
|
||||
@Test fun skipsGlobalDeclarations() = box()
|
||||
}
|
||||
+2
-2
@@ -10,10 +10,10 @@ function test(n) {
|
||||
}
|
||||
|
||||
function box() {
|
||||
var result = test(20)
|
||||
var result = test(20);
|
||||
if (result != 20) return "fail1: " + result;
|
||||
|
||||
result = test(-20)
|
||||
result = test(-20);
|
||||
if (result != 20) return "fail2: " + result;
|
||||
|
||||
return "OK"
|
||||
|
||||
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
var $tmp;
|
||||
|
||||
function test(n) {
|
||||
if (n >= 0) {
|
||||
$tmp = n;
|
||||
}
|
||||
else {
|
||||
$tmp = -n;
|
||||
}
|
||||
var result = $tmp;
|
||||
return result;
|
||||
}
|
||||
|
||||
function box() {
|
||||
var result = test(20);
|
||||
if (result != 20) return "fail1: " + result;
|
||||
|
||||
result = test(-20);
|
||||
if (result != 20) return "fail2: " + result;
|
||||
|
||||
if ($tmp != 20) return "fail3: " + result;
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
var $tmp;
|
||||
|
||||
function test(n) {
|
||||
if (n >= 0) {
|
||||
$tmp = n;
|
||||
}
|
||||
else {
|
||||
$tmp = -n;
|
||||
}
|
||||
var result = $tmp;
|
||||
return result;
|
||||
}
|
||||
|
||||
function box() {
|
||||
var result = test(20);
|
||||
if (result != 20) return "fail1: " + result;
|
||||
|
||||
result = test(-20);
|
||||
if (result != 20) return "fail2: " + result;
|
||||
|
||||
if ($tmp != 20) return "fail3: " + result;
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
var $tmp;
|
||||
|
||||
function test(a, b, c) {
|
||||
$tmp = a + b;
|
||||
return $tmp + c;
|
||||
}
|
||||
|
||||
function box() {
|
||||
var result = test(2, 3, 4);
|
||||
if (result != 9) return "fail1: " + result;
|
||||
if ($tmp != 5) return "fail2: " + $tmp;
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
var $tmp;
|
||||
|
||||
function test(a, b, c) {
|
||||
$tmp = a + b;
|
||||
return $tmp + c;
|
||||
}
|
||||
|
||||
function box() {
|
||||
var result = test(2, 3, 4);
|
||||
if (result != 9) return "fail1: " + result;
|
||||
if ($tmp != 5) return "fail2: " + $tmp;
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user