Changeset 267029 in webkit


Ignore:
Timestamp:
Sep 14, 2020 12:49:01 PM (4 years ago)
Author:
Alexey Shvayka
Message:

Make a few built-in methods throw if called as top-level functions
https://bugs.webkit.org/show_bug.cgi?id=216467

Reviewed by Darin Adler.

JSTests:

  • test262/expectations.yaml: Mark 10 test cases as passing.

Source/JavaScriptCore:

Non-strict userland functions substitute undefined & null this values
with the global object [1], while built-in functions do not [2].

This patch adds 5 missing toThis(globalObject, ECMAMode::strict()) calls,
preventing built-in methods from being called as top-level functions:

`
let {toString} = Error.prototype;
toString(); now throws TypeError
`

Aligns JSC with V8 and SpiderMonkey.
This change is performance-neutral due to DFG inlining of OpToThis.
All other callFrame->thisValue() usages were vetted to be spec-correct.

[1]: https://tc39.es/ecma262/#sec-ordinarycallbindthis (step 6.a.iii)
[2]: https://tc39.es/ecma262/#sec-built-in-function-objects-call-thisargument-argumentslist (step 10)

  • runtime/ArrayPrototype.cpp:

(JSC::createArrayIteratorObject):

  • runtime/DatePrototype.cpp:

(JSC::dateProtoFuncToPrimitiveSymbol):
(JSC::dateProtoFuncToJSON):

  • runtime/ErrorPrototype.cpp:

(JSC::errorProtoFuncToString):

  • runtime/RegExpPrototype.cpp:

