Skip to content

Commit

Permalink
Experimental-computed-props
Browse files Browse the repository at this point in the history
  • Loading branch information
rPraml committed May 25, 2021
1 parent 88d40c6 commit 98ef815
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 69 deletions.
52 changes: 36 additions & 16 deletions src/org/mozilla/javascript/CodeGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -1130,21 +1130,7 @@ private void visitLiteral(Node node, Node child) {
addIndexOp(Icode_LITERAL_NEW, count);
stackChange(2);
while (child != null) {
int childType = child.getType();
if (childType == Token.GET) {
visitExpression(child.getFirstChild(), 0);
addIcode(Icode_LITERAL_GETTER);
} else if (childType == Token.SET) {
visitExpression(child.getFirstChild(), 0);
addIcode(Icode_LITERAL_SETTER);
} else if (childType == Token.METHOD) {
visitExpression(child.getFirstChild(), 0);
addIcode(Icode_LITERAL_SET);
} else {
visitExpression(child, 0);
addIcode(Icode_LITERAL_SET);
}
stackChange(-1);
visitLiteral(child);
child = child.getNext();
}
if (type == Token.ARRAYLIT) {
Expand All @@ -1157,9 +1143,43 @@ private void visitLiteral(Node node, Node child) {
addIndexOp(Icode_SPARE_ARRAYLIT, index);
}
} else {
int computedProps = 0;
for (Object propertyId : propertyIds) {
if (propertyId instanceof Node) {
computedProps++;
}
}
if (computedProps > 0) {
addIndexOp(Icode_LITERAL_NEW, computedProps);
stackChange(2);
for (Object propertyId : propertyIds) {
if (propertyId instanceof Node) {
visitLiteral((Node) propertyId);
}
}
stackChange(-2);
}
int index = literalIds.size();
literalIds.add(propertyIds);
addIndexOp(Token.OBJECTLIT, index);
addIndexOp(computedProps == 0 ? Token.OBJECTLIT : Icode_OBJECT_COMPUTED_PROPS, index);
}
stackChange(-1);
}

