Ignore:
Timestamp:
May 8, 2014, 5:22:30 PM (11 years ago)
Author:
[email protected]
Message:

Base case for get-by-id inline cache doesn't check for HasImpureGetOwnPropertySlot
https://bugs.webkit.org/show_bug.cgi?id=132695

Reviewed by Filip Pizlo.

We check in the case where we're accessing something other than the base object (e.g. the prototype),
but we fail to do so for the base object.

  • jit/Repatch.cpp:

(JSC::tryCacheGetByID):
(JSC::tryBuildGetByIDList):

  • jsc.cpp: Added some infrastructure to support this test. We don't currently trigger this bug anywhere in WebKit

because all of the values that are returned that could be impure are set to uncacheable anyways.
(WTF::ImpureGetter::ImpureGetter):
(WTF::ImpureGetter::createStructure):
(WTF::ImpureGetter::create):
(WTF::ImpureGetter::finishCreation):
(WTF::ImpureGetter::getOwnPropertySlot):
(WTF::ImpureGetter::visitChildren):
(WTF::ImpureGetter::setDelegate):
(GlobalObject::finishCreation):
(functionCreateImpureGetter):
(functionSetImpureGetterDelegate):

  • tests/stress/impure-get-own-property-slot-inline-cache.js: Added.

(foo):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/jsc.cpp

    r168396 r168510  
    220220};
    221221
     222class ImpureGetter : public JSNonFinalObject {
     223public:
     224    ImpureGetter(VM& vm, Structure* structure)
     225        : Base(vm, structure)
     226    {
     227    }
     228
     229    DECLARE_INFO;
     230    typedef JSNonFinalObject Base;
     231
     232    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     233    {
     234        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     235    }
     236
     237    static ImpureGetter* create(VM& vm, Structure* structure, JSObject* delegate)
     238    {
     239        ImpureGetter* getter = new (NotNull, allocateCell<ImpureGetter>(vm.heap, sizeof(ImpureGetter))) ImpureGetter(vm, structure);
     240        getter->finishCreation(vm, delegate);
     241        return getter;
     242    }
     243
     244    void finishCreation(VM& vm, JSObject* delegate)
     245    {
     246        Base::finishCreation(vm);
     247        if (delegate)
     248            m_delegate.set(vm, this, delegate);
     249    }
     250
     251    static const unsigned StructureFlags = JSC::HasImpureGetOwnPropertySlot | JSC::OverridesGetOwnPropertySlot | JSC::OverridesVisitChildren | Base::StructureFlags;
     252
     253    static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName name, PropertySlot& slot)
     254    {
     255        ImpureGetter* thisObject = jsCast<ImpureGetter*>(object);
     256       
     257        if (thisObject->m_delegate && thisObject->m_delegate->getPropertySlot(exec, name, slot))
     258            return true;
     259
     260        return Base::getOwnPropertySlot(object, exec, name, slot);
     261    }
     262
     263    static void visitChildren(JSCell* cell, SlotVisitor& visitor)
     264    {
     265        Base::visitChildren(cell, visitor);
     266        ImpureGetter* thisObject = jsCast<ImpureGetter*>(cell);
     267        visitor.append(&thisObject->m_delegate);
     268    }
     269
     270    void setDelegate(VM& vm, JSObject* delegate)
     271    {
     272        m_delegate.set(vm, this, delegate);
     273    }
     274
     275private:
     276    WriteBarrier<JSObject> m_delegate;
     277};
     278
    222279const ClassInfo Element::s_info = { "Element", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(Element) };
    223280const ClassInfo Masquerader::s_info = { "Masquerader", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(Masquerader) };
    224281const ClassInfo Root::s_info = { "Root", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(Root) };
     282const ClassInfo ImpureGetter::s_info = { "ImpureGetter", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ImpureGetter) };
    225283
    226284ElementHandleOwner* Element::handleOwner()
     
    243301
    244302static EncodedJSValue JSC_HOST_CALL functionCreateProxy(ExecState*);
     303static EncodedJSValue JSC_HOST_CALL functionCreateImpureGetter(ExecState*);
     304static EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(ExecState*);
    245305
    246306static EncodedJSValue JSC_HOST_CALL functionSetElementRoot(ExecState*);
     
    422482
    423483        addFunction(vm, "createProxy", functionCreateProxy, 1);
     484
     485        addFunction(vm, "createImpureGetter", functionCreateImpureGetter, 1);
     486        addFunction(vm, "setImpureGetterDelegate", functionSetImpureGetterDelegate, 2);
    424487       
    425488        JSArray* array = constructEmptyArray(globalExec(), 0);
     
    590653    JSProxy* proxy = JSProxy::create(exec->vm(), structure, jsTarget);
    591654    return JSValue::encode(proxy);
     655}
     656
     657EncodedJSValue JSC_HOST_CALL functionCreateImpureGetter(ExecState* exec)
     658{
     659    JSLockHolder lock(exec);
     660    JSValue target = exec->argument(0);
     661    JSObject* delegate = nullptr;
     662    if (target.isObject())
     663        delegate = asObject(target.asCell());
     664    Structure* structure = ImpureGetter::createStructure(exec->vm(), exec->lexicalGlobalObject(), jsNull());
     665    ImpureGetter* result = ImpureGetter::create(exec->vm(), structure, delegate);
     666    return JSValue::encode(result);
     667}
     668
     669EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(ExecState* exec)
     670{
     671    JSLockHolder lock(exec);
     672    JSValue base = exec->argument(0);
     673    if (!base.isObject())
     674        return JSValue::encode(jsUndefined());
     675    JSValue delegate = exec->argument(1);
     676    if (!delegate.isObject())
     677        return JSValue::encode(jsUndefined());
     678    ImpureGetter* impureGetter = jsCast<ImpureGetter*>(asObject(base.asCell()));
     679    impureGetter->setDelegate(exec->vm(), asObject(delegate.asCell()));
     680    return JSValue::encode(jsUndefined());
    592681}
    593682
Note: See TracChangeset for help on using the changeset viewer.