Skip to content

Commit

Permalink
Fix: methods cannot be used as constructor
Browse files Browse the repository at this point in the history
The spec says that invoking a method as a constructor is not valid,
but invoking normal functions is. This is, for example, `node`:

```js
> o = { method() {}, notAMethod: function() {} }
{ method: [Function: method], notAMethod: [Function: notAMethod] }
> new o.method()
Uncaught TypeError: o.method is not a constructor
> new o.notAMethod()
notAMethod {}
```

This PR implements the same behavior in Rhino, and fixes #1299.
  • Loading branch information
andreabergia committed Dec 24, 2024
1 parent a65afb3 commit b462d96
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 4 deletions.
5 changes: 5 additions & 0 deletions rhino/src/main/java/org/mozilla/javascript/BaseFunction.java
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,11 @@ public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] ar

@Override
public Scriptable construct(Context cx, Scriptable scope, Object[] args) {
if (this.getHomeObject() != null) {
// Only methods have home objects associated with them
throw ScriptRuntime.typeErrorById("msg.not.ctor", getFunctionName());
}

Scriptable result = createObject(cx, scope);
if (result != null) {
Object val = call(cx, scope, result, args);
Expand Down
7 changes: 7 additions & 0 deletions rhino/src/main/java/org/mozilla/javascript/Interpreter.java
Original file line number Diff line number Diff line change
Expand Up @@ -2206,6 +2206,13 @@ private static Object interpretLoop(Context cx, CallFrame frame, Object throwabl
if (lhs instanceof InterpretedFunction) {
InterpretedFunction f = (InterpretedFunction) lhs;
if (frame.fnOrScript.securityDomain == f.securityDomain) {
if (f.getHomeObject() != null) {
// Only methods have home objects associated with
// them
throw ScriptRuntime.typeErrorById(
"msg.not.ctor", f.getFunctionName());
}

Scriptable newInstance =
f.createObject(cx, frame.scope);
CallFrame calleeFrame =
Expand Down
5 changes: 4 additions & 1 deletion tests/testsrc/jstests/harmony/method-definition.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ assertEquals(123, {
}.abc());

// Method is the kind of function, that is non-constructor.
// assertThrows('new (({ a() {} }).a)', TypeError);
assertThrows(function() {
new (({ a() {} }).a)
}, TypeError);
assertNotNull(new (({ notAMethod: function() {} }).notAMethod));

var desc = Object.getOwnPropertyDescriptor({
a() {
Expand Down
4 changes: 1 addition & 3 deletions tests/testsrc/test262.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4857,7 +4857,7 @@ language/expressions/new 41/59 (69.49%)

~language/expressions/new.target

language/expressions/object 719/1169 (61.51%)
language/expressions/object 717/1169 (61.33%)
dstr/async-gen-meth-ary-init-iter-close.js {unsupported: [async-iteration, async]}
dstr/async-gen-meth-ary-init-iter-get-err.js {unsupported: [async-iteration]}
dstr/async-gen-meth-ary-init-iter-get-err-array-prototype.js {unsupported: [async-iteration]}
Expand Down Expand Up @@ -5461,7 +5461,6 @@ language/expressions/object 719/1169 (61.51%)
method-definition/gen-yield-spread-arr-multiple.js
method-definition/gen-yield-spread-arr-single.js
method-definition/gen-yield-spread-obj.js
method-definition/generator-invoke-ctor.js
method-definition/generator-invoke-fn-strict.js non-strict
method-definition/generator-length-dflt.js
method-definition/generator-name-prop-string.js
Expand All @@ -5480,7 +5479,6 @@ language/expressions/object 719/1169 (61.51%)
method-definition/meth-eval-var-scope-syntax-err.js non-strict
method-definition/meth-object-destructuring-param-strict-body.js
method-definition/meth-rest-param-strict-body.js
method-definition/name-invoke-ctor.js
method-definition/name-invoke-fn-strict.js non-strict
method-definition/name-length-dflt.js
method-definition/name-name-prop-string.js
Expand Down

0 comments on commit b462d96

Please sign in to comment.