source: webkit/trunk/Source/JavaScriptCore/tools/JSDollarVM.cpp

Last change on this file was 295608, checked in by Alexey Shvayka, 3 years ago

CommonSlowPaths::putDirectWithReify() is incorrect for DontDelete properties
https://bugs.webkit.org/show_bug.cgi?id=241651
<rdar://94016559>

Reviewed by Saam Barati.

Provided the base object has no read-only / accessor / custom properties,
putDirectWithReify() is incorrect for an object with non-configurable property,
whether it's on the structure or a non-reified static none.

In that case, putDirectWithReify() ignores existing non-configurable / non-reified
descriptor and produces an incorrect property descriptor instead of throwing TypeError.
One it's observed in the wild is via an instance field [1].

The issue was due to incorrect ReadOnly-focused check for putDirect() fast path,
which would be correct for Set but not for DefineOwnProperty.

Apart from introducing tighter fast patch check, this change extracts
JSFunction::mayHaveNonReifiedPrototype() helper, cleaning up JSFunction's overrides,
and removes now unused PutModeDefineOwnPropertyIgnoringExtensibility, which apart from
ignoring extensibility, also ignored read-only / accessor / custom properties,
which felt a bit counter-intuitive.

This change carefully preserves the fast path introduced in webkit.org/b/232479.

[1]: https://tc39.es/ecma262/#sec-definefield

  • Source/JavaScriptCore/runtime/CommonSlowPaths.h:

(JSC::CommonSlowPaths::originalStructureBeforePut):
(JSC::CommonSlowPaths::canPutDirectFast):
(JSC::CommonSlowPaths::putDirectWithReify):
(JSC::CommonSlowPaths::putDirectAccessorWithReify):

  • Source/JavaScriptCore/runtime/JSFunction.cpp:

(JSC::JSFunction::getOwnPropertySlot):
(JSC::JSFunction::put):
(JSC::JSFunction::deleteProperty):
(JSC::JSFunction::defineOwnProperty):
(JSC::JSFunction::reifyLazyPropertyIfNeeded):
(JSC::JSFunction::reifyLazyPrototypeIfNeeded):

  • Source/JavaScriptCore/runtime/JSFunction.h:
  • Source/JavaScriptCore/runtime/JSFunctionInlines.h:

(JSC::JSFunction::mayHaveNonReifiedPrototype):

  • Source/JavaScriptCore/runtime/JSObject.cpp:

(JSC::JSObject::putDirectCustomAccessor):
(JSC::JSObject::putDirectNonIndexAccessor):

  • Source/JavaScriptCore/runtime/JSObject.h:

(JSC::JSObject::putDirect):
(JSC::JSObject::putDirectRespectingExtensibility): Deleted.

  • Source/JavaScriptCore/runtime/JSObjectInlines.h:

(JSC::JSObject::putDirectInternal):

  • Source/JavaScriptCore/tools/JSDollarVM.cpp:

(JSC::JSC_DEFINE_HOST_FUNCTION):
(JSC::JSDollarVM::finishCreation):

Canonical link: https://commits.webkit.org/251613@main

