diff --git a/core/src/main/java/org/teavm/backend/c/generate/CallSiteGenerator.java b/core/src/main/java/org/teavm/backend/c/generate/CallSiteGenerator.java index 923fdb610..f0db060a0 100644 --- a/core/src/main/java/org/teavm/backend/c/generate/CallSiteGenerator.java +++ b/core/src/main/java/org/teavm/backend/c/generate/CallSiteGenerator.java @@ -46,18 +46,20 @@ public class CallSiteGenerator { } public void generate(List callSites) { - writer.print("static ").print(callSiteLocationName).println(" callSiteLocations[];"); - writer.print("static ").print(exceptionHandlerName).println(" exceptionHandlers[];"); - + CodeWriter writerForLocations = writer.fragment(); generateCallSites(callSites); + + CodeWriter oldWriter = writer; + writer = writerForLocations; generateLocations(); generateHandlers(); + writer = oldWriter; } private void generateCallSites(List callSites) { String callSiteName = context.getNames().forClass(CALL_SITE); - writer.print("static ").print(callSiteName).print(" callSites[] = {").indent(); + writer.print("static ").print(callSiteName).print(" callSites[" + callSites.size() + "] = {").indent(); String handlerCountName = fieldName(CALL_SITE, "handlerCount"); String firstHandlerName = fieldName(CALL_SITE, "firstHandler"); String locationName = fieldName(CALL_SITE, "location"); @@ -97,7 +99,8 @@ public class CallSiteGenerator { } private void generateLocations() { - writer.print("static ").print(callSiteLocationName).print(" callSiteLocations[] = {").indent(); + writer.print("static ").print(callSiteLocationName).print(" callSiteLocations[" + locations.size() + "] = {") + .indent(); String fileNameName = fieldName(CALL_SITE_LOCATION, "fileName"); String classNameName = fieldName(CALL_SITE_LOCATION, "className"); @@ -128,7 +131,8 @@ public class CallSiteGenerator { } private void generateHandlers() { - writer.print("static ").print(exceptionHandlerName).print(" exceptionHandlers[] = {").indent(); + writer.print("static ").print(exceptionHandlerName).print(" exceptionHandlers[" + exceptionHandlers.size() + + "] = {").indent(); String idName = fieldName(EXCEPTION_HANDLER, "id"); String exceptionClassName = fieldName(EXCEPTION_HANDLER, "exceptionClass"); diff --git a/core/src/main/java/org/teavm/backend/c/generate/ClassGenerator.java b/core/src/main/java/org/teavm/backend/c/generate/ClassGenerator.java index 80eaf1b37..b96a09248 100644 --- a/core/src/main/java/org/teavm/backend/c/generate/ClassGenerator.java +++ b/core/src/main/java/org/teavm/backend/c/generate/ClassGenerator.java @@ -276,7 +276,7 @@ public class ClassGenerator { String name = context.getNames().forClassInstance(type); vtableForwardWriter.print("static ").print(structName).print(" ").print(name).println(";"); - vtableWriter.print("static ").print(structName).print(" ").print(name).println(" = {").indent(); + vtableWriter.print("static alignas(8) ").print(structName).print(" ").print(name).println(" = {").indent(); if (className != null) { vtableWriter.println(".parent = {").indent(); @@ -372,7 +372,6 @@ public class ClassGenerator { arrayTypeExpr = "NULL"; } - vtableWriter.println(".parent = {},"); vtableWriter.print(".").print(classFieldName("size")).print(" = ").print(sizeExpr).println(","); vtableWriter.print(".").print(classFieldName("flags")).println(" = " + flags + ","); vtableWriter.print(".").print(classFieldName("tag")).print(" = ").print(String.valueOf(tag)).println(","); diff --git a/core/src/main/java/org/teavm/backend/c/generate/NameProvider.java b/core/src/main/java/org/teavm/backend/c/generate/NameProvider.java index d2f20554c..e98251c71 100644 --- a/core/src/main/java/org/teavm/backend/c/generate/NameProvider.java +++ b/core/src/main/java/org/teavm/backend/c/generate/NameProvider.java @@ -116,7 +116,7 @@ public class NameProvider { return memberFieldNames.computeIfAbsent(field, k -> { Set occupied = occupiedClassNames.computeIfAbsent(k.getClassName(), c -> new HashSet<>(Arrays.asList("parent"))); - return pickUnoccupied(field.getFieldName(), occupied); + return pickUnoccupied(sanitize(field.getFieldName()), occupied); }); } @@ -154,7 +154,7 @@ public class NameProvider { StringBuilder sb = new StringBuilder(); suggestForClass(field.getClassName(), sb); sb.append('_'); - sb.append(field.getFieldName()); + sb.append(sanitize(field.getFieldName())); return sb.toString(); } diff --git a/core/src/main/java/org/teavm/backend/c/generate/StringPoolGenerator.java b/core/src/main/java/org/teavm/backend/c/generate/StringPoolGenerator.java index 009c0909e..0d8136500 100644 --- a/core/src/main/java/org/teavm/backend/c/generate/StringPoolGenerator.java +++ b/core/src/main/java/org/teavm/backend/c/generate/StringPoolGenerator.java @@ -35,9 +35,9 @@ public class StringPoolGenerator { private void generateStringArrays(List strings) { for (int i = 0; i < strings.size(); ++i) { String s = strings.get(i); - writer.print("static struct { JavaArray hdr; char16_t data[" + s.length() + 1 + "]; } str_array_" + i) + writer.print("static struct { JavaArray hdr; char16_t data[" + (s.length() + 1) + "]; } str_array_" + i) .println(" = {").indent(); - writer.println(".hdr = { .parent = {}, .size = " + s.length() + "},"); + writer.println(".hdr = { .size = " + s.length() + "},"); writer.print(".data = "); generateStringLiteral(s); writer.println(); @@ -53,7 +53,6 @@ public class StringPoolGenerator { writer.println("static JavaString stringPool[" + strings.size() + "] = {").indent(); for (int i = 0; i < strings.size(); ++i) { writer.println("{").indent(); - writer.println(".parent = {},"); writer.println("." + charactersName + " = (JavaArray*) &str_array_" + i + ","); writer.println("." + hashCodeName + " = INT32_C(" + strings.get(i).hashCode() + ")"); writer.outdent().print("}"); diff --git a/core/src/main/java/org/teavm/runtime/ExceptionHandling.java b/core/src/main/java/org/teavm/runtime/ExceptionHandling.java index d6f587070..98b54f7a1 100644 --- a/core/src/main/java/org/teavm/runtime/ExceptionHandling.java +++ b/core/src/main/java/org/teavm/runtime/ExceptionHandling.java @@ -30,7 +30,7 @@ public final class ExceptionHandling { private static Throwable thrownException; - @Export(name = "sys$catchException") + @Export(name = "sys_catchException") @Unmanaged public static Throwable catchException() { Throwable exception = thrownException; diff --git a/core/src/main/resources/org/teavm/backend/c/runtime.c b/core/src/main/resources/org/teavm/backend/c/runtime.c index e30d26f26..e73cfaf24 100644 --- a/core/src/main/resources/org/teavm/backend/c/runtime.c +++ b/core/src/main/resources/org/teavm/backend/c/runtime.c @@ -3,10 +3,19 @@ #include #include #include -#include #include #include + +#ifdef __GNUC__ +#include +#include #include +#endif + +#ifdef _MSC_VER +#define alignas(x) +#include +#endif struct JavaObject; struct JavaArray; @@ -78,7 +87,8 @@ 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) { +#ifdef __GNUC__ +static void initHeap(int64_t heapSize) { long workSize = heapSize / 16; long regionsSize = (long) (heapSize / gc_regionSize); @@ -116,4 +126,68 @@ static int64_t currentTimeMillis() { clock_gettime(CLOCK_REALTIME, &time); return time.tv_sec * 1000 + (int64_t) round(time.tv_nsec / 1000000); -} \ No newline at end of file +} +#endif + +#ifdef _MSC_VER +static void initHeap(int64_t heapSize) { + long workSize = heapSize / 16; + long regionsSize = (long) (heapSize / gc_regionSize); + + SYSTEM_INFO systemInfo; + GetSystemInfo(&systemInfo); + long pageSize = systemInfo.dwPageSize; + 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 = VirtualAlloc( + NULL, + heapPages, + MEM_RESERVE | MEM_COMMIT, + PAGE_READWRITE + ); + gc_gcStorageAddress = VirtualAlloc( + NULL, + workPages, + MEM_RESERVE | MEM_COMMIT, + PAGE_READWRITE + ); + gc_regionsAddress = VirtualAlloc( + NULL, + regionsPages, + MEM_RESERVE | MEM_COMMIT, + PAGE_READWRITE + ); + + gc_gcStorageSize = (int) workSize; + gc_regionMaxCount = regionsSize; + gc_availableBytes = heapSize; +} + +static SYSTEMTIME unixEpochStart = { + .wYear = 1970, + .wMonth = 1, + .wDayOfWeek = 3, + .wDay = 1, + .wHour = 0, + .wMinute = 0, + .wSecond = 0, + .wMilliseconds = 0 +}; + +static int64_t currentTimeMillis() { + SYSTEMTIME time; + FILETIME fileTime; + GetSystemTime(&time); + SystemTimeToFileTime(&time, &fileTime); + + FILETIME fileTimeStart; + SystemTimeToFileTime(&unixEpochStart, &fileTimeStart); + + uint64_t current = fileTime.dwLowDateTime | ((uint64_t) fileTime.dwHighDateTime << 32); + uint64_t start = fileTimeStart.dwLowDateTime | ((uint64_t) fileTimeStart.dwHighDateTime << 32); + + return (int64_t) ((current - start) / 10000); +} +#endif