statementMap = new HashMap<>();
@@ -876,7 +874,7 @@ public class AstIO {
return expr;
}
case 12: {
- UnwrapArrayExpr expr = new UnwrapArrayExpr(arrayElementTypes[input.readByte()]);
+ UnwrapArrayExpr expr = new UnwrapArrayExpr(ArrayType.values()[input.readByte()]);
expr.setArray(readExpr(input));
return expr;
}
diff --git a/core/src/main/java/org/teavm/model/lowlevel/ClassInitializerTransformer.java b/core/src/main/java/org/teavm/model/lowlevel/ClassInitializerTransformer.java
index 2127247f0..02e782487 100644
--- a/core/src/main/java/org/teavm/model/lowlevel/ClassInitializerTransformer.java
+++ b/core/src/main/java/org/teavm/model/lowlevel/ClassInitializerTransformer.java
@@ -99,7 +99,7 @@ public class ClassInitializerTransformer {
checkInitialized.setReceiver(initializedVariable);
block.add(checkInitialized);
- BranchingInstruction branching = new BranchingInstruction(BranchingCondition.EQUAL);
+ BranchingInstruction branching = new BranchingInstruction(BranchingCondition.NOT_EQUAL);
branching.setOperand(initializedVariable);
branching.setConsequent(continueBlock);
branching.setAlternative(initBlock);
diff --git a/core/src/main/java/org/teavm/model/lowlevel/ManagedMethodRepository.java b/core/src/main/java/org/teavm/model/lowlevel/ManagedMethodRepository.java
index 2f8c993be..59af9ab65 100644
--- a/core/src/main/java/org/teavm/model/lowlevel/ManagedMethodRepository.java
+++ b/core/src/main/java/org/teavm/model/lowlevel/ManagedMethodRepository.java
@@ -36,14 +36,15 @@ public class ManagedMethodRepository {
}
private boolean computeIsManaged(MethodReference methodReference) {
- ClassReader cls = classSource.get(methodReference.getClassName());
- if (cls == null) {
+ MethodReader method = classSource.resolve(methodReference);
+ if (method == null) {
return true;
}
+
+ ClassReader cls = classSource.get(method.getOwnerName());
if (cls.getAnnotations().get(Unmanaged.class.getName()) != null) {
return false;
}
- MethodReader method = cls.getMethod(methodReference.getDescriptor());
return method == null || method.getAnnotations().get(Unmanaged.class.getName()) == null;
}
}
diff --git a/core/src/main/java/org/teavm/backend/wasm/patches/ClassPatch.java b/core/src/main/java/org/teavm/model/transformation/ClassPatch.java
similarity index 97%
rename from core/src/main/java/org/teavm/backend/wasm/patches/ClassPatch.java
rename to core/src/main/java/org/teavm/model/transformation/ClassPatch.java
index fc691beba..3f266795e 100644
--- a/core/src/main/java/org/teavm/backend/wasm/patches/ClassPatch.java
+++ b/core/src/main/java/org/teavm/model/transformation/ClassPatch.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Alexey Andreev.
+ * 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.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.teavm.backend.wasm.patches;
+package org.teavm.model.transformation;
import org.teavm.diagnostics.Diagnostics;
import org.teavm.model.BasicBlock;
diff --git a/core/src/main/java/org/teavm/runtime/Allocator.java b/core/src/main/java/org/teavm/runtime/Allocator.java
index 353014a5b..af7c9314b 100644
--- a/core/src/main/java/org/teavm/runtime/Allocator.java
+++ b/core/src/main/java/org/teavm/runtime/Allocator.java
@@ -33,10 +33,10 @@ public final class Allocator {
}
public static Address allocateArray(RuntimeClass tag, int size) {
- int itemSize = (tag.itemType.flags & RuntimeClass.PRIMITIVE) != 0 ? tag.itemType.size : 4;
+ int itemSize = (tag.itemType.flags & RuntimeClass.PRIMITIVE) != 0 ? tag.itemType.size : Address.sizeOf();
int sizeInBytes = Address.align(Address.fromInt(Structure.sizeOf(RuntimeArray.class)), itemSize).toInt();
sizeInBytes += itemSize * size;
- sizeInBytes = Address.align(Address.fromInt(sizeInBytes), 4).toInt();
+ sizeInBytes = Address.align(Address.fromInt(sizeInBytes), Address.sizeOf()).toInt();
Address result = GC.alloc(sizeInBytes).toAddress();
fillZero(result, sizeInBytes);
@@ -47,6 +47,7 @@ public final class Allocator {
return result;
}
+ @Unmanaged
public static RuntimeArray allocateMultiArray(RuntimeClass tag, Address dimensions, int dimensionCount) {
int size = dimensions.getInt();
RuntimeArray array = allocateArray(tag, dimensions.getInt()).toStructure();
diff --git a/core/src/main/java/org/teavm/runtime/CallSiteLocation.java b/core/src/main/java/org/teavm/runtime/CallSiteLocation.java
index ec133d90f..c0a505cc5 100644
--- a/core/src/main/java/org/teavm/runtime/CallSiteLocation.java
+++ b/core/src/main/java/org/teavm/runtime/CallSiteLocation.java
@@ -15,8 +15,12 @@
*/
package org.teavm.runtime;
+import org.teavm.interop.StaticInit;
import org.teavm.interop.Structure;
+import org.teavm.interop.Unmanaged;
+@Unmanaged
+@StaticInit
public class CallSiteLocation extends Structure {
public String fileName;
public String className;
diff --git a/core/src/main/java/org/teavm/runtime/ExceptionHandling.java b/core/src/main/java/org/teavm/runtime/ExceptionHandling.java
index 0d9a11b8b..d6f587070 100644
--- a/core/src/main/java/org/teavm/runtime/ExceptionHandling.java
+++ b/core/src/main/java/org/teavm/runtime/ExceptionHandling.java
@@ -65,6 +65,11 @@ public final class ExceptionHandling {
}
}
+ @Unmanaged
+ public static void throwClassCastException() {
+ throw new ClassCastException();
+ }
+
@Unmanaged
public static int callStackSize() {
Address stackFrame = ShadowStack.getStackTop();
@@ -77,8 +82,8 @@ public final class ExceptionHandling {
}
@Unmanaged
- public static void fillStackTrace(StackTraceElement[] target, int skip) {
- Address stackFrame = ShadowStack.getNextStackFrame(ShadowStack.getNextStackFrame(ShadowStack.getStackTop()));
+ public static void fillStackTrace(StackTraceElement[] target) {
+ Address stackFrame = ShadowStack.getNextStackFrame(ShadowStack.getStackTop());
int index = 0;
while (stackFrame != null && index < target.length) {
int callSiteId = ShadowStack.getCallSiteId(stackFrame);
@@ -87,12 +92,7 @@ public final class ExceptionHandling {
StackTraceElement element = createElement(location != null ? location.className : "",
location != null ? location.methodName : "", location != null ? location.fileName : null,
location != null ? location.lineNumber : -1);
- if (skip > 0) {
- skip--;
- } else {
- target[index++] = element;
- }
-
+ target[index++] = element;
stackFrame = ShadowStack.getNextStackFrame(stackFrame);
}
}
diff --git a/core/src/main/java/org/teavm/runtime/GC.java b/core/src/main/java/org/teavm/runtime/GC.java
index 91013dd3e..658b5c1f4 100644
--- a/core/src/main/java/org/teavm/runtime/GC.java
+++ b/core/src/main/java/org/teavm/runtime/GC.java
@@ -63,7 +63,7 @@ public final class GC {
public static RuntimeObject alloc(int size) {
FreeChunk current = currentChunk;
- Address next = currentChunk.toAddress().add(size);
+ Address next = current.toAddress().add(size);
if (!next.add(Structure.sizeOf(FreeChunk.class)).isLessThan(currentChunkLimit)) {
getAvailableChunk(size);
current = currentChunk;
@@ -125,7 +125,7 @@ public final class GC {
Address staticRoots = Mutator.getStaticGCRoots();
int staticCount = staticRoots.getInt();
- staticRoots = staticRoots.add(8);
+ staticRoots = staticRoots.add(Address.sizeOf());
while (staticCount-- > 0) {
RuntimeObject object = staticRoots.getAddress().getAddress().toStructure();
if (object != null) {
@@ -187,13 +187,13 @@ public final class GC {
} else {
if ((cls.itemType.flags & RuntimeClass.PRIMITIVE) == 0) {
RuntimeArray array = (RuntimeArray) object;
- Address base = Address.align(array.toAddress().add(RuntimeArray.class, 1), 4);
+ Address base = Address.align(array.toAddress().add(RuntimeArray.class, 1), Address.sizeOf());
for (int i = 0; i < array.size; ++i) {
RuntimeObject reference = base.getAddress().toStructure();
if (reference != null && !isMarked(reference)) {
MarkQueue.enqueue(reference);
}
- base = base.add(4);
+ base = base.add(Address.sizeOf());
}
}
}
@@ -248,6 +248,7 @@ public final class GC {
}
} else {
if (lastFreeSpace != null) {
+ lastFreeSpace.classReference = 0;
lastFreeSpace.size = (int) (object.toAddress().toLong() - lastFreeSpace.toAddress().toLong());
freeChunkPtr.value = lastFreeSpace;
freeChunkPtr = Structure.add(FreeChunkHolder.class, freeChunkPtr, 1);
@@ -266,6 +267,7 @@ public final class GC {
if (lastFreeSpace != null) {
int freeSize = (int) (object.toAddress().toLong() - lastFreeSpace.toAddress().toLong());
+ lastFreeSpace.classReference = 0;
lastFreeSpace.size = freeSize;
freeChunkPtr.value = lastFreeSpace;
freeChunkPtr = Structure.add(FreeChunkHolder.class, freeChunkPtr, 1);
@@ -348,7 +350,7 @@ public final class GC {
Address address = Address.fromInt(Structure.sizeOf(RuntimeArray.class));
address = Address.align(address, itemSize);
address = address.add(itemSize * array.size);
- address = Address.align(address, 4);
+ address = Address.align(address, Address.sizeOf());
return address.toInt();
}
}
diff --git a/core/src/main/java/org/teavm/runtime/RuntimeArray.java b/core/src/main/java/org/teavm/runtime/RuntimeArray.java
index f06d15d85..b2ac7533a 100644
--- a/core/src/main/java/org/teavm/runtime/RuntimeArray.java
+++ b/core/src/main/java/org/teavm/runtime/RuntimeArray.java
@@ -15,6 +15,6 @@
*/
package org.teavm.runtime;
-public class RuntimeArray extends RuntimeJavaObject {
+public class RuntimeArray extends RuntimeObject {
public int size;
}
diff --git a/core/src/main/java/org/teavm/runtime/RuntimeClass.java b/core/src/main/java/org/teavm/runtime/RuntimeClass.java
index 5a44da28b..5bab39fd2 100644
--- a/core/src/main/java/org/teavm/runtime/RuntimeClass.java
+++ b/core/src/main/java/org/teavm/runtime/RuntimeClass.java
@@ -18,7 +18,7 @@ package org.teavm.runtime;
import org.teavm.interop.Address;
import org.teavm.interop.Unmanaged;
-public class RuntimeClass extends RuntimeJavaObject {
+public class RuntimeClass extends RuntimeObject {
public static final int INITIALIZED = 1;
public static final int PRIMITIVE = 2;
public static final int ENUM = 4;
@@ -27,7 +27,7 @@ public class RuntimeClass extends RuntimeJavaObject {
public int flags;
public int tag;
public int canary;
- public RuntimeJavaObject name;
+ public RuntimeObject name;
public RuntimeClass itemType;
public RuntimeClass arrayType;
public IsSupertypeFunction isSupertypeOf;
diff --git a/core/src/main/java/org/teavm/runtime/RuntimeObject.java b/core/src/main/java/org/teavm/runtime/RuntimeObject.java
index 882a53108..1ae4bf34f 100644
--- a/core/src/main/java/org/teavm/runtime/RuntimeObject.java
+++ b/core/src/main/java/org/teavm/runtime/RuntimeObject.java
@@ -15,11 +15,15 @@
*/
package org.teavm.runtime;
+import org.teavm.interop.StaticInit;
import org.teavm.interop.Structure;
+@StaticInit
public class RuntimeObject extends Structure {
public static final int GC_MARKED = 0x80000000;
- public static final int MONITOR_EXISTS = 0x20000000;
+
+ public static int nextId;
public int classReference;
+ public int hashCode;
}
diff --git a/core/src/main/java/org/teavm/vm/TeaVM.java b/core/src/main/java/org/teavm/vm/TeaVM.java
index 5de0c0450..15839d29e 100644
--- a/core/src/main/java/org/teavm/vm/TeaVM.java
+++ b/core/src/main/java/org/teavm/vm/TeaVM.java
@@ -236,6 +236,11 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
return diagnostics;
}
+ @Override
+ public String[] getPlatformTags() {
+ return target.getPlatformTags();
+ }
+
/**
* Adds an entry point. TeaVM guarantees, that all methods that are required by the entry point
* will be available at run-time in browser. Also you need to specify for each parameter of entry point
diff --git a/core/src/main/java/org/teavm/vm/TeaVMTarget.java b/core/src/main/java/org/teavm/vm/TeaVMTarget.java
index 7214fcb72..94ddddedc 100644
--- a/core/src/main/java/org/teavm/vm/TeaVMTarget.java
+++ b/core/src/main/java/org/teavm/vm/TeaVMTarget.java
@@ -42,4 +42,6 @@ public interface TeaVMTarget {
void afterOptimizations(Program program, MethodReader method, ListableClassReaderSource classSource);
void emit(ListableClassHolderSource classes, BuildTarget buildTarget, String outputName) throws IOException;
+
+ String[] getPlatformTags();
}
diff --git a/core/src/main/java/org/teavm/vm/spi/TeaVMHost.java b/core/src/main/java/org/teavm/vm/spi/TeaVMHost.java
index 52cfb86a7..80eca48dd 100644
--- a/core/src/main/java/org/teavm/vm/spi/TeaVMHost.java
+++ b/core/src/main/java/org/teavm/vm/spi/TeaVMHost.java
@@ -58,4 +58,6 @@ public interface TeaVMHost {
* visible to VM.
*/
Properties getProperties();
+
+ String[] getPlatformTags();
}
diff --git a/core/src/main/resources/org/teavm/backend/c/runtime-epilogue.c b/core/src/main/resources/org/teavm/backend/c/runtime-epilogue.c
new file mode 100644
index 000000000..6f2b4cdfc
--- /dev/null
+++ b/core/src/main/resources/org/teavm/backend/c/runtime-epilogue.c
@@ -0,0 +1,7 @@
+static inline int32_t instanceof(void* obj, int32_t (*cls)(JavaClass*)) {
+ return obj != NULL && cls(CLASS_OF(obj));
+}
+
+static inline void* checkcast(void* obj, int32_t (*cls)(JavaClass*)) {
+ return obj == NULL || cls(CLASS_OF(obj)) ? obj : throwClassCastException();
+}
\ No newline at end of file
diff --git a/core/src/main/resources/org/teavm/backend/c/runtime.c b/core/src/main/resources/org/teavm/backend/c/runtime.c
new file mode 100644
index 000000000..dbade4f91
--- /dev/null
+++ b/core/src/main/resources/org/teavm/backend/c/runtime.c
@@ -0,0 +1,119 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+struct JavaObject;
+struct JavaArray;
+struct JavaClass;
+struct JavaString;
+typedef struct JavaObject JavaObject;
+typedef struct JavaArray JavaArray;
+typedef struct JavaClass JavaClass;
+typedef struct JavaString JavaString;
+
+#define PACK_CLASS(cls) ((int32_t) (((uintptr_t) (cls)) >> 3))
+#define UNPACK_CLASS(cls) ((JavaClass *) (uintptr_t) (uint32_t) (uintptr_t) (((int64_t*) NULL) + cls))
+#define CLASS_OF(obj) (UNPACK_CLASS(((JavaObject*) (obj))->header))
+#define AS(ptr, type) ((type*) (ptr))
+
+#define VTABLE(obj, type) (AS(CLASS_OF(obj), type))
+#define METHOD(obj, type, method) (VTABLE(obj, type)->method)
+#define FIELD(ptr, type, name) (AS(ptr, type)->name)
+
+#define TO_BYTE(i) ((((i) << 24) >> 24))
+#define TO_SHORT(i) ((((i) << 16) >> 16))
+#define TO_CHAR(i) ((char16_t) (i))
+
+static inline int32_t compare_i32(int32_t a, int32_t b) {
+ return a > b ? INT32_C(1) : a < b ? INT32_C(-1) : INT32_C(0);
+}
+static inline int32_t compare_i64(int64_t a, int64_t b) {
+ return a > b ? INT32_C(1) : a < b ? INT32_C(-1) : INT32_C(0);
+}
+static inline int32_t compare_float(float a, float b) {
+ return a > b ? INT32_C(1) : a < b ? INT32_C(-1) : INT32_C(0);
+}
+static inline int32_t compare_double(double a, double b) {
+ return a > b ? INT32_C(1) : a < b ? INT32_C(-1) : INT32_C(0);
+}
+
+#define ALIGN(addr, alignment) ((void*) (((uintptr_t) (addr) + ((alignment) - 1)) / (alignment) * (alignment)))
+#define ARRAY_LENGTH(array) (((JavaArray*) (array))->size)
+#define ARRAY_DATA(array, type) ((type*) ALIGN((((JavaArray*) (array)) + 1), sizeof(type)))
+#define ARRAY_AT(array, type, index) (((type*) ARRAY_DATA(array, type))[index])
+
+static void* throwClassCastException();
+static inline int32_t instanceof(void*, int32_t (*)(JavaClass*));
+static inline void* checkcast(void*, int32_t (*)(JavaClass*));
+
+#define ALLOC_STACK(size) \
+ void* __shadowStack__[(size) + 3]; \
+ __shadowStack__[0] = stackTop; \
+ __shadowStack__[2] = (void*) size; \
+ stackTop = __shadowStack__
+
+#define RELEASE_STACK stackTop = __shadowStack__[0]
+#define GC_ROOT(index, ptr) __shadowStack__[3 + (index)] = ptr
+#define GC_ROOT_RELEASE(index) __shadowStack__[3 + (index)] = NULL
+#define CALL_SITE(id) (__shadowStack__[1] = (void*) (id))
+#define EXCEPTION_HANDLER ((int32_t) (intptr_t) (__shadowStack__[1]))
+#define SET_EXCEPTION_HANDLER(frame, id) (((void**) (frame))[1] = (void*) (intptr_t) (id))
+
+#define ADDRESS_ADD(address, offset) ((char *) (address) + (offset))
+#define STRUCTURE_ADD(structure, address, offset) (((structure*) (address)) + offset)
+
+static void** stackTop;
+
+static void* gc_gcStorageAddress = NULL;
+static int32_t gc_gcStorageSize = INT32_C(0);
+static void* gc_heapAddress = NULL;
+static void* gc_regionsAddress = NULL;
+static int32_t gc_regionSize = INT32_C(32768);
+static int32_t gc_regionMaxCount = INT32_C(0);
+static int64_t gc_availableBytes = INT64_C(0);
+
+static void initHeap(long heapSize) {
+ long workSize = heapSize / 16;
+ long regionsSize = (long) (heapSize / gc_regionSize);
+
+ long pageSize = sysconf(_SC_PAGE_SIZE);
+ int heapPages = (int) ((heapSize + pageSize + 1) / pageSize * pageSize);
+ int workPages = (int) ((workSize + pageSize + 1) / pageSize * pageSize);
+ int regionsPages = (int) ((regionsSize * 2 + pageSize + 1) / pageSize * pageSize);
+
+ gc_heapAddress = mmap(
+ NULL,
+ heapPages,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS,
+ 0, 0);
+ gc_gcStorageAddress = mmap(
+ NULL,
+ workPages,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS,
+ 0, 0);
+ gc_regionsAddress = mmap(
+ NULL,
+ regionsPages,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS,
+ 0, 0);
+
+ gc_gcStorageSize = (int) workSize;
+ gc_regionMaxCount = regionsSize;
+ gc_availableBytes = heapSize;
+}
+
+static int64_t currentTimeMillis() {
+ struct timespec time;
+ clock_gettime(CLOCK_REALTIME, &time);
+
+ return time.tv_sec * 1000 + round(time.tv_nsec / 1000000);
+}
\ No newline at end of file
diff --git a/interop/core/src/main/java/org/teavm/interop/PlatformMarker.java b/interop/core/src/main/java/org/teavm/interop/PlatformMarker.java
index 9374bd93b..f3a454e76 100644
--- a/interop/core/src/main/java/org/teavm/interop/PlatformMarker.java
+++ b/interop/core/src/main/java/org/teavm/interop/PlatformMarker.java
@@ -23,4 +23,5 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.METHOD })
public @interface PlatformMarker {
+ String value() default "";
}
diff --git a/interop/core/src/main/java/org/teavm/interop/PlatformMarkers.java b/interop/core/src/main/java/org/teavm/interop/PlatformMarkers.java
new file mode 100644
index 000000000..c53ef5f55
--- /dev/null
+++ b/interop/core/src/main/java/org/teavm/interop/PlatformMarkers.java
@@ -0,0 +1,26 @@
+/*
+ * 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.interop;
+
+public final class PlatformMarkers {
+ private PlatformMarkers() {
+ }
+
+ public static final String JAVASCRIPT = "javascript";
+ public static final String WEBASSEMBLY = "webassembly";
+ public static final String C = "c";
+ public static final String LOW_LEVEL = "low_level";
+}
diff --git a/platform/src/main/java/org/teavm/platform/Platform.java b/platform/src/main/java/org/teavm/platform/Platform.java
index 4e9eca8e9..f8955a524 100644
--- a/platform/src/main/java/org/teavm/platform/Platform.java
+++ b/platform/src/main/java/org/teavm/platform/Platform.java
@@ -37,6 +37,7 @@ public final class Platform {
private static boolean newInstancePrepared;
@InjectedBy(PlatformGenerator.class)
+ @Unmanaged
public static native PlatformObject getPlatformObject(Object obj);
@GeneratedBy(PlatformGenerator.class)
@@ -80,6 +81,7 @@ public final class Platform {
@InjectedBy(PlatformGenerator.class)
@PluggableDependency(PlatformGenerator.class)
+ @Unmanaged
public static native Class> asJavaClass(PlatformObject obj);
public static PlatformConsole getConsole() {
@@ -213,6 +215,7 @@ public final class Platform {
}
@DelegateTo("getArrayItemLowLevel")
+ @Unmanaged
public static PlatformClass getArrayItem(PlatformClass cls) {
return cls.getMetadata().getArrayItem();
}
diff --git a/platform/src/main/java/org/teavm/platform/PlatformClass.java b/platform/src/main/java/org/teavm/platform/PlatformClass.java
index b469b87cb..42b112fcf 100644
--- a/platform/src/main/java/org/teavm/platform/PlatformClass.java
+++ b/platform/src/main/java/org/teavm/platform/PlatformClass.java
@@ -15,16 +15,20 @@
*/
package org.teavm.platform;
+import org.teavm.interop.Unmanaged;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
public interface PlatformClass extends JSObject {
@JSProperty("$meta")
+ @Unmanaged
PlatformClassMetadata getMetadata();
@JSProperty("classObject")
+ @Unmanaged
void setJavaClass(PlatformObject obj);
@JSProperty("classObject")
+ @Unmanaged
PlatformObject getJavaClass();
}
diff --git a/platform/src/main/java/org/teavm/platform/PlatformObject.java b/platform/src/main/java/org/teavm/platform/PlatformObject.java
index fd5ccca58..5da60dc2e 100644
--- a/platform/src/main/java/org/teavm/platform/PlatformObject.java
+++ b/platform/src/main/java/org/teavm/platform/PlatformObject.java
@@ -15,16 +15,20 @@
*/
package org.teavm.platform;
+import org.teavm.interop.Unmanaged;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
public interface PlatformObject extends JSObject {
@JSProperty("constructor")
+ @Unmanaged
PlatformClass getPlatformClass();
@JSProperty("$id$")
+ @Unmanaged
int getId();
@JSProperty("$id$")
+ @Unmanaged
void setId(int id);
}
diff --git a/tools/cli/src/main/java/org/teavm/cli/TeaVMRunner.java b/tools/cli/src/main/java/org/teavm/cli/TeaVMRunner.java
index 18416acf1..3780452c6 100644
--- a/tools/cli/src/main/java/org/teavm/cli/TeaVMRunner.java
+++ b/tools/cli/src/main/java/org/teavm/cli/TeaVMRunner.java
@@ -74,7 +74,7 @@ public final class TeaVMRunner {
options.addOption(OptionBuilder
.withArgName("target")
.hasArg()
- .withDescription("target type (javascript/js, webassembly/wasm)")
+ .withDescription("target type (javascript/js, webassembly/wasm, C)")
.create('t'));
options.addOption(OptionBuilder
.withArgName("directory")
@@ -141,7 +141,13 @@ public final class TeaVMRunner {
.withLongOpt("wasm-version")
.withArgName("version")
.hasArg()
- .withDescription("WebAssembly binary version (11, 12, 13)")
+ .withDescription("WebAssembly binary version (currently, only 1 is supported)")
+ .create());
+ options.addOption(OptionBuilder
+ .withLongOpt("min-heap")
+ .withArgName("size")
+ .hasArg()
+ .withDescription("Minimum heap size in bytes (for C and WebAssembly)")
.create());
}
@@ -179,6 +185,7 @@ public final class TeaVMRunner {
parseIncrementalOptions();
parseJavaScriptOptions();
parseWasmOptions();
+ parseHeap();
interactive = commandLine.hasOption('w');
@@ -202,6 +209,9 @@ public final class TeaVMRunner {
case "wasm":
tool.setTargetType(TeaVMTargetType.WEBASSEMBLY);
break;
+ case "c":
+ tool.setTargetType(TeaVMTargetType.C);
+ break;
}
}
}
@@ -318,6 +328,20 @@ public final class TeaVMRunner {
}
}
+ private void parseHeap() {
+ if (commandLine.hasOption("min-heap")) {
+ int size;
+ try {
+ size = Integer.parseInt(commandLine.getOptionValue("min-heap"));
+ } catch (NumberFormatException e) {
+ System.err.print("Wrong heap size");
+ printUsage();
+ return;
+ }
+ tool.setMinHeapSize(size);
+ }
+ }
+
private void setUp() {
tool.setLog(log);
tool.getProperties().putAll(System.getProperties());
diff --git a/tools/core/src/main/java/org/teavm/tooling/TeaVMTargetType.java b/tools/core/src/main/java/org/teavm/tooling/TeaVMTargetType.java
index db950d0be..77d816ca7 100644
--- a/tools/core/src/main/java/org/teavm/tooling/TeaVMTargetType.java
+++ b/tools/core/src/main/java/org/teavm/tooling/TeaVMTargetType.java
@@ -17,5 +17,6 @@ package org.teavm.tooling;
public enum TeaVMTargetType {
JAVASCRIPT,
- WEBASSEMBLY
+ WEBASSEMBLY,
+ C
}
diff --git a/tools/core/src/main/java/org/teavm/tooling/TeaVMTool.java b/tools/core/src/main/java/org/teavm/tooling/TeaVMTool.java
index 2f3890e33..e6e6f3b29 100644
--- a/tools/core/src/main/java/org/teavm/tooling/TeaVMTool.java
+++ b/tools/core/src/main/java/org/teavm/tooling/TeaVMTool.java
@@ -33,6 +33,7 @@ import java.util.List;
import java.util.Properties;
import java.util.Set;
import org.apache.commons.io.IOUtils;
+import org.teavm.backend.c.CTarget;
import org.teavm.backend.javascript.JavaScriptTarget;
import org.teavm.backend.javascript.rendering.RenderingManager;
import org.teavm.backend.wasm.WasmTarget;
@@ -97,7 +98,9 @@ public class TeaVMTool implements BaseTeaVMTool {
private JavaScriptTarget javaScriptTarget;
private WasmTarget webAssemblyTarget;
private WasmBinaryVersion wasmVersion = WasmBinaryVersion.V_0x1;
+ private CTarget cTarget;
private Set generatedFiles = new HashSet<>();
+ private int minHeapSize = 32 * (1 << 20);
public File getTargetDirectory() {
return targetDirectory;
@@ -224,6 +227,10 @@ public class TeaVMTool implements BaseTeaVMTool {
this.optimizationLevel = optimizationLevel;
}
+ public void setMinHeapSize(int minHeapSize) {
+ this.minHeapSize = minHeapSize;
+ }
+
public ClassLoader getClassLoader() {
return classLoader;
}
@@ -308,6 +315,8 @@ public class TeaVMTool implements BaseTeaVMTool {
return prepareJavaScriptTarget();
case WEBASSEMBLY:
return prepareWebAssemblyTarget();
+ case C:
+ return prepareCTarget();
}
throw new IllegalStateException("Unknown target type: " + targetType);
}
@@ -333,9 +342,16 @@ public class TeaVMTool implements BaseTeaVMTool {
webAssemblyTarget.setCEmitted(debugInformationGenerated);
webAssemblyTarget.setWastEmitted(debugInformationGenerated);
webAssemblyTarget.setVersion(wasmVersion);
+ webAssemblyTarget.setMinHeapSize(minHeapSize);
return webAssemblyTarget;
}
+ private CTarget prepareCTarget() {
+ cTarget = new CTarget();
+ cTarget.setMinHeapSize(minHeapSize);
+ return cTarget;
+ }
+
public void generate() throws TeaVMToolException {
try {
cancelled = false;
@@ -449,6 +465,8 @@ public class TeaVMTool implements BaseTeaVMTool {
return "classes.js";
case WEBASSEMBLY:
return "classes.wasm";
+ case C:
+ return "classes.c";
default:
return "classes";
}