⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 284757 in webkit


Ignore:
Timestamp:
Oct 24, 2021, 8:32:25 AM (5 years ago)
Author:
commit-queue@webkit.org
Message:

InternalFunction::createSubclassStructure() should use prototype's global object
https://bugs.webkit.org/show_bug.cgi?id=231874

Patch by Alexey Shvayka <ashvayka@apple.com> on 2021-10-24
Reviewed by Yusuke Suzuki.

JSTests:

  • stress/internal-function-subclass-structure-realm.js: Added.

Source/JavaScriptCore:

In case NewTarget has a cross-realm "prototype" object, even though the instance
structure is created with correct Prototype, it's m_globalObject is of NewTarget's
realm instead of prototype's.

That is observable in various places, including when calling CustomAccessor, fast paths
for iteration protocol / collection constructors, isHavingABadTime() handling etc.

This patch fixes structure's global object to be correct: per spec [1], we fallback to
NewTarget's realm only if "prototype" is a primitive.

[1]: https://tc39.es/ecma262/#sec-getprototypefromconstructor (step 3.b)

  • runtime/InternalFunction.cpp:

(JSC::InternalFunction::createSubclassStructure):

Location:
trunk
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r284751 r284757  
     12021-10-24  Alexey Shvayka  <ashvayka@apple.com>
     2
     3        InternalFunction::createSubclassStructure() should use prototype's global object
     4        https://bugs.webkit.org/show_bug.cgi?id=231874
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        * stress/internal-function-subclass-structure-realm.js: Added.
     9
    1102021-10-23  Phillip Mates  <pmates@igalia.com>
    211
  • trunk/Source/JavaScriptCore/ChangeLog

    r284726 r284757  
     12021-10-24  Alexey Shvayka  <ashvayka@apple.com>
     2
     3        InternalFunction::createSubclassStructure() should use prototype's global object
     4        https://bugs.webkit.org/show_bug.cgi?id=231874
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        In case NewTarget has a cross-realm "prototype" object, even though the instance
     9        structure is created with correct [[Prototype]], it's m_globalObject is of NewTarget's
     10        realm instead of prototype's.
     11
     12        That is observable in various places, including when calling CustomAccessor, fast paths
     13        for iteration protocol / collection constructors, isHavingABadTime() handling etc.
     14
     15        This patch fixes structure's global object to be correct: per spec [1], we fallback to
     16        NewTarget's realm only if "prototype" is a primitive.
     17
     18        [1]: https://tc39.es/ecma262/#sec-getprototypefromconstructor (step 3.b)
     19
     20        * runtime/InternalFunction.cpp:
     21        (JSC::InternalFunction::createSubclassStructure):
     22
    1232021-10-22  Justin Michaud  <justin_michaud@apple.com>
    224
  • trunk/Source/JavaScriptCore/runtime/InternalFunction.cpp

    r282864 r284757  
    143143    // newTarget may be an InternalFunction if we were called from Reflect.construct.
    144144    JSFunction* targetFunction = jsDynamicCast<JSFunction*>(vm, newTarget);
    145     JSGlobalObject* baseGlobalObject = baseClass->globalObject();
    146145
    147146    if (LIKELY(targetFunction)) {
    148147        FunctionRareData* rareData = targetFunction->ensureRareData(vm);
    149148        Structure* structure = rareData->internalFunctionAllocationStructure();
    150         if (LIKELY(structure && structure->classInfo() == baseClass->classInfo() && structure->globalObject() == baseGlobalObject))
     149        if (LIKELY(structure && structure->classInfo() == baseClass->classInfo() && structure->globalObject() == baseClass->globalObject()))
    151150            return structure;
    152151
     
    155154        RETURN_IF_EXCEPTION(scope, nullptr);
    156155        if (JSObject* prototype = jsDynamicCast<JSObject*>(vm, prototypeValue))
    157             return rareData->createInternalFunctionAllocationStructureFromBase(vm, baseGlobalObject, prototype, baseClass);
     156            return rareData->createInternalFunctionAllocationStructureFromBase(vm, prototype->globalObject(vm), prototype, baseClass);
    158157    } else {
    159158        JSValue prototypeValue = newTarget->get(globalObject, vm.propertyNames->prototype);
     
    162161            // This only happens if someone Reflect.constructs our builtin constructor with another builtin constructor as the new.target.
    163162            // Thus, we don't care about the cost of looking up the structure from our hash table every time.
    164             return vm.structureCache.emptyStructureForPrototypeFromBaseStructure(baseGlobalObject, prototype, baseClass);
     163            return vm.structureCache.emptyStructureForPrototypeFromBaseStructure(prototype->globalObject(vm), prototype, baseClass);
    165164        }
    166165    }
Note: See TracChangeset for help on using the changeset viewer.