Coverage Report

Created: 2025-08-28 06:48

/src/hermes/lib/VM/Callable.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
#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
558
    Handle<JSObject> parentHandle) {
71
558
  return JSObject::create(runtime, parentHandle);
72
558
}
73
74
239
void Callable::defineLazyProperties(Handle<Callable> fn, Runtime &runtime) {
75
  // lazy functions can be Bound or JS Functions.
76
239
  if (auto jsFun = Handle<JSFunction>::dyn_vmcast(fn)) {
77
239
    const CodeBlock *codeBlock = jsFun->getCodeBlock(runtime);
78
    // Create empty object for prototype.
79
239
    auto prototypeParent = vmisa<JSGeneratorFunction>(*jsFun)
80
239
        ? Handle<JSObject>::vmcast(&runtime.generatorPrototype)
81
239
        : 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
239
    auto prototypeObjectHandle =
89
239
        codeBlock->getHeaderFlags().isCallProhibited(/* construct */ true) &&
90
239
            !vmisa<JSGeneratorFunction>(*jsFun)
91
239
        ? Runtime::makeNullHandle<JSObject>()
92
239
        : runtime.makeHandle(JSObject::create(runtime, prototypeParent));
93
94
239
    auto cr = Callable::defineNameLengthAndPrototype(
95
239
        fn,
96
239
        runtime,
97
239
        codeBlock->getNameMayAllocate(),
98
239
        codeBlock->getParamCount() - 1,
99
239
        prototypeObjectHandle,
100
239
        Callable::WritablePrototype::Yes,
101
239
        codeBlock->isStrictMode());
102
239
    assert(
103
239
        cr != ExecutionStatus::EXCEPTION && "failed to define length and name");
104
239
    (void)cr;
105
239
  } else {
106
    // no other kind of function can be lazy currently
107
0
    assert(false && "invalid lazy function");
108
0
  }
109
239
}
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
45.1k
    bool strictMode) {
119
45.1k
  PropertyFlags pf;
120
45.1k
  pf.clear();
121
45.1k
  pf.enumerable = 0;
122
45.1k
  pf.writable = 0;
123
45.1k
  pf.configurable = 1;
124
125
45.1k
  GCScope scope{runtime, "defineNameLengthAndPrototype"};
126
127
45.1k
  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
45.1k
#define DEFINE_PROP(OBJ_HANDLE, SYMBOL, HANDLE)                            \
133
98.7k
  do {                                                                     \
134
98.7k
    auto status = JSObject::defineNewOwnProperty(                          \
135
98.7k
        OBJ_HANDLE, runtime, Predefined::getSymbolID(SYMBOL), pf, HANDLE); \
136
98.7k
    if (LLVM_UNLIKELY(status == ExecutionStatus::EXCEPTION)) {             \
137
0
      return ExecutionStatus::EXCEPTION;                                   \
138
0
    }                                                                      \
139
98.7k
  } while (false)
140
141
45.1k
  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
45.1k
  auto lengthHandle =
146
45.1k
      runtime.makeHandle(HermesValue::encodeUntrustedNumberValue(paramCount));
147
45.1k
  DEFINE_PROP(selfHandle, P::length, lengthHandle);
148
149
  // Define the name.
150
  // 10.2.8 SetFunctionName is performed after 10.2.3 OrdinaryFunctionCreate.
151
45.1k
  auto nameHandle = runtime.makeHandle(runtime.getStringPrimFromSymbolID(name));
152
45.1k
  DEFINE_PROP(selfHandle, P::name, nameHandle);
153
154
45.1k
  if (strictMode) {
155
    // Define .callee and .arguments properties: throw always in strict mode.
156
186
    auto accessor =
157
186
        Handle<PropertyAccessor>::vmcast(&runtime.throwTypeErrorAccessor);
158
159
186
    pf.clear();
160
186
    pf.enumerable = 0;
161
186
    pf.configurable = 0;
162
186
    pf.accessor = 1;
163
164
186
    DEFINE_PROP(selfHandle, P::caller, accessor);
165
186
    DEFINE_PROP(selfHandle, P::arguments, accessor);
166
186
  }
167
168
45.1k
  if (prototypeObjectHandle) {
169
    // Set its 'prototype' property.
170
4.05k
    pf.clear();
171
4.05k
    pf.enumerable = 0;
172
    /// System constructors have read-only prototypes.
173
4.05k
    pf.writable = (uint8_t)writablePrototype;
174
4.05k
    pf.configurable = 0;
175
4.05k
    DEFINE_PROP(selfHandle, P::prototype, prototypeObjectHandle);
176
177
4.05k
    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.05k
      pf.clear();
183
4.05k
      pf.enumerable = 0;
184
4.05k
      pf.writable = 1;
185
4.05k
      pf.configurable = 1;
186
4.05k
      DEFINE_PROP(prototypeObjectHandle, P::constructor, selfHandle);
187
4.05k
    }
188
4.05k
  }
189
190
45.1k
  return ExecutionStatus::RETURNED;
