Skip to content

Commit

Permalink
Allow updating of name of a function, as required by the standard (#…
Browse files Browse the repository at this point in the history
…1398)

Make the attributes of the "name" properties of functions match current ECMAScript specs.

See #1297 for more details
  • Loading branch information
andreabergia authored Oct 31, 2023
1 parent 1457790 commit 05ab4ff
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 19 deletions.
1 change: 1 addition & 0 deletions src/org/mozilla/javascript/Arguments.java
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ private static class ThrowTypeError extends BaseFunction {

ThrowTypeError(String propertyName) {
this.propertyName = propertyName;
super.setInstanceIdAttributes(BaseFunction.Id_name, PERMANENT | READONLY | DONTENUM);
}

@Override
Expand Down
14 changes: 11 additions & 3 deletions src/org/mozilla/javascript/BaseFunction.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public boolean hasInstance(Scriptable instance) {
throw ScriptRuntime.typeErrorById("msg.instanceof.bad.prototype", getFunctionName());
}

private static final int Id_length = 1,
protected static final int Id_length = 1,
Id_arity = 2,
Id_name = 3,
Id_prototype = 4,
Expand Down Expand Up @@ -169,7 +169,9 @@ protected Object getInstanceIdValue(int id) {
case Id_arity:
return arityPropertyAttributes >= 0 ? getArity() : NOT_FOUND;
case Id_name:
return namePropertyAttributes >= 0 ? getFunctionName() : NOT_FOUND;
return namePropertyAttributes >= 0
? (nameValue != null ? nameValue : getFunctionName())
: NOT_FOUND;
case Id_prototype:
return getPrototypeProperty();
case Id_arguments:
Expand Down Expand Up @@ -200,6 +202,11 @@ protected void setInstanceIdValue(int id, Object value) {
case Id_name:
if (value == NOT_FOUND) {
namePropertyAttributes = -1;
nameValue = null;
} else if (value instanceof CharSequence) {
nameValue = ScriptRuntime.toString(value);
} else {
nameValue = "";
}
return;
case Id_arity:
Expand Down Expand Up @@ -650,6 +657,7 @@ protected int findPrototypeId(String s) {

private Object prototypeProperty;
private Object argumentsObj = NOT_FOUND;
private String nameValue = null;
private boolean isGeneratorFunction = false;

// For function object instances, attributes are
Expand All @@ -658,6 +666,6 @@ protected int findPrototypeId(String s) {
private int prototypePropertyAttributes = PERMANENT | DONTENUM;
private int argumentsAttributes = PERMANENT | DONTENUM;
private int arityPropertyAttributes = PERMANENT | READONLY | DONTENUM;
private int namePropertyAttributes = PERMANENT | READONLY | DONTENUM;
private int namePropertyAttributes = READONLY | DONTENUM;
private int lengthPropertyAttributes = PERMANENT | READONLY | DONTENUM;
}
5 changes: 3 additions & 2 deletions src/org/mozilla/javascript/IdScriptableObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -867,13 +867,14 @@ protected void defineOwnProperty(
checkPropertyChange(name, current, desc);
int attr = (info >>> 16);
Object value = getProperty(desc, "value");
if (value != NOT_FOUND && (attr & READONLY) == 0) {
if (value != NOT_FOUND && ((attr & READONLY) == 0 || (attr & PERMANENT) == 0)) {
Object currentValue = getInstanceIdValue(id);
if (!sameValue(value, currentValue)) {
setInstanceIdValue(id, value);
}
}
setAttributes(name, applyDescriptorToAttributeBitset(attr, desc));
attr = applyDescriptorToAttributeBitset(attr, desc);
setAttributes(name, attr);
return;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.javascript.tests.es6;

import static org.junit.Assert.assertEquals;

import org.junit.Test;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.tests.Utils;

/** Test that we can redefine a function's name. */
public class Issue1297FunctionNameTest {
private static final String source =
"'use strict';"
+ "function X() {};\n"
+ "Object.defineProperty(X, 'name', {value: 'y', configurable: true, writable: true});"
+ "X.name";

@Test
public void canSetFunctionName() {
Utils.runWithAllOptimizationLevels(
cx -> {
Scriptable scope = cx.initStandardObjects(null);
Object result = cx.evaluateString(scope, source, "test", 1, null);
assertEquals("y", result);
return null;
});
}
}
21 changes: 7 additions & 14 deletions testsrc/test262.properties
Original file line number Diff line number Diff line change
Expand Up @@ -449,12 +449,10 @@ built-ins/Date 39/707 (5.52%)
S15.1.3.2_A2.4_T1.js
S15.1.3.2_A5.2.js

built-ins/encodeURI 2/30 (6.67%)
name.js
built-ins/encodeURI 1/30 (3.33%)
S15.1.3.3_A5.2.js

built-ins/encodeURIComponent 2/30 (6.67%)
name.js
built-ins/encodeURIComponent 1/30 (3.33%)
S15.1.3.4_A5.2.js

built-ins/Error 5/42 (11.9%)
Expand All @@ -464,9 +462,8 @@ built-ins/Error 5/42 (11.9%)
prototype/S15.11.4_A2.js
proto-from-ctor-realm.js {unsupported: [Reflect]}

built-ins/eval 3/9 (33.33%)
built-ins/eval 2/9 (22.22%)
length-non-configurable.js
name.js
private-identifiers-not-empty.js {unsupported: [class-fields-private]}

built-ins/Function 186/505 (36.83%)
Expand Down Expand Up @@ -674,19 +671,17 @@ built-ins/global 0/29 (0.0%)

built-ins/Infinity 0/6 (0.0%)

built-ins/isFinite 8/16 (50.0%)
built-ins/isFinite 7/16 (43.75%)
length.js
name.js
toprimitive-call-abrupt.js
toprimitive-get-abrupt.js
toprimitive-not-callable-throws.js
toprimitive-result-is-object-throws.js
toprimitive-result-is-symbol-throws.js
toprimitive-valid-result.js

built-ins/isNaN 8/16 (50.0%)
built-ins/isNaN 7/16 (43.75%)
length.js
name.js
toprimitive-call-abrupt.js
toprimitive-get-abrupt.js
toprimitive-not-callable-throws.js
Expand Down Expand Up @@ -901,13 +896,11 @@ built-ins/Object 127/3150 (4.03%)
proto-from-ctor-realm.js {unsupported: [Reflect]}
subclass-object-arg.js {unsupported: [Reflect.construct, Reflect, class]}

built-ins/parseFloat 3/58 (5.17%)
name.js
built-ins/parseFloat 2/58 (3.45%)
S15.1.2.3_A2_T10_U180E.js {unsupported: [u180e]}
S15.1.2.3_A7.2.js

built-ins/parseInt 3/60 (5.0%)
name.js
built-ins/parseInt 2/60 (3.33%)
S15.1.2.2_A2_T10_U180E.js {unsupported: [u180e]}
S15.1.2.2_A9.2.js

Expand Down

0 comments on commit 05ab4ff

Please sign in to comment.