feat: implement non-enumerable members in classes
This commit is contained in:
parent
59e6f34a01
commit
8dee4353d4
@ -454,11 +454,11 @@ public class Instruction {
|
||||
return new Instruction(Type.KEYS, own, onlyEnumerable);
|
||||
}
|
||||
|
||||
public static Instruction defProp(boolean setter) {
|
||||
return new Instruction(Type.DEF_PROP, setter);
|
||||
public static Instruction defProp(boolean setter, boolean enumerable) {
|
||||
return new Instruction(Type.DEF_PROP, setter, enumerable);
|
||||
}
|
||||
public static Instruction defField() {
|
||||
return new Instruction(Type.DEF_FIELD);
|
||||
public static Instruction defField(boolean enumerable) {
|
||||
return new Instruction(Type.DEF_FIELD, enumerable);
|
||||
}
|
||||
|
||||
public static Instruction operation(Operation op) {
|
||||
|
@ -11,19 +11,20 @@ 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.members.FieldMemberNode;
|
||||
import me.topchetoeu.jscript.compilation.members.Member;
|
||||
import me.topchetoeu.jscript.compilation.members.MethodMemberNode;
|
||||
import me.topchetoeu.jscript.compilation.members.PropertyMemberNode;
|
||||
|
||||
public abstract class ClassNode extends FunctionNode {
|
||||
public static final class ClassBody {
|
||||
public final List<Node> staticMembers;
|
||||
public final List<Member> staticMembers;
|
||||
public final List<FieldMemberNode> protoFields;
|
||||
public final List<Node> protoMembers;
|
||||
public final List<Member> protoMembers;
|
||||
public final Parameters constructorParameters;
|
||||
public final CompoundNode constructorBody;
|
||||
|
||||
public ClassBody(
|
||||
List<Node> staticMembers, List<FieldMemberNode> protoFields, List<Node> protoMembers,
|
||||
List<Member> staticMembers, List<FieldMemberNode> protoFields, List<Member> protoMembers,
|
||||
Parameters constructorParameters, CompoundNode constructorBody
|
||||
) {
|
||||
this.staticMembers = staticMembers;
|
||||
@ -34,13 +35,15 @@ public abstract class ClassNode extends FunctionNode {
|
||||
}
|
||||
}
|
||||
|
||||
// public static final Key<Void>
|
||||
|
||||
public final ClassBody body;
|
||||
public final String name;
|
||||
|
||||
@Override public String name() { return name; }
|
||||
|
||||
public void compileStatic(CompileResult target) {
|
||||
for (var member : body.staticMembers) member.compile(target, true);
|
||||
for (var member : body.staticMembers) member.compile(target, true, false);
|
||||
}
|
||||
public void compilePrototype(CompileResult target) {
|
||||
if (body.protoMembers.size() > 0) {
|
||||
@ -48,17 +51,17 @@ public abstract class ClassNode extends FunctionNode {
|
||||
target.add(Instruction.loadMember("prototype"));
|
||||
|
||||
for (var i = 0; i < body.protoMembers.size() - 1; i++) {
|
||||
body.protoMembers.get(i).compile(target, true);
|
||||
body.protoMembers.get(i).compile(target, true, false);
|
||||
}
|
||||
|
||||
body.protoMembers.get(body.protoMembers.size() - 1).compile(target, false);
|
||||
body.protoMembers.get(body.protoMembers.size() - 1).compile(target, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void compilePreBody(CompileResult target) {
|
||||
for (var member : body.protoFields) {
|
||||
target.add(Instruction.loadThis());
|
||||
member.compile(target, false);
|
||||
member.compile(target, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,7 +79,7 @@ public abstract class ClassNode extends FunctionNode {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public static ParseRes<Node> parseMember(Source src, int i) {
|
||||
public static ParseRes<Member> parseMember(Source src, int i) {
|
||||
return ParseRes.first(src, i,
|
||||
PropertyMemberNode::parse,
|
||||
FieldMemberNode::parseClass,
|
||||
@ -93,8 +96,8 @@ public abstract class ClassNode extends FunctionNode {
|
||||
n += Parsing.skipEmpty(src, i + n);
|
||||
|
||||
var fields = new LinkedList<FieldMemberNode>();
|
||||
var members = new LinkedList<Node>();
|
||||
var statics = new LinkedList<Node>();
|
||||
var members = new LinkedList<Member>();
|
||||
var statics = new LinkedList<Member>();
|
||||
|
||||
var params = new Parameters(new ArrayList<>());
|
||||
var body = new CompoundNode(loc, false);
|
||||
@ -106,7 +109,7 @@ public abstract class ClassNode extends FunctionNode {
|
||||
}
|
||||
|
||||
while (true) {
|
||||
ParseRes<Node> prop = parseMember(src, i + n);
|
||||
ParseRes<Member> prop = parseMember(src, i + n);
|
||||
|
||||
if (prop.isSuccess()) {
|
||||
n += prop.n;
|
||||
|
@ -27,10 +27,6 @@ public abstract class FunctionNode extends Node {
|
||||
public final CompileResult compileBody(Environment env, FunctionScope scope, boolean lastReturn, String _name, String selfName) {
|
||||
var name = this.name() != null ? this.name() : _name;
|
||||
|
||||
env = env.child()
|
||||
.remove(LabelContext.BREAK_CTX)
|
||||
.remove(LabelContext.CONTINUE_CTX);
|
||||
|
||||
return new CompileResult(env, scope, params.params.size(), target -> {
|
||||
compilePreBody(target);
|
||||
|
||||
@ -68,7 +64,7 @@ public abstract class FunctionNode extends Node {
|
||||
});
|
||||
}
|
||||
public final CompileResult compileBody(CompileResult parent, String name, String selfName) {
|
||||
return compileBody(parent.env, new FunctionScope(parent.scope), false, name, selfName);
|
||||
return compileBody(parent.env.get(JavaScript.COMPILE_ROOT).child(), new FunctionScope(parent.scope), false, name, selfName);
|
||||
}
|
||||
|
||||
public abstract void compile(CompileResult target, boolean pollute, String name, BreakpointType bp);
|
||||
|
@ -7,6 +7,7 @@ import java.util.Set;
|
||||
|
||||
import me.topchetoeu.jscript.common.SyntaxException;
|
||||
import me.topchetoeu.jscript.common.environment.Environment;
|
||||
import me.topchetoeu.jscript.common.environment.Key;
|
||||
import me.topchetoeu.jscript.common.parsing.Filename;
|
||||
import me.topchetoeu.jscript.common.parsing.ParseRes;
|
||||
import me.topchetoeu.jscript.common.parsing.Parsing;
|
||||
@ -31,6 +32,7 @@ import me.topchetoeu.jscript.compilation.values.ArrayNode;
|
||||
import me.topchetoeu.jscript.compilation.values.ClassValueNode;
|
||||
import me.topchetoeu.jscript.compilation.values.ObjectNode;
|
||||
import me.topchetoeu.jscript.compilation.values.RegexNode;
|
||||
import me.topchetoeu.jscript.compilation.values.SuperNode;
|
||||
import me.topchetoeu.jscript.compilation.values.ThisNode;
|
||||
import me.topchetoeu.jscript.compilation.values.VariableNode;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.BoolNode;
|
||||
@ -59,6 +61,8 @@ public final class JavaScript {
|
||||
}
|
||||
}
|
||||
|
||||
public static final Key<Environment> COMPILE_ROOT = Key.of();
|
||||
|
||||
static final Set<String> reserved = new HashSet<>(Arrays.asList(
|
||||
"true", "false", "void", "null", "this", "if", "else", "try", "catch",
|
||||
"finally", "for", "do", "while", "switch", "case", "default", "new",
|
||||
@ -120,6 +124,7 @@ public final class JavaScript {
|
||||
if (id.result.equals("false")) return ParseRes.res(new BoolNode(loc, false), n);
|
||||
if (id.result.equals("null")) return ParseRes.res(new NullNode(loc), n);
|
||||
if (id.result.equals("this")) return ParseRes.res(new ThisNode(loc), n);
|
||||
if (id.result.equals("super")) return ParseRes.res(new SuperNode(loc), n);
|
||||
if (id.result.equals("arguments")) return ParseRes.res(new ArgumentsNode(loc), n);
|
||||
|
||||
return ParseRes.failed();
|
||||
@ -264,6 +269,9 @@ public final class JavaScript {
|
||||
}
|
||||
|
||||
public static CompileResult compile(Environment env, Node ...statements) {
|
||||
env = env.child();
|
||||
env.add(COMPILE_ROOT, env);
|
||||
|
||||
var func = new FunctionValueNode(null, null, new Parameters(Arrays.asList()), new CompoundNode(null, true, statements), null);
|
||||
var res = func.compileBody(env, new FunctionScope(true), true, null, null);
|
||||
res.buildTask.run();
|
||||
|
@ -13,17 +13,20 @@ import me.topchetoeu.jscript.compilation.values.VariableNode;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.StringNode;
|
||||
import me.topchetoeu.jscript.compilation.values.operations.AssignNode;
|
||||
|
||||
public class AssignShorthandNode extends Node {
|
||||
public class AssignShorthandNode implements Member {
|
||||
public final Location loc;
|
||||
public final Node key;
|
||||
public final AssignTarget target;
|
||||
public final Node value;
|
||||
|
||||
@Override public void compile(CompileResult target, boolean pollute) {
|
||||
@Override public Location loc() { return loc; }
|
||||
|
||||
@Override public void compile(CompileResult target, boolean pollute, boolean enumerable) {
|
||||
throw new SyntaxException(loc(), "Unexpected assign shorthand in non-destructor context");
|
||||
}
|
||||
|
||||
public AssignShorthandNode(Location loc, Node key, AssignTarget target, Node value) {
|
||||
super(loc);
|
||||
this.loc = loc;
|
||||
this.key = key;
|
||||
this.target = target;
|
||||
this.value = value;
|
||||
|
@ -12,22 +12,25 @@ import me.topchetoeu.jscript.compilation.values.ObjectNode;
|
||||
import me.topchetoeu.jscript.compilation.values.VariableNode;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.StringNode;
|
||||
|
||||
public class FieldMemberNode extends Node {
|
||||
public class FieldMemberNode implements Member {
|
||||
public final Location loc;
|
||||
public final Node key;
|
||||
public final Node value;
|
||||
|
||||
@Override public void compile(CompileResult target, boolean pollute) {
|
||||
@Override public Location loc() { return loc; }
|
||||
|
||||
@Override public void compile(CompileResult target, boolean pollute, boolean enumerable) {
|
||||
if (pollute) target.add(Instruction.dup());
|
||||
key.compile(target, true);
|
||||
|
||||
if (value == null) target.add(Instruction.pushUndefined());
|
||||
else value.compile(target, true);
|
||||
|
||||
target.add(Instruction.defField());
|
||||
target.add(Instruction.defField(enumerable));
|
||||
}
|
||||
|
||||
public FieldMemberNode(Location loc, Node key, Node value) {
|
||||
super(loc);
|
||||
this.loc = loc;
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
@ -0,0 +1,10 @@
|
||||
package me.topchetoeu.jscript.compilation.members;
|
||||
|
||||
import me.topchetoeu.jscript.common.parsing.Location;
|
||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||
|
||||
public interface Member {
|
||||
Location loc();
|
||||
|
||||
void compile(CompileResult target, boolean pollute, boolean enumerable);
|
||||
}
|
@ -14,7 +14,7 @@ import me.topchetoeu.jscript.compilation.Parameters;
|
||||
import me.topchetoeu.jscript.compilation.values.ObjectNode;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.StringNode;
|
||||
|
||||
public class MethodMemberNode extends FunctionNode {
|
||||
public class MethodMemberNode extends FunctionNode implements Member {
|
||||
public final Node key;
|
||||
|
||||
@Override public String name() {
|
||||
@ -28,8 +28,11 @@ public class MethodMemberNode extends FunctionNode {
|
||||
|
||||
var id = target.addChild(compileBody(target, name, null));
|
||||
target.add(_i -> Instruction.loadFunc(id, true, false, false, name, captures(id, target)));
|
||||
}
|
||||
|
||||
target.add(Instruction.defField());
|
||||
@Override public void compile(CompileResult target, boolean pollute, boolean enumerable) {
|
||||
compile(target, pollute);
|
||||
target.add(Instruction.defField(enumerable));
|
||||
}
|
||||
|
||||
public MethodMemberNode(Location loc, Location end, Node key, Parameters params, CompoundNode body) {
|
||||
|
@ -17,7 +17,7 @@ import me.topchetoeu.jscript.compilation.patterns.Pattern;
|
||||
import me.topchetoeu.jscript.compilation.values.ObjectNode;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.StringNode;
|
||||
|
||||
public class PropertyMemberNode extends FunctionNode {
|
||||
public class PropertyMemberNode extends FunctionNode implements Member{
|
||||
public final Node key;
|
||||
public final Pattern argument;
|
||||
|
||||
@ -38,8 +38,12 @@ public class PropertyMemberNode extends FunctionNode {
|
||||
|
||||
var id = target.addChild(compileBody(target, name, null));
|
||||
target.add(_i -> Instruction.loadFunc(id, true, false, false, name, captures(id, target)));
|
||||
}
|
||||
|
||||
target.add(Instruction.defProp(isSetter()));
|
||||
|
||||
@Override public void compile(CompileResult target, boolean pollute, boolean enumerable) {
|
||||
compile(target, pollute);
|
||||
target.add(Instruction.defProp(isSetter(), enumerable));
|
||||
}
|
||||
|
||||
public PropertyMemberNode(Location loc, Location end, Node key, Pattern argument, CompoundNode body) {
|
||||
|
@ -14,6 +14,7 @@ import me.topchetoeu.jscript.compilation.JavaScript;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
import me.topchetoeu.jscript.compilation.members.AssignShorthandNode;
|
||||
import me.topchetoeu.jscript.compilation.members.FieldMemberNode;
|
||||
import me.topchetoeu.jscript.compilation.members.Member;
|
||||
import me.topchetoeu.jscript.compilation.members.MethodMemberNode;
|
||||
import me.topchetoeu.jscript.compilation.members.PropertyMemberNode;
|
||||
import me.topchetoeu.jscript.compilation.patterns.AssignTarget;
|
||||
@ -23,7 +24,7 @@ import me.topchetoeu.jscript.compilation.values.constants.NumberNode;
|
||||
import me.topchetoeu.jscript.compilation.values.constants.StringNode;
|
||||
|
||||
public class ObjectNode extends Node implements AssignTargetLike {
|
||||
public final List<Node> members;
|
||||
public final List<Member> members;
|
||||
|
||||
// TODO: Implement spreading into object
|
||||
|
||||
@ -64,7 +65,7 @@ public class ObjectNode extends Node implements AssignTargetLike {
|
||||
|
||||
@Override public void compile(CompileResult target, boolean pollute) {
|
||||
target.add(Instruction.loadObj());
|
||||
for (var el : members) el.compile(target, true);
|
||||
for (var el : members) el.compile(target, true, true);
|
||||
}
|
||||
|
||||
@Override public AssignTarget toAssignTarget() {
|
||||
@ -82,7 +83,7 @@ public class ObjectNode extends Node implements AssignTargetLike {
|
||||
return new ObjectPattern(loc(), newMembers);
|
||||
}
|
||||
|
||||
public ObjectNode(Location loc, List<Node> map) {
|
||||
public ObjectNode(Location loc, List<Member> map) {
|
||||
super(loc);
|
||||
this.members = map;
|
||||
}
|
||||
@ -126,7 +127,7 @@ public class ObjectNode extends Node implements AssignTargetLike {
|
||||
n++;
|
||||
n += Parsing.skipEmpty(src, i + n);
|
||||
|
||||
var members = new LinkedList<Node>();
|
||||
var members = new LinkedList<Member>();
|
||||
|
||||
if (src.is(i + n, "}")) {
|
||||
n++;
|
||||
@ -134,7 +135,7 @@ public class ObjectNode extends Node implements AssignTargetLike {
|
||||
}
|
||||
|
||||
while (true) {
|
||||
ParseRes<Node> prop = ParseRes.first(src, i + n,
|
||||
ParseRes<Member> prop = ParseRes.first(src, i + n,
|
||||
MethodMemberNode::parse,
|
||||
PropertyMemberNode::parse,
|
||||
FieldMemberNode::parseObject,
|
||||
|
@ -0,0 +1,17 @@
|
||||
package me.topchetoeu.jscript.compilation.values;
|
||||
|
||||
import me.topchetoeu.jscript.common.SyntaxException;
|
||||
import me.topchetoeu.jscript.common.parsing.Location;
|
||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||
import me.topchetoeu.jscript.compilation.Node;
|
||||
|
||||
|
||||
public class SuperNode extends Node {
|
||||
@Override public void compile(CompileResult target, boolean pollute) {
|
||||
throw new SyntaxException(loc(), "Unexpected 'super' reference here");
|
||||
}
|
||||
|
||||
public SuperNode(Location loc) {
|
||||
super(loc);
|
||||
}
|
||||
}
|
@ -45,6 +45,8 @@ public class VariableNode extends Node implements Pattern, ChangeTarget {
|
||||
if (i == null) return Instruction.globDef(name);
|
||||
else return Instruction.nop();
|
||||
});
|
||||
|
||||
target.setLocation(loc());
|
||||
}
|
||||
|
||||
@Override public void destruct(CompileResult target, DeclarationType decl, boolean shouldDeclare) {
|
||||
@ -57,10 +59,12 @@ public class VariableNode extends Node implements Pattern, ChangeTarget {
|
||||
var v = target.scope.define(decl, name, loc());
|
||||
target.add(_i -> v.index().toInit());
|
||||
}
|
||||
|
||||
target.setLocation(loc());
|
||||
}
|
||||
|
||||
@Override public void compile(CompileResult target, boolean pollute) {
|
||||
target.add(toGet(target, loc(), name, true, false));
|
||||
target.add(toGet(target, loc(), name, true, false)).setLocation(loc());
|
||||
}
|
||||
|
||||
public static IntFunction<Instruction> toGet(CompileResult target, Location loc, String name, boolean keep, boolean forceGet) {
|
||||
|
@ -7,6 +7,7 @@ import me.topchetoeu.jscript.common.Instruction;
|
||||
import me.topchetoeu.jscript.common.Operation;
|
||||
import me.topchetoeu.jscript.common.environment.Environment;
|
||||
import me.topchetoeu.jscript.runtime.exceptions.EngineException;
|
||||
import me.topchetoeu.jscript.runtime.values.Member.FieldMember;
|
||||
import me.topchetoeu.jscript.runtime.values.Member.PropertyMember;
|
||||
import me.topchetoeu.jscript.runtime.values.Value;
|
||||
import me.topchetoeu.jscript.runtime.values.functions.CodeFunction;
|
||||
@ -68,8 +69,8 @@ public class InstructionRunner {
|
||||
else if (val instanceof FunctionValue func) accessor = func;
|
||||
else throw EngineException.ofType("Getter must be a function or undefined.");
|
||||
|
||||
if ((boolean)instr.get(0)) obj.defineOwnMember(env, key, new PropertyMember(obj, null, accessor, true, true));
|
||||
else obj.defineOwnMember(env, key, new PropertyMember(obj, accessor, null, true, true));
|
||||
if ((boolean)instr.get(0)) obj.defineOwnMember(env, key, new PropertyMember(obj, null, accessor, true, instr.get(1)));
|
||||
else obj.defineOwnMember(env, key, new PropertyMember(obj, accessor, null, true, instr.get(1)));
|
||||
|
||||
frame.codePtr++;
|
||||
return null;
|
||||
@ -79,7 +80,7 @@ public class InstructionRunner {
|
||||
var key = frame.pop();
|
||||
var obj = frame.pop();
|
||||
|
||||
obj.defineOwnMember(env, key, val);
|
||||
obj.defineOwnMember(env, key, FieldMember.of(obj, val, true, instr.get(0), true));
|
||||
|
||||
frame.codePtr++;
|
||||
return null;
|
||||
|
@ -1,5 +1,3 @@
|
||||
// return;
|
||||
|
||||
const target = arguments[0];
|
||||
const primordials = arguments[1];
|
||||
|
||||
@ -20,28 +18,26 @@ const symbol = primordials.symbol || (() => {
|
||||
};
|
||||
});
|
||||
|
||||
const number = primordials.number || (() => {
|
||||
return {
|
||||
parseInt() { throw new Error("parseInt not supported"); },
|
||||
parseFloat() { throw new Error("parseFloat not supported"); },
|
||||
isNaN: (val) => val !== val,
|
||||
NaN: 0 / 0,
|
||||
Infinity: 1 / 0,
|
||||
};
|
||||
});
|
||||
const number = primordials.number || {
|
||||
parseInt() { throw new Error("parseInt not supported"); },
|
||||
parseFloat() { throw new Error("parseFloat not supported"); },
|
||||
isNaN: (val) => val !== val,
|
||||
NaN: 0 / 0,
|
||||
Infinity: 1 / 0,
|
||||
};
|
||||
|
||||
const fromCharCode = primordials.string.fromCharCode;
|
||||
const fromCodePoint = primordials.string.fromCodePoint;
|
||||
const stringBuild = primordials.string.stringBuild;
|
||||
const string = primordials.string;
|
||||
|
||||
const defineProperty = primordials.object.defineProperty;
|
||||
const defineField = primordials.object.defineField;
|
||||
const getOwnMember = primordials.object.getMember;
|
||||
const getOwnSymbolMember = primordials.object.getOwnSymbolMember;
|
||||
const getOwnMembers = primordials.object.getOwnMembers;
|
||||
const getOwnSymbolMembers = primordials.object.getOwnSymbolMembers;
|
||||
const getPrototype = primordials.object.getPrototype;
|
||||
const setPrototype = primordials.object.setPrototype;
|
||||
const object = primordials.object || {
|
||||
defineProperty() { throw new Error("Define property not polyfillable"); },
|
||||
defineField(obj, key, a, b, c, value) { obj[key] = value; },
|
||||
getOwnMember() { throw new Error("Get own member not polyfillable"); },
|
||||
getOwnSymbolMember() { throw new Error("Get own symbol member not polyfillable"); },
|
||||
getOwnMembers() { throw new Error("Get own members not polyfillable"); },
|
||||
getOwnSymbolMembers() { throw new Error("Get own symbol members not polyfillable"); },
|
||||
getPrototype() { throw new Error("Get prototype not polyfillable"); },
|
||||
setPrototype() { throw new Error("Set prototype not polyfillable"); },
|
||||
}
|
||||
|
||||
const invokeType = primordials.function.invokeType;
|
||||
const setConstructable = primordials.function.setConstructable;
|
||||
@ -97,14 +93,14 @@ class Symbol {
|
||||
setCallable(Symbol, true);
|
||||
setConstructable(Symbol, false);
|
||||
|
||||
defineField(Symbol, "asyncIterator", false, false, false, Symbol("Symbol.asyncIterator"));
|
||||
defineField(Symbol, "iterator", false, false, false, Symbol("Symbol.iterator"));
|
||||
defineField(Symbol, "match", false, false, false, Symbol("Symbol.match"));
|
||||
defineField(Symbol, "matchAll", false, false, false, Symbol("Symbol.matchAll"));
|
||||
defineField(Symbol, "replace", false, false, false, Symbol("Symbol.replace"));
|
||||
defineField(Symbol, "search", false, false, false, Symbol("Symbol.search"));
|
||||
defineField(Symbol, "split", false, false, false, Symbol("Symbol.split"));
|
||||
defineField(Symbol, "toStringTag", false, false, false, Symbol("Symbol.toStringTag"));
|
||||
object.defineField(Symbol, "asyncIterator", false, false, false, Symbol("Symbol.asyncIterator"));
|
||||
object.defineField(Symbol, "iterator", false, false, false, Symbol("Symbol.iterator"));
|
||||
object.defineField(Symbol, "match", false, false, false, Symbol("Symbol.match"));
|
||||
object.defineField(Symbol, "matchAll", false, false, false, Symbol("Symbol.matchAll"));
|
||||
object.defineField(Symbol, "replace", false, false, false, Symbol("Symbol.replace"));
|
||||
object.defineField(Symbol, "search", false, false, false, Symbol("Symbol.search"));
|
||||
object.defineField(Symbol, "split", false, false, false, Symbol("Symbol.split"));
|
||||
object.defineField(Symbol, "toStringTag", false, false, false, Symbol("Symbol.toStringTag"));
|
||||
|
||||
Symbol();
|
||||
target.Symbol = Symbol;
|
||||
@ -160,14 +156,14 @@ class Number {
|
||||
}
|
||||
}
|
||||
|
||||
defineField(Number, "EPSILON", false, false, false, 2.220446049250313e-16);
|
||||
defineField(Number, "MIN_SAFE_INTEGER", false, false, false, -9007199254740991);
|
||||
defineField(Number, "MAX_SAFE_INTEGER", false, false, false, 9007199254740991);
|
||||
defineField(Number, "POSITIVE_INFINITY", false, false, false, +number.Infinity);
|
||||
defineField(Number, "NEGATIVE_INFINITY", false, false, false, -number.Infinity);
|
||||
defineField(Number, "NaN", false, false, false, number.NaN);
|
||||
defineField(Number, "MAX_VALUE", false, false, false, 1.7976931348623157e+308);
|
||||
defineField(Number, "MIN_VALUE", false, false, false, 5e-324);
|
||||
object.defineField(Number, "EPSILON", false, false, false, 2.220446049250313e-16);
|
||||
object.defineField(Number, "MIN_SAFE_INTEGER", false, false, false, -9007199254740991);
|
||||
object.defineField(Number, "MAX_SAFE_INTEGER", false, false, false, 9007199254740991);
|
||||
object.defineField(Number, "POSITIVE_INFINITY", false, false, false, +number.Infinity);
|
||||
object.defineField(Number, "NEGATIVE_INFINITY", false, false, false, -number.Infinity);
|
||||
object.defineField(Number, "NaN", false, false, false, number.NaN);
|
||||
object.defineField(Number, "MAX_VALUE", false, false, false, 1.7976931348623157e+308);
|
||||
object.defineField(Number, "MIN_VALUE", false, false, false, 5e-324);
|
||||
|
||||
setCallable(Number, true);
|
||||
target.Number = Number;
|
||||
@ -202,20 +198,20 @@ class String {
|
||||
res[arguments.length] = 0;
|
||||
|
||||
for (let i = 0; i < arguments.length; i++) {
|
||||
res[i] = fromCharCode(+arguments[i]);
|
||||
res[i] = string.fromCharCode(+arguments[i]);
|
||||
}
|
||||
|
||||
return stringBuild(res);
|
||||
return string.stringBuild(res);
|
||||
}
|
||||
static fromCodePoint() {
|
||||
const res = [];
|
||||
res[arguments.length] = 0;
|
||||
|
||||
for (let i = 0; i < arguments.length; i++) {
|
||||
res[i] = fromCodePoint(+arguments[i]);
|
||||
res[i] = string.fromCodePoint(+arguments[i]);
|
||||
}
|
||||
|
||||
return stringBuild(res);
|
||||
return string.stringBuild(res);
|
||||
}
|
||||
}
|
||||
|
||||
@ -290,8 +286,6 @@ class Object {
|
||||
if ("get" in desc || "set" in desc) {
|
||||
let get = desc.get, set = desc.set;
|
||||
|
||||
print(typeof get);
|
||||
|
||||
if (get !== undefined && typeof get !== "function") throw new TypeError("Getter must be a function: " + get);
|
||||
if (set !== undefined && typeof set !== "function") throw new TypeError("Setter must be a function: " + set);
|
||||
|
||||
@ -299,11 +293,11 @@ class Object {
|
||||
throw new TypeError("Invalid property descriptor. Cannot both specify accessors and a value or writable attribute");
|
||||
}
|
||||
|
||||
if (!defineProperty(obj, key, desc.enumerable, desc.configurable, get, set)) {
|
||||
if (!object.defineProperty(obj, key, desc.enumerable, desc.configurable, get, set)) {
|
||||
throw new TypeError("Cannot redefine property: " + key);
|
||||
}
|
||||
}
|
||||
else if (!defineField(obj, key, desc.writable, desc.enumerable, desc.configurable, desc.value)) {
|
||||
else if (!object.defineField(obj, key, desc.writable, desc.enumerable, desc.configurable, desc.value)) {
|
||||
throw new TypeError("Cannot redefine property: " + key);
|
||||
}
|
||||
|
||||
@ -312,7 +306,7 @@ class Object {
|
||||
}
|
||||
|
||||
setCallable(Object, true);
|
||||
setPrototype(Object.prototype, null);
|
||||
object.setPrototype(Object.prototype, null);
|
||||
target.Object = Object;
|
||||
|
||||
class Function {
|
||||
@ -322,7 +316,7 @@ class Function {
|
||||
}
|
||||
|
||||
constructor() {
|
||||
const parts = ["return function annonymous("];
|
||||
const parts = ["(function annonymous("];
|
||||
|
||||
for (let i = 0; i < arguments.length - 1; i++) {
|
||||
if (i > 0) parts[parts.length] = ",";
|
||||
@ -330,9 +324,9 @@ class Function {
|
||||
}
|
||||
parts[parts.length] = "){\n";
|
||||
parts[parts.length] = String(arguments[arguments.length - 1]);
|
||||
parts[parts.length] = "\n}";
|
||||
parts[parts.length] = "\n})";
|
||||
|
||||
const res = compile(stringBuild(parts))();
|
||||
const res = compile(string.stringBuild(parts))();
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -341,27 +335,20 @@ class Function {
|
||||
|
||||
if (wrap) parts[parts.length] = "return (function() {\n";
|
||||
if (globals.length > 0) {
|
||||
parts[parts.length] = "var ";
|
||||
parts[parts.length] = "let {";
|
||||
|
||||
for (let i = 0; i < globals.length; i++) {
|
||||
if (i > 0) parts[parts.length] = ",";
|
||||
parts[parts.length] = globals[i];
|
||||
}
|
||||
|
||||
parts[parts.length] = ";((g=arguments[0])=>{";
|
||||
|
||||
for (let i = 0; i < globals.length; i++) {
|
||||
const name = globals[i];
|
||||
parts[parts.length] = name + "=g[" + json.stringify(name) + "];";
|
||||
}
|
||||
|
||||
parts[parts.length] = "})()\n";
|
||||
parts[parts.length] = "} = arguments[0];";
|
||||
}
|
||||
|
||||
parts[parts.length] = src;
|
||||
if (wrap) parts[parts.length] = "\n})(arguments[0])";
|
||||
|
||||
const res = compile(stringBuild(parts));
|
||||
const res = compile(string.stringBuild(parts));
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@ -400,8 +387,8 @@ class Error {
|
||||
}
|
||||
}
|
||||
|
||||
defineField(Error.prototype, "name", true, false, true, "Error");
|
||||
defineField(Error.prototype, "message", true, false, true, "");
|
||||
object.defineField(Error.prototype, "name", true, false, true, "Error");
|
||||
object.defineField(Error.prototype, "message", true, false, true, "");
|
||||
setCallable(Error, true);
|
||||
target.Error = Error;
|
||||
|
||||
@ -412,9 +399,9 @@ class SyntaxError {
|
||||
}
|
||||
}
|
||||
|
||||
defineField(SyntaxError.prototype, "name", true, false, true, "SyntaxError");
|
||||
setPrototype(SyntaxError, Error);
|
||||
setPrototype(SyntaxError.prototype, Error.prototype);
|
||||
object.defineField(SyntaxError.prototype, "name", true, false, true, "SyntaxError");
|
||||
object.setPrototype(SyntaxError, Error);
|
||||
object.setPrototype(SyntaxError.prototype, Error.prototype);
|
||||
setCallable(SyntaxError, true);
|
||||
target.SyntaxError = SyntaxError;
|
||||
|
||||
@ -425,9 +412,9 @@ class TypeError {
|
||||
}
|
||||
}
|
||||
|
||||
defineField(TypeError.prototype, "name", true, false, true, "TypeError");
|
||||
setPrototype(TypeError, Error);
|
||||
setPrototype(TypeError.prototype, Error.prototype);
|
||||
object.defineField(TypeError.prototype, "name", true, false, true, "TypeError");
|
||||
object.setPrototype(TypeError, Error);
|
||||
object.setPrototype(TypeError.prototype, Error.prototype);
|
||||
setCallable(TypeError, true);
|
||||
target.TypeError = TypeError;
|
||||
|
||||
@ -438,9 +425,9 @@ class RangeError {
|
||||
}
|
||||
}
|
||||
|
||||
defineField(RangeError.prototype, "name", true, false, true, "RangeError");
|
||||
setPrototype(RangeError, Error);
|
||||
setPrototype(RangeError.prototype, Error.prototype);
|
||||
object.defineField(RangeError.prototype, "name", true, false, true, "RangeError");
|
||||
object.setPrototype(RangeError, Error);
|
||||
object.setPrototype(RangeError.prototype, Error.prototype);
|
||||
setCallable(RangeError, true);
|
||||
target.RangeError = RangeError;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user