1/*
2 * Copyright (C) 2007-2019 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Cameron Zwarich ([email protected])
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "config.h"
31#include "JSGlobalObject.h"
32
33#include "ArrayConstructor.h"
34#include "ArrayIteratorPrototype.h"
35#include "ArrayPrototype.h"
36#include "AsyncFromSyncIteratorPrototype.h"
37#include "AtomicsObject.h"
38#include "AsyncFunctionConstructor.h"
39#include "AsyncFunctionPrototype.h"
40#include "AsyncGeneratorFunctionConstructor.h"
41#include "AsyncGeneratorFunctionPrototype.h"
42#include "AsyncGeneratorPrototype.h"
43#include "AsyncIteratorPrototype.h"
44#include "BigIntConstructor.h"
45#include "BigIntObject.h"
46#include "BigIntPrototype.h"
47#include "BooleanConstructor.h"
48#include "BooleanPrototype.h"
49#include "BuiltinNames.h"
50#include "CatchScope.h"
51#include "ClonedArguments.h"
52#include "CodeBlock.h"
53#include "CodeBlockSetInlines.h"
54#include "CodeCache.h"
55#include "ConsoleObject.h"
56#include "DateConstructor.h"
57#include "DatePrototype.h"
58#include "Debugger.h"
59#include "DebuggerScope.h"
60#include "DirectArguments.h"
61#include "DirectEvalExecutable.h"
62#include "ECMAScriptSpecInternalFunctions.h"
63#include "Error.h"
64#include "ErrorConstructor.h"
65#include "ErrorPrototype.h"
66#include "Exception.h"
67#include "FunctionConstructor.h"
68#include "FunctionPrototype.h"
69#include "GeneratorFunctionConstructor.h"
70#include "GeneratorFunctionPrototype.h"
71#include "GeneratorPrototype.h"
72#include "GetterSetter.h"
73#include "HeapIterationScope.h"
74#include "IndirectEvalExecutable.h"
75#include "InspectorInstrumentationObject.h"
76#include "Interpreter.h"
77#include "IteratorPrototype.h"
78#include "JSAPIWrapperObject.h"
79#include "JSArrayBuffer.h"
80#include "JSArrayBufferConstructor.h"
81#include "JSArrayBufferPrototype.h"
82#include "JSAsyncFunction.h"
83#include "JSAsyncGeneratorFunction.h"
84#include "JSBigInt.h"
85#include "JSBoundFunction.h"
86#include "JSCInlines.h"
87#include "JSCallbackConstructor.h"
88#include "JSCallbackFunction.h"
89#include "JSCallbackObject.h"
90#include "JSCustomGetterSetterFunction.h"
91#include "JSDataView.h"
92#include "JSDataViewPrototype.h"
93#include "JSDollarVM.h"
94#include "JSFunction.h"
95#include "JSGeneratorFunction.h"
96#include "JSGenericTypedArrayViewConstructorInlines.h"
97#include "JSGenericTypedArrayViewInlines.h"
98#include "JSGenericTypedArrayViewPrototypeInlines.h"
99#include "JSGlobalObjectFunctions.h"
100#include "JSInternalPromise.h"
101#include "JSInternalPromiseConstructor.h"
102#include "JSInternalPromisePrototype.h"
103#include "JSLexicalEnvironment.h"
104#include "JSLock.h"
105#include "JSMap.h"
106#include "JSMicrotask.h"
107#include "JSModuleEnvironment.h"
108#include "JSModuleLoader.h"
109#include "JSModuleNamespaceObject.h"
110#include "JSModuleRecord.h"
111#include "JSNativeStdFunction.h"
112#include "JSNonDestructibleProxy.h"
113#include "JSONObject.h"
114#include "JSPromise.h"
115#include "JSPromiseConstructor.h"
116#include "JSPromisePrototype.h"
117#include "JSSet.h"
118#include "JSStringIterator.h"
119#include "JSTypedArrayConstructors.h"
120#include "JSTypedArrayPrototypes.h"
121#include "JSTypedArrayViewConstructor.h"
122#include "JSTypedArrayViewPrototype.h"
123#include "JSTypedArrays.h"
124#include "JSWeakMap.h"
125#include "JSWeakSet.h"
126#include "JSWebAssembly.h"
127#include "JSWithScope.h"
128#include "LazyClassStructureInlines.h"
129#include "LazyPropertyInlines.h"
130#include "Lookup.h"
131#include "MapConstructor.h"
132#include "MapIteratorPrototype.h"
133#include "MapPrototype.h"
134#include "MarkedSpaceInlines.h"
135#include "MathObject.h"
136#include "Microtask.h"
137#include "NativeErrorConstructor.h"
138#include "NativeErrorPrototype.h"
139#include "NullGetterFunction.h"
140#include "NullSetterFunction.h"
141#include "NumberConstructor.h"
142#include "NumberPrototype.h"
143#include "ObjCCallbackFunction.h"
144#include "ObjectConstructor.h"
145#include "ObjectPropertyChangeAdaptiveWatchpoint.h"
146#include "ObjectPropertyConditionSet.h"
147#include "ObjectPrototype.h"
148#include "ParserError.h"
149#include "ProxyConstructor.h"
150#include "ProxyObject.h"
151#include "ProxyRevoke.h"
152#include "ReflectObject.h"
153#include "RegExpCache.h"
154#include "RegExpConstructor.h"
155#include "RegExpMatchesArray.h"
156#include "RegExpObject.h"
157#include "RegExpPrototype.h"
158#include "ScopedArguments.h"
159#include "SetConstructor.h"
160#include "SetIteratorPrototype.h"
161#include "SetPrototype.h"
162#include "StrictEvalActivation.h"
163#include "StringConstructor.h"
164#include "StringIteratorPrototype.h"
165#include "StringPrototype.h"
166#include "Symbol.h"
167#include "SymbolConstructor.h"
168#include "SymbolObject.h"
169#include "SymbolPrototype.h"
170#include "VariableWriteFireDetail.h"
171#include "WasmCapabilities.h"
172#include "WeakGCMapInlines.h"
173#include "WeakMapConstructor.h"
174#include "WeakMapPrototype.h"
175#include "WeakSetConstructor.h"
176#include "WeakSetPrototype.h"
177#include "WebAssemblyPrototype.h"
178#include "WebAssemblyToJSCallee.h"
179#include <wtf/RandomNumber.h>
180
181#if ENABLE(INTL)
182#include "IntlCollator.h"
183#include "IntlCollatorPrototype.h"
184#include "IntlDateTimeFormat.h"
185#include "IntlDateTimeFormatPrototype.h"
186#include "IntlNumberFormat.h"
187#include "IntlNumberFormatPrototype.h"
188#include "IntlObject.h"
189#include "IntlPluralRules.h"
190#include "IntlPluralRulesPrototype.h"
191#include <unicode/ucol.h>
192#include <unicode/udat.h>
193#include <unicode/unum.h>
194#endif // ENABLE(INTL)
195
196#if ENABLE(REMOTE_INSPECTOR)
197#include "JSGlobalObjectDebuggable.h"
198#include "JSGlobalObjectInspectorController.h"
199#endif
200
201#ifdef JSC_GLIB_API_ENABLED
202#include "JSCCallbackFunction.h"
203#include "JSCWrapperMap.h"
204#endif
205
206namespace JSC {
207
208static JSValue createProxyProperty(VM& vm, JSObject* object)
209{
210 JSGlobalObject* global = jsCast<JSGlobalObject*>(object);
211 return ProxyConstructor::create(vm, ProxyConstructor::createStructure(vm, global, global->functionPrototype()));
212}
213
214static JSValue createJSONProperty(VM& vm, JSObject* object)
215{
216 JSGlobalObject* global = jsCast<JSGlobalObject*>(object);
217 return JSONObject::create(vm, JSONObject::createStructure(vm, global, global->objectPrototype()));
218}
219
220static JSValue createMathProperty(VM& vm, JSObject* object)
221{
222 JSGlobalObject* global = jsCast<JSGlobalObject*>(object);
223 return MathObject::create(vm, global, MathObject::createStructure(vm, global, global->objectPrototype()));
224}
225
226static JSValue createReflectProperty(VM& vm, JSObject* object)
227{
228 JSGlobalObject* global = jsCast<JSGlobalObject*>(object);
229 return ReflectObject::create(vm, global, ReflectObject::createStructure(vm, global, global->objectPrototype()));
230}
231
232static JSValue createConsoleProperty(VM& vm, JSObject* object)
233{
234 JSGlobalObject* global = jsCast<JSGlobalObject*>(object);
235 return ConsoleObject::create(vm, global, ConsoleObject::createStructure(vm, global, constructEmptyObject(global->globalExec())));
236}
237
238static EncodedJSValue JSC_HOST_CALL makeBoundFunction(ExecState* exec)
239{
240 VM& vm = exec->vm();
241 auto scope = DECLARE_THROW_SCOPE(vm);
242
243 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
244
245 JSObject* target = asObject(exec->uncheckedArgument(0));
246 JSValue boundThis = exec->uncheckedArgument(1);
247 JSValue boundArgs = exec->uncheckedArgument(2);
248 JSValue lengthValue = exec->uncheckedArgument(3);
249 JSString* nameString = asString(exec->uncheckedArgument(4));
250
251 ASSERT(lengthValue.isInt32AsAnyInt());
252 int32_t length = lengthValue.asInt32AsAnyInt();
253
254 String name = nameString->value(exec);
255 RETURN_IF_EXCEPTION(scope, { });
256
257 RELEASE_AND_RETURN(scope, JSValue::encode(JSBoundFunction::create(vm, exec, globalObject, target, boundThis, boundArgs.isCell() ? jsCast<JSArray*>(boundArgs) : nullptr, length, WTFMove(name))));
258}
259
260static EncodedJSValue JSC_HOST_CALL hasOwnLengthProperty(ExecState* exec)
261{
262 VM& vm = exec->vm();
263 JSObject* target = asObject(exec->uncheckedArgument(0));
264 return JSValue::encode(jsBoolean(target->hasOwnProperty(exec, vm.propertyNames->length)));
265}
266
267#if !ASSERT_DISABLED
268static EncodedJSValue JSC_HOST_CALL assertCall(ExecState* exec)
269{
270 RELEASE_ASSERT(exec->argument(0).isBoolean());
271 if (exec->argument(0).asBoolean())
272 return JSValue::encode(jsUndefined());
273
274 bool iteratedOnce = false;
275 CodeBlock* codeBlock = nullptr;
276 unsigned line;
277 exec->iterate([&] (StackVisitor& visitor) {
278 if (!iteratedOnce) {
279 iteratedOnce = true;
280 return StackVisitor::Continue;
281 }
282
283 RELEASE_ASSERT(visitor->hasLineAndColumnInfo());
284 unsigned column;
285 visitor->computeLineAndColumn(line, column);
286 codeBlock = visitor->codeBlock();
287 return StackVisitor::Done;
288 });
289 RELEASE_ASSERT(!!codeBlock);
290 RELEASE_ASSERT_WITH_MESSAGE(false, "JS assertion failed at line %u in:\n%s\n", line, codeBlock->sourceCodeForTools().data());
291 return JSValue::encode(jsUndefined());
292}
293#endif
294
295} // namespace JSC
296
297#include "JSGlobalObject.lut.h"
298
299namespace JSC {
300
301const ClassInfo JSGlobalObject::s_info = { "GlobalObject", &Base::s_info, &globalObjectTable, nullptr, CREATE_METHOD_TABLE(JSGlobalObject) };
302
303const GlobalObjectMethodTable JSGlobalObject::s_globalObjectMethodTable = {
304 &supportsRichSourceInfo,
305 &shouldInterruptScript,
306 &javaScriptRuntimeFlags,
307 nullptr, // queueTaskToEventLoop
308 &shouldInterruptScriptBeforeTimeout,
309 nullptr, // moduleLoaderImportModule
310 nullptr, // moduleLoaderResolve
311 nullptr, // moduleLoaderFetch
312 nullptr, // moduleLoaderCreateImportMetaProperties
313 nullptr, // moduleLoaderEvaluate
314 nullptr, // promiseRejectionTracker
315 nullptr, // defaultLanguage
316 nullptr, // compileStreaming
317 nullptr, // instantiateStreaming
318};
319
320/* Source for JSGlobalObject.lut.h
321@begin globalObjectTable
322 isNaN JSBuiltin DontEnum|Function 1
323 isFinite JSBuiltin DontEnum|Function 1
324 escape globalFuncEscape DontEnum|Function 1
325 unescape globalFuncUnescape DontEnum|Function 1
326 decodeURI globalFuncDecodeURI DontEnum|Function 1
327 decodeURIComponent globalFuncDecodeURIComponent DontEnum|Function 1
328 encodeURI globalFuncEncodeURI DontEnum|Function 1
329 encodeURIComponent globalFuncEncodeURIComponent DontEnum|Function 1
330 eval JSGlobalObject::m_evalFunction DontEnum|CellProperty
331 globalThis JSGlobalObject::m_globalThis DontEnum|CellProperty
332 parseInt JSGlobalObject::m_parseIntFunction DontEnum|CellProperty
333 parseFloat JSGlobalObject::m_parseFloatFunction DontEnum|CellProperty
334 ArrayBuffer JSGlobalObject::m_arrayBufferStructure DontEnum|ClassStructure
335 EvalError JSGlobalObject::m_evalErrorStructure DontEnum|ClassStructure
336 RangeError JSGlobalObject::m_rangeErrorStructure DontEnum|ClassStructure
337 ReferenceError JSGlobalObject::m_referenceErrorStructure DontEnum|ClassStructure
338 SyntaxError JSGlobalObject::m_syntaxErrorStructure DontEnum|ClassStructure
339 TypeError JSGlobalObject::m_typeErrorStructure DontEnum|ClassStructure
340 URIError JSGlobalObject::m_URIErrorStructure DontEnum|ClassStructure
341 Proxy createProxyProperty DontEnum|PropertyCallback
342 Reflect createReflectProperty DontEnum|PropertyCallback
343 JSON createJSONProperty DontEnum|PropertyCallback
344 Math createMathProperty DontEnum|PropertyCallback
345 console createConsoleProperty DontEnum|PropertyCallback
346 Int8Array JSGlobalObject::m_typedArrayInt8 DontEnum|ClassStructure
347 Int16Array JSGlobalObject::m_typedArrayInt16 DontEnum|ClassStructure
348 Int32Array JSGlobalObject::m_typedArrayInt32 DontEnum|ClassStructure
349 Uint8Array JSGlobalObject::m_typedArrayUint8 DontEnum|ClassStructure
350 Uint8ClampedArray JSGlobalObject::m_typedArrayUint8Clamped DontEnum|ClassStructure
351 Uint16Array JSGlobalObject::m_typedArrayUint16 DontEnum|ClassStructure
352 Uint32Array JSGlobalObject::m_typedArrayUint32 DontEnum|ClassStructure
353 Float32Array JSGlobalObject::m_typedArrayFloat32 DontEnum|ClassStructure
354 Float64Array JSGlobalObject::m_typedArrayFloat64 DontEnum|ClassStructure
355 DataView JSGlobalObject::m_typedArrayDataView DontEnum|ClassStructure
356 Date JSGlobalObject::m_dateStructure DontEnum|ClassStructure
357 Error JSGlobalObject::m_errorStructure DontEnum|ClassStructure
358 Boolean JSGlobalObject::m_booleanObjectStructure DontEnum|ClassStructure
359 Number JSGlobalObject::m_numberObjectStructure DontEnum|ClassStructure
360 Symbol JSGlobalObject::m_symbolObjectStructure DontEnum|ClassStructure
361 WeakMap JSGlobalObject::m_weakMapStructure DontEnum|ClassStructure
362 WeakSet JSGlobalObject::m_weakSetStructure DontEnum|ClassStructure
363@end
364*/
365
366static EncodedJSValue JSC_HOST_CALL enqueueJob(ExecState* exec)
367{
368 VM& vm = exec->vm();
369 JSGlobalObject* globalObject = exec->lexicalGlobalObject();
370
371 JSValue job = exec->argument(0);
372 JSValue arguments = exec->argument(1);
373 ASSERT(arguments.inherits<JSArray>(vm));
374
375 globalObject->queueMicrotask(createJSMicrotask(vm, job, jsCast<JSArray*>(arguments)));
376
377 return JSValue::encode(jsUndefined());
378}
379
380JSGlobalObject::JSGlobalObject(VM& vm, Structure* structure, const GlobalObjectMethodTable* globalObjectMethodTable)
381 : Base(vm, structure, 0)
382 , m_vm(vm)
383 , m_masqueradesAsUndefinedWatchpoint(adoptRef(new WatchpointSet(IsWatched)))
384 , m_havingABadTimeWatchpoint(adoptRef(new WatchpointSet(IsWatched)))
385 , m_varInjectionWatchpoint(adoptRef(new WatchpointSet(IsWatched)))
386 , m_weakRandom(Options::forceWeakRandomSeed() ? Options::forcedWeakRandomSeed() : static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
387 , m_arrayIteratorProtocolWatchpoint(IsWatched)
388 , m_mapIteratorProtocolWatchpoint(IsWatched)
389 , m_setIteratorProtocolWatchpoint(IsWatched)
390 , m_stringIteratorProtocolWatchpoint(IsWatched)
391 , m_mapSetWatchpoint(IsWatched)
392 , m_setAddWatchpoint(IsWatched)
393 , m_arraySpeciesWatchpoint(ClearWatchpoint)
394 , m_numberToStringWatchpoint(IsWatched)
395 , m_runtimeFlags()
396 , m_stackTraceLimit(Options::defaultErrorStackTraceLimit())
397 , m_globalObjectMethodTable(globalObjectMethodTable ? globalObjectMethodTable : &s_globalObjectMethodTable)
398{
399}
400
401JSGlobalObject::~JSGlobalObject()
402{
403#if ENABLE(REMOTE_INSPECTOR)
404 m_inspectorController->globalObjectDestroyed();
405#endif
406
407 if (m_debugger)
408 m_debugger->detach(this, Debugger::GlobalObjectIsDestructing);
409}
410
411void JSGlobalObject::destroy(JSCell* cell)
412{
413 static_cast<JSGlobalObject*>(cell)->JSGlobalObject::~JSGlobalObject();
414}
415
416void JSGlobalObject::setGlobalThis(VM& vm, JSObject* globalThis)
417{
418 m_globalThis.set(vm, this, globalThis);
419}
420
421static JSObject* getGetterById(ExecState* exec, JSObject* base, const Identifier& ident)
422{
423 JSValue baseValue = JSValue(base);
424 PropertySlot slot(baseValue, PropertySlot::InternalMethodType::VMInquiry);
425 baseValue.getPropertySlot(exec, ident, slot);
426 return slot.getPureResult().toObject(exec);
427}
428
429template<ErrorType errorType>
430void JSGlobalObject::initializeErrorConstructor(LazyClassStructure::Initializer& init)
431{
432 init.setPrototype(NativeErrorPrototype::create(init.vm, NativeErrorPrototype::createStructure(init.vm, this, m_errorStructure.prototype(this)), errorTypeName(errorType)));
433 init.setStructure(ErrorInstance::createStructure(init.vm, this, init.prototype));
434 init.setConstructor(NativeErrorConstructor<errorType>::create(init.vm, NativeErrorConstructor<errorType>::createStructure(init.vm, this, m_errorStructure.constructor(this)), jsCast<NativeErrorPrototype*>(init.prototype)));
435}
436
437void JSGlobalObject::init(VM& vm)
438{
439 ASSERT(vm.currentThreadIsHoldingAPILock());
440 auto catchScope = DECLARE_CATCH_SCOPE(vm);
441
442 Base::setStructure(vm, Structure::toCacheableDictionaryTransition(vm, structure(vm)));
443
444 m_debugger = 0;
445
446#if ENABLE(REMOTE_INSPECTOR)
447 m_inspectorController = std::make_unique<Inspector::JSGlobalObjectInspectorController>(*this);
448 m_inspectorDebuggable = std::make_unique<JSGlobalObjectDebuggable>(*this);
449 m_inspectorDebuggable->init();
450 m_consoleClient = m_inspectorController->consoleClient();
451#endif
452
453 m_functionPrototype.set(vm, this, FunctionPrototype::create(vm, FunctionPrototype::createStructure(vm, this, jsNull()))); // The real prototype will be set once ObjectPrototype is created.
454 m_calleeStructure.set(vm, this, JSCallee::createStructure(vm, this, jsNull()));
455
456 m_globalLexicalEnvironment.set(vm, this, JSGlobalLexicalEnvironment::create(vm, JSGlobalLexicalEnvironment::createStructure(vm, this), this));
457 // Need to create the callee structure (above) before creating the callee.
458 JSCallee* globalCallee = JSCallee::create(vm, this, globalScope());
459 m_globalCallee.set(vm, this, globalCallee);
460
461 ExecState::initGlobalExec(JSGlobalObject::globalExec(), globalCallee);
462 ExecState* exec = JSGlobalObject::globalExec();
463
464 JSCallee* stackOverflowFrameCallee = JSCallee::create(vm, this, globalScope());
465 m_stackOverflowFrameCallee.set(vm, this, stackOverflowFrameCallee);
466
467 m_hostFunctionStructure.set(vm, this, JSFunction::createStructure(vm, this, m_functionPrototype.get()));
468
469 auto initFunctionStructures = [&] (FunctionStructures& structures) {
470 structures.strictFunctionStructure.set(vm, this, JSFunction::createStructure(vm, this, m_functionPrototype.get()));
471 structures.sloppyFunctionStructure.set(vm, this, JSFunction::createStructure(vm, this, m_functionPrototype.get()));
472 structures.arrowFunctionStructure.set(vm, this, JSFunction::createStructure(vm, this, m_functionPrototype.get()));
473 };
474 initFunctionStructures(m_builtinFunctions);
475 initFunctionStructures(m_ordinaryFunctions);
476
477 m_customGetterSetterFunctionStructure.initLater(
478 [] (const Initializer<Structure>& init) {
479 init.set(JSCustomGetterSetterFunction::createStructure(init.vm, init.owner, init.owner->m_functionPrototype.get()));
480 });
481 m_boundFunctionStructure.initLater(
482 [] (const Initializer<Structure>& init) {
483 init.set(JSBoundFunction::createStructure(init.vm, init.owner, init.owner->m_functionPrototype.get()));
484 });
485 m_getterSetterStructure.set(vm, this, GetterSetter::createStructure(vm, this, jsNull()));
486 m_nativeStdFunctionStructure.initLater(
487 [] (const Initializer<Structure>& init) {
488 init.set(JSNativeStdFunction::createStructure(init.vm, init.owner, init.owner->m_functionPrototype.get()));
489 });
490 JSFunction* callFunction = nullptr;
491 JSFunction* applyFunction = nullptr;
492 JSFunction* hasInstanceSymbolFunction = nullptr;
493 m_functionPrototype->addFunctionProperties(vm, this, &callFunction, &applyFunction, &hasInstanceSymbolFunction);
494 m_callFunction.set(vm, this, callFunction);
495 m_applyFunction.set(vm, this, applyFunction);
496 m_arrayProtoToStringFunction.initLater(
497 [] (const Initializer<JSFunction>& init) {
498 init.set(JSFunction::create(init.vm, init.owner, 0, init.vm.propertyNames->toString.string(), arrayProtoFuncToString, NoIntrinsic));
499 });
500 m_arrayProtoValuesFunction.initLater(
501 [] (const Initializer<JSFunction>& init) {
502 init.set(JSFunction::create(init.vm, arrayPrototypeValuesCodeGenerator(init.vm), init.owner));
503 });
504 m_initializePromiseFunction.initLater(
505 [] (const Initializer<JSFunction>& init) {
506 init.set(JSFunction::create(init.vm, promiseOperationsInitializePromiseCodeGenerator(init.vm), init.owner));
507 });
508
509 m_iteratorProtocolFunction.initLater(
510 [] (const Initializer<JSFunction>& init) {
511 init.set(JSFunction::create(init.vm, iteratorHelpersPerformIterationCodeGenerator(init.vm), init.owner));
512 });
513
514 m_promiseResolveFunction.initLater(
515 [] (const Initializer<JSFunction>& init) {
516 init.set(JSFunction::create(init.vm, promiseConstructorResolveCodeGenerator(init.vm), init.owner));
517 });
518
519 m_newPromiseCapabilityFunction.set(vm, this, JSFunction::create(vm, promiseOperationsNewPromiseCapabilityCodeGenerator(vm), this));
520 m_functionProtoHasInstanceSymbolFunction.set(vm, this, hasInstanceSymbolFunction);
521 m_throwTypeErrorGetterSetter.initLater(
522 [] (const Initializer<GetterSetter>& init) {
523 JSFunction* thrower = init.owner->throwTypeErrorFunction();
524 GetterSetter* getterSetter = GetterSetter::create(init.vm, init.owner, thrower, thrower);
525 init.set(getterSetter);
526 });
527
528 m_nullGetterFunction.set(vm, this, NullGetterFunction::create(vm, NullGetterFunction::createStructure(vm, this, m_functionPrototype.get())));
529 m_nullSetterFunction.set(vm, this, NullSetterFunction::create(vm, NullSetterFunction::createStructure(vm, this, m_functionPrototype.get())));
530 m_objectPrototype.set(vm, this, ObjectPrototype::create(vm, this, ObjectPrototype::createStructure(vm, this, jsNull())));
531 GetterSetter* protoAccessor = GetterSetter::create(vm, this,
532 JSFunction::create(vm, this, 0, makeString("get ", vm.propertyNames->underscoreProto.string()), globalFuncProtoGetter, UnderscoreProtoIntrinsic),
533 JSFunction::create(vm, this, 0, makeString("set ", vm.propertyNames->underscoreProto.string()), globalFuncProtoSetter));
534 m_objectPrototype->putDirectNonIndexAccessorWithoutTransition(vm, vm.propertyNames->underscoreProto, protoAccessor, PropertyAttribute::Accessor | PropertyAttribute::DontEnum);
535 m_functionPrototype->structure(vm)->setPrototypeWithoutTransition(vm, m_objectPrototype.get());
536 m_objectStructureForObjectConstructor.set(vm, this, vm.structureCache.emptyObjectStructureForPrototype(this, m_objectPrototype.get(), JSFinalObject::defaultInlineCapacity()));
537 m_objectProtoValueOfFunction.set(vm, this, jsCast<JSFunction*>(objectPrototype()->getDirect(vm, vm.propertyNames->valueOf)));
538
539 JSFunction* thrower = JSFunction::create(vm, this, 0, String(), globalFuncThrowTypeErrorArgumentsCalleeAndCaller);
540 GetterSetter* getterSetter = GetterSetter::create(vm, this, thrower, thrower);
541 m_throwTypeErrorArgumentsCalleeAndCallerGetterSetter.set(vm, this, getterSetter);
542
543 m_functionPrototype->initRestrictedProperties(vm, this);
544
545 m_speciesGetterSetter.set(vm, this, GetterSetter::create(vm, this, JSFunction::create(vm, globalOperationsSpeciesGetterCodeGenerator(vm), this), nullptr));
546
547 m_typedArrayProto.initLater(
548 [] (const Initializer<JSTypedArrayViewPrototype>& init) {
549 init.set(JSTypedArrayViewPrototype::create(init.vm, init.owner, JSTypedArrayViewPrototype::createStructure(init.vm, init.owner, init.owner->m_objectPrototype.get())));
550
551 // Make sure that the constructor gets initialized, too.
552 init.owner->m_typedArraySuperConstructor.get(init.owner);
553 });
554 m_typedArraySuperConstructor.initLater(
555 [] (const Initializer<JSTypedArrayViewConstructor>& init) {
556 JSTypedArrayViewPrototype* prototype = init.owner->m_typedArrayProto.get(init.owner);
557 JSTypedArrayViewConstructor* constructor = JSTypedArrayViewConstructor::create(init.vm, init.owner, JSTypedArrayViewConstructor::createStructure(init.vm, init.owner, init.owner->m_functionPrototype.get()), prototype, init.owner->m_speciesGetterSetter.get());
558 prototype->putDirectWithoutTransition(init.vm, init.vm.propertyNames->constructor, constructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
559 init.set(constructor);
560 });
561
562#define INIT_TYPED_ARRAY_LATER(type) \
563 m_typedArray ## type.initLater( \
564 [] (LazyClassStructure::Initializer& init) { \
565 init.setPrototype(JS ## type ## ArrayPrototype::create(init.vm, init.global, JS ## type ## ArrayPrototype::createStructure(init.vm, init.global, init.global->m_typedArrayProto.get(init.global)))); \
566 init.setStructure(JS ## type ## Array::createStructure(init.vm, init.global, init.prototype)); \
567 init.setConstructor(JS ## type ## ArrayConstructor::create(init.vm, init.global, JS ## type ## ArrayConstructor::createStructure(init.vm, init.global, init.global->m_typedArraySuperConstructor.get(init.global)), init.prototype, #type "Array"_s, typedArrayConstructorAllocate ## type ## ArrayCodeGenerator(init.vm))); \
568 init.global->putDirectWithoutTransition(init.vm, init.vm.propertyNames->builtinNames().type ## ArrayPrivateName(), init.constructor, static_cast<unsigned>(PropertyAttribute::DontEnum)); \
569 });
570 FOR_EACH_TYPED_ARRAY_TYPE_EXCLUDING_DATA_VIEW(INIT_TYPED_ARRAY_LATER)
571#undef INIT_TYPED_ARRAY_LATER
572
573 m_typedArrayDataView.initLater(
574 [] (LazyClassStructure::Initializer& init) {
575 init.setPrototype(JSDataViewPrototype::create(init.vm, JSDataViewPrototype::createStructure(init.vm, init.global, init.global->m_objectPrototype.get())));
576 init.setStructure(JSDataView::createStructure(init.vm, init.global, init.prototype));
577 init.setConstructor(JSDataViewConstructor::create(init.vm, init.global, JSDataViewConstructor::createStructure(init.vm, init.global, init.global->m_functionPrototype.get()), init.prototype, "DataView"_s, nullptr));
578 });
579
580 m_lexicalEnvironmentStructure.set(vm, this, JSLexicalEnvironment::createStructure(vm, this));
581 m_moduleEnvironmentStructure.initLater(
582 [] (const Initializer<Structure>& init) {
583 init.set(JSModuleEnvironment::createStructure(init.vm, init.owner));
584 });
585 m_strictEvalActivationStructure.initLater(
586 [] (const Initializer<Structure>& init) {
587 init.set(StrictEvalActivation::createStructure(init.vm, init.owner, jsNull()));
588 });
589 m_debuggerScopeStructure.initLater(
590 [] (const Initializer<Structure>& init) {
591 init.set(DebuggerScope::createStructure(init.vm, init.owner));
592 });
593 m_withScopeStructure.initLater(
594 [] (const Initializer<Structure>& init) {
595 init.set(JSWithScope::createStructure(init.vm, init.owner, jsNull()));
596 });
597
598 m_nullPrototypeObjectStructure.set(vm, this, JSFinalObject::createStructure(vm, this, jsNull(), JSFinalObject::defaultInlineCapacity()));
599
600 m_callbackFunctionStructure.initLater(
601 [] (const Initializer<Structure>& init) {
602 init.set(JSCallbackFunction::createStructure(init.vm, init.owner, init.owner->m_functionPrototype.get()));
603 });
604 m_directArgumentsStructure.set(vm, this, DirectArguments::createStructure(vm, this, m_objectPrototype.get()));
605 m_scopedArgumentsStructure.set(vm, this, ScopedArguments::createStructure(vm, this, m_objectPrototype.get()));
606 m_clonedArgumentsStructure.set(vm, this, ClonedArguments::createStructure(vm, this, m_objectPrototype.get()));
607 m_callbackConstructorStructure.initLater(
608 [] (const Initializer<Structure>& init) {
609 init.set(JSCallbackConstructor::createStructure(init.vm, init.owner, init.owner->m_objectPrototype.get()));
610 });
611 m_callbackObjectStructure.initLater(
612 [] (const Initializer<Structure>& init) {
613 init.set(JSCallbackObject<JSDestructibleObject>::createStructure(init.vm, init.owner, init.owner->m_objectPrototype.get()));
614 });
615
616#if JSC_OBJC_API_ENABLED
617 m_objcCallbackFunctionStructure.initLater(
618 [] (const Initializer<Structure>& init) {
619 init.set(ObjCCallbackFunction::createStructure(init.vm, init.owner, init.owner->m_functionPrototype.get()));
620 });
621 m_objcWrapperObjectStructure.initLater(
622 [] (const Initializer<Structure>& init) {
623 init.set(JSCallbackObject<JSAPIWrapperObject>::createStructure(init.vm, init.owner, init.owner->m_objectPrototype.get()));
624 });
625#endif
626#ifdef JSC_GLIB_API_ENABLED
627 m_glibCallbackFunctionStructure.initLater(
628 [] (const Initializer<Structure>& init) {
629 init.set(JSCCallbackFunction::createStructure(init.vm, init.owner, init.owner->m_functionPrototype.get()));
630 });
631 m_glibWrapperObjectStructure.initLater(
632 [] (const Initializer<Structure>& init) {
633 init.set(JSCallbackObject<JSAPIWrapperObject>::createStructure(init.vm, init.owner, init.owner->m_objectPrototype.get()));
634 });
635#endif
636 m_arrayPrototype.set(vm, this, ArrayPrototype::create(vm, this, ArrayPrototype::createStructure(vm, this, m_objectPrototype.get())));
637
638 m_originalArrayStructureForIndexingShape[arrayIndexFromIndexingType(UndecidedShape)].set(vm, this, JSArray::createStructure(vm, this, m_arrayPrototype.get(), ArrayWithUndecided));
639 m_originalArrayStructureForIndexingShape[arrayIndexFromIndexingType(Int32Shape)].set(vm, this, JSArray::createStructure(vm, this, m_arrayPrototype.get(), ArrayWithInt32));
640 m_originalArrayStructureForIndexingShape[arrayIndexFromIndexingType(DoubleShape)].set(vm, this, JSArray::createStructure(vm, this, m_arrayPrototype.get(), ArrayWithDouble));
641 m_originalArrayStructureForIndexingShape[arrayIndexFromIndexingType(ContiguousShape)].set(vm, this, JSArray::createStructure(vm, this, m_arrayPrototype.get(), ArrayWithContiguous));
642 m_originalArrayStructureForIndexingShape[arrayIndexFromIndexingType(ArrayStorageShape)].set(vm, this, JSArray::createStructure(vm, this, m_arrayPrototype.get(), ArrayWithArrayStorage));
643 m_originalArrayStructureForIndexingShape[arrayIndexFromIndexingType(SlowPutArrayStorageShape)].set(vm, this, JSArray::createStructure(vm, this, m_arrayPrototype.get(), ArrayWithSlowPutArrayStorage));
644 m_originalArrayStructureForIndexingShape[arrayIndexFromIndexingType(CopyOnWriteArrayWithInt32)].set(vm, this, JSArray::createStructure(vm, this, m_arrayPrototype.get(), CopyOnWriteArrayWithInt32));
645 m_originalArrayStructureForIndexingShape[arrayIndexFromIndexingType(CopyOnWriteArrayWithDouble)].set(vm, this, JSArray::createStructure(vm, this, m_arrayPrototype.get(), CopyOnWriteArrayWithDouble));
646 m_originalArrayStructureForIndexingShape[arrayIndexFromIndexingType(CopyOnWriteArrayWithContiguous)].set(vm, this, JSArray::createStructure(vm, this, m_arrayPrototype.get(), CopyOnWriteArrayWithContiguous));
647 for (unsigned i = 0; i < NumberOfArrayIndexingModes; ++i)
648 m_arrayStructureForIndexingShapeDuringAllocation[i] = m_originalArrayStructureForIndexingShape[i];
649
650 m_regExpPrototype.set(vm, this, RegExpPrototype::create(vm, this, RegExpPrototype::createStructure(vm, this, m_objectPrototype.get())));
651 m_regExpStructure.set(vm, this, RegExpObject::createStructure(vm, this, m_regExpPrototype.get()));
652 m_regExpMatchesArrayStructure.set(vm, this, createRegExpMatchesArrayStructure(vm, this));
653 m_regExpMatchesArrayWithGroupsStructure.set(vm, this, createRegExpMatchesArrayWithGroupsStructure(vm, this));
654
655 m_moduleRecordStructure.initLater(
656 [] (const Initializer<Structure>& init) {
657 init.set(JSModuleRecord::createStructure(init.vm, init.owner, jsNull()));
658 });
659 m_moduleNamespaceObjectStructure.initLater(
660 [] (const Initializer<Structure>& init) {
661 init.set(JSModuleNamespaceObject::createStructure(init.vm, init.owner, jsNull()));
662 });
663 m_proxyObjectStructure.initLater(
664 [] (const Initializer<Structure>& init) {
665 bool isCallable = false;
666 init.set(ProxyObject::createStructure(init.vm, init.owner, jsNull(), isCallable));
667 });
668 m_callableProxyObjectStructure.initLater(
669 [] (const Initializer<Structure>& init) {
670 bool isCallable = true;
671 init.set(ProxyObject::createStructure(init.vm, init.owner, jsNull(), isCallable));
672 });
673 m_proxyRevokeStructure.initLater(
674 [] (const Initializer<Structure>& init) {
675 init.set(ProxyRevoke::createStructure(init.vm, init.owner, init.owner->m_functionPrototype.get()));
676 });
677
678 m_parseIntFunction.initLater(
679 [] (const Initializer<JSFunction>& init) {
680 init.set(JSFunction::create(init.vm, init.owner, 2, init.vm.propertyNames->parseInt.string(), globalFuncParseInt, ParseIntIntrinsic));
681 });
682 m_parseFloatFunction.initLater(
683 [] (const Initializer<JSFunction>& init) {
684 init.set(JSFunction::create(init.vm, init.owner, 1, init.vm.propertyNames->parseFloat.string(), globalFuncParseFloat, NoIntrinsic));
685 });
686
687#if ENABLE(SHARED_ARRAY_BUFFER)
688 m_sharedArrayBufferPrototype.set(vm, this, JSArrayBufferPrototype::create(vm, this, JSArrayBufferPrototype::createStructure(vm, this, m_objectPrototype.get()), ArrayBufferSharingMode::Shared));
689 m_sharedArrayBufferStructure.set(vm, this, JSArrayBuffer::createStructure(vm, this, m_sharedArrayBufferPrototype.get()));
690#endif
691
692 m_iteratorPrototype.set(vm, this, IteratorPrototype::create(vm, this, IteratorPrototype::createStructure(vm, this, m_objectPrototype.get())));
693 m_asyncIteratorPrototype.set(vm, this, AsyncIteratorPrototype::create(vm, this, AsyncIteratorPrototype::createStructure(vm, this, m_objectPrototype.get())));
694
695 m_generatorPrototype.set(vm, this, GeneratorPrototype::create(vm, this, GeneratorPrototype::createStructure(vm, this, m_iteratorPrototype.get())));
696 m_asyncGeneratorPrototype.set(vm, this, AsyncGeneratorPrototype::create(vm, this, AsyncGeneratorPrototype::createStructure(vm, this, m_asyncIteratorPrototype.get())));
697
698#define CREATE_PROTOTYPE_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase) do { \
699 m_ ## lowerName ## Prototype.set(vm, this, capitalName##Prototype::create(vm, this, capitalName##Prototype::createStructure(vm, this, m_ ## prototypeBase ## Prototype.get()))); \
700 m_ ## properName ## Structure.set(vm, this, instanceType::createStructure(vm, this, m_ ## lowerName ## Prototype.get())); \
701 } while (0);
702
703 FOR_EACH_SIMPLE_BUILTIN_TYPE(CREATE_PROTOTYPE_FOR_SIMPLE_TYPE)
704
705 if (UNLIKELY(Options::useBigInt()))
706 FOR_BIG_INT_BUILTIN_TYPE_WITH_CONSTRUCTOR(CREATE_PROTOTYPE_FOR_SIMPLE_TYPE)
707
708 FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(CREATE_PROTOTYPE_FOR_SIMPLE_TYPE)
709
710#undef CREATE_PROTOTYPE_FOR_SIMPLE_TYPE
711
712#define CREATE_PROTOTYPE_FOR_LAZY_TYPE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase) \
713 m_ ## properName ## Structure.initLater(\
714 [] (LazyClassStructure::Initializer& init) { \
715 init.setPrototype(capitalName##Prototype::create(init.vm, init.global, capitalName##Prototype::createStructure(init.vm, init.global, init.global->m_ ## prototypeBase ## Prototype.get()))); \
716 init.setStructure(instanceType::createStructure(init.vm, init.global, init.prototype)); \
717 init.setConstructor(capitalName ## Constructor::create(init.vm, capitalName ## Constructor::createStructure(init.vm, init.global, init.global->m_functionPrototype.get()), jsCast<capitalName ## Prototype*>(init.prototype), init.global->m_speciesGetterSetter.get())); \
718 });
719
720 FOR_EACH_LAZY_BUILTIN_TYPE(CREATE_PROTOTYPE_FOR_LAZY_TYPE)
721
722 // Constructors
723
724 ObjectConstructor* objectConstructor = ObjectConstructor::create(vm, this, ObjectConstructor::createStructure(vm, this, m_functionPrototype.get()), m_objectPrototype.get());
725 m_objectConstructor.set(vm, this, objectConstructor);
726
727 JSFunction* throwTypeErrorFunction = JSFunction::create(vm, this, 0, String(), globalFuncThrowTypeError);
728 m_throwTypeErrorFunction.set(vm, this, throwTypeErrorFunction);
729
730 JSCell* functionConstructor = FunctionConstructor::create(vm, FunctionConstructor::createStructure(vm, this, m_functionPrototype.get()), m_functionPrototype.get());
731
732 ArrayConstructor* arrayConstructor = ArrayConstructor::create(vm, this, ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_arrayPrototype.get(), m_speciesGetterSetter.get());
733 m_arrayConstructor.set(vm, this, arrayConstructor);
734
735 RegExpConstructor* regExpConstructor = RegExpConstructor::create(vm, RegExpConstructor::createStructure(vm, this, m_functionPrototype.get()), m_regExpPrototype.get(), m_speciesGetterSetter.get());
736 m_regExpGlobalData.cachedResult().record(vm, this, nullptr, jsEmptyString(&vm), MatchResult(0, 0));
737
738#if ENABLE(SHARED_ARRAY_BUFFER)
739 JSSharedArrayBufferConstructor* sharedArrayBufferConstructor = nullptr;
740 sharedArrayBufferConstructor = JSSharedArrayBufferConstructor::create(vm, JSSharedArrayBufferConstructor::createStructure(vm, this, m_functionPrototype.get()), m_sharedArrayBufferPrototype.get(), m_speciesGetterSetter.get());
741 m_sharedArrayBufferPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, sharedArrayBufferConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
742
743 AtomicsObject* atomicsObject = AtomicsObject::create(vm, this, AtomicsObject::createStructure(vm, this, m_objectPrototype.get()));
744#endif
745
746#define CREATE_CONSTRUCTOR_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase) \
747capitalName ## Constructor* lowerName ## Constructor = capitalName ## Constructor::create(vm, capitalName ## Constructor::createStructure(vm, this, m_functionPrototype.get()), m_ ## lowerName ## Prototype.get(), m_speciesGetterSetter.get()); \
748m_ ## lowerName ## Prototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, lowerName ## Constructor, static_cast<unsigned>(PropertyAttribute::DontEnum)); \
749
750 FOR_EACH_SIMPLE_BUILTIN_TYPE(CREATE_CONSTRUCTOR_FOR_SIMPLE_TYPE)
751 BigIntConstructor* bigIntConstructor = nullptr;
752 if (UNLIKELY(Options::useBigInt())) {
753 bigIntConstructor = BigIntConstructor::create(vm, BigIntConstructor::createStructure(vm, this, m_functionPrototype.get()), m_bigIntPrototype.get(), m_speciesGetterSetter.get());
754 m_bigIntPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, bigIntConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
755 }
756
757#undef CREATE_CONSTRUCTOR_FOR_SIMPLE_TYPE
758
759 m_promiseConstructor.set(vm, this, promiseConstructor);
760 m_internalPromiseConstructor.set(vm, this, internalPromiseConstructor);
761
762 m_evalErrorStructure.initLater(
763 [] (LazyClassStructure::Initializer& init) {
764 init.global->initializeErrorConstructor<ErrorType::EvalError>(init);
765 });
766 m_rangeErrorStructure.initLater(
767 [] (LazyClassStructure::Initializer& init) {
768 init.global->initializeErrorConstructor<ErrorType::RangeError>(init);
769 });
770 m_referenceErrorStructure.initLater(
771 [] (LazyClassStructure::Initializer& init) {
772 init.global->initializeErrorConstructor<ErrorType::ReferenceError>(init);
773 });
774 m_syntaxErrorStructure.initLater(
775 [] (LazyClassStructure::Initializer& init) {
776 init.global->initializeErrorConstructor<ErrorType::SyntaxError>(init);
777 });
778 m_typeErrorStructure.initLater(
779 [] (LazyClassStructure::Initializer& init) {
780 init.global->initializeErrorConstructor<ErrorType::TypeError>(init);
781 });
782 m_URIErrorStructure.initLater(
783 [] (LazyClassStructure::Initializer& init) {
784 init.global->initializeErrorConstructor<ErrorType::URIError>(init);
785 });
786
787 m_generatorFunctionPrototype.set(vm, this, GeneratorFunctionPrototype::create(vm, GeneratorFunctionPrototype::createStructure(vm, this, m_functionPrototype.get())));
788 GeneratorFunctionConstructor* generatorFunctionConstructor = GeneratorFunctionConstructor::create(vm, GeneratorFunctionConstructor::createStructure(vm, this, functionConstructor), m_generatorFunctionPrototype.get());
789 m_generatorFunctionPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, generatorFunctionConstructor, PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
790 m_generatorFunctionStructure.set(vm, this, JSGeneratorFunction::createStructure(vm, this, m_generatorFunctionPrototype.get()));
791
792 m_generatorPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, m_generatorFunctionPrototype.get(), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
793 m_generatorFunctionPrototype->putDirectWithoutTransition(vm, vm.propertyNames->prototype, m_generatorPrototype.get(), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
794
795 m_asyncFunctionPrototype.set(vm, this, AsyncFunctionPrototype::create(vm, AsyncFunctionPrototype::createStructure(vm, this, m_functionPrototype.get())));
796 AsyncFunctionConstructor* asyncFunctionConstructor = AsyncFunctionConstructor::create(vm, AsyncFunctionConstructor::createStructure(vm, this, functionConstructor), m_asyncFunctionPrototype.get());
797 m_asyncFunctionPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, asyncFunctionConstructor, PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
798 m_asyncFunctionStructure.set(vm, this, JSAsyncFunction::createStructure(vm, this, m_asyncFunctionPrototype.get()));
799
800 m_asyncGeneratorFunctionPrototype.set(vm, this, AsyncGeneratorFunctionPrototype::create(vm, AsyncGeneratorFunctionPrototype::createStructure(vm, this, m_functionPrototype.get())));
801 AsyncGeneratorFunctionConstructor* asyncGeneratorFunctionConstructor = AsyncGeneratorFunctionConstructor::create(vm, AsyncGeneratorFunctionConstructor::createStructure(vm, this, functionConstructor), m_asyncGeneratorFunctionPrototype.get());
802 m_asyncGeneratorFunctionPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, asyncGeneratorFunctionConstructor, PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
803 m_asyncGeneratorFunctionStructure.set(vm, this, JSAsyncGeneratorFunction::createStructure(vm, this, m_asyncGeneratorFunctionPrototype.get()));
804
805 m_asyncGeneratorPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, m_asyncGeneratorFunctionPrototype.get(), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
806 m_asyncGeneratorFunctionPrototype->putDirectWithoutTransition(vm, vm.propertyNames->prototype, m_asyncGeneratorPrototype.get(), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
807
808 m_objectPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, objectConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
809 m_functionPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, functionConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
810 m_arrayPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, arrayConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
811 m_regExpPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, regExpConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
812
813 putDirectWithoutTransition(vm, vm.propertyNames->Object, objectConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
814 putDirectWithoutTransition(vm, vm.propertyNames->Function, functionConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
815 putDirectWithoutTransition(vm, vm.propertyNames->Array, arrayConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
816 putDirectWithoutTransition(vm, vm.propertyNames->RegExp, regExpConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
817
818 putDirectWithoutTransition(vm, vm.propertyNames->builtinNames().ObjectPrivateName(), objectConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
819 putDirectWithoutTransition(vm, vm.propertyNames->builtinNames().ArrayPrivateName(), arrayConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
820
821#if ENABLE(SHARED_ARRAY_BUFFER)
822 putDirectWithoutTransition(vm, vm.propertyNames->SharedArrayBuffer, sharedArrayBufferConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
823 putDirectWithoutTransition(vm, Identifier::fromString(exec, "Atomics"), atomicsObject, static_cast<unsigned>(PropertyAttribute::DontEnum));
824#endif
825
826#define PUT_CONSTRUCTOR_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase) \
827putDirectWithoutTransition(vm, vm.propertyNames-> jsName, lowerName ## Constructor, static_cast<unsigned>(PropertyAttribute::DontEnum)); \
828
829 FOR_EACH_SIMPLE_BUILTIN_TYPE_WITH_CONSTRUCTOR(PUT_CONSTRUCTOR_FOR_SIMPLE_TYPE)
830 if (UNLIKELY(Options::useBigInt()))
831 FOR_BIG_INT_BUILTIN_TYPE_WITH_CONSTRUCTOR(PUT_CONSTRUCTOR_FOR_SIMPLE_TYPE)
832
833#undef PUT_CONSTRUCTOR_FOR_SIMPLE_TYPE
834 m_iteratorResultObjectStructure.initLater(
835 [] (const Initializer<Structure>& init) {
836 init.set(createIteratorResultObjectStructure(init.vm, *init.owner));
837 });
838
839 m_evalFunction.initLater(
840 [] (const Initializer<JSFunction>& init) {
841 init.set(JSFunction::create(init.vm, init.owner, 1, init.vm.propertyNames->eval.string(), globalFuncEval, NoIntrinsic));
842 });
843
844#if ENABLE(INTL)
845 m_collatorStructure.initLater(
846 [] (const Initializer<Structure>& init) {
847 JSGlobalObject* globalObject = jsCast<JSGlobalObject*>(init.owner);
848 IntlCollatorPrototype* collatorPrototype = IntlCollatorPrototype::create(init.vm, globalObject, IntlCollatorPrototype::createStructure(init.vm, globalObject, globalObject->objectPrototype()));
849 init.set(IntlCollator::createStructure(init.vm, globalObject, collatorPrototype));
850 });
851 m_numberFormatStructure.initLater(
852 [] (const Initializer<Structure>& init) {
853 JSGlobalObject* globalObject = jsCast<JSGlobalObject*>(init.owner);
854 IntlNumberFormatPrototype* numberFormatPrototype = IntlNumberFormatPrototype::create(init.vm, globalObject, IntlNumberFormatPrototype::createStructure(init.vm, globalObject, globalObject->objectPrototype()));
855 init.set(IntlNumberFormat::createStructure(init.vm, globalObject, numberFormatPrototype));
856 });
857 m_dateTimeFormatStructure.initLater(
858 [] (const Initializer<Structure>& init) {
859 JSGlobalObject* globalObject = jsCast<JSGlobalObject*>(init.owner);
860 IntlDateTimeFormatPrototype* dateTimeFormatPrototype = IntlDateTimeFormatPrototype::create(init.vm, globalObject, IntlDateTimeFormatPrototype::createStructure(init.vm, globalObject, globalObject->objectPrototype()));
861 init.set(IntlDateTimeFormat::createStructure(init.vm, globalObject, dateTimeFormatPrototype));
862 });
863 m_pluralRulesStructure.initLater(
864 [] (const Initializer<Structure>& init) {
865 JSGlobalObject* globalObject = jsCast<JSGlobalObject*>(init.owner);
866 IntlPluralRulesPrototype* pluralRulesPrototype = IntlPluralRulesPrototype::create(init.vm, globalObject, IntlPluralRulesPrototype::createStructure(init.vm, globalObject, globalObject->objectPrototype()));
867 init.set(IntlPluralRules::createStructure(init.vm, globalObject, pluralRulesPrototype));
868 });
869
870 IntlObject* intl = IntlObject::create(vm, IntlObject::createStructure(vm, this, m_objectPrototype.get()));
871 putDirectWithoutTransition(vm, vm.propertyNames->Intl, intl, static_cast<unsigned>(PropertyAttribute::DontEnum));
872#endif // ENABLE(INTL)
873
874 m_moduleLoader.initLater(
875 [] (const Initializer<JSModuleLoader>& init) {
876 auto catchScope = DECLARE_CATCH_SCOPE(init.vm);
877 init.set(JSModuleLoader::create(init.owner->globalExec(), init.vm, init.owner, JSModuleLoader::createStructure(init.vm, init.owner, jsNull())));
878 catchScope.releaseAssertNoException();
879 });
880 if (Options::exposeInternalModuleLoader())
881 putDirectWithoutTransition(vm, vm.propertyNames->Loader, moduleLoader(), static_cast<unsigned>(PropertyAttribute::DontEnum));
882
883 JSFunction* builtinLog = JSFunction::create(vm, this, 1, vm.propertyNames->emptyIdentifier.string(), globalFuncBuiltinLog);
884 JSFunction* builtinDescribe = JSFunction::create(vm, this, 1, vm.propertyNames->emptyIdentifier.string(), globalFuncBuiltinDescribe);
885
886 JSFunction* privateFuncTrunc = JSFunction::create(vm, this, 0, String(), mathProtoFuncTrunc, TruncIntrinsic);
887
888 JSFunction* privateFuncPropertyIsEnumerable = JSFunction::create(vm, this, 0, String(), globalFuncPropertyIsEnumerable);
889 JSFunction* privateFuncOwnKeys = JSFunction::create(vm, this, 0, String(), globalFuncOwnKeys);
890 JSFunction* privateFuncImportModule = JSFunction::create(vm, this, 0, String(), globalFuncImportModule);
891 JSFunction* privateFuncMakeTypeError = JSFunction::create(vm, this, 0, String(), globalFuncMakeTypeError);
892 JSFunction* privateFuncTypedArrayLength = JSFunction::create(vm, this, 0, String(), typedArrayViewPrivateFuncLength);
893 JSFunction* privateFuncTypedArrayGetOriginalConstructor = JSFunction::create(vm, this, 0, String(), typedArrayViewPrivateFuncGetOriginalConstructor);
894 JSFunction* privateFuncTypedArraySort = JSFunction::create(vm, this, 0, String(), typedArrayViewPrivateFuncSort);
895 JSFunction* privateFuncIsTypedArrayView = JSFunction::create(vm, this, 0, String(), typedArrayViewPrivateFuncIsTypedArrayView, IsTypedArrayViewIntrinsic);
896 JSFunction* privateFuncTypedArraySubarrayCreate = JSFunction::create(vm, this, 0, String(), typedArrayViewPrivateFuncSubarrayCreate);
897 JSFunction* privateFuncIsBoundFunction = JSFunction::create(vm, this, 0, String(), isBoundFunction);
898 JSFunction* privateFuncHasInstanceBoundFunction = JSFunction::create(vm, this, 0, String(), hasInstanceBoundFunction);
899 JSFunction* privateFuncInstanceOf = JSFunction::create(vm, this, 0, String(), objectPrivateFuncInstanceOf);
900 JSFunction* privateFuncThisTimeValue = JSFunction::create(vm, this, 0, String(), dateProtoFuncGetTime);
901#if ENABLE(INTL)
902 JSFunction* privateFuncDateTimeFormat = JSFunction::create(vm, this, 0, String(), globalFuncDateTimeFormat);
903#endif
904 JSFunction* privateFuncIsArrayConstructor = JSFunction::create(vm, this, 0, String(), arrayConstructorPrivateFuncIsArrayConstructor);
905 JSFunction* privateFuncIsArraySlow = JSFunction::create(vm, this, 0, String(), arrayConstructorPrivateFuncIsArraySlow);
906 JSFunction* privateFuncConcatMemcpy = JSFunction::create(vm, this, 0, String(), arrayProtoPrivateFuncConcatMemcpy);
907 JSFunction* privateFuncAppendMemcpy = JSFunction::create(vm, this, 0, String(), arrayProtoPrivateFuncAppendMemcpy);
908 JSFunction* privateFuncMapBucketHead = JSFunction::create(vm, this, 0, String(), mapPrivateFuncMapBucketHead, JSMapBucketHeadIntrinsic);
909 JSFunction* privateFuncMapBucketNext = JSFunction::create(vm, this, 0, String(), mapPrivateFuncMapBucketNext, JSMapBucketNextIntrinsic);
910 JSFunction* privateFuncMapBucketKey = JSFunction::create(vm, this, 0, String(), mapPrivateFuncMapBucketKey, JSMapBucketKeyIntrinsic);
911 JSFunction* privateFuncMapBucketValue = JSFunction::create(vm, this, 0, String(), mapPrivateFuncMapBucketValue, JSMapBucketValueIntrinsic);
912 JSFunction* privateFuncSetBucketHead = JSFunction::create(vm, this, 0, String(), setPrivateFuncSetBucketHead, JSSetBucketHeadIntrinsic);
913 JSFunction* privateFuncSetBucketNext = JSFunction::create(vm, this, 0, String(), setPrivateFuncSetBucketNext, JSSetBucketNextIntrinsic);
914 JSFunction* privateFuncSetBucketKey = JSFunction::create(vm, this, 0, String(), setPrivateFuncSetBucketKey, JSSetBucketKeyIntrinsic);
915
916 JSObject* regExpProtoFlagsGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->flags);
917 catchScope.assertNoException();
918 JSObject* regExpProtoGlobalGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->global);
919 catchScope.assertNoException();
920 m_regExpProtoGlobalGetter.set(vm, this, regExpProtoGlobalGetterObject);
921 JSObject* regExpProtoIgnoreCaseGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->ignoreCase);
922 catchScope.assertNoException();
923 JSObject* regExpProtoMultilineGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->multiline);
924 catchScope.assertNoException();
925 JSObject* regExpProtoSourceGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->source);
926 catchScope.assertNoException();
927 JSObject* regExpProtoStickyGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->sticky);
928 catchScope.assertNoException();
929 JSObject* regExpProtoUnicodeGetterObject = getGetterById(exec, m_regExpPrototype.get(), vm.propertyNames->unicode);
930 catchScope.assertNoException();
931 m_regExpProtoUnicodeGetter.set(vm, this, regExpProtoUnicodeGetterObject);
932 JSObject* builtinRegExpExec = asObject(m_regExpPrototype->getDirect(vm, vm.propertyNames->exec).asCell());
933 m_regExpProtoExec.set(vm, this, builtinRegExpExec);
934 JSObject* regExpSymbolReplace = asObject(m_regExpPrototype->getDirect(vm, vm.propertyNames->replaceSymbol).asCell());
935 m_regExpProtoSymbolReplace.set(vm, this, regExpSymbolReplace);
936
937#define CREATE_PRIVATE_GLOBAL_FUNCTION(name, code) JSFunction* name ## PrivateFunction = JSFunction::create(vm, code ## CodeGenerator(vm), this);
938 JSC_FOREACH_BUILTIN_FUNCTION_PRIVATE_GLOBAL_NAME(CREATE_PRIVATE_GLOBAL_FUNCTION)
939#undef CREATE_PRIVATE_GLOBAL_FUNCTION
940
941 JSObject* arrayIteratorPrototype = ArrayIteratorPrototype::create(vm, this, ArrayIteratorPrototype::createStructure(vm, this, m_iteratorPrototype.get()));
942 createArrayIteratorPrivateFunction->putDirect(vm, vm.propertyNames->prototype, arrayIteratorPrototype);
943
944 JSObject* asyncFromSyncIteratorPrototype = AsyncFromSyncIteratorPrototype::create(vm, this, AsyncFromSyncIteratorPrototype::createStructure(vm, this, m_iteratorPrototype.get()));
945 AsyncFromSyncIteratorConstructorPrivateFunction->putDirect(vm, vm.propertyNames->prototype, asyncFromSyncIteratorPrototype);
946
947 JSObject* mapIteratorPrototype = MapIteratorPrototype::create(vm, this, MapIteratorPrototype::createStructure(vm, this, m_iteratorPrototype.get()));
948 createMapIteratorPrivateFunction->putDirect(vm, vm.propertyNames->prototype, mapIteratorPrototype);
949
950 JSObject* setIteratorPrototype = SetIteratorPrototype::create(vm, this, SetIteratorPrototype::createStructure(vm, this, m_iteratorPrototype.get()));
951 createSetIteratorPrivateFunction->putDirect(vm, vm.propertyNames->prototype, setIteratorPrototype);
952
953 GlobalPropertyInfo staticGlobals[] = {
954#define INIT_PRIVATE_GLOBAL(name, code) GlobalPropertyInfo(vm.propertyNames->builtinNames().name ## PrivateName(), name ## PrivateFunction, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
955 JSC_FOREACH_BUILTIN_FUNCTION_PRIVATE_GLOBAL_NAME(INIT_PRIVATE_GLOBAL)
956#undef INIT_PRIVATE_GLOBAL
957 GlobalPropertyInfo(vm.propertyNames->NaN, jsNaN(), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
958 GlobalPropertyInfo(vm.propertyNames->Infinity, jsNumber(std::numeric_limits<double>::infinity()), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
959 GlobalPropertyInfo(vm.propertyNames->undefinedKeyword, jsUndefined(), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
960 GlobalPropertyInfo(vm.propertyNames->builtinNames().propertyIsEnumerablePrivateName(), privateFuncPropertyIsEnumerable, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
961 GlobalPropertyInfo(vm.propertyNames->builtinNames().ownKeysPrivateName(), privateFuncOwnKeys, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
962 GlobalPropertyInfo(vm.propertyNames->builtinNames().importModulePrivateName(), privateFuncImportModule, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
963 GlobalPropertyInfo(vm.propertyNames->builtinNames().enqueueJobPrivateName(), JSFunction::create(vm, this, 0, String(), enqueueJob), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
964 GlobalPropertyInfo(vm.propertyNames->builtinNames().makeTypeErrorPrivateName(), privateFuncMakeTypeError, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
965 GlobalPropertyInfo(vm.propertyNames->builtinNames().typedArrayLengthPrivateName(), privateFuncTypedArrayLength, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
966 GlobalPropertyInfo(vm.propertyNames->builtinNames().typedArrayGetOriginalConstructorPrivateName(), privateFuncTypedArrayGetOriginalConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
967 GlobalPropertyInfo(vm.propertyNames->builtinNames().typedArraySortPrivateName(), privateFuncTypedArraySort, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
968 GlobalPropertyInfo(vm.propertyNames->builtinNames().isTypedArrayViewPrivateName(), privateFuncIsTypedArrayView, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
969 GlobalPropertyInfo(vm.propertyNames->builtinNames().typedArraySubarrayCreatePrivateName(), privateFuncTypedArraySubarrayCreate, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
970 GlobalPropertyInfo(vm.propertyNames->builtinNames().isBoundFunctionPrivateName(), privateFuncIsBoundFunction, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
971 GlobalPropertyInfo(vm.propertyNames->builtinNames().hasInstanceBoundFunctionPrivateName(), privateFuncHasInstanceBoundFunction, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
972 GlobalPropertyInfo(vm.propertyNames->builtinNames().instanceOfPrivateName(), privateFuncInstanceOf, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
973 GlobalPropertyInfo(vm.propertyNames->builtinNames().BuiltinLogPrivateName(), builtinLog, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
974 GlobalPropertyInfo(vm.propertyNames->builtinNames().BuiltinDescribePrivateName(), builtinDescribe, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
975 GlobalPropertyInfo(vm.propertyNames->builtinNames().RegExpPrivateName(), regExpConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
976 GlobalPropertyInfo(vm.propertyNames->builtinNames().truncPrivateName(), privateFuncTrunc, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
977 GlobalPropertyInfo(vm.propertyNames->builtinNames().PromisePrivateName(), promiseConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
978 GlobalPropertyInfo(vm.propertyNames->builtinNames().InternalPromisePrivateName(), internalPromiseConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
979
980 GlobalPropertyInfo(vm.propertyNames->builtinNames().repeatCharacterPrivateName(), JSFunction::create(vm, this, 2, String(), stringProtoFuncRepeatCharacter), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
981 GlobalPropertyInfo(vm.propertyNames->builtinNames().isArrayPrivateName(), arrayConstructor->getDirect(vm, vm.propertyNames->isArray), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
982 GlobalPropertyInfo(vm.propertyNames->builtinNames().isArraySlowPrivateName(), privateFuncIsArraySlow, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
983 GlobalPropertyInfo(vm.propertyNames->builtinNames().isArrayConstructorPrivateName(), privateFuncIsArrayConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
984 GlobalPropertyInfo(vm.propertyNames->builtinNames().concatMemcpyPrivateName(), privateFuncConcatMemcpy, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
985 GlobalPropertyInfo(vm.propertyNames->builtinNames().appendMemcpyPrivateName(), privateFuncAppendMemcpy, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
986
987 GlobalPropertyInfo(vm.propertyNames->builtinNames().hostPromiseRejectionTrackerPrivateName(), JSFunction::create(vm, this, 2, String(), globalFuncHostPromiseRejectionTracker), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
988 GlobalPropertyInfo(vm.propertyNames->builtinNames().InspectorInstrumentationPrivateName(), InspectorInstrumentationObject::create(vm, this, InspectorInstrumentationObject::createStructure(vm, this, m_objectPrototype.get())), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
989 GlobalPropertyInfo(vm.propertyNames->builtinNames().SetPrivateName(), setConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
990 GlobalPropertyInfo(vm.propertyNames->builtinNames().thisTimeValuePrivateName(), privateFuncThisTimeValue, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
991#if ENABLE(INTL)
992 GlobalPropertyInfo(vm.propertyNames->builtinNames().dateTimeFormatPrivateName(), privateFuncDateTimeFormat, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
993#endif // ENABLE(INTL)
994
995 GlobalPropertyInfo(vm.propertyNames->builtinNames().isConstructorPrivateName(), JSFunction::create(vm, this, 1, String(), esSpecIsConstructor, NoIntrinsic), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
996
997 GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoFlagsGetterPrivateName(), regExpProtoFlagsGetterObject, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
998 GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoGlobalGetterPrivateName(), regExpProtoGlobalGetterObject, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
999 GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoIgnoreCaseGetterPrivateName(), regExpProtoIgnoreCaseGetterObject, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1000 GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoMultilineGetterPrivateName(), regExpProtoMultilineGetterObject, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1001 GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoSourceGetterPrivateName(), regExpProtoSourceGetterObject, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1002 GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoStickyGetterPrivateName(), regExpProtoStickyGetterObject, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1003 GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpProtoUnicodeGetterPrivateName(), regExpProtoUnicodeGetterObject, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1004
1005 // RegExp.prototype helpers.
1006 GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpBuiltinExecPrivateName(), builtinRegExpExec, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1007 GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpCreatePrivateName(), JSFunction::create(vm, this, 2, String(), esSpecRegExpCreate, NoIntrinsic), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1008 GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpMatchFastPrivateName(), JSFunction::create(vm, this, 1, String(), regExpProtoFuncMatchFast, RegExpMatchFastIntrinsic), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1009 GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpSearchFastPrivateName(), JSFunction::create(vm, this, 1, String(), regExpProtoFuncSearchFast), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1010 GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpSplitFastPrivateName(), JSFunction::create(vm, this, 2, String(), regExpProtoFuncSplitFast), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1011 GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpPrototypeSymbolReplacePrivateName(), m_regExpPrototype->getDirect(vm, vm.propertyNames->replaceSymbol), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1012 GlobalPropertyInfo(vm.propertyNames->builtinNames().regExpTestFastPrivateName(), JSFunction::create(vm, this, 1, String(), regExpProtoFuncTestFast, RegExpTestFastIntrinsic), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1013
1014 // String.prototype helpers.
1015 GlobalPropertyInfo(vm.propertyNames->builtinNames().stringIncludesInternalPrivateName(), JSFunction::create(vm, this, 1, String(), builtinStringIncludesInternal), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1016 GlobalPropertyInfo(vm.propertyNames->builtinNames().stringSplitFastPrivateName(), JSFunction::create(vm, this, 2, String(), stringProtoFuncSplitFast), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1017 GlobalPropertyInfo(vm.propertyNames->builtinNames().stringSubstrInternalPrivateName(), JSFunction::create(vm, this, 2, String(), builtinStringSubstrInternal), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1018
1019 // Function prototype helpers.
1020 GlobalPropertyInfo(vm.propertyNames->builtinNames().makeBoundFunctionPrivateName(), JSFunction::create(vm, this, 5, String(), makeBoundFunction), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1021 GlobalPropertyInfo(vm.propertyNames->builtinNames().hasOwnLengthPropertyPrivateName(), JSFunction::create(vm, this, 1, String(), hasOwnLengthProperty), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1022
1023 // Map and Set helpers.
1024 GlobalPropertyInfo(vm.propertyNames->builtinNames().mapBucketHeadPrivateName(), privateFuncMapBucketHead, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1025 GlobalPropertyInfo(vm.propertyNames->builtinNames().mapBucketNextPrivateName(), privateFuncMapBucketNext, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1026 GlobalPropertyInfo(vm.propertyNames->builtinNames().mapBucketKeyPrivateName(), privateFuncMapBucketKey, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1027 GlobalPropertyInfo(vm.propertyNames->builtinNames().mapBucketValuePrivateName(), privateFuncMapBucketValue, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1028 GlobalPropertyInfo(vm.propertyNames->builtinNames().setBucketHeadPrivateName(), privateFuncSetBucketHead, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1029 GlobalPropertyInfo(vm.propertyNames->builtinNames().setBucketNextPrivateName(), privateFuncSetBucketNext, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1030 GlobalPropertyInfo(vm.propertyNames->builtinNames().setBucketKeyPrivateName(), privateFuncSetBucketKey, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1031#if ENABLE(WEBASSEMBLY) && ENABLE(WEBASSEMBLY_STREAMING_API)
1032 // WebAssembly Streaming API
1033 GlobalPropertyInfo(vm.propertyNames->builtinNames().webAssemblyCompileStreamingInternalPrivateName(), JSFunction::create(vm, this, 1, String(), webAssemblyCompileStreamingInternal), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1034 GlobalPropertyInfo(vm.propertyNames->builtinNames().webAssemblyInstantiateStreamingInternalPrivateName(), JSFunction::create(vm, this, 1, String(), webAssemblyInstantiateStreamingInternal), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1035#endif
1036#if !ASSERT_DISABLED
1037 GlobalPropertyInfo(vm.propertyNames->builtinNames().assertPrivateName(), JSFunction::create(vm, this, 1, String(), assertCall), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1038#endif
1039 };
1040 addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals));
1041
1042 m_specialPointers[Special::CallFunction] = m_callFunction.get();
1043 m_specialPointers[Special::ApplyFunction] = m_applyFunction.get();
1044 m_specialPointers[Special::ObjectConstructor] = objectConstructor;
1045 m_specialPointers[Special::ArrayConstructor] = arrayConstructor;
1046
1047 m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::ThrowTypeErrorFunction)] = m_throwTypeErrorFunction.get();
1048
1049 if (UNLIKELY(Options::useDollarVM()))
1050 exposeDollarVM(vm);
1051
1052#if ENABLE(WEBASSEMBLY)
1053 if (Wasm::isSupported()) {
1054 auto* webAssemblyPrototype = WebAssemblyPrototype::create(vm, this, WebAssemblyPrototype::createStructure(vm, this, m_objectPrototype.get()));
1055 m_webAssemblyModuleRecordStructure.initLater(
1056 [] (const Initializer<Structure>& init) {
1057 init.set(WebAssemblyModuleRecord::createStructure(init.vm, init.owner, init.owner->m_objectPrototype.get()));
1058 });
1059 m_webAssemblyFunctionStructure.initLater(
1060 [] (const Initializer<Structure>& init) {
1061 init.set(WebAssemblyFunction::createStructure(init.vm, init.owner, init.owner->m_functionPrototype.get()));
1062 });
1063 m_jsToWasmICCalleeStructure.initLater(
1064 [] (const Initializer<Structure>& init) {
1065 init.set(JSToWasmICCallee::createStructure(init.vm, init.owner, jsNull()));
1066 });
1067 m_webAssemblyWrapperFunctionStructure.initLater(
1068 [] (const Initializer<Structure>& init) {
1069 init.set(WebAssemblyWrapperFunction::createStructure(init.vm, init.owner, init.owner->m_functionPrototype.get()));
1070 });
1071 m_webAssemblyToJSCalleeStructure.initLater(
1072 [] (const Initializer<Structure>& init) {
1073 init.set(WebAssemblyToJSCallee::createStructure(init.vm, init.owner, jsNull()));
1074 });
1075 auto* webAssembly = JSWebAssembly::create(vm, this, JSWebAssembly::createStructure(vm, this, webAssemblyPrototype));
1076 putDirectWithoutTransition(vm, Identifier::fromString(exec, "WebAssembly"), webAssembly, static_cast<unsigned>(PropertyAttribute::DontEnum));
1077
1078#define CREATE_WEBASSEMBLY_PROTOTYPE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase) \
1079 m_ ## properName ## Structure.initLater(\
1080 [] (LazyClassStructure::Initializer& init) { \
1081 init.setPrototype(capitalName##Prototype::create(init.vm, init.global, capitalName##Prototype::createStructure(init.vm, init.global, init.global->prototypeBase ## Prototype()))); \
1082 init.setStructure(instanceType::createStructure(init.vm, init.global, init.prototype)); \
1083 init.setConstructor(capitalName ## Constructor::create(init.vm, capitalName ## Constructor::createStructure(init.vm, init.global, init.global->functionPrototype()), jsCast<capitalName ## Prototype*>(init.prototype))); \
1084 });
1085
1086 FOR_EACH_WEBASSEMBLY_CONSTRUCTOR_TYPE(CREATE_WEBASSEMBLY_PROTOTYPE)
1087
1088#undef CREATE_WEBASSEMBLY_CONSTRUCTOR
1089 }
1090#endif // ENABLE(WEBASSEMBLY)
1091
1092#undef CREATE_PROTOTYPE_FOR_LAZY_TYPE
1093
1094 auto setupAdaptiveWatchpoint = [&] (JSObject* base, const Identifier& ident) -> ObjectPropertyCondition {
1095 // Performing these gets should not throw.
1096 ExecState* exec = globalExec();
1097 PropertySlot slot(base, PropertySlot::InternalMethodType::Get);
1098 bool result = base->getOwnPropertySlot(base, exec, ident, slot);
1099 ASSERT_UNUSED(result, result);
1100 catchScope.assertNoException();
1101 RELEASE_ASSERT(slot.isCacheableValue());
1102 JSValue functionValue = slot.getValue(exec, ident);
1103 catchScope.assertNoException();
1104 ASSERT(jsDynamicCast<JSFunction*>(vm, functionValue));
1105
1106 ObjectPropertyCondition condition = generateConditionForSelfEquivalence(m_vm, nullptr, base, ident.impl());
1107 RELEASE_ASSERT(condition.requiredValue() == functionValue);
1108
1109 bool isWatchable = condition.isWatchable(PropertyCondition::EnsureWatchability);
1110 RELEASE_ASSERT(isWatchable); // We allow this to install the necessary watchpoints.
1111
1112 return condition;
1113 };
1114
1115 {
1116 ObjectPropertyCondition condition = setupAdaptiveWatchpoint(arrayIteratorPrototype, m_vm.propertyNames->next);
1117 m_arrayIteratorPrototypeNext = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_arrayIteratorProtocolWatchpoint);
1118 m_arrayIteratorPrototypeNext->install(vm);
1119 }
1120 {
1121 ObjectPropertyCondition condition = setupAdaptiveWatchpoint(this->arrayPrototype(), m_vm.propertyNames->iteratorSymbol);
1122 m_arrayPrototypeSymbolIteratorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_arrayIteratorProtocolWatchpoint);
1123 m_arrayPrototypeSymbolIteratorWatchpoint->install(vm);
1124 }
1125
1126 {
1127 ObjectPropertyCondition condition = setupAdaptiveWatchpoint(mapIteratorPrototype, m_vm.propertyNames->next);
1128 m_mapIteratorPrototypeNextWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_mapIteratorProtocolWatchpoint);
1129 m_mapIteratorPrototypeNextWatchpoint->install(vm);
1130 }
1131 {
1132 ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_mapPrototype.get(), m_vm.propertyNames->iteratorSymbol);
1133 m_mapPrototypeSymbolIteratorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_mapIteratorProtocolWatchpoint);
1134 m_mapPrototypeSymbolIteratorWatchpoint->install(vm);
1135 }
1136
1137 {
1138 ObjectPropertyCondition condition = setupAdaptiveWatchpoint(setIteratorPrototype, m_vm.propertyNames->next);
1139 m_setIteratorPrototypeNextWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_setIteratorProtocolWatchpoint);
1140 m_setIteratorPrototypeNextWatchpoint->install(vm);
1141 }
1142 {
1143 ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_setPrototype.get(), m_vm.propertyNames->iteratorSymbol);
1144 m_setPrototypeSymbolIteratorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_setIteratorProtocolWatchpoint);
1145 m_setPrototypeSymbolIteratorWatchpoint->install(vm);
1146 }
1147
1148 {
1149 ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_stringIteratorPrototype.get(), m_vm.propertyNames->next);
1150 m_stringIteratorPrototypeNextWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_stringIteratorProtocolWatchpoint);
1151 m_stringIteratorPrototypeNextWatchpoint->install(vm);
1152 }
1153 {
1154 ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_stringPrototype.get(), m_vm.propertyNames->iteratorSymbol);
1155 m_stringPrototypeSymbolIteratorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_stringIteratorProtocolWatchpoint);
1156 m_stringPrototypeSymbolIteratorWatchpoint->install(vm);
1157 }
1158
1159 {
1160 ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_mapPrototype.get(), m_vm.propertyNames->set);
1161 m_mapPrototypeSetWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_mapSetWatchpoint);
1162 m_mapPrototypeSetWatchpoint->install(vm);
1163 }
1164
1165 {
1166 ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_setPrototype.get(), m_vm.propertyNames->add);
1167 m_setPrototypeAddWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_setAddWatchpoint);
1168 m_setPrototypeAddWatchpoint->install(vm);
1169 }
1170
1171 // Unfortunately, the prototype objects of the builtin objects can be touched from concurrent compilers. So eagerly initialize them only if we use JIT.
1172 if (VM::canUseJIT()) {
1173 this->booleanPrototype();
1174 auto* numberPrototype = this->numberPrototype();
1175 this->symbolPrototype();
1176
1177 ObjectPropertyCondition condition = setupAdaptiveWatchpoint(numberPrototype, m_vm.propertyNames->toString);
1178 m_numberPrototypeToStringWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_numberToStringWatchpoint);
1179 m_numberPrototypeToStringWatchpoint->install(vm);
1180 m_numberProtoToStringFunction.set(vm, this, jsCast<JSFunction*>(numberPrototype->getDirect(vm, vm.propertyNames->toString)));
1181 }
1182
1183 fixupPrototypeChainWithObjectPrototype(vm);
1184}
1185
1186bool JSGlobalObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
1187{
1188 VM& vm = exec->vm();
1189 auto scope = DECLARE_THROW_SCOPE(vm);
1190 JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(cell);
1191 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(thisObject));
1192
1193 if (UNLIKELY(isThisValueAltered(slot, thisObject)))
1194 RELEASE_AND_RETURN(scope, ordinarySetSlow(exec, thisObject, propertyName, value, slot.thisValue(), slot.isStrictMode()));
1195
1196 bool shouldThrowReadOnlyError = slot.isStrictMode();
1197 bool ignoreReadOnlyErrors = false;
1198 bool putResult = false;
1199 bool done = symbolTablePutTouchWatchpointSet(thisObject, exec, propertyName, value, shouldThrowReadOnlyError, ignoreReadOnlyErrors, putResult);
1200 EXCEPTION_ASSERT((!!scope.exception() == (done && !putResult)) || !shouldThrowReadOnlyError);
1201 if (done)
1202 return putResult;
1203 RELEASE_AND_RETURN(scope, Base::put(thisObject, exec, propertyName, value, slot));
1204}
1205
1206bool JSGlobalObject::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool shouldThrow)
1207{
1208 JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(object);
1209 PropertySlot slot(thisObject, PropertySlot::InternalMethodType::VMInquiry);
1210 // silently ignore attempts to add accessors aliasing vars.
1211 if (descriptor.isAccessorDescriptor() && symbolTableGet(thisObject, propertyName, slot))
1212 return false;
1213 return Base::defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow);
1214}
1215
1216void JSGlobalObject::addGlobalVar(const Identifier& ident)
1217{
1218 ConcurrentJSLocker locker(symbolTable()->m_lock);
1219 SymbolTableEntry entry = symbolTable()->get(locker, ident.impl());
1220 if (!entry.isNull())
1221 return;
1222
1223 ScopeOffset offset = symbolTable()->takeNextScopeOffset(locker);
1224 SymbolTableEntry newEntry(VarOffset(offset), 0);
1225 newEntry.prepareToWatch();
1226 symbolTable()->add(locker, ident.impl(), WTFMove(newEntry));
1227
1228 ScopeOffset offsetForAssert = addVariables(1, jsUndefined());
1229 RELEASE_ASSERT(offsetForAssert == offset);
1230}
1231
1232void JSGlobalObject::addFunction(ExecState* exec, const Identifier& propertyName)
1233{
1234 VM& vm = exec->vm();
1235 VM::DeletePropertyModeScope scope(vm, VM::DeletePropertyMode::IgnoreConfigurable);
1236 methodTable(vm)->deleteProperty(this, exec, propertyName);
1237 addGlobalVar(propertyName);
1238}
1239
1240void JSGlobalObject::setGlobalScopeExtension(JSScope* scope)
1241{
1242 m_globalScopeExtension.set(vm(), this, scope);
1243}
1244
1245void JSGlobalObject::clearGlobalScopeExtension()
1246{
1247 m_globalScopeExtension.clear();
1248}
1249
1250static inline JSObject* lastInPrototypeChain(VM& vm, JSObject* object)
1251{
1252 JSObject* o = object;
1253 while (o->getPrototypeDirect(vm).isObject())
1254 o = asObject(o->getPrototypeDirect(vm));
1255 return o;
1256}
1257
1258// Private namespace for helpers for JSGlobalObject::haveABadTime()
1259namespace {
1260
1261class GlobalObjectDependencyFinder : public MarkedBlock::VoidFunctor {
1262public:
1263 GlobalObjectDependencyFinder(VM& vm)
1264 : m_vm(vm)
1265 { }
1266
1267 IterationStatus operator()(HeapCell*, HeapCell::Kind) const;
1268
1269 void addDependency(JSGlobalObject* key, JSGlobalObject* dependent);
1270 HashSet<JSGlobalObject*>* dependentsFor(JSGlobalObject* key);
1271
1272private:
1273 void visit(JSObject*);
1274
1275 VM& m_vm;
1276 HashMap<JSGlobalObject*, HashSet<JSGlobalObject*>> m_dependencies;
1277};
1278
1279inline void GlobalObjectDependencyFinder::addDependency(JSGlobalObject* key, JSGlobalObject* dependent)
1280{
1281 auto keyResult = m_dependencies.add(key, HashSet<JSGlobalObject*>());
1282 keyResult.iterator->value.add(dependent);
1283}
1284
1285inline HashSet<JSGlobalObject*>* GlobalObjectDependencyFinder::dependentsFor(JSGlobalObject* key)
1286{
1287 auto iterator = m_dependencies.find(key);
1288 if (iterator == m_dependencies.end())
1289 return nullptr;
1290 return &iterator->value;
1291}
1292
1293inline void GlobalObjectDependencyFinder::visit(JSObject* object)
1294{
1295 VM& vm = m_vm;
1296
1297 if (!object->mayBePrototype())
1298 return;
1299
1300 JSObject* current = object;
1301 JSGlobalObject* objectGlobalObject = object->globalObject(vm);
1302 do {
1303 JSValue prototypeValue = current->getPrototypeDirect(vm);
1304 if (prototypeValue.isNull())
1305 return;
1306 current = asObject(prototypeValue);
1307
1308 JSGlobalObject* protoGlobalObject = current->globalObject(vm);
1309 if (protoGlobalObject != objectGlobalObject)
1310 addDependency(protoGlobalObject, objectGlobalObject);
1311 } while (true);
1312}
1313
1314IterationStatus GlobalObjectDependencyFinder::operator()(HeapCell* cell, HeapCell::Kind kind) const
1315{
1316 if (isJSCellKind(kind) && static_cast<JSCell*>(cell)->isObject()) {
1317 // FIXME: This const_cast exists because this isn't a C++ lambda.
1318 // https://bugs.webkit.org/show_bug.cgi?id=159644
1319 const_cast<GlobalObjectDependencyFinder*>(this)->visit(jsCast<JSObject*>(static_cast<JSCell*>(cell)));
1320 }
1321 return IterationStatus::Continue;
1322}
1323
1324enum class BadTimeFinderMode {
1325 SingleGlobal,
1326 MultipleGlobals
1327};
1328
1329template<BadTimeFinderMode mode>
1330class ObjectsWithBrokenIndexingFinder : public MarkedBlock::VoidFunctor {
1331public:
1332 ObjectsWithBrokenIndexingFinder(VM&, Vector<JSObject*>&, JSGlobalObject*);
1333 ObjectsWithBrokenIndexingFinder(VM&, Vector<JSObject*>&, HashSet<JSGlobalObject*>&);
1334
1335 bool needsMultiGlobalsScan() const { return m_needsMultiGlobalsScan; }
1336 IterationStatus operator()(HeapCell*, HeapCell::Kind) const;
1337
1338private:
1339 IterationStatus visit(JSObject*);
1340
1341 VM& m_vm;
1342 Vector<JSObject*>& m_foundObjects;
1343 JSGlobalObject* m_globalObject { nullptr }; // Only used for SingleBadTimeGlobal mode.
1344 HashSet<JSGlobalObject*>* m_globalObjects { nullptr }; // Only used for BadTimeGlobalGraph mode;
1345 bool m_needsMultiGlobalsScan { false };
1346};
1347
1348template<>
1349ObjectsWithBrokenIndexingFinder<BadTimeFinderMode::SingleGlobal>::ObjectsWithBrokenIndexingFinder(
1350 VM& vm, Vector<JSObject*>& foundObjects, JSGlobalObject* globalObject)
1351 : m_vm(vm)
1352 , m_foundObjects(foundObjects)
1353 , m_globalObject(globalObject)
1354{
1355}
1356
1357template<>
1358ObjectsWithBrokenIndexingFinder<BadTimeFinderMode::MultipleGlobals>::ObjectsWithBrokenIndexingFinder(
1359 VM& vm, Vector<JSObject*>& foundObjects, HashSet<JSGlobalObject*>& globalObjects)
1360 : m_vm(vm)
1361 , m_foundObjects(foundObjects)
1362 , m_globalObjects(&globalObjects)
1363{
1364}
1365
1366inline bool hasBrokenIndexing(IndexingType type)
1367{
1368 return type && !hasSlowPutArrayStorage(type);
1369}
1370
1371inline bool hasBrokenIndexing(JSObject* object)
1372{
1373 IndexingType type = object->indexingType();
1374 return hasBrokenIndexing(type);
1375}
1376
1377template<BadTimeFinderMode mode>
1378inline IterationStatus ObjectsWithBrokenIndexingFinder<mode>::visit(JSObject* object)
1379{
1380 VM& vm = m_vm;
1381
1382 // We only want to have a bad time in the affected global object, not in the entire
1383 // VM. But we have to be careful, since there may be objects that claim to belong to
1384 // a different global object that have prototypes from our global object.
1385 auto isInAffectedGlobalObject = [&] (JSObject* object) {
1386 JSGlobalObject* objectGlobalObject { nullptr };
1387 bool objectMayBePrototype { false };
1388
1389 if (mode == BadTimeFinderMode::SingleGlobal) {
1390 objectGlobalObject = object->globalObject(vm);
1391 if (objectGlobalObject == m_globalObject)
1392 return true;
1393
1394 objectMayBePrototype = object->mayBePrototype();
1395 }
1396
1397 for (JSObject* current = object; ;) {
1398 JSGlobalObject* currentGlobalObject = current->globalObject(vm);
1399 if (mode == BadTimeFinderMode::SingleGlobal) {
1400 if (objectMayBePrototype && currentGlobalObject != objectGlobalObject)
1401 m_needsMultiGlobalsScan = true;
1402 if (currentGlobalObject == m_globalObject)
1403 return true;
1404 } else {
1405 if (m_globalObjects->contains(currentGlobalObject))
1406 return true;
1407 }
1408
1409 JSValue prototypeValue = current->getPrototypeDirect(vm);
1410 if (prototypeValue.isNull())
1411 return false;
1412 current = asObject(prototypeValue);
1413 }
1414 RELEASE_ASSERT_NOT_REACHED();
1415 };
1416
1417 if (JSFunction* function = jsDynamicCast<JSFunction*>(vm, object)) {
1418 if (FunctionRareData* rareData = function->rareData()) {
1419 // We only use this to cache JSFinalObjects. They do not start off with a broken indexing type.
1420 ASSERT(!(rareData->objectAllocationStructure() && hasBrokenIndexing(rareData->objectAllocationStructure()->indexingType())));
1421
1422 if (Structure* structure = rareData->internalFunctionAllocationStructure()) {
1423 if (hasBrokenIndexing(structure->indexingType())) {
1424 bool isRelevantGlobalObject =
1425 (mode == BadTimeFinderMode::SingleGlobal
1426 ? m_globalObject == structure->globalObject()
1427 : m_globalObjects->contains(structure->globalObject()))
1428 || (structure->hasMonoProto() && !structure->storedPrototype().isNull() && isInAffectedGlobalObject(asObject(structure->storedPrototype())));
1429 if (mode == BadTimeFinderMode::SingleGlobal && m_needsMultiGlobalsScan)
1430 return IterationStatus::Done; // Bailing early and let the MultipleGlobals path handle everything.
1431 if (isRelevantGlobalObject)
1432 rareData->clearInternalFunctionAllocationProfile();
1433 }
1434 }
1435 }
1436 }
1437
1438 // Run this filter first, since it's cheap, and ought to filter out a lot of objects.
1439 if (!hasBrokenIndexing(object))
1440 return IterationStatus::Continue;
1441
1442 if (isInAffectedGlobalObject(object))
1443 m_foundObjects.append(object);
1444
1445 if (mode == BadTimeFinderMode::SingleGlobal && m_needsMultiGlobalsScan)
1446 return IterationStatus::Done; // Bailing early and let the MultipleGlobals path handle everything.
1447
1448 return IterationStatus::Continue;
1449}
1450
1451template<BadTimeFinderMode mode>
1452IterationStatus ObjectsWithBrokenIndexingFinder<mode>::operator()(HeapCell* cell, HeapCell::Kind kind) const
1453{
1454 if (isJSCellKind(kind) && static_cast<JSCell*>(cell)->isObject()) {
1455 // FIXME: This const_cast exists because this isn't a C++ lambda.
1456 // https://bugs.webkit.org/show_bug.cgi?id=159644
1457 return const_cast<ObjectsWithBrokenIndexingFinder*>(this)->visit(jsCast<JSObject*>(static_cast<JSCell*>(cell)));
1458 }
1459 return IterationStatus::Continue;
1460}
1461
1462} // end private namespace for helpers for JSGlobalObject::haveABadTime()
1463
1464void JSGlobalObject::fireWatchpointAndMakeAllArrayStructuresSlowPut(VM& vm)
1465{
1466 if (isHavingABadTime())
1467 return;
1468
1469 // Make sure that all allocations or indexed storage transitions that are inlining
1470 // the assumption that it's safe to transition to a non-SlowPut array storage don't
1471 // do so anymore.
1472 m_havingABadTimeWatchpoint->fireAll(vm, "Having a bad time");
1473 ASSERT(isHavingABadTime()); // The watchpoint is what tells us that we're having a bad time.
1474
1475 // Make sure that all JSArray allocations that load the appropriate structure from
1476 // this object now load a structure that uses SlowPut.
1477 for (unsigned i = 0; i < NumberOfArrayIndexingModes; ++i)
1478 m_arrayStructureForIndexingShapeDuringAllocation[i].set(vm, this, originalArrayStructureForIndexingType(ArrayWithSlowPutArrayStorage));
1479
1480 // Same for any special array structures.
1481 Structure* slowPutStructure;
1482 slowPutStructure = createRegExpMatchesArraySlowPutStructure(vm, this);
1483 m_regExpMatchesArrayStructure.set(vm, this, slowPutStructure);
1484 slowPutStructure = createRegExpMatchesArrayWithGroupsSlowPutStructure(vm, this);
1485 m_regExpMatchesArrayWithGroupsStructure.set(vm, this, slowPutStructure);
1486 slowPutStructure = ClonedArguments::createSlowPutStructure(vm, this, m_objectPrototype.get());
1487 m_clonedArgumentsStructure.set(vm, this, slowPutStructure);
1488};
1489
1490void JSGlobalObject::haveABadTime(VM& vm)
1491{
1492 ASSERT(&vm == &this->vm());
1493
1494 if (isHavingABadTime())
1495 return;
1496
1497 vm.structureCache.clear(); // We may be caching array structures in here.
1498
1499 DeferGC deferGC(vm.heap);
1500
1501 // Consider the following objects and prototype chains:
1502 // O (of global G1) -> A (of global G1)
1503 // B (of global G2) where G2 has a bad time
1504 //
1505 // If we set B as the prototype of A, G1 will need to have a bad time.
1506 // See comments in Structure::mayInterceptIndexedAccesses() for why.
1507 //
1508 // Now, consider the following objects and prototype chains:
1509 // O1 (of global G1) -> A1 (of global G1) -> B1 (of global G2)
1510 // O2 (of global G2) -> A2 (of global G2)
1511 // B2 (of global G3) where G3 has a bad time.
1512 //
1513 // G1 and G2 does not have a bad time, but G3 already has a bad time.
1514 // If we set B2 as the prototype of A2, then G2 needs to have a bad time.
1515 // Note that by induction, G1 also now needs to have a bad time because of
1516 // O1 -> A1 -> B1.
1517 //
1518 // We describe this as global G1 being affected by global G2, and G2 by G3.
1519 // Similarly, we say that G1 is dependent on G2, and G2 on G3.
1520 // Hence, when G3 has a bad time, we need to ensure that all globals that
1521 // are transitively dependent on it also have a bad time (G2 and G1 in this
1522 // example).
1523 //
1524 // Apart from clearing the VM structure cache above, there are 2 more things
1525 // that we have to do when globals have a bad time:
1526 // 1. For each affected global:
1527 // a. Fire its HaveABadTime watchpoint.
1528 // b. Convert all of its array structures to SlowPutArrayStorage.
1529 // 2. Make sure that all affected objects switch to the slow kind of
1530 // indexed storage. An object is considered to be affected if it has
1531 // indexed storage and has a prototype object which may have indexed
1532 // accessors. If the prototype object belongs to a global having a bad
1533 // time, then the prototype object is considered to possibly have indexed
1534 // accessors. See comments in Structure::mayInterceptIndexedAccesses()
1535 // for details.
1536 //
1537 // Note: step 1 must be completed before step 2 because step 2 relies on
1538 // the HaveABadTime watchpoint having already been fired on all affected
1539 // globals.
1540 //
1541 // In the common case, only this global will start having a bad time here,
1542 // and no other globals are affected by it. So, we first proceed on this assumption
1543 // with a simpler ObjectsWithBrokenIndexingFinder scan to find heap objects
1544 // affected by this global that need to be converted to SlowPutArrayStorage.
1545 // We'll also have the finder check for the presence of other global objects
1546 // depending on this one.
1547 //
1548 // If we do discover other globals depending on this one, we'll abort this
1549 // first ObjectsWithBrokenIndexingFinder scan because it will be insufficient
1550 // to find all affected objects that need to be converted to SlowPutArrayStorage.
1551 // It also does not make dependent globals have a bad time. Instead, we'll
1552 // take a more comprehensive approach of first creating a dependency graph
1553 // between globals, and then using that graph to determine all affected
1554 // globals and objects. With that, we can make all affected globals have a
1555 // bad time, and convert all affected objects to SlowPutArrayStorage.
1556
1557 fireWatchpointAndMakeAllArrayStructuresSlowPut(vm); // Step 1 above.
1558
1559 Vector<JSObject*> foundObjects;
1560 ObjectsWithBrokenIndexingFinder<BadTimeFinderMode::SingleGlobal> finder(vm, foundObjects, this);
1561 {
1562 HeapIterationScope iterationScope(vm.heap);
1563 vm.heap.objectSpace().forEachLiveCell(iterationScope, finder); // Attempt step 2 above.
1564 }
1565
1566 if (finder.needsMultiGlobalsScan()) {
1567 foundObjects.clear();
1568
1569 // Find all globals that will also have a bad time as a side effect of
1570 // this global having a bad time.
1571 GlobalObjectDependencyFinder dependencies(vm);
1572 {
1573 HeapIterationScope iterationScope(vm.heap);
1574 vm.heap.objectSpace().forEachLiveCell(iterationScope, dependencies);
1575 }
1576
1577 HashSet<JSGlobalObject*> globalsHavingABadTime;
1578 Deque<JSGlobalObject*> globals;
1579
1580 globals.append(this);
1581 while (!globals.isEmpty()) {
1582 JSGlobalObject* global = globals.takeFirst();
1583 global->fireWatchpointAndMakeAllArrayStructuresSlowPut(vm); // Step 1 above.
1584 auto result = globalsHavingABadTime.add(global);
1585 if (result.isNewEntry) {
1586 if (HashSet<JSGlobalObject*>* dependents = dependencies.dependentsFor(global)) {
1587 for (JSGlobalObject* dependentGlobal : *dependents)
1588 globals.append(dependentGlobal);
1589 }
1590 }
1591 }
1592
1593 ObjectsWithBrokenIndexingFinder<BadTimeFinderMode::MultipleGlobals> finder(vm, foundObjects, globalsHavingABadTime);
1594 {
1595 HeapIterationScope iterationScope(vm.heap);
1596 vm.heap.objectSpace().forEachLiveCell(iterationScope, finder); // Step 2 above.
1597 }
1598 }
1599
1600 while (!foundObjects.isEmpty()) {
1601 JSObject* object = asObject(foundObjects.last());
1602 foundObjects.removeLast();
1603 ASSERT(hasBrokenIndexing(object));
1604 object->switchToSlowPutArrayStorage(vm);
1605 }
1606}
1607
1608void JSGlobalObject::fixupPrototypeChainWithObjectPrototype(VM& vm)
1609{
1610 JSObject* oldLastInPrototypeChain = lastInPrototypeChain(vm, this);
1611 JSObject* objectPrototype = m_objectPrototype.get();
1612 if (oldLastInPrototypeChain != objectPrototype)
1613 oldLastInPrototypeChain->setPrototypeDirect(vm, objectPrototype);
1614}
1615
1616// Set prototype, and also insert the object prototype at the end of the chain.
1617void JSGlobalObject::resetPrototype(VM& vm, JSValue prototype)
1618{
1619 if (getPrototypeDirect(vm) == prototype)
1620 return;
1621 setPrototypeDirect(vm, prototype);
1622 fixupPrototypeChainWithObjectPrototype(vm);
1623 // Whenever we change the prototype of the global object, we need to create a new JSProxy with the correct prototype.
1624 setGlobalThis(vm, JSNonDestructibleProxy::create(vm, JSNonDestructibleProxy::createStructure(vm, this, prototype, PureForwardingProxyType), this));
1625}
1626
1627void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
1628{
1629 JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(cell);
1630 ASSERT_GC_OBJECT_INHERITS(thisObject, info());
1631 Base::visitChildren(thisObject, visitor);
1632
1633 visitor.append(thisObject->m_globalThis);
1634
1635 visitor.append(thisObject->m_globalLexicalEnvironment);
1636 visitor.append(thisObject->m_globalScopeExtension);
1637 visitor.append(thisObject->m_globalCallee);
1638 visitor.append(thisObject->m_stackOverflowFrameCallee);
1639 thisObject->m_evalErrorStructure.visit(visitor);
1640 thisObject->m_rangeErrorStructure.visit(visitor);
1641 thisObject->m_referenceErrorStructure.visit(visitor);
1642 thisObject->m_syntaxErrorStructure.visit(visitor);
1643 thisObject->m_typeErrorStructure.visit(visitor);
1644 thisObject->m_URIErrorStructure.visit(visitor);
1645 visitor.append(thisObject->m_objectConstructor);
1646 visitor.append(thisObject->m_promiseConstructor);
1647
1648#if ENABLE(INTL)
1649 visitor.append(thisObject->m_defaultCollator);
1650 thisObject->m_collatorStructure.visit(visitor);
1651 thisObject->m_numberFormatStructure.visit(visitor);
1652 thisObject->m_dateTimeFormatStructure.visit(visitor);
1653 thisObject->m_pluralRulesStructure.visit(visitor);
1654#endif
1655 visitor.append(thisObject->m_nullGetterFunction);
1656 visitor.append(thisObject->m_nullSetterFunction);
1657
1658 thisObject->m_parseIntFunction.visit(visitor);
1659 thisObject->m_parseFloatFunction.visit(visitor);
1660 visitor.append(thisObject->m_callFunction);
1661 visitor.append(thisObject->m_applyFunction);
1662 visitor.append(thisObject->m_throwTypeErrorFunction);
1663 thisObject->m_arrayProtoToStringFunction.visit(visitor);
1664 thisObject->m_arrayProtoValuesFunction.visit(visitor);
1665 thisObject->m_evalFunction.visit(visitor);
1666 thisObject->m_initializePromiseFunction.visit(visitor);
1667 thisObject->m_iteratorProtocolFunction.visit(visitor);
1668 thisObject->m_promiseResolveFunction.visit(visitor);
1669 visitor.append(thisObject->m_objectProtoValueOfFunction);
1670 visitor.append(thisObject->m_numberProtoToStringFunction);
1671 visitor.append(thisObject->m_newPromiseCapabilityFunction);
1672 visitor.append(thisObject->m_functionProtoHasInstanceSymbolFunction);
1673 thisObject->m_throwTypeErrorGetterSetter.visit(visitor);
1674 visitor.append(thisObject->m_throwTypeErrorArgumentsCalleeAndCallerGetterSetter);
1675 thisObject->m_moduleLoader.visit(visitor);
1676
1677 visitor.append(thisObject->m_objectPrototype);
1678 visitor.append(thisObject->m_functionPrototype);
1679 visitor.append(thisObject->m_arrayPrototype);
1680 visitor.append(thisObject->m_iteratorPrototype);
1681 visitor.append(thisObject->m_generatorFunctionPrototype);
1682 visitor.append(thisObject->m_generatorPrototype);
1683 visitor.append(thisObject->m_asyncFunctionPrototype);
1684 visitor.append(thisObject->m_asyncGeneratorPrototype);
1685 visitor.append(thisObject->m_asyncIteratorPrototype);
1686 visitor.append(thisObject->m_asyncGeneratorFunctionPrototype);
1687
1688 thisObject->m_debuggerScopeStructure.visit(visitor);
1689 thisObject->m_withScopeStructure.visit(visitor);
1690 thisObject->m_strictEvalActivationStructure.visit(visitor);
1691 visitor.append(thisObject->m_lexicalEnvironmentStructure);
1692 thisObject->m_moduleEnvironmentStructure.visit(visitor);
1693 visitor.append(thisObject->m_directArgumentsStructure);
1694 visitor.append(thisObject->m_scopedArgumentsStructure);
1695 visitor.append(thisObject->m_clonedArgumentsStructure);
1696 visitor.append(thisObject->m_objectStructureForObjectConstructor);
1697 for (unsigned i = 0; i < NumberOfArrayIndexingModes; ++i)
1698 visitor.append(thisObject->m_originalArrayStructureForIndexingShape[i]);
1699 for (unsigned i = 0; i < NumberOfArrayIndexingModes; ++i)
1700 visitor.append(thisObject->m_arrayStructureForIndexingShapeDuringAllocation[i]);
1701 thisObject->m_callbackConstructorStructure.visit(visitor);
1702 thisObject->m_callbackFunctionStructure.visit(visitor);
1703 thisObject->m_callbackObjectStructure.visit(visitor);
1704#if JSC_OBJC_API_ENABLED
1705 thisObject->m_objcCallbackFunctionStructure.visit(visitor);
1706 thisObject->m_objcWrapperObjectStructure.visit(visitor);
1707#endif
1708#ifdef JSC_GLIB_API_ENABLED
1709 thisObject->m_glibCallbackFunctionStructure.visit(visitor);
1710 thisObject->m_glibWrapperObjectStructure.visit(visitor);
1711#endif
1712 visitor.append(thisObject->m_nullPrototypeObjectStructure);
1713 visitor.append(thisObject->m_calleeStructure);
1714
1715 visitor.append(thisObject->m_hostFunctionStructure);
1716 auto visitFunctionStructures = [&] (FunctionStructures& structures) {
1717 visitor.append(structures.arrowFunctionStructure);
1718 visitor.append(structures.sloppyFunctionStructure);
1719 visitor.append(structures.strictFunctionStructure);
1720 };
1721 visitFunctionStructures(thisObject->m_builtinFunctions);
1722 visitFunctionStructures(thisObject->m_ordinaryFunctions);
1723
1724 thisObject->m_customGetterSetterFunctionStructure.visit(visitor);
1725 thisObject->m_boundFunctionStructure.visit(visitor);
1726 visitor.append(thisObject->m_getterSetterStructure);
1727 thisObject->m_nativeStdFunctionStructure.visit(visitor);
1728 visitor.append(thisObject->m_bigIntObjectStructure);
1729 visitor.append(thisObject->m_regExpStructure);
1730 visitor.append(thisObject->m_generatorFunctionStructure);
1731 visitor.append(thisObject->m_asyncFunctionStructure);
1732 visitor.append(thisObject->m_asyncGeneratorFunctionStructure);
1733 thisObject->m_iteratorResultObjectStructure.visit(visitor);
1734 visitor.append(thisObject->m_regExpMatchesArrayStructure);
1735 visitor.append(thisObject->m_regExpMatchesArrayWithGroupsStructure);
1736 thisObject->m_moduleRecordStructure.visit(visitor);
1737 thisObject->m_moduleNamespaceObjectStructure.visit(visitor);
1738 thisObject->m_proxyObjectStructure.visit(visitor);
1739 thisObject->m_callableProxyObjectStructure.visit(visitor);
1740 thisObject->m_proxyRevokeStructure.visit(visitor);
1741
1742#if ENABLE(SHARED_ARRAY_BUFFER)
1743 visitor.append(thisObject->m_sharedArrayBufferPrototype);
1744 visitor.append(thisObject->m_sharedArrayBufferStructure);
1745#endif
1746
1747#define VISIT_SIMPLE_TYPE(CapitalName, lowerName, properName, instanceType, jsName, prototypeBase) do { \
1748 visitor.append(thisObject->m_ ## lowerName ## Prototype); \
1749 visitor.append(thisObject->m_ ## properName ## Structure); \
1750 } while (0);
1751
1752#define VISIT_LAZY_TYPE(CapitalName, lowerName, properName, instanceType, jsName, prototypeBase) \
1753 thisObject->m_ ## properName ## Structure.visit(visitor);
1754
1755 FOR_EACH_SIMPLE_BUILTIN_TYPE(VISIT_SIMPLE_TYPE)
1756 if (UNLIKELY(Options::useBigInt()))
1757 FOR_BIG_INT_BUILTIN_TYPE_WITH_CONSTRUCTOR(VISIT_SIMPLE_TYPE)
1758 FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(VISIT_SIMPLE_TYPE)
1759
1760 FOR_EACH_LAZY_BUILTIN_TYPE(VISIT_LAZY_TYPE)
1761
1762#if ENABLE(WEBASSEMBLY)
1763 thisObject->m_webAssemblyModuleRecordStructure.visit(visitor);
1764 thisObject->m_webAssemblyFunctionStructure.visit(visitor);
1765 thisObject->m_jsToWasmICCalleeStructure.visit(visitor);
1766 thisObject->m_webAssemblyWrapperFunctionStructure.visit(visitor);
1767 thisObject->m_webAssemblyToJSCalleeStructure.visit(visitor);
1768 FOR_EACH_WEBASSEMBLY_CONSTRUCTOR_TYPE(VISIT_LAZY_TYPE)
1769#endif // ENABLE(WEBASSEMBLY)
1770
1771#undef VISIT_SIMPLE_TYPE
1772#undef VISIT_LAZY_TYPE
1773
1774 for (unsigned i = NumberOfTypedArrayTypes; i--;)
1775 thisObject->lazyTypedArrayStructure(indexToTypedArrayType(i)).visit(visitor);
1776
1777 visitor.append(thisObject->m_speciesGetterSetter);
1778 thisObject->m_typedArrayProto.visit(visitor);
1779 thisObject->m_typedArraySuperConstructor.visit(visitor);
1780 thisObject->m_regExpGlobalData.visitAggregate(visitor);
1781}
1782
1783ExecState* JSGlobalObject::globalExec()
1784{
1785 return CallFrame::create(m_globalCallFrame);
1786}
1787
1788void JSGlobalObject::exposeDollarVM(VM& vm)
1789{
1790 if (hasOwnProperty(globalExec(), vm.propertyNames->builtinNames().dollarVMPrivateName()))
1791 return;
1792
1793 JSDollarVM* dollarVM = JSDollarVM::create(vm, JSDollarVM::createStructure(vm, this, m_objectPrototype.get()));
1794
1795 GlobalPropertyInfo extraStaticGlobals[] = {
1796 GlobalPropertyInfo(vm.propertyNames->builtinNames().dollarVMPrivateName(), dollarVM, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
1797 };
1798 addStaticGlobals(extraStaticGlobals, WTF_ARRAY_LENGTH(extraStaticGlobals));
1799
1800 putDirect(vm, Identifier::fromString(globalExec(), "$vm"), dollarVM, static_cast<unsigned>(PropertyAttribute::DontEnum));
1801}
1802
1803void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count)
1804{
1805 ScopeOffset startOffset = addVariables(count, jsUndefined());
1806
1807 for (int i = 0; i < count; ++i) {
1808 GlobalPropertyInfo& global = globals[i];
1809 // This `configurable = false` is necessary condition for static globals,
1810 // otherwise lexical bindings can change the result of GlobalVar queries too.
1811 // We won't be able to declare a global lexical variable with the sanem name to
1812 // the static globals because configurable = false.
1813 ASSERT(global.attributes & PropertyAttribute::DontDelete);
1814
1815 WatchpointSet* watchpointSet = nullptr;
1816 WriteBarrierBase<Unknown>* variable = nullptr;
1817 {
1818 ConcurrentJSLocker locker(symbolTable()->m_lock);
1819 ScopeOffset offset = symbolTable()->takeNextScopeOffset(locker);
1820 RELEASE_ASSERT(offset == startOffset + i);
1821 SymbolTableEntry newEntry(VarOffset(offset), global.attributes);
1822 newEntry.prepareToWatch();
1823 watchpointSet = newEntry.watchpointSet();
1824 symbolTable()->add(locker, global.identifier.impl(), WTFMove(newEntry));
1825 variable = &variableAt(offset);
1826 }
1827 symbolTablePutTouchWatchpointSet(vm(), this, global.identifier, global.value, variable, watchpointSet);
1828 }
1829}
1830
1831bool JSGlobalObject::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
1832{
1833 if (Base::getOwnPropertySlot(object, exec, propertyName, slot))
1834 return true;
1835 return symbolTableGet(jsCast<JSGlobalObject*>(object), propertyName, slot);
1836}
1837
1838void JSGlobalObject::clearRareData(JSCell* cell)
1839{
1840 jsCast<JSGlobalObject*>(cell)->m_rareData = nullptr;
1841}
1842
1843void JSGlobalObject::tryInstallArraySpeciesWatchpoint(ExecState* exec)
1844{
1845 RELEASE_ASSERT(!m_arrayPrototypeConstructorWatchpoint);
1846 RELEASE_ASSERT(!m_arrayConstructorSpeciesWatchpoint);
1847
1848 VM& vm = exec->vm();
1849 auto scope = DECLARE_THROW_SCOPE(vm);
1850
1851 // First we need to make sure that the Array.prototype.constructor property points to Array
1852 // and that Array[Symbol.species] is the primordial GetterSetter.
1853 ArrayPrototype* arrayPrototype = this->arrayPrototype();
1854
1855 // We only initialize once so flattening the structures does not have any real cost.
1856 Structure* prototypeStructure = arrayPrototype->structure(vm);
1857 if (prototypeStructure->isDictionary())
1858 prototypeStructure = prototypeStructure->flattenDictionaryStructure(vm, arrayPrototype);
1859 RELEASE_ASSERT(!prototypeStructure->isDictionary());
1860
1861 ArrayConstructor* arrayConstructor = this->arrayConstructor();
1862
1863 auto invalidateWatchpoint = [&] {
1864 m_arraySpeciesWatchpoint.invalidate(vm, StringFireDetail("Was not able to set up array species watchpoint."));
1865 };
1866
1867 PropertySlot constructorSlot(arrayPrototype, PropertySlot::InternalMethodType::VMInquiry);
1868 arrayPrototype->getOwnPropertySlot(arrayPrototype, exec, vm.propertyNames->constructor, constructorSlot);
1869 scope.assertNoException();
1870 if (constructorSlot.slotBase() != arrayPrototype
1871 || !constructorSlot.isCacheableValue()
1872 || constructorSlot.getValue(exec, vm.propertyNames->constructor) != arrayConstructor) {
1873 invalidateWatchpoint();
1874 return;
1875 }
1876
1877 Structure* constructorStructure = arrayConstructor->structure(vm);
1878 if (constructorStructure->isDictionary())
1879 constructorStructure = constructorStructure->flattenDictionaryStructure(vm, arrayConstructor);
1880
1881 PropertySlot speciesSlot(arrayConstructor, PropertySlot::InternalMethodType::VMInquiry);
1882 arrayConstructor->getOwnPropertySlot(arrayConstructor, exec, vm.propertyNames->speciesSymbol, speciesSlot);
1883 scope.assertNoException();
1884 if (speciesSlot.slotBase() != arrayConstructor
1885 || !speciesSlot.isCacheableGetter()
1886 || speciesSlot.getterSetter() != speciesGetterSetter()) {
1887 invalidateWatchpoint();
1888 return;
1889 }
1890
1891 // Now we need to setup the watchpoints to make sure these conditions remain valid.
1892 prototypeStructure->startWatchingPropertyForReplacements(vm, constructorSlot.cachedOffset());
1893 constructorStructure->startWatchingPropertyForReplacements(vm, speciesSlot.cachedOffset());
1894
1895 ObjectPropertyCondition constructorCondition = ObjectPropertyCondition::equivalence(vm, arrayPrototype, arrayPrototype, vm.propertyNames->constructor.impl(), arrayConstructor);
1896 ObjectPropertyCondition speciesCondition = ObjectPropertyCondition::equivalence(vm, arrayPrototype, arrayConstructor, vm.propertyNames->speciesSymbol.impl(), speciesGetterSetter());
1897
1898 if (!constructorCondition.isWatchable() || !speciesCondition.isWatchable()) {
1899 invalidateWatchpoint();
1900 return;
1901 }
1902
1903 // We only watch this from the DFG, and the DFG makes sure to only start watching if the watchpoint is in the IsWatched state.
1904 RELEASE_ASSERT(!m_arraySpeciesWatchpoint.isBeingWatched());
1905 m_arraySpeciesWatchpoint.touch(vm, "Set up array species watchpoint.");
1906
1907 m_arrayPrototypeConstructorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, constructorCondition, m_arraySpeciesWatchpoint);
1908 m_arrayPrototypeConstructorWatchpoint->install(vm);
1909
1910 m_arrayConstructorSpeciesWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, speciesCondition, m_arraySpeciesWatchpoint);
1911 m_arrayConstructorSpeciesWatchpoint->install(vm);
1912}
1913
1914void slowValidateCell(JSGlobalObject* globalObject)
1915{
1916 RELEASE_ASSERT(globalObject->isGlobalObject());
1917 ASSERT_GC_OBJECT_INHERITS(globalObject, JSGlobalObject::info());
1918}
1919
1920void JSGlobalObject::setRemoteDebuggingEnabled(bool enabled)
1921{
1922#if ENABLE(REMOTE_INSPECTOR)
1923 m_inspectorDebuggable->setRemoteDebuggingAllowed(enabled);
1924#else
1925 UNUSED_PARAM(enabled);
1926#endif
1927}
1928
1929bool JSGlobalObject::remoteDebuggingEnabled() const
1930{
1931#if ENABLE(REMOTE_INSPECTOR)
1932 return m_inspectorDebuggable->remoteDebuggingAllowed();
1933#else
1934 return false;
1935#endif
1936}
1937
1938void JSGlobalObject::setName(const String& name)
1939{
1940 m_name = name;
1941
1942#if ENABLE(REMOTE_INSPECTOR)
1943 m_inspectorDebuggable->update();
1944#endif
1945}
1946
1947# if ENABLE(INTL)
1948static void addMissingScriptLocales(HashSet<String>& availableLocales)
1949{
1950 if (availableLocales.contains("pa-Arab-PK"))
1951 availableLocales.add("pa-PK"_s);
1952 if (availableLocales.contains("zh-Hans-CN"))
1953 availableLocales.add("zh-CN"_s);
1954 if (availableLocales.contains("zh-Hant-HK"))
1955 availableLocales.add("zh-HK"_s);
1956 if (availableLocales.contains("zh-Hans-SG"))
1957 availableLocales.add("zh-SG"_s);
1958 if (availableLocales.contains("zh-Hant-TW"))
1959 availableLocales.add("zh-TW"_s);
1960}
1961
1962const HashSet<String>& JSGlobalObject::intlCollatorAvailableLocales()
1963{
1964 if (m_intlCollatorAvailableLocales.isEmpty()) {
1965 int32_t count = ucol_countAvailable();
1966 for (int32_t i = 0; i < count; ++i) {
1967 String locale = convertICULocaleToBCP47LanguageTag(ucol_getAvailable(i));
1968 if (!locale.isEmpty())
1969 m_intlCollatorAvailableLocales.add(locale);
1970 }
1971 addMissingScriptLocales(m_intlCollatorAvailableLocales);
1972 }
1973 return m_intlCollatorAvailableLocales;
1974}
1975
1976const HashSet<String>& JSGlobalObject::intlDateTimeFormatAvailableLocales()
1977{
1978 if (m_intlDateTimeFormatAvailableLocales.isEmpty()) {
1979 int32_t count = udat_countAvailable();
1980 for (int32_t i = 0; i < count; ++i) {
1981 String locale = convertICULocaleToBCP47LanguageTag(udat_getAvailable(i));
1982 if (!locale.isEmpty())
1983 m_intlDateTimeFormatAvailableLocales.add(locale);
1984 }
1985 addMissingScriptLocales(m_intlDateTimeFormatAvailableLocales);
1986 }
1987 return m_intlDateTimeFormatAvailableLocales;
1988}
1989
1990const HashSet<String>& JSGlobalObject::intlNumberFormatAvailableLocales()
1991{
1992 if (m_intlNumberFormatAvailableLocales.isEmpty()) {
1993 int32_t count = unum_countAvailable();
1994 for (int32_t i = 0; i < count; ++i) {
1995 String locale = convertICULocaleToBCP47LanguageTag(unum_getAvailable(i));
1996 if (!locale.isEmpty())
1997 m_intlNumberFormatAvailableLocales.add(locale);
1998 }
1999 addMissingScriptLocales(m_intlNumberFormatAvailableLocales);
2000 }
2001 return m_intlNumberFormatAvailableLocales;
2002}
2003
2004const HashSet<String>& JSGlobalObject::intlPluralRulesAvailableLocales()
2005{
2006 if (m_intlPluralRulesAvailableLocales.isEmpty()) {
2007 int32_t count = uloc_countAvailable();
2008 for (int32_t i = 0; i < count; ++i) {
2009 String locale = convertICULocaleToBCP47LanguageTag(uloc_getAvailable(i));
2010 if (!locale.isEmpty())
2011 m_intlPluralRulesAvailableLocales.add(locale);
2012 }
2013 addMissingScriptLocales(m_intlPluralRulesAvailableLocales);
2014 }
2015 return m_intlPluralRulesAvailableLocales;
2016}
2017
2018IntlCollator* JSGlobalObject::defaultCollator(ExecState* exec)
2019{
2020 VM& vm = exec->vm();
2021 auto scope = DECLARE_THROW_SCOPE(vm);
2022
2023 if (m_defaultCollator)
2024 return m_defaultCollator.get();
2025
2026 IntlCollator* collator = IntlCollator::create(vm, collatorStructure());
2027 collator->initializeCollator(*exec, jsUndefined(), jsUndefined());
2028 RETURN_IF_EXCEPTION(scope, nullptr);
2029 m_defaultCollator.set(vm, this, collator);
2030 return collator;
2031}
2032
2033#endif // ENABLE(INTL)
2034
2035void JSGlobalObject::bumpGlobalLexicalBindingEpoch(VM& vm)
2036{
2037 if (++m_globalLexicalBindingEpoch == Options::thresholdForGlobalLexicalBindingEpoch()) {
2038 // Since the epoch overflows, we should rewrite all the CodeBlock to adjust to the newly started generation.
2039 m_globalLexicalBindingEpoch = 1;
2040 vm.heap.codeBlockSet().iterate([&] (CodeBlock* codeBlock) {
2041 if (codeBlock->globalObject() != this)
2042 return;
2043 codeBlock->notifyLexicalBindingUpdate();
2044 });
2045 }
2046}
2047
2048void JSGlobalObject::queueMicrotask(Ref<Microtask>&& task)
2049{
2050 if (globalObjectMethodTable()->queueTaskToEventLoop) {
2051 globalObjectMethodTable()->queueTaskToEventLoop(*this, WTFMove(task));
2052 return;
2053 }
2054
2055 vm().queueMicrotask(*this, WTFMove(task));
2056}
2057
2058void JSGlobalObject::setDebugger(Debugger* debugger)
2059{
2060 m_debugger = debugger;
2061 if (debugger)
2062 vm().ensureShadowChicken();
2063}
2064
2065bool JSGlobalObject::hasDebugger() const
2066{
2067 return m_debugger;
2068}
2069
2070bool JSGlobalObject::hasInteractiveDebugger() const
2071{
2072 return m_debugger && m_debugger->isInteractivelyDebugging();
2073}
2074
2075#if ENABLE(DFG_JIT)
2076WatchpointSet* JSGlobalObject::getReferencedPropertyWatchpointSet(UniquedStringImpl* uid)
2077{
2078 ConcurrentJSLocker locker(m_referencedGlobalPropertyWatchpointSetsLock);
2079 return m_referencedGlobalPropertyWatchpointSets.get(uid);
2080}
2081
2082WatchpointSet& JSGlobalObject::ensureReferencedPropertyWatchpointSet(UniquedStringImpl* uid)
2083{
2084 ConcurrentJSLocker locker(m_referencedGlobalPropertyWatchpointSetsLock);
2085 return m_referencedGlobalPropertyWatchpointSets.ensure(uid, [] {
2086 return WatchpointSet::create(IsWatched);
2087 }).iterator->value.get();
2088}
2089#endif
2090
2091JSGlobalObject* JSGlobalObject::create(VM& vm, Structure* structure)
2092{
2093 JSGlobalObject* globalObject = new (NotNull, allocateCell<JSGlobalObject>(vm.heap)) JSGlobalObject(vm, structure);
2094 globalObject->finishCreation(vm);
2095 return globalObject;
2096}
2097
2098void JSGlobalObject::finishCreation(VM& vm)
2099{
2100 Base::finishCreation(vm);
2101 structure(vm)->setGlobalObject(vm, this);
2102 m_runtimeFlags = m_globalObjectMethodTable->javaScriptRuntimeFlags(this);
2103 init(vm);
2104 setGlobalThis(vm, JSNonDestructibleProxy::create(vm, JSNonDestructibleProxy::createStructure(vm, this, getPrototypeDirect(vm), PureForwardingProxyType), this));
2105 ASSERT(type() == GlobalObjectType);
2106}
2107
2108void JSGlobalObject::finishCreation(VM& vm, JSObject* thisValue)
2109{
2110 Base::finishCreation(vm);
2111 structure(vm)->setGlobalObject(vm, this);
2112 m_runtimeFlags = m_globalObjectMethodTable->javaScriptRuntimeFlags(this);
2113 init(vm);
2114 setGlobalThis(vm, thisValue);
2115 ASSERT(type() == GlobalObjectType);
2116}
2117
2118#ifdef JSC_GLIB_API_ENABLED
2119void JSGlobalObject::setWrapperMap(std::unique_ptr<WrapperMap>&& map)
2120{
2121 m_wrapperMap = WTFMove(map);
2122}
2123#endif
2124
2125} // namespace JSC
2126