Add a way to mark a rejected promise as handled
[WebKit-https.git] / Source / JavaScriptCore / tools / JSDollarVM.cpp
1 /*
2  * Copyright (C) 2015-2019 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "JSDollarVM.h"
28
29 #include "BuiltinExecutableCreator.h"
30 #include "BuiltinNames.h"
31 #include "CodeBlock.h"
32 #include "DOMAttributeGetterSetter.h"
33 #include "DOMJITGetterSetter.h"
34 #include "Debugger.h"
35 #include "Error.h"
36 #include "FrameTracers.h"
37 #include "FunctionCodeBlock.h"
38 #include "GetterSetter.h"
39 #include "JSArray.h"
40 #include "JSArrayBuffer.h"
41 #include "JSCInlines.h"
42 #include "JSFunction.h"
43 #include "JSONObject.h"
44 #include "JSProxy.h"
45 #include "JSString.h"
46 #include "Options.h"
47 #include "Parser.h"
48 #include "ProbeContext.h"
49 #include "ShadowChicken.h"
50 #include "Snippet.h"
51 #include "SnippetParams.h"
52 #include "TypeProfiler.h"
53 #include "TypeProfilerLog.h"
54 #include "VMInspector.h"
55 #include "WasmCapabilities.h"
56 #include <wtf/Atomics.h>
57 #include <wtf/CPUTime.h>
58 #include <wtf/DataLog.h>
59 #include <wtf/ProcessID.h>
60 #include <wtf/StringPrintStream.h>
61
62 #if ENABLE(WEBASSEMBLY)
63 #include "JSWebAssemblyHelpers.h"
64 #include "WasmStreamingParser.h"
65 #endif
66
67 using namespace JSC;
68
69 IGNORE_WARNINGS_BEGIN("frame-address")
70
71 extern "C" void ctiMasmProbeTrampoline();
72
73 namespace JSC {
74
75 // This class is only here as a simple way to grant JSDollarVM friend privileges
76 // to all the classes that it needs special access to.
77 class JSDollarVMHelper {
78 public:
79     JSDollarVMHelper(VM& vm)
80         : m_vm(vm)
81     { }
82
83     void updateVMStackLimits() { return m_vm.updateStackLimits(); };
84
85     static EncodedJSValue JSC_HOST_CALL functionGetStructureTransitionList(JSGlobalObject*, CallFrame*);
86
87 private:
88     VM& m_vm;
89 };
90
91 } // namespace JSC
92
93 namespace {
94
95 // We must RELEASE_ASSERT(Options::useDollarVM()) in all JSDollarVM functions
96 // that are non-trivial at an eye's glance. This includes (but is not limited to):
97 //      constructors
98 //      create() factory
99 //      createStructure() factory
100 //      finishCreation()
101 //      HOST_CALL or operation functions
102 //      Constructors and methods of utility and test classes
103 //      lambda functions
104 //
105 // The way to do this RELEASE_ASSERT is with the DollarVMAssertScope below.
106 //
107 // The only exception are some constexpr constructors used for instantiating
108 // globals (since these must have trivial constructors) e.g. DOMJITAttribute.
109 // Instead, these constructors should always be ALWAYS_INLINE.
110
111 class JSDollarVMCallFrame : public JSNonFinalObject {
112     using Base = JSNonFinalObject;
113 public:
114     template<typename CellType, SubspaceAccess>
115     static CompleteSubspace* subspaceFor(VM& vm)
116     {
117         return &vm.cellSpace;
118     }
119
120     JSDollarVMCallFrame(VM& vm, Structure* structure)
121         : Base(vm, structure)
122     {
123         DollarVMAssertScope assertScope;
124     }
125
126     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
127     {
128         DollarVMAssertScope assertScope;
129         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
130     }
131
132     static JSDollarVMCallFrame* create(JSGlobalObject* globalObject, CallFrame* callFrame, unsigned requestedFrameIndex)
133     {
134         DollarVMAssertScope assertScope;
135         VM& vm = globalObject->vm();
136         Structure* structure = createStructure(vm, globalObject, jsNull());
137         JSDollarVMCallFrame* frame = new (NotNull, allocateCell<JSDollarVMCallFrame>(vm.heap)) JSDollarVMCallFrame(vm, structure);
138         frame->finishCreation(vm, callFrame, requestedFrameIndex);
139         return frame;
140     }
141
142     void finishCreation(VM& vm, CallFrame* callFrame, unsigned requestedFrameIndex)
143     {
144         DollarVMAssertScope assertScope;
145         Base::finishCreation(vm);
146
147         auto addProperty = [&] (VM& vm, const char* name, JSValue value) {
148             DollarVMAssertScope assertScope;
149             JSDollarVMCallFrame::addProperty(vm, name, value);
150         };
151
152         unsigned frameIndex = 0;
153         bool isValid = false;
154         callFrame->iterate(vm, [&] (StackVisitor& visitor) {
155             DollarVMAssertScope assertScope;
156
157             if (frameIndex++ != requestedFrameIndex)
158                 return StackVisitor::Continue;
159
160             addProperty(vm, "name", jsString(vm, visitor->functionName()));
161
162             if (visitor->callee().isCell())
163                 addProperty(vm, "callee", visitor->callee().asCell());
164
165             CodeBlock* codeBlock = visitor->codeBlock();
166             if (codeBlock) {
167                 addProperty(vm, "codeBlock", codeBlock);
168                 addProperty(vm, "unlinkedCodeBlock", codeBlock->unlinkedCodeBlock());
169                 addProperty(vm, "executable", codeBlock->ownerExecutable());
170             }
171             isValid = true;
172
173             return StackVisitor::Done;
174         });
175
176         addProperty(vm, "valid", jsBoolean(isValid));
177     }
178
179     DECLARE_INFO;
180
181 private:
182     void addProperty(VM& vm, const char* name, JSValue value)
183     {
184         DollarVMAssertScope assertScope;
185         Identifier identifier = Identifier::fromString(vm, name);
186         putDirect(vm, identifier, value);
187     }
188 };
189
190 const ClassInfo JSDollarVMCallFrame::s_info = { "CallFrame", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDollarVMCallFrame) };
191
192 class ElementHandleOwner;
193 class Root;
194
195 class Element : public JSNonFinalObject {
196 public:
197     Element(VM& vm, Structure* structure)
198         : Base(vm, structure)
199     {
200         DollarVMAssertScope assertScope;
201     }
202
203     typedef JSNonFinalObject Base;
204     template<typename CellType, SubspaceAccess>
205     static CompleteSubspace* subspaceFor(VM& vm)
206     {
207         return &vm.cellSpace;
208     }
209
210     Root* root() const { return m_root.get(); }
211     void setRoot(VM& vm, Root* root) { m_root.set(vm, this, root); }
212
213     static Element* create(VM& vm, JSGlobalObject* globalObject, Root* root)
214     {
215         DollarVMAssertScope assertScope;
216         Structure* structure = createStructure(vm, globalObject, jsNull());
217         Element* element = new (NotNull, allocateCell<Element>(vm.heap)) Element(vm, structure);
218         element->finishCreation(vm, root);
219         return element;
220     }
221
222     void finishCreation(VM&, Root*);
223
224     static void visitChildren(JSCell* cell, SlotVisitor& visitor)
225     {
226         DollarVMAssertScope assertScope;
227         Element* thisObject = jsCast<Element*>(cell);
228         ASSERT_GC_OBJECT_INHERITS(thisObject, info());
229         Base::visitChildren(thisObject, visitor);
230         visitor.append(thisObject->m_root);
231     }
232
233     static ElementHandleOwner* handleOwner();
234
235     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
236     {
237         DollarVMAssertScope assertScope;
238         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
239     }
240
241     DECLARE_INFO;
242
243 private:
244     WriteBarrier<Root> m_root;
245 };
246
247 class ElementHandleOwner : public WeakHandleOwner {
248     WTF_MAKE_FAST_ALLOCATED;
249 public:
250     bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason) override
251     {
252         DollarVMAssertScope assertScope;
253         if (UNLIKELY(reason))
254             *reason = "JSC::Element is opaque root";
255         Element* element = jsCast<Element*>(handle.slot()->asCell());
256         return visitor.containsOpaqueRoot(element->root());
257     }
258 };
259
260 class Root : public JSDestructibleObject {
261 public:
262     using Base = JSDestructibleObject;
263     template<typename CellType, SubspaceAccess>
264     static CompleteSubspace* subspaceFor(VM& vm)
265     {
266         return &vm.destructibleObjectSpace;
267     }
268
269     Root(VM& vm, Structure* structure)
270         : Base(vm, structure)
271     {
272         DollarVMAssertScope assertScope;
273     }
274
275     Element* element()
276     {
277         return m_element.get();
278     }
279
280     void setElement(Element* element)
281     {
282         DollarVMAssertScope assertScope;
283         Weak<Element> newElement(element, Element::handleOwner());
284         m_element.swap(newElement);
285     }
286
287     static Root* create(VM& vm, JSGlobalObject* globalObject)
288     {
289         DollarVMAssertScope assertScope;
290         Structure* structure = createStructure(vm, globalObject, jsNull());
291         Root* root = new (NotNull, allocateCell<Root>(vm.heap)) Root(vm, structure);
292         root->finishCreation(vm);
293         return root;
294     }
295
296     DECLARE_INFO;
297
298     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
299     {
300         DollarVMAssertScope assertScope;
301         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
302     }
303
304     static void visitChildren(JSCell* thisObject, SlotVisitor& visitor)
305     {
306         DollarVMAssertScope assertScope;
307         ASSERT_GC_OBJECT_INHERITS(thisObject, info());
308         Base::visitChildren(thisObject, visitor);
309         visitor.addOpaqueRoot(thisObject);
310     }
311
312 private:
313     Weak<Element> m_element;
314 };
315
316 class SimpleObject : public JSNonFinalObject {
317 public:
318     SimpleObject(VM& vm, Structure* structure)
319         : Base(vm, structure)
320     {
321         DollarVMAssertScope assertScope;
322     }
323
324     typedef JSNonFinalObject Base;
325     static constexpr bool needsDestruction = false;
326     template<typename CellType, SubspaceAccess>
327     static CompleteSubspace* subspaceFor(VM& vm)
328     {
329         return &vm.cellSpace;
330     }
331
332     static SimpleObject* create(VM& vm, JSGlobalObject* globalObject)
333     {
334         DollarVMAssertScope assertScope;
335         Structure* structure = createStructure(vm, globalObject, jsNull());
336         SimpleObject* simpleObject = new (NotNull, allocateCell<SimpleObject>(vm.heap)) SimpleObject(vm, structure);
337         simpleObject->finishCreation(vm);
338         return simpleObject;
339     }
340
341     static void visitChildren(JSCell* cell, SlotVisitor& visitor)
342     {
343         DollarVMAssertScope assertScope;
344         SimpleObject* thisObject = jsCast<SimpleObject*>(cell);
345         ASSERT_GC_OBJECT_INHERITS(thisObject, info());
346         Base::visitChildren(thisObject, visitor);
347         visitor.append(thisObject->m_hiddenValue);
348     }
349
350     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
351     {
352         DollarVMAssertScope assertScope;
353         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
354     }
355
356     JSValue hiddenValue()
357     {
358         return m_hiddenValue.get();
359     }
360
361     void setHiddenValue(VM& vm, JSValue value)
362     {
363         ASSERT(value.isCell());
364         m_hiddenValue.set(vm, this, value);
365     }
366
367     DECLARE_INFO;
368
369 private:
370     WriteBarrier<JSC::Unknown> m_hiddenValue;
371 };
372
373 class ImpureGetter : public JSNonFinalObject {
374 public:
375     ImpureGetter(VM& vm, Structure* structure)
376         : Base(vm, structure)
377     {
378         DollarVMAssertScope assertScope;
379     }
380
381     DECLARE_INFO;
382     typedef JSNonFinalObject Base;
383     static constexpr unsigned StructureFlags = Base::StructureFlags | JSC::GetOwnPropertySlotIsImpure | JSC::OverridesGetOwnPropertySlot;
384
385     template<typename CellType, SubspaceAccess>
386     static CompleteSubspace* subspaceFor(VM& vm)
387     {
388         return &vm.cellSpace;
389     }
390
391     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
392     {
393         DollarVMAssertScope assertScope;
394         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
395     }
396
397     static ImpureGetter* create(VM& vm, Structure* structure, JSObject* delegate)
398     {
399         DollarVMAssertScope assertScope;
400         ImpureGetter* getter = new (NotNull, allocateCell<ImpureGetter>(vm.heap)) ImpureGetter(vm, structure);
401         getter->finishCreation(vm, delegate);
402         return getter;
403     }
404
405     void finishCreation(VM& vm, JSObject* delegate)
406     {
407         DollarVMAssertScope assertScope;
408         Base::finishCreation(vm);
409         if (delegate)
410             m_delegate.set(vm, this, delegate);
411     }
412
413     static bool getOwnPropertySlot(JSObject* object, JSGlobalObject* globalObject, PropertyName name, PropertySlot& slot)
414     {
415         DollarVMAssertScope assertScope;
416         VM& vm = globalObject->vm();
417         auto scope = DECLARE_THROW_SCOPE(vm);
418         ImpureGetter* thisObject = jsCast<ImpureGetter*>(object);
419         
420         if (thisObject->m_delegate) {
421             if (thisObject->m_delegate->getPropertySlot(globalObject, name, slot))
422                 return true;
423             RETURN_IF_EXCEPTION(scope, false);
424         }
425
426         return Base::getOwnPropertySlot(object, globalObject, name, slot);
427     }
428
429     static void visitChildren(JSCell* cell, SlotVisitor& visitor)
430     {
431         DollarVMAssertScope assertScope;
432         ASSERT_GC_OBJECT_INHERITS(cell, info());
433         Base::visitChildren(cell, visitor);
434         ImpureGetter* thisObject = jsCast<ImpureGetter*>(cell);
435         visitor.append(thisObject->m_delegate);
436     }
437
438     void setDelegate(VM& vm, JSObject* delegate)
439     {
440         m_delegate.set(vm, this, delegate);
441     }
442
443 private:
444     WriteBarrier<JSObject> m_delegate;
445 };
446
447 class CustomGetter : public JSNonFinalObject {
448 public:
449     CustomGetter(VM& vm, Structure* structure)
450         : Base(vm, structure)
451     {
452         DollarVMAssertScope assertScope;
453     }
454
455     DECLARE_INFO;
456     typedef JSNonFinalObject Base;
457     static constexpr unsigned StructureFlags = Base::StructureFlags | JSC::OverridesGetOwnPropertySlot;
458
459     template<typename CellType, SubspaceAccess>
460     static CompleteSubspace* subspaceFor(VM& vm)
461     {
462         return &vm.cellSpace;
463     }
464
465     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
466     {
467         DollarVMAssertScope assertScope;
468         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
469     }
470
471     static CustomGetter* create(VM& vm, Structure* structure)
472     {
473         DollarVMAssertScope assertScope;
474         CustomGetter* getter = new (NotNull, allocateCell<CustomGetter>(vm.heap)) CustomGetter(vm, structure);
475         getter->finishCreation(vm);
476         return getter;
477     }
478
479     static bool getOwnPropertySlot(JSObject* object, JSGlobalObject* globalObject, PropertyName propertyName, PropertySlot& slot)
480     {
481         DollarVMAssertScope assertScope;
482         VM& vm = globalObject->vm();
483         CustomGetter* thisObject = jsCast<CustomGetter*>(object);
484         if (propertyName == PropertyName(Identifier::fromString(vm, "customGetter"))) {
485             slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum, thisObject->customGetter);
486             return true;
487         }
488         
489         if (propertyName == PropertyName(Identifier::fromString(vm, "customGetterAccessor"))) {
490             slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::CustomAccessor, thisObject->customGetterAcessor);
491             return true;
492         }
493         
494         return JSObject::getOwnPropertySlot(thisObject, globalObject, propertyName, slot);
495     }
496
497 private:
498     static EncodedJSValue customGetter(JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName)
499     {
500         DollarVMAssertScope assertScope;
501         VM& vm = globalObject->vm();
502         auto scope = DECLARE_THROW_SCOPE(vm);
503
504         CustomGetter* thisObject = jsDynamicCast<CustomGetter*>(vm, JSValue::decode(thisValue));
505         if (!thisObject)
506             return throwVMTypeError(globalObject, scope);
507         bool shouldThrow = thisObject->get(globalObject, PropertyName(Identifier::fromString(vm, "shouldThrow"))).toBoolean(globalObject);
508         RETURN_IF_EXCEPTION(scope, encodedJSValue());
509         if (shouldThrow)
510             return throwVMTypeError(globalObject, scope);
511         return JSValue::encode(jsNumber(100));
512     }
513     
514     static EncodedJSValue customGetterAcessor(JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName)
515     {
516         DollarVMAssertScope assertScope;
517         VM& vm = globalObject->vm();
518         auto scope = DECLARE_THROW_SCOPE(vm);
519         
520         JSObject* thisObject = jsDynamicCast<JSObject*>(vm, JSValue::decode(thisValue));
521         if (!thisObject)
522             return throwVMTypeError(globalObject, scope);
523         bool shouldThrow = thisObject->get(globalObject, PropertyName(Identifier::fromString(vm, "shouldThrow"))).toBoolean(globalObject);
524         RETURN_IF_EXCEPTION(scope, encodedJSValue());
525         if (shouldThrow)
526             return throwVMTypeError(globalObject, scope);
527         return JSValue::encode(jsNumber(100));
528     }
529 };
530
531 class RuntimeArray : public JSArray {
532 public:
533     typedef JSArray Base;
534     static constexpr unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames;
535
536     template<typename CellType, SubspaceAccess>
537     static CompleteSubspace* subspaceFor(VM& vm)
538     {
539         return &vm.cellSpace;
540     }
541
542     static RuntimeArray* create(JSGlobalObject* globalObject, CallFrame* callFrame)
543     {
544         DollarVMAssertScope assertScope;
545         VM& vm = globalObject->vm();
546         Structure* structure = createStructure(vm, globalObject, createPrototype(vm, globalObject));
547         RuntimeArray* runtimeArray = new (NotNull, allocateCell<RuntimeArray>(vm.heap)) RuntimeArray(globalObject, structure);
548         runtimeArray->finishCreation(globalObject, callFrame);
549         vm.heap.addFinalizer(runtimeArray, destroy);
550         return runtimeArray;
551     }
552
553     ~RuntimeArray() { }
554
555     static void destroy(JSCell* cell)
556     {
557         DollarVMAssertScope assertScope;
558         static_cast<RuntimeArray*>(cell)->RuntimeArray::~RuntimeArray();
559     }
560
561     static constexpr bool needsDestruction = false;
562
563     static bool getOwnPropertySlot(JSObject* object, JSGlobalObject* globalObject, PropertyName propertyName, PropertySlot& slot)
564     {
565         DollarVMAssertScope assertScope;
566         VM& vm = globalObject->vm();
567         RuntimeArray* thisObject = jsCast<RuntimeArray*>(object);
568         if (propertyName == vm.propertyNames->length) {
569             slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum, thisObject->lengthGetter);
570             return true;
571         }
572
573         Optional<uint32_t> index = parseIndex(propertyName);
574         if (index && index.value() < thisObject->getLength()) {
575             slot.setValue(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::DontEnum, jsNumber(thisObject->m_vector[index.value()]));
576             return true;
577         }
578
579         return JSObject::getOwnPropertySlot(thisObject, globalObject, propertyName, slot);
580     }
581
582     static bool getOwnPropertySlotByIndex(JSObject* object, JSGlobalObject* globalObject, unsigned index, PropertySlot& slot)
583     {
584         DollarVMAssertScope assertScope;
585         RuntimeArray* thisObject = jsCast<RuntimeArray*>(object);
586         if (index < thisObject->getLength()) {
587             slot.setValue(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::DontEnum, jsNumber(thisObject->m_vector[index]));
588             return true;
589         }
590
591         return JSObject::getOwnPropertySlotByIndex(thisObject, globalObject, index, slot);
592     }
593
594     static NO_RETURN_DUE_TO_CRASH bool put(JSCell*, JSGlobalObject*, PropertyName, JSValue, PutPropertySlot&)
595     {
596         RELEASE_ASSERT_NOT_REACHED();
597     }
598
599     static NO_RETURN_DUE_TO_CRASH bool deleteProperty(JSCell*, JSGlobalObject*, PropertyName, DeletePropertySlot&)
600     {
601         RELEASE_ASSERT_NOT_REACHED();
602     }
603
604     unsigned getLength() const { return m_vector.size(); }
605
606     DECLARE_INFO;
607
608     static ArrayPrototype* createPrototype(VM&, JSGlobalObject* globalObject)
609     {
610         DollarVMAssertScope assertScope;
611         return globalObject->arrayPrototype();
612     }
613
614     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
615     {
616         DollarVMAssertScope assertScope;
617         return Structure::create(vm, globalObject, prototype, TypeInfo(DerivedArrayType, StructureFlags), info(), ArrayClass);
618     }
619
620 protected:
621     void finishCreation(JSGlobalObject* globalObject, CallFrame* callFrame)
622     {
623         DollarVMAssertScope assertScope;
624         VM& vm = globalObject->vm();
625         Base::finishCreation(vm);
626         ASSERT(inherits(vm, info()));
627
628         for (size_t i = 0; i < callFrame->argumentCount(); i++)
629             m_vector.append(callFrame->argument(i).toInt32(globalObject));
630     }
631
632 private:
633     RuntimeArray(JSGlobalObject* globalObject, Structure* structure)
634         : JSArray(globalObject->vm(), structure, 0)
635     {
636         DollarVMAssertScope assertScope;
637     }
638
639     static EncodedJSValue lengthGetter(JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName)
640     {
641         DollarVMAssertScope assertScope;
642         VM& vm = globalObject->vm();
643         auto scope = DECLARE_THROW_SCOPE(vm);
644
645         RuntimeArray* thisObject = jsDynamicCast<RuntimeArray*>(vm, JSValue::decode(thisValue));
646         if (!thisObject)
647             return throwVMTypeError(globalObject, scope);
648         return JSValue::encode(jsNumber(thisObject->getLength()));
649     }
650
651     Vector<int> m_vector;
652 };
653
654 static const struct CompactHashIndex staticCustomAccessorTableIndex[2] = {
655     { 0, -1 },
656     { -1, -1 },
657 };
658
659 static EncodedJSValue testStaticAccessorGetter(JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName)
660 {
661     DollarVMAssertScope assertScope;
662     VM& vm = globalObject->vm();
663     
664     JSObject* thisObject = jsDynamicCast<JSObject*>(vm, JSValue::decode(thisValue));
665     RELEASE_ASSERT(thisObject);
666
667     if (JSValue result = thisObject->getDirect(vm, PropertyName(Identifier::fromString(vm, "testField"))))
668         return JSValue::encode(result);
669     return JSValue::encode(jsUndefined());
670 }
671
672 static bool testStaticAccessorPutter(JSGlobalObject* globalObject, EncodedJSValue thisValue, EncodedJSValue value)
673 {
674     DollarVMAssertScope assertScope;
675     VM& vm = globalObject->vm();
676     
677     JSObject* thisObject = jsDynamicCast<JSObject*>(vm, JSValue::decode(thisValue));
678     RELEASE_ASSERT(thisObject);
679
680     return thisObject->putDirect(vm, PropertyName(Identifier::fromString(vm, "testField")), JSValue::decode(value));
681 }
682
683 static const struct HashTableValue staticCustomAccessorTableValues[1] = {
684     { "testStaticAccessor", static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(testStaticAccessorGetter), (intptr_t)static_cast<PutPropertySlot::PutValueFunc>(testStaticAccessorPutter) } },
685 };
686
687 static const struct HashTable staticCustomAccessorTable =
688     { 1, 1, true, nullptr, staticCustomAccessorTableValues, staticCustomAccessorTableIndex };
689
690 class StaticCustomAccessor : public JSNonFinalObject {
691     using Base = JSNonFinalObject;
692 public:
693     StaticCustomAccessor(VM& vm, Structure* structure)
694         : Base(vm, structure)
695     {
696         DollarVMAssertScope assertScope;
697     }
698
699     DECLARE_INFO;
700
701     static constexpr unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable | OverridesGetOwnPropertySlot;
702
703     template<typename CellType, SubspaceAccess>
704     static CompleteSubspace* subspaceFor(VM& vm)
705     {
706         return &vm.cellSpace;
707     }
708
709     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
710     {
711         DollarVMAssertScope assertScope;
712         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
713     }
714
715     static StaticCustomAccessor* create(VM& vm, Structure* structure)
716     {
717         DollarVMAssertScope assertScope;
718         StaticCustomAccessor* accessor = new (NotNull, allocateCell<StaticCustomAccessor>(vm.heap)) StaticCustomAccessor(vm, structure);
719         accessor->finishCreation(vm);
720         return accessor;
721     }
722
723     static bool getOwnPropertySlot(JSObject* thisObject, JSGlobalObject* globalObject, PropertyName propertyName, PropertySlot& slot)
724     {
725         if (String(propertyName.uid()) == "thinAirCustomGetter") {
726             slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::CustomAccessor, testStaticAccessorGetter);
727             return true;
728         }
729         return JSNonFinalObject::getOwnPropertySlot(thisObject, globalObject, propertyName, slot);
730     }
731 };
732
733 class ObjectDoingSideEffectPutWithoutCorrectSlotStatus : public JSNonFinalObject {
734     using Base = JSNonFinalObject;
735 public:
736     template<typename CellType, SubspaceAccess>
737     static CompleteSubspace* subspaceFor(VM& vm)
738     {
739         return &vm.cellSpace;
740     }
741
742     ObjectDoingSideEffectPutWithoutCorrectSlotStatus(VM& vm, Structure* structure)
743         : Base(vm, structure)
744     {
745         DollarVMAssertScope assertScope;
746     }
747
748     DECLARE_INFO;
749
750     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
751     {
752         DollarVMAssertScope assertScope;
753         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
754     }
755
756     static ObjectDoingSideEffectPutWithoutCorrectSlotStatus* create(VM& vm, Structure* structure)
757     {
758         DollarVMAssertScope assertScope;
759         ObjectDoingSideEffectPutWithoutCorrectSlotStatus* accessor = new (NotNull, allocateCell<ObjectDoingSideEffectPutWithoutCorrectSlotStatus>(vm.heap)) ObjectDoingSideEffectPutWithoutCorrectSlotStatus(vm, structure);
760         accessor->finishCreation(vm);
761         return accessor;
762     }
763
764     static bool put(JSCell* cell, JSGlobalObject* globalObject, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
765     {
766         DollarVMAssertScope assertScope;
767         auto* thisObject = jsCast<ObjectDoingSideEffectPutWithoutCorrectSlotStatus*>(cell);
768         auto throwScope = DECLARE_THROW_SCOPE(globalObject->vm());
769         auto* string = value.toString(globalObject);
770         RETURN_IF_EXCEPTION(throwScope, false);
771         RELEASE_AND_RETURN(throwScope, Base::put(thisObject, globalObject, propertyName, string, slot));
772     }
773 };
774
775 class DOMJITNode : public JSNonFinalObject {
776 public:
777     DOMJITNode(VM& vm, Structure* structure)
778         : Base(vm, structure)
779     {
780         DollarVMAssertScope assertScope;
781     }
782
783     DECLARE_INFO;
784     typedef JSNonFinalObject Base;
785     static constexpr unsigned StructureFlags = Base::StructureFlags;
786
787     template<typename CellType, SubspaceAccess>
788     static CompleteSubspace* subspaceFor(VM& vm)
789     {
790         return &vm.cellSpace;
791     }
792
793     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
794     {
795         DollarVMAssertScope assertScope;
796         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
797     }
798
799 #if ENABLE(JIT)
800     static Ref<Snippet> checkSubClassSnippet()
801     {
802         DollarVMAssertScope assertScope;
803         Ref<Snippet> snippet = Snippet::create();
804         snippet->setGenerator([=] (CCallHelpers& jit, SnippetParams& params) {
805             DollarVMAssertScope assertScope;
806             CCallHelpers::JumpList failureCases;
807             failureCases.append(jit.branchIfNotType(params[0].gpr(), JSC::JSType(LastJSCObjectType + 1)));
808             return failureCases;
809         });
810         return snippet;
811     }
812 #endif
813
814     static DOMJITNode* create(VM& vm, Structure* structure)
815     {
816         DollarVMAssertScope assertScope;
817         DOMJITNode* getter = new (NotNull, allocateCell<DOMJITNode>(vm.heap)) DOMJITNode(vm, structure);
818         getter->finishCreation(vm);
819         return getter;
820     }
821
822     int32_t value() const
823     {
824         return m_value;
825     }
826
827     static ptrdiff_t offsetOfValue() { return OBJECT_OFFSETOF(DOMJITNode, m_value); }
828
829 private:
830     int32_t m_value { 42 };
831 };
832
833 class DOMJITGetter : public DOMJITNode {
834 public:
835     DOMJITGetter(VM& vm, Structure* structure)
836         : Base(vm, structure)
837     {
838         DollarVMAssertScope assertScope;
839     }
840
841     DECLARE_INFO;
842     typedef DOMJITNode Base;
843     static constexpr unsigned StructureFlags = Base::StructureFlags;
844
845     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
846     {
847         DollarVMAssertScope assertScope;
848         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
849     }
850
851     static DOMJITGetter* create(VM& vm, Structure* structure)
852     {
853         DollarVMAssertScope assertScope;
854         DOMJITGetter* getter = new (NotNull, allocateCell<DOMJITGetter>(vm.heap)) DOMJITGetter(vm, structure);
855         getter->finishCreation(vm);
856         return getter;
857     }
858
859     class DOMJITAttribute : public DOMJIT::GetterSetter {
860     public:
861         ALWAYS_INLINE constexpr DOMJITAttribute()
862             : DOMJIT::GetterSetter(
863                 DOMJITGetter::customGetter,
864 #if ENABLE(JIT)
865                 &callDOMGetter,
866 #else
867                 nullptr,
868 #endif
869                 SpecInt32Only)
870         {
871         }
872
873 #if ENABLE(JIT)
874         static EncodedJSValue JIT_OPERATION slowCall(JSGlobalObject* globalObject, void* pointer)
875         {
876             DollarVMAssertScope assertScope;
877             VM& vm = globalObject->vm();
878             CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
879             JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
880             return JSValue::encode(jsNumber(static_cast<DOMJITGetter*>(pointer)->value()));
881         }
882
883         static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()
884         {
885             DollarVMAssertScope assertScope;
886             Ref<DOMJIT::CallDOMGetterSnippet> snippet = DOMJIT::CallDOMGetterSnippet::create();
887             snippet->requireGlobalObject = true;
888             snippet->setGenerator([=] (CCallHelpers& jit, SnippetParams& params) {
889                 DollarVMAssertScope assertScope;
890                 JSValueRegs results = params[0].jsValueRegs();
891                 GPRReg domGPR = params[1].gpr();
892                 GPRReg globalObjectGPR = params[2].gpr();
893                 params.addSlowPathCall(jit.jump(), jit, slowCall, results, globalObjectGPR, domGPR);
894                 return CCallHelpers::JumpList();
895
896             });
897             return snippet;
898         }
899 #endif
900     };
901
902 private:
903     void finishCreation(VM&);
904
905     static EncodedJSValue customGetter(JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName)
906     {
907         DollarVMAssertScope assertScope;
908         VM& vm = globalObject->vm();
909         DOMJITNode* thisObject = jsDynamicCast<DOMJITNode*>(vm, JSValue::decode(thisValue));
910         ASSERT(thisObject);
911         return JSValue::encode(jsNumber(thisObject->value()));
912     }
913 };
914
915 static const DOMJITGetter::DOMJITAttribute DOMJITGetterDOMJIT;
916
917 void DOMJITGetter::finishCreation(VM& vm)
918 {
919     DollarVMAssertScope assertScope;
920     Base::finishCreation(vm);
921     const DOMJIT::GetterSetter* domJIT = &DOMJITGetterDOMJIT;
922     auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJIT->getter(), nullptr, DOMAttributeAnnotation { DOMJITNode::info(), domJIT });
923     putDirectCustomAccessor(vm, Identifier::fromString(vm, "customGetter"), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);
924 }
925
926
927 class DOMJITGetterComplex : public DOMJITNode {
928 public:
929     DOMJITGetterComplex(VM& vm, Structure* structure)
930         : Base(vm, structure)
931     {
932         DollarVMAssertScope assertScope;
933     }
934
935     DECLARE_INFO;
936     typedef DOMJITNode Base;
937     static constexpr unsigned StructureFlags = Base::StructureFlags;
938
939     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
940     {
941         DollarVMAssertScope assertScope;
942         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
943     }
944
945     static DOMJITGetterComplex* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
946     {
947         DollarVMAssertScope assertScope;
948         DOMJITGetterComplex* getter = new (NotNull, allocateCell<DOMJITGetterComplex>(vm.heap)) DOMJITGetterComplex(vm, structure);
949         getter->finishCreation(vm, globalObject);
950         return getter;
951     }
952
953     class DOMJITAttribute : public DOMJIT::GetterSetter {
954     public:
955         ALWAYS_INLINE constexpr DOMJITAttribute()
956             : DOMJIT::GetterSetter(
957                 DOMJITGetterComplex::customGetter,
958 #if ENABLE(JIT)
959                 &callDOMGetter,
960 #else
961                 nullptr,
962 #endif
963                 SpecInt32Only)
964         {
965         }
966
967 #if ENABLE(JIT)
968         static EncodedJSValue JIT_OPERATION slowCall(JSGlobalObject* globalObject, void* pointer)
969         {
970             DollarVMAssertScope assertScope;
971             VM& vm = globalObject->vm();
972             CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
973             JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
974             auto scope = DECLARE_THROW_SCOPE(vm);
975             auto* object = static_cast<DOMJITNode*>(pointer);
976             auto* domjitGetterComplex = jsDynamicCast<DOMJITGetterComplex*>(vm, object);
977             if (domjitGetterComplex) {
978                 if (domjitGetterComplex->m_enableException)
979                     return JSValue::encode(throwException(globalObject, scope, createError(globalObject, "DOMJITGetterComplex slow call exception"_s)));
980             }
981             return JSValue::encode(jsNumber(object->value()));
982         }
983
984         static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()
985         {
986             DollarVMAssertScope assertScope;
987             Ref<DOMJIT::CallDOMGetterSnippet> snippet = DOMJIT::CallDOMGetterSnippet::create();
988             static_assert(GPRInfo::numberOfRegisters >= 4, "Number of registers should be larger or equal to 4.");
989             unsigned numGPScratchRegisters = GPRInfo::numberOfRegisters - 4;
990             snippet->numGPScratchRegisters = numGPScratchRegisters;
991             snippet->numFPScratchRegisters = 3;
992             snippet->requireGlobalObject = true;
993             snippet->setGenerator([=] (CCallHelpers& jit, SnippetParams& params) {
994                 DollarVMAssertScope assertScope;
995                 JSValueRegs results = params[0].jsValueRegs();
996                 GPRReg domGPR = params[1].gpr();
997                 GPRReg globalObjectGPR = params[2].gpr();
998                 for (unsigned i = 0; i < numGPScratchRegisters; ++i)
999                     jit.move(CCallHelpers::TrustedImm32(42), params.gpScratch(i));
1000
1001                 params.addSlowPathCall(jit.jump(), jit, slowCall, results, globalObjectGPR, domGPR);
1002                 return CCallHelpers::JumpList();
1003             });
1004             return snippet;
1005         }
1006 #endif
1007     };
1008
1009 private:
1010     void finishCreation(VM&, JSGlobalObject*);
1011
1012     static EncodedJSValue JSC_HOST_CALL functionEnableException(JSGlobalObject* globalObject, CallFrame* callFrame)
1013     {
1014         DollarVMAssertScope assertScope;
1015         VM& vm = globalObject->vm();
1016         auto* object = jsDynamicCast<DOMJITGetterComplex*>(vm, callFrame->thisValue());
1017         if (object)
1018             object->m_enableException = true;
1019         return JSValue::encode(jsUndefined());
1020     }
1021
1022     static EncodedJSValue customGetter(JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName)
1023     {
1024         DollarVMAssertScope assertScope;
1025         VM& vm = globalObject->vm();
1026         auto scope = DECLARE_THROW_SCOPE(vm);
1027
1028         auto* thisObject = jsDynamicCast<DOMJITGetterComplex*>(vm, JSValue::decode(thisValue));
1029         ASSERT(thisObject);
1030         if (thisObject->m_enableException)
1031             return JSValue::encode(throwException(globalObject, scope, createError(globalObject, "DOMJITGetterComplex slow call exception"_s)));
1032         return JSValue::encode(jsNumber(thisObject->value()));
1033     }
1034
1035     bool m_enableException { false };
1036 };
1037
1038 static const DOMJITGetterComplex::DOMJITAttribute DOMJITGetterComplexDOMJIT;
1039
1040 void DOMJITGetterComplex::finishCreation(VM& vm, JSGlobalObject* globalObject)
1041 {
1042     DollarVMAssertScope assertScope;
1043     Base::finishCreation(vm);
1044     const DOMJIT::GetterSetter* domJIT = &DOMJITGetterComplexDOMJIT;
1045     auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJIT->getter(), nullptr, DOMAttributeAnnotation { DOMJITGetterComplex::info(), domJIT });
1046     putDirectCustomAccessor(vm, Identifier::fromString(vm, "customGetter"), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);
1047     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "enableException"), 0, functionEnableException, NoIntrinsic, 0);
1048 }
1049
1050 class DOMJITFunctionObject : public DOMJITNode {
1051 public:
1052     DOMJITFunctionObject(VM& vm, Structure* structure)
1053         : Base(vm, structure)
1054     {
1055         DollarVMAssertScope assertScope;
1056     }
1057
1058     DECLARE_INFO;
1059     typedef DOMJITNode Base;
1060     static constexpr unsigned StructureFlags = Base::StructureFlags;
1061
1062     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
1063     {
1064         DollarVMAssertScope assertScope;
1065         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
1066     }
1067
1068     static DOMJITFunctionObject* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
1069     {
1070         DollarVMAssertScope assertScope;
1071         DOMJITFunctionObject* object = new (NotNull, allocateCell<DOMJITFunctionObject>(vm.heap)) DOMJITFunctionObject(vm, structure);
1072         object->finishCreation(vm, globalObject);
1073         return object;
1074     }
1075
1076     static EncodedJSValue JSC_HOST_CALL functionWithTypeCheck(JSGlobalObject* globalObject, CallFrame* callFrame)
1077     {
1078         DollarVMAssertScope assertScope;
1079         VM& vm = globalObject->vm();
1080         auto scope = DECLARE_THROW_SCOPE(vm);
1081
1082         DOMJITNode* thisObject = jsDynamicCast<DOMJITNode*>(vm, callFrame->thisValue());
1083         if (!thisObject)
1084             return throwVMTypeError(globalObject, scope);
1085         return JSValue::encode(jsNumber(thisObject->value()));
1086     }
1087
1088     static EncodedJSValue JIT_OPERATION functionWithoutTypeCheck(JSGlobalObject* globalObject, DOMJITNode* node)
1089     {
1090         DollarVMAssertScope assertScope;
1091         VM& vm = globalObject->vm();
1092         CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
1093         JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
1094         return JSValue::encode(jsNumber(node->value()));
1095     }
1096
1097 #if ENABLE(JIT)
1098     static Ref<Snippet> checkSubClassSnippet()
1099     {
1100         DollarVMAssertScope assertScope;
1101         Ref<Snippet> snippet = Snippet::create();
1102         snippet->numFPScratchRegisters = 1;
1103         snippet->setGenerator([=] (CCallHelpers& jit, SnippetParams& params) {
1104             DollarVMAssertScope assertScope;
1105             static const double value = 42.0;
1106             CCallHelpers::JumpList failureCases;
1107             // May use scratch registers.
1108             jit.loadDouble(CCallHelpers::TrustedImmPtr(&value), params.fpScratch(0));
1109             failureCases.append(jit.branchIfNotType(params[0].gpr(), JSC::JSType(LastJSCObjectType + 1)));
1110             return failureCases;
1111         });
1112         return snippet;
1113     }
1114 #endif
1115
1116 private:
1117     void finishCreation(VM&, JSGlobalObject*);
1118 };
1119
1120 static const DOMJIT::Signature DOMJITFunctionObjectSignature(DOMJITFunctionObject::functionWithoutTypeCheck, DOMJITFunctionObject::info(), DOMJIT::Effect::forRead(DOMJIT::HeapRange::top()), SpecInt32Only);
1121
1122 void DOMJITFunctionObject::finishCreation(VM& vm, JSGlobalObject* globalObject)
1123 {
1124     DollarVMAssertScope assertScope;
1125     Base::finishCreation(vm);
1126     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "func"), 0, functionWithTypeCheck, NoIntrinsic, &DOMJITFunctionObjectSignature, static_cast<unsigned>(PropertyAttribute::ReadOnly));
1127 }
1128
1129 class DOMJITCheckSubClassObject : public DOMJITNode {
1130 public:
1131     DOMJITCheckSubClassObject(VM& vm, Structure* structure)
1132         : Base(vm, structure)
1133     {
1134         DollarVMAssertScope assertScope;
1135     }
1136
1137     DECLARE_INFO;
1138     typedef DOMJITNode Base;
1139     static constexpr unsigned StructureFlags = Base::StructureFlags;
1140
1141     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
1142     {
1143         DollarVMAssertScope assertScope;
1144         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
1145     }
1146
1147     static DOMJITCheckSubClassObject* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
1148     {
1149         DollarVMAssertScope assertScope;
1150         DOMJITCheckSubClassObject* object = new (NotNull, allocateCell<DOMJITCheckSubClassObject>(vm.heap)) DOMJITCheckSubClassObject(vm, structure);
1151         object->finishCreation(vm, globalObject);
1152         return object;
1153     }
1154
1155     static EncodedJSValue JSC_HOST_CALL functionWithTypeCheck(JSGlobalObject* globalObject, CallFrame* callFrame)
1156     {
1157         DollarVMAssertScope assertScope;
1158         VM& vm = globalObject->vm();
1159         auto scope = DECLARE_THROW_SCOPE(vm);
1160
1161         auto* thisObject = jsDynamicCast<DOMJITCheckSubClassObject*>(vm, callFrame->thisValue());
1162         if (!thisObject)
1163             return throwVMTypeError(globalObject, scope);
1164         return JSValue::encode(jsNumber(thisObject->value()));
1165     }
1166
1167     static EncodedJSValue JIT_OPERATION functionWithoutTypeCheck(JSGlobalObject* globalObject, DOMJITNode* node)
1168     {
1169         DollarVMAssertScope assertScope;
1170         VM& vm = globalObject->vm();
1171         CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
1172         JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
1173         return JSValue::encode(jsNumber(node->value()));
1174     }
1175
1176 private:
1177     void finishCreation(VM&, JSGlobalObject*);
1178 };
1179
1180 static const DOMJIT::Signature DOMJITCheckSubClassObjectSignature(DOMJITCheckSubClassObject::functionWithoutTypeCheck, DOMJITCheckSubClassObject::info(), DOMJIT::Effect::forRead(DOMJIT::HeapRange::top()), SpecInt32Only);
1181
1182 void DOMJITCheckSubClassObject::finishCreation(VM& vm, JSGlobalObject* globalObject)
1183 {
1184     DollarVMAssertScope assertScope;
1185     Base::finishCreation(vm);
1186     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "func"), 0, functionWithTypeCheck, NoIntrinsic, &DOMJITCheckSubClassObjectSignature, static_cast<unsigned>(PropertyAttribute::ReadOnly));
1187 }
1188
1189 class DOMJITGetterBaseJSObject : public DOMJITNode {
1190 public:
1191     DOMJITGetterBaseJSObject(VM& vm, Structure* structure)
1192         : Base(vm, structure)
1193     {
1194         DollarVMAssertScope assertScope;
1195     }
1196
1197     DECLARE_INFO;
1198     using Base = DOMJITNode;
1199     static constexpr unsigned StructureFlags = Base::StructureFlags;
1200
1201     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
1202     {
1203         DollarVMAssertScope assertScope;
1204         return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
1205     }
1206
1207     static DOMJITGetterBaseJSObject* create(VM& vm, Structure* structure)
1208     {
1209         DollarVMAssertScope assertScope;
1210         DOMJITGetterBaseJSObject* getter = new (NotNull, allocateCell<DOMJITGetterBaseJSObject>(vm.heap)) DOMJITGetterBaseJSObject(vm, structure);
1211         getter->finishCreation(vm);
1212         return getter;
1213     }
1214
1215     class DOMJITAttribute : public DOMJIT::GetterSetter {
1216     public:
1217         ALWAYS_INLINE constexpr DOMJITAttribute()
1218             : DOMJIT::GetterSetter(
1219                 DOMJITGetterBaseJSObject::customGetter,
1220 #if ENABLE(JIT)
1221                 &callDOMGetter,
1222 #else
1223                 nullptr,
1224 #endif
1225                 SpecBytecodeTop)
1226         {
1227         }
1228
1229 #if ENABLE(JIT)
1230         static EncodedJSValue JIT_OPERATION slowCall(JSGlobalObject* globalObject, void* pointer)
1231         {
1232             DollarVMAssertScope assertScope;
1233             VM& vm = globalObject->vm();
1234             CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
1235             JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
1236             JSObject* object = static_cast<JSObject*>(pointer);
1237             return JSValue::encode(object->getPrototypeDirect(vm));
1238         }
1239
1240         static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()
1241         {
1242             DollarVMAssertScope assertScope;
1243             Ref<DOMJIT::CallDOMGetterSnippet> snippet = DOMJIT::CallDOMGetterSnippet::create();
1244             snippet->requireGlobalObject = true;
1245             snippet->setGenerator([=] (CCallHelpers& jit, SnippetParams& params) {
1246                 DollarVMAssertScope assertScope;
1247                 JSValueRegs results = params[0].jsValueRegs();
1248                 GPRReg domGPR = params[1].gpr();
1249                 GPRReg globalObjectGPR = params[2].gpr();
1250                 params.addSlowPathCall(jit.jump(), jit, slowCall, results, globalObjectGPR, domGPR);
1251                 return CCallHelpers::JumpList();
1252
1253             });
1254             return snippet;
1255         }
1256 #endif
1257     };
1258
1259 private:
1260     void finishCreation(VM&);
1261
1262     static EncodedJSValue customGetter(JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName)
1263     {
1264         DollarVMAssertScope assertScope;
1265         VM& vm = globalObject->vm();
1266         JSObject* thisObject = jsDynamicCast<JSObject*>(vm, JSValue::decode(thisValue));
1267         RELEASE_ASSERT(thisObject);
1268         return JSValue::encode(thisObject->getPrototypeDirect(vm));
1269     }
1270 };
1271
1272 static const DOMJITGetterBaseJSObject::DOMJITAttribute DOMJITGetterBaseJSObjectDOMJIT;
1273
1274 void DOMJITGetterBaseJSObject::finishCreation(VM& vm)
1275 {
1276     DollarVMAssertScope assertScope;
1277     Base::finishCreation(vm);
1278     const DOMJIT::GetterSetter* domJIT = &DOMJITGetterBaseJSObjectDOMJIT;
1279     auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJIT->getter(), nullptr, DOMAttributeAnnotation { JSObject::info(), domJIT });
1280     putDirectCustomAccessor(vm, Identifier::fromString(vm, "customGetter"), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);
1281 }
1282
1283 class Message : public ThreadSafeRefCounted<Message> {
1284 public:
1285     Message(ArrayBufferContents&&, int32_t);
1286     ~Message();
1287
1288     ArrayBufferContents&& releaseContents() { return WTFMove(m_contents); }
1289     int32_t index() const { return m_index; }
1290
1291 private:
1292     ArrayBufferContents m_contents;
1293     int32_t m_index { 0 };
1294 };
1295
1296 class JSTestCustomGetterSetter : public JSNonFinalObject {
1297 public:
1298     using Base = JSNonFinalObject;
1299     static constexpr unsigned StructureFlags = Base::StructureFlags;
1300
1301     template<typename CellType, SubspaceAccess>
1302     static CompleteSubspace* subspaceFor(VM& vm)
1303     {
1304         return &vm.cellSpace;
1305     }
1306
1307     JSTestCustomGetterSetter(VM& vm, Structure* structure)
1308         : Base(vm, structure)
1309     {
1310         DollarVMAssertScope assertScope;
1311     }
1312
1313     static JSTestCustomGetterSetter* create(VM& vm, JSGlobalObject*, Structure* structure)
1314     {
1315         DollarVMAssertScope assertScope;
1316         JSTestCustomGetterSetter* result = new (NotNull, allocateCell<JSTestCustomGetterSetter>(vm.heap)) JSTestCustomGetterSetter(vm, structure);
1317         result->finishCreation(vm);
1318         return result;
1319     }
1320
1321     void finishCreation(VM&);
1322
1323     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject)
1324     {
1325         DollarVMAssertScope assertScope;
1326         return Structure::create(vm, globalObject, globalObject->objectPrototype(), TypeInfo(ObjectType, StructureFlags), info());
1327     }
1328
1329     DECLARE_INFO;
1330 };
1331
1332
1333 static EncodedJSValue customGetAccessor(JSGlobalObject*, EncodedJSValue thisValue, PropertyName)
1334 {
1335     // Passed |this|
1336     return thisValue;
1337 }
1338
1339 static EncodedJSValue customGetValue(JSGlobalObject* globalObject, EncodedJSValue slotValue, PropertyName)
1340 {
1341     RELEASE_ASSERT(JSValue::decode(slotValue).inherits<JSTestCustomGetterSetter>(globalObject->vm()));
1342     // Passed property holder.
1343     return slotValue;
1344 }
1345
1346 static bool customSetAccessor(JSGlobalObject* globalObject, EncodedJSValue thisObject, EncodedJSValue encodedValue)
1347 {
1348     DollarVMAssertScope assertScope;
1349     VM& vm = globalObject->vm();
1350
1351     JSValue value = JSValue::decode(encodedValue);
1352     RELEASE_ASSERT(value.isObject());
1353     JSObject* object = asObject(value);
1354     PutPropertySlot slot(object);
1355     object->put(object, globalObject, Identifier::fromString(vm, "result"), JSValue::decode(thisObject), slot);
1356
1357     return true;
1358 }
1359
1360 static bool customSetValue(JSGlobalObject* globalObject, EncodedJSValue slotValue, EncodedJSValue encodedValue)
1361 {
1362     DollarVMAssertScope assertScope;
1363     VM& vm = globalObject->vm();
1364
1365     RELEASE_ASSERT(JSValue::decode(slotValue).inherits<JSTestCustomGetterSetter>(globalObject->vm()));
1366
1367     JSValue value = JSValue::decode(encodedValue);
1368     RELEASE_ASSERT(value.isObject());
1369     JSObject* object = asObject(value);
1370     PutPropertySlot slot(object);
1371     object->put(object, globalObject, Identifier::fromString(vm, "result"), JSValue::decode(slotValue), slot);
1372
1373     return true;
1374 }
1375
1376 void JSTestCustomGetterSetter::finishCreation(VM& vm)
1377 {
1378     DollarVMAssertScope assertScope;
1379     Base::finishCreation(vm);
1380
1381     putDirectCustomAccessor(vm, Identifier::fromString(vm, "customValue"),
1382         CustomGetterSetter::create(vm, customGetValue, customSetValue), 0);
1383     putDirectCustomAccessor(vm, Identifier::fromString(vm, "customAccessor"),
1384         CustomGetterSetter::create(vm, customGetAccessor, customSetAccessor), static_cast<unsigned>(PropertyAttribute::CustomAccessor));
1385 }
1386
1387 const ClassInfo Element::s_info = { "Element", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(Element) };
1388 const ClassInfo Root::s_info = { "Root", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(Root) };
1389 const ClassInfo SimpleObject::s_info = { "SimpleObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(SimpleObject) };
1390 const ClassInfo ImpureGetter::s_info = { "ImpureGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(ImpureGetter) };
1391 const ClassInfo CustomGetter::s_info = { "CustomGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(CustomGetter) };
1392 const ClassInfo RuntimeArray::s_info = { "RuntimeArray", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(RuntimeArray) };
1393 #if ENABLE(JIT)
1394 const ClassInfo DOMJITNode::s_info = { "DOMJITNode", &Base::s_info, nullptr, &DOMJITNode::checkSubClassSnippet, CREATE_METHOD_TABLE(DOMJITNode) };
1395 #else
1396 const ClassInfo DOMJITNode::s_info = { "DOMJITNode", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITNode) };
1397 #endif
1398 const ClassInfo DOMJITGetter::s_info = { "DOMJITGetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetter) };
1399 const ClassInfo DOMJITGetterComplex::s_info = { "DOMJITGetterComplex", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetterComplex) };
1400 const ClassInfo DOMJITGetterBaseJSObject::s_info = { "DOMJITGetterBaseJSObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetterBaseJSObject) };
1401 #if ENABLE(JIT)
1402 const ClassInfo DOMJITFunctionObject::s_info = { "DOMJITFunctionObject", &Base::s_info, nullptr, &DOMJITFunctionObject::checkSubClassSnippet, CREATE_METHOD_TABLE(DOMJITFunctionObject) };
1403 #else
1404 const ClassInfo DOMJITFunctionObject::s_info = { "DOMJITFunctionObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITFunctionObject) };
1405 #endif
1406 const ClassInfo DOMJITCheckSubClassObject::s_info = { "DOMJITCheckSubClassObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITCheckSubClassObject) };
1407 const ClassInfo JSTestCustomGetterSetter::s_info = { "JSTestCustomGetterSetter", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestCustomGetterSetter) };
1408
1409 const ClassInfo StaticCustomAccessor::s_info = { "StaticCustomAccessor", &Base::s_info, &staticCustomAccessorTable, nullptr, CREATE_METHOD_TABLE(StaticCustomAccessor) };
1410 const ClassInfo ObjectDoingSideEffectPutWithoutCorrectSlotStatus::s_info = { "ObjectDoingSideEffectPutWithoutCorrectSlotStatus", &Base::s_info, &staticCustomAccessorTable, nullptr, CREATE_METHOD_TABLE(ObjectDoingSideEffectPutWithoutCorrectSlotStatus) };
1411
1412 ElementHandleOwner* Element::handleOwner()
1413 {
1414     DollarVMAssertScope assertScope;
1415     static ElementHandleOwner* owner = 0;
1416     if (!owner)
1417         owner = new ElementHandleOwner();
1418     return owner;
1419 }
1420
1421 void Element::finishCreation(VM& vm, Root* root)
1422 {
1423     DollarVMAssertScope assertScope;
1424     Base::finishCreation(vm);
1425     setRoot(vm, root);
1426     m_root->setElement(this);
1427 }
1428
1429 #if ENABLE(WEBASSEMBLY)
1430
1431 static EncodedJSValue JSC_HOST_CALL functionWasmStreamingParserAddBytes(JSGlobalObject*, CallFrame*);
1432 static EncodedJSValue JSC_HOST_CALL functionWasmStreamingParserFinalize(JSGlobalObject*, CallFrame*);
1433
1434 class WasmStreamingParser : public JSDestructibleObject {
1435 public:
1436     using Base = JSDestructibleObject;
1437     template<typename CellType, SubspaceAccess>
1438     static CompleteSubspace* subspaceFor(VM& vm)
1439     {
1440         return &vm.destructibleObjectSpace;
1441     }
1442
1443     class Client final : public Wasm::StreamingParserClient {
1444     public:
1445         explicit Client(WasmStreamingParser* parser)
1446             : m_parser(parser)
1447         {
1448         }
1449
1450         bool didReceiveSectionData(Wasm::Section) override { return true; }
1451         bool didReceiveFunctionData(unsigned, const Wasm::FunctionData&) override { return true; }
1452         void didFinishParsing() override { }
1453
1454         WasmStreamingParser* m_parser;
1455     };
1456
1457     WasmStreamingParser(VM& vm, Structure* structure)
1458         : Base(vm, structure)
1459         , m_info(Wasm::ModuleInformation::create())
1460         , m_client(this)
1461         , m_streamingParser(m_info.get(), m_client)
1462     {
1463         DollarVMAssertScope assertScope;
1464     }
1465
1466     static WasmStreamingParser* create(VM& vm, JSGlobalObject* globalObject)
1467     {
1468         DollarVMAssertScope assertScope;
1469         Structure* structure = createStructure(vm, globalObject, jsNull());
1470         WasmStreamingParser* result = new (NotNull, allocateCell<WasmStreamingParser>(vm.heap)) WasmStreamingParser(vm, structure);
1471         result->finishCreation(vm);
1472         return result;
1473     }
1474
1475     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
1476     {
1477         DollarVMAssertScope assertScope;
1478         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
1479     }
1480
1481     Wasm::StreamingParser& streamingParser() { return m_streamingParser; }
1482
1483     void finishCreation(VM& vm)
1484     {
1485         DollarVMAssertScope assertScope;
1486         Base::finishCreation(vm);
1487
1488         JSGlobalObject* globalObject = this->globalObject(vm);
1489         putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "addBytes"), 0, functionWasmStreamingParserAddBytes, NoIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
1490         putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "finalize"), 0, functionWasmStreamingParserFinalize, NoIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
1491     }
1492
1493     DECLARE_INFO;
1494
1495     Ref<Wasm::ModuleInformation> m_info;
1496     Client m_client;
1497     Wasm::StreamingParser m_streamingParser;
1498 };
1499
1500 const ClassInfo WasmStreamingParser::s_info = { "WasmStreamingParser", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(WasmStreamingParser) };
1501
1502 EncodedJSValue JSC_HOST_CALL functionWasmStreamingParserAddBytes(JSGlobalObject* globalObject, CallFrame* callFrame)
1503 {
1504     DollarVMAssertScope assertScope;
1505     VM& vm = globalObject->vm();
1506     auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
1507
1508     auto* thisObject = jsDynamicCast<WasmStreamingParser*>(vm, callFrame->thisValue());
1509     if (!thisObject)
1510         RELEASE_AND_RETURN(scope, JSValue::encode(jsBoolean(false)));
1511
1512     auto data = getWasmBufferFromValue(globalObject, callFrame->argument(0));
1513     RETURN_IF_EXCEPTION(scope, encodedJSValue());
1514     RELEASE_AND_RETURN(scope, JSValue::encode(jsNumber(static_cast<int32_t>(thisObject->streamingParser().addBytes(bitwise_cast<const uint8_t*>(data.first), data.second)))));
1515 }
1516
1517 EncodedJSValue JSC_HOST_CALL functionWasmStreamingParserFinalize(JSGlobalObject* globalObject, CallFrame* callFrame)
1518 {
1519     DollarVMAssertScope assertScope;
1520     VM& vm = globalObject->vm();
1521     auto* thisObject = jsDynamicCast<WasmStreamingParser*>(vm, callFrame->thisValue());
1522     if (!thisObject)
1523         return JSValue::encode(jsBoolean(false));
1524     return JSValue::encode(jsNumber(static_cast<int32_t>(thisObject->streamingParser().finalize())));
1525 }
1526
1527 #endif
1528
1529 } // namespace
1530
1531 namespace JSC {
1532
1533 const ClassInfo JSDollarVM::s_info = { "DollarVM", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDollarVM) };
1534
1535 // Triggers a crash immediately.
1536 // Usage: $vm.crash()
1537 static NO_RETURN_DUE_TO_CRASH EncodedJSValue JSC_HOST_CALL functionCrash(JSGlobalObject*, CallFrame*)
1538 {
1539     DollarVMAssertScope assertScope;
1540     CRASH();
1541 }
1542
1543 // Executes a breakpoint instruction if the first argument is truthy or is unset.
1544 // Usage: $vm.breakpoint(<condition>)
1545 static EncodedJSValue JSC_HOST_CALL functionBreakpoint(JSGlobalObject* globalObject, CallFrame* callFrame)
1546 {
1547     DollarVMAssertScope assertScope;
1548     // Nothing should throw here but we might as well double check...
1549     VM& vm = globalObject->vm();
1550     auto scope = DECLARE_CATCH_SCOPE(vm);
1551     UNUSED_PARAM(scope);
1552     if (!callFrame->argumentCount() || callFrame->argument(0).toBoolean(globalObject))
1553         WTFBreakpointTrap();
1554
1555     return encodedJSUndefined();
1556 }
1557
1558 // Returns true if the current frame is a DFG frame.
1559 // Usage: isDFG = $vm.dfgTrue()
1560 static EncodedJSValue JSC_HOST_CALL functionDFGTrue(JSGlobalObject*, CallFrame*)
1561 {
1562     DollarVMAssertScope assertScope;
1563     return JSValue::encode(jsBoolean(false));
1564 }
1565
1566 // Returns true if the current frame is a FTL frame.
1567 // Usage: isFTL = $vm.ftlTrue()
1568 static EncodedJSValue JSC_HOST_CALL functionFTLTrue(JSGlobalObject*, CallFrame*)
1569 {
1570     DollarVMAssertScope assertScope;
1571     return JSValue::encode(jsBoolean(false));
1572 }
1573
1574 static EncodedJSValue JSC_HOST_CALL functionCpuMfence(JSGlobalObject*, CallFrame*)
1575 {
1576     DollarVMAssertScope assertScope;
1577 #if CPU(X86_64) && !OS(WINDOWS)
1578     asm volatile("mfence" ::: "memory");
1579 #endif
1580     return JSValue::encode(jsUndefined());
1581 }
1582
1583 static EncodedJSValue JSC_HOST_CALL functionCpuRdtsc(JSGlobalObject*, CallFrame*)
1584 {
1585     DollarVMAssertScope assertScope;
1586 #if CPU(X86_64) && !OS(WINDOWS)
1587     unsigned high;
1588     unsigned low;
1589     asm volatile ("rdtsc" : "=a"(low), "=d"(high));
1590     return JSValue::encode(jsNumber(low));
1591 #else
1592     return JSValue::encode(jsNumber(0));
1593 #endif
1594 }
1595
1596 static EncodedJSValue JSC_HOST_CALL functionCpuCpuid(JSGlobalObject*, CallFrame*)
1597 {
1598     DollarVMAssertScope assertScope;
1599 #if CPU(X86_64) && !OS(WINDOWS)
1600     WTF::x86_cpuid();
1601 #endif
1602     return JSValue::encode(jsUndefined());
1603 }
1604
1605 static EncodedJSValue JSC_HOST_CALL functionCpuPause(JSGlobalObject*, CallFrame*)
1606 {
1607     DollarVMAssertScope assertScope;
1608 #if CPU(X86_64) && !OS(WINDOWS)
1609     asm volatile ("pause" ::: "memory");
1610 #endif
1611     return JSValue::encode(jsUndefined());
1612 }
1613
1614 // This takes either a JSArrayBuffer, JSArrayBufferView*, or any other object as its first
1615 // argument. The second argument is expected to be an integer.
1616 //
1617 // If the first argument is a JSArrayBuffer, it'll clflush on that buffer
1618 // plus the second argument as a byte offset. It'll also flush on the object
1619 // itself so its length, etc, aren't in the cache.
1620 //
1621 // If the first argument is not a JSArrayBuffer, we load the butterfly
1622 // and clflush at the address of the butterfly.
1623 static EncodedJSValue JSC_HOST_CALL functionCpuClflush(JSGlobalObject* globalObject, CallFrame* callFrame)
1624 {
1625     DollarVMAssertScope assertScope;
1626 #if CPU(X86_64) && !OS(WINDOWS)
1627     VM& vm = globalObject->vm();
1628
1629     if (!callFrame->argument(1).isInt32())
1630         return JSValue::encode(jsBoolean(false));
1631
1632     auto clflush = [] (void* ptr) {
1633         DollarVMAssertScope assertScope;
1634         char* ptrToFlush = static_cast<char*>(ptr);
1635         asm volatile ("clflush %0" :: "m"(*ptrToFlush) : "memory");
1636     };
1637
1638     Vector<void*> toFlush;
1639
1640     uint32_t offset = callFrame->argument(1).asUInt32();
1641
1642     if (JSArrayBufferView* view = jsDynamicCast<JSArrayBufferView*>(vm, callFrame->argument(0)))
1643         toFlush.append(bitwise_cast<char*>(view->vector()) + offset);
1644     else if (JSObject* object = jsDynamicCast<JSObject*>(vm, callFrame->argument(0))) {
1645         switch (object->indexingType()) {
1646         case ALL_INT32_INDEXING_TYPES:
1647         case ALL_CONTIGUOUS_INDEXING_TYPES:
1648         case ALL_DOUBLE_INDEXING_TYPES:
1649             toFlush.append(bitwise_cast<char*>(object->butterfly()) + Butterfly::offsetOfVectorLength());
1650             toFlush.append(bitwise_cast<char*>(object->butterfly()) + Butterfly::offsetOfPublicLength());
1651         }
1652     }
1653
1654     if (!toFlush.size())
1655         return JSValue::encode(jsBoolean(false));
1656
1657     for (void* ptr : toFlush)
1658         clflush(ptr);
1659     return JSValue::encode(jsBoolean(true));
1660 #else
1661     UNUSED_PARAM(globalObject);
1662     UNUSED_PARAM(callFrame);
1663     return JSValue::encode(jsBoolean(false));
1664 #endif
1665 }
1666
1667 class CallerFrameJITTypeFunctor {
1668 public:
1669     CallerFrameJITTypeFunctor()
1670         : m_currentFrame(0)
1671         , m_jitType(JITType::None)
1672     {
1673         DollarVMAssertScope assertScope;
1674     }
1675
1676     StackVisitor::Status operator()(StackVisitor& visitor) const
1677     {
1678         if (m_currentFrame++ > 1) {
1679             m_jitType = visitor->codeBlock()->jitType();
1680             return StackVisitor::Done;
1681         }
1682         return StackVisitor::Continue;
1683     }
1684     
1685     JITType jitType() { return m_jitType; }
1686
1687 private:
1688     mutable unsigned m_currentFrame;
1689     mutable JITType m_jitType;
1690 };
1691
1692 static FunctionExecutable* getExecutableForFunction(JSValue theFunctionValue)
1693 {
1694     DollarVMAssertScope assertScope;
1695     if (!theFunctionValue.isCell())
1696         return nullptr;
1697     
1698     VM& vm = theFunctionValue.asCell()->vm();
1699     JSFunction* theFunction = jsDynamicCast<JSFunction*>(vm, theFunctionValue);
1700     if (!theFunction)
1701         return nullptr;
1702     
1703     FunctionExecutable* executable = jsDynamicCast<FunctionExecutable*>(vm,
1704         theFunction->executable());
1705
1706     return executable;
1707 }
1708
1709 // Returns true if the current frame is a LLInt frame.
1710 // Usage: isLLInt = $vm.llintTrue()
1711 static EncodedJSValue JSC_HOST_CALL functionLLintTrue(JSGlobalObject* globalObject, CallFrame* callFrame)
1712 {
1713     DollarVMAssertScope assertScope;
1714     VM& vm = globalObject->vm();
1715     if (!callFrame)
1716         return JSValue::encode(jsUndefined());
1717     CallerFrameJITTypeFunctor functor;
1718     callFrame->iterate(vm, functor);
1719     return JSValue::encode(jsBoolean(functor.jitType() == JITType::InterpreterThunk));
1720 }
1721
1722 // Returns true if the current frame is a baseline JIT frame.
1723 // Usage: isBaselineJIT = $vm.jitTrue()
1724 static EncodedJSValue JSC_HOST_CALL functionJITTrue(JSGlobalObject* globalObject, CallFrame* callFrame)
1725 {
1726     DollarVMAssertScope assertScope;
1727     VM& vm = globalObject->vm();
1728     if (!callFrame)
1729         return JSValue::encode(jsUndefined());
1730     CallerFrameJITTypeFunctor functor;
1731     callFrame->iterate(vm, functor);
1732     return JSValue::encode(jsBoolean(functor.jitType() == JITType::BaselineJIT));
1733 }
1734
1735 // Set that the argument function should not be inlined.
1736 // Usage:
1737 // function f() { };
1738 // $vm.noInline(f);
1739 static EncodedJSValue JSC_HOST_CALL functionNoInline(JSGlobalObject*, CallFrame* callFrame)
1740 {
1741     DollarVMAssertScope assertScope;
1742     if (callFrame->argumentCount() < 1)
1743         return JSValue::encode(jsUndefined());
1744     
1745     JSValue theFunctionValue = callFrame->uncheckedArgument(0);
1746
1747     if (FunctionExecutable* executable = getExecutableForFunction(theFunctionValue))
1748         executable->setNeverInline(true);
1749     
1750     return JSValue::encode(jsUndefined());
1751 }
1752
1753 // Runs a full GC synchronously.
1754 // Usage: $vm.gc()
1755 static EncodedJSValue JSC_HOST_CALL functionGC(JSGlobalObject* globalObject, CallFrame*)
1756 {
1757     DollarVMAssertScope assertScope;
1758     VMInspector::gc(globalObject);
1759     return JSValue::encode(jsUndefined());
1760 }
1761
1762 // Runs the edenGC synchronously.
1763 // Usage: $vm.edenGC()
1764 static EncodedJSValue JSC_HOST_CALL functionEdenGC(JSGlobalObject* globalObject, CallFrame*)
1765 {
1766     DollarVMAssertScope assertScope;
1767     VMInspector::edenGC(globalObject);
1768     return JSValue::encode(jsUndefined());
1769 }
1770
1771 // Runs a full GC, but sweep asynchronously.
1772 // Usage: $vm.gcSweepAsynchronously()
1773 static EncodedJSValue JSC_HOST_CALL functionGCSweepAsynchronously(JSGlobalObject* globalObject, CallFrame*)
1774 {
1775     DollarVMAssertScope assertScope;
1776     globalObject->vm().heap.collectNow(Async, CollectionScope::Full);
1777     return JSValue::encode(jsUndefined());
1778 }
1779
1780 // Dumps the hashes of all subspaces currently registered with the VM.
1781 // Usage: $vm.dumpSubspaceHashes()
1782 static EncodedJSValue JSC_HOST_CALL functionDumpSubspaceHashes(JSGlobalObject* globalObject, CallFrame*)
1783 {
1784     DollarVMAssertScope assertScope;
1785     VM& vm = globalObject->vm();
1786     VMInspector::dumpSubspaceHashes(&vm);
1787     return JSValue::encode(jsUndefined());
1788 }
1789
1790 // Gets a JSDollarVMCallFrame for a specified frame index.
1791 // Usage: var callFrame = $vm.callFrame(0) // frame 0 is the top frame.
1792 // Usage: var callFrame = $vm.callFrame() // implies frame 0 i.e. current frame.
1793 //
1794 // This gives you the ability to query the following:
1795 //    callFrame.valid; // false if we asked for a frame beyond the end of the stack, else true.
1796 //    callFrame.callee;
1797 //    callFrame.codeBlock;
1798 //    callFrame.unlinkedCodeBlock;
1799 //    callFrame.executable;
1800 //
1801 // Note: you cannot toString() a codeBlock, unlinkedCodeBlock, or executable because
1802 // there are internal objects and not a JS object. Hence, you cannot do string
1803 // concatenation with them.
1804 static EncodedJSValue JSC_HOST_CALL functionCallFrame(JSGlobalObject* globalObject, CallFrame* callFrame)
1805 {
1806     DollarVMAssertScope assertScope;
1807     unsigned frameNumber = 1;
1808     if (callFrame->argumentCount() >= 1) {
1809         JSValue value = callFrame->uncheckedArgument(0);
1810         if (!value.isUInt32())
1811             return JSValue::encode(jsUndefined());
1812
1813         // We need to inc the frame number because the caller would consider
1814         // its own frame as frame 0. Hence, we need discount the frame for this
1815         // function.
1816         frameNumber = value.asUInt32() + 1;
1817     }
1818
1819     return JSValue::encode(JSDollarVMCallFrame::create(globalObject, callFrame, frameNumber));
1820 }
1821
1822 // Gets a token for the CodeBlock for a specified frame index.
1823 // Usage: codeBlockToken = $vm.codeBlockForFrame(0) // frame 0 is the top frame.
1824 // Usage: codeBlockToken = $vm.codeBlockForFrame() // implies frame 0 i.e. current frame.
1825 static EncodedJSValue JSC_HOST_CALL functionCodeBlockForFrame(JSGlobalObject* globalObject, CallFrame* callFrame)
1826 {
1827     DollarVMAssertScope assertScope;
1828     unsigned frameNumber = 1;
1829     if (callFrame->argumentCount() >= 1) {
1830         JSValue value = callFrame->uncheckedArgument(0);
1831         if (!value.isUInt32())
1832             return JSValue::encode(jsUndefined());
1833
1834         // We need to inc the frame number because the caller would consider
1835         // its own frame as frame 0. Hence, we need discount the frame for this
1836         // function.
1837         frameNumber = value.asUInt32() + 1;
1838     }
1839
1840     CodeBlock* codeBlock = VMInspector::codeBlockForFrame(globalObject, callFrame, frameNumber);
1841     if (codeBlock)
1842         return JSValue::encode(codeBlock);
1843     return JSValue::encode(jsUndefined());
1844 }
1845
1846 static CodeBlock* codeBlockFromArg(JSGlobalObject* globalObject, CallFrame* callFrame)
1847 {
1848     DollarVMAssertScope assertScope;
1849     VM& vm = globalObject->vm();
1850     if (callFrame->argumentCount() < 1)
1851         return nullptr;
1852
1853     JSValue value = callFrame->uncheckedArgument(0);
1854     CodeBlock* candidateCodeBlock = nullptr;
1855     if (value.isCell()) {
1856         JSFunction* func = jsDynamicCast<JSFunction*>(vm, value.asCell());
1857         if (func) {
1858             if (func->isHostFunction())
1859                 candidateCodeBlock = nullptr;
1860             else
1861                 candidateCodeBlock = func->jsExecutable()->eitherCodeBlock();
1862         } else
1863             candidateCodeBlock = static_cast<CodeBlock*>(value.asCell());
1864     }
1865
1866     if (candidateCodeBlock && VMInspector::isValidCodeBlock(globalObject, candidateCodeBlock))
1867         return candidateCodeBlock;
1868
1869     if (candidateCodeBlock)
1870         dataLog("Invalid codeBlock: ", RawPointer(candidateCodeBlock), " ", value, "\n");
1871     else
1872         dataLog("Invalid codeBlock: ", value, "\n");
1873     return nullptr;
1874 }
1875
1876 // Usage: $vm.print("codeblock = ", $vm.codeBlockFor(functionObj))
1877 // Usage: $vm.print("codeblock = ", $vm.codeBlockFor(codeBlockToken))
1878 // Note: you cannot toString() a codeBlock because it's an internal object and not
1879 // a JS object. Hence, you cannot do string concatenation with it.
1880 static EncodedJSValue JSC_HOST_CALL functionCodeBlockFor(JSGlobalObject* globalObject, CallFrame* callFrame)
1881 {
1882     DollarVMAssertScope assertScope;
1883     CodeBlock* codeBlock = codeBlockFromArg(globalObject, callFrame);
1884     WTF::StringPrintStream stream;
1885     if (codeBlock) {
1886         stream.print(*codeBlock);
1887         return JSValue::encode(jsString(globalObject->vm(), stream.toString()));
1888     }
1889     return JSValue::encode(jsUndefined());
1890 }
1891
1892 // Usage: $vm.dumpSourceFor(functionObj)
1893 // Usage: $vm.dumpSourceFor(codeBlockToken)
1894 static EncodedJSValue JSC_HOST_CALL functionDumpSourceFor(JSGlobalObject* globalObject, CallFrame* callFrame)
1895 {
1896     DollarVMAssertScope assertScope;
1897     CodeBlock* codeBlock = codeBlockFromArg(globalObject, callFrame);
1898     if (codeBlock)
1899         codeBlock->dumpSource();
1900     return JSValue::encode(jsUndefined());
1901 }
1902
1903 // Usage: $vm.dumpBytecodeFor(functionObj)
1904 // Usage: $vm.dumpBytecodeFor(codeBlock)
1905 static EncodedJSValue JSC_HOST_CALL functionDumpBytecodeFor(JSGlobalObject* globalObject, CallFrame* callFrame)
1906 {
1907     DollarVMAssertScope assertScope;
1908     CodeBlock* codeBlock = codeBlockFromArg(globalObject, callFrame);
1909     if (codeBlock)
1910         codeBlock->dumpBytecode();
1911     return JSValue::encode(jsUndefined());
1912 }
1913
1914 static EncodedJSValue doPrint(JSGlobalObject* globalObject, CallFrame* callFrame, bool addLineFeed)
1915 {
1916     DollarVMAssertScope assertScope;
1917     auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
1918     for (unsigned i = 0; i < callFrame->argumentCount(); ++i) {
1919         JSValue arg = callFrame->uncheckedArgument(i);
1920         if (arg.isCell()
1921             && !arg.isObject()
1922             && !arg.isString()
1923             && !arg.isBigInt()) {
1924             dataLog(arg);
1925             continue;
1926         }
1927         String argStr = callFrame->uncheckedArgument(i).toWTFString(globalObject);
1928         RETURN_IF_EXCEPTION(scope, encodedJSValue());
1929         dataLog(argStr);
1930     }
1931     if (addLineFeed)
1932         dataLog("\n");
1933     return JSValue::encode(jsUndefined());
1934 }
1935
1936 // Prints a series of comma separate strings without appending a newline.
1937 // Usage: $vm.dataLog(str1, str2, str3)
1938 static EncodedJSValue JSC_HOST_CALL functionDataLog(JSGlobalObject* globalObject, CallFrame* callFrame)
1939 {
1940     DollarVMAssertScope assertScope;
1941     const bool addLineFeed = false;
1942     return doPrint(globalObject, callFrame, addLineFeed);
1943 }
1944
1945 // Prints a series of comma separate strings and appends a newline.
1946 // Usage: $vm.print(str1, str2, str3)
1947 static EncodedJSValue JSC_HOST_CALL functionPrint(JSGlobalObject* globalObject, CallFrame* callFrame)
1948 {
1949     DollarVMAssertScope assertScope;
1950     const bool addLineFeed = true;
1951     return doPrint(globalObject, callFrame, addLineFeed);
1952 }
1953
1954 // Dumps the current CallFrame.
1955 // Usage: $vm.dumpCallFrame()
1956 static EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(JSGlobalObject* globalObject, CallFrame* callFrame)
1957 {
1958     DollarVMAssertScope assertScope;
1959     // When the callers call this function, they are expecting to dump their
1960     // own frame. So skip 1 for this frame.
1961     VMInspector::dumpCallFrame(globalObject, callFrame, 1);
1962     return JSValue::encode(jsUndefined());
1963 }
1964
1965 // Dumps the JS stack.
1966 // Usage: $vm.printStack()
1967 static EncodedJSValue JSC_HOST_CALL functionDumpStack(JSGlobalObject* globalObject, CallFrame* callFrame)
1968 {
1969     DollarVMAssertScope assertScope;
1970     // When the callers call this function, they are expecting to dump the
1971     // stack starting their own frame. So skip 1 for this frame.
1972     VMInspector::dumpStack(globalObject, callFrame, 1);
1973     return JSValue::encode(jsUndefined());
1974 }
1975
1976 // Dumps the current CallFrame.
1977 // Usage: $vm.dumpRegisters(N) // dump the registers of the Nth CallFrame.
1978 // Usage: $vm.dumpRegisters() // dump the registers of the current CallFrame.
1979 // FIXME: Currently, this function dumps the physical frame. We should make
1980 // it dump the logical frame (i.e. be able to dump inlined frames as well).
1981 static EncodedJSValue JSC_HOST_CALL functionDumpRegisters(JSGlobalObject* globalObject, CallFrame* callFrame)
1982 {
1983     DollarVMAssertScope assertScope;
1984     VM& vm = globalObject->vm();
1985     unsigned requestedFrameIndex = 1;
1986     if (callFrame->argumentCount() >= 1) {
1987         JSValue value = callFrame->uncheckedArgument(0);
1988         if (!value.isUInt32())
1989             return JSValue::encode(jsUndefined());
1990
1991         // We need to inc the frame number because the caller would consider
1992         // its own frame as frame 0. Hence, we need discount the frame for this
1993         // function.
1994         requestedFrameIndex = value.asUInt32() + 1;
1995     }
1996
1997     unsigned frameIndex = 0;
1998     callFrame->iterate(vm, [&] (StackVisitor& visitor) {
1999         DollarVMAssertScope assertScope;
2000         if (frameIndex++ != requestedFrameIndex)
2001             return StackVisitor::Continue;
2002         VMInspector::dumpRegisters(visitor->callFrame());
2003         return StackVisitor::Done;
2004     });
2005
2006     return encodedJSUndefined();
2007 }
2008
2009 // Dumps the internal memory layout of a JSCell.
2010 // Usage: $vm.dumpCell(cell)
2011 static EncodedJSValue JSC_HOST_CALL functionDumpCell(JSGlobalObject*, CallFrame* callFrame)
2012 {
2013     DollarVMAssertScope assertScope;
2014     JSValue value = callFrame->argument(0);
2015     if (!value.isCell())
2016         return encodedJSUndefined();
2017     
2018     VMInspector::dumpCellMemory(value.asCell());
2019     return encodedJSUndefined();
2020 }
2021
2022 // Gets the dataLog dump of the indexingMode of the passed value.
2023 // Usage: $vm.print("indexingMode = " + $vm.indexingMode(jsValue))
2024 static EncodedJSValue JSC_HOST_CALL functionIndexingMode(JSGlobalObject* globalObject, CallFrame* callFrame)
2025 {
2026     DollarVMAssertScope assertScope;
2027     if (!callFrame->argument(0).isObject())
2028         return encodedJSUndefined();
2029
2030     WTF::StringPrintStream stream;
2031     stream.print(IndexingTypeDump(callFrame->uncheckedArgument(0).getObject()->indexingMode()));
2032     return JSValue::encode(jsString(globalObject->vm(), stream.toString()));
2033 }
2034
2035 static EncodedJSValue JSC_HOST_CALL functionInlineCapacity(JSGlobalObject* globalObject, CallFrame* callFrame)
2036 {
2037     DollarVMAssertScope assertScope;
2038     VM& vm = globalObject->vm();
2039     if (auto* object = jsDynamicCast<JSObject*>(vm, callFrame->argument(0)))
2040         return JSValue::encode(jsNumber(object->structure(vm)->inlineCapacity()));
2041
2042     return encodedJSUndefined();
2043 }
2044
2045 // Gets the dataLog dump of a given JS value as a string.
2046 // Usage: $vm.print("value = " + $vm.value(jsValue))
2047 static EncodedJSValue JSC_HOST_CALL functionValue(JSGlobalObject* globalObject, CallFrame* callFrame)
2048 {
2049     DollarVMAssertScope assertScope;
2050     WTF::StringPrintStream stream;
2051     for (unsigned i = 0; i < callFrame->argumentCount(); ++i) {
2052         if (i)
2053             stream.print(", ");
2054         stream.print(callFrame->uncheckedArgument(i));
2055     }
2056     
2057     return JSValue::encode(jsString(globalObject->vm(), stream.toString()));
2058 }
2059
2060 // Gets the pid of the current process.
2061 // Usage: $vm.print("pid = " + $vm.getpid())
2062 static EncodedJSValue JSC_HOST_CALL functionGetPID(JSGlobalObject*, CallFrame*)
2063 {
2064     DollarVMAssertScope assertScope;
2065     return JSValue::encode(jsNumber(getCurrentProcessID()));
2066 }
2067
2068 // Make the globalObject have a bad time. Does nothing if the object is not a JSGlobalObject.
2069 // Usage: $vm.haveABadTime(globalObject)
2070 static EncodedJSValue JSC_HOST_CALL functionHaveABadTime(JSGlobalObject* globalObject, CallFrame* callFrame)
2071 {
2072     DollarVMAssertScope assertScope;
2073     VM& vm = globalObject->vm();
2074     JSLockHolder lock(vm);
2075     JSValue objValue = callFrame->argument(0);
2076     if (!objValue.isObject())
2077         return JSValue::encode(jsBoolean(false));
2078
2079     JSObject* obj = asObject(objValue.asCell());
2080     JSGlobalObject* target = jsDynamicCast<JSGlobalObject*>(vm, obj);
2081     if (!target)
2082         JSValue::encode(jsBoolean(false));
2083
2084     target->haveABadTime(vm);
2085     return JSValue::encode(jsBoolean(true));
2086 }
2087
2088 // Checks if the object (or its global if the object is not a global) is having a bad time.
2089 // Usage: $vm.isHavingABadTime(obj)
2090 static EncodedJSValue JSC_HOST_CALL functionIsHavingABadTime(JSGlobalObject* globalObject, CallFrame* callFrame)
2091 {
2092     DollarVMAssertScope assertScope;
2093     VM& vm = globalObject->vm();
2094     JSLockHolder lock(vm);
2095     JSValue objValue = callFrame->argument(0);
2096     if (!objValue.isObject())
2097         return JSValue::encode(jsUndefined());
2098
2099     JSObject* obj = asObject(objValue.asCell());
2100     JSGlobalObject* target = jsDynamicCast<JSGlobalObject*>(vm, obj);
2101     if (target)
2102         JSValue::encode(jsBoolean(target->isHavingABadTime()));
2103
2104     target= obj->globalObject();
2105     if (!target)
2106         return JSValue::encode(jsUndefined());
2107
2108     return JSValue::encode(jsBoolean(target->isHavingABadTime()));
2109 }
2110
2111 // Calls the specified test function after adjusting the stack to have the specified
2112 // remaining size from the end of the physical stack.
2113 // Usage: $vm.callWithStackSize(funcToCall, desiredStackSize)
2114 //
2115 // This function will only work in test configurations, specifically, only if JSC
2116 // options are not frozen. For the jsc shell, the --disableOptionsFreezingForTesting
2117 // argument needs to be passed in on the command line.
2118
2119 #if ENABLE(MASM_PROBE)
2120 static void callWithStackSizeProbeFunction(Probe::State* state)
2121 {
2122     JSGlobalObject* globalObject = bitwise_cast<JSGlobalObject*>(state->arg);
2123     JSFunction* function = bitwise_cast<JSFunction*>(state->probeFunction);
2124     state->initializeStackFunction = nullptr;
2125     state->initializeStackArg = nullptr;
2126
2127     DollarVMAssertScope assertScope;
2128     VM& vm = globalObject->vm();
2129
2130     CallData callData;
2131     CallType callType = getCallData(vm, function, callData);
2132     MarkedArgumentBuffer args;
2133     call(globalObject, function, callType, callData, jsUndefined(), args);
2134 }
2135 #endif // ENABLE(MASM_PROBE)
2136
2137 SUPPRESS_ASAN
2138 static EncodedJSValue JSC_HOST_CALL functionCallWithStackSize(JSGlobalObject* globalObject, CallFrame* callFrame)
2139 {
2140     DollarVMAssertScope assertScope;
2141     VM& vm = globalObject->vm();
2142     JSLockHolder lock(vm);
2143     auto throwScope = DECLARE_THROW_SCOPE(vm);
2144
2145 #if OS(DARWIN) && CPU(X86_64)
2146     constexpr bool isSupportedByPlatform = true;
2147 #else
2148     constexpr bool isSupportedByPlatform = false;
2149 #endif
2150
2151     if (!isSupportedByPlatform)
2152         return throwVMError(globalObject, throwScope, "Not supported for this platform");
2153
2154 #if ENABLE(MASM_PROBE)
2155     if (g_jscConfig.isPermanentlyFrozen || !g_jscConfig.disabledFreezingForTesting)
2156         return throwVMError(globalObject, throwScope, "Options are frozen");
2157
2158     if (callFrame->argumentCount() < 2)
2159         return throwVMError(globalObject, throwScope, "Invalid number of arguments");
2160     JSValue arg0 = callFrame->argument(0);
2161     JSValue arg1 = callFrame->argument(1);
2162     if (!arg0.isFunction(vm))
2163         return throwVMError(globalObject, throwScope, "arg0 should be a function");
2164     if (!arg1.isNumber())
2165         return throwVMError(globalObject, throwScope, "arg1 should be a number");
2166
2167     JSFunction* function = jsCast<JSFunction*>(arg0);
2168     size_t desiredStackSize = arg1.asNumber();
2169
2170     const StackBounds& bounds = Thread::current().stack();
2171     uint8_t* currentStackPosition = bitwise_cast<uint8_t*>(currentStackPointer());
2172     uint8_t* end = bitwise_cast<uint8_t*>(bounds.end());
2173     uint8_t* desiredStart = end + desiredStackSize;
2174     if (desiredStart >= currentStackPosition)
2175         return throwVMError(globalObject, throwScope, "Unable to setup desired stack size");
2176
2177     JSDollarVMHelper helper(vm);
2178
2179     unsigned originalMaxPerThreadStackUsage = Options::maxPerThreadStackUsage();
2180     void* originalVMSoftStackLimit = vm.softStackLimit();
2181     void* originalVMStackLimit = vm.stackLimit();
2182
2183     // This is a hack to make the VM think it's stack limits are near the end
2184     // of the physical stack.
2185     uint8_t* vmStackStart = bitwise_cast<uint8_t*>(vm.stackPointerAtVMEntry());
2186     uint8_t* vmStackEnd = vmStackStart - originalMaxPerThreadStackUsage;
2187     ptrdiff_t sizeDiff = vmStackEnd - end;
2188     RELEASE_ASSERT(sizeDiff >= 0);
2189     RELEASE_ASSERT(sizeDiff < UINT_MAX);
2190
2191     Options::maxPerThreadStackUsage() = originalMaxPerThreadStackUsage + sizeDiff;
2192     helper.updateVMStackLimits();
2193
2194 #if OS(DARWIN) && CPU(X86_64)
2195     __asm__ volatile (
2196         "subq %[sizeDiff], %%rsp" "\n"
2197         "pushq %%rax" "\n"
2198         "pushq %%rcx" "\n"
2199         "pushq %%rdx" "\n"
2200         "pushq %%rbx" "\n"
2201         "callq *%%rax" "\n"
2202         "addq %[sizeDiff], %%rsp" "\n"
2203         :
2204         : "a" (ctiMasmProbeTrampoline)
2205         , "c" (callWithStackSizeProbeFunction)
2206         , "d" (function)
2207         , "b" (globalObject)
2208         , [sizeDiff] "rm" (sizeDiff)
2209         : "memory"
2210     );
2211 #else
2212     UNUSED_PARAM(function);
2213 #if !COMPILER(MSVC)
2214     UNUSED_PARAM(callWithStackSizeProbeFunction);
2215 #endif
2216 #endif // OS(DARWIN) && CPU(X86_64)
2217
2218     Options::maxPerThreadStackUsage() = originalMaxPerThreadStackUsage;
2219     helper.updateVMStackLimits();
2220     RELEASE_ASSERT(vm.softStackLimit() == originalVMSoftStackLimit);
2221     RELEASE_ASSERT(vm.stackLimit() == originalVMStackLimit);
2222
2223     throwScope.release();
2224     return encodedJSUndefined();
2225
2226 #else // not ENABLE(MASM_PROBE)
2227     UNUSED_PARAM(callFrame);
2228     return throwVMError(globalObject, throwScope, "Not supported for this platform");
2229 #endif // ENABLE(MASM_PROBE)
2230 }
2231
2232 // Creates a new global object.
2233 // Usage: $vm.createGlobalObject()
2234 static EncodedJSValue JSC_HOST_CALL functionCreateGlobalObject(JSGlobalObject* globalObject, CallFrame*)
2235 {
2236     DollarVMAssertScope assertScope;
2237     VM& vm = globalObject->vm();
2238     JSLockHolder lock(vm);
2239     return JSValue::encode(JSGlobalObject::create(vm, JSGlobalObject::createStructure(vm, jsNull())));
2240 }
2241
2242 static EncodedJSValue JSC_HOST_CALL functionCreateProxy(JSGlobalObject* globalObject, CallFrame* callFrame)
2243 {
2244     DollarVMAssertScope assertScope;
2245     VM& vm = globalObject->vm();
2246     JSLockHolder lock(vm);
2247     JSValue target = callFrame->argument(0);
2248     if (!target.isObject())
2249         return JSValue::encode(jsUndefined());
2250     JSObject* jsTarget = asObject(target.asCell());
2251     Structure* structure = JSProxy::createStructure(vm, globalObject, jsTarget->getPrototypeDirect(vm), ImpureProxyType);
2252     JSProxy* proxy = JSProxy::create(vm, structure, jsTarget);
2253     return JSValue::encode(proxy);
2254 }
2255
2256 static EncodedJSValue JSC_HOST_CALL functionCreateRuntimeArray(JSGlobalObject* globalObject, CallFrame* callFrame)
2257 {
2258     DollarVMAssertScope assertScope;
2259     JSLockHolder lock(globalObject);
2260     RuntimeArray* array = RuntimeArray::create(globalObject, callFrame);
2261     return JSValue::encode(array);
2262 }
2263
2264 static EncodedJSValue JSC_HOST_CALL functionCreateNullRopeString(JSGlobalObject* globalObject, CallFrame*)
2265 {
2266     DollarVMAssertScope assertScope;
2267     VM& vm = globalObject->vm();
2268     JSLockHolder lock(vm);
2269     return JSValue::encode(JSRopeString::createNullForTesting(vm));
2270 }
2271
2272 static EncodedJSValue JSC_HOST_CALL functionCreateImpureGetter(JSGlobalObject* globalObject, CallFrame* callFrame)
2273 {
2274     DollarVMAssertScope assertScope;
2275     VM& vm = globalObject->vm();
2276     JSLockHolder lock(vm);
2277     JSValue target = callFrame->argument(0);
2278     JSObject* delegate = nullptr;
2279     if (target.isObject())
2280         delegate = asObject(target.asCell());
2281     Structure* structure = ImpureGetter::createStructure(vm, globalObject, jsNull());
2282     ImpureGetter* result = ImpureGetter::create(vm, structure, delegate);
2283     return JSValue::encode(result);
2284 }
2285
2286 static EncodedJSValue JSC_HOST_CALL functionCreateCustomGetterObject(JSGlobalObject* globalObject, CallFrame*)
2287 {
2288     DollarVMAssertScope assertScope;
2289     VM& vm = globalObject->vm();
2290     JSLockHolder lock(vm);
2291     Structure* structure = CustomGetter::createStructure(vm, globalObject, jsNull());
2292     CustomGetter* result = CustomGetter::create(vm, structure);
2293     return JSValue::encode(result);
2294 }
2295
2296 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITNodeObject(JSGlobalObject* globalObject, CallFrame*)
2297 {
2298     DollarVMAssertScope assertScope;
2299     VM& vm = globalObject->vm();
2300     JSLockHolder lock(vm);
2301     Structure* structure = DOMJITNode::createStructure(vm, globalObject, DOMJITGetter::create(vm, DOMJITGetter::createStructure(vm, globalObject, jsNull())));
2302     DOMJITNode* result = DOMJITNode::create(vm, structure);
2303     return JSValue::encode(result);
2304 }
2305
2306 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterObject(JSGlobalObject* globalObject, CallFrame*)
2307 {
2308     DollarVMAssertScope assertScope;
2309     VM& vm = globalObject->vm();
2310     JSLockHolder lock(vm);
2311     Structure* structure = DOMJITGetter::createStructure(vm, globalObject, jsNull());
2312     DOMJITGetter* result = DOMJITGetter::create(vm, structure);
2313     return JSValue::encode(result);
2314 }
2315
2316 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterComplexObject(JSGlobalObject* globalObject, CallFrame*)
2317 {
2318     DollarVMAssertScope assertScope;
2319     VM& vm = globalObject->vm();
2320     JSLockHolder lock(vm);
2321     Structure* structure = DOMJITGetterComplex::createStructure(vm, globalObject, jsNull());
2322     DOMJITGetterComplex* result = DOMJITGetterComplex::create(vm, globalObject, structure);
2323     return JSValue::encode(result);
2324 }
2325
2326 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITFunctionObject(JSGlobalObject* globalObject, CallFrame*)
2327 {
2328     DollarVMAssertScope assertScope;
2329     VM& vm = globalObject->vm();
2330     JSLockHolder lock(vm);
2331     Structure* structure = DOMJITFunctionObject::createStructure(vm, globalObject, jsNull());
2332     DOMJITFunctionObject* result = DOMJITFunctionObject::create(vm, globalObject, structure);
2333     return JSValue::encode(result);
2334 }
2335
2336 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITCheckSubClassObject(JSGlobalObject* globalObject, CallFrame*)
2337 {
2338     DollarVMAssertScope assertScope;
2339     VM& vm = globalObject->vm();
2340     JSLockHolder lock(vm);
2341     Structure* structure = DOMJITCheckSubClassObject::createStructure(vm, globalObject, jsNull());
2342     DOMJITCheckSubClassObject* result = DOMJITCheckSubClassObject::create(vm, globalObject, structure);
2343     return JSValue::encode(result);
2344 }
2345
2346 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterBaseJSObject(JSGlobalObject* globalObject, CallFrame*)
2347 {
2348     DollarVMAssertScope assertScope;
2349     VM& vm = globalObject->vm();
2350     JSLockHolder lock(vm);
2351     Structure* structure = DOMJITGetterBaseJSObject::createStructure(vm, globalObject, jsNull());
2352     DOMJITGetterBaseJSObject* result = DOMJITGetterBaseJSObject::create(vm, structure);
2353     return JSValue::encode(result);
2354 }
2355
2356 #if ENABLE(WEBASSEMBLY)
2357 static EncodedJSValue JSC_HOST_CALL functionCreateWasmStreamingParser(JSGlobalObject* globalObject, CallFrame*)
2358 {
2359     DollarVMAssertScope assertScope;
2360     VM& vm = globalObject->vm();
2361     JSLockHolder lock(vm);
2362     return JSValue::encode(WasmStreamingParser::create(vm, globalObject));
2363 }
2364 #endif
2365
2366 static EncodedJSValue JSC_HOST_CALL functionCreateStaticCustomAccessor(JSGlobalObject* globalObject, CallFrame*)
2367 {
2368     DollarVMAssertScope assertScope;
2369     VM& vm = globalObject->vm();
2370     JSLockHolder lock(vm);
2371     Structure* structure = StaticCustomAccessor::createStructure(vm, globalObject, jsNull());
2372     auto* result = StaticCustomAccessor::create(vm, structure);
2373     return JSValue::encode(result);
2374 }
2375
2376 static EncodedJSValue JSC_HOST_CALL functionCreateObjectDoingSideEffectPutWithoutCorrectSlotStatus(JSGlobalObject* globalObject, CallFrame* callFrame)
2377 {
2378     DollarVMAssertScope assertScope;
2379     VM& vm = globalObject->vm();
2380     JSLockHolder lock(vm);
2381
2382     auto* dollarVM = jsDynamicCast<JSDollarVM*>(vm, callFrame->thisValue());
2383     RELEASE_ASSERT(dollarVM);
2384     auto* result = ObjectDoingSideEffectPutWithoutCorrectSlotStatus::create(vm, dollarVM->objectDoingSideEffectPutWithoutCorrectSlotStatusStructure());
2385     return JSValue::encode(result);
2386 }
2387
2388 static EncodedJSValue JSC_HOST_CALL functionCreateEmptyFunctionWithName(JSGlobalObject* globalObject, CallFrame* callFrame)
2389 {
2390     DollarVMAssertScope assertScope;
2391     VM& vm = globalObject->vm();
2392     JSLockHolder lock(vm);
2393     auto scope = DECLARE_THROW_SCOPE(vm);
2394
2395     const String name = callFrame->argument(0).toWTFString(globalObject);
2396     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2397
2398     RELEASE_AND_RETURN(scope, JSValue::encode(JSFunction::create(vm, globalObject, 1, name, functionCreateEmptyFunctionWithName)));
2399 }
2400
2401 static EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(JSGlobalObject* globalObject, CallFrame* callFrame)
2402 {
2403     DollarVMAssertScope assertScope;
2404     VM& vm = globalObject->vm();
2405     JSLockHolder lock(vm);
2406     auto scope = DECLARE_THROW_SCOPE(vm);
2407
2408     JSValue base = callFrame->argument(0);
2409     if (!base.isObject())
2410         return JSValue::encode(jsUndefined());
2411     JSValue delegate = callFrame->argument(1);
2412     if (!delegate.isObject())
2413         return JSValue::encode(jsUndefined());
2414     ImpureGetter* impureGetter = jsDynamicCast<ImpureGetter*>(vm, asObject(base.asCell()));
2415     if (UNLIKELY(!impureGetter)) {
2416         throwTypeError(globalObject, scope, "argument is not an ImpureGetter"_s);
2417         return encodedJSValue();
2418     }
2419     impureGetter->setDelegate(vm, asObject(delegate.asCell()));
2420     return JSValue::encode(jsUndefined());
2421 }
2422
2423 static EncodedJSValue JSC_HOST_CALL functionCreateBuiltin(JSGlobalObject* globalObject, CallFrame* callFrame)
2424 {
2425     DollarVMAssertScope assertScope;
2426     VM& vm = globalObject->vm();
2427     auto scope = DECLARE_THROW_SCOPE(vm);
2428
2429     if (callFrame->argumentCount() < 1 || !callFrame->argument(0).isString())
2430         return JSValue::encode(jsUndefined());
2431
2432     String functionText = asString(callFrame->argument(0))->value(globalObject);
2433     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2434
2435     SourceCode source = makeSource(functionText, { });
2436     JSFunction* func = JSFunction::create(vm, createBuiltinExecutable(vm, source, Identifier::fromString(vm, "foo"), ConstructorKind::None, ConstructAbility::CannotConstruct)->link(vm, nullptr, source), globalObject);
2437
2438     return JSValue::encode(func);
2439 }
2440
2441 static EncodedJSValue JSC_HOST_CALL functionGetPrivateProperty(JSGlobalObject* globalObject, CallFrame* callFrame)
2442 {
2443     DollarVMAssertScope assertScope;
2444     VM& vm = globalObject->vm();
2445     auto scope = DECLARE_THROW_SCOPE(vm);
2446
2447     if (callFrame->argumentCount() < 2 || !callFrame->argument(1).isString())
2448         return encodedJSUndefined();
2449
2450     String str = asString(callFrame->argument(1))->value(globalObject);
2451     RETURN_IF_EXCEPTION(scope, encodedJSValue());
2452
2453     SymbolImpl* symbol = vm.propertyNames->builtinNames().lookUpPrivateName(str);
2454     if (!symbol)
2455         return throwVMError(globalObject, scope, "Unknown private name.");
2456
2457     RELEASE_AND_RETURN(scope, JSValue::encode(callFrame->argument(0).get(globalObject, symbol)));
2458 }
2459
2460 static EncodedJSValue JSC_HOST_CALL functionCreateRoot(JSGlobalObject* globalObject, CallFrame*)
2461 {
2462     DollarVMAssertScope assertScope;
2463     VM& vm = globalObject->vm();
2464     JSLockHolder lock(vm);
2465     return JSValue::encode(Root::create(vm, globalObject));
2466 }
2467
2468 static EncodedJSValue JSC_HOST_CALL functionCreateElement(JSGlobalObject* globalObject, CallFrame* callFrame)
2469 {
2470     DollarVMAssertScope assertScope;
2471     VM& vm = globalObject->vm();
2472     JSLockHolder lock(vm);
2473     auto scope = DECLARE_THROW_SCOPE(vm);
2474
2475     Root* root = jsDynamicCast<Root*>(vm, callFrame->argument(0));
2476     if (!root)
2477         return JSValue::encode(throwException(globalObject, scope, createError(globalObject, "Cannot create Element without a Root."_s)));
2478     return JSValue::encode(Element::create(vm, globalObject, root));
2479 }
2480
2481 static EncodedJSValue JSC_HOST_CALL functionGetElement(JSGlobalObject* globalObject, CallFrame* callFrame)
2482 {
2483     DollarVMAssertScope assertScope;
2484     VM& vm = globalObject->vm();
2485     JSLockHolder lock(vm);
2486     Root* root = jsDynamicCast<Root*>(vm, callFrame->argument(0));
2487     if (!root)
2488         return JSValue::encode(jsUndefined());
2489     Element* result = root->element();
2490     return JSValue::encode(result ? result : jsUndefined());
2491 }
2492
2493 static EncodedJSValue JSC_HOST_CALL functionCreateSimpleObject(JSGlobalObject* globalObject, CallFrame*)
2494 {
2495     DollarVMAssertScope assertScope;
2496     VM& vm = globalObject->vm();
2497     JSLockHolder lock(vm);
2498     return JSValue::encode(SimpleObject::create(vm, globalObject));
2499 }
2500
2501 static EncodedJSValue JSC_HOST_CALL functionGetHiddenValue(JSGlobalObject* globalObject, CallFrame* callFrame)
2502 {
2503     DollarVMAssertScope assertScope;
2504     VM& vm = globalObject->vm();
2505     JSLockHolder lock(vm);
2506     auto scope = DECLARE_THROW_SCOPE(vm);
2507
2508     SimpleObject* simpleObject = jsDynamicCast<SimpleObject*>(vm, callFrame->argument(0));
2509     if (UNLIKELY(!simpleObject)) {
2510         throwTypeError(globalObject, scope, "Invalid use of getHiddenValue test function"_s);
2511         return encodedJSValue();
2512     }
2513     return JSValue::encode(simpleObject->hiddenValue());
2514 }
2515
2516 static EncodedJSValue JSC_HOST_CALL functionSetHiddenValue(JSGlobalObject* globalObject, CallFrame* callFrame)
2517 {
2518     DollarVMAssertScope assertScope;
2519     VM& vm = globalObject->vm();
2520     JSLockHolder lock(vm);
2521     auto scope = DECLARE_THROW_SCOPE(vm);
2522
2523     SimpleObject* simpleObject = jsDynamicCast<SimpleObject*>(vm, callFrame->argument(0));
2524     if (UNLIKELY(!simpleObject)) {
2525         throwTypeError(globalObject, scope, "Invalid use of setHiddenValue test function"_s);
2526         return encodedJSValue();
2527     }
2528     JSValue value = callFrame->argument(1);
2529     simpleObject->setHiddenValue(vm, value);
2530     return JSValue::encode(jsUndefined());
2531 }
2532
2533 static EncodedJSValue JSC_HOST_CALL functionShadowChickenFunctionsOnStack(JSGlobalObject* globalObject, CallFrame* callFrame)
2534 {
2535     DollarVMAssertScope assertScope;
2536     VM& vm = globalObject->vm();
2537     auto scope = DECLARE_THROW_SCOPE(vm);
2538     if (auto* shadowChicken = vm.shadowChicken()) {
2539         scope.release();
2540         return JSValue::encode(shadowChicken->functionsOnStack(globalObject, callFrame));
2541     }
2542
2543     JSArray* result = constructEmptyArray(globalObject, 0);
2544     RETURN_IF_EXCEPTION(scope, { });
2545     StackVisitor::visit(callFrame, vm, [&] (StackVisitor& visitor) -> StackVisitor::Status {
2546         DollarVMAssertScope assertScope;
2547         if (visitor->isInlinedFrame())
2548             return StackVisitor::Continue;
2549         if (visitor->isWasmFrame())
2550             return StackVisitor::Continue;
2551         result->push(globalObject, jsCast<JSObject*>(visitor->callee().asCell()));
2552         scope.releaseAssertNoException(); // This function is only called from tests.
2553         return StackVisitor::Continue;
2554     });
2555     RETURN_IF_EXCEPTION(scope, { });
2556     return JSValue::encode(result);
2557 }
2558
2559 static EncodedJSValue JSC_HOST_CALL functionSetGlobalConstRedeclarationShouldNotThrow(JSGlobalObject* globalObject, CallFrame*)
2560 {
2561     DollarVMAssertScope assertScope;
2562     VM& vm = globalObject->vm();
2563     vm.setGlobalConstRedeclarationShouldThrow(false);
2564     return JSValue::encode(jsUndefined());
2565 }
2566
2567 static EncodedJSValue JSC_HOST_CALL functionFindTypeForExpression(JSGlobalObject* globalObject, CallFrame* callFrame)
2568 {
2569     DollarVMAssertScope assertScope;
2570     VM& vm = globalObject->vm();
2571     RELEASE_ASSERT(vm.typeProfiler());
2572     vm.typeProfilerLog()->processLogEntries(vm, "jsc Testing API: functionFindTypeForExpression"_s);
2573
2574     JSValue functionValue = callFrame->argument(0);
2575     RELEASE_ASSERT(functionValue.isFunction(vm));
2576     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
2577
2578     RELEASE_ASSERT(callFrame->argument(1).isString());
2579     String substring = asString(callFrame->argument(1))->value(globalObject);
2580     String sourceCodeText = executable->source().view().toString();
2581     unsigned offset = static_cast<unsigned>(sourceCodeText.find(substring) + executable->source().startOffset());
2582     
2583     String jsonString = vm.typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorNormal, offset, executable->sourceID(), vm);
2584     return JSValue::encode(JSONParse(globalObject, jsonString));
2585 }
2586
2587 static EncodedJSValue JSC_HOST_CALL functionReturnTypeFor(JSGlobalObject* globalObject, CallFrame* callFrame)
2588 {
2589     DollarVMAssertScope assertScope;
2590     VM& vm = globalObject->vm();
2591     RELEASE_ASSERT(vm.typeProfiler());
2592     vm.typeProfilerLog()->processLogEntries(vm, "jsc Testing API: functionReturnTypeFor"_s);
2593
2594     JSValue functionValue = callFrame->argument(0);
2595     RELEASE_ASSERT(functionValue.isFunction(vm));
2596     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
2597
2598     unsigned offset = executable->typeProfilingStartOffset(vm);
2599     String jsonString = vm.typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorFunctionReturn, offset, executable->sourceID(), vm);
2600     return JSValue::encode(JSONParse(globalObject, jsonString));
2601 }
2602
2603 static EncodedJSValue JSC_HOST_CALL functionFlattenDictionaryObject(JSGlobalObject* globalObject, CallFrame* callFrame)
2604 {
2605     DollarVMAssertScope assertScope;
2606     VM& vm = globalObject->vm();
2607     JSValue value = callFrame->argument(0);
2608     RELEASE_ASSERT(value.isObject() && value.getObject()->structure()->isDictionary());
2609     value.getObject()->flattenDictionaryObject(vm);
2610     return encodedJSUndefined();
2611 }
2612
2613 static EncodedJSValue JSC_HOST_CALL functionDumpBasicBlockExecutionRanges(JSGlobalObject* globalObject, CallFrame*)
2614 {
2615     DollarVMAssertScope assertScope;
2616     VM& vm = globalObject->vm();
2617     RELEASE_ASSERT(vm.controlFlowProfiler());
2618     vm.controlFlowProfiler()->dumpData();
2619     return JSValue::encode(jsUndefined());
2620 }
2621
2622 static EncodedJSValue JSC_HOST_CALL functionHasBasicBlockExecuted(JSGlobalObject* globalObject, CallFrame* callFrame)
2623 {
2624     DollarVMAssertScope assertScope;
2625     VM& vm = globalObject->vm();
2626     RELEASE_ASSERT(vm.controlFlowProfiler());
2627
2628     JSValue functionValue = callFrame->argument(0);
2629     RELEASE_ASSERT(functionValue.isFunction(vm));
2630     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
2631
2632     RELEASE_ASSERT(callFrame->argument(1).isString());
2633     String substring = asString(callFrame->argument(1))->value(globalObject);
2634     String sourceCodeText = executable->source().view().toString();
2635     RELEASE_ASSERT(sourceCodeText.contains(substring));
2636     int offset = sourceCodeText.find(substring) + executable->source().startOffset();
2637     
2638     bool hasExecuted = vm.controlFlowProfiler()->hasBasicBlockAtTextOffsetBeenExecuted(offset, executable->sourceID(), vm);
2639     return JSValue::encode(jsBoolean(hasExecuted));
2640 }
2641
2642 static EncodedJSValue JSC_HOST_CALL functionBasicBlockExecutionCount(JSGlobalObject* globalObject, CallFrame* callFrame)
2643 {
2644     DollarVMAssertScope assertScope;
2645     VM& vm = globalObject->vm();
2646     RELEASE_ASSERT(vm.controlFlowProfiler());
2647
2648     JSValue functionValue = callFrame->argument(0);
2649     RELEASE_ASSERT(functionValue.isFunction(vm));
2650     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
2651
2652     RELEASE_ASSERT(callFrame->argument(1).isString());
2653     String substring = asString(callFrame->argument(1))->value(globalObject);
2654     String sourceCodeText = executable->source().view().toString();
2655     RELEASE_ASSERT(sourceCodeText.contains(substring));
2656     int offset = sourceCodeText.find(substring) + executable->source().startOffset();
2657     
2658     size_t executionCount = vm.controlFlowProfiler()->basicBlockExecutionCountAtTextOffset(offset, executable->sourceID(), vm);
2659     return JSValue::encode(JSValue(executionCount));
2660 }
2661
2662 static EncodedJSValue JSC_HOST_CALL functionEnableExceptionFuzz(JSGlobalObject*, CallFrame*)
2663 {
2664     DollarVMAssertScope assertScope;
2665     Options::useExceptionFuzz() = true;
2666     return JSValue::encode(jsUndefined());
2667 }
2668
2669 class DoNothingDebugger final : public Debugger {
2670     WTF_MAKE_NONCOPYABLE(DoNothingDebugger);
2671     WTF_MAKE_FAST_ALLOCATED;
2672 public:
2673     DoNothingDebugger(VM& vm)
2674         : Debugger(vm)
2675     {
2676         DollarVMAssertScope assertScope;
2677         setSuppressAllPauses(true);
2678     }
2679
2680 private:
2681     void sourceParsed(JSGlobalObject*, SourceProvider*, int, const WTF::String&) override
2682     {
2683         DollarVMAssertScope assertScope;
2684     }
2685 };
2686
2687 static EncodedJSValue changeDebuggerModeWhenIdle(JSGlobalObject* globalObject, OptionSet<CodeGenerationMode> codeGenerationMode)
2688 {
2689     DollarVMAssertScope assertScope;
2690
2691     bool debuggerRequested = codeGenerationMode.contains(CodeGenerationMode::Debugger);
2692     if (debuggerRequested == globalObject->hasDebugger())
2693         return JSValue::encode(jsUndefined());
2694
2695     VM* vm = &globalObject->vm();
2696     vm->whenIdle([=] () {
2697         DollarVMAssertScope assertScope;
2698         if (debuggerRequested) {
2699             Debugger* debugger = new DoNothingDebugger(globalObject->vm());
2700             globalObject->setDebugger(debugger);
2701             debugger->activateBreakpoints(); // Also deletes all code.
2702         } else {
2703             Debugger* debugger = globalObject->debugger();
2704             debugger->deactivateBreakpoints(); // Also deletes all code.
2705             globalObject->setDebugger(nullptr);
2706             delete debugger;
2707         }
2708     });
2709     return JSValue::encode(jsUndefined());
2710 }
2711
2712 static EncodedJSValue JSC_HOST_CALL functionEnableDebuggerModeWhenIdle(JSGlobalObject* globalObject, CallFrame*)
2713 {
2714     DollarVMAssertScope assertScope;
2715     return changeDebuggerModeWhenIdle(globalObject, { CodeGenerationMode::Debugger });
2716 }
2717
2718 static EncodedJSValue JSC_HOST_CALL functionDisableDebuggerModeWhenIdle(JSGlobalObject* globalObject, CallFrame*)
2719 {
2720     DollarVMAssertScope assertScope;
2721     return changeDebuggerModeWhenIdle(globalObject, { });
2722 }
2723
2724 static EncodedJSValue JSC_HOST_CALL functionDeleteAllCodeWhenIdle(JSGlobalObject* globalObject, CallFrame*)
2725 {
2726     DollarVMAssertScope assertScope;
2727     VM* vm = &globalObject->vm();
2728     vm->whenIdle([=] () {
2729         DollarVMAssertScope assertScope;
2730         vm->deleteAllCode(PreventCollectionAndDeleteAllCode);
2731     });
2732     return JSValue::encode(jsUndefined());
2733 }
2734
2735 static EncodedJSValue JSC_HOST_CALL functionGlobalObjectCount(JSGlobalObject* globalObject, CallFrame*)
2736 {
2737     DollarVMAssertScope assertScope;
2738     return JSValue::encode(jsNumber(globalObject->vm().heap.globalObjectCount()));
2739 }
2740
2741 static EncodedJSValue JSC_HOST_CALL functionGlobalObjectForObject(JSGlobalObject* globalObject, CallFrame* callFrame)
2742 {
2743     DollarVMAssertScope assertScope;
2744     JSValue value = callFrame->argument(0);
2745     RELEASE_ASSERT(value.isObject());
2746     JSGlobalObject* result = jsCast<JSObject*>(value)->globalObject(globalObject->vm());
2747     RELEASE_ASSERT(result);
2748     return JSValue::encode(result);
2749 }
2750
2751 static EncodedJSValue JSC_HOST_CALL functionGetGetterSetter(JSGlobalObject* globalObject, CallFrame* callFrame)
2752 {
2753     DollarVMAssertScope assertScope;
2754     VM& vm = globalObject->vm();
2755     auto scope = DECLARE_THROW_SCOPE(vm);
2756
2757     JSValue value = callFrame->argument(0);
2758     if (!value.isObject())
2759         return JSValue::encode(jsUndefined());
2760
2761     JSValue property = callFrame->argument(1);
2762     if (!property.isString())
2763         return JSValue::encode(jsUndefined());
2764
2765     auto propertyName = asString(property)->toIdentifier(globalObject);
2766     RETURN_IF_EXCEPTION(scope, { });
2767
2768     PropertySlot slot(value, PropertySlot::InternalMethodType::VMInquiry);
2769     value.getPropertySlot(globalObject, propertyName, slot);
2770     RETURN_IF_EXCEPTION(scope, { });
2771
2772     JSValue result;
2773     if (slot.isCacheableGetter())
2774         result = slot.getterSetter();
2775     else
2776         result = jsNull();
2777
2778     return JSValue::encode(result);
2779 }
2780
2781 static EncodedJSValue JSC_HOST_CALL functionLoadGetterFromGetterSetter(JSGlobalObject* globalObject, CallFrame* callFrame)
2782 {
2783     DollarVMAssertScope assertScope;
2784     VM& vm = globalObject->vm();
2785     auto scope = DECLARE_THROW_SCOPE(vm);
2786
2787     GetterSetter* getterSetter = jsDynamicCast<GetterSetter*>(vm, callFrame->argument(0));
2788     if (UNLIKELY(!getterSetter)) {
2789         throwTypeError(globalObject, scope, "Invalid use of loadGetterFromGetterSetter test function: argument is not a GetterSetter"_s);
2790         return encodedJSValue();
2791     }
2792
2793     JSObject* getter = getterSetter->getter();
2794     RELEASE_ASSERT(getter);
2795     return JSValue::encode(getter);
2796 }
2797
2798 static EncodedJSValue JSC_HOST_CALL functionCreateCustomTestGetterSetter(JSGlobalObject* globalObject, CallFrame*)
2799 {
2800     DollarVMAssertScope assertScope;
2801     VM& vm = globalObject->vm();
2802     return JSValue::encode(JSTestCustomGetterSetter::create(vm, globalObject, JSTestCustomGetterSetter::createStructure(vm, globalObject)));
2803 }
2804
2805 static EncodedJSValue JSC_HOST_CALL functionDeltaBetweenButterflies(JSGlobalObject* globalObject, CallFrame* callFrame)
2806 {
2807     DollarVMAssertScope assertScope;
2808     VM& vm = globalObject->vm();
2809     JSObject* a = jsDynamicCast<JSObject*>(vm, callFrame->argument(0));
2810     JSObject* b = jsDynamicCast<JSObject*>(vm, callFrame->argument(1));
2811     if (!a || !b)
2812         return JSValue::encode(jsNumber(PNaN));
2813
2814     ptrdiff_t delta = bitwise_cast<char*>(a->butterfly()) - bitwise_cast<char*>(b->butterfly());
2815     if (delta < 0)
2816         return JSValue::encode(jsNumber(PNaN));
2817     if (delta > std::numeric_limits<int32_t>::max())
2818         return JSValue::encode(jsNumber(PNaN));
2819     return JSValue::encode(jsNumber(static_cast<int32_t>(delta)));
2820 }
2821
2822 static EncodedJSValue JSC_HOST_CALL functionCurrentCPUTime(JSGlobalObject*, CallFrame*)
2823 {
2824     DollarVMAssertScope assertScope;
2825     return JSValue::encode(jsNumber(CPUTime::forCurrentThread().value()));
2826 }
2827
2828 static EncodedJSValue JSC_HOST_CALL functionTotalGCTime(JSGlobalObject* globalObject, CallFrame*)
2829 {
2830     DollarVMAssertScope assertScope;
2831     VM& vm = globalObject->vm();
2832     return JSValue::encode(jsNumber(vm.heap.totalGCTime().seconds()));
2833 }
2834
2835 static EncodedJSValue JSC_HOST_CALL functionParseCount(JSGlobalObject*, CallFrame*)
2836 {
2837     DollarVMAssertScope assertScope;
2838     return JSValue::encode(jsNumber(globalParseCount.load()));
2839 }
2840
2841 static EncodedJSValue JSC_HOST_CALL functionIsWasmSupported(JSGlobalObject*, CallFrame*)
2842 {
2843     DollarVMAssertScope assertScope;
2844 #if ENABLE(WEBASSEMBLY)
2845     return JSValue::encode(jsBoolean(Wasm::isSupported()));
2846 #else
2847     return JSValue::encode(jsBoolean(false));
2848 #endif
2849 }
2850
2851 static EncodedJSValue JSC_HOST_CALL functionMake16BitStringIfPossible(JSGlobalObject* globalObject, CallFrame* callFrame)
2852 {
2853     DollarVMAssertScope assertScope;
2854     VM& vm = globalObject->vm();
2855     auto scope = DECLARE_THROW_SCOPE(vm);
2856     String string = callFrame->argument(0).toWTFString(globalObject);
2857     RETURN_IF_EXCEPTION(scope, { });
2858     if (!string.is8Bit())
2859         return JSValue::encode(jsString(vm, WTFMove(string)));
2860     Vector<UChar> buffer;
2861     buffer.resize(string.length());
2862     StringImpl::copyCharacters(buffer.data(), string.characters8(), string.length());
2863     return JSValue::encode(jsString(vm, String::adopt(WTFMove(buffer))));
2864 }
2865
2866 EncodedJSValue JSC_HOST_CALL JSDollarVMHelper::functionGetStructureTransitionList(JSGlobalObject* globalObject, CallFrame* callFrame)
2867 {
2868     DollarVMAssertScope assertScope;
2869     VM& vm = globalObject->vm();
2870     auto scope = DECLARE_THROW_SCOPE(vm);
2871     JSObject* obj = callFrame->argument(0).toObject(globalObject);
2872     RETURN_IF_EXCEPTION(scope, { });
2873     if (!obj)
2874         return JSValue::encode(jsNull());
2875     Vector<Structure*, 8> structures;
2876
2877     for (auto* structure = obj->structure(); structure; structure = structure->previousID(vm))
2878         structures.append(structure);
2879
2880     JSArray* result = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), 0);
2881     RETURN_IF_EXCEPTION(scope, { });
2882
2883     for (size_t i = 0; i < structures.size(); ++i) {
2884         auto* structure = structures[structures.size() - i - 1];
2885         result->push(globalObject, JSValue(structure->id()));
2886         RETURN_IF_EXCEPTION(scope, { });
2887         result->push(globalObject, JSValue(structure->transitionOffset()));
2888         RETURN_IF_EXCEPTION(scope, { });
2889         result->push(globalObject, JSValue(structure->maxOffset()));
2890         RETURN_IF_EXCEPTION(scope, { });
2891         if (auto* transitionPropertyName = structure->transitionPropertyName())
2892             result->push(globalObject, jsString(vm, String(*transitionPropertyName)));
2893         else
2894             result->push(globalObject, jsNull());
2895         RETURN_IF_EXCEPTION(scope, { });
2896         result->push(globalObject, JSValue(structure->isPropertyDeletionTransition()));
2897         RETURN_IF_EXCEPTION(scope, { });
2898     }
2899
2900     return JSValue::encode(result);
2901 }
2902
2903 static EncodedJSValue JSC_HOST_CALL functionGetConcurrently(JSGlobalObject* globalObject, CallFrame* callFrame)
2904 {
2905     DollarVMAssertScope assertScope;
2906     VM& vm = globalObject->vm();
2907     auto scope = DECLARE_THROW_SCOPE(vm);
2908     JSObject* obj = callFrame->argument(0).toObject(globalObject);
2909     RETURN_IF_EXCEPTION(scope, { });
2910     if (!obj)
2911         return JSValue::encode(jsNull());
2912     String property = callFrame->argument(1).toWTFString(globalObject);
2913     RETURN_IF_EXCEPTION(scope, { });
2914     auto name = PropertyName(Identifier::fromString(vm, property));
2915     auto offset = obj->structure()->getConcurrently(name.uid());
2916     if (offset != invalidOffset)
2917         ASSERT(JSValue::encode(obj->getDirect(offset)));
2918     JSValue result = JSValue(offset != invalidOffset);
2919     RETURN_IF_EXCEPTION(scope, { });
2920     return JSValue::encode(result);
2921 }
2922
2923 static EncodedJSValue JSC_HOST_CALL functionHasOwnLengthProperty(JSGlobalObject* globalObject, CallFrame* callFrame)
2924 {
2925     VM& vm = globalObject->vm();
2926
2927     JSObject* target = asObject(callFrame->uncheckedArgument(0));
2928     JSFunction* function = jsDynamicCast<JSFunction*>(vm, target);
2929     return JSValue::encode(jsBoolean(function->canAssumeNameAndLengthAreOriginal(vm)));
2930 }
2931
2932 static EncodedJSValue JSC_HOST_CALL functionRejectPromiseAsHandled(JSGlobalObject* globalObject, CallFrame* callFrame)
2933 {
2934     JSPromise* promise = jsCast<JSPromise*>(callFrame->uncheckedArgument(0));
2935     JSValue reason = callFrame->uncheckedArgument(1);
2936     promise->rejectAsHandled(globalObject, reason);
2937     return JSValue::encode(jsUndefined());
2938 }
2939
2940 void JSDollarVM::finishCreation(VM& vm)
2941 {
2942     DollarVMAssertScope assertScope;
2943     Base::finishCreation(vm);
2944
2945     JSGlobalObject* globalObject = this->globalObject(vm);
2946
2947     auto addFunction = [&] (VM& vm, const char* name, NativeFunction function, unsigned arguments) {
2948         DollarVMAssertScope assertScope;
2949         JSDollarVM::addFunction(vm, globalObject, name, function, arguments);
2950     };
2951     auto addConstructibleFunction = [&] (VM& vm, const char* name, NativeFunction function, unsigned arguments) {
2952         DollarVMAssertScope assertScope;
2953         JSDollarVM::addConstructibleFunction(vm, globalObject, name, function, arguments);
2954     };
2955
2956     addFunction(vm, "abort", functionCrash, 0);
2957     addFunction(vm, "crash", functionCrash, 0);
2958     addFunction(vm, "breakpoint", functionBreakpoint, 0);
2959
2960     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "dfgTrue"), 0, functionDFGTrue, DFGTrueIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
2961     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "ftlTrue"), 0, functionFTLTrue, FTLTrueIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
2962
2963     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "cpuMfence"), 0, functionCpuMfence, CPUMfenceIntrinsic, 0);
2964     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "cpuRdtsc"), 0, functionCpuRdtsc, CPURdtscIntrinsic, 0);
2965     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "cpuCpuid"), 0, functionCpuCpuid, CPUCpuidIntrinsic, 0);
2966     putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "cpuPause"), 0, functionCpuPause, CPUPauseIntrinsic, 0);
2967     addFunction(vm, "cpuClflush", functionCpuClflush, 2);
2968
2969     addFunction(vm, "llintTrue", functionLLintTrue, 0);
2970     addFunction(vm, "jitTrue", functionJITTrue, 0);
2971
2972     addFunction(vm, "noInline", functionNoInline, 1);
2973
2974     addFunction(vm, "gc", functionGC, 0);
2975     addFunction(vm, "gcSweepAsynchronously", functionGCSweepAsynchronously, 0);
2976     addFunction(vm, "edenGC", functionEdenGC, 0);
2977     addFunction(vm, "dumpSubspaceHashes", functionDumpSubspaceHashes, 0);
2978
2979     addFunction(vm, "callFrame", functionCallFrame, 1);
2980     addFunction(vm, "codeBlockFor", functionCodeBlockFor, 1);
2981     addFunction(vm, "codeBlockForFrame", functionCodeBlockForFrame, 1);
2982     addFunction(vm, "dumpSourceFor", functionDumpSourceFor, 1);
2983     addFunction(vm, "dumpBytecodeFor", functionDumpBytecodeFor, 1);
2984
2985     addFunction(vm, "dataLog", functionDataLog, 1);
2986     addFunction(vm, "print", functionPrint, 1);
2987     addFunction(vm, "dumpCallFrame", functionDumpCallFrame, 0);
2988     addFunction(vm, "dumpStack", functionDumpStack, 0);
2989     addFunction(vm, "dumpRegisters", functionDumpRegisters, 1);
2990
2991     addFunction(vm, "dumpCell", functionDumpCell, 1);
2992
2993     addFunction(vm, "indexingMode", functionIndexingMode, 1);
2994     addFunction(vm, "inlineCapacity", functionInlineCapacity, 1);
2995     addFunction(vm, "value", functionValue, 1);
2996     addFunction(vm, "getpid", functionGetPID, 0);
2997
2998     addFunction(vm, "haveABadTime", functionHaveABadTime, 1);
2999     addFunction(vm, "isHavingABadTime", functionIsHavingABadTime, 1);
3000
3001     addFunction(vm, "callWithStackSize", functionCallWithStackSize, 2);
3002
3003     addFunction(vm, "createGlobalObject", functionCreateGlobalObject, 0);
3004     addFunction(vm, "createProxy", functionCreateProxy, 1);
3005     addFunction(vm, "createRuntimeArray", functionCreateRuntimeArray, 0);
3006     addFunction(vm, "createNullRopeString", functionCreateNullRopeString, 0);
3007
3008     addFunction(vm, "createImpureGetter", functionCreateImpureGetter, 1);
3009     addFunction(vm, "createCustomGetterObject", functionCreateCustomGetterObject, 0);
3010     addFunction(vm, "createDOMJITNodeObject", functionCreateDOMJITNodeObject, 0);
3011     addFunction(vm, "createDOMJITGetterObject", functionCreateDOMJITGetterObject, 0);
3012     addFunction(vm, "createDOMJITGetterComplexObject", functionCreateDOMJITGetterComplexObject, 0);
3013     addFunction(vm, "createDOMJITFunctionObject", functionCreateDOMJITFunctionObject, 0);
3014     addFunction(vm, "createDOMJITCheckSubClassObject", functionCreateDOMJITCheckSubClassObject, 0);
3015     addFunction(vm, "createDOMJITGetterBaseJSObject", functionCreateDOMJITGetterBaseJSObject, 0);
3016     addFunction(vm, "createBuiltin", functionCreateBuiltin, 2);
3017 #if ENABLE(WEBASSEMBLY)
3018     addFunction(vm, "createWasmStreamingParser", functionCreateWasmStreamingParser, 0);
3019 #endif
3020     addFunction(vm, "createStaticCustomAccessor", functionCreateStaticCustomAccessor, 0);
3021     addFunction(vm, "createObjectDoingSideEffectPutWithoutCorrectSlotStatus", functionCreateObjectDoingSideEffectPutWithoutCorrectSlotStatus, 0);
3022     addFunction(vm, "createEmptyFunctionWithName", functionCreateEmptyFunctionWithName, 1);
3023     addFunction(vm, "getPrivateProperty", functionGetPrivateProperty, 2);
3024     addFunction(vm, "setImpureGetterDelegate", functionSetImpureGetterDelegate, 2);
3025
3026     addConstructibleFunction(vm, "Root", functionCreateRoot, 0);
3027     addConstructibleFunction(vm, "Element", functionCreateElement, 1);
3028     addFunction(vm, "getElement", functionGetElement, 1);
3029
3030     addConstructibleFunction(vm, "SimpleObject", functionCreateSimpleObject, 0);
3031     addFunction(vm, "getHiddenValue", functionGetHiddenValue, 1);
3032     addFunction(vm, "setHiddenValue", functionSetHiddenValue, 2);
3033
3034     addFunction(vm, "shadowChickenFunctionsOnStack", functionShadowChickenFunctionsOnStack, 0);
3035     addFunction(vm, "setGlobalConstRedeclarationShouldNotThrow", functionSetGlobalConstRedeclarationShouldNotThrow, 0);
3036
3037     addFunction(vm, "findTypeForExpression", functionFindTypeForExpression, 2);
3038     addFunction(vm, "returnTypeFor", functionReturnTypeFor, 1);
3039
3040     addFunction(vm, "flattenDictionaryObject", functionFlattenDictionaryObject, 1);
3041
3042     addFunction(vm, "dumpBasicBlockExecutionRanges", functionDumpBasicBlockExecutionRanges , 0);
3043     addFunction(vm, "hasBasicBlockExecuted", functionHasBasicBlockExecuted, 2);
3044     addFunction(vm, "basicBlockExecutionCount", functionBasicBlockExecutionCount, 2);
3045
3046     addFunction(vm, "enableExceptionFuzz", functionEnableExceptionFuzz, 0);
3047
3048     addFunction(vm, "enableDebuggerModeWhenIdle", functionEnableDebuggerModeWhenIdle, 0);
3049     addFunction(vm, "disableDebuggerModeWhenIdle", functionDisableDebuggerModeWhenIdle, 0);
3050
3051     addFunction(vm, "deleteAllCodeWhenIdle", functionDeleteAllCodeWhenIdle, 0);
3052
3053     addFunction(vm, "globalObjectCount", functionGlobalObjectCount, 0);
3054     addFunction(vm, "globalObjectForObject", functionGlobalObjectForObject, 1);
3055
3056     addFunction(vm, "getGetterSetter", functionGetGetterSetter, 2);
3057     addFunction(vm, "loadGetterFromGetterSetter", functionLoadGetterFromGetterSetter, 1);
3058     addFunction(vm, "createCustomTestGetterSetter", functionCreateCustomTestGetterSetter, 1);
3059
3060     addFunction(vm, "deltaBetweenButterflies", functionDeltaBetweenButterflies, 2);
3061     
3062     addFunction(vm, "currentCPUTime", functionCurrentCPUTime, 0);
3063     addFunction(vm, "totalGCTime", functionTotalGCTime, 0);
3064
3065     addFunction(vm, "parseCount", functionParseCount, 0);
3066
3067     addFunction(vm, "isWasmSupported", functionIsWasmSupported, 0);
3068     addFunction(vm, "make16BitStringIfPossible", functionMake16BitStringIfPossible, 1);
3069
3070     addFunction(vm, "getStructureTransitionList", JSDollarVMHelper::functionGetStructureTransitionList, 1);
3071     addFunction(vm, "getConcurrently", functionGetConcurrently, 2);
3072
3073     addFunction(vm, "hasOwnLengthProperty", functionHasOwnLengthProperty, 1);
3074     addFunction(vm, "rejectPromiseAsHandled", functionRejectPromiseAsHandled, 1);
3075
3076     m_objectDoingSideEffectPutWithoutCorrectSlotStatusStructure.set(vm, this, ObjectDoingSideEffectPutWithoutCorrectSlotStatus::createStructure(vm, globalObject, jsNull()));
3077 }
3078
3079 void JSDollarVM::addFunction(VM& vm, JSGlobalObject* globalObject, const char* name, NativeFunction function, unsigned arguments)
3080 {
3081     DollarVMAssertScope assertScope;
3082     Identifier identifier = Identifier::fromString(vm, name);
3083     putDirect(vm, identifier, JSFunction::create(vm, globalObject, arguments, identifier.string(), function));
3084 }
3085
3086 void JSDollarVM::addConstructibleFunction(VM& vm, JSGlobalObject* globalObject, const char* name, NativeFunction function, unsigned arguments)
3087 {
3088     DollarVMAssertScope assertScope;
3089     Identifier identifier = Identifier::fromString(vm, name);
3090     putDirect(vm, identifier, JSFunction::create(vm, globalObject, arguments, identifier.string(), function, NoIntrinsic, function));
3091 }
3092
3093 void JSDollarVM::visitChildren(JSCell* cell, SlotVisitor& visitor)
3094 {
3095     JSDollarVM* thisObject = jsCast<JSDollarVM*>(cell);
3096     Base::visitChildren(thisObject, visitor);
3097     visitor.append(thisObject->m_objectDoingSideEffectPutWithoutCorrectSlotStatusStructure);
3098 }
3099
3100 } // namespace JSC
3101
3102 IGNORE_WARNINGS_END