mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 00:04: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.java.lang.annotation.TAnnotation;
|
||||
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.PlatformClass;
|
||||
import org.teavm.platform.metadata.ClassResource;
|
||||
import org.teavm.platform.metadata.ClassScopedMetadataProvider;
|
||||
import org.teavm.runtime.RuntimeClass;
|
||||
import org.teavm.runtime.RuntimeObject;
|
||||
|
||||
public class TClass<T> extends TObject implements TAnnotatedElement {
|
||||
TString name;
|
||||
|
@ -93,11 +97,11 @@ public class TClass<T> extends TObject implements TAnnotatedElement {
|
|||
}
|
||||
|
||||
public boolean isPrimitive() {
|
||||
return platformClass.getMetadata().isPrimitive();
|
||||
return Platform.isPrimitive(platformClass);
|
||||
}
|
||||
|
||||
public boolean isArray() {
|
||||
return platformClass.getMetadata().getArrayItem() != null;
|
||||
return Platform.getArrayItem(platformClass) != null;
|
||||
}
|
||||
|
||||
public boolean isEnum() {
|
||||
|
@ -105,7 +109,7 @@ public class TClass<T> extends TObject implements TAnnotatedElement {
|
|||
}
|
||||
|
||||
public TClass<?> getComponentType() {
|
||||
return getClass(platformClass.getMetadata().getArrayItem());
|
||||
return getClass(Platform.getArrayItem(platformClass));
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
if ((type.itemType.flags & RuntimeClass.PRIMITIVE) == 0) {
|
||||
itemSize = Address.sizeOf();
|
||||
|
|
|
@ -21,14 +21,26 @@ import org.teavm.interop.DelegateTo;
|
|||
import org.teavm.backend.javascript.spi.GeneratedBy;
|
||||
import org.teavm.platform.PlatformClass;
|
||||
import org.teavm.runtime.Allocator;
|
||||
import org.teavm.runtime.RuntimeArray;
|
||||
import org.teavm.runtime.RuntimeClass;
|
||||
import org.teavm.runtime.RuntimeObject;
|
||||
|
||||
public final class TArray extends TObject {
|
||||
@GeneratedBy(ArrayNativeGenerator.class)
|
||||
@PluggableDependency(ArrayNativeGenerator.class)
|
||||
@DelegateTo("getLengthLowLevel")
|
||||
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 {
|
||||
if (componentType == null) {
|
||||
throw new TNullPointerException();
|
||||
|
|
|
@ -32,7 +32,7 @@ public final class Example {
|
|||
testLazyInitialization();
|
||||
testHashCode();
|
||||
testArrayList();
|
||||
//testArrayCopy();
|
||||
testArrayCopy();
|
||||
}
|
||||
|
||||
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.AllocatorIntrinsic;
|
||||
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.PlatformClassMetadataIntrinsic;
|
||||
import org.teavm.backend.wasm.intrinsics.PlatformIntrinsic;
|
||||
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.WasmStructureIntrinsic;
|
||||
import org.teavm.backend.wasm.model.WasmFunction;
|
||||
import org.teavm.backend.wasm.model.WasmMemorySegment;
|
||||
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.classes.TagRegistry;
|
||||
import org.teavm.model.classes.VirtualTableProvider;
|
||||
import org.teavm.model.instructions.CloneArrayInstruction;
|
||||
import org.teavm.model.instructions.InvocationType;
|
||||
import org.teavm.model.instructions.InvokeInstruction;
|
||||
import org.teavm.runtime.Allocator;
|
||||
|
@ -125,6 +126,7 @@ public class WasmTarget implements TeaVMTarget {
|
|||
List<ClassHolderTransformer> transformers = new ArrayList<>();
|
||||
transformers.add(new ObjectPatch());
|
||||
transformers.add(new ClassPatch());
|
||||
transformers.add(new WasmDependencyListener());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
|
@ -158,6 +160,8 @@ public class WasmTarget implements TeaVMTarget {
|
|||
Address.class, void.class), null).use();
|
||||
dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "fillZero", Address.class, int.class,
|
||||
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",
|
||||
RuntimeClass.class, Address.class), null).use();
|
||||
|
@ -188,7 +192,8 @@ public class WasmTarget implements TeaVMTarget {
|
|||
VirtualTableProvider vtableProvider = createVirtualTableProvider(classes);
|
||||
TagRegistry tagRegistry = new TagRegistry(classes);
|
||||
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<>(),
|
||||
new HashSet<>());
|
||||
|
@ -197,12 +202,12 @@ public class WasmTarget implements TeaVMTarget {
|
|||
vtableProvider, tagRegistry, stringPool);
|
||||
|
||||
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 AllocatorIntrinsic());
|
||||
context.addIntrinsic(new PlatformIntrinsic());
|
||||
context.addIntrinsic(new PlatformClassIntrinsic());
|
||||
context.addIntrinsic(new PlatformClassMetadataIntrinsic());
|
||||
context.addIntrinsic(new PlatformObjectIntrinsic(classGenerator));
|
||||
context.addIntrinsic(new ClassIntrinsic());
|
||||
|
||||
|
@ -393,6 +398,8 @@ public class WasmTarget implements TeaVMTarget {
|
|||
if (invoke.getType() == InvocationType.VIRTUAL) {
|
||||
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.DataValue;
|
||||
import org.teavm.interop.Address;
|
||||
import org.teavm.interop.Function;
|
||||
import org.teavm.interop.Structure;
|
||||
import org.teavm.model.ClassReader;
|
||||
import org.teavm.model.ClassReaderSource;
|
||||
|
@ -63,7 +64,8 @@ public class WasmClassGenerator {
|
|||
DataPrimitives.INT, /* tag */
|
||||
DataPrimitives.INT, /* canary */
|
||||
DataPrimitives.ADDRESS, /* item type */
|
||||
DataPrimitives.ADDRESS /* array type */);
|
||||
DataPrimitives.ADDRESS, /* array type */
|
||||
DataPrimitives.INT /* isInstance function */);
|
||||
|
||||
public WasmClassGenerator(ClassReaderSource classSource, VirtualTableProvider vtableProvider,
|
||||
TagRegistry tagRegistry, BinaryWriter binaryWriter) {
|
||||
|
@ -216,10 +218,22 @@ public class WasmClassGenerator {
|
|||
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) {
|
||||
if (cls.getName().equals(Structure.class.getName()) || cls.getName().equals(Address.class.getName())) {
|
||||
data.size = 0;
|
||||
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())) {
|
||||
addClass(ValueType.object(cls.getParent()));
|
||||
ClassBinaryData parentData = binaryDataMap.get(ValueType.object(cls.getParent()));
|
||||
|
@ -228,6 +242,10 @@ public class WasmClassGenerator {
|
|||
if (parentData.start == -1) {
|
||||
data.start = -1;
|
||||
}
|
||||
if (parentData.function) {
|
||||
data.function = true;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
data.size = 4;
|
||||
data.alignment = 4;
|
||||
|
@ -328,5 +346,6 @@ public class WasmClassGenerator {
|
|||
int start;
|
||||
ObjectIntMap<String> fieldLayout = new ObjectIntOpenHashMap<>();
|
||||
DataValue data;
|
||||
boolean function;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,13 +18,19 @@ package org.teavm.backend.wasm.generate;
|
|||
import org.teavm.dependency.AbstractDependencyListener;
|
||||
import org.teavm.dependency.DependencyAgent;
|
||||
import org.teavm.dependency.MethodDependency;
|
||||
import org.teavm.diagnostics.Diagnostics;
|
||||
import org.teavm.interop.DelegateTo;
|
||||
import org.teavm.model.AnnotationReader;
|
||||
import org.teavm.model.CallLocation;
|
||||
import org.teavm.model.ClassHolder;
|
||||
import org.teavm.model.ClassHolderTransformer;
|
||||
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;
|
||||
|
||||
public class WasmDependencyListener extends AbstractDependencyListener {
|
||||
public class WasmDependencyListener extends AbstractDependencyListener implements ClassHolderTransformer {
|
||||
@Override
|
||||
public void methodReached(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||
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) {
|
||||
String str = (String) expr.getValue();
|
||||
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 {
|
||||
throw new IllegalArgumentException("Constant unsupported: " + expr.getValue());
|
||||
}
|
||||
|
|
|
@ -109,13 +109,16 @@ public class WasmGenerator {
|
|||
public WasmFunction generateNative(MethodReference methodReference) {
|
||||
WasmFunction function = new WasmFunction(WasmMangling.mangleMethod(methodReference));
|
||||
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);
|
||||
if (importedMethod != null) {
|
||||
function.setImportName(importedMethod.name);
|
||||
function.setImportModule(importedMethod.module);
|
||||
} else {
|
||||
function.setImportName("<unknown>");
|
||||
}
|
||||
|
||||
return function;
|
||||
|
|
|
@ -27,8 +27,16 @@ import org.teavm.runtime.Allocator;
|
|||
public class AllocatorIntrinsic implements WasmIntrinsic {
|
||||
@Override
|
||||
public boolean isApplicable(MethodReference methodReference) {
|
||||
return methodReference.getClassName().equals(Allocator.class.getName())
|
||||
&& methodReference.getName().equals("fillZero");
|
||||
if (!methodReference.getClassName().equals(Allocator.class.getName())) {
|
||||
return false;
|
||||
}
|
||||
switch (methodReference.getName()) {
|
||||
case "fillZero":
|
||||
case "moveMemoryBlock":
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -39,7 +47,8 @@ public class AllocatorIntrinsic implements WasmIntrinsic {
|
|||
MethodReference delegateMetod = new MethodReference(WasmRuntime.class.getName(),
|
||||
invocation.getMethod().getDescriptor());
|
||||
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()));
|
||||
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.backend.wasm.model.expression.WasmExpression;
|
||||
import org.teavm.model.MethodDescriptor;
|
||||
import org.teavm.model.MethodReference;
|
||||
|
||||
public class PlatformIntrinsic implements WasmIntrinsic {
|
||||
|
@ -24,7 +25,18 @@ public class PlatformIntrinsic implements WasmIntrinsic {
|
|||
|
||||
@Override
|
||||
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
|
||||
|
|
|
@ -20,21 +20,20 @@ import org.teavm.ast.InvocationExpr;
|
|||
import org.teavm.backend.wasm.generate.WasmClassGenerator;
|
||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||
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.ValueType;
|
||||
|
||||
public class WasmStructureIntrinsic implements WasmIntrinsic {
|
||||
public class StructureIntrinsic implements WasmIntrinsic {
|
||||
private WasmClassGenerator classGenerator;
|
||||
|
||||
public WasmStructureIntrinsic(WasmClassGenerator classGenerator) {
|
||||
public StructureIntrinsic(WasmClassGenerator classGenerator) {
|
||||
this.classGenerator = classGenerator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(MethodReference methodReference) {
|
||||
return !methodReference.getClassName().equals(Address.class.getName())
|
||||
&& classGenerator.getClassPointer(ValueType.object(methodReference.getClassName())) < 0;
|
||||
return methodReference.getClassName().equals(Structure.class.getName());
|
||||
}
|
||||
|
||||
@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;
|
||||
|
||||
public class RuntimeArray extends RuntimeJavaObject {
|
||||
int size;
|
||||
public int size;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package org.teavm.runtime;
|
||||
|
||||
import org.teavm.interop.Address;
|
||||
|
||||
public class RuntimeClass extends RuntimeJavaObject {
|
||||
public static final int INITIALIZED = 1;
|
||||
public static final int PRIMITIVE = 2;
|
||||
|
@ -25,6 +27,7 @@ public class RuntimeClass extends RuntimeJavaObject {
|
|||
public int canary;
|
||||
public RuntimeClass itemType;
|
||||
public RuntimeClass arrayType;
|
||||
public IsSupertypeFunction isSupertypeOf;
|
||||
|
||||
public static int computeCanary(int size, int tag) {
|
||||
return size ^ (tag << 8) ^ (tag >>> 24) ^ 0xAAAAAAAA;
|
||||
|
@ -33,4 +36,8 @@ public class RuntimeClass extends RuntimeJavaObject {
|
|||
public int computeCanary() {
|
||||
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.InjectedBy;
|
||||
import org.teavm.dependency.PluggableDependency;
|
||||
import org.teavm.interop.DelegateTo;
|
||||
import org.teavm.jso.JSBody;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.browser.Window;
|
||||
import org.teavm.platform.metadata.ClassResource;
|
||||
import org.teavm.platform.metadata.StaticFieldResource;
|
||||
import org.teavm.platform.plugin.PlatformGenerator;
|
||||
import org.teavm.runtime.RuntimeClass;
|
||||
import org.teavm.runtime.RuntimeObject;
|
||||
|
||||
public final class Platform {
|
||||
private Platform() {
|
||||
|
@ -37,14 +40,21 @@ public final class Platform {
|
|||
@PluggableDependency(PlatformGenerator.class)
|
||||
public static native Object clone(Object obj);
|
||||
|
||||
@DelegateTo("isInstanceLowLevel")
|
||||
public static boolean isInstance(PlatformObject obj, PlatformClass cls) {
|
||||
return obj != null && !isUndefined(obj.getPlatformClass().getMetadata())
|
||||
&& 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';")
|
||||
private static native boolean isUndefined(JSObject object);
|
||||
|
||||
@DelegateTo("isAssignableLowLevel")
|
||||
public static boolean isAssignable(PlatformClass from, PlatformClass to) {
|
||||
if (from == to) {
|
||||
return true;
|
||||
|
@ -58,6 +68,11 @@ public final class Platform {
|
|||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isAssignableLowLevel(RuntimeClass from, RuntimeClass to) {
|
||||
return to.isSupertypeOf.apply(from);
|
||||
}
|
||||
|
||||
@InjectedBy(PlatformGenerator.class)
|
||||
@PluggableDependency(PlatformGenerator.class)
|
||||
public static native Class<?> asJavaClass(PlatformObject obj);
|
||||
|
@ -131,4 +146,24 @@ public final class Platform {
|
|||
public static PlatformString stringFromCharCode(int 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.JSProperty;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public interface PlatformClassMetadata extends JSObject {
|
||||
@JSProperty("item")
|
||||
PlatformClass getArrayItem();
|
||||
|
|
Loading…
Reference in New Issue
Block a user