191
192
45.1k
#undef DEFINE_PROP
193
45.1k
}
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
1.07M
    bool construct) {
202
1.07M
  ScopedNativeCallFrame newFrame{
203
1.07M
      runtime,
204
1.07M
      0,
205
1.07M
      selfHandle.getHermesValue(),
206
1.07M
      construct ? selfHandle.getHermesValue()
207
1.07M
                : HermesValue::encodeUndefinedValue(),
208
1.07M
      *thisArgHandle};
209
1.07M
  if (LLVM_UNLIKELY(newFrame.overflowed()))
210
0
    return runtime.raiseStackOverflow(Runtime::StackOverflowKind::NativeStack);
211
1.07M
  return call(selfHandle, runtime);
212
1.07M
}
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
100
    Runtime &runtime) {
402
100
  CallResult<PseudoHandle<>> propRes{
403
100
      createPseudoHandle(HermesValue::encodeUndefinedValue())};
404
100
  NamedPropertyDescriptor desc;
405
100
  if (JSObject::getOwnNamedDescriptor(
406
100
          selfHandle,
407
100
          runtime,
408
100
          Predefined::getSymbolID(Predefined::length),
409
100
          desc)) {
410
100
    propRes = JSObject::getNamedPropertyValue_RJS(
411
100
        selfHandle, runtime, selfHandle, desc);
412
100
  } 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
100
  {
433
100
    NoAllocScope naScope{runtime};
434
435
100
    if (propRes == ExecutionStatus::EXCEPTION) {
436
0
      return ExecutionStatus::EXCEPTION;
437
0
    }
438
439
100
    if (!(*propRes)->isNumber()) {
440
0
      return 0.0;
441
0
    }
442
100
  }
443
444
100
  auto intRes =
445
100
      toIntegerOrInfinity(runtime, runtime.makeHandle(std::move(*propRes)));
446
100
  if (intRes == ExecutionStatus::EXCEPTION) {
447
0
    return ExecutionStatus::EXCEPTION;
448
0
  }
449
450
100
  return intRes->getNumber();
451
100
}
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
93
    ConstArgIterator argsWithThis) {
499
93
  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
93
  auto arrRes = ArrayStorage::create(runtime, argCount + 1);
504
93
  if (LLVM_UNLIKELY(arrRes == ExecutionStatus::EXCEPTION)) {
505
0
    return ExecutionStatus::EXCEPTION;
506
0
  }
507
93
  auto arrHandle = runtime.makeMutableHandle(vmcast<ArrayStorage>(*arrRes));
508
509
93
  if (argCountWithThis) {
510
186
    for (unsigned i = 0; i != argCountWithThis; ++i) {
511
93
      ArrayStorage::push_back(arrHandle, runtime, Handle<>(&argsWithThis[i]));
512
93
    }
513
93
  } 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
93
  auto *cell = runtime.makeAFixed<BoundFunction>(
520
93
      runtime,
521
93
      Handle<JSObject>::vmcast(&runtime.functionPrototype),
522
93
      runtime.getHiddenClassForPrototype(
523
93
          runtime.functionPrototypeRawPtr, numOverlapSlots<BoundFunction>()),
524
93
      target,
525
93
      arrHandle);
526
93
  auto selfHandle = JSObjectInit::initToHandle(runtime, cell);
527
528
93
  if (initializeLengthAndName_RJS(selfHandle, runtime, target, argCount) ==
529
93
      ExecutionStatus::EXCEPTION) {
530
0
    return ExecutionStatus::EXCEPTION;
531
0
  }
532
93
  return selfHandle.getHermesValue();
533
93
}
534
535
ExecutionStatus BoundFunction::initializeLengthAndName_RJS(
536
    Handle<Callable> selfHandle,
537
    Runtime &runtime,
538
    Handle<Callable> target,
539
93
    unsigned argCount) {
540
93
  if (LLVM_UNLIKELY(target->isLazy())) {
541
0
    Callable::initializeLazyObject(runtime, target);
542
0
  }
543
544
  // Extract target.length.
545
93
  auto targetLength = Callable::extractOwnLengthProperty_RJS(target, runtime);
546
93
  if (targetLength == ExecutionStatus::EXCEPTION)
547
0
    return ExecutionStatus::EXCEPTION;
548
549
  // Define .length
550
93
  PropertyFlags pf{};
551
93
  pf.enumerable = 0;
552
93
  pf.writable = 0;
553
93
  pf.configurable = 1;
554
555
  // Length is the number of formal arguments.
556
93
  auto length = runtime.makeHandle(HermesValue::encodeUntrustedNumberValue(
557
93
      argCount >= *targetLength ? 0.0 : *targetLength - argCount));
558
93
  if (LLVM_UNLIKELY(
559
93
          JSObject::defineNewOwnProperty(
560
93
              selfHandle,
561
93
              runtime,
562
93
              Predefined::getSymbolID(Predefined::length),
563
93
              pf,
564
93
              length) == ExecutionStatus::EXCEPTION)) {
565
0
    return ExecutionStatus::EXCEPTION;
566
0
  }
567
568
  // Set the name by prepending "bound ".
569
93
  auto propRes = JSObject::getNamed_RJS(
570
93
      target, runtime, Predefined::getSymbolID(Predefined::name));
571
93
  if (LLVM_UNLIKELY(propRes == ExecutionStatus::EXCEPTION)) {
572
0
    return ExecutionStatus::EXCEPTION;
573
0
  }
574
93
  auto nameHandle = (*propRes)->isString()
575
93
      ? runtime.makeHandle<StringPrimitive>(propRes->getHermesValue())
576
93
      : runtime.getPredefinedStringHandle(Predefined::emptyString);
577
93
  auto nameView = StringPrimitive::createStringView(runtime, nameHandle);
578
93
  llvh::SmallU16String<32> boundName{"bound "};
579
93
  boundName.append(nameView.begin(), nameView.end());
580
  // Share name strings for repeatedly bound functions by using the
581
  // identifier table. If a new symbol is created, it will disappear
582
  // after the name string dies, since nothing else refers to it.
583
93
  auto &identifierTable = runtime.getIdentifierTable();
584
93
  auto boundNameSym = identifierTable.getSymbolHandle(runtime, boundName);
585
93
  if (LLVM_UNLIKELY(boundNameSym == ExecutionStatus::EXCEPTION)) {
586
0
    return ExecutionStatus::EXCEPTION;
587
0
  }
588
93
  Handle<StringPrimitive> boundNameHandle(
589
93
      runtime, identifierTable.getStringPrim(runtime, **boundNameSym));
590
93
  DefinePropertyFlags dpf = DefinePropertyFlags::getDefaultNewPropertyFlags();
591
93
  dpf.writable = 0;
592
93
  dpf.enumerable = 0;
593
594
93
  if (LLVM_UNLIKELY(
595
93
          JSObject::defineOwnProperty(
596
93
              selfHandle,
597
93
              runtime,
598
93
              Predefined::getSymbolID(Predefined::name),
599
93
              dpf,
600
93
              boundNameHandle) == ExecutionStatus::EXCEPTION)) {
601
0
    return ExecutionStatus::EXCEPTION;
602
0
  }
603
604
  // Define .callee and .arguments properties: throw always in bound functions.
605
93
  auto accessor =
606
93
      Handle<PropertyAccessor>::vmcast(&runtime.throwTypeErrorAccessor);
607
608
93
  pf.clear();
609
93
  pf.enumerable = 0;
610
93
  pf.configurable = 0;
611
93
  pf.accessor = 1;
612
613
93
  if (LLVM_UNLIKELY(
614
93
          JSObject::defineNewOwnProperty(
615
93
              selfHandle,
616
93
              runtime,
617
93
              Predefined::getSymbolID(Predefined::caller),
618
93
              pf,
619
93
              accessor) == ExecutionStatus::EXCEPTION)) {
620
0
    return ExecutionStatus::EXCEPTION;
621
0
  }
622
623
93
  if (LLVM_UNLIKELY(
624
93
          JSObject::defineNewOwnProperty(
625
93
              selfHandle,
626
93
              runtime,
627
93
              Predefined::getSymbolID(Predefined::arguments),
628
93
              pf,
629
93
              accessor) == ExecutionStatus::EXCEPTION)) {
630
0
    return ExecutionStatus::EXCEPTION;
631
0
  }
632
633
93
  return ExecutionStatus::RETURNED;
634
93
}
635
636
CallResult<PseudoHandle<JSObject>> BoundFunction::_newObjectImpl_RJS(
637
    Handle<Callable> selfHandle,
638
    Runtime &runtime,
639
0
    Handle<JSObject>) {
640
0
  auto *self = vmcast<BoundFunction>(*selfHandle);
641
642
  // If it is a chain of bound functions, skip directly to the end.
643
0
  while (auto *targetAsBound =
644
0
             dyn_vmcast<BoundFunction>(self->getTarget(runtime)))
645
0
    self = targetAsBound;
646
647
0
  auto targetHandle = runtime.makeHandle(self->getTarget(runtime));
648
649
  // We must duplicate the [[Construct]] functionality here.
650
651
  // Obtain "target.prototype".
652
0
  auto propRes = JSObject::getNamed_RJS(
653
0
      targetHandle, runtime, Predefined::getSymbolID(Predefined::prototype));
654
0
  if (propRes == ExecutionStatus::EXCEPTION)
655
0
    return ExecutionStatus::EXCEPTION;
656
0
  auto prototype = runtime.makeHandle(std::move(*propRes));
657
658
  // If target.prototype is an object, use it, otherwise use the standard
659
  // object prototype.
660
0
  return targetHandle->getVT()->newObject(
661
0
      targetHandle,
662
0
      runtime,
663
0
      prototype->isObject()
664
0
          ? Handle<JSObject>::vmcast(prototype)
665
0
          : Handle<JSObject>::vmcast(&runtime.objectPrototype));
666
0
}
667
668
CallResult<PseudoHandle<>> BoundFunction::_boundCall(
669
    BoundFunction *self,
670
    const Inst *ip,
671
0
    Runtime &runtime) {
672
0
  ScopedNativeDepthTracker depthTracker{runtime};
673
0
  if (LLVM_UNLIKELY(depthTracker.overflowed())) {
674
0
    return runtime.raiseStackOverflow(Runtime::StackOverflowKind::NativeStack);
675
0
  }
676
677
0
  CallResult<PseudoHandle<>> res{ExecutionStatus::EXCEPTION};
678
0
  StackFramePtr originalCalleeFrame = StackFramePtr(runtime.getStackPointer());
679
  // Save the original newTarget since we will overwrite it.
680
0
  HermesValue originalNewTarget = originalCalleeFrame.getNewTargetRef();
681
  // Save the original arg count since we will lose it.
682
0
  auto originalArgCount = originalCalleeFrame.getArgCount();
683
  // Keep track of the total arg count.
684
0
  auto totalArgCount = originalArgCount;
685
686
0
  auto callerFrame = runtime.getCurrentFrame();
687
  // We must preserve the "thisArg" passed to us by the caller because it is in
688
  // a register that is not supposed to be modified by a call. Copy it to the
689
  // scratch register in the caller's frame.
690
  // Note that since there is only one scratch reg, we must process all chained
691
  // bound calls in one go (which is more efficient anyway).
692
0
  callerFrame.getScratchRef() = originalCalleeFrame.getThisArgRef();
693
694
  // Pop the stack down to the first argument, erasing the call frame - we don't
695
  // need the call frame since we will build a new one.
696
0
  runtime.popToSavedStackPointer(&originalCalleeFrame.getThisArgRef());
697
698
  // Loop, copying the bound arguments of all chained bound functions.
699
0
  for (;;) {
700
0
    auto boundArgCount = self->getArgCountWithThis(runtime) - 1;
701
0
    totalArgCount += boundArgCount;
702
703
    // Check if we have enough stack for the arguments and the frame metadata.
704
0
    if (LLVM_UNLIKELY(!runtime.checkAvailableStack(
705
0
            StackFrameLayout::callerOutgoingRegisters(boundArgCount)))) {
706
      // Oops, we ran out of stack in the middle of calling a bound function.
707
      // Restore everything and bail.
708
709
      // We can't "pop" the stack pointer to an arbitrary value, which may be
710
      // higher than the current pointer. So, first we pop everything that we
711
      // may have pushed, then allocate the correct amount to get back to the
712
      // initial state.
713
0
      runtime.popToSavedStackPointer(&originalCalleeFrame.getThisArgRef());
714
0
      runtime.allocUninitializedStack(
715
0
          StackFrameLayout::CallerExtraRegistersAtEnd + 1);
716
0
      assert(
717
0
          runtime.getStackPointer() == originalCalleeFrame.ptr() &&
718
0
          "Stack wasn't restored properly");
719
720
0
      res = runtime.raiseStackOverflow(
721
0
          Runtime::StackOverflowKind::JSRegisterStack);
722
0
      goto bail;
723
0
    }
724
725
    // Allocate space only for the arguments for now.
726
0
    auto *stack = runtime.allocUninitializedStack(boundArgCount);
727
728
    // Copy the bound arguments (but not the bound "this").
729
0
    std::uninitialized_copy_n(
730
0
        self->getArgsWithThis(runtime) + 1, boundArgCount, ArgIterator(stack));
731
732
    // Loop while the target is another bound function.
733
0
    auto *targetAsBound = dyn_vmcast<BoundFunction>(self->getTarget(runtime));
734
0
    if (!targetAsBound)
735
0
      break;
736
0
    self = targetAsBound;
737
0
  }
738
739
  // Block scope for non-trivial variables to avoid complaints from "goto".
740
0
  {
741
    // Allocate space for "thisArg" and the frame metdata following the outgoing
742
    // registers. Note that we already checked earlier that we have enough
743
    // stack.
744
0
    auto *stack = runtime.allocUninitializedStack(
745
0
        StackFrameLayout::CallerExtraRegistersAtEnd + 1);
746
747
    // Initialize the new frame metadata.
748
0
    auto newCalleeFrame = StackFramePtr::initFrame(
749
0
        stack,
750
0
        runtime.getCurrentFrame(),
751
0
        ip,
752
0
        nullptr,
753
0
        totalArgCount,
754
0
        HermesValue::encodeObjectValue(self->getTarget(runtime)),
755
0
        originalNewTarget);
756
    // Initialize "thisArg". When constructing we must use the original 'this',
757
    // not the bound one.
758
0
    newCalleeFrame.getThisArgRef() = !originalNewTarget.isUndefined()
759
0
        ? static_cast<HermesValue>(callerFrame.getScratchRef())
760
0
        : self->getArgsWithThis(runtime)[0];
761
762
0
    res =
763
0
        Callable::call(newCalleeFrame.getCalleeClosureHandleUnsafe(), runtime);
764
765
0
    assert(
766
0
        runtime.getCurrentFrame() == callerFrame &&
767
0
        "caller frame not restored");
768
769
    // Restore the original stack level.
770
0
    runtime.popToSavedStackPointer(originalCalleeFrame.ptr());
771
0
  }
772
773
0
bail:
774
  // We must restore the original call frame. There is no need to restore
775
  // all the fields to their previous values, just the registers which are not
776
  // supposed to be modified by a call.
777
0
  StackFramePtr::initFrame(
778
0
      originalCalleeFrame.ptr(),
779
0
      StackFramePtr{},
780
0
      ip,
781
0
      nullptr,
782
0
      0,
783
0
      HermesValue::encodeEmptyValue(),
784
0
      HermesValue::encodeEmptyValue());
785
786
  // Restore "thisArg" and clear the scratch register to avoid a leak.
787
0
  originalCalleeFrame.getThisArgRef() = callerFrame.getScratchRef();
788
0
  callerFrame.getScratchRef() = HermesValue::encodeUndefinedValue();
789
790
0
  return res;
791
0
}
792
793
CallResult<PseudoHandle<>> BoundFunction::_callImpl(
794
    Handle<Callable> selfHandle,
795
0
    Runtime &runtime) {
796
  // Pass `nullptr` as the IP because this function is never called
797
  // from the interpreter, which should use `_boundCall` directly.
798
0
  return _boundCall(vmcast<BoundFunction>(selfHandle.get()), nullptr, runtime);
799
0
}
800
801
//===----------------------------------------------------------------------===//
802
// class NativeFunction
803
804
const CallableVTable NativeFunction::vt{
805
    {
806
        VTable(
807
            CellKind::NativeFunctionKind,
808
            cellSize<NativeFunction>(),
809
            nullptr,
810
            nullptr,
811
            nullptr
812
#ifdef HERMES_MEMORY_INSTRUMENTATION
813
            ,
814
            VTable::HeapSnapshotMetadata{
815
                HeapSnapshot::NodeType::Closure,
816
                NativeFunction::_snapshotNameImpl,
817
                NativeFunction::_snapshotAddEdgesImpl,
818
                nullptr,
819
                nullptr}
820
#endif
821
            ),
822
        NativeFunction::_getOwnIndexedRangeImpl,
823
        NativeFunction::_haveOwnIndexedImpl,
824
        NativeFunction::_getOwnIndexedPropertyFlagsImpl,
825
        NativeFunction::_getOwnIndexedImpl,
826
        NativeFunction::_setOwnIndexedImpl,
827
        NativeFunction::_deleteOwnIndexedImpl,
828
        NativeFunction::_checkAllOwnIndexedImpl,
829
    },
830
    NativeFunction::_newObjectImpl,
831
    NativeFunction::_callImpl};
