diff --git a/classlib/src/main/java/org/teavm/classlib/java/util/TDate.java b/classlib/src/main/java/org/teavm/classlib/java/util/TDate.java index bba2f652c..f7459572c 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/util/TDate.java +++ b/classlib/src/main/java/org/teavm/classlib/java/util/TDate.java @@ -64,6 +64,8 @@ public class TDate implements TComparable { public TDate(int year, int month, int date, int hrs, int min, int sec) { this(PlatformDetector.isLowLevel() ? initDateLowLevel(year, month, date, hrs, min, sec) + : PlatformDetector.isWebAssemblyGC() + ? (long) initDateWasmGC(year + 1900, month, date, hrs, min, sec) : (long) new JSDate(year, month, date, hrs, min, sec).getTime()); if (!PlatformDetector.isLowLevel()) { setYear(year); @@ -77,6 +79,10 @@ public class TDate implements TComparable { @UnsupportedOn(Platforms.WEBASSEMBLY) private static native long initDateLowLevel(int year, int month, int date, int hrs, int min, int sec); + @Import(name = "create", module = "teavmDate") + @NoSideEffects + private static native double initDateWasmGC(int year, int month, int date, int hrs, int min, int sec); + public TDate(String s) { this(parse(s)); } @@ -90,6 +96,8 @@ public class TDate implements TComparable { public static long UTC(int year, int month, int date, int hrs, int min, int sec) { if (PlatformDetector.isLowLevel()) { return initUtcDateLowLevel(year, month, date, hrs, min, sec); + } else if (PlatformDetector.isWebAssemblyGC()) { + return (long) initUtcDateWasmGC(year + 1900, month, date, hrs, min, sec); } else { return (long) JSDate.UTC(year + 1900, month, date, hrs, min, sec); } @@ -102,6 +110,9 @@ public class TDate implements TComparable { @UnsupportedOn(Platforms.WEBASSEMBLY) private static native long initUtcDateLowLevel(int year, int month, int date, int hrs, int min, int sec); + @Import(name = "createFromUTC", module = "teavmDate") + private static native double initUtcDateWasmGC(int year, int month, int date, int hrs, int min, int sec); + @Deprecated public static long parse(String s) { if (PlatformDetector.isLowLevel()) { @@ -126,10 +137,15 @@ public class TDate implements TComparable { public int getYear() { if (PlatformDetector.isLowLevel()) { return getYearLowLevel(value); + } else if (PlatformDetector.isWebAssemblyGC()) { + return getYearWasmGC(value) - 1900; } return new JSDate(value).getFullYear() - 1900; } + @Import(name = "getYear", module = "teavmDate") + private static native int getYearWasmGC(double timestamp); + @Import(name = "teavm_date_getYear") @NoSideEffects @Unmanaged @@ -142,12 +158,18 @@ public class TDate implements TComparable { if (PlatformDetector.isLowLevel()) { value = setYearLowLevel(value, year); return; + } else if (PlatformDetector.isWebAssemblyGC()) { + value = (long) setYearWasmGC(value, year + 1900); + return; } var date = new JSDate(value); date.setFullYear(year + 1900); value = (long) date.getTime(); } + @Import(name = "setYear", module = "teavmDate") + private static native double setYearWasmGC(double timestamp, int year); + @Import(name = "teavm_date_setYear") @NoSideEffects @Unmanaged @@ -159,6 +181,8 @@ public class TDate implements TComparable { public int getMonth() { if (PlatformDetector.isLowLevel()) { return getMonthLowLevel(value); + } else if (PlatformDetector.isWebAssemblyGC()) { + return getMonthWasmGC(value); } return new JSDate(value).getMonth(); } @@ -170,11 +194,17 @@ public class TDate implements TComparable { @UnsupportedOn(Platforms.WEBASSEMBLY) private static native int getMonthLowLevel(long date); + @Import(name = "getMonth", module = "teavmDate") + private static native int getMonthWasmGC(double timestamp); + @Deprecated public void setMonth(int month) { if (PlatformDetector.isLowLevel()) { value = setMonthLowLevel(value, month); return; + } else if (PlatformDetector.isWebAssemblyGC()) { + value = (long) setMonthWasmGC(value, month); + return; } var date = new JSDate(value); date.setMonth(month); @@ -188,10 +218,15 @@ public class TDate implements TComparable { @UnsupportedOn(Platforms.WEBASSEMBLY) private static native long setMonthLowLevel(long date, int month); + @Import(name = "setMonth", module = "teavmDate") + private static native double setMonthWasmGC(double timestamp, int month); + @Deprecated public int getDate() { if (PlatformDetector.isLowLevel()) { return getDateLowLevel(value); + } else if (PlatformDetector.isWebAssemblyGC()) { + return getDateWasmGC(value); } return new JSDate(value).getDate(); } @@ -203,11 +238,17 @@ public class TDate implements TComparable { @UnsupportedOn(Platforms.WEBASSEMBLY) private static native int getDateLowLevel(long date); + @Import(name = "getDate", module = "teavmDate") + private static native int getDateWasmGC(double timestamp); + @Deprecated public void setDate(int date) { if (PlatformDetector.isLowLevel()) { value = setDateLowLevel(value, date); return; + } else if (PlatformDetector.isWebAssemblyGC()) { + value = (long) setDateWasmGC(value, date); + return; } var d = new JSDate(value); d.setDate(date); @@ -221,6 +262,9 @@ public class TDate implements TComparable { @UnsupportedOn(Platforms.WEBASSEMBLY) private static native int setDateLowLevel(long target, int date); + @Import(name = "setDate", module = "teavmDate") + private static native double setDateWasmGC(double timestamp, int date); + @Deprecated public int getDay() { if (PlatformDetector.isLowLevel()) { @@ -373,8 +417,10 @@ public class TDate implements TComparable { public String toString() { if (PlatformDetector.isC()) { return toStringC(value); - } else if (PlatformDetector.isWebAssembly() || PlatformDetector.isWebAssemblyGC()) { + } else if (PlatformDetector.isWebAssembly()) { return toStringWebAssembly(value); + } else if (PlatformDetector.isWebAssemblyGC()) { + return toStringWebAssemblyGC(value); } else { return JSDate.create(value).stringValue(); } @@ -388,6 +434,9 @@ public class TDate implements TComparable { @Import(module = "teavm", name = "dateToString") private static native String toStringWebAssembly(double date); + @Import(module = "teavmDate", name = "dateToString") + private static native String toStringWebAssemblyGC(double date); + @Deprecated public String toLocaleString() { return new JSDate(value).toLocaleFormat("%c"); diff --git a/core/src/main/java/org/teavm/backend/wasm/intrinsics/gc/SystemIntrinsic.java b/core/src/main/java/org/teavm/backend/wasm/intrinsics/gc/SystemIntrinsic.java index d6bbfcf3e..5f4e204fc 100644 --- a/core/src/main/java/org/teavm/backend/wasm/intrinsics/gc/SystemIntrinsic.java +++ b/core/src/main/java/org/teavm/backend/wasm/intrinsics/gc/SystemIntrinsic.java @@ -32,7 +32,7 @@ public class SystemIntrinsic implements WasmGCIntrinsic { workerFunction = new WasmFunction(context.functionTypes().of(WasmType.FLOAT64)); workerFunction.setName("teavm@currentTimeMillis"); workerFunction.setImportName("currentTimeMillis"); - workerFunction.setImportModule("teavm"); + workerFunction.setImportModule("teavmDate"); context.module().functions.add(workerFunction); } var call = new WasmCall(workerFunction); diff --git a/core/src/main/java/org/teavm/backend/wasm/runtime/gc/WasmGCSupport.java b/core/src/main/java/org/teavm/backend/wasm/runtime/gc/WasmGCSupport.java index 6cd582d0f..bc5814f8a 100644 --- a/core/src/main/java/org/teavm/backend/wasm/runtime/gc/WasmGCSupport.java +++ b/core/src/main/java/org/teavm/backend/wasm/runtime/gc/WasmGCSupport.java @@ -48,10 +48,10 @@ public class WasmGCSupport { return x; } - @Import(name = "putcharStdout") + @Import(name = "putcharStdout", module = "teavmConsole") public static native void putCharStdout(char c); - @Import(name = "putcharStderr") + @Import(name = "putcharStderr", module = "teavmConsole") public static native void putCharStderr(char c); public static char[] nextCharArray() { diff --git a/core/src/main/resources/org/teavm/backend/wasm/wasm-gc-runtime.js b/core/src/main/resources/org/teavm/backend/wasm/wasm-gc-runtime.js index 612cd3832..c09f739c1 100644 --- a/core/src/main/resources/org/teavm/backend/wasm/wasm-gc-runtime.js +++ b/core/src/main/resources/org/teavm/backend/wasm/wasm-gc-runtime.js @@ -28,7 +28,45 @@ TeaVM.wasm = function() { let stringFinalizationRegistry = new FinalizationRegistry(heldValue => { exports.reportGarbageCollectedString(heldValue); }); - imports.teavm = { + imports.teavmDate = { + currentTimeMillis() { + return new Date().getTime(); + }, + dateToString(timestamp) { + return stringToJava(new Date(timestamp).toString()); + }, + getYear(timestamp) { + return new Date(timestamp).getFullYear(); + }, + setYear(timestamp, year) { + let date = new Date(timestamp); + date.setFullYear(year); + return date.getTime(); + }, + getMonth(timestamp) { + return new Date(timestamp).getMonth(); + }, + setMonth(timestamp, month) { + let date = new Date(timestamp); + date.setMonth(month); + return date.getTime(); + }, + getDate(timestamp) { + return new Date(timestamp).getDate(); + }, + setDate(timestamp, value) { + let date = new Date(timestamp); + date.setDate(value); + return date.getTime(); + }, + create(year, month, date, hrs, min, sec) { + return new Date(year, month, date, hrs, min, sec).getTime(); + }, + createFromUTC(year, month, date, hrs, min, sec) { + return Date.UTC(year, month, date, hrs, min, sec); + } + }; + imports.teavmConsole = { putcharStderr(c) { if (c === 10) { console.error(stderr); @@ -45,12 +83,8 @@ TeaVM.wasm = function() { stdout += String.fromCharCode(c); } }, - currentTimeMillis() { - return new Date().getTime(); - }, - dateToString(timestamp) { - return stringToJava(new Date(timestamp).toString()); - }, + }; + imports.teavm = { createWeakRef(value, heldValue) { let weakRef = new WeakRef(value); if (heldValue !== null) { diff --git a/samples/pi/src/main/webapp/wasm-gc.html b/samples/pi/src/main/webapp/wasm-gc.html index b28eb95f4..dced17163 100644 --- a/samples/pi/src/main/webapp/wasm-gc.html +++ b/samples/pi/src/main/webapp/wasm-gc.html @@ -35,8 +35,8 @@ function putwchar(ch) { $rt_putStdoutCustom(String.fromCharCode(ch)); } - o.teavm.putcharStderr = putwchar; - o.teavm.putcharStdout = putwchar; + o.teavmConsole.putcharStderr = putwchar; + o.teavmConsole.putcharStdout = putwchar; }, }).then(teavm => { this.instance = teavm.instance; diff --git a/tools/browser-runner/src/main/resources/test-server/frame.js b/tools/browser-runner/src/main/resources/test-server/frame.js index c932810d3..ffa0140b2 100644 --- a/tools/browser-runner/src/main/resources/test-server/frame.js +++ b/tools/browser-runner/src/main/resources/test-server/frame.js @@ -212,8 +212,8 @@ function launchWasmGCTest(file, argument, callback) { TeaVM.wasm.load(file.path, { installImports: function(o) { - o.teavm.putcharStdout = putchar; - o.teavm.putcharStderr = putcharStderr; + o.teavmConsole.putcharStdout = putchar; + o.teavmConsole.putcharStderr = putcharStderr; o.teavmTest = { success() { callback(wrapResponse({ status: "OK" }));