Partial merge with async.

This commit is contained in:
Steve Hannah 2015-02-09 09:49:53 -08:00
commit 9465d24723
213 changed files with 1912 additions and 1204 deletions

View File

@ -82,6 +82,7 @@
<module>teavm-platform</module> <module>teavm-platform</module>
<module>teavm-cli</module> <module>teavm-cli</module>
<module>teavm-chrome-rdp</module> <module>teavm-chrome-rdp</module>
<module>teavm-tests</module>
</modules> </modules>
<dependencyManagement> <dependencyManagement>

View File

@ -49,6 +49,16 @@
<artifactId>teavm-core</artifactId> <artifactId>teavm-core</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.teavm</groupId>
<artifactId>teavm-jso</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.teavm</groupId>
<artifactId>teavm-dom</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>com.google.code.gson</groupId> <groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId> <artifactId>gson</artifactId>
@ -74,34 +84,6 @@
</instructions> </instructions>
</configuration> </configuration>
</plugin> </plugin>
<plugin>
<groupId>org.teavm</groupId>
<artifactId>teavm-maven-plugin</artifactId>
<version>${project.version}</version>
<dependencies>
<dependency>
<groupId>org.teavm</groupId>
<artifactId>teavm-platform</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>generate-javascript-tests</id>
<goals>
<goal>build-test-javascript</goal>
</goals>
<phase>process-test-classes</phase>
<configuration>
<minifying>false</minifying>
<properties>
<java.util.Locale.available>en, en_US, en_GB, ru, ru_RU</java.util.Locale.available>
</properties>
<incremental>${teavm.classlib.test.incremental}</incremental>
</configuration>
</execution>
</executions>
</plugin>
<plugin> <plugin>
<groupId>org.codehaus.mojo</groupId> <groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId> <artifactId>exec-maven-plugin</artifactId>
@ -135,15 +117,6 @@
</arguments> </arguments>
</configuration> </configuration>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>org/teavm/platform/metadata/*.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId> <artifactId>maven-source-plugin</artifactId>

View File

@ -0,0 +1,40 @@
/*
* Copyright 2015 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.classlib.impl;
import java.util.HashMap;
import java.util.Map;
import org.teavm.model.ClassReader;
import org.teavm.model.MethodReference;
import org.teavm.platform.metadata.*;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class DeclaringClassMetadataGenerator implements ClassScopedMetadataGenerator {
@Override
public Map<String, Resource> generateMetadata(MetadataGeneratorContext context, MethodReference method) {
Map<String, Resource> result = new HashMap<>();
for (String clsName : context.getClassSource().getClassNames()) {
ClassReader cls = context.getClassSource().get(clsName);
if (cls.getOwnerName() != null) {
result.put(clsName, context.createClassResource(cls.getOwnerName()));
}
}
return result;
}
}

View File

@ -18,6 +18,7 @@ package org.teavm.classlib.impl;
import java.util.ServiceLoader; import java.util.ServiceLoader;
import org.teavm.classlib.impl.unicode.CLDRReader; import org.teavm.classlib.impl.unicode.CLDRReader;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.platform.PlatformClass;
import org.teavm.vm.spi.TeaVMHost; import org.teavm.vm.spi.TeaVMHost;
import org.teavm.vm.spi.TeaVMPlugin; import org.teavm.vm.spi.TeaVMPlugin;
@ -28,15 +29,11 @@ import org.teavm.vm.spi.TeaVMPlugin;
public class JCLPlugin implements TeaVMPlugin { public class JCLPlugin implements TeaVMPlugin {
@Override @Override
public void install(TeaVMHost host) { public void install(TeaVMHost host) {
host.add(new EnumDependencySupport());
host.add(new EnumTransformer());
host.add(new ClassLookupDependencySupport());
host.add(new NewInstanceDependencySupport());
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(ServiceLoader.class, "loadServices", MethodReference loadServicesMethod = new MethodReference(ServiceLoader.class, "loadServices",
Class.class, Object[].class); PlatformClass.class, Object[].class);
host.add(loadServicesMethod, serviceLoaderSupp); host.add(loadServicesMethod, serviceLoaderSupp);
JavacSupport javacSupport = new JavacSupport(); JavacSupport javacSupport = new JavacSupport();
host.add(javacSupport); host.add(javacSupport);

View File

@ -23,8 +23,8 @@ import java.net.URL;
import java.util.*; import java.util.*;
import org.teavm.codegen.SourceWriter; import org.teavm.codegen.SourceWriter;
import org.teavm.dependency.*; import org.teavm.dependency.*;
import org.teavm.javascript.ni.Generator; import org.teavm.javascript.spi.Generator;
import org.teavm.javascript.ni.GeneratorContext; import org.teavm.javascript.spi.GeneratorContext;
import org.teavm.model.CallLocation; import org.teavm.model.CallLocation;
import org.teavm.model.MethodDescriptor; import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
@ -65,7 +65,7 @@ public class ServiceLoaderSupport implements Generator, DependencyListener {
} }
writer.outdent().append("}").softNewLine(); writer.outdent().append("}").softNewLine();
String param = context.getParameterName(1); String param = context.getParameterName(1);
writer.append("var cls = " + param + ".$data;").softNewLine(); writer.append("var cls = " + param + ";").softNewLine();
writer.append("if (!cls.$$serviceList$$) {").indent().softNewLine(); writer.append("if (!cls.$$serviceList$$) {").indent().softNewLine();
writer.append("return $rt_createArray($rt_objcls(), 0);").softNewLine(); writer.append("return $rt_createArray($rt_objcls(), 0);").softNewLine();
writer.outdent().append("}").softNewLine(); writer.outdent().append("}").softNewLine();

View File

@ -0,0 +1,54 @@
/*
* Copyright 2015 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.classlib.java.lang;
import org.teavm.classlib.impl.unicode.UnicodeHelper;
import org.teavm.classlib.impl.unicode.UnicodeSupport;
import org.teavm.model.MethodReference;
import org.teavm.platform.metadata.MetadataGenerator;
import org.teavm.platform.metadata.MetadataGeneratorContext;
import org.teavm.platform.metadata.Resource;
import org.teavm.platform.metadata.StringResource;
/**
*
* @author Alexey Andreev
*/
public class CharacterMetadataGenerator implements MetadataGenerator {
@Override
public Resource generateMetadata(MetadataGeneratorContext context, MethodReference method) {
switch (method.getName()) {
case "obtainDigitMapping":
return generateObtainDigitMapping(context);
case "obtainClasses":
return generateObtainClasses(context);
default:
return null;
}
}
private Resource generateObtainDigitMapping(MetadataGeneratorContext context) {
StringResource res = context.createResource(StringResource.class);
res.setValue(UnicodeHelper.encodeIntByte(UnicodeSupport.getDigitValues()));
return res;
}
private Resource generateObtainClasses(MetadataGeneratorContext context) {
StringResource res = context.createResource(StringResource.class);
res.setValue(UnicodeHelper.compressRle(UnicodeSupport.getClasses()));
return res;
}
}

View File

@ -1,88 +0,0 @@
/*
* 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.classlib.java.lang;
import java.io.IOException;
import org.teavm.classlib.impl.unicode.UnicodeHelper;
import org.teavm.classlib.impl.unicode.UnicodeSupport;
import org.teavm.codegen.SourceWriter;
import org.teavm.dependency.DependencyAgent;
import org.teavm.dependency.DependencyPlugin;
import org.teavm.dependency.MethodDependency;
import org.teavm.javascript.ni.Generator;
import org.teavm.javascript.ni.GeneratorContext;
import org.teavm.model.CallLocation;
import org.teavm.model.MethodReference;
/**
*
* @author Alexey Andreev
*/
public class CharacterNativeGenerator implements Generator, DependencyPlugin {
@Override
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException {
switch (methodRef.getName()) {
case "toLowerCase":
writer.append("return String.fromCharCode(").append(context.getParameterName(1))
.append(").toLowerCase().charCodeAt(0)|0;").softNewLine();
break;
case "toUpperCase":
writer.append("return String.fromCharCode(").append(context.getParameterName(1))
.append(").toUpperCase().charCodeAt(0)|0;").softNewLine();
break;
case "obtainDigitMapping":
generateObtainDigitMapping(writer);
break;
case "obtainClasses":
generateObtainClasses(writer);
break;
}
}
@Override
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
switch (method.getReference().getName()) {
case "obtainDigitMapping":
case "obtainClasses":
method.getResult().propagate(agent.getType("java.lang.String"));
break;
}
}
private void generateObtainDigitMapping(SourceWriter writer) throws IOException {
String str = UnicodeHelper.encodeIntByte(UnicodeSupport.getDigitValues());
writer.append("return $rt_str(");
splitString(writer, str);
writer.append(");").softNewLine();
}
private void generateObtainClasses(SourceWriter writer) throws IOException {
String str = UnicodeHelper.compressRle(UnicodeSupport.getClasses());
writer.append("return $rt_str(");
splitString(writer, str);
writer.append(");").softNewLine();
}
private void splitString(SourceWriter writer, String str) throws IOException {
for (int i = 0; i < str.length(); i += 512) {
if (i > 0) {
writer.ws().append("+").newLine();
}
int j = Math.min(i + 512, str.length());
writer.append("\"").append(str.substring(i, j)).append("\"");
}
}
}

View File

@ -1,216 +0,0 @@
/*
* Copyright 2013 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.classlib.java.lang;
import java.io.IOException;
import org.teavm.codegen.SourceWriter;
import org.teavm.dependency.DependencyAgent;
import org.teavm.dependency.DependencyPlugin;
import org.teavm.dependency.MethodDependency;
import org.teavm.javascript.ni.Generator;
import org.teavm.javascript.ni.GeneratorContext;
import org.teavm.javascript.ni.Injector;
import org.teavm.javascript.ni.InjectorContext;
import org.teavm.model.*;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class ClassNativeGenerator implements Generator, Injector, DependencyPlugin {
@Override
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef)
throws IOException {
switch (methodRef.getName()) {
case "getComponentType0":
generateGetComponentType(context, writer);
break;
case "getSuperclass":
generateGetSuperclass(context, writer);
break;
case "forNameImpl":
generateForName(context, writer);
break;
case "newInstance":
generateNewInstance(context, writer);
break;
case "getDeclaringClass":
generateGetDeclaringClass(context, writer);
break;
}
}
private void generateGetComponentType(GeneratorContext context, SourceWriter writer) throws IOException {
String thisArg = context.getParameterName(0);
writer.append("var item = " + thisArg + ".$data.$meta.item;").softNewLine();
writer.append("return item != null ? $rt_cls(item) : null;").softNewLine();
}
private void generateGetSuperclass(GeneratorContext context, SourceWriter writer) throws IOException {
String thisArg = context.getParameterName(0);
writer.append("var superclass = " + thisArg + ".$data.$meta.superclass;").softNewLine();
writer.append("return superclass ? $rt_cls(superclass) : null;").softNewLine();
}
@Override
public void generate(InjectorContext context, MethodReference methodRef) throws IOException {
switch (methodRef.getName()) {
case "isInstance":
generateIsInstance(context);
break;
case "isAssignableFrom":
generateIsAssignableFrom(context);
break;
case "voidClass":
context.getWriter().append("$rt_cls($rt_voidcls())");
break;
case "booleanClass":
context.getWriter().append("$rt_cls($rt_booleancls())");
break;
case "charClass":
context.getWriter().append("$rt_cls($rt_charcls())");
break;
case "byteClass":
context.getWriter().append("$rt_cls($rt_bytecls())");
break;
case "shortClass":
context.getWriter().append("$rt_cls($rt_shortcls())");
break;
case "intClass":
context.getWriter().append("$rt_cls($rt_intcls())");
break;
case "longClass":
context.getWriter().append("$rt_cls($rt_longcls())");
break;
case "floatClass":
context.getWriter().append("$rt_cls($rt_floatcls())");
break;
case "doubleClass":
context.getWriter().append("$rt_cls($rt_doublecls())");
break;
case "wrapClass":
context.writeExpr(context.getArgument(0));
break;
case "getEnumConstantsImpl":
context.writeExpr(context.getArgument(0));
context.getWriter().append(".$data.values()");
break;
}
}
private void generateIsAssignableFrom(InjectorContext context) throws IOException {
SourceWriter writer = context.getWriter();
writer.append("$rt_isAssignable(");
context.writeExpr(context.getArgument(1));
writer.append(".$data,").ws();
context.writeExpr(context.getArgument(0));
writer.append(".$data)");
}
private void generateIsInstance(InjectorContext context) throws IOException {
SourceWriter writer = context.getWriter();
writer.append("$rt_isInstance(");
context.writeExpr(context.getArgument(1));
writer.append(",").ws();
context.writeExpr(context.getArgument(0));
writer.append(".$data)");
}
private void generateForName(GeneratorContext context, SourceWriter writer) throws IOException {
String param = context.getParameterName(1);
writer.append("switch ($rt_ustr(" + param + ")) {").softNewLine().indent();
for (String name : context.getClassSource().getClassNames()) {
writer.append("case \"" + name + "\": ").appendClass(name).append(".$clinit(); ")
.append("return $rt_cls(").appendClass(name).append(");").softNewLine();
}
writer.append("default: return null;").softNewLine();
writer.outdent().append("}").softNewLine();
}
private void generateNewInstance(GeneratorContext context, SourceWriter writer) throws IOException {
String self = context.getParameterName(0);
writer.append("if (!").appendClass("java.lang.Class").append(".$$constructors$$) {").indent().softNewLine();
writer.appendClass("java.lang.Class").append(".$$constructors$$ = true;").softNewLine();
for (String clsName : context.getClassSource().getClassNames()) {
ClassReader cls = context.getClassSource().get(clsName);
MethodReader method = cls.getMethod(new MethodDescriptor("<init>", ValueType.VOID));
if (method != null) {
writer.appendClass(clsName).append(".$$constructor$$ = ").appendMethodBody(method.getReference())
.append(";").softNewLine();
}
}
writer.outdent().append("}").softNewLine();
writer.append("var cls = " + self + ".$data;").softNewLine();
writer.append("var ctor = cls.$$constructor$$;").softNewLine();
writer.append("if (!ctor) {").indent().softNewLine();
writer.append("var ex = new ").appendClass(InstantiationException.class.getName()).append("();").softNewLine();
writer.appendMethodBody(new MethodReference(InstantiationException.class.getName(), new MethodDescriptor(
"<init>", ValueType.VOID))).append("(ex);").softNewLine();
writer.append("$rt_throw(ex);").softNewLine();
writer.outdent().append("}").softNewLine();
writer.append("var instance = new cls();").softNewLine();
writer.append("ctor(instance);").softNewLine();
writer.append("return instance;").softNewLine();
}
private void generateGetDeclaringClass(GeneratorContext context, SourceWriter writer) throws IOException {
String self = context.getParameterName(0);
writer.append("if (!").appendClass("java.lang.Class").append(".$$owners$$) {").indent().softNewLine();
writer.appendClass("java.lang.Class").append(".$$owners$$ = true;").softNewLine();
for (String clsName : context.getClassSource().getClassNames()) {
ClassReader cls = context.getClassSource().get(clsName);
writer.appendClass(clsName).append(".$$owner$$ = ");
if (cls.getOwnerName() != null) {
writer.appendClass(cls.getOwnerName());
} else {
writer.append("null");
}
writer.append(";").softNewLine();
}
writer.outdent().append("}").softNewLine();
writer.append("var cls = " + self + ".$data;").softNewLine();
writer.append("return cls.$$owner$$ != null ? $rt_cls(cls.$$owner$$) : null;").softNewLine();
}
@Override
public void methodAchieved(DependencyAgent agent, MethodDependency graph, CallLocation location) {
switch (graph.getReference().getName()) {
case "voidClass":
case "booleanClass":
case "byteClass":
case "shortClass":
case "charClass":
case "intClass":
case "longClass":
case "floatClass":
case "doubleClass":
case "wrapClass":
case "getSuperclass":
case "getComponentType0":
case "forNameImpl":
case "getDeclaringClass":
graph.getResult().propagate(agent.getType("java.lang.Class"));
break;
case "getName":
graph.getResult().propagate(agent.getType("java.lang.String"));
break;
case "newInstance":
agent.linkMethod(new MethodReference(InstantiationException.class, "<init>", void.class),
location).use();
break;
}
}
}

View File

@ -1,41 +0,0 @@
/*
* Copyright 2013 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.classlib.java.lang;
import java.io.IOException;
import org.teavm.codegen.SourceWriter;
import org.teavm.javascript.ni.Generator;
import org.teavm.javascript.ni.GeneratorContext;
import org.teavm.model.MethodReference;
/**
*
* @author Alexey Andreev
*/
public class ConsoleOutputStreamGenerator implements Generator {
@Override
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException {
if (methodRef.getClassName().endsWith("_stderr")) {
if (methodRef.getName().equals("write")) {
writer.append("$rt_putStderr(").append(context.getParameterName(1)).append(");").softNewLine();
}
} else if (methodRef.getClassName().endsWith("_stdout")) {
if (methodRef.getName().equals("write")) {
writer.append("$rt_putStdout(").append(context.getParameterName(1)).append(");").softNewLine();
}
}
}
}

