Coverage Report

Created: 2023-11-19 07:23

/src/hermes/lib/VM/JSLib/GlobalObject.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) Meta Platforms, Inc. and affiliates.
3
 *
4
 * This source code is licensed under the MIT license found in the
5
 * LICENSE file in the root directory of this source tree.
6
 */
7
8
//===----------------------------------------------------------------------===//
9
/// \file
10
/// Initialize the global object ES5.1 15.1
11
//===----------------------------------------------------------------------===//
12
#include "hermes/Platform/Intl/PlatformIntl.h"
13
#include "hermes/VM/JSArrayBuffer.h"
14
#include "hermes/VM/JSDataView.h"
15
#include "hermes/VM/JSLib.h"
16
#include "hermes/VM/JSTypedArray.h"
17
#include "hermes/VM/Operations.h"
18
#include "hermes/VM/PrimitiveBox.h"
19
#include "hermes/VM/PropertyAccessor.h"
20
#include "hermes/VM/StringView.h"
21
22
#include "dtoa/dtoa.h"
23
24
#include "JSLibInternal.h"
25
26
namespace hermes {
27
namespace vm {
28
29
/// ES5.1 15.1.2.4
30
0
CallResult<HermesValue> isNaN(void *, Runtime &runtime, NativeArgs args) {
31
0
  auto res = toNumber_RJS(runtime, args.getArgHandle(0));
32
0
  if (LLVM_UNLIKELY(res == ExecutionStatus::EXCEPTION)) {
33
0
    return ExecutionStatus::EXCEPTION;
34
0
  }
35
0
  return HermesValue::encodeBoolValue(std::isnan(res->getNumber()));
36
0
}
37
38
/// ES5.1 15.1.2.5
39
0
CallResult<HermesValue> isFinite(void *, Runtime &runtime, NativeArgs args) {
40
0
  auto res = toNumber_RJS(runtime, args.getArgHandle(0));
41
0
  if (LLVM_UNLIKELY(res == ExecutionStatus::EXCEPTION)) {
42
0
    return ExecutionStatus::EXCEPTION;
43
0
  }
44
0
  auto value = res->getDouble();
45
0
  return HermesValue::encodeBoolValue(std::isfinite(value));
46
0
}
47
48
/// Needed to construct Function.prototype.
49
0
CallResult<HermesValue> emptyFunction(void *, Runtime &, NativeArgs) {
50
0
  return HermesValue::encodeUndefinedValue();
51
0
}
52
53
/// Given a character \p c in radix \p radix, checks if it's valid.
54
0
static bool isValidRadixChar(char16_t c, int radix) {
55
  // c is 0..9.
56
0
  if (c >= '0' && c <= '9') {
57
0
    return (radix >= 10 || c < '0' + radix);
58
0
  }
59
0
  c = letterToLower(c);
60
0
  return (radix > 10 && c >= 'a' && c < 'a' + radix - 10);
61
0
}
62
63
/// ES5.1 15.1.2.2 parseInt(string, radix)
64
0
CallResult<HermesValue> parseInt(void *, Runtime &runtime, NativeArgs args) {
65
  // toString(arg0).
66
0
  auto strRes = toString_RJS(runtime, args.getArgHandle(0));
67
0
  if (LLVM_UNLIKELY(strRes == ExecutionStatus::EXCEPTION)) {
68
0
    return ExecutionStatus::EXCEPTION;
69
0
  }
70
0
  auto str = runtime.makeHandle(std::move(*strRes));
71
72
0
  int radix = 10;
73
0
  bool stripPrefix = true;
74
  // If radix (arg1) is present and not undefined, toInt32_RJS(arg1).
75
0
  if (args.getArgCount() > 1 && !args.getArg(1).isUndefined()) {
76
0
    auto intRes = toInt32_RJS(runtime, args.getArgHandle(1));
77
0
    if (LLVM_UNLIKELY(intRes == ExecutionStatus::EXCEPTION)) {
78
0
      return ExecutionStatus::EXCEPTION;
79
0
    }
80
0
    radix = static_cast<int>(intRes->getNumber());
81
0
    if (radix == 0) {
82
0
      radix = 10;
83
0
    } else if (radix < 2 || radix > 36) {
84
0
      return HermesValue::encodeNaNValue();
85
0
    } else if (radix != 16) {
86
0
      stripPrefix = false;
87
0
    }
88
0
  }
89
90
0
  auto strView = StringPrimitive::createStringView(runtime, str);
91
0
  auto begin = strView.begin();
92
0
  auto end = strView.end();
93
94
  // Remove leading whitespaces.
95
0
  while (begin != end &&
96
0
         (isWhiteSpaceChar(*begin) || isLineTerminatorChar(*begin))) {
97
0
    ++begin;
98
0
  }
99
100
  // Process sign.
101
0
  int sign = 1;
102
0
  if (begin != end && (*begin == u'+' || *begin == u'-')) {
103
0
    if (*begin == u'-') {
104
0
      sign = -1;
105
0
    }
106
0
    ++begin;
107
0
  }
108
109
  // Strip 0x or 0X for 16-radix number.
110
0
  if (stripPrefix && begin != end) {
111
0
    if (*begin == u'0') {
112
0
      ++begin;
113
0
      if (begin != end && letterToLower(*begin) == u'x') {
114
0
        ++begin;
115
0
        radix = 16;
116
0
      } else {
117
0
        --begin;
118
0
      }
119
0
    }
120
0
  }
121
122
  // Find the longest prefix that's still a valid int.
123
0
  auto realEnd = begin;
124
0
  for (; realEnd != end && isValidRadixChar(*realEnd, radix); ++realEnd) {
125
0
  }
126
0
  if (realEnd == begin) {
127
    // Return NaN if string has no digits.
128
0
    return HermesValue::encodeNaNValue();
129
0
  }
130
131
0
  return HermesValue::encodeUntrustedNumberValue(
132
0
      sign * parseIntWithRadix(strView.slice(begin, realEnd), radix));
133
0
}
134
135
// Check if str1 is a prefix of str2.
136
0
static bool isPrefix(StringView str1, StringView str2) {
137
0
  if (str1.length() > str2.length()) {
138
0
    return false;
139
0
  }
140
0
  for (auto first1 = str1.begin(), last1 = str1.end(), first2 = str2.begin();
141
0
       first1 != last1;
142
0
       ++first1, ++first2) {
143
0
    if (*first1 != *first2) {
144
0
      return false;
145
0
    }
146
0
  }
147
0
  return true;
148
0
}
149
150
/// ES5.1 15.1.2.3 parseFloat(string)
151
0
CallResult<HermesValue> parseFloat(void *, Runtime &runtime, NativeArgs args) {
152
  // toString(arg0).
153
0
  auto res = toString_RJS(runtime, args.getArgHandle(0));
154
0
  if (LLVM_UNLIKELY(res == ExecutionStatus::EXCEPTION)) {
155
0
    return ExecutionStatus::EXCEPTION;
156
0
  }
157
158
0
  auto strHandle = runtime.makeHandle(std::move(*res));
159
0
  auto origStr = StringPrimitive::createStringView(runtime, strHandle);
160
161
0
  auto &idTable = runtime.getIdentifierTable();
162
163
  // Trim leading whitespaces.
164
0
  auto begin = origStr.begin();
165
0
  auto end = origStr.end();
166
167
0
  while (begin != end &&
168
0
         (isWhiteSpaceChar(*begin) || isLineTerminatorChar(*begin))) {
169
0
    ++begin;
170
0
  }
171
0
  StringView str16 = origStr.slice(begin, end);
172
173
  // Check for special values.
174
  // parseFloat allows for partial match, hence we have to check for
175
  // substring.
176
0
  if (LLVM_UNLIKELY(isPrefix(
177
0
          idTable.getStringView(
178
0
              runtime, Predefined::getSymbolID(Predefined::Infinity)),
179
0
          str16))) {
180
0
    return HermesValue::encodeUntrustedNumberValue(
181
0
        std::numeric_limits<double>::infinity());
182
0
  }
183
0
  if (LLVM_UNLIKELY(isPrefix(
184
0
          idTable.getStringView(
185
0
              runtime, Predefined::getSymbolID(Predefined::PositiveInfinity)),
186
0
          str16))) {
187
0
    return HermesValue::encodeUntrustedNumberValue(
188
0
        std::numeric_limits<double>::infinity());
189
0
  }
190
0
  if (LLVM_UNLIKELY(isPrefix(
191
0
          idTable.getStringView(
192
0
              runtime, Predefined::getSymbolID(Predefined::NegativeInfinity)),
193
0
          str16))) {
194
0
    return HermesValue::encodeUntrustedNumberValue(
195
0
        -std::numeric_limits<double>::infinity());
196
0
  }
197
0
  if (LLVM_UNLIKELY(isPrefix(
198
0
          idTable.getStringView(
199
0
              runtime, Predefined::getSymbolID(Predefined::NaN)),
200
0
          str16))) {
201
0
    return HermesValue::encodeNaNValue();
202
0
  }
203
204
  // Copy 16 bit chars into 8 bit chars as long as the character is
205
  // still a valid decimal number character.
206
0
  auto len = str16.length();
207
0
  llvh::SmallVector<char, 32> str8(len + 1);
208
0
  uint32_t i = 0;
209
0
  for (auto c : str16) {
210
0
    if ((c >= u'0' && c <= u'9') || c == '.' || letterToLower(c) == 'e' ||
211
0
        c == '+' || c == '-') {
212
0
      str8[i] = static_cast<char>(c);
213
0
    } else {
214
0
      break;
215
0
    }
216
0
    ++i;
217
0
  }
218
0
  if (i == 0) {
219
    // Empty string.
220
0
    return HermesValue::encodeNaNValue();
221
0
  }
222
  // Use hermes_g_strtod to figure out the longest prefix that's still valid.
223
  // hermes_g_strtod will try to convert the string to int for as long as it
224
  // can, and set endPtr to the last location where the prefix so far is still
225
  // a valid integer.
226
0
  len = i;
227
0
  str8[len] = '\0';
228
0
  char *endPtr;
229
0
  ::hermes_g_strtod(str8.data(), &endPtr);
230
0
  if (endPtr == str8.data()) {
231
    // Empty string.
232
0
    return HermesValue::encodeNaNValue();
233
0
  }
234
  // Now we know the prefix untill endPtr is a valid int.
235
0
  *endPtr = '\0';
236
0
  return HermesValue::encodeUntrustedNumberValue(
237
0
      ::hermes_g_strtod(str8.data(), &endPtr));
238
0
}
239
240
/// Customized global function. gc() forces a GC collect.
241
205
CallResult<HermesValue> gc(void *, Runtime &runtime, NativeArgs) {
242
205
  runtime.collect("forced");
243
205
  return HermesValue::encodeUndefinedValue();
244
205
}
245
246
CallResult<HermesValue>
247
0
throwTypeError(void *ctx, Runtime &runtime, NativeArgs) {
248
0
  static const char *TypeErrorMessage[] = {
249
0
      "Restricted in strict mode",
250
0
      "Dynamic requires are not allowed after static resolution",
251
0
  };
252
253
0
  uint64_t kind = (uint64_t)ctx;
254
0
  assert(
255
0
      kind < (uint64_t)TypeErrorKind::NumKinds &&
256
0
      "[[ThrowTypeError]] wrong error kind passed as context");
257
0
  return runtime.raiseTypeError(TypeErrorMessage[kind]);
258
0
}
259
260
// NOTE: when declaring more global symbols, don't forget to update
261
// "Libhermes.h".
262
105
void initGlobalObject(Runtime &runtime, const JSLibFlags &jsLibFlags) {
263
105
  GCScope gcScope{runtime, "initGlobalObject", 330};
264
265
  // Not enumerable, not writable, not configurable.
266
105
  DefinePropertyFlags constantDPF =
267
105
      DefinePropertyFlags::getDefaultNewPropertyFlags();
268
105
  constantDPF.enumerable = 0;
269
105
  constantDPF.writable = 0;
270
105
  constantDPF.configurable = 0;
271
272
  // Not enumerable, but writable and configurable.
273
105
  DefinePropertyFlags normalDPF =
274
105
      DefinePropertyFlags::getNewNonEnumerableFlags();
275
276
  // Not enumerable, not writable but configurable.
277
105
  DefinePropertyFlags configurableOnlyPDF =
278
105
      DefinePropertyFlags::getDefaultNewPropertyFlags();
279
105
  configurableOnlyPDF.enumerable = 0;
280
105
  configurableOnlyPDF.writable = 0;
281
282
  /// Clear the configurable flag.
283
105
  DefinePropertyFlags clearConfigurableDPF{};
284
105
  clearConfigurableDPF.setConfigurable = 1;
285
105
  clearConfigurableDPF.configurable = 0;
286
287
  // Define a function on the global object with name \p name.
288
  // Allocates a NativeObject and puts it in the global object.
289
105
  auto defineGlobalFunc =
290
1.36k
      [&](SymbolID name, NativeFunctionPtr functionPtr, unsigned paramCount) {
291
1.36k
        gcScope.clearAllHandles();
292
293
1.36k
        auto func = NativeFunction::createWithoutPrototype(
294
1.36k
            runtime, nullptr, functionPtr, name, paramCount);
295
1.36k
        runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
296
1.36k
            runtime.getGlobal(), runtime, name, normalDPF, func));
297
1.36k
        return func;
298
1.36k
      };
299
300
  // 15.1.1.1 NaN.
301
105
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
302
105
      runtime.getGlobal(),
303
105
      runtime,
304
105
      Predefined::getSymbolID(Predefined::NaN),
305
105
      constantDPF,
306
105
      runtime.makeHandle(HermesValue::encodeNaNValue())));
