From 7fd3166f9bcf20fcbfcd6c4052c5a8b5a043933f Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 27 Sep 2023 14:30:20 +0200 Subject: [PATCH] wasm: support Date.toString --- .../org/teavm/classlib/java/util/TDate.java | 12 ++++--- .../org/teavm/backend/wasm/wasm-runtime.js | 31 ++++++++++++++----- 2 files changed, 31 insertions(+), 12 deletions(-) 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 4f6273494..f2f3dd39a 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 @@ -370,8 +370,10 @@ public class TDate implements TComparable { @Override public String toString() { - if (PlatformDetector.isLowLevel()) { - return toStringLowLevel(value); + if (PlatformDetector.isC()) { + return toStringC(value); + } else if (PlatformDetector.isWebAssembly()) { + return toStringWebAssembly(value); } else { return JSDate.create(value).stringValue(); } @@ -380,8 +382,10 @@ public class TDate implements TComparable { @Import(name = "teavm_date_format") @NoSideEffects @RuntimeInclude("date.h") - @UnsupportedOn(Platforms.WEBASSEMBLY) - private static native String toStringLowLevel(long date); + private static native String toStringC(long date); + + @Import(module = "teavm", name = "dateToString") + private static native String toStringWebAssembly(double date); @Deprecated public String toLocaleString() { diff --git a/core/src/main/resources/org/teavm/backend/wasm/wasm-runtime.js b/core/src/main/resources/org/teavm/backend/wasm/wasm-runtime.js index b9d8a7f17..dac22a5f6 100644 --- a/core/src/main/resources/org/teavm/backend/wasm/wasm-runtime.js +++ b/core/src/main/resources/org/teavm/backend/wasm/wasm-runtime.js @@ -50,11 +50,25 @@ TeaVM.wasm = function() { let memory = instance.exports.memory.buffer; let arrayPtr = instance.exports.teavm_stringData(string); let length = instance.exports.teavm_arrayLength(arrayPtr); - let arrayData = new DataView(memory, instance.exports.teavm_charArrayData(arrayPtr), length * 2); + let arrayData = new Uint16Array(memory, instance.exports.teavm_charArrayData(arrayPtr), length * 2); for (let i = 0; i < length; ++i) { - putwchar(arrayData.getUint16(i * 2, true)); + putwchar(arrayData[i]); } } + function dateToString(timestamp, controller) { + const s = new Date(timestamp).toString(); + let instance = controller.instance; + let result = instance.allocateString(s.length); + if (result === 0) { + return 0; + } + let resultAddress = instance.objectArrayData(instance.stringData(result)); + let resultView = new Uint16Array(instance.exports.memory.buffer, resultAddress, s.length); + for (let i = 0; i < s.length; ++i) { + resultView[i] = s.charCodeAt(i); + } + return result; + } function logInt(i) { lineBuffer += i.toString(); } @@ -87,14 +101,15 @@ TeaVM.wasm = function() { controller.complete = false; obj.teavm = { currentTimeMillis: currentTimeMillis, - nanoTime: function() { return performance.now(); }, + nanoTime: () => performance.now(), putwcharsOut: (chars, count) => putwchars(controller, chars, count), putwcharsErr: (chars, count) => putwchars(controller, chars, count), getNativeOffset: getNativeOffset, logString: string => logString(string, controller), logInt: logInt, logOutOfMemory: () => console.log("Out of memory"), - teavm_interrupt: () => interrupt(controller) + teavm_interrupt: () => interrupt(controller), + dateToString: (timestamp) => dateToString(timestamp, controller) }; obj.teavmMath = Math; @@ -184,16 +199,16 @@ TeaVM.wasm = function() { } return new Promise((resolve, reject) => { let javaArgs = teavm.allocateStringArray(args.length); - let javaArgsData = new DataView(teavm.memory.buffer, teavm.objectArrayData(javaArgs), args.length * 4); + let javaArgsData = new Int32Array(teavm.memory.buffer, teavm.objectArrayData(javaArgs), args.length); for (let i = 0; i < args.length; ++i) { let arg = args[i]; let javaArg = teavm.allocateString(arg.length); let javaArgAddress = teavm.objectArrayData(teavm.stringData(javaArg)); - let javaArgData = new DataView(teavm.memory.buffer, javaArgAddress, arg.length * 2); + let javaArgData = new Uint16Array(teavm.memory.buffer, javaArgAddress, arg.length); for (let j = 0; j < arg.length; ++j) { - javaArgData.setUint16(j * 2, arg.charCodeAt(j), true); + javaArgData[j] = arg.charCodeAt(j); } - javaArgsData.setInt32(i * 4, javaArg, true); + javaArgsData[i] = javaArg; } controller.resolve = resolve;