View File

@ -17,10 +17,10 @@ package org.teavm.classlib.java.lang;
import java.io.IOException; import java.io.IOException;
import org.teavm.codegen.SourceWriter; import org.teavm.codegen.SourceWriter;
import org.teavm.javascript.ni.Generator; import org.teavm.javascript.spi.Generator;
import org.teavm.javascript.ni.GeneratorContext; import org.teavm.javascript.spi.GeneratorContext;
import org.teavm.javascript.ni.Injector; import org.teavm.javascript.spi.Injector;
import org.teavm.javascript.ni.InjectorContext; import org.teavm.javascript.spi.InjectorContext;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
/** /**

View File

@ -17,10 +17,10 @@ package org.teavm.classlib.java.lang;
import java.io.IOException; import java.io.IOException;
import org.teavm.codegen.SourceWriter; import org.teavm.codegen.SourceWriter;
import org.teavm.javascript.ni.Generator; import org.teavm.javascript.spi.Generator;
import org.teavm.javascript.ni.GeneratorContext; import org.teavm.javascript.spi.GeneratorContext;
import org.teavm.javascript.ni.Injector; import org.teavm.javascript.spi.Injector;
import org.teavm.javascript.ni.InjectorContext; import org.teavm.javascript.spi.InjectorContext;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
/** /**

View File

@ -17,8 +17,8 @@ package org.teavm.classlib.java.lang;
import java.io.IOException; import java.io.IOException;
import org.teavm.codegen.SourceWriter; import org.teavm.codegen.SourceWriter;
import org.teavm.javascript.ni.Generator; import org.teavm.javascript.spi.Generator;
import org.teavm.javascript.ni.GeneratorContext; import org.teavm.javascript.spi.GeneratorContext;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
/** /**

View File

@ -17,8 +17,8 @@ package org.teavm.classlib.java.lang;
import java.io.IOException; import java.io.IOException;
import org.teavm.codegen.SourceWriter; import org.teavm.codegen.SourceWriter;
import org.teavm.javascript.ni.Generator; import org.teavm.javascript.spi.Generator;
import org.teavm.javascript.ni.GeneratorContext; import org.teavm.javascript.spi.GeneratorContext;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
/** /**

View File

@ -1,182 +0,0 @@
/*
* Copyright 2013 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.classlib.java.lang;
import java.io.IOException;
import org.teavm.codegen.SourceWriter;
import org.teavm.dependency.*;
import org.teavm.javascript.ni.Generator;
import org.teavm.javascript.ni.GeneratorContext;
import org.teavm.javascript.ni.Injector;
import org.teavm.javascript.ni.InjectorContext;
import org.teavm.model.CallLocation;
import org.teavm.model.MethodReference;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class ObjectNativeGenerator implements Generator, Injector, DependencyPlugin {
@Override
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException {
switch (methodRef.getDescriptor().getName()) {
case "<init>":
generateInit(context, writer);
break;
case "hashCode":
case "identity":
generateHashCode(context, writer);
break;
case "clone":
generateClone(context, writer);
break;
case "wait":
generateWait(context, writer);
break;
case "notify":
generateNotify(context, writer);
break;
case "notifyAll":
generateNotifyAll(context, writer);
break;
}
}
@Override
public void generate(InjectorContext context, MethodReference methodRef) throws IOException {
switch (methodRef.getName()) {
case "getClass":
generateGetClass(context);
break;
case "wrap":
generateWrap(context);
break;
}
}
@Override
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
switch (method.getReference().getName()) {
case "clone":
method.getVariable(0).connect(method.getResult());
break;
case "getClass":
achieveGetClass(agent, method);
break;
case "wrap":
method.getVariable(1).connect(method.getResult());
break;
//case "wait":
// method.getVariable(0).connect(method.getResult());
// break;
}
}
private void generateInit(GeneratorContext context, SourceWriter writer) throws IOException {
writer.append(context.getParameterName(0)).append(".$id = $rt_nextId();").softNewLine();
}
private void generateGetClass(InjectorContext context) throws IOException {
SourceWriter writer = context.getWriter();
writer.append("$rt_cls(");
context.writeExpr(context.getArgument(0));
writer.append(".constructor)");
}
private void achieveGetClass(DependencyAgent agent, MethodDependency method) {
MethodReference initMethod = new MethodReference(Class.class, "createNew", Class.class);
agent.linkMethod(initMethod, null).use();
method.getResult().propagate(agent.getType("java.lang.Class"));
}
private void generateHashCode(GeneratorContext context, SourceWriter writer) throws IOException {
writer.append("return ").append(context.getParameterName(0)).append(".$id;").softNewLine();
}
private void generateClone(GeneratorContext context, SourceWriter writer) throws IOException {
String obj = context.getParameterName(0);
writer.append("var copy = new ").append(obj).append(".constructor();").softNewLine();
writer.append("for (var field in " + obj + ") {").softNewLine().indent();
writer.append("if (!" + obj + ".hasOwnProperty(field)) {").softNewLine().indent();
writer.append("continue;").softNewLine().outdent().append("}").softNewLine();
writer.append("copy[field] = " + obj + "[field];").softNewLine().outdent().append("}").softNewLine();
writer.append("return copy;").softNewLine();
}
private void generateWrap(InjectorContext context) throws IOException {
context.writeExpr(context.getArgument(0));
}
private void generateWait(GeneratorContext context, SourceWriter writer) throws IOException {
String pname = context.getParameterName(1);
String obj = context.getParameterName(0);
writer.append("(function(){").indent().softNewLine();
writer.append("var completed = false;").softNewLine();
writer.append("var retCallback = ").append(context.getCompleteContinuation()).append(";").softNewLine();
writer.append("var callback = function(){").indent().softNewLine();
writer.append("if (completed){return;} completed=true;").softNewLine();
writer.append("retCallback($rt_asyncResult(null));").softNewLine();
writer.outdent().append("};").softNewLine();
writer.append("if (").append(pname).append(">0){").indent().softNewLine();
writer.append("$rt_setTimeout(callback, ").append(pname).append(");").softNewLine();
writer.outdent().append("}").softNewLine();
addNotifyListener(context, writer, "callback");
writer.outdent().append("})();").softNewLine();
}
private void generateNotify(GeneratorContext context, SourceWriter writer) throws IOException {
sendNotify(context, writer);
}
private void generateNotifyAll(GeneratorContext context, SourceWriter writer) throws IOException {
sendNotifyAll(context, writer);
}
private String getNotifyListeners(GeneratorContext context){
return context.getParameterName(0)+".__notifyListeners";
}
private void addNotifyListener(GeneratorContext context, SourceWriter writer, String callback) throws IOException {
String lArr = getNotifyListeners(context);
writer.append(lArr).append("=").append(lArr).append("||[];").softNewLine();
writer.append(lArr).append(".push(").append(callback).append(");").softNewLine();
}
private void sendNotify(GeneratorContext context, SourceWriter writer) throws IOException {
String lArr = getNotifyListeners(context);
writer.append("$rt_setTimeout(function(){").indent().softNewLine();
writer.append("if (!").append(lArr).append(" || ").append(lArr).append(".length===0){return;}").softNewLine();
writer.append(lArr).append(".shift().apply(null);").softNewLine();
writer.outdent().append("}, 0);").softNewLine();
}
private void sendNotifyAll(GeneratorContext context, SourceWriter writer) throws IOException {
String obj = context.getParameterName(0);
String lArr = getNotifyListeners(context);
writer.append("$rt_setTimeout(function(){").indent().softNewLine();
writer.append("if (!").append(lArr).append("){return;}").softNewLine();
writer.append("while (").append(lArr).append(".length>0){").indent().softNewLine();
writer.append(lArr).append(".shift().call(null);").softNewLine();
writer.outdent().append("}");
writer.outdent().append("}, 0);").softNewLine();
}
}

View File

@ -1,49 +0,0 @@
/*
* Copyright 2013 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.classlib.java.lang;
import java.io.IOException;
import org.teavm.dependency.DependencyAgent;
import org.teavm.dependency.DependencyPlugin;
import org.teavm.dependency.MethodDependency;
import org.teavm.javascript.ni.Injector;
import org.teavm.javascript.ni.InjectorContext;
import org.teavm.model.CallLocation;
import org.teavm.model.MethodReference;
/**
*
* @author Alexey Andreev
*/
public class StringNativeGenerator implements Injector, DependencyPlugin {
@Override
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
switch (method.getReference().getName()) {
case "wrap":
method.getVariable(1).connect(method.getResult());
break;
}
}
@Override
public void generate(InjectorContext context, MethodReference methodRef) throws IOException {
switch (methodRef.getName()) {
case "wrap":
context.writeExpr(context.getArgument(0));
break;
}
}
}

View File

@ -18,8 +18,8 @@ package org.teavm.classlib.java.lang;
import java.io.IOException; import java.io.IOException;
import org.teavm.codegen.SourceWriter; import org.teavm.codegen.SourceWriter;
import org.teavm.dependency.*; import org.teavm.dependency.*;
import org.teavm.javascript.ni.Generator; import org.teavm.javascript.spi.Generator;
import org.teavm.javascript.ni.GeneratorContext; import org.teavm.javascript.spi.GeneratorContext;
import org.teavm.model.CallLocation; import org.teavm.model.CallLocation;
import org.teavm.model.FieldReference; import org.teavm.model.FieldReference;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
@ -48,9 +48,6 @@ public class SystemNativeGenerator implements Generator, DependencyPlugin {
.appendField(new FieldReference("java.lang.System", "err")) .appendField(new FieldReference("java.lang.System", "err"))
.ws().append('=').ws().append(context.getParameterName(1)).append(";").softNewLine(); .ws().append('=').ws().append(context.getParameterName(1)).append(";").softNewLine();
break; break;
case "identityHashCode":
writer.append("return ").append(context.getParameterName(1)).append(".$id;").softNewLine();
break;
} }
} }

View File

