Coverage Report

Created: 2025-12-12 07:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hermes/lib/VM/Callable.cpp
Line
Count
Source
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
#include "hermes/VM/Callable.h"
9
10
#include "hermes/VM/ArrayLike.h"
11
#include "hermes/VM/BuildMetadata.h"
12
#include "hermes/VM/JSDataView.h"
13
#include "hermes/VM/JSDate.h"
14
#include "hermes/VM/JSError.h"
15
#include "hermes/VM/JSMapImpl.h"
16
#include "hermes/VM/JSNativeFunctions.h"
17
#include "hermes/VM/JSProxy.h"
18
#include "hermes/VM/JSRegExp.h"
19
#include "hermes/VM/JSTypedArray.h"
20
#include "hermes/VM/JSWeakMapImpl.h"
21
#include "hermes/VM/JSWeakRef.h"
22
#include "hermes/VM/PrimitiveBox.h"
23
#include "hermes/VM/PropertyAccessor.h"
24
#include "hermes/VM/SmallXString.h"
25
#include "hermes/VM/StackFrame-inline.h"
26
#include "hermes/VM/StringPrimitive.h"
27
28
#include "llvh/ADT/ArrayRef.h"
29
#pragma GCC diagnostic push
30
31
#ifdef HERMES_COMPILER_SUPPORTS_WSHORTEN_64_TO_32
32
#pragma GCC diagnostic ignored "-Wshorten-64-to-32"
33
#endif
34
namespace hermes {
35
namespace vm {
36
37
//===----------------------------------------------------------------------===//
38
// class Environment
39
40
const VTable Environment::vt{CellKind::EnvironmentKind, 0};
41
42
1
void EnvironmentBuildMeta(const GCCell *cell, Metadata::Builder &mb) {
43
1
  const auto *self = static_cast<const Environment *>(cell);
44
1
  mb.setVTable(&Environment::vt);
45
1
  mb.addField("parentEnvironment", &self->parentEnvironment_);
46
1
  mb.addArray(self->getSlots(), &self->size_, sizeof(GCHermesValue));
47
1
}
48
49
//===----------------------------------------------------------------------===//
50
// class Callable
51
52
9
void CallableBuildMeta(const GCCell *cell, Metadata::Builder &mb) {
53
9
  mb.addJSObjectOverlapSlots(JSObject::numOverlapSlots<Callable>());
54
9
  JSObjectBuildMeta(cell, mb);
55
9
  const auto *self = static_cast<const Callable *>(cell);
56
9
  mb.setVTable(&Callable::vt);
57
9
  mb.addField("environment", &self->environment_);
58
9
}
59
60
#ifdef HERMES_MEMORY_INSTRUMENTATION
61
0
std::string Callable::_snapshotNameImpl(GCCell *cell, GC &gc) {
62
0
  auto *const self = reinterpret_cast<Callable *>(cell);
63
0
  return self->getNameIfExists(gc.getPointerBase());
64
0
}
65
#endif
66
67
CallResult<PseudoHandle<JSObject>> Callable::_newObjectImpl(
68
    Handle<Callable> /*selfHandle*/,
69
    Runtime &runtime,
70
678
    Handle<JSObject> parentHandle) {
71
678
  return JSObject::create(runtime, parentHandle);
72
678
}
73
74
347
void Callable::defineLazyProperties(Handle<Callable> fn, Runtime &runtime) {
75
  // lazy functions can be Bound or JS Functions.
76
347
  if (auto jsFun = Handle<JSFunction>::dyn_vmcast(fn)) {
77
347
    const CodeBlock *codeBlock = jsFun->getCodeBlock(runtime);
78
    // Create empty object for prototype.
79
347
    auto prototypeParent = vmisa<JSGeneratorFunction>(*jsFun)
80
347
        ? Handle<JSObject>::vmcast(&runtime.generatorPrototype)
81
347
        : Handle<JSObject>::vmcast(&runtime.objectPrototype);
82
83
    // According to ES12 26.7.4, AsyncFunction instances do not have a
84
    // 'prototype' property, hence we need to set an null handle here.
85
    // Functions that cannot be used with `new` should also not define a
86
    // 'prototype' property, such as arrow functions per 15.3.4, except for
87
    // generator functions.
88
347
    auto prototypeObjectHandle =
89
347
        codeBlock->getHeaderFlags().isCallProhibited(/* construct */ true) &&
90
0
            !vmisa<JSGeneratorFunction>(*jsFun)
91
347
        ? Runtime::makeNullHandle<JSObject>()
92
347
        : runtime.makeHandle(JSObject::create(runtime, prototypeParent));
93
94
347
    auto cr = Callable::defineNameLengthAndPrototype(
95
347
        fn,
96
347
        runtime,
97
347
        codeBlock->getNameMayAllocate(),
98
347
        codeBlock->getParamCount() - 1,
99
347
        prototypeObjectHandle,
100
347
        Callable::WritablePrototype::Yes,
101
347
        codeBlock->isStrictMode());
102
347
    assert(
103
347
        cr != ExecutionStatus::EXCEPTION && "failed to define length and name");
104
347
    (void)cr;
105
347
  } else {
106
    // no other kind of function can be lazy currently
107
0
    assert(false && "invalid lazy function");
108
0
  }
109
347
}
110
111
ExecutionStatus Callable::defineNameLengthAndPrototype(
112
    Handle<Callable> selfHandle,
113
    Runtime &runtime,
114
    SymbolID name,
115
    unsigned paramCount,
116
    Handle<JSObject> prototypeObjectHandle,
117
    WritablePrototype writablePrototype,
118
54.9k
    bool strictMode) {
119
54.9k
  PropertyFlags pf;
120
54.9k
  pf.clear();
121
54.9k
  pf.enumerable = 0;
122
54.9k
  pf.writable = 0;
123
54.9k
  pf.configurable = 1;
124
125
54.9k
  GCScope scope{runtime, "defineNameLengthAndPrototype"};
126
127
54.9k
  namespace P = Predefined;
128
/// Adds a property to the object in \p OBJ_HANDLE.  \p SYMBOL provides its name
129
/// as a \c Predefined enum value, and its value is  rooted in \p HANDLE.  If
130
/// property definition fails, the exceptional execution status will be
131
/// propagated to the outer function.
132
54.9k
#define DEFINE_PROP(OBJ_HANDLE, SYMBOL, HANDLE)                            \
133
120k
  do {                                                                     \
134
120k
    auto status = JSObject::defineNewOwnProperty(                          \
135
120k
        OBJ_HANDLE, runtime, Predefined::getSymbolID(SYMBOL), pf, HANDLE); \
136
120k
    if (LLVM_UNLIKELY(status == ExecutionStatus::EXCEPTION)) {             \
137
0
      return ExecutionStatus::EXCEPTION;                                   \
138
0
    }                                                                      \
139
120k
  } while (false)
140
141
54.9k
  assert(name.isValid() && "A name must always be provided");
142
143
  // Length is the number of formal arguments.
144
  // 10.2.9 SetFunctionLength is performed during 10.2.3 OrdinaryFunctionCreate.
145
54.9k
  auto lengthHandle =
146
54.9k
      runtime.makeHandle(HermesValue::encodeUntrustedNumberValue(paramCount));
147
54.9k
  DEFINE_PROP(selfHandle, P::length, lengthHandle);
148
149
  // Define the name.
150
  // 10.2.8 SetFunctionName is performed after 10.2.3 OrdinaryFunctionCreate.
151
54.9k
  auto nameHandle = runtime.makeHandle(runtime.getStringPrimFromSymbolID(name));
152
54.9k
  DEFINE_PROP(selfHandle, P::name, nameHandle);
153
154
54.9k
  if (strictMode) {
155
    // Define .callee and .arguments properties: throw always in strict mode.
156
226
    auto accessor =
157
226
        Handle<PropertyAccessor>::vmcast(&runtime.throwTypeErrorAccessor);
158
159
226
    pf.clear();
160
226
    pf.enumerable = 0;
161
226
    pf.configurable = 0;
162
226
    pf.accessor = 1;
163
164
226
    DEFINE_PROP(selfHandle, P::caller, accessor);
165
226
    DEFINE_PROP(selfHandle, P::arguments, accessor);
166
226
  }
167
168
54.9k
  if (prototypeObjectHandle) {
169
    // Set its 'prototype' property.
170
4.98k
    pf.clear();
171
4.98k
    pf.enumerable = 0;
172
    /// System constructors have read-only prototypes.
173
4.98k
    pf.writable = (uint8_t)writablePrototype;
174
4.98k
    pf.configurable = 0;
175
4.98k
    DEFINE_PROP(selfHandle, P::prototype, prototypeObjectHandle);
176
177
4.98k
    if (LLVM_LIKELY(!vmisa<JSGeneratorFunction>(*selfHandle))) {
178
      // Set the 'constructor' property in the prototype object.
179
      // This must not be set for GeneratorFunctions, because
180
      // prototypes must not point back to their constructors.
181
      // See the diagram: ES9.0 25.2 (GeneratorFunction objects).
182
4.98k
      pf.clear();
183
4.98k
      pf.enumerable = 0;
184
4.98k
      pf.writable = 1;
185
4.98k
      pf.configurable = 1;
186
4.98k
      DEFINE_PROP(prototypeObjectHandle, P::constructor, selfHandle);
187
4.98k
    }
188
4.98k
  }
189
190
54.9k
  return ExecutionStatus::RETURNED;
191
192
54.9k
#undef DEFINE_PROP
193
54.9k
}
194
195
/// Execute this function with no arguments. This is just a convenience
196
/// helper method; it actually invokes the interpreter recursively.
197
CallResult<PseudoHandle<>> Callable::executeCall0(
198
    Handle<Callable> selfHandle,
199
    Runtime &runtime,
200
    Handle<> thisArgHandle,
201
856k
    bool construct) {
202
856k
  ScopedNativeCallFrame newFrame{
203
856k
      runtime,
204
856k
      0,
205
856k
      selfHandle.getHermesValue(),
206
856k
      construct ? selfHandle.getHermesValue()
207
856k
                : HermesValue::encodeUndefinedValue(),
208
856k
      *thisArgHandle};
209
856k
  if (LLVM_UNLIKELY(newFrame.overflowed()))
210
0
    return runtime.raiseStackOverflow(Runtime::StackOverflowKind::NativeStack);
211
856k
  return call(selfHandle, runtime);
212
856k
}
213
214
/// Execute this function with one argument. This is just a convenience
215
/// helper method; it actually invokes the interpreter recursively.
216
CallResult<PseudoHandle<>> Callable::executeCall1(
217
    Handle<Callable> selfHandle,
218
    Runtime &runtime,
219
    Handle<> thisArgHandle,
220
    HermesValue param1,
221
0
    bool construct) {
222
0
  ScopedNativeCallFrame newFrame{
223
0
      runtime,
224
0
      1,
225
0
      selfHandle.getHermesValue(),
226
0
      construct ? selfHandle.getHermesValue()
227
0
                : HermesValue::encodeUndefinedValue(),
228
0
      *thisArgHandle};
229
0
  if (LLVM_UNLIKELY(newFrame.overflowed()))
230
0
    return runtime.raiseStackOverflow(Runtime::StackOverflowKind::NativeStack);
231
0
  newFrame->getArgRef(0) = param1;
232
0
  return call(selfHandle, runtime);
233
0
}
234
235
/// Execute this function with two arguments. This is just a convenience
236
/// helper method; it actually invokes the interpreter recursively.
237
CallResult<PseudoHandle<>> Callable::executeCall2(
238
    Handle<Callable> selfHandle,
239
    Runtime &runtime,
240
    Handle<> thisArgHandle,
241
    HermesValue param1,
242
    HermesValue param2,
243
0
    bool construct) {
244
0
  ScopedNativeCallFrame newFrame{
245
0
      runtime,
246
0
      2,
247
0
      selfHandle.getHermesValue(),
248
0
      construct ? selfHandle.getHermesValue()
249
0
                : HermesValue::encodeUndefinedValue(),
250
0
      *thisArgHandle};
251
0
  if (LLVM_UNLIKELY(newFrame.overflowed()))
252
0
    return runtime.raiseStackOverflow(Runtime::StackOverflowKind::NativeStack);
253
0
  newFrame->getArgRef(0) = param1;
254
0
  newFrame->getArgRef(1) = param2;
255
0
  return call(selfHandle, runtime);
256
0
}
257
258
/// Execute this function with three arguments. This is just a convenience
259
/// helper method; it actually invokes the interpreter recursively.
260
CallResult<PseudoHandle<>> Callable::executeCall3(
261
    Handle<Callable> selfHandle,
262
    Runtime &runtime,
263
    Handle<> thisArgHandle,
264
    HermesValue param1,
265
    HermesValue param2,
266
    HermesValue param3,
267
0
    bool construct) {
268
0
  ScopedNativeCallFrame newFrame{
269
0
      runtime,
270
0
      3,
271
0
      selfHandle.getHermesValue(),
272
0
      construct ? selfHandle.getHermesValue()
273
0
                : HermesValue::encodeUndefinedValue(),
274
0
      *thisArgHandle};
275
0
  if (LLVM_UNLIKELY(newFrame.overflowed()))
276
0
    return runtime.raiseStackOverflow(Runtime::StackOverflowKind::NativeStack);
277
0
  newFrame->getArgRef(0) = param1;
278
0
  newFrame->getArgRef(1) = param2;
279
0
  newFrame->getArgRef(2) = param3;
280
0
  return call(selfHandle, runtime);
281
0
}
282
283
/// Execute this function with four arguments. This is just a convenience
284
/// helper method; it actually invokes the interpreter recursively.
285
CallResult<PseudoHandle<>> Callable::executeCall4(
286
    Handle<Callable> selfHandle,
287
    Runtime &runtime,
288
    Handle<> thisArgHandle,
289
    HermesValue param1,
290
    HermesValue param2,
291
    HermesValue param3,
292
    HermesValue param4,
293
0
    bool construct) {
294
0
  ScopedNativeCallFrame newFrame{
295
0
      runtime,
296
0
      4,
297
0
      selfHandle.getHermesValue(),
298
0
      construct ? selfHandle.getHermesValue()
299
0
                : HermesValue::encodeUndefinedValue(),
300
0
      *thisArgHandle};
301
0
  if (LLVM_UNLIKELY(newFrame.overflowed()))
302
0
    return runtime.raiseStackOverflow(Runtime::StackOverflowKind::NativeStack);
303
0
  newFrame->getArgRef(0) = param1;
304
0
  newFrame->getArgRef(1) = param2;
305
0
  newFrame->getArgRef(2) = param3;
306
0
  newFrame->getArgRef(3) = param4;
307
0
  return call(selfHandle, runtime);
308
0
}
309
310
CallResult<PseudoHandle<>> Callable::executeCall(
311
    Handle<Callable> selfHandle,
312
    Runtime &runtime,
313
    Handle<> newTarget,
314
    Handle<> thisArgument,
315
0
    Handle<JSObject> arrayLike) {
316
0
  CallResult<uint64_t> nRes = getArrayLikeLength_RJS(arrayLike, runtime);
317
0
  if (LLVM_UNLIKELY(nRes == ExecutionStatus::EXCEPTION)) {
318
0
    return ExecutionStatus::EXCEPTION;
319
0
  }
320
0
  if (*nRes > UINT32_MAX) {
321
0
    return runtime.raiseRangeError("Too many arguments for apply");
322
0
  }
323
0
  uint32_t n = static_cast<uint32_t>(*nRes);
324
0
  ScopedNativeCallFrame newFrame{
325
0
      runtime, n, selfHandle.getHermesValue(), *newTarget, *thisArgument};
326
0
  if (LLVM_UNLIKELY(newFrame.overflowed()))
327
0
    return runtime.raiseStackOverflow(Runtime::StackOverflowKind::NativeStack);
328
329
  // Initialize the arguments to undefined because we might allocate and cause
330
  // a gc while populating them.
331
  // TODO: look into doing this lazily.
332
0
  newFrame.fillArguments(n, HermesValue::encodeUndefinedValue());
333
334
0
  if (LLVM_UNLIKELY(
335
0
          createListFromArrayLike_RJS(
336
0
              arrayLike,
337
0
              runtime,
338
0
              n,
339
0
              [&newFrame](Runtime &, uint64_t index, PseudoHandle<> value) {
340
0
                newFrame->getArgRef(index) = value.getHermesValue();
341
0
                return ExecutionStatus::RETURNED;
342
0
              }) == ExecutionStatus::EXCEPTION)) {
343
0
    return ExecutionStatus::EXCEPTION;
344
0
  }
345
346
0
  return Callable::call(selfHandle, runtime);
347
0
}
348
349
CallResult<PseudoHandle<>> Callable::executeConstruct0(
350
    Handle<Callable> selfHandle,
351
0
    Runtime &runtime) {
352
0
  auto thisVal = Callable::createThisForConstruct_RJS(selfHandle, runtime);
353
0
  if (LLVM_UNLIKELY(thisVal == ExecutionStatus::EXCEPTION)) {
354
0
    return ExecutionStatus::EXCEPTION;
355
0
  }
356
0
  auto thisValHandle = runtime.makeHandle<JSObject>(std::move(thisVal->get()));
357
0
  auto result = executeCall0(selfHandle, runtime, thisValHandle, true);
358
0
  if (LLVM_UNLIKELY(result == ExecutionStatus::EXCEPTION)) {
359
0
    return ExecutionStatus::EXCEPTION;
360
0
  }
361
0
  return (*result)->isObject() ? std::move(result)
362
0
                               : CallResult<PseudoHandle<>>(createPseudoHandle(
363
0
                                     thisValHandle.getHermesValue()));
364
0
}
365
366
CallResult<PseudoHandle<>> Callable::executeConstruct1(
367
    Handle<Callable> selfHandle,
368
    Runtime &runtime,
369
0
    Handle<> param1) {
370
0
  auto thisVal = Callable::createThisForConstruct_RJS(selfHandle, runtime);
371
0
  if (LLVM_UNLIKELY(thisVal == ExecutionStatus::EXCEPTION)) {
372
0
    return ExecutionStatus::EXCEPTION;
373
0
  }
374
0
  auto thisValHandle = runtime.makeHandle<JSObject>(std::move(thisVal->get()));
375
0
  CallResult<PseudoHandle<>> result =
376
0
      executeCall1(selfHandle, runtime, thisValHandle, *param1, true);
377
0
  if (LLVM_UNLIKELY(result == ExecutionStatus::EXCEPTION)) {
378
0
    return ExecutionStatus::EXCEPTION;
379
0
  }
380
0
  return (*result)->isObject() ? std::move(result)
381
0
                               : CallResult<PseudoHandle<>>(createPseudoHandle(
382
0
                                     thisValHandle.getHermesValue()));
383
0
}
384
385
CallResult<PseudoHandle<JSObject>> Callable::createThisForConstruct_RJS(
386
    Handle<Callable> selfHandle,
387
0
    Runtime &runtime) {
388
0
  CallResult<PseudoHandle<>> prototypeProp = JSObject::getNamed_RJS(
389
0
      selfHandle, runtime, Predefined::getSymbolID(Predefined::prototype));
390
0
  if (LLVM_UNLIKELY(prototypeProp == ExecutionStatus::EXCEPTION)) {
391
0
    return ExecutionStatus::EXCEPTION;
392
0
  }
393
0
  Handle<JSObject> prototype = vmisa<JSObject>(prototypeProp->get())
394
0
      ? runtime.makeHandle<JSObject>(prototypeProp->get())
395
0
      : Handle<JSObject>::vmcast(&runtime.objectPrototype);
396
0
  return Callable::newObject(selfHandle, runtime, prototype);
397
0
}
398
399
CallResult<double> Callable::extractOwnLengthProperty_RJS(
400
    Handle<Callable> selfHandle,
401
193
    Runtime &runtime) {
402
193
  CallResult<PseudoHandle<>> propRes{
403
193
      createPseudoHandle(HermesValue::encodeUndefinedValue())};
404
193
  NamedPropertyDescriptor desc;
405
193
  if (JSObject::getOwnNamedDescriptor(
406
193
          selfHandle,
407
193
          runtime,
408
193
          Predefined::getSymbolID(Predefined::length),
409
193
          desc)) {
410
193
    propRes = JSObject::getNamedPropertyValue_RJS(
411
193
        selfHandle, runtime, selfHandle, desc);
412
193
  } else if (selfHandle->isProxyObject()) {
413
0
    ComputedPropertyDescriptor desc;
414
0
    CallResult<bool> hasLength = JSProxy::getOwnProperty(
415
0
        selfHandle,
416
0
        runtime,
417
0
        runtime.getPredefinedStringHandle(Predefined::length),
418
0
        desc,
419
0
        nullptr);
420
0
    if (LLVM_UNLIKELY(hasLength == ExecutionStatus::EXCEPTION)) {
421
0
      return ExecutionStatus::EXCEPTION;
422
0
    }
423
0
    if (*hasLength) {
424
0
      propRes = JSProxy::getNamed(
425
0
          selfHandle,
426
0
          runtime,
427
0
          Predefined::getSymbolID(Predefined::length),
428
0
          selfHandle);
429
0
    }
430
0
  }
431
432
193
  {
433
193
    NoAllocScope naScope{runtime};
434
435
193
    if (propRes == ExecutionStatus::EXCEPTION) {
436
0
      return ExecutionStatus::EXCEPTION;
437
0
    }
438
439
193
    if (!(*propRes)->isNumber()) {
440
0
      return 0.0;
441
0
    }
442
193
  }
443
444
193
  auto intRes =
445
193
      toIntegerOrInfinity(runtime, runtime.makeHandle(std::move(*propRes)));
446
193
  if (intRes == ExecutionStatus::EXCEPTION) {
447
0
    return ExecutionStatus::EXCEPTION;
448
0
  }
449
450
193
  return intRes->getNumber();
451
193
}
452
453
//===----------------------------------------------------------------------===//
454
// class BoundFunction
455
456
const CallableVTable BoundFunction::vt{
457
    {
458
        VTable(
459
            CellKind::BoundFunctionKind,
460
            cellSize<BoundFunction>(),
461
            nullptr,
462
            nullptr,
463
            nullptr
464
#ifdef HERMES_MEMORY_INSTRUMENTATION
465
            ,
466
            VTable::HeapSnapshotMetadata{
467
                HeapSnapshot::NodeType::Closure,
468
                BoundFunction::_snapshotNameImpl,
469
                BoundFunction::_snapshotAddEdgesImpl,
470
                nullptr,
471
                nullptr}
472
#endif
473
            ),
474
        BoundFunction::_getOwnIndexedRangeImpl,
475
        BoundFunction::_haveOwnIndexedImpl,
476
        BoundFunction::_getOwnIndexedPropertyFlagsImpl,
477
        BoundFunction::_getOwnIndexedImpl,
478
        BoundFunction::_setOwnIndexedImpl,
479
        BoundFunction::_deleteOwnIndexedImpl,
480
        BoundFunction::_checkAllOwnIndexedImpl,
481
    },
482
    BoundFunction::_newObjectImpl_RJS,
483
    BoundFunction::_callImpl};
484
485
1
void BoundFunctionBuildMeta(const GCCell *cell, Metadata::Builder &mb) {
486
1
  mb.addJSObjectOverlapSlots(JSObject::numOverlapSlots<BoundFunction>());
487
1
  CallableBuildMeta(cell, mb);
488
1
  const auto *self = static_cast<const BoundFunction *>(cell);
489
1
  mb.setVTable(&BoundFunction::vt);
490
1
  mb.addField("target", &self->target_);
491
1
  mb.addField("argStorage", &self->argStorage_);
492
1
}
493
494
CallResult<HermesValue> BoundFunction::create(
495
    Runtime &runtime,
496
    Handle<Callable> target,
497
    unsigned argCountWithThis,
498
113
    ConstArgIterator argsWithThis) {
499
113
  unsigned argCount = argCountWithThis > 0 ? argCountWithThis - 1 : 0;
500
501
  // Copy the arguments. If we don't have any, we must at least initialize
502
  // 'this' to 'undefined'.
503
113
  auto arrRes = ArrayStorage::create(runtime, argCount + 1);
504
113
  if (LLVM_UNLIKELY(arrRes == ExecutionStatus::EXCEPTION)) {
505
0
    return ExecutionStatus::EXCEPTION;
506
0
  }
507
113
  auto arrHandle = runtime.makeMutableHandle(vmcast<ArrayStorage>(*arrRes));
508
509
113
  if (argCountWithThis) {
510
226
    for (unsigned i = 0; i != argCountWithThis; ++i) {
511
113
      ArrayStorage::push_back(arrHandle, runtime, Handle<>(&argsWithThis[i]));
512
113
    }
513
113
  } else {
514
    // Don't need to worry about resizing since it was created with a capacity
515
    // of at least 1.
516
0
    ArrayStorage::push_back(arrHandle, runtime, Runtime::getUndefinedValue());
517
0
  }
518
519
113
  auto *cell = runtime.makeAFixed<BoundFunction>(
520
113
      runtime,
521
113
      Handle<JSObject>::vmcast(&runtime.functionPrototype),
522
113
      runtime.getHiddenClassForPrototype(
523
113
          runtime.functionPrototypeRawPtr, numOverlapSlots<BoundFunction>()),
524
113
      target,
525
113
      arrHandle);
526
113
  auto selfHandle = JSObjectInit::initToHandle(runtime, cell);
527
528
113
  if (initializeLengthAndName_RJS(selfHandle, runtime, target, argCount) ==
529
113
      ExecutionStatus::EXCEPTION) {
530
0
    return ExecutionStatus::EXCEPTION;
531
0
  }
532
113
  return selfHandle.getHermesValue();
533
113
}
534
535
ExecutionStatus BoundFunction::initializeLengthAndName_RJS(
536
    Handle<Callable> selfHandle,
537
    Runtime &runtime,
538
    Handle<Callable> target,
539
113
    unsigned argCount) {
540
113
  if (LLVM_UNLIKELY(target->isLazy())) {
541
0
    Callable::initializeLazyObject(runtime, target);
542
0
  }
543
544
  // Extract target.length.
545
113
  auto targetLength = Callable::extractOwnLengthProperty_RJS(target, runtime);
546
113
  if (targetLength == ExecutionStatus::EXCEPTION)
547
0
    return ExecutionStatus::EXCEPTION;
548
549
  // Define .length
550
113
  PropertyFlags pf{};
551
113
  pf.enumerable = 0;
552
113
  pf.writable = 0;
553
113
  pf.configurable = 1;
554
555
  // Length is the number of formal arguments.
556
113
  auto length = runtime.makeHandle(
557
113
      HermesValue::encodeUntrustedNumberValue(
558
113
          argCount >= *targetLength ? 0.0 : *targetLength - argCount));
559
113
  if (LLVM_UNLIKELY(
560
113
          JSObject::defineNewOwnProperty(
561
113
              selfHandle,
562
113
              runtime,
563
113
              Predefined::getSymbolID(Predefined::length),
564
113
              pf,
565
113
              length) == ExecutionStatus::EXCEPTION)) {
566
0
    return ExecutionStatus::EXCEPTION;
567
0
  }
568
569
  // Set the name by prepending "bound ".
570
113
  auto propRes = JSObject::getNamed_RJS(
571
113
      target, runtime, Predefined::getSymbolID(Predefined::name));
572
113
  if (LLVM_UNLIKELY(propRes == ExecutionStatus::EXCEPTION)) {
573
0
    return ExecutionStatus::EXCEPTION;
574
0
  }
575
113
  auto nameHandle = (*propRes)->isString()
576
113
      ? runtime.makeHandle<StringPrimitive>(propRes->getHermesValue())
577
113
      : runtime.getPredefinedStringHandle(Predefined::emptyString);
578
113
  auto nameView = StringPrimitive::createStringView(runtime, nameHandle);
579
113
  llvh::SmallU16String<32> boundName{"bound "};
580
113
  boundName.append(nameView.begin(), nameView.end());
581
  // Share name strings for repeatedly bound functions by using the
582
  // identifier table. If a new symbol is created, it will disappear
583
  // after the name string dies, since nothing else refers to it.
584
113
  auto &identifierTable = runtime.getIdentifierTable();
585
113
  auto boundNameSym = identifierTable.getSymbolHandle(runtime, boundName);
586
113
  if (LLVM_UNLIKELY(boundNameSym == ExecutionStatus::EXCEPTION)) {
587
0
    return ExecutionStatus::EXCEPTION;
588
0
  }
589
113
  Handle<StringPrimitive> boundNameHandle(
590
113
      runtime, identifierTable.getStringPrim(runtime, **boundNameSym));
591
113
  DefinePropertyFlags dpf = DefinePropertyFlags::getDefaultNewPropertyFlags();
592
113
  dpf.writable = 0;
593
113
  dpf.enumerable = 0;
594
595
113
  if (LLVM_UNLIKELY(
596
113
          JSObject::defineOwnProperty(
597
113
              selfHandle,
598
113
              runtime,
599
113
              Predefined::getSymbolID(Predefined::name),
600
113
              dpf,
601
113
              boundNameHandle) == ExecutionStatus::EXCEPTION)) {
602
0
    return ExecutionStatus::EXCEPTION;
603
0
  }
604
605
  // Define .callee and .arguments properties: throw always in bound functions.
606
113
  auto accessor =
607
113
      Handle<PropertyAccessor>::vmcast(&runtime.throwTypeErrorAccessor);
608
609
113
  pf.clear();
610
113
  pf.enumerable = 0;
611
113
  pf.configurable = 0;
612
113
  pf.accessor = 1;
613
614
113
  if (LLVM_UNLIKELY(
615
113
          JSObject::defineNewOwnProperty(
616
113
              selfHandle,
617
113
              runtime,
618
113
              Predefined::getSymbolID(Predefined::caller),
619
113
              pf,
620
113
              accessor) == ExecutionStatus::EXCEPTION)) {
621
0
    return ExecutionStatus::EXCEPTION;
622
0
  }
623
624
113
  if (LLVM_UNLIKELY(
625
113
          JSObject::defineNewOwnProperty(
626
113
              selfHandle,
627
113
              runtime,
628
113
              Predefined::getSymbolID(Predefined::arguments),
629
113
              pf,
630
113
              accessor) == ExecutionStatus::EXCEPTION)) {
631
0
    return ExecutionStatus::EXCEPTION;
632
0
  }
633
634
113
  return ExecutionStatus::RETURNED;
635
113
}
636
637
CallResult<PseudoHandle<JSObject>> BoundFunction::_newObjectImpl_RJS(
638
    Handle<Callable> selfHandle,
639
    Runtime &runtime,
640
0
    Handle<JSObject>) {
641
0
  auto *self = vmcast<BoundFunction>(*selfHandle);
642
643
  // If it is a chain of bound functions, skip directly to the end.
644
0
  while (auto *targetAsBound =
645
0
             dyn_vmcast<BoundFunction>(self->getTarget(runtime)))
646
0
    self = targetAsBound;
647
648
0
  auto targetHandle = runtime.makeHandle(self->getTarget(runtime));
649
650
  // We must duplicate the [[Construct]] functionality here.
651
652
  // Obtain "target.prototype".
653
0
  auto propRes = JSObject::getNamed_RJS(
654
0
      targetHandle, runtime, Predefined::getSymbolID(Predefined::prototype));
655
0
  if (propRes == ExecutionStatus::EXCEPTION)
656
0
    return ExecutionStatus::EXCEPTION;
657
0
  auto prototype = runtime.makeHandle(std::move(*propRes));
658
659
  // If target.prototype is an object, use it, otherwise use the standard
660
  // object prototype.
661
0
  return targetHandle->getVT()->newObject(
662
0
      targetHandle,
663
0
      runtime,
664
0
      prototype->isObject()
665
0
          ? Handle<JSObject>::vmcast(prototype)
666
0
          : Handle<JSObject>::vmcast(&runtime.objectPrototype));
667
0
}
668
669
CallResult<PseudoHandle<>> BoundFunction::_boundCall(
670
    BoundFunction *self,
671
    const Inst *ip,
672
0
    Runtime &runtime) {
673
0
  ScopedNativeDepthTracker depthTracker{runtime};
674
0
  if (LLVM_UNLIKELY(depthTracker.overflowed())) {
675
0
    return runtime.raiseStackOverflow(Runtime::StackOverflowKind::NativeStack);
676
0
  }
677
678
0
  CallResult<PseudoHandle<>> res{ExecutionStatus::EXCEPTION};
679
0
  StackFramePtr originalCalleeFrame = StackFramePtr(runtime.getStackPointer());
680
  // Save the original newTarget since we will overwrite it.
681
0
  HermesValue originalNewTarget = originalCalleeFrame.getNewTargetRef();
682
  // Save the original arg count since we will lose it.
683
0
  auto originalArgCount = originalCalleeFrame.getArgCount();
684
  // Keep track of the total arg count.
685
0
  auto totalArgCount = originalArgCount;
686
687
0
  auto callerFrame = runtime.getCurrentFrame();
688
  // We must preserve the "thisArg" passed to us by the caller because it is in
689
  // a register that is not supposed to be modified by a call. Copy it to the
690
  // scratch register in the caller's frame.
691
  // Note that since there is only one scratch reg, we must process all chained
692
  // bound calls in one go (which is more efficient anyway).
693
0
  callerFrame.getScratchRef() = originalCalleeFrame.getThisArgRef();
694
695
  // Pop the stack down to the first argument, erasing the call frame - we don't
696
  // need the call frame since we will build a new one.
697
0
  runtime.popToSavedStackPointer(&originalCalleeFrame.getThisArgRef());
698
699
  // Loop, copying the bound arguments of all chained bound functions.
700
0
  for (;;) {
701
0
    auto boundArgCount = self->getArgCountWithThis(runtime) - 1;
702
0
    totalArgCount += boundArgCount;
703
704
    // Check if we have enough stack for the arguments and the frame metadata.
705
0
    if (LLVM_UNLIKELY(!runtime.checkAvailableStack(
706
0
            StackFrameLayout::callerOutgoingRegisters(boundArgCount)))) {
707
      // Oops, we ran out of stack in the middle of calling a bound function.
708
      // Restore everything and bail.
709
710
      // We can't "pop" the stack pointer to an arbitrary value, which may be
711
      // higher than the current pointer. So, first we pop everything that we
712
      // may have pushed, then allocate the correct amount to get back to the
713
      // initial state.
714
0
      runtime.popToSavedStackPointer(&originalCalleeFrame.getThisArgRef());
715
0
      runtime.allocUninitializedStack(
716
0
          StackFrameLayout::CallerExtraRegistersAtEnd + 1);
717
0
      assert(
718
0
          runtime.getStackPointer() == originalCalleeFrame.ptr() &&
719
0
          "Stack wasn't restored properly");
720
721
0
      res = runtime.raiseStackOverflow(
722
0
          Runtime::StackOverflowKind::JSRegisterStack);
723
0
      goto bail;
724
0
    }
725
726
    // Allocate space only for the arguments for now.
727
0
    auto *stack = runtime.allocUninitializedStack(boundArgCount);
728
729
    // Copy the bound arguments (but not the bound "this").
730
0
    std::uninitialized_copy_n(
731
0
        self->getArgsWithThis(runtime) + 1, boundArgCount, ArgIterator(stack));
732
733
    // Loop while the target is another bound function.
734
0
    auto *targetAsBound = dyn_vmcast<BoundFunction>(self->getTarget(runtime));
735
0
    if (!targetAsBound)
736
0
      break;
737
0
    self = targetAsBound;
738
0
  }
739
740
  // Block scope for non-trivial variables to avoid complaints from "goto".
741
0
  {
742
    // Allocate space for "thisArg" and the frame metdata following the outgoing
743
    // registers. Note that we already checked earlier that we have enough
744
    // stack.
745
0
    auto *stack = runtime.allocUninitializedStack(
746
0
        StackFrameLayout::CallerExtraRegistersAtEnd + 1);
747
748
    // Initialize the new frame metadata.
749
0
    auto newCalleeFrame = StackFramePtr::initFrame(
750
0
        stack,
751
0
        runtime.getCurrentFrame(),
752
0
        ip,
753
0
        nullptr,
754
0
        totalArgCount,
755
0
        HermesValue::encodeObjectValue(self->getTarget(runtime)),
756
0
        originalNewTarget);
757
    // Initialize "thisArg". When constructing we must use the original 'this',
758
    // not the bound one.
759
0
    newCalleeFrame.getThisArgRef() = !originalNewTarget.isUndefined()
760
0
        ? static_cast<HermesValue>(callerFrame.getScratchRef())
761
0
        : self->getArgsWithThis(runtime)[0];
762
763
0
    res =
764
0
        Callable::call(newCalleeFrame.getCalleeClosureHandleUnsafe(), runtime);
765
766
0
    assert(
767
0
        runtime.getCurrentFrame() == callerFrame &&
768
0
        "caller frame not restored");
769
770
    // Restore the original stack level.
771
0
    runtime.popToSavedStackPointer(originalCalleeFrame.ptr());
772
0
  }
773
774
0
bail:
775
  // We must restore the original call frame. There is no need to restore
776
  // all the fields to their previous values, just the registers which are not
777
  // supposed to be modified by a call.
778
0
  StackFramePtr::initFrame(
779
0
      originalCalleeFrame.ptr(),
780
0
      StackFramePtr{},
781
0
      ip,
782
0
      nullptr,
783
0
      0,
784
0
      HermesValue::encodeEmptyValue(),
785
0
      HermesValue::encodeEmptyValue());
786
787
  // Restore "thisArg" and clear the scratch register to avoid a leak.
788
0
  originalCalleeFrame.getThisArgRef() = callerFrame.getScratchRef();
789
0
  callerFrame.getScratchRef() = HermesValue::encodeUndefinedValue();
790
791
0
  return res;
792
0
}
793
794
CallResult<PseudoHandle<>> BoundFunction::_callImpl(
795
    Handle<Callable> selfHandle,
796
0
    Runtime &runtime) {
797
  // Pass `nullptr` as the IP because this function is never called
798
  // from the interpreter, which should use `_boundCall` directly.
799
0
  return _boundCall(vmcast<BoundFunction>(selfHandle.get()), nullptr, runtime);
800
0
}
801
802
//===----------------------------------------------------------------------===//
803
// class NativeFunction
804
805
const CallableVTable NativeFunction::vt{
806
    {
807
        VTable(
808
            CellKind::NativeFunctionKind,
809
            cellSize<NativeFunction>(),
810
            nullptr,
811
            nullptr,
812
            nullptr
813
#ifdef HERMES_MEMORY_INSTRUMENTATION
814
            ,
815
            VTable::HeapSnapshotMetadata{
816
                HeapSnapshot::NodeType::Closure,
817
                NativeFunction::_snapshotNameImpl,
818
                NativeFunction::_snapshotAddEdgesImpl,
819
                nullptr,
820
                nullptr}
821
#endif
822
            ),
823
        NativeFunction::_getOwnIndexedRangeImpl,
824
        NativeFunction::_haveOwnIndexedImpl,
825
        NativeFunction::_getOwnIndexedPropertyFlagsImpl,
826
        NativeFunction::_getOwnIndexedImpl,
827
        NativeFunction::_setOwnIndexedImpl,
828
        NativeFunction::_deleteOwnIndexedImpl,
829
        NativeFunction::_checkAllOwnIndexedImpl,
830
    },
831
    NativeFunction::_newObjectImpl,
832
    NativeFunction::_callImpl};
833
834
4
void NativeFunctionBuildMeta(const GCCell *cell, Metadata::Builder &mb) {
835
4
  mb.addJSObjectOverlapSlots(JSObject::numOverlapSlots<NativeFunction>());
836
4
  CallableBuildMeta(cell, mb);
837
4
  mb.setVTable(&NativeFunction::vt);
838
4
}
839
840
#ifdef HERMES_MEMORY_INSTRUMENTATION
841
0
std::string NativeFunction::_snapshotNameImpl(GCCell *cell, GC &gc) {
842
0
  auto *const self = reinterpret_cast<NativeFunction *>(cell);
843
0
  return getFunctionName(self->functionPtr_);
844
0
}
845
#endif
846
847
Handle<NativeFunction> NativeFunction::create(
848
    Runtime &runtime,
849
    Handle<JSObject> parentHandle,
850
    void *context,
851
    NativeFunctionPtr functionPtr,
852
    SymbolID name,
853
    unsigned paramCount,
854
    Handle<JSObject> prototypeObjectHandle,
855
49.8k
    unsigned additionalSlotCount) {
856
49.8k
  size_t reservedSlots =
857
49.8k
      numOverlapSlots<NativeFunction>() + additionalSlotCount;
858
49.8k
  auto *cell = runtime.makeAFixed<NativeFunction>(
859
49.8k
      runtime,
860
49.8k
      parentHandle,
861
49.8k
      runtime.getHiddenClassForPrototype(*parentHandle, reservedSlots),
862
49.8k
      context,
863
49.8k
      functionPtr);
864
49.8k
  auto selfHandle = JSObjectInit::initToHandle(runtime, cell);
865
866
  // Allocate a propStorage if the number of additional slots requires it.
867
49.8k
  runtime.ignoreAllocationFailure(
868
49.8k
      JSObject::allocatePropStorage(selfHandle, runtime, reservedSlots));
869
870
49.8k
  auto st = defineNameLengthAndPrototype(
871
49.8k
      selfHandle,
872
49.8k
      runtime,
873
49.8k
      name,
874
49.8k
      paramCount,
875
49.8k
      prototypeObjectHandle,
876
49.8k
      Callable::WritablePrototype::Yes,
877
49.8k
      false);
878
49.8k
  (void)st;
879
49.8k
  assert(
880
49.8k
      st != ExecutionStatus::EXCEPTION && "defineLengthAndPrototype() failed");
881
882
49.8k
  return selfHandle;
883
49.8k
}
884
885
Handle<NativeFunction> NativeFunction::create(
886
    Runtime &runtime,
887
    Handle<JSObject> parentHandle,
888
    Handle<Environment> parentEnvHandle,
889
    void *context,
890
    NativeFunctionPtr functionPtr,
891
    SymbolID name,
892
    unsigned paramCount,
893
    Handle<JSObject> prototypeObjectHandle,
894
0
    unsigned additionalSlotCount) {
895
0
  auto *cell = runtime.makeAFixed<NativeFunction>(
896
0
      runtime,
897
0
      parentHandle,
898
0
      runtime.getHiddenClassForPrototype(
899
0
          *parentHandle,
900
0
          numOverlapSlots<NativeFunction>() + additionalSlotCount),
901
0
      parentEnvHandle,
902
0
      context,
903
0
      functionPtr);
904
0
  auto selfHandle = JSObjectInit::initToHandle(runtime, cell);
905
906
0
  auto st = defineNameLengthAndPrototype(
907
0
      selfHandle,
908
0
      runtime,
909
0
      name,
910
0
      paramCount,
911
0
      prototypeObjectHandle,
912
0
      Callable::WritablePrototype::Yes,
913
0
      false);
914
0
  (void)st;
915
0
  assert(
916
0
      st != ExecutionStatus::EXCEPTION && "defineLengthAndPrototype() failed");
917
918
0
  return selfHandle;
919
0
}
920
921
CallResult<PseudoHandle<>> NativeFunction::_callImpl(
922
    Handle<Callable> selfHandle,
923
856k
    Runtime &runtime) {
924
856k
  return _nativeCall(vmcast<NativeFunction>(selfHandle.get()), runtime);
925
856k
}
926
927
CallResult<PseudoHandle<JSObject>> NativeFunction::_newObjectImpl(
928
    Handle<Callable>,
929
    Runtime &runtime,
930
0
    Handle<JSObject>) {
931
0
  return runtime.raiseTypeError(
932
0
      "This function cannot be used as a constructor.");
933
0
}
934
935
//===----------------------------------------------------------------------===//
936
// class NativeConstructor
937
938
template <class From>
939
static CallResult<PseudoHandle<JSObject>> toCallResultPseudoHandleJSObject(
940
0
    PseudoHandle<From> &&other) {
941
0
  return PseudoHandle<JSObject>{std::move(other)};
942
0
}
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSObject>(hermes::vm::PseudoHandle<hermes::vm::JSObject>&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSFunction>(hermes::vm::PseudoHandle<hermes::vm::JSFunction>&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSArrayBuffer>(hermes::vm::PseudoHandle<hermes::vm::JSArrayBuffer>&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSBoolean>(hermes::vm::PseudoHandle<hermes::vm::JSBoolean>&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSDataView>(hermes::vm::PseudoHandle<hermes::vm::JSDataView>&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSDate>(hermes::vm::PseudoHandle<hermes::vm::JSDate>&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSError>(hermes::vm::PseudoHandle<hermes::vm::JSError>&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSMapImpl<(hermes::vm::CellKind)48> >(hermes::vm::PseudoHandle<hermes::vm::JSMapImpl<(hermes::vm::CellKind)48> >&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSNumber>(hermes::vm::PseudoHandle<hermes::vm::JSNumber>&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSProxy>(hermes::vm::PseudoHandle<hermes::vm::JSProxy>&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSRegExp>(hermes::vm::PseudoHandle<hermes::vm::JSRegExp>&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSMapImpl<(hermes::vm::CellKind)47> >(hermes::vm::PseudoHandle<hermes::vm::JSMapImpl<(hermes::vm::CellKind)47> >&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSSymbol>(hermes::vm::PseudoHandle<hermes::vm::JSSymbol>&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSWeakRef>(hermes::vm::PseudoHandle<hermes::vm::JSWeakRef>&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSGeneratorFunction>(hermes::vm::PseudoHandle<hermes::vm::JSGeneratorFunction>&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSAsyncFunction>(hermes::vm::PseudoHandle<hermes::vm::JSAsyncFunction>&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSTypedArray<signed char, (hermes::vm::CellKind)35> >(hermes::vm::PseudoHandle<hermes::vm::JSTypedArray<signed char, (hermes::vm::CellKind)35> >&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSTypedArray<short, (hermes::vm::CellKind)36> >(hermes::vm::PseudoHandle<hermes::vm::JSTypedArray<short, (hermes::vm::CellKind)36> >&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSTypedArray<int, (hermes::vm::CellKind)37> >(hermes::vm::PseudoHandle<hermes::vm::JSTypedArray<int, (hermes::vm::CellKind)37> >&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSTypedArray<unsigned char, (hermes::vm::CellKind)38> >(hermes::vm::PseudoHandle<hermes::vm::JSTypedArray<unsigned char, (hermes::vm::CellKind)38> >&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSTypedArray<unsigned char, (hermes::vm::CellKind)39> >(hermes::vm::PseudoHandle<hermes::vm::JSTypedArray<unsigned char, (hermes::vm::CellKind)39> >&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSTypedArray<unsigned short, (hermes::vm::CellKind)40> >(hermes::vm::PseudoHandle<hermes::vm::JSTypedArray<unsigned short, (hermes::vm::CellKind)40> >&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSTypedArray<unsigned int, (hermes::vm::CellKind)41> >(hermes::vm::PseudoHandle<hermes::vm::JSTypedArray<unsigned int, (hermes::vm::CellKind)41> >&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSTypedArray<float, (hermes::vm::CellKind)42> >(hermes::vm::PseudoHandle<hermes::vm::JSTypedArray<float, (hermes::vm::CellKind)42> >&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSTypedArray<double, (hermes::vm::CellKind)43> >(hermes::vm::PseudoHandle<hermes::vm::JSTypedArray<double, (hermes::vm::CellKind)43> >&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSTypedArray<long, (hermes::vm::CellKind)44> >(hermes::vm::PseudoHandle<hermes::vm::JSTypedArray<long, (hermes::vm::CellKind)44> >&&)
Unexecuted instantiation: Callable.cpp:hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::toCallResultPseudoHandleJSObject<hermes::vm::JSTypedArray<unsigned long, (hermes::vm::CellKind)45> >(hermes::vm::PseudoHandle<hermes::vm::JSTypedArray<unsigned long, (hermes::vm::CellKind)45> >&&)
943
944
template <class From>
945
static CallResult<PseudoHandle<JSObject>> toCallResultPseudoHandleJSObject(
946
0
    CallResult<PseudoHandle<From>> &&other) {
947
0
  return std::move(other);
948
0
}
Unexecuted instantiation: Callable.cpp:_ZN6hermes2vmL32toCallResultPseudoHandleJSObjectINS0_13JSWeakMapImplILNS0_8CellKindE51EEEEENS0_10CallResultINS0_12PseudoHandleINS0_8JSObjectEEELNS0_6detail20CallResultSpecializeE6EEEONS5_INS6_IT_EEXsr6detail23GetCallResultSpecializeISD_EE5valueEEE
Unexecuted instantiation: Callable.cpp:_ZN6hermes2vmL32toCallResultPseudoHandleJSObjectINS0_13JSWeakMapImplILNS0_8CellKindE52EEEEENS0_10CallResultINS0_12PseudoHandleINS0_8JSObjectEEELNS0_6detail20CallResultSpecializeE6EEEONS5_INS6_IT_EEXsr6detail23GetCallResultSpecializeISD_EE5valueEEE
949
950
template <class From>
951
static CallResult<PseudoHandle<JSObject>> toCallResultPseudoHandleJSObject(
952
0
    CallResult<Handle<From>> other) {
953
0
  if (LLVM_UNLIKELY(other == ExecutionStatus::EXCEPTION)) {
954
0
    return ExecutionStatus::EXCEPTION;
955
0
  }
956
0
  return PseudoHandle<JSObject>{*other};
957
0
}
Unexecuted instantiation: Callable.cpp:_ZN6hermes2vmL32toCallResultPseudoHandleJSObjectINS0_7JSArrayEEENS0_10CallResultINS0_12PseudoHandleINS0_8JSObjectEEELNS0_6detail20CallResultSpecializeE6EEENS3_INS0_6HandleIT_EEXsr6detail23GetCallResultSpecializeISC_EE5valueEEE
Unexecuted instantiation: Callable.cpp:_ZN6hermes2vmL32toCallResultPseudoHandleJSObjectINS0_8JSBigIntEEENS0_10CallResultINS0_12PseudoHandleINS0_8JSObjectEEELNS0_6detail20CallResultSpecializeE6EEENS3_INS0_6HandleIT_EEXsr6detail23GetCallResultSpecializeISC_EE5valueEEE
Unexecuted instantiation: Callable.cpp:_ZN6hermes2vmL32toCallResultPseudoHandleJSObjectINS0_8JSStringEEENS0_10CallResultINS0_12PseudoHandleINS0_8JSObjectEEELNS0_6detail20CallResultSpecializeE6EEENS3_INS0_6HandleIT_EEXsr6detail23GetCallResultSpecializeISC_EE5valueEEE
958
959
template <class From>
960
static CallResult<PseudoHandle<JSObject>> toCallResultPseudoHandleJSObject(
961
    Handle<From> other) {
962
  return PseudoHandle<JSObject>{other};
963
}
964
965
template <class NativeClass>
966
CallResult<PseudoHandle<JSObject>> NativeConstructor::creatorFunction(
967
    Runtime &runtime,
968
    Handle<JSObject> prototype,
969
0
    void *) {
970
0
  return toCallResultPseudoHandleJSObject(
971
0
      NativeClass::create(runtime, prototype));
972
0
}
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSObject>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSFunction>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSArray>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSArrayBuffer>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSBoolean>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSDataView>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSDate>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSError>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSMapImpl<(hermes::vm::CellKind)48> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSBigInt>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSNumber>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSProxy>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSRegExp>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSMapImpl<(hermes::vm::CellKind)47> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSString>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSSymbol>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSWeakMapImpl<(hermes::vm::CellKind)51> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSWeakMapImpl<(hermes::vm::CellKind)52> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSWeakRef>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSGeneratorFunction>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSAsyncFunction>(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSTypedArray<signed char, (hermes::vm::CellKind)35> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSTypedArray<short, (hermes::vm::CellKind)36> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSTypedArray<int, (hermes::vm::CellKind)37> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSTypedArray<unsigned char, (hermes::vm::CellKind)38> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSTypedArray<unsigned char, (hermes::vm::CellKind)39> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSTypedArray<unsigned short, (hermes::vm::CellKind)40> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSTypedArray<unsigned int, (hermes::vm::CellKind)41> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSTypedArray<float, (hermes::vm::CellKind)42> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSTypedArray<double, (hermes::vm::CellKind)43> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSTypedArray<long, (hermes::vm::CellKind)44> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
Unexecuted instantiation: hermes::vm::CallResult<hermes::vm::PseudoHandle<hermes::vm::JSObject>, (hermes::vm::detail::CallResultSpecialize)6> hermes::vm::NativeConstructor::creatorFunction<hermes::vm::JSTypedArray<unsigned long, (hermes::vm::CellKind)45> >(hermes::vm::Runtime&, hermes::vm::Handle<hermes::vm::JSObject>, void*)
973
974
#define NATIVE_CONSTRUCTOR(fun)                    \
975
  template CallResult<PseudoHandle<JSObject>> fun( \
976
      Runtime &, Handle<JSObject>, void *);
977
#include "hermes/VM/NativeFunctions.def"
978
#undef NATIVE_CONSTRUCTOR
979
980
const CallableVTable NativeConstructor::vt{
981
    {
982
        VTable(
983
            CellKind::NativeConstructorKind,
984
            cellSize<NativeConstructor>(),
985
            nullptr,
986
            nullptr,
987
            nullptr
988
#ifdef HERMES_MEMORY_INSTRUMENTATION
989
            ,
990
            VTable::HeapSnapshotMetadata{
991
                HeapSnapshot::NodeType::Closure,
992
                NativeConstructor::_snapshotNameImpl,
993
                NativeConstructor::_snapshotAddEdgesImpl,
994
                nullptr,
995
                nullptr}
996
#endif
997
            ),
998
        NativeConstructor::_getOwnIndexedRangeImpl,
999
        NativeConstructor::_haveOwnIndexedImpl,
1000
        NativeConstructor::_getOwnIndexedPropertyFlagsImpl,
1001
        NativeConstructor::_getOwnIndexedImpl,
1002
        NativeConstructor::_setOwnIndexedImpl,
1003
        NativeConstructor::_deleteOwnIndexedImpl,
1004
        NativeConstructor::_checkAllOwnIndexedImpl,
1005
    },
1006
    NativeConstructor::_newObjectImpl,
1007
    NativeConstructor::_callImpl};
1008
1009
1
void NativeConstructorBuildMeta(const GCCell *cell, Metadata::Builder &mb) {
1010
1
  mb.addJSObjectOverlapSlots(JSObject::numOverlapSlots<NativeConstructor>());
1011
1
  NativeFunctionBuildMeta(cell, mb);
1012
1
  mb.setVTable(&NativeConstructor::vt);
1013
1
}
1014
1015
#ifndef NDEBUG
1016
CallResult<PseudoHandle<>> NativeConstructor::_callImpl(
1017
    Handle<Callable> selfHandle,
1018
0
    Runtime &runtime) {
1019
0
  StackFramePtr newFrame{runtime.getStackPointer()};
1020
1021
0
  if (newFrame.isConstructorCall()) {
1022
0
    auto consHandle = Handle<NativeConstructor>::vmcast(selfHandle);
1023
0
    assert(
1024
0
        consHandle->targetKind_ ==
1025
0
            vmcast<JSObject>(newFrame.getThisArgRef())->getKind() &&
1026
0
        "call(construct=true) called without the correct 'this' value");
1027
0
  }
1028
0
  return NativeFunction::_callImpl(selfHandle, runtime);
1029
0
}
1030
#endif
1031
1032
//===----------------------------------------------------------------------===//
1033
// class JSFunction
1034
1035
const CallableVTable JSFunction::vt{
1036
    {
1037
        VTable(
1038
            CellKind::JSFunctionKind,
1039
            cellSize<JSFunction>(),
1040
            nullptr,
1041
            nullptr,
1042
            nullptr
1043
#ifdef HERMES_MEMORY_INSTRUMENTATION
1044
            ,
1045
            VTable::HeapSnapshotMetadata{
1046
                HeapSnapshot::NodeType::Closure,
1047
                JSFunction::_snapshotNameImpl,
1048
                JSFunction::_snapshotAddEdgesImpl,
1049
                nullptr,
1050
                JSFunction::_snapshotAddLocationsImpl}
1051
#endif
1052
            ),
1053
        JSFunction::_getOwnIndexedRangeImpl,
1054
        JSFunction::_haveOwnIndexedImpl,
1055
        JSFunction::_getOwnIndexedPropertyFlagsImpl,
1056
        JSFunction::_getOwnIndexedImpl,
1057
        JSFunction::_setOwnIndexedImpl,
1058
        JSFunction::_deleteOwnIndexedImpl,
1059
        JSFunction::_checkAllOwnIndexedImpl,
1060
    },
1061
    JSFunction::_newObjectImpl,
1062
    JSFunction::_callImpl};
1063
1064
4
void JSFunctionBuildMeta(const GCCell *cell, Metadata::Builder &mb) {
1065
4
  mb.addJSObjectOverlapSlots(JSObject::numOverlapSlots<JSFunction>());
1066
4
  CallableBuildMeta(cell, mb);
1067
4
  const auto *self = static_cast<const JSFunction *>(cell);
1068
4
  mb.addField("domain", &self->domain_);
1069
4
  mb.setVTable(&JSFunction::vt);
1070
4
}
1071
1072
PseudoHandle<JSFunction> JSFunction::create(
1073
    Runtime &runtime,
1074
    Handle<Domain> domain,
1075
    Handle<JSObject> parentHandle,
1076
    Handle<Environment> envHandle,
1077
4.41k
    CodeBlock *codeBlock) {
1078
4.41k
  auto *cell = runtime.makeAFixed<JSFunction, kHasFinalizer>(
1079
4.41k
      runtime,
1080
4.41k
      domain,
1081
4.41k
      parentHandle,
1082
4.41k
      runtime.getHiddenClassForPrototype(
1083
4.41k
          *parentHandle, numOverlapSlots<JSFunction>()),
1084
4.41k
      envHandle,
1085
4.41k
      codeBlock);
1086
4.41k
  auto self = JSObjectInit::initToPseudoHandle(runtime, cell);
1087
4.41k
  self->flags_.lazyObject = 1;
1088
4.41k
  return self;
1089
4.41k
}
1090
1091
#ifdef HERMES_MEMORY_INSTRUMENTATION
1092
void JSFunction::addLocationToSnapshot(
1093
    HeapSnapshot &snap,
1094
    HeapSnapshot::NodeID id,
1095
0
    GC &gc) const {
1096
0
  if (auto location = codeBlock_.get(gc)->getSourceLocation()) {
1097
0
    snap.addLocation(
1098
0
        id,
1099
0
        codeBlock_.get(gc)->getRuntimeModule()->getScriptID(),
1100
0
        location->line,
1101
0
        location->column);
1102
0
  }
1103
0
}
1104
#endif
1105
1106
CallResult<PseudoHandle<>> JSFunction::_callImpl(
1107
    Handle<Callable> selfHandle,
1108
0
    Runtime &runtime) {
1109
0
  auto *self = vmcast<JSFunction>(selfHandle.get());
1110
0
  CallResult<HermesValue> result{ExecutionStatus::EXCEPTION};
1111
0
  result = runtime.interpretFunction(self->getCodeBlock(runtime));
1112
0
  if (LLVM_UNLIKELY(result == ExecutionStatus::EXCEPTION)) {
1113
0
    return ExecutionStatus::EXCEPTION;
1114
0
  }
1115
0
  return createPseudoHandle(*result);
1116
0
}
1117
1118
#ifdef HERMES_MEMORY_INSTRUMENTATION
1119
0
std::string JSFunction::_snapshotNameImpl(GCCell *cell, GC &gc) {
1120
0
  auto *const self = vmcast<JSFunction>(cell);
1121
0
  std::string funcName = Callable::_snapshotNameImpl(self, gc);
1122
0
  if (!funcName.empty()) {
1123
0
    return funcName;
1124
0
  }
1125
0
  return self->codeBlock_.get(gc)->getNameString(gc.getCallbacks());
1126
0
}
1127
1128
void JSFunction::_snapshotAddEdgesImpl(
1129
    GCCell *cell,
1130
    GC &gc,
1131
0
    HeapSnapshot &snap) {
1132
0
  auto *const self = vmcast<JSFunction>(cell);
1133
  // Add the super type's edges too.
1134
0
  Callable::_snapshotAddEdgesImpl(self, gc, snap);
1135
1136
  // A node for the code block will be added as part of the RuntimeModule.
1137
0
  snap.addNamedEdge(
1138
0
      HeapSnapshot::EdgeType::Shortcut,
1139
0
      "codeBlock",
1140
0
      gc.getIDTracker().getNativeID(self->codeBlock_.get(gc)));
1141
0
}
1142
1143
void JSFunction::_snapshotAddLocationsImpl(
1144
    GCCell *cell,
1145
    GC &gc,
1146
0
    HeapSnapshot &snap) {
1147
0
  auto *const self = vmcast<JSFunction>(cell);
1148
0
  self->addLocationToSnapshot(snap, gc.getObjectID(self), gc);
1149
0
}
1150
#endif
1151
1152
//===----------------------------------------------------------------------===//
1153
// class JSAsyncFunction
1154
1155
const CallableVTable JSAsyncFunction::vt{
1156
    {
1157
        VTable(
1158
            CellKind::JSAsyncFunctionKind,
1159
            cellSize<JSAsyncFunction>(),
1160
            nullptr,
1161
            nullptr,
1162
            nullptr
1163
#ifdef HERMES_MEMORY_INSTRUMENTATION
1164
            ,
1165
            VTable::HeapSnapshotMetadata{
1166
                HeapSnapshot::NodeType::Closure,
1167
                JSAsyncFunction::_snapshotNameImpl,
1168
                JSAsyncFunction::_snapshotAddEdgesImpl,
1169
                nullptr,
1170
                nullptr}
1171
#endif
1172
            ),
1173
        JSAsyncFunction::_getOwnIndexedRangeImpl,
1174
        JSAsyncFunction::_haveOwnIndexedImpl,
1175
        JSAsyncFunction::_getOwnIndexedPropertyFlagsImpl,
1176
        JSAsyncFunction::_getOwnIndexedImpl,
1177
        JSAsyncFunction::_setOwnIndexedImpl,
1178
        JSAsyncFunction::_deleteOwnIndexedImpl,
1179
        JSAsyncFunction::_checkAllOwnIndexedImpl,
1180
    },
1181
    JSAsyncFunction::_newObjectImpl,
1182
    JSAsyncFunction::_callImpl};
1183
1184
1
void JSAsyncFunctionBuildMeta(const GCCell *cell, Metadata::Builder &mb) {
1185
1
  mb.addJSObjectOverlapSlots(JSObject::numOverlapSlots<JSAsyncFunction>());
1186
1
  JSFunctionBuildMeta(cell, mb);
1187
1
  mb.setVTable(&JSAsyncFunction::vt);
1188
1
}
1189
1190
PseudoHandle<JSAsyncFunction> JSAsyncFunction::create(
1191
    Runtime &runtime,
1192
    Handle<Domain> domain,
1193
    Handle<JSObject> parentHandle,
1194
    Handle<Environment> envHandle,
1195
0
    CodeBlock *codeBlock) {
1196
0
  auto *cell = runtime.makeAFixed<JSAsyncFunction, kHasFinalizer>(
1197
0
      runtime,
1198
0
      domain,
1199
0
      parentHandle,
1200
0
      runtime.getHiddenClassForPrototype(
1201
0
          *parentHandle, numOverlapSlots<JSAsyncFunction>()),
1202
0
      envHandle,
1203
0
      codeBlock);
1204
0
  auto self = JSObjectInit::initToPseudoHandle(runtime, cell);
1205
0
  self->flags_.lazyObject = 1;
1206
0
  return self;
1207
0
}
1208
1209
//===----------------------------------------------------------------------===//
1210
// class JSGeneratorFunction
1211
1212
const CallableVTable JSGeneratorFunction::vt{
1213
    {
1214
        VTable(
1215
            CellKind::JSGeneratorFunctionKind,
1216
            cellSize<JSGeneratorFunction>(),
1217
            nullptr,
1218
            nullptr,
1219
            nullptr
1220
#ifdef HERMES_MEMORY_INSTRUMENTATION
1221
            ,
1222
            VTable::HeapSnapshotMetadata{
1223
                HeapSnapshot::NodeType::Closure,
1224
                JSGeneratorFunction::_snapshotNameImpl,
1225
                JSGeneratorFunction::_snapshotAddEdgesImpl,
1226
                nullptr,
1227
                nullptr}
1228
#endif
1229
            ),
1230
        JSGeneratorFunction::_getOwnIndexedRangeImpl,
1231
        JSGeneratorFunction::_haveOwnIndexedImpl,
1232
        JSGeneratorFunction::_getOwnIndexedPropertyFlagsImpl,
1233
        JSGeneratorFunction::_getOwnIndexedImpl,
1234
        JSGeneratorFunction::_setOwnIndexedImpl,
1235
        JSGeneratorFunction::_deleteOwnIndexedImpl,
1236
        JSGeneratorFunction::_checkAllOwnIndexedImpl,
1237
    },
1238
    JSGeneratorFunction::_newObjectImpl,
1239
    JSGeneratorFunction::_callImpl};
1240
1241
1
void JSGeneratorFunctionBuildMeta(const GCCell *cell, Metadata::Builder &mb) {
1242
1
  mb.addJSObjectOverlapSlots(JSObject::numOverlapSlots<JSGeneratorFunction>());
1243
1
  JSFunctionBuildMeta(cell, mb);
1244
1
  mb.setVTable(&JSGeneratorFunction::vt);
1245
1
}
1246
1247
PseudoHandle<JSGeneratorFunction> JSGeneratorFunction::create(
1248
    Runtime &runtime,
1249
    Handle<Domain> domain,
1250
    Handle<JSObject> parentHandle,
1251
    Handle<Environment> envHandle,
1252
0
    CodeBlock *codeBlock) {
1253
0
  auto *cell = runtime.makeAFixed<JSGeneratorFunction, kHasFinalizer>(
1254
0
      runtime,
1255
0
      domain,
1256
0
      parentHandle,
1257
0
      runtime.getHiddenClassForPrototype(
1258
0
          *parentHandle, numOverlapSlots<JSGeneratorFunction>()),
1259
0
      envHandle,
1260
0
      codeBlock);
1261
0
  auto self = JSObjectInit::initToPseudoHandle(runtime, cell);
1262
0
  self->flags_.lazyObject = 1;
1263
0
  return self;
1264
0
}
1265
1266
//===----------------------------------------------------------------------===//
1267
// class GeneratorInnerFunction
1268
1269
const CallableVTable GeneratorInnerFunction::vt{
1270
    {
1271
        VTable(
1272
            CellKind::GeneratorInnerFunctionKind,
1273
            cellSize<GeneratorInnerFunction>(),
1274
            nullptr,
1275
            nullptr,
1276
            nullptr
1277
#ifdef HERMES_MEMORY_INSTRUMENTATION
1278
            ,
1279
            VTable::HeapSnapshotMetadata{
1280
                HeapSnapshot::NodeType::Closure,
1281
                GeneratorInnerFunction::_snapshotNameImpl,
1282
                GeneratorInnerFunction::_snapshotAddEdgesImpl,
1283
                nullptr,
1284
                nullptr}
1285
#endif
1286
            ),
1287
        GeneratorInnerFunction::_getOwnIndexedRangeImpl,
1288
        GeneratorInnerFunction::_haveOwnIndexedImpl,
1289
        GeneratorInnerFunction::_getOwnIndexedPropertyFlagsImpl,
1290
        GeneratorInnerFunction::_getOwnIndexedImpl,
1291
        GeneratorInnerFunction::_setOwnIndexedImpl,
1292
        GeneratorInnerFunction::_deleteOwnIndexedImpl,
1293
        GeneratorInnerFunction::_checkAllOwnIndexedImpl,
1294
    },
1295
    GeneratorInnerFunction::_newObjectImpl,
1296
    GeneratorInnerFunction::_callImpl};
1297
1298
void GeneratorInnerFunctionBuildMeta(
1299
    const GCCell *cell,
1300
1
    Metadata::Builder &mb) {
1301
1
  mb.addJSObjectOverlapSlots(
1302
1
      JSObject::numOverlapSlots<GeneratorInnerFunction>());
1303
1
  JSFunctionBuildMeta(cell, mb);
1304
1
  const auto *self = static_cast<const GeneratorInnerFunction *>(cell);
1305
1
  mb.setVTable(&GeneratorInnerFunction::vt);
1306
1
  mb.addField("savedContext", &self->savedContext_);
1307
1
  mb.addField("result", &self->result_);
1308
1
}
1309
1310
CallResult<Handle<GeneratorInnerFunction>> GeneratorInnerFunction::create(
1311
    Runtime &runtime,
1312
    Handle<Domain> domain,
1313
    Handle<JSObject> parentHandle,
1314
    Handle<Environment> envHandle,
1315
    CodeBlock *codeBlock,
1316
0
    NativeArgs args) {
1317
0
  auto *cell = runtime.makeAFixed<GeneratorInnerFunction>(
1318
0
      runtime,
1319
0
      domain,
1320
0
      parentHandle,
1321
0
      runtime.getHiddenClassForPrototype(
1322
0
          *parentHandle, numOverlapSlots<GeneratorInnerFunction>()),
1323
0
      envHandle,
1324
0
      codeBlock,
1325
0
      args.getArgCount());
1326
0
  auto self = JSObjectInit::initToHandle(runtime, cell);
1327
1328
0
  const uint32_t ctxSize = getContextSize(codeBlock, args.getArgCount());
1329
1330
0
  auto ctxRes = ArrayStorage::create(runtime, ctxSize, ctxSize);
1331
0
  if (LLVM_UNLIKELY(ctxRes == ExecutionStatus::EXCEPTION)) {
1332
0
    return ExecutionStatus::EXCEPTION;
1333
0
  }
1334
0
  auto ctx = runtime.makeHandle<ArrayStorage>(*ctxRes);
1335
1336
  // Set "this" as the first element.
1337
0
  ctx->set(0, args.getThisArg(), runtime.getHeap());
1338
1339
  // Set the rest of the arguments.
1340
  // Argument i goes in slot i+1 to account for the "this".
1341
0
  for (uint32_t i = 0, e = args.getArgCount(); i < e; ++i) {
1342
0
    ctx->set(i + 1, args.getArg(i), runtime.getHeap());
1343
0
  }
1344
1345
0
  self->savedContext_.set(runtime, ctx.get(), runtime.getHeap());
1346
1347
0
  return self;
1348
0
}
1349
1350
/// Call the callable with arguments already on the stack.
1351
CallResult<PseudoHandle<>> GeneratorInnerFunction::callInnerFunction(
1352
    Handle<GeneratorInnerFunction> selfHandle,
1353
    Runtime &runtime,
1354
    Handle<> arg,
1355
0
    Action action) {
1356
0
  auto self = Handle<GeneratorInnerFunction>::vmcast(selfHandle);
1357
1358
0
  SmallHermesValue shv =
1359
0
      SmallHermesValue::encodeHermesValue(arg.getHermesValue(), runtime);
1360
0
  self->result_.set(shv, runtime.getHeap());
1361
0
  self->action_ = action;
1362
1363
0
  auto ctx = runtime.makeMutableHandle(selfHandle->savedContext_);
1364
  // Account for the `this` argument stored as the first element of ctx.
1365
0
  const uint32_t argCount = self->argCount_;
1366
  // Generators cannot be used as constructors, so newTarget is always
1367
  // undefined.
1368
0
  HermesValue newTarget = HermesValue::encodeUndefinedValue();
1369
0
  ScopedNativeCallFrame frame{
1370
0
      runtime,
1371
0
      argCount, // Account for `this`.
1372
0
      selfHandle.getHermesValue(),
1373
0
      newTarget,
1374
0
      ctx->at(0)};
1375
0
  if (LLVM_UNLIKELY(frame.overflowed()))
1376
0
    return runtime.raiseStackOverflow(Runtime::StackOverflowKind::NativeStack);
1377
0
  for (ArrayStorage::size_type i = 0, e = argCount; i < e; ++i) {
1378
0
    frame->getArgRef(i) = ctx->at(i + 1);
1379
0
  }
1380
1381
  // Force lazy compilation immediately in order to size the context properly.
1382
  // We're about to call the function anyway, so this doesn't reduce laziness.
1383
  // Note that this will do nothing after the very first time a lazy function
1384
  // is called, so we only resize before we save any registers at all.
1385
0
  if (LLVM_UNLIKELY(selfHandle->getCodeBlock(runtime)->isLazy())) {
1386
0
    if (LLVM_UNLIKELY(
1387
0
            selfHandle->getCodeBlock(runtime)->lazyCompile(runtime) ==
1388
0
            ExecutionStatus::EXCEPTION)) {
1389
0
      return ExecutionStatus::EXCEPTION;
1390
0
    }
1391
0
    if (LLVM_UNLIKELY(
1392
0
            ArrayStorage::resize(
1393
0
                ctx,
1394
0
                runtime,
1395
0
                getContextSize(
1396
0
                    selfHandle->getCodeBlock(runtime),
1397
0
                    selfHandle->argCount_)) == ExecutionStatus::EXCEPTION)) {
1398
0
      return ExecutionStatus::EXCEPTION;
1399
0
    }
1400
0
    selfHandle->savedContext_.set(runtime, ctx.get(), runtime.getHeap());
1401
0
  }
1402
1403
0
  return JSFunction::_callImpl(selfHandle, runtime);
1404
0
}
1405
1406
0
void GeneratorInnerFunction::restoreStack(Runtime &runtime) {
1407
0
  const uint32_t frameOffset = getFrameOffsetInContext();
1408
0
  const uint32_t frameSize = getFrameSizeInContext(runtime);
1409
  // Start at the lower end of the range to be copied.
1410
0
  PinnedHermesValue *dst = runtime.getCurrentFrame().ptr();
1411
0
  assert(
1412
0
      dst + frameSize <= runtime.getStackPointer() &&
1413
0
      "writing off the end of the stack");
1414
0
  const GCHermesValue *src =
1415
0
      savedContext_.getNonNull(runtime)->data() + frameOffset;
1416
0
  GCHermesValueUtil::copyToPinned(src, src + frameSize, dst);
1417
0
}
1418
1419
0
void GeneratorInnerFunction::saveStack(Runtime &runtime) {
1420
0
  const uint32_t frameOffset = getFrameOffsetInContext();
1421
0
  const uint32_t frameSize = getFrameSizeInContext(runtime);
1422
  // Start at the lower end of the range to be copied.
1423
0
  PinnedHermesValue *first = runtime.getCurrentFrame().ptr();
1424
0
  assert(
1425
0
      first + frameSize <= runtime.getStackPointer() &&
1426
0
      "reading off the end of the stack");
1427
  // Use GCHermesValue::copy to ensure write barriers are executed.
1428
0
  GCHermesValue::copy(
1429
0
      first,
1430
0
      first + frameSize,
1431
0
      savedContext_.getNonNull(runtime)->data() + frameOffset,
1432
0
      runtime.getHeap());
1433
0
}
1434
1435
} // namespace vm
1436
} // namespace hermes