307
308
  // 15.1.1.2 Infinity.
309
105
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
310
105
      runtime.getGlobal(),
311
105
      runtime,
312
105
      Predefined::getSymbolID(Predefined::Infinity),
313
105
      constantDPF,
314
105
      runtime.makeHandle(HermesValue::encodeUntrustedNumberValue(
315
105
          std::numeric_limits<double>::infinity()))));
316
317
  // 15.1.1.2 undefined.
318
105
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
319
105
      runtime.getGlobal(),
320
105
      runtime,
321
105
      Predefined::getSymbolID(Predefined::undefined),
322
105
      constantDPF,
323
105
      runtime.makeHandle(HermesValue::encodeUndefinedValue())));
324
325
  // "Forward declaration" of Object.prototype. Its properties will be populated
326
  // later.
327
328
105
  runtime.objectPrototype =
329
105
      JSObject::create(runtime, Runtime::makeNullHandle<JSObject>())
330
105
          .getHermesValue();
331
105
  runtime.objectPrototypeRawPtr = vmcast<JSObject>(runtime.objectPrototype);
332
333
  // "Forward declaration" of Error.prototype. Its properties will be populated
334
  // later.
335
105
  runtime.ErrorPrototype = JSObject::create(runtime).getHermesValue();
336
337
// "Forward declaration" of the prototype for native error types. Their
338
// properties will be populated later.
339
105
#define NATIVE_ERROR_TYPE(name)                                       \
340
945
  runtime.name##Prototype =                                           \
