mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-08 07:54:11 -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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader getClassLoader() {
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateClassName() {
|
||||
return "$$tmp$$.TempClass" + classNameSuffix++;
|
||||
|
|
|
@ -338,6 +338,21 @@ class DependencyGraphBuilder {
|
|||
@Override
|
||||
public void createArray(VariableReader receiver, ValueType itemType, VariableReader size) {
|
||||
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
|
||||
|
|
|
@ -27,6 +27,8 @@ import org.teavm.model.MethodReference;
|
|||
public interface DependencyInfo {
|
||||
ClassReaderSource getClassSource();
|
||||
|
||||
ClassLoader getClassLoader();
|
||||
|
||||
boolean isMethodAchievable(MethodReference methodRef);
|
||||
|
||||
Collection<MethodReference> getAchievableMethods();
|
||||
|
|
|
@ -33,6 +33,13 @@ public class DirectoryBuildTarget implements BuildTarget {
|
|||
|
||||
@Override
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -166,6 +166,48 @@ public final class JS {
|
|||
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);
|
||||
|
||||
@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) {
|
||||
return new Iterable<T>() {
|
||||
@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;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public interface JSConstructor<T extends JSObject> extends JSFunction {
|
||||
T construct();
|
||||
|
||||
T construct(JSObject a);
|
||||
|
||||
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);
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface JSConstructor {
|
||||
String value() default "";
|
||||
}
|
||||
|
|
|
@ -20,9 +20,12 @@ package org.teavm.jso;
|
|||
* @author Alexey Andreev
|
||||
*/
|
||||
public interface JSGlobal extends JSObject {
|
||||
@JSProperty
|
||||
JSConstructor<JSArray<JSObject>> getArray();
|
||||
@JSConstructor
|
||||
JSObject newObject();
|
||||
|
||||
@JSProperty
|
||||
JSConstructor<JSObject> getObject();
|
||||
@JSConstructor
|
||||
<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(')');
|
||||
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":
|
||||
context.writeExpr(context.getArgument(0));
|
||||
break;
|
||||
|
|
|
@ -89,7 +89,7 @@ class JavascriptNativeProcessor {
|
|||
}
|
||||
} else if (isProperSetter(method.getDescriptor())) {
|
||||
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 {
|
||||
throw new RuntimeException("Method " + invoke.getMethod() + " is not " +
|
||||
"a proper native JavaScript property declaration");
|
||||
|
@ -112,25 +112,47 @@ class JavascriptNativeProcessor {
|
|||
"a proper native JavaScript indexer declaration");
|
||||
}
|
||||
} else {
|
||||
if (method.getResultType() != ValueType.VOID && !isSupportedType(method.getResultType())) {
|
||||
throw new RuntimeException("Method " + invoke.getMethod() + " is not " +
|
||||
"a proper native JavaScript method declaration");
|
||||
String name = method.getName();
|
||||
AnnotationReader constructorAnnot = method.getAnnotations().get(JSConstructor.class.getName());
|
||||
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()) {
|
||||
if (!isSupportedType(arg)) {
|
||||
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;
|
||||
InvokeInstruction newInvoke = new InvokeInstruction();
|
||||
ValueType[] signature = new ValueType[method.parameterCount() + 3];
|
||||
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.setReceiver(result);
|
||||
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) {
|
||||
Variable arg = wrapArgument(invoke.getArguments().get(k), method.parameterType(k));
|
||||
newInvoke.getArguments().add(arg);
|
||||
|
|
Loading…
Reference in New Issue
Block a user