feat: fully remove typescript init code
This commit is contained in:
parent
63b04019cf
commit
68f3b6d926
114
lib/core.ts
114
lib/core.ts
@ -1,114 +0,0 @@
|
|||||||
interface Environment {
|
|
||||||
global: typeof globalThis & Record<string, any>;
|
|
||||||
proto(name: string): object;
|
|
||||||
setProto(name: string, val: object): void;
|
|
||||||
symbol(name: string): symbol;
|
|
||||||
}
|
|
||||||
interface Internals {
|
|
||||||
object: ObjectConstructor;
|
|
||||||
function: FunctionConstructor;
|
|
||||||
array: ArrayConstructor;
|
|
||||||
promise: PromiseConstructor;
|
|
||||||
bool: BooleanConstructor;
|
|
||||||
number: NumberConstructor;
|
|
||||||
string: StringConstructor;
|
|
||||||
symbol: SymbolConstructor;
|
|
||||||
error: ErrorConstructor;
|
|
||||||
syntax: SyntaxErrorConstructor;
|
|
||||||
type: TypeErrorConstructor;
|
|
||||||
range: RangeErrorConstructor;
|
|
||||||
|
|
||||||
regexp: typeof RegExp;
|
|
||||||
map: typeof Map;
|
|
||||||
set: typeof Set;
|
|
||||||
|
|
||||||
timers: {
|
|
||||||
setTimeout: <T extends any[]>(handle: (...args: [ ...T, ...any[] ]) => void, delay?: number, ...args: T) => number,
|
|
||||||
setInterval: <T extends any[]>(handle: (...args: [ ...T, ...any[] ]) => void, delay?: number, ...args: T) => number,
|
|
||||||
clearTimeout: (id: number) => void,
|
|
||||||
clearInterval: (id: number) => void,
|
|
||||||
}
|
|
||||||
|
|
||||||
markSpecial(...funcs: Function[]): void;
|
|
||||||
getEnv(func: Function): Environment | undefined;
|
|
||||||
setEnv<T>(func: T, env: Environment): T;
|
|
||||||
apply(func: Function, thisArg: any, args: any[], env?: Environment): any;
|
|
||||||
bind(func: Function, thisArg: any): any;
|
|
||||||
delay(timeout: number, callback: Function): () => void;
|
|
||||||
pushMessage(micro: boolean, func: Function, thisArg: any, args: any[]): void;
|
|
||||||
|
|
||||||
strlen(val: string): number;
|
|
||||||
char(val: string): number;
|
|
||||||
stringFromStrings(arr: string[]): string;
|
|
||||||
stringFromChars(arr: number[]): string;
|
|
||||||
getSymbol(name?: string): symbol;
|
|
||||||
symbolToString(sym: symbol): string;
|
|
||||||
|
|
||||||
isArray(obj: any): boolean;
|
|
||||||
generator(func: (_yield: <T>(val: T) => unknown) => (...args: any[]) => unknown): GeneratorFunction;
|
|
||||||
defineField(obj: object, key: any, val: any, writable: boolean, enumerable: boolean, configurable: boolean): boolean;
|
|
||||||
defineProp(obj: object, key: any, get: Function | undefined, set: Function | undefined, enumerable: boolean, configurable: boolean): boolean;
|
|
||||||
keys(obj: object, onlyString: boolean): any[];
|
|
||||||
ownProp(obj: any, key: string): PropertyDescriptor<any, any>;
|
|
||||||
ownPropKeys(obj: any): any[];
|
|
||||||
lock(obj: object, type: 'ext' | 'seal' | 'freeze'): void;
|
|
||||||
extensible(obj: object): boolean;
|
|
||||||
|
|
||||||
sort(arr: any[], comaprator: (a: any, b: any) => number): void;
|
|
||||||
|
|
||||||
log(...args: any[]): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
var env: Environment = arguments[0], internals: Internals = arguments[1];
|
|
||||||
|
|
||||||
try {
|
|
||||||
const Array = env.global.Array = internals.array;
|
|
||||||
env.global.Object = internals.object;
|
|
||||||
env.global.Function = internals.function;
|
|
||||||
env.global.Promise = internals.promise;
|
|
||||||
env.global.Boolean = internals.bool;
|
|
||||||
env.global.Number = internals.number;
|
|
||||||
env.global.String = internals.string;
|
|
||||||
env.global.Symbol = internals.symbol;
|
|
||||||
env.global.Error = internals.error;
|
|
||||||
env.global.SyntaxError = internals.syntax;
|
|
||||||
env.global.TypeError = internals.type;
|
|
||||||
env.global.RangeError = internals.range;
|
|
||||||
env.global.RegExp = internals.regexp;
|
|
||||||
env.global.Map = internals.map;
|
|
||||||
env.global.Set = internals.set;
|
|
||||||
env.global.setInterval = internals.bind(internals.timers.setInterval, internals.timers);
|
|
||||||
env.global.setTimeout = internals.bind(internals.timers.setTimeout, internals.timers);
|
|
||||||
env.global.clearInterval = internals.bind(internals.timers.clearInterval, internals.timers);
|
|
||||||
env.global.clearTimeout = internals.bind(internals.timers.clearTimeout, internals.timers);
|
|
||||||
const log = env.global.log = internals.bind(internals.log, internals);
|
|
||||||
|
|
||||||
env.setProto('object', env.global.Object.prototype);
|
|
||||||
env.setProto('function', env.global.Function.prototype);
|
|
||||||
env.setProto('array', env.global.Array.prototype);
|
|
||||||
env.setProto('number', env.global.Number.prototype);
|
|
||||||
env.setProto('string', env.global.String.prototype);
|
|
||||||
env.setProto('symbol', env.global.Symbol.prototype);
|
|
||||||
env.setProto('bool', env.global.Boolean.prototype);
|
|
||||||
|
|
||||||
env.setProto('error', env.global.Error.prototype);
|
|
||||||
env.setProto('rangeErr', env.global.RangeError.prototype);
|
|
||||||
env.setProto('typeErr', env.global.TypeError.prototype);
|
|
||||||
env.setProto('syntaxErr', env.global.SyntaxError.prototype);
|
|
||||||
|
|
||||||
(env.global.Object.prototype as any).__proto__ = null;
|
|
||||||
|
|
||||||
log('Loaded polyfills!');
|
|
||||||
}
|
|
||||||
catch (e: any) {
|
|
||||||
let err = 'Uncaught error while loading polyfills: ';
|
|
||||||
|
|
||||||
if (typeof Error !== 'undefined' && e instanceof Error && e.toString !== {}.toString) err += e;
|
|
||||||
else if ('message' in e) {
|
|
||||||
if ('name' in e) err += e.name + ": " + e.message;
|
|
||||||
else err += 'Error: ' + e.message;
|
|
||||||
}
|
|
||||||
else err += "[unknown]";
|
|
||||||
|
|
||||||
internals.log(err);
|
|
||||||
}
|
|
@ -7,10 +7,11 @@ import java.io.InputStreamReader;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.engine.MessageContext;
|
import me.topchetoeu.jscript.engine.Message;
|
||||||
import me.topchetoeu.jscript.engine.Context;
|
import me.topchetoeu.jscript.engine.Context;
|
||||||
import me.topchetoeu.jscript.engine.Engine;
|
import me.topchetoeu.jscript.engine.Engine;
|
||||||
import me.topchetoeu.jscript.engine.Environment;
|
import me.topchetoeu.jscript.engine.Environment;
|
||||||
|
import me.topchetoeu.jscript.engine.values.NativeFunction;
|
||||||
import me.topchetoeu.jscript.engine.values.Values;
|
import me.topchetoeu.jscript.engine.values.Values;
|
||||||
import me.topchetoeu.jscript.events.Observer;
|
import me.topchetoeu.jscript.events.Observer;
|
||||||
import me.topchetoeu.jscript.exceptions.EngineException;
|
import me.topchetoeu.jscript.exceptions.EngineException;
|
||||||
@ -63,30 +64,35 @@ public class Main {
|
|||||||
engine = new Engine();
|
engine = new Engine();
|
||||||
|
|
||||||
env = new Environment(null, null, null);
|
env = new Environment(null, null, null);
|
||||||
var builderEnv = new Environment(null, null, null);
|
|
||||||
var exited = new boolean[1];
|
var exited = new boolean[1];
|
||||||
|
|
||||||
env.global.define("exit", ctx -> {
|
engine.pushMsg(false, new Message(engine), new NativeFunction((ctx, thisArg, _a) -> {
|
||||||
exited[0] = true;
|
new Internals().apply(env);
|
||||||
task.interrupt();
|
|
||||||
throw new InterruptedException();
|
|
||||||
});
|
|
||||||
env.global.define("go", ctx -> {
|
|
||||||
try {
|
|
||||||
var func = ctx.compile("do.js", new String(Files.readAllBytes(Path.of("do.js"))));
|
|
||||||
return func.call(ctx);
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
throw new EngineException("Couldn't open do.js");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
engine.pushMsg(
|
env.global.define("exit", _ctx -> {
|
||||||
false,
|
exited[0] = true;
|
||||||
new Context(builderEnv, new MessageContext(engine)),
|
task.interrupt();
|
||||||
"core.js", resourceToString("js/core.js"),
|
throw new InterruptedException();
|
||||||
null, env, new Internals(env)
|
});
|
||||||
).toObservable().on(valuePrinter);
|
env.global.define("go", _ctx -> {
|
||||||
|
try {
|
||||||
|
var func = _ctx.compile("do.js", new String(Files.readAllBytes(Path.of("do.js"))));
|
||||||
|
return func.call(_ctx);
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
throw new EngineException("Couldn't open do.js");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}), null);
|
||||||
|
|
||||||
|
// engine.pushMsg(
|
||||||
|
// false,
|
||||||
|
// new Context(builderEnv, new MessageContext(engine)),
|
||||||
|
// "core.js", resourceToString("js/core.js"),
|
||||||
|
// null, env, new Internals(env)
|
||||||
|
// ).toObservable().on(valuePrinter);
|
||||||
|
|
||||||
task = engine.start();
|
task = engine.start();
|
||||||
var reader = new Thread(() -> {
|
var reader = new Thread(() -> {
|
||||||
@ -96,7 +102,7 @@ public class Main {
|
|||||||
var raw = in.readLine();
|
var raw = in.readLine();
|
||||||
|
|
||||||
if (raw == null) break;
|
if (raw == null) break;
|
||||||
engine.pushMsg(false, new Context(env, new MessageContext(engine)), "<stdio>", raw, null).toObservable().once(valuePrinter);
|
engine.pushMsg(false, new Context(env, new Message(engine)), "<stdio>", raw, null).toObservable().once(valuePrinter);
|
||||||
}
|
}
|
||||||
catch (EngineException e) {
|
catch (EngineException e) {
|
||||||
try {
|
try {
|
||||||
|
@ -6,15 +6,22 @@ import me.topchetoeu.jscript.parsing.Parsing;
|
|||||||
|
|
||||||
public class Context {
|
public class Context {
|
||||||
public final Environment env;
|
public final Environment env;
|
||||||
public final MessageContext message;
|
public final Message message;
|
||||||
|
|
||||||
public FunctionValue compile(String filename, String raw) throws InterruptedException {
|
public FunctionValue compile(String filename, String raw) throws InterruptedException {
|
||||||
var res = Values.toString(this, env.compile.call(this, null, raw, filename));
|
var res = Values.toString(this, env.compile.call(this, null, raw, filename));
|
||||||
return Parsing.compile(env, filename, res);
|
return Parsing.compile(env, filename, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Context(Environment funcCtx, MessageContext msgCtx) {
|
public Context setEnv(Environment env) {
|
||||||
this.env = funcCtx;
|
return new Context(env, message);
|
||||||
this.message = msgCtx;
|
}
|
||||||
|
public Context setMsg(Message msg) {
|
||||||
|
return new Context(env, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Context(Environment env, Message msg) {
|
||||||
|
this.env = env;
|
||||||
|
this.message = msg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,9 +32,9 @@ public class Engine {
|
|||||||
public final Object thisArg;
|
public final Object thisArg;
|
||||||
public final Object[] args;
|
public final Object[] args;
|
||||||
public final DataNotifier<Object> notifier = new DataNotifier<>();
|
public final DataNotifier<Object> notifier = new DataNotifier<>();
|
||||||
public final MessageContext ctx;
|
public final Message ctx;
|
||||||
|
|
||||||
public Task(MessageContext ctx, FunctionValue func, Object thisArg, Object[] args) {
|
public Task(Message ctx, FunctionValue func, Object thisArg, Object[] args) {
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
this.func = func;
|
this.func = func;
|
||||||
this.thisArg = thisArg;
|
this.thisArg = thisArg;
|
||||||
@ -102,7 +102,7 @@ public class Engine {
|
|||||||
return this.thread != null;
|
return this.thread != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Awaitable<Object> pushMsg(boolean micro, MessageContext ctx, FunctionValue func, Object thisArg, Object ...args) {
|
public Awaitable<Object> pushMsg(boolean micro, Message ctx, FunctionValue func, Object thisArg, Object ...args) {
|
||||||
var msg = new Task(ctx, func, thisArg, args);
|
var msg = new Task(ctx, func, thisArg, args);
|
||||||
if (micro) microTasks.addLast(msg);
|
if (micro) microTasks.addLast(msg);
|
||||||
else macroTasks.addLast(msg);
|
else macroTasks.addLast(msg);
|
||||||
|
@ -60,6 +60,10 @@ public class Environment {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Context context(Message msg) {
|
||||||
|
return new Context(this, msg);
|
||||||
|
}
|
||||||
|
|
||||||
public Environment(FunctionValue compile, WrappersProvider nativeConverter, GlobalScope global) {
|
public Environment(FunctionValue compile, WrappersProvider nativeConverter, GlobalScope global) {
|
||||||
if (compile == null) compile = new NativeFunction("compile", (ctx, thisArg, args) -> args.length == 0 ? "" : args[0]);
|
if (compile == null) compile = new NativeFunction("compile", (ctx, thisArg, args) -> args.length == 0 ? "" : args[0]);
|
||||||
if (nativeConverter == null) nativeConverter = new NativeWrapperProvider(this);
|
if (nativeConverter == null) nativeConverter = new NativeWrapperProvider(this);
|
||||||
|
@ -7,7 +7,7 @@ import java.util.List;
|
|||||||
import me.topchetoeu.jscript.engine.frame.CodeFrame;
|
import me.topchetoeu.jscript.engine.frame.CodeFrame;
|
||||||
import me.topchetoeu.jscript.exceptions.EngineException;
|
import me.topchetoeu.jscript.exceptions.EngineException;
|
||||||
|
|
||||||
public class MessageContext {
|
public class Message {
|
||||||
public final Engine engine;
|
public final Engine engine;
|
||||||
|
|
||||||
private final ArrayList<CodeFrame> frames = new ArrayList<>();
|
private final ArrayList<CodeFrame> frames = new ArrayList<>();
|
||||||
@ -15,7 +15,7 @@ public class MessageContext {
|
|||||||
|
|
||||||
public List<CodeFrame> frames() { return Collections.unmodifiableList(frames); }
|
public List<CodeFrame> frames() { return Collections.unmodifiableList(frames); }
|
||||||
|
|
||||||
public MessageContext pushFrame(Context ctx, CodeFrame frame) throws InterruptedException {
|
public Message pushFrame(Context ctx, CodeFrame frame) throws InterruptedException {
|
||||||
this.frames.add(frame);
|
this.frames.add(frame);
|
||||||
if (this.frames.size() > maxStackFrames) throw EngineException.ofRange("Stack overflow!");
|
if (this.frames.size() > maxStackFrames) throw EngineException.ofRange("Stack overflow!");
|
||||||
return this;
|
return this;
|
||||||
@ -46,7 +46,11 @@ public class MessageContext {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MessageContext(Engine engine) {
|
public Context context(Environment env) {
|
||||||
|
return new Context(env, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Message(Engine engine) {
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -55,7 +55,7 @@ public class ObjectValue {
|
|||||||
|
|
||||||
public final boolean memberWritable(Object key) {
|
public final boolean memberWritable(Object key) {
|
||||||
if (state == State.FROZEN) return false;
|
if (state == State.FROZEN) return false;
|
||||||
return values.containsKey(key) && !nonWritableSet.contains(key);
|
return !values.containsKey(key) || !nonWritableSet.contains(key);
|
||||||
}
|
}
|
||||||
public final boolean memberConfigurable(Object key) {
|
public final boolean memberConfigurable(Object key) {
|
||||||
if (state == State.SEALED || state == State.FROZEN) return false;
|
if (state == State.SEALED || state == State.FROZEN) return false;
|
||||||
|
@ -20,7 +20,7 @@ public class FunctionPolyfill {
|
|||||||
|
|
||||||
return func.call(ctx, thisArg, args);
|
return func.call(ctx, thisArg, args);
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static FunctionValue bind(Context ctx, FunctionValue func, Object thisArg, Object... args) throws InterruptedException {
|
@Native(thisArg = true) public static FunctionValue bind(FunctionValue func, Object thisArg, Object... args) {
|
||||||
if (!(func instanceof FunctionValue)) throw EngineException.ofError("Expected this to be a function.");
|
if (!(func instanceof FunctionValue)) throw EngineException.ofError("Expected this to be a function.");
|
||||||
|
|
||||||
return new NativeFunction(func.name + " (bound)", (callCtx, _0, callArgs) -> {
|
return new NativeFunction(func.name + " (bound)", (callCtx, _0, callArgs) -> {
|
||||||
@ -33,7 +33,7 @@ public class FunctionPolyfill {
|
|||||||
System.arraycopy(callArgs, 0, resArgs, args.length, callArgs.length);
|
System.arraycopy(callArgs, 0, resArgs, args.length, callArgs.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
return func.call(ctx, thisArg, resArgs);
|
return func.call(callCtx, thisArg, resArgs);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static String toString(Context ctx, Object func) {
|
@Native(thisArg = true) public static String toString(Context ctx, Object func) {
|
||||||
|
@ -1,49 +1,29 @@
|
|||||||
package me.topchetoeu.jscript.polyfills;
|
package me.topchetoeu.jscript.polyfills;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.engine.Context;
|
import me.topchetoeu.jscript.engine.Context;
|
||||||
import me.topchetoeu.jscript.engine.Environment;
|
import me.topchetoeu.jscript.engine.Environment;
|
||||||
import me.topchetoeu.jscript.engine.values.ArrayValue;
|
|
||||||
import me.topchetoeu.jscript.engine.values.CodeFunction;
|
|
||||||
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
||||||
import me.topchetoeu.jscript.engine.values.NativeFunction;
|
|
||||||
import me.topchetoeu.jscript.engine.values.ObjectValue;
|
|
||||||
import me.topchetoeu.jscript.engine.values.Symbol;
|
|
||||||
import me.topchetoeu.jscript.engine.values.Values;
|
import me.topchetoeu.jscript.engine.values.Values;
|
||||||
import me.topchetoeu.jscript.interop.Native;
|
import me.topchetoeu.jscript.interop.Native;
|
||||||
|
|
||||||
public class Internals {
|
public class Internals {
|
||||||
public final Environment targetEnv;
|
private HashMap<Integer, Thread> threads = new HashMap<>();
|
||||||
|
private int i = 0;
|
||||||
|
|
||||||
@Native public final FunctionValue
|
@Native public FunctionValue bind(FunctionValue func, Object thisArg) throws InterruptedException {
|
||||||
object, function, array,
|
return FunctionPolyfill.bind(func, thisArg);
|
||||||
bool, number, string, symbol,
|
}
|
||||||
promise, map, set, regexp,
|
@Native public void log(Context ctx, Object ...args) throws InterruptedException {
|
||||||
error, syntax, type, range;
|
for (var arg : args) {
|
||||||
|
Values.printValue(ctx, arg);
|
||||||
@Native public final TimerPolyfills timers = new TimerPolyfills();
|
|
||||||
|
|
||||||
@Native public void markSpecial(FunctionValue ...funcs) {
|
|
||||||
for (var func : funcs) {
|
|
||||||
func.special = true;
|
|
||||||
}
|
}
|
||||||
|
System.out.println();
|
||||||
}
|
}
|
||||||
@Native public Environment getEnv(Object func) {
|
|
||||||
if (func instanceof CodeFunction) return ((CodeFunction)func).environment;
|
@Native public int setTimeout(Context ctx, FunctionValue func, int delay, Object ...args) {
|
||||||
else return null;
|
var thread = new Thread(() -> {
|
||||||
}
|
|
||||||
@Native public Object setEnv(Object func, Environment env) {
|
|
||||||
if (func instanceof CodeFunction) ((CodeFunction)func).environment = env;
|
|
||||||
return func;
|
|
||||||
}
|
|
||||||
@Native public Object apply(Context ctx, FunctionValue func, Object thisArg, ArrayValue args, Environment env) throws InterruptedException {
|
|
||||||
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;
|
var ms = (long)delay;
|
||||||
var ns = (int)((delay - ms) * 10000000);
|
var ns = (int)((delay - ms) * 10000000);
|
||||||
|
|
||||||
@ -52,130 +32,66 @@ public class Internals {
|
|||||||
}
|
}
|
||||||
catch (InterruptedException e) { return; }
|
catch (InterruptedException e) { return; }
|
||||||
|
|
||||||
ctx.message.engine.pushMsg(false, ctx.message, callback, null);
|
ctx.message.engine.pushMsg(false, ctx.message, func, null, args);
|
||||||
});
|
});
|
||||||
thread.start();
|
thread.start();
|
||||||
|
|
||||||
return new NativeFunction((_ctx, thisArg, args) -> {
|
threads.put(++i, thread);
|
||||||
thread.interrupt();
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@Native public void pushMessage(Context ctx, boolean micro, FunctionValue func, Object thisArg, Object[] args) {
|
|
||||||
ctx.message.engine.pushMsg(micro, ctx.message, func, thisArg, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Native public int strlen(String str) {
|
return i;
|
||||||
return str.length();
|
|
||||||
}
|
}
|
||||||
@Native("char") public int _char(String str) {
|
@Native public int setInterval(Context ctx, FunctionValue func, int delay, Object ...args) {
|
||||||
return str.charAt(0);
|
var thread = new Thread(() -> {
|
||||||
}
|
var ms = (long)delay;
|
||||||
@Native public String stringFromChars(char[] str) {
|
var ns = (int)((delay - ms) * 10000000);
|
||||||
return new String(str);
|
|
||||||
}
|
|
||||||
@Native public String stringFromStrings(String[] str) {
|
|
||||||
var res = new char[str.length];
|
|
||||||
|
|
||||||
for (var i = 0; i < str.length; i++) res[i] = str[i].charAt(0);
|
while (true) {
|
||||||
|
try {
|
||||||
return stringFromChars(res);
|
Thread.sleep(ms, ns);
|
||||||
}
|
}
|
||||||
@Native public Symbol getSymbol(String str) {
|
catch (InterruptedException e) { return; }
|
||||||
return new Symbol(str);
|
|
||||||
}
|
ctx.message.engine.pushMsg(false, ctx.message, func, null, args);
|
||||||
@Native public String symbolToString(Symbol str) {
|
|
||||||
return str.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Native public void log(Context ctx, Object ...args) throws InterruptedException {
|
|
||||||
for (var arg : args) {
|
|
||||||
Values.printValue(ctx, arg);
|
|
||||||
}
|
|
||||||
System.out.println();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Native public boolean isArray(Object obj) {
|
|
||||||
return obj instanceof ArrayValue;
|
|
||||||
}
|
|
||||||
@Native public GeneratorPolyfill generator(FunctionValue obj) {
|
|
||||||
return new GeneratorPolyfill(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Native public boolean defineField(Context ctx, ObjectValue obj, Object key, Object val, boolean writable, boolean enumerable, boolean configurable) {
|
|
||||||
return obj.defineProperty(ctx, key, val, writable, configurable, enumerable);
|
|
||||||
}
|
|
||||||
@Native public boolean defineProp(Context ctx, ObjectValue obj, Object key, FunctionValue getter, FunctionValue setter, boolean enumerable, boolean configurable) {
|
|
||||||
return obj.defineProperty(ctx, key, getter, setter, configurable, enumerable);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Native public ArrayValue keys(Context ctx, Object obj, boolean onlyString) throws InterruptedException {
|
|
||||||
var res = new ArrayValue();
|
|
||||||
|
|
||||||
var i = 0;
|
|
||||||
var list = Values.getMembers(ctx, obj, true, false);
|
|
||||||
|
|
||||||
for (var el : list) res.set(ctx, i++, el);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
@Native public ArrayValue ownPropKeys(Context ctx, Object obj, boolean symbols) throws InterruptedException {
|
|
||||||
var res = new ArrayValue();
|
|
||||||
|
|
||||||
if (Values.isObject(obj)) {
|
|
||||||
var i = 0;
|
|
||||||
var list = Values.object(obj).keys(true);
|
|
||||||
|
|
||||||
for (var el : list) res.set(ctx, i++, el);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
@Native public ObjectValue ownProp(Context ctx, ObjectValue val, Object key) throws InterruptedException {
|
|
||||||
return val.getMemberDescriptor(ctx, key);
|
|
||||||
}
|
|
||||||
@Native public void lock(ObjectValue val, String type) {
|
|
||||||
switch (type) {
|
|
||||||
case "ext": val.preventExtensions(); break;
|
|
||||||
case "seal": val.seal(); break;
|
|
||||||
case "freeze": val.freeze(); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Native public boolean extensible(ObjectValue val) {
|
|
||||||
return val.extensible();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Native public void sort(Context ctx, ArrayValue arr, FunctionValue cmp) {
|
|
||||||
arr.sort((a, b) -> {
|
|
||||||
try {
|
|
||||||
var res = Values.toNumber(ctx, cmp.call(ctx, null, a, b));
|
|
||||||
if (res < 0) return -1;
|
|
||||||
if (res > 0) return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
thread.start();
|
||||||
|
|
||||||
|
threads.put(++i, thread);
|
||||||
|
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Internals(Environment targetEnv) {
|
@Native public void clearTimeout(Context ctx, int i) {
|
||||||
this.targetEnv = targetEnv;
|
var thread = threads.remove(i);
|
||||||
this.object = targetEnv.wrappersProvider.getConstr(ObjectPolyfill.class);
|
if (thread != null) thread.interrupt();
|
||||||
this.function = targetEnv.wrappersProvider.getConstr(FunctionPolyfill.class);
|
}
|
||||||
this.promise = targetEnv.wrappersProvider.getConstr(PromisePolyfill.class);
|
@Native public void clearInterval(Context ctx, int i) {
|
||||||
this.array = targetEnv.wrappersProvider.getConstr(ArrayPolyfill.class);
|
clearTimeout(ctx, i);
|
||||||
this.bool = targetEnv.wrappersProvider.getConstr(BooleanPolyfill.class);
|
}
|
||||||
this.number = targetEnv.wrappersProvider.getConstr(NumberPolyfill.class);
|
|
||||||
this.string = targetEnv.wrappersProvider.getConstr(StringPolyfill.class);
|
public void apply(Environment env) {
|
||||||
this.symbol = targetEnv.wrappersProvider.getConstr(SymbolPolyfill.class);
|
var wp = env.wrappersProvider;
|
||||||
this.map = targetEnv.wrappersProvider.getConstr(MapPolyfill.class);
|
var glob = env.global;
|
||||||
this.set = targetEnv.wrappersProvider.getConstr(SetPolyfill.class);
|
|
||||||
this.error = targetEnv.wrappersProvider.getConstr(ErrorPolyfill.class);
|
glob.define(null, "Object", false, wp.getConstr(ObjectPolyfill.class));
|
||||||
this.syntax = targetEnv.wrappersProvider.getConstr(SyntaxErrorPolyfill.class);
|
glob.define(null, "Function", false, wp.getConstr(FunctionPolyfill.class));
|
||||||
this.type = targetEnv.wrappersProvider.getConstr(TypeErrorPolyfill.class);
|
glob.define(null, "Array", false, wp.getConstr(ArrayPolyfill.class));
|
||||||
this.range = targetEnv.wrappersProvider.getConstr(RangeErrorPolyfill.class);
|
|
||||||
this.regexp = targetEnv.wrappersProvider.getConstr(RegExpPolyfill.class);
|
glob.define(null, "Boolean", false, wp.getConstr(BooleanPolyfill.class));
|
||||||
|
glob.define(null, "Number", false, wp.getConstr(NumberPolyfill.class));
|
||||||
|
glob.define(null, "String", false, wp.getConstr(StringPolyfill.class));
|
||||||
|
glob.define(null, "Symbol", false, wp.getConstr(SymbolPolyfill.class));
|
||||||
|
|
||||||
|
glob.define(null, "Promise", false, wp.getConstr(PromisePolyfill.class));
|
||||||
|
glob.define(null, "RegExp", false, wp.getConstr(RegExpPolyfill.class));
|
||||||
|
glob.define(null, "Map", false, wp.getConstr(MapPolyfill.class));
|
||||||
|
glob.define(null, "Set", false, wp.getConstr(SetPolyfill.class));
|
||||||
|
|
||||||
|
glob.define(null, "Error", false, wp.getConstr(ErrorPolyfill.class));
|
||||||
|
glob.define(null, "SyntaxError", false, wp.getConstr(SyntaxErrorPolyfill.class));
|
||||||
|
glob.define(null, "TypeError", false, wp.getConstr(TypeErrorPolyfill.class));
|
||||||
|
glob.define(null, "RangeError", false, wp.getConstr(RangeErrorPolyfill.class));
|
||||||
|
|
||||||
|
System.out.println("Loaded polyfills!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package me.topchetoeu.jscript.polyfills;
|
package me.topchetoeu.jscript.polyfills;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.engine.MessageContext;
|
import me.topchetoeu.jscript.engine.Message;
|
||||||
import me.topchetoeu.jscript.interop.Native;
|
import me.topchetoeu.jscript.interop.Native;
|
||||||
|
|
||||||
public class Math {
|
public class Math {
|
||||||
@ -22,19 +22,19 @@ public class Math {
|
|||||||
public static final double LOG10E = java.lang.Math.log10(java.lang.Math.E);
|
public static final double LOG10E = java.lang.Math.log10(java.lang.Math.E);
|
||||||
|
|
||||||
@Native
|
@Native
|
||||||
public static double asin(MessageContext ctx, double x) throws InterruptedException {
|
public static double asin(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.asin(x);
|
return java.lang.Math.asin(x);
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static double acos(MessageContext ctx, double x) throws InterruptedException {
|
public static double acos(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.acos(x);
|
return java.lang.Math.acos(x);
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static double atan(MessageContext ctx, double x) throws InterruptedException {
|
public static double atan(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.atan(x);
|
return java.lang.Math.atan(x);
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static double atan2(MessageContext ctx, double y, double x) throws InterruptedException {
|
public static double atan2(Message ctx, double y, double x) throws InterruptedException {
|
||||||
double _y = y;
|
double _y = y;
|
||||||
double _x = x;
|
double _x = x;
|
||||||
if (_x == 0) {
|
if (_x == 0) {
|
||||||
@ -51,59 +51,59 @@ public class Math {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Native
|
@Native
|
||||||
public static double asinh(MessageContext ctx, double x) throws InterruptedException {
|
public static double asinh(Message ctx, double x) throws InterruptedException {
|
||||||
double _x = x;
|
double _x = x;
|
||||||
return java.lang.Math.log(_x + java.lang.Math.sqrt(_x * _x + 1));
|
return java.lang.Math.log(_x + java.lang.Math.sqrt(_x * _x + 1));
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static double acosh(MessageContext ctx, double x) throws InterruptedException {
|
public static double acosh(Message ctx, double x) throws InterruptedException {
|
||||||
double _x = x;
|
double _x = x;
|
||||||
return java.lang.Math.log(_x + java.lang.Math.sqrt(_x * _x - 1));
|
return java.lang.Math.log(_x + java.lang.Math.sqrt(_x * _x - 1));
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static double atanh(MessageContext ctx, double x) throws InterruptedException {
|
public static double atanh(Message ctx, double x) throws InterruptedException {
|
||||||
double _x = x;
|
double _x = x;
|
||||||
if (_x <= -1 || _x >= 1) return Double.NaN;
|
if (_x <= -1 || _x >= 1) return Double.NaN;
|
||||||
return .5 * java.lang.Math.log((1 + _x) / (1 - _x));
|
return .5 * java.lang.Math.log((1 + _x) / (1 - _x));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native
|
@Native
|
||||||
public static double sin(MessageContext ctx, double x) throws InterruptedException {
|
public static double sin(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.sin(x);
|
return java.lang.Math.sin(x);
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static double cos(MessageContext ctx, double x) throws InterruptedException {
|
public static double cos(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.cos(x);
|
return java.lang.Math.cos(x);
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static double tan(MessageContext ctx, double x) throws InterruptedException {
|
public static double tan(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.tan(x);
|
return java.lang.Math.tan(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native
|
@Native
|
||||||
public static double sinh(MessageContext ctx, double x) throws InterruptedException {
|
public static double sinh(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.sinh(x);
|
return java.lang.Math.sinh(x);
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static double cosh(MessageContext ctx, double x) throws InterruptedException {
|
public static double cosh(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.cosh(x);
|
return java.lang.Math.cosh(x);
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static double tanh(MessageContext ctx, double x) throws InterruptedException {
|
public static double tanh(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.tanh(x);
|
return java.lang.Math.tanh(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native
|
@Native
|
||||||
public static double sqrt(MessageContext ctx, double x) throws InterruptedException {
|
public static double sqrt(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.sqrt(x);
|
return java.lang.Math.sqrt(x);
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static double cbrt(MessageContext ctx, double x) throws InterruptedException {
|
public static double cbrt(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.cbrt(x);
|
return java.lang.Math.cbrt(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native
|
@Native
|
||||||
public static double hypot(MessageContext ctx, double ...vals) throws InterruptedException {
|
public static double hypot(Message ctx, double ...vals) throws InterruptedException {
|
||||||
var res = 0.;
|
var res = 0.;
|
||||||
for (var el : vals) {
|
for (var el : vals) {
|
||||||
var val = el;
|
var val = el;
|
||||||
@ -112,68 +112,68 @@ public class Math {
|
|||||||
return java.lang.Math.sqrt(res);
|
return java.lang.Math.sqrt(res);
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static int imul(MessageContext ctx, double a, double b) throws InterruptedException {
|
public static int imul(Message ctx, double a, double b) throws InterruptedException {
|
||||||
return (int)a * (int)b;
|
return (int)a * (int)b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native
|
@Native
|
||||||
public static double exp(MessageContext ctx, double x) throws InterruptedException {
|
public static double exp(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.exp(x);
|
return java.lang.Math.exp(x);
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static double expm1(MessageContext ctx, double x) throws InterruptedException {
|
public static double expm1(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.expm1(x);
|
return java.lang.Math.expm1(x);
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static double pow(MessageContext ctx, double x, double y) throws InterruptedException {
|
public static double pow(Message ctx, double x, double y) throws InterruptedException {
|
||||||
return java.lang.Math.pow(x, y);
|
return java.lang.Math.pow(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native
|
@Native
|
||||||
public static double log(MessageContext ctx, double x) throws InterruptedException {
|
public static double log(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.log(x);
|
return java.lang.Math.log(x);
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static double log10(MessageContext ctx, double x) throws InterruptedException {
|
public static double log10(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.log10(x);
|
return java.lang.Math.log10(x);
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static double log1p(MessageContext ctx, double x) throws InterruptedException {
|
public static double log1p(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.log1p(x);
|
return java.lang.Math.log1p(x);
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static double log2(MessageContext ctx, double x) throws InterruptedException {
|
public static double log2(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.log(x) / LN2;
|
return java.lang.Math.log(x) / LN2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native
|
@Native
|
||||||
public static double ceil(MessageContext ctx, double x) throws InterruptedException {
|
public static double ceil(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.ceil(x);
|
return java.lang.Math.ceil(x);
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static double floor(MessageContext ctx, double x) throws InterruptedException {
|
public static double floor(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.floor(x);
|
return java.lang.Math.floor(x);
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static double round(MessageContext ctx, double x) throws InterruptedException {
|
public static double round(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.round(x);
|
return java.lang.Math.round(x);
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static float fround(MessageContext ctx, double x) throws InterruptedException {
|
public static float fround(Message ctx, double x) throws InterruptedException {
|
||||||
return (float)x;
|
return (float)x;
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static double trunc(MessageContext ctx, double x) throws InterruptedException {
|
public static double trunc(Message ctx, double x) throws InterruptedException {
|
||||||
var _x = x;
|
var _x = x;
|
||||||
return java.lang.Math.floor(java.lang.Math.abs(_x)) * java.lang.Math.signum(_x);
|
return java.lang.Math.floor(java.lang.Math.abs(_x)) * java.lang.Math.signum(_x);
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static double abs(MessageContext ctx, double x) throws InterruptedException {
|
public static double abs(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.abs(x);
|
return java.lang.Math.abs(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native
|
@Native
|
||||||
public static double max(MessageContext ctx, double ...vals) throws InterruptedException {
|
public static double max(Message ctx, double ...vals) throws InterruptedException {
|
||||||
var res = Double.NEGATIVE_INFINITY;
|
var res = Double.NEGATIVE_INFINITY;
|
||||||
|
|
||||||
for (var el : vals) {
|
for (var el : vals) {
|
||||||
@ -184,7 +184,7 @@ public class Math {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static double min(MessageContext ctx, double ...vals) throws InterruptedException {
|
public static double min(Message ctx, double ...vals) throws InterruptedException {
|
||||||
var res = Double.POSITIVE_INFINITY;
|
var res = Double.POSITIVE_INFINITY;
|
||||||
|
|
||||||
for (var el : vals) {
|
for (var el : vals) {
|
||||||
@ -196,7 +196,7 @@ public class Math {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Native
|
@Native
|
||||||
public static double sign(MessageContext ctx, double x) throws InterruptedException {
|
public static double sign(Message ctx, double x) throws InterruptedException {
|
||||||
return java.lang.Math.signum(x);
|
return java.lang.Math.signum(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +205,7 @@ public class Math {
|
|||||||
return java.lang.Math.random();
|
return java.lang.Math.random();
|
||||||
}
|
}
|
||||||
@Native
|
@Native
|
||||||
public static int clz32(MessageContext ctx, double x) throws InterruptedException {
|
public static int clz32(Message ctx, double x) throws InterruptedException {
|
||||||
return Integer.numberOfLeadingZeros((int)x);
|
return Integer.numberOfLeadingZeros((int)x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import me.topchetoeu.jscript.engine.Context;
|
import me.topchetoeu.jscript.engine.Context;
|
||||||
import me.topchetoeu.jscript.engine.Environment;
|
import me.topchetoeu.jscript.engine.Environment;
|
||||||
import me.topchetoeu.jscript.engine.MessageContext;
|
import me.topchetoeu.jscript.engine.Message;
|
||||||
import me.topchetoeu.jscript.engine.values.ArrayValue;
|
import me.topchetoeu.jscript.engine.values.ArrayValue;
|
||||||
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
||||||
import me.topchetoeu.jscript.engine.values.NativeFunction;
|
import me.topchetoeu.jscript.engine.values.NativeFunction;
|
||||||
@ -297,9 +297,9 @@ public class PromisePolyfill {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handle(Context ctx, FunctionValue fulfill, FunctionValue reject) {
|
private void handle(Context ctx, FunctionValue fulfill, FunctionValue reject) {
|
||||||
if (state == STATE_FULFILLED) ctx.message.engine.pushMsg(true, new MessageContext(ctx.message.engine), fulfill, null, val);
|
if (state == STATE_FULFILLED) ctx.message.engine.pushMsg(true, new Message(ctx.message.engine), fulfill, null, val);
|
||||||
else if (state == STATE_REJECTED) {
|
else if (state == STATE_REJECTED) {
|
||||||
ctx.message.engine.pushMsg(true, new MessageContext(ctx.message.engine), reject, null, val);
|
ctx.message.engine.pushMsg(true, new Message(ctx.message.engine), reject, null, val);
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
else handles.add(new Handle(ctx, fulfill, reject));
|
else handles.add(new Handle(ctx, fulfill, reject));
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user