Fix issues in strict mode

This commit is contained in:
konsoletyper 2014-10-19 11:02:56 +04:00
parent 5420ca89f6
commit 3de49d6d54
8 changed files with 134 additions and 18 deletions

View File

@ -85,8 +85,6 @@
<phase>process-test-classes</phase> <phase>process-test-classes</phase>
<configuration> <configuration>
<minifying>false</minifying> <minifying>false</minifying>
<sourceMapsGenerated>true</sourceMapsGenerated>
<sourceFilesCopied>true</sourceFilesCopied>
<properties> <properties>
<java.util.Locale.available>en, en_US, en_GB, ru, ru_RU</java.util.Locale.available> <java.util.Locale.available>en, en_US, en_GB, ru, ru_RU</java.util.Locale.available>
</properties> </properties>

View File

@ -15,10 +15,9 @@
*/ */
package org.teavm.classlib.impl; package org.teavm.classlib.impl;
import java.util.ServiceLoader;
import org.teavm.classlib.impl.unicode.CLDRReader; import org.teavm.classlib.impl.unicode.CLDRReader;
import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.model.ValueType;
import org.teavm.vm.spi.TeaVMHost; import org.teavm.vm.spi.TeaVMHost;
import org.teavm.vm.spi.TeaVMPlugin; import org.teavm.vm.spi.TeaVMPlugin;
@ -36,9 +35,8 @@ public class JCLPlugin implements TeaVMPlugin {
host.add(new ObjectEnrichRenderer()); host.add(new ObjectEnrichRenderer());
ServiceLoaderSupport serviceLoaderSupp = new ServiceLoaderSupport(host.getClassLoader()); ServiceLoaderSupport serviceLoaderSupp = new ServiceLoaderSupport(host.getClassLoader());
host.add(serviceLoaderSupp); host.add(serviceLoaderSupp);
MethodReference loadServicesMethod = new MethodReference("java.util.ServiceLoader", new MethodDescriptor( MethodReference loadServicesMethod = new MethodReference(ServiceLoader.class, "loadServices",
"loadServices", ValueType.object("java.lang.Class"), Class.class, Object[].class);
ValueType.arrayOf(ValueType.object("java.lang.Object"))));
host.add(loadServicesMethod, serviceLoaderSupp); host.add(loadServicesMethod, serviceLoaderSupp);
JavacSupport javacSupport = new JavacSupport(); JavacSupport javacSupport = new JavacSupport();
host.add(javacSupport); host.add(javacSupport);

View File

@ -47,7 +47,7 @@ public class ServiceLoaderSupport implements Generator, DependencyListener {
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException {
writer.append("if (!").appendClass("java.util.ServiceLoader").append(".$$services$$) {").indent() writer.append("if (!").appendClass("java.util.ServiceLoader").append(".$$services$$) {").indent()
.softNewLine(); .softNewLine();
writer.appendClass("java.util.ServiceLoader").append("$$services$$ = true;").softNewLine(); writer.appendClass("java.util.ServiceLoader").append(".$$services$$ = true;").softNewLine();
for (Map.Entry<String, List<String>> entry : serviceMap.entrySet()) { for (Map.Entry<String, List<String>> entry : serviceMap.entrySet()) {
writer.appendClass(entry.getKey()).append(".$$serviceList$$ = ["); writer.appendClass(entry.getKey()).append(".$$serviceList$$ = [");
List<String> implementations = entry.getValue(); List<String> implementations = entry.getValue();

View File

@ -540,16 +540,23 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
for (int var : method.getVariables()) { for (int var : method.getVariables()) {
variableCount = Math.max(variableCount, var + 1); variableCount = Math.max(variableCount, var + 1);
} }
boolean hasVars = variableCount > ref.parameterCount() + 1; TryCatchFinder tryCatchFinder = new TryCatchFinder();
if (hasVars) { method.getBody().acceptVisitor(tryCatchFinder);
boolean hasTryCatch = tryCatchFinder.tryCatchFound;
List<String> variableNames = new ArrayList<>();
for (int i = ref.parameterCount() + 1; i < variableCount; ++i) {
variableNames.add(variableName(i));
}
if (hasTryCatch) {
variableNames.add("$je");
}
if (!variableNames.isEmpty()) {
writer.append("var "); writer.append("var ");
boolean first = true; for (int i = 0; i < variableNames.size(); ++i) {
for (int i = ref.parameterCount() + 1; i < variableCount; ++i) { if (i > 0) {
if (!first) {
writer.append(",").ws(); writer.append(",").ws();
} }
first = false; writer.append(variableNames.get(i));
writer.append(variableName(i));
} }
writer.append(";").softNewLine(); writer.append(";").softNewLine();
} }

View File

@ -0,0 +1,113 @@
/*
* Copyright 2014 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.javascript;
import java.util.List;
import org.teavm.javascript.ast.*;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
class TryCatchFinder implements StatementVisitor {
public boolean tryCatchFound;
@Override
public void visit(AssignmentStatement statement) {
}
private void visitSequence(List<Statement> statements) {
if (tryCatchFound) {
return;
}
for (Statement statement : statements) {
statement.acceptVisitor(this);
if (tryCatchFound) {
return;
}
}
}
@Override
public void visit(SequentialStatement statement) {
if (tryCatchFound) {
return;
}
visitSequence(statement.getSequence());
}
@Override
public void visit(ConditionalStatement statement) {
if (tryCatchFound) {
return;
}
visitSequence(statement.getConsequent());
visitSequence(statement.getAlternative());
}
@Override
public void visit(SwitchStatement statement) {
if (tryCatchFound) {
return;
}
for (SwitchClause clause : statement.getClauses()) {
visitSequence(clause.getBody());
if (tryCatchFound) {
return;
}
}
visitSequence(statement.getDefaultClause());
}
@Override
public void visit(WhileStatement statement) {
if (!tryCatchFound) {
visitSequence(statement.getBody());
}
}
@Override
public void visit(BlockStatement statement) {
if (!tryCatchFound) {
visitSequence(statement.getBody());
}
}
@Override
public void visit(BreakStatement statement) {
}
@Override
public void visit(ContinueStatement statement) {
}
@Override
public void visit(ReturnStatement statement) {
}
@Override
public void visit(ThrowStatement statement) {
}
@Override
public void visit(InitClassStatement statement) {
}
@Override
public void visit(TryCatchStatement statement) {
tryCatchFound = true;
}
}

View File

@ -434,10 +434,10 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
renderer.addInjector(entry.getKey(), entry.getValue()); renderer.addInjector(entry.getKey(), entry.getValue());
} }
try { try {
sourceWriter.append("\"use strict\"").newLine();
for (RendererListener listener : rendererListeners) { for (RendererListener listener : rendererListeners) {
listener.begin(renderer, target); listener.begin(renderer, target);
} }
sourceWriter.append("\"use strict\";").newLine();
renderer.renderRuntime(); renderer.renderRuntime();
for (ClassNode clsNode : clsNodes) { for (ClassNode clsNode : clsNodes) {
ClassReader cls = classSet.get(clsNode.getName()); ClassReader cls = classSet.get(clsNode.getName());

View File

@ -72,7 +72,7 @@ if (ArrayBuffer) {
return new ($rt_arraycls(cls))(nativeArray); return new ($rt_arraycls(cls))(nativeArray);
}; };
$rt_createCharArray = function(sz) { $rt_createCharArray = function(sz) {
return $rt_createNumericArray($rt_bytecls(), new Uint16Array(new ArrayBuffer(sz << 1)), 0); return $rt_createNumericArray($rt_charcls(), new Uint16Array(new ArrayBuffer(sz << 1)), 0);
}; };
$rt_createByteArray = function(sz) { $rt_createByteArray = function(sz) {
return $rt_createNumericArray($rt_bytecls(), new Int8Array(new ArrayBuffer(sz)), 0); return $rt_createNumericArray($rt_bytecls(), new Int8Array(new ArrayBuffer(sz)), 0);

View File

@ -77,7 +77,7 @@ public class MetadataProviderNativeGenerator implements Generator {
Resource resource = generator.generateMetadata(metadataContext, methodRef); Resource resource = generator.generateMetadata(metadataContext, methodRef);
writer.append("if (!window.hasOwnProperty(\"").appendMethodBody(methodRef).append("$$resource\")) {") writer.append("if (!window.hasOwnProperty(\"").appendMethodBody(methodRef).append("$$resource\")) {")
.indent().softNewLine(); .indent().softNewLine();
writer.appendMethodBody(methodRef).append("$$resource = "); writer.append("window.").appendMethodBody(methodRef).append("$$resource = ");
ResourceWriterHelper.write(writer, resource); ResourceWriterHelper.write(writer, resource);
writer.append(';').softNewLine(); writer.append(';').softNewLine();
writer.outdent().append('}').softNewLine(); writer.outdent().append('}').softNewLine();