diff --git a/core/src/main/java/org/teavm/backend/javascript/JavaScriptTarget.java b/core/src/main/java/org/teavm/backend/javascript/JavaScriptTarget.java index f858ac9ef..4b85dde2b 100644 --- a/core/src/main/java/org/teavm/backend/javascript/JavaScriptTarget.java +++ b/core/src/main/java/org/teavm/backend/javascript/JavaScriptTarget.java @@ -318,6 +318,7 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost { } int start = sourceWriter.getOffset(); sourceWriter.append("\"use strict\";").newLine(); + renderer.prepare(clsNodes); renderer.renderRuntime(); renderer.render(clsNodes); renderer.renderStringPool(); diff --git a/core/src/main/java/org/teavm/backend/javascript/codegen/MinifyingAliasProvider.java b/core/src/main/java/org/teavm/backend/javascript/codegen/MinifyingAliasProvider.java index ee940fbec..18fa3fb6c 100644 --- a/core/src/main/java/org/teavm/backend/javascript/codegen/MinifyingAliasProvider.java +++ b/core/src/main/java/org/teavm/backend/javascript/codegen/MinifyingAliasProvider.java @@ -83,7 +83,7 @@ public class MinifyingAliasProvider implements AliasProvider { public String getClassInitAlias(String className) { String result; do { - result = RenderingUtil.indexToId(lastSuffix++, startLetters); + result = RenderingUtil.indexToId(lastSuffix++, startLetters); } while (!usedAliases.add(result) || RenderingUtil.KEYWORDS.contains(result)); return result; } diff --git a/core/src/main/java/org/teavm/backend/javascript/rendering/NameFrequencyEstimator.java b/core/src/main/java/org/teavm/backend/javascript/rendering/NameFrequencyEstimator.java index 6ed711667..ef28ef3b3 100644 --- a/core/src/main/java/org/teavm/backend/javascript/rendering/NameFrequencyEstimator.java +++ b/core/src/main/java/org/teavm/backend/javascript/rendering/NameFrequencyEstimator.java @@ -100,6 +100,11 @@ class NameFrequencyEstimator extends RecursiveVisitor implements MethodNodeVisit consumer.consumeFunction("$rt_resuming"); consumer.consumeFunction("$rt_invalidPointer"); } + method.acceptVisitor(this); + } + + if (clinit != null) { + consumer.consumeFunction("$rt_eraseClinit"); } // Metadata diff --git a/core/src/main/java/org/teavm/backend/javascript/rendering/Renderer.java b/core/src/main/java/org/teavm/backend/javascript/rendering/Renderer.java index f3adeafb4..5ef0525c5 100644 --- a/core/src/main/java/org/teavm/backend/javascript/rendering/Renderer.java +++ b/core/src/main/java/org/teavm/backend/javascript/rendering/Renderer.java @@ -295,7 +295,7 @@ public class Renderer implements RenderingManager { private void renderRuntimeAliases() throws IOException { String[] names = { "$rt_throw", "$rt_compare", "$rt_nullCheck", "$rt_cls", "$rt_createArray", "$rt_isInstance", "$rt_nativeThread", "$rt_suspending", "$rt_resuming", "$rt_invalidPointer", - "$rt_s" }; + "$rt_s", "$rt_eraseClinit" }; boolean first = true; for (String name : names) { if (!first) { @@ -307,7 +307,7 @@ public class Renderer implements RenderingManager { writer.newLine(); } - public void render(List classes) throws RenderingException { + public void prepare(List classes) { if (minifying) { NamingOrderer orderer = new NamingOrderer(); NameFrequencyEstimator estimator = new NameFrequencyEstimator(orderer, classSource, asyncMethods, @@ -317,7 +317,9 @@ public class Renderer implements RenderingManager { } orderer.apply(naming); } + } + public void render(List classes) throws RenderingException { if (minifying) { try { renderRuntimeAliases(); @@ -484,8 +486,8 @@ public class Renderer implements RenderingManager { private void renderEraseClinit(ClassNode cls) throws IOException { writer.append(naming.getNameForClassInit(cls.getName())).ws().append("=").ws() - .appendClass(cls.getName()).append(".$clinit").ws().append("=").ws() - .append("function(){};").newLine(); + .appendFunction("$rt_eraseClinit").append("(") + .appendClass(cls.getName()).append(");").softNewLine(); } private void renderClassMetadata(List classes) { @@ -713,22 +715,24 @@ public class Renderer implements RenderingManager { MethodReference ref = method.getReference(); debugEmitter.emitMethod(ref.getDescriptor()); writer.append("function ").append(naming.getNameForInit(ref)).append("("); - for (int i = 1; i <= ref.parameterCount(); ++i) { - if (i > 1) { + for (int i = 0; i < ref.parameterCount(); ++i) { + if (i > 0) { writer.append(",").ws(); } writer.append(variableNameForInitializer(i)); } writer.append(")").ws().append("{").softNewLine().indent(); - writer.append("var $r").ws().append("=").ws().append("new ").appendClass( + + String instanceName = variableNameForInitializer(ref.parameterCount()); + writer.append("var " + instanceName).ws().append("=").ws().append("new ").appendClass( ref.getClassName()).append("();").softNewLine(); - writer.append(naming.getFullNameFor(ref)).append("($r"); - for (int i = 1; i <= ref.parameterCount(); ++i) { + writer.append(naming.getFullNameFor(ref)).append("(" + instanceName); + for (int i = 0; i < ref.parameterCount(); ++i) { writer.append(",").ws(); writer.append(variableNameForInitializer(i)); } writer.append(");").softNewLine(); - writer.append("return $r;").softNewLine(); + writer.append("return " + instanceName + ";").softNewLine(); writer.outdent().append("}").newLine(); debugEmitter.emitMethod(null); } diff --git a/core/src/main/java/org/teavm/backend/javascript/rendering/RenderingUtil.java b/core/src/main/java/org/teavm/backend/javascript/rendering/RenderingUtil.java index ecbc05cbf..5a3d5e0f9 100644 --- a/core/src/main/java/org/teavm/backend/javascript/rendering/RenderingUtil.java +++ b/core/src/main/java/org/teavm/backend/javascript/rendering/RenderingUtil.java @@ -27,7 +27,7 @@ public final class RenderingUtil { "super", "switch", "this", "throw", "try", "typeof", "var", "void", "while", "with", "yield", "NaN"))); public static final String VARIABLE_START_CHARS = "abcdefghijklmnopqrstuvwxyz"; - public static final String VARIABLE_PART_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + public static final String VARIABLE_PART_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$_"; private RenderingUtil() { } diff --git a/core/src/main/java/org/teavm/backend/javascript/rendering/StatementRenderer.java b/core/src/main/java/org/teavm/backend/javascript/rendering/StatementRenderer.java index c6c9aaedd..a31152782 100644 --- a/core/src/main/java/org/teavm/backend/javascript/rendering/StatementRenderer.java +++ b/core/src/main/java/org/teavm/backend/javascript/rendering/StatementRenderer.java @@ -462,10 +462,6 @@ public class StatementRenderer implements ExprVisitor, StatementVisitor { } private String generateVariableName(int index) { - if (index == 0 && minifying) { - return "$t"; - } - if (!minifying) { VariableNode variable = index < currentMethod.getVariables().size() ? currentMethod.getVariables().get(index) @@ -484,7 +480,7 @@ public class StatementRenderer implements ExprVisitor, StatementVisitor { return "var$" + index; } } else { - return RenderingUtil.indexToId(--index); + return RenderingUtil.indexToId(index); } } diff --git a/core/src/main/resources/org/teavm/backend/javascript/runtime.js b/core/src/main/resources/org/teavm/backend/javascript/runtime.js index 28ec2be2a..58a9642ff 100644 --- a/core/src/main/resources/org/teavm/backend/javascript/runtime.js +++ b/core/src/main/resources/org/teavm/backend/javascript/runtime.js @@ -520,6 +520,9 @@ function $rt_stringPool(strings) { function $rt_s(index) { return $rt_stringPool_instance[index]; } +function $rt_eraseClinit(target) { + return target.$clinit = function() {}; +} function TeaVMThread(runner) { this.status = 3; this.stack = [];