refactor: move NO_RETURN to Values, remove some casters from Values

This commit is contained in:
TopchetoEU 2024-01-06 17:43:47 +02:00
parent 71f735b812
commit 5f4011aa0c
Signed by: topchetoeu
GPG Key ID: 6531B8583E5F6ED4
10 changed files with 86 additions and 91 deletions

View File

@ -27,7 +27,7 @@ public interface DebugController {
* @param frame The frame in which execution is occuring * @param frame The frame in which execution is occuring
* @param instruction The instruction which was or will be executed * @param instruction The instruction which was or will be executed
* @param loc The most recent location the code frame has been at * @param loc The most recent location the code frame has been at
* @param returnVal The return value of the instruction, Runners.NO_RETURN if none * @param returnVal The return value of the instruction, Values.NO_RETURN if none
* @param error The error that the instruction threw, null if none * @param error The error that the instruction threw, null if none
* @param caught Whether or not the error has been caught * @param caught Whether or not the error has been caught
* @return Whether or not the frame should restart * @return Whether or not the frame should restart

View File

@ -17,7 +17,6 @@ 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.frame.CodeFrame; import me.topchetoeu.jscript.engine.frame.CodeFrame;
import me.topchetoeu.jscript.engine.frame.Runners;
import me.topchetoeu.jscript.engine.scope.GlobalScope; import me.topchetoeu.jscript.engine.scope.GlobalScope;
import me.topchetoeu.jscript.engine.values.ArrayValue; import me.topchetoeu.jscript.engine.values.ArrayValue;
import me.topchetoeu.jscript.engine.values.CodeFunction; import me.topchetoeu.jscript.engine.values.CodeFunction;
@ -906,7 +905,7 @@ public class SimpleDebugger implements Debugger {
if (error != null && (execptionType == CatchType.ALL || execptionType == CatchType.UNCAUGHT && !caught)) { if (error != null && (execptionType == CatchType.ALL || execptionType == CatchType.UNCAUGHT && !caught)) {
pauseException(ctx); pauseException(ctx);
} }
else if (loc != null && (state == State.STEPPING_IN || state == State.STEPPING_OVER) && returnVal != Runners.NO_RETURN && stepOutFrame == frame) { else if (loc != null && (state == State.STEPPING_IN || state == State.STEPPING_OVER) && returnVal != Values.NO_RETURN && stepOutFrame == frame) {
pauseDebug(ctx, null); pauseDebug(ctx, null);
} }
else if (isBreakpointable && locToBreakpoint.containsKey(loc)) { else if (isBreakpointable && locToBreakpoint.containsKey(loc)) {
@ -935,7 +934,7 @@ public class SimpleDebugger implements Debugger {
case STEPPING_IN: case STEPPING_IN:
case STEPPING_OVER: case STEPPING_OVER:
if (stepOutFrame.frame == frame.frame) { if (stepOutFrame.frame == frame.frame) {
if (returnVal != Runners.NO_RETURN || error != null) { if (returnVal != Values.NO_RETURN || error != null) {
state = State.STEPPING_OUT; state = State.STEPPING_OUT;
continue; continue;
} }

View File

@ -191,18 +191,18 @@ public class CodeFrame {
} }
public Object next(Object value, Object returnValue, EngineException error) { public Object next(Object value, Object returnValue, EngineException error) {
if (value != Runners.NO_RETURN) push(ctx, value); if (value != Values.NO_RETURN) push(ctx, value);
Instruction instr = null; Instruction instr = null;
if (codePtr >= 0 && codePtr < function.body.length) instr = function.body[codePtr]; if (codePtr >= 0 && codePtr < function.body.length) instr = function.body[codePtr];
if (returnValue == Runners.NO_RETURN && error == null) { if (returnValue == Values.NO_RETURN && error == null) {
try { try {
if (Thread.currentThread().isInterrupted()) throw new InterruptException(); if (Thread.currentThread().isInterrupted()) throw new InterruptException();
if (instr == null) returnValue = null; if (instr == null) returnValue = null;
else { else {
DebugContext.get(ctx).onInstruction(ctx, this, instr, Runners.NO_RETURN, null, false); DebugContext.get(ctx).onInstruction(ctx, this, instr, Values.NO_RETURN, null, false);
if (instr.location != null) prevLoc = instr.location; if (instr.location != null) prevLoc = instr.location;
@ -227,7 +227,7 @@ public class CodeFrame {
if (tryCtx.hasCatch()) newCtx = tryCtx._catch(error); if (tryCtx.hasCatch()) newCtx = tryCtx._catch(error);
else if (tryCtx.hasFinally()) newCtx = tryCtx._finally(PendingResult.ofThrow(error, instr)); else if (tryCtx.hasFinally()) newCtx = tryCtx._finally(PendingResult.ofThrow(error, instr));
} }
else if (returnValue != Runners.NO_RETURN) { else if (returnValue != Values.NO_RETURN) {
if (tryCtx.hasFinally()) newCtx = tryCtx._finally(PendingResult.ofReturn(returnValue, instr)); if (tryCtx.hasFinally()) newCtx = tryCtx._finally(PendingResult.ofReturn(returnValue, instr));
} }
else if (jumpFlag && !tryCtx.inBounds(codePtr)) { else if (jumpFlag && !tryCtx.inBounds(codePtr)) {
@ -254,7 +254,7 @@ public class CodeFrame {
tryStack.push(newCtx); tryStack.push(newCtx);
} }
error = null; error = null;
returnValue = Runners.NO_RETURN; returnValue = Values.NO_RETURN;
break; break;
} }
else { else {
@ -272,7 +272,7 @@ public class CodeFrame {
tryStack.pop(); tryStack.pop();
codePtr = tryCtx.end; codePtr = tryCtx.end;
if (tryCtx.result.instruction != null) instr = tryCtx.result.instruction; if (tryCtx.result.instruction != null) instr = tryCtx.result.instruction;
if (!jumpFlag && returnValue == Runners.NO_RETURN && error == null) { if (!jumpFlag && returnValue == Values.NO_RETURN && error == null) {
if (tryCtx.result.isJump) { if (tryCtx.result.isJump) {
codePtr = tryCtx.result.ptr; codePtr = tryCtx.result.ptr;
jumpFlag = true; jumpFlag = true;
@ -300,12 +300,12 @@ public class CodeFrame {
DebugContext.get(ctx).onInstruction(ctx, this, instr, null, error, caught); DebugContext.get(ctx).onInstruction(ctx, this, instr, null, error, caught);
throw error; throw error;
} }
if (returnValue != Runners.NO_RETURN) { if (returnValue != Values.NO_RETURN) {
DebugContext.get(ctx).onInstruction(ctx, this, instr, returnValue, null, false); DebugContext.get(ctx).onInstruction(ctx, this, instr, returnValue, null, false);
return returnValue; return returnValue;
} }
return Runners.NO_RETURN; return Values.NO_RETURN;
} }
public void onPush() { public void onPush() {

View File

@ -10,14 +10,13 @@ import me.topchetoeu.jscript.engine.Operation;
import me.topchetoeu.jscript.engine.scope.ValueVariable; import me.topchetoeu.jscript.engine.scope.ValueVariable;
import me.topchetoeu.jscript.engine.values.ArrayValue; import me.topchetoeu.jscript.engine.values.ArrayValue;
import me.topchetoeu.jscript.engine.values.CodeFunction; import me.topchetoeu.jscript.engine.values.CodeFunction;
import me.topchetoeu.jscript.engine.values.FunctionValue;
import me.topchetoeu.jscript.engine.values.ObjectValue; import me.topchetoeu.jscript.engine.values.ObjectValue;
import me.topchetoeu.jscript.engine.values.Symbol; 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.exceptions.EngineException; import me.topchetoeu.jscript.exceptions.EngineException;
public class Runners { public class Runners {
public static final Object NO_RETURN = new Object();
public static Object execReturn(Context ctx, Instruction instr, CodeFrame frame) { public static Object execReturn(Context ctx, Instruction instr, CodeFrame frame) {
return frame.pop(); return frame.pop();
} }
@ -36,7 +35,7 @@ public class Runners {
frame.push(ctx, Values.call(ctx, func, thisArg, callArgs)); frame.push(ctx, Values.call(ctx, func, thisArg, callArgs));
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execCallNew(Context ctx, Instruction instr, CodeFrame frame) { public static Object execCallNew(Context ctx, Instruction instr, CodeFrame frame) {
var callArgs = frame.take(instr.get(0)); var callArgs = frame.take(instr.get(0));
@ -45,14 +44,14 @@ public class Runners {
frame.push(ctx, Values.callNew(ctx, funcObj, callArgs)); frame.push(ctx, Values.callNew(ctx, funcObj, callArgs));
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execMakeVar(Context ctx, Instruction instr, CodeFrame frame) { public static Object execMakeVar(Context ctx, Instruction instr, CodeFrame frame) {
var name = (String)instr.get(0); var name = (String)instr.get(0);
ctx.environment.global.define(name); ctx.environment.global.define(name);
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execDefProp(Context ctx, Instruction instr, CodeFrame frame) { public static Object execDefProp(Context ctx, Instruction instr, CodeFrame frame) {
var setter = frame.pop(); var setter = frame.pop();
@ -60,14 +59,14 @@ public class Runners {
var name = frame.pop(); var name = frame.pop();
var obj = frame.pop(); var obj = frame.pop();
if (getter != null && !Values.isFunction(getter)) throw EngineException.ofType("Getter must be a function or undefined."); if (getter != null && !(getter instanceof FunctionValue)) throw EngineException.ofType("Getter must be a function or undefined.");
if (setter != null && !Values.isFunction(setter)) throw EngineException.ofType("Setter must be a function or undefined."); if (setter != null && !(setter instanceof FunctionValue)) throw EngineException.ofType("Setter must be a function or undefined.");
if (!Values.isObject(obj)) throw EngineException.ofType("Property apply target must be an object."); if (!(obj instanceof ObjectValue)) throw EngineException.ofType("Property apply target must be an object.");
Values.object(obj).defineProperty(ctx, name, Values.function(getter), Values.function(setter), false, false); Values.object(obj).defineProperty(ctx, name, Values.function(getter), Values.function(setter), false, false);
frame.push(ctx, obj); frame.push(ctx, obj);
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execInstanceof(Context ctx, Instruction instr, CodeFrame frame) { public static Object execInstanceof(Context ctx, Instruction instr, CodeFrame frame) {
var type = frame.pop(); var type = frame.pop();
@ -82,7 +81,7 @@ public class Runners {
} }
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execKeys(Context ctx, Instruction instr, CodeFrame frame) { public static Object execKeys(Context ctx, Instruction instr, CodeFrame frame) {
var val = frame.pop(); var val = frame.pop();
@ -100,7 +99,7 @@ public class Runners {
} }
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execTryStart(Context ctx, Instruction instr, CodeFrame frame) { public static Object execTryStart(Context ctx, Instruction instr, CodeFrame frame) {
@ -112,11 +111,11 @@ public class Runners {
int end = (int)instr.get(2) + start; int end = (int)instr.get(2) + start;
frame.addTry(start, end, catchStart, finallyStart); frame.addTry(start, end, catchStart, finallyStart);
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execTryEnd(Context ctx, Instruction instr, CodeFrame frame) { public static Object execTryEnd(Context ctx, Instruction instr, CodeFrame frame) {
frame.popTryFlag = true; frame.popTryFlag = true;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execDup(Context ctx, Instruction instr, CodeFrame frame) { public static Object execDup(Context ctx, Instruction instr, CodeFrame frame) {
@ -127,17 +126,17 @@ public class Runners {
} }
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execLoadUndefined(Context ctx, Instruction instr, CodeFrame frame) { public static Object execLoadUndefined(Context ctx, Instruction instr, CodeFrame frame) {
frame.push(ctx, null); frame.push(ctx, null);
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execLoadValue(Context ctx, Instruction instr, CodeFrame frame) { public static Object execLoadValue(Context ctx, Instruction instr, CodeFrame frame) {
frame.push(ctx, instr.get(0)); frame.push(ctx, instr.get(0));
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execLoadVar(Context ctx, Instruction instr, CodeFrame frame) { public static Object execLoadVar(Context ctx, Instruction instr, CodeFrame frame) {
var i = instr.get(0); var i = instr.get(0);
@ -146,24 +145,24 @@ public class Runners {
else frame.push(ctx, frame.scope.get((int)i).get(ctx)); else frame.push(ctx, frame.scope.get((int)i).get(ctx));
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execLoadObj(Context ctx, Instruction instr, CodeFrame frame) { public static Object execLoadObj(Context ctx, Instruction instr, CodeFrame frame) {
frame.push(ctx, new ObjectValue()); frame.push(ctx, new ObjectValue());
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execLoadGlob(Context ctx, Instruction instr, CodeFrame frame) { public static Object execLoadGlob(Context ctx, Instruction instr, CodeFrame frame) {
frame.push(ctx, ctx.environment.global.obj); frame.push(ctx, ctx.environment.global.obj);
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execLoadArr(Context ctx, Instruction instr, CodeFrame frame) { public static Object execLoadArr(Context ctx, Instruction instr, CodeFrame frame) {
var res = new ArrayValue(); var res = new ArrayValue();
res.setSize(instr.get(0)); res.setSize(instr.get(0));
frame.push(ctx, res); frame.push(ctx, res);
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execLoadFunc(Context ctx, Instruction instr, CodeFrame frame) { public static Object execLoadFunc(Context ctx, Instruction instr, CodeFrame frame) {
long id = (Long)instr.get(0); long id = (Long)instr.get(0);
@ -178,7 +177,7 @@ public class Runners {
frame.push(ctx, func); frame.push(ctx, func);
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execLoadMember(Context ctx, Instruction instr, CodeFrame frame) { public static Object execLoadMember(Context ctx, Instruction instr, CodeFrame frame) {
var key = frame.pop(); var key = frame.pop();
@ -191,7 +190,7 @@ public class Runners {
throw EngineException.ofType(e.getMessage()); throw EngineException.ofType(e.getMessage());
} }
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execLoadKeyMember(Context ctx, Instruction instr, CodeFrame frame) { public static Object execLoadKeyMember(Context ctx, Instruction instr, CodeFrame frame) {
frame.push(ctx, instr.get(0)); frame.push(ctx, instr.get(0));
@ -205,13 +204,13 @@ public class Runners {
throw EngineException.ofSyntax("Regex is not supported."); throw EngineException.ofSyntax("Regex is not supported.");
} }
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execDiscard(Context ctx, Instruction instr, CodeFrame frame) { public static Object execDiscard(Context ctx, Instruction instr, CodeFrame frame) {
frame.pop(); frame.pop();
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execStoreMember(Context ctx, Instruction instr, CodeFrame frame) { public static Object execStoreMember(Context ctx, Instruction instr, CodeFrame frame) {
var val = frame.pop(); var val = frame.pop();
@ -221,7 +220,7 @@ public class Runners {
if (!Values.setMember(ctx, obj, key, val)) throw EngineException.ofSyntax("Can't set member '" + key + "'."); if (!Values.setMember(ctx, obj, key, val)) throw EngineException.ofSyntax("Can't set member '" + key + "'.");
if ((boolean)instr.get(0)) frame.push(ctx, val); if ((boolean)instr.get(0)) frame.push(ctx, val);
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execStoreVar(Context ctx, Instruction instr, CodeFrame frame) { public static Object execStoreVar(Context ctx, Instruction instr, CodeFrame frame) {
var val = (boolean)instr.get(1) ? frame.peek() : frame.pop(); var val = (boolean)instr.get(1) ? frame.peek() : frame.pop();
@ -231,18 +230,18 @@ public class Runners {
else frame.scope.get((int)i).set(ctx, val); else frame.scope.get((int)i).set(ctx, val);
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execStoreSelfFunc(Context ctx, Instruction instr, CodeFrame frame) { public static Object execStoreSelfFunc(Context ctx, Instruction instr, CodeFrame frame) {
frame.scope.locals[(int)instr.get(0)].set(ctx, frame.function); frame.scope.locals[(int)instr.get(0)].set(ctx, frame.function);
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execJmp(Context ctx, Instruction instr, CodeFrame frame) { public static Object execJmp(Context ctx, Instruction instr, CodeFrame frame) {
frame.codePtr += (int)instr.get(0); frame.codePtr += (int)instr.get(0);
frame.jumpFlag = true; frame.jumpFlag = true;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execJmpIf(Context ctx, Instruction instr, CodeFrame frame) { public static Object execJmpIf(Context ctx, Instruction instr, CodeFrame frame) {
if (Values.toBoolean(frame.pop())) { if (Values.toBoolean(frame.pop())) {
@ -250,7 +249,7 @@ public class Runners {
frame.jumpFlag = true; frame.jumpFlag = true;
} }
else frame.codePtr ++; else frame.codePtr ++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execJmpIfNot(Context ctx, Instruction instr, CodeFrame frame) { public static Object execJmpIfNot(Context ctx, Instruction instr, CodeFrame frame) {
if (Values.not(frame.pop())) { if (Values.not(frame.pop())) {
@ -258,7 +257,7 @@ public class Runners {
frame.jumpFlag = true; frame.jumpFlag = true;
} }
else frame.codePtr ++; else frame.codePtr ++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execIn(Context ctx, Instruction instr, CodeFrame frame) { public static Object execIn(Context ctx, Instruction instr, CodeFrame frame) {
@ -267,7 +266,7 @@ public class Runners {
frame.push(ctx, Values.hasMember(ctx, obj, index, false)); frame.push(ctx, Values.hasMember(ctx, obj, index, false));
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execTypeof(Context ctx, Instruction instr, CodeFrame frame) { public static Object execTypeof(Context ctx, Instruction instr, CodeFrame frame) {
String name = instr.get(0); String name = instr.get(0);
@ -284,11 +283,11 @@ public class Runners {
frame.push(ctx, Values.type(obj)); frame.push(ctx, Values.type(obj));
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execNop(Context ctx, Instruction instr, CodeFrame frame) { public static Object execNop(Context ctx, Instruction instr, CodeFrame frame) {
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execDelete(Context ctx, Instruction instr, CodeFrame frame) { public static Object execDelete(Context ctx, Instruction instr, CodeFrame frame) {
@ -297,7 +296,7 @@ public class Runners {
if (!Values.deleteMember(ctx, val, key)) throw EngineException.ofSyntax("Can't delete member '" + key + "'."); if (!Values.deleteMember(ctx, val, key)) throw EngineException.ofSyntax("Can't delete member '" + key + "'.");
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object execOperation(Context ctx, Instruction instr, CodeFrame frame) { public static Object execOperation(Context ctx, Instruction instr, CodeFrame frame) {
@ -308,7 +307,7 @@ public class Runners {
frame.push(ctx, Values.operation(ctx, op, args)); frame.push(ctx, Values.operation(ctx, op, args));
frame.codePtr++; frame.codePtr++;
return NO_RETURN; return Values.NO_RETURN;
} }
public static Object exec(Context ctx, Instruction instr, CodeFrame frame) { public static Object exec(Context ctx, Instruction instr, CodeFrame frame) {

View File

@ -6,7 +6,6 @@ import me.topchetoeu.jscript.compilation.Instruction;
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.frame.CodeFrame; import me.topchetoeu.jscript.engine.frame.CodeFrame;
import me.topchetoeu.jscript.engine.frame.Runners;
import me.topchetoeu.jscript.engine.scope.ValueVariable; import me.topchetoeu.jscript.engine.scope.ValueVariable;
public class CodeFunction extends FunctionValue { public class CodeFunction extends FunctionValue {
@ -37,8 +36,8 @@ public class CodeFunction extends FunctionValue {
try { try {
while (true) { while (true) {
var res = frame.next(Runners.NO_RETURN, Runners.NO_RETURN, null); var res = frame.next(Values.NO_RETURN, Values.NO_RETURN, null);
if (res != Runners.NO_RETURN) return res; if (res != Values.NO_RETURN) return res;
} }
} }
finally { finally {

View File

@ -167,7 +167,7 @@ public class ObjectValue {
prototype = null; prototype = null;
return true; return true;
} }
else if (Values.isObject(val)) { else if (val instanceof ObjectValue) {
var obj = Values.object(val); var obj = Values.object(val);
if (ctx != null) { if (ctx != null) {

View File

@ -40,10 +40,8 @@ public class Values {
} }
public static final Object NULL = new Object(); public static final Object NULL = new Object();
public static final Object NO_RETURN = new Object();
public static boolean isObject(Object val) { return val instanceof ObjectValue; }
public static boolean isFunction(Object val) { return val instanceof FunctionValue; }
public static boolean isArray(Object val) { return val instanceof ArrayValue; }
public static boolean isWrapper(Object val) { return val instanceof NativeWrapper; } public static boolean isWrapper(Object val) { return val instanceof NativeWrapper; }
public static boolean isWrapper(Object val, Class<?> clazz) { public static boolean isWrapper(Object val, Class<?> clazz) {
if (!isWrapper(val)) return false; if (!isWrapper(val)) return false;
@ -90,8 +88,8 @@ public class Values {
private static Object tryCallConvertFunc(Context ctx, Object obj, String name) { private static Object tryCallConvertFunc(Context ctx, Object obj, String name) {
var func = getMember(ctx, obj, name); var func = getMember(ctx, obj, name);
if (func != null) { if (func instanceof FunctionValue) {
var res = ((FunctionValue)func).call(ctx, obj); var res = Values.call(ctx, func, obj);
if (isPrimitive(res)) return res; if (isPrimitive(res)) return res;
} }
@ -285,7 +283,7 @@ public class Values {
obj = normalize(ctx, obj); key = normalize(ctx, key); obj = normalize(ctx, obj); key = normalize(ctx, key);
if (obj == null) throw new IllegalArgumentException("Tried to access member of undefined."); if (obj == null) throw new IllegalArgumentException("Tried to access member of undefined.");
if (obj == NULL) throw new IllegalArgumentException("Tried to access member of null."); if (obj == NULL) throw new IllegalArgumentException("Tried to access member of null.");
if (isObject(obj)) return object(obj).getMember(ctx, key); if (obj instanceof ObjectValue) return object(obj).getMember(ctx, key);
if (obj instanceof String && key instanceof Number) { if (obj instanceof String && key instanceof Number) {
var i = number(key); var i = number(key);
@ -311,7 +309,7 @@ public class Values {
if (obj == null) throw EngineException.ofType("Tried to access member of undefined."); if (obj == null) throw EngineException.ofType("Tried to access member of undefined.");
if (obj == NULL) throw EngineException.ofType("Tried to access member of null."); if (obj == NULL) throw EngineException.ofType("Tried to access member of null.");
if (key != null && "__proto__".equals(key)) return setPrototype(ctx, obj, val); if (key != null && "__proto__".equals(key)) return setPrototype(ctx, obj, val);
if (isObject(obj)) return object(obj).setMember(ctx, key, val, false); if (obj instanceof ObjectValue) return object(obj).setMember(ctx, key, val, false);
var proto = getPrototype(ctx, obj); var proto = getPrototype(ctx, obj);
return proto.setMember(ctx, key, val, obj, true); return proto.setMember(ctx, key, val, obj, true);
@ -321,7 +319,7 @@ public class Values {
obj = normalize(ctx, obj); key = normalize(ctx, key); obj = normalize(ctx, obj); key = normalize(ctx, key);
if ("__proto__".equals(key)) return true; if ("__proto__".equals(key)) return true;
if (isObject(obj)) return object(obj).hasMember(ctx, key, own); if (obj instanceof ObjectValue) return object(obj).hasMember(ctx, key, own);
if (obj instanceof String && key instanceof Number) { if (obj instanceof String && key instanceof Number) {
var i = number(key); var i = number(key);
@ -338,13 +336,13 @@ public class Values {
if (obj == null || obj == NULL) return false; if (obj == null || obj == NULL) return false;
obj = normalize(ctx, obj); key = normalize(ctx, key); obj = normalize(ctx, obj); key = normalize(ctx, key);
if (isObject(obj)) return object(obj).deleteMember(ctx, key); if (obj instanceof ObjectValue) return object(obj).deleteMember(ctx, key);
else return false; else return false;
} }
public static ObjectValue getPrototype(Context ctx, Object obj) { public static ObjectValue getPrototype(Context ctx, Object obj) {
if (obj == null || obj == NULL) return null; if (obj == null || obj == NULL) return null;
obj = normalize(ctx, obj); obj = normalize(ctx, obj);
if (isObject(obj)) return object(obj).getPrototype(ctx); if (obj instanceof ObjectValue) return object(obj).getPrototype(ctx);
if (ctx == null) return null; if (ctx == null) return null;
if (obj instanceof String) return ctx.get(Environment.STRING_PROTO); if (obj instanceof String) return ctx.get(Environment.STRING_PROTO);
@ -356,12 +354,12 @@ public class Values {
} }
public static boolean setPrototype(Context ctx, Object obj, Object proto) { public static boolean setPrototype(Context ctx, Object obj, Object proto) {
obj = normalize(ctx, obj); obj = normalize(ctx, obj);
return isObject(obj) && object(obj).setPrototype(ctx, proto); return obj instanceof ObjectValue && object(obj).setPrototype(ctx, proto);
} }
public static List<Object> getMembers(Context ctx, Object obj, boolean own, boolean includeNonEnumerable) { public static List<Object> getMembers(Context ctx, Object obj, boolean own, boolean includeNonEnumerable) {
List<Object> res = new ArrayList<>(); List<Object> res = new ArrayList<>();
if (isObject(obj)) res = object(obj).keys(includeNonEnumerable); if (obj instanceof ObjectValue) res = object(obj).keys(includeNonEnumerable);
if (obj instanceof String) { if (obj instanceof String) {
for (var i = 0; i < ((String)obj).length(); i++) res.add((double)i); for (var i = 0; i < ((String)obj).length(); i++) res.add((double)i);
} }
@ -397,7 +395,7 @@ public class Values {
} }
public static Object call(Context ctx, Object func, Object thisArg, Object ...args) { public static Object call(Context ctx, Object func, Object thisArg, Object ...args) {
if (!isFunction(func)) throw EngineException.ofType("Tried to call a non-function value."); if (!(func instanceof FunctionValue)) throw EngineException.ofType("Tried to call a non-function value.");
return function(func).call(ctx, thisArg, args); return function(func).call(ctx, thisArg, args);
} }
public static Object callNew(Context ctx, Object func, Object ...args) { public static Object callNew(Context ctx, Object func, Object ...args) {
@ -557,13 +555,13 @@ public class Values {
var symbol = Symbol.get("Symbol.iterator"); var symbol = Symbol.get("Symbol.iterator");
var iteratorFunc = getMember(ctx, obj, symbol); var iteratorFunc = getMember(ctx, obj, symbol);
if (!isFunction(iteratorFunc)) return Collections.emptyIterator(); if (!(iteratorFunc instanceof FunctionValue)) return Collections.emptyIterator();
var iterator = iteratorFunc instanceof FunctionValue ? var iterator = iteratorFunc instanceof FunctionValue ?
((FunctionValue)iteratorFunc).call(ctx, obj, obj) : ((FunctionValue)iteratorFunc).call(ctx, obj, obj) :
iteratorFunc; iteratorFunc;
var nextFunc = getMember(ctx, call(ctx, iteratorFunc, obj), "next"); var nextFunc = getMember(ctx, call(ctx, iteratorFunc, obj), "next");
if (!isFunction(nextFunc)) return Collections.emptyIterator(); if (!(nextFunc instanceof FunctionValue)) return Collections.emptyIterator();
return new Iterator<Object>() { return new Iterator<Object>() {
private Object value = null; private Object value = null;

View File

@ -2,10 +2,10 @@ package me.topchetoeu.jscript.lib;
import me.topchetoeu.jscript.engine.Context; import me.topchetoeu.jscript.engine.Context;
import me.topchetoeu.jscript.engine.frame.CodeFrame; import me.topchetoeu.jscript.engine.frame.CodeFrame;
import me.topchetoeu.jscript.engine.frame.Runners;
import me.topchetoeu.jscript.engine.values.CodeFunction; 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.NativeFunction;
import me.topchetoeu.jscript.engine.values.Values;
import me.topchetoeu.jscript.exceptions.EngineException; import me.topchetoeu.jscript.exceptions.EngineException;
import me.topchetoeu.jscript.interop.Arguments; import me.topchetoeu.jscript.interop.Arguments;
import me.topchetoeu.jscript.interop.WrapperName; import me.topchetoeu.jscript.interop.WrapperName;
@ -28,11 +28,11 @@ public class AsyncFunctionLib extends FunctionValue {
awaiting = false; awaiting = false;
while (!awaiting) { while (!awaiting) {
try { try {
res = frame.next(inducedValue, Runners.NO_RETURN, inducedError); res = frame.next(inducedValue, Values.NO_RETURN, inducedError);
inducedValue = Runners.NO_RETURN; inducedValue = Values.NO_RETURN;
inducedError = null; inducedError = null;
if (res != Runners.NO_RETURN) { if (res != Values.NO_RETURN) {
promise.fulfill(ctx, res); promise.fulfill(ctx, res);
break; break;
} }
@ -52,7 +52,7 @@ public class AsyncFunctionLib extends FunctionValue {
} }
@Override @Override
public void onReject(EngineException err) { public void onReject(EngineException err) {
next(ctx, Runners.NO_RETURN, err); next(ctx, Values.NO_RETURN, err);
} }
}); });
} }
@ -70,7 +70,7 @@ public class AsyncFunctionLib extends FunctionValue {
var func = factory.call(ctx, thisArg, new NativeFunction("await", handler::await)); var func = factory.call(ctx, thisArg, new NativeFunction("await", handler::await));
if (!(func instanceof CodeFunction)) throw EngineException.ofType("Return value of argument must be a js function."); if (!(func instanceof CodeFunction)) throw EngineException.ofType("Return value of argument must be a js function.");
handler.frame = new CodeFrame(ctx, thisArg, args, (CodeFunction)func); handler.frame = new CodeFrame(ctx, thisArg, args, (CodeFunction)func);
handler.next(ctx, Runners.NO_RETURN, null); handler.next(ctx, Values.NO_RETURN, null);
return handler.promise; return handler.promise;
} }

View File

@ -4,8 +4,8 @@ import java.util.Map;
import me.topchetoeu.jscript.engine.Context; import me.topchetoeu.jscript.engine.Context;
import me.topchetoeu.jscript.engine.frame.CodeFrame; import me.topchetoeu.jscript.engine.frame.CodeFrame;
import me.topchetoeu.jscript.engine.frame.Runners;
import me.topchetoeu.jscript.engine.values.ObjectValue; import me.topchetoeu.jscript.engine.values.ObjectValue;
import me.topchetoeu.jscript.engine.values.Values;
import me.topchetoeu.jscript.exceptions.EngineException; import me.topchetoeu.jscript.exceptions.EngineException;
import me.topchetoeu.jscript.interop.Arguments; import me.topchetoeu.jscript.interop.Arguments;
import me.topchetoeu.jscript.interop.Expose; import me.topchetoeu.jscript.interop.Expose;
@ -24,7 +24,7 @@ public class AsyncGeneratorLib {
if (inducedError != null) throw inducedError; if (inducedError != null) throw inducedError;
currPromise.fulfill(ctx, new ObjectValue(ctx, Map.of( currPromise.fulfill(ctx, new ObjectValue(ctx, Map.of(
"done", true, "done", true,
"value", inducedReturn == Runners.NO_RETURN ? null : inducedReturn "value", inducedReturn == Values.NO_RETURN ? null : inducedReturn
))); )));
return; return;
} }
@ -36,10 +36,10 @@ public class AsyncGeneratorLib {
while (state == 0) { while (state == 0) {
try { try {
res = frame.next(inducedValue, inducedReturn, inducedError); res = frame.next(inducedValue, inducedReturn, inducedError);
inducedValue = inducedReturn = Runners.NO_RETURN; inducedValue = inducedReturn = Values.NO_RETURN;
inducedError = null; inducedError = null;
if (res != Runners.NO_RETURN) { if (res != Values.NO_RETURN) {
var obj = new ObjectValue(); var obj = new ObjectValue();
obj.defineProperty(ctx, "done", true); obj.defineProperty(ctx, "done", true);
obj.defineProperty(ctx, "value", res); obj.defineProperty(ctx, "value", res);
@ -57,10 +57,10 @@ public class AsyncGeneratorLib {
if (state == 1) { if (state == 1) {
PromiseLib.handle(ctx, frame.pop(), new Handle() { PromiseLib.handle(ctx, frame.pop(), new Handle() {
@Override public void onFulfil(Object val) { @Override public void onFulfil(Object val) {
next(ctx, val, Runners.NO_RETURN, null); next(ctx, val, Values.NO_RETURN, null);
} }
@Override public void onReject(EngineException err) { @Override public void onReject(EngineException err) {
next(ctx, Runners.NO_RETURN, Runners.NO_RETURN, err); next(ctx, Values.NO_RETURN, Values.NO_RETURN, err);
} }
}); });
} }
@ -90,18 +90,18 @@ public class AsyncGeneratorLib {
@Expose public PromiseLib __next(Arguments args) { @Expose public PromiseLib __next(Arguments args) {
this.currPromise = new PromiseLib(); this.currPromise = new PromiseLib();
if (args.has(0)) next(args.ctx, args.get(0), Runners.NO_RETURN, null); if (args.has(0)) next(args.ctx, args.get(0), Values.NO_RETURN, null);
else next(args.ctx, Runners.NO_RETURN, Runners.NO_RETURN, null); else next(args.ctx, Values.NO_RETURN, Values.NO_RETURN, null);
return this.currPromise; return this.currPromise;
} }
@Expose public PromiseLib __return(Arguments args) { @Expose public PromiseLib __return(Arguments args) {
this.currPromise = new PromiseLib(); this.currPromise = new PromiseLib();
next(args.ctx, Runners.NO_RETURN, args.get(0), null); next(args.ctx, Values.NO_RETURN, args.get(0), null);
return this.currPromise; return this.currPromise;
} }
@Expose public PromiseLib __throw(Arguments args) { @Expose public PromiseLib __throw(Arguments args) {
this.currPromise = new PromiseLib(); this.currPromise = new PromiseLib();
next(args.ctx, Runners.NO_RETURN, Runners.NO_RETURN, new EngineException(args.get(0)).setCtx(args.ctx)); next(args.ctx, Values.NO_RETURN, Values.NO_RETURN, new EngineException(args.get(0)).setCtx(args.ctx));
return this.currPromise; return this.currPromise;
} }
} }

View File

@ -2,8 +2,8 @@ package me.topchetoeu.jscript.lib;
import me.topchetoeu.jscript.engine.Context; import me.topchetoeu.jscript.engine.Context;
import me.topchetoeu.jscript.engine.frame.CodeFrame; import me.topchetoeu.jscript.engine.frame.CodeFrame;
import me.topchetoeu.jscript.engine.frame.Runners;
import me.topchetoeu.jscript.engine.values.ObjectValue; import me.topchetoeu.jscript.engine.values.ObjectValue;
import me.topchetoeu.jscript.engine.values.Values;
import me.topchetoeu.jscript.exceptions.EngineException; import me.topchetoeu.jscript.exceptions.EngineException;
import me.topchetoeu.jscript.interop.Arguments; import me.topchetoeu.jscript.interop.Arguments;
import me.topchetoeu.jscript.interop.Expose; import me.topchetoeu.jscript.interop.Expose;
@ -17,10 +17,10 @@ public class GeneratorLib {
private ObjectValue next(Context ctx, Object inducedValue, Object inducedReturn, EngineException inducedError) { private ObjectValue next(Context ctx, Object inducedValue, Object inducedReturn, EngineException inducedError) {
if (done) { if (done) {
if (inducedError != Runners.NO_RETURN) throw inducedError; if (inducedError != Values.NO_RETURN) throw inducedError;
var res = new ObjectValue(); var res = new ObjectValue();
res.defineProperty(ctx, "done", true); res.defineProperty(ctx, "done", true);
res.defineProperty(ctx, "value", inducedReturn == Runners.NO_RETURN ? null : inducedReturn); res.defineProperty(ctx, "value", inducedReturn == Values.NO_RETURN ? null : inducedReturn);
return res; return res;
} }
@ -31,9 +31,9 @@ public class GeneratorLib {
while (!yielding) { while (!yielding) {
try { try {
res = frame.next(inducedValue, inducedReturn, inducedError); res = frame.next(inducedValue, inducedReturn, inducedError);
inducedReturn = Runners.NO_RETURN; inducedReturn = Values.NO_RETURN;
inducedError = null; inducedError = null;
if (res != Runners.NO_RETURN) { if (res != Values.NO_RETURN) {
done = true; done = true;
break; break;
} }
@ -55,14 +55,14 @@ public class GeneratorLib {
} }
@Expose public ObjectValue __next(Arguments args) { @Expose public ObjectValue __next(Arguments args) {
if (args.n() == 0) return next(args.ctx, Runners.NO_RETURN, Runners.NO_RETURN, null); if (args.n() == 0) return next(args.ctx, Values.NO_RETURN, Values.NO_RETURN, null);
else return next(args.ctx, args.get(0), Runners.NO_RETURN, null); else return next(args.ctx, args.get(0), Values.NO_RETURN, null);
} }
@Expose public ObjectValue __throw(Arguments args) { @Expose public ObjectValue __throw(Arguments args) {
return next(args.ctx, Runners.NO_RETURN, Runners.NO_RETURN, new EngineException(args.get(0)).setCtx(args.ctx)); return next(args.ctx, Values.NO_RETURN, Values.NO_RETURN, new EngineException(args.get(0)).setCtx(args.ctx));
} }
@Expose public ObjectValue __return(Arguments args) { @Expose public ObjectValue __return(Arguments args) {
return next(args.ctx, Runners.NO_RETURN, args.get(0), null); return next(args.ctx, Values.NO_RETURN, args.get(0), null);
} }
@Override public String toString() { @Override public String toString() {