Changeset 225129 in webkit for trunk/Source/JavaScriptCore/tools
- Timestamp:
- Nov 24, 2017, 2:58:16 AM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore/tools
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/tools/JSDollarVM.cpp
r224938 r225129 27 27 #include "JSDollarVM.h" 28 28 29 #include "BuiltinExecutableCreator.h" 29 30 #include "CodeBlock.h" 31 #include "DOMAttributeGetterSetter.h" 32 #include "DOMJITGetterSetter.h" 33 #include "FrameTracers.h" 30 34 #include "FunctionCodeBlock.h" 35 #include "GetterSetter.h" 36 #include "JSArray.h" 31 37 #include "JSArrayBuffer.h" 32 38 #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" 33 48 #include "VMInspector.h" 34 49 #include <wtf/Atomics.h> … … 37 52 #include <wtf/StringPrintStream.h> 38 53 54 using namespace JSC; 55 using namespace WTF; 56 57 namespace { 58 59 class ElementHandleOwner; 60 class Root; 61 62 class Element : public JSNonFinalObject { 63 public: 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 101 private: 102 WriteBarrier<Root> m_root; 103 }; 104 105 class ElementHandleOwner : public WeakHandleOwner { 106 public: 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 114 class Root : public JSDestructibleObject { 115 public: 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 155 private: 156 Weak<Element> m_element; 157 }; 158 159 class SimpleObject : public JSNonFinalObject { 160 public: 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 203 private: 204 WriteBarrier<JSC::Unknown> m_hiddenValue; 205 }; 206 207 class ImpureGetter : public JSNonFinalObject { 208 public: 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 264 private: 265 WriteBarrier<JSObject> m_delegate; 266 }; 267 268 class CustomGetter : public JSNonFinalObject { 269 public: 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 307 private: 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 339 class RuntimeArray : public JSArray { 340 public: 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 417 protected: 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 428 private: 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 448 class DOMJITNode : public JSNonFinalObject { 449 public: 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 494 private: 495 int32_t m_value { 42 }; 496 }; 497 498 class DOMJITGetter : public DOMJITNode { 499 public: 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 559 private: 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 571 static const DOMJITGetter::DOMJITAttribute DOMJITGetterDOMJIT; 572 573 void 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 581 class DOMJITGetterComplex : public DOMJITNode { 582 public: 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 654 private: 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 681 static const DOMJITGetterComplex::DOMJITAttribute DOMJITGetterComplexDOMJIT; 682 683 void 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 692 class DOMJITFunctionObject : public DOMJITNode { 693 public: 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 754 private: 755 void finishCreation(VM&, JSGlobalObject*); 756 }; 757 758 static const DOMJIT::Signature DOMJITFunctionObjectSignature((uintptr_t)DOMJITFunctionObject::unsafeFunction, DOMJITFunctionObject::info(), DOMJIT::Effect::forRead(DOMJIT::HeapRange::top()), SpecInt32Only); 759 760 void 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 766 class DOMJITCheckSubClassObject : public DOMJITNode { 767 public: 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 808 private: 809 void finishCreation(VM&, JSGlobalObject*); 810 }; 811 812 static const DOMJIT::Signature DOMJITCheckSubClassObjectSignature((uintptr_t)DOMJITCheckSubClassObject::unsafeFunction, DOMJITCheckSubClassObject::info(), DOMJIT::Effect::forRead(DOMJIT::HeapRange::top()), SpecInt32Only); 813 814 void 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 820 class DOMJITGetterBaseJSObject : public DOMJITNode { 821 public: 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 882 private: 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 894 static const DOMJITGetterBaseJSObject::DOMJITAttribute DOMJITGetterBaseJSObjectDOMJIT; 895 896 void 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 904 class Message : public ThreadSafeRefCounted<Message> { 905 public: 906 Message(ArrayBufferContents&&, int32_t); 907 ~Message(); 908 909 ArrayBufferContents&& releaseContents() { return WTFMove(m_contents); } 910 int32_t index() const { return m_index; } 911 912 private: 913 ArrayBufferContents m_contents; 914 int32_t m_index { 0 }; 915 }; 916 917 class JSTestCustomGetterSetter : public JSNonFinalObject { 918 public: 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 944 static EncodedJSValue customGetAccessor(ExecState*, EncodedJSValue thisValue, PropertyName) 945 { 946 // Passed |this| 947 return thisValue; 948 } 949 950 static 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 957 static 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 970 static 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 985 void 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 995 const ClassInfo Element::s_info = { "Element", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(Element) }; 996 const ClassInfo Root::s_info = { "Root", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(Root) }; 997 const ClassInfo SimpleObject::s_info = { "SimpleObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(SimpleObject) }; 998 const ClassInfo ImpureGetter::s_info = { "ImpureGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(ImpureGetter) }; 999 const ClassInfo CustomGetter::s_info = { "CustomGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(CustomGetter) }; 1000 const ClassInfo RuntimeArray::s_info = { "RuntimeArray", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(RuntimeArray) }; 1001 #if ENABLE(JIT) 1002 const ClassInfo DOMJITNode::s_info = { "DOMJITNode", &Base::s_info, nullptr, &DOMJITNode::checkSubClassSnippet, CREATE_METHOD_TABLE(DOMJITNode) }; 1003 #else 1004 const ClassInfo DOMJITNode::s_info = { "DOMJITNode", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITNode) }; 1005 #endif 1006 const ClassInfo DOMJITGetter::s_info = { "DOMJITGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetter) }; 1007 const ClassInfo DOMJITGetterComplex::s_info = { "DOMJITGetterComplex", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetterComplex) }; 1008 const ClassInfo DOMJITGetterBaseJSObject::s_info = { "DOMJITGetterBaseJSObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetterBaseJSObject) }; 1009 #if ENABLE(JIT) 1010 const ClassInfo DOMJITFunctionObject::s_info = { "DOMJITFunctionObject", &Base::s_info, nullptr, &DOMJITFunctionObject::checkSubClassSnippet, CREATE_METHOD_TABLE(DOMJITFunctionObject) }; 1011 #else 1012 const ClassInfo DOMJITFunctionObject::s_info = { "DOMJITFunctionObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITFunctionObject) }; 1013 #endif 1014 const ClassInfo DOMJITCheckSubClassObject::s_info = { "DOMJITCheckSubClassObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITCheckSubClassObject) }; 1015 const ClassInfo JSTestCustomGetterSetter::s_info = { "JSTestCustomGetterSetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestCustomGetterSetter) }; 1016 1017 ElementHandleOwner* Element::handleOwner() 1018 { 1019 static ElementHandleOwner* owner = 0; 1020 if (!owner) 1021 owner = new ElementHandleOwner(); 1022 return owner; 1023 } 1024 1025 void 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 39 1034 namespace JSC { 40 1035 41 1036 const 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 }48 1037 49 1038 // Triggers a crash immediately. 50 1039 // Usage: $vm.crash() 51 static EncodedJSValue JSC_HOST_CALL functionCrash(ExecState*)1040 static NO_RETURN_DUE_TO_CRASH EncodedJSValue JSC_HOST_CALL functionCrash(ExecState*) 52 1041 { 53 1042 CRASH(); 54 return JSValue::encode(jsUndefined());55 1043 } 56 1044 … … 357 1345 } 358 1346 359 void JSDollarVM::finishCreation(VM& vm, JSGlobalObject* globalObject) 1347 static 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 1360 static 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 1367 static 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 1380 static 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 1389 static 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 1398 static 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 1407 static 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 1416 static 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 1425 static 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 1434 static 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 1443 static 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 1464 static 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 1481 static 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 1488 static 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 1500 static 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 1511 static 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 1518 static 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 1532 static 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 1548 static EncodedJSValue JSC_HOST_CALL functionShadowChickenFunctionsOnStack(ExecState* exec) 1549 { 1550 VM& vm = exec->vm(); 1551 return JSValue::encode(vm.shadowChicken().functionsOnStack(exec)); 1552 } 1553 1554 static EncodedJSValue JSC_HOST_CALL functionSetGlobalConstRedeclarationShouldNotThrow(ExecState* exec) 1555 { 1556 VM& vm = exec->vm(); 1557 vm.setGlobalConstRedeclarationShouldThrow(false); 1558 return JSValue::encode(jsUndefined()); 1559 } 1560 1561 static 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 1580 static 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 1595 static 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 1603 static 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 1622 static 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 1641 static EncodedJSValue JSC_HOST_CALL functionEnableExceptionFuzz(ExecState*) 1642 { 1643 Options::useExceptionFuzz() = true; 1644 return JSValue::encode(jsUndefined()); 1645 } 1646 1647 static 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 1656 static 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 1678 static 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 1694 static 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 1701 void JSDollarVM::finishCreation(VM& vm) 360 1702 { 361 1703 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 365 1717 putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "dfgTrue"), 0, functionDFGTrue, DFGTrueIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum)); 366 1718 … … 369 1721 putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "cpuCpuid"), 0, functionCpuCpuid, CPUCpuidIntrinsic, 0); 370 1722 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 1784 void 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 1790 void 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)); 390 1794 } 391 1795 -
trunk/Source/JavaScriptCore/tools/JSDollarVM.h
r224838 r225129 41 41 } 42 42 43 static JSDollarVM* create(VM& vm, JSGlobalObject* globalObject,Structure* structure)43 static JSDollarVM* create(VM& vm, Structure* structure) 44 44 { 45 45 JSDollarVM* instance = new (NotNull, allocateCell<JSDollarVM>(vm.heap)) JSDollarVM(vm, structure); 46 instance->finishCreation(vm , globalObject);46 instance->finishCreation(vm); 47 47 return instance; 48 48 } … … 54 54 } 55 55 56 void finishCreation(VM& , JSGlobalObject*);56 void finishCreation(VM&); 57 57 void addFunction(VM&, JSGlobalObject*, const char* name, NativeFunction, unsigned arguments); 58 void addConstructibleFunction(VM&, JSGlobalObject*, const char* name, NativeFunction, unsigned arguments); 58 59 }; 59 60
Note:
See TracChangeset
for help on using the changeset viewer.