341
945
      JSObject::create(                                               \
342
945
          runtime, Handle<JSObject>::vmcast(&runtime.ErrorPrototype)) \
343
945
          .getHermesValue();
344
105
#define AGGREGATE_ERROR_TYPE(name) NATIVE_ERROR_TYPE(name)
345
105
#include "hermes/FrontEndDefs/NativeErrorTypes.def"
346
347
  // "Forward declaration" of the internal CallSite prototype. Its properties
348
  // will be populated later.
349
105
  runtime.callSitePrototype =
350
105
      JSObject::create(
351
105
          runtime, Handle<JSObject>::vmcast(&runtime.objectPrototype))
352
105
          .getHermesValue();
353
354
  // "Forward declaration" of Function.prototype. Its properties will be
355
  // populated later.
356
105
  Handle<NativeFunction> funcRes = NativeFunction::create(
357
105
      runtime,
358
105
      Handle<JSObject>::vmcast(&runtime.objectPrototype),
359
105
      nullptr,
360
105
      emptyFunction,
361
105
      Predefined::getSymbolID(Predefined::emptyString),
362
105
      0,
363
105
      Runtime::makeNullHandle<JSObject>());
364
105
  runtime.functionPrototype = funcRes.getHermesValue();
365
105
  runtime.functionPrototypeRawPtr = funcRes.get();
