Changeset 225129 in webkit for trunk/Source/JavaScriptCore/jsc.cpp
- Timestamp:
- Nov 24, 2017, 2:58:16 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/jsc.cpp
r224770 r225129 25 25 #include "ArrayBuffer.h" 26 26 #include "ArrayPrototype.h" 27 #include "BuiltinExecutableCreator.h"28 27 #include "BuiltinNames.h" 29 28 #include "ButterflyInlines.h" … … 32 31 #include "Completion.h" 33 32 #include "ConfigFile.h" 34 #include "DOMAttributeGetterSetter.h"35 #include "DOMJITGetterSetter.h"36 33 #include "Disassembler.h" 37 34 #include "Exception.h" 38 35 #include "ExceptionHelpers.h" 39 #include "FrameTracers.h"40 #include "GetterSetter.h"41 36 #include "HeapProfiler.h" 42 37 #include "HeapSnapshotBuilder.h" … … 54 49 #include "JSNativeStdFunction.h" 55 50 #include "JSONObject.h" 56 #include "JSProxy.h"57 51 #include "JSSourceCode.h" 58 52 #include "JSString.h" … … 69 63 #include "ReleaseHeapAccessScope.h" 70 64 #include "SamplingProfiler.h" 71 #include "ShadowChicken.h"72 #include "Snippet.h"73 #include "SnippetParams.h"74 65 #include "StackVisitor.h" 75 66 #include "StructureInlines.h" … … 77 68 #include "SuperSampler.h" 78 69 #include "TestRunnerUtils.h" 79 #include "TypeProfiler.h"80 #include "TypeProfilerLog.h"81 70 #include "TypedArrayInlines.h" 82 71 #include "WasmContext.h" … … 163 152 } 164 153 165 class Element;166 class ElementHandleOwner;167 class Masuqerader;168 class Root;169 class RuntimeArray;170 171 class Element : public JSNonFinalObject {172 public:173 Element(VM& vm, Structure* structure)174 : Base(vm, structure)175 {176 }177 178 typedef JSNonFinalObject Base;179 180 Root* root() const { return m_root.get(); }181 void setRoot(VM& vm, Root* root) { m_root.set(vm, this, root); }182 183 static Element* create(VM& vm, JSGlobalObject* globalObject, Root* root)184 {185 Structure* structure = createStructure(vm, globalObject, jsNull());186 Element* element = new (NotNull, allocateCell<Element>(vm.heap, sizeof(Element))) Element(vm, structure);187 element->finishCreation(vm, root);188 return element;189 }190 191 void finishCreation(VM&, Root*);192 193 static void visitChildren(JSCell* cell, SlotVisitor& visitor)194 {195 Element* thisObject = jsCast<Element*>(cell);196 ASSERT_GC_OBJECT_INHERITS(thisObject, info());197 Base::visitChildren(thisObject, visitor);198 visitor.append(thisObject->m_root);199 }200 201 static ElementHandleOwner* handleOwner();202 203 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)204 {205 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());206 }207 208 DECLARE_INFO;209 210 private:211 WriteBarrier<Root> m_root;212 };213 214 class ElementHandleOwner : public WeakHandleOwner {215 public:216 bool isReachableFromOpaqueRoots(Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor) override217 {218 Element* element = jsCast<Element*>(handle.slot()->asCell());219 return visitor.containsOpaqueRoot(element->root());220 }221 };222 223 154 class Masquerader : public JSNonFinalObject { 224 155 public: … … 248 179 }; 249 180 250 class Root : public JSDestructibleObject {251 public:252 Root(VM& vm, Structure* structure)253 : Base(vm, structure)254 {255 }256 257 Element* element()258 {259 return m_element.get();260 }261 262 void setElement(Element* element)263 {264 Weak<Element> newElement(element, Element::handleOwner());265 m_element.swap(newElement);266 }267 268 static Root* create(VM& vm, JSGlobalObject* globalObject)269 {270 Structure* structure = createStructure(vm, globalObject, jsNull());271 Root* root = new (NotNull, allocateCell<Root>(vm.heap, sizeof(Root))) Root(vm, structure);272 root->finishCreation(vm);273 return root;274 }275 276 typedef JSDestructibleObject Base;277 278 DECLARE_INFO;279 280 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)281 {282 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());283 }284 285 static void visitChildren(JSCell* thisObject, SlotVisitor& visitor)286 {287 Base::visitChildren(thisObject, visitor);288 visitor.addOpaqueRoot(thisObject);289 }290 291 private:292 Weak<Element> m_element;293 };294 295 class ImpureGetter : public JSNonFinalObject {296 public:297 ImpureGetter(VM& vm, Structure* structure)298 : Base(vm, structure)299 {300 }301 302 DECLARE_INFO;303 typedef JSNonFinalObject Base;304 static const unsigned StructureFlags = Base::StructureFlags | JSC::GetOwnPropertySlotIsImpure | JSC::OverridesGetOwnPropertySlot;305 306 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)307 {308 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());309 }310 311 static ImpureGetter* create(VM& vm, Structure* structure, JSObject* delegate)312 {313 ImpureGetter* getter = new (NotNull, allocateCell<ImpureGetter>(vm.heap, sizeof(ImpureGetter))) ImpureGetter(vm, structure);314 getter->finishCreation(vm, delegate);315 return getter;316 }317 318 void finishCreation(VM& vm, JSObject* delegate)319 {320 Base::finishCreation(vm);321 if (delegate)322 m_delegate.set(vm, this, delegate);323 }324 325 static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName name, PropertySlot& slot)326 {327 VM& vm = exec->vm();328 auto scope = DECLARE_THROW_SCOPE(vm);329 ImpureGetter* thisObject = jsCast<ImpureGetter*>(object);330 331 if (thisObject->m_delegate) {332 if (thisObject->m_delegate->getPropertySlot(exec, name, slot))333 return true;334 RETURN_IF_EXCEPTION(scope, false);335 }336 337 return Base::getOwnPropertySlot(object, exec, name, slot);338 }339 340 static void visitChildren(JSCell* cell, SlotVisitor& visitor)341 {342 Base::visitChildren(cell, visitor);343 ImpureGetter* thisObject = jsCast<ImpureGetter*>(cell);344 visitor.append(thisObject->m_delegate);345 }346 347 void setDelegate(VM& vm, JSObject* delegate)348 {349 m_delegate.set(vm, this, delegate);350 }351 352 private:353 WriteBarrier<JSObject> m_delegate;354 };355 356 class CustomGetter : public JSNonFinalObject {357 public:358 CustomGetter(VM& vm, Structure* structure)359 : Base(vm, structure)360 {361 }362 363 DECLARE_INFO;364 typedef JSNonFinalObject Base;365 static const unsigned StructureFlags = Base::StructureFlags | JSC::OverridesGetOwnPropertySlot;366 367 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)368 {369 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());370 }371 372 static CustomGetter* create(VM& vm, Structure* structure)373 {374 CustomGetter* getter = new (NotNull, allocateCell<CustomGetter>(vm.heap, sizeof(CustomGetter))) CustomGetter(vm, structure);375 getter->finishCreation(vm);376 return getter;377 }378 379 static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)380 {381 CustomGetter* thisObject = jsCast<CustomGetter*>(object);382 if (propertyName == PropertyName(Identifier::fromString(exec, "customGetter"))) {383 slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum, thisObject->customGetter);384 return true;385 }386 387 if (propertyName == PropertyName(Identifier::fromString(exec, "customGetterAccessor"))) {388 slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::CustomAccessor, thisObject->customGetterAcessor);389 return true;390 }391 392 return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot);393 }394 395 private:396 static EncodedJSValue customGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)397 {398 VM& vm = exec->vm();399 auto scope = DECLARE_THROW_SCOPE(vm);400 401 CustomGetter* thisObject = jsDynamicCast<CustomGetter*>(vm, JSValue::decode(thisValue));402 if (!thisObject)403 return throwVMTypeError(exec, scope);404 bool shouldThrow = thisObject->get(exec, PropertyName(Identifier::fromString(exec, "shouldThrow"))).toBoolean(exec);405 RETURN_IF_EXCEPTION(scope, encodedJSValue());406 if (shouldThrow)407 return throwVMTypeError(exec, scope);408 return JSValue::encode(jsNumber(100));409 }410 411 static EncodedJSValue customGetterAcessor(ExecState* exec, EncodedJSValue thisValue, PropertyName)412 {413 VM& vm = exec->vm();414 auto scope = DECLARE_THROW_SCOPE(vm);415 416 JSObject* thisObject = jsDynamicCast<JSObject*>(vm, JSValue::decode(thisValue));417 if (!thisObject)418 return throwVMTypeError(exec, scope);419 bool shouldThrow = thisObject->get(exec, PropertyName(Identifier::fromString(exec, "shouldThrow"))).toBoolean(exec);420 RETURN_IF_EXCEPTION(scope, encodedJSValue());421 if (shouldThrow)422 return throwVMTypeError(exec, scope);423 return JSValue::encode(jsNumber(100));424 }425 };426 427 class RuntimeArray : public JSArray {428 public:429 typedef JSArray Base;430 static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames;431 432 static RuntimeArray* create(ExecState* exec)433 {434 VM& vm = exec->vm();435 JSGlobalObject* globalObject = exec->lexicalGlobalObject();436 Structure* structure = createStructure(vm, globalObject, createPrototype(vm, globalObject));437 RuntimeArray* runtimeArray = new (NotNull, allocateCell<RuntimeArray>(vm.heap)) RuntimeArray(exec, structure);438 runtimeArray->finishCreation(exec);439 vm.heap.addFinalizer(runtimeArray, destroy);440 return runtimeArray;441 }442 443 ~RuntimeArray() { }444 445 static void destroy(JSCell* cell)446 {447 static_cast<RuntimeArray*>(cell)->RuntimeArray::~RuntimeArray();448 }449 450 static const bool needsDestruction = false;451 452 static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)453 {454 VM& vm = exec->vm();455 RuntimeArray* thisObject = jsCast<RuntimeArray*>(object);456 if (propertyName == vm.propertyNames->length) {457 slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum, thisObject->lengthGetter);458 return true;459 }460 461 std::optional<uint32_t> index = parseIndex(propertyName);462 if (index && index.value() < thisObject->getLength()) {463 slot.setValue(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::DontEnum, jsNumber(thisObject->m_vector[index.value()]));464 return true;465 }466 467 return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot);468 }469 470 static bool getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned index, PropertySlot& slot)471 {472 RuntimeArray* thisObject = jsCast<RuntimeArray*>(object);473 if (index < thisObject->getLength()) {474 slot.setValue(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::DontEnum, jsNumber(thisObject->m_vector[index]));475 return true;476 }477 478 return JSObject::getOwnPropertySlotByIndex(thisObject, exec, index, slot);479 }480 481 static NO_RETURN_DUE_TO_CRASH bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&)482 {483 RELEASE_ASSERT_NOT_REACHED();484 }485 486 static NO_RETURN_DUE_TO_CRASH bool deleteProperty(JSCell*, ExecState*, PropertyName)487 {488 RELEASE_ASSERT_NOT_REACHED();489 }490 491 unsigned getLength() const { return m_vector.size(); }492 493 DECLARE_INFO;494 495 static ArrayPrototype* createPrototype(VM&, JSGlobalObject* globalObject)496 {497 return globalObject->arrayPrototype();498 }499 500 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)501 {502 return Structure::create(vm, globalObject, prototype, TypeInfo(DerivedArrayType, StructureFlags), info(), ArrayClass);503 }504 505 protected:506 void finishCreation(ExecState* exec)507 {508 VM& vm = exec->vm();509 Base::finishCreation(vm);510 ASSERT(inherits(vm, info()));511 512 for (size_t i = 0; i < exec->argumentCount(); i++)513 m_vector.append(exec->argument(i).toInt32(exec));514 }515 516 private:517 RuntimeArray(ExecState* exec, Structure* structure)518 : JSArray(exec->vm(), structure, 0)519 {520 }521 522 static EncodedJSValue lengthGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)523 {524 VM& vm = exec->vm();525 auto scope = DECLARE_THROW_SCOPE(vm);526 527 RuntimeArray* thisObject = jsDynamicCast<RuntimeArray*>(vm, JSValue::decode(thisValue));528 if (!thisObject)529 return throwVMTypeError(exec, scope);530 return JSValue::encode(jsNumber(thisObject->getLength()));531 }532 533 Vector<int> m_vector;534 };535 536 class SimpleObject : public JSNonFinalObject {537 public:538 SimpleObject(VM& vm, Structure* structure)539 : Base(vm, structure)540 {541 }542 543 typedef JSNonFinalObject Base;544 static const bool needsDestruction = false;545 546 static SimpleObject* create(VM& vm, JSGlobalObject* globalObject)547 {548 Structure* structure = createStructure(vm, globalObject, jsNull());549 SimpleObject* simpleObject = new (NotNull, allocateCell<SimpleObject>(vm.heap, sizeof(SimpleObject))) SimpleObject(vm, structure);550 simpleObject->finishCreation(vm);551 return simpleObject;552 }553 554 static void visitChildren(JSCell* cell, SlotVisitor& visitor)555 {556 SimpleObject* thisObject = jsCast<SimpleObject*>(cell);557 ASSERT_GC_OBJECT_INHERITS(thisObject, info());558 Base::visitChildren(thisObject, visitor);559 visitor.append(thisObject->m_hiddenValue);560 }561 562 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)563 {564 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());565 }566 567 JSValue hiddenValue()568 {569 return m_hiddenValue.get();570 }571 572 void setHiddenValue(VM& vm, JSValue value)573 {574 ASSERT(value.isCell());575 m_hiddenValue.set(vm, this, value);576 }577 578 DECLARE_INFO;579 580 private:581 WriteBarrier<JSC::Unknown> m_hiddenValue;582 };583 584 class DOMJITNode : public JSNonFinalObject {585 public:586 DOMJITNode(VM& vm, Structure* structure)587 : Base(vm, structure)588 {589 }590 591 DECLARE_INFO;592 typedef JSNonFinalObject Base;593 static const unsigned StructureFlags = Base::StructureFlags;594 595 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)596 {597 return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());598 }599 600 #if ENABLE(JIT)601 static Ref<Snippet> checkSubClassSnippet()602 {603 Ref<Snippet> snippet = Snippet::create();604 snippet->setGenerator([=](CCallHelpers& jit, SnippetParams& params) {605 CCallHelpers::JumpList failureCases;606 failureCases.append(jit.branch8(607 CCallHelpers::NotEqual,608 CCallHelpers::Address(params[0].gpr(), JSCell::typeInfoTypeOffset()),609 CCallHelpers::TrustedImm32(JSC::JSType(LastJSCObjectType + 1))));610 return failureCases;611 });612 return snippet;613 }614 #endif615 616 static DOMJITNode* create(VM& vm, Structure* structure)617 {618 DOMJITNode* getter = new (NotNull, allocateCell<DOMJITNode>(vm.heap, sizeof(DOMJITNode))) DOMJITNode(vm, structure);619 getter->finishCreation(vm);620 return getter;621 }622 623 int32_t value() const624 {625 return m_value;626 }627 628 static ptrdiff_t offsetOfValue() { return OBJECT_OFFSETOF(DOMJITNode, m_value); }629 630 private:631 int32_t m_value { 42 };632 };633 634 class DOMJITGetter : public DOMJITNode {635 public:636 DOMJITGetter(VM& vm, Structure* structure)637 : Base(vm, structure)638 {639 }640 641 DECLARE_INFO;642 typedef DOMJITNode Base;643 static const unsigned StructureFlags = Base::StructureFlags;644 645 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)646 {647 return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());648 }649 650 static DOMJITGetter* create(VM& vm, Structure* structure)651 {652 DOMJITGetter* getter = new (NotNull, allocateCell<DOMJITGetter>(vm.heap, sizeof(DOMJITGetter))) DOMJITGetter(vm, structure);653 getter->finishCreation(vm);654 return getter;655 }656 657 class DOMJITAttribute : public DOMJIT::GetterSetter {658 public:659 constexpr DOMJITAttribute()660 : DOMJIT::GetterSetter(661 DOMJITGetter::customGetter,662 #if ENABLE(JIT)663 &callDOMGetter,664 #else665 nullptr,666 #endif667 SpecInt32Only)668 {669 }670 671 #if ENABLE(JIT)672 static EncodedJSValue JIT_OPERATION slowCall(ExecState* exec, void* pointer)673 {674 VM& vm = exec->vm();675 NativeCallFrameTracer tracer(&vm, exec);676 return JSValue::encode(jsNumber(static_cast<DOMJITGetter*>(pointer)->value()));677 }678 679 static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()680 {681 Ref<DOMJIT::CallDOMGetterSnippet> snippet = DOMJIT::CallDOMGetterSnippet::create();682 snippet->requireGlobalObject = false;683 snippet->setGenerator([=](CCallHelpers& jit, SnippetParams& params) {684 JSValueRegs results = params[0].jsValueRegs();685 GPRReg dom = params[1].gpr();686 params.addSlowPathCall(jit.jump(), jit, slowCall, results, dom);687 return CCallHelpers::JumpList();688 689 });690 return snippet;691 }692 #endif693 };694 695 private:696 void finishCreation(VM&);697 698 static EncodedJSValue customGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)699 {700 VM& vm = exec->vm();701 DOMJITNode* thisObject = jsDynamicCast<DOMJITNode*>(vm, JSValue::decode(thisValue));702 ASSERT(thisObject);703 return JSValue::encode(jsNumber(thisObject->value()));704 }705 };706 707 static const DOMJITGetter::DOMJITAttribute DOMJITGetterDOMJIT;708 709 void DOMJITGetter::finishCreation(VM& vm)710 {711 Base::finishCreation(vm);712 const DOMJIT::GetterSetter* domJIT = &DOMJITGetterDOMJIT;713 auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJIT->getter(), nullptr, DOMAttributeAnnotation { DOMJITNode::info(), domJIT });714 putDirectCustomAccessor(vm, Identifier::fromString(&vm, "customGetter"), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);715 }716 717 class DOMJITGetterComplex : public DOMJITNode {718 public:719 DOMJITGetterComplex(VM& vm, Structure* structure)720 : Base(vm, structure)721 {722 }723 724 DECLARE_INFO;725 typedef DOMJITNode Base;726 static const unsigned StructureFlags = Base::StructureFlags;727 728 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)729 {730 return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());731 }732 733 static DOMJITGetterComplex* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)734 {735 DOMJITGetterComplex* getter = new (NotNull, allocateCell<DOMJITGetterComplex>(vm.heap, sizeof(DOMJITGetterComplex))) DOMJITGetterComplex(vm, structure);736 getter->finishCreation(vm, globalObject);737 return getter;738 }739 740 class DOMJITAttribute : public DOMJIT::GetterSetter {741 public:742 constexpr DOMJITAttribute()743 : DOMJIT::GetterSetter(744 DOMJITGetterComplex::customGetter,745 #if ENABLE(JIT)746 &callDOMGetter,747 #else748 nullptr,749 #endif750 SpecInt32Only)751 {752 }753 754 #if ENABLE(JIT)755 static EncodedJSValue JIT_OPERATION slowCall(ExecState* exec, void* pointer)756 {757 VM& vm = exec->vm();758 NativeCallFrameTracer tracer(&vm, exec);759 auto scope = DECLARE_THROW_SCOPE(vm);760 auto* object = static_cast<DOMJITNode*>(pointer);761 auto* domjitGetterComplex = jsDynamicCast<DOMJITGetterComplex*>(vm, object);762 if (domjitGetterComplex) {763 if (domjitGetterComplex->m_enableException)764 return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("DOMJITGetterComplex slow call exception"))));765 }766 return JSValue::encode(jsNumber(object->value()));767 }768 769 static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()770 {771 Ref<DOMJIT::CallDOMGetterSnippet> snippet = DOMJIT::CallDOMGetterSnippet::create();772 static_assert(GPRInfo::numberOfRegisters >= 4, "Number of registers should be larger or equal to 4.");773 unsigned numGPScratchRegisters = GPRInfo::numberOfRegisters - 4;774 snippet->numGPScratchRegisters = numGPScratchRegisters;775 snippet->numFPScratchRegisters = 3;776 snippet->setGenerator([=](CCallHelpers& jit, SnippetParams& params) {777 JSValueRegs results = params[0].jsValueRegs();778 GPRReg domGPR = params[1].gpr();779 for (unsigned i = 0; i < numGPScratchRegisters; ++i)780 jit.move(CCallHelpers::TrustedImm32(42), params.gpScratch(i));781 782 params.addSlowPathCall(jit.jump(), jit, slowCall, results, domGPR);783 return CCallHelpers::JumpList();784 });785 return snippet;786 }787 #endif788 };789 790 private:791 void finishCreation(VM&, JSGlobalObject*);792 793 static EncodedJSValue JSC_HOST_CALL functionEnableException(ExecState* exec)794 {795 VM& vm = exec->vm();796 auto* object = jsDynamicCast<DOMJITGetterComplex*>(vm, exec->thisValue());797 if (object)798 object->m_enableException = true;799 return JSValue::encode(jsUndefined());800 }801 802 static EncodedJSValue customGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)803 {804 VM& vm = exec->vm();805 auto scope = DECLARE_THROW_SCOPE(vm);806 807 auto* thisObject = jsDynamicCast<DOMJITGetterComplex*>(vm, JSValue::decode(thisValue));808 ASSERT(thisObject);809 if (thisObject->m_enableException)810 return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("DOMJITGetterComplex slow call exception"))));811 return JSValue::encode(jsNumber(thisObject->value()));812 }813 814 bool m_enableException { false };815 };816 817 static const DOMJITGetterComplex::DOMJITAttribute DOMJITGetterComplexDOMJIT;818 819 void DOMJITGetterComplex::finishCreation(VM& vm, JSGlobalObject* globalObject)820 {821 Base::finishCreation(vm);822 const DOMJIT::GetterSetter* domJIT = &DOMJITGetterComplexDOMJIT;823 auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJIT->getter(), nullptr, DOMAttributeAnnotation { DOMJITGetterComplex::info(), domJIT });824 putDirectCustomAccessor(vm, Identifier::fromString(&vm, "customGetter"), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);825 putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "enableException"), 0, functionEnableException, NoIntrinsic, 0);826 }827 828 class DOMJITFunctionObject : public DOMJITNode {829 public:830 DOMJITFunctionObject(VM& vm, Structure* structure)831 : Base(vm, structure)832 {833 }834 835 DECLARE_INFO;836 typedef DOMJITNode Base;837 static const unsigned StructureFlags = Base::StructureFlags;838 839 840 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)841 {842 return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());843 }844 845 static DOMJITFunctionObject* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)846 {847 DOMJITFunctionObject* object = new (NotNull, allocateCell<DOMJITFunctionObject>(vm.heap, sizeof(DOMJITFunctionObject))) DOMJITFunctionObject(vm, structure);848 object->finishCreation(vm, globalObject);849 return object;850 }851 852 static EncodedJSValue JSC_HOST_CALL safeFunction(ExecState* exec)853 {854 VM& vm = exec->vm();855 auto scope = DECLARE_THROW_SCOPE(vm);856 857 DOMJITNode* thisObject = jsDynamicCast<DOMJITNode*>(vm, exec->thisValue());858 if (!thisObject)859 return throwVMTypeError(exec, scope);860 return JSValue::encode(jsNumber(thisObject->value()));861 }862 863 static EncodedJSValue JIT_OPERATION unsafeFunction(ExecState* exec, DOMJITNode* node)864 {865 VM& vm = exec->vm();866 NativeCallFrameTracer tracer(&vm, exec);867 return JSValue::encode(jsNumber(node->value()));868 }869 870 #if ENABLE(JIT)871 static Ref<Snippet> checkSubClassSnippet()872 {873 Ref<Snippet> snippet = Snippet::create();874 snippet->numFPScratchRegisters = 1;875 snippet->setGenerator([=](CCallHelpers& jit, SnippetParams& params) {876 static const double value = 42.0;877 CCallHelpers::JumpList failureCases;878 // May use scratch registers.879 jit.loadDouble(CCallHelpers::TrustedImmPtr(&value), params.fpScratch(0));880 failureCases.append(jit.branch8(881 CCallHelpers::NotEqual,882 CCallHelpers::Address(params[0].gpr(), JSCell::typeInfoTypeOffset()),883 CCallHelpers::TrustedImm32(JSC::JSType(LastJSCObjectType + 1))));884 return failureCases;885 });886 return snippet;887 }888 #endif889 890 private:891 void finishCreation(VM&, JSGlobalObject*);892 };893 894 static const DOMJIT::Signature DOMJITFunctionObjectSignature((uintptr_t)DOMJITFunctionObject::unsafeFunction, DOMJITFunctionObject::info(), DOMJIT::Effect::forRead(DOMJIT::HeapRange::top()), SpecInt32Only);895 896 void DOMJITFunctionObject::finishCreation(VM& vm, JSGlobalObject* globalObject)897 {898 Base::finishCreation(vm);899 putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "func"), 0, safeFunction, NoIntrinsic, &DOMJITFunctionObjectSignature, static_cast<unsigned>(PropertyAttribute::ReadOnly));900 }901 902 class DOMJITCheckSubClassObject : public DOMJITNode {903 public:904 DOMJITCheckSubClassObject(VM& vm, Structure* structure)905 : Base(vm, structure)906 {907 }908 909 DECLARE_INFO;910 typedef DOMJITNode Base;911 static const unsigned StructureFlags = Base::StructureFlags;912 913 914 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)915 {916 return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());917 }918 919 static DOMJITCheckSubClassObject* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)920 {921 DOMJITCheckSubClassObject* object = new (NotNull, allocateCell<DOMJITCheckSubClassObject>(vm.heap, sizeof(DOMJITCheckSubClassObject))) DOMJITCheckSubClassObject(vm, structure);922 object->finishCreation(vm, globalObject);923 return object;924 }925 926 static EncodedJSValue JSC_HOST_CALL safeFunction(ExecState* exec)927 {928 VM& vm = exec->vm();929 auto scope = DECLARE_THROW_SCOPE(vm);930 931 auto* thisObject = jsDynamicCast<DOMJITCheckSubClassObject*>(vm, exec->thisValue());932 if (!thisObject)933 return throwVMTypeError(exec, scope);934 return JSValue::encode(jsNumber(thisObject->value()));935 }936 937 static EncodedJSValue JIT_OPERATION unsafeFunction(ExecState* exec, DOMJITNode* node)938 {939 VM& vm = exec->vm();940 NativeCallFrameTracer tracer(&vm, exec);941 return JSValue::encode(jsNumber(node->value()));942 }943 944 private:945 void finishCreation(VM&, JSGlobalObject*);946 };947 948 static const DOMJIT::Signature DOMJITCheckSubClassObjectSignature((uintptr_t)DOMJITCheckSubClassObject::unsafeFunction, DOMJITCheckSubClassObject::info(), DOMJIT::Effect::forRead(DOMJIT::HeapRange::top()), SpecInt32Only);949 950 void DOMJITCheckSubClassObject::finishCreation(VM& vm, JSGlobalObject* globalObject)951 {952 Base::finishCreation(vm);953 putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "func"), 0, safeFunction, NoIntrinsic, &DOMJITCheckSubClassObjectSignature, static_cast<unsigned>(PropertyAttribute::ReadOnly));954 }955 956 class DOMJITGetterBaseJSObject : public DOMJITNode {957 public:958 DOMJITGetterBaseJSObject(VM& vm, Structure* structure)959 : Base(vm, structure)960 {961 }962 963 DECLARE_INFO;964 using Base = DOMJITNode;965 static const unsigned StructureFlags = Base::StructureFlags;966 967 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)968 {969 return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());970 }971 972 static DOMJITGetterBaseJSObject* create(VM& vm, Structure* structure)973 {974 DOMJITGetterBaseJSObject* getter = new (NotNull, allocateCell<DOMJITGetterBaseJSObject>(vm.heap, sizeof(DOMJITGetterBaseJSObject))) DOMJITGetterBaseJSObject(vm, structure);975 getter->finishCreation(vm);976 return getter;977 }978 979 class DOMJITAttribute : public DOMJIT::GetterSetter {980 public:981 constexpr DOMJITAttribute()982 : DOMJIT::GetterSetter(983 DOMJITGetterBaseJSObject::customGetter,984 #if ENABLE(JIT)985 &callDOMGetter,986 #else987 nullptr,988 #endif989 SpecBytecodeTop)990 {991 }992 993 #if ENABLE(JIT)994 static EncodedJSValue JIT_OPERATION slowCall(ExecState* exec, void* pointer)995 {996 VM& vm = exec->vm();997 NativeCallFrameTracer tracer(&vm, exec);998 JSObject* object = static_cast<JSObject*>(pointer);999 return JSValue::encode(object->getPrototypeDirect(vm));1000 }1001 1002 static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()1003 {1004 Ref<DOMJIT::CallDOMGetterSnippet> snippet = DOMJIT::CallDOMGetterSnippet::create();1005 snippet->requireGlobalObject = false;1006 snippet->setGenerator([=](CCallHelpers& jit, SnippetParams& params) {1007 JSValueRegs results = params[0].jsValueRegs();1008 GPRReg dom = params[1].gpr();1009 params.addSlowPathCall(jit.jump(), jit, slowCall, results, dom);1010 return CCallHelpers::JumpList();1011 1012 });1013 return snippet;1014 }1015 #endif1016 };1017 1018 private:1019 void finishCreation(VM&);1020 1021 static EncodedJSValue customGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName)1022 {1023 VM& vm = exec->vm();1024 JSObject* thisObject = jsDynamicCast<JSObject*>(vm, JSValue::decode(thisValue));1025 RELEASE_ASSERT(thisObject);1026 return JSValue::encode(thisObject->getPrototypeDirect(vm));1027 }1028 };1029 1030 static const DOMJITGetterBaseJSObject::DOMJITAttribute DOMJITGetterBaseJSObjectDOMJIT;1031 1032 void DOMJITGetterBaseJSObject::finishCreation(VM& vm)1033 {1034 Base::finishCreation(vm);1035 const DOMJIT::GetterSetter* domJIT = &DOMJITGetterBaseJSObjectDOMJIT;1036 auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJIT->getter(), nullptr, DOMAttributeAnnotation { JSObject::info(), domJIT });1037 putDirectCustomAccessor(vm, Identifier::fromString(&vm, "customGetter"), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);1038 }1039 1040 const ClassInfo Element::s_info = { "Element", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(Element) };1041 181 const ClassInfo Masquerader::s_info = { "Masquerader", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(Masquerader) }; 1042 const ClassInfo Root::s_info = { "Root", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(Root) };1043 const ClassInfo ImpureGetter::s_info = { "ImpureGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(ImpureGetter) };1044 const ClassInfo CustomGetter::s_info = { "CustomGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(CustomGetter) };1045 #if ENABLE(JIT)1046 const ClassInfo DOMJITNode::s_info = { "DOMJITNode", &Base::s_info, nullptr, &DOMJITNode::checkSubClassSnippet, CREATE_METHOD_TABLE(DOMJITNode) };1047 #else1048 const ClassInfo DOMJITNode::s_info = { "DOMJITNode", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITNode) };1049 #endif1050 const ClassInfo DOMJITGetter::s_info = { "DOMJITGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetter) };1051 const ClassInfo DOMJITGetterComplex::s_info = { "DOMJITGetterComplex", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetterComplex) };1052 const ClassInfo DOMJITGetterBaseJSObject::s_info = { "DOMJITGetterBaseJSObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetterBaseJSObject) };1053 #if ENABLE(JIT)1054 const ClassInfo DOMJITFunctionObject::s_info = { "DOMJITFunctionObject", &Base::s_info, nullptr, &DOMJITFunctionObject::checkSubClassSnippet, CREATE_METHOD_TABLE(DOMJITFunctionObject) };1055 #else1056 const ClassInfo DOMJITFunctionObject::s_info = { "DOMJITFunctionObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITFunctionObject) };1057 #endif1058 const ClassInfo DOMJITCheckSubClassObject::s_info = { "DOMJITCheckSubClassObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITCheckSubClassObject) };1059 const ClassInfo RuntimeArray::s_info = { "RuntimeArray", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(RuntimeArray) };1060 const ClassInfo SimpleObject::s_info = { "SimpleObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(SimpleObject) };1061 182 static unsigned asyncTestPasses { 0 }; 1062 183 static unsigned asyncTestExpectedPasses { 0 }; 1063 1064 ElementHandleOwner* Element::handleOwner()1065 {1066 static ElementHandleOwner* owner = 0;1067 if (!owner)1068 owner = new ElementHandleOwner();1069 return owner;1070 }1071 1072 void Element::finishCreation(VM& vm, Root* root)1073 {1074 Base::finishCreation(vm);1075 setRoot(vm, root);1076 m_root->setElement(this);1077 }1078 184 1079 185 } … … 1143 249 }; 1144 250 1145 class JSTestCustomGetterSetter : public JSNonFinalObject { 1146 public: 1147 using Base = JSNonFinalObject; 1148 static const unsigned StructureFlags = Base::StructureFlags; 1149 1150 JSTestCustomGetterSetter(VM& vm, Structure* structure) 1151 : Base(vm, structure) 1152 { } 1153 1154 static JSTestCustomGetterSetter* create(VM& vm, JSGlobalObject*, Structure* structure) 1155 { 1156 JSTestCustomGetterSetter* result = new (NotNull, allocateCell<JSTestCustomGetterSetter>(vm.heap, sizeof(JSTestCustomGetterSetter))) JSTestCustomGetterSetter(vm, structure); 1157 result->finishCreation(vm); 1158 return result; 1159 } 1160 1161 void finishCreation(VM& vm); 1162 1163 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject) 1164 { 1165 return Structure::create(vm, globalObject, globalObject->objectPrototype(), TypeInfo(ObjectType, StructureFlags), info()); 1166 } 1167 1168 DECLARE_INFO; 1169 }; 1170 1171 1172 static EncodedJSValue customGetAccessor(ExecState*, EncodedJSValue thisValue, PropertyName) 1173 { 1174 // Passed |this| 1175 return thisValue; 1176 } 1177 1178 static EncodedJSValue customGetValue(ExecState* exec, EncodedJSValue slotValue, PropertyName) 1179 { 1180 RELEASE_ASSERT(JSValue::decode(slotValue).inherits(exec->vm(), JSTestCustomGetterSetter::info())); 1181 // Passed property holder. 1182 return slotValue; 1183 } 1184 1185 static bool customSetAccessor(ExecState* exec, EncodedJSValue thisObject, EncodedJSValue encodedValue) 1186 { 1187 VM& vm = exec->vm(); 1188 1189 JSValue value = JSValue::decode(encodedValue); 1190 RELEASE_ASSERT(value.isObject()); 1191 JSObject* object = asObject(value); 1192 PutPropertySlot slot(object); 1193 object->put(object, exec, Identifier::fromString(&vm, "result"), JSValue::decode(thisObject), slot); 1194 1195 return true; 1196 } 1197 1198 static bool customSetValue(ExecState* exec, EncodedJSValue slotValue, EncodedJSValue encodedValue) 1199 { 1200 VM& vm = exec->vm(); 1201 1202 RELEASE_ASSERT(JSValue::decode(slotValue).inherits(exec->vm(), JSTestCustomGetterSetter::info())); 1203 1204 JSValue value = JSValue::decode(encodedValue); 1205 RELEASE_ASSERT(value.isObject()); 1206 JSObject* object = asObject(value); 1207 PutPropertySlot slot(object); 1208 object->put(object, exec, Identifier::fromString(&vm, "result"), JSValue::decode(slotValue), slot); 1209 1210 return true; 1211 } 1212 1213 void JSTestCustomGetterSetter::finishCreation(VM& vm) 1214 { 1215 Base::finishCreation(vm); 1216 1217 putDirectCustomAccessor(vm, Identifier::fromString(&vm, "customValue"), 1218 CustomGetterSetter::create(vm, customGetValue, customSetValue), 0); 1219 putDirectCustomAccessor(vm, Identifier::fromString(&vm, "customAccessor"), 1220 CustomGetterSetter::create(vm, customGetAccessor, customSetAccessor), static_cast<unsigned>(PropertyAttribute::CustomAccessor)); 1221 } 1222 1223 const ClassInfo JSTestCustomGetterSetter::s_info = { "JSTestCustomGetterSetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestCustomGetterSetter) }; 1224 1225 static EncodedJSValue JSC_HOST_CALL functionCreateProxy(ExecState*); 1226 static EncodedJSValue JSC_HOST_CALL functionCreateRuntimeArray(ExecState*); 1227 static EncodedJSValue JSC_HOST_CALL functionCreateImpureGetter(ExecState*); 1228 static EncodedJSValue JSC_HOST_CALL functionCreateCustomGetterObject(ExecState*); 1229 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITNodeObject(ExecState*); 1230 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterObject(ExecState*); 1231 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterComplexObject(ExecState*); 1232 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITFunctionObject(ExecState*); 1233 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITCheckSubClassObject(ExecState*); 1234 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterBaseJSObject(ExecState*); 1235 static EncodedJSValue JSC_HOST_CALL functionCreateBuiltin(ExecState*); 251 1236 252 static EncodedJSValue JSC_HOST_CALL functionCreateGlobalObject(ExecState*); 1237 static EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(ExecState*); 1238 1239 static EncodedJSValue JSC_HOST_CALL functionSetElementRoot(ExecState*); 1240 static EncodedJSValue JSC_HOST_CALL functionCreateRoot(ExecState*); 1241 static EncodedJSValue JSC_HOST_CALL functionCreateElement(ExecState*); 1242 static EncodedJSValue JSC_HOST_CALL functionGetElement(ExecState*); 1243 static EncodedJSValue JSC_HOST_CALL functionCreateSimpleObject(ExecState*); 1244 static EncodedJSValue JSC_HOST_CALL functionGetHiddenValue(ExecState*); 1245 static EncodedJSValue JSC_HOST_CALL functionSetHiddenValue(ExecState*); 253 1246 254 static EncodedJSValue JSC_HOST_CALL functionPrintStdOut(ExecState*); 1247 255 static EncodedJSValue JSC_HOST_CALL functionPrintStdErr(ExecState*); … … 1257 265 static EncodedJSValue JSC_HOST_CALL functionHeapSize(ExecState*); 1258 266 static EncodedJSValue JSC_HOST_CALL functionAddressOf(ExecState*); 1259 static EncodedJSValue JSC_HOST_CALL functionGetGetterSetter(ExecState*);1260 267 #ifndef NDEBUG 1261 268 static EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(ExecState*); … … 1281 288 static EncodedJSValue JSC_HOST_CALL functionFailNextNewCodeBlock(ExecState*); 1282 289 static NO_RETURN_WITH_VALUE EncodedJSValue JSC_HOST_CALL functionQuit(ExecState*); 1283 static NO_RETURN_DUE_TO_CRASH EncodedJSValue JSC_HOST_CALL functionAbort(ExecState*);1284 290 static EncodedJSValue JSC_HOST_CALL functionFalse1(ExecState*); 1285 291 static EncodedJSValue JSC_HOST_CALL functionFalse2(ExecState*); … … 1292 298 static EncodedJSValue JSC_HOST_CALL functionHasCustomProperties(ExecState*); 1293 299 static EncodedJSValue JSC_HOST_CALL functionDumpTypesForAllVariables(ExecState*); 1294 static EncodedJSValue JSC_HOST_CALL functionFindTypeForExpression(ExecState*);1295 static EncodedJSValue JSC_HOST_CALL functionReturnTypeFor(ExecState*);1296 static EncodedJSValue JSC_HOST_CALL functionDumpBasicBlockExecutionRanges(ExecState*);1297 static EncodedJSValue JSC_HOST_CALL functionHasBasicBlockExecuted(ExecState*);1298 static EncodedJSValue JSC_HOST_CALL functionBasicBlockExecutionCount(ExecState*);1299 static EncodedJSValue JSC_HOST_CALL functionEnableExceptionFuzz(ExecState*);1300 300 static EncodedJSValue JSC_HOST_CALL functionDrainMicrotasks(ExecState*); 1301 301 static EncodedJSValue JSC_HOST_CALL functionIs32BitPlatform(ExecState*); … … 1324 324 #endif 1325 325 1326 static EncodedJSValue JSC_HOST_CALL functionShadowChickenFunctionsOnStack(ExecState*);1327 static EncodedJSValue JSC_HOST_CALL functionSetGlobalConstRedeclarationShouldNotThrow(ExecState*);1328 326 static EncodedJSValue JSC_HOST_CALL functionGetRandomSeed(ExecState*); 1329 327 static EncodedJSValue JSC_HOST_CALL functionSetRandomSeed(ExecState*); 1330 328 static EncodedJSValue JSC_HOST_CALL functionIsRope(ExecState*); 1331 329 static EncodedJSValue JSC_HOST_CALL functionCallerSourceOrigin(ExecState*); 1332 static EncodedJSValue JSC_HOST_CALL functionGlobalObjectForObject(ExecState*);1333 330 static EncodedJSValue JSC_HOST_CALL functionDollarCreateRealm(ExecState*); 1334 331 static EncodedJSValue JSC_HOST_CALL functionDollarDetachArrayBuffer(ExecState*); … … 1344 341 static EncodedJSValue JSC_HOST_CALL functionHeapCapacity(ExecState*); 1345 342 static EncodedJSValue JSC_HOST_CALL functionFlashHeapAccess(ExecState*); 1346 static EncodedJSValue JSC_HOST_CALL functionLoadGetterFromGetterSetter(ExecState*);1347 static EncodedJSValue JSC_HOST_CALL functionCreateCustomTestGetterSetter(ExecState*);1348 343 1349 344 struct Script { … … 1481 476 addFunction(vm, "printErr", functionPrintStdErr, 1); 1482 477 addFunction(vm, "quit", functionQuit, 0); 1483 addFunction(vm, "abort", functionAbort, 0);1484 478 addFunction(vm, "gc", functionGCAndSweep, 0); 1485 479 addFunction(vm, "fullGC", functionFullGC, 0); … … 1488 482 addFunction(vm, "gcHeapSize", functionHeapSize, 0); 1489 483 addFunction(vm, "addressOf", functionAddressOf, 1); 1490 addFunction(vm, "getGetterSetter", functionGetGetterSetter, 2);1491 484 #ifndef NDEBUG 1492 485 addFunction(vm, "dumpCallFrame", functionDumpCallFrame, 0); … … 1519 512 addFunction(vm, "clearSamplingFlags", functionClearSamplingFlags, 1); 1520 513 #endif 1521 addFunction(vm, "shadowChickenFunctionsOnStack", functionShadowChickenFunctionsOnStack, 0); 1522 addFunction(vm, "setGlobalConstRedeclarationShouldNotThrow", functionSetGlobalConstRedeclarationShouldNotThrow, 0); 1523 addConstructableFunction(vm, "Root", functionCreateRoot, 0); 1524 addConstructableFunction(vm, "Element", functionCreateElement, 1); 1525 addFunction(vm, "getElement", functionGetElement, 1); 1526 addFunction(vm, "setElementRoot", functionSetElementRoot, 2); 1527 1528 addConstructableFunction(vm, "SimpleObject", functionCreateSimpleObject, 0); 1529 addFunction(vm, "getHiddenValue", functionGetHiddenValue, 1); 1530 addFunction(vm, "setHiddenValue", functionSetHiddenValue, 2); 1531 514 1532 515 putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "DFGTrue"), 0, functionFalse1, DFGTrueIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum)); 1533 516 putDirectNativeFunction(vm, this, Identifier::fromString(&vm, "OSRExit"), 0, functionUndefined1, OSRExitIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum)); … … 1541 524 addFunction(vm, "hasCustomProperties", functionHasCustomProperties, 0); 1542 525 1543 addFunction(vm, "createProxy", functionCreateProxy, 1);1544 addFunction(vm, "createRuntimeArray", functionCreateRuntimeArray, 0);1545 1546 addFunction(vm, "createImpureGetter", functionCreateImpureGetter, 1);1547 addFunction(vm, "createCustomGetterObject", functionCreateCustomGetterObject, 0);1548 addFunction(vm, "createDOMJITNodeObject", functionCreateDOMJITNodeObject, 0);1549 addFunction(vm, "createDOMJITGetterObject", functionCreateDOMJITGetterObject, 0);1550 addFunction(vm, "createDOMJITGetterComplexObject", functionCreateDOMJITGetterComplexObject, 0);1551 addFunction(vm, "createDOMJITFunctionObject", functionCreateDOMJITFunctionObject, 0);1552 addFunction(vm, "createDOMJITCheckSubClassObject", functionCreateDOMJITCheckSubClassObject, 0);1553 addFunction(vm, "createDOMJITGetterBaseJSObject", functionCreateDOMJITGetterBaseJSObject, 0);1554 addFunction(vm, "createBuiltin", functionCreateBuiltin, 2);1555 526 addFunction(vm, "createGlobalObject", functionCreateGlobalObject, 0); 1556 addFunction(vm, "setImpureGetterDelegate", functionSetImpureGetterDelegate, 2);1557 527 1558 528 addFunction(vm, "dumpTypesForAllVariables", functionDumpTypesForAllVariables , 0); 1559 addFunction(vm, "findTypeForExpression", functionFindTypeForExpression, 2);1560 addFunction(vm, "returnTypeFor", functionReturnTypeFor, 1);1561 1562 addFunction(vm, "dumpBasicBlockExecutionRanges", functionDumpBasicBlockExecutionRanges , 0);1563 addFunction(vm, "hasBasicBlockExecuted", functionHasBasicBlockExecuted, 2);1564 addFunction(vm, "basicBlockExecutionCount", functionBasicBlockExecutionCount, 2);1565 1566 addFunction(vm, "enableExceptionFuzz", functionEnableExceptionFuzz, 0);1567 529 1568 530 addFunction(vm, "drainMicrotasks", functionDrainMicrotasks, 0); … … 1572 534 addFunction(vm, "isRope", functionIsRope, 1); 1573 535 addFunction(vm, "callerSourceOrigin", functionCallerSourceOrigin, 0); 1574 1575 addFunction(vm, "globalObjectForObject", functionGlobalObjectForObject, 1);1576 536 1577 537 addFunction(vm, "is32BitPlatform", functionIs32BitPlatform, 0); … … 1636 596 addFunction(vm, "heapCapacity", functionHeapCapacity, 0); 1637 597 addFunction(vm, "flashHeapAccess", functionFlashHeapAccess, 0); 1638 1639 addFunction(vm, "loadGetterFromGetterSetter", functionLoadGetterFromGetterSetter, 1);1640 addFunction(vm, "createCustomTestGetterSetter", functionCreateCustomTestGetterSetter, 1);1641 598 } 1642 599 … … 1652 609 } 1653 610 1654 void addConstructableFunction(VM& vm, const char* name, NativeFunction function, unsigned arguments)1655 {1656 Identifier identifier = Identifier::fromString(&vm, name);1657 putDirect(vm, identifier, JSFunction::create(vm, this, arguments, identifier.string(), function, NoIntrinsic, function));1658 }1659 1660 611 static JSInternalPromise* moduleLoaderImportModule(JSGlobalObject*, ExecState*, JSModuleLoader*, JSString*, JSValue, const SourceOrigin&); 1661 612 static Identifier moduleLoaderResolve(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSValue, JSValue); … … 2126 1077 } 2127 1078 2128 EncodedJSValue JSC_HOST_CALL functionCreateRoot(ExecState* exec)2129 {2130 VM& vm = exec->vm();2131 JSLockHolder lock(vm);2132 return JSValue::encode(Root::create(vm, exec->lexicalGlobalObject()));2133 }2134 2135 EncodedJSValue JSC_HOST_CALL functionCreateElement(ExecState* exec)2136 {2137 VM& vm = exec->vm();2138 JSLockHolder lock(vm);2139 auto scope = DECLARE_THROW_SCOPE(vm);2140 2141 Root* root = jsDynamicCast<Root*>(vm, exec->argument(0));2142 if (!root)2143 return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("Cannot create Element without a Root."))));2144 return JSValue::encode(Element::create(vm, exec->lexicalGlobalObject(), root));2145 }2146 2147 EncodedJSValue JSC_HOST_CALL functionGetElement(ExecState* exec)2148 {2149 VM& vm = exec->vm();2150 JSLockHolder lock(vm);2151 Root* root = jsDynamicCast<Root*>(vm, exec->argument(0));2152 if (!root)2153 return JSValue::encode(jsUndefined());2154 Element* result = root->element();2155 return JSValue::encode(result ? result : jsUndefined());2156 }2157 2158 EncodedJSValue JSC_HOST_CALL functionSetElementRoot(ExecState* exec)2159 {2160 VM& vm = exec->vm();2161 JSLockHolder lock(vm);2162 Element* element = jsDynamicCast<Element*>(vm, exec->argument(0));2163 Root* root = jsDynamicCast<Root*>(vm, exec->argument(1));2164 if (element && root)2165 element->setRoot(vm, root);2166 return JSValue::encode(jsUndefined());2167 }2168 2169 EncodedJSValue JSC_HOST_CALL functionCreateSimpleObject(ExecState* exec)2170 {2171 VM& vm = exec->vm();2172 JSLockHolder lock(vm);2173 return JSValue::encode(SimpleObject::create(vm, exec->lexicalGlobalObject()));2174 }2175 2176 EncodedJSValue JSC_HOST_CALL functionGetHiddenValue(ExecState* exec)2177 {2178 VM& vm = exec->vm();2179 JSLockHolder lock(vm);2180 auto scope = DECLARE_THROW_SCOPE(vm);2181 2182 SimpleObject* simpleObject = jsDynamicCast<SimpleObject*>(vm, exec->argument(0));2183 if (UNLIKELY(!simpleObject)) {2184 throwTypeError(exec, scope, ASCIILiteral("Invalid use of getHiddenValue test function"));2185 return encodedJSValue();2186 }2187 return JSValue::encode(simpleObject->hiddenValue());2188 }2189 2190 EncodedJSValue JSC_HOST_CALL functionSetHiddenValue(ExecState* exec)2191 {2192 VM& vm = exec->vm();2193 JSLockHolder lock(vm);2194 auto scope = DECLARE_THROW_SCOPE(vm);2195 2196 SimpleObject* simpleObject = jsDynamicCast<SimpleObject*>(vm, exec->argument(0));2197 if (UNLIKELY(!simpleObject)) {2198 throwTypeError(exec, scope, ASCIILiteral("Invalid use of setHiddenValue test function"));2199 return encodedJSValue();2200 }2201 JSValue value = exec->argument(1);2202 simpleObject->setHiddenValue(vm, value);2203 return JSValue::encode(jsUndefined());2204 }2205 2206 EncodedJSValue JSC_HOST_CALL functionCreateProxy(ExecState* exec)2207 {2208 VM& vm = exec->vm();2209 JSLockHolder lock(vm);2210 JSValue target = exec->argument(0);2211 if (!target.isObject())2212 return JSValue::encode(jsUndefined());2213 JSObject* jsTarget = asObject(target.asCell());2214 Structure* structure = JSProxy::createStructure(vm, exec->lexicalGlobalObject(), jsTarget->getPrototypeDirect(vm), ImpureProxyType);2215 JSProxy* proxy = JSProxy::create(vm, structure, jsTarget);2216 return JSValue::encode(proxy);2217 }2218 2219 EncodedJSValue JSC_HOST_CALL functionCreateRuntimeArray(ExecState* exec)2220 {2221 JSLockHolder lock(exec);2222 RuntimeArray* array = RuntimeArray::create(exec);2223 return JSValue::encode(array);2224 }2225 2226 EncodedJSValue JSC_HOST_CALL functionCreateImpureGetter(ExecState* exec)2227 {2228 VM& vm = exec->vm();2229 JSLockHolder lock(vm);2230 JSValue target = exec->argument(0);2231 JSObject* delegate = nullptr;2232 if (target.isObject())2233 delegate = asObject(target.asCell());2234 Structure* structure = ImpureGetter::createStructure(vm, exec->lexicalGlobalObject(), jsNull());2235 ImpureGetter* result = ImpureGetter::create(vm, structure, delegate);2236 return JSValue::encode(result);2237 }2238 2239 EncodedJSValue JSC_HOST_CALL functionCreateCustomGetterObject(ExecState* exec)2240 {2241 VM& vm = exec->vm();2242 JSLockHolder lock(vm);2243 Structure* structure = CustomGetter::createStructure(vm, exec->lexicalGlobalObject(), jsNull());2244 CustomGetter* result = CustomGetter::create(vm, structure);2245 return JSValue::encode(result);2246 }2247 2248 EncodedJSValue JSC_HOST_CALL functionCreateDOMJITNodeObject(ExecState* exec)2249 {2250 VM& vm = exec->vm();2251 JSLockHolder lock(vm);2252 Structure* structure = DOMJITNode::createStructure(vm, exec->lexicalGlobalObject(), DOMJITGetter::create(vm, DOMJITGetter::createStructure(vm, exec->lexicalGlobalObject(), jsNull())));2253 DOMJITNode* result = DOMJITNode::create(vm, structure);2254 return JSValue::encode(result);2255 }2256 2257 EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterObject(ExecState* exec)2258 {2259 VM& vm = exec->vm();2260 JSLockHolder lock(vm);2261 Structure* structure = DOMJITGetter::createStructure(vm, exec->lexicalGlobalObject(), jsNull());2262 DOMJITGetter* result = DOMJITGetter::create(vm, structure);2263 return JSValue::encode(result);2264 }2265 2266 EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterComplexObject(ExecState* exec)2267 {2268 VM& vm = exec->vm();2269 JSLockHolder lock(vm);2270 Structure* structure = DOMJITGetterComplex::createStructure(vm, exec->lexicalGlobalObject(), jsNull());2271 DOMJITGetterComplex* result = DOMJITGetterComplex::create(vm, exec->lexicalGlobalObject(), structure);2272 return JSValue::encode(result);2273 }2274 2275 EncodedJSValue JSC_HOST_CALL functionCreateDOMJITFunctionObject(ExecState* exec)2276 {2277 VM& vm = exec->vm();2278 JSLockHolder lock(vm);2279 Structure* structure = DOMJITFunctionObject::createStructure(vm, exec->lexicalGlobalObject(), jsNull());2280 DOMJITFunctionObject* result = DOMJITFunctionObject::create(vm, exec->lexicalGlobalObject(), structure);2281 return JSValue::encode(result);2282 }2283 2284 EncodedJSValue JSC_HOST_CALL functionCreateDOMJITCheckSubClassObject(ExecState* exec)2285 {2286 VM& vm = exec->vm();2287 JSLockHolder lock(vm);2288 Structure* structure = DOMJITCheckSubClassObject::createStructure(vm, exec->lexicalGlobalObject(), jsNull());2289 DOMJITCheckSubClassObject* result = DOMJITCheckSubClassObject::create(vm, exec->lexicalGlobalObject(), structure);2290 return JSValue::encode(result);2291 }2292 2293 EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterBaseJSObject(ExecState* exec)2294 {2295 VM& vm = exec->vm();2296 JSLockHolder lock(vm);2297 Structure* structure = DOMJITGetterBaseJSObject::createStructure(vm, exec->lexicalGlobalObject(), jsNull());2298 DOMJITGetterBaseJSObject* result = DOMJITGetterBaseJSObject::create(vm, structure);2299 return JSValue::encode(result);2300 }2301 2302 2303 EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(ExecState* exec)2304 {2305 VM& vm = exec->vm();2306 JSLockHolder lock(vm);2307 auto scope = DECLARE_THROW_SCOPE(vm);2308 2309 JSValue base = exec->argument(0);2310 if (!base.isObject())2311 return JSValue::encode(jsUndefined());2312 JSValue delegate = exec->argument(1);2313 if (!delegate.isObject())2314 return JSValue::encode(jsUndefined());2315 ImpureGetter* impureGetter = jsDynamicCast<ImpureGetter*>(vm, asObject(base.asCell()));2316 if (UNLIKELY(!impureGetter)) {2317 throwTypeError(exec, scope, ASCIILiteral("argument is not an ImpureGetter"));2318 return encodedJSValue();2319 }2320 impureGetter->setDelegate(vm, asObject(delegate.asCell()));2321 return JSValue::encode(jsUndefined());2322 }2323 2324 1079 EncodedJSValue JSC_HOST_CALL functionGCAndSweep(ExecState* exec) 2325 1080 { … … 2375 1130 } 2376 1131 2377 static EncodedJSValue JSC_HOST_CALL functionGetGetterSetter(ExecState* exec)2378 {2379 JSValue value = exec->argument(0);2380 if (!value.isObject())2381 return JSValue::encode(jsUndefined());2382 2383 JSValue property = exec->argument(1);2384 if (!property.isString())2385 return JSValue::encode(jsUndefined());2386 2387 PropertySlot slot(value, PropertySlot::InternalMethodType::VMInquiry);2388 value.getPropertySlot(exec, asString(property)->toIdentifier(exec), slot);2389 2390 JSValue result;2391 if (slot.isCacheableGetter())2392 result = slot.getterSetter();2393 else2394 result = jsNull();2395 2396 return JSValue::encode(result);2397 }2398 2399 1132 EncodedJSValue JSC_HOST_CALL functionVersion(ExecState*) 2400 1133 { … … 2584 1317 #endif 2585 1318 2586 EncodedJSValue JSC_HOST_CALL functionShadowChickenFunctionsOnStack(ExecState* exec)2587 {2588 VM& vm = exec->vm();2589 return JSValue::encode(vm.shadowChicken().functionsOnStack(exec));2590 }2591 2592 EncodedJSValue JSC_HOST_CALL functionSetGlobalConstRedeclarationShouldNotThrow(ExecState* exec)2593 {2594 VM& vm = exec->vm();2595 vm.setGlobalConstRedeclarationShouldThrow(false);2596 return JSValue::encode(jsUndefined());2597 }2598 2599 1319 EncodedJSValue JSC_HOST_CALL functionGetRandomSeed(ExecState* exec) 2600 1320 { … … 2628 1348 return JSValue::encode(jsNull()); 2629 1349 return JSValue::encode(jsString(state, sourceOrigin.string())); 2630 }2631 2632 EncodedJSValue JSC_HOST_CALL functionGlobalObjectForObject(ExecState* exec)2633 {2634 JSValue value = exec->argument(0);2635 RELEASE_ASSERT(value.isObject());2636 JSGlobalObject* globalObject = jsCast<JSObject*>(value)->globalObject();2637 RELEASE_ASSERT(globalObject);2638 return JSValue::encode(globalObject);2639 1350 } 2640 1351 … … 3020 1731 } 3021 1732 3022 EncodedJSValue JSC_HOST_CALL functionLoadGetterFromGetterSetter(ExecState* exec)3023 {3024 VM& vm = exec->vm();3025 auto scope = DECLARE_THROW_SCOPE(vm);3026 3027 GetterSetter* getterSetter = jsDynamicCast<GetterSetter*>(vm, exec->argument(0));3028 if (UNLIKELY(!getterSetter)) {3029 throwTypeError(exec, scope, ASCIILiteral("Invalid use of loadGetterFromGetterSetter test function: argument is not a GetterSetter"));3030 return encodedJSValue();3031 }3032 3033 JSObject* getter = getterSetter->getter();3034 RELEASE_ASSERT(getter);3035 return JSValue::encode(getter);3036 }3037 3038 EncodedJSValue JSC_HOST_CALL functionCreateCustomTestGetterSetter(ExecState* exec)3039 {3040 VM& vm = exec->vm();3041 JSGlobalObject* globalObject = exec->lexicalGlobalObject();3042 return JSValue::encode(JSTestCustomGetterSetter::create(vm, globalObject, JSTestCustomGetterSetter::createStructure(vm, globalObject)));3043 }3044 3045 1733 template<typename ValueType> 3046 1734 typename std::enable_if<!std::is_fundamental<ValueType>::value>::type addOption(VM&, JSObject*, Identifier, ValueType) { } … … 3110 1798 } 3111 1799 3112 EncodedJSValue JSC_HOST_CALL functionAbort(ExecState*)3113 {3114 CRASH();3115 }3116 3117 1800 EncodedJSValue JSC_HOST_CALL functionFalse1(ExecState*) { return JSValue::encode(jsBoolean(false)); } 3118 1801 EncodedJSValue JSC_HOST_CALL functionFalse2(ExecState*) { return JSValue::encode(jsBoolean(false)); } … … 3154 1837 VM& vm = exec->vm(); 3155 1838 vm.dumpTypeProfilerData(); 3156 return JSValue::encode(jsUndefined());3157 }3158 3159 EncodedJSValue JSC_HOST_CALL functionFindTypeForExpression(ExecState* exec)3160 {3161 VM& vm = exec->vm();3162 RELEASE_ASSERT(vm.typeProfiler());3163 vm.typeProfilerLog()->processLogEntries(ASCIILiteral("jsc Testing API: functionFindTypeForExpression"));3164 3165 JSValue functionValue = exec->argument(0);3166 RELEASE_ASSERT(functionValue.isFunction());3167 FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();3168 3169 RELEASE_ASSERT(exec->argument(1).isString());3170 String substring = asString(exec->argument(1))->value(exec);3171 String sourceCodeText = executable->source().view().toString();3172 unsigned offset = static_cast<unsigned>(sourceCodeText.find(substring) + executable->source().startOffset());3173 3174 String jsonString = vm.typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorNormal, offset, executable->sourceID(), vm);3175 return JSValue::encode(JSONParse(exec, jsonString));3176 }3177 3178 EncodedJSValue JSC_HOST_CALL functionReturnTypeFor(ExecState* exec)3179 {3180 VM& vm = exec->vm();3181 RELEASE_ASSERT(vm.typeProfiler());3182 vm.typeProfilerLog()->processLogEntries(ASCIILiteral("jsc Testing API: functionReturnTypeFor"));3183 3184 JSValue functionValue = exec->argument(0);3185 RELEASE_ASSERT(functionValue.isFunction());3186 FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();3187 3188 unsigned offset = executable->typeProfilingStartOffset();3189 String jsonString = vm.typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorFunctionReturn, offset, executable->sourceID(), vm);3190 return JSValue::encode(JSONParse(exec, jsonString));3191 }3192 3193 EncodedJSValue JSC_HOST_CALL functionDumpBasicBlockExecutionRanges(ExecState* exec)3194 {3195 VM& vm = exec->vm();3196 RELEASE_ASSERT(vm.controlFlowProfiler());3197 vm.controlFlowProfiler()->dumpData();3198 return JSValue::encode(jsUndefined());3199 }3200 3201 EncodedJSValue JSC_HOST_CALL functionHasBasicBlockExecuted(ExecState* exec)3202 {3203 VM& vm = exec->vm();3204 RELEASE_ASSERT(vm.controlFlowProfiler());3205 3206 JSValue functionValue = exec->argument(0);3207 RELEASE_ASSERT(functionValue.isFunction());3208 FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();3209 3210 RELEASE_ASSERT(exec->argument(1).isString());3211 String substring = asString(exec->argument(1))->value(exec);3212 String sourceCodeText = executable->source().view().toString();3213 RELEASE_ASSERT(sourceCodeText.contains(substring));3214 int offset = sourceCodeText.find(substring) + executable->source().startOffset();3215 3216 bool hasExecuted = vm.controlFlowProfiler()->hasBasicBlockAtTextOffsetBeenExecuted(offset, executable->sourceID(), vm);3217 return JSValue::encode(jsBoolean(hasExecuted));3218 }3219 3220 EncodedJSValue JSC_HOST_CALL functionBasicBlockExecutionCount(ExecState* exec)3221 {3222 VM& vm = exec->vm();3223 RELEASE_ASSERT(vm.controlFlowProfiler());3224 3225 JSValue functionValue = exec->argument(0);3226 RELEASE_ASSERT(functionValue.isFunction());3227 FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();3228 3229 RELEASE_ASSERT(exec->argument(1).isString());3230 String substring = asString(exec->argument(1))->value(exec);3231 String sourceCodeText = executable->source().view().toString();3232 RELEASE_ASSERT(sourceCodeText.contains(substring));3233 int offset = sourceCodeText.find(substring) + executable->source().startOffset();3234 3235 size_t executionCount = vm.controlFlowProfiler()->basicBlockExecutionCountAtTextOffset(offset, executable->sourceID(), vm);3236 return JSValue::encode(JSValue(executionCount));3237 }3238 3239 EncodedJSValue JSC_HOST_CALL functionEnableExceptionFuzz(ExecState*)3240 {3241 Options::useExceptionFuzz() = true;3242 1839 return JSValue::encode(jsUndefined()); 3243 1840 } … … 3285 1882 return JSValue::encode(throwException(exec, scope, error)); 3286 1883 return JSValue::encode(jsUndefined()); 3287 }3288 3289 EncodedJSValue JSC_HOST_CALL functionCreateBuiltin(ExecState* exec)3290 {3291 VM& vm = exec->vm();3292 auto scope = DECLARE_THROW_SCOPE(vm);3293 3294 if (exec->argumentCount() < 1 || !exec->argument(0).isString())3295 return JSValue::encode(jsUndefined());3296 3297 String functionText = asString(exec->argument(0))->value(exec);3298 RETURN_IF_EXCEPTION(scope, encodedJSValue());3299 3300 const SourceCode& source = makeSource(functionText, { });3301 JSFunction* func = JSFunction::create(vm, createBuiltinExecutable(vm, source, Identifier::fromString(&vm, "foo"), ConstructorKind::None, ConstructAbility::CannotConstruct)->link(vm, source), exec->lexicalGlobalObject());3302 3303 return JSValue::encode(func);3304 1884 } 3305 1885
Note:
See TracChangeset
for help on using the changeset viewer.