Changeset 225129 in webkit for trunk/Source/JavaScriptCore/tools


Ignore:
Timestamp:
Nov 24, 2017, 2:58:16 AM (8 years ago)
Author:
[email protected]
Message:

Move unsafe jsc shell test functions to the $vm object.
https://bugs.webkit.org/show_bug.cgi?id=179980

Reviewed by Yusuke Suzuki.

JSTests:

  • controlFlowProfiler/driver/driver.js:
  • controlFlowProfiler/execution-count.js:
  • controlFlowProfiler/if-statement.js:
  • controlFlowProfiler/loop-statements.js:
  • controlFlowProfiler/switch-statements.js:
  • controlFlowProfiler/test-jit.js:
  • exceptionFuzz/3d-cube.js:
  • exceptionFuzz/date-format-xparb.js:
  • exceptionFuzz/earley-boyer.js:
  • heapProfiler/basic-edges.js:
  • heapProfiler/property-edge-types.js:
  • microbenchmarks/try-get-by-id-basic.js:
  • microbenchmarks/try-get-by-id-polymorphic.js:
  • modules/namespace-object-try-get.js:
  • stress/argument-count-bytecode.js:
  • stress/argument-intrinsic-basic.js:
  • stress/argument-intrinsic-inlining-use-caller-arg.js:
  • stress/argument-intrinsic-inlining-with-result-escape.js:
  • stress/argument-intrinsic-inlining-with-vararg-with-enough-arguments.js:
  • stress/argument-intrinsic-inlining-with-vararg.js:
  • stress/argument-intrinsic-nested-inlining.js:
  • stress/argument-intrinsic-not-convert-to-get-argument.js:
  • stress/argument-intrinsic-with-stack-write.js:
  • stress/arity-mismatch-get-argument.js:
  • stress/array-message-passing.js:
  • stress/array-push-with-force-exit.js:
  • stress/check-dom-with-signature.js:
  • stress/check-sub-class.js:
  • stress/compare-eq-incomplete-profile.js:
  • stress/custom-get-set-inline-caching-one-level-up-proto-chain.js:
  • stress/do-eval-virtual-call-correctly.js:
  • stress/dom-jit-with-poly-proto.js:
  • stress/domjit-exception-ic.js:
  • stress/domjit-exception.js:
  • stress/domjit-getter-complex-with-incorrect-object.js:
  • stress/domjit-getter-complex.js:
  • stress/domjit-getter-poly.js:
  • stress/domjit-getter-proto.js:
  • stress/domjit-getter-super-poly.js:
  • stress/domjit-getter-try-catch-getter-as-get-by-id-register-restoration.js:
  • stress/domjit-getter-type-check.js:
  • stress/domjit-getter.js:
  • stress/exit-during-inlined-arity-fixup-recover-proper-frame.js:
  • stress/for-in-proxy-target-changed-structure.js:
  • stress/for-in-proxy.js:
  • stress/generational-opaque-roots.js:
  • stress/global-const-redeclaration-setting-2.js:
  • stress/global-const-redeclaration-setting-3.js:
  • stress/global-const-redeclaration-setting-4.js:
  • stress/global-const-redeclaration-setting-5.js:
  • stress/global-const-redeclaration-setting.js:
  • stress/import-basic.js:
  • stress/import-from-eval.js:
  • stress/import-reject-with-exception.js:
  • stress/import-syntax.js:
  • stress/impure-get-own-property-slot-inline-cache.js:
  • stress/is-constructor.js:
  • stress/istypedarrayview-intrinsic.js:
  • stress/jsc-setImpureGetterDelegate-on-bad-type.js:
  • stress/jsc-test-functions-should-be-more-robust.js:
  • stress/object-toString-with-proxy.js:
  • stress/poly-proto-custom-value-and-accessor.js:
  • stress/proxy-inline-cache.js:
  • stress/re-execute-error-module.js:
  • stress/regress-150532.js:
  • stress/regress-156992.js:
  • stress/regress-179619.js:
  • stress/resources/shadow-chicken-support.js:
  • stress/runtime-array.js:
  • stress/sampling-profiler-microtasks.js:
  • stress/shadow-chicken-enabled.js:
  • stress/spread-correct-global-object-on-exception.js:
  • stress/super-get-by-id.js:
  • stress/tailCallForwardArguments.js:
  • stress/to-object-intrinsic-boolean-edge.js:
  • stress/to-object-intrinsic-null-or-undefined-edge.js:
  • stress/to-object-intrinsic-number-edge.js:
  • stress/to-object-intrinsic-object-edge.js:
  • stress/to-object-intrinsic-string-edge.js:
  • stress/to-object-intrinsic-symbol-edge.js:
  • stress/to-object-intrinsic.js:
  • stress/try-catch-custom-getter-as-get-by-id.js:
  • stress/try-get-by-id-poly-proto.js:
  • stress/try-get-by-id-should-spill-registers-dfg.js:
  • stress/try-get-by-id.js:
  • typeProfiler/arrow-functions.js:
  • typeProfiler/basic.js:
  • typeProfiler/captured.js:
  • typeProfiler/classes.js:
  • typeProfiler/dfg-jit-optimizations.js:
  • typeProfiler/dictionary-mode.js:
  • typeProfiler/es6-block-scoping.js:
  • typeProfiler/es6-classes.js:
  • typeProfiler/inheritance.js:
  • typeProfiler/int52-dfg.js:
  • typeProfiler/loop.js:
  • typeProfiler/optional-fields.js:
  • typeProfiler/overflow.js:
  • typeProfiler/return.js:
  • typeProfiler/symbol.js:
  • typeProfiler/weird-prototype-chain.js:

Source/JavaScriptCore:

Also removed setElementRoot() which was not used.

  • jsc.cpp:

(GlobalObject::finishCreation):
(WTF::Element::Element): Deleted.
(WTF::Element::root const): Deleted.
(WTF::Element::setRoot): Deleted.
(WTF::Element::create): Deleted.
(WTF::Element::visitChildren): Deleted.
(WTF::Element::createStructure): Deleted.
(WTF::Root::Root): Deleted.
(WTF::Root::element): Deleted.
(WTF::Root::setElement): Deleted.
(WTF::Root::create): Deleted.
(WTF::Root::createStructure): Deleted.
(WTF::Root::visitChildren): Deleted.
(WTF::ImpureGetter::ImpureGetter): Deleted.
(WTF::ImpureGetter::createStructure): Deleted.
(WTF::ImpureGetter::create): Deleted.
(WTF::ImpureGetter::finishCreation): Deleted.
(WTF::ImpureGetter::getOwnPropertySlot): Deleted.
(WTF::ImpureGetter::visitChildren): Deleted.
(WTF::ImpureGetter::setDelegate): Deleted.
(WTF::CustomGetter::CustomGetter): Deleted.
(WTF::CustomGetter::createStructure): Deleted.
(WTF::CustomGetter::create): Deleted.
(WTF::CustomGetter::getOwnPropertySlot): Deleted.
(WTF::CustomGetter::customGetter): Deleted.
(WTF::CustomGetter::customGetterAcessor): Deleted.
(WTF::RuntimeArray::create): Deleted.
(WTF::RuntimeArray::~RuntimeArray): Deleted.
(WTF::RuntimeArray::destroy): Deleted.
(WTF::RuntimeArray::getOwnPropertySlot): Deleted.
(WTF::RuntimeArray::getOwnPropertySlotByIndex): Deleted.
(WTF::RuntimeArray::put): Deleted.
(WTF::RuntimeArray::deleteProperty): Deleted.
(WTF::RuntimeArray::getLength const): Deleted.
(WTF::RuntimeArray::createPrototype): Deleted.
(WTF::RuntimeArray::createStructure): Deleted.
(WTF::RuntimeArray::finishCreation): Deleted.
(WTF::RuntimeArray::RuntimeArray): Deleted.
(WTF::RuntimeArray::lengthGetter): Deleted.
(WTF::SimpleObject::SimpleObject): Deleted.
(WTF::SimpleObject::create): Deleted.
(WTF::SimpleObject::visitChildren): Deleted.
(WTF::SimpleObject::createStructure): Deleted.
(WTF::SimpleObject::hiddenValue): Deleted.
(WTF::SimpleObject::setHiddenValue): Deleted.
(WTF::DOMJITNode::DOMJITNode): Deleted.
(WTF::DOMJITNode::createStructure): Deleted.
(WTF::DOMJITNode::checkSubClassSnippet): Deleted.
(WTF::DOMJITNode::create): Deleted.
(WTF::DOMJITNode::value const): Deleted.
(WTF::DOMJITNode::offsetOfValue): Deleted.
(WTF::DOMJITGetter::DOMJITGetter): Deleted.
(WTF::DOMJITGetter::createStructure): Deleted.
(WTF::DOMJITGetter::create): Deleted.
(WTF::DOMJITGetter::DOMJITAttribute::DOMJITAttribute): Deleted.
(WTF::DOMJITGetter::DOMJITAttribute::slowCall): Deleted.
(WTF::DOMJITGetter::DOMJITAttribute::callDOMGetter): Deleted.
(WTF::DOMJITGetter::customGetter): Deleted.
(WTF::DOMJITGetter::finishCreation): Deleted.
(WTF::DOMJITGetterComplex::DOMJITGetterComplex): Deleted.
(WTF::DOMJITGetterComplex::createStructure): Deleted.
(WTF::DOMJITGetterComplex::create): Deleted.
(WTF::DOMJITGetterComplex::DOMJITAttribute::DOMJITAttribute): Deleted.
(WTF::DOMJITGetterComplex::DOMJITAttribute::slowCall): Deleted.
(WTF::DOMJITGetterComplex::DOMJITAttribute::callDOMGetter): Deleted.
(WTF::DOMJITGetterComplex::functionEnableException): Deleted.
(WTF::DOMJITGetterComplex::customGetter): Deleted.
(WTF::DOMJITGetterComplex::finishCreation): Deleted.
(WTF::DOMJITFunctionObject::DOMJITFunctionObject): Deleted.
(WTF::DOMJITFunctionObject::createStructure): Deleted.
(WTF::DOMJITFunctionObject::create): Deleted.
(WTF::DOMJITFunctionObject::safeFunction): Deleted.
(WTF::DOMJITFunctionObject::unsafeFunction): Deleted.
(WTF::DOMJITFunctionObject::checkSubClassSnippet): Deleted.
(WTF::DOMJITFunctionObject::finishCreation): Deleted.
(WTF::DOMJITCheckSubClassObject::DOMJITCheckSubClassObject): Deleted.
(WTF::DOMJITCheckSubClassObject::createStructure): Deleted.
(WTF::DOMJITCheckSubClassObject::create): Deleted.
(WTF::DOMJITCheckSubClassObject::safeFunction): Deleted.
(WTF::DOMJITCheckSubClassObject::unsafeFunction): Deleted.
(WTF::DOMJITCheckSubClassObject::finishCreation): Deleted.
(WTF::DOMJITGetterBaseJSObject::DOMJITGetterBaseJSObject): Deleted.
(WTF::DOMJITGetterBaseJSObject::createStructure): Deleted.
(WTF::DOMJITGetterBaseJSObject::create): Deleted.
(WTF::DOMJITGetterBaseJSObject::DOMJITAttribute::DOMJITAttribute): Deleted.
(WTF::DOMJITGetterBaseJSObject::DOMJITAttribute::slowCall): Deleted.
(WTF::DOMJITGetterBaseJSObject::DOMJITAttribute::callDOMGetter): Deleted.
(WTF::DOMJITGetterBaseJSObject::customGetter): Deleted.
(WTF::DOMJITGetterBaseJSObject::finishCreation): Deleted.
(WTF::Element::handleOwner): Deleted.
(WTF::Element::finishCreation): Deleted.
(JSTestCustomGetterSetter::JSTestCustomGetterSetter): Deleted.
(JSTestCustomGetterSetter::create): Deleted.
(JSTestCustomGetterSetter::createStructure): Deleted.
(customGetAccessor): Deleted.
(customGetValue): Deleted.
(customSetAccessor): Deleted.
(customSetValue): Deleted.
(JSTestCustomGetterSetter::finishCreation): Deleted.
(GlobalObject::addConstructableFunction): Deleted.
(functionCreateRoot): Deleted.
(functionCreateElement): Deleted.
(functionGetElement): Deleted.
(functionSetElementRoot): Deleted.
(functionCreateSimpleObject): Deleted.
(functionGetHiddenValue): Deleted.
(functionSetHiddenValue): Deleted.
(functionCreateProxy): Deleted.
(functionCreateRuntimeArray): Deleted.
(functionCreateImpureGetter): Deleted.
(functionCreateCustomGetterObject): Deleted.
(functionCreateDOMJITNodeObject): Deleted.
(functionCreateDOMJITGetterObject): Deleted.
(functionCreateDOMJITGetterComplexObject): Deleted.
(functionCreateDOMJITFunctionObject): Deleted.
(functionCreateDOMJITCheckSubClassObject): Deleted.
(functionCreateDOMJITGetterBaseJSObject): Deleted.
(functionSetImpureGetterDelegate): Deleted.
(functionGetGetterSetter): Deleted.
(functionShadowChickenFunctionsOnStack): Deleted.
(functionSetGlobalConstRedeclarationShouldNotThrow): Deleted.
(functionGlobalObjectForObject): Deleted.
(functionLoadGetterFromGetterSetter): Deleted.
(functionCreateCustomTestGetterSetter): Deleted.
(functionAbort): Deleted.
(functionFindTypeForExpression): Deleted.
(functionReturnTypeFor): Deleted.
(functionDumpBasicBlockExecutionRanges): Deleted.
(functionHasBasicBlockExecuted): Deleted.
(functionBasicBlockExecutionCount): Deleted.
(functionEnableExceptionFuzz): Deleted.
(functionCreateBuiltin): Deleted.

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):

  • tools/JSDollarVM.cpp:

(WTF::Element::Element):
(WTF::Element::root const):
(WTF::Element::setRoot):
(WTF::Element::create):
(WTF::Element::visitChildren):
(WTF::Element::createStructure):
(WTF::Root::Root):
(WTF::Root::element):
(WTF::Root::setElement):
(WTF::Root::create):
(WTF::Root::createStructure):
(WTF::Root::visitChildren):
(WTF::SimpleObject::SimpleObject):
(WTF::SimpleObject::create):
(WTF::SimpleObject::visitChildren):
(WTF::SimpleObject::createStructure):
(WTF::SimpleObject::hiddenValue):
(WTF::SimpleObject::setHiddenValue):
(WTF::ImpureGetter::ImpureGetter):
(WTF::ImpureGetter::createStructure):
(WTF::ImpureGetter::create):
(WTF::ImpureGetter::finishCreation):
(WTF::ImpureGetter::getOwnPropertySlot):
(WTF::ImpureGetter::visitChildren):
(WTF::ImpureGetter::setDelegate):
(WTF::CustomGetter::CustomGetter):
(WTF::CustomGetter::createStructure):
(WTF::CustomGetter::create):
(WTF::CustomGetter::getOwnPropertySlot):
(WTF::CustomGetter::customGetter):
(WTF::CustomGetter::customGetterAcessor):
(WTF::RuntimeArray::create):
(WTF::RuntimeArray::~RuntimeArray):
(WTF::RuntimeArray::destroy):
(WTF::RuntimeArray::getOwnPropertySlot):
(WTF::RuntimeArray::getOwnPropertySlotByIndex):
(WTF::RuntimeArray::put):
(WTF::RuntimeArray::deleteProperty):
(WTF::RuntimeArray::getLength const):
(WTF::RuntimeArray::createPrototype):
(WTF::RuntimeArray::createStructure):
(WTF::RuntimeArray::finishCreation):
(WTF::RuntimeArray::RuntimeArray):
(WTF::RuntimeArray::lengthGetter):
(WTF::DOMJITNode::DOMJITNode):
(WTF::DOMJITNode::createStructure):
(WTF::DOMJITNode::checkSubClassSnippet):
(WTF::DOMJITNode::create):
(WTF::DOMJITNode::value const):
(WTF::DOMJITNode::offsetOfValue):
(WTF::DOMJITGetter::DOMJITGetter):
(WTF::DOMJITGetter::createStructure):
(WTF::DOMJITGetter::create):
(WTF::DOMJITGetter::DOMJITAttribute::DOMJITAttribute):
(WTF::DOMJITGetter::DOMJITAttribute::slowCall):
(WTF::DOMJITGetter::DOMJITAttribute::callDOMGetter):
(WTF::DOMJITGetter::customGetter):
(WTF::DOMJITGetter::finishCreation):
(WTF::DOMJITGetterComplex::DOMJITGetterComplex):
(WTF::DOMJITGetterComplex::createStructure):
(WTF::DOMJITGetterComplex::create):
(WTF::DOMJITGetterComplex::DOMJITAttribute::DOMJITAttribute):
(WTF::DOMJITGetterComplex::DOMJITAttribute::slowCall):
(WTF::DOMJITGetterComplex::DOMJITAttribute::callDOMGetter):
(WTF::DOMJITGetterComplex::functionEnableException):
(WTF::DOMJITGetterComplex::customGetter):
(WTF::DOMJITGetterComplex::finishCreation):
(WTF::DOMJITFunctionObject::DOMJITFunctionObject):
(WTF::DOMJITFunctionObject::createStructure):
(WTF::DOMJITFunctionObject::create):
(WTF::DOMJITFunctionObject::safeFunction):
(WTF::DOMJITFunctionObject::unsafeFunction):
(WTF::DOMJITFunctionObject::checkSubClassSnippet):
(WTF::DOMJITFunctionObject::finishCreation):
(WTF::DOMJITCheckSubClassObject::DOMJITCheckSubClassObject):
(WTF::DOMJITCheckSubClassObject::createStructure):
(WTF::DOMJITCheckSubClassObject::create):
(WTF::DOMJITCheckSubClassObject::safeFunction):
(WTF::DOMJITCheckSubClassObject::unsafeFunction):
(WTF::DOMJITCheckSubClassObject::finishCreation):
(WTF::DOMJITGetterBaseJSObject::DOMJITGetterBaseJSObject):
(WTF::DOMJITGetterBaseJSObject::createStructure):
(WTF::DOMJITGetterBaseJSObject::create):
(WTF::DOMJITGetterBaseJSObject::DOMJITAttribute::DOMJITAttribute):
(WTF::DOMJITGetterBaseJSObject::DOMJITAttribute::slowCall):
(WTF::DOMJITGetterBaseJSObject::DOMJITAttribute::callDOMGetter):
(WTF::DOMJITGetterBaseJSObject::customGetter):
(WTF::DOMJITGetterBaseJSObject::finishCreation):
(WTF::Message::releaseContents):
(WTF::Message::index const):
(WTF::JSTestCustomGetterSetter::JSTestCustomGetterSetter):
(WTF::JSTestCustomGetterSetter::create):
(WTF::JSTestCustomGetterSetter::createStructure):
(WTF::customGetAccessor):
(WTF::customGetValue):
(WTF::customSetAccessor):
(WTF::customSetValue):
(WTF::JSTestCustomGetterSetter::finishCreation):
(WTF::Element::handleOwner):
(WTF::Element::finishCreation):
(JSC::functionCrash):
(JSC::functionCreateProxy):
(JSC::functionCreateRuntimeArray):
(JSC::functionCreateImpureGetter):
(JSC::functionCreateCustomGetterObject):
(JSC::functionCreateDOMJITNodeObject):
(JSC::functionCreateDOMJITGetterObject):
(JSC::functionCreateDOMJITGetterComplexObject):
(JSC::functionCreateDOMJITFunctionObject):
(JSC::functionCreateDOMJITCheckSubClassObject):
(JSC::functionCreateDOMJITGetterBaseJSObject):
(JSC::functionSetImpureGetterDelegate):
(JSC::functionCreateBuiltin):
(JSC::functionCreateRoot):
(JSC::functionCreateElement):
(JSC::functionGetElement):
(JSC::functionCreateSimpleObject):
(JSC::functionGetHiddenValue):
(JSC::functionSetHiddenValue):
(JSC::functionShadowChickenFunctionsOnStack):
(JSC::functionSetGlobalConstRedeclarationShouldNotThrow):
(JSC::functionFindTypeForExpression):
(JSC::functionReturnTypeFor):
(JSC::functionDumpBasicBlockExecutionRanges):
(JSC::functionHasBasicBlockExecuted):
(JSC::functionBasicBlockExecutionCount):
(JSC::functionEnableExceptionFuzz):
(JSC::functionGlobalObjectForObject):
(JSC::functionGetGetterSetter):
(JSC::functionLoadGetterFromGetterSetter):
(JSC::functionCreateCustomTestGetterSetter):
(JSC::JSDollarVM::finishCreation):
(JSC::JSDollarVM::addFunction):
(JSC::JSDollarVM::addConstructibleFunction):

  • tools/JSDollarVM.h:

(JSC::JSDollarVM::create):

Tools:

Always set --useDollarVM=true for jsc runs of benchmarks. This is needed because
some microbenchmarks relies on createBuiltin().

Also set --useDollarVM=true for runExceptionFuzz and runExecutableAllocationFuzz.

  • Scripts/run-jsc-benchmarks:
  • Scripts/run-jsc-stress-tests:

LayoutTests:

  • js/script-tests/stack-trace.js:
  • js/stack-trace-expected.txt:
Location:
trunk/Source/JavaScriptCore/tools
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/tools/JSDollarVM.cpp

    r224938 r225129  
    2727#include "JSDollarVM.h"
    2828
     29#include "BuiltinExecutableCreator.h"
    2930#include "CodeBlock.h"
     31#include "DOMAttributeGetterSetter.h"
     32#include "DOMJITGetterSetter.h"
     33#include "FrameTracers.h"
    3034#include "FunctionCodeBlock.h"
     35#include "GetterSetter.h"
     36#include "JSArray.h"
    3137#include "JSArrayBuffer.h"
    3238#include "JSCInlines.h"
     39#include "JSFunction.h"
     40#include "JSONObject.h"
     41#include "JSProxy.h"
     42#include "JSString.h"
     43#include "ShadowChicken.h"
     44#include "Snippet.h"
     45#include "SnippetParams.h"
     46#include "TypeProfiler.h"
     47#include "TypeProfilerLog.h"
    3348#include "VMInspector.h"
    3449#include <wtf/Atomics.h>
     
    3752#include <wtf/StringPrintStream.h>
    3853
     54using namespace JSC;
     55using namespace WTF;
     56
     57namespace {
     58
     59class ElementHandleOwner;
     60class Root;
     61
     62class Element : public JSNonFinalObject {
     63public:
     64    Element(VM& vm, Structure* structure)
     65        : Base(vm, structure)
     66    {
     67    }
     68
     69    typedef JSNonFinalObject Base;
     70
     71    Root* root() const { return m_root.get(); }
     72    void setRoot(VM& vm, Root* root) { m_root.set(vm, this, root); }
     73
     74    static Element* create(VM& vm, JSGlobalObject* globalObject, Root* root)
     75    {
     76        Structure* structure = createStructure(vm, globalObject, jsNull());
     77        Element* element = new (NotNull, allocateCell<Element>(vm.heap, sizeof(Element))) Element(vm, structure);
     78        element->finishCreation(vm, root);
     79        return element;
     80    }
     81
     82    void finishCreation(VM&, Root*);
     83
     84    static void visitChildren(JSCell* cell, SlotVisitor& visitor)
     85    {
     86        Element* thisObject = jsCast<Element*>(cell);
     87        ASSERT_GC_OBJECT_INHERITS(thisObject, info());
     88        Base::visitChildren(thisObject, visitor);
     89        visitor.append(thisObject->m_root);
     90    }
     91
     92    static ElementHandleOwner* handleOwner();
     93
     94    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     95    {
     96        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     97    }
     98
     99    DECLARE_INFO;
     100
     101private:
     102    WriteBarrier<Root> m_root;
     103};
     104
     105class ElementHandleOwner : public WeakHandleOwner {
     106public:
     107    bool isReachableFromOpaqueRoots(Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor) override
     108    {
     109        Element* element = jsCast<Element*>(handle.slot()->asCell());
     110        return visitor.containsOpaqueRoot(element->root());
     111    }
     112};
     113
     114class Root : public JSDestructibleObject {
     115public:
     116    Root(VM& vm, Structure* structure)
     117        : Base(vm, structure)
     118    {
     119    }
     120
     121    Element* element()
     122    {
     123        return m_element.get();
     124    }
     125
     126    void setElement(Element* element)
     127    {
     128        Weak<Element> newElement(element, Element::handleOwner());
     129        m_element.swap(newElement);
     130    }
     131
     132    static Root* create(VM& vm, JSGlobalObject* globalObject)
     133    {
     134        Structure* structure = createStructure(vm, globalObject, jsNull());
     135        Root* root = new (NotNull, allocateCell<Root>(vm.heap, sizeof(Root))) Root(vm, structure);
     136        root->finishCreation(vm);
     137        return root;
     138    }
     139
     140    typedef JSDestructibleObject Base;
     141
     142    DECLARE_INFO;
     143
     144    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     145    {
     146        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     147    }
     148
     149    static void visitChildren(JSCell* thisObject, SlotVisitor& visitor)
     150    {
     151        Base::visitChildren(thisObject, visitor);
     152        visitor.addOpaqueRoot(thisObject);
     153    }
     154
     155private:
     156    Weak<Element> m_element;
     157};
     158
     159class SimpleObject : public JSNonFinalObject {
     160public:
     161    SimpleObject(VM& vm, Structure* structure)
     162        : Base(vm, structure)
     163    {
     164    }
     165
     166    typedef JSNonFinalObject Base;
     167    static const bool needsDestruction = false;
     168
     169    static SimpleObject* create(VM& vm, JSGlobalObject* globalObject)
     170    {
     171        Structure* structure = createStructure(vm, globalObject, jsNull());
     172        SimpleObject* simpleObject = new (NotNull, allocateCell<SimpleObject>(vm.heap, sizeof(SimpleObject))) SimpleObject(vm, structure);
     173        simpleObject->finishCreation(vm);
     174        return simpleObject;
     175    }
     176
     177    static void visitChildren(JSCell* cell, SlotVisitor& visitor)
     178    {
     179        SimpleObject* thisObject = jsCast<SimpleObject*>(cell);
     180        ASSERT_GC_OBJECT_INHERITS(thisObject, info());
     181        Base::visitChildren(thisObject, visitor);
     182        visitor.append(thisObject->m_hiddenValue);
     183    }
     184
     185    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     186    {
     187        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     188    }
     189
     190    JSValue hiddenValue()
     191    {
     192        return m_hiddenValue.get();
     193    }
     194
     195    void setHiddenValue(VM& vm, JSValue value)
     196    {
     197        ASSERT(value.isCell());
     198        m_hiddenValue.set(vm, this, value);
     199    }
     200
     201    DECLARE_INFO;
     202
     203private:
     204    WriteBarrier<JSC::Unknown> m_hiddenValue;
     205};
     206
     207class ImpureGetter : public JSNonFinalObject {
     208public:
     209    ImpureGetter(VM& vm, Structure* structure)
     210        : Base(vm, structure)
     211    {
     212    }
     213
     214    DECLARE_INFO;
     215    typedef JSNonFinalObject Base;
     216    static const unsigned StructureFlags = Base::StructureFlags | JSC::GetOwnPropertySlotIsImpure | JSC::OverridesGetOwnPropertySlot;
     217
     218    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     219    {
     220        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     221    }
     222
     223    static ImpureGetter* create(VM& vm, Structure* structure, JSObject* delegate)
     224    {
     225        ImpureGetter* getter = new (NotNull, allocateCell<ImpureGetter>(vm.heap, sizeof(ImpureGetter))) ImpureGetter(vm, structure);
     226        getter->finishCreation(vm, delegate);
     227        return getter;
     228    }
     229
     230    void finishCreation(VM& vm, JSObject* delegate)
     231    {
     232        Base::finishCreation(vm);
     233        if (delegate)
     234            m_delegate.set(vm, this, delegate);
     235    }
     236
     237    static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName name, PropertySlot& slot)
     238    {
     239        VM& vm = exec->vm();
     240        auto scope = DECLARE_THROW_SCOPE(vm);
     241        ImpureGetter* thisObject = jsCast<ImpureGetter*>(object);
     242       
     243        if (thisObject->m_delegate) {
     244            if (thisObject->m_delegate->getPropertySlot(exec, name, slot))
     245                return true;
     246            RETURN_IF_EXCEPTION(scope, false);
     247        }
     248
     249        return Base::getOwnPropertySlot(object, exec, name, slot);
     250    }
     251
     252    static void visitChildren(JSCell* cell, SlotVisitor& visitor)
     253    {
     254        Base::visitChildren(cell, visitor);
     255        ImpureGetter* thisObject = jsCast<ImpureGetter*>(cell);
     256        visitor.append(thisObject->m_delegate);
     257    }
     258
     259    void setDelegate(VM& vm, JSObject* delegate)
     260    {
     261        m_delegate.set(vm, this, delegate);
     262    }
     263
     264private:
     265    WriteBarrier<JSObject> m_delegate;
     266};
     267
     268class CustomGetter : public JSNonFinalObject {
     269public:
     270    CustomGetter(VM& vm, Structure* structure)
     271        : Base(vm, structure)
     272    {
     273    }
     274
     275    DECLARE_INFO;
     276    typedef JSNonFinalObject Base;
     277    static const unsigned StructureFlags = Base::StructureFlags | JSC::OverridesGetOwnPropertySlot;
     278
     279    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     280    {
     281        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     282    }
     283
     284    static CustomGetter* create(VM& vm, Structure* structure)
     285    {
     286        CustomGetter* getter = new (NotNull, allocateCell<CustomGetter>(vm.heap, sizeof(CustomGetter))) CustomGetter(vm, structure);
     287        getter->finishCreation(vm);
     288        return getter;
     289    }
     290
     291    static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
     292    {
     293        CustomGetter* thisObject = jsCast<CustomGetter*>(object);
     294        if (propertyName == PropertyName(Identifier::fromString(exec, "customGetter"))) {
     295            slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum, thisObject->customGetter);
     296            return true;
     297        }
     298       
     299        if (propertyName == PropertyName(Identifier::fromString(exec, "customGetterAccessor"))) {
     300            slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::CustomAccessor, thisObject->customGetterAcessor);
     301            return true;
     302        }
     303       
     304        return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot);
     305    }
     306
     307private:
     308    static EncodedJSValue customGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)
     309    {
     310        VM& vm = exec->vm();
     311        auto scope = DECLARE_THROW_SCOPE(vm);
     312
     313        CustomGetter* thisObject = jsDynamicCast<CustomGetter*>(vm, JSValue::decode(thisValue));
     314        if (!thisObject)
     315            return throwVMTypeError(exec, scope);
     316        bool shouldThrow = thisObject->get(exec, PropertyName(Identifier::fromString(exec, "shouldThrow"))).toBoolean(exec);
     317        RETURN_IF_EXCEPTION(scope, encodedJSValue());
     318        if (shouldThrow)
     319            return throwVMTypeError(exec, scope);
     320        return JSValue::encode(jsNumber(100));
     321    }
     322   
     323    static EncodedJSValue customGetterAcessor(ExecState* exec, EncodedJSValue thisValue, PropertyName)
     324    {
     325        VM& vm = exec->vm();
     326        auto scope = DECLARE_THROW_SCOPE(vm);
     327       
     328        JSObject* thisObject = jsDynamicCast<JSObject*>(vm, JSValue::decode(thisValue));
     329        if (!thisObject)
     330            return throwVMTypeError(exec, scope);
     331        bool shouldThrow = thisObject->get(exec, PropertyName(Identifier::fromString(exec, "shouldThrow"))).toBoolean(exec);
     332        RETURN_IF_EXCEPTION(scope, encodedJSValue());
     333        if (shouldThrow)
     334            return throwVMTypeError(exec, scope);
     335        return JSValue::encode(jsNumber(100));
     336    }
     337};
     338
     339class RuntimeArray : public JSArray {
     340public:
     341    typedef JSArray Base;
     342    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames;
     343
     344    static RuntimeArray* create(ExecState* exec)
     345    {
     346        VM& vm = exec->vm();
     347        JSGlobalObject* globalObject = exec->lexicalGlobalObject();
     348        Structure* structure = createStructure(vm, globalObject, createPrototype(vm, globalObject));
     349        RuntimeArray* runtimeArray = new (NotNull, allocateCell<RuntimeArray>(vm.heap)) RuntimeArray(exec, structure);
     350        runtimeArray->finishCreation(exec);
     351        vm.heap.addFinalizer(runtimeArray, destroy);
     352        return runtimeArray;
     353    }
     354
     355    ~RuntimeArray() { }
     356
     357    static void destroy(JSCell* cell)
     358    {
     359        static_cast<RuntimeArray*>(cell)->RuntimeArray::~RuntimeArray();
     360    }
     361
     362    static const bool needsDestruction = false;
     363
     364    static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
     365    {
     366        VM& vm = exec->vm();
     367        RuntimeArray* thisObject = jsCast<RuntimeArray*>(object);
     368        if (propertyName == vm.propertyNames->length) {
     369            slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum, thisObject->lengthGetter);
     370            return true;
     371        }
     372
     373        std::optional<uint32_t> index = parseIndex(propertyName);
     374        if (index && index.value() < thisObject->getLength()) {
     375            slot.setValue(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::DontEnum, jsNumber(thisObject->m_vector[index.value()]));
     376            return true;
     377        }
     378
     379        return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot);
     380    }
     381
     382    static bool getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned index, PropertySlot& slot)
     383    {
     384        RuntimeArray* thisObject = jsCast<RuntimeArray*>(object);
     385        if (index < thisObject->getLength()) {
     386            slot.setValue(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::DontEnum, jsNumber(thisObject->m_vector[index]));
     387            return true;
     388        }
     389
     390        return JSObject::getOwnPropertySlotByIndex(thisObject, exec, index, slot);
     391    }
     392
     393    static NO_RETURN_DUE_TO_CRASH bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&)
     394    {
     395        RELEASE_ASSERT_NOT_REACHED();
     396    }
     397
     398    static NO_RETURN_DUE_TO_CRASH bool deleteProperty(JSCell*, ExecState*, PropertyName)
     399    {
     400        RELEASE_ASSERT_NOT_REACHED();
     401    }
     402
     403    unsigned getLength() const { return m_vector.size(); }
     404
     405    DECLARE_INFO;
     406
     407    static ArrayPrototype* createPrototype(VM&, JSGlobalObject* globalObject)
     408    {
     409        return globalObject->arrayPrototype();
     410    }
     411
     412    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     413    {
     414        return Structure::create(vm, globalObject, prototype, TypeInfo(DerivedArrayType, StructureFlags), info(), ArrayClass);
     415    }
     416
     417protected:
     418    void finishCreation(ExecState* exec)
     419    {
     420        VM& vm = exec->vm();
     421        Base::finishCreation(vm);
     422        ASSERT(inherits(vm, info()));
     423
     424        for (size_t i = 0; i < exec->argumentCount(); i++)
     425            m_vector.append(exec->argument(i).toInt32(exec));
     426    }
     427
     428private:
     429    RuntimeArray(ExecState* exec, Structure* structure)
     430        : JSArray(exec->vm(), structure, 0)
     431    {
     432    }
     433
     434    static EncodedJSValue lengthGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)
     435    {
     436        VM& vm = exec->vm();
     437        auto scope = DECLARE_THROW_SCOPE(vm);
     438
     439        RuntimeArray* thisObject = jsDynamicCast<RuntimeArray*>(vm, JSValue::decode(thisValue));
     440        if (!thisObject)
     441            return throwVMTypeError(exec, scope);
     442        return JSValue::encode(jsNumber(thisObject->getLength()));
     443    }
     444
     445    Vector<int> m_vector;
     446};
     447
     448class DOMJITNode : public JSNonFinalObject {
     449public:
     450    DOMJITNode(VM& vm, Structure* structure)
     451        : Base(vm, structure)
     452    {
     453    }
     454
     455    DECLARE_INFO;
     456    typedef JSNonFinalObject Base;
     457    static const unsigned StructureFlags = Base::StructureFlags;
     458
     459    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     460    {
     461        return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
     462    }
     463
     464#if ENABLE(JIT)
     465    static Ref<Snippet> checkSubClassSnippet()
     466    {
     467        Ref<Snippet> snippet = Snippet::create();
     468        snippet->setGenerator([=](CCallHelpers& jit, SnippetParams& params) {
     469            CCallHelpers::JumpList failureCases;
     470            failureCases.append(jit.branch8(
     471                CCallHelpers::NotEqual,
     472                CCallHelpers::Address(params[0].gpr(), JSCell::typeInfoTypeOffset()),
     473                CCallHelpers::TrustedImm32(JSC::JSType(LastJSCObjectType + 1))));
     474            return failureCases;
     475        });
     476        return snippet;
     477    }
     478#endif
     479
     480    static DOMJITNode* create(VM& vm, Structure* structure)
     481    {
     482        DOMJITNode* getter = new (NotNull, allocateCell<DOMJITNode>(vm.heap, sizeof(DOMJITNode))) DOMJITNode(vm, structure);
     483        getter->finishCreation(vm);
     484        return getter;
     485    }
     486
     487    int32_t value() const
     488    {
     489        return m_value;
     490    }
     491
     492    static ptrdiff_t offsetOfValue() { return OBJECT_OFFSETOF(DOMJITNode, m_value); }
     493
     494private:
     495    int32_t m_value { 42 };
     496};
     497
     498class DOMJITGetter : public DOMJITNode {
     499public:
     500    DOMJITGetter(VM& vm, Structure* structure)
     501        : Base(vm, structure)
     502    {
     503    }
     504
     505    DECLARE_INFO;
     506    typedef DOMJITNode Base;
     507    static const unsigned StructureFlags = Base::StructureFlags;
     508
     509    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     510    {
     511        return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
     512    }
     513
     514    static DOMJITGetter* create(VM& vm, Structure* structure)
     515    {
     516        DOMJITGetter* getter = new (NotNull, allocateCell<DOMJITGetter>(vm.heap, sizeof(DOMJITGetter))) DOMJITGetter(vm, structure);
     517        getter->finishCreation(vm);
     518        return getter;
     519    }
     520
     521    class DOMJITAttribute : public DOMJIT::GetterSetter {
     522    public:
     523        constexpr DOMJITAttribute()
     524            : DOMJIT::GetterSetter(
     525                DOMJITGetter::customGetter,
     526#if ENABLE(JIT)
     527                &callDOMGetter,
     528#else
     529                nullptr,
     530#endif
     531                SpecInt32Only)
     532        {
     533        }
     534
     535#if ENABLE(JIT)
     536        static EncodedJSValue JIT_OPERATION slowCall(ExecState* exec, void* pointer)
     537        {
     538            VM& vm = exec->vm();
     539            NativeCallFrameTracer tracer(&vm, exec);
     540            return JSValue::encode(jsNumber(static_cast<DOMJITGetter*>(pointer)->value()));
     541        }
     542
     543        static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()
     544        {
     545            Ref<DOMJIT::CallDOMGetterSnippet> snippet = DOMJIT::CallDOMGetterSnippet::create();
     546            snippet->requireGlobalObject = false;
     547            snippet->setGenerator([=](CCallHelpers& jit, SnippetParams& params) {
     548                JSValueRegs results = params[0].jsValueRegs();
     549                GPRReg dom = params[1].gpr();
     550                params.addSlowPathCall(jit.jump(), jit, slowCall, results, dom);
     551                return CCallHelpers::JumpList();
     552
     553            });
     554            return snippet;
     555        }
     556#endif
     557    };
     558
     559private:
     560    void finishCreation(VM&);
     561
     562    static EncodedJSValue customGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)
     563    {
     564        VM& vm = exec->vm();
     565        DOMJITNode* thisObject = jsDynamicCast<DOMJITNode*>(vm, JSValue::decode(thisValue));
     566        ASSERT(thisObject);
     567        return JSValue::encode(jsNumber(thisObject->value()));
     568    }
     569};
     570
     571static const DOMJITGetter::DOMJITAttribute DOMJITGetterDOMJIT;
     572
     573void DOMJITGetter::finishCreation(VM& vm)
     574{
     575    Base::finishCreation(vm);
     576    const DOMJIT::GetterSetter* domJIT = &DOMJITGetterDOMJIT;
     577    auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJIT->getter(), nullptr, DOMAttributeAnnotation { DOMJITNode::info(), domJIT });
     578    putDirectCustomAccessor(vm, Identifier::fromString(&vm, "customGetter"), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);
     579}
     580
     581class DOMJITGetterComplex : public DOMJITNode {
     582public:
     583    DOMJITGetterComplex(VM& vm, Structure* structure)
     584        : Base(vm, structure)
     585    {
     586    }
     587
     588    DECLARE_INFO;
     589    typedef DOMJITNode Base;
     590    static const unsigned StructureFlags = Base::StructureFlags;
     591
     592    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     593    {
     594        return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
     595    }
     596
     597    static DOMJITGetterComplex* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
     598    {
     599        DOMJITGetterComplex* getter = new (NotNull, allocateCell<DOMJITGetterComplex>(vm.heap, sizeof(DOMJITGetterComplex))) DOMJITGetterComplex(vm, structure);
     600        getter->finishCreation(vm, globalObject);
     601        return getter;
     602    }
     603
     604    class DOMJITAttribute : public DOMJIT::GetterSetter {
     605    public:
     606        constexpr DOMJITAttribute()
     607            : DOMJIT::GetterSetter(
     608                DOMJITGetterComplex::customGetter,
     609#if ENABLE(JIT)
     610                &callDOMGetter,
     611#else
     612                nullptr,
     613#endif
     614                SpecInt32Only)
     615        {
     616        }
     617
     618#if ENABLE(JIT)
     619        static EncodedJSValue JIT_OPERATION slowCall(ExecState* exec, void* pointer)
     620        {
     621            VM& vm = exec->vm();
     622            NativeCallFrameTracer tracer(&vm, exec);
     623            auto scope = DECLARE_THROW_SCOPE(vm);
     624            auto* object = static_cast<DOMJITNode*>(pointer);
     625            auto* domjitGetterComplex = jsDynamicCast<DOMJITGetterComplex*>(vm, object);
     626            if (domjitGetterComplex) {
     627                if (domjitGetterComplex->m_enableException)
     628                    return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("DOMJITGetterComplex slow call exception"))));
     629            }
     630            return JSValue::encode(jsNumber(object->value()));
     631        }
     632
     633        static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()
     634        {
     635            Ref<DOMJIT::CallDOMGetterSnippet> snippet = DOMJIT::CallDOMGetterSnippet::create();
     636            static_assert(GPRInfo::numberOfRegisters >= 4, "Number of registers should be larger or equal to 4.");
     637            unsigned numGPScratchRegisters = GPRInfo::numberOfRegisters - 4;
     638            snippet->numGPScratchRegisters = numGPScratchRegisters;
     639            snippet->numFPScratchRegisters = 3;
     640            snippet->setGenerator([=](CCallHelpers& jit, SnippetParams& params) {
     641                JSValueRegs results = params[0].jsValueRegs();
     642                GPRReg domGPR = params[1].gpr();
     643                for (unsigned i = 0; i < numGPScratchRegisters; ++i)
     644                    jit.move(CCallHelpers::TrustedImm32(42), params.gpScratch(i));
     645
     646                params.addSlowPathCall(jit.jump(), jit, slowCall, results, domGPR);
     647                return CCallHelpers::JumpList();
     648            });
     649            return snippet;
     650        }
     651#endif
     652    };
     653
     654private:
     655    void finishCreation(VM&, JSGlobalObject*);
     656
     657    static EncodedJSValue JSC_HOST_CALL functionEnableException(ExecState* exec)
     658    {
     659        VM& vm = exec->vm();
     660        auto* object = jsDynamicCast<DOMJITGetterComplex*>(vm, exec->thisValue());
     661        if (object)
     662            object->m_enableException = true;
     663        return JSValue::encode(jsUndefined());
     664    }
     665
     666    static EncodedJSValue customGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)
     667    {
     668        VM& vm = exec->vm();
     669        auto scope = DECLARE_THROW_SCOPE(vm);
     670
     671        auto* thisObject = jsDynamicCast<DOMJITGetterComplex*>(vm, JSValue::decode(thisValue));
     672        ASSERT(thisObject);
     673        if (thisObject->m_enableException)
     674            return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("DOMJITGetterComplex slow call exception"))));
     675        return JSValue::encode(jsNumber(thisObject->value()));
     676    }
     677
     678    bool m_enableException { false };
     679};
     680
     681static const DOMJITGetterComplex::DOMJITAttribute DOMJITGetterComplexDOMJIT;
     682
     683void DOMJITGetterComplex::finishCreation(VM& vm, JSGlobalObject* globalObject)
     684{
     685    Base::finishCreation(vm);
     686    const DOMJIT::GetterSetter* domJIT = &DOMJITGetterComplexDOMJIT;
     687    auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJIT->getter(), nullptr, DOMAttributeAnnotation { DOMJITGetterComplex::info(), domJIT });
     688    putDirectCustomAccessor(vm, Identifier::fromString(&vm, "customGetter"), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);
     689    putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "enableException"), 0, functionEnableException, NoIntrinsic, 0);
     690}
     691
     692class DOMJITFunctionObject : public DOMJITNode {
     693public:
     694    DOMJITFunctionObject(VM& vm, Structure* structure)
     695        : Base(vm, structure)
     696    {
     697    }
     698
     699    DECLARE_INFO;
     700    typedef DOMJITNode Base;
     701    static const unsigned StructureFlags = Base::StructureFlags;
     702
     703
     704    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     705    {
     706        return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
     707    }
     708
     709    static DOMJITFunctionObject* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
     710    {
     711        DOMJITFunctionObject* object = new (NotNull, allocateCell<DOMJITFunctionObject>(vm.heap, sizeof(DOMJITFunctionObject))) DOMJITFunctionObject(vm, structure);
     712        object->finishCreation(vm, globalObject);
     713        return object;
     714    }
     715
     716    static EncodedJSValue JSC_HOST_CALL safeFunction(ExecState* exec)
     717    {
     718        VM& vm = exec->vm();
     719        auto scope = DECLARE_THROW_SCOPE(vm);
     720
     721        DOMJITNode* thisObject = jsDynamicCast<DOMJITNode*>(vm, exec->thisValue());
     722        if (!thisObject)
     723            return throwVMTypeError(exec, scope);
     724        return JSValue::encode(jsNumber(thisObject->value()));
     725    }
     726
     727    static EncodedJSValue JIT_OPERATION unsafeFunction(ExecState* exec, DOMJITNode* node)
     728    {
     729        VM& vm = exec->vm();
     730        NativeCallFrameTracer tracer(&vm, exec);
     731        return JSValue::encode(jsNumber(node->value()));
     732    }
     733
     734#if ENABLE(JIT)
     735    static Ref<Snippet> checkSubClassSnippet()
     736    {
     737        Ref<Snippet> snippet = Snippet::create();
     738        snippet->numFPScratchRegisters = 1;
     739        snippet->setGenerator([=](CCallHelpers& jit, SnippetParams& params) {
     740            static const double value = 42.0;
     741            CCallHelpers::JumpList failureCases;
     742            // May use scratch registers.
     743            jit.loadDouble(CCallHelpers::TrustedImmPtr(&value), params.fpScratch(0));
     744            failureCases.append(jit.branch8(
     745                CCallHelpers::NotEqual,
     746                CCallHelpers::Address(params[0].gpr(), JSCell::typeInfoTypeOffset()),
     747                CCallHelpers::TrustedImm32(JSC::JSType(LastJSCObjectType + 1))));
     748            return failureCases;
     749        });
     750        return snippet;
     751    }
     752#endif
     753
     754private:
     755    void finishCreation(VM&, JSGlobalObject*);
     756};
     757
     758static const DOMJIT::Signature DOMJITFunctionObjectSignature((uintptr_t)DOMJITFunctionObject::unsafeFunction, DOMJITFunctionObject::info(), DOMJIT::Effect::forRead(DOMJIT::HeapRange::top()), SpecInt32Only);
     759
     760void DOMJITFunctionObject::finishCreation(VM& vm, JSGlobalObject* globalObject)
     761{
     762    Base::finishCreation(vm);
     763    putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "func"), 0, safeFunction, NoIntrinsic, &DOMJITFunctionObjectSignature, static_cast<unsigned>(PropertyAttribute::ReadOnly));
     764}
     765
     766class DOMJITCheckSubClassObject : public DOMJITNode {
     767public:
     768    DOMJITCheckSubClassObject(VM& vm, Structure* structure)
     769        : Base(vm, structure)
     770    {
     771    }
     772
     773    DECLARE_INFO;
     774    typedef DOMJITNode Base;
     775    static const unsigned StructureFlags = Base::StructureFlags;
     776
     777
     778    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     779    {
     780        return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
     781    }
     782
     783    static DOMJITCheckSubClassObject* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
     784    {
     785        DOMJITCheckSubClassObject* object = new (NotNull, allocateCell<DOMJITCheckSubClassObject>(vm.heap, sizeof(DOMJITCheckSubClassObject))) DOMJITCheckSubClassObject(vm, structure);
     786        object->finishCreation(vm, globalObject);
     787        return object;
     788    }
     789
     790    static EncodedJSValue JSC_HOST_CALL safeFunction(ExecState* exec)
     791    {
     792        VM& vm = exec->vm();
     793        auto scope = DECLARE_THROW_SCOPE(vm);
     794
     795        auto* thisObject = jsDynamicCast<DOMJITCheckSubClassObject*>(vm, exec->thisValue());
     796        if (!thisObject)
     797            return throwVMTypeError(exec, scope);
     798        return JSValue::encode(jsNumber(thisObject->value()));
     799    }
     800
     801    static EncodedJSValue JIT_OPERATION unsafeFunction(ExecState* exec, DOMJITNode* node)
     802    {
     803        VM& vm = exec->vm();
     804        NativeCallFrameTracer tracer(&vm, exec);
     805        return JSValue::encode(jsNumber(node->value()));
     806    }
     807
     808private:
     809    void finishCreation(VM&, JSGlobalObject*);
     810};
     811
     812static const DOMJIT::Signature DOMJITCheckSubClassObjectSignature((uintptr_t)DOMJITCheckSubClassObject::unsafeFunction, DOMJITCheckSubClassObject::info(), DOMJIT::Effect::forRead(DOMJIT::HeapRange::top()), SpecInt32Only);
     813
     814void DOMJITCheckSubClassObject::finishCreation(VM& vm, JSGlobalObject* globalObject)
     815{
     816    Base::finishCreation(vm);
     817    putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "func"), 0, safeFunction, NoIntrinsic, &DOMJITCheckSubClassObjectSignature, static_cast<unsigned>(PropertyAttribute::ReadOnly));
     818}
     819
     820class DOMJITGetterBaseJSObject : public DOMJITNode {
     821public:
     822    DOMJITGetterBaseJSObject(VM& vm, Structure* structure)
     823        : Base(vm, structure)
     824    {
     825    }
     826
     827    DECLARE_INFO;
     828    using Base = DOMJITNode;
     829    static const unsigned StructureFlags = Base::StructureFlags;
     830
     831    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     832    {
     833        return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
     834    }
     835
     836    static DOMJITGetterBaseJSObject* create(VM& vm, Structure* structure)
     837    {
     838        DOMJITGetterBaseJSObject* getter = new (NotNull, allocateCell<DOMJITGetterBaseJSObject>(vm.heap, sizeof(DOMJITGetterBaseJSObject))) DOMJITGetterBaseJSObject(vm, structure);
     839        getter->finishCreation(vm);
     840        return getter;
     841    }
     842
     843    class DOMJITAttribute : public DOMJIT::GetterSetter {
     844    public:
     845        constexpr DOMJITAttribute()
     846            : DOMJIT::GetterSetter(
     847                DOMJITGetterBaseJSObject::customGetter,
     848#if ENABLE(JIT)
     849                &callDOMGetter,
     850#else
     851                nullptr,
     852#endif
     853                SpecBytecodeTop)
     854        {
     855        }
     856
     857#if ENABLE(JIT)
     858        static EncodedJSValue JIT_OPERATION slowCall(ExecState* exec, void* pointer)
     859        {
     860            VM& vm = exec->vm();
     861            NativeCallFrameTracer tracer(&vm, exec);
     862            JSObject* object = static_cast<JSObject*>(pointer);
     863            return JSValue::encode(object->getPrototypeDirect(vm));
     864        }
     865
     866        static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()
     867        {
     868            Ref<DOMJIT::CallDOMGetterSnippet> snippet = DOMJIT::CallDOMGetterSnippet::create();
     869            snippet->requireGlobalObject = false;
     870            snippet->setGenerator([=](CCallHelpers& jit, SnippetParams& params) {
     871                JSValueRegs results = params[0].jsValueRegs();
     872                GPRReg dom = params[1].gpr();
     873                params.addSlowPathCall(jit.jump(), jit, slowCall, results, dom);
     874                return CCallHelpers::JumpList();
     875
     876            });
     877            return snippet;
     878        }
     879#endif
     880    };
     881
     882private:
     883    void finishCreation(VM&);
     884
     885    static EncodedJSValue customGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)
     886    {
     887        VM& vm = exec->vm();
     888        JSObject* thisObject = jsDynamicCast<JSObject*>(vm, JSValue::decode(thisValue));
     889        RELEASE_ASSERT(thisObject);
     890        return JSValue::encode(thisObject->getPrototypeDirect(vm));
     891    }
     892};
     893
     894static const DOMJITGetterBaseJSObject::DOMJITAttribute DOMJITGetterBaseJSObjectDOMJIT;
     895
     896void DOMJITGetterBaseJSObject::finishCreation(VM& vm)
     897{
     898    Base::finishCreation(vm);
     899    const DOMJIT::GetterSetter* domJIT = &DOMJITGetterBaseJSObjectDOMJIT;
     900    auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJIT->getter(), nullptr, DOMAttributeAnnotation { JSObject::info(), domJIT });
     901    putDirectCustomAccessor(vm, Identifier::fromString(&vm, "customGetter"), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);
     902}
     903
     904class Message : public ThreadSafeRefCounted<Message> {
     905public:
     906    Message(ArrayBufferContents&&, int32_t);
     907    ~Message();
     908
     909    ArrayBufferContents&& releaseContents() { return WTFMove(m_contents); }
     910    int32_t index() const { return m_index; }
     911
     912private:
     913    ArrayBufferContents m_contents;
     914    int32_t m_index { 0 };
     915};
     916
     917class JSTestCustomGetterSetter : public JSNonFinalObject {
     918public:
     919    using Base = JSNonFinalObject;
     920    static const unsigned StructureFlags = Base::StructureFlags;
     921
     922    JSTestCustomGetterSetter(VM& vm, Structure* structure)
     923        : Base(vm, structure)
     924    { }
     925
     926    static JSTestCustomGetterSetter* create(VM& vm, JSGlobalObject*, Structure* structure)
     927    {
     928        JSTestCustomGetterSetter* result = new (NotNull, allocateCell<JSTestCustomGetterSetter>(vm.heap, sizeof(JSTestCustomGetterSetter))) JSTestCustomGetterSetter(vm, structure);
     929        result->finishCreation(vm);
     930        return result;
     931    }
     932
     933    void finishCreation(VM&);
     934
     935    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject)
     936    {
     937        return Structure::create(vm, globalObject, globalObject->objectPrototype(), TypeInfo(ObjectType, StructureFlags), info());
     938    }
     939
     940    DECLARE_INFO;
     941};
     942
     943
     944static EncodedJSValue customGetAccessor(ExecState*, EncodedJSValue thisValue, PropertyName)
     945{
     946    // Passed |this|
     947    return thisValue;
     948}
     949
     950static EncodedJSValue customGetValue(ExecState* exec, EncodedJSValue slotValue, PropertyName)
     951{
     952    RELEASE_ASSERT(JSValue::decode(slotValue).inherits(exec->vm(), JSTestCustomGetterSetter::info()));
     953    // Passed property holder.
     954    return slotValue;
     955}
     956
     957static bool customSetAccessor(ExecState* exec, EncodedJSValue thisObject, EncodedJSValue encodedValue)
     958{
     959    VM& vm = exec->vm();
     960
     961    JSValue value = JSValue::decode(encodedValue);
     962    RELEASE_ASSERT(value.isObject());
     963    JSObject* object = asObject(value);
     964    PutPropertySlot slot(object);
     965    object->put(object, exec, Identifier::fromString(&vm, "result"), JSValue::decode(thisObject), slot);
     966
     967    return true;
     968}
     969
     970static bool customSetValue(ExecState* exec, EncodedJSValue slotValue, EncodedJSValue encodedValue)
     971{
     972    VM& vm = exec->vm();
     973
     974    RELEASE_ASSERT(JSValue::decode(slotValue).inherits(exec->vm(), JSTestCustomGetterSetter::info()));
     975
     976    JSValue value = JSValue::decode(encodedValue);
     977    RELEASE_ASSERT(value.isObject());
     978    JSObject* object = asObject(value);
     979    PutPropertySlot slot(object);
     980    object->put(object, exec, Identifier::fromString(&vm, "result"), JSValue::decode(slotValue), slot);
     981
     982    return true;
     983}
     984
     985void JSTestCustomGetterSetter::finishCreation(VM& vm)
     986{
     987    Base::finishCreation(vm);
     988
     989    putDirectCustomAccessor(vm, Identifier::fromString(&vm, "customValue"),
     990        CustomGetterSetter::create(vm, customGetValue, customSetValue), 0);
     991    putDirectCustomAccessor(vm, Identifier::fromString(&vm, "customAccessor"),
     992        CustomGetterSetter::create(vm, customGetAccessor, customSetAccessor), static_cast<unsigned>(PropertyAttribute::CustomAccessor));
     993}
     994
     995const ClassInfo Element::s_info = { "Element", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(Element) };
     996const ClassInfo Root::s_info = { "Root", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(Root) };
     997const ClassInfo SimpleObject::s_info = { "SimpleObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(SimpleObject) };
     998const ClassInfo ImpureGetter::s_info = { "ImpureGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(ImpureGetter) };
     999const ClassInfo CustomGetter::s_info = { "CustomGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(CustomGetter) };
     1000const ClassInfo RuntimeArray::s_info = { "RuntimeArray", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(RuntimeArray) };
     1001#if ENABLE(JIT)
     1002const ClassInfo DOMJITNode::s_info = { "DOMJITNode", &Base::s_info, nullptr, &DOMJITNode::checkSubClassSnippet, CREATE_METHOD_TABLE(DOMJITNode) };
     1003#else
     1004const ClassInfo DOMJITNode::s_info = { "DOMJITNode", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITNode) };
     1005#endif
     1006const ClassInfo DOMJITGetter::s_info = { "DOMJITGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetter) };
     1007const ClassInfo DOMJITGetterComplex::s_info = { "DOMJITGetterComplex", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetterComplex) };
     1008const ClassInfo DOMJITGetterBaseJSObject::s_info = { "DOMJITGetterBaseJSObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetterBaseJSObject) };
     1009#if ENABLE(JIT)
     1010const ClassInfo DOMJITFunctionObject::s_info = { "DOMJITFunctionObject", &Base::s_info, nullptr, &DOMJITFunctionObject::checkSubClassSnippet, CREATE_METHOD_TABLE(DOMJITFunctionObject) };
     1011#else
     1012const ClassInfo DOMJITFunctionObject::s_info = { "DOMJITFunctionObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITFunctionObject) };
     1013#endif
     1014const ClassInfo DOMJITCheckSubClassObject::s_info = { "DOMJITCheckSubClassObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITCheckSubClassObject) };
     1015const ClassInfo JSTestCustomGetterSetter::s_info = { "JSTestCustomGetterSetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestCustomGetterSetter) };
     1016
     1017ElementHandleOwner* Element::handleOwner()
     1018{
     1019    static ElementHandleOwner* owner = 0;
     1020    if (!owner)
     1021        owner = new ElementHandleOwner();
     1022    return owner;
     1023}
     1024
     1025void Element::finishCreation(VM& vm, Root* root)
     1026{
     1027    Base::finishCreation(vm);
     1028    setRoot(vm, root);
     1029    m_root->setElement(this);
     1030}
     1031
     1032} // namespace
     1033
    391034namespace JSC {
    401035
    411036const ClassInfo JSDollarVM::s_info = { "DollarVM", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDollarVM) };
    42 
    43 void JSDollarVM::addFunction(VM& vm, JSGlobalObject* globalObject, const char* name, NativeFunction function, unsigned arguments)
    44 {
    45     Identifier identifier = Identifier::fromString(&vm, name);
    46     putDirect(vm, identifier, JSFunction::create(vm, globalObject, arguments, identifier.string(), function));
    47 }
    481037
    491038// Triggers a crash immediately.
    501039// Usage: $vm.crash()
    51 static EncodedJSValue JSC_HOST_CALL functionCrash(ExecState*)
     1040static NO_RETURN_DUE_TO_CRASH EncodedJSValue JSC_HOST_CALL functionCrash(ExecState*)
    521041{
    531042    CRASH();
    54     return JSValue::encode(jsUndefined());
    551043}
    561044
     
    3571345}
    3581346
    359 void JSDollarVM::finishCreation(VM& vm, JSGlobalObject* globalObject)
     1347static EncodedJSValue JSC_HOST_CALL functionCreateProxy(ExecState* exec)
     1348{
     1349    VM& vm = exec->vm();
     1350    JSLockHolder lock(vm);
     1351    JSValue target = exec->argument(0);
     1352    if (!target.isObject())
     1353        return JSValue::encode(jsUndefined());
     1354    JSObject* jsTarget = asObject(target.asCell());
     1355    Structure* structure = JSProxy::createStructure(vm, exec->lexicalGlobalObject(), jsTarget->getPrototypeDirect(vm), ImpureProxyType);
     1356    JSProxy* proxy = JSProxy::create(vm, structure, jsTarget);
     1357    return JSValue::encode(proxy);
     1358}
     1359
     1360static EncodedJSValue JSC_HOST_CALL functionCreateRuntimeArray(ExecState* exec)
     1361{
     1362    JSLockHolder lock(exec);
     1363    RuntimeArray* array = RuntimeArray::create(exec);
     1364    return JSValue::encode(array);
     1365}
     1366
     1367static EncodedJSValue JSC_HOST_CALL functionCreateImpureGetter(ExecState* exec)
     1368{
     1369    VM& vm = exec->vm();
     1370    JSLockHolder lock(vm);
     1371    JSValue target = exec->argument(0);
     1372    JSObject* delegate = nullptr;
     1373    if (target.isObject())
     1374        delegate = asObject(target.asCell());
     1375    Structure* structure = ImpureGetter::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
     1376    ImpureGetter* result = ImpureGetter::create(vm, structure, delegate);
     1377    return JSValue::encode(result);
     1378}
     1379
     1380static EncodedJSValue JSC_HOST_CALL functionCreateCustomGetterObject(ExecState* exec)
     1381{
     1382    VM& vm = exec->vm();
     1383    JSLockHolder lock(vm);
     1384    Structure* structure = CustomGetter::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
     1385    CustomGetter* result = CustomGetter::create(vm, structure);
     1386    return JSValue::encode(result);
     1387}
     1388
     1389static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITNodeObject(ExecState* exec)
     1390{
     1391    VM& vm = exec->vm();
     1392    JSLockHolder lock(vm);
     1393    Structure* structure = DOMJITNode::createStructure(vm, exec->lexicalGlobalObject(), DOMJITGetter::create(vm, DOMJITGetter::createStructure(vm, exec->lexicalGlobalObject(), jsNull())));
     1394    DOMJITNode* result = DOMJITNode::create(vm, structure);
     1395    return JSValue::encode(result);
     1396}
     1397
     1398static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterObject(ExecState* exec)
     1399{
     1400    VM& vm = exec->vm();
     1401    JSLockHolder lock(vm);
     1402    Structure* structure = DOMJITGetter::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
     1403    DOMJITGetter* result = DOMJITGetter::create(vm, structure);
     1404    return JSValue::encode(result);
     1405}
     1406
     1407static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterComplexObject(ExecState* exec)
     1408{
     1409    VM& vm = exec->vm();
     1410    JSLockHolder lock(vm);
     1411    Structure* structure = DOMJITGetterComplex::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
     1412    DOMJITGetterComplex* result = DOMJITGetterComplex::create(vm, exec->lexicalGlobalObject(), structure);
     1413    return JSValue::encode(result);
     1414}
     1415
     1416static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITFunctionObject(ExecState* exec)
     1417{
     1418    VM& vm = exec->vm();
     1419    JSLockHolder lock(vm);
     1420    Structure* structure = DOMJITFunctionObject::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
     1421    DOMJITFunctionObject* result = DOMJITFunctionObject::create(vm, exec->lexicalGlobalObject(), structure);
     1422    return JSValue::encode(result);
     1423}
     1424
     1425static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITCheckSubClassObject(ExecState* exec)
     1426{
     1427    VM& vm = exec->vm();
     1428    JSLockHolder lock(vm);
     1429    Structure* structure = DOMJITCheckSubClassObject::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
     1430    DOMJITCheckSubClassObject* result = DOMJITCheckSubClassObject::create(vm, exec->lexicalGlobalObject(), structure);
     1431    return JSValue::encode(result);
     1432}
     1433
     1434static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterBaseJSObject(ExecState* exec)
     1435{
     1436    VM& vm = exec->vm();
     1437    JSLockHolder lock(vm);
     1438    Structure* structure = DOMJITGetterBaseJSObject::createStructure(vm, exec->lexicalGlobalObject(), jsNull());
     1439    DOMJITGetterBaseJSObject* result = DOMJITGetterBaseJSObject::create(vm, structure);
     1440    return JSValue::encode(result);
     1441}
     1442
     1443static EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(ExecState* exec)
     1444{
     1445    VM& vm = exec->vm();
     1446    JSLockHolder lock(vm);
     1447    auto scope = DECLARE_THROW_SCOPE(vm);
     1448
     1449    JSValue base = exec->argument(0);
     1450    if (!base.isObject())
     1451        return JSValue::encode(jsUndefined());
     1452    JSValue delegate = exec->argument(1);
     1453    if (!delegate.isObject())
     1454        return JSValue::encode(jsUndefined());
     1455    ImpureGetter* impureGetter = jsDynamicCast<ImpureGetter*>(vm, asObject(base.asCell()));
     1456    if (UNLIKELY(!impureGetter)) {
     1457        throwTypeError(exec, scope, ASCIILiteral("argument is not an ImpureGetter"));
     1458        return encodedJSValue();
     1459    }
     1460    impureGetter->setDelegate(vm, asObject(delegate.asCell()));
     1461    return JSValue::encode(jsUndefined());
     1462}
     1463
     1464static EncodedJSValue JSC_HOST_CALL functionCreateBuiltin(ExecState* exec)
     1465{
     1466    VM& vm = exec->vm();
     1467    auto scope = DECLARE_THROW_SCOPE(vm);
     1468
     1469    if (exec->argumentCount() < 1 || !exec->argument(0).isString())
     1470        return JSValue::encode(jsUndefined());
     1471
     1472    String functionText = asString(exec->argument(0))->value(exec);
     1473    RETURN_IF_EXCEPTION(scope, encodedJSValue());
     1474
     1475    const SourceCode& source = makeSource(functionText, { });
     1476    JSFunction* func = JSFunction::create(vm, createBuiltinExecutable(vm, source, Identifier::fromString(&vm, "foo"), ConstructorKind::None, ConstructAbility::CannotConstruct)->link(vm, source), exec->lexicalGlobalObject());
     1477
     1478    return JSValue::encode(func);
     1479}
     1480
     1481static EncodedJSValue JSC_HOST_CALL functionCreateRoot(ExecState* exec)
     1482{
     1483    VM& vm = exec->vm();
     1484    JSLockHolder lock(vm);
     1485    return JSValue::encode(Root::create(vm, exec->lexicalGlobalObject()));
     1486}
     1487
     1488static EncodedJSValue JSC_HOST_CALL functionCreateElement(ExecState* exec)
     1489{
     1490    VM& vm = exec->vm();
     1491    JSLockHolder lock(vm);
     1492    auto scope = DECLARE_THROW_SCOPE(vm);
     1493
     1494    Root* root = jsDynamicCast<Root*>(vm, exec->argument(0));
     1495    if (!root)
     1496        return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("Cannot create Element without a Root."))));
     1497    return JSValue::encode(Element::create(vm, exec->lexicalGlobalObject(), root));
     1498}
     1499
     1500static EncodedJSValue JSC_HOST_CALL functionGetElement(ExecState* exec)
     1501{
     1502    VM& vm = exec->vm();
     1503    JSLockHolder lock(vm);
     1504    Root* root = jsDynamicCast<Root*>(vm, exec->argument(0));
     1505    if (!root)
     1506        return JSValue::encode(jsUndefined());
     1507    Element* result = root->element();
     1508    return JSValue::encode(result ? result : jsUndefined());
     1509}
     1510
     1511static EncodedJSValue JSC_HOST_CALL functionCreateSimpleObject(ExecState* exec)
     1512{
     1513    VM& vm = exec->vm();
     1514    JSLockHolder lock(vm);
     1515    return JSValue::encode(SimpleObject::create(vm, exec->lexicalGlobalObject()));
     1516}
     1517
     1518static EncodedJSValue JSC_HOST_CALL functionGetHiddenValue(ExecState* exec)
     1519{
     1520    VM& vm = exec->vm();
     1521    JSLockHolder lock(vm);
     1522    auto scope = DECLARE_THROW_SCOPE(vm);
     1523
     1524    SimpleObject* simpleObject = jsDynamicCast<SimpleObject*>(vm, exec->argument(0));
     1525    if (UNLIKELY(!simpleObject)) {
     1526        throwTypeError(exec, scope, ASCIILiteral("Invalid use of getHiddenValue test function"));
     1527        return encodedJSValue();
     1528    }
     1529    return JSValue::encode(simpleObject->hiddenValue());
     1530}
     1531
     1532static EncodedJSValue JSC_HOST_CALL functionSetHiddenValue(ExecState* exec)
     1533{
     1534    VM& vm = exec->vm();
     1535    JSLockHolder lock(vm);
     1536    auto scope = DECLARE_THROW_SCOPE(vm);
     1537
     1538    SimpleObject* simpleObject = jsDynamicCast<SimpleObject*>(vm, exec->argument(0));
     1539    if (UNLIKELY(!simpleObject)) {
     1540        throwTypeError(exec, scope, ASCIILiteral("Invalid use of setHiddenValue test function"));
     1541        return encodedJSValue();
     1542    }
     1543    JSValue value = exec->argument(1);
     1544    simpleObject->setHiddenValue(vm, value);
     1545    return JSValue::encode(jsUndefined());
     1546}
     1547
     1548static EncodedJSValue JSC_HOST_CALL functionShadowChickenFunctionsOnStack(ExecState* exec)
     1549{
     1550    VM& vm = exec->vm();
     1551    return JSValue::encode(vm.shadowChicken().functionsOnStack(exec));
     1552}
     1553
     1554static EncodedJSValue JSC_HOST_CALL functionSetGlobalConstRedeclarationShouldNotThrow(ExecState* exec)
     1555{
     1556    VM& vm = exec->vm();
     1557    vm.setGlobalConstRedeclarationShouldThrow(false);
     1558    return JSValue::encode(jsUndefined());
     1559}
     1560
     1561static EncodedJSValue JSC_HOST_CALL functionFindTypeForExpression(ExecState* exec)
     1562{
     1563    VM& vm = exec->vm();
     1564    RELEASE_ASSERT(vm.typeProfiler());
     1565    vm.typeProfilerLog()->processLogEntries(ASCIILiteral("jsc Testing API: functionFindTypeForExpression"));
     1566
     1567    JSValue functionValue = exec->argument(0);
     1568    RELEASE_ASSERT(functionValue.isFunction());
     1569    FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
     1570
     1571    RELEASE_ASSERT(exec->argument(1).isString());
     1572    String substring = asString(exec->argument(1))->value(exec);
     1573    String sourceCodeText = executable->source().view().toString();
     1574    unsigned offset = static_cast<unsigned>(sourceCodeText.find(substring) + executable->source().startOffset());
     1575   
     1576    String jsonString = vm.typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorNormal, offset, executable->sourceID(), vm);
     1577    return JSValue::encode(JSONParse(exec, jsonString));
     1578}
     1579
     1580static EncodedJSValue JSC_HOST_CALL functionReturnTypeFor(ExecState* exec)
     1581{
     1582    VM& vm = exec->vm();
     1583    RELEASE_ASSERT(vm.typeProfiler());
     1584    vm.typeProfilerLog()->processLogEntries(ASCIILiteral("jsc Testing API: functionReturnTypeFor"));
     1585
     1586    JSValue functionValue = exec->argument(0);
     1587    RELEASE_ASSERT(functionValue.isFunction());
     1588    FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
     1589
     1590    unsigned offset = executable->typeProfilingStartOffset();
     1591    String jsonString = vm.typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorFunctionReturn, offset, executable->sourceID(), vm);
     1592    return JSValue::encode(JSONParse(exec, jsonString));
     1593}
     1594
     1595static EncodedJSValue JSC_HOST_CALL functionDumpBasicBlockExecutionRanges(ExecState* exec)
     1596{
     1597    VM& vm = exec->vm();
     1598    RELEASE_ASSERT(vm.controlFlowProfiler());
     1599    vm.controlFlowProfiler()->dumpData();
     1600    return JSValue::encode(jsUndefined());
     1601}
     1602
     1603static EncodedJSValue JSC_HOST_CALL functionHasBasicBlockExecuted(ExecState* exec)
     1604{
     1605    VM& vm = exec->vm();
     1606    RELEASE_ASSERT(vm.controlFlowProfiler());
     1607
     1608    JSValue functionValue = exec->argument(0);
     1609    RELEASE_ASSERT(functionValue.isFunction());
     1610    FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
     1611
     1612    RELEASE_ASSERT(exec->argument(1).isString());
     1613    String substring = asString(exec->argument(1))->value(exec);
     1614    String sourceCodeText = executable->source().view().toString();
     1615    RELEASE_ASSERT(sourceCodeText.contains(substring));
     1616    int offset = sourceCodeText.find(substring) + executable->source().startOffset();
     1617   
     1618    bool hasExecuted = vm.controlFlowProfiler()->hasBasicBlockAtTextOffsetBeenExecuted(offset, executable->sourceID(), vm);
     1619    return JSValue::encode(jsBoolean(hasExecuted));
     1620}
     1621
     1622static EncodedJSValue JSC_HOST_CALL functionBasicBlockExecutionCount(ExecState* exec)
     1623{
     1624    VM& vm = exec->vm();
     1625    RELEASE_ASSERT(vm.controlFlowProfiler());
     1626
     1627    JSValue functionValue = exec->argument(0);
     1628    RELEASE_ASSERT(functionValue.isFunction());
     1629    FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
     1630
     1631    RELEASE_ASSERT(exec->argument(1).isString());
     1632    String substring = asString(exec->argument(1))->value(exec);
     1633    String sourceCodeText = executable->source().view().toString();
     1634    RELEASE_ASSERT(sourceCodeText.contains(substring));
     1635    int offset = sourceCodeText.find(substring) + executable->source().startOffset();
     1636   
     1637    size_t executionCount = vm.controlFlowProfiler()->basicBlockExecutionCountAtTextOffset(offset, executable->sourceID(), vm);
     1638    return JSValue::encode(JSValue(executionCount));
     1639}
     1640
     1641static EncodedJSValue JSC_HOST_CALL functionEnableExceptionFuzz(ExecState*)
     1642{
     1643    Options::useExceptionFuzz() = true;
     1644    return JSValue::encode(jsUndefined());
     1645}
     1646
     1647static EncodedJSValue JSC_HOST_CALL functionGlobalObjectForObject(ExecState* exec)
     1648{
     1649    JSValue value = exec->argument(0);
     1650    RELEASE_ASSERT(value.isObject());
     1651    JSGlobalObject* globalObject = jsCast<JSObject*>(value)->globalObject();
     1652    RELEASE_ASSERT(globalObject);
     1653    return JSValue::encode(globalObject);
     1654}
     1655
     1656static EncodedJSValue JSC_HOST_CALL functionGetGetterSetter(ExecState* exec)
     1657{
     1658    JSValue value = exec->argument(0);
     1659    if (!value.isObject())
     1660        return JSValue::encode(jsUndefined());
     1661
     1662    JSValue property = exec->argument(1);
     1663    if (!property.isString())
     1664        return JSValue::encode(jsUndefined());
     1665
     1666    PropertySlot slot(value, PropertySlot::InternalMethodType::VMInquiry);
     1667    value.getPropertySlot(exec, asString(property)->toIdentifier(exec), slot);
     1668
     1669    JSValue result;
     1670    if (slot.isCacheableGetter())
     1671        result = slot.getterSetter();
     1672    else
     1673        result = jsNull();
     1674
     1675    return JSValue::encode(result);
     1676}
     1677
     1678static EncodedJSValue JSC_HOST_CALL functionLoadGetterFromGetterSetter(ExecState* exec)
     1679{
     1680    VM& vm = exec->vm();
     1681    auto scope = DECLARE_THROW_SCOPE(vm);
     1682
     1683    GetterSetter* getterSetter = jsDynamicCast<GetterSetter*>(vm, exec->argument(0));
     1684    if (UNLIKELY(!getterSetter)) {
     1685        throwTypeError(exec, scope, ASCIILiteral("Invalid use of loadGetterFromGetterSetter test function: argument is not a GetterSetter"));
     1686        return encodedJSValue();
     1687    }
     1688
     1689    JSObject* getter = getterSetter->getter();
     1690    RELEASE_ASSERT(getter);
     1691    return JSValue::encode(getter);
     1692}
     1693
     1694static EncodedJSValue JSC_HOST_CALL functionCreateCustomTestGetterSetter(ExecState* exec)
     1695{
     1696    VM& vm = exec->vm();
     1697    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
     1698    return JSValue::encode(JSTestCustomGetterSetter::create(vm, globalObject, JSTestCustomGetterSetter::createStructure(vm, globalObject)));
     1699}
     1700
     1701void JSDollarVM::finishCreation(VM& vm)
    3601702{
    3611703    Base::finishCreation(vm);
    362    
    363     addFunction(vm, globalObject, "crash", functionCrash, 0);
    364    
     1704
     1705    JSGlobalObject* globalObject = structure(vm)->globalObject();
     1706
     1707    auto addFunction = [&] (VM& vm, const char* name, NativeFunction function, unsigned arguments) {
     1708        JSDollarVM::addFunction(vm, globalObject, name, function, arguments);
     1709    };
     1710    auto addConstructibleFunction = [&] (VM& vm, const char* name, NativeFunction function, unsigned arguments) {
     1711        JSDollarVM::addConstructibleFunction(vm, globalObject, name, function, arguments);
     1712    };
     1713
     1714    addFunction(vm, "abort", functionCrash, 0);
     1715    addFunction(vm, "crash", functionCrash, 0);
     1716
    3651717    putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "dfgTrue"), 0, functionDFGTrue, DFGTrueIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
    3661718
     
    3691721    putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "cpuCpuid"), 0, functionCpuCpuid, CPUCpuidIntrinsic, 0);
    3701722    putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "cpuPause"), 0, functionCpuPause, CPUPauseIntrinsic, 0);
    371     addFunction(vm, globalObject, "cpuClflush", functionCpuClflush, 2);
    372    
    373     addFunction(vm, globalObject, "llintTrue", functionLLintTrue, 0);
    374     addFunction(vm, globalObject, "jitTrue", functionJITTrue, 0);
    375    
    376     addFunction(vm, globalObject, "gc", functionGC, 0);
    377     addFunction(vm, globalObject, "edenGC", functionEdenGC, 0);
    378    
    379     addFunction(vm, globalObject, "codeBlockFor", functionCodeBlockFor, 1);
    380     addFunction(vm, globalObject, "codeBlockForFrame", functionCodeBlockForFrame, 1);
    381     addFunction(vm, globalObject, "printSourceFor", functionPrintSourceFor, 1);
    382     addFunction(vm, globalObject, "printBytecodeFor", functionPrintBytecodeFor, 1);
    383    
    384     addFunction(vm, globalObject, "print", functionPrint, 1);
    385     addFunction(vm, globalObject, "printCallFrame", functionPrintCallFrame, 0);
    386     addFunction(vm, globalObject, "printStack", functionPrintStack, 0);
    387 
    388     addFunction(vm, globalObject, "value", functionValue, 1);
    389     addFunction(vm, globalObject, "getpid", functionGetPID, 0);
     1723    addFunction(vm, "cpuClflush", functionCpuClflush, 2);
     1724
     1725    addFunction(vm, "llintTrue", functionLLintTrue, 0);
     1726    addFunction(vm, "jitTrue", functionJITTrue, 0);
     1727
     1728    addFunction(vm, "gc", functionGC, 0);
     1729    addFunction(vm, "edenGC", functionEdenGC, 0);
     1730
     1731    addFunction(vm, "codeBlockFor", functionCodeBlockFor, 1);
     1732    addFunction(vm, "codeBlockForFrame", functionCodeBlockForFrame, 1);
     1733    addFunction(vm, "printSourceFor", functionPrintSourceFor, 1);
     1734    addFunction(vm, "printBytecodeFor", functionPrintBytecodeFor, 1);
     1735
     1736    addFunction(vm, "print", functionPrint, 1);
     1737    addFunction(vm, "printCallFrame", functionPrintCallFrame, 0);
     1738    addFunction(vm, "printStack", functionPrintStack, 0);
     1739
     1740    addFunction(vm, "value", functionValue, 1);
     1741    addFunction(vm, "getpid", functionGetPID, 0);
     1742
     1743    addFunction(vm, "createProxy", functionCreateProxy, 1);
     1744    addFunction(vm, "createRuntimeArray", functionCreateRuntimeArray, 0);
     1745
     1746    addFunction(vm, "createImpureGetter", functionCreateImpureGetter, 1);
     1747    addFunction(vm, "createCustomGetterObject", functionCreateCustomGetterObject, 0);
     1748    addFunction(vm, "createDOMJITNodeObject", functionCreateDOMJITNodeObject, 0);
     1749    addFunction(vm, "createDOMJITGetterObject", functionCreateDOMJITGetterObject, 0);
     1750    addFunction(vm, "createDOMJITGetterComplexObject", functionCreateDOMJITGetterComplexObject, 0);
     1751    addFunction(vm, "createDOMJITFunctionObject", functionCreateDOMJITFunctionObject, 0);
     1752    addFunction(vm, "createDOMJITCheckSubClassObject", functionCreateDOMJITCheckSubClassObject, 0);
     1753    addFunction(vm, "createDOMJITGetterBaseJSObject", functionCreateDOMJITGetterBaseJSObject, 0);
     1754    addFunction(vm, "createBuiltin", functionCreateBuiltin, 2);
     1755    addFunction(vm, "setImpureGetterDelegate", functionSetImpureGetterDelegate, 2);
     1756
     1757    addConstructibleFunction(vm, "Root", functionCreateRoot, 0);
     1758    addConstructibleFunction(vm, "Element", functionCreateElement, 1);
     1759    addFunction(vm, "getElement", functionGetElement, 1);
     1760
     1761    addConstructibleFunction(vm, "SimpleObject", functionCreateSimpleObject, 0);
     1762    addFunction(vm, "getHiddenValue", functionGetHiddenValue, 1);
     1763    addFunction(vm, "setHiddenValue", functionSetHiddenValue, 2);
     1764
     1765    addFunction(vm, "shadowChickenFunctionsOnStack", functionShadowChickenFunctionsOnStack, 0);
     1766    addFunction(vm, "setGlobalConstRedeclarationShouldNotThrow", functionSetGlobalConstRedeclarationShouldNotThrow, 0);
     1767
     1768    addFunction(vm, "findTypeForExpression", functionFindTypeForExpression, 2);
     1769    addFunction(vm, "returnTypeFor", functionReturnTypeFor, 1);
     1770
     1771    addFunction(vm, "dumpBasicBlockExecutionRanges", functionDumpBasicBlockExecutionRanges , 0);
     1772    addFunction(vm, "hasBasicBlockExecuted", functionHasBasicBlockExecuted, 2);
     1773    addFunction(vm, "basicBlockExecutionCount", functionBasicBlockExecutionCount, 2);
     1774
     1775    addFunction(vm, "enableExceptionFuzz", functionEnableExceptionFuzz, 0);
     1776
     1777    addFunction(vm, "globalObjectForObject", functionGlobalObjectForObject, 1);
     1778
     1779    addFunction(vm, "getGetterSetter", functionGetGetterSetter, 2);
     1780    addFunction(vm, "loadGetterFromGetterSetter", functionLoadGetterFromGetterSetter, 1);
     1781    addFunction(vm, "createCustomTestGetterSetter", functionCreateCustomTestGetterSetter, 1);
     1782}
     1783
     1784void JSDollarVM::addFunction(VM& vm, JSGlobalObject* globalObject, const char* name, NativeFunction function, unsigned arguments)
     1785{
     1786    Identifier identifier = Identifier::fromString(&vm, name);
     1787    putDirect(vm, identifier, JSFunction::create(vm, globalObject, arguments, identifier.string(), function));
     1788}
     1789
     1790void JSDollarVM::addConstructibleFunction(VM& vm, JSGlobalObject* globalObject, const char* name, NativeFunction function, unsigned arguments)
     1791{
     1792    Identifier identifier = Identifier::fromString(&vm, name);
     1793    putDirect(vm, identifier, JSFunction::create(vm, globalObject, arguments, identifier.string(), function, NoIntrinsic, function));
    3901794}
    3911795
  • trunk/Source/JavaScriptCore/tools/JSDollarVM.h

    r224838 r225129  
    4141    }
    4242
    43     static JSDollarVM* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
     43    static JSDollarVM* create(VM& vm, Structure* structure)
    4444    {
    4545        JSDollarVM* instance = new (NotNull, allocateCell<JSDollarVM>(vm.heap)) JSDollarVM(vm, structure);
    46         instance->finishCreation(vm, globalObject);
     46        instance->finishCreation(vm);
    4747        return instance;
    4848    }
     
    5454    }
    5555
    56     void finishCreation(VM&, JSGlobalObject*);
     56    void finishCreation(VM&);
    5757    void addFunction(VM&, JSGlobalObject*, const char* name, NativeFunction, unsigned arguments);
     58    void addConstructibleFunction(VM&, JSGlobalObject*, const char* name, NativeFunction, unsigned arguments);
    5859};
    5960
Note: See TracChangeset for help on using the changeset viewer.