366
105
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
367
105
      Handle<JSObject>::vmcast(&runtime.functionPrototype),
368
105
      runtime,
369
105
      Predefined::getSymbolID(Predefined::length),
370
105
      configurableOnlyPDF,
371
105
      Runtime::getZeroValue()));
372
373
  // [[ThrowTypeError]].
374
105
  auto throwTypeErrorFunction = NativeFunction::create(
375
105
      runtime,
376
105
      Handle<JSObject>::vmcast(&runtime.functionPrototype),
377
105
      (void *)TypeErrorKind::NonStrictOnly,
378
105
      throwTypeError,
379
105
      Predefined::getSymbolID(Predefined::emptyString),
380
105
      0,
381
105
      Runtime::makeNullHandle<JSObject>());
382
105
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
383
105
      throwTypeErrorFunction,
384
105
      runtime,
385
105
      Predefined::getSymbolID(Predefined::length),
386
105
      clearConfigurableDPF,
387
105
      Runtime::getUndefinedValue()));
388
105
  runtime.throwTypeErrorAccessor = PropertyAccessor::create(
389
105
      runtime, throwTypeErrorFunction, throwTypeErrorFunction);
390
391
  // Define the 'parseInt' function.
392
105
  runtime.parseIntFunction =
393
105
      defineGlobalFunc(
394
105
          Predefined::getSymbolID(Predefined::parseInt), parseInt, 2)