File size: 159.1 KB
Line 
1/*
2 * Copyright (C) 2015-2022 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 "ArrayPrototype.h"
30#include "BuiltinNames.h"
31#include "CodeBlock.h"
32#include "ControlFlowProfiler.h"
33#include "DOMAttributeGetterSetter.h"
34#include "DOMJITGetterSetter.h"
35#include "Debugger.h"
36#include "FrameTracers.h"
37#include "FunctionCodeBlock.h"
38#include "GetterSetter.h"
39#include "JITSizeStatistics.h"
40#include "JSArray.h"
41#include "JSCInlines.h"
42#include "JSONObject.h"
43#include "JSString.h"
44#include "LinkBuffer.h"
45#include "Options.h"
46#include "Parser.h"
47#include "ProbeContext.h"
48#include "ShadowChicken.h"
49#include "Snippet.h"
50#include "SnippetParams.h"
51#include "TypeProfiler.h"
52#include "TypeProfilerLog.h"
53#include "VMInspector.h"
54#include "VMTrapsInlines.h"
55#include "WasmCapabilities.h"
56#include <unicode/uversion.h>
57#include <wtf/ApproximateTime.h>
58#include <wtf/Atomics.h>
59#include <wtf/CPUTime.h>
60#include <wtf/DataLog.h>
61#include <wtf/Language.h>
62#include <wtf/ProcessID.h>
63#include <wtf/StringPrintStream.h>
64#include <wtf/unicode/icu/ICUHelpers.h>
65
66#if !USE(SYSTEM_MALLOC)
67#include <bmalloc/BPlatform.h>
68#if BUSE(LIBPAS)
69#include <bmalloc/pas_debug_spectrum.h>
70#include <bmalloc/pas_fd_stream.h>
71#include <bmalloc/pas_heap_lock.h>
72#endif
73#endif
74
75#if ENABLE(WEBASSEMBLY)
76#include "JSWebAssemblyHelpers.h"
77#include "WasmModuleInformation.h"
78#include "WasmStreamingCompiler.h"
79#include "WasmStreamingParser.h"
80#endif
81
82using namespace JSC;
83
84IGNORE_WARNINGS_BEGIN("frame-address")
85
86extern "C" void ctiMasmProbeTrampoline();
87
88namespace JSC {
89
90// This class is only here as a simple way to grant JSDollarVM friend privileges
91// to all the classes that it needs special access to.
92class JSDollarVMHelper {
93public:
94 JSDollarVMHelper(VM& vm)
95 : m_vm(vm)
96 { }
97
98 void updateVMStackLimits() { return m_vm.updateStackLimits(); };
99
100 VM& m_vm;
101};
102
103} // namespace JSC
104
105namespace {
106
107static JSC_DECLARE_HOST_FUNCTION(functionDOMJITGetterComplexEnableException);
108static JSC_DECLARE_HOST_FUNCTION(functionDOMJITFunctionObjectWithTypeCheck);
109static JSC_DECLARE_HOST_FUNCTION(functionDOMJITCheckJSCastObjectWithTypeCheck);
110
111// We must RELEASE_ASSERT(Options::useDollarVM()) in all JSDollarVM functions
112// that are non-trivial at an eye's glance. This includes (but is not limited to):
113// constructors
114// create() factory
115// createStructure() factory
116// finishCreation()
117// HOST_CALL or operation functions
118// Constructors and methods of utility and test classes
119// lambda functions
120//
121// The way to do this RELEASE_ASSERT is with the DollarVMAssertScope below.
122//
123// The only exception are some constexpr constructors used for instantiating
124// globals (since these must have trivial constructors) e.g. DOMJITAttribute.
125// Instead, these constructors should always be ALWAYS_INLINE.
126
127class JSDollarVMCallFrame : public JSNonFinalObject {
128 using Base = JSNonFinalObject;
129public:
130 template<typename CellType, SubspaceAccess>
131 static CompleteSubspace* subspaceFor(VM& vm)
132 {
133 return &vm.cellSpace();
134 }
135
136 JSDollarVMCallFrame(VM& vm, Structure* structure)
137 : Base(vm, structure)
138 {
139 DollarVMAssertScope assertScope;
140 }
141
142 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
143 {
144 DollarVMAssertScope assertScope;
145 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
146 }
147
148 static JSDollarVMCallFrame* create(JSGlobalObject* globalObject, CallFrame* callFrame, unsigned requestedFrameIndex)
149 {
150 DollarVMAssertScope assertScope;
151 VM& vm = globalObject->vm();
152 Structure* structure = createStructure(vm, globalObject, jsNull());
153 JSDollarVMCallFrame* frame = new (NotNull, allocateCell<JSDollarVMCallFrame>(vm)) JSDollarVMCallFrame(vm, structure);
154 frame->finishCreation(vm, callFrame, requestedFrameIndex);
155 return frame;
156 }
157
158 void finishCreation(VM& vm, CallFrame* callFrame, unsigned requestedFrameIndex)
159 {
160 DollarVMAssertScope assertScope;
161 Base::finishCreation(vm);
162
163 auto addProperty = [&] (VM& vm, ASCIILiteral name, JSValue value) {
164 DollarVMAssertScope assertScope;
165 JSDollarVMCallFrame::addProperty(vm, name, value);
166 };
167
168 unsigned frameIndex = 0;
169 bool isValid = false;
170 callFrame->iterate(vm, [&] (StackVisitor& visitor) {
171 DollarVMAssertScope assertScope;
172
173 if (frameIndex++ != requestedFrameIndex)
174 return IterationStatus::Continue;
175
176 addProperty(vm, "name"_s, jsString(vm, visitor->functionName()));
177
178 if (visitor->callee().isCell())
179 addProperty(vm, "callee"_s, visitor->callee().asCell());
180
181 CodeBlock* codeBlock = visitor->codeBlock();
182 if (codeBlock) {
183 addProperty(vm, "codeBlock"_s, codeBlock);
184 addProperty(vm, "unlinkedCodeBlock"_s, codeBlock->unlinkedCodeBlock());
185 addProperty(vm, "executable"_s, codeBlock->ownerExecutable());
186 }
187 isValid = true;
188
189 return IterationStatus::Done;
190 });
191
192 addProperty(vm, "valid"_s, jsBoolean(isValid));
193 }
194
195 DECLARE_INFO;
196
197private:
198 void addProperty(VM& vm, ASCIILiteral name, JSValue value)
199 {
200 DollarVMAssertScope assertScope;
201 Identifier identifier = Identifier::fromString(vm, name);
202 putDirect(vm, identifier, value);
203 }
204};
205
206const ClassInfo JSDollarVMCallFrame::s_info = { "CallFrame"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDollarVMCallFrame) };
207
208class ElementHandleOwner;
209class Root;
210
211class Element : public JSNonFinalObject {
212public:
213 Element(VM& vm, Structure* structure)
214 : Base(vm, structure)
215 {
216 DollarVMAssertScope assertScope;
217 }
218
219 typedef JSNonFinalObject Base;
220 template<typename CellType, SubspaceAccess>
221 static CompleteSubspace* subspaceFor(VM& vm)
222 {
223 return &vm.cellSpace();
224 }
225
226 Root* root() const { return m_root.get(); }
227 void setRoot(VM& vm, Root* root) { m_root.set(vm, this, root); }
228
229 static Element* create(VM& vm, JSGlobalObject* globalObject, Root* root)
230 {
231 DollarVMAssertScope assertScope;
232 Structure* structure = createStructure(vm, globalObject, jsNull());
233 Element* element = new (NotNull, allocateCell<Element>(vm)) Element(vm, structure);
234 element->finishCreation(vm, root);
235 return element;
236 }
237
238 void finishCreation(VM&, Root*);
239
240 DECLARE_VISIT_CHILDREN;
241
242 static ElementHandleOwner* handleOwner();
243
244 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
245 {
246 DollarVMAssertScope assertScope;
247 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
248 }
249
250 DECLARE_INFO;
251
252private:
253 WriteBarrier<Root> m_root;
254};
255
256template<typename Visitor>
257void Element::visitChildrenImpl(JSCell* cell, Visitor& visitor)
258{
259 DollarVMAssertScope assertScope;
260 Element* thisObject = jsCast<Element*>(cell);
261 ASSERT_GC_OBJECT_INHERITS(thisObject, info());
262 Base::visitChildren(thisObject, visitor);
263 visitor.append(thisObject->m_root);
264}
265
266DEFINE_VISIT_CHILDREN(Element);
267
268class ElementHandleOwner final : public WeakHandleOwner {
269 WTF_MAKE_FAST_ALLOCATED;
270public:
271 bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, const char** reason) final
272 {
273 DollarVMAssertScope assertScope;
274 if (UNLIKELY(reason))
275 *reason = "JSC::Element is opaque root";
276 Element* element = jsCast<Element*>(handle.slot()->asCell());
277 return visitor.containsOpaqueRoot(element->root());
278 }
279};
280
281class Root final : public JSDestructibleObject {
282public:
283 using Base = JSDestructibleObject;
284 template<typename CellType, SubspaceAccess>
285 static CompleteSubspace* subspaceFor(VM& vm)
286 {
287 return &vm.destructibleObjectSpace();
288 }
289
290 Root(VM& vm, Structure* structure)
291 : Base(vm, structure)
292 {
293 DollarVMAssertScope assertScope;
294 }
295
296 Element* element()
297 {
298 return m_element.get();
299 }
300
301 void setElement(Element* element)
302 {
303 DollarVMAssertScope assertScope;
304 Weak<Element> newElement(element, Element::handleOwner());
305 m_element.swap(newElement);
306 }
307
308 static Root* create(VM& vm, JSGlobalObject* globalObject)
309 {
310 DollarVMAssertScope assertScope;
311 Structure* structure = createStructure(vm, globalObject, jsNull());
312 Root* root = new (NotNull, allocateCell<Root>(vm)) Root(vm, structure);
313 root->finishCreation(vm);
314 return root;
315 }
316
317 DECLARE_INFO;
318
319 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
320 {
321 DollarVMAssertScope assertScope;
322 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
323 }
324
325 DECLARE_VISIT_CHILDREN;
326
327private:
328 Weak<Element> m_element;
329};
330
331template<typename Visitor>
332void Root::visitChildrenImpl(JSCell* thisObject, Visitor& visitor)
333{
334 DollarVMAssertScope assertScope;
335 ASSERT_GC_OBJECT_INHERITS(thisObject, info());
336 Base::visitChildren(thisObject, visitor);
337 visitor.addOpaqueRoot(thisObject);
338}
339
340DEFINE_VISIT_CHILDREN(Root);
341
342class SimpleObject : public JSNonFinalObject {
343public:
344 SimpleObject(VM& vm, Structure* structure)
345 : Base(vm, structure)
346 {
347 DollarVMAssertScope assertScope;
348 }
349
350 typedef JSNonFinalObject Base;
351 template<typename CellType, SubspaceAccess>
352 static CompleteSubspace* subspaceFor(VM& vm)
353 {
354 return &vm.cellSpace();
355 }
356
357 static SimpleObject* create(VM& vm, JSGlobalObject* globalObject)
358 {
359 DollarVMAssertScope assertScope;
360 Structure* structure = createStructure(vm, globalObject, jsNull());
361 SimpleObject* simpleObject = new (NotNull, allocateCell<SimpleObject>(vm)) SimpleObject(vm, structure);
362 simpleObject->finishCreation(vm);
363 return simpleObject;
364 }
365
366 DECLARE_VISIT_CHILDREN;
367
368 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
369 {
370 DollarVMAssertScope assertScope;
371 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
372 }
373
374 JSValue hiddenValue()
375 {
376 return m_hiddenValue.get();
377 }
378
379 void setHiddenValue(VM& vm, JSValue value)
380 {
381 ASSERT(value.isCell());
382 m_hiddenValue.set(vm, this, value);
383 }
384
385 static CallData getConstructData(JSCell*)
386 {
387 CallData constructData;
388 constructData.type = CallData::Type::Native;
389 constructData.native.function = callHostFunctionAsConstructor;
390 return constructData;
391 }
392
393 DECLARE_INFO;
394
395private:
396 WriteBarrier<JSC::Unknown> m_hiddenValue;
397};
398
399template<typename Visitor>
400void SimpleObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
401{
402 DollarVMAssertScope assertScope;
403 SimpleObject* thisObject = jsCast<SimpleObject*>(cell);
404 ASSERT_GC_OBJECT_INHERITS(thisObject, info());
405 Base::visitChildren(thisObject, visitor);
406 visitor.append(thisObject->m_hiddenValue);
407}
408
409DEFINE_VISIT_CHILDREN(SimpleObject);
410
411class ImpureGetter : public JSNonFinalObject {
412public:
413 ImpureGetter(VM& vm, Structure* structure)
414 : Base(vm, structure)
415 {
416 DollarVMAssertScope assertScope;
417 }
418
419 DECLARE_INFO;
420 typedef JSNonFinalObject Base;
421 static constexpr unsigned StructureFlags = Base::StructureFlags | JSC::GetOwnPropertySlotIsImpure | JSC::OverridesGetOwnPropertySlot;
422
423 template<typename CellType, SubspaceAccess>
424 static CompleteSubspace* subspaceFor(VM& vm)
425 {
426 return &vm.cellSpace();
427 }
428
429 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
430 {
431 DollarVMAssertScope assertScope;
432 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
433 }
434
435 static ImpureGetter* create(VM& vm, Structure* structure, JSObject* delegate)
436 {
437 DollarVMAssertScope assertScope;
438 ImpureGetter* getter = new (NotNull, allocateCell<ImpureGetter>(vm)) ImpureGetter(vm, structure);
439 getter->finishCreation(vm, delegate);
440 return getter;
441 }
442
443 void finishCreation(VM& vm, JSObject* delegate)
444 {
445 DollarVMAssertScope assertScope;
446 Base::finishCreation(vm);
447 if (delegate)
448 m_delegate.set(vm, this, delegate);
449 }
450
451 static bool getOwnPropertySlot(JSObject* object, JSGlobalObject* globalObject, PropertyName name, PropertySlot& slot)
452 {
453 DollarVMAssertScope assertScope;
454 VM& vm = globalObject->vm();
455 auto scope = DECLARE_THROW_SCOPE(vm);
456 ImpureGetter* thisObject = jsCast<ImpureGetter*>(object);
457
458 if (thisObject->m_delegate) {
459 if (thisObject->m_delegate->getPropertySlot(globalObject, name, slot))
460 return true;
461 RETURN_IF_EXCEPTION(scope, false);
462 }
463
464 return Base::getOwnPropertySlot(object, globalObject, name, slot);
465 }
466
467 DECLARE_VISIT_CHILDREN;
468
469 void setDelegate(VM& vm, JSObject* delegate)
470 {
471 m_delegate.set(vm, this, delegate);
472 }
473
474private:
475 WriteBarrier<JSObject> m_delegate;
476};
477
478template<typename Visitor>
479void ImpureGetter::visitChildrenImpl(JSCell* cell, Visitor& visitor)
480{
481 DollarVMAssertScope assertScope;
482 ASSERT_GC_OBJECT_INHERITS(cell, info());
483 Base::visitChildren(cell, visitor);
484 ImpureGetter* thisObject = jsCast<ImpureGetter*>(cell);
485 visitor.append(thisObject->m_delegate);
486}
487
488DEFINE_VISIT_CHILDREN(ImpureGetter);
489
490static JSC_DECLARE_CUSTOM_GETTER(customGetterValueGetter);
491static JSC_DECLARE_CUSTOM_GETTER(customGetterAcessorGetter);
492
493class CustomGetter : public JSNonFinalObject {
494public:
495 CustomGetter(VM& vm, Structure* structure)
496 : Base(vm, structure)
497 {
498 DollarVMAssertScope assertScope;
499 }
500
501 DECLARE_INFO;
502 typedef JSNonFinalObject Base;
503 static constexpr unsigned StructureFlags = Base::StructureFlags | JSC::OverridesGetOwnPropertySlot;
504
505 template<typename CellType, SubspaceAccess>
506 static CompleteSubspace* subspaceFor(VM& vm)
507 {
508 return &vm.cellSpace();
509 }
510
511 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
512 {
513 DollarVMAssertScope assertScope;
514 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
515 }
516
517 static CustomGetter* create(VM& vm, Structure* structure)
518 {
519 DollarVMAssertScope assertScope;
520 CustomGetter* getter = new (NotNull, allocateCell<CustomGetter>(vm)) CustomGetter(vm, structure);
521 getter->finishCreation(vm);
522 return getter;
523 }
524
525 static bool getOwnPropertySlot(JSObject* object, JSGlobalObject* globalObject, PropertyName propertyName, PropertySlot& slot)
526 {
527 DollarVMAssertScope assertScope;
528 VM& vm = globalObject->vm();
529 CustomGetter* thisObject = jsCast<CustomGetter*>(object);
530 if (propertyName == PropertyName(Identifier::fromString(vm, "customGetter"_s))) {
531 slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum, customGetterValueGetter);
532 return true;
533 }
534
535 if (propertyName == PropertyName(Identifier::fromString(vm, "customGetterAccessor"_s))) {
536 slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::CustomAccessor, customGetterAcessorGetter);
537 return true;
538 }
539
540 return JSObject::getOwnPropertySlot(thisObject, globalObject, propertyName, slot);
541 }
542};
543
544JSC_DEFINE_CUSTOM_GETTER(customGetterValueGetter, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
545{
546 DollarVMAssertScope assertScope;
547 VM& vm = globalObject->vm();
548 auto scope = DECLARE_THROW_SCOPE(vm);
549
550 CustomGetter* thisObject = jsDynamicCast<CustomGetter*>(JSValue::decode(thisValue));
551 if (!thisObject)
552 return throwVMTypeError(globalObject, scope);
553 bool shouldThrow = thisObject->get(globalObject, PropertyName(Identifier::fromString(vm, "shouldThrow"_s))).toBoolean(globalObject);
554 RETURN_IF_EXCEPTION(scope, encodedJSValue());
555 if (shouldThrow)
556 return throwVMTypeError(globalObject, scope);
557 return JSValue::encode(jsNumber(100));
558}
559
560JSC_DEFINE_CUSTOM_GETTER(customGetterAcessorGetter, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
561{
562 DollarVMAssertScope assertScope;
563 VM& vm = globalObject->vm();
564 auto scope = DECLARE_THROW_SCOPE(vm);
565
566 JSObject* thisObject = jsDynamicCast<JSObject*>(JSValue::decode(thisValue));
567 if (!thisObject)
568 return throwVMTypeError(globalObject, scope);
569 bool shouldThrow = thisObject->get(globalObject, PropertyName(Identifier::fromString(vm, "shouldThrow"_s))).toBoolean(globalObject);
570 RETURN_IF_EXCEPTION(scope, encodedJSValue());
571 if (shouldThrow)
572 return throwVMTypeError(globalObject, scope);
573 return JSValue::encode(jsNumber(100));
574}
575
576static JSC_DECLARE_CUSTOM_GETTER(runtimeArrayLengthGetter);
577
578class RuntimeArray : public JSArray {
579public:
580 typedef JSArray Base;
581 static constexpr unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero;
582
583IGNORE_WARNINGS_BEGIN("unused-const-variable")
584 static constexpr bool needsDestruction = false;
585IGNORE_WARNINGS_END
586
587 template<typename CellType, SubspaceAccess>
588 static CompleteSubspace* subspaceFor(VM& vm)
589 {
590 return &vm.cellSpace();
591 }
592
593 static RuntimeArray* create(JSGlobalObject* globalObject, CallFrame* callFrame)
594 {
595 DollarVMAssertScope assertScope;
596 VM& vm = globalObject->vm();
597 Structure* structure = createStructure(vm, globalObject, createPrototype(vm, globalObject));
598 RuntimeArray* runtimeArray = new (NotNull, allocateCell<RuntimeArray>(vm)) RuntimeArray(globalObject, structure);
599 runtimeArray->finishCreation(globalObject, callFrame);
600 vm.heap.addFinalizer(runtimeArray, destroy);
601 return runtimeArray;
602 }
603
604 ~RuntimeArray() { }
605
606 static void destroy(JSCell* cell)
607 {
608 DollarVMAssertScope assertScope;
609 static_cast<RuntimeArray*>(cell)->RuntimeArray::~RuntimeArray();
610 }
611
612 static bool getOwnPropertySlot(JSObject* object, JSGlobalObject* globalObject, PropertyName propertyName, PropertySlot& slot)
613 {
614 DollarVMAssertScope assertScope;
615 VM& vm = globalObject->vm();
616 RuntimeArray* thisObject = jsCast<RuntimeArray*>(object);
617 if (propertyName == vm.propertyNames->length) {
618 slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum, runtimeArrayLengthGetter);
619 return true;
620 }
621
622 std::optional<uint32_t> index = parseIndex(propertyName);
623 if (index && index.value() < thisObject->getLength()) {
624 slot.setValue(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::DontEnum, jsNumber(thisObject->m_vector[index.value()]));
625 return true;
626 }
627
628 return JSObject::getOwnPropertySlot(thisObject, globalObject, propertyName, slot);
629 }
630
631 static bool getOwnPropertySlotByIndex(JSObject* object, JSGlobalObject* globalObject, unsigned index, PropertySlot& slot)
632 {
633 DollarVMAssertScope assertScope;
634 RuntimeArray* thisObject = jsCast<RuntimeArray*>(object);
635 if (index < thisObject->getLength()) {
636 slot.setValue(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::DontEnum, jsNumber(thisObject->m_vector[index]));
637 return true;
638 }
639
640 return JSObject::getOwnPropertySlotByIndex(thisObject, globalObject, index, slot);
641 }
642
643 static NO_RETURN_DUE_TO_CRASH bool put(JSCell*, JSGlobalObject*, PropertyName, JSValue, PutPropertySlot&)
644 {
645 RELEASE_ASSERT_NOT_REACHED();
646 }
647
648 static NO_RETURN_DUE_TO_CRASH bool deleteProperty(JSCell*, JSGlobalObject*, PropertyName, DeletePropertySlot&)
649 {
650 RELEASE_ASSERT_NOT_REACHED();
651 }
652
653 unsigned getLength() const { return m_vector.size(); }
654
655 DECLARE_INFO;
656
657 static ArrayPrototype* createPrototype(VM&, JSGlobalObject* globalObject)
658 {
659 DollarVMAssertScope assertScope;
660 return globalObject->arrayPrototype();
661 }
662
663 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
664 {
665 DollarVMAssertScope assertScope;
666 return Structure::create(vm, globalObject, prototype, TypeInfo(DerivedArrayType, StructureFlags), info(), ArrayClass);
667 }
668
669protected:
670 void finishCreation(JSGlobalObject* globalObject, CallFrame* callFrame)
671 {
672 DollarVMAssertScope assertScope;
673 VM& vm = globalObject->vm();
674 Base::finishCreation(vm);
675 ASSERT(inherits(info()));
676
677 for (size_t i = 0; i < callFrame->argumentCount(); i++)
678 m_vector.append(callFrame->argument(i).toInt32(globalObject));
679 }
680
681private:
682 RuntimeArray(JSGlobalObject* globalObject, Structure* structure)
683 : JSArray(globalObject->vm(), structure, nullptr)
684 {
685 DollarVMAssertScope assertScope;
686 }
687
688 Vector<int> m_vector;
689};
690
691JSC_DEFINE_CUSTOM_GETTER(runtimeArrayLengthGetter, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
692{
693 DollarVMAssertScope assertScope;
694 VM& vm = globalObject->vm();
695 auto scope = DECLARE_THROW_SCOPE(vm);
696
697 RuntimeArray* thisObject = jsDynamicCast<RuntimeArray*>(JSValue::decode(thisValue));
698 if (!thisObject)
699 return throwVMTypeError(globalObject, scope);
700 return JSValue::encode(jsNumber(thisObject->getLength()));
701}
702
703static JSC_DECLARE_CUSTOM_GETTER(testStaticAccessorGetter);
704static JSC_DECLARE_CUSTOM_SETTER(testStaticAccessorPutter);
705
706JSC_DEFINE_CUSTOM_GETTER(testStaticAccessorGetter, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
707{
708 DollarVMAssertScope assertScope;
709 VM& vm = globalObject->vm();
710 auto scope = DECLARE_THROW_SCOPE(vm);
711
712 JSObject* thisObject = jsDynamicCast<JSObject*>(JSValue::decode(thisValue));
713 if (!thisObject)
714 return throwVMTypeError(globalObject, scope);
715
716 if (JSValue result = thisObject->getDirect(vm, PropertyName(Identifier::fromString(vm, "testField"_s))))
717 return JSValue::encode(result);
718 return JSValue::encode(jsUndefined());
719}
720
721JSC_DEFINE_CUSTOM_SETTER(testStaticAccessorPutter, (JSGlobalObject* globalObject, EncodedJSValue thisValue, EncodedJSValue value, PropertyName))
722{
723 DollarVMAssertScope assertScope;
724 VM& vm = globalObject->vm();
725 auto scope = DECLARE_THROW_SCOPE(vm);
726
727 JSValue receiver = JSValue::decode(thisValue);
728 JSObject* thisObject = receiver.isObject() ? asObject(receiver) : receiver.synthesizePrototype(globalObject);
729 RETURN_IF_EXCEPTION(scope, false);
730 RELEASE_ASSERT(thisObject);
731
732 return thisObject->putDirect(vm, PropertyName(Identifier::fromString(vm, "testField"_s)), JSValue::decode(value));
733}
734
735static const struct CompactHashIndex staticCustomAccessorTableIndex[9] = {
736 { -1, -1 },
737 { -1, -1 },
738 { 2, -1 },
739 { -1, -1 },
740 { 0, 8 },
741 { -1, -1 },
742 { -1, -1 },
743 { -1, -1 },
744 { 1, -1 },
745};
746
747static const struct HashTableValue staticCustomAccessorTableValues[3] = {
748 { "testStaticAccessor"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(testStaticAccessorGetter), (intptr_t)static_cast<PutPropertySlot::PutValueFunc>(testStaticAccessorPutter) } },
749 { "testStaticAccessorDontEnum"_s, PropertyAttribute::CustomAccessor | PropertyAttribute::DontEnum, NoIntrinsic, { (intptr_t)static_cast<GetValueFunc>(testStaticAccessorGetter), (intptr_t)static_cast<PutValueFunc>(testStaticAccessorPutter) } },
750 { "testStaticAccessorReadOnly"_s, PropertyAttribute::CustomAccessor | PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly, NoIntrinsic, { (intptr_t)static_cast<GetValueFunc>(testStaticAccessorGetter), 0 } },
751};
752
753static const struct HashTable staticCustomAccessorTable =
754 { 3, 7, true, nullptr, staticCustomAccessorTableValues, staticCustomAccessorTableIndex };
755
756class StaticCustomAccessor : public JSNonFinalObject {
757 using Base = JSNonFinalObject;
758public:
759 StaticCustomAccessor(VM& vm, Structure* structure)
760 : Base(vm, structure)
761 {
762 DollarVMAssertScope assertScope;
763 }
764
765 DECLARE_INFO;
766
767 static constexpr unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable | OverridesGetOwnPropertySlot;
768
769 template<typename CellType, SubspaceAccess>
770 static CompleteSubspace* subspaceFor(VM& vm)
771 {
772 return &vm.cellSpace();
773 }
774
775 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
776 {
777 DollarVMAssertScope assertScope;
778 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
779 }
780
781 static StaticCustomAccessor* create(VM& vm, Structure* structure)
782 {
783 DollarVMAssertScope assertScope;
784 StaticCustomAccessor* accessor = new (NotNull, allocateCell<StaticCustomAccessor>(vm)) StaticCustomAccessor(vm, structure);
785 accessor->finishCreation(vm);
786 return accessor;
787 }
788
789 static bool getOwnPropertySlot(JSObject* thisObject, JSGlobalObject* globalObject, PropertyName propertyName, PropertySlot& slot)
790 {
791 if (String(propertyName.uid()) == "thinAirCustomGetter"_s) {
792 slot.setCacheableCustom(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::CustomAccessor, testStaticAccessorGetter);
793 return true;
794 }
795 return JSNonFinalObject::getOwnPropertySlot(thisObject, globalObject, propertyName, slot);
796 }
797};
798
799static JSC_DECLARE_CUSTOM_GETTER(testStaticValueGetter);
800static JSC_DECLARE_CUSTOM_SETTER(testStaticValuePutter);
801static JSC_DECLARE_CUSTOM_SETTER(testStaticValuePutterSetFlag);
802
803JSC_DEFINE_CUSTOM_GETTER(testStaticValueGetter, (JSGlobalObject*, EncodedJSValue, PropertyName))
804{
805 DollarVMAssertScope assertScope;
806 return JSValue::encode(jsUndefined());
807}
808
809JSC_DEFINE_CUSTOM_SETTER(testStaticValuePutter, (JSGlobalObject* globalObject, EncodedJSValue thisValue, EncodedJSValue value, PropertyName))
810{
811 DollarVMAssertScope assertScope;
812 VM& vm = globalObject->vm();
813 auto scope = DECLARE_THROW_SCOPE(vm);
814
815 JSObject* thisObject = jsDynamicCast<JSObject*>(JSValue::decode(thisValue));
816 if (!thisObject)
817 return throwVMTypeError(globalObject, scope);
818
819 return thisObject->putDirect(vm, PropertyName(Identifier::fromString(vm, "testStaticValue"_s)), JSValue::decode(value));
820}
821
822JSC_DEFINE_CUSTOM_SETTER(testStaticValuePutterSetFlag, (JSGlobalObject* globalObject, EncodedJSValue thisValue, EncodedJSValue, PropertyName))
823{
824 DollarVMAssertScope assertScope;
825 VM& vm = globalObject->vm();
826 auto scope = DECLARE_THROW_SCOPE(vm);
827
828 JSObject* thisObject = jsDynamicCast<JSObject*>(JSValue::decode(thisValue));
829 if (!thisObject)
830 return throwVMTypeError(globalObject, scope);
831
832 return thisObject->putDirect(vm, PropertyName(Identifier::fromString(vm, "testStaticValueSetterCalled"_s)), jsBoolean(true));
833}
834
835static const struct CompactHashIndex staticCustomValueTableIndex[8] = {
836 { 1, -1 },
837 { -1, -1 },
838 { -1, -1 },
839 { -1, -1 },
840 { 3, -1 },
841 { 2, -1 },
842 { 0, -1 },
843 { -1, -1 },
844};
845
846static const struct HashTableValue staticCustomValueTableValues[4] = {
847 { "testStaticValue"_s, static_cast<unsigned>(PropertyAttribute::CustomValue), NoIntrinsic, { (intptr_t)static_cast<GetValueFunc>(testStaticValueGetter), (intptr_t)static_cast<PutValueFunc>(testStaticValuePutter) } },
848 { "testStaticValueNoSetter"_s, PropertyAttribute::CustomValue | PropertyAttribute::DontEnum, NoIntrinsic, { (intptr_t)static_cast<GetValueFunc>(testStaticValueGetter), 0 } },
849 { "testStaticValueReadOnly"_s, PropertyAttribute::CustomValue | PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly, NoIntrinsic, { (intptr_t)static_cast<GetValueFunc>(testStaticValueGetter), 0 } },
850 { "testStaticValueSetFlag"_s, static_cast<unsigned>(PropertyAttribute::CustomValue), NoIntrinsic, { (intptr_t)static_cast<GetValueFunc>(testStaticValueGetter), (intptr_t)static_cast<PutValueFunc>(testStaticValuePutterSetFlag) } },
851};
852
853static const struct HashTable staticCustomValueTable =
854 { 4, 7, true, nullptr, staticCustomValueTableValues, staticCustomValueTableIndex };
855
856class StaticCustomValue : public JSNonFinalObject {
857 using Base = JSNonFinalObject;
858public:
859 StaticCustomValue(VM& vm, Structure* structure)
860 : Base(vm, structure)
861 {
862 DollarVMAssertScope assertScope;
863 }
864
865 DECLARE_INFO;
866
867 static constexpr unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
868
869 template<typename CellType, SubspaceAccess>
870 static CompleteSubspace* subspaceFor(VM& vm)
871 {
872 return &vm.cellSpace();
873 }
874
875 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
876 {
877 DollarVMAssertScope assertScope;
878 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
879 }
880
881 static StaticCustomValue* create(VM& vm, Structure* structure)
882 {
883 DollarVMAssertScope assertScope;
884 StaticCustomValue* accessor = new (NotNull, allocateCell<StaticCustomValue>(vm)) StaticCustomValue(vm, structure);
885 accessor->finishCreation(vm);
886 return accessor;
887 }
888};
889
890static JSC_DECLARE_HOST_FUNCTION(staticDontDeleteDontEnumMethod);
891
892class StaticDontDeleteDontEnum : public JSNonFinalObject {
893public:
894 using Base = JSNonFinalObject;
895 static constexpr unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
896
897 StaticDontDeleteDontEnum(VM& vm, Structure* structure)
898 : Base(vm, structure)
899 {
900 DollarVMAssertScope assertScope;
901 }
902
903 DECLARE_INFO;
904
905 template<typename CellType, SubspaceAccess>
906 static CompleteSubspace* subspaceFor(VM& vm)
907 {
908 return &vm.cellSpace();
909 }
910
911 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
912 {
913 DollarVMAssertScope assertScope;
914 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
915 }
916
917 static StaticDontDeleteDontEnum* create(VM& vm, Structure* structure)
918 {
919 DollarVMAssertScope assertScope;
920 StaticDontDeleteDontEnum* result = new (NotNull, allocateCell<StaticDontDeleteDontEnum>(vm)) StaticDontDeleteDontEnum(vm, structure);
921 result->finishCreation(vm);
922 return result;
923 }
924};
925
926JSC_DEFINE_HOST_FUNCTION(staticDontDeleteDontEnumMethod, (JSGlobalObject*, CallFrame*))
927{
928 DollarVMAssertScope assertScope;
929 return encodedJSUndefined();
930}
931
932static const struct CompactHashIndex staticDontDeleteDontEnumTableIndex[8] = {
933 { 0, -1 },
934 { 1, -1 },
935 { -1, -1 },
936 { -1, -1 },
937 { -1, -1 },
938 { 2, -1 },
939 { -1, -1 },
940 { -1, -1 },
941};
942
943static const struct HashTableValue staticDontDeleteDontEnumTableValues[3] = {
944 { "dontEnum"_s, static_cast<unsigned>(PropertyAttribute::Function|PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(staticDontDeleteDontEnumMethod), (intptr_t)(0) } },
945 { "dontDelete"_s, static_cast<unsigned>(PropertyAttribute::Function|PropertyAttribute::DontDelete), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(staticDontDeleteDontEnumMethod), (intptr_t)(0) } },
946 { "dontDeleteDontEnum"_s, static_cast<unsigned>(PropertyAttribute::Function|PropertyAttribute::DontDelete|PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t)static_cast<RawNativeFunction>(staticDontDeleteDontEnumMethod), (intptr_t)(0) } },
947};
948
949static const struct HashTable staticDontDeleteDontEnumTable =
950 { 3, 7, false, nullptr, staticDontDeleteDontEnumTableValues, staticDontDeleteDontEnumTableIndex };
951
952class ObjectDoingSideEffectPutWithoutCorrectSlotStatus : public JSNonFinalObject {
953 using Base = JSNonFinalObject;
954 static constexpr unsigned StructureFlags = Base::StructureFlags | OverridesPut;
955public:
956 template<typename CellType, SubspaceAccess>
957 static CompleteSubspace* subspaceFor(VM& vm)
958 {
959 return &vm.cellSpace();
960 }
961
962 ObjectDoingSideEffectPutWithoutCorrectSlotStatus(VM& vm, Structure* structure)
963 : Base(vm, structure)
964 {
965 DollarVMAssertScope assertScope;
966 }
967
968 DECLARE_INFO;
969
970 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
971 {
972 DollarVMAssertScope assertScope;
973 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
974 }
975
976 static ObjectDoingSideEffectPutWithoutCorrectSlotStatus* create(VM& vm, Structure* structure)
977 {
978 DollarVMAssertScope assertScope;
979 ObjectDoingSideEffectPutWithoutCorrectSlotStatus* accessor = new (NotNull, allocateCell<ObjectDoingSideEffectPutWithoutCorrectSlotStatus>(vm)) ObjectDoingSideEffectPutWithoutCorrectSlotStatus(vm, structure);
980 accessor->finishCreation(vm);
981 return accessor;
982 }
983
984 static bool put(JSCell* cell, JSGlobalObject* globalObject, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
985 {
986 DollarVMAssertScope assertScope;
987 auto* thisObject = jsCast<ObjectDoingSideEffectPutWithoutCorrectSlotStatus*>(cell);
988 auto throwScope = DECLARE_THROW_SCOPE(globalObject->vm());
989 auto* string = value.toString(globalObject);
990 RETURN_IF_EXCEPTION(throwScope, false);
991 RELEASE_AND_RETURN(throwScope, Base::put(thisObject, globalObject, propertyName, string, slot));
992 }
993};
994
995class DOMJITNode : public JSNonFinalObject {
996public:
997 DOMJITNode(VM& vm, Structure* structure)
998 : Base(vm, structure)
999 {
1000 DollarVMAssertScope assertScope;
1001 }
1002
1003 DECLARE_INFO;
1004 typedef JSNonFinalObject Base;
1005 static constexpr unsigned StructureFlags = Base::StructureFlags;
1006
1007 template<typename CellType, SubspaceAccess>
1008 static CompleteSubspace* subspaceFor(VM& vm)
1009 {
1010 return &vm.cellSpace();
1011 }
1012
1013 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
1014 {
1015 DollarVMAssertScope assertScope;
1016 return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
1017 }
1018
1019#if ENABLE(JIT)
1020 static Ref<Snippet> checkSubClassSnippet()
1021 {
1022 DollarVMAssertScope assertScope;
1023 Ref<Snippet> snippet = Snippet::create();
1024 snippet->setGenerator([=] (CCallHelpers& jit, SnippetParams& params) {
1025 DollarVMAssertScope assertScope;
1026 CCallHelpers::JumpList failureCases;
1027 failureCases.append(jit.branchIfNotType(params[0].gpr(), JSC::JSType(LastJSCObjectType + 1)));
1028 return failureCases;
1029 });
1030 return snippet;
1031 }
1032#endif
1033
1034 static DOMJITNode* create(VM& vm, Structure* structure)
1035 {
1036 DollarVMAssertScope assertScope;
1037 DOMJITNode* getter = new (NotNull, allocateCell<DOMJITNode>(vm)) DOMJITNode(vm, structure);
1038 getter->finishCreation(vm);
1039 return getter;
1040 }
1041
1042 int32_t value() const
1043 {
1044 return m_value;
1045 }
1046
1047 static ptrdiff_t offsetOfValue() { return OBJECT_OFFSETOF(DOMJITNode, m_value); }
1048
1049private:
1050 int32_t m_value { 42 };
1051};
1052
1053
1054static JSC_DECLARE_CUSTOM_GETTER(domJITGetterCustomGetter);
1055extern "C" { static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(domJITGetterSlowCall, EncodedJSValue, (JSGlobalObject*, void*)); }
1056
1057class DOMJITGetter : public DOMJITNode {
1058public:
1059 DOMJITGetter(VM& vm, Structure* structure)
1060 : Base(vm, structure)
1061 {
1062 DollarVMAssertScope assertScope;
1063 }
1064
1065 DECLARE_INFO;
1066 typedef DOMJITNode Base;
1067 static constexpr unsigned StructureFlags = Base::StructureFlags;
1068
1069 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
1070 {
1071 DollarVMAssertScope assertScope;
1072 return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
1073 }
1074
1075 static DOMJITGetter* create(VM& vm, Structure* structure)
1076 {
1077 DollarVMAssertScope assertScope;
1078 DOMJITGetter* getter = new (NotNull, allocateCell<DOMJITGetter>(vm)) DOMJITGetter(vm, structure);
1079 getter->finishCreation(vm);
1080 return getter;
1081 }
1082
1083 class DOMJITAttribute : public DOMJIT::GetterSetter {
1084 public:
1085 ALWAYS_INLINE constexpr DOMJITAttribute()
1086 : DOMJIT::GetterSetter(
1087 domJITGetterCustomGetter,
1088#if ENABLE(JIT)
1089 &callDOMGetter,
1090#else
1091 nullptr,
1092#endif
1093 SpecInt32Only)
1094 {
1095 }
1096
1097#if ENABLE(JIT)
1098 static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()
1099 {
1100 DollarVMAssertScope assertScope;
1101 Ref<DOMJIT::CallDOMGetterSnippet> snippet = DOMJIT::CallDOMGetterSnippet::create();
1102 snippet->requireGlobalObject = true;
1103 snippet->setGenerator([=] (CCallHelpers& jit, SnippetParams& params) {
1104 DollarVMAssertScope assertScope;
1105 JSValueRegs results = params[0].jsValueRegs();
1106 GPRReg domGPR = params[1].gpr();
1107 GPRReg globalObjectGPR = params[2].gpr();
1108 params.addSlowPathCall(jit.jump(), jit, domJITGetterSlowCall, results, globalObjectGPR, domGPR);
1109 return CCallHelpers::JumpList();
1110
1111 });
1112 return snippet;
1113 }
1114#endif
1115 };
1116
1117private:
1118 void finishCreation(VM&);
1119};
1120
1121static const DOMJITGetter::DOMJITAttribute DOMJITGetterDOMJIT;
1122
1123void DOMJITGetter::finishCreation(VM& vm)
1124{
1125 DollarVMAssertScope assertScope;
1126 Base::finishCreation(vm);
1127 {
1128 const DOMJIT::GetterSetter* domJIT = &DOMJITGetterDOMJIT;
1129 auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJIT->getter(), nullptr, DOMAttributeAnnotation { DOMJITNode::info(), domJIT });
1130 putDirectCustomAccessor(vm, Identifier::fromString(vm, "customGetter"_s), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);
1131 }
1132 {
1133 auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJITGetterCustomGetter, nullptr, DOMAttributeAnnotation { DOMJITNode::info(), nullptr });
1134 putDirectCustomAccessor(vm, Identifier::fromString(vm, "customGetter2"_s), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);
1135 }
1136}
1137
1138JSC_DEFINE_CUSTOM_GETTER(domJITGetterCustomGetter, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
1139{
1140 DollarVMAssertScope assertScope;
1141 VM& vm = globalObject->vm();
1142 auto scope = DECLARE_THROW_SCOPE(vm);
1143 DOMJITNode* thisObject = jsDynamicCast<DOMJITNode*>(JSValue::decode(thisValue));
1144 if (!thisObject)
1145 return throwVMTypeError(globalObject, scope);
1146 return JSValue::encode(jsNumber(thisObject->value()));
1147}
1148
1149JSC_DEFINE_JIT_OPERATION(domJITGetterSlowCall, EncodedJSValue, (JSGlobalObject* globalObject, void* pointer))
1150{
1151 DollarVMAssertScope assertScope;
1152 VM& vm = globalObject->vm();
1153 CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
1154 JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
1155 return JSValue::encode(jsNumber(static_cast<DOMJITGetter*>(pointer)->value()));
1156}
1157
1158
1159static JSC_DECLARE_CUSTOM_GETTER(domJITGetterNoEffectCustomGetter);
1160extern "C" { static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(domJITGetterNoEffectSlowCall, EncodedJSValue, (JSGlobalObject*, void*)); }
1161
1162class DOMJITGetterNoEffects : public DOMJITNode {
1163public:
1164 DOMJITGetterNoEffects(VM& vm, Structure* structure)
1165 : Base(vm, structure)
1166 {
1167 DollarVMAssertScope assertScope;
1168 }
1169
1170 DECLARE_INFO;
1171 typedef DOMJITNode Base;
1172 static constexpr unsigned StructureFlags = Base::StructureFlags;
1173
1174 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
1175 {
1176 DollarVMAssertScope assertScope;
1177 return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
1178 }
1179
1180 static DOMJITGetterNoEffects* create(VM& vm, Structure* structure)
1181 {
1182 DollarVMAssertScope assertScope;
1183 DOMJITGetterNoEffects* getter = new (NotNull, allocateCell<DOMJITGetterNoEffects>(vm)) DOMJITGetterNoEffects(vm, structure);
1184 getter->finishCreation(vm);
1185 return getter;
1186 }
1187
1188 class DOMJITAttribute : public DOMJIT::GetterSetter {
1189 public:
1190 ALWAYS_INLINE constexpr DOMJITAttribute()
1191 : DOMJIT::GetterSetter(
1192 domJITGetterNoEffectCustomGetter,
1193#if ENABLE(JIT)
1194 &callDOMGetter,
1195#else
1196 nullptr,
1197#endif
1198 SpecInt32Only)
1199 {
1200 }
1201
1202#if ENABLE(JIT)
1203 static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()
1204 {
1205 DollarVMAssertScope assertScope;
1206 Ref<DOMJIT::CallDOMGetterSnippet> snippet = DOMJIT::CallDOMGetterSnippet::create();
1207 snippet->effect = DOMJIT::Effect::forRead(DOMJIT::HeapRange(10, 11));
1208 snippet->requireGlobalObject = true;
1209 snippet->setGenerator([=] (CCallHelpers& jit, SnippetParams& params) {
1210 DollarVMAssertScope assertScope;
1211 JSValueRegs results = params[0].jsValueRegs();
1212 GPRReg domGPR = params[1].gpr();
1213 GPRReg globalObjectGPR = params[2].gpr();
1214 params.addSlowPathCall(jit.jump(), jit, domJITGetterNoEffectSlowCall, results, globalObjectGPR, domGPR);
1215 return CCallHelpers::JumpList();
1216
1217 });
1218 return snippet;
1219 }
1220#endif
1221 };
1222
1223private:
1224 void finishCreation(VM&);
1225};
1226
1227static const DOMJITGetterNoEffects::DOMJITAttribute DOMJITGetterNoEffectsDOMJIT;
1228
1229void DOMJITGetterNoEffects::finishCreation(VM& vm)
1230{
1231 DollarVMAssertScope assertScope;
1232 Base::finishCreation(vm);
1233 const DOMJIT::GetterSetter* domJIT = &DOMJITGetterNoEffectsDOMJIT;
1234 auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJIT->getter(), nullptr, DOMAttributeAnnotation { DOMJITNode::info(), domJIT });
1235 putDirectCustomAccessor(vm, Identifier::fromString(vm, "customGetter"_s), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);
1236}
1237
1238JSC_DEFINE_CUSTOM_GETTER(domJITGetterNoEffectCustomGetter, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
1239{
1240 DollarVMAssertScope assertScope;
1241 VM& vm = globalObject->vm();
1242 auto scope = DECLARE_THROW_SCOPE(vm);
1243 DOMJITNode* thisObject = jsDynamicCast<DOMJITNode*>(JSValue::decode(thisValue));
1244 if (!thisObject)
1245 return throwVMTypeError(globalObject, scope);
1246 return JSValue::encode(jsNumber(thisObject->value()));
1247}
1248
1249JSC_DEFINE_JIT_OPERATION(domJITGetterNoEffectSlowCall, EncodedJSValue, (JSGlobalObject* globalObject, void* pointer))
1250{
1251 DollarVMAssertScope assertScope;
1252 VM& vm = globalObject->vm();
1253 CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
1254 JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
1255 return JSValue::encode(jsNumber(static_cast<DOMJITGetterNoEffects*>(pointer)->value()));
1256}
1257
1258static JSC_DECLARE_CUSTOM_GETTER(domJITGetterComplexCustomGetter);
1259extern "C" { static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(domJITGetterComplexSlowCall, EncodedJSValue, (JSGlobalObject*, void*)); }
1260
1261class DOMJITGetterComplex : public DOMJITNode {
1262public:
1263 DOMJITGetterComplex(VM& vm, Structure* structure)
1264 : Base(vm, structure)
1265 {
1266 DollarVMAssertScope assertScope;
1267 }
1268
1269 DECLARE_INFO;
1270 typedef DOMJITNode Base;
1271 static constexpr unsigned StructureFlags = Base::StructureFlags;
1272
1273 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
1274 {
1275 DollarVMAssertScope assertScope;
1276 return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
1277 }
1278
1279 static DOMJITGetterComplex* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
1280 {
1281 DollarVMAssertScope assertScope;
1282 DOMJITGetterComplex* getter = new (NotNull, allocateCell<DOMJITGetterComplex>(vm)) DOMJITGetterComplex(vm, structure);
1283 getter->finishCreation(vm, globalObject);
1284 return getter;
1285 }
1286
1287 class DOMJITAttribute : public DOMJIT::GetterSetter {
1288 public:
1289 ALWAYS_INLINE constexpr DOMJITAttribute()
1290 : DOMJIT::GetterSetter(
1291 domJITGetterComplexCustomGetter,
1292#if ENABLE(JIT)
1293 &callDOMGetter,
1294#else
1295 nullptr,
1296#endif
1297 SpecInt32Only)
1298 {
1299 }
1300
1301#if ENABLE(JIT)
1302 static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()
1303 {
1304 DollarVMAssertScope assertScope;
1305 Ref<DOMJIT::CallDOMGetterSnippet> snippet = DOMJIT::CallDOMGetterSnippet::create();
1306 static_assert(GPRInfo::numberOfRegisters >= 4, "Number of registers should be larger or equal to 4.");
1307 unsigned numGPScratchRegisters = GPRInfo::numberOfRegisters - 4;
1308 snippet->numGPScratchRegisters = numGPScratchRegisters;
1309 snippet->numFPScratchRegisters = 3;
1310 snippet->requireGlobalObject = true;
1311 snippet->setGenerator([=] (CCallHelpers& jit, SnippetParams& params) {
1312 DollarVMAssertScope assertScope;
1313 JSValueRegs results = params[0].jsValueRegs();
1314 GPRReg domGPR = params[1].gpr();
1315 GPRReg globalObjectGPR = params[2].gpr();
1316 for (unsigned i = 0; i < numGPScratchRegisters; ++i)
1317 jit.move(CCallHelpers::TrustedImm32(42), params.gpScratch(i));
1318
1319 params.addSlowPathCall(jit.jump(), jit, domJITGetterComplexSlowCall, results, globalObjectGPR, domGPR);
1320 return CCallHelpers::JumpList();
1321 });
1322 return snippet;
1323 }
1324#endif
1325 };
1326
1327 void finishCreation(VM&, JSGlobalObject*);
1328
1329 bool m_enableException { false };
1330};
1331
1332JSC_DEFINE_HOST_FUNCTION(functionDOMJITGetterComplexEnableException, (JSGlobalObject*, CallFrame* callFrame))
1333{
1334 DollarVMAssertScope assertScope;
1335 auto* object = jsDynamicCast<DOMJITGetterComplex*>(callFrame->thisValue());
1336 if (object)
1337 object->m_enableException = true;
1338 return JSValue::encode(jsUndefined());
1339}
1340
1341JSC_DEFINE_CUSTOM_GETTER(domJITGetterComplexCustomGetter, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
1342{
1343 DollarVMAssertScope assertScope;
1344 VM& vm = globalObject->vm();
1345 auto scope = DECLARE_THROW_SCOPE(vm);
1346
1347 auto* thisObject = jsDynamicCast<DOMJITGetterComplex*>(JSValue::decode(thisValue));
1348 if (!thisObject)
1349 return throwVMTypeError(globalObject, scope);
1350 if (thisObject->m_enableException)
1351 return JSValue::encode(throwException(globalObject, scope, createError(globalObject, "DOMJITGetterComplex slow call exception"_s)));
1352 return JSValue::encode(jsNumber(thisObject->value()));
1353}
1354
1355JSC_DEFINE_JIT_OPERATION(domJITGetterComplexSlowCall, EncodedJSValue, (JSGlobalObject* globalObject, void* pointer))
1356{
1357 DollarVMAssertScope assertScope;
1358 VM& vm = globalObject->vm();
1359 CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
1360 JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
1361 auto scope = DECLARE_THROW_SCOPE(vm);
1362 auto* object = static_cast<DOMJITNode*>(pointer);
1363 auto* domjitGetterComplex = jsDynamicCast<DOMJITGetterComplex*>(object);
1364 if (domjitGetterComplex) {
1365 if (domjitGetterComplex->m_enableException)
1366 return JSValue::encode(throwException(globalObject, scope, createError(globalObject, "DOMJITGetterComplex slow call exception"_s)));
1367 }
1368 return JSValue::encode(jsNumber(object->value()));
1369}
1370
1371static const DOMJITGetterComplex::DOMJITAttribute DOMJITGetterComplexDOMJIT;
1372
1373void DOMJITGetterComplex::finishCreation(VM& vm, JSGlobalObject* globalObject)
1374{
1375 DollarVMAssertScope assertScope;
1376 Base::finishCreation(vm);
1377 const DOMJIT::GetterSetter* domJIT = &DOMJITGetterComplexDOMJIT;
1378 auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJIT->getter(), nullptr, DOMAttributeAnnotation { DOMJITGetterComplex::info(), domJIT });
1379 putDirectCustomAccessor(vm, Identifier::fromString(vm, "customGetter"_s), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);
1380 putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "enableException"_s), 0, functionDOMJITGetterComplexEnableException, NoIntrinsic, 0);
1381}
1382
1383extern "C" { static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(functionDOMJITFunctionObjectWithoutTypeCheck, EncodedJSValue, (JSGlobalObject* globalObject, DOMJITNode*)); }
1384
1385class DOMJITFunctionObject : public DOMJITNode {
1386public:
1387 DOMJITFunctionObject(VM& vm, Structure* structure)
1388 : Base(vm, structure)
1389 {
1390 DollarVMAssertScope assertScope;
1391 }
1392
1393 DECLARE_INFO;
1394 typedef DOMJITNode Base;
1395 static constexpr unsigned StructureFlags = Base::StructureFlags;
1396
1397 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
1398 {
1399 DollarVMAssertScope assertScope;
1400 return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
1401 }
1402
1403 static DOMJITFunctionObject* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
1404 {
1405 DollarVMAssertScope assertScope;
1406 DOMJITFunctionObject* object = new (NotNull, allocateCell<DOMJITFunctionObject>(vm)) DOMJITFunctionObject(vm, structure);
1407 object->finishCreation(vm, globalObject);
1408 return object;
1409 }
1410
1411#if ENABLE(JIT)
1412 static Ref<Snippet> checkSubClassSnippet()
1413 {
1414 DollarVMAssertScope assertScope;
1415 Ref<Snippet> snippet = Snippet::create();
1416 snippet->numFPScratchRegisters = 1;
1417 snippet->setGenerator([=] (CCallHelpers& jit, SnippetParams& params) {
1418 DollarVMAssertScope assertScope;
1419 static const double value = 42.0;
1420 CCallHelpers::JumpList failureCases;
1421 // May use scratch registers.
1422 jit.loadDouble(CCallHelpers::TrustedImmPtr(&value), params.fpScratch(0));
1423 failureCases.append(jit.branchIfNotType(params[0].gpr(), JSC::JSType(LastJSCObjectType + 1)));
1424 return failureCases;
1425 });
1426 return snippet;
1427 }
1428#endif
1429
1430private:
1431 void finishCreation(VM&, JSGlobalObject*);
1432};
1433
1434JSC_DEFINE_HOST_FUNCTION(functionDOMJITFunctionObjectWithTypeCheck, (JSGlobalObject* globalObject, CallFrame* callFrame))
1435{
1436 DollarVMAssertScope assertScope;
1437 VM& vm = globalObject->vm();
1438 auto scope = DECLARE_THROW_SCOPE(vm);
1439
1440 DOMJITNode* thisObject = jsDynamicCast<DOMJITNode*>(callFrame->thisValue());
1441 if (!thisObject)
1442 return throwVMTypeError(globalObject, scope);
1443 return JSValue::encode(jsNumber(thisObject->value()));
1444}
1445
1446JSC_DEFINE_JIT_OPERATION(functionDOMJITFunctionObjectWithoutTypeCheck, EncodedJSValue, (JSGlobalObject* globalObject, DOMJITNode* node))
1447{
1448 DollarVMAssertScope assertScope;
1449 VM& vm = globalObject->vm();
1450 CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
1451 JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
1452 return JSValue::encode(jsNumber(node->value()));
1453}
1454
1455static const DOMJIT::Signature DOMJITFunctionObjectSignature(functionDOMJITFunctionObjectWithoutTypeCheck, DOMJITFunctionObject::info(), DOMJIT::Effect::forRead(DOMJIT::HeapRange(DOMJIT::HeapRange::ConstExpr, 0, 1)), SpecInt32Only);
1456
1457void DOMJITFunctionObject::finishCreation(VM& vm, JSGlobalObject* globalObject)
1458{
1459 DollarVMAssertScope assertScope;
1460 Base::finishCreation(vm);
1461 putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "func"_s), 0, functionDOMJITFunctionObjectWithTypeCheck, NoIntrinsic, &DOMJITFunctionObjectSignature, static_cast<unsigned>(PropertyAttribute::ReadOnly));
1462}
1463
1464extern "C" { static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(functionDOMJITCheckJSCastObjectWithoutTypeCheck, EncodedJSValue, (JSGlobalObject* globalObject, DOMJITNode* node)); }
1465
1466class DOMJITCheckJSCastObject : public DOMJITNode {
1467public:
1468 DOMJITCheckJSCastObject(VM& vm, Structure* structure)
1469 : Base(vm, structure)
1470 {
1471 DollarVMAssertScope assertScope;
1472 }
1473
1474 DECLARE_INFO;
1475 typedef DOMJITNode Base;
1476 static constexpr unsigned StructureFlags = Base::StructureFlags;
1477
1478 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
1479 {
1480 DollarVMAssertScope assertScope;
1481 return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
1482 }
1483
1484 static DOMJITCheckJSCastObject* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
1485 {
1486 DollarVMAssertScope assertScope;
1487 DOMJITCheckJSCastObject* object = new (NotNull, allocateCell<DOMJITCheckJSCastObject>(vm)) DOMJITCheckJSCastObject(vm, structure);
1488 object->finishCreation(vm, globalObject);
1489 return object;
1490 }
1491
1492private:
1493 void finishCreation(VM&, JSGlobalObject*);
1494};
1495
1496JSC_DEFINE_HOST_FUNCTION(functionDOMJITCheckJSCastObjectWithTypeCheck, (JSGlobalObject* globalObject, CallFrame* callFrame))
1497{
1498 DollarVMAssertScope assertScope;
1499 VM& vm = globalObject->vm();
1500 auto scope = DECLARE_THROW_SCOPE(vm);
1501
1502 auto* thisObject = jsDynamicCast<DOMJITCheckJSCastObject*>(callFrame->thisValue());
1503 if (!thisObject)
1504 return throwVMTypeError(globalObject, scope);
1505 return JSValue::encode(jsNumber(thisObject->value()));
1506}
1507
1508JSC_DEFINE_JIT_OPERATION(functionDOMJITCheckJSCastObjectWithoutTypeCheck, EncodedJSValue, (JSGlobalObject* globalObject, DOMJITNode* node))
1509{
1510 DollarVMAssertScope assertScope;
1511 VM& vm = globalObject->vm();
1512 CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
1513 JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
1514 return JSValue::encode(jsNumber(node->value()));
1515}
1516
1517static const DOMJIT::Signature DOMJITCheckJSCastObjectSignature(functionDOMJITCheckJSCastObjectWithoutTypeCheck, DOMJITCheckJSCastObject::info(), DOMJIT::Effect::forRead(DOMJIT::HeapRange::top()), SpecInt32Only);
1518
1519void DOMJITCheckJSCastObject::finishCreation(VM& vm, JSGlobalObject* globalObject)
1520{
1521 DollarVMAssertScope assertScope;
1522 Base::finishCreation(vm);
1523 putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "func"_s), 0, functionDOMJITCheckJSCastObjectWithTypeCheck, NoIntrinsic, &DOMJITCheckJSCastObjectSignature, static_cast<unsigned>(PropertyAttribute::ReadOnly));
1524}
1525
1526static JSC_DECLARE_CUSTOM_GETTER(domJITGetterBaseJSObjectCustomGetter);
1527extern "C" { static JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(domJITGetterBaseJSObjectSlowCall, EncodedJSValue, (JSGlobalObject*, void*)); }
1528
1529class DOMJITGetterBaseJSObject : public DOMJITNode {
1530public:
1531 DOMJITGetterBaseJSObject(VM& vm, Structure* structure)
1532 : Base(vm, structure)
1533 {
1534 DollarVMAssertScope assertScope;
1535 }
1536
1537 DECLARE_INFO;
1538 using Base = DOMJITNode;
1539 static constexpr unsigned StructureFlags = Base::StructureFlags;
1540
1541 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
1542 {
1543 DollarVMAssertScope assertScope;
1544 return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info());
1545 }
1546
1547 static DOMJITGetterBaseJSObject* create(VM& vm, Structure* structure)
1548 {
1549 DollarVMAssertScope assertScope;
1550 DOMJITGetterBaseJSObject* getter = new (NotNull, allocateCell<DOMJITGetterBaseJSObject>(vm)) DOMJITGetterBaseJSObject(vm, structure);
1551 getter->finishCreation(vm);
1552 return getter;
1553 }
1554
1555 class DOMJITAttribute : public DOMJIT::GetterSetter {
1556 public:
1557 ALWAYS_INLINE constexpr DOMJITAttribute()
1558 : DOMJIT::GetterSetter(
1559 domJITGetterBaseJSObjectCustomGetter,
1560#if ENABLE(JIT)
1561 &callDOMGetter,
1562#else
1563 nullptr,
1564#endif
1565 SpecBytecodeTop)
1566 {
1567 }
1568
1569#if ENABLE(JIT)
1570 static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()
1571 {
1572 DollarVMAssertScope assertScope;
1573 Ref<DOMJIT::CallDOMGetterSnippet> snippet = DOMJIT::CallDOMGetterSnippet::create();
1574 snippet->requireGlobalObject = true;
1575 snippet->setGenerator([=] (CCallHelpers& jit, SnippetParams& params) {
1576 DollarVMAssertScope assertScope;
1577 JSValueRegs results = params[0].jsValueRegs();
1578 GPRReg domGPR = params[1].gpr();
1579 GPRReg globalObjectGPR = params[2].gpr();
1580 params.addSlowPathCall(jit.jump(), jit, domJITGetterBaseJSObjectSlowCall, results, globalObjectGPR, domGPR);
1581 return CCallHelpers::JumpList();
1582
1583 });
1584 return snippet;
1585 }
1586#endif
1587 };
1588
1589private:
1590 void finishCreation(VM&);
1591};
1592
1593static const DOMJITGetterBaseJSObject::DOMJITAttribute DOMJITGetterBaseJSObjectDOMJIT;
1594
1595void DOMJITGetterBaseJSObject::finishCreation(VM& vm)
1596{
1597 DollarVMAssertScope assertScope;
1598 Base::finishCreation(vm);
1599 const DOMJIT::GetterSetter* domJIT = &DOMJITGetterBaseJSObjectDOMJIT;
1600 auto* customGetterSetter = DOMAttributeGetterSetter::create(vm, domJIT->getter(), nullptr, DOMAttributeAnnotation { JSObject::info(), domJIT });
1601 putDirectCustomAccessor(vm, Identifier::fromString(vm, "customGetter"_s), customGetterSetter, PropertyAttribute::ReadOnly | PropertyAttribute::CustomAccessor);
1602}
1603
1604JSC_DEFINE_CUSTOM_GETTER(domJITGetterBaseJSObjectCustomGetter, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
1605{
1606 DollarVMAssertScope assertScope;
1607 VM& vm = globalObject->vm();
1608 auto scope = DECLARE_THROW_SCOPE(vm);
1609 JSObject* thisObject = jsDynamicCast<JSObject*>(JSValue::decode(thisValue));
1610 if (!thisObject)
1611 return throwVMTypeError(globalObject, scope);
1612 return JSValue::encode(thisObject->getPrototypeDirect());
1613}
1614
1615JSC_DEFINE_JIT_OPERATION(domJITGetterBaseJSObjectSlowCall, EncodedJSValue, (JSGlobalObject* globalObject, void* pointer))
1616{
1617 DollarVMAssertScope assertScope;
1618 VM& vm = globalObject->vm();
1619 CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
1620 JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
1621 JSObject* object = static_cast<JSObject*>(pointer);
1622 return JSValue::encode(object->getPrototypeDirect());
1623}
1624
1625class Message : public ThreadSafeRefCounted<Message> {
1626public:
1627 Message(ArrayBufferContents&&, int32_t);
1628 ~Message();
1629
1630 ArrayBufferContents&& releaseContents() { return WTFMove(m_contents); }
1631 int32_t index() const { return m_index; }
1632
1633private:
1634 ArrayBufferContents m_contents;
1635 int32_t m_index { 0 };
1636};
1637
1638class JSTestCustomGetterSetter : public JSNonFinalObject {
1639public:
1640 using Base = JSNonFinalObject;
1641 static constexpr unsigned StructureFlags = Base::StructureFlags;
1642
1643 template<typename CellType, SubspaceAccess>
1644 static CompleteSubspace* subspaceFor(VM& vm)
1645 {
1646 return &vm.cellSpace();
1647 }
1648
1649 JSTestCustomGetterSetter(VM& vm, Structure* structure)
1650 : Base(vm, structure)
1651 {
1652 DollarVMAssertScope assertScope;
1653 }
1654
1655 static JSTestCustomGetterSetter* create(VM& vm, JSGlobalObject*, Structure* structure)
1656 {
1657 DollarVMAssertScope assertScope;
1658 JSTestCustomGetterSetter* result = new (NotNull, allocateCell<JSTestCustomGetterSetter>(vm)) JSTestCustomGetterSetter(vm, structure);
1659 result->finishCreation(vm);
1660 return result;
1661 }
1662
1663 void finishCreation(VM&);
1664
1665 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject)
1666 {
1667 DollarVMAssertScope assertScope;
1668 return Structure::create(vm, globalObject, globalObject->objectPrototype(), TypeInfo(ObjectType, StructureFlags), info());
1669 }
1670
1671 DECLARE_INFO;
1672};
1673
1674
1675static JSC_DECLARE_CUSTOM_GETTER(customGetAccessor);
1676static JSC_DECLARE_CUSTOM_GETTER(customGetValue);
1677static JSC_DECLARE_CUSTOM_GETTER(customGetValue2);
1678static JSC_DECLARE_CUSTOM_GETTER(customGetAccessorGlobalObject);
1679static JSC_DECLARE_CUSTOM_GETTER(customGetValueGlobalObject);
1680static JSC_DECLARE_CUSTOM_SETTER(customSetAccessor);
1681static JSC_DECLARE_CUSTOM_SETTER(customSetAccessorGlobalObject);
1682static JSC_DECLARE_CUSTOM_SETTER(customSetValue);
1683static JSC_DECLARE_CUSTOM_SETTER(customSetValue2);
1684static JSC_DECLARE_CUSTOM_SETTER(customSetValueGlobalObject);
1685static JSC_DECLARE_CUSTOM_SETTER(customFunctionSetter);
1686
1687JSC_DEFINE_CUSTOM_GETTER(customGetAccessor, (JSGlobalObject*, EncodedJSValue thisValue, PropertyName))
1688{
1689 // Passed |this|
1690 return thisValue;
1691}
1692
1693JSC_DEFINE_CUSTOM_GETTER(customGetValue, (JSGlobalObject*, EncodedJSValue slotValue, PropertyName))
1694{
1695 RELEASE_ASSERT(JSValue::decode(slotValue).inherits<JSTestCustomGetterSetter>());
1696 // Passed property holder.
1697 return slotValue;
1698}
1699
1700JSC_DEFINE_CUSTOM_GETTER(customGetValue2, (JSGlobalObject* globalObject, EncodedJSValue slotValue, PropertyName))
1701{
1702 DollarVMAssertScope assertScope;
1703 VM& vm = globalObject->vm();
1704
1705 RELEASE_ASSERT(JSValue::decode(slotValue).inherits<JSTestCustomGetterSetter>());
1706
1707 auto* target = jsCast<JSTestCustomGetterSetter*>(JSValue::decode(slotValue));
1708 JSValue value = target->getDirect(vm, Identifier::fromString(vm, "value2"_s));
1709 return JSValue::encode(value ? value : jsUndefined());
1710}
1711
1712JSC_DEFINE_CUSTOM_GETTER(customGetAccessorGlobalObject, (JSGlobalObject* globalObject, EncodedJSValue, PropertyName))
1713{
1714 return JSValue::encode(globalObject);
1715}
1716
1717JSC_DEFINE_CUSTOM_GETTER(customGetValueGlobalObject, (JSGlobalObject* globalObject, EncodedJSValue, PropertyName))
1718{
1719 return JSValue::encode(globalObject);
1720}
1721
1722JSC_DEFINE_CUSTOM_SETTER(customSetAccessor, (JSGlobalObject* globalObject, EncodedJSValue thisObject, EncodedJSValue encodedValue, PropertyName))
1723{
1724 DollarVMAssertScope assertScope;
1725 VM& vm = globalObject->vm();
1726
1727 JSValue value = JSValue::decode(encodedValue);
1728 if (!value.isObject())
1729 return false;
1730
1731 JSObject* object = asObject(value);
1732 PutPropertySlot slot(object);
1733 object->put(object, globalObject, Identifier::fromString(vm, "result"_s), JSValue::decode(thisObject), slot);
1734
1735 return true;
1736}
1737
1738JSC_DEFINE_CUSTOM_SETTER(customSetAccessorGlobalObject, (JSGlobalObject* globalObject, EncodedJSValue, EncodedJSValue encodedValue, PropertyName))
1739{
1740 DollarVMAssertScope assertScope;
1741 VM& vm = globalObject->vm();
1742
1743 JSValue value = JSValue::decode(encodedValue);
1744 if (!value.isObject())
1745 return false;
1746
1747 JSObject* object = asObject(value);
1748 PutPropertySlot slot(object);
1749 object->put(object, globalObject, Identifier::fromString(vm, "result"_s), globalObject, slot);
1750
1751 return true;
1752}
1753
1754JSC_DEFINE_CUSTOM_SETTER(customSetValue, (JSGlobalObject* globalObject, EncodedJSValue slotValue, EncodedJSValue encodedValue, PropertyName))
1755{
1756 DollarVMAssertScope assertScope;
1757 VM& vm = globalObject->vm();
1758
1759 RELEASE_ASSERT(JSValue::decode(slotValue).inherits<JSTestCustomGetterSetter>());
1760
1761 JSValue value = JSValue::decode(encodedValue);
1762 if (!value.isObject())
1763 return false;
1764
1765 JSObject* object = asObject(value);
1766 PutPropertySlot slot(object);
1767 object->put(object, globalObject, Identifier::fromString(vm, "result"_s), JSValue::decode(slotValue), slot);
1768
1769 return true;
1770}
1771
1772JSC_DEFINE_CUSTOM_SETTER(customSetValueGlobalObject, (JSGlobalObject* globalObject, EncodedJSValue slotValue, EncodedJSValue encodedValue, PropertyName))
1773{
1774 DollarVMAssertScope assertScope;
1775 VM& vm = globalObject->vm();
1776
1777 RELEASE_ASSERT(JSValue::decode(slotValue).inherits<JSTestCustomGetterSetter>());
1778
1779 JSValue value = JSValue::decode(encodedValue);
1780 if (!value.isObject())
1781 return false;
1782
1783 JSObject* object = asObject(value);
1784 PutPropertySlot slot(object);
1785 object->put(object, globalObject, Identifier::fromString(vm, "result"_s), globalObject, slot);
1786
1787 return true;
1788}
1789
1790JSC_DEFINE_CUSTOM_SETTER(customSetValue2, (JSGlobalObject* globalObject, EncodedJSValue slotValue, EncodedJSValue encodedValue, PropertyName))
1791{
1792 DollarVMAssertScope assertScope;
1793 VM& vm = globalObject->vm();
1794
1795 RELEASE_ASSERT(JSValue::decode(slotValue).inherits<JSTestCustomGetterSetter>());
1796 auto* target = jsCast<JSTestCustomGetterSetter*>(JSValue::decode(slotValue));
1797 PutPropertySlot slot(target);
1798 target->putDirect(vm, Identifier::fromString(vm, "value2"_s), JSValue::decode(encodedValue));
1799 return true;
1800}
1801
1802JSC_DEFINE_CUSTOM_SETTER(customFunctionSetter, (JSGlobalObject* globalObject, EncodedJSValue, EncodedJSValue encodedValue, PropertyName))
1803{
1804 DollarVMAssertScope assertScope;
1805
1806 JSValue value = JSValue::decode(encodedValue);
1807 JSFunction* function = jsDynamicCast<JSFunction*>(value);
1808 if (!function)
1809 return false;
1810
1811 auto callData = JSC::getCallData(function);
1812 MarkedArgumentBuffer args;
1813 call(globalObject, function, callData, jsUndefined(), args);
1814
1815 return true;
1816}
1817
1818void JSTestCustomGetterSetter::finishCreation(VM& vm)
1819{
1820 DollarVMAssertScope assertScope;
1821 Base::finishCreation(vm);
1822
1823 putDirectCustomAccessor(vm, Identifier::fromString(vm, "customValue"_s),
1824 CustomGetterSetter::create(vm, customGetValue, customSetValue), 0);
1825 putDirectCustomAccessor(vm, Identifier::fromString(vm, "customValue2"_s),
1826 CustomGetterSetter::create(vm, customGetValue2, customSetValue2), static_cast<unsigned>(PropertyAttribute::CustomValue));
1827 putDirectCustomAccessor(vm, Identifier::fromString(vm, "customAccessor"_s),
1828 CustomGetterSetter::create(vm, customGetAccessor, customSetAccessor), static_cast<unsigned>(PropertyAttribute::CustomAccessor));
1829 putDirectCustomAccessor(vm, Identifier::fromString(vm, "customValueGlobalObject"_s),
1830 CustomGetterSetter::create(vm, customGetValueGlobalObject, customSetValueGlobalObject), static_cast<unsigned>(PropertyAttribute::CustomValue));
1831 putDirectCustomAccessor(vm, Identifier::fromString(vm, "customAccessorGlobalObject"_s),
1832 CustomGetterSetter::create(vm, customGetAccessorGlobalObject, customSetAccessorGlobalObject), static_cast<unsigned>(PropertyAttribute::CustomAccessor));
1833 putDirectCustomAccessor(vm, Identifier::fromString(vm, "customValueNoSetter"_s),
1834 CustomGetterSetter::create(vm, customGetValue, nullptr), static_cast<unsigned>(PropertyAttribute::CustomValue));
1835 putDirectCustomAccessor(vm, Identifier::fromString(vm, "customAccessorReadOnly"_s),
1836 CustomGetterSetter::create(vm, customGetAccessor, nullptr), PropertyAttribute::CustomAccessor | PropertyAttribute::ReadOnly);
1837
1838 putDirectCustomAccessor(vm, Identifier::fromString(vm, "customFunction"_s),
1839 CustomGetterSetter::create(vm, customGetAccessor, customFunctionSetter), static_cast<unsigned>(PropertyAttribute::CustomAccessor));
1840
1841}
1842
1843const ClassInfo Element::s_info = { "Element"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(Element) };
1844const ClassInfo Root::s_info = { "Root"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(Root) };
1845const ClassInfo SimpleObject::s_info = { "SimpleObject"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(SimpleObject) };
1846const ClassInfo ImpureGetter::s_info = { "ImpureGetter"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(ImpureGetter) };
1847const ClassInfo CustomGetter::s_info = { "CustomGetter"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(CustomGetter) };
1848const ClassInfo RuntimeArray::s_info = { "RuntimeArray"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(RuntimeArray) };
1849#if ENABLE(JIT)
1850const ClassInfo DOMJITNode::s_info = { "DOMJITNode"_s, &Base::s_info, nullptr, &DOMJITNode::checkSubClassSnippet, CREATE_METHOD_TABLE(DOMJITNode) };
1851#else
1852const ClassInfo DOMJITNode::s_info = { "DOMJITNode"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITNode) };
1853#endif
1854const ClassInfo DOMJITGetter::s_info = { "DOMJITGetter"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetter) };
1855const ClassInfo DOMJITGetterNoEffects::s_info = { "DOMJITGetterNoEffects"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetterNoEffects) };
1856const ClassInfo DOMJITGetterComplex::s_info = { "DOMJITGetterComplex"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetterComplex) };
1857const ClassInfo DOMJITGetterBaseJSObject::s_info = { "DOMJITGetterBaseJSObject"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITGetterBaseJSObject) };
1858#if ENABLE(JIT)
1859const ClassInfo DOMJITFunctionObject::s_info = { "DOMJITFunctionObject"_s, &Base::s_info, nullptr, &DOMJITFunctionObject::checkSubClassSnippet, CREATE_METHOD_TABLE(DOMJITFunctionObject) };
1860#else
1861const ClassInfo DOMJITFunctionObject::s_info = { "DOMJITFunctionObject"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITFunctionObject) };
1862#endif
1863const ClassInfo DOMJITCheckJSCastObject::s_info = { "DOMJITCheckJSCastObject"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DOMJITCheckJSCastObject) };
1864const ClassInfo JSTestCustomGetterSetter::s_info = { "JSTestCustomGetterSetter"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSTestCustomGetterSetter) };
1865
1866const ClassInfo StaticCustomAccessor::s_info = { "StaticCustomAccessor"_s, &Base::s_info, &staticCustomAccessorTable, nullptr, CREATE_METHOD_TABLE(StaticCustomAccessor) };
1867const ClassInfo StaticCustomValue::s_info = { "StaticCustomValue"_s, &Base::s_info, &staticCustomValueTable, nullptr, CREATE_METHOD_TABLE(StaticCustomValue) };
1868const ClassInfo StaticDontDeleteDontEnum::s_info = { "StaticDontDeleteDontEnum"_s, &Base::s_info, &staticDontDeleteDontEnumTable, nullptr, CREATE_METHOD_TABLE(StaticDontDeleteDontEnum) };
1869const ClassInfo ObjectDoingSideEffectPutWithoutCorrectSlotStatus::s_info = { "ObjectDoingSideEffectPutWithoutCorrectSlotStatus"_s, &Base::s_info, &staticCustomAccessorTable, nullptr, CREATE_METHOD_TABLE(ObjectDoingSideEffectPutWithoutCorrectSlotStatus) };
1870
1871ElementHandleOwner* Element::handleOwner()
1872{
1873 DollarVMAssertScope assertScope;
1874 static ElementHandleOwner* owner = nullptr;
1875 if (!owner)
1876 owner = new ElementHandleOwner();
1877 return owner;
1878}
1879
1880void Element::finishCreation(VM& vm, Root* root)
1881{
1882 DollarVMAssertScope assertScope;
1883 Base::finishCreation(vm);
1884 setRoot(vm, root);
1885 m_root->setElement(this);
1886}
1887
1888#if ENABLE(WEBASSEMBLY)
1889
1890static JSC_DECLARE_HOST_FUNCTION(functionWasmStreamingParserAddBytes);
1891static JSC_DECLARE_HOST_FUNCTION(functionWasmStreamingParserFinalize);
1892
1893class WasmStreamingParser : public JSDestructibleObject {
1894public:
1895 using Base = JSDestructibleObject;
1896 template<typename CellType, SubspaceAccess>
1897 static CompleteSubspace* subspaceFor(VM& vm)
1898 {
1899 return &vm.destructibleObjectSpace();
1900 }
1901
1902 class Client final : public Wasm::StreamingParserClient {
1903 public:
1904 explicit Client(WasmStreamingParser* parser)
1905 : m_parser(parser)
1906 {
1907 }
1908
1909 bool didReceiveSectionData(Wasm::Section) final { return true; }
1910 bool didReceiveFunctionData(unsigned, const Wasm::FunctionData&) final { return true; }
1911 void didFinishParsing() final { }
1912
1913 WasmStreamingParser* m_parser;
1914 };
1915
1916 WasmStreamingParser(VM& vm, Structure* structure)
1917 : Base(vm, structure)
1918 , m_info(Wasm::ModuleInformation::create())
1919 , m_client(this)
1920 , m_streamingParser(m_info.get(), m_client)
1921 {
1922 DollarVMAssertScope assertScope;
1923 }
1924
1925 static WasmStreamingParser* create(VM& vm, JSGlobalObject* globalObject)
1926 {
1927 DollarVMAssertScope assertScope;
1928 Structure* structure = createStructure(vm, globalObject, jsNull());
1929 WasmStreamingParser* result = new (NotNull, allocateCell<WasmStreamingParser>(vm)) WasmStreamingParser(vm, structure);
1930 result->finishCreation(vm);
1931 return result;
1932 }
1933
1934 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
1935 {
1936 DollarVMAssertScope assertScope;
1937 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
1938 }
1939
1940 Wasm::StreamingParser& streamingParser() { return m_streamingParser; }
1941
1942 void finishCreation(VM& vm)
1943 {
1944 DollarVMAssertScope assertScope;
1945 Base::finishCreation(vm);
1946
1947 JSGlobalObject* globalObject = this->globalObject();
1948 putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "addBytes"_s), 0, functionWasmStreamingParserAddBytes, NoIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
1949 putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "finalize"_s), 0, functionWasmStreamingParserFinalize, NoIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
1950 }
1951
1952 DECLARE_INFO;
1953
1954 Ref<Wasm::ModuleInformation> m_info;
1955 Client m_client;
1956 Wasm::StreamingParser m_streamingParser;
1957};
1958
1959const ClassInfo WasmStreamingParser::s_info = { "WasmStreamingParser"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(WasmStreamingParser) };
1960
1961JSC_DEFINE_HOST_FUNCTION(functionWasmStreamingParserAddBytes, (JSGlobalObject* globalObject, CallFrame* callFrame))
1962{
1963 DollarVMAssertScope assertScope;
1964 VM& vm = globalObject->vm();
1965 auto scope = DECLARE_THROW_SCOPE(vm);
1966
1967 auto* thisObject = jsDynamicCast<WasmStreamingParser*>(callFrame->thisValue());
1968 if (!thisObject)
1969 RELEASE_AND_RETURN(scope, JSValue::encode(jsBoolean(false)));
1970
1971 JSValue value = callFrame->argument(0);
1972 BaseWebAssemblySourceProvider* provider = nullptr;
1973 if (auto* source = jsDynamicCast<JSSourceCode*>(value))
1974 provider = static_cast<BaseWebAssemblySourceProvider*>(source->sourceCode().provider());
1975 WebAssemblySourceProviderBufferGuard guard(provider);
1976
1977 auto data = getWasmBufferFromValue(globalObject, value, guard);
1978 RETURN_IF_EXCEPTION(scope, encodedJSValue());
1979 RELEASE_AND_RETURN(scope, JSValue::encode(jsNumber(static_cast<int32_t>(thisObject->streamingParser().addBytes(bitwise_cast<const uint8_t*>(data.first), data.second)))));
1980}
1981
1982JSC_DEFINE_HOST_FUNCTION(functionWasmStreamingParserFinalize, (JSGlobalObject*, CallFrame* callFrame))
1983{
1984 DollarVMAssertScope assertScope;
1985 auto* thisObject = jsDynamicCast<WasmStreamingParser*>(callFrame->thisValue());
1986 if (!thisObject)
1987 return JSValue::encode(jsBoolean(false));
1988 return JSValue::encode(jsNumber(static_cast<int32_t>(thisObject->streamingParser().finalize())));
1989}
1990
1991static JSC_DECLARE_HOST_FUNCTION(functionWasmStreamingCompilerAddBytes);
1992
1993class WasmStreamingCompiler : public JSDestructibleObject {
1994public:
1995 using Base = JSDestructibleObject;
1996 template<typename CellType, SubspaceAccess>
1997 static CompleteSubspace* subspaceFor(VM& vm)
1998 {
1999 return &vm.destructibleObjectSpace();
2000 }
2001
2002 WasmStreamingCompiler(VM& vm, Structure* structure, Wasm::CompilerMode compilerMode, JSGlobalObject* globalObject, JSPromise* promise, JSObject* importObject)
2003 : Base(vm, structure)
2004 , m_promise(vm, this, promise)
2005 , m_streamingCompiler(Wasm::StreamingCompiler::create(vm, compilerMode, globalObject, promise, importObject))
2006 {
2007 DollarVMAssertScope assertScope;
2008 }
2009
2010 static WasmStreamingCompiler* create(VM& vm, JSGlobalObject* globalObject, Wasm::CompilerMode compilerMode, JSObject* importObject)
2011 {
2012 DollarVMAssertScope assertScope;
2013 JSPromise* promise = JSPromise::create(vm, globalObject->promiseStructure());
2014 Structure* structure = createStructure(vm, globalObject, jsNull());
2015 WasmStreamingCompiler* result = new (NotNull, allocateCell<WasmStreamingCompiler>(vm)) WasmStreamingCompiler(vm, structure, compilerMode, globalObject, promise, importObject);
2016 result->finishCreation(vm);
2017 return result;
2018 }
2019
2020 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
2021 {
2022 DollarVMAssertScope assertScope;
2023 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
2024 }
2025
2026 Wasm::StreamingCompiler& streamingCompiler() { return m_streamingCompiler.get(); }
2027
2028 JSPromise* promise() const { return m_promise.get(); }
2029
2030 void finishCreation(VM& vm)
2031 {
2032 DollarVMAssertScope assertScope;
2033 Base::finishCreation(vm);
2034
2035 JSGlobalObject* globalObject = this->globalObject();
2036 putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "addBytes"_s), 0, functionWasmStreamingCompilerAddBytes, NoIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
2037 }
2038
2039 DECLARE_VISIT_CHILDREN;
2040
2041 DECLARE_INFO;
2042
2043 WriteBarrier<JSPromise> m_promise;
2044 Ref<Wasm::StreamingCompiler> m_streamingCompiler;
2045};
2046
2047template<typename Visitor>
2048void WasmStreamingCompiler::visitChildrenImpl(JSCell* cell, Visitor& visitor)
2049{
2050 DollarVMAssertScope assertScope;
2051 auto* thisObject = jsCast<WasmStreamingCompiler*>(cell);
2052 ASSERT_GC_OBJECT_INHERITS(thisObject, info());
2053 Base::visitChildren(thisObject, visitor);
2054 visitor.append(thisObject->m_promise);
2055}
2056
2057DEFINE_VISIT_CHILDREN(WasmStreamingCompiler);
2058
2059const ClassInfo WasmStreamingCompiler::s_info = { "WasmStreamingCompiler"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(WasmStreamingCompiler) };
2060
2061JSC_DEFINE_HOST_FUNCTION(functionWasmStreamingCompilerAddBytes, (JSGlobalObject* globalObject, CallFrame* callFrame))
2062{
2063 DollarVMAssertScope assertScope;
2064 VM& vm = globalObject->vm();
2065 auto scope = DECLARE_THROW_SCOPE(vm);
2066
2067 auto* thisObject = jsDynamicCast<WasmStreamingCompiler*>(callFrame->thisValue());
2068 if (!thisObject)
2069 RELEASE_AND_RETURN(scope, JSValue::encode(jsBoolean(false)));
2070
2071 JSValue value = callFrame->argument(0);
2072 BaseWebAssemblySourceProvider* provider = nullptr;
2073 if (auto* source = jsDynamicCast<JSSourceCode*>(value))
2074 provider = static_cast<BaseWebAssemblySourceProvider*>(source->sourceCode().provider());
2075 WebAssemblySourceProviderBufferGuard guard(provider);
2076
2077 auto data = getWasmBufferFromValue(globalObject, value, guard);
2078 RETURN_IF_EXCEPTION(scope, { });
2079 thisObject->streamingCompiler().addBytes(bitwise_cast<const uint8_t*>(data.first), data.second);
2080 return JSValue::encode(jsUndefined());
2081}
2082
2083#endif
2084
2085} // namespace
2086
2087namespace JSC {
2088
2089static NO_RETURN_DUE_TO_CRASH JSC_DECLARE_HOST_FUNCTION(functionCrash);
2090static JSC_DECLARE_HOST_FUNCTION(functionBreakpoint);
2091static JSC_DECLARE_HOST_FUNCTION(functionDFGTrue);
2092static JSC_DECLARE_HOST_FUNCTION(functionFTLTrue);
2093static JSC_DECLARE_HOST_FUNCTION(functionCpuMfence);
2094static JSC_DECLARE_HOST_FUNCTION(functionCpuRdtsc);
2095static JSC_DECLARE_HOST_FUNCTION(functionCpuCpuid);
2096static JSC_DECLARE_HOST_FUNCTION(functionCpuPause);
2097static JSC_DECLARE_HOST_FUNCTION(functionCpuClflush);
2098static JSC_DECLARE_HOST_FUNCTION(functionLLintTrue);
2099static JSC_DECLARE_HOST_FUNCTION(functionBaselineJITTrue);
2100static JSC_DECLARE_HOST_FUNCTION(functionNoInline);
2101static JSC_DECLARE_HOST_FUNCTION(functionGC);
2102static JSC_DECLARE_HOST_FUNCTION(functionEdenGC);
2103static JSC_DECLARE_HOST_FUNCTION(functionGCSweepAsynchronously);
2104static JSC_DECLARE_HOST_FUNCTION(functionDumpSubspaceHashes);
2105static JSC_DECLARE_HOST_FUNCTION(functionCallFrame);
2106static JSC_DECLARE_HOST_FUNCTION(functionCodeBlockForFrame);
2107static JSC_DECLARE_HOST_FUNCTION(functionCodeBlockFor);
2108static JSC_DECLARE_HOST_FUNCTION(functionDumpSourceFor);
2109static JSC_DECLARE_HOST_FUNCTION(functionDumpBytecodeFor);
2110static JSC_DECLARE_HOST_FUNCTION(functionDataLog);
2111static JSC_DECLARE_HOST_FUNCTION(functionPrint);
2112static JSC_DECLARE_HOST_FUNCTION(functionDumpCallFrame);
2113static JSC_DECLARE_HOST_FUNCTION(functionDumpStack);
2114static JSC_DECLARE_HOST_FUNCTION(functionDumpRegisters);
2115static JSC_DECLARE_HOST_FUNCTION(functionDumpCell);
2116static JSC_DECLARE_HOST_FUNCTION(functionIndexingMode);
2117static JSC_DECLARE_HOST_FUNCTION(functionInlineCapacity);
2118static JSC_DECLARE_HOST_FUNCTION(functionClearLinkBufferStats);
2119static JSC_DECLARE_HOST_FUNCTION(functionLinkBufferStats);
2120static JSC_DECLARE_HOST_FUNCTION(functionValue);
2121static JSC_DECLARE_HOST_FUNCTION(functionGetPID);
2122static JSC_DECLARE_HOST_FUNCTION(functionHaveABadTime);
2123static JSC_DECLARE_HOST_FUNCTION(functionIsHavingABadTime);
2124static JSC_DECLARE_HOST_FUNCTION(functionCallWithStackSize);
2125static JSC_DECLARE_HOST_FUNCTION(functionCreateGlobalObject);
2126static JSC_DECLARE_HOST_FUNCTION(functionCreateProxy);
2127static JSC_DECLARE_HOST_FUNCTION(functionCreateRuntimeArray);
2128static JSC_DECLARE_HOST_FUNCTION(functionCreateNullRopeString);
2129static JSC_DECLARE_HOST_FUNCTION(functionCreateImpureGetter);
2130static JSC_DECLARE_HOST_FUNCTION(functionCreateCustomGetterObject);
2131static JSC_DECLARE_HOST_FUNCTION(functionCreateDOMJITNodeObject);
2132static JSC_DECLARE_HOST_FUNCTION(functionCreateDOMJITGetterObject);
2133static JSC_DECLARE_HOST_FUNCTION(functionCreateDOMJITGetterNoEffectsObject);
2134static JSC_DECLARE_HOST_FUNCTION(functionCreateDOMJITGetterComplexObject);
2135static JSC_DECLARE_HOST_FUNCTION(functionCreateDOMJITFunctionObject);
2136static JSC_DECLARE_HOST_FUNCTION(functionCreateDOMJITCheckJSCastObject);
2137static JSC_DECLARE_HOST_FUNCTION(functionCreateDOMJITGetterBaseJSObject);
2138#if ENABLE(WEBASSEMBLY)
2139static JSC_DECLARE_HOST_FUNCTION(functionCreateWasmStreamingParser);
2140static JSC_DECLARE_HOST_FUNCTION(functionCreateWasmStreamingCompilerForCompile);
2141static JSC_DECLARE_HOST_FUNCTION(functionCreateWasmStreamingCompilerForInstantiate);
2142#endif
2143static JSC_DECLARE_HOST_FUNCTION(functionCreateStaticCustomAccessor);
2144static JSC_DECLARE_HOST_FUNCTION(functionCreateStaticCustomValue);
2145static JSC_DECLARE_HOST_FUNCTION(functionCreateStaticDontDeleteDontEnum);
2146static JSC_DECLARE_HOST_FUNCTION(functionCreateObjectDoingSideEffectPutWithoutCorrectSlotStatus);
2147static JSC_DECLARE_HOST_FUNCTION(functionCreateEmptyFunctionWithName);
2148static JSC_DECLARE_HOST_FUNCTION(functionSetImpureGetterDelegate);
2149static JSC_DECLARE_HOST_FUNCTION(functionCreateBuiltin);
2150static JSC_DECLARE_HOST_FUNCTION(functionGetPrivateProperty);
2151static JSC_DECLARE_HOST_FUNCTION(functionCreateRoot);
2152static JSC_DECLARE_HOST_FUNCTION(functionCreateElement);
2153static JSC_DECLARE_HOST_FUNCTION(functionGetElement);
2154static JSC_DECLARE_HOST_FUNCTION(functionCreateSimpleObject);
2155static JSC_DECLARE_HOST_FUNCTION(functionGetHiddenValue);
2156static JSC_DECLARE_HOST_FUNCTION(functionSetHiddenValue);
2157static JSC_DECLARE_HOST_FUNCTION(functionShadowChickenFunctionsOnStack);
2158static JSC_DECLARE_HOST_FUNCTION(functionSetGlobalConstRedeclarationShouldNotThrow);
2159static JSC_DECLARE_HOST_FUNCTION(functionFindTypeForExpression);
2160static JSC_DECLARE_HOST_FUNCTION(functionReturnTypeFor);
2161static JSC_DECLARE_HOST_FUNCTION(functionFlattenDictionaryObject);
2162static JSC_DECLARE_HOST_FUNCTION(functionDumpBasicBlockExecutionRanges);
2163static JSC_DECLARE_HOST_FUNCTION(functionHasBasicBlockExecuted);
2164static JSC_DECLARE_HOST_FUNCTION(functionBasicBlockExecutionCount);
2165static JSC_DECLARE_HOST_FUNCTION(functionEnableDebuggerModeWhenIdle);
2166static JSC_DECLARE_HOST_FUNCTION(functionDisableDebuggerModeWhenIdle);
2167static JSC_DECLARE_HOST_FUNCTION(functionDeleteAllCodeWhenIdle);
2168static JSC_DECLARE_HOST_FUNCTION(functionGlobalObjectCount);
2169static JSC_DECLARE_HOST_FUNCTION(functionGlobalObjectForObject);
2170static JSC_DECLARE_HOST_FUNCTION(functionGetGetterSetter);
2171static JSC_DECLARE_HOST_FUNCTION(functionLoadGetterFromGetterSetter);
2172static JSC_DECLARE_HOST_FUNCTION(functionCreateCustomTestGetterSetter);
2173static JSC_DECLARE_HOST_FUNCTION(functionDeltaBetweenButterflies);
2174static JSC_DECLARE_HOST_FUNCTION(functionCurrentCPUTime);
2175static JSC_DECLARE_HOST_FUNCTION(functionTotalGCTime);
2176static JSC_DECLARE_HOST_FUNCTION(functionParseCount);
2177static JSC_DECLARE_HOST_FUNCTION(functionIsWasmSupported);
2178static JSC_DECLARE_HOST_FUNCTION(functionMake16BitStringIfPossible);
2179static JSC_DECLARE_HOST_FUNCTION(functionGetStructureTransitionList);;
2180static JSC_DECLARE_HOST_FUNCTION(functionGetConcurrently);
2181static JSC_DECLARE_HOST_FUNCTION(functionHasOwnLengthProperty);
2182static JSC_DECLARE_HOST_FUNCTION(functionRejectPromiseAsHandled);
2183static JSC_DECLARE_HOST_FUNCTION(functionSetUserPreferredLanguages);
2184static JSC_DECLARE_HOST_FUNCTION(functionICUVersion);
2185static JSC_DECLARE_HOST_FUNCTION(functionICUHeaderVersion);
2186static JSC_DECLARE_HOST_FUNCTION(functionAssertEnabled);
2187static JSC_DECLARE_HOST_FUNCTION(functionSecurityAssertEnabled);
2188static JSC_DECLARE_HOST_FUNCTION(functionAsanEnabled);
2189static JSC_DECLARE_HOST_FUNCTION(functionIsMemoryLimited);
2190static JSC_DECLARE_HOST_FUNCTION(functionUseJIT);
2191static JSC_DECLARE_HOST_FUNCTION(functionIsGigacageEnabled);
2192static JSC_DECLARE_HOST_FUNCTION(functionToCacheableDictionary);
2193static JSC_DECLARE_HOST_FUNCTION(functionToUncacheableDictionary);
2194static JSC_DECLARE_HOST_FUNCTION(functionIsPrivateSymbol);
2195static JSC_DECLARE_HOST_FUNCTION(functionDumpAndResetPasDebugSpectrum);
2196static JSC_DECLARE_HOST_FUNCTION(functionMonotonicTimeNow);
2197static JSC_DECLARE_HOST_FUNCTION(functionWallTimeNow);
2198static JSC_DECLARE_HOST_FUNCTION(functionApproximateTimeNow);
2199#if ENABLE(JIT)
2200static JSC_DECLARE_HOST_FUNCTION(functionJITSizeStatistics);
2201static JSC_DECLARE_HOST_FUNCTION(functionDumpJITSizeStatistics);
2202static JSC_DECLARE_HOST_FUNCTION(functionResetJITSizeStatistics);
2203#endif
2204
2205static JSC_DECLARE_HOST_FUNCTION(functionEnsureArrayStorage);
2206
2207const ClassInfo JSDollarVM::s_info = { "DollarVM"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDollarVM) };
2208
2209static EncodedJSValue doPrint(JSGlobalObject* globalObject, CallFrame* callFrame, bool addLineFeed)
2210{
2211 DollarVMAssertScope assertScope;
2212 auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
2213 for (unsigned i = 0; i < callFrame->argumentCount(); ++i) {
2214 JSValue arg = callFrame->uncheckedArgument(i);
2215 if (arg.isCell()
2216 && !arg.isObject()
2217 && !arg.isString()
2218 && !arg.isBigInt()) {
2219 dataLog(arg);
2220 continue;
2221 }
2222 String argStr = callFrame->uncheckedArgument(i).toWTFString(globalObject);
2223 RETURN_IF_EXCEPTION(scope, encodedJSValue());
2224 dataLog(argStr);
2225 }
2226 if (addLineFeed)
2227 dataLog("\n");
2228 return JSValue::encode(jsUndefined());
2229}
2230
2231// Triggers a crash after dumping any paramater passed to it.
2232// Usage: $vm.crash(...)
2233JSC_DEFINE_HOST_FUNCTION_WITH_ATTRIBUTES(functionCrash, NO_RETURN_DUE_TO_CRASH, (JSGlobalObject* globalObject, CallFrame* callFrame))
2234{
2235 DollarVMAssertScope assertScope;
2236
2237 VM& vm = globalObject->vm();
2238 auto scope = DECLARE_CATCH_SCOPE(vm);
2239 if (callFrame->argumentCount()) {
2240 dataLogLn("Dumping ", callFrame->argumentCount(), " values before crashing:");
2241 const bool addLineFeed = true;
2242 doPrint(globalObject, callFrame, addLineFeed);
2243 if (scope.exception()) {
2244 JSValue value = scope.exception()->value();
2245 scope.clearException();
2246 dataLogLn("Error thrown while crashing: ", value.toWTFString(globalObject));
2247 }
2248 }
2249
2250 CRASH();
2251}
2252
2253// Executes a breakpoint instruction if the first argument is truthy or is unset.
2254// Usage: $vm.breakpoint(<condition>)
2255JSC_DEFINE_HOST_FUNCTION(functionBreakpoint, (JSGlobalObject* globalObject, CallFrame* callFrame))
2256{
2257 DollarVMAssertScope assertScope;
2258 // Nothing should throw here but we might as well double check...
2259 VM& vm = globalObject->vm();
2260 auto scope = DECLARE_CATCH_SCOPE(vm);
2261 UNUSED_PARAM(scope);
2262 if (!callFrame->argumentCount() || callFrame->argument(0).toBoolean(globalObject))
2263 WTFBreakpointTrap();
2264
2265 return encodedJSUndefined();
2266}
2267
2268// Returns true if the current frame is a DFG frame.
2269// Usage: isDFG = $vm.dfgTrue()
2270JSC_DEFINE_HOST_FUNCTION(functionDFGTrue, (JSGlobalObject*, CallFrame*))
2271{
2272 DollarVMAssertScope assertScope;
2273 return JSValue::encode(jsBoolean(false));
2274}
2275
2276// Returns true if the current frame is a FTL frame.
2277// Usage: isFTL = $vm.ftlTrue()
2278JSC_DEFINE_HOST_FUNCTION(functionFTLTrue, (JSGlobalObject*, CallFrame*))
2279{
2280 DollarVMAssertScope assertScope;
2281 return JSValue::encode(jsBoolean(false));
2282}
2283
2284JSC_DEFINE_HOST_FUNCTION(functionCpuMfence, (JSGlobalObject*, CallFrame*))
2285{
2286 DollarVMAssertScope assertScope;
2287#if CPU(X86_64) && !OS(WINDOWS)
2288 asm volatile("mfence" ::: "memory");
2289#endif
2290 return JSValue::encode(jsUndefined());
2291}
2292
2293JSC_DEFINE_HOST_FUNCTION(functionCpuRdtsc, (JSGlobalObject*, CallFrame*))
2294{
2295 DollarVMAssertScope assertScope;
2296#if CPU(X86_64) && !OS(WINDOWS)
2297 unsigned high;
2298 unsigned low;
2299 asm volatile ("rdtsc" : "=a"(low), "=d"(high));
2300 return JSValue::encode(jsNumber(low));
2301#else
2302 return JSValue::encode(jsNumber(0));
2303#endif
2304}
2305
2306JSC_DEFINE_HOST_FUNCTION(functionCpuCpuid, (JSGlobalObject*, CallFrame*))
2307{
2308 DollarVMAssertScope assertScope;
2309#if CPU(X86_64) && !OS(WINDOWS)
2310 WTF::x86_cpuid();
2311#endif
2312 return JSValue::encode(jsUndefined());
2313}
2314
2315JSC_DEFINE_HOST_FUNCTION(functionCpuPause, (JSGlobalObject*, CallFrame*))
2316{
2317 DollarVMAssertScope assertScope;
2318#if CPU(X86_64) && !OS(WINDOWS)
2319 asm volatile ("pause" ::: "memory");
2320#endif
2321 return JSValue::encode(jsUndefined());
2322}
2323
2324// This takes either a JSArrayBuffer, JSArrayBufferView*, or any other object as its first
2325// argument. The second argument is expected to be an integer.
2326//
2327// If the first argument is a JSArrayBuffer, it'll clflush on that buffer
2328// plus the second argument as a byte offset. It'll also flush on the object
2329// itself so its length, etc, aren't in the cache.
2330//
2331// If the first argument is not a JSArrayBuffer, we load the butterfly
2332// and clflush at the address of the butterfly.
2333JSC_DEFINE_HOST_FUNCTION(functionCpuClflush, (JSGlobalObject*, CallFrame* callFrame))
2334{
2335 DollarVMAssertScope assertScope;
2336#if CPU(X86_64) && !OS(WINDOWS)
2337 if (!callFrame->argument(1).isUInt32())
2338 return JSValue::encode(jsBoolean(false));
2339
2340 auto clflush = [] (void* ptr) {
2341 DollarVMAssertScope assertScope;
2342 char* ptrToFlush = static_cast<char*>(ptr);
2343 asm volatile ("clflush %0" :: "m"(*ptrToFlush) : "memory");
2344 };
2345
2346 Vector<void*> toFlush;
2347
2348 uint32_t offset = callFrame->argument(1).asUInt32();
2349
2350 if (JSArrayBufferView* view = jsDynamicCast<JSArrayBufferView*>(callFrame->argument(0)))
2351 toFlush.append(bitwise_cast<char*>(view->vector()) + offset);
2352 else if (JSObject* object = jsDynamicCast<JSObject*>(callFrame->argument(0))) {
2353 switch (object->indexingType()) {
2354 case ALL_INT32_INDEXING_TYPES:
2355 case ALL_CONTIGUOUS_INDEXING_TYPES:
2356 case ALL_DOUBLE_INDEXING_TYPES:
2357 toFlush.append(bitwise_cast<char*>(object->butterfly()) + Butterfly::offsetOfVectorLength());
2358 toFlush.append(bitwise_cast<char*>(object->butterfly()) + Butterfly::offsetOfPublicLength());
2359 }
2360 }
2361
2362 if (!toFlush.size())
2363 return JSValue::encode(jsBoolean(false));
2364
2365 for (void* ptr : toFlush)
2366 clflush(ptr);
2367 return JSValue::encode(jsBoolean(true));
2368#else
2369 UNUSED_PARAM(callFrame);
2370 return JSValue::encode(jsBoolean(false));
2371#endif
2372}
2373
2374class CallerFrameJITTypeFunctor {
2375public:
2376 CallerFrameJITTypeFunctor()
2377 {
2378 DollarVMAssertScope assertScope;
2379 }
2380
2381 IterationStatus operator()(StackVisitor& visitor) const
2382 {
2383 unsigned index = m_currentFrame++;
2384 // First frame (index 0) is `llintTrue` etc. function itself.
2385 if (index == 1) {
2386 if (visitor->codeBlock())
2387 m_jitType = visitor->codeBlock()->jitType();
2388 return IterationStatus::Done;
2389 }
2390 return IterationStatus::Continue;
2391 }
2392
2393 JITType jitType() { return m_jitType; }
2394
2395private:
2396 mutable unsigned m_currentFrame { 0 };
2397 mutable JITType m_jitType { JITType::None };
2398};
2399
2400static FunctionExecutable* getExecutableForFunction(JSValue theFunctionValue)
2401{
2402 DollarVMAssertScope assertScope;
2403 if (!theFunctionValue.isCell())
2404 return nullptr;
2405
2406 JSFunction* theFunction = jsDynamicCast<JSFunction*>(theFunctionValue);
2407 if (!theFunction)
2408 return nullptr;
2409
2410 FunctionExecutable* executable = jsDynamicCast<FunctionExecutable*>(theFunction->executable());
2411
2412 return executable;
2413}
2414
2415// Returns true if the current frame is a LLInt frame.
2416// Usage: isLLInt = $vm.llintTrue()
2417JSC_DEFINE_HOST_FUNCTION(functionLLintTrue, (JSGlobalObject* globalObject, CallFrame* callFrame))
2418{
2419 DollarVMAssertScope assertScope;
2420 VM& vm = globalObject->vm();
2421 if (!callFrame)
2422 return JSValue::encode(jsUndefined());
2423 CallerFrameJITTypeFunctor functor;
2424 callFrame->iterate(vm, functor);
2425 return JSValue::encode(jsBoolean(functor.jitType() == JITType::InterpreterThunk));
2426}
2427
2428// Returns true if the current frame is a baseline JIT frame.
2429// Usage: isBaselineJIT = $vm.baselineJITTrue()
2430JSC_DEFINE_HOST_FUNCTION(functionBaselineJITTrue, (JSGlobalObject* globalObject, CallFrame* callFrame))
2431{
2432 DollarVMAssertScope assertScope;
2433 VM& vm = globalObject->vm();
2434 if (!callFrame)
2435 return JSValue::encode(jsUndefined());
2436 CallerFrameJITTypeFunctor functor;
2437 callFrame->iterate(vm, functor);
2438 return JSValue::encode(jsBoolean(functor.jitType() == JITType::BaselineJIT));
2439}
2440
2441// Set that the argument function should not be inlined.
2442// Usage:
2443// function f() { };
2444// $vm.noInline(f);
2445JSC_DEFINE_HOST_FUNCTION(functionNoInline, (JSGlobalObject*, CallFrame* callFrame))
2446{
2447 DollarVMAssertScope assertScope;
2448 if (callFrame->argumentCount() < 1)
2449 return JSValue::encode(jsUndefined());
2450
2451 JSValue theFunctionValue = callFrame->uncheckedArgument(0);
2452
2453 if (FunctionExecutable* executable = getExecutableForFunction(theFunctionValue))
2454 executable->setNeverInline(true);
2455
2456 return JSValue::encode(jsUndefined());
2457}
2458
2459// Runs a full GC synchronously.
2460// Usage: $vm.gc()
2461JSC_DEFINE_HOST_FUNCTION(functionGC, (JSGlobalObject* globalObject, CallFrame*))
2462{
2463 DollarVMAssertScope assertScope;
2464 VMInspector::gc(&globalObject->vm());
2465 return JSValue::encode(jsUndefined());
2466}
2467
2468// Runs the edenGC synchronously.
2469// Usage: $vm.edenGC()
2470JSC_DEFINE_HOST_FUNCTION(functionEdenGC, (JSGlobalObject* globalObject, CallFrame*))
2471{
2472 DollarVMAssertScope assertScope;
2473 VMInspector::edenGC(&globalObject->vm());
2474 return JSValue::encode(jsUndefined());
2475}
2476
2477// Runs a full GC, but sweep asynchronously.
2478// Usage: $vm.gcSweepAsynchronously()
2479JSC_DEFINE_HOST_FUNCTION(functionGCSweepAsynchronously, (JSGlobalObject* globalObject, CallFrame*))
2480{
2481 DollarVMAssertScope assertScope;
2482 globalObject->vm().heap.collectNow(Async, CollectionScope::Full);
2483 return JSValue::encode(jsUndefined());
2484}
2485
2486// Dumps the hashes of all subspaces currently registered with the VM.
2487// Usage: $vm.dumpSubspaceHashes()
2488JSC_DEFINE_HOST_FUNCTION(functionDumpSubspaceHashes, (JSGlobalObject* globalObject, CallFrame*))
2489{
2490 DollarVMAssertScope assertScope;
2491 VM& vm = globalObject->vm();
2492 VMInspector::dumpSubspaceHashes(&vm);
2493 return JSValue::encode(jsUndefined());
2494}
2495
2496// Gets a JSDollarVMCallFrame for a specified frame index.
2497// Usage: var callFrame = $vm.callFrame(0) // frame 0 is the top frame.
2498// Usage: var callFrame = $vm.callFrame() // implies frame 0 i.e. current frame.
2499//
2500// This gives you the ability to query the following:
2501// callFrame.valid; // false if we asked for a frame beyond the end of the stack, else true.
2502// callFrame.callee;
2503// callFrame.codeBlock;
2504// callFrame.unlinkedCodeBlock;
2505// callFrame.executable;
2506//
2507// Note: you cannot toString() a codeBlock, unlinkedCodeBlock, or executable because
2508// there are internal objects and not a JS object. Hence, you cannot do string
2509// concatenation with them.
2510JSC_DEFINE_HOST_FUNCTION(functionCallFrame, (JSGlobalObject* globalObject, CallFrame* callFrame))
2511{
2512 DollarVMAssertScope assertScope;
2513 unsigned frameNumber = 1;
2514 if (callFrame->argumentCount() >= 1) {
2515 JSValue value = callFrame->uncheckedArgument(0);
2516 if (!value.isUInt32())
2517 return JSValue::encode(jsUndefined());
2518
2519 // We need to inc the frame number because the caller would consider
2520 // its own frame as frame 0. Hence, we need discount the frame for this
2521 // function.
2522 frameNumber = value.asUInt32() + 1;
2523 }
2524
2525 return JSValue::encode(JSDollarVMCallFrame::create(globalObject, callFrame, frameNumber));
2526}
2527
2528// Gets a token for the CodeBlock for a specified frame index.
2529// Usage: codeBlockToken = $vm.codeBlockForFrame(0) // frame 0 is the top frame.
2530// Usage: codeBlockToken = $vm.codeBlockForFrame() // implies frame 0 i.e. current frame.
2531JSC_DEFINE_HOST_FUNCTION(functionCodeBlockForFrame, (JSGlobalObject* globalObject, CallFrame* callFrame))
2532{
2533 DollarVMAssertScope assertScope;
2534 unsigned frameNumber = 1;
2535 if (callFrame->argumentCount() >= 1) {
2536 JSValue value = callFrame->uncheckedArgument(0);
2537 if (!value.isUInt32())
2538 return JSValue::encode(jsUndefined());
2539
2540 // We need to inc the frame number because the caller would consider
2541 // its own frame as frame 0. Hence, we need discount the frame for this
2542 // function.
2543 frameNumber = value.asUInt32() + 1;
2544 }
2545
2546 CodeBlock* codeBlock = VMInspector::codeBlockForFrame(&globalObject->vm(), callFrame, frameNumber);
2547 if (codeBlock)
2548 return JSValue::encode(codeBlock);
2549 return JSValue::encode(jsUndefined());
2550}
2551
2552static CodeBlock* codeBlockFromArg(JSGlobalObject* globalObject, CallFrame* callFrame)
2553{
2554 DollarVMAssertScope assertScope;
2555 VM& vm = globalObject->vm();
2556 if (callFrame->argumentCount() < 1)
2557 return nullptr;
2558
2559 JSValue value = callFrame->uncheckedArgument(0);
2560 CodeBlock* candidateCodeBlock = nullptr;
2561 if (value.isCell()) {
2562 JSFunction* func = jsDynamicCast<JSFunction*>(value.asCell());
2563 if (func) {
2564 if (func->isHostFunction())
2565 candidateCodeBlock = nullptr;
2566 else
2567 candidateCodeBlock = func->jsExecutable()->eitherCodeBlock();
2568 } else
2569 candidateCodeBlock = static_cast<CodeBlock*>(value.asCell());
2570 }
2571
2572 if (candidateCodeBlock && VMInspector::isValidCodeBlock(&vm, candidateCodeBlock))
2573 return candidateCodeBlock;
2574
2575 if (candidateCodeBlock)
2576 dataLog("Invalid codeBlock: ", RawPointer(candidateCodeBlock), " ", value, "\n");
2577 else
2578 dataLog("Invalid codeBlock: ", value, "\n");
2579 return nullptr;
2580}
2581
2582// Usage: $vm.print("codeblock = ", $vm.codeBlockFor(functionObj))
2583// Usage: $vm.print("codeblock = ", $vm.codeBlockFor(codeBlockToken))
2584// Note: you cannot toString() a codeBlock because it's an internal object and not
2585// a JS object. Hence, you cannot do string concatenation with it.
2586JSC_DEFINE_HOST_FUNCTION(functionCodeBlockFor, (JSGlobalObject* globalObject, CallFrame* callFrame))
2587{
2588 DollarVMAssertScope assertScope;
2589 CodeBlock* codeBlock = codeBlockFromArg(globalObject, callFrame);
2590 WTF::StringPrintStream stream;
2591 if (codeBlock) {
2592 stream.print(*codeBlock);
2593 return JSValue::encode(jsString(globalObject->vm(), stream.toString()));
2594 }
2595 return JSValue::encode(jsUndefined());
2596}
2597
2598// Usage: $vm.dumpSourceFor(functionObj)
2599// Usage: $vm.dumpSourceFor(codeBlockToken)
2600JSC_DEFINE_HOST_FUNCTION(functionDumpSourceFor, (JSGlobalObject* globalObject, CallFrame* callFrame))
2601{
2602 DollarVMAssertScope assertScope;
2603 CodeBlock* codeBlock = codeBlockFromArg(globalObject, callFrame);
2604 if (codeBlock)
2605 codeBlock->dumpSource();
2606 return JSValue::encode(jsUndefined());
2607}
2608
2609// Usage: $vm.dumpBytecodeFor(functionObj)
2610// Usage: $vm.dumpBytecodeFor(codeBlock)
2611JSC_DEFINE_HOST_FUNCTION(functionDumpBytecodeFor, (JSGlobalObject* globalObject, CallFrame* callFrame))
2612{
2613 DollarVMAssertScope assertScope;
2614 CodeBlock* codeBlock = codeBlockFromArg(globalObject, callFrame);
2615 if (codeBlock)
2616 codeBlock->dumpBytecode();
2617 return JSValue::encode(jsUndefined());
2618}
2619
2620// Prints a series of comma separate strings without appending a newline.
2621// Usage: $vm.dataLog(str1, str2, str3)
2622JSC_DEFINE_HOST_FUNCTION(functionDataLog, (JSGlobalObject* globalObject, CallFrame* callFrame))
2623{
2624 DollarVMAssertScope assertScope;
2625 const bool addLineFeed = false;
2626 return doPrint(globalObject, callFrame, addLineFeed);
2627}
2628
2629// Prints a series of comma separate strings and appends a newline.
2630// Usage: $vm.print(str1, str2, str3)
2631JSC_DEFINE_HOST_FUNCTION(functionPrint, (JSGlobalObject* globalObject, CallFrame* callFrame))
2632{
2633 DollarVMAssertScope assertScope;
2634 const bool addLineFeed = true;
2635 return doPrint(globalObject, callFrame, addLineFeed);
2636}
2637
2638// Dumps the current CallFrame.
2639// Usage: $vm.dumpCallFrame()
2640JSC_DEFINE_HOST_FUNCTION(functionDumpCallFrame, (JSGlobalObject* globalObject, CallFrame* callFrame))
2641{
2642 DollarVMAssertScope assertScope;
2643 // When the callers call this function, they are expecting to dump their
2644 // own frame. So skip 1 for this frame.
2645 VMInspector::dumpCallFrame(&globalObject->vm(), callFrame, 1);
2646 return JSValue::encode(jsUndefined());
2647}
2648
2649// Dumps the JS stack.
2650// Usage: $vm.printStack()
2651JSC_DEFINE_HOST_FUNCTION(functionDumpStack, (JSGlobalObject* globalObject, CallFrame* callFrame))
2652{
2653 DollarVMAssertScope assertScope;
2654 // When the callers call this function, they are expecting to dump the
2655 // stack starting their own frame. So skip 1 for this frame.
2656 VMInspector::dumpStack(&globalObject->vm(), callFrame, 1);
2657 return JSValue::encode(jsUndefined());
2658}
2659
2660// Dumps the current CallFrame.
2661// Usage: $vm.dumpRegisters(N) // dump the registers of the Nth CallFrame.
2662// Usage: $vm.dumpRegisters() // dump the registers of the current CallFrame.
2663// FIXME: Currently, this function dumps the physical frame. We should make
2664// it dump the logical frame (i.e. be able to dump inlined frames as well).
2665JSC_DEFINE_HOST_FUNCTION(functionDumpRegisters, (JSGlobalObject* globalObject, CallFrame* callFrame))
2666{
2667 DollarVMAssertScope assertScope;
2668 VM& vm = globalObject->vm();
2669 unsigned requestedFrameIndex = 1;
2670 if (callFrame->argumentCount() >= 1) {
2671 JSValue value = callFrame->uncheckedArgument(0);
2672 if (!value.isUInt32())
2673 return JSValue::encode(jsUndefined());
2674
2675 // We need to inc the frame number because the caller would consider
2676 // its own frame as frame 0. Hence, we need discount the frame for this
2677 // function.
2678 requestedFrameIndex = value.asUInt32() + 1;
2679 }
2680
2681 unsigned frameIndex = 0;
2682 callFrame->iterate(vm, [&] (StackVisitor& visitor) {
2683 DollarVMAssertScope assertScope;
2684 if (frameIndex++ != requestedFrameIndex)
2685 return IterationStatus::Continue;
2686 VMInspector::dumpRegisters(visitor->callFrame());
2687 return IterationStatus::Done;
2688 });
2689
2690 return encodedJSUndefined();
2691}
2692
2693// Dumps the internal memory layout of a JSCell.
2694// Usage: $vm.dumpCell(cell)
2695JSC_DEFINE_HOST_FUNCTION(functionDumpCell, (JSGlobalObject*, CallFrame* callFrame))
2696{
2697 DollarVMAssertScope assertScope;
2698 JSValue value = callFrame->argument(0);
2699 if (!value.isCell())
2700 return encodedJSUndefined();
2701
2702 VMInspector::dumpCellMemory(value.asCell());
2703 return encodedJSUndefined();
2704}
2705
2706// Gets the dataLog dump of the indexingMode of the passed value.
2707// Usage: $vm.print("indexingMode = " + $vm.indexingMode(jsValue))
2708JSC_DEFINE_HOST_FUNCTION(functionIndexingMode, (JSGlobalObject* globalObject, CallFrame* callFrame))
2709{
2710 DollarVMAssertScope assertScope;
2711 if (!callFrame->argument(0).isObject())
2712 return encodedJSUndefined();
2713
2714 WTF::StringPrintStream stream;
2715 stream.print(IndexingTypeDump(callFrame->uncheckedArgument(0).getObject()->indexingMode()));
2716 return JSValue::encode(jsString(globalObject->vm(), stream.toString()));
2717}
2718
2719JSC_DEFINE_HOST_FUNCTION(functionInlineCapacity, (JSGlobalObject*, CallFrame* callFrame))
2720{
2721 DollarVMAssertScope assertScope;
2722 if (auto* object = jsDynamicCast<JSObject*>(callFrame->argument(0)))
2723 return JSValue::encode(jsNumber(object->structure()->inlineCapacity()));
2724
2725 return encodedJSUndefined();
2726}
2727
2728// Clears the LinkBuffer profile statistics.
2729// Usage: $vm.clearLinkBufferStats()
2730JSC_DEFINE_HOST_FUNCTION(functionClearLinkBufferStats, (JSGlobalObject*, CallFrame*))
2731{
2732 DollarVMAssertScope assertScope;
2733#if ENABLE(ASSEMBLER)
2734 LinkBuffer::clearProfileStatistics();
2735#endif
2736 return JSValue::encode(jsUndefined());
2737}
2738
2739// Dumps the LinkBuffer profile statistics as a string.
2740// Usage: $vm.print($vm.linkBufferStats())
2741JSC_DEFINE_HOST_FUNCTION(functionLinkBufferStats, (JSGlobalObject* globalObject, CallFrame*))
2742{
2743 DollarVMAssertScope assertScope;
2744#if ENABLE(ASSEMBLER)
2745 WTF::StringPrintStream stream;
2746 LinkBuffer::dumpProfileStatistics(&stream);
2747 return JSValue::encode(jsString(globalObject->vm(), stream.toString()));
2748#else
2749 UNUSED_PARAM(globalObject);
2750 return JSValue::encode(jsUndefined());
2751#endif
2752}
2753
2754// Gets the dataLog dump of a given JS value as a string.
2755// Usage: $vm.print("value = " + $vm.value(jsValue))
2756JSC_DEFINE_HOST_FUNCTION(functionValue, (JSGlobalObject* globalObject, CallFrame* callFrame))
2757{
2758 DollarVMAssertScope assertScope;
2759 WTF::StringPrintStream stream;
2760 for (unsigned i = 0; i < callFrame->argumentCount(); ++i) {
2761 if (i)
2762 stream.print(", ");
2763 stream.print(callFrame->uncheckedArgument(i));
2764 }
2765
2766 return JSValue::encode(jsString(globalObject->vm(), stream.toString()));
2767}
2768
2769// Gets the pid of the current process.
2770// Usage: $vm.print("pid = " + $vm.getpid())
2771JSC_DEFINE_HOST_FUNCTION(functionGetPID, (JSGlobalObject*, CallFrame*))
2772{
2773 DollarVMAssertScope assertScope;
2774 return JSValue::encode(jsNumber(getCurrentProcessID()));
2775}
2776
2777// Make the globalObject have a bad time. Does nothing if the object is not a JSGlobalObject.
2778// Usage: $vm.haveABadTime(globalObject)
2779JSC_DEFINE_HOST_FUNCTION(functionHaveABadTime, (JSGlobalObject* globalObject, CallFrame* callFrame))
2780{
2781 DollarVMAssertScope assertScope;
2782 VM& vm = globalObject->vm();
2783 auto scope = DECLARE_THROW_SCOPE(vm);
2784 JSGlobalObject* target = globalObject;
2785 if (!callFrame->argument(0).isUndefined()) {
2786 JSObject* obj = callFrame->argument(0).getObject();
2787 if (!obj)
2788 return throwVMTypeError(globalObject, scope, "haveABadTime expects first argument to be an object if provided"_s);
2789 target = obj->globalObject();
2790 }
2791
2792 target->haveABadTime(vm);
2793 return JSValue::encode(jsBoolean(true));
2794}
2795
2796// Checks if the object (or its global if the object is not a global) is having a bad time.
2797// Usage: $vm.isHavingABadTime(obj)
2798JSC_DEFINE_HOST_FUNCTION(functionIsHavingABadTime, (JSGlobalObject* globalObject, CallFrame* callFrame))
2799{
2800 DollarVMAssertScope assertScope;
2801 VM& vm = globalObject->vm();
2802 auto scope = DECLARE_THROW_SCOPE(vm);
2803 JSGlobalObject* target = globalObject;
2804 if (!callFrame->argument(0).isUndefined()) {
2805 JSObject* obj = callFrame->argument(0).getObject();
2806 if (!obj)
2807 return throwVMTypeError(globalObject, scope, "isHavingABadTime expects first argument to be an object if provided"_s);
2808 target = obj->globalObject();
2809 }
2810
2811 return JSValue::encode(jsBoolean(target->isHavingABadTime()));
2812}
2813
2814// Calls the specified test function after adjusting the stack to have the specified
2815// remaining size from the end of the physical stack.
2816// Usage: $vm.callWithStackSize(funcToCall, desiredStackSize)
2817//
2818// This function will only work in test configurations, specifically, only if JSC
2819// options are not frozen. For the jsc shell, the --disableOptionsFreezingForTesting
2820// argument needs to be passed in on the command line.
2821
2822#if ENABLE(ASSEMBLER)
2823static void callWithStackSizeProbeFunction(Probe::State* state)
2824{
2825 JSGlobalObject* globalObject = bitwise_cast<JSGlobalObject*>(state->arg);
2826 // The bits loaded from state->probeFunction will be tagged like
2827 // a C function. So, we'll need to untag it to extract the bits
2828 // for the JSFunction*.
2829 JSFunction* function = bitwise_cast<JSFunction*>(untagCodePtr<CFunctionPtrTag>(state->probeFunction));
2830 state->initializeStackFunction = nullptr;
2831 state->initializeStackArg = nullptr;
2832
2833 DollarVMAssertScope assertScope;
2834
2835 auto callData = JSC::getCallData(function);
2836 MarkedArgumentBuffer args;
2837 call(globalObject, function, callData, jsUndefined(), args);
2838}
2839#endif // ENABLE(ASSEMBLER)
2840
2841JSC_DEFINE_HOST_FUNCTION_WITH_ATTRIBUTES(functionCallWithStackSize, SUPPRESS_ASAN, (JSGlobalObject* globalObject, CallFrame* callFrame))
2842{
2843 DollarVMAssertScope assertScope;
2844 VM& vm = globalObject->vm();
2845 JSLockHolder lock(vm);
2846 auto throwScope = DECLARE_THROW_SCOPE(vm);
2847
2848#if OS(DARWIN) && CPU(X86_64)
2849 constexpr bool isSupportedByPlatform = true;
2850#else
2851 constexpr bool isSupportedByPlatform = false;
2852#endif
2853
2854 if (!isSupportedByPlatform)
2855 return throwVMError(globalObject, throwScope, "Not supported for this platform"_s);
2856
2857#if ENABLE(ASSEMBLER)
2858 if (g_jscConfig.isPermanentlyFrozen() || !g_jscConfig.disabledFreezingForTesting)
2859 return throwVMError(globalObject, throwScope, "Options are frozen"_s);
2860
2861 if (callFrame->argumentCount() < 2)
2862 return throwVMError(globalObject, throwScope, "Invalid number of arguments"_s);
2863 JSValue arg0 = callFrame->argument(0);
2864 JSValue arg1 = callFrame->argument(1);
2865 if (!arg0.isCallable())
2866 return throwVMError(globalObject, throwScope, "arg0 should be a function"_s);
2867 if (!arg1.isNumber())
2868 return throwVMError(globalObject, throwScope, "arg1 should be a number"_s);
2869
2870 JSFunction* function = jsCast<JSFunction*>(arg0);
2871 size_t desiredStackSize = arg1.asNumber();
2872
2873 const StackBounds& bounds = Thread::current().stack();
2874 uint8_t* currentStackPosition = bitwise_cast<uint8_t*>(currentStackPointer());
2875 uint8_t* end = bitwise_cast<uint8_t*>(bounds.end());
2876 uint8_t* desiredStart = end + desiredStackSize;
2877 if (desiredStart >= currentStackPosition)
2878 return throwVMError(globalObject, throwScope, "Unable to setup desired stack size"_s);
2879
2880 JSDollarVMHelper helper(vm);
2881
2882 unsigned originalMaxPerThreadStackUsage = Options::maxPerThreadStackUsage();
2883 void* originalVMSoftStackLimit = vm.softStackLimit();
2884 void* originalVMStackLimit = vm.stackLimit();
2885
2886 // This is a hack to make the VM think it's stack limits are near the end
2887 // of the physical stack.
2888 uint8_t* vmStackStart = bitwise_cast<uint8_t*>(vm.stackPointerAtVMEntry());
2889 uint8_t* vmStackEnd = vmStackStart - originalMaxPerThreadStackUsage;
2890 ptrdiff_t sizeDiff = vmStackEnd - end;
2891 RELEASE_ASSERT(sizeDiff >= 0);
2892 RELEASE_ASSERT(static_cast<uint64_t>(sizeDiff) < UINT_MAX);
2893
2894 Options::maxPerThreadStackUsage() = originalMaxPerThreadStackUsage + sizeDiff;
2895 helper.updateVMStackLimits();
2896
2897#if OS(DARWIN) && CPU(X86_64)
2898 __asm__ volatile (
2899 "subq %[sizeDiff], %%rsp" "\n"
2900 "pushq %%rax" "\n"
2901 "pushq %%rcx" "\n"
2902 "pushq %%rdx" "\n"
2903 "pushq %%rbx" "\n"
2904 "callq *%%rax" "\n"
2905 "addq %[sizeDiff], %%rsp" "\n"
2906 :
2907 : "a" (ctiMasmProbeTrampoline)
2908 , "c" (callWithStackSizeProbeFunction)
2909 , "d" (function)
2910 , "b" (globalObject)
2911 , [sizeDiff] "rm" (sizeDiff)
2912 : "memory"
2913 );
2914#else
2915 UNUSED_PARAM(function);
2916#if !COMPILER(MSVC)
2917 UNUSED_PARAM(callWithStackSizeProbeFunction);
2918#endif
2919#endif // OS(DARWIN) && CPU(X86_64)
2920
2921 Options::maxPerThreadStackUsage() = originalMaxPerThreadStackUsage;
2922 helper.updateVMStackLimits();
2923 RELEASE_ASSERT(vm.softStackLimit() == originalVMSoftStackLimit);
2924 RELEASE_ASSERT(vm.stackLimit() == originalVMStackLimit);
2925
2926 throwScope.release();
2927 return encodedJSUndefined();
2928
2929#else // not ENABLE(ASSEMBLER)
2930 UNUSED_PARAM(callFrame);
2931 return throwVMError(globalObject, throwScope, "Not supported for this platform"_s);
2932#endif // ENABLE(ASSEMBLER)
2933}
2934
2935// Creates a new global object.
2936// Usage: $vm.createGlobalObject()
2937JSC_DEFINE_HOST_FUNCTION(functionCreateGlobalObject, (JSGlobalObject* globalObject, CallFrame*))
2938{
2939 DollarVMAssertScope assertScope;
2940 VM& vm = globalObject->vm();
2941 JSLockHolder lock(vm);
2942 return JSValue::encode(JSGlobalObject::create(vm, JSGlobalObject::createStructure(vm, jsNull())));
2943}
2944
2945JSC_DEFINE_HOST_FUNCTION(functionCreateProxy, (JSGlobalObject* globalObject, CallFrame* callFrame))
2946{
2947 DollarVMAssertScope assertScope;
2948 VM& vm = globalObject->vm();
2949 JSLockHolder lock(vm);
2950 JSValue target = callFrame->argument(0);
2951 if (!target.isObject())
2952 return JSValue::encode(jsUndefined());
2953 JSObject* jsTarget = asObject(target.asCell());
2954 Structure* structure = JSProxy::createStructure(vm, globalObject, jsTarget->getPrototypeDirect());
2955 JSProxy* proxy = JSProxy::create(vm, structure, jsTarget);
2956 return JSValue::encode(proxy);
2957}
2958
2959JSC_DEFINE_HOST_FUNCTION(functionCreateRuntimeArray, (JSGlobalObject* globalObject, CallFrame* callFrame))
2960{
2961 DollarVMAssertScope assertScope;
2962 JSLockHolder lock(globalObject);
2963 RuntimeArray* array = RuntimeArray::create(globalObject, callFrame);
2964 return JSValue::encode(array);
2965}
2966
2967JSC_DEFINE_HOST_FUNCTION(functionCreateNullRopeString, (JSGlobalObject* globalObject, CallFrame*))
2968{
2969 DollarVMAssertScope assertScope;
2970 VM& vm = globalObject->vm();
2971 JSLockHolder lock(vm);
2972 return JSValue::encode(JSRopeString::createNullForTesting(vm));
2973}
2974
2975JSC_DEFINE_HOST_FUNCTION(functionCreateImpureGetter, (JSGlobalObject* globalObject, CallFrame* callFrame))
2976{
2977 DollarVMAssertScope assertScope;
2978 VM& vm = globalObject->vm();
2979 JSLockHolder lock(vm);
2980 JSValue target = callFrame->argument(0);
2981 JSObject* delegate = nullptr;
2982 if (target.isObject())
2983 delegate = asObject(target.asCell());
2984 Structure* structure = ImpureGetter::createStructure(vm, globalObject, jsNull());
2985 ImpureGetter* result = ImpureGetter::create(vm, structure, delegate);
2986 return JSValue::encode(result);
2987}
2988
2989JSC_DEFINE_HOST_FUNCTION(functionCreateCustomGetterObject, (JSGlobalObject* globalObject, CallFrame*))
2990{
2991 DollarVMAssertScope assertScope;
2992 VM& vm = globalObject->vm();
2993 JSLockHolder lock(vm);
2994 Structure* structure = CustomGetter::createStructure(vm, globalObject, jsNull());
2995 CustomGetter* result = CustomGetter::create(vm, structure);
2996 return JSValue::encode(result);
2997}
2998
2999JSC_DEFINE_HOST_FUNCTION(functionCreateDOMJITNodeObject, (JSGlobalObject* globalObject, CallFrame*))
3000{
3001 DollarVMAssertScope assertScope;
3002 VM& vm = globalObject->vm();
3003 JSLockHolder lock(vm);
3004 Structure* structure = DOMJITNode::createStructure(vm, globalObject, DOMJITGetter::create(vm, DOMJITGetter::createStructure(vm, globalObject, jsNull())));
3005 DOMJITNode* result = DOMJITNode::create(vm, structure);
3006 return JSValue::encode(result);
3007}
3008
3009JSC_DEFINE_HOST_FUNCTION(functionCreateDOMJITGetterObject, (JSGlobalObject* globalObject, CallFrame*))
3010{
3011 DollarVMAssertScope assertScope;
3012 VM& vm = globalObject->vm();
3013 JSLockHolder lock(vm);
3014 Structure* structure = DOMJITGetter::createStructure(vm, globalObject, jsNull());
3015 DOMJITGetter* result = DOMJITGetter::create(vm, structure);
3016 return JSValue::encode(result);
3017}
3018
3019JSC_DEFINE_HOST_FUNCTION(functionCreateDOMJITGetterNoEffectsObject, (JSGlobalObject* globalObject, CallFrame*))
3020{
3021 DollarVMAssertScope assertScope;
3022 VM& vm = globalObject->vm();
3023 JSLockHolder lock(vm);
3024 Structure* structure = DOMJITGetterNoEffects::createStructure(vm, globalObject, jsNull());
3025 DOMJITGetterNoEffects* result = DOMJITGetterNoEffects::create(vm, structure);
3026 return JSValue::encode(result);
3027}
3028
3029JSC_DEFINE_HOST_FUNCTION(functionCreateDOMJITGetterComplexObject, (JSGlobalObject* globalObject, CallFrame*))
3030{
3031 DollarVMAssertScope assertScope;
3032 VM& vm = globalObject->vm();
3033 JSLockHolder lock(vm);
3034 Structure* structure = DOMJITGetterComplex::createStructure(vm, globalObject, jsNull());
3035 DOMJITGetterComplex* result = DOMJITGetterComplex::create(vm, globalObject, structure);
3036 return JSValue::encode(result);
3037}
3038
3039JSC_DEFINE_HOST_FUNCTION(functionCreateDOMJITFunctionObject, (JSGlobalObject* globalObject, CallFrame*))
3040{
3041 DollarVMAssertScope assertScope;
3042 VM& vm = globalObject->vm();
3043 JSLockHolder lock(vm);
3044 Structure* structure = DOMJITFunctionObject::createStructure(vm, globalObject, jsNull());
3045 DOMJITFunctionObject* result = DOMJITFunctionObject::create(vm, globalObject, structure);
3046 return JSValue::encode(result);
3047}
3048
3049JSC_DEFINE_HOST_FUNCTION(functionCreateDOMJITCheckJSCastObject, (JSGlobalObject* globalObject, CallFrame*))
3050{
3051 DollarVMAssertScope assertScope;
3052 VM& vm = globalObject->vm();
3053 JSLockHolder lock(vm);
3054 Structure* structure = DOMJITCheckJSCastObject::createStructure(vm, globalObject, jsNull());
3055 DOMJITCheckJSCastObject* result = DOMJITCheckJSCastObject::create(vm, globalObject, structure);
3056 return JSValue::encode(result);
3057}
3058
3059JSC_DEFINE_HOST_FUNCTION(functionCreateDOMJITGetterBaseJSObject, (JSGlobalObject* globalObject, CallFrame*))
3060{
3061 DollarVMAssertScope assertScope;
3062 VM& vm = globalObject->vm();
3063 JSLockHolder lock(vm);
3064 Structure* structure = DOMJITGetterBaseJSObject::createStructure(vm, globalObject, jsNull());
3065 DOMJITGetterBaseJSObject* result = DOMJITGetterBaseJSObject::create(vm, structure);
3066 return JSValue::encode(result);
3067}
3068
3069#if ENABLE(WEBASSEMBLY)
3070JSC_DEFINE_HOST_FUNCTION(functionCreateWasmStreamingParser, (JSGlobalObject* globalObject, CallFrame*))
3071{
3072 DollarVMAssertScope assertScope;
3073 VM& vm = globalObject->vm();
3074 JSLockHolder lock(vm);
3075 return JSValue::encode(WasmStreamingParser::create(vm, globalObject));
3076}
3077
3078JSC_DEFINE_HOST_FUNCTION(functionCreateWasmStreamingCompilerForCompile, (JSGlobalObject* globalObject, CallFrame* callFrame))
3079{
3080 DollarVMAssertScope assertScope;
3081 VM& vm = globalObject->vm();
3082 JSLockHolder lock(vm);
3083 auto scope = DECLARE_THROW_SCOPE(vm);
3084
3085 auto callback = jsDynamicCast<JSFunction*>(callFrame->argument(0));
3086 if (!callback)
3087 return throwVMTypeError(globalObject, scope, "First argument is not a JS function"_s);
3088
3089 auto compiler = WasmStreamingCompiler::create(vm, globalObject, Wasm::CompilerMode::Validation, nullptr);
3090 MarkedArgumentBuffer args;
3091 args.append(compiler);
3092 call(globalObject, callback, jsUndefined(), args, "You shouldn't see this..."_s);
3093 if (UNLIKELY(scope.exception()))
3094 scope.clearException();
3095 compiler->streamingCompiler().finalize(globalObject);
3096 RETURN_IF_EXCEPTION(scope, { });
3097 return JSValue::encode(compiler->promise());
3098}
3099
3100JSC_DEFINE_HOST_FUNCTION(functionCreateWasmStreamingCompilerForInstantiate, (JSGlobalObject* globalObject, CallFrame* callFrame))
3101{
3102 DollarVMAssertScope assertScope;
3103 VM& vm = globalObject->vm();
3104 JSLockHolder lock(vm);
3105 auto scope = DECLARE_THROW_SCOPE(vm);
3106
3107 auto callback = jsDynamicCast<JSFunction*>(callFrame->argument(0));
3108 if (!callback)
3109 return throwVMTypeError(globalObject, scope, "First argument is not a JS function"_s);
3110
3111 JSValue importArgument = callFrame->argument(1);
3112 JSObject* importObject = importArgument.getObject();
3113 if (UNLIKELY(!importArgument.isUndefined() && !importObject))
3114 return throwVMTypeError(globalObject, scope);
3115
3116 auto compiler = WasmStreamingCompiler::create(vm, globalObject, Wasm::CompilerMode::FullCompile, importObject);
3117 MarkedArgumentBuffer args;
3118 args.append(compiler);
3119 call(globalObject, callback, jsUndefined(), args, "You shouldn't see this..."_s);
3120 if (UNLIKELY(scope.exception()))
3121 scope.clearException();
3122 compiler->streamingCompiler().finalize(globalObject);
3123 RETURN_IF_EXCEPTION(scope, { });
3124 return JSValue::encode(compiler->promise());
3125}
3126#endif
3127
3128JSC_DEFINE_HOST_FUNCTION(functionCreateStaticCustomAccessor, (JSGlobalObject* globalObject, CallFrame*))
3129{
3130 DollarVMAssertScope assertScope;
3131 VM& vm = globalObject->vm();
3132 JSLockHolder lock(vm);
3133 Structure* structure = StaticCustomAccessor::createStructure(vm, globalObject, jsNull());
3134 auto* result = StaticCustomAccessor::create(vm, structure);
3135 return JSValue::encode(result);
3136}
3137
3138JSC_DEFINE_HOST_FUNCTION(functionCreateStaticCustomValue, (JSGlobalObject* globalObject, CallFrame*))
3139{
3140 DollarVMAssertScope assertScope;
3141 VM& vm = globalObject->vm();
3142 JSLockHolder lock(vm);
3143 Structure* structure = StaticCustomValue::createStructure(vm, globalObject, jsNull());
3144 auto* result = StaticCustomValue::create(vm, structure);
3145 return JSValue::encode(result);
3146}
3147
3148JSC_DEFINE_HOST_FUNCTION(functionCreateStaticDontDeleteDontEnum, (JSGlobalObject* globalObject, CallFrame*))
3149{
3150 DollarVMAssertScope assertScope;
3151 VM& vm = globalObject->vm();
3152 JSLockHolder lock(vm);
3153 Structure* structure = StaticDontDeleteDontEnum::createStructure(vm, globalObject, jsNull());
3154 auto* result = StaticDontDeleteDontEnum::create(vm, structure);
3155 return JSValue::encode(result);
3156}
3157
3158JSC_DEFINE_HOST_FUNCTION(functionCreateObjectDoingSideEffectPutWithoutCorrectSlotStatus, (JSGlobalObject* globalObject, CallFrame* callFrame))
3159{
3160 DollarVMAssertScope assertScope;
3161 VM& vm = globalObject->vm();
3162 JSLockHolder lock(vm);
3163
3164 auto* dollarVM = jsDynamicCast<JSDollarVM*>(callFrame->thisValue());
3165 RELEASE_ASSERT(dollarVM);
3166 auto* result = ObjectDoingSideEffectPutWithoutCorrectSlotStatus::create(vm, dollarVM->objectDoingSideEffectPutWithoutCorrectSlotStatusStructure());
3167 return JSValue::encode(result);
3168}
3169
3170JSC_DEFINE_HOST_FUNCTION(functionCreateEmptyFunctionWithName, (JSGlobalObject* globalObject, CallFrame* callFrame))
3171{
3172 DollarVMAssertScope assertScope;
3173 VM& vm = globalObject->vm();
3174 JSLockHolder lock(vm);
3175 auto scope = DECLARE_THROW_SCOPE(vm);
3176
3177 const String name = callFrame->argument(0).toWTFString(globalObject);
3178 RETURN_IF_EXCEPTION(scope, encodedJSValue());
3179
3180 RELEASE_AND_RETURN(scope, JSValue::encode(JSFunction::create(vm, globalObject, 1, name, functionCreateEmptyFunctionWithName)));
3181}
3182
3183JSC_DEFINE_HOST_FUNCTION(functionSetImpureGetterDelegate, (JSGlobalObject* globalObject, CallFrame* callFrame))
3184{
3185 DollarVMAssertScope assertScope;
3186 VM& vm = globalObject->vm();
3187 JSLockHolder lock(vm);
3188 auto scope = DECLARE_THROW_SCOPE(vm);
3189
3190 JSValue base = callFrame->argument(0);
3191 if (!base.isObject())
3192 return JSValue::encode(jsUndefined());
3193 JSValue delegate = callFrame->argument(1);
3194 if (!delegate.isObject())
3195 return JSValue::encode(jsUndefined());
3196 ImpureGetter* impureGetter = jsDynamicCast<ImpureGetter*>(asObject(base.asCell()));
3197 if (UNLIKELY(!impureGetter)) {
3198 throwTypeError(globalObject, scope, "argument is not an ImpureGetter"_s);
3199 return encodedJSValue();
3200 }
3201 impureGetter->setDelegate(vm, asObject(delegate.asCell()));
3202 return JSValue::encode(jsUndefined());
3203}
3204
3205JSC_DEFINE_HOST_FUNCTION(functionCreateBuiltin, (JSGlobalObject* globalObject, CallFrame* callFrame))
3206{
3207 DollarVMAssertScope assertScope;
3208 VM& vm = globalObject->vm();
3209 auto scope = DECLARE_THROW_SCOPE(vm);
3210
3211 if (callFrame->argumentCount() < 1 || !callFrame->argument(0).isString())
3212 return JSValue::encode(jsUndefined());
3213
3214 String functionText = asString(callFrame->argument(0))->value(globalObject);
3215 RETURN_IF_EXCEPTION(scope, encodedJSValue());
3216
3217 SourceCode source = makeSource(WTFMove(functionText), { });
3218 JSFunction* func = JSFunction::create(vm, createBuiltinExecutable(vm, source, Identifier::fromString(vm, "foo"_s), ConstructorKind::None, ConstructAbility::CannotConstruct)->link(vm, nullptr, source), globalObject);
3219
3220 return JSValue::encode(func);
3221}
3222
3223JSC_DEFINE_HOST_FUNCTION(functionGetPrivateProperty, (JSGlobalObject* globalObject, CallFrame* callFrame))
3224{
3225 DollarVMAssertScope assertScope;
3226 VM& vm = globalObject->vm();
3227 auto scope = DECLARE_THROW_SCOPE(vm);
3228
3229 if (callFrame->argumentCount() < 2 || !callFrame->argument(1).isString())
3230 return encodedJSUndefined();
3231
3232 String str = asString(callFrame->argument(1))->value(globalObject);
3233 RETURN_IF_EXCEPTION(scope, encodedJSValue());
3234
3235 SymbolImpl* symbol = vm.propertyNames->builtinNames().lookUpPrivateName(str);
3236 if (!symbol)
3237 return throwVMError(globalObject, scope, "Unknown private name."_s);
3238
3239 RELEASE_AND_RETURN(scope, JSValue::encode(callFrame->argument(0).get(globalObject, symbol)));
3240}
3241
3242JSC_DEFINE_HOST_FUNCTION(functionCreateRoot, (JSGlobalObject* globalObject, CallFrame*))
3243{
3244 DollarVMAssertScope assertScope;
3245 VM& vm = globalObject->vm();
3246 JSLockHolder lock(vm);
3247 return JSValue::encode(Root::create(vm, globalObject));
3248}
3249
3250JSC_DEFINE_HOST_FUNCTION(functionCreateElement, (JSGlobalObject* globalObject, CallFrame* callFrame))
3251{
3252 DollarVMAssertScope assertScope;
3253 VM& vm = globalObject->vm();
3254 JSLockHolder lock(vm);
3255 auto scope = DECLARE_THROW_SCOPE(vm);
3256
3257 Root* root = jsDynamicCast<Root*>(callFrame->argument(0));
3258 if (!root)
3259 return JSValue::encode(throwException(globalObject, scope, createError(globalObject, "Cannot create Element without a Root."_s)));
3260 return JSValue::encode(Element::create(vm, globalObject, root));
3261}
3262
3263JSC_DEFINE_HOST_FUNCTION(functionGetElement, (JSGlobalObject* globalObject, CallFrame* callFrame))
3264{
3265 DollarVMAssertScope assertScope;
3266 VM& vm = globalObject->vm();
3267 JSLockHolder lock(vm);
3268 Root* root = jsDynamicCast<Root*>(callFrame->argument(0));
3269 if (!root)
3270 return JSValue::encode(jsUndefined());
3271 Element* result = root->element();
3272 return JSValue::encode(result ? result : jsUndefined());
3273}
3274
3275JSC_DEFINE_HOST_FUNCTION(functionCreateSimpleObject, (JSGlobalObject* globalObject, CallFrame*))
3276{
3277 DollarVMAssertScope assertScope;
3278 VM& vm = globalObject->vm();
3279 JSLockHolder lock(vm);
3280 return JSValue::encode(SimpleObject::create(vm, globalObject));
3281}
3282
3283JSC_DEFINE_HOST_FUNCTION(functionGetHiddenValue, (JSGlobalObject* globalObject, CallFrame* callFrame))
3284{
3285 DollarVMAssertScope assertScope;
3286 VM& vm = globalObject->vm();
3287 JSLockHolder lock(vm);
3288 auto scope = DECLARE_THROW_SCOPE(vm);
3289
3290 SimpleObject* simpleObject = jsDynamicCast<SimpleObject*>(callFrame->argument(0));
3291 if (UNLIKELY(!simpleObject)) {
3292 throwTypeError(globalObject, scope, "Invalid use of getHiddenValue test function"_s);
3293 return encodedJSValue();
3294 }
3295 return JSValue::encode(simpleObject->hiddenValue());
3296}
3297
3298JSC_DEFINE_HOST_FUNCTION(functionSetHiddenValue, (JSGlobalObject* globalObject, CallFrame* callFrame))
3299{
3300 DollarVMAssertScope assertScope;
3301 VM& vm = globalObject->vm();
3302 JSLockHolder lock(vm);
3303 auto scope = DECLARE_THROW_SCOPE(vm);
3304
3305 SimpleObject* simpleObject = jsDynamicCast<SimpleObject*>(callFrame->argument(0));
3306 if (UNLIKELY(!simpleObject)) {
3307 throwTypeError(globalObject, scope, "Invalid use of setHiddenValue test function"_s);
3308 return encodedJSValue();
3309 }
3310 JSValue value = callFrame->argument(1);
3311 simpleObject->setHiddenValue(vm, value);
3312 return JSValue::encode(jsUndefined());
3313}
3314
3315JSC_DEFINE_HOST_FUNCTION(functionShadowChickenFunctionsOnStack, (JSGlobalObject* globalObject, CallFrame* callFrame))
3316{
3317 DollarVMAssertScope assertScope;
3318 VM& vm = globalObject->vm();
3319 DeferTermination deferScope(vm);
3320 auto scope = DECLARE_THROW_SCOPE(vm);
3321 if (auto* shadowChicken = vm.shadowChicken()) {
3322 scope.release();
3323 return JSValue::encode(shadowChicken->functionsOnStack(globalObject, callFrame));
3324 }
3325
3326 JSArray* result = constructEmptyArray(globalObject, nullptr);
3327 RETURN_IF_EXCEPTION(scope, { });
3328 StackVisitor::visit(callFrame, vm, [&] (StackVisitor& visitor) -> IterationStatus {
3329 DollarVMAssertScope assertScope;
3330 if (visitor->isInlinedFrame())
3331 return IterationStatus::Continue;
3332 if (visitor->isWasmFrame())
3333 return IterationStatus::Continue;
3334 result->push(globalObject, jsCast<JSObject*>(visitor->callee().asCell()));
3335 scope.releaseAssertNoException(); // This function is only called from tests.
3336 return IterationStatus::Continue;
3337 });
3338 RETURN_IF_EXCEPTION(scope, { });
3339 return JSValue::encode(result);
3340}
3341
3342JSC_DEFINE_HOST_FUNCTION(functionSetGlobalConstRedeclarationShouldNotThrow, (JSGlobalObject* globalObject, CallFrame*))
3343{
3344 DollarVMAssertScope assertScope;
3345 VM& vm = globalObject->vm();
3346 vm.setGlobalConstRedeclarationShouldThrow(false);
3347 return JSValue::encode(jsUndefined());
3348}
3349
3350JSC_DEFINE_HOST_FUNCTION(functionFindTypeForExpression, (JSGlobalObject* globalObject, CallFrame* callFrame))
3351{
3352 DollarVMAssertScope assertScope;
3353 VM& vm = globalObject->vm();
3354 RELEASE_ASSERT(vm.typeProfiler());
3355 vm.typeProfilerLog()->processLogEntries(vm, "jsc Testing API: functionFindTypeForExpression"_s);
3356
3357 JSValue functionValue = callFrame->argument(0);
3358 RELEASE_ASSERT(functionValue.isCallable());
3359 FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(functionValue.asCell()->getObject()))->jsExecutable();
3360
3361 RELEASE_ASSERT(callFrame->argument(1).isString());
3362 String substring = asString(callFrame->argument(1))->value(globalObject);
3363 String sourceCodeText = executable->source().view().toString();
3364 unsigned offset = static_cast<unsigned>(sourceCodeText.find(substring) + executable->source().startOffset());
3365
3366 String jsonString = vm.typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorNormal, offset, executable->sourceID(), vm);
3367 return JSValue::encode(JSONParse(globalObject, jsonString));
3368}
3369
3370JSC_DEFINE_HOST_FUNCTION(functionReturnTypeFor, (JSGlobalObject* globalObject, CallFrame* callFrame))
3371{
3372 DollarVMAssertScope assertScope;
3373 VM& vm = globalObject->vm();
3374 RELEASE_ASSERT(vm.typeProfiler());
3375 vm.typeProfilerLog()->processLogEntries(vm, "jsc Testing API: functionReturnTypeFor"_s);
3376
3377 JSValue functionValue = callFrame->argument(0);
3378 RELEASE_ASSERT(functionValue.isCallable());
3379 FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(functionValue.asCell()->getObject()))->jsExecutable();
3380
3381 unsigned offset = executable->typeProfilingStartOffset(vm);
3382 String jsonString = vm.typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorFunctionReturn, offset, executable->sourceID(), vm);
3383 return JSValue::encode(JSONParse(globalObject, jsonString));
3384}
3385
3386JSC_DEFINE_HOST_FUNCTION(functionFlattenDictionaryObject, (JSGlobalObject* globalObject, CallFrame* callFrame))
3387{
3388 DollarVMAssertScope assertScope;
3389 VM& vm = globalObject->vm();
3390 JSValue value = callFrame->argument(0);
3391 RELEASE_ASSERT(value.isObject() && value.getObject()->structure()->isDictionary());
3392 value.getObject()->flattenDictionaryObject(vm);
3393 return encodedJSUndefined();
3394}
3395
3396JSC_DEFINE_HOST_FUNCTION(functionDumpBasicBlockExecutionRanges, (JSGlobalObject* globalObject, CallFrame*))
3397{
3398 DollarVMAssertScope assertScope;
3399 VM& vm = globalObject->vm();
3400 RELEASE_ASSERT(vm.controlFlowProfiler());
3401 vm.controlFlowProfiler()->dumpData();
3402 return JSValue::encode(jsUndefined());
3403}
3404
3405JSC_DEFINE_HOST_FUNCTION(functionHasBasicBlockExecuted, (JSGlobalObject* globalObject, CallFrame* callFrame))
3406{
3407 DollarVMAssertScope assertScope;
3408 VM& vm = globalObject->vm();
3409 RELEASE_ASSERT(vm.controlFlowProfiler());
3410
3411 JSValue functionValue = callFrame->argument(0);
3412 RELEASE_ASSERT(functionValue.isCallable());
3413 FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(functionValue.asCell()->getObject()))->jsExecutable();
3414
3415 RELEASE_ASSERT(callFrame->argument(1).isString());
3416 String substring = asString(callFrame->argument(1))->value(globalObject);
3417 String sourceCodeText = executable->source().view().toString();
3418 RELEASE_ASSERT(sourceCodeText.contains(substring));
3419 int offset = sourceCodeText.find(substring) + executable->source().startOffset();
3420
3421 bool hasExecuted = vm.controlFlowProfiler()->hasBasicBlockAtTextOffsetBeenExecuted(offset, executable->sourceID(), vm);
3422 return JSValue::encode(jsBoolean(hasExecuted));
3423}
3424
3425JSC_DEFINE_HOST_FUNCTION(functionBasicBlockExecutionCount, (JSGlobalObject* globalObject, CallFrame* callFrame))
3426{
3427 DollarVMAssertScope assertScope;
3428 VM& vm = globalObject->vm();
3429 RELEASE_ASSERT(vm.controlFlowProfiler());
3430
3431 JSValue functionValue = callFrame->argument(0);
3432 RELEASE_ASSERT(functionValue.isCallable());
3433 FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(functionValue.asCell()->getObject()))->jsExecutable();
3434
3435 RELEASE_ASSERT(callFrame->argument(1).isString());
3436 String substring = asString(callFrame->argument(1))->value(globalObject);
3437 String sourceCodeText = executable->source().view().toString();
3438 RELEASE_ASSERT(sourceCodeText.contains(substring));
3439 int offset = sourceCodeText.find(substring) + executable->source().startOffset();
3440
3441 size_t executionCount = vm.controlFlowProfiler()->basicBlockExecutionCountAtTextOffset(offset, executable->sourceID(), vm);
3442 return JSValue::encode(JSValue(executionCount));
3443}
3444
3445class DoNothingDebugger final : public Debugger {
3446 WTF_MAKE_NONCOPYABLE(DoNothingDebugger);
3447 WTF_MAKE_FAST_ALLOCATED;
3448public:
3449 DoNothingDebugger(VM& vm)
3450 : Debugger(vm)
3451 {
3452 DollarVMAssertScope assertScope;
3453 setSuppressAllPauses(true);
3454 }
3455
3456private:
3457 void sourceParsed(JSGlobalObject*, SourceProvider*, int, const WTF::String&) final
3458 {
3459 DollarVMAssertScope assertScope;
3460 }
3461};
3462
3463static EncodedJSValue changeDebuggerModeWhenIdle(JSGlobalObject* globalObject, OptionSet<CodeGenerationMode> codeGenerationMode)
3464{
3465 DollarVMAssertScope assertScope;
3466
3467 bool debuggerRequested = codeGenerationMode.contains(CodeGenerationMode::Debugger);
3468 if (debuggerRequested == globalObject->hasDebugger())
3469 return JSValue::encode(jsUndefined());
3470
3471 VM* vm = &globalObject->vm();
3472 vm->whenIdle([=] () {
3473 DollarVMAssertScope assertScope;
3474 if (debuggerRequested) {
3475 Debugger* debugger = new DoNothingDebugger(globalObject->vm());
3476 globalObject->setDebugger(debugger);
3477 debugger->activateBreakpoints(); // Also deletes all code.
3478 } else {
3479 Debugger* debugger = globalObject->debugger();
3480 debugger->deactivateBreakpoints(); // Also deletes all code.
3481 globalObject->setDebugger(nullptr);
3482 delete debugger;
3483 }
3484 });
3485 return JSValue::encode(jsUndefined());
3486}
3487
3488JSC_DEFINE_HOST_FUNCTION(functionEnableDebuggerModeWhenIdle, (JSGlobalObject* globalObject, CallFrame*))
3489{
3490 DollarVMAssertScope assertScope;
3491 return changeDebuggerModeWhenIdle(globalObject, { CodeGenerationMode::Debugger });
3492}
3493
3494JSC_DEFINE_HOST_FUNCTION(functionDisableDebuggerModeWhenIdle, (JSGlobalObject* globalObject, CallFrame*))
3495{
3496 DollarVMAssertScope assertScope;
3497 return changeDebuggerModeWhenIdle(globalObject, { });
3498}
3499
3500JSC_DEFINE_HOST_FUNCTION(functionDeleteAllCodeWhenIdle, (JSGlobalObject* globalObject, CallFrame*))
3501{
3502 DollarVMAssertScope assertScope;
3503 VM* vm = &globalObject->vm();
3504 vm->whenIdle([=] () {
3505 DollarVMAssertScope assertScope;
3506 vm->deleteAllCode(PreventCollectionAndDeleteAllCode);
3507 });
3508 return JSValue::encode(jsUndefined());
3509}
3510
3511JSC_DEFINE_HOST_FUNCTION(functionGlobalObjectCount, (JSGlobalObject* globalObject, CallFrame*))
3512{
3513 DollarVMAssertScope assertScope;
3514 return JSValue::encode(jsNumber(globalObject->vm().heap.globalObjectCount()));
3515}
3516
3517JSC_DEFINE_HOST_FUNCTION(functionGlobalObjectForObject, (JSGlobalObject*, CallFrame* callFrame))
3518{
3519 DollarVMAssertScope assertScope;
3520 JSValue value = callFrame->argument(0);
3521 RELEASE_ASSERT(value.isObject());
3522 JSGlobalObject* result = jsCast<JSObject*>(value)->globalObject();
3523 RELEASE_ASSERT(result);
3524 return JSValue::encode(result);
3525}
3526
3527JSC_DEFINE_HOST_FUNCTION(functionGetGetterSetter, (JSGlobalObject* globalObject, CallFrame* callFrame))
3528{
3529 DollarVMAssertScope assertScope;
3530 VM& vm = globalObject->vm();
3531 auto scope = DECLARE_THROW_SCOPE(vm);
3532
3533 JSValue value = callFrame->argument(0);
3534 if (!value.isObject())
3535 return JSValue::encode(jsUndefined());
3536
3537 JSValue property = callFrame->argument(1);
3538 if (!property.isString())
3539 return JSValue::encode(jsUndefined());
3540
3541 auto propertyName = asString(property)->toIdentifier(globalObject);
3542 RETURN_IF_EXCEPTION(scope, { });
3543
3544 PropertySlot slot(value, PropertySlot::InternalMethodType::VMInquiry, &vm);
3545 value.getPropertySlot(globalObject, propertyName, slot);
3546 RETURN_IF_EXCEPTION(scope, { });
3547
3548 JSValue result;
3549 if (slot.isCacheableGetter())
3550 result = slot.getterSetter();
3551 else
3552 result = jsNull();
3553
3554 return JSValue::encode(result);
3555}
3556
3557JSC_DEFINE_HOST_FUNCTION(functionLoadGetterFromGetterSetter, (JSGlobalObject* globalObject, CallFrame* callFrame))
3558{
3559 DollarVMAssertScope assertScope;
3560 VM& vm = globalObject->vm();
3561 auto scope = DECLARE_THROW_SCOPE(vm);
3562
3563 GetterSetter* getterSetter = jsDynamicCast<GetterSetter*>(callFrame->argument(0));
3564 if (UNLIKELY(!getterSetter)) {
3565 throwTypeError(globalObject, scope, "Invalid use of loadGetterFromGetterSetter test function: argument is not a GetterSetter"_s);
3566 return encodedJSValue();
3567 }
3568
3569 JSObject* getter = getterSetter->getter();
3570 RELEASE_ASSERT(getter);
3571 return JSValue::encode(getter);
3572}
3573
3574JSC_DEFINE_HOST_FUNCTION(functionCreateCustomTestGetterSetter, (JSGlobalObject* globalObject, CallFrame*))
3575{
3576 DollarVMAssertScope assertScope;
3577 VM& vm = globalObject->vm();
3578 return JSValue::encode(JSTestCustomGetterSetter::create(vm, globalObject, JSTestCustomGetterSetter::createStructure(vm, globalObject)));
3579}
3580
3581JSC_DEFINE_HOST_FUNCTION(functionDeltaBetweenButterflies, (JSGlobalObject*, CallFrame* callFrame))
3582{
3583 DollarVMAssertScope assertScope;
3584 JSObject* a = jsDynamicCast<JSObject*>(callFrame->argument(0));
3585 JSObject* b = jsDynamicCast<JSObject*>(callFrame->argument(1));
3586 if (!a || !b)
3587 return JSValue::encode(jsNumber(PNaN));
3588
3589 ptrdiff_t delta = bitwise_cast<char*>(a->butterfly()) - bitwise_cast<char*>(b->butterfly());
3590 if (delta < 0)
3591 return JSValue::encode(jsNumber(PNaN));
3592 if (delta > std::numeric_limits<int32_t>::max())
3593 return JSValue::encode(jsNumber(PNaN));
3594 return JSValue::encode(jsNumber(static_cast<int32_t>(delta)));
3595}
3596
3597JSC_DEFINE_HOST_FUNCTION(functionCurrentCPUTime, (JSGlobalObject*, CallFrame*))
3598{
3599 DollarVMAssertScope assertScope;
3600 return JSValue::encode(jsNumber(CPUTime::forCurrentThread().value()));
3601}
3602
3603JSC_DEFINE_HOST_FUNCTION(functionTotalGCTime, (JSGlobalObject* globalObject, CallFrame*))
3604{
3605 DollarVMAssertScope assertScope;
3606 VM& vm = globalObject->vm();
3607 return JSValue::encode(jsNumber(vm.heap.totalGCTime().seconds()));
3608}
3609
3610JSC_DEFINE_HOST_FUNCTION(functionParseCount, (JSGlobalObject*, CallFrame*))
3611{
3612 DollarVMAssertScope assertScope;
3613 return JSValue::encode(jsNumber(globalParseCount.load()));
3614}
3615
3616JSC_DEFINE_HOST_FUNCTION(functionIsWasmSupported, (JSGlobalObject*, CallFrame*))
3617{
3618 DollarVMAssertScope assertScope;
3619#if ENABLE(WEBASSEMBLY)
3620 return JSValue::encode(jsBoolean(Wasm::isSupported()));
3621#else
3622 return JSValue::encode(jsBoolean(false));
3623#endif
3624}
3625
3626JSC_DEFINE_HOST_FUNCTION(functionMake16BitStringIfPossible, (JSGlobalObject* globalObject, CallFrame* callFrame))
3627{
3628 DollarVMAssertScope assertScope;
3629 VM& vm = globalObject->vm();
3630 auto scope = DECLARE_THROW_SCOPE(vm);
3631 String string = callFrame->argument(0).toWTFString(globalObject);
3632 RETURN_IF_EXCEPTION(scope, { });
3633 if (!string.is8Bit())
3634 return JSValue::encode(jsString(vm, WTFMove(string)));
3635 Vector<UChar> buffer;
3636 buffer.resize(string.length());
3637 StringImpl::copyCharacters(buffer.data(), string.characters8(), string.length());
3638 return JSValue::encode(jsString(vm, String::adopt(WTFMove(buffer))));
3639}
3640
3641JSC_DEFINE_HOST_FUNCTION(functionGetStructureTransitionList, (JSGlobalObject* globalObject, CallFrame* callFrame))
3642{
3643 DollarVMAssertScope assertScope;
3644 VM& vm = globalObject->vm();
3645 auto scope = DECLARE_THROW_SCOPE(vm);
3646 JSObject* obj = callFrame->argument(0).toObject(globalObject);
3647 RETURN_IF_EXCEPTION(scope, { });
3648 if (!obj)
3649 return JSValue::encode(jsNull());
3650 Vector<Structure*, 8> structures;
3651
3652 for (auto* structure = obj->structure(); structure; structure = structure->previousID())
3653 structures.append(structure);
3654
3655 JSArray* result = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), 0);
3656 RETURN_IF_EXCEPTION(scope, { });
3657
3658 for (size_t i = 0; i < structures.size(); ++i) {
3659 auto* structure = structures[structures.size() - i - 1];
3660 result->push(globalObject, JSValue(structure->id().bits()));
3661 RETURN_IF_EXCEPTION(scope, { });
3662 result->push(globalObject, JSValue(structure->transitionOffset()));
3663 RETURN_IF_EXCEPTION(scope, { });
3664 result->push(globalObject, JSValue(structure->maxOffset()));
3665 RETURN_IF_EXCEPTION(scope, { });
3666 if (structure->transitionPropertyName())
3667 result->push(globalObject, jsString(vm, String(*structure->transitionPropertyName())));
3668 else
3669 result->push(globalObject, jsNull());
3670 RETURN_IF_EXCEPTION(scope, { });
3671 result->push(globalObject, jsNumber(static_cast<int32_t>(structure->transitionKind())));
3672 RETURN_IF_EXCEPTION(scope, { });
3673 }
3674
3675 return JSValue::encode(result);
3676}
3677
3678JSC_DEFINE_HOST_FUNCTION(functionGetConcurrently, (JSGlobalObject* globalObject, CallFrame* callFrame))
3679{
3680 DollarVMAssertScope assertScope;
3681 VM& vm = globalObject->vm();
3682 auto scope = DECLARE_THROW_SCOPE(vm);
3683 JSObject* obj = callFrame->argument(0).toObject(globalObject);
3684 RETURN_IF_EXCEPTION(scope, { });
3685 if (!obj)
3686 return JSValue::encode(jsNull());
3687 String property = callFrame->argument(1).toWTFString(globalObject);
3688 RETURN_IF_EXCEPTION(scope, { });
3689 auto name = PropertyName(Identifier::fromString(vm, property));
3690 auto offset = obj->structure()->getConcurrently(name.uid());
3691 if (offset != invalidOffset)
3692 ASSERT(JSValue::encode(obj->getDirect(offset)));
3693 JSValue result = JSValue(offset != invalidOffset);
3694 RETURN_IF_EXCEPTION(scope, { });
3695 return JSValue::encode(result);
3696}
3697
3698JSC_DEFINE_HOST_FUNCTION(functionHasOwnLengthProperty, (JSGlobalObject* globalObject, CallFrame* callFrame))
3699{
3700 DollarVMAssertScope assertScope;
3701 VM& vm = globalObject->vm();
3702
3703 JSObject* target = asObject(callFrame->uncheckedArgument(0));
3704 JSFunction* function = jsDynamicCast<JSFunction*>(target);
3705 return JSValue::encode(jsBoolean(function->canAssumeNameAndLengthAreOriginal(vm)));
3706}
3707
3708JSC_DEFINE_HOST_FUNCTION(functionRejectPromiseAsHandled, (JSGlobalObject* globalObject, CallFrame* callFrame))
3709{
3710 DollarVMAssertScope assertScope;
3711 JSPromise* promise = jsCast<JSPromise*>(callFrame->uncheckedArgument(0));
3712 JSValue reason = callFrame->uncheckedArgument(1);
3713 promise->rejectAsHandled(globalObject, reason);
3714 return JSValue::encode(jsUndefined());
3715}
3716
3717JSC_DEFINE_HOST_FUNCTION(functionSetUserPreferredLanguages, (JSGlobalObject* globalObject, CallFrame* callFrame))
3718{
3719 DollarVMAssertScope assertScope;
3720 VM& vm = globalObject->vm();
3721 auto scope = DECLARE_THROW_SCOPE(vm);
3722
3723 JSArray* array = jsDynamicCast<JSArray*>(callFrame->argument(0));
3724 if (!array)
3725 return throwVMTypeError(globalObject, scope, "Expected first argument to be an array"_s);
3726
3727 Vector<String> languages;
3728 unsigned length = array->length();
3729 for (unsigned i = 0; i < length; i++) {
3730 String language = array->get(globalObject, i).toWTFString(globalObject);
3731 RETURN_IF_EXCEPTION(scope, encodedJSValue());
3732 languages.append(language);
3733 }
3734
3735 overrideUserPreferredLanguages(languages);
3736 return JSValue::encode(jsUndefined());
3737}
3738
3739JSC_DEFINE_HOST_FUNCTION(functionICUVersion, (JSGlobalObject*, CallFrame*))
3740{
3741 DollarVMAssertScope assertScope;
3742 return JSValue::encode(jsNumber(WTF::ICU::majorVersion()));
3743}
3744
3745JSC_DEFINE_HOST_FUNCTION(functionICUHeaderVersion, (JSGlobalObject*, CallFrame*))
3746{
3747 DollarVMAssertScope assertScope;
3748 return JSValue::encode(jsNumber(U_ICU_VERSION_MAJOR_NUM));
3749}
3750
3751JSC_DEFINE_HOST_FUNCTION(functionAssertEnabled, (JSGlobalObject*, CallFrame*))
3752{
3753 DollarVMAssertScope assertScope;
3754 return JSValue::encode(jsBoolean(ASSERT_ENABLED));
3755}
3756
3757JSC_DEFINE_HOST_FUNCTION(functionSecurityAssertEnabled, (JSGlobalObject*, CallFrame*))
3758{
3759 DollarVMAssertScope assertScope;
3760#if ENABLE(SECURITY_ASSERTIONS)
3761 return JSValue::encode(jsBoolean(true));
3762#else
3763 return JSValue::encode(jsBoolean(false));
3764#endif
3765}
3766
3767JSC_DEFINE_HOST_FUNCTION(functionAsanEnabled, (JSGlobalObject*, CallFrame*))
3768{
3769 DollarVMAssertScope assertScope;
3770 return JSValue::encode(jsBoolean(ASAN_ENABLED));
3771}
3772
3773JSC_DEFINE_HOST_FUNCTION(functionIsMemoryLimited, (JSGlobalObject*, CallFrame*))
3774{
3775 DollarVMAssertScope assertScope;
3776#if PLATFORM(IOS) || PLATFORM(APPLETV) || PLATFORM(WATCHOS)
3777 return JSValue::encode(jsBoolean(true));
3778#else
3779 return JSValue::encode(jsBoolean(false));
3780#endif
3781}
3782
3783JSC_DEFINE_HOST_FUNCTION(functionUseJIT, (JSGlobalObject*, CallFrame*))
3784{
3785 DollarVMAssertScope assertScope;
3786 return JSValue::encode(jsBoolean(Options::useJIT()));
3787}
3788
3789JSC_DEFINE_HOST_FUNCTION(functionIsGigacageEnabled, (JSGlobalObject*, CallFrame*))
3790{
3791 DollarVMAssertScope assertScope;
3792 return JSValue::encode(jsBoolean(Gigacage::isEnabled()));
3793}
3794
3795JSC_DEFINE_HOST_FUNCTION(functionToCacheableDictionary, (JSGlobalObject* globalObject, CallFrame* callFrame))
3796{
3797 DollarVMAssertScope assertScope;
3798 VM& vm = globalObject->vm();
3799 auto scope = DECLARE_THROW_SCOPE(vm);
3800
3801 JSObject* object = jsDynamicCast<JSObject*>(callFrame->argument(0));
3802 if (!object)
3803 return throwVMTypeError(globalObject, scope, "Expected first argument to be an object"_s);
3804 if (!object->structure()->isUncacheableDictionary())
3805 object->convertToDictionary(vm);
3806 return JSValue::encode(object);
3807}
3808
3809JSC_DEFINE_HOST_FUNCTION(functionToUncacheableDictionary, (JSGlobalObject* globalObject, CallFrame* callFrame))
3810{
3811 DollarVMAssertScope assertScope;
3812 VM& vm = globalObject->vm();
3813 auto scope = DECLARE_THROW_SCOPE(vm);
3814
3815 JSObject* object = jsDynamicCast<JSObject*>(callFrame->argument(0));
3816 if (!object)
3817 return throwVMTypeError(globalObject, scope, "Expected first argument to be an object"_s);
3818 object->convertToUncacheableDictionary(vm);
3819 return JSValue::encode(object);
3820}
3821
3822JSC_DEFINE_HOST_FUNCTION(functionIsPrivateSymbol, (JSGlobalObject*, CallFrame* callFrame))
3823{
3824 DollarVMAssertScope assertScope;
3825
3826 if (!(callFrame->argument(0).isSymbol()))
3827 return JSValue::encode(jsBoolean(false));
3828
3829 return JSValue::encode(jsBoolean(asSymbol(callFrame->argument(0))->uid().isPrivate()));
3830}
3831
3832JSC_DEFINE_HOST_FUNCTION(functionDumpAndResetPasDebugSpectrum, (JSGlobalObject*, CallFrame*))
3833{
3834 DollarVMAssertScope assertScope;
3835#if !USE(SYSTEM_MALLOC)
3836#if BUSE(LIBPAS)
3837 pas_heap_lock_lock();
3838 pas_debug_spectrum_dump(&pas_log_stream.base);
3839 pas_debug_spectrum_reset();
3840 pas_heap_lock_unlock();
3841#endif
3842#endif
3843 return JSValue::encode(jsUndefined());
3844}
3845
3846JSC_DEFINE_HOST_FUNCTION(functionMonotonicTimeNow, (JSGlobalObject*, CallFrame*))
3847{
3848 return JSValue::encode(jsNumber(MonotonicTime::now().secondsSinceEpoch().milliseconds()));
3849}
3850
3851JSC_DEFINE_HOST_FUNCTION(functionWallTimeNow, (JSGlobalObject*, CallFrame*))
3852{
3853 return JSValue::encode(jsNumber(WallTime::now().secondsSinceEpoch().milliseconds()));
3854}
3855
3856JSC_DEFINE_HOST_FUNCTION(functionApproximateTimeNow, (JSGlobalObject*, CallFrame*))
3857{
3858 return JSValue::encode(jsNumber(ApproximateTime::now().secondsSinceEpoch().milliseconds()));
3859}
3860
3861#if ENABLE(JIT)
3862JSC_DEFINE_HOST_FUNCTION(functionJITSizeStatistics, (JSGlobalObject* globalObject, CallFrame*))
3863{
3864 DollarVMAssertScope assertScope;
3865
3866 VM& vm = globalObject->vm();
3867
3868 if (!vm.jitSizeStatistics)
3869 return JSValue::encode(jsUndefined());
3870
3871 WTF::StringPrintStream stream;
3872 stream.print(*vm.jitSizeStatistics);
3873 return JSValue::encode(jsString(vm, stream.toString()));
3874}
3875
3876JSC_DEFINE_HOST_FUNCTION(functionDumpJITSizeStatistics, (JSGlobalObject* globalObject, CallFrame*))
3877{
3878 DollarVMAssertScope assertScope;
3879
3880 VM& vm = globalObject->vm();
3881
3882 if (!vm.jitSizeStatistics)
3883 return JSValue::encode(jsUndefined());
3884
3885 dataLogLn(*vm.jitSizeStatistics);
3886 return JSValue::encode(jsUndefined());
3887}
3888
3889JSC_DEFINE_HOST_FUNCTION(functionResetJITSizeStatistics, (JSGlobalObject* globalObject, CallFrame*))
3890{
3891 DollarVMAssertScope assertScope;
3892
3893 VM& vm = globalObject->vm();
3894
3895 if (!vm.jitSizeStatistics)
3896 return JSValue::encode(jsUndefined());
3897
3898 vm.jitSizeStatistics->reset();
3899 return JSValue::encode(jsUndefined());
3900}
3901#endif
3902
3903JSC_DEFINE_HOST_FUNCTION(functionEnsureArrayStorage, (JSGlobalObject* globalObject, CallFrame* callFrame))
3904{
3905 DollarVMAssertScope assertScope;
3906
3907 VM& vm = globalObject->vm();
3908
3909 JSValue arg = callFrame->argument(0);
3910 if (arg.isObject())
3911 asObject(arg)->ensureArrayStorage(vm);
3912 return JSValue::encode(jsUndefined());
3913}
3914
3915constexpr unsigned jsDollarVMPropertyAttributes = PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::DontDelete;
3916
3917void JSDollarVM::finishCreation(VM& vm)
3918{
3919 DollarVMAssertScope assertScope;
3920 Base::finishCreation(vm);
3921
3922 JSGlobalObject* globalObject = this->globalObject();
3923
3924 auto addFunction = [&] (VM& vm, ASCIILiteral name, NativeFunction function, unsigned arguments) {
3925 DollarVMAssertScope assertScope;
3926 JSDollarVM::addFunction(vm, globalObject, name, function, arguments);
3927 };
3928 auto addConstructibleFunction = [&] (VM& vm, ASCIILiteral name, NativeFunction function, unsigned arguments) {
3929 DollarVMAssertScope assertScope;
3930 JSDollarVM::addConstructibleFunction(vm, globalObject, name, function, arguments);
3931 };
3932
3933 addFunction(vm, "abort"_s, functionCrash, 0);
3934 addFunction(vm, "crash"_s, functionCrash, 0);
3935 addFunction(vm, "breakpoint"_s, functionBreakpoint, 0);
3936
3937 putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "dfgTrue"_s), 0, functionDFGTrue, DFGTrueIntrinsic, jsDollarVMPropertyAttributes);
3938 putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "ftlTrue"_s), 0, functionFTLTrue, FTLTrueIntrinsic, jsDollarVMPropertyAttributes);
3939
3940 putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "cpuMfence"_s), 0, functionCpuMfence, CPUMfenceIntrinsic, jsDollarVMPropertyAttributes);
3941 putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "cpuRdtsc"_s), 0, functionCpuRdtsc, CPURdtscIntrinsic, jsDollarVMPropertyAttributes);
3942 putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "cpuCpuid"_s), 0, functionCpuCpuid, CPUCpuidIntrinsic, jsDollarVMPropertyAttributes);
3943 putDirectNativeFunction(vm, globalObject, Identifier::fromString(vm, "cpuPause"_s), 0, functionCpuPause, CPUPauseIntrinsic, jsDollarVMPropertyAttributes);
3944 addFunction(vm, "cpuClflush"_s, functionCpuClflush, 2);
3945
3946 addFunction(vm, "llintTrue"_s, functionLLintTrue, 0);
3947 addFunction(vm, "baselineJITTrue"_s, functionBaselineJITTrue, 0);
3948
3949 addFunction(vm, "noInline"_s, functionNoInline, 1);
3950
3951 addFunction(vm, "gc"_s, functionGC, 0);
3952 addFunction(vm, "gcSweepAsynchronously"_s, functionGCSweepAsynchronously, 0);
3953 addFunction(vm, "edenGC"_s, functionEdenGC, 0);
3954 addFunction(vm, "dumpSubspaceHashes"_s, functionDumpSubspaceHashes, 0);
3955
3956 addFunction(vm, "callFrame"_s, functionCallFrame, 1);
3957 addFunction(vm, "codeBlockFor"_s, functionCodeBlockFor, 1);
3958 addFunction(vm, "codeBlockForFrame"_s, functionCodeBlockForFrame, 1);
3959 addFunction(vm, "dumpSourceFor"_s, functionDumpSourceFor, 1);
3960 addFunction(vm, "dumpBytecodeFor"_s, functionDumpBytecodeFor, 1);
3961
3962 addFunction(vm, "dataLog"_s, functionDataLog, 1);
3963 addFunction(vm, "print"_s, functionPrint, 1);
3964 addFunction(vm, "dumpCallFrame"_s, functionDumpCallFrame, 0);
3965 addFunction(vm, "dumpStack"_s, functionDumpStack, 0);
3966 addFunction(vm, "dumpRegisters"_s, functionDumpRegisters, 1);
3967
3968 addFunction(vm, "dumpCell"_s, functionDumpCell, 1);
3969
3970 addFunction(vm, "indexingMode"_s, functionIndexingMode, 1);
3971 addFunction(vm, "inlineCapacity"_s, functionInlineCapacity, 1);
3972 addFunction(vm, "clearLinkBufferStats"_s, functionClearLinkBufferStats, 0);
3973 addFunction(vm, "linkBufferStats"_s, functionLinkBufferStats, 0);
3974 addFunction(vm, "value"_s, functionValue, 1);
3975 addFunction(vm, "getpid"_s, functionGetPID, 0);
3976
3977 addFunction(vm, "haveABadTime"_s, functionHaveABadTime, 1);
3978 addFunction(vm, "isHavingABadTime"_s, functionIsHavingABadTime, 1);
3979
3980 addFunction(vm, "callWithStackSize"_s, functionCallWithStackSize, 2);
3981
3982 addFunction(vm, "createGlobalObject"_s, functionCreateGlobalObject, 0);
3983 addFunction(vm, "createProxy"_s, functionCreateProxy, 1);
3984 addFunction(vm, "createRuntimeArray"_s, functionCreateRuntimeArray, 0);
3985 addFunction(vm, "createNullRopeString"_s, functionCreateNullRopeString, 0);
3986
3987 addFunction(vm, "createImpureGetter"_s, functionCreateImpureGetter, 1);
3988 addFunction(vm, "createCustomGetterObject"_s, functionCreateCustomGetterObject, 0);
3989 addFunction(vm, "createDOMJITNodeObject"_s, functionCreateDOMJITNodeObject, 0);
3990 addFunction(vm, "createDOMJITGetterObject"_s, functionCreateDOMJITGetterObject, 0);
3991 addFunction(vm, "createDOMJITGetterNoEffectsObject"_s, functionCreateDOMJITGetterNoEffectsObject, 0);
3992 addFunction(vm, "createDOMJITGetterComplexObject"_s, functionCreateDOMJITGetterComplexObject, 0);
3993 addFunction(vm, "createDOMJITFunctionObject"_s, functionCreateDOMJITFunctionObject, 0);
3994 addFunction(vm, "createDOMJITCheckJSCastObject"_s, functionCreateDOMJITCheckJSCastObject, 0);
3995 addFunction(vm, "createDOMJITGetterBaseJSObject"_s, functionCreateDOMJITGetterBaseJSObject, 0);
3996 addFunction(vm, "createBuiltin"_s, functionCreateBuiltin, 2);
3997#if ENABLE(WEBASSEMBLY)
3998 addFunction(vm, "createWasmStreamingParser"_s, functionCreateWasmStreamingParser, 0);
3999 addFunction(vm, "createWasmStreamingCompilerForCompile"_s, functionCreateWasmStreamingCompilerForCompile, 0);
4000 addFunction(vm, "createWasmStreamingCompilerForInstantiate"_s, functionCreateWasmStreamingCompilerForInstantiate, 0);
4001#endif
4002 addFunction(vm, "createStaticCustomAccessor"_s, functionCreateStaticCustomAccessor, 0);
4003 addFunction(vm, "createStaticCustomValue"_s, functionCreateStaticCustomValue, 0);
4004 addFunction(vm, "createStaticDontDeleteDontEnum"_s, functionCreateStaticDontDeleteDontEnum, 0);
4005 addFunction(vm, "createObjectDoingSideEffectPutWithoutCorrectSlotStatus"_s, functionCreateObjectDoingSideEffectPutWithoutCorrectSlotStatus, 0);
4006 addFunction(vm, "createEmptyFunctionWithName"_s, functionCreateEmptyFunctionWithName, 1);
4007 addFunction(vm, "getPrivateProperty"_s, functionGetPrivateProperty, 2);
4008 addFunction(vm, "setImpureGetterDelegate"_s, functionSetImpureGetterDelegate, 2);
4009
4010 addConstructibleFunction(vm, "Root"_s, functionCreateRoot, 0);
4011 addConstructibleFunction(vm, "Element"_s, functionCreateElement, 1);
4012 addFunction(vm, "getElement"_s, functionGetElement, 1);
4013
4014 addConstructibleFunction(vm, "SimpleObject"_s, functionCreateSimpleObject, 0);
4015 addFunction(vm, "getHiddenValue"_s, functionGetHiddenValue, 1);
4016 addFunction(vm, "setHiddenValue"_s, functionSetHiddenValue, 2);
4017
4018 addFunction(vm, "shadowChickenFunctionsOnStack"_s, functionShadowChickenFunctionsOnStack, 0);
4019 addFunction(vm, "setGlobalConstRedeclarationShouldNotThrow"_s, functionSetGlobalConstRedeclarationShouldNotThrow, 0);
4020
4021 addFunction(vm, "findTypeForExpression"_s, functionFindTypeForExpression, 2);
4022 addFunction(vm, "returnTypeFor"_s, functionReturnTypeFor, 1);
4023
4024 addFunction(vm, "flattenDictionaryObject"_s, functionFlattenDictionaryObject, 1);
4025
4026 addFunction(vm, "dumpBasicBlockExecutionRanges"_s, functionDumpBasicBlockExecutionRanges , 0);
4027 addFunction(vm, "hasBasicBlockExecuted"_s, functionHasBasicBlockExecuted, 2);
4028 addFunction(vm, "basicBlockExecutionCount"_s, functionBasicBlockExecutionCount, 2);
4029
4030 addFunction(vm, "enableDebuggerModeWhenIdle"_s, functionEnableDebuggerModeWhenIdle, 0);
4031 addFunction(vm, "disableDebuggerModeWhenIdle"_s, functionDisableDebuggerModeWhenIdle, 0);
4032
4033 addFunction(vm, "deleteAllCodeWhenIdle"_s, functionDeleteAllCodeWhenIdle, 0);
4034
4035 addFunction(vm, "globalObjectCount"_s, functionGlobalObjectCount, 0);
4036 addFunction(vm, "globalObjectForObject"_s, functionGlobalObjectForObject, 1);
4037
4038 addFunction(vm, "getGetterSetter"_s, functionGetGetterSetter, 2);
4039 addFunction(vm, "loadGetterFromGetterSetter"_s, functionLoadGetterFromGetterSetter, 1);
4040 addFunction(vm, "createCustomTestGetterSetter"_s, functionCreateCustomTestGetterSetter, 1);
4041
4042 addFunction(vm, "deltaBetweenButterflies"_s, functionDeltaBetweenButterflies, 2);
4043
4044 addFunction(vm, "currentCPUTime"_s, functionCurrentCPUTime, 0);
4045 addFunction(vm, "totalGCTime"_s, functionTotalGCTime, 0);
4046
4047 addFunction(vm, "parseCount"_s, functionParseCount, 0);
4048
4049 addFunction(vm, "isWasmSupported"_s, functionIsWasmSupported, 0);
4050 addFunction(vm, "make16BitStringIfPossible"_s, functionMake16BitStringIfPossible, 1);
4051
4052 addFunction(vm, "getStructureTransitionList"_s, functionGetStructureTransitionList, 1);
4053 addFunction(vm, "getConcurrently"_s, functionGetConcurrently, 2);
4054
4055 addFunction(vm, "hasOwnLengthProperty"_s, functionHasOwnLengthProperty, 1);
4056 addFunction(vm, "rejectPromiseAsHandled"_s, functionRejectPromiseAsHandled, 1);
4057
4058 addFunction(vm, "setUserPreferredLanguages"_s, functionSetUserPreferredLanguages, 1);
4059 addFunction(vm, "icuVersion"_s, functionICUVersion, 0);
4060 addFunction(vm, "icuHeaderVersion"_s, functionICUHeaderVersion, 0);
4061
4062 addFunction(vm, "assertEnabled"_s, functionAssertEnabled, 0);
4063 addFunction(vm, "securityAssertEnabled"_s, functionSecurityAssertEnabled, 0);
4064 addFunction(vm, "asanEnabled"_s, functionAsanEnabled, 0);
4065
4066 addFunction(vm, "isMemoryLimited"_s, functionIsMemoryLimited, 0);
4067 addFunction(vm, "useJIT"_s, functionUseJIT, 0);
4068 addFunction(vm, "isGigacageEnabled"_s, functionIsGigacageEnabled, 0);
4069
4070 addFunction(vm, "toCacheableDictionary"_s, functionToCacheableDictionary, 1);
4071 addFunction(vm, "toUncacheableDictionary"_s, functionToUncacheableDictionary, 1);
4072
4073 addFunction(vm, "isPrivateSymbol"_s, functionIsPrivateSymbol, 1);
4074 addFunction(vm, "dumpAndResetPasDebugSpectrum"_s, functionDumpAndResetPasDebugSpectrum, 0);
4075
4076 addFunction(vm, "monotonicTimeNow"_s, functionMonotonicTimeNow, 0);
4077 addFunction(vm, "wallTimeNow"_s, functionWallTimeNow, 0);
4078 addFunction(vm, "approximateTimeNow"_s, functionApproximateTimeNow, 0);
4079
4080#if ENABLE(JIT)
4081 addFunction(vm, "jitSizeStatistics"_s, functionJITSizeStatistics, 0);
4082 addFunction(vm, "dumpJITSizeStatistics"_s, functionDumpJITSizeStatistics, 0);
4083 addFunction(vm, "resetJITSizeStatistics"_s, functionResetJITSizeStatistics, 0);
4084#endif
4085
4086 addFunction(vm, "ensureArrayStorage"_s, functionEnsureArrayStorage, 1);
4087
4088 m_objectDoingSideEffectPutWithoutCorrectSlotStatusStructureID.set(vm, this, ObjectDoingSideEffectPutWithoutCorrectSlotStatus::createStructure(vm, globalObject, jsNull()));
4089}
4090
4091void JSDollarVM::addFunction(VM& vm, JSGlobalObject* globalObject, ASCIILiteral name, NativeFunction function, unsigned arguments)
4092{
4093 DollarVMAssertScope assertScope;
4094 Identifier identifier = Identifier::fromString(vm, name);
4095 putDirect(vm, identifier, JSFunction::create(vm, globalObject, arguments, identifier.string(), function), jsDollarVMPropertyAttributes);
4096}
4097
4098void JSDollarVM::addConstructibleFunction(VM& vm, JSGlobalObject* globalObject, ASCIILiteral name, NativeFunction function, unsigned arguments)
4099{
4100 DollarVMAssertScope assertScope;
4101 Identifier identifier = Identifier::fromString(vm, name);
4102 putDirect(vm, identifier, JSFunction::create(vm, globalObject, arguments, identifier.string(), function, NoIntrinsic, function), jsDollarVMPropertyAttributes);
4103}
4104
4105template<typename Visitor>
4106void JSDollarVM::visitChildrenImpl(JSCell* cell, Visitor& visitor)
4107{
4108 JSDollarVM* thisObject = jsCast<JSDollarVM*>(cell);
4109 Base::visitChildren(thisObject, visitor);
4110 visitor.append(thisObject->m_objectDoingSideEffectPutWithoutCorrectSlotStatusStructureID);
4111}
4112
4113DEFINE_VISIT_CHILDREN(JSDollarVM);
4114
4115} // namespace JSC
4116
4117IGNORE_WARNINGS_END
Note: See TracBrowser for help on using the repository browser.