@ -16,7 +16,6 @@
package org.teavm.classlib.java.lang; package org.teavm.classlib.java.lang;
import org.teavm.classlib.java.io.TSerializable; import org.teavm.classlib.java.io.TSerializable;
import org.teavm.javascript.ni.GeneratedBy;
/** /**
* *
@ -80,7 +79,6 @@ public class TBoolean extends TObject implements TSerializable, TComparable<TBoo
} }
@Override @Override
@GeneratedBy(ObjectNativeGenerator.class)
public int hashCode() { public int hashCode() {
return value ? 1231 : 1237; return value ? 1231 : 1237;
} }

View File

@ -17,8 +17,9 @@ package org.teavm.classlib.java.lang;
import org.teavm.classlib.impl.charset.UTF16Helper; import org.teavm.classlib.impl.charset.UTF16Helper;
import org.teavm.classlib.impl.unicode.UnicodeHelper; import org.teavm.classlib.impl.unicode.UnicodeHelper;
import org.teavm.dependency.PluggableDependency; import org.teavm.platform.Platform;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.platform.metadata.MetadataProvider;
import org.teavm.platform.metadata.StringResource;
/** /**
* *
@ -222,18 +223,21 @@ public class TCharacter extends TObject implements TComparable<TCharacter> {
return UTF16Helper.lowSurrogate(codePoint); return UTF16Helper.lowSurrogate(codePoint);
} }
// TODO: implement toLowerCase/toUpperCase/toTitleCase using UnicodeData.txt instead of built-in JS public static char toLowerCase(char ch) {
@GeneratedBy(CharacterNativeGenerator.class) return (char)toLowerCase((int)ch);
public static native char toLowerCase(char ch); }
@GeneratedBy(CharacterNativeGenerator.class) public static int toLowerCase(int ch) {
public static native int toLowerCase(int ch); return Platform.stringFromCharCode(ch).toLowerCase().charCodeAt(0);
}
@GeneratedBy(CharacterNativeGenerator.class) public static char toUpperCase(char ch) {
public static native char toUpperCase(char ch); return (char)toUpperCase((int)ch);
}
@GeneratedBy(CharacterNativeGenerator.class) public static int toUpperCase(int codePoint) {
public static native int toUpperCase(int codePoint); return Platform.stringFromCharCode(codePoint).toUpperCase().charCodeAt(0);
}
public static int digit(char ch, int radix) { public static int digit(char ch, int radix) {
return digit((int)ch, radix); return digit((int)ch, radix);
@ -286,25 +290,23 @@ public class TCharacter extends TObject implements TComparable<TCharacter> {
private static int[] getDigitMapping() { private static int[] getDigitMapping() {
if (digitMapping == null) { if (digitMapping == null) {
digitMapping = UnicodeHelper.decodeIntByte(obtainDigitMapping()); digitMapping = UnicodeHelper.decodeIntByte(obtainDigitMapping().getValue());
} }
return digitMapping; return digitMapping;
} }
@GeneratedBy(CharacterNativeGenerator.class) @MetadataProvider(CharacterMetadataGenerator.class)
@PluggableDependency(CharacterNativeGenerator.class) private static native StringResource obtainDigitMapping();
private static native String obtainDigitMapping();
private static UnicodeHelper.Range[] getClasses() { private static UnicodeHelper.Range[] getClasses() {
if (classMapping == null) { if (classMapping == null) {
classMapping = UnicodeHelper.extractRle(obtainClasses()); classMapping = UnicodeHelper.extractRle(obtainClasses().getValue());
} }
return classMapping; return classMapping;
} }
@GeneratedBy(CharacterNativeGenerator.class) @MetadataProvider(CharacterMetadataGenerator.class)
@PluggableDependency(CharacterNativeGenerator.class) private static native StringResource obtainClasses();
private static native String obtainClasses();
public static int toChars(int codePoint, char[] dst, int dstIndex) { public static int toChars(int codePoint, char[] dst, int dstIndex) {
if (codePoint >= UTF16Helper.SUPPLEMENTARY_PLANE) { if (codePoint >= UTF16Helper.SUPPLEMENTARY_PLANE) {

View File

@ -15,9 +15,11 @@
*/ */
package org.teavm.classlib.java.lang; package org.teavm.classlib.java.lang;
import org.teavm.dependency.PluggableDependency; import org.teavm.classlib.impl.DeclaringClassMetadataGenerator;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.platform.Platform;
import org.teavm.javascript.ni.InjectedBy; import org.teavm.platform.PlatformClass;
import org.teavm.platform.metadata.ClassResource;
import org.teavm.platform.metadata.ClassScopedMetadataProvider;
/** /**
* *
@ -25,113 +27,130 @@ import org.teavm.javascript.ni.InjectedBy;
*/ */
public class TClass<T> extends TObject { public class TClass<T> extends TObject {
TString name; TString name;
TString binaryName;
boolean primitive;
boolean array;
boolean isEnum;
private TClass<?> componentType; private TClass<?> componentType;
private boolean componentTypeDirty = true; private boolean componentTypeDirty = true;
private PlatformClass platformClass;
static TClass<?> createNew() { private TClass(PlatformClass platformClass) {
return new TClass<>(); this.platformClass = platformClass;
platformClass.setJavaClass(Platform.getPlatformObject(this));
} }
@InjectedBy(ClassNativeGenerator.class) public static TClass<?> getClass(PlatformClass cls) {
public native boolean isInstance(TObject obj); if (cls == null) {
return null;
}
TClass<?> result = (TClass<?>)(Object)Platform.asJavaClass(cls.getJavaClass());
if (result == null) {
result = new TClass<>(cls);
}
return result;
}
@InjectedBy(ClassNativeGenerator.class) public PlatformClass getPlatformClass() {
public native boolean isAssignableFrom(TClass<?> obj); return platformClass;
}
public boolean isInstance(TObject obj) {
return Platform.isInstance(Platform.getPlatformObject(obj), platformClass);
}
public boolean isAssignableFrom(TClass<?> obj) {
return Platform.isAssignable(obj.getPlatformClass(), platformClass);
}
@PluggableDependency(ClassNativeGenerator.class)
public TString getName() { public TString getName() {
if (name == null) {
name = TString.wrap(platformClass.getMetadata().getName());
}
return name; return name;
} }
public boolean isPrimitive() { public boolean isPrimitive() {
return primitive; return platformClass.getMetadata().isPrimitive();
} }
public boolean isArray() { public boolean isArray() {
return array; return platformClass.getMetadata().getArrayItem() != null;
} }
public boolean isEnum() { public boolean isEnum() {
return isEnum; return platformClass.getMetadata().isEnum();
} }
public TClass<?> getComponentType() { public TClass<?> getComponentType() {
if (componentTypeDirty) { if (componentTypeDirty) {
componentType = getComponentType0(); PlatformClass arrayItem = platformClass.getMetadata().getArrayItem();
componentType = arrayItem != null ? getClass(arrayItem) : null;
componentTypeDirty = false; componentTypeDirty = false;
} }
return componentType; return componentType;
} }
@GeneratedBy(ClassNativeGenerator.class) @SuppressWarnings("unchecked")
@PluggableDependency(ClassNativeGenerator.class) static TClass<TVoid> voidClass() {
private native TClass<?> getComponentType0(); return (TClass<TVoid>)getClass(Platform.getPrimitives().getVoidClass());
}
@InjectedBy(ClassNativeGenerator.class) @SuppressWarnings("unchecked")
@PluggableDependency(ClassNativeGenerator.class) static TClass<TBoolean> booleanClass() {
static native TClass<TVoid> voidClass(); return (TClass<TBoolean>)getClass(Platform.getPrimitives().getBooleanClass());
}
@InjectedBy(ClassNativeGenerator.class) @SuppressWarnings("unchecked")
@PluggableDependency(ClassNativeGenerator.class) static TClass<TCharacter> charClass() {
static native TClass<TBoolean> booleanClass(); return (TClass<TCharacter>)getClass(Platform.getPrimitives().getCharClass());
}
@InjectedBy(ClassNativeGenerator.class) @SuppressWarnings("unchecked")
@PluggableDependency(ClassNativeGenerator.class) static TClass<TByte> byteClass() {
static native TClass<TCharacter> charClass(); return (TClass<TByte>)getClass(Platform.getPrimitives().getByteClass());
}
@InjectedBy(ClassNativeGenerator.class) @SuppressWarnings("unchecked")
@PluggableDependency(ClassNativeGenerator.class) static TClass<TShort> shortClass() {
static native TClass<TByte> byteClass(); return (TClass<TShort>)getClass(Platform.getPrimitives().getShortClass());
}
@InjectedBy(ClassNativeGenerator.class) @SuppressWarnings("unchecked")
@PluggableDependency(ClassNativeGenerator.class) static TClass<TInteger> intClass() {
static native TClass<TShort> shortClass(); return (TClass<TInteger>)getClass(Platform.getPrimitives().getIntClass());
}
@InjectedBy(ClassNativeGenerator.class) @SuppressWarnings("unchecked")
@PluggableDependency(ClassNativeGenerator.class) static TClass<TLong> longClass() {
static native TClass<TInteger> intClass(); return (TClass<TLong>)getClass(Platform.getPrimitives().getLongClass());
}
@InjectedBy(ClassNativeGenerator.class) @SuppressWarnings("unchecked")
@PluggableDependency(ClassNativeGenerator.class) static TClass<TFloat> floatClass() {
static native TClass<TLong> longClass(); return (TClass<TFloat>)getClass(Platform.getPrimitives().getFloatClass());
}
@InjectedBy(ClassNativeGenerator.class) @SuppressWarnings("unchecked")
@PluggableDependency(ClassNativeGenerator.class) static TClass<TDouble> doubleClass() {
static native TClass<TFloat> floatClass(); return (TClass<TDouble>)getClass(Platform.getPrimitives().getDoubleClass());
}
@InjectedBy(ClassNativeGenerator.class)
@PluggableDependency(ClassNativeGenerator.class)
static native TClass<TDouble> doubleClass();
@InjectedBy(ClassNativeGenerator.class)
@PluggableDependency(ClassNativeGenerator.class)
public static native <S extends TObject> TClass<S> wrapClass(Class<S> cls);
public boolean desiredAssertionStatus() { public boolean desiredAssertionStatus() {
return true; return true;
} }
@GeneratedBy(ClassNativeGenerator.class) @SuppressWarnings("unchecked")
@PluggableDependency(ClassNativeGenerator.class) public TClass<? super T> getSuperclass() {
public native TClass<? super T> getSuperclass(); return (TClass<? super T>)getClass(platformClass.getMetadata().getSuperclass());
public T[] getEnumConstants() {
return isEnum ? getEnumConstantsImpl() : null;
} }
@InjectedBy(ClassNativeGenerator.class) @SuppressWarnings("unchecked")
public native T[] getEnumConstantsImpl(); public T[] getEnumConstants() {
return isEnum() ? (T[])Platform.getEnumConstants(platformClass) : null;
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public T cast(TObject obj) { public T cast(TObject obj) {
if (obj != null && !isAssignableFrom(TClass.wrapClass(obj.getClass()))) { if (obj != null && !isAssignableFrom((TClass<?>)(Object)obj.getClass())) {
throw new TClassCastException(TString.wrap(new TStringBuilder() throw new TClassCastException(TString.wrap(obj.getClass().getName() +
.append(TClass.wrapClass(obj.getClass()).getName()) " is not subtype of " + name));
.append(TString.wrap(" is not subtype of ")).append(name).toString()));
} }
return (T)obj; return (T)obj;
} }
@ -140,31 +159,36 @@ public class TClass<T> extends TObject {
return TClassLoader.getSystemClassLoader(); return TClassLoader.getSystemClassLoader();
} }
@GeneratedBy(ClassNativeGenerator.class)
@PluggableDependency(ClassNativeGenerator.class)
private static native TClass<?> forNameImpl(TString name);
public static TClass<?> forName(TString name) throws TClassNotFoundException { public static TClass<?> forName(TString name) throws TClassNotFoundException {
TClass<?> result = forNameImpl(name); PlatformClass cls = Platform.lookupClass(name.toString());
if (result == null) { if (cls == null) {
throw new TClassNotFoundException(); throw new TClassNotFoundException();
} }
return result; return getClass(cls);
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
public static TClass<?> forName(TString name, boolean initialize, TClassLoader loader) public static TClass<?> forName(TString name, boolean initialize, TClassLoader loader)
throws TClassNotFoundException { throws TClassNotFoundException {
return forName(name); return forName(name);
} }
@GeneratedBy(ClassNativeGenerator.class) @SuppressWarnings("unchecked")
@PluggableDependency(ClassNativeGenerator.class) public T newInstance() throws TInstantiationException, TIllegalAccessException {
public native T newInstance() throws TInstantiationException, TIllegalAccessException; Object instance = Platform.newInstance(platformClass);
if (instance == null) {
throw new TInstantiationException();
}
return (T)instance;
}
@GeneratedBy(ClassNativeGenerator.class) public TClass<?> getDeclaringClass() {
@PluggableDependency(ClassNativeGenerator.class) ClassResource res = getDeclaringClass(platformClass);
public native TClass<?> getDeclaringClass(); return res != null ? getClass(Platform.classFromResource(res)) : null;
}
@ClassScopedMetadataProvider(DeclaringClassMetadataGenerator.class)
private static native ClassResource getDeclaringClass(PlatformClass cls);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <U> TClass<? extends U> asSubclass(TClass<U> clazz) { public <U> TClass<? extends U> asSubclass(TClass<U> clazz) {

View File

@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang;
import org.teavm.classlib.java.io.TIOException; import org.teavm.classlib.java.io.TIOException;
import org.teavm.classlib.java.io.TOutputStream; import org.teavm.classlib.java.io.TOutputStream;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.platform.Platform;
/** /**
* *
@ -25,6 +25,7 @@ import org.teavm.javascript.ni.GeneratedBy;
*/ */
class TConsoleOutputStream_stderr extends TOutputStream { class TConsoleOutputStream_stderr extends TOutputStream {
@Override @Override
@GeneratedBy(ConsoleOutputStreamGenerator.class) public void write(int b) throws TIOException {
public native void write(int b) throws TIOException; Platform.getConsole().error(b);
}
} }

View File

@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang;
import org.teavm.classlib.java.io.TIOException; import org.teavm.classlib.java.io.TIOException;
import org.teavm.classlib.java.io.TOutputStream; import org.teavm.classlib.java.io.TOutputStream;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.platform.Platform;
/** /**
* *
@ -25,6 +25,7 @@ import org.teavm.javascript.ni.GeneratedBy;
*/ */
class TConsoleOutputStream_stdout extends TOutputStream { class TConsoleOutputStream_stdout extends TOutputStream {
@Override @Override
@GeneratedBy(ConsoleOutputStreamGenerator.class) public void write(int b) throws TIOException {
public native void write(int b) throws TIOException; Platform.getConsole().output(b);
}
} }

View File

@ -15,8 +15,8 @@
*/ */
package org.teavm.classlib.java.lang; package org.teavm.classlib.java.lang;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.javascript.spi.GeneratedBy;
import org.teavm.javascript.ni.InjectedBy; import org.teavm.javascript.spi.InjectedBy;
/** /**
* *

View File

@ -16,7 +16,7 @@
package org.teavm.classlib.java.lang; package org.teavm.classlib.java.lang;
import org.teavm.classlib.java.io.TSerializable; import org.teavm.classlib.java.io.TSerializable;
import org.teavm.javascript.ni.Rename; import org.teavm.javascript.spi.Rename;
/** /**
* *
@ -61,7 +61,7 @@ public abstract class TEnum<E extends TEnum<E>> extends TObject implements TComp
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public final TClass<E> getDeclaringClass() { public final TClass<E> getDeclaringClass() {
return (TClass<E>)TClass.wrapClass(getClass()); return (TClass<E>)(Object)getClass();
} }
@Override @Override

View File

@ -15,7 +15,7 @@
*/ */
package org.teavm.classlib.java.lang; package org.teavm.classlib.java.lang;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.javascript.spi.GeneratedBy;
/** /**
* *

View File

@ -15,7 +15,7 @@
*/ */
package org.teavm.classlib.java.lang; package org.teavm.classlib.java.lang;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.javascript.spi.GeneratedBy;
/** /**
* *

View File

@ -15,7 +15,7 @@
*/ */
package org.teavm.classlib.java.lang; package org.teavm.classlib.java.lang;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.javascript.spi.GeneratedBy;
/** /**
* *

View File

@ -15,6 +15,7 @@
*/ */
package org.teavm.classlib.java.lang; package org.teavm.classlib.java.lang;
<<<<<<< HEAD
import org.teavm.dependency.PluggableDependency; import org.teavm.dependency.PluggableDependency;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.javascript.ni.GeneratedBy;
@ -22,6 +23,11 @@ import org.teavm.javascript.ni.InjectedBy;
import org.teavm.javascript.ni.Rename; import org.teavm.javascript.ni.Rename;
import org.teavm.javascript.ni.Superclass; import org.teavm.javascript.ni.Superclass;
import org.teavm.runtime.Async; import org.teavm.runtime.Async;
=======
import org.teavm.javascript.spi.Rename;
import org.teavm.javascript.spi.Superclass;
import org.teavm.platform.Platform;
>>>>>>> dd25ae4759716d735fe6f93a54c8bfab2e7fc7bf
/** /**
* *
@ -69,18 +75,20 @@ public class TObject {
public TObject() { public TObject() {
} }
@GeneratedBy(ObjectNativeGenerator.class)
@Rename("<init>") @Rename("<init>")
private native void init(); private void init() {
Platform.getPlatformObject(this).setId(Platform.nextObjectId());
}
@InjectedBy(ObjectNativeGenerator.class)
@Rename("getClass") @Rename("getClass")
@PluggableDependency(ObjectNativeGenerator.class) public final TClass<?> getClass0() {
public native final TClass<?> getClass0(); return TClass.getClass(Platform.getPlatformObject(this).getPlatformClass());
}
@Override @Override
@GeneratedBy(ObjectNativeGenerator.class) public int hashCode() {
public native int hashCode(); return identity();
}
@Rename("equals") @Rename("equals")
public boolean equals0(TObject other) { public boolean equals0(TObject other) {
@ -92,13 +100,19 @@ public class TObject {
return getClass().getName() + "@" + TInteger.toHexString(identity()); return getClass().getName() + "@" + TInteger.toHexString(identity());
} }
@GeneratedBy(ObjectNativeGenerator.class) int identity() {
native int identity(); return Platform.getPlatformObject(this).getId();
}
@GeneratedBy(ObjectNativeGenerator.class)
@PluggableDependency(ObjectNativeGenerator.class)
@Override @Override
protected native Object clone() throws TCloneNotSupportedException; protected Object clone() throws TCloneNotSupportedException {
if (!(this instanceof TCloneable) && Platform.getPlatformObject(this)
.getPlatformClass().getMetadata().getArrayItem() == null) {
throw new TCloneNotSupportedException();
}
Platform.getPlatformObject(this).setId(Platform.nextObjectId());
return Platform.clone(this);
}
@GeneratedBy(ObjectNativeGenerator.class) @GeneratedBy(ObjectNativeGenerator.class)
@Rename("notify") @Rename("notify")
@ -137,7 +151,7 @@ public class TObject {
protected void finalize() throws TThrowable { protected void finalize() throws TThrowable {
} }
@InjectedBy(ObjectNativeGenerator.class) public static TObject wrap(Object obj) {
@PluggableDependency(ObjectNativeGenerator.class) return (TObject)obj;
public static native TObject wrap(Object obj); }
} }

View File

@ -15,7 +15,7 @@
*/ */
package org.teavm.classlib.java.lang; package org.teavm.classlib.java.lang;
import org.teavm.javascript.ni.Superclass; import org.teavm.javascript.spi.Superclass;
/** /**
* *

View File

@ -23,8 +23,6 @@ import org.teavm.classlib.java.util.TComparator;
import org.teavm.classlib.java.util.THashMap; import org.teavm.classlib.java.util.THashMap;
import org.teavm.classlib.java.util.TMap; import org.teavm.classlib.java.util.TMap;
import org.teavm.classlib.java.util.regex.TPattern; import org.teavm.classlib.java.util.regex.TPattern;
import org.teavm.dependency.PluggableDependency;
import org.teavm.javascript.ni.InjectedBy;
/** /**
* *
@ -592,9 +590,9 @@ public class TString extends TObject implements TSerializable, TComparable<TStri
return hashCode; return hashCode;
} }
@InjectedBy(StringNativeGenerator.class) public static TString wrap(String str) {
@PluggableDependency(StringNativeGenerator.class) return (TString)(Object)str;
public static native TString wrap(String str); }
public TString toLowerCase() { public TString toLowerCase() {
if (isEmpty()) { if (isEmpty()) {

View File

@ -18,7 +18,7 @@ package org.teavm.classlib.java.lang;
import org.teavm.classlib.java.io.TPrintStream; import org.teavm.classlib.java.io.TPrintStream;
import org.teavm.classlib.java.lang.reflect.TArray; import org.teavm.classlib.java.lang.reflect.TArray;
import org.teavm.dependency.PluggableDependency; import org.teavm.dependency.PluggableDependency;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.javascript.spi.GeneratedBy;
/** /**
* *
@ -93,9 +93,9 @@ public final class TSystem extends TObject {
return currentTimeMillis() * 10000000; return currentTimeMillis() * 10000000;
} }
@GeneratedBy(SystemNativeGenerator.class) public static int identityHashCode(Object x) {
@PluggableDependency(SystemNativeGenerator.class) return ((TObject)x).identity();
public static native int identityHashCode(Object x); }
public static TString lineSeparator() { public static TString lineSeparator() {
return TString.wrap("\n"); return TString.wrap("\n");

View File

@ -15,20 +15,33 @@
*/ */
package org.teavm.classlib.java.lang; package org.teavm.classlib.java.lang;
<<<<<<< HEAD
import org.teavm.dependency.PluggableDependency; import org.teavm.dependency.PluggableDependency;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.javascript.ni.GeneratedBy;
import org.teavm.runtime.Async; import org.teavm.runtime.Async;
=======
import org.teavm.dom.browser.TimerHandler;
import org.teavm.dom.browser.Window;
import org.teavm.javascript.spi.Async;
import org.teavm.jso.JS;
import org.teavm.platform.async.AsyncCallback;
>>>>>>> dd25ae4759716d735fe6f93a54c8bfab2e7fc7bf
/** /**
* *
* @author Alexey Andreev * @author Alexey Andreev
*/ */
public class TThread extends TObject implements TRunnable { public class TThread extends TObject implements TRunnable {
<<<<<<< HEAD
private static TThread mainThread = new TThread(TString.wrap("main")); private static TThread mainThread = new TThread(TString.wrap("main"));
private static TThread currentThread = mainThread; private static TThread currentThread = mainThread;
private static long nextId = 1; private static long nextId = 1;
private static int activeCount = 1; private static int activeCount = 1;
private long id; private long id;
=======
private static Window window = (Window)JS.getGlobal();
private static TThread currentThread = new TThread(TString.wrap("main"));
>>>>>>> dd25ae4759716d735fe6f93a54c8bfab2e7fc7bf
private TString name; private TString name;
private TRunnable target; private TRunnable target;
@ -90,9 +103,16 @@ public class TThread extends TObject implements TRunnable {
} }
@Async @Async
@GeneratedBy(ThreadNativeGenerator.class)
public static native void yield(); public static native void yield();
private static void yield(final AsyncCallback<Void> callback) {
window.setTimeout(new TimerHandler() {
@Override public void onTimer() {
callback.complete(null);
}
}, 0);
}
public void interrupt() { public void interrupt() {
} }
@ -116,13 +136,21 @@ public class TThread extends TObject implements TRunnable {
return TObject.holdsLock(obj); return TObject.holdsLock(obj);
} }
public static void sleep(long millis) throws TInterruptedException {
sleep((double)millis);
}
@Async @Async
<<<<<<< HEAD
@GeneratedBy(ThreadNativeGenerator.class) @GeneratedBy(ThreadNativeGenerator.class)
private static native void sleep(double millis) throws TInterruptedException; private static native void sleep(double millis) throws TInterruptedException;
=======
public static native void sleep(long millis) throws TInterruptedException;
private static void sleep(long millis, final AsyncCallback<Void> callback) {
window.setTimeout(new TimerHandler() {
@Override public void onTimer() {
callback.complete(null);
}
}, millis);
}
>>>>>>> dd25ae4759716d735fe6f93a54c8bfab2e7fc7bf
} }

View File

@ -17,9 +17,9 @@ package org.teavm.classlib.java.lang;
import org.teavm.classlib.java.io.TPrintStream; import org.teavm.classlib.java.io.TPrintStream;
import org.teavm.classlib.java.util.TArrays; import org.teavm.classlib.java.util.TArrays;
import org.teavm.javascript.ni.Remove; import org.teavm.javascript.spi.Remove;
import org.teavm.javascript.ni.Rename; import org.teavm.javascript.spi.Rename;
import org.teavm.javascript.ni.Superclass; import org.teavm.javascript.spi.Superclass;
/** /**
* *

View File

@ -1,77 +0,0 @@
/*
* Copyright 2015 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.classlib.java.lang;
import java.io.IOException;
import org.teavm.codegen.SourceWriter;
import org.teavm.dependency.DependencyAgent;
import org.teavm.dependency.DependencyPlugin;
import org.teavm.dependency.MethodDependency;
import org.teavm.javascript.ni.Generator;
import org.teavm.javascript.ni.GeneratorContext;
import org.teavm.model.CallLocation;
import org.teavm.model.MethodReference;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class ThreadNativeGenerator implements Generator, DependencyPlugin {
private static final MethodReference launchRef = new MethodReference(Thread.class,
"launch", Thread.class, void.class);
@Override
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException {
if (methodRef.getName().equals("sleep")) {
generateSleep(context, writer);
} else if (methodRef.getName().equals("yield")) {
generateYield(context, writer);
} else if ( methodRef.getName().equals("start")){
generateStart(context, writer);
}
}
@Override
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
switch (method.getReference().getName()) {
case "start": {
MethodDependency performMethod = agent.linkMethod(launchRef, null);
method.getVariable(0).connect(performMethod.getVariable(1));
performMethod.use();
break;
}
}
}
private void generateSleep(GeneratorContext context, SourceWriter writer) throws IOException {
writer.append("$rt_setTimeout(function() {").indent().softNewLine();
writer.append(context.getCompleteContinuation()).append("($rt_asyncResult(null));").softNewLine();
writer.outdent().append("},").ws().append(context.getParameterName(1)).append(");").softNewLine();
}
private void generateYield(GeneratorContext context, SourceWriter writer) throws IOException {
writer.append("$rt_setTimeout(function() {").indent().softNewLine();
writer.append(context.getCompleteContinuation()).append("($rt_asyncResult(null));").softNewLine();
writer.outdent().append("},").ws().append("0);").softNewLine();
}
private void generateStart(GeneratorContext context, SourceWriter writer) throws IOException {
String obj = context.getParameterName(0);
writer.append("$rt_setTimeout(function() { $rt_rootInvocationAdapter(").appendMethodBody(launchRef).append(")(")
.append(obj).append(");},0);").softNewLine();
}
}

View File

@ -18,8 +18,8 @@ package org.teavm.classlib.java.lang.reflect;
import java.io.IOException; import java.io.IOException;
import org.teavm.codegen.SourceWriter; import org.teavm.codegen.SourceWriter;
import org.teavm.dependency.*; import org.teavm.dependency.*;
import org.teavm.javascript.ni.Generator; import org.teavm.javascript.spi.Generator;
import org.teavm.javascript.ni.GeneratorContext; import org.teavm.javascript.spi.GeneratorContext;
import org.teavm.model.CallLocation; import org.teavm.model.CallLocation;
import org.teavm.model.ClassReader; import org.teavm.model.ClassReader;
import org.teavm.model.MethodDescriptor; import org.teavm.model.MethodDescriptor;
@ -93,15 +93,14 @@ public class ArrayNativeGenerator implements Generator, DependencyPlugin {
private void generateNewInstance(GeneratorContext context, SourceWriter writer) throws IOException { private void generateNewInstance(GeneratorContext context, SourceWriter writer) throws IOException {
String type = context.getParameterName(1); String type = context.getParameterName(1);
String length = context.getParameterName(2); String length = context.getParameterName(2);
writer.append("var cls = " + type + ".$data;").softNewLine(); writer.append("if (").append(type).append(".$meta.primitive) {").softNewLine().indent();
writer.append("if (cls.primitive) {").softNewLine().indent();
for (String primitive : primitives) { for (String primitive : primitives) {
writer.append("if (cls == $rt_" + primitive.toLowerCase() + "cls()) {").indent().softNewLine(); writer.append("if (" + type + " == $rt_" + primitive.toLowerCase() + "cls()) {").indent().softNewLine();
writer.append("return $rt_create" + primitive + "Array(" + length + ");").softNewLine(); writer.append("return $rt_create" + primitive + "Array(" + length + ");").softNewLine();
writer.outdent().append("}").softNewLine(); writer.outdent().append("}").softNewLine();
} }
writer.outdent().append("} else {").indent().softNewLine(); writer.outdent().append("} else {").indent().softNewLine();
writer.append("return $rt_createArray(cls, " + length + ")").softNewLine(); writer.append("return $rt_createArray(" + type + ", " + length + ")").softNewLine();
writer.outdent().append("}").softNewLine(); writer.outdent().append("}").softNewLine();
} }

View File

@ -17,7 +17,8 @@ package org.teavm.classlib.java.lang.reflect;
import org.teavm.classlib.java.lang.*; import org.teavm.classlib.java.lang.*;
import org.teavm.dependency.PluggableDependency; import org.teavm.dependency.PluggableDependency;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.javascript.spi.GeneratedBy;
import org.teavm.platform.PlatformClass;
/** /**
* *
@ -38,12 +39,12 @@ public final class TArray extends TObject {
if (length < 0) { if (length < 0) {
throw new TNegativeArraySizeException(); throw new TNegativeArraySizeException();
} }
return newInstanceImpl(componentType, length); return newInstanceImpl(componentType.getPlatformClass(), length);
} }
@GeneratedBy(ArrayNativeGenerator.class) @GeneratedBy(ArrayNativeGenerator.class)
@PluggableDependency(ArrayNativeGenerator.class) @PluggableDependency(ArrayNativeGenerator.class)
private static native TObject newInstanceImpl(TClass<?> componentType, int length); private static native TObject newInstanceImpl(PlatformClass componentType, int length);
public static TObject get(TObject array, int index) throws TIllegalArgumentException, public static TObject get(TObject array, int index) throws TIllegalArgumentException,
TArrayIndexOutOfBoundsException { TArrayIndexOutOfBoundsException {

View File

@ -21,7 +21,7 @@ import org.teavm.classlib.java.lang.TException;
import org.teavm.classlib.java.lang.TIllegalArgumentException; import org.teavm.classlib.java.lang.TIllegalArgumentException;
import org.teavm.classlib.java.lang.TNullPointerException; import org.teavm.classlib.java.lang.TNullPointerException;
import org.teavm.classlib.java.lang.TString; import org.teavm.classlib.java.lang.TString;
import org.teavm.javascript.ni.Rename; import org.teavm.javascript.spi.Rename;
/** /**
* A {@code URISyntaxException} will be thrown if some information could not be parsed * A {@code URISyntaxException} will be thrown if some information could not be parsed

View File

@ -20,8 +20,8 @@ import org.teavm.codegen.SourceWriter;
import org.teavm.dependency.DependencyAgent; import org.teavm.dependency.DependencyAgent;
import org.teavm.dependency.DependencyPlugin; import org.teavm.dependency.DependencyPlugin;
import org.teavm.dependency.MethodDependency; import org.teavm.dependency.MethodDependency;
import org.teavm.javascript.ni.Generator; import org.teavm.javascript.spi.Generator;
import org.teavm.javascript.ni.GeneratorContext; import org.teavm.javascript.spi.GeneratorContext;
import org.teavm.model.CallLocation; import org.teavm.model.CallLocation;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;

View File

@ -17,8 +17,8 @@ package org.teavm.classlib.java.util;
import java.io.IOException; import java.io.IOException;
import org.teavm.codegen.SourceWriter; import org.teavm.codegen.SourceWriter;
import org.teavm.javascript.ni.Generator; import org.teavm.javascript.spi.Generator;
import org.teavm.javascript.ni.GeneratorContext; import org.teavm.javascript.spi.GeneratorContext;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
/** /**

View File

@ -16,7 +16,7 @@
package org.teavm.classlib.java.util; package org.teavm.classlib.java.util;
import org.teavm.classlib.java.lang.*; import org.teavm.classlib.java.lang.*;
import org.teavm.javascript.ni.Rename; import org.teavm.javascript.spi.Rename;
/** /**
* *

View File

@ -18,7 +18,7 @@ package org.teavm.classlib.java.util;
import java.util.Arrays; import java.util.Arrays;
import org.teavm.classlib.java.io.TSerializable; import org.teavm.classlib.java.io.TSerializable;
import org.teavm.classlib.java.lang.*; import org.teavm.classlib.java.lang.*;
import org.teavm.javascript.ni.Rename; import org.teavm.javascript.spi.Rename;
/** /**
* *

View File

@ -17,7 +17,7 @@ package org.teavm.classlib.java.util;
import org.teavm.classlib.java.io.TSerializable; import org.teavm.classlib.java.io.TSerializable;
import org.teavm.classlib.java.lang.*; import org.teavm.classlib.java.lang.*;
import org.teavm.javascript.ni.Rename; import org.teavm.javascript.spi.Rename;
/** /**
* *

View File

@ -18,7 +18,7 @@ package org.teavm.classlib.java.util;
import org.teavm.classlib.java.lang.TComparable; import org.teavm.classlib.java.lang.TComparable;
import org.teavm.classlib.java.lang.TSystem; import org.teavm.classlib.java.lang.TSystem;
import org.teavm.dependency.PluggableDependency; import org.teavm.dependency.PluggableDependency;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.javascript.spi.GeneratedBy;
/** /**
* *

View File

@ -39,7 +39,7 @@ import org.teavm.classlib.java.lang.TCloneNotSupportedException;
import org.teavm.classlib.java.lang.TIllegalArgumentException; import org.teavm.classlib.java.lang.TIllegalArgumentException;
import org.teavm.classlib.java.lang.TIllegalStateException; import org.teavm.classlib.java.lang.TIllegalStateException;
import org.teavm.classlib.java.lang.TObject; import org.teavm.classlib.java.lang.TObject;
import org.teavm.javascript.ni.Rename; import org.teavm.javascript.spi.Rename;
public class THashMap<K, V> extends TAbstractMap<K, V> implements TSerializable { public class THashMap<K, V> extends TAbstractMap<K, V> implements TSerializable {
transient int elementCount; transient int elementCount;

View File

@ -20,7 +20,7 @@ import org.teavm.classlib.java.io.TSerializable;
import org.teavm.classlib.java.lang.TCloneNotSupportedException; import org.teavm.classlib.java.lang.TCloneNotSupportedException;
import org.teavm.classlib.java.lang.TCloneable; import org.teavm.classlib.java.lang.TCloneable;
import org.teavm.classlib.java.lang.TObject; import org.teavm.classlib.java.lang.TObject;
import org.teavm.javascript.ni.Rename; import org.teavm.javascript.spi.Rename;
/** /**
* *

View File

@ -18,7 +18,7 @@ package org.teavm.classlib.java.util;
import org.teavm.classlib.java.io.TSerializable; import org.teavm.classlib.java.io.TSerializable;
import org.teavm.classlib.java.lang.TMath; import org.teavm.classlib.java.lang.TMath;
import org.teavm.classlib.java.lang.TObject; import org.teavm.classlib.java.lang.TObject;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.javascript.spi.GeneratedBy;
/** /**
* *

View File

@ -16,6 +16,7 @@
package org.teavm.classlib.java.util; package org.teavm.classlib.java.util;
import org.teavm.classlib.java.lang.*; import org.teavm.classlib.java.lang.*;
import org.teavm.platform.PlatformClass;
/** /**
* *
@ -48,7 +49,7 @@ public final class TServiceLoader<S> extends TObject implements TIterable<S> {
} }
public static <S> TServiceLoader<S> load(TClass<S> service) { public static <S> TServiceLoader<S> load(TClass<S> service) {
return new TServiceLoader<>(loadServices(service)); return new TServiceLoader<>(loadServices(service.getPlatformClass()));
} }
public static <S> TServiceLoader<S> load(TClass<S> service, @SuppressWarnings("unused") TClassLoader loader) { public static <S> TServiceLoader<S> load(TClass<S> service, @SuppressWarnings("unused") TClassLoader loader) {
@ -59,7 +60,7 @@ public final class TServiceLoader<S> extends TObject implements TIterable<S> {
return load(service); return load(service);
} }
private static native <T> T[] loadServices(TClass<T> serviceType); private static native <T> T[] loadServices(PlatformClass cls);
public void reload() { public void reload() {
// Do nothing, services are bound at build time // Do nothing, services are bound at build time

View File

@ -19,7 +19,7 @@ import org.teavm.classlib.java.lang.TIllegalStateException;
import org.teavm.classlib.java.lang.TObject; import org.teavm.classlib.java.lang.TObject;
import org.teavm.classlib.java.lang.TString; import org.teavm.classlib.java.lang.TString;
import org.teavm.dependency.PluggableDependency; import org.teavm.dependency.PluggableDependency;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.javascript.spi.GeneratedBy;
/** /**
* *

View File

@ -21,8 +21,8 @@ import org.teavm.codegen.SourceWriter;
import org.teavm.dependency.DependencyAgent; import org.teavm.dependency.DependencyAgent;
import org.teavm.dependency.DependencyPlugin; import org.teavm.dependency.DependencyPlugin;
import org.teavm.dependency.MethodDependency; import org.teavm.dependency.MethodDependency;
import org.teavm.javascript.ni.Generator; import org.teavm.javascript.spi.Generator;
import org.teavm.javascript.ni.GeneratorContext; import org.teavm.javascript.spi.GeneratorContext;
import org.teavm.model.CallLocation; import org.teavm.model.CallLocation;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;

View File

@ -17,8 +17,8 @@ package org.teavm.classlib.java.util.logging;
import java.io.IOException; import java.io.IOException;
import org.teavm.codegen.SourceWriter; import org.teavm.codegen.SourceWriter;
import org.teavm.javascript.ni.Generator; import org.teavm.javascript.spi.Generator;
import org.teavm.javascript.ni.GeneratorContext; import org.teavm.javascript.spi.GeneratorContext;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
/** /**

View File

@ -18,7 +18,7 @@ package org.teavm.classlib.java.util.logging;
import org.teavm.classlib.java.lang.*; import org.teavm.classlib.java.lang.*;
import org.teavm.classlib.java.util.THashMap; import org.teavm.classlib.java.util.THashMap;
import org.teavm.classlib.java.util.TMap; import org.teavm.classlib.java.util.TMap;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.javascript.spi.GeneratedBy;
/** /**
* *

View File

@ -57,15 +57,15 @@ public class DefaultNamingStrategy implements NamingStrategy {
@Override @Override
public String getNameFor(MethodReference method) { public String getNameFor(MethodReference method) {
return getNameFor(method, false); return getNameFor(method, 'S');
} }
@Override @Override
public String getNameForAsync(MethodReference method) throws NamingException { public String getNameForAsync(MethodReference method) throws NamingException {
return getNameFor(method, true); return getNameFor(method, 'A');
} }
private String getNameFor(MethodReference method, boolean async) { private String getNameFor(MethodReference method, char classifier) {
MethodReference origMethod = method; MethodReference origMethod = method;
method = getRealMethod(method); method = getRealMethod(method);
if (method == null) { if (method == null) {
@ -76,7 +76,7 @@ public class DefaultNamingStrategy implements NamingStrategy {
if (methodHolder.hasModifier(ElementModifier.STATIC) || if (methodHolder.hasModifier(ElementModifier.STATIC) ||
method.getDescriptor().getName().equals("<init>") || method.getDescriptor().getName().equals("<init>") ||
methodHolder.getLevel() == AccessLevel.PRIVATE) { methodHolder.getLevel() == AccessLevel.PRIVATE) {
String key = (async ? "A" : "S") + method.toString(); String key = classifier + method.toString();
String alias = privateAliases.get(key); String alias = privateAliases.get(key);
if (alias == null) { if (alias == null) {
alias = aliasProvider.getAlias(method); alias = aliasProvider.getAlias(method);
@ -84,7 +84,7 @@ public class DefaultNamingStrategy implements NamingStrategy {
} }
return alias; return alias;
} else { } else {
String key = (async ? "A" : "S") + method.getDescriptor().toString(); String key = classifier + method.getDescriptor().toString();
String alias = aliases.get(key); String alias = aliases.get(key);
if (alias == null) { if (alias == null) {
alias = aliasProvider.getAlias(method); alias = aliasProvider.getAlias(method);
@ -96,15 +96,24 @@ public class DefaultNamingStrategy implements NamingStrategy {
@Override @Override
public String getFullNameFor(MethodReference method) throws NamingException { public String getFullNameFor(MethodReference method) throws NamingException {
return getFullNameFor(method, 'S');
}
@Override
public String getNameForInit(MethodReference method) throws NamingException {
return getFullNameFor(method, 'I');
}
private String getFullNameFor(MethodReference method, char classifier) throws NamingException {
MethodReference originalMethod = method; MethodReference originalMethod = method;
if (!minifying) { if (!minifying) {
return getNameFor(method.getClassName()) + "_" + getNameFor(method); return getNameFor(method.getClassName()) + "_" + getNameFor(method, classifier);
} }
method = getRealMethod(method); method = getRealMethod(method);
if (method == null) { if (method == null) {
throw new NamingException("Can't provide name for method as it was not found: " + originalMethod); throw new NamingException("Can't provide name for method as it was not found: " + originalMethod);
} }
String key = method.toString(); String key = classifier + method.toString();
String alias = privateAliases.get(key); String alias = privateAliases.get(key);
if (alias == null) { if (alias == null) {
alias = aliasProvider.getAlias(method); alias = aliasProvider.getAlias(method);

View File

@ -29,6 +29,8 @@ public interface NamingStrategy {
String getNameForAsync(MethodReference method) throws NamingException; String getNameForAsync(MethodReference method) throws NamingException;
String getNameForInit(MethodReference method) throws NamingException;
String getFullNameFor(MethodReference method) throws NamingException; String getFullNameFor(MethodReference method) throws NamingException;
String getNameFor(FieldReference field) throws NamingException; String getNameFor(FieldReference field) throws NamingException;

View File

@ -103,6 +103,10 @@ public class SourceWriter implements Appendable, LocationProvider {
return append(naming.getNameFor(cls)); return append(naming.getNameFor(cls));
} }
public SourceWriter appendClass(Class<?> cls) throws NamingException, IOException {
return append(naming.getNameFor(cls.getName()));
}
public SourceWriter appendField(FieldReference field) throws NamingException, IOException { public SourceWriter appendField(FieldReference field) throws NamingException, IOException {
return append(naming.getNameFor(field)); return append(naming.getNameFor(field));
} }
@ -113,7 +117,12 @@ public class SourceWriter implements Appendable, LocationProvider {
public SourceWriter appendMethod(String className, String name, ValueType... params) public SourceWriter appendMethod(String className, String name, ValueType... params)
throws NamingException, IOException { throws NamingException, IOException {
return append(naming.getNameFor(new MethodReference(className, new MethodDescriptor(name, params)))); return append(naming.getNameFor(new MethodReference(className, name, params)));
}
public SourceWriter appendMethod(Class<?> cls, String name, Class<?>... params)
throws NamingException, IOException {
return append(naming.getNameFor(new MethodReference(cls, name, params)));
} }
public SourceWriter appendMethodBody(MethodReference method) throws NamingException, IOException { public SourceWriter appendMethodBody(MethodReference method) throws NamingException, IOException {
@ -125,6 +134,11 @@ public class SourceWriter implements Appendable, LocationProvider {
return append(naming.getFullNameFor(new MethodReference(className, new MethodDescriptor(name, params)))); return append(naming.getFullNameFor(new MethodReference(className, new MethodDescriptor(name, params))));
} }
public SourceWriter appendMethodBody(Class<?> cls, String name, Class<?>... params)
throws NamingException, IOException {
return append(naming.getFullNameFor(new MethodReference(cls, name, params)));
}
private void appendIndent() throws IOException { private void appendIndent() throws IOException {
if (minified) { if (minified) {
return; return;

View File

@ -22,5 +22,5 @@ import org.teavm.model.CallLocation;
* @author Alexey Andreev * @author Alexey Andreev
*/ */
public interface DependencyPlugin { public interface DependencyPlugin {
void methodAchieved(DependencyAgent checker, MethodDependency method, CallLocation location); void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location);
} }

View File

@ -18,10 +18,10 @@ package org.teavm.javascript;
import java.util.*; import java.util.*;
import org.teavm.common.*; import org.teavm.common.*;
import org.teavm.javascript.ast.*; import org.teavm.javascript.ast.*;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.javascript.spi.GeneratedBy;
import org.teavm.javascript.ni.Generator; import org.teavm.javascript.spi.Generator;
import org.teavm.javascript.ni.InjectedBy; import org.teavm.javascript.spi.InjectedBy;
import org.teavm.javascript.ni.PreserveOriginalName; import org.teavm.javascript.spi.PreserveOriginalName;
import org.teavm.model.*; import org.teavm.model.*;
import org.teavm.model.util.AsyncProgramSplitter; import org.teavm.model.util.AsyncProgramSplitter;
import org.teavm.model.util.ProgramUtils; import org.teavm.model.util.ProgramUtils;

View File

@ -26,11 +26,12 @@ import org.teavm.common.ServiceRepository;
import org.teavm.debugging.information.DebugInformationEmitter; import org.teavm.debugging.information.DebugInformationEmitter;
import org.teavm.debugging.information.DeferredCallSite; import org.teavm.debugging.information.DeferredCallSite;
import org.teavm.debugging.information.DummyDebugInformationEmitter; import org.teavm.debugging.information.DummyDebugInformationEmitter;
import org.teavm.diagnostics.Diagnostics;
import org.teavm.javascript.ast.*; import org.teavm.javascript.ast.*;
import org.teavm.javascript.ni.GeneratorContext; import org.teavm.javascript.spi.GeneratorContext;
import org.teavm.javascript.ni.InjectedBy; import org.teavm.javascript.spi.InjectedBy;
import org.teavm.javascript.ni.Injector; import org.teavm.javascript.spi.Injector;
import org.teavm.javascript.ni.InjectorContext; import org.teavm.javascript.spi.InjectorContext;
import org.teavm.model.*; import org.teavm.model.*;
/** /**
@ -53,6 +54,9 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
private Deque<LocationStackEntry> locationStack = new ArrayDeque<>(); private Deque<LocationStackEntry> locationStack = new ArrayDeque<>();
private DeferredCallSite lastCallSite; private DeferredCallSite lastCallSite;
private DeferredCallSite prevCallSite; private DeferredCallSite prevCallSite;
private Set<MethodReference> asyncMethods;
private Set<MethodReference> asyncFamilyMethods;
private Diagnostics diagnostics;
private boolean async; private boolean async;
@Override @Override
@ -110,12 +114,16 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
} }
public Renderer(SourceWriter writer, ListableClassHolderSource classSource, ClassLoader classLoader, public Renderer(SourceWriter writer, ListableClassHolderSource classSource, ClassLoader classLoader,
ServiceRepository services) { ServiceRepository services, Set<MethodReference> asyncMethods, Set<MethodReference> asyncFamilyMethods,
Diagnostics diagnostics) {
this.naming = writer.getNaming(); this.naming = writer.getNaming();
this.writer = writer; this.writer = writer;
this.classSource = classSource; this.classSource = classSource;
this.classLoader = classLoader; this.classLoader = classLoader;
this.services = services; this.services = services;
this.asyncMethods = new HashSet<>(asyncMethods);
this.asyncFamilyMethods = new HashSet<>(asyncFamilyMethods);
this.diagnostics = diagnostics;
} }
@Override @Override
@ -199,43 +207,11 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
} }
private void renderRuntimeCls() throws IOException { private void renderRuntimeCls() throws IOException {
writer.append("function $rt_cls").ws().append("(clsProto)").ws().append("{") writer.append("function $rt_cls(cls)").ws().append("{").softNewLine().indent();
.indent().softNewLine(); writer.append("return ").appendMethodBody("java.lang.Class", "getClass",
String classClass = "java.lang.Class"; ValueType.object("org.teavm.platform.PlatformClass"),
writer.append("var cls").ws().append("=").ws().append("clsProto.classObject;").softNewLine(); ValueType.object("java.lang.Class")).append("(cls);")
writer.append("if").ws().append("(typeof cls").ws().append("===").ws().append("'undefined')").ws() .softNewLine();
.append("{").softNewLine().indent();
MethodReference createMethodRef = new MethodReference(classClass, "createNew", ValueType.object(classClass));
writer.append("cls").ws().append("=").ws().appendMethodBody(createMethodRef).append("();").softNewLine();
writer.append("cls.$data = clsProto;").softNewLine();
if (classSource.get(classClass).getField("name") != null) {
writer.append("cls.").appendField(new FieldReference(classClass, "name")).ws().append("=").ws()
.append("clsProto.$meta.name").ws().append("!==").ws().append("undefined").ws().append("?").ws()
.append("$rt_str(clsProto.$meta.name)").ws().append(":").ws().append("null;").softNewLine();
}
if (classSource.get(classClass).getField("name") != null) {
writer.append("cls.").appendField(new FieldReference(classClass, "binaryName")).ws().append("=").ws()
.append("clsProto.$meta.binaryName").ws().append("!==").ws().append("undefined").ws()
.append("?").ws()
.append("$rt_str(clsProto.$meta.binaryName)").ws().append(":").ws().append("null;").softNewLine();
}
if (classSource.get(classClass).getField("primitive") != null) {
writer.append("cls.").appendField(new FieldReference(classClass, "primitive"))
.append(" = clsProto.$meta.primitive ? 1 : 0;").newLine();
}
if (classSource.get(classClass).getField("array") != null) {
writer.append("cls.").appendField(new FieldReference(classClass, "array")).ws()
.append("=").ws().append("clsProto.$meta.item").ws().append("?").ws()
.append("1").ws().append(":").ws().append("0;").softNewLine();
}
if (classSource.get(classClass).getField("isEnum") != null) {
writer.append("cls.").appendField(new FieldReference(classClass, "isEnum")).ws()
.append("=").ws().append("clsProto.$meta.enum").ws().append("?").ws()
.append("1").ws().append(":").ws().append("0;").softNewLine();
}
writer.append("clsProto.classObject").ws().append("=").ws().append("cls;").softNewLine();
writer.outdent().append("}").softNewLine();
writer.append("return cls;").softNewLine();
writer.outdent().append("}").newLine(); writer.outdent().append("}").newLine();
} }
@ -247,8 +223,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
writer.append("for (var i = 0; i < str.length; i = (i + 1) | 0) {").indent().softNewLine(); writer.append("for (var i = 0; i < str.length; i = (i + 1) | 0) {").indent().softNewLine();
writer.append("charsBuffer[i] = str.charCodeAt(i) & 0xFFFF;").softNewLine(); writer.append("charsBuffer[i] = str.charCodeAt(i) & 0xFFFF;").softNewLine();
writer.outdent().append("}").softNewLine(); writer.outdent().append("}").softNewLine();
writer.append("return ").appendClass("java.lang.String").append(".") writer.append("return ").append(naming.getNameForInit(stringCons)).append("(characters);").softNewLine();
.appendMethod(stringCons).append("(characters);").softNewLine();
writer.outdent().append("}").newLine(); writer.outdent().append("}").newLine();
} }
@ -269,11 +244,10 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
} }
private void renderRuntimeNullCheck() throws IOException { private void renderRuntimeNullCheck() throws IOException {
String npe = "java.lang.NullPointerException";
writer.append("function $rt_nullCheck(val) {").indent().softNewLine(); writer.append("function $rt_nullCheck(val) {").indent().softNewLine();
writer.append("if (val === null) {").indent().softNewLine(); writer.append("if (val === null) {").indent().softNewLine();
writer.append("$rt_throw(").appendClass(npe).append('.').appendMethod(npe, "<init>", ValueType.VOID) writer.append("$rt_throw(").append(naming.getNameForInit(new MethodReference(NullPointerException.class,
.append("());").softNewLine(); "<init>", void.class))).append("());").softNewLine();
writer.outdent().append("}").softNewLine(); writer.outdent().append("}").softNewLine();
writer.append("return val;").softNewLine(); writer.append("return val;").softNewLine();
writer.outdent().append("}").newLine(); writer.outdent().append("}").newLine();
@ -327,6 +301,23 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
.append(constantToString(value)).append(";").softNewLine(); .append(constantToString(value)).append(";").softNewLine();
} }
List<MethodNode> nonInitMethods = new ArrayList<>();
List<MethodNode> virtualMethods = new ArrayList<>();
MethodHolder clinit = classSource.get(cls.getName()).getMethod(
new MethodDescriptor("<clinit>", ValueType.VOID));
List<String> stubNames = new ArrayList<>();
List<MethodNode> clinitMethods = new ArrayList<>();
for (MethodNode method : cls.getMethods()) {
if (!method.getModifiers().contains(NodeModifier.STATIC) &&
!method.getReference().getName().equals("<init>")) {
nonInitMethods.add(method);
} else {
clinitMethods.add(method);
stubNames.add(naming.getFullNameFor(method.getReference()));
}
}
boolean needsClinit = clinit != null || !clinitMethods.isEmpty();
writer.append("$rt_declClass(").appendClass(cls.getName()).append(",").ws().append("{") writer.append("$rt_declClass(").appendClass(cls.getName()).append(",").ws().append("{")
.indent().softNewLine(); .indent().softNewLine();
writer.append("name").ws().append(":").ws().append("\"").append(escapeString(cls.getName())) writer.append("name").ws().append(":").ws().append("\"").append(escapeString(cls.getName()))
@ -349,41 +340,36 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
writer.append(",").softNewLine(); writer.append(",").softNewLine();
writer.append("superclass").ws().append(":").ws().appendClass(cls.getParentName()); writer.append("superclass").ws().append(":").ws().appendClass(cls.getParentName());
} }
if (!cls.getModifiers().contains(NodeModifier.INTERFACE)) { if (!cls.getModifiers().contains(NodeModifier.INTERFACE) && needsClinit) {
writer.append(",").softNewLine().append("clinit").ws().append(":").ws() writer.append(",").softNewLine().append("clinit").ws().append(":").ws()
.append("function()").ws().append("{").ws() .append("function()").ws().append("{").ws()
.appendClass(cls.getName()).append("_$clinit();").ws().append("}"); .appendClass(cls.getName()).append("_$clinit();").ws().append("}");
} }
writer.ws().append("});").newLine().outdent(); writer.ws().append("});").newLine().outdent();
List<MethodNode> nonInitMethods = new ArrayList<>();
List<MethodNode> virtualMethods = new ArrayList<>();
writer.append("function ").appendClass(cls.getName()).append("_$clinit()").ws() if (needsClinit) {
.append("{").softNewLine().indent(); writer.append("function ").appendClass(cls.getName()).append("_$clinit()").ws()
writer.appendClass(cls.getName()).append("_$clinit").ws().append("=").ws() .append("{").softNewLine().indent();
.append("function(){};").newLine(); writer.appendClass(cls.getName()).append("_$clinit").ws().append("=").ws()
List<String> stubNames = new ArrayList<>(); .append("function(){};").newLine();
for (MethodNode method : cls.getMethods()) { for (MethodNode method : clinitMethods) {
if (!method.getModifiers().contains(NodeModifier.STATIC) &&
!method.getReference().getName().equals("<init>")) {
nonInitMethods.add(method);
} else {
renderBody(method, true); renderBody(method, true);
stubNames.add(naming.getFullNameFor(method.getReference()));
} }
if (clinit != null) {
writer.appendMethodBody(new MethodReference(cls.getName(), clinit.getDescriptor()))
.append("();").softNewLine();
}
writer.outdent().append("}").newLine();
} }
MethodHolder methodHolder = classSource.get(cls.getName()).getMethod(
new MethodDescriptor("<clinit>", ValueType.VOID));
if (methodHolder != null) {
writer.appendMethodBody(new MethodReference(cls.getName(), methodHolder.getDescriptor()))
.append("();").softNewLine();
}
writer.outdent().append("}").newLine();
if (!cls.getModifiers().contains(NodeModifier.INTERFACE)) { if (!cls.getModifiers().contains(NodeModifier.INTERFACE)) {
for (MethodNode method : cls.getMethods()) { for (MethodNode method : cls.getMethods()) {
cls.getMethods(); cls.getMethods();
if (!method.getModifiers().contains(NodeModifier.STATIC)) { if (!method.getModifiers().contains(NodeModifier.STATIC)) {
virtualMethods.add(method); if (method.getReference().getName().equals("<init>")) {
renderInitializer(method);
} else {
virtualMethods.add(method);
}
} else if (method.isOriginalNamePreserved()) { } else if (method.isOriginalNamePreserved()) {
renderStaticDeclaration(method); renderStaticDeclaration(method);
} }
@ -441,7 +427,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
private void renderInitializer(MethodNode method) throws IOException { private void renderInitializer(MethodNode method) throws IOException {
MethodReference ref = method.getReference(); MethodReference ref = method.getReference();
debugEmitter.emitMethod(ref.getDescriptor()); debugEmitter.emitMethod(ref.getDescriptor());
writer.appendClass(ref.getClassName()).append(".").appendMethod(ref).ws().append("=").ws().append("function("); writer.append("function ").append(naming.getNameForInit(ref)).append("(");
for (int i = 1; i <= ref.parameterCount(); ++i) { for (int i = 1; i <= ref.parameterCount(); ++i) {
if (i > 1) { if (i > 1) {
writer.append(",").ws(); writer.append(",").ws();
@ -451,11 +437,9 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
writer.append(")").ws().append("{").newLine().indent(); writer.append(")").ws().append("{").newLine().indent();
writer.append("var result").ws().append("=").ws().append("new ").appendClass( writer.append("var result").ws().append("=").ws().append("new ").appendClass(
ref.getClassName()).append("();").softNewLine(); ref.getClassName()).append("();").softNewLine();
writer.append("result.").appendMethod(ref).append("("); writer.append(naming.getFullNameFor(ref)).append("(result");
for (int i = 1; i <= ref.parameterCount(); ++i) { for (int i = 1; i <= ref.parameterCount(); ++i) {
if (i > 1) { writer.append(",").ws();
writer.append(",").ws();
}
writer.append(variableName(i)); writer.append(variableName(i));
} }
writer.append(");").softNewLine(); writer.append(");").softNewLine();
@ -480,18 +464,26 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
debugEmitter.emitMethod(method.getReference().getDescriptor()); debugEmitter.emitMethod(method.getReference().getDescriptor());
MethodReference ref = method.getReference(); MethodReference ref = method.getReference();
writer.append(",").newLine(); writer.append(",").newLine();
String methodName = method.isAsync() ? naming.getNameForAsync(ref) : naming.getNameFor(ref);
if (method.isOriginalNamePreserved()) { if (method.isOriginalNamePreserved()) {
writer.append("[\"").appendMethod(ref).append("\",").ws().append("\"").append(ref.getName()) writer.append("[\"").append(methodName).append("\",").ws().append("\"").append(ref.getName())
.append("\"]"); .append("\"]");
} else { } else {
writer.append("\"").appendMethod(ref).append("\""); writer.append("\"").append(methodName).append("\"");
} }
writer.append(",").ws().append("function("); writer.append(",").ws().append("function(");
List<String> args = new ArrayList<>();
for (int i = 1; i <= ref.parameterCount(); ++i) { for (int i = 1; i <= ref.parameterCount(); ++i) {
if (i > 1) { args.add(variableName(i));
}
if (method.isAsync()) {
args.add("$return");
}
for (int i = 0; i < args.size(); ++i) {
if (i > 0) {
writer.append(",").ws(); writer.append(",").ws();
} }
writer.append(variableName(i)); writer.append(args.get(i));
} }
writer.append(")").ws().append("{").ws(); writer.append(")").ws().append("{").ws();
if (ref.getDescriptor().getResultType() != ValueType.VOID) { if (ref.getDescriptor().getResultType() != ValueType.VOID) {
@ -499,13 +491,13 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
} }
writer.appendMethodBody(ref).append("("); writer.appendMethodBody(ref).append("(");
writer.append("this"); writer.append("this");
for (int i = 1; i <= ref.parameterCount(); ++i) { for (int i = 0; i < args.size(); ++i) {
writer.append(",").ws().append(variableName(i)); writer.append(",").ws().append(args.get(i));
} }
writer.append(");").ws().append("}"); writer.append(");").ws().append("}");
debugEmitter.emitMethod(null); debugEmitter.emitMethod(null);
if (!method.isAsync()) { if (!method.isAsync() && asyncFamilyMethods.contains(method.getReference())) {
writer.append(",").newLine(); writer.append(",").newLine();
writer.append("\"").append(naming.getNameForAsync(ref)).append("\",").ws(); writer.append("\"").append(naming.getNameForAsync(ref)).append("\",").ws();
writer.append("$rt_asyncAdapter(").appendMethodBody(ref).append(')'); writer.append("$rt_asyncAdapter(").appendMethodBody(ref).append(')');
@ -713,10 +705,20 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
return async; return async;
} }
@Override
public boolean isAsync(MethodReference method) {
return asyncMethods.contains(method);
}
@Override @Override
public String getCompleteContinuation() { public String getCompleteContinuation() {
return "$return"; return "$return";
} }
@Override
public Diagnostics getDiagnostics() {
return diagnostics;
}
} }
private void pushLocation(NodeLocation location) { private void pushLocation(NodeLocation location) {
@ -1471,7 +1473,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
if (expr.getType() == InvocationType.DYNAMIC) { if (expr.getType() == InvocationType.DYNAMIC) {
expr.getArguments().get(0).acceptVisitor(this); expr.getArguments().get(0).acceptVisitor(this);
} }
String className = naming.getNameFor(expr.getMethod().getClassName());
String name = expr.getAsyncTarget() == null ? naming.getNameFor(expr.getMethod()) : String name = expr.getAsyncTarget() == null ? naming.getNameFor(expr.getMethod()) :
naming.getNameForAsync(expr.getMethod()); naming.getNameForAsync(expr.getMethod());
String fullName = naming.getFullNameFor(expr.getMethod()); String fullName = naming.getFullNameFor(expr.getMethod());
@ -1517,7 +1518,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
virtual = true; virtual = true;
break; break;
case CONSTRUCTOR: case CONSTRUCTOR:
writer.append(className).append(".").append(name).append("("); writer.append(naming.getNameForInit(expr.getMethod())).append("(");
prevCallSite = debugEmitter.emitCallSite(); prevCallSite = debugEmitter.emitCallSite();
for (int i = 0; i < expr.getArguments().size(); ++i) { for (int i = 0; i < expr.getArguments().size(); ++i) {
if (i > 0) { if (i > 0) {

View File

@ -227,6 +227,9 @@ class UnusedVariableEliminator implements ExprVisitor, StatementVisitor {
@Override @Override
public void visit(RestoreAsyncStatement statement) { public void visit(RestoreAsyncStatement statement) {
if (statement.getReceiver() != null) {
statement.setReceiver(renumber(statement.getReceiver()));
}
} }
@Override @Override

View File

@ -15,7 +15,7 @@
*/ */
package org.teavm.javascript.ast; package org.teavm.javascript.ast;
import org.teavm.javascript.ni.Generator; import org.teavm.javascript.spi.Generator;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
/** /**

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.teavm.runtime; package org.teavm.javascript.spi;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.teavm.javascript.ni; package org.teavm.javascript.spi;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.teavm.javascript.ni; package org.teavm.javascript.spi;
import java.io.IOException; import java.io.IOException;
import org.teavm.codegen.SourceWriter; import org.teavm.codegen.SourceWriter;

View File

@ -13,11 +13,13 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.teavm.javascript.ni; package org.teavm.javascript.spi;
import java.util.Properties; import java.util.Properties;
import org.teavm.common.ServiceRepository; import org.teavm.common.ServiceRepository;
import org.teavm.diagnostics.Diagnostics;
import org.teavm.model.ListableClassReaderSource; import org.teavm.model.ListableClassReaderSource;
import org.teavm.model.MethodReference;
/** /**
* *
@ -35,4 +37,8 @@ public interface GeneratorContext extends ServiceRepository {
boolean isAsync(); boolean isAsync();
String getCompleteContinuation(); String getCompleteContinuation();
boolean isAsync(MethodReference method);
Diagnostics getDiagnostics();
} }

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.teavm.javascript.ni; package org.teavm.javascript.spi;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.teavm.javascript.ni; package org.teavm.javascript.spi;
import java.io.IOException; import java.io.IOException;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.teavm.javascript.ni; package org.teavm.javascript.spi;
import java.io.IOException; import java.io.IOException;
import java.util.Properties; import java.util.Properties;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.teavm.javascript.ni; package org.teavm.javascript.spi;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.teavm.javascript.ni; package org.teavm.javascript.spi;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.teavm.javascript.ni; package org.teavm.javascript.spi;
import java.lang.annotation.*; import java.lang.annotation.*;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.teavm.javascript.ni; package org.teavm.javascript.spi;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.teavm.runtime; package org.teavm.javascript.spi;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;

View File

@ -15,16 +15,15 @@
*/ */
package org.teavm.model.util; package org.teavm.model.util;
import java.util.HashSet; import java.util.*;
import java.util.Set;
import org.teavm.callgraph.CallGraph; import org.teavm.callgraph.CallGraph;
import org.teavm.callgraph.CallGraphNode; import org.teavm.callgraph.CallGraphNode;
import org.teavm.callgraph.CallSite; import org.teavm.callgraph.CallSite;
import org.teavm.diagnostics.Diagnostics; import org.teavm.diagnostics.Diagnostics;
import org.teavm.javascript.ni.InjectedBy; import org.teavm.javascript.spi.Async;
import org.teavm.javascript.spi.InjectedBy;
import org.teavm.javascript.spi.Sync;
import org.teavm.model.*; import org.teavm.model.*;
import org.teavm.runtime.Async;
import org.teavm.runtime.Sync;
/** /**
* *
@ -32,6 +31,9 @@ import org.teavm.runtime.Sync;
*/ */
public class AsyncMethodFinder { public class AsyncMethodFinder {
private Set<MethodReference> asyncMethods = new HashSet<>(); private Set<MethodReference> asyncMethods = new HashSet<>();
private Map<MethodReference, Boolean> asyncFamilyMethods = new HashMap<>();
private Set<MethodReference> readonlyAsyncMethods = Collections.unmodifiableSet(asyncMethods);
private Set<MethodReference> readonlyAsyncFamilyMethods = Collections.unmodifiableSet(asyncFamilyMethods.keySet());
private CallGraph callGraph; private CallGraph callGraph;
private Diagnostics diagnostics; private Diagnostics diagnostics;
private ListableClassReaderSource classSource; private ListableClassReaderSource classSource;
@ -42,7 +44,11 @@ public class AsyncMethodFinder {
} }
public Set<MethodReference> getAsyncMethods() { public Set<MethodReference> getAsyncMethods() {
return asyncMethods; return readonlyAsyncMethods;
}
public Set<MethodReference> getAsyncFamilyMethods() {
return readonlyAsyncFamilyMethods;
} }
public void find(ListableClassReaderSource classSource) { public void find(ListableClassReaderSource classSource) {
@ -58,6 +64,17 @@ public class AsyncMethodFinder {
} }
} }
} }
for (String clsName : classSource.getClassNames()) {
ClassReader cls = classSource.get(clsName);
for (MethodReader method : cls.getMethods()) {
addToFamily(method.getReference());
}
}
for (Map.Entry<MethodReference, Boolean> entry : new ArrayList<>(asyncFamilyMethods.entrySet())) {
if (!entry.getValue()) {
asyncFamilyMethods.remove(entry.getKey());
}
}
} }
private void add(MethodReference methodRef) { private void add(MethodReference methodRef) {
@ -85,5 +102,76 @@ public class AsyncMethodFinder {
for (CallSite callSite : node.getCallerCallSites()) { for (CallSite callSite : node.getCallerCallSites()) {
add(callSite.getCaller().getMethod()); add(callSite.getCaller().getMethod());
} }
Set<MethodReference> visited = new HashSet<>();
Set<MethodReference> overriden = new HashSet<>();
if (cls.getParent() != null && !cls.getParent().equals(cls.getName())) {
findOverridenMethods(new MethodReference(cls.getParent(), methodRef.getDescriptor()), overriden, visited);
}
for (String iface : cls.getInterfaces()) {
findOverridenMethods(new MethodReference(iface, methodRef.getDescriptor()), overriden, visited);
}
for (MethodReference overridenMethod : overriden) {
add(overridenMethod);
}
}
private boolean addToFamily(MethodReference methodRef) {
Boolean cachedResult = asyncFamilyMethods.get(methodRef);
if (cachedResult != null) {
return cachedResult;
}
boolean result = addToFamilyCacheMiss(methodRef);
asyncFamilyMethods.put(methodRef, result);
return result;
}
private boolean addToFamilyCacheMiss(MethodReference methodRef) {
if (asyncMethods.contains(methodRef)) {
return true;
}
ClassReader cls = classSource.get(methodRef.getClassName());
if (cls == null) {
return false;
}
List<String> parents = new ArrayList<>();
if (cls.getParent() != null && !cls.getParent().equals(cls.getName())) {
parents.add(cls.getParent());
}
parents.addAll(cls.getInterfaces());
Set<MethodReference> visited = new HashSet<>();
Set<MethodReference> overriden = new HashSet<>();
for (String parent : parents) {
findOverridenMethods(new MethodReference(parent, methodRef.getDescriptor()), overriden, visited);
}
for (MethodReference overridenMethod : overriden) {
if (addToFamily(overridenMethod)) {
return true;
}
}
return false;
}
private void findOverridenMethods(MethodReference methodRef, Set<MethodReference> result,
Set<MethodReference> visited) {
if (!visited.add(methodRef)) {
return;
}
ClassReader cls = classSource.get(methodRef.getClassName());
if (cls == null) {
return;
}
MethodReader method = cls.getMethod(methodRef.getDescriptor());
if (method != null) {
result.add(methodRef);
} else {
if (cls.getParent() != null && !cls.getParent().equals(cls.getName())) {
findOverridenMethods(new MethodReference(cls.getParent(), methodRef.getDescriptor()), result, visited);
}
for (String iface : cls.getInterfaces()) {
findOverridenMethods(new MethodReference(iface, methodRef.getDescriptor()), result, visited);
}
}
} }
} }