(JSC::regExpProtoFuncToString):

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r267017 r267029  
     12020-09-14  Alexey Shvayka  <shvaikalesh@gmail.com>
     2
     3        Make a few built-in methods throw if called as top-level functions
     4        https://bugs.webkit.org/show_bug.cgi?id=216467
     5
     6        Reviewed by Darin Adler.
     7
     8        * test262/expectations.yaml: Mark 10 test cases as passing.
     9
    1102020-09-14  Saam Barati  <sbarati@apple.com>
    211
  • trunk/JSTests/test262/expectations.yaml

    r266973 r267029  
    610610  default: 'Test262Error: Expected a RangeError but got a TypeError'
    611611  strict mode: 'Test262Error: Expected a RangeError but got a TypeError'
    612 test/built-ins/Array/prototype/methods-called-as-functions.js:
    613   default: 'Test262Error: entries Expected a TypeError to be thrown but no exception was thrown at all'
    614   strict mode: 'Test262Error: entries Expected a TypeError to be thrown but no exception was thrown at all'
    615612test/built-ins/ArrayBuffer/prototype/byteLength/detached-buffer.js:
    616613  default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
     
    643640  default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
    644641  strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
    645 test/built-ins/Date/prototype/Symbol.toPrimitive/called-as-function.js:
    646   default: 'Test262Error: Expected a TypeError but got a Test262Error'
    647   strict mode: 'Test262Error: Expected a TypeError but got a Test262Error'
    648 test/built-ins/Date/prototype/toJSON/called-as-function.js:
    649   default: 'Test262Error: Expected a TypeError but got a Test262Error'
    650   strict mode: 'Test262Error: Expected a TypeError but got a Test262Error'
    651 test/built-ins/Error/prototype/toString/called-as-function.js:
    652   default: 'Test262Error: Expected a TypeError but got a Test262Error'
    653   strict mode: 'Test262Error: Expected a TypeError but got a Test262Error'
    654642test/built-ins/Function/call-bind-this-realm-undef.js:
    655643  default: 'Test262Error: implicit undefined Expected SameValue(«[object global]», «[object Undefined]») to be true'
     
    12861274  default: 'Test262Error: Expected SameValue(«�», «null») to be true'
    12871275  strict mode: 'Test262Error: Expected SameValue(«�», «null») to be true'
    1288 test/built-ins/RegExp/prototype/toString/called-as-function.js:
    1289   default: 'Test262Error: Expected a TypeError but got a Test262Error'
    1290   strict mode: 'Test262Error: Expected a TypeError but got a Test262Error'
    12911276test/built-ins/RegExp/quantifier-integer-limit.js:
    12921277  default: 'SyntaxError: Invalid regular expression: number too large in {} quantifier'
  • trunk/Source/JavaScriptCore/ChangeLog

    r267028 r267029  
     12020-09-14  Alexey Shvayka  <shvaikalesh@gmail.com>
     2
     3        Make a few built-in methods throw if called as top-level functions
     4        https://bugs.webkit.org/show_bug.cgi?id=216467
     5
     6        Reviewed by Darin Adler.
     7
     8        Non-strict userland functions substitute undefined & null `this` values
     9        with the global object [1], while built-in functions do not [2].
     10
     11        This patch adds 5 missing toThis(globalObject, ECMAMode::strict()) calls,
     12        preventing built-in methods from being called as top-level functions:
     13
     14        ```
     15        let {toString} = Error.prototype;
     16        toString(); // now throws TypeError
     17        ```
     18
     19        Aligns JSC with V8 and SpiderMonkey.
     20        This change is performance-neutral due to DFG inlining of OpToThis.
     21        All other callFrame->thisValue() usages were vetted to be spec-correct.
     22
     23        [1]: https://tc39.es/ecma262/#sec-ordinarycallbindthis (step 6.a.iii)
     24        [2]: https://tc39.es/ecma262/#sec-built-in-function-objects-call-thisargument-argumentslist (step 10)
     25
     26        * runtime/ArrayPrototype.cpp:
     27        (JSC::createArrayIteratorObject):
     28        * runtime/DatePrototype.cpp:
     29        (JSC::dateProtoFuncToPrimitiveSymbol):
     30        (JSC::dateProtoFuncToJSON):
     31        * runtime/ErrorPrototype.cpp:
     32        (JSC::errorProtoFuncToString):
     33        * runtime/RegExpPrototype.cpp:
     34        (JSC::regExpProtoFuncToString):
     35
    1362020-09-14  Devin Rousso  <drousso@apple.com>
    237
  • trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp

    r266641 r267029  
    829829    auto scope = DECLARE_THROW_SCOPE(vm);
    830830
    831     JSObject* thisObject  = callFrame->thisValue().toObject(globalObject);
     831    JSObject* thisObject = callFrame->thisValue().toThis(globalObject, ECMAMode::strict()).toObject(globalObject);
    832832    EXCEPTION_ASSERT(!!scope.exception() == !thisObject);
    833833    UNUSED_PARAM(scope);
  • trunk/Source/JavaScriptCore/runtime/DatePrototype.cpp

    r263250 r267029  
    353353    VM& vm = globalObject->vm();
    354354    auto scope = DECLARE_THROW_SCOPE(vm);
    355     JSValue thisValue = callFrame->thisValue();
     355    JSValue thisValue = callFrame->thisValue().toThis(globalObject, ECMAMode::strict());
    356356    if (!thisValue.isObject())
    357357        return throwVMTypeError(globalObject, scope, "Date.prototype[Symbol.toPrimitive] expected |this| to be an object.");
     
    884884    VM& vm = globalObject->vm();
    885885    auto scope = DECLARE_THROW_SCOPE(vm);
    886     JSValue thisValue = callFrame->thisValue();
     886    JSValue thisValue = callFrame->thisValue().toThis(globalObject, ECMAMode::strict());
    887887    JSObject* object = thisValue.toObject(globalObject);
    888888    RETURN_IF_EXCEPTION(scope, encodedJSValue());
  • trunk/Source/JavaScriptCore/runtime/ErrorPrototype.cpp

    r261895 r267029  
    7474
    7575    // 1. Let O be the this value.
    76     JSValue thisValue = callFrame->thisValue();
     76    JSValue thisValue = callFrame->thisValue().toThis(globalObject, ECMAMode::strict());
    7777
    7878    // 2. If Type(O) is not Object, throw a TypeError exception.
  • trunk/Source/JavaScriptCore/runtime/RegExpPrototype.cpp

    r262908 r267029  
    207207    auto scope = DECLARE_THROW_SCOPE(vm);
    208208
    209     JSValue thisValue = callFrame->thisValue();
     209    JSValue thisValue = callFrame->thisValue().toThis(globalObject, ECMAMode::strict());
    210210    if (!thisValue.isObject())
    211211        return throwVMTypeError(globalObject, scope);
Note: See TracChangeset for help on using the changeset viewer.