395
105
          .getHermesValue();
396
397
  // Define the 'parseFloat' function.
398
105
  runtime.parseFloatFunction =
399
105
      defineGlobalFunc(
400
105
          Predefined::getSymbolID(Predefined::parseFloat), parseFloat, 1)
401
105
          .getHermesValue();
402
403
  // "Forward declaration" of String.prototype. Its properties will be
404
  // populated later.
405
105
  runtime.stringPrototype =
406
105
      runtime
407
105
          .ignoreAllocationFailure(JSString::create(
408
105
              runtime,
409
105
              runtime.getPredefinedStringHandle(Predefined::emptyString),
410
105
              Handle<JSObject>::vmcast(&runtime.objectPrototype)))
411
105
          .getHermesValue();
412
413
  // "Forward declaration" of BigInt.prototype. Its properties will be
414
  // populated later.
415
105
  runtime.bigintPrototype = JSObject::create(runtime).getHermesValue();
416
417
  // "Forward declaration" of Number.prototype. Its properties will be
418
  // populated later.
419
105
  runtime.numberPrototype =
420
105
      JSNumber::create(
421
105
          runtime, +0.0, Handle<JSObject>::vmcast(&runtime.objectPrototype))
422
105
          .getHermesValue();
423
424
  // "Forward declaration" of Boolean.prototype. Its properties will be
425
  // populated later.
426
105
  runtime.booleanPrototype =
427
105
      JSBoolean::create(
428
105
          runtime, false, Handle<JSObject>::vmcast(&runtime.objectPrototype))
429
105
          .getHermesValue();
430
431
  // "Forward declaration" of Symbol.prototype. Its properties will be
432
  // populated later.
433
105
  runtime.symbolPrototype = JSObject::create(runtime).getHermesValue();
434
435
  // "Forward declaration" of Date.prototype. Its properties will be
436
  // populated later.
437
105
  runtime.datePrototype =
438
105
      JSObject::create(
439
105
          runtime, Handle<JSObject>::vmcast(&runtime.objectPrototype))
440
105
          .getHermesValue();
441
442
  // "Forward declaration" of %IteratorPrototype%.
443
105
  runtime.iteratorPrototype = JSObject::create(runtime).getHermesValue();
444
445
  // "Forward declaration" of Array.prototype. Its properties will be
446
  // populated later.
447
105
  runtime.arrayPrototype =
448
105
      runtime
449
105
          .ignoreAllocationFailure(JSArray::createNoAllocPropStorage(
450
105
              runtime,
451
105
              Handle<JSObject>::vmcast(&runtime.objectPrototype),
452
105
              JSArray::createClass(
453
105
                  runtime, Handle<JSObject>::vmcast(&runtime.objectPrototype)),
454
105
              0,
455
105
              0))
456
105
          .getHermesValue();
457
458
  // Declare the array class.
459
105
  runtime.arrayClass =
460
105
      JSArray::createClass(
461
105
          runtime, Handle<JSObject>::vmcast(&runtime.arrayPrototype))
462
105
          .getHermesValue();
463
464
  // Declare the regexp match object class.
465
105
  runtime.regExpMatchClass =
466
105
      JSRegExp::createMatchClass(
467
105
          runtime, Handle<HiddenClass>::vmcast(&runtime.arrayClass))
468
105
          .getHermesValue();
469
470
  // "Forward declaration" of ArrayBuffer.prototype. Its properties will be
471
  // populated later.
472
105
  runtime.arrayBufferPrototype =
473
105
      JSObject::create(
474
105
          runtime, Handle<JSObject>::vmcast(&runtime.objectPrototype))
475
105
          .getHermesValue();
476
477
  // "Forward declaration" of DataView.prototype. Its properties will be
478
  // populated later.
479
105
  runtime.dataViewPrototype =
480
105
      JSObject::create(
481
105
          runtime, Handle<JSObject>::vmcast(&runtime.objectPrototype))
482
105
          .getHermesValue();
483
484
  // "Forward declaration" of TypedArrayBase.prototype. Its properties will be
485
  // populated later.
486
105
  runtime.typedArrayBasePrototype = JSObject::create(runtime).getHermesValue();
