mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-09 00:14:10 -08:00
Fixes bugs in JSO and building resources
This commit is contained in:
parent
ae60a7b4a0
commit
bf68cf4b7d
|
@ -120,6 +120,11 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
return classSource;
|
return classSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassLoader getClassLoader() {
|
||||||
|
return classLoader;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String generateClassName() {
|
public String generateClassName() {
|
||||||
return "$$tmp$$.TempClass" + classNameSuffix++;
|
return "$$tmp$$.TempClass" + classNameSuffix++;
|
||||||
|
|
|
@ -338,6 +338,21 @@ class DependencyGraphBuilder {
|
||||||
@Override
|
@Override
|
||||||
public void createArray(VariableReader receiver, ValueType itemType, VariableReader size) {
|
public void createArray(VariableReader receiver, ValueType itemType, VariableReader size) {
|
||||||
useRunners.add(new TypePropagationRunner(nodes[receiver.getIndex()], "[" + itemType));
|
useRunners.add(new TypePropagationRunner(nodes[receiver.getIndex()], "[" + itemType));
|
||||||
|
final String className = extractClassName(itemType);
|
||||||
|
if (className != null) {
|
||||||
|
useRunners.add(new Runnable() {
|
||||||
|
@Override public void run() {
|
||||||
|
dependencyChecker.initClass(className, callerStack);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String extractClassName(ValueType itemType) {
|
||||||
|
while (itemType instanceof ValueType.Array) {
|
||||||
|
itemType = ((ValueType.Array)itemType).getItemType();
|
||||||
|
}
|
||||||
|
return itemType instanceof ValueType.Object ? ((ValueType.Object)itemType).getClassName() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -27,6 +27,8 @@ import org.teavm.model.MethodReference;
|
||||||
public interface DependencyInfo {
|
public interface DependencyInfo {
|
||||||
ClassReaderSource getClassSource();
|
ClassReaderSource getClassSource();
|
||||||
|
|
||||||
|
ClassLoader getClassLoader();
|
||||||
|
|
||||||
boolean isMethodAchievable(MethodReference methodRef);
|
boolean isMethodAchievable(MethodReference methodRef);
|
||||||
|
|
||||||
Collection<MethodReference> getAchievableMethods();
|
Collection<MethodReference> getAchievableMethods();
|
||||||
|
|
|
@ -33,6 +33,13 @@ public class DirectoryBuildTarget implements BuildTarget {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OutputStream createResource(String fileName) throws IOException {
|
public OutputStream createResource(String fileName) throws IOException {
|
||||||
|
int index = fileName.lastIndexOf('/');
|
||||||
|
if (index >= 0) {
|
||||||
|
File dir = new File(directory, fileName.substring(0, index));
|
||||||
|
if (!dir.exists()) {
|
||||||
|
dir.mkdirs();
|
||||||
|
}
|
||||||
|
}
|
||||||
return new FileOutputStream(new File(directory, fileName));
|
return new FileOutputStream(new File(directory, fileName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,6 +166,48 @@ public final class JS {
|
||||||
public static native JSObject invoke(JSObject instance, JSObject method, JSObject a, JSObject b, JSObject c,
|
public static native JSObject invoke(JSObject instance, JSObject method, JSObject a, JSObject b, JSObject c,
|
||||||
JSObject d, JSObject e, JSObject f, JSObject g, JSObject h);
|
JSObject d, JSObject e, JSObject f, JSObject g, JSObject h);
|
||||||
|
|
||||||
|
@InjectedBy(JSNativeGenerator.class)
|
||||||
|
@PluggableDependency(JSNativeGenerator.class)
|
||||||
|
public static native JSObject instantiate(JSObject instance, JSObject constructor);
|
||||||
|
|
||||||
|
@InjectedBy(JSNativeGenerator.class)
|
||||||
|
@PluggableDependency(JSNativeGenerator.class)
|
||||||
|
public static native JSObject instantiate(JSObject instance, JSObject constructor, JSObject a);
|
||||||
|
|
||||||
|
@InjectedBy(JSNativeGenerator.class)
|
||||||
|
@PluggableDependency(JSNativeGenerator.class)
|
||||||
|
public static native JSObject instantiate(JSObject instance, JSObject constructor, JSObject a, JSObject b);
|
||||||
|
|
||||||
|
@InjectedBy(JSNativeGenerator.class)
|
||||||
|
@PluggableDependency(JSNativeGenerator.class)
|
||||||
|
public static native JSObject instantiate(JSObject instance, JSObject constructor, JSObject a, JSObject b,
|
||||||
|
JSObject c);
|
||||||
|
|
||||||
|
@InjectedBy(JSNativeGenerator.class)
|
||||||
|
@PluggableDependency(JSNativeGenerator.class)
|
||||||
|
public static native JSObject instantiate(JSObject instance, JSObject constructor, JSObject a, JSObject b,
|
||||||
|
JSObject c, JSObject d);
|
||||||
|
|
||||||
|
@InjectedBy(JSNativeGenerator.class)
|
||||||
|
@PluggableDependency(JSNativeGenerator.class)
|
||||||
|
public static native JSObject instantiate(JSObject instance, JSObject constructor, JSObject a, JSObject b,
|
||||||
|
JSObject c, JSObject d, JSObject e);
|
||||||
|
|
||||||
|
@InjectedBy(JSNativeGenerator.class)
|
||||||
|
@PluggableDependency(JSNativeGenerator.class)
|
||||||
|
public static native JSObject instantiate(JSObject instance, JSObject constructor, JSObject a, JSObject b,
|
||||||
|
JSObject c, JSObject d, JSObject e, JSObject f);
|
||||||
|
|
||||||
|
@InjectedBy(JSNativeGenerator.class)
|
||||||
|
@PluggableDependency(JSNativeGenerator.class)
|
||||||
|
public static native JSObject instantiate(JSObject instance, JSObject constructor, JSObject a, JSObject b,
|
||||||
|
JSObject c, JSObject d, JSObject e, JSObject f, JSObject g);
|
||||||
|
|
||||||
|
@InjectedBy(JSNativeGenerator.class)
|
||||||
|
@PluggableDependency(JSNativeGenerator.class)
|
||||||
|
public static native JSObject instantiate(JSObject instance, JSObject constructor, JSObject a, JSObject b,
|
||||||
|
JSObject c, JSObject d, JSObject e, JSObject f, JSObject g, JSObject h);
|
||||||
|
|
||||||
public static <T extends JSObject> Iterable<T> iterate(final JSArray<T> array) {
|
public static <T extends JSObject> Iterable<T> iterate(final JSArray<T> array) {
|
||||||
return new Iterable<T>() {
|
return new Iterable<T>() {
|
||||||
@Override public Iterator<T> iterator() {
|
@Override public Iterator<T> iterator() {
|
||||||
|
|
|
@ -1,40 +1,16 @@
|
||||||
/*
|
|
||||||
* 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.jso;
|
package org.teavm.jso;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public interface JSConstructor<T extends JSObject> extends JSFunction {
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
T construct();
|
@Target(ElementType.METHOD)
|
||||||
|
public @interface JSConstructor {
|
||||||
T construct(JSObject a);
|
String value() default "";
|
||||||
|
|
||||||
T construct(JSObject a, JSObject b);
|
|
||||||
|
|
||||||
T construct(JSObject a, JSObject b, JSObject c);
|
|
||||||
|
|
||||||
T construct(JSObject a, JSObject b, JSObject c, JSObject d);
|
|
||||||
|
|
||||||
T construct(JSObject a, JSObject b, JSObject c, JSObject d, JSObject e);
|
|
||||||
|
|
||||||
T construct(JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f);
|
|
||||||
|
|
||||||
T construct(JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f, JSObject g);
|
|
||||||
|
|
||||||
T construct(JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f, JSObject g, JSObject h);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,12 @@ package org.teavm.jso;
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public interface JSGlobal extends JSObject {
|
public interface JSGlobal extends JSObject {
|
||||||
@JSProperty
|
@JSConstructor
|
||||||
JSConstructor<JSArray<JSObject>> getArray();
|
JSObject newObject();
|
||||||
|
|
||||||
@JSProperty
|
@JSConstructor
|
||||||
JSConstructor<JSObject> getObject();
|
<T extends JSObject> JSArray<T> newArray();
|
||||||
|
|
||||||
|
@JSConstructor
|
||||||
|
<T extends JSObject> JSArray<T> newArray(int sz);
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,19 @@ public class JSNativeGenerator implements Generator, Injector, DependencyPlugin
|
||||||
}
|
}
|
||||||
writer.append(')');
|
writer.append(')');
|
||||||
break;
|
break;
|
||||||
|
case "instantiate":
|
||||||
|
writer.append("(new ");
|
||||||
|
context.writeExpr(context.getArgument(0));
|
||||||
|
renderProperty(context.getArgument(1), context);
|
||||||
|
writer.append('(');
|
||||||
|
for (int i = 2; i < context.argumentCount(); ++i) {
|
||||||
|
if (i > 2) {
|
||||||
|
writer.append(',').ws();
|
||||||
|
}
|
||||||
|
context.writeExpr(context.getArgument(i));
|
||||||
|
}
|
||||||
|
writer.append("))");
|
||||||
|
break;
|
||||||
case "wrap":
|
case "wrap":
|
||||||
context.writeExpr(context.getArgument(0));
|
context.writeExpr(context.getArgument(0));
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -89,7 +89,7 @@ class JavascriptNativeProcessor {
|
||||||
}
|
}
|
||||||
} else if (isProperSetter(method.getDescriptor())) {
|
} else if (isProperSetter(method.getDescriptor())) {
|
||||||
Variable wrapped = wrap(invoke.getArguments().get(0), method.parameterType(0));
|
Variable wrapped = wrap(invoke.getArguments().get(0), method.parameterType(0));
|
||||||
addPropertySet(cutPrefix(method.getName(), 3), invoke.getArguments().get(0), wrapped);
|
addPropertySet(cutPrefix(method.getName(), 3), invoke.getInstance(), wrapped);
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Method " + invoke.getMethod() + " is not " +
|
throw new RuntimeException("Method " + invoke.getMethod() + " is not " +
|
||||||
"a proper native JavaScript property declaration");
|
"a proper native JavaScript property declaration");
|
||||||
|
@ -112,25 +112,47 @@ class JavascriptNativeProcessor {
|
||||||
"a proper native JavaScript indexer declaration");
|
"a proper native JavaScript indexer declaration");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (method.getResultType() != ValueType.VOID && !isSupportedType(method.getResultType())) {
|
String name = method.getName();
|
||||||
throw new RuntimeException("Method " + invoke.getMethod() + " is not " +
|
AnnotationReader constructorAnnot = method.getAnnotations().get(JSConstructor.class.getName());
|
||||||
"a proper native JavaScript method declaration");
|
boolean isConstructor = false;
|
||||||
|
if (constructorAnnot != null) {
|
||||||
|
if (!isSupportedType(method.getResultType())) {
|
||||||
|
throw new RuntimeException("Method " + invoke.getMethod() + " is not " +
|
||||||
|
"a proper native JavaScript constructor declaration");
|
||||||
|
}
|
||||||
|
AnnotationValue nameVal = constructorAnnot.getValue("value");
|
||||||
|
name = nameVal != null ? constructorAnnot.getValue("value").getString() : "";
|
||||||
|
if (name.isEmpty()) {
|
||||||
|
if (!method.getName().startsWith("new") || method.getName().length() == 3) {
|
||||||
|
throw new RuntimeException("Method " + invoke.getMethod() + " is not " +
|
||||||
|
"declared as a native JavaScript constructor, but its name does " +
|
||||||
|
"not satisfy conventions");
|
||||||
|
}
|
||||||
|
name = method.getName().substring(3);
|
||||||
|
}
|
||||||
|
isConstructor = true;
|
||||||
|
} else {
|
||||||
|
if (method.getResultType() != ValueType.VOID && !isSupportedType(method.getResultType())) {
|
||||||
|
throw new RuntimeException("Method " + invoke.getMethod() + " is not " +
|
||||||
|
"a proper native JavaScript method declaration");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (ValueType arg : method.getParameterTypes()) {
|
for (ValueType arg : method.getParameterTypes()) {
|
||||||
if (!isSupportedType(arg)) {
|
if (!isSupportedType(arg)) {
|
||||||
throw new RuntimeException("Method " + invoke.getMethod() + " is not " +
|
throw new RuntimeException("Method " + invoke.getMethod() + " is not " +
|
||||||
"a proper native JavaScript method declaration");
|
"a proper native JavaScript method or constructor declaration");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Variable result = invoke.getReceiver() != null ? program.createVariable() : null;
|
Variable result = invoke.getReceiver() != null ? program.createVariable() : null;
|
||||||
InvokeInstruction newInvoke = new InvokeInstruction();
|
InvokeInstruction newInvoke = new InvokeInstruction();
|
||||||
ValueType[] signature = new ValueType[method.parameterCount() + 3];
|
ValueType[] signature = new ValueType[method.parameterCount() + 3];
|
||||||
Arrays.fill(signature, ValueType.object(JSObject.class.getName()));
|
Arrays.fill(signature, ValueType.object(JSObject.class.getName()));
|
||||||
newInvoke.setMethod(new MethodReference(JS.class.getName(), "invoke", signature));
|
newInvoke.setMethod(new MethodReference(JS.class.getName(),
|
||||||
|
isConstructor ? "instantiate" : "invoke", signature));
|
||||||
newInvoke.setType(InvocationType.SPECIAL);
|
newInvoke.setType(InvocationType.SPECIAL);
|
||||||
newInvoke.setReceiver(result);
|
newInvoke.setReceiver(result);
|
||||||
newInvoke.getArguments().add(invoke.getInstance());
|
newInvoke.getArguments().add(invoke.getInstance());
|
||||||
newInvoke.getArguments().add(addStringWrap(addString(method.getName())));
|
newInvoke.getArguments().add(addStringWrap(addString(name)));
|
||||||
for (int k = 0; k < invoke.getArguments().size(); ++k) {
|
for (int k = 0; k < invoke.getArguments().size(); ++k) {
|
||||||
Variable arg = wrapArgument(invoke.getArguments().get(k), method.parameterType(k));
|
Variable arg = wrapArgument(invoke.getArguments().get(k), method.parameterType(k));
|
||||||
newInvoke.getArguments().add(arg);
|
newInvoke.getArguments().add(arg);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user