wasm gc: fix Date API support

This commit is contained in:
Alexey Andreev 2024-09-26 18:24:15 +02:00
parent b9f406dcaa
commit 951d0c53c3
6 changed files with 98 additions and 15 deletions

View File

@ -64,6 +64,8 @@ public class TDate implements TComparable<TDate> {
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<TDate> {
@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<TDate> {
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<TDate> {
@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<TDate> {
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<TDate> {
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<TDate> {
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<TDate> {
@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<TDate> {
@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<TDate> {
@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<TDate> {
@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<TDate> {
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<TDate> {
@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");

View File

@ -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);

View File

@ -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() {

View File

@ -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) {

View File

@ -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;

View File

@ -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" }));