mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 00:04:10 -08:00
Add support of Object.hashCode
This commit is contained in:
parent
8c6cf1840b
commit
35b59ed916
|
@ -49,6 +49,7 @@ import org.teavm.javascript.spi.Injector;
|
|||
import org.teavm.model.BasicBlock;
|
||||
import org.teavm.model.CallLocation;
|
||||
import org.teavm.model.ClassHolder;
|
||||
import org.teavm.model.ClassHolderTransformer;
|
||||
import org.teavm.model.ElementModifier;
|
||||
import org.teavm.model.InstructionLocation;
|
||||
import org.teavm.model.ListableClassHolderSource;
|
||||
|
@ -82,6 +83,11 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
|
|||
private final Set<MethodReference> asyncMethods = new HashSet<>();
|
||||
private final Set<MethodReference> asyncFamilyMethods = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public List<ClassHolderTransformer> getTransformers() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setController(TeaVMTargetController controller) {
|
||||
this.controller = controller;
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
package org.teavm.runtime;
|
||||
|
||||
public class RuntimeArray extends RuntimeObject {
|
||||
RuntimeObject monitor;
|
||||
public class RuntimeArray extends RuntimeJavaObject {
|
||||
int size;
|
||||
}
|
||||
|
|
21
core/src/main/java/org/teavm/runtime/RuntimeJavaObject.java
Normal file
21
core/src/main/java/org/teavm/runtime/RuntimeJavaObject.java
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
public class RuntimeJavaObject extends RuntimeObject {
|
||||
public static int nextId = 1;
|
||||
public RuntimeObject monitor;
|
||||
}
|
|
@ -18,5 +18,8 @@ package org.teavm.runtime;
|
|||
import org.teavm.interop.Structure;
|
||||
|
||||
public class RuntimeObject extends Structure {
|
||||
public static final int GC_MARKED = 0x80000000;
|
||||
public static final int MONITOR_EXISTS = 0x20000000;
|
||||
|
||||
public int classReference;
|
||||
}
|
||||
|
|
|
@ -134,6 +134,10 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
}
|
||||
};
|
||||
|
||||
for (ClassHolderTransformer transformer : target.getTransformers()) {
|
||||
dependencyChecker.addClassTransformer(transformer);
|
||||
}
|
||||
|
||||
for (TeaVMHostExtension extension : target.getHostExtensions()) {
|
||||
for (Class<?> extensionType : getExtensionTypes(extension)) {
|
||||
extensions.put(extensionType, extension);
|
||||
|
|
|
@ -18,10 +18,13 @@ package org.teavm.vm;
|
|||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
import org.teavm.dependency.DependencyChecker;
|
||||
import org.teavm.model.ClassHolderTransformer;
|
||||
import org.teavm.model.ListableClassHolderSource;
|
||||
import org.teavm.vm.spi.TeaVMHostExtension;
|
||||
|
||||
public interface TeaVMTarget {
|
||||
List<ClassHolderTransformer> getTransformers();
|
||||
|
||||
void setController(TeaVMTargetController controller);
|
||||
|
||||
List<TeaVMHostExtension> getHostExtensions();
|
||||
|
|
|
@ -60,6 +60,12 @@ public final class Example {
|
|||
Initialized.foo();
|
||||
Initialized.foo();
|
||||
Initialized.foo();
|
||||
|
||||
Object o = new Object();
|
||||
WasmRuntime.print(o.hashCode());
|
||||
WasmRuntime.print(o.hashCode());
|
||||
WasmRuntime.print(new Object().hashCode());
|
||||
WasmRuntime.print(new Object().hashCode());
|
||||
}
|
||||
|
||||
private static Base instance(int index) {
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.io.IOException;
|
|||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
@ -33,6 +34,7 @@ import org.teavm.interop.StaticInit;
|
|||
import org.teavm.model.BasicBlock;
|
||||
import org.teavm.model.CallLocation;
|
||||
import org.teavm.model.ClassHolder;
|
||||
import org.teavm.model.ClassHolderTransformer;
|
||||
import org.teavm.model.ClassReader;
|
||||
import org.teavm.model.ElementModifier;
|
||||
import org.teavm.model.FieldReference;
|
||||
|
@ -84,6 +86,7 @@ import org.teavm.wasm.model.expression.WasmIntType;
|
|||
import org.teavm.wasm.model.expression.WasmLoadInt32;
|
||||
import org.teavm.wasm.model.expression.WasmReturn;
|
||||
import org.teavm.wasm.model.expression.WasmStoreInt32;
|
||||
import org.teavm.wasm.patches.ObjectPatch;
|
||||
import org.teavm.wasm.render.WasmRenderer;
|
||||
|
||||
public class WasmTarget implements TeaVMTarget {
|
||||
|
@ -104,6 +107,13 @@ public class WasmTarget implements TeaVMTarget {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ClassHolderTransformer> getTransformers() {
|
||||
List<ClassHolderTransformer> transformers = new ArrayList<>();
|
||||
transformers.add(new ObjectPatch());
|
||||
return transformers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contributeDependencies(DependencyChecker dependencyChecker) {
|
||||
for (Class type : Arrays.asList(int.class, long.class, float.class, double.class)) {
|
||||
|
|
|
@ -62,9 +62,7 @@ import org.teavm.ast.UnwrapArrayExpr;
|
|||
import org.teavm.ast.VariableExpr;
|
||||
import org.teavm.ast.WhileStatement;
|
||||
import org.teavm.interop.Address;
|
||||
import org.teavm.model.ClassReader;
|
||||
import org.teavm.model.FieldReference;
|
||||
import org.teavm.model.MethodDescriptor;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.ValueType;
|
||||
import org.teavm.model.classes.TagRegistry;
|
||||
|
@ -111,6 +109,7 @@ import org.teavm.wasm.model.expression.WasmStoreFloat64;
|
|||
import org.teavm.wasm.model.expression.WasmStoreInt32;
|
||||
import org.teavm.wasm.model.expression.WasmStoreInt64;
|
||||
import org.teavm.wasm.model.expression.WasmSwitch;
|
||||
import org.teavm.wasm.model.expression.WasmUnreachable;
|
||||
|
||||
class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
||||
private WasmGenerationContext context;
|
||||
|
@ -735,6 +734,23 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
|||
call.getArguments().add(result);
|
||||
}
|
||||
result = call;
|
||||
} else if (expr.getType() == InvocationType.CONSTRUCTOR) {
|
||||
WasmBlock block = new WasmBlock(false);
|
||||
WasmLocal tmp = function.getLocalVariables().get(getTemporaryInt32());
|
||||
block.getBody().add(new WasmSetLocal(tmp, allocateObject(expr.getMethod().getClassName())));
|
||||
|
||||
String methodName = WasmMangling.mangleMethod(expr.getMethod());
|
||||
WasmCall call = new WasmCall(methodName);
|
||||
call.getArguments().add(new WasmGetLocal(tmp));
|
||||
for (Expr argument : expr.getArguments()) {
|
||||
argument.acceptVisitor(this);
|
||||
call.getArguments().add(result);
|
||||
}
|
||||
block.getBody().add(call);
|
||||
|
||||
block.getBody().add(new WasmGetLocal(tmp));
|
||||
|
||||
result = block;
|
||||
} else {
|
||||
expr.getArguments().get(0).acceptVisitor(this);
|
||||
WasmExpression instance = result;
|
||||
|
@ -860,12 +876,16 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
|||
|
||||
@Override
|
||||
public void visit(NewExpr expr) {
|
||||
int tag = classGenerator.getClassPointer(ValueType.object(expr.getConstructedClass()));
|
||||
result = allocateObject(expr.getConstructedClass());
|
||||
}
|
||||
|
||||
private WasmExpression allocateObject(String className) {
|
||||
int tag = classGenerator.getClassPointer(ValueType.object(className));
|
||||
String allocName = WasmMangling.mangleMethod(new MethodReference(Allocator.class, "allocate",
|
||||
RuntimeClass.class, Address.class));
|
||||
WasmCall call = new WasmCall(allocName);
|
||||
call.getArguments().add(new WasmInt32Constant(tag));
|
||||
result = call;
|
||||
return call;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -952,7 +972,13 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
|||
|
||||
@Override
|
||||
public void visit(ThrowStatement statement) {
|
||||
WasmBlock block = new WasmBlock(false);
|
||||
statement.getException().acceptVisitor(this);
|
||||
block.getBody().add(result);
|
||||
|
||||
block.getBody().add(new WasmUnreachable());
|
||||
|
||||
result = block;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -53,6 +53,7 @@ public class WasmAddressIntrinsic implements WasmIntrinsic {
|
|||
return new WasmConversion(WasmType.INT32, WasmType.INT64, false, value);
|
||||
}
|
||||
case "fromInt":
|
||||
case "ofObject":
|
||||
return manager.generate(invocation.getArguments().get(0));
|
||||
case "fromLong": {
|
||||
WasmExpression value = manager.generate(invocation.getArguments().get(0));
|
||||
|
|
59
core/src/main/java/org/teavm/wasm/patches/ObjectPatch.java
Normal file
59
core/src/main/java/org/teavm/wasm/patches/ObjectPatch.java
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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.wasm.patches;
|
||||
|
||||
import org.teavm.diagnostics.Diagnostics;
|
||||
import org.teavm.interop.Address;
|
||||
import org.teavm.model.ClassHolder;
|
||||
import org.teavm.model.ClassHolderTransformer;
|
||||
import org.teavm.model.ClassReaderSource;
|
||||
import org.teavm.model.MethodDescriptor;
|
||||
import org.teavm.model.MethodHolder;
|
||||
import org.teavm.model.Program;
|
||||
import org.teavm.model.util.ProgramUtils;
|
||||
import org.teavm.runtime.RuntimeJavaObject;
|
||||
import org.teavm.runtime.RuntimeObject;
|
||||
|
||||
public class ObjectPatch implements ClassHolderTransformer {
|
||||
@Override
|
||||
public void transformClass(ClassHolder cls, ClassReaderSource innerSource, Diagnostics diagnostics) {
|
||||
if (!cls.getName().equals("java.lang.Object")) {
|
||||
return;
|
||||
}
|
||||
|
||||
MethodHolder method = cls.getMethod(new MethodDescriptor("identity", int.class));
|
||||
Program patchedProgram = ProgramUtils.copy(innerSource.get(ObjectPatch.class.getName())
|
||||
.getMethod(new MethodDescriptor("patchedIdentity", int.class)).getProgram());
|
||||
method.setProgram(patchedProgram);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private int patchedIdentity() {
|
||||
RuntimeJavaObject object = Address.ofObject(this).toStructure();
|
||||
if ((object.classReference & RuntimeObject.MONITOR_EXISTS) != 0) {
|
||||
object = (RuntimeJavaObject) object.monitor;
|
||||
}
|
||||
int result = object.monitor.toAddress().toInt();
|
||||
if (result == 0) {
|
||||
result = RuntimeJavaObject.nextId++;
|
||||
if (result == 0) {
|
||||
result = RuntimeJavaObject.nextId++;
|
||||
}
|
||||
object.monitor = Address.fromInt(result).toStructure();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -57,4 +57,6 @@ public final class Address {
|
|||
public static native Address fromInt(int value);
|
||||
|
||||
public static native Address fromLong(long value);
|
||||
|
||||
public static native Address ofObject(Object obj);
|
||||
}
|
||||
|
|
|
@ -17,10 +17,6 @@ package org.teavm.interop;
|
|||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.METHOD, ElementType.CONSTRUCTOR })
|
||||
public @interface Rename {
|
||||
|
|
Loading…
Reference in New Issue
Block a user