View File

@ -17,9 +17,9 @@ package org.teavm.parsing;
import java.util.Map; import java.util.Map;
import org.teavm.common.Mapper; import org.teavm.common.Mapper;
import org.teavm.javascript.ni.Remove; import org.teavm.javascript.spi.Remove;
import org.teavm.javascript.ni.Rename; import org.teavm.javascript.spi.Rename;
import org.teavm.javascript.ni.Superclass; import org.teavm.javascript.spi.Superclass;
import org.teavm.model.*; import org.teavm.model.*;
import org.teavm.model.instructions.*; import org.teavm.model.instructions.*;
import org.teavm.model.util.ModelUtils; import org.teavm.model.util.ModelUtils;

View File

@ -26,10 +26,10 @@ import org.teavm.diagnostics.AccumulationDiagnostics;
import org.teavm.diagnostics.ProblemProvider; import org.teavm.diagnostics.ProblemProvider;
import org.teavm.javascript.*; import org.teavm.javascript.*;
import org.teavm.javascript.ast.ClassNode; import org.teavm.javascript.ast.ClassNode;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.javascript.spi.GeneratedBy;
import org.teavm.javascript.ni.Generator; import org.teavm.javascript.spi.Generator;
import org.teavm.javascript.ni.InjectedBy; import org.teavm.javascript.spi.InjectedBy;
import org.teavm.javascript.ni.Injector; import org.teavm.javascript.spi.Injector;
import org.teavm.model.*; import org.teavm.model.*;
import org.teavm.model.instructions.*; import org.teavm.model.instructions.*;
import org.teavm.model.util.*; import org.teavm.model.util.*;
@ -90,6 +90,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
private boolean cancelled; private boolean cancelled;
private ListableClassHolderSource writtenClasses; private ListableClassHolderSource writtenClasses;
private Set<MethodReference> asyncMethods = new HashSet<>(); private Set<MethodReference> asyncMethods = new HashSet<>();
private Set<MethodReference> asyncFamilyMethods = new HashSet<>();
TeaVM(ClassReaderSource classSource, ClassLoader classLoader) { TeaVM(ClassReaderSource classSource, ClassLoader classLoader) {
this.classSource = classSource; this.classSource = classSource;
@ -334,7 +335,8 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
return progressListener.progressReached(0) == TeaVMProgressFeedback.CONTINUE; return progressListener.progressReached(0) == TeaVMProgressFeedback.CONTINUE;
} }
}); });
dependencyChecker.linkMethod(new MethodReference(Class.class, "createNew", Class.class), null).use(); dependencyChecker.linkMethod(new MethodReference(Class.class.getName(), "getClass",
ValueType.object("org.teavm.platform.PlatformClass"), ValueType.parse(Class.class)), null).use();
dependencyChecker.linkMethod(new MethodReference(String.class, "<init>", char[].class, void.class), dependencyChecker.linkMethod(new MethodReference(String.class, "<init>", char[].class, void.class),
null).use(); null).use();
dependencyChecker.linkMethod(new MethodReference(String.class, "getChars", int.class, int.class, char[].class, dependencyChecker.linkMethod(new MethodReference(String.class, "getChars", int.class, int.class, char[].class,
@ -400,7 +402,8 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
SourceWriterBuilder builder = new SourceWriterBuilder(naming); SourceWriterBuilder builder = new SourceWriterBuilder(naming);
builder.setMinified(minifying); builder.setMinified(minifying);
SourceWriter sourceWriter = builder.build(writer); SourceWriter sourceWriter = builder.build(writer);
Renderer renderer = new Renderer(sourceWriter, classSet, classLoader, this); Renderer renderer = new Renderer(sourceWriter, classSet, classLoader, this, asyncMethods, asyncFamilyMethods,
diagnostics);
renderer.setProperties(properties); renderer.setProperties(properties);
if (debugEmitter != null) { if (debugEmitter != null) {
int classIndex = 0; int classIndex = 0;
@ -564,6 +567,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
AsyncMethodFinder asyncFinder = new AsyncMethodFinder(dependencyChecker.getCallGraph(), diagnostics); AsyncMethodFinder asyncFinder = new AsyncMethodFinder(dependencyChecker.getCallGraph(), diagnostics);
asyncFinder.find(classes); asyncFinder.find(classes);
asyncMethods.addAll(asyncFinder.getAsyncMethods()); asyncMethods.addAll(asyncFinder.getAsyncMethods());
asyncFamilyMethods.addAll(asyncFinder.getAsyncFamilyMethods());
progressListener.phaseStarted(TeaVMPhase.DECOMPILATION, classes.getClassNames().size()); progressListener.phaseStarted(TeaVMPhase.DECOMPILATION, classes.getClassNames().size());
Decompiler decompiler = new Decompiler(classes, classLoader, asyncFinder.getAsyncMethods()); Decompiler decompiler = new Decompiler(classes, classLoader, asyncFinder.getAsyncMethods());

View File

@ -17,8 +17,8 @@ package org.teavm.vm.spi;
import java.util.Properties; import java.util.Properties;
import org.teavm.dependency.DependencyListener; import org.teavm.dependency.DependencyListener;
import org.teavm.javascript.ni.Generator; import org.teavm.javascript.spi.Generator;
import org.teavm.javascript.ni.Injector; import org.teavm.javascript.spi.Injector;
import org.teavm.model.ClassHolderTransformer; import org.teavm.model.ClassHolderTransformer;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.vm.TeaVM; import org.teavm.vm.TeaVM;

View File

@ -130,15 +130,18 @@ function $rt_arraycls(cls) {
} }
var name = "[" + cls.$meta.binaryName; var name = "[" + cls.$meta.binaryName;
arraycls.$meta = { item : cls, supertypes : [$rt_objcls()], primitive : false, superclass : $rt_objcls(), arraycls.$meta = { item : cls, supertypes : [$rt_objcls()], primitive : false, superclass : $rt_objcls(),
name : name, binaryName : name }; name : name, binaryName : name, enum : false };
arraycls.classObject = null;
cls.$array = arraycls; cls.$array = arraycls;
} }
return cls.$array; return cls.$array;
} }
function $rt_createcls() { function $rt_createcls() {
return { return {
classObject : null,
$meta : { $meta : {
supertypes : [] supertypes : [],
superclass : null
} }
}; };
} }
@ -147,6 +150,8 @@ function $rt_createPrimitiveCls(name, binaryName) {
cls.$meta.primitive = true; cls.$meta.primitive = true;
cls.$meta.name = name; cls.$meta.name = name;
cls.$meta.binaryName = binaryName; cls.$meta.binaryName = binaryName;
cls.$meta.enum = false;
cls.$meta.item = null;
return cls; return cls;
} }
var $rt_booleanclsCache = null; var $rt_booleanclsCache = null;
@ -365,19 +370,22 @@ function $rt_putStderr(ch) {
} }
function $rt_declClass(cls, data) { function $rt_declClass(cls, data) {
cls.$meta = {}; cls.$meta = {};
cls.$meta.superclass = data.superclass; var m = cls.$meta
cls.$meta.supertypes = data.interfaces ? data.interfaces.slice() : []; m.superclass = typeof(data.superclass) !== 'undefined' ? data.superclass : null;
m.supertypes = data.interfaces ? data.interfaces.slice() : [];
if (data.superclass) { if (data.superclass) {
cls.$meta.supertypes.push(data.superclass); m.supertypes.push(data.superclass);
cls.prototype = new data.superclass(); cls.prototype = new data.superclass();
} else { } else {
cls.prototype = new Object(); cls.prototype = new Object();
} }
cls.$meta.name = data.name; m.name = data.name;
cls.$meta.binaryName = "L" + data.name + ";"; m.binaryName = "L" + data.name + ";";
cls.$meta.enum = data.enum; m.enum = data.enum;
m.item = null;
cls.prototype.constructor = cls; cls.prototype.constructor = cls;
cls.$clinit = data.clinit; cls.classObject = null;
cls.$clinit = data.clinit ? data.clinit : function() {};
} }
function $rt_virtualMethods(cls) { function $rt_virtualMethods(cls) {
for (var i = 1; i < arguments.length; i += 2) { for (var i = 1; i < arguments.length; i += 2) {
@ -404,7 +412,6 @@ function $rt_asyncError(e) {
} }
function $rt_asyncAdapter(f) { function $rt_asyncAdapter(f) {
return function() { return function() {
var e;
var result; var result;
var args = Array.prototype.slice.apply(arguments); var args = Array.prototype.slice.apply(arguments);
var $return = args.pop(); var $return = args.pop();
@ -419,11 +426,6 @@ function $rt_asyncAdapter(f) {
function $rt_rootInvocationAdapter(f, extraArgs) { function $rt_rootInvocationAdapter(f, extraArgs) {
return function() { return function() {
var args = Array.prototype.slice.apply(arguments); var args = Array.prototype.slice.apply(arguments);
if (extraArgs) {
for (var i = 0; i < extraArts.length; ++i) {
args.push(extraArgs[i]);
}
}
args.push(function(result) { args.push(function(result) {
result(); result();
}); });

View File

@ -370,11 +370,11 @@ var JUnitClient = {};
JUnitClient.run = function() { JUnitClient.run = function() {
var handler = window.addEventListener("message", function() { var handler = window.addEventListener("message", function() {
window.removeEventListener("message", handler); window.removeEventListener("message", handler);
var message = {};
try { try {
var instance = new TestClass(); var instance = new TestClass();
initInstance(instance); initInstance(instance);
runTest(instance, function(restore) { runTest(instance, function(restore) {
var message = {};
try { try {
var result = restore(); var result = restore();
message.status = "ok"; message.status = "ok";

View File

@ -29,7 +29,7 @@ import org.teavm.jso.JSProperty;
* *
* @author Alexey Andreev * @author Alexey Andreev
*/ */
public interface Window extends JSGlobal, EventTarget, StorageProvider { public interface Window extends JSGlobal, EventTarget, StorageProvider, TypedArrayFactory {
@JSProperty @JSProperty
HTMLDocument getDocument(); HTMLDocument getDocument();
@ -42,10 +42,14 @@ public interface Window extends JSGlobal, EventTarget, StorageProvider {
int setTimeout(TimerHandler handler, int delay); int setTimeout(TimerHandler handler, int delay);
int setTimeout(TimerHandler handler, double delay);
void clearTimeout(int timeoutId); void clearTimeout(int timeoutId);
int setInterval(TimerHandler handler, int delay); int setInterval(TimerHandler handler, int delay);
int setInterval(TimerHandler handler, double delay);
void clearInterval(int timeoutId); void clearInterval(int timeoutId);
@JSProperty("JSON") @JSProperty("JSON")
@ -53,79 +57,4 @@ public interface Window extends JSGlobal, EventTarget, StorageProvider {
@JSConstructor("XMLHttpRequest") @JSConstructor("XMLHttpRequest")
XMLHttpRequest createXMLHttpRequest(); XMLHttpRequest createXMLHttpRequest();
@JSConstructor("ArrayBuffer")
ArrayBuffer createArrayBuffer(int length);
@JSConstructor("Int8Array")
Int8Array createInt8Array(int length);
@JSConstructor("Int8Array")
Int8Array createInt8Array(ArrayBuffer buffer);
@JSConstructor("Int8Array")
Int8Array createInt8Array(ArrayBuffer buffer, int offset, int length);
@JSConstructor("Uint8Array")
Uint8Array createUint8Array(int length);
@JSConstructor("Uint8Array")
Uint8Array createUint8Array(ArrayBuffer buffer);
@JSConstructor("Uint8Array")
Uint8Array createUint8Array(ArrayBuffer buffer, int offset, int length);
@JSConstructor("Uint8ClampedArray")
Uint8ClampedArray createUint8ClampedArray(int length);
@JSConstructor("Uint8ClampedArray")
Uint8ClampedArray createUint8ClampedArray(ArrayBuffer buffer);
@JSConstructor("Uint8ClampedArray")
Uint8ClampedArray createUintClamped8Array(ArrayBuffer buffer, int offset, int length);
@JSConstructor("Int16Array")
Int16Array createInt16Array(int length);
@JSConstructor("Int16Array")
Int16Array createInt16Array(ArrayBuffer buffer);
@JSConstructor("Int16Array")
Int16Array createInt16Array(ArrayBuffer buffer, int offset, int length);
@JSConstructor("Uint16Array")
Uint16Array createUint16Array(int length);
@JSConstructor("Uint16Array")
Uint16Array createUint16Array(ArrayBuffer buffer);
@JSConstructor("Uint16Array")
Uint16Array createUint16Array(ArrayBuffer buffer, int offset, int length);
@JSConstructor("Int32Array")
Int32Array createInt32Array(int length);
@JSConstructor("Int32Array")
Int32Array createInt32Array(ArrayBuffer buffer);
@JSConstructor("Int32Array")
Int32Array createInt32Array(ArrayBuffer buffer, int offset, int length);
@JSConstructor("Float32Array")
Float32Array createFloat32Array(int length);
@JSConstructor("Float32Array")
Float32Array createFloat32Array(ArrayBuffer buffer);
@JSConstructor("Float32Array")
Float32Array createFloat32Array(ArrayBuffer buffer, int offset, int length);
@JSConstructor("Float64Array")
Float64Array createFloat64Array(int length);
@JSConstructor("Float64Array")
Float64Array createFloat64Array(ArrayBuffer buffer);
@JSConstructor("Float64Array")
Float64Array createFloat64Array(ArrayBuffer buffer, int offset, int length);
} }

View File

@ -0,0 +1,100 @@
/*
* Copyright 2015 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.dom.typedarrays;
import org.teavm.jso.JSConstructor;
import org.teavm.jso.JSObject;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public interface TypedArrayFactory extends JSObject {
@JSConstructor("ArrayBuffer")
ArrayBuffer createArrayBuffer(int length);
@JSConstructor("Int8Array")
Int8Array createInt8Array(int length);
@JSConstructor("Int8Array")
Int8Array createInt8Array(ArrayBuffer buffer);
@JSConstructor("Int8Array")
Int8Array createInt8Array(ArrayBuffer buffer, int offset, int length);
@JSConstructor("Uint8Array")
Uint8Array createUint8Array(int length);
@JSConstructor("Uint8Array")
Uint8Array createUint8Array(ArrayBuffer buffer);
@JSConstructor("Uint8Array")
Uint8Array createUint8Array(ArrayBuffer buffer, int offset, int length);
@JSConstructor("Uint8ClampedArray")
Uint8ClampedArray createUint8ClampedArray(int length);
@JSConstructor("Uint8ClampedArray")
Uint8ClampedArray createUint8ClampedArray(ArrayBuffer buffer);
@JSConstructor("Uint8ClampedArray")
Uint8ClampedArray createUintClamped8Array(ArrayBuffer buffer, int offset, int length);
@JSConstructor("Int16Array")
Int16Array createInt16Array(int length);
@JSConstructor("Int16Array")
Int16Array createInt16Array(ArrayBuffer buffer);
@JSConstructor("Int16Array")
Int16Array createInt16Array(ArrayBuffer buffer, int offset, int length);
@JSConstructor("Uint16Array")
Uint16Array createUint16Array(int length);
@JSConstructor("Uint16Array")
Uint16Array createUint16Array(ArrayBuffer buffer);
@JSConstructor("Uint16Array")
Uint16Array createUint16Array(ArrayBuffer buffer, int offset, int length);
@JSConstructor("Int32Array")
Int32Array createInt32Array(int length);
@JSConstructor("Int32Array")
Int32Array createInt32Array(ArrayBuffer buffer);
@JSConstructor("Int32Array")
Int32Array createInt32Array(ArrayBuffer buffer, int offset, int length);
@JSConstructor("Float32Array")
Float32Array createFloat32Array(int length);
@JSConstructor("Float32Array")
Float32Array createFloat32Array(ArrayBuffer buffer);
@JSConstructor("Float32Array")
Float32Array createFloat32Array(ArrayBuffer buffer, int offset, int length);
@JSConstructor("Float64Array")
Float64Array createFloat64Array(int length);
@JSConstructor("Float64Array")
Float64Array createFloat64Array(ArrayBuffer buffer);
@JSConstructor("Float64Array")
Float64Array createFloat64Array(ArrayBuffer buffer, int offset, int length);
}

View File

@ -59,7 +59,7 @@ Export-Package: org.teavm.cache,
org.teavm.diagnostics, org.teavm.diagnostics,
org.teavm.javascript, org.teavm.javascript,
org.teavm.javascript.ast, org.teavm.javascript.ast,
org.teavm.javascript.ni, org.teavm.javascript.spi,
org.teavm.model, org.teavm.model,
org.teavm.model.instructions, org.teavm.model.instructions,
org.teavm.model.util, org.teavm.model.util,

View File

@ -21,8 +21,8 @@ import net.java.html.js.JavaScriptBody;
import org.teavm.codegen.NamingStrategy; import org.teavm.codegen.NamingStrategy;
import org.teavm.codegen.SourceWriter; import org.teavm.codegen.SourceWriter;
import org.teavm.javascript.Renderer; import org.teavm.javascript.Renderer;
import org.teavm.javascript.ni.Generator; import org.teavm.javascript.spi.Generator;
import org.teavm.javascript.ni.GeneratorContext; import org.teavm.javascript.spi.GeneratorContext;
import org.teavm.model.*; import org.teavm.model.*;
/** /**

View File

@ -17,7 +17,7 @@ package org.teavm.html4j;
import net.java.html.js.JavaScriptBody; import net.java.html.js.JavaScriptBody;
import org.teavm.diagnostics.Diagnostics; import org.teavm.diagnostics.Diagnostics;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.javascript.spi.GeneratedBy;
import org.teavm.model.*; import org.teavm.model.*;
/** /**

View File

@ -15,7 +15,7 @@
*/ */
package org.teavm.html4j; package org.teavm.html4j;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.javascript.spi.GeneratedBy;
/** /**
* *

View File

@ -17,8 +17,8 @@ package org.teavm.html4j;
import java.io.IOException; import java.io.IOException;
import org.teavm.codegen.SourceWriter; import org.teavm.codegen.SourceWriter;
import org.teavm.javascript.ni.Generator; import org.teavm.javascript.spi.Generator;
import org.teavm.javascript.ni.GeneratorContext; import org.teavm.javascript.spi.GeneratorContext;
import org.teavm.model.*; import org.teavm.model.*;
/** /**

View File

@ -43,42 +43,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs
<build> <build>
<plugins> <plugins>
<plugin>
<groupId>org.teavm</groupId>
<artifactId>teavm-maven-plugin</artifactId>
<version>${project.version}</version>
<dependencies>
<dependency>
<groupId>org.teavm</groupId>
<artifactId>teavm-classlib</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>generate-javascript-tests</id>
<goals>
<goal>build-test-javascript</goal>
</goals>
<phase>process-test-classes</phase>
<configuration>
<minifying>false</minifying>
<properties>
<java.util.Locale.available>en, en_US, en_GB, ru, ru_RU</java.util.Locale.available>
</properties>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>**</exclude>
</excludes>
</configuration>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId> <artifactId>maven-checkstyle-plugin</artifactId>

View File

@ -17,7 +17,7 @@ package org.teavm.jso;
import java.util.Iterator; import java.util.Iterator;
import org.teavm.dependency.PluggableDependency; import org.teavm.dependency.PluggableDependency;
import org.teavm.javascript.ni.InjectedBy; import org.teavm.javascript.spi.InjectedBy;
import org.teavm.jso.plugin.JSNativeGenerator; import org.teavm.jso.plugin.JSNativeGenerator;
/** /**
@ -101,6 +101,9 @@ public final class JS {
@InjectedBy(JSNativeGenerator.class) @InjectedBy(JSNativeGenerator.class)
public static native JSObject wrap(short num); public static native JSObject wrap(short num);
@InjectedBy(JSNativeGenerator.class)
public static native JSObject marshall(Object obj);
public static <T extends JSObject> JSArray<T> wrap(T[] array) { public static <T extends JSObject> JSArray<T> wrap(T[] array) {
JSArray<T> result = createArray(array.length); JSArray<T> result = createArray(array.length);
for (int i = 0; i < array.length; ++i) { for (int i = 0; i < array.length; ++i) {

View File

@ -18,8 +18,8 @@ package org.teavm.jso.plugin;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import org.teavm.codegen.SourceWriter; import org.teavm.codegen.SourceWriter;
import org.teavm.javascript.ni.Generator; import org.teavm.javascript.spi.Generator;
import org.teavm.javascript.ni.GeneratorContext; import org.teavm.javascript.spi.GeneratorContext;
import org.teavm.model.*; import org.teavm.model.*;
/** /**

View File

@ -21,8 +21,8 @@ import org.teavm.dependency.*;
import org.teavm.javascript.ast.ConstantExpr; import org.teavm.javascript.ast.ConstantExpr;
import org.teavm.javascript.ast.Expr; import org.teavm.javascript.ast.Expr;
import org.teavm.javascript.ast.InvocationExpr; import org.teavm.javascript.ast.InvocationExpr;
import org.teavm.javascript.ni.Injector; import org.teavm.javascript.spi.Injector;
import org.teavm.javascript.ni.InjectorContext; import org.teavm.javascript.spi.InjectorContext;
import org.teavm.jso.JS; import org.teavm.jso.JS;
import org.teavm.model.CallLocation; import org.teavm.model.CallLocation;
import org.teavm.model.ClassReader; import org.teavm.model.ClassReader;
@ -88,6 +88,9 @@ public class JSNativeGenerator implements Injector, DependencyPlugin {
} }
writer.append("))"); writer.append("))");
break; break;
case "marshall":
context.writeExpr(context.getArgument(0));
break;
case "wrap": case "wrap":
if (methodRef.getDescriptor().parameterType(0).isObject("java.lang.String")) { if (methodRef.getDescriptor().parameterType(0).isObject("java.lang.String")) {
writer.append("$rt_ustr("); writer.append("$rt_ustr(");

View File

@ -17,8 +17,8 @@ package org.teavm.jso.plugin;
import java.util.*; import java.util.*;
import org.teavm.diagnostics.Diagnostics; import org.teavm.diagnostics.Diagnostics;
import org.teavm.javascript.ni.GeneratedBy; import org.teavm.javascript.spi.GeneratedBy;
import org.teavm.javascript.ni.PreserveOriginalName; import org.teavm.javascript.spi.PreserveOriginalName;
import org.teavm.jso.*; import org.teavm.jso.*;
import org.teavm.model.*; import org.teavm.model.*;
import org.teavm.model.instructions.*; import org.teavm.model.instructions.*;

View File

@ -35,6 +35,16 @@
<artifactId>teavm-core</artifactId> <artifactId>teavm-core</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.teavm</groupId>
<artifactId>teavm-jso</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.teavm</groupId>
<artifactId>teavm-dom</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>

View File

@ -0,0 +1,98 @@
/*
* Copyright 2015 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.platform;
import org.teavm.dependency.PluggableDependency;
import org.teavm.javascript.spi.GeneratedBy;
import org.teavm.javascript.spi.InjectedBy;
import org.teavm.jso.JS;
import org.teavm.platform.metadata.ClassResource;
import org.teavm.platform.plugin.PlatformGenerator;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public final class Platform {
private Platform() {
}
public static PlatformObject getPlatformObject(Object obj) {
return (PlatformObject)JS.marshall(obj);
}
@GeneratedBy(PlatformGenerator.class)
@PluggableDependency(PlatformGenerator.class)
public static native Object clone(Object obj);
public static boolean isInstance(PlatformObject obj, PlatformClass cls) {
return obj != null && !JS.isUndefined(obj.getPlatformClass().getMetadata()) &&
isAssignable(obj.getPlatformClass(), cls);
}
public static boolean isAssignable(PlatformClass from, PlatformClass to) {
if (from == to) {
return true;
}
PlatformSequence<PlatformClass> supertypes = from.getMetadata().getSupertypes();
for (int i = 0; i < supertypes.getLength(); ++i) {
if (isAssignable(supertypes.get(i), to)) {
return true;
}
}
return false;
}
@InjectedBy(PlatformGenerator.class)
@PluggableDependency(PlatformGenerator.class)
public static native Class<?> asJavaClass(PlatformObject obj);
public static PlatformPrimitives getPrimitives() {
return (PlatformPrimitives)JS.getGlobal();
}
public static PlatformConsole getConsole() {
return (PlatformConsole)JS.getGlobal();
}
public static int nextObjectId() {
return ((PlatformHelper)JS.getGlobal()).nextId();
}
@GeneratedBy(PlatformGenerator.class)
@PluggableDependency(PlatformGenerator.class)
public static native <T> T newInstance(PlatformClass cls);
@GeneratedBy(PlatformGenerator.class)
@PluggableDependency(PlatformGenerator.class)
public static native PlatformClass lookupClass(String name);
@GeneratedBy(PlatformGenerator.class)
@PluggableDependency(PlatformGenerator.class)
public static native void initClass(PlatformClass cls);
@InjectedBy(PlatformGenerator.class)
@PluggableDependency(PlatformGenerator.class)
public static native PlatformClass classFromResource(ClassResource resource);
@InjectedBy(PlatformGenerator.class)
@PluggableDependency(PlatformGenerator.class)
public static native Enum<?>[] getEnumConstants(PlatformClass cls);
public static PlatformString stringFromCharCode(int charCode) {
return ((PlatformHelper)JS.getGlobal()).getStringClass().fromCharCode(charCode);
}
}

View File

@ -0,0 +1,34 @@
/*
* Copyright 2015 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.platform;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public interface PlatformClass extends JSObject {
@JSProperty("$meta")
PlatformClassMetadata getMetadata();
@JSProperty("classObject")
void setJavaClass(PlatformObject obj);
@JSProperty("classObject")
PlatformObject getJavaClass();
}

View File

@ -0,0 +1,43 @@
/*
* Copyright 2015 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.platform;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public interface PlatformClassMetadata extends JSObject {
@JSProperty("item")
PlatformClass getArrayItem();
@JSProperty
PlatformSequence<PlatformClass> getSupertypes();
@JSProperty
PlatformClass getSuperclass();
@JSProperty
String getName();
@JSProperty
boolean isPrimitive();
@JSProperty
boolean isEnum();
}

View File

@ -0,0 +1,31 @@
/*
* Copyright 2015 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.platform;
import org.teavm.jso.JSMethod;
import org.teavm.jso.JSObject;
/**
*
* @author Alexey Andreev
*/
public interface PlatformConsole extends JSObject {
@JSMethod("rt_putStdout")
void output(int b);
@JSMethod("rt_putStderr")
void error(int b);
}

View File

@ -0,0 +1,32 @@
/*
* Copyright 2015 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.platform;
import org.teavm.jso.JSMethod;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
/**
*
* @author Alexey Andreev
*/
interface PlatformHelper extends JSObject {
@JSMethod("$rt_nextId")
int nextId();
@JSProperty("String")
PlatformStringClass getStringClass();
}

View File

@ -0,0 +1,34 @@
/*
* Copyright 2015 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.platform;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public interface PlatformObject extends JSObject {
@JSProperty("constructor")
PlatformClass getPlatformClass();
@JSProperty("$id")
int getId();
@JSProperty("$id")
void setId(int id);
}

View File

@ -0,0 +1,52 @@
/*
* Copyright 2015 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.platform;
import org.teavm.jso.JSMethod;
import org.teavm.jso.JSObject;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public interface PlatformPrimitives extends JSObject {
@JSMethod("$rt_voidcls")
PlatformClass getVoidClass();
@JSMethod("$rt_booleancls")
PlatformClass getBooleanClass();
@JSMethod("$rt_bytecls")
PlatformClass getByteClass();
@JSMethod("$rt_shortcls")
PlatformClass getShortClass();
@JSMethod("$rt_charcls")
PlatformClass getCharClass();
@JSMethod("$rt_intcls")
PlatformClass getIntClass();
@JSMethod("$rt_longcls")
PlatformClass getLongClass();
@JSMethod("$rt_floatcls")
PlatformClass getFloatClass();
@JSMethod("$rt_doublecls")
PlatformClass getDoubleClass();
}

View File

@ -0,0 +1,32 @@
/*
* Copyright 2015 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.platform;
import org.teavm.jso.JSIndexer;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public interface PlatformSequence<T extends JSObject> extends JSObject {
@JSProperty
int getLength();
@JSIndexer
T get(int index);
}

View File

@ -0,0 +1,30 @@
/*
* Copyright 2015 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.platform;
import org.teavm.jso.JSObject;
/**
*
* @author Alexey Andreev
*/
public interface PlatformString extends JSObject {
PlatformString toUpperCase();
PlatformString toLowerCase();
int charCodeAt(int index);
}

View File

@ -0,0 +1,26 @@
/*
* Copyright 2015 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.platform;
import org.teavm.jso.JSObject;
/**
*
* @author Alexey Andreev
*/
interface PlatformStringClass extends JSObject {
PlatformString fromCharCode(int charCode);
}

View File

@ -13,14 +13,14 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.teavm.runtime; package org.teavm.platform.async;
/** /**
* *
* @author Alexey Andreev * @author Alexey Andreev <konsoletyper@gmail.com>
*/ */
public interface AsyncCallback<T> { public interface AsyncCallback<T> {
void complete(T value); void complete(T result);
void error(Exception e); void error(Throwable e);
} }

Some files were not shown because too many files have changed in this diff Show More