ES6 Object and assignment destructors + object stuff #28
@ -404,10 +404,10 @@ public class Instruction {
|
||||
return new Instruction(Type.LOAD_ARR, count);
|
||||
}
|
||||
public static Instruction dup() {
|
||||
return new Instruction(Type.DUP, 1);
|
||||
return new Instruction(Type.DUP, 1, 0);
|
||||
}
|
||||
public static Instruction dup(int count) {
|
||||
return new Instruction(Type.DUP, count);
|
||||
public static Instruction dup(int count, int offset) {
|
||||
return new Instruction(Type.DUP, count, offset);
|
||||
}
|
||||
|
||||
public static Instruction storeVar(int i) {
|
||||
|
@ -1,7 +1,9 @@
|
||||
package me.topchetoeu.jscript.compilation;
|
||||
|
||||
import me.topchetoeu.jscript.common.Operation;
|
||||
|
||||
public interface AssignableNode {
|
||||
public abstract Node toAssign(Node val, Operation operation);
|
||||
public void compileBeforeAssign(CompileResult target, boolean operator);
|
||||
public void compileAfterAssign(CompileResult target, boolean operator, boolean pollute);
|
||||
public default String assignName() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ public abstract class FunctionNode extends Node {
|
||||
return new CompileResult(env, scope, params.params.size(), target -> {
|
||||
if (params.params.size() > 0) {
|
||||
target.add(Instruction.loadArgs(true));
|
||||
if (params.params.size() > 1) target.add(Instruction.dup(params.params.size() - 1));
|
||||
if (params.params.size() > 1) target.add(Instruction.dup(params.params.size() - 1, 0));
|
||||
var i = 0;
|
||||
|
||||
for (var param : params.params) {
|
||||
|
@ -39,6 +39,7 @@ import me.topchetoeu.jscript.compilation.values.operations.ChangeNode;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.DiscardNode;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.IndexNode;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.OperationNode;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.PostfixNode;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.TypeofNode;
|
||||
import me.topchetoeu.jscript.runtime.exceptions.SyntaxException;
|
||||
|
||||
@ -140,8 +141,8 @@ public final class JavaScript {
|
||||
ParseRes<Node> res = ParseRes.first(src, i + n,
|
||||
(s, j) -> OperationNode.parseInstanceof(s, j, _prev, precedence),
|
||||
(s, j) -> OperationNode.parseIn(s, j, _prev, precedence),
|
||||
(s, j) -> ChangeNode.parsePostfixIncrease(s, j, _prev, precedence),
|
||||
(s, j) -> ChangeNode.parsePostfixDecrease(s, j, _prev, precedence),
|
||||
(s, j) -> PostfixNode.parsePostfixIncrease(s, j, _prev, precedence),
|
||||
(s, j) -> PostfixNode.parsePostfixDecrease(s, j, _prev, precedence),
|
||||
(s, j) -> OperationNode.parseOperator(s, j, _prev, precedence),
|
||||
(s, j) -> IfNode.parseTernary(s, j, _prev, precedence),
|
||||
(s, j) -> IndexNode.parseMember(s, j, _prev, precedence),
|
||||
|
@ -4,7 +4,6 @@ import java.util.function.IntFunction;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import me.topchetoeu.jscript.common.Instruction;
|
||||
import me.topchetoeu.jscript.common.Operation;
|
||||
import me.topchetoeu.jscript.common.parsing.Location;
|
||||
import me.topchetoeu.jscript.common.parsing.ParseRes;
|
||||
import me.topchetoeu.jscript.common.parsing.Parsing;
|
||||
@ -13,14 +12,20 @@ import me.topchetoeu.jscript.compilation.AssignableNode;
|
||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||
import me.topchetoeu.jscript.compilation.JavaScript;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.VariableAssignNode;
|
||||
import me.topchetoeu.jscript.runtime.exceptions.SyntaxException;
|
||||
|
||||
public class VariableNode extends Node implements AssignableNode {
|
||||
public final String name;
|
||||
|
||||
@Override public Node toAssign(Node val, Operation operation) {
|
||||
return new VariableAssignNode(loc(), name, val, operation);
|
||||
@Override public String assignName() { return name; }
|
||||
|
||||
@Override public void compileBeforeAssign(CompileResult target, boolean operator) {
|
||||
if (operator) {
|
||||
target.add(VariableNode.toGet(target, loc(), name));
|
||||
}
|
||||
}
|
||||
@Override public void compileAfterAssign(CompileResult target, boolean operator, boolean pollute) {
|
||||
target.add(VariableNode.toSet(target, loc(), name, pollute, false));
|
||||
}
|
||||
|
||||
@Override public void compile(CompileResult target, boolean pollute) {
|
||||
|
@ -0,0 +1,23 @@
|
||||
package me.topchetoeu.jscript.compilation.values.operations;
|
||||
|
||||
import me.topchetoeu.jscript.common.parsing.Location;
|
||||
import me.topchetoeu.jscript.compilation.AssignableNode;
|
||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
public class AssignNode extends Node {
|
||||
public final AssignableNode assignable;
|
||||
public final Node value;
|
||||
|
||||
@Override public void compile(CompileResult target, boolean pollute) {
|
||||
assignable.compileBeforeAssign(target, false);
|
||||
value.compile(target, true);
|
||||
assignable.compileAfterAssign(target, false, pollute);
|
||||
}
|
||||
|
||||
public AssignNode(Location loc, AssignableNode assignable, Node value) {
|
||||
super(loc);
|
||||
this.assignable = assignable;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
@ -13,24 +13,22 @@ import me.topchetoeu.jscript.compilation.Node;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.NumberNode;
|
||||
|
||||
public class ChangeNode extends Node {
|
||||
public final AssignableNode value;
|
||||
public final double addAmount;
|
||||
public final boolean postfix;
|
||||
public final AssignableNode assignable;
|
||||
public final Node value;
|
||||
public final Operation op;
|
||||
|
||||
@Override public void compile(CompileResult target, boolean pollute) {
|
||||
value.toAssign(new NumberNode(loc(), -addAmount), Operation.SUBTRACT).compile(target, true);
|
||||
if (!pollute) target.add(Instruction.discard());
|
||||
else if (postfix) {
|
||||
target.add(Instruction.pushValue(addAmount));
|
||||
target.add(Instruction.operation(Operation.SUBTRACT));
|
||||
}
|
||||
assignable.compileBeforeAssign(target, true);
|
||||
value.compile(target, true);
|
||||
target.add(Instruction.operation(op));
|
||||
assignable.compileAfterAssign(target, true, pollute);
|
||||
}
|
||||
|
||||
public ChangeNode(Location loc, AssignableNode value, double addAmount, boolean postfix) {
|
||||
public ChangeNode(Location loc, AssignableNode assignable, Node value, Operation op) {
|
||||
super(loc);
|
||||
this.assignable = assignable;
|
||||
this.value = value;
|
||||
this.addAmount = addAmount;
|
||||
this.postfix = postfix;
|
||||
this.op = op;
|
||||
}
|
||||
|
||||
public static ParseRes<ChangeNode> parsePrefixIncrease(Source src, int i) {
|
||||
@ -44,7 +42,7 @@ public class ChangeNode extends Node {
|
||||
if (!res.isSuccess()) return res.chainError(src.loc(i + n), "Expected assignable value after prefix operator.");
|
||||
else if (!(res.result instanceof AssignableNode)) return ParseRes.error(src.loc(i + n), "Expected assignable value after prefix operator.");
|
||||
|
||||
return ParseRes.res(new ChangeNode(loc, (AssignableNode)res.result, 1, false), n + res.n);
|
||||
return ParseRes.res(new ChangeNode(loc, (AssignableNode)res.result, new NumberNode(loc, -1), Operation.SUBTRACT), n + res.n);
|
||||
}
|
||||
public static ParseRes<ChangeNode> parsePrefixDecrease(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
@ -57,31 +55,6 @@ public class ChangeNode extends Node {
|
||||
if (!res.isSuccess()) return res.chainError(src.loc(i + n), "Expected assignable value after prefix operator.");
|
||||
else if (!(res.result instanceof AssignableNode)) return ParseRes.error(src.loc(i + n), "Expected assignable value after prefix operator.");
|
||||
|
||||
return ParseRes.res(new ChangeNode(loc, (AssignableNode)res.result, -1, false), n + res.n);
|
||||
}
|
||||
|
||||
public static ParseRes<ChangeNode> parsePostfixIncrease(Source src, int i, Node prev, int precedence) {
|
||||
if (precedence > 15) return ParseRes.failed();
|
||||
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
if (!src.is(i + n, "++")) return ParseRes.failed();
|
||||
if (!(prev instanceof AssignableNode)) return ParseRes.error(src.loc(i + n), "Expected assignable value before suffix operator.");
|
||||
n += 2;
|
||||
|
||||
return ParseRes.res(new ChangeNode(loc, (AssignableNode)prev, 1, true), n);
|
||||
}
|
||||
public static ParseRes<ChangeNode> parsePostfixDecrease(Source src, int i, Node prev, int precedence) {
|
||||
if (precedence > 15) return ParseRes.failed();
|
||||
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
if (!src.is(i + n, "--")) return ParseRes.failed();
|
||||
if (!(prev instanceof AssignableNode)) return ParseRes.error(src.loc(i + n), "Expected assignable value before suffix operator.");
|
||||
n += 2;
|
||||
|
||||
return ParseRes.res(new ChangeNode(loc, (AssignableNode)prev, -1, true), n);
|
||||
return ParseRes.res(new ChangeNode(loc, (AssignableNode)res.result, new NumberNode(loc, 1), Operation.SUBTRACT), n + res.n);
|
||||
}
|
||||
}
|
||||
|
@ -1,74 +0,0 @@
|
||||
package me.topchetoeu.jscript.compilation.values.operations;
|
||||
|
||||
import me.topchetoeu.jscript.common.Instruction;
|
||||
import me.topchetoeu.jscript.common.Operation;
|
||||
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||
import me.topchetoeu.jscript.common.parsing.Location;
|
||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.NumberNode;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.StringNode;
|
||||
|
||||
public class IndexAssignNode extends Node {
|
||||
public final Node object;
|
||||
public final Node index;
|
||||
public final Node value;
|
||||
public final Operation operation;
|
||||
|
||||
@Override public void compile(CompileResult target, boolean pollute) {
|
||||
if (operation != null) {
|
||||
object.compile(target, true);
|
||||
|
||||
if (index instanceof NumberNode num && (int)num.value == num.value) {
|
||||
target.add(Instruction.loadMember((int)num.value));
|
||||
value.compile(target, true);
|
||||
target.add(Instruction.operation(operation));
|
||||
target.add(Instruction.storeMember((int)num.value, pollute));
|
||||
}
|
||||
else if (index instanceof StringNode str) {
|
||||
target.add(Instruction.loadMember(str.value));
|
||||
value.compile(target, true);
|
||||
target.add(Instruction.operation(operation));
|
||||
target.add(Instruction.storeMember(str.value, pollute));
|
||||
}
|
||||
else {
|
||||
index.compile(target, true);
|
||||
target.add(Instruction.dup(2));
|
||||
|
||||
target.add(Instruction.loadMember());
|
||||
value.compile(target, true);
|
||||
target.add(Instruction.operation(operation));
|
||||
|
||||
target.add(Instruction.storeMember(pollute));
|
||||
}
|
||||
target.setLocationAndDebug(loc(), BreakpointType.STEP_IN);
|
||||
}
|
||||
else {
|
||||
object.compile(target, true);
|
||||
|
||||
if (index instanceof NumberNode num && (int)num.value == num.value) {
|
||||
value.compile(target, true);
|
||||
target.add(Instruction.storeMember((int)num.value, pollute));
|
||||
}
|
||||
else if (index instanceof StringNode str) {
|
||||
value.compile(target, true);
|
||||
target.add(Instruction.storeMember(str.value, pollute));
|
||||
}
|
||||
else {
|
||||
index.compile(target, true);
|
||||
value.compile(target, true);
|
||||
target.add(Instruction.storeMember(pollute));
|
||||
}
|
||||
|
||||
target.setLocationAndDebug(loc(), BreakpointType.STEP_IN);;
|
||||
}
|
||||
}
|
||||
|
||||
public IndexAssignNode(Location loc, Node object, Node index, Node value, Operation operation) {
|
||||
super(loc);
|
||||
this.object = object;
|
||||
this.index = index;
|
||||
this.value = value;
|
||||
this.operation = operation;
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package me.topchetoeu.jscript.compilation.values.operations;
|
||||
|
||||
import me.topchetoeu.jscript.common.Instruction;
|
||||
import me.topchetoeu.jscript.common.Operation;
|
||||
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||
import me.topchetoeu.jscript.common.parsing.Location;
|
||||
import me.topchetoeu.jscript.common.parsing.ParseRes;
|
||||
@ -18,9 +17,46 @@ public class IndexNode extends Node implements AssignableNode {
|
||||
public final Node object;
|
||||
public final Node index;
|
||||
|
||||
@Override public Node toAssign(Node val, Operation operation) {
|
||||
return new IndexAssignNode(loc(), object, index, val, operation);
|
||||
@Override public void compileBeforeAssign(CompileResult target, boolean op) {
|
||||
object.compile(target, true);
|
||||
|
||||
if (index instanceof NumberNode num && (int)num.value == num.value) {
|
||||
if (op) {
|
||||
target.add(Instruction.dup());
|
||||
target.add(Instruction.loadMember((int)num.value));
|
||||
}
|
||||
}
|
||||
else if (index instanceof StringNode str) {
|
||||
if (op) {
|
||||
target.add(Instruction.dup());
|
||||
target.add(Instruction.loadMember(str.value));
|
||||
}
|
||||
}
|
||||
else {
|
||||
index.compile(target, true);
|
||||
|
||||
if (op) {
|
||||
target.add(Instruction.dup(1, 1));
|
||||
target.add(Instruction.dup(1, 1));
|
||||
target.add(Instruction.loadMember());
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override public void compileAfterAssign(CompileResult target, boolean op, boolean pollute) {
|
||||
if (index instanceof NumberNode num && (int)num.value == num.value) {
|
||||
target.add(Instruction.storeMember((int)num.value, pollute));
|
||||
}
|
||||
else if (index instanceof StringNode str) {
|
||||
target.add(Instruction.storeMember(str.value, pollute));
|
||||
}
|
||||
else {
|
||||
target.add(Instruction.storeMember(pollute));
|
||||
}
|
||||
}
|
||||
|
||||
// @Override public Node toAssign(Node val, Operation operation) {
|
||||
// return new IndexAssignNode(loc(), object, index, val, operation);
|
||||
// }
|
||||
public void compile(CompileResult target, boolean dupObj, boolean pollute) {
|
||||
object.compile(target, true);
|
||||
if (dupObj) target.add(Instruction.dup());
|
||||
|
@ -58,7 +58,9 @@ public class OperationNode extends Node {
|
||||
|
||||
var other = JavaScript.parseExpression(src, i, precedence);
|
||||
if (!other.isSuccess()) return other.chainError(src.loc(i + other.n), String.format("Expected a value after '%s'", token));
|
||||
return ParseRes.res(((AssignableNode)prev).toAssign(other.result, operation), other.n);
|
||||
|
||||
if (operation == null) return ParseRes.res(new AssignNode(loc, ((AssignableNode)prev), other.result), other.n);
|
||||
else return ParseRes.res(new ChangeNode(loc, ((AssignableNode)prev), other.result, operation), other.n);
|
||||
}
|
||||
|
||||
public AssignmentOperatorFactory(String token, int precedence, Operation operation) {
|
||||
|
@ -0,0 +1,52 @@
|
||||
package me.topchetoeu.jscript.compilation.values.operations;
|
||||
|
||||
import me.topchetoeu.jscript.common.Instruction;
|
||||
import me.topchetoeu.jscript.common.Operation;
|
||||
import me.topchetoeu.jscript.common.parsing.Location;
|
||||
import me.topchetoeu.jscript.common.parsing.ParseRes;
|
||||
import me.topchetoeu.jscript.common.parsing.Parsing;
|
||||
import me.topchetoeu.jscript.common.parsing.Source;
|
||||
import me.topchetoeu.jscript.compilation.AssignableNode;
|
||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.NumberNode;
|
||||
|
||||
public class PostfixNode extends ChangeNode {
|
||||
@Override public void compile(CompileResult target, boolean pollute) {
|
||||
super.compile(target, pollute);
|
||||
|
||||
if (pollute) {
|
||||
value.compile(target, true);
|
||||
target.add(Instruction.operation(Operation.ADD));
|
||||
}
|
||||
}
|
||||
|
||||
public PostfixNode(Location loc, AssignableNode value, double addAmount) {
|
||||
super(loc, value, new NumberNode(loc, -addAmount), Operation.SUBTRACT);
|
||||
}
|
||||
|
||||
public static ParseRes<ChangeNode> parsePostfixIncrease(Source src, int i, Node prev, int precedence) {
|
||||
if (precedence > 15) return ParseRes.failed();
|
||||
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
if (!src.is(i + n, "++")) return ParseRes.failed();
|
||||
if (!(prev instanceof AssignableNode)) return ParseRes.error(src.loc(i + n), "Expected assignable value before suffix operator.");
|
||||
n += 2;
|
||||
|
||||
return ParseRes.res(new PostfixNode(loc, (AssignableNode)prev, 1), n);
|
||||
}
|
||||
public static ParseRes<ChangeNode> parsePostfixDecrease(Source src, int i, Node prev, int precedence) {
|
||||
if (precedence > 15) return ParseRes.failed();
|
||||
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
if (!src.is(i + n, "--")) return ParseRes.failed();
|
||||
if (!(prev instanceof AssignableNode)) return ParseRes.error(src.loc(i + n), "Expected assignable value before suffix operator.");
|
||||
n += 2;
|
||||
|
||||
return ParseRes.res(new PostfixNode(loc, (AssignableNode)prev, -1), n);
|
||||
}
|
||||
}
|
@ -41,10 +41,8 @@ public final class Engine implements EventLoop {
|
||||
try {
|
||||
((Task<Object>)task).notifier.complete(task.runnable.get());
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
if (e instanceof InterruptException) throw e;
|
||||
task.notifier.completeExceptionally(e);
|
||||
}
|
||||
catch (InterruptException e) { throw e; }
|
||||
catch (RuntimeException e) { task.notifier.completeExceptionally(e); }
|
||||
}
|
||||
catch (InterruptedException | InterruptException e) {
|
||||
for (var msg : tasks) msg.notifier.cancel(false);
|
||||
|
@ -229,12 +229,21 @@ public class SimpleRepl {
|
||||
if (((ArgumentsValue)args.get(0)).frame.isNew) return new StringValue("new");
|
||||
else return new StringValue("call");
|
||||
}));
|
||||
|
||||
res.defineOwnMember(env, "invoke", new NativeFunction(args -> {
|
||||
var func = (FunctionValue)args.get(0);
|
||||
var self = args.get(1);
|
||||
var funcArgs = (ArrayValue)args.get(2);
|
||||
var name = args.get(3).toString(env).value;
|
||||
|
||||
return func.call(env, self, funcArgs.toArray());
|
||||
return func.invoke(env, name, self, funcArgs.toArray());
|
||||
}));
|
||||
res.defineOwnMember(env, "construct", new NativeFunction(args -> {
|
||||
var func = (FunctionValue)args.get(0);
|
||||
var funcArgs = (ArrayValue)args.get(1);
|
||||
var name = args.get(2).toString(env).value;
|
||||
|
||||
return func.construct(env, name, funcArgs.toArray());
|
||||
}));
|
||||
|
||||
return res;
|
||||
@ -264,7 +273,7 @@ public class SimpleRepl {
|
||||
var self = args.get(1);
|
||||
var funcArgs = (ArrayValue)args.get(2);
|
||||
|
||||
return func.call(env, self, funcArgs.toArray());
|
||||
return func.invoke(env, self, funcArgs.toArray());
|
||||
}));
|
||||
|
||||
return res;
|
||||
@ -303,6 +312,12 @@ public class SimpleRepl {
|
||||
case "object":
|
||||
args.env.add(Value.OBJECT_PROTO, obj);
|
||||
break;
|
||||
case "function":
|
||||
args.env.add(Value.FUNCTION_PROTO, obj);
|
||||
break;
|
||||
case "array":
|
||||
args.env.add(Value.ARRAY_PROTO, obj);
|
||||
break;
|
||||
}
|
||||
|
||||
return Value.UNDEFINED;
|
||||
|
@ -13,12 +13,12 @@ public interface Member {
|
||||
public final boolean enumerable;
|
||||
|
||||
@Override public Value get(Environment env, Value self) {
|
||||
if (getter != null) return getter.call(env, self);
|
||||
if (getter != null) return getter.call(env, false, "", self);
|
||||
else return Value.UNDEFINED;
|
||||
}
|
||||
@Override public boolean set(Environment env, Value val, Value self) {
|
||||
if (setter == null) return false;
|
||||
setter.call(env, self, val);
|
||||
setter.call(env, false, "", self, val);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package me.topchetoeu.jscript.runtime.values.primitives;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import me.topchetoeu.jscript.common.environment.Environment;
|
||||
import me.topchetoeu.jscript.runtime.exceptions.EngineException;
|
||||
import me.topchetoeu.jscript.runtime.values.KeyCache;
|
||||
@ -24,12 +22,6 @@ public final class VoidValue extends PrimitiveValue {
|
||||
@Override public Member getOwnMember(Environment env, KeyCache key) {
|
||||
throw EngineException.ofError(String.format("Cannot read properties of %s (reading '%s')", name, key.toString(env)));
|
||||
}
|
||||
@Override public Set<String> getOwnMembers(Environment env, boolean onlyEnumerable) {
|
||||
throw EngineException.ofError(String.format("Cannot read properties of %s (listing all members)", name));
|
||||
}
|
||||
@Override public Set<SymbolValue> getOwnSymbolMembers(Environment env, boolean onlyEnumerable) {
|
||||
throw EngineException.ofError(String.format("Cannot read properties of %s (listing all symbol members)", name));
|
||||
}
|
||||
|
||||
public VoidValue(String name, StringValue type) {
|
||||
this.name = name;
|
||||
|
@ -29,6 +29,7 @@ const invokeType = primordials.function.invokeType;
|
||||
const setConstructable = primordials.function.setConstructable;
|
||||
const setCallable = primordials.function.setCallable;
|
||||
const invoke = primordials.function.invoke;
|
||||
const construct = primordials.function.construct;
|
||||
|
||||
const json = primordials.json;
|
||||
|
||||
@ -305,9 +306,7 @@ defineField(Function.prototype, "valueOf", true, false, true, function() {
|
||||
|
||||
target.Function = Function;
|
||||
|
||||
let spread_obj;
|
||||
|
||||
setIntrinsic("spread_obj", spread_obj = (target, obj) => {
|
||||
setIntrinsic("spread_obj", target.spread_obj = (target, obj) => {
|
||||
if (obj === null || obj === undefined) return;
|
||||
const members = getOwnMembers(obj, true);
|
||||
const symbols = getOwnSymbolMembers(obj, true);
|
||||
@ -322,11 +321,16 @@ setIntrinsic("spread_obj", spread_obj = (target, obj) => {
|
||||
target[member] = obj[member];
|
||||
}
|
||||
});
|
||||
|
||||
target.spread_obj = spread_obj;
|
||||
setIntrinsic("apply", target.spread_call = (func, self, args) => {
|
||||
return invoke(func, self, args);
|
||||
});
|
||||
setIntrinsic("apply", target.spread_new = (func, args) => {
|
||||
return invoke(func, null, args);
|
||||
});
|
||||
|
||||
setGlobalPrototype("string", String.prototype);
|
||||
setGlobalPrototype("number", Number.prototype);
|
||||
setGlobalPrototype("boolean", Boolean.prototype);
|
||||
setGlobalPrototype("symbol", Symbol.prototype);
|
||||
setGlobalPrototype("object", Object.prototype);
|
||||
setGlobalPrototype("function", Function.prototype);
|
||||
|
Loading…
Reference in New Issue
Block a user