487
488
// Typed arrays
489
// NOTE: a TypedArray's prototype is a normal object, not a TypedArray.
490
105
#define TYPED_ARRAY(name, type)                                                \
491
1.15k
  runtime.name##ArrayPrototype =                                               \
492
1.15k
      JSObject::create(                                                        \
493
1.15k
          runtime, Handle<JSObject>::vmcast(&runtime.typedArrayBasePrototype)) \
494
1.15k
          .getHermesValue();
495
105
#include "hermes/VM/TypedArrays.def"
496
497
  // "Forward declaration" of Set.prototype. Its properties will be
498
  // populated later.
499
105
  runtime.setPrototype = JSObject::create(runtime).getHermesValue();
500
501
105
  runtime.setIteratorPrototype =
502
105
      createSetIteratorPrototype(runtime).getHermesValue();
503
504
  // "Forward declaration" of Map.prototype. Its properties will be
505
  // populated later.
506
105
  runtime.mapPrototype = JSObject::create(runtime).getHermesValue();
507
508
105
  runtime.mapIteratorPrototype =
509
105
      createMapIteratorPrototype(runtime).getHermesValue();
510
511
  // "Forward declaration" of RegExp.prototype.
512
  // ES6: 21.2.5 "The RegExp prototype object is an ordinary object. It is not a
513
  // RegExp instance..."
514
105
  runtime.regExpPrototype =
515
105
      JSObject::create(
516
105
          runtime, Handle<JSObject>::vmcast(&runtime.objectPrototype))
517
105
          .getHermesValue();
518
519
  // "Forward declaration" of WeakMap.prototype.
520
105
  runtime.weakMapPrototype = JSObject::create(runtime).getHermesValue();
521
522
  // "Forward declaration" of WeakSet.prototype.
523
105
  runtime.weakSetPrototype = JSObject::create(runtime).getHermesValue();
524
525
  // Only define WeakRef if microtasks are being used.
526
105
  if (LLVM_UNLIKELY(runtime.hasMicrotaskQueue())) {
527
    // "Forward declaration" of WeakRef.prototype.
528
0
    runtime.weakRefPrototype = JSObject::create(runtime).getHermesValue();
529
0
  }
530
531
  // "Forward declaration" of %ArrayIteratorPrototype%.
532
105
  runtime.arrayIteratorPrototype =
533
105
      JSObject::create(
534
105
          runtime, Handle<JSObject>::vmcast(&runtime.iteratorPrototype))
535
105
          .getHermesValue();
536
537
  // "Forward declaration" of %StringIteratorPrototype%.
538
105
  runtime.stringIteratorPrototype =
539
105
      JSObject::create(
540
105
          runtime, Handle<JSObject>::vmcast(&runtime.iteratorPrototype))
541
105
          .getHermesValue();
542
543
  // "Forward declaration" of %RegExpStringIteratorPrototype%.
544
105
  runtime.regExpStringIteratorPrototype =
545
105
      JSObject::create(
546
105
          runtime, Handle<JSObject>::vmcast(&runtime.iteratorPrototype))
547
105
          .getHermesValue();
548
549
  // "Forward declaration" of "Generator prototype object"
550
105
  runtime.generatorPrototype =
551
105
      JSObject::create(
552
105
          runtime, Handle<JSObject>::vmcast(&runtime.iteratorPrototype))
553
105
          .getHermesValue();
554
555
  // "Forward declaration" of %GeneratorFunction.prototype%
556
105
  runtime.generatorFunctionPrototype =
557
105
      JSObject::create(
558
105
          runtime, Handle<JSObject>::vmcast(&runtime.functionPrototype))
559
105
          .getHermesValue();
560
561
  // "Forward declaration" of %AsyncFunction.prototype%
562
105
  runtime.asyncFunctionPrototype =
563
105
      JSObject::create(
564
105
          runtime, Handle<JSObject>::vmcast(&runtime.functionPrototype))
565
105
          .getHermesValue();
566
567
  // Object constructor.
568
105
  createObjectConstructor(runtime);
569
570
  // JSError constructor.
571
105
  runtime.errorConstructor = createErrorConstructor(runtime).getHermesValue();
572
573
// All Native Error constructors.
574
105
#define NATIVE_ERROR_TYPE(name)                            \
575
945
  runtime.name##Constructor =                              \
576
945
      create##name##Constructor(runtime).getHermesValue(); \
577
945
  gcScope.clearAllHandles();
578
105
#define AGGREGATE_ERROR_TYPE(name) NATIVE_ERROR_TYPE(name)
579
105
#include "hermes/FrontEndDefs/NativeErrorTypes.def"
580
581
  // Populate the internal CallSite prototype.
