mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
C backend: make compiled binary independent of load location
This commit is contained in:
parent
8cf69db8bb
commit
76ca3f06cf
|
@ -53,6 +53,7 @@ import org.teavm.backend.c.intrinsic.PlatformClassIntrinsic;
|
||||||
import org.teavm.backend.c.intrinsic.PlatformClassMetadataIntrinsic;
|
import org.teavm.backend.c.intrinsic.PlatformClassMetadataIntrinsic;
|
||||||
import org.teavm.backend.c.intrinsic.PlatformIntrinsic;
|
import org.teavm.backend.c.intrinsic.PlatformIntrinsic;
|
||||||
import org.teavm.backend.c.intrinsic.PlatformObjectIntrinsic;
|
import org.teavm.backend.c.intrinsic.PlatformObjectIntrinsic;
|
||||||
|
import org.teavm.backend.c.intrinsic.RuntimeClassIntrinsic;
|
||||||
import org.teavm.backend.c.intrinsic.ShadowStackIntrinsic;
|
import org.teavm.backend.c.intrinsic.ShadowStackIntrinsic;
|
||||||
import org.teavm.backend.c.intrinsic.StructureIntrinsic;
|
import org.teavm.backend.c.intrinsic.StructureIntrinsic;
|
||||||
import org.teavm.dependency.ClassDependency;
|
import org.teavm.dependency.ClassDependency;
|
||||||
|
@ -231,6 +232,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
|
||||||
intrinsics.add(new MutatorIntrinsic());
|
intrinsics.add(new MutatorIntrinsic());
|
||||||
intrinsics.add(new ExceptionHandlingIntrinsic());
|
intrinsics.add(new ExceptionHandlingIntrinsic());
|
||||||
intrinsics.add(new FunctionIntrinsic(characteristics, exportDependencyListener.getResolvedMethods()));
|
intrinsics.add(new FunctionIntrinsic(characteristics, exportDependencyListener.getResolvedMethods()));
|
||||||
|
intrinsics.add(new RuntimeClassIntrinsic());
|
||||||
|
|
||||||
List<Generator> generators = new ArrayList<>();
|
List<Generator> generators = new ArrayList<>();
|
||||||
generators.add(new ArrayGenerator());
|
generators.add(new ArrayGenerator());
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 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.c.intrinsic;
|
||||||
|
|
||||||
|
import org.teavm.ast.InvocationExpr;
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
import org.teavm.runtime.RuntimeClass;
|
||||||
|
|
||||||
|
public class RuntimeClassIntrinsic implements Intrinsic {
|
||||||
|
@Override
|
||||||
|
public boolean canHandle(MethodReference method) {
|
||||||
|
if (!method.getClassName().equals(RuntimeClass.class.getName())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (method.getName()) {
|
||||||
|
case "pack":
|
||||||
|
case "unpack":
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(IntrinsicContext context, InvocationExpr invocation) {
|
||||||
|
switch (invocation.getMethod().getName()) {
|
||||||
|
case "pack":
|
||||||
|
context.writer().print("PACK_CLASS(");
|
||||||
|
context.emit(invocation.getArguments().get(0));
|
||||||
|
context.writer().print(")");
|
||||||
|
break;
|
||||||
|
case "unpack":
|
||||||
|
context.writer().print("UNPACK_CLASS(");
|
||||||
|
context.emit(invocation.getArguments().get(0));
|
||||||
|
context.writer().print(")");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -52,6 +52,7 @@ import org.teavm.backend.wasm.intrinsics.PlatformClassIntrinsic;
|
||||||
import org.teavm.backend.wasm.intrinsics.PlatformClassMetadataIntrinsic;
|
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.RuntimeClassIntrinsic;
|
||||||
import org.teavm.backend.wasm.intrinsics.ShadowStackIntrinsic;
|
import org.teavm.backend.wasm.intrinsics.ShadowStackIntrinsic;
|
||||||
import org.teavm.backend.wasm.intrinsics.StructureIntrinsic;
|
import org.teavm.backend.wasm.intrinsics.StructureIntrinsic;
|
||||||
import org.teavm.backend.wasm.intrinsics.WasmIntrinsicFactory;
|
import org.teavm.backend.wasm.intrinsics.WasmIntrinsicFactory;
|
||||||
|
@ -332,6 +333,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
|
||||||
context.addIntrinsic(new PlatformObjectIntrinsic(classGenerator));
|
context.addIntrinsic(new PlatformObjectIntrinsic(classGenerator));
|
||||||
context.addIntrinsic(new PlatformClassMetadataIntrinsic());
|
context.addIntrinsic(new PlatformClassMetadataIntrinsic());
|
||||||
context.addIntrinsic(new ClassIntrinsic());
|
context.addIntrinsic(new ClassIntrinsic());
|
||||||
|
context.addIntrinsic(new RuntimeClassIntrinsic());
|
||||||
context.addGenerator(new ArrayGenerator());
|
context.addGenerator(new ArrayGenerator());
|
||||||
|
|
||||||
IntrinsicFactoryContext intrinsicFactoryContext = new IntrinsicFactoryContext();
|
IntrinsicFactoryContext intrinsicFactoryContext = new IntrinsicFactoryContext();
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 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.model.expression.WasmExpression;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmInt32Constant;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmIntBinary;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmIntBinaryOperation;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmIntType;
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
import org.teavm.runtime.RuntimeClass;
|
||||||
|
|
||||||
|
public class RuntimeClassIntrinsic implements WasmIntrinsic {
|
||||||
|
@Override
|
||||||
|
public boolean isApplicable(MethodReference methodReference) {
|
||||||
|
if (!methodReference.getClassName().equals(RuntimeClass.class.getName())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (methodReference.getName()) {
|
||||||
|
case "pack":
|
||||||
|
case "unpack":
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WasmExpression apply(InvocationExpr invocation, WasmIntrinsicManager manager) {
|
||||||
|
switch (invocation.getMethod().getName()) {
|
||||||
|
case "pack":
|
||||||
|
return new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.SHR_UNSIGNED,
|
||||||
|
manager.generate(invocation.getArguments().get(0)), new WasmInt32Constant(3));
|
||||||
|
case "unpack":
|
||||||
|
return new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.SHL,
|
||||||
|
manager.generate(invocation.getArguments().get(0)), new WasmInt32Constant(3));
|
||||||
|
default:
|
||||||
|
throw new AssertionError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,7 +28,7 @@ public final class Allocator {
|
||||||
public static Address allocate(RuntimeClass tag) {
|
public static Address allocate(RuntimeClass tag) {
|
||||||
RuntimeObject object = GC.alloc(tag.size);
|
RuntimeObject object = GC.alloc(tag.size);
|
||||||
fillZero(object.toAddress(), tag.size);
|
fillZero(object.toAddress(), tag.size);
|
||||||
object.classReference = tag.toAddress().toInt() >> 3;
|
object.classReference = tag.pack();
|
||||||
return object.toAddress();
|
return object.toAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ public final class Allocator {
|
||||||
fillZero(result, sizeInBytes);
|
fillZero(result, sizeInBytes);
|
||||||
|
|
||||||
RuntimeArray array = result.toStructure();
|
RuntimeArray array = result.toStructure();
|
||||||
array.classReference = tag.toAddress().toInt() >> 3;
|
array.classReference = tag.pack();
|
||||||
array.size = size;
|
array.size = size;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -61,6 +61,12 @@ public class RuntimeClass extends RuntimeObject {
|
||||||
|
|
||||||
@Unmanaged
|
@Unmanaged
|
||||||
public static RuntimeClass getClass(RuntimeObject object) {
|
public static RuntimeClass getClass(RuntimeObject object) {
|
||||||
return Address.fromInt(object.classReference << 3).toStructure();
|
return unpack(object.classReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Unmanaged
|
||||||
|
public static native RuntimeClass unpack(int n);
|
||||||
|
|
||||||
|
@Unmanaged
|
||||||
|
public final native int pack();
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,8 @@ typedef struct JavaArray JavaArray;
|
||||||
typedef struct JavaClass JavaClass;
|
typedef struct JavaClass JavaClass;
|
||||||
typedef struct JavaString JavaString;
|
typedef struct JavaString JavaString;
|
||||||
|
|
||||||
#define PACK_CLASS(cls) ((int32_t) (((uintptr_t) (cls)) >> 3))
|
#define PACK_CLASS(cls) ((int32_t) ((uintptr_t) ((char*) (cls) - (char*) &TeaVM_beforeClasses) >> 3))
|
||||||
#define UNPACK_CLASS(cls) ((JavaClass *) (uintptr_t) (uint32_t) (uintptr_t) (((int64_t*) NULL) + cls))
|
#define UNPACK_CLASS(cls) ((JavaClass*) ((char*) &TeaVM_beforeClasses + ((cls) << 3)))
|
||||||
#define CLASS_OF(obj) (UNPACK_CLASS(((JavaObject*) (obj))->header))
|
#define CLASS_OF(obj) (UNPACK_CLASS(((JavaObject*) (obj))->header))
|
||||||
#define AS(ptr, type) ((type*) (ptr))
|
#define AS(ptr, type) ((type*) (ptr))
|
||||||
|
|
||||||
|
@ -65,10 +65,10 @@ static inline int32_t instanceof(void*, int32_t (*)(JavaClass*));
|
||||||
static inline void* checkcast(void*, int32_t (*)(JavaClass*));
|
static inline void* checkcast(void*, int32_t (*)(JavaClass*));
|
||||||
|
|
||||||
#define ALLOC_STACK(size) \
|
#define ALLOC_STACK(size) \
|
||||||
void* __shadowStack__[(size) + 3]; \
|
void* __shadowStack__[(size) + 3]; \
|
||||||
__shadowStack__[0] = stackTop; \
|
__shadowStack__[0] = stackTop; \
|
||||||
__shadowStack__[2] = (void*) size; \
|
__shadowStack__[2] = (void*) size; \
|
||||||
stackTop = __shadowStack__
|
stackTop = __shadowStack__
|
||||||
|
|
||||||
#define RELEASE_STACK stackTop = __shadowStack__[0]
|
#define RELEASE_STACK stackTop = __shadowStack__[0]
|
||||||
#define GC_ROOT(index, ptr) __shadowStack__[3 + (index)] = ptr
|
#define GC_ROOT(index, ptr) __shadowStack__[3 + (index)] = ptr
|
||||||
|
@ -106,6 +106,8 @@ static int32_t gc_regionSize = INT32_C(32768);
|
||||||
static int32_t gc_regionMaxCount = INT32_C(0);
|
static int32_t gc_regionMaxCount = INT32_C(0);
|
||||||
static int64_t gc_availableBytes = INT64_C(0);
|
static int64_t gc_availableBytes = INT64_C(0);
|
||||||
|
|
||||||
|
static char TeaVM_beforeClasses[128] = "TEAVM";
|
||||||
|
|
||||||
static double TeaVM_rand() {
|
static double TeaVM_rand() {
|
||||||
return rand() / ((double) RAND_MAX + 1);
|
return rand() / ((double) RAND_MAX + 1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user