832
833
4
void NativeFunctionBuildMeta(const GCCell *cell, Metadata::Builder &mb) {
834
4
  mb.addJSObjectOverlapSlots(JSObject::numOverlapSlots<NativeFunction>());
835
4
  CallableBuildMeta(cell, mb);
836
4
  mb.setVTable(&NativeFunction::vt);
837
4
}
838
839
#ifdef HERMES_MEMORY_INSTRUMENTATION
840
0
std::string NativeFunction::_snapshotNameImpl(GCCell *cell, GC &gc) {
841
0
  auto *const self = reinterpret_cast<NativeFunction *>(cell);
842
0
  return getFunctionName(self->functionPtr_);
843
0
}
844
#endif
845
846
Handle<NativeFunction> NativeFunction::create(
847
    Runtime &runtime,
848
    Handle<JSObject> parentHandle,
849
    void *context,
850
    NativeFunctionPtr functionPtr,
851
    SymbolID name,
852
    unsigned paramCount,
853
    Handle<JSObject> prototypeObjectHandle,
854
41.0k
    unsigned additionalSlotCount) {
855
41.0k
  size_t reservedSlots =
856
41.0k
      numOverlapSlots<NativeFunction>() + additionalSlotCount;
857
41.0k
  auto *cell = runtime.makeAFixed<NativeFunction>(
858
41.0k
      runtime,
859
41.0k
      parentHandle,
860
41.0k
      runtime.getHiddenClassForPrototype(*parentHandle, reservedSlots),
861
41.0k
      context,
862
41.0k
      functionPtr);
863
41.0k
  auto selfHandle = JSObjectInit::initToHandle(runtime, cell);
864
865
  // Allocate a propStorage if the number of additional slots requires it.
866
41.0k
  runtime.ignoreAllocationFailure(
867
41.0k
      JSObject::allocatePropStorage(selfHandle, runtime, reservedSlots));
868
869
41.0k
  auto st = defineNameLengthAndPrototype(
870
41.0k
      selfHandle,
871
41.0k
      runtime,
872
41.0k
      name,
873
41.0k
      paramCount,
874
41.0k
      prototypeObjectHandle,
875
41.0k
      Callable::WritablePrototype::Yes,
876
41.0k
      false);
877
41.0k
  (void)st;
878
41.0k
  assert(
879
41.0k
      st != ExecutionStatus::EXCEPTION && "defineLengthAndPrototype() failed");
880
881
41.0k
  return selfHandle;
882
41.0k
}
883
884
Handle<NativeFunction> NativeFunction::create(
885
    Runtime &runtime,
886
    Handle<JSObject> parentHandle,
887
    Handle<Environment> parentEnvHandle,
888
    void *context,
889
    NativeFunctionPtr functionPtr,
890
    SymbolID name,
891
    unsigned paramCount,
892
    Handle<JSObject> prototypeObjectHandle,
893
0
    unsigned additionalSlotCount) {
894
0
  auto *cell = runtime.makeAFixed<NativeFunction>(
895
0
      runtime,
896
0
      parentHandle,
897
0
      runtime.getHiddenClassForPrototype(
898
0
          *parentHandle,
899
0
          numOverlapSlots<NativeFunction>() + additionalSlotCount),
900
0
      parentEnvHandle,
901
0
      context,
902
0
      functionPtr);
903
0
  auto selfHandle = JSObjectInit::initToHandle(runtime, cell);
904
905
0
  auto st = defineNameLengthAndPrototype(
906
0
      selfHandle,
907
0
      runtime,
908
0
      name,
909
0
      paramCount,
910
0
      prototypeObjectHandle,
911
0
      Callable::WritablePrototype::Yes,
912
0
      false);
913
0
  (void)st;
914
0
  assert(
915
0
      st != ExecutionStatus::EXCEPTION && "defineLengthAndPrototype() failed");
916
917
0
  return selfHandle;
918
0
}
919
920
CallResult<PseudoHandle<>> NativeFunction::_callImpl(
921
    Handle<Callable> selfHandle,
922
1.07M
    Runtime &runtime) {
923
1.07M
  return _nativeCall(vmcast<NativeFunction>(selfHandle.get()), runtime);
924
1.07M
}
925
926
CallResult<PseudoHandle<JSObject>> NativeFunction::_newObjectImpl(
927
    Handle<Callable>,
928
    Runtime &runtime,
929
0
    Handle<JSObject>) {
930
0
  return runtime.raiseTypeError(
931
0
      "This function cannot be used as a constructor.");
932
0
}
933
934
//===----------------------------------------------------------------------===//
935
// class NativeConstructor
936
937
template <class From>
938
static CallResult<PseudoHandle<JSObject>> toCallResultPseudoHandleJSObject(
939
0
    PseudoHandle<From> &&other) {
940
0
  return PseudoHandle<JSObject>{std::move(other)};
941
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> >&&)
942
943
template <class From>
944
static CallResult<PseudoHandle<JSObject>> toCallResultPseudoHandleJSObject(
945
0
    CallResult<PseudoHandle<From>> &&other) {
946
0
  return std::move(other);
947
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
948
949
template <class From>
950
static CallResult<PseudoHandle<JSObject>> toCallResultPseudoHandleJSObject(
951
0
    CallResult<Handle<From>> other) {
952
0
  if (LLVM_UNLIKELY(other == ExecutionStatus::EXCEPTION)) {
953
0
    return ExecutionStatus::EXCEPTION;
954
0
  }
955
0
  return PseudoHandle<JSObject>{*other};
956
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
957
958
template <class From>
959
static CallResult<PseudoHandle<JSObject>> toCallResultPseudoHandleJSObject(
960
    Handle<From> other) {
961
  return PseudoHandle<JSObject>{other};
962
}
963
964
template <class NativeClass>
965
CallResult<PseudoHandle<JSObject>> NativeConstructor::creatorFunction(
966
    Runtime &runtime,
967
    Handle<JSObject> prototype,
968
0
    void *) {
969
0
  return toCallResultPseudoHandleJSObject(
970
0
      NativeClass::create(runtime, prototype));
971
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*)
972
973
#define NATIVE_CONSTRUCTOR(fun)                    \
974
  template CallResult<PseudoHandle<JSObject>> fun( \
975
      Runtime &, Handle<JSObject>, void *);
976
#include "hermes/VM/NativeFunctions.def"
977
#undef NATIVE_CONSTRUCTOR
978
979
const CallableVTable NativeConstructor::vt{
980
    {
981
        VTable(
982
            CellKind::NativeConstructorKind,
983
            cellSize<NativeConstructor>(),
984
            nullptr,
985
            nullptr,
986
            nullptr
987
#ifdef HERMES_MEMORY_INSTRUMENTATION
988
            ,
989
            VTable::HeapSnapshotMetadata{
990
                HeapSnapshot::NodeType::Closure,
991
                NativeConstructor::_snapshotNameImpl,
992
                NativeConstructor::_snapshotAddEdgesImpl,
993
                nullptr,
994
                nullptr}
995
#endif
996
            ),
997
        NativeConstructor::_getOwnIndexedRangeImpl,
998
        NativeConstructor::_haveOwnIndexedImpl,
999
        NativeConstructor::_getOwnIndexedPropertyFlagsImpl,
1000
        NativeConstructor::_getOwnIndexedImpl,
1001
        NativeConstructor::_setOwnIndexedImpl,
1002
        NativeConstructor::_deleteOwnIndexedImpl,
1003
        NativeConstructor::_checkAllOwnIndexedImpl,
1004
    },
1005
    NativeConstructor::_newObjectImpl,
1006
    NativeConstructor::_callImpl};
1007
1008
1
void NativeConstructorBuildMeta(const GCCell *cell, Metadata::Builder &mb) {
1009
1
  mb.addJSObjectOverlapSlots(JSObject::numOverlapSlots<NativeConstructor>());
1010
1
  NativeFunctionBuildMeta(cell, mb);
1011
1
  mb.setVTable(&NativeConstructor::vt);
1012
1
}
1013
1014
#ifndef NDEBUG
1015
CallResult<PseudoHandle<>> NativeConstructor::_callImpl(
1016
    Handle<Callable> selfHandle,
1017
0
    Runtime &runtime) {
1018
0
  StackFramePtr newFrame{runtime.getStackPointer()};
1019
1020
0
  if (newFrame.isConstructorCall()) {
1021
0
    auto consHandle = Handle<NativeConstructor>::vmcast(selfHandle);
1022
0
    assert(
1023
0
        consHandle->targetKind_ ==
1024
0
            vmcast<JSObject>(newFrame.getThisArgRef())->getKind() &&
1025
0
        "call(construct=true) called without the correct 'this' value");
1026
0
  }
1027
0
  return NativeFunction::_callImpl(selfHandle, runtime);
1028
0
}
1029
#endif
1030
1031
//===----------------------------------------------------------------------===//
1032
// class JSFunction
1033
1034
const CallableVTable JSFunction::vt{
1035
    {
1036
        VTable(
1037
            CellKind::JSFunctionKind,
1038
            cellSize<JSFunction>(),
1039
            nullptr,
1040
            nullptr,
1041
            nullptr
1042
#ifdef HERMES_MEMORY_INSTRUMENTATION
1043
            ,
1044
            VTable::HeapSnapshotMetadata{
1045
                HeapSnapshot::NodeType::Closure,
1046
                JSFunction::_snapshotNameImpl,
1047
                JSFunction::_snapshotAddEdgesImpl,
1048
                nullptr,
1049
                JSFunction::_snapshotAddLocationsImpl}
1050
#endif
1051
            ),
1052
        JSFunction::_getOwnIndexedRangeImpl,
1053
        JSFunction::_haveOwnIndexedImpl,
1054
        JSFunction::_getOwnIndexedPropertyFlagsImpl,
1055
        JSFunction::_getOwnIndexedImpl,
1056
        JSFunction::_setOwnIndexedImpl,
1057
        JSFunction::_deleteOwnIndexedImpl,
1058
        JSFunction::_checkAllOwnIndexedImpl,
1059
    },
1060
    JSFunction::_newObjectImpl,
1061
    JSFunction::_callImpl};
1062
1063
4
void JSFunctionBuildMeta(const GCCell *cell, Metadata::Builder &mb) {
1064
4
  mb.addJSObjectOverlapSlots(JSObject::numOverlapSlots<JSFunction>());
1065
4
  CallableBuildMeta(cell, mb);
1066
4
  const auto *self = static_cast<const JSFunction *>(cell);
1067
4
  mb.addField("domain", &self->domain_);
1068
4
  mb.setVTable(&JSFunction::vt);
1069
4
}
1070
1071
PseudoHandle<JSFunction> JSFunction::create(
1072
    Runtime &runtime,
1073
    Handle<Domain> domain,
1074
    Handle<JSObject> parentHandle,
1075
    Handle<Environment> envHandle,
1076
3.52k
    CodeBlock *codeBlock) {
1077
3.52k
  auto *cell = runtime.makeAFixed<JSFunction, kHasFinalizer>(
1078
3.52k
      runtime,
1079
3.52k
      domain,
1080
3.52k
      parentHandle,
1081
3.52k
      runtime.getHiddenClassForPrototype(
1082
3.52k
          *parentHandle, numOverlapSlots<JSFunction>()),
1083
3.52k
      envHandle,
1084
3.52k
      codeBlock);
1085
3.52k
  auto self = JSObjectInit::initToPseudoHandle(runtime, cell);
1086
3.52k
  self->flags_.lazyObject = 1;
1087
3.52k
  return self;
1088
3.52k
}
1089
1090
#ifdef HERMES_MEMORY_INSTRUMENTATION
1091
void JSFunction::addLocationToSnapshot(
1092
    HeapSnapshot &snap,
1093
    HeapSnapshot::NodeID id,
1094
0
    GC &gc) const {
1095
0
  if (auto location = codeBlock_.get(gc)->getSourceLocation()) {
1096
0
    snap.addLocation(
1097
0
        id,
1098
0
        codeBlock_.get(gc)->getRuntimeModule()->getScriptID(),
1099
0
        location->line,
1100
0
        location->column);
1101
0
  }
1102
0
}
1103
#endif
1104
1105
CallResult<PseudoHandle<>> JSFunction::_callImpl(
1106
    Handle<Callable> selfHandle,
1107
0
    Runtime &runtime) {
1108
0
  auto *self = vmcast<JSFunction>(selfHandle.get());
1109
0
  CallResult<HermesValue> result{ExecutionStatus::EXCEPTION};
1110
0
  result = runtime.interpretFunction(self->getCodeBlock(runtime));
1111
0
  if (LLVM_UNLIKELY(result == ExecutionStatus::EXCEPTION)) {
1112
0
    return ExecutionStatus::EXCEPTION;
1113
0
  }
1114
0
  return createPseudoHandle(*result);
1115
0
}
1116
1117
#ifdef HERMES_MEMORY_INSTRUMENTATION
1118
0
std::string JSFunction::_snapshotNameImpl(GCCell *cell, GC &gc) {
1119
0
  auto *const self = vmcast<JSFunction>(cell);
1120
0
  std::string funcName = Callable::_snapshotNameImpl(self, gc);
1121
0
  if (!funcName.empty()) {
1122
0
    return funcName;
1123
0
  }
1124
0
  return self->codeBlock_.get(gc)->getNameString(gc.getCallbacks());
1125
0
}
1126
1127
void JSFunction::_snapshotAddEdgesImpl(
1128
    GCCell *cell,
1129
    GC &gc,
1130
0
    HeapSnapshot &snap) {
1131
0
  auto *const self = vmcast<JSFunction>(cell);
1132
  // Add the super type's edges too.
1133
0
  Callable::_snapshotAddEdgesImpl(self, gc, snap);
1134
1135
  // A node for the code block will be added as part of the RuntimeModule.
1136
0
  snap.addNamedEdge(
1137
0
      HeapSnapshot::EdgeType::Shortcut,
1138
0
      "codeBlock",
1139
0
      gc.getIDTracker().getNativeID(self->codeBlock_.get(gc)));
1140
0
}
1141
1142
void JSFunction::_snapshotAddLocationsImpl(
1143
    GCCell *cell,
1144
    GC &gc,
1145
0
    HeapSnapshot &snap) {
1146
0
  auto *const self = vmcast<JSFunction>(cell);
1147
0
  self->addLocationToSnapshot(snap, gc.getObjectID(self), gc);
1148
0
}
1149
#endif
1150
1151
//===----------------------------------------------------------------------===//
1152
// class JSAsyncFunction
1153
1154
const CallableVTable JSAsyncFunction::vt{
1155
    {
1156
        VTable(
1157
            CellKind::JSAsyncFunctionKind,
1158
            cellSize<JSAsyncFunction>(),
1159
            nullptr,
1160
            nullptr,
1161
            nullptr
1162
#ifdef HERMES_MEMORY_INSTRUMENTATION
1163
            ,
1164
            VTable::HeapSnapshotMetadata{
1165
                HeapSnapshot::NodeType::Closure,
1166
                JSAsyncFunction::_snapshotNameImpl,
1167
                JSAsyncFunction::_snapshotAddEdgesImpl,
1168
                nullptr,
1169
                nullptr}
1170
#endif
1171
            ),
1172
        JSAsyncFunction::_getOwnIndexedRangeImpl,
1173
        JSAsyncFunction::_haveOwnIndexedImpl,
1174
        JSAsyncFunction::_getOwnIndexedPropertyFlagsImpl,
1175
        JSAsyncFunction::_getOwnIndexedImpl,
1176
        JSAsyncFunction::_setOwnIndexedImpl,
1177
        JSAsyncFunction::_deleteOwnIndexedImpl,
1178
        JSAsyncFunction::_checkAllOwnIndexedImpl,
1179
    },
1180
    JSAsyncFunction::_newObjectImpl,
1181
    JSAsyncFunction::_callImpl};
1182
1183
1
void JSAsyncFunctionBuildMeta(const GCCell *cell, Metadata::Builder &mb) {
1184
1
  mb.addJSObjectOverlapSlots(JSObject::numOverlapSlots<JSAsyncFunction>());
1185
1
  JSFunctionBuildMeta(cell, mb);
1186
1
  mb.setVTable(&JSAsyncFunction::vt);
1187
1
}
1188
1189
PseudoHandle<JSAsyncFunction> JSAsyncFunction::create(
1190
    Runtime &runtime,
1191
    Handle<Domain> domain,
1192
    Handle<JSObject> parentHandle,
1193
    Handle<Environment> envHandle,
1194
0
    CodeBlock *codeBlock) {
1195
0
  auto *cell = runtime.makeAFixed<JSAsyncFunction, kHasFinalizer>(
1196
0
      runtime,
1197
0
      domain,
1198
0
      parentHandle,
1199
0
      runtime.getHiddenClassForPrototype(
1200
0
          *parentHandle, numOverlapSlots<JSAsyncFunction>()),
1201
0
      envHandle,
1202
0
      codeBlock);
1203
0
  auto self = JSObjectInit::initToPseudoHandle(runtime, cell);
1204
0
  self->flags_.lazyObject = 1;
1205
0
  return self;
1206
0
}
1207
1208
//===----------------------------------------------------------------------===//
1209
// class JSGeneratorFunction
1210
1211
const CallableVTable JSGeneratorFunction::vt{
1212
    {
1213
        VTable(
1214
            CellKind::JSGeneratorFunctionKind,
1215
            cellSize<JSGeneratorFunction>(),
1216
            nullptr,
1217
            nullptr,
1218
            nullptr
1219
#ifdef HERMES_MEMORY_INSTRUMENTATION
1220
            ,
1221
            VTable::HeapSnapshotMetadata{
1222
                HeapSnapshot::NodeType::Closure,
1223
                JSGeneratorFunction::_snapshotNameImpl,
1224
                JSGeneratorFunction::_snapshotAddEdgesImpl,
1225
                nullptr,
1226
                nullptr}
1227
#endif
1228
            ),
1229
        JSGeneratorFunction::_getOwnIndexedRangeImpl,
1230
        JSGeneratorFunction::_haveOwnIndexedImpl,
1231
        JSGeneratorFunction::_getOwnIndexedPropertyFlagsImpl,
1232
        JSGeneratorFunction::_getOwnIndexedImpl,
1233
        JSGeneratorFunction::_setOwnIndexedImpl,
1234
        JSGeneratorFunction::_deleteOwnIndexedImpl,
1235
        JSGeneratorFunction::_checkAllOwnIndexedImpl,
1236
    },
1237
    JSGeneratorFunction::_newObjectImpl,
1238
    JSGeneratorFunction::_callImpl};
1239
1240
1
void JSGeneratorFunctionBuildMeta(const GCCell *cell, Metadata::Builder &mb) {
1241
1
  mb.addJSObjectOverlapSlots(JSObject::numOverlapSlots<JSGeneratorFunction>());
1242
1
  JSFunctionBuildMeta(cell, mb);
1243
1
  mb.setVTable(&JSGeneratorFunction::vt);
1244
1
}
1245
1246
PseudoHandle<JSGeneratorFunction> JSGeneratorFunction::create(
1247
    Runtime &runtime,
1248
    Handle<Domain> domain,
1249
    Handle<JSObject> parentHandle,
1250
    Handle<Environment> envHandle,
1251
10
    CodeBlock *codeBlock) {
1252
10
  auto *cell = runtime.makeAFixed<JSGeneratorFunction, kHasFinalizer>(
1253
10
      runtime,
1254
10
      domain,
1255
10
      parentHandle,
1256
10
      runtime.getHiddenClassForPrototype(
1257
10
          *parentHandle, numOverlapSlots<JSGeneratorFunction>()),
1258
10
      envHandle,
1259
10
      codeBlock);
1260
10
  auto self = JSObjectInit::initToPseudoHandle(runtime, cell);
1261
10
  self->flags_.lazyObject = 1;
1262
10
  return self;
1263
10
}
1264
1265
//===----------------------------------------------------------------------===//
1266
// class GeneratorInnerFunction
1267
1268
const CallableVTable GeneratorInnerFunction::vt{
1269
    {
1270
        VTable(
1271
            CellKind::GeneratorInnerFunctionKind,
1272
            cellSize<GeneratorInnerFunction>(),
1273
            nullptr,
1274
            nullptr,
1275
            nullptr
1276
#ifdef HERMES_MEMORY_INSTRUMENTATION
1277
            ,
1278
            VTable::HeapSnapshotMetadata{
1279
                HeapSnapshot::NodeType::Closure,
1280
                GeneratorInnerFunction::_snapshotNameImpl,
1281
                GeneratorInnerFunction::_snapshotAddEdgesImpl,
1282
                nullptr,
1283
                nullptr}
1284
#endif
1285
            ),
1286
        GeneratorInnerFunction::_getOwnIndexedRangeImpl,
1287
        GeneratorInnerFunction::_haveOwnIndexedImpl,
1288
        GeneratorInnerFunction::_getOwnIndexedPropertyFlagsImpl,
1289
        GeneratorInnerFunction::_getOwnIndexedImpl,
1290
        GeneratorInnerFunction::_setOwnIndexedImpl,
1291
        GeneratorInnerFunction::_deleteOwnIndexedImpl,
1292
        GeneratorInnerFunction::_checkAllOwnIndexedImpl,
1293
    },
1294
    GeneratorInnerFunction::_newObjectImpl,
1295
    GeneratorInnerFunction::_callImpl};
1296
1297
void GeneratorInnerFunctionBuildMeta(
1298
    const GCCell *cell,
1299
1
    Metadata::Builder &mb) {
1300
1
  mb.addJSObjectOverlapSlots(
1301
1
      JSObject::numOverlapSlots<GeneratorInnerFunction>());
1302
1
  JSFunctionBuildMeta(cell, mb);
1303
1
  const auto *self = static_cast<const GeneratorInnerFunction *>(cell);
1304
1
  mb.setVTable(&GeneratorInnerFunction::vt);
1305
1
  mb.addField("savedContext", &self->savedContext_);
1306
1
  mb.addField("result", &self->result_);
1307
1
}
1308
1309
CallResult<Handle<GeneratorInnerFunction>> GeneratorInnerFunction::create(
1310
    Runtime &runtime,
1311
    Handle<Domain> domain,
1312
    Handle<JSObject> parentHandle,
1313
    Handle<Environment> envHandle,
1314
    CodeBlock *codeBlock,
1315
0
    NativeArgs args) {
1316
0
  auto *cell = runtime.makeAFixed<GeneratorInnerFunction>(
1317
0
      runtime,
1318
0
      domain,
1319
0
      parentHandle,
1320
0
      runtime.getHiddenClassForPrototype(
1321
0
          *parentHandle, numOverlapSlots<GeneratorInnerFunction>()),
1322
0
      envHandle,
1323
0
      codeBlock,
1324
0
      args.getArgCount());
1325
0
  auto self = JSObjectInit::initToHandle(runtime, cell);
1326
1327
0
  const uint32_t ctxSize = getContextSize(codeBlock, args.getArgCount());
1328
1329
0
  auto ctxRes = ArrayStorage::create(runtime, ctxSize, ctxSize);
1330
0
  if (LLVM_UNLIKELY(ctxRes == ExecutionStatus::EXCEPTION)) {
1331
0
    return ExecutionStatus::EXCEPTION;
1332
0
  }
1333
0
  auto ctx = runtime.makeHandle<ArrayStorage>(*ctxRes);
1334
1335
  // Set "this" as the first element.
1336
0
  ctx->set(0, args.getThisArg(), runtime.getHeap());
1337
1338
  // Set the rest of the arguments.
1339
  // Argument i goes in slot i+1 to account for the "this".
1340
0
  for (uint32_t i = 0, e = args.getArgCount(); i < e; ++i) {
1341
0
    ctx->set(i + 1, args.getArg(i), runtime.getHeap());
1342
0
  }
1343
1344
0
  self->savedContext_.set(runtime, ctx.get(), runtime.getHeap());
1345
1346
0
  return self;
1347
0
}
1348
1349
/// Call the callable with arguments already on the stack.
1350
CallResult<PseudoHandle<>> GeneratorInnerFunction::callInnerFunction(
1351
    Handle<GeneratorInnerFunction> selfHandle,
1352
    Runtime &runtime,
1353
    Handle<> arg,
1354
0
    Action action) {
1355
0
  auto self = Handle<GeneratorInnerFunction>::vmcast(selfHandle);
1356
1357
0
  SmallHermesValue shv =
1358
0
      SmallHermesValue::encodeHermesValue(arg.getHermesValue(), runtime);
1359
0
  self->result_.set(shv, runtime.getHeap());
1360
0
  self->action_ = action;
1361
1362
0
  auto ctx = runtime.makeMutableHandle(selfHandle->savedContext_);
1363
  // Account for the `this` argument stored as the first element of ctx.
1364
0
  const uint32_t argCount = self->argCount_;
1365
  // Generators cannot be used as constructors, so newTarget is always
1366
  // undefined.
1367
0
  HermesValue newTarget = HermesValue::encodeUndefinedValue();
1368
0
  ScopedNativeCallFrame frame{
1369
0
      runtime,
1370
0
      argCount, // Account for `this`.
1371
0
      selfHandle.getHermesValue(),
1372
0
      newTarget,
1373
0
      ctx->at(0)};
1374
0
  if (LLVM_UNLIKELY(frame.overflowed()))
1375
0
    return runtime.raiseStackOverflow(Runtime::StackOverflowKind::NativeStack);
1376
0
  for (ArrayStorage::size_type i = 0, e = argCount; i < e; ++i) {
1377
0
    frame->getArgRef(i) = ctx->at(i + 1);
1378
0
  }
1379
1380
  // Force lazy compilation immediately in order to size the context properly.
1381
  // We're about to call the function anyway, so this doesn't reduce laziness.
1382
  // Note that this will do nothing after the very first time a lazy function
1383
  // is called, so we only resize before we save any registers at all.
1384
0
  if (LLVM_UNLIKELY(selfHandle->getCodeBlock(runtime)->isLazy())) {
1385
0
    if (LLVM_UNLIKELY(
1386
0
            selfHandle->getCodeBlock(runtime)->lazyCompile(runtime) ==
1387
0
            ExecutionStatus::EXCEPTION)) {
1388
0
      return ExecutionStatus::EXCEPTION;
1389
0
    }
1390
0
    if (LLVM_UNLIKELY(
1391
0
            ArrayStorage::resize(
1392
0
                ctx,
1393
0
                runtime,
1394
0
                getContextSize(
1395
0
                    selfHandle->getCodeBlock(runtime),
1396
0
                    selfHandle->argCount_)) == ExecutionStatus::EXCEPTION)) {
1397
0
      return ExecutionStatus::EXCEPTION;
1398
0
    }
1399
0
    selfHandle->savedContext_.set(runtime, ctx.get(), runtime.getHeap());
1400
0
  }
1401
1402
0
  return JSFunction::_callImpl(selfHandle, runtime);
1403
0
}
1404
1405
0
void GeneratorInnerFunction::restoreStack(Runtime &runtime) {
1406
0
  const uint32_t frameOffset = getFrameOffsetInContext();
1407
0
  const uint32_t frameSize = getFrameSizeInContext(runtime);
1408
  // Start at the lower end of the range to be copied.
1409
0
  PinnedHermesValue *dst = runtime.getCurrentFrame().ptr();
1410
0
  assert(
1411
0
      dst + frameSize <= runtime.getStackPointer() &&
1412
0
      "writing off the end of the stack");
1413
0
  const GCHermesValue *src =
1414
0
      savedContext_.getNonNull(runtime)->data() + frameOffset;
1415
0
  GCHermesValueUtil::copyToPinned(src, src + frameSize, dst);
1416
0
}
1417
1418
0
void GeneratorInnerFunction::saveStack(Runtime &runtime) {
1419
0
  const uint32_t frameOffset = getFrameOffsetInContext();
1420
0
  const uint32_t frameSize = getFrameSizeInContext(runtime);
1421
  // Start at the lower end of the range to be copied.
1422
0
  PinnedHermesValue *first = runtime.getCurrentFrame().ptr();
1423
0
  assert(
1424
0
      first + frameSize <= runtime.getStackPointer() &&
1425
0
      "reading off the end of the stack");
1426
  // Use GCHermesValue::copy to ensure write barriers are executed.
1427
0
  GCHermesValue::copy(
1428
0
      first,
1429
0
      first + frameSize,
1430
0
      savedContext_.getNonNull(runtime)->data() + frameOffset,
1431
0
      runtime.getHeap());
1432
0
}
1433
1434
} // namespace vm
1435
} // namespace hermes