private void visitLiteral(Node child) {
int childType = child.getType();
if (childType == Token.GET) {
visitExpression(child.getFirstChild(), 0);
addIcode(Icode_LITERAL_GETTER);
} else if (childType == Token.SET) {
visitExpression(child.getFirstChild(), 0);
addIcode(Icode_LITERAL_SETTER);
} else if (childType == Token.METHOD) {
visitExpression(child.getFirstChild(), 0);
addIcode(Icode_LITERAL_SET);
} else {
visitExpression(child, 0);
addIcode(Icode_LITERAL_SET);
}
stackChange(-1);
}
Expand Down
4 changes: 4 additions & 0 deletions src/org/mozilla/javascript/IRFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,10 @@ private Object getPropKey(Node id) {
double n = ((NumberLiteral) id).getNumber();
decompiler.addNumber(n);
key = ScriptRuntime.getIndexObject(n);
} else if (id instanceof AstNode) {
decompiler.addToken(Token.LB);
key = transform((AstNode) id);
decompiler.addToken(Token.RB);
} else {
throw Kit.codeBug();
}
Expand Down
4 changes: 3 additions & 1 deletion src/org/mozilla/javascript/Icode.java
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,10 @@ abstract class Icode {
Icode_REG_BIGINT2 = -72,
Icode_REG_BIGINT4 = -73,

// Object with computed properties
Icode_OBJECT_COMPUTED_PROPS = -74,
// Last icode
MIN_ICODE = -73;
MIN_ICODE = -74;

static String bytecodeName(int bytecode) {
if (!validBytecode(bytecode)) {
Expand Down
22 changes: 22 additions & 0 deletions src/org/mozilla/javascript/Interpreter.java
Original file line number Diff line number Diff line change
Expand Up @@ -2262,6 +2262,28 @@ private static Object interpretLoop(Context cx, CallFrame frame, Object throwabl
stack[stackTop] = val;
continue Loop;
}
case Icode_OBJECT_COMPUTED_PROPS:
{
Object[] computedProps = (Object[]) stack[stackTop];
--stackTop;
int[] computedPropsSetters = (int[]) stack[stackTop];
--stackTop;
Object[] data = (Object[]) stack[stackTop];
--stackTop;
int[] getterSetters = (int[]) stack[stackTop];
Object[] props = (Object[]) frame.idata.literalIds[indexReg];
int j = 0;
for (int i = 0; i < props.length; i++) {
if (props[i] instanceof Node) {
props[i] = computedProps[j++];
}
}
Object val =
ScriptRuntime.newObjectLiteral(
props, data, getterSetters, cx, frame.scope);
stack[stackTop] = val;
continue Loop;
}
case Icode_ENTERDQ:
{
Object lhs = stack[stackTop];
Expand Down
20 changes: 17 additions & 3 deletions src/org/mozilla/javascript/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -3425,11 +3425,19 @@ private ObjectLiteral objectLiteral() throws IOException {
if (afterComma != -1) warnTrailingComma(pos, elems, afterComma);
break commaLoop;
}
AstNode pname = objliteralProperty();
AstNode pname;
if (tt == Token.LB) {
consumeToken();
pname = assignExpr();
mustMatchToken(Token.RB, "msg.bad.prop", true);
propertyName = "[" + pname.toSource() + "]";
} else {
pname = objliteralProperty();
propertyName = ts.getString();
}
if (pname == null) {
reportError("msg.bad.prop");
} else {
propertyName = ts.getString();
int ppos = ts.tokenBeg;
consumeToken();

Expand All @@ -3453,7 +3461,13 @@ private ObjectLiteral objectLiteral() throws IOException {
}
}
if (entryKind == GET_ENTRY || entryKind == SET_ENTRY) {
pname = objliteralProperty();
if (peeked == Token.LB) {
consumeToken();
pname = assignExpr();
mustMatchToken(Token.RB, "msg.bad.prop", true);
} else {
pname = objliteralProperty();
}
if (pname == null) {
reportError("msg.bad.prop");
}
Expand Down
2 changes: 1 addition & 1 deletion src/org/mozilla/javascript/ScriptRuntime.java
Original file line number Diff line number Diff line change
Expand Up @@ -4312,7 +4312,7 @@ public static Scriptable newObjectLiteral(
ScriptableObject so = (ScriptableObject) object;
Callable getterOrSetter = (Callable) value;
boolean isSetter = getterSetter == 1;
so.setGetterOrSetter((String) id, 0, getterOrSetter, isSetter);
so.setGetterOrSetter(stringId, 0, getterOrSetter, isSetter);
}
}
}
Expand Down
16 changes: 12 additions & 4 deletions src/org/mozilla/javascript/optimizer/BodyCodegen.java
Original file line number Diff line number Diff line change
Expand Up @@ -2018,17 +2018,25 @@ private void visitArrayLiteral(Node node, Node child, boolean topLevel) {
}

/** load array with property ids */
private void addLoadPropertyIds(Object[] properties, int count) {
private void addLoadPropertyIds(Node node, Object[] properties, int count) {
addNewObjectArray(count);
for (int i = 0; i != count; ++i) {
cfw.add(ByteCode.DUP);
cfw.addPush(i);
Object id = properties[i];
if (id instanceof String) {
cfw.addPush((String) id);
} else {
} else if (id instanceof Integer) {
cfw.addPush(((Integer) id).intValue());
addScriptRuntimeInvoke("wrapInt", "(I)Ljava/lang/Integer;");
} else {
Node child = (Node) id;
int childType = child.getType();
if (childType == Token.GET || childType == Token.SET || childType == Token.METHOD) {
generateExpression(child.getFirstChild(), node);
} else {
generateExpression(child, node);
}
}
cfw.add(ByteCode.AASTORE);
}
Expand Down Expand Up @@ -2110,11 +2118,11 @@ private void visitObjectLiteral(Node node, Node child, boolean topLevel) {
// TODO: this is actually only necessary if the yield operation is
// a child of this object or its children (bug 757410)
addLoadPropertyValues(node, child, count);
addLoadPropertyIds(properties, count);
addLoadPropertyIds(node, properties, count);
// swap property-values and property-ids arrays
cfw.add(ByteCode.SWAP);
} else {
addLoadPropertyIds(properties, count);
addLoadPropertyIds(node, properties, count);
addLoadPropertyValues(node, child, count);
}

Expand Down
17 changes: 17 additions & 0 deletions testsrc/org/mozilla/javascript/tests/es6/NativeObjectTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,24 @@ public void testFromEntriesOnArray() {
evaluateAndAssert("Object.fromEntries(Object.entries(['x','y','z']))", map);
}

@Test
public void testSymbolKey() {
// TODO: Write proper tests.
cx.setOptimizationLevel(0);
Object result =
cx.evaluateString(
scope, "({[Symbol.iterator]:'foo'})[Symbol.iterator]", "test", 1, null);

assertEquals("foo", result);
result =
cx.evaluateString(
scope, "Object.keys({[4+Math.PI]:'foo'}).join(',')", "test", 1, null);

assertEquals("7.141592653589793", result);
}

private void evaluateAndAssert(String script, Object expected) {

Object result = cx.evaluateString(scope, script, "test", 1, null);
assertEquals(expected, result);
}
Expand Down
45 changes: 1 addition & 44 deletions testsrc/test262.properties
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,6 @@ built-ins/Array
! from/iter-map-fn-this-non-strict.js
! from/iter-set-elem-prop-err.js
! from/source-object-constructor.js
# Uses "get" syntax that's not implemented
! from/source-object-iterator-1.js
! from/source-object-iterator-2.js
# Object.preventExtensions doesn't seem to throw
! of/return-abrupt-from-data-property.js
! prototype/Symbol.unscopables/prop-desc.js
Expand Down Expand Up @@ -152,8 +149,7 @@ built-ins/BigInt
# Check IsInteger in ES2020, not IsSafeInteger
# https://github.com/tc39/test262/commit/bf1b79d65a760a5f03df1198557da2d010f8f397#diff-3ecd6a0c50da5c8f8eff723afb6182a889b7315d99545b055559e22d302cc453
! prototype/toString/prototype-call.js
# Computed property is not support
! prototype/toString/thisbigintvalue-not-valid-throws.js


built-ins/Boolean

Expand Down Expand Up @@ -628,7 +624,6 @@ built-ins/JSON
! stringify/value-tojson-arguments.js

built-ins/Map
! iterator-is-undefined-throws.js
! Symbol.species/length.js
! Symbol.species/return-value.js
! Symbol.species/symbol-species-name.js
Expand Down Expand Up @@ -729,18 +724,11 @@ built-ins/Object
! defineProperty/15.2.3.6-4-293-3.js
! defineProperty/15.2.3.6-4-293-4.js
! defineProperty/15.2.3.6-4-336.js
! fromEntries/evaluation-order.js
! fromEntries/iterator-closed-for-null-entry.js
! fromEntries/iterator-closed-for-string-entry.js
! fromEntries/iterator-closed-for-throwing-entry-key-accessor.js
! fromEntries/iterator-closed-for-throwing-entry-key-tostring.js
! fromEntries/iterator-closed-for-throwing-entry-value-accessor.js
! fromEntries/iterator-not-closed-for-next-returning-non-object.js
! fromEntries/iterator-not-closed-for-throwing-done-accessor.js
! fromEntries/iterator-not-closed-for-throwing-next.js
! fromEntries/iterator-not-closed-for-uncallable-next.js
! fromEntries/to-property-key.js
! fromEntries/uses-keys-not-iterator.js
! getOwnPropertyDescriptor/15.2.3.3-4-187.js
! getOwnPropertyDescriptor/15.2.3.3-4-212.js
! getOwnPropertyDescriptor/15.2.3.3-4-213.js
Expand Down Expand Up @@ -1118,32 +1106,18 @@ built-ins/String
! prototype/substring/S15.5.4.15_A1_T5.js
! prototype/toLocaleLowerCase/special_casing_conditional.js
! prototype/toLowerCase/special_casing_conditional.js
! prototype/trimEnd/this-value-object-cannot-convert-to-primitive-err.js
! prototype/trimEnd/this-value-object-toprimitive-call-err.js
! prototype/trimEnd/this-value-object-toprimitive-meth-err.js
! prototype/trimEnd/this-value-object-toprimitive-meth-priority.js
! prototype/trimEnd/this-value-object-toprimitive-returns-object-err.js
! prototype/trimEnd/this-value-object-tostring-call-err.js
! prototype/trimEnd/this-value-object-tostring-meth-err.js
! prototype/trimEnd/this-value-object-tostring-meth-priority.js
! prototype/trimEnd/this-value-object-tostring-returns-object-err.js
! prototype/trimEnd/this-value-object-valueof-call-err.js
! prototype/trimEnd/this-value-object-valueof-meth-err.js
! prototype/trimEnd/this-value-object-valueof-meth-priority.js
! prototype/trimEnd/this-value-object-valueof-returns-object-err.js
! prototype/trimStart/this-value-object-cannot-convert-to-primitive-err.js
! prototype/trimStart/this-value-object-toprimitive-call-err.js
! prototype/trimStart/this-value-object-toprimitive-meth-err.js
! prototype/trimStart/this-value-object-toprimitive-meth-priority.js
! prototype/trimStart/this-value-object-toprimitive-returns-object-err.js
! prototype/trimStart/this-value-object-tostring-call-err.js
! prototype/trimStart/this-value-object-tostring-meth-err.js
! prototype/trimStart/this-value-object-tostring-meth-priority.js
! prototype/trimStart/this-value-object-tostring-returns-object-err.js
! prototype/trimStart/this-value-object-valueof-call-err.js
! prototype/trimStart/this-value-object-valueof-meth-err.js
! prototype/trimStart/this-value-object-valueof-meth-priority.js
! prototype/trimStart/this-value-object-valueof-returns-object-err.js
! raw/return-the-string-value-from-template.js
! raw/special-characters.js
! raw/template-substitutions-are-appended-on-same-index.js
Expand Down Expand Up @@ -2838,7 +2812,6 @@ language/comments

language/computed-property-names
! basics/number.js
! basics/string.js
! basics/symbol.js
! class/accessor/getter-duplicates.js
! class/accessor/getter.js
Expand Down Expand Up @@ -2868,13 +2841,10 @@ language/computed-property-names
! class/static/setter-prototype.js
! object/accessor/getter-duplicates.js
! object/accessor/getter-super.js
! object/accessor/getter.js
! object/accessor/setter-duplicates.js
! object/accessor/setter-super.js
! object/accessor/setter.js
! object/method/generator.js
! object/method/number.js
! object/method/string.js
! object/method/super.js
! object/method/symbol.js
! object/property/number-duplicates.js
Expand Down Expand Up @@ -3696,29 +3666,17 @@ language/expressions/object
! 11.1.5_4-4-a-3.js
! 11.1.5_4-4-b-1.js
! __proto__-permitted-dup.js
! accessor-name-computed-err-evaluation.js
! accessor-name-computed-err-to-prop-key.js
! accessor-name-computed-err-unresolvable.js
! accessor-name-computed-in.js
! accessor-name-computed-yield-expr.js
! accessor-name-computed-yield-id.js
! accessor-name-computed.js
! accessor-name-literal-numeric-binary.js
! accessor-name-literal-numeric-exponent.js
! accessor-name-literal-numeric-hex.js
! accessor-name-literal-numeric-leading-decimal.js
! accessor-name-literal-numeric-non-canonical.js
! accessor-name-literal-numeric-octal.js
! accessor-name-literal-numeric-zero.js
! accessor-name-literal-string-char-escape.js
! accessor-name-literal-string-default.js
! accessor-name-literal-string-default-escaped.js
! accessor-name-literal-string-default-escaped-ext.js
! accessor-name-literal-string-double-quote.js
! accessor-name-literal-string-empty.js
! accessor-name-literal-string-hex-escape.js
! accessor-name-literal-string-line-continuation.js
! accessor-name-literal-string-single-quote.js
! accessor-name-literal-string-unicode-escape.js
! computed-__proto__.js
! computed-property-evaluation-order.js
Expand Down Expand Up @@ -4051,7 +4009,6 @@ language/expressions/object
! method-definition/name-param-id-yield.js
! method-definition/name-param-init-yield.js
! method-definition/name-param-redecl.js
! method-definition/name-prop-name-eval-error.js
! method-definition/name-prop-name-yield-expr.js
! method-definition/name-prop-name-yield-id.js
! method-definition/name-prototype-prop.js
Expand Down

0 comments on commit 98ef815

Please sign in to comment.