mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
System.arrayCopy works
This commit is contained in:
parent
ca3258417b
commit
1ae683ead3
|
@ -21,10 +21,14 @@ import java.util.Map;
|
||||||
import org.teavm.classlib.impl.DeclaringClassMetadataGenerator;
|
import org.teavm.classlib.impl.DeclaringClassMetadataGenerator;
|
||||||
import org.teavm.classlib.java.lang.annotation.TAnnotation;
|
import org.teavm.classlib.java.lang.annotation.TAnnotation;
|
||||||
import org.teavm.classlib.java.lang.reflect.TAnnotatedElement;
|
import org.teavm.classlib.java.lang.reflect.TAnnotatedElement;
|
||||||
|
import org.teavm.interop.Address;
|
||||||
|
import org.teavm.interop.DelegateTo;
|
||||||
import org.teavm.platform.Platform;
|
import org.teavm.platform.Platform;
|
||||||
import org.teavm.platform.PlatformClass;
|
import org.teavm.platform.PlatformClass;
|
||||||
import org.teavm.platform.metadata.ClassResource;
|
import org.teavm.platform.metadata.ClassResource;
|
||||||
import org.teavm.platform.metadata.ClassScopedMetadataProvider;
|
import org.teavm.platform.metadata.ClassScopedMetadataProvider;
|
||||||
|
import org.teavm.runtime.RuntimeClass;
|
||||||
|
import org.teavm.runtime.RuntimeObject;
|
||||||
|
|
||||||
public class TClass<T> extends TObject implements TAnnotatedElement {
|
public class TClass<T> extends TObject implements TAnnotatedElement {
|
||||||
TString name;
|
TString name;
|
||||||
|
@ -93,11 +97,11 @@ public class TClass<T> extends TObject implements TAnnotatedElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPrimitive() {
|
public boolean isPrimitive() {
|
||||||
return platformClass.getMetadata().isPrimitive();
|
return Platform.isPrimitive(platformClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isArray() {
|
public boolean isArray() {
|
||||||
return platformClass.getMetadata().getArrayItem() != null;
|
return Platform.getArrayItem(platformClass) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEnum() {
|
public boolean isEnum() {
|
||||||
|
@ -105,7 +109,7 @@ public class TClass<T> extends TObject implements TAnnotatedElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
public TClass<?> getComponentType() {
|
public TClass<?> getComponentType() {
|
||||||
return getClass(platformClass.getMetadata().getArrayItem());
|
return getClass(Platform.getArrayItem(platformClass));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean desiredAssertionStatus() {
|
public boolean desiredAssertionStatus() {
|
||||||
|
|
|
@ -80,7 +80,7 @@ public final class TSystem extends TObject {
|
||||||
private static native void doArrayCopy(Object src, int srcPos, Object dest, int destPos, int length);
|
private static native void doArrayCopy(Object src, int srcPos, Object dest, int destPos, int length);
|
||||||
|
|
||||||
static void doArrayCopyLowLevel(RuntimeArray src, int srcPos, RuntimeArray dest, int destPos, int length) {
|
static void doArrayCopyLowLevel(RuntimeArray src, int srcPos, RuntimeArray dest, int destPos, int length) {
|
||||||
RuntimeClass type = Address.fromInt(src.classReference << 3).toStructure();
|
RuntimeClass type = RuntimeClass.getClass(src);
|
||||||
int itemSize = type.itemType.size;
|
int itemSize = type.itemType.size;
|
||||||
if ((type.itemType.flags & RuntimeClass.PRIMITIVE) == 0) {
|
if ((type.itemType.flags & RuntimeClass.PRIMITIVE) == 0) {
|
||||||
itemSize = Address.sizeOf();
|
itemSize = Address.sizeOf();
|
||||||
|
|
|
@ -21,14 +21,26 @@ import org.teavm.interop.DelegateTo;
|
||||||
import org.teavm.backend.javascript.spi.GeneratedBy;
|
import org.teavm.backend.javascript.spi.GeneratedBy;
|
||||||
import org.teavm.platform.PlatformClass;
|
import org.teavm.platform.PlatformClass;
|
||||||
import org.teavm.runtime.Allocator;
|
import org.teavm.runtime.Allocator;
|
||||||
|
import org.teavm.runtime.RuntimeArray;
|
||||||
import org.teavm.runtime.RuntimeClass;
|
import org.teavm.runtime.RuntimeClass;
|
||||||
import org.teavm.runtime.RuntimeObject;
|
import org.teavm.runtime.RuntimeObject;
|
||||||
|
|
||||||
public final class TArray extends TObject {
|
public final class TArray extends TObject {
|
||||||
@GeneratedBy(ArrayNativeGenerator.class)
|
@GeneratedBy(ArrayNativeGenerator.class)
|
||||||
@PluggableDependency(ArrayNativeGenerator.class)
|
@PluggableDependency(ArrayNativeGenerator.class)
|
||||||
|
@DelegateTo("getLengthLowLevel")
|
||||||
public static native int getLength(TObject array) throws TIllegalArgumentException;
|
public static native int getLength(TObject array) throws TIllegalArgumentException;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static int getLengthLowLevel(RuntimeObject obj) {
|
||||||
|
RuntimeClass cls = RuntimeClass.getClass(obj);
|
||||||
|
if (cls.itemType == null) {
|
||||||
|
throw new TIllegalArgumentException();
|
||||||
|
}
|
||||||
|
RuntimeArray array = (RuntimeArray) obj;
|
||||||
|
return array.size;
|
||||||
|
}
|
||||||
|
|
||||||
public static TObject newInstance(TClass<?> componentType, int length) throws TNegativeArraySizeException {
|
public static TObject newInstance(TClass<?> componentType, int length) throws TNegativeArraySizeException {
|
||||||
if (componentType == null) {
|
if (componentType == null) {
|
||||||
throw new TNullPointerException();
|
throw new TNullPointerException();
|
||||||
|
|
|
@ -32,7 +32,7 @@ public final class Example {
|
||||||
testLazyInitialization();
|
testLazyInitialization();
|
||||||
testHashCode();
|
testHashCode();
|
||||||
testArrayList();
|
testArrayList();
|
||||||
//testArrayCopy();
|
testArrayCopy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void testFibonacci() {
|
private static void testFibonacci() {
|
||||||
|
|
|
@ -36,12 +36,12 @@ import org.teavm.backend.wasm.generate.WasmStringPool;
|
||||||
import org.teavm.backend.wasm.intrinsics.AddressIntrinsic;
|
import org.teavm.backend.wasm.intrinsics.AddressIntrinsic;
|
||||||
import org.teavm.backend.wasm.intrinsics.AllocatorIntrinsic;
|
import org.teavm.backend.wasm.intrinsics.AllocatorIntrinsic;
|
||||||
import org.teavm.backend.wasm.intrinsics.ClassIntrinsic;
|
import org.teavm.backend.wasm.intrinsics.ClassIntrinsic;
|
||||||
|
import org.teavm.backend.wasm.intrinsics.FunctionIntrinsic;
|
||||||
import org.teavm.backend.wasm.intrinsics.PlatformClassIntrinsic;
|
import org.teavm.backend.wasm.intrinsics.PlatformClassIntrinsic;
|
||||||
import org.teavm.backend.wasm.intrinsics.PlatformClassMetadataIntrinsic;
|
|
||||||
import org.teavm.backend.wasm.intrinsics.PlatformIntrinsic;
|
import org.teavm.backend.wasm.intrinsics.PlatformIntrinsic;
|
||||||
import org.teavm.backend.wasm.intrinsics.PlatformObjectIntrinsic;
|
import org.teavm.backend.wasm.intrinsics.PlatformObjectIntrinsic;
|
||||||
|
import org.teavm.backend.wasm.intrinsics.StructureIntrinsic;
|
||||||
import org.teavm.backend.wasm.intrinsics.WasmRuntimeIntrinsic;
|
import org.teavm.backend.wasm.intrinsics.WasmRuntimeIntrinsic;
|
||||||
import org.teavm.backend.wasm.intrinsics.WasmStructureIntrinsic;
|
|
||||||
import org.teavm.backend.wasm.model.WasmFunction;
|
import org.teavm.backend.wasm.model.WasmFunction;
|
||||||
import org.teavm.backend.wasm.model.WasmMemorySegment;
|
import org.teavm.backend.wasm.model.WasmMemorySegment;
|
||||||
import org.teavm.backend.wasm.model.WasmModule;
|
import org.teavm.backend.wasm.model.WasmModule;
|
||||||
|
@ -88,6 +88,7 @@ import org.teavm.model.Program;
|
||||||
import org.teavm.model.ValueType;
|
import org.teavm.model.ValueType;
|
||||||
import org.teavm.model.classes.TagRegistry;
|
import org.teavm.model.classes.TagRegistry;
|
||||||
import org.teavm.model.classes.VirtualTableProvider;
|
import org.teavm.model.classes.VirtualTableProvider;
|
||||||
|
import org.teavm.model.instructions.CloneArrayInstruction;
|
||||||
import org.teavm.model.instructions.InvocationType;
|
import org.teavm.model.instructions.InvocationType;
|
||||||
import org.teavm.model.instructions.InvokeInstruction;
|
import org.teavm.model.instructions.InvokeInstruction;
|
||||||
import org.teavm.runtime.Allocator;
|
import org.teavm.runtime.Allocator;
|
||||||
|
@ -125,6 +126,7 @@ public class WasmTarget implements TeaVMTarget {
|
||||||
List<ClassHolderTransformer> transformers = new ArrayList<>();
|
List<ClassHolderTransformer> transformers = new ArrayList<>();
|
||||||
transformers.add(new ObjectPatch());
|
transformers.add(new ObjectPatch());
|
||||||
transformers.add(new ClassPatch());
|
transformers.add(new ClassPatch());
|
||||||
|
transformers.add(new WasmDependencyListener());
|
||||||
return transformers;
|
return transformers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,6 +160,8 @@ public class WasmTarget implements TeaVMTarget {
|
||||||
Address.class, void.class), null).use();
|
Address.class, void.class), null).use();
|
||||||
dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "fillZero", Address.class, int.class,
|
dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "fillZero", Address.class, int.class,
|
||||||
void.class), null).use();
|
void.class), null).use();
|
||||||
|
dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "moveMemoryBlock", Address.class,
|
||||||
|
Address.class, int.class, void.class), null).use();
|
||||||
|
|
||||||
dependencyChecker.linkMethod(new MethodReference(Allocator.class, "allocate",
|
dependencyChecker.linkMethod(new MethodReference(Allocator.class, "allocate",
|
||||||
RuntimeClass.class, Address.class), null).use();
|
RuntimeClass.class, Address.class), null).use();
|
||||||
|
@ -188,7 +192,8 @@ public class WasmTarget implements TeaVMTarget {
|
||||||
VirtualTableProvider vtableProvider = createVirtualTableProvider(classes);
|
VirtualTableProvider vtableProvider = createVirtualTableProvider(classes);
|
||||||
TagRegistry tagRegistry = new TagRegistry(classes);
|
TagRegistry tagRegistry = new TagRegistry(classes);
|
||||||
BinaryWriter binaryWriter = new BinaryWriter(256);
|
BinaryWriter binaryWriter = new BinaryWriter(256);
|
||||||
WasmClassGenerator classGenerator = new WasmClassGenerator(classes, vtableProvider, tagRegistry, binaryWriter);
|
WasmClassGenerator classGenerator = new WasmClassGenerator(
|
||||||
|
classes, vtableProvider, tagRegistry, binaryWriter);
|
||||||
|
|
||||||
Decompiler decompiler = new Decompiler(classes, controller.getClassLoader(), new HashSet<>(),
|
Decompiler decompiler = new Decompiler(classes, controller.getClassLoader(), new HashSet<>(),
|
||||||
new HashSet<>());
|
new HashSet<>());
|
||||||
|
@ -197,12 +202,12 @@ public class WasmTarget implements TeaVMTarget {
|
||||||
vtableProvider, tagRegistry, stringPool);
|
vtableProvider, tagRegistry, stringPool);
|
||||||
|
|
||||||
context.addIntrinsic(new AddressIntrinsic(classGenerator));
|
context.addIntrinsic(new AddressIntrinsic(classGenerator));
|
||||||
context.addIntrinsic(new WasmStructureIntrinsic(classGenerator));
|
context.addIntrinsic(new StructureIntrinsic(classGenerator));
|
||||||
|
context.addIntrinsic(new FunctionIntrinsic(classGenerator));
|
||||||
context.addIntrinsic(new WasmRuntimeIntrinsic());
|
context.addIntrinsic(new WasmRuntimeIntrinsic());
|
||||||
context.addIntrinsic(new AllocatorIntrinsic());
|
context.addIntrinsic(new AllocatorIntrinsic());
|
||||||
context.addIntrinsic(new PlatformIntrinsic());
|
context.addIntrinsic(new PlatformIntrinsic());
|
||||||
context.addIntrinsic(new PlatformClassIntrinsic());
|
context.addIntrinsic(new PlatformClassIntrinsic());
|
||||||
context.addIntrinsic(new PlatformClassMetadataIntrinsic());
|
|
||||||
context.addIntrinsic(new PlatformObjectIntrinsic(classGenerator));
|
context.addIntrinsic(new PlatformObjectIntrinsic(classGenerator));
|
||||||
context.addIntrinsic(new ClassIntrinsic());
|
context.addIntrinsic(new ClassIntrinsic());
|
||||||
|
|
||||||
|
@ -393,6 +398,8 @@ public class WasmTarget implements TeaVMTarget {
|
||||||
if (invoke.getType() == InvocationType.VIRTUAL) {
|
if (invoke.getType() == InvocationType.VIRTUAL) {
|
||||||
virtualMethods.add(invoke.getMethod());
|
virtualMethods.add(invoke.getMethod());
|
||||||
}
|
}
|
||||||
|
} else if (insn instanceof CloneArrayInstruction) {
|
||||||
|
virtualMethods.add(new MethodReference(Object.class, "clone", Object.class));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.teavm.backend.wasm.binary.DataStructure;
|
||||||
import org.teavm.backend.wasm.binary.DataType;
|
import org.teavm.backend.wasm.binary.DataType;
|
||||||
import org.teavm.backend.wasm.binary.DataValue;
|
import org.teavm.backend.wasm.binary.DataValue;
|
||||||
import org.teavm.interop.Address;
|
import org.teavm.interop.Address;
|
||||||
|
import org.teavm.interop.Function;
|
||||||
import org.teavm.interop.Structure;
|
import org.teavm.interop.Structure;
|
||||||
import org.teavm.model.ClassReader;
|
import org.teavm.model.ClassReader;
|
||||||
import org.teavm.model.ClassReaderSource;
|
import org.teavm.model.ClassReaderSource;
|
||||||
|
@ -63,7 +64,8 @@ public class WasmClassGenerator {
|
||||||
DataPrimitives.INT, /* tag */
|
DataPrimitives.INT, /* tag */
|
||||||
DataPrimitives.INT, /* canary */
|
DataPrimitives.INT, /* canary */
|
||||||
DataPrimitives.ADDRESS, /* item type */
|
DataPrimitives.ADDRESS, /* item type */
|
||||||
DataPrimitives.ADDRESS /* array type */);
|
DataPrimitives.ADDRESS, /* array type */
|
||||||
|
DataPrimitives.INT /* isInstance function */);
|
||||||
|
|
||||||
public WasmClassGenerator(ClassReaderSource classSource, VirtualTableProvider vtableProvider,
|
public WasmClassGenerator(ClassReaderSource classSource, VirtualTableProvider vtableProvider,
|
||||||
TagRegistry tagRegistry, BinaryWriter binaryWriter) {
|
TagRegistry tagRegistry, BinaryWriter binaryWriter) {
|
||||||
|
@ -216,10 +218,22 @@ public class WasmClassGenerator {
|
||||||
return data.start < 0;
|
return data.start < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isFunctionClass(String className) {
|
||||||
|
ValueType type = ValueType.object(className);
|
||||||
|
addClass(type);
|
||||||
|
return binaryDataMap.get(type).function;
|
||||||
|
}
|
||||||
|
|
||||||
private void calculateLayout(ClassReader cls, ClassBinaryData data) {
|
private void calculateLayout(ClassReader cls, ClassBinaryData data) {
|
||||||
if (cls.getName().equals(Structure.class.getName()) || cls.getName().equals(Address.class.getName())) {
|
if (cls.getName().equals(Structure.class.getName()) || cls.getName().equals(Address.class.getName())) {
|
||||||
data.size = 0;
|
data.size = 0;
|
||||||
data.start = -1;
|
data.start = -1;
|
||||||
|
return;
|
||||||
|
} else if (cls.getName().equals(Function.class.getName())) {
|
||||||
|
data.size = 0;
|
||||||
|
data.start = -1;
|
||||||
|
data.function = true;
|
||||||
|
return;
|
||||||
} else if (cls.getParent() != null && !cls.getParent().equals(cls.getName())) {
|
} else if (cls.getParent() != null && !cls.getParent().equals(cls.getName())) {
|
||||||
addClass(ValueType.object(cls.getParent()));
|
addClass(ValueType.object(cls.getParent()));
|
||||||
ClassBinaryData parentData = binaryDataMap.get(ValueType.object(cls.getParent()));
|
ClassBinaryData parentData = binaryDataMap.get(ValueType.object(cls.getParent()));
|
||||||
|
@ -228,6 +242,10 @@ public class WasmClassGenerator {
|
||||||
if (parentData.start == -1) {
|
if (parentData.start == -1) {
|
||||||
data.start = -1;
|
data.start = -1;
|
||||||
}
|
}
|
||||||
|
if (parentData.function) {
|
||||||
|
data.function = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
data.size = 4;
|
data.size = 4;
|
||||||
data.alignment = 4;
|
data.alignment = 4;
|
||||||
|
@ -328,5 +346,6 @@ public class WasmClassGenerator {
|
||||||
int start;
|
int start;
|
||||||
ObjectIntMap<String> fieldLayout = new ObjectIntOpenHashMap<>();
|
ObjectIntMap<String> fieldLayout = new ObjectIntOpenHashMap<>();
|
||||||
DataValue data;
|
DataValue data;
|
||||||
|
boolean function;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,19 @@ package org.teavm.backend.wasm.generate;
|
||||||
import org.teavm.dependency.AbstractDependencyListener;
|
import org.teavm.dependency.AbstractDependencyListener;
|
||||||
import org.teavm.dependency.DependencyAgent;
|
import org.teavm.dependency.DependencyAgent;
|
||||||
import org.teavm.dependency.MethodDependency;
|
import org.teavm.dependency.MethodDependency;
|
||||||
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
import org.teavm.interop.DelegateTo;
|
import org.teavm.interop.DelegateTo;
|
||||||
import org.teavm.model.AnnotationReader;
|
import org.teavm.model.AnnotationReader;
|
||||||
import org.teavm.model.CallLocation;
|
import org.teavm.model.CallLocation;
|
||||||
|
import org.teavm.model.ClassHolder;
|
||||||
|
import org.teavm.model.ClassHolderTransformer;
|
||||||
import org.teavm.model.ClassReader;
|
import org.teavm.model.ClassReader;
|
||||||
|
import org.teavm.model.ClassReaderSource;
|
||||||
|
import org.teavm.model.ElementModifier;
|
||||||
|
import org.teavm.model.MethodHolder;
|
||||||
import org.teavm.model.MethodReader;
|
import org.teavm.model.MethodReader;
|
||||||
|
|
||||||
public class WasmDependencyListener extends AbstractDependencyListener {
|
public class WasmDependencyListener extends AbstractDependencyListener implements ClassHolderTransformer {
|
||||||
@Override
|
@Override
|
||||||
public void methodReached(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
public void methodReached(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||||
AnnotationReader delegateAnnot = method.getMethod().getAnnotations().get(DelegateTo.class.getName());
|
AnnotationReader delegateAnnot = method.getMethod().getAnnotations().get(DelegateTo.class.getName());
|
||||||
|
@ -40,4 +46,15 @@ public class WasmDependencyListener extends AbstractDependencyListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transformClass(ClassHolder cls, ClassReaderSource innerSource, Diagnostics diagnostics) {
|
||||||
|
for (MethodHolder method : cls.getMethods()) {
|
||||||
|
AnnotationReader delegateAnnot = method.getAnnotations().get(DelegateTo.class.getName());
|
||||||
|
if (delegateAnnot != null) {
|
||||||
|
method.setProgram(null);
|
||||||
|
method.getModifiers().add(ElementModifier.NATIVE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -572,6 +572,9 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||||
} else if (expr.getValue() instanceof String) {
|
} else if (expr.getValue() instanceof String) {
|
||||||
String str = (String) expr.getValue();
|
String str = (String) expr.getValue();
|
||||||
result = new WasmInt32Constant(context.getStringPool().getStringPointer(str));
|
result = new WasmInt32Constant(context.getStringPool().getStringPointer(str));
|
||||||
|
} else if (expr.getValue() instanceof ValueType) {
|
||||||
|
int pointer = classGenerator.getClassPointer((ValueType) expr.getValue());
|
||||||
|
result = new WasmInt32Constant(pointer);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Constant unsupported: " + expr.getValue());
|
throw new IllegalArgumentException("Constant unsupported: " + expr.getValue());
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,13 +109,16 @@ public class WasmGenerator {
|
||||||
public WasmFunction generateNative(MethodReference methodReference) {
|
public WasmFunction generateNative(MethodReference methodReference) {
|
||||||
WasmFunction function = new WasmFunction(WasmMangling.mangleMethod(methodReference));
|
WasmFunction function = new WasmFunction(WasmMangling.mangleMethod(methodReference));
|
||||||
for (int i = 0; i < methodReference.parameterCount(); ++i) {
|
for (int i = 0; i < methodReference.parameterCount(); ++i) {
|
||||||
function.getParameters().add(WasmGeneratorUtil.mapType(methodReference.parameterType(i)));
|
WasmType paramType = WasmGeneratorUtil.mapType(methodReference.parameterType(i));
|
||||||
|
function.getParameters().add(paramType);
|
||||||
}
|
}
|
||||||
|
|
||||||
WasmGenerationContext.ImportedMethod importedMethod = context.getImportedMethod(methodReference);
|
WasmGenerationContext.ImportedMethod importedMethod = context.getImportedMethod(methodReference);
|
||||||
if (importedMethod != null) {
|
if (importedMethod != null) {
|
||||||
function.setImportName(importedMethod.name);
|
function.setImportName(importedMethod.name);
|
||||||
function.setImportModule(importedMethod.module);
|
function.setImportModule(importedMethod.module);
|
||||||
|
} else {
|
||||||
|
function.setImportName("<unknown>");
|
||||||
}
|
}
|
||||||
|
|
||||||
return function;
|
return function;
|
||||||
|
|
|
@ -27,8 +27,16 @@ import org.teavm.runtime.Allocator;
|
||||||
public class AllocatorIntrinsic implements WasmIntrinsic {
|
public class AllocatorIntrinsic implements WasmIntrinsic {
|
||||||
@Override
|
@Override
|
||||||
public boolean isApplicable(MethodReference methodReference) {
|
public boolean isApplicable(MethodReference methodReference) {
|
||||||
return methodReference.getClassName().equals(Allocator.class.getName())
|
if (!methodReference.getClassName().equals(Allocator.class.getName())) {
|
||||||
&& methodReference.getName().equals("fillZero");
|
return false;
|
||||||
|
}
|
||||||
|
switch (methodReference.getName()) {
|
||||||
|
case "fillZero":
|
||||||
|
case "moveMemoryBlock":
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -39,7 +47,8 @@ public class AllocatorIntrinsic implements WasmIntrinsic {
|
||||||
MethodReference delegateMetod = new MethodReference(WasmRuntime.class.getName(),
|
MethodReference delegateMetod = new MethodReference(WasmRuntime.class.getName(),
|
||||||
invocation.getMethod().getDescriptor());
|
invocation.getMethod().getDescriptor());
|
||||||
WasmCall call = new WasmCall(WasmMangling.mangleMethod(delegateMetod));
|
WasmCall call = new WasmCall(WasmMangling.mangleMethod(delegateMetod));
|
||||||
call.getArguments().addAll(invocation.getArguments().stream().map(manager::generate)
|
call.getArguments().addAll(invocation.getArguments().stream()
|
||||||
|
.map(manager::generate)
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
return call;
|
return call;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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.backend.wasm.intrinsics;
|
||||||
|
|
||||||
|
import org.teavm.ast.InvocationExpr;
|
||||||
|
import org.teavm.backend.wasm.generate.WasmClassGenerator;
|
||||||
|
import org.teavm.backend.wasm.generate.WasmGeneratorUtil;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmIndirectCall;
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
import org.teavm.model.ValueType;
|
||||||
|
|
||||||
|
public class FunctionIntrinsic implements WasmIntrinsic {
|
||||||
|
private WasmClassGenerator classGenerator;
|
||||||
|
|
||||||
|
public FunctionIntrinsic(WasmClassGenerator classGenerator) {
|
||||||
|
this.classGenerator = classGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isApplicable(MethodReference methodReference) {
|
||||||
|
return classGenerator.isFunctionClass(methodReference.getClassName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WasmExpression apply(InvocationExpr invocation, WasmIntrinsicManager manager) {
|
||||||
|
WasmExpression selector = manager.generate(invocation.getArguments().get(0));
|
||||||
|
WasmIndirectCall call = new WasmIndirectCall(selector);
|
||||||
|
|
||||||
|
for (ValueType type : invocation.getMethod().getParameterTypes()) {
|
||||||
|
call.getParameterTypes().add(WasmGeneratorUtil.mapType(type));
|
||||||
|
}
|
||||||
|
if (invocation.getMethod().getReturnType() != ValueType.VOID) {
|
||||||
|
call.setReturnType(WasmGeneratorUtil.mapType(invocation.getMethod().getReturnType()));
|
||||||
|
}
|
||||||
|
for (int i = 1; i < invocation.getArguments().size(); ++i) {
|
||||||
|
call.getArguments().add(manager.generate(invocation.getArguments().get(i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return call;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2016 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.backend.wasm.intrinsics;
|
|
||||||
|
|
||||||
import org.teavm.ast.InvocationExpr;
|
|
||||||
import org.teavm.ast.QualificationExpr;
|
|
||||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
|
||||||
import org.teavm.model.FieldReference;
|
|
||||||
import org.teavm.model.MethodReference;
|
|
||||||
import org.teavm.runtime.RuntimeClass;
|
|
||||||
|
|
||||||
public class PlatformClassMetadataIntrinsic implements WasmIntrinsic {
|
|
||||||
private static final String PLATFORM_CLASS_METADATA_NAME = "org.teavm.platform.PlatformClassMetadata";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isApplicable(MethodReference methodReference) {
|
|
||||||
return methodReference.getClassName().equals(PLATFORM_CLASS_METADATA_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public WasmExpression apply(InvocationExpr invocation, WasmIntrinsicManager manager) {
|
|
||||||
switch (invocation.getMethod().getName()) {
|
|
||||||
case "getArrayItem": {
|
|
||||||
QualificationExpr expr = new QualificationExpr();
|
|
||||||
expr.setQualified(invocation.getArguments().get(0));
|
|
||||||
expr.setField(new FieldReference(RuntimeClass.class.getName(), "itemType"));
|
|
||||||
expr.setLocation(invocation.getLocation());
|
|
||||||
return manager.generate(expr);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException(invocation.getMethod().toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -17,6 +17,7 @@ package org.teavm.backend.wasm.intrinsics;
|
||||||
|
|
||||||
import org.teavm.ast.InvocationExpr;
|
import org.teavm.ast.InvocationExpr;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||||
|
import org.teavm.model.MethodDescriptor;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
public class PlatformIntrinsic implements WasmIntrinsic {
|
public class PlatformIntrinsic implements WasmIntrinsic {
|
||||||
|
@ -24,7 +25,18 @@ public class PlatformIntrinsic implements WasmIntrinsic {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isApplicable(MethodReference methodReference) {
|
public boolean isApplicable(MethodReference methodReference) {
|
||||||
return methodReference.getClassName().equals(PLATFORM);
|
return methodReference.getClassName().equals(PLATFORM)
|
||||||
|
&& isApplicableToMethod(methodReference.getDescriptor());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isApplicableToMethod(MethodDescriptor methodDescriptor) {
|
||||||
|
switch (methodDescriptor.getName()) {
|
||||||
|
case "getPlatformObject":
|
||||||
|
case "asJavaClass":
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,21 +20,20 @@ import org.teavm.ast.InvocationExpr;
|
||||||
import org.teavm.backend.wasm.generate.WasmClassGenerator;
|
import org.teavm.backend.wasm.generate.WasmClassGenerator;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmInt32Constant;
|
import org.teavm.backend.wasm.model.expression.WasmInt32Constant;
|
||||||
import org.teavm.interop.Address;
|
import org.teavm.interop.Structure;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.model.ValueType;
|
import org.teavm.model.ValueType;
|
||||||
|
|
||||||
public class WasmStructureIntrinsic implements WasmIntrinsic {
|
public class StructureIntrinsic implements WasmIntrinsic {
|
||||||
private WasmClassGenerator classGenerator;
|
private WasmClassGenerator classGenerator;
|
||||||
|
|
||||||
public WasmStructureIntrinsic(WasmClassGenerator classGenerator) {
|
public StructureIntrinsic(WasmClassGenerator classGenerator) {
|
||||||
this.classGenerator = classGenerator;
|
this.classGenerator = classGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isApplicable(MethodReference methodReference) {
|
public boolean isApplicable(MethodReference methodReference) {
|
||||||
return !methodReference.getClassName().equals(Address.class.getName())
|
return methodReference.getClassName().equals(Structure.class.getName());
|
||||||
&& classGenerator.getClassPointer(ValueType.object(methodReference.getClassName())) < 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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.runtime;
|
||||||
|
|
||||||
|
import org.teavm.interop.Function;
|
||||||
|
|
||||||
|
public abstract class IsSupertypeFunction extends Function {
|
||||||
|
public abstract boolean apply(RuntimeClass superType);
|
||||||
|
}
|
|
@ -16,5 +16,5 @@
|
||||||
package org.teavm.runtime;
|
package org.teavm.runtime;
|
||||||
|
|
||||||
public class RuntimeArray extends RuntimeJavaObject {
|
public class RuntimeArray extends RuntimeJavaObject {
|
||||||
int size;
|
public int size;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.runtime;
|
package org.teavm.runtime;
|
||||||
|
|
||||||
|
import org.teavm.interop.Address;
|
||||||
|
|
||||||
public class RuntimeClass extends RuntimeJavaObject {
|
public class RuntimeClass extends RuntimeJavaObject {
|
||||||
public static final int INITIALIZED = 1;
|
public static final int INITIALIZED = 1;
|
||||||
public static final int PRIMITIVE = 2;
|
public static final int PRIMITIVE = 2;
|
||||||
|
@ -25,6 +27,7 @@ public class RuntimeClass extends RuntimeJavaObject {
|
||||||
public int canary;
|
public int canary;
|
||||||
public RuntimeClass itemType;
|
public RuntimeClass itemType;
|
||||||
public RuntimeClass arrayType;
|
public RuntimeClass arrayType;
|
||||||
|
public IsSupertypeFunction isSupertypeOf;
|
||||||
|
|
||||||
public static int computeCanary(int size, int tag) {
|
public static int computeCanary(int size, int tag) {
|
||||||
return size ^ (tag << 8) ^ (tag >>> 24) ^ 0xAAAAAAAA;
|
return size ^ (tag << 8) ^ (tag >>> 24) ^ 0xAAAAAAAA;
|
||||||
|
@ -33,4 +36,8 @@ public class RuntimeClass extends RuntimeJavaObject {
|
||||||
public int computeCanary() {
|
public int computeCanary() {
|
||||||
return computeCanary(size, tag);
|
return computeCanary(size, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static RuntimeClass getClass(RuntimeObject object) {
|
||||||
|
return Address.fromInt(object.classReference << 3).toStructure();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
19
interop/core/src/main/java/org/teavm/interop/Function.java
Normal file
19
interop/core/src/main/java/org/teavm/interop/Function.java
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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.interop;
|
||||||
|
|
||||||
|
public abstract class Function {
|
||||||
|
}
|
|
@ -19,12 +19,15 @@ import java.lang.annotation.Annotation;
|
||||||
import org.teavm.backend.javascript.spi.GeneratedBy;
|
import org.teavm.backend.javascript.spi.GeneratedBy;
|
||||||
import org.teavm.backend.javascript.spi.InjectedBy;
|
import org.teavm.backend.javascript.spi.InjectedBy;
|
||||||
import org.teavm.dependency.PluggableDependency;
|
import org.teavm.dependency.PluggableDependency;
|
||||||
|
import org.teavm.interop.DelegateTo;
|
||||||
import org.teavm.jso.JSBody;
|
import org.teavm.jso.JSBody;
|
||||||
import org.teavm.jso.JSObject;
|
import org.teavm.jso.JSObject;
|
||||||
import org.teavm.jso.browser.Window;
|
import org.teavm.jso.browser.Window;
|
||||||
import org.teavm.platform.metadata.ClassResource;
|
import org.teavm.platform.metadata.ClassResource;
|
||||||
import org.teavm.platform.metadata.StaticFieldResource;
|
import org.teavm.platform.metadata.StaticFieldResource;
|
||||||
import org.teavm.platform.plugin.PlatformGenerator;
|
import org.teavm.platform.plugin.PlatformGenerator;
|
||||||
|
import org.teavm.runtime.RuntimeClass;
|
||||||
|
import org.teavm.runtime.RuntimeObject;
|
||||||
|
|
||||||
public final class Platform {
|
public final class Platform {
|
||||||
private Platform() {
|
private Platform() {
|
||||||
|
@ -37,14 +40,21 @@ public final class Platform {
|
||||||
@PluggableDependency(PlatformGenerator.class)
|
@PluggableDependency(PlatformGenerator.class)
|
||||||
public static native Object clone(Object obj);
|
public static native Object clone(Object obj);
|
||||||
|
|
||||||
|
@DelegateTo("isInstanceLowLevel")
|
||||||
public static boolean isInstance(PlatformObject obj, PlatformClass cls) {
|
public static boolean isInstance(PlatformObject obj, PlatformClass cls) {
|
||||||
return obj != null && !isUndefined(obj.getPlatformClass().getMetadata())
|
return obj != null && !isUndefined(obj.getPlatformClass().getMetadata())
|
||||||
&& isAssignable(obj.getPlatformClass(), cls);
|
&& isAssignable(obj.getPlatformClass(), cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static boolean isInstanceLowLevel(RuntimeClass self, RuntimeObject object) {
|
||||||
|
return isAssignableLowLevel(RuntimeClass.getClass(object), self);
|
||||||
|
}
|
||||||
|
|
||||||
@JSBody(params = "object", script = "return typeof object === 'undefined';")
|
@JSBody(params = "object", script = "return typeof object === 'undefined';")
|
||||||
private static native boolean isUndefined(JSObject object);
|
private static native boolean isUndefined(JSObject object);
|
||||||
|
|
||||||
|
@DelegateTo("isAssignableLowLevel")
|
||||||
public static boolean isAssignable(PlatformClass from, PlatformClass to) {
|
public static boolean isAssignable(PlatformClass from, PlatformClass to) {
|
||||||
if (from == to) {
|
if (from == to) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -58,6 +68,11 @@ public final class Platform {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static boolean isAssignableLowLevel(RuntimeClass from, RuntimeClass to) {
|
||||||
|
return to.isSupertypeOf.apply(from);
|
||||||
|
}
|
||||||
|
|
||||||
@InjectedBy(PlatformGenerator.class)
|
@InjectedBy(PlatformGenerator.class)
|
||||||
@PluggableDependency(PlatformGenerator.class)
|
@PluggableDependency(PlatformGenerator.class)
|
||||||
public static native Class<?> asJavaClass(PlatformObject obj);
|
public static native Class<?> asJavaClass(PlatformObject obj);
|
||||||
|
@ -131,4 +146,24 @@ public final class Platform {
|
||||||
public static PlatformString stringFromCharCode(int charCode) {
|
public static PlatformString stringFromCharCode(int charCode) {
|
||||||
return ((PlatformHelper) Window.current()).getStringClass().fromCharCode(charCode);
|
return ((PlatformHelper) Window.current()).getStringClass().fromCharCode(charCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DelegateTo("isPrimitiveLowLevel")
|
||||||
|
public static boolean isPrimitive(PlatformClass cls) {
|
||||||
|
return cls.getMetadata().isPrimitive();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static boolean isPrimitiveLowLevel(RuntimeClass cls) {
|
||||||
|
return (cls.flags & RuntimeClass.PRIMITIVE) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@DelegateTo("getArrayItemLowLevel")
|
||||||
|
public static PlatformClass getArrayItem(PlatformClass cls) {
|
||||||
|
return cls.getMetadata().getArrayItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static RuntimeClass getArrayItemLowLevel(RuntimeClass cls) {
|
||||||
|
return cls.itemType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,6 @@ package org.teavm.platform;
|
||||||
import org.teavm.jso.JSObject;
|
import org.teavm.jso.JSObject;
|
||||||
import org.teavm.jso.JSProperty;
|
import org.teavm.jso.JSProperty;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public interface PlatformClassMetadata extends JSObject {
|
public interface PlatformClassMetadata extends JSObject {
|
||||||
@JSProperty("item")
|
@JSProperty("item")
|
||||||
PlatformClass getArrayItem();
|
PlatformClass getArrayItem();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user