582
105
  populateCallSitePrototype(runtime);
583
584
  // String constructor.
585
105
  createStringConstructor(runtime);
586
587
  // BigInt constructor.
588
105
  createBigIntConstructor(runtime);
589
590
  // Function constructor.
591
105
  runtime.functionConstructor =
592
105
      createFunctionConstructor(runtime).getHermesValue();
593
594
  // Number constructor.
595
105
  createNumberConstructor(runtime);
596
597
  // Boolean constructor.
598
105
  createBooleanConstructor(runtime);
599
600
  // Date constructor.
601
105
  createDateConstructor(runtime);
602
603
  // RegExp constructor
604
105
  createRegExpConstructor(runtime);
605
105
  runtime.regExpLastInput = HermesValue::encodeUndefinedValue();
606
105
  runtime.regExpLastRegExp = HermesValue::encodeUndefinedValue();
607
608
  // Array constructor.
609
105
  createArrayConstructor(runtime);
610
611
105
  if (runtime.hasArrayBuffer()) {
612
    // ArrayBuffer constructor.
613
105
    createArrayBufferConstructor(runtime);
614
615
    // DataView constructor.
616
105
    createDataViewConstructor(runtime);
617
618
    // TypedArrayBase constructor.
619
105
    runtime.typedArrayBaseConstructor =
620
105
        createTypedArrayBaseConstructor(runtime).getHermesValue();
621
622
105
#define TYPED_ARRAY(name, type)                                 \
623
1.15k
  runtime.name##ArrayConstructor =                              \
624
1.15k
      create##name##ArrayConstructor(runtime).getHermesValue(); \
625
1.15k
  gcScope.clearAllHandles();
626
105
#include "hermes/VM/TypedArrays.def"
627
105
  } else {
628
0
    gcScope.clearAllHandles();
629
0
  } // hasArrayBuffer
630
631
  // Set constructor.
632
105
  createSetConstructor(runtime);
633
634
  // Map constructor.
635
105
  createMapConstructor(runtime);
636
637
  // WeakMap constructor.
638
105
  createWeakMapConstructor(runtime);
639
640
  // WeakSet constructor.
641
105
  createWeakSetConstructor(runtime);
642
643
  // Only define WeakRef constructor if microtasks are being used.
644
105
  if (LLVM_UNLIKELY(runtime.hasMicrotaskQueue())) {
645
    // WeakRef constructor.
646
0
    createWeakRefConstructor(runtime);
647
0
  }
648
649
  // Symbol constructor.
650
105
  createSymbolConstructor(runtime);
651
652
  /// %IteratorPrototype%.
653
105
  populateIteratorPrototype(runtime);
654
655
  /// Array Iterator.
656
105
  populateArrayIteratorPrototype(runtime);
657
658
  /// String Iterator.
659
105
  populateStringIteratorPrototype(runtime);
660
661
  /// RegExp String Iterator.
662
105
  populateRegExpStringIteratorPrototype(runtime);
663
664
  // GeneratorFunction constructor (not directly exposed in the global object).
665
105
  createGeneratorFunctionConstructor(runtime);
666
667
  // AsyncFunction constructor (not directly exposed in the global object).
668
105
  createAsyncFunctionConstructor(runtime);
669
670
  // %GeneratorPrototype%.
671
105
  populateGeneratorPrototype(runtime);
672
673
  // Proxy constructor.
674
105
  if (LLVM_UNLIKELY(runtime.hasES6Proxy())) {
675
105
    createProxyConstructor(runtime);
676
105
  }
677
678
  // Define the global Math object
679
105
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
680
105
      runtime.getGlobal(),
681
105
      runtime,
682
105
      Predefined::getSymbolID(Predefined::Math),
683
105
      normalDPF,
684
105
      createMathObject(runtime)));
685
686
  // Define the global JSON object
687
105
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
688
105
      runtime.getGlobal(),
689
105
      runtime,
690
105
      Predefined::getSymbolID(Predefined::JSON),
691
105
      normalDPF,
692
105
      createJSONObject(runtime)));
693
694
105
  if (LLVM_UNLIKELY(runtime.hasES6Proxy())) {
695
    // Define the global Reflect object
696
105
    runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
697
105
        runtime.getGlobal(),
698
105
        runtime,
699
105
        Predefined::getSymbolID(Predefined::Reflect),
700
105
        normalDPF,
701
105
        createReflectObject(runtime)));
