feat: implement timers in java

This commit is contained in:
2023-09-28 10:25:32 +03:00
parent 9c65bacbac
commit 63b04019cf
9 changed files with 102 additions and 228 deletions

View File

@@ -24,9 +24,14 @@ public class FunctionPolyfill {
if (!(func instanceof FunctionValue)) throw EngineException.ofError("Expected this to be a function.");
return new NativeFunction(func.name + " (bound)", (callCtx, _0, callArgs) -> {
var resArgs = new Object[args.length + callArgs.length];
System.arraycopy(args, 0, resArgs, 0, args.length);
System.arraycopy(callArgs, 0, resArgs, args.length, callArgs.length);
Object[] resArgs;
if (args.length == 0) resArgs = callArgs;
else {
resArgs = new Object[args.length + callArgs.length];
System.arraycopy(args, 0, resArgs, 0, args.length);
System.arraycopy(callArgs, 0, resArgs, args.length, callArgs.length);
}
return func.call(ctx, thisArg, resArgs);
});

View File

@@ -1,7 +1,6 @@
package me.topchetoeu.jscript.polyfills;
import me.topchetoeu.jscript.engine.Context;
import me.topchetoeu.jscript.engine.Environment;
import me.topchetoeu.jscript.engine.frame.CodeFrame;
import me.topchetoeu.jscript.engine.frame.Runners;
import me.topchetoeu.jscript.engine.values.CodeFunction;

View File

@@ -20,6 +20,8 @@ public class Internals {
promise, map, set, regexp,
error, syntax, type, range;
@Native public final TimerPolyfills timers = new TimerPolyfills();
@Native public void markSpecial(FunctionValue ...funcs) {
for (var func : funcs) {
func.special = true;
@@ -37,6 +39,9 @@ public class Internals {
if (env != null) ctx = new Context(env, ctx.message);
return func.call(ctx, thisArg, args.toArray());
}
@Native public FunctionValue bind(Context ctx, FunctionValue func, Object thisArg) throws InterruptedException {
return FunctionPolyfill.bind(ctx, func, thisArg);
}
@Native public FunctionValue delay(Context ctx, double delay, FunctionValue callback) throws InterruptedException {
var thread = new Thread((Runnable)() -> {
var ms = (long)delay;

View File

@@ -0,0 +1,60 @@
package me.topchetoeu.jscript.polyfills;
import java.util.HashMap;
import me.topchetoeu.jscript.engine.Context;
import me.topchetoeu.jscript.engine.values.FunctionValue;
import me.topchetoeu.jscript.interop.Native;
public class TimerPolyfills {
private HashMap<Integer, Thread> threads = new HashMap<>();
private int i = 0;
@Native public int setTimeout(Context ctx, FunctionValue func, int delay, Object ...args) {
var thread = new Thread(() -> {
var ms = (long)delay;
var ns = (int)((delay - ms) * 10000000);
try {
Thread.sleep(ms, ns);
}
catch (InterruptedException e) { return; }
ctx.message.engine.pushMsg(false, ctx.message, func, null, args);
});
thread.start();
threads.put(++i, thread);
return i;
}
@Native public int setInterval(Context ctx, FunctionValue func, int delay, Object ...args) {
var thread = new Thread(() -> {
var ms = (long)delay;
var ns = (int)((delay - ms) * 10000000);
while (true) {
try {
Thread.sleep(ms, ns);
}
catch (InterruptedException e) { return; }
ctx.message.engine.pushMsg(false, ctx.message, func, null, args);
}
});
thread.start();
threads.put(++i, thread);
return i;
}
@Native public void clearTimeout(Context ctx, int i) {
var thread = threads.remove(i);
if (thread != null) thread.interrupt();
}
@Native public void clearInterval(Context ctx, int i) {
clearTimeout(ctx, i);
}
}