702
105
  }
703
704
  // Define the global %HermesInternal object.
705
105
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
706
105
      runtime.getGlobal(),
707
105
      runtime,
708
105
      Predefined::getSymbolID(Predefined::HermesInternal),
709
105
      constantDPF,
710
105
      createHermesInternalObject(runtime, jsLibFlags)));
711
712
105
#ifdef HERMES_ENABLE_DEBUGGER
713
714
  // Define the global %DebuggerInternal object.
715
105
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
716
105
      runtime.getGlobal(),
717
105
      runtime,
718
105
      runtime.getIdentifierTable().registerLazyIdentifier(
719
105
          createASCIIRef("DebuggerInternal")),
720
105
      constantDPF,
721
105
      createDebuggerInternalObject(runtime)));
722
723
105
#endif // HERMES_ENABLE_DEBUGGER
724
725
  // Define the 'print' function.
726
105
  defineGlobalFunc(Predefined::getSymbolID(Predefined::print), print, 1);
727
728
  // Define the 'eval' function.
729
105
  defineGlobalFunc(Predefined::getSymbolID(Predefined::eval), eval, 1);
730
731
  // Define the 'isNaN' function.
732
105
  defineGlobalFunc(Predefined::getSymbolID(Predefined::isNaN), isNaN, 1);
733
734
  // Define the 'isFinite' function.
735
105
  defineGlobalFunc(Predefined::getSymbolID(Predefined::isFinite), isFinite, 1);
736
737
  // Define the 'escape' function.
738
105
  defineGlobalFunc(Predefined::getSymbolID(Predefined::escape), escape, 1);
739
740
  // Define the 'unescape' function.
741
105
  defineGlobalFunc(Predefined::getSymbolID(Predefined::unescape), unescape, 1);
742
743
  // Define the 'decodeURI' function.
744
105
  defineGlobalFunc(
745
105
      Predefined::getSymbolID(Predefined::decodeURI), decodeURI, 1);
746
747
  // Define the 'decodeURIComponent' function.
748
105
  defineGlobalFunc(
749
105
      Predefined::getSymbolID(Predefined::decodeURIComponent),
750
105
      decodeURIComponent,
751
105
      1);
752
753
  // Define the 'encodeURI' function.
754
105
  defineGlobalFunc(
755
105
      Predefined::getSymbolID(Predefined::encodeURI), encodeURI, 1);
756
757
  // Define the 'encodeURIComponent' function.
758
105
  defineGlobalFunc(
759
105
      Predefined::getSymbolID(Predefined::encodeURIComponent),
760
105
      encodeURIComponent,
761
105
      1);
762
763
  // Define the 'globalThis' property.
764
105
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
765
105
      runtime.getGlobal(),
766
105
      runtime,
767
105
      Predefined::getSymbolID(Predefined::globalThis),
768
105
      normalDPF,
769
105
      runtime.getGlobal()));
770
771
  // Define the 'require' function.
772
105
  runtime.requireFunction =
773
105
      NativeFunction::create(
774
105
          runtime,
775
105
          Handle<JSObject>::vmcast(&runtime.functionPrototype),
776
105
          nullptr,
777
105
          require,
778
105
          Predefined::getSymbolID(Predefined::require),
779
105
          1,
780
105
          Runtime::makeNullHandle<JSObject>())
781
105
          .getHermesValue();
782
783
105
  if (jsLibFlags.enableHermesInternal) {
784
    // Define the 'gc' function.
785
105
    defineGlobalFunc(Predefined::getSymbolID(Predefined::gc), gc, 0);
786
105
  }
787
788
#ifdef HERMES_ENABLE_IR_INSTRUMENTATION
789
  // Define the global __instrument object
790
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
791
      runtime.getGlobal(),
792
      runtime,
793
      runtime.getIdentifierTable().registerLazyIdentifier(
794
          createASCIIRef("__instrument")),
795
      normalDPF,
796
      createInstrumentObject(runtime)));
797
#endif
798
799
#ifdef HERMES_ENABLE_INTL
800
  // Define the global Intl object
801
  // TODO T65916424: Consider how we can move this somewhere more modular.
802
  if (runtime.hasIntl()) {
803
    runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
804
        runtime.getGlobal(),
805
        runtime,
806
        Predefined::getSymbolID(Predefined::Intl),
807
        normalDPF,
808
        intl::createIntlObject(runtime)));
809
  }
810
#endif
811
105
}
812
813
} // namespace vm
814
} // namespace hermes