Coverage Report

Created: 2025-12-12 07:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hermes/lib/IR/IRBuilder.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 "llvh/Support/Casting.h"
9
#include "llvh/Support/ErrorHandling.h"
10
11
#include "hermes/AST/Context.h"
12
#include "hermes/IR/IR.h"
13
#include "hermes/IR/IRBuilder.h"
14
15
using namespace hermes;
16
17
119k
BasicBlock *IRBuilder::createBasicBlock(Function *Parent) {
18
119k
  assert(Parent && "Invalid insertion point");
19
119k
  return new BasicBlock(Parent);
20
119k
}
21
22
Function *IRBuilder::createFunction(
23
    ScopeDesc *scopeDesc,
24
    Identifier OriginalName,
25
    Function::DefinitionKind definitionKind,
26
    bool strictMode,
27
    SourceVisibility sourceVisibility,
28
    SMRange sourceRange,
29
    bool isGlobal,
30
23.2k
    Function *insertBefore) {
31
  // Function must have a name. If the source doesn't provide the function name,
32
  // Hermes will try to infer the name from the name of a variable or property
33
  // it is assigned to. If there was no inference, an empty string is used.
34
23.2k
  if (!OriginalName.isValid()) {
35
21.8k
    OriginalName = createIdentifier("");
36
21.8k
  }
37
23.2k
  return new Function(
38
23.2k
      M,
39
23.2k
      scopeDesc,
40
23.2k
      OriginalName,
41
23.2k
      definitionKind,
42
23.2k
      strictMode,
43
23.2k
      sourceVisibility,
44
23.2k
      isGlobal,
45
23.2k
      sourceRange,
46
23.2k
      insertBefore);
47
23.2k
}
48
49
GeneratorFunction *IRBuilder::createGeneratorFunction(
50
    ScopeDesc *scopeDesc,
51
    Identifier OriginalName,
52
    Function::DefinitionKind definitionKind,
53
    bool strictMode,
54
    SourceVisibility sourceVisibility,
55
    SMRange sourceRange,
56
0
    Function *insertBefore) {
57
0
  if (!OriginalName.isValid()) {
58
    // Function must have a name, even it's empty.
59
    // Eventually we will give it a properly inferred name.
60
0
    OriginalName = createIdentifier("");
61
0
  }
62
0
  return new GeneratorFunction(
63
0
      M,
64
0
      scopeDesc,
65
0
      OriginalName,
66
0
      definitionKind,
67
0
      strictMode,
68
0
      sourceVisibility,
69
0
      /* isGlobal */ false,
70
0
      sourceRange,
71
0
      insertBefore);
72
0
}
73
74
GeneratorInnerFunction *IRBuilder::createGeneratorInnerFunction(
75
    ScopeDesc *scopeDesc,
76
    Identifier OriginalName,
77
    Function::DefinitionKind definitionKind,
78
    bool strictMode,
79
    SMRange sourceRange,
80
0
    Function *insertBefore) {
81
0
  if (!OriginalName.isValid()) {
82
    // Function must have a name, even it's empty.
83
    // Eventually we will give it a properly inferred name.
84
0
    OriginalName = createIdentifier("");
85
0
  }
86
0
  return new GeneratorInnerFunction(
87
0
      M,
88
0
      scopeDesc,
89
0
      OriginalName,
90
0
      definitionKind,
91
0
      strictMode,
92
0
      /* isGlobal */ false,
93
0
      sourceRange,
94
0
      insertBefore);
95
0
}
96
97
Function *IRBuilder::createTopLevelFunction(
98
    ScopeDesc *scopeDesc,
99
    bool strictMode,
100
    SourceVisibility sourceVisibility,
101
147
    SMRange sourceRange) {
102
  // Notice that this synthesized name is not a legal javascript name and
103
  // can't collide with functions in the processed program.
104
147
  return createFunction(
105
147
      scopeDesc,
106
147
      "global",
107
147
      Function::DefinitionKind::ES5Function,
108
147
      strictMode,
109
147
      sourceVisibility,
110
147
      sourceRange,
111
147
      true);
112
147
}
113
114
Function *IRBuilder::createFunction(
115
    ScopeDesc *scopeDesc,
116
    llvh::StringRef OriginalName,
117
    Function::DefinitionKind definitionKind,
118
    bool strictMode,
119
    SourceVisibility sourceVisibility,
120
    SMRange sourceRange,
121
    bool isGlobal,
122
147
    Function *insertBefore) {
123
147
  Identifier OrigIden =
124
147
      OriginalName.empty() ? Identifier{} : createIdentifier(OriginalName);
125
147
  return createFunction(
126
147
      scopeDesc,
127
147
      OrigIden,
128
147
      definitionKind,
129
147
      strictMode,
130
147
      sourceVisibility,
131
147
      sourceRange,
132
147
      isGlobal,
133
147
      insertBefore);
134
147
}
135
136
AsyncFunction *IRBuilder::createAsyncFunction(
137
    ScopeDesc *scopeDesc,
138
    Identifier OriginalName,
139
    Function::DefinitionKind definitionKind,
140
    bool strictMode,
141
    SourceVisibility sourceVisibility,
142
    SMRange sourceRange,
143
0
    Function *insertBefore) {
144
0
  if (!OriginalName.isValid()) {
145
    // Function must have a name, even it's empty.
146
    // Eventually we will give it a properly inferred name.
147
0
    OriginalName = createIdentifier("");
148
0
  }
149
0
  return new AsyncFunction(
150
0
      M,
151
0
      scopeDesc,
152
0
      OriginalName,
153
0
      definitionKind,
154
0
      strictMode,
155
0
      sourceVisibility,
156
0
      /* isGlobal */ false,
157
0
      sourceRange,
158
0
      insertBefore);
159
0
}
160
161
GlobalObjectProperty *IRBuilder::createGlobalObjectProperty(
162
    Identifier name,
163
9.88k
    bool declared) {
164
9.88k
  return M->addGlobalProperty(name, declared);
165
9.88k
}
166
GlobalObjectProperty *IRBuilder::createGlobalObjectProperty(
167
    llvh::StringRef name,
168
0
    bool declared) {
169
0
  return createGlobalObjectProperty(
170
0
      M->getContext().getIdentifier(name), declared);
171
0
}
172
173
23.0k
Parameter *IRBuilder::createParameter(Function *Parent, Identifier Name) {
174
23.0k
  return new Parameter(Parent, Name, false);
175
23.0k
}
176
177
0
Parameter *IRBuilder::createParameter(Function *Parent, llvh::StringRef Name) {
178
0
  return createParameter(Parent, createIdentifier(Name));
179
0
}
180
181
23.1k
Parameter *IRBuilder::createThisParameter(Function *Parent) {
182
23.1k
  return new Parameter(Parent, createIdentifier("this"), true);
183
23.1k
}
184
185
Variable *IRBuilder::createVariable(
186
    ScopeDesc *Parent,
187
    Variable::DeclKind declKind,
188
23.0k
    Identifier Name) {
189
23.0k
  return new Variable(Parent, declKind, Name);
190
23.0k
}
191
192
Variable *IRBuilder::createVariable(
193
    ScopeDesc *Parent,
194
    Variable::DeclKind declKind,
195
0
    llvh::StringRef Name) {
196
0
  return createVariable(Parent, declKind, createIdentifier(Name));
197
0
}
198
199
676k
LiteralNumber *IRBuilder::getLiteralNumber(double value) {
200
676k
  return M->getLiteralNumber(value);
201
676k
}
202
203
// FIXME: use proper language semantics.
204
2
LiteralNumber *IRBuilder::getLiteralPositiveZero() {
205
2
  return M->getLiteralNumber(+0.0);
206
2
}
207
208
0
LiteralNumber *IRBuilder::getLiteralNegativeZero() {
209
0
  return M->getLiteralNumber(-0.0);
210
0
}
211
212
0
LiteralNumber *IRBuilder::getLiteralNaN() {
213
0
  return M->getLiteralNumber(std::numeric_limits<double>::quiet_NaN());
214
0
}
215
216
99
LiteralBigInt *IRBuilder::getLiteralBigInt(UniqueString *value) {
217
99
  return M->getLiteralBigInt(value);
218
99
}
219
220
283k
LiteralString *IRBuilder::getLiteralString(llvh::StringRef value) {
221
283k
  Identifier Iden = createIdentifier(value);
222
283k
  return getLiteralString(Iden);
223
283k
}
224
225
318k
LiteralString *IRBuilder::getLiteralString(Identifier value) {
226
318k
  return M->getLiteralString(value);
227
318k
}
228
229
323k
LiteralBool *IRBuilder::getLiteralBool(bool value) {
230
323k
  return M->getLiteralBool(value);
231
323k
}
232
233
23.1k
LiteralEmpty *IRBuilder::getLiteralEmpty() {
234
23.1k
  return M->getLiteralEmpty();
235
23.1k
}
236
237
73.8k
LiteralUndefined *IRBuilder::getLiteralUndefined() {
238
73.8k
  return M->getLiteralUndefined();
239
73.8k
}
240
241
1.36k
LiteralNull *IRBuilder::getLiteralNull() {
242
1.36k
  return M->getLiteralNull();
243
1.36k
}
244
245
318k
GlobalObject *IRBuilder::getGlobalObject() {
246
318k
  return M->getGlobalObject();
247
318k
}
248
249
0
EmptySentinel *IRBuilder::getEmptySentinel() {
250
0
  return M->getEmptySentinel();
251
0
}
252
253
328k
Identifier IRBuilder::createIdentifier(llvh::StringRef str) {
254
328k
  return M->getContext().getIdentifier(str);
255
328k
}
256
257
62.7k
BranchInst *IRBuilder::createBranchInst(BasicBlock *Destination) {
258
62.7k
  auto *BI = new BranchInst(getInsertionBlock(), Destination);
259
62.7k
  insert(BI);
260
62.7k
  return BI;
261
62.7k
}
262
263
CondBranchInst *
264
7.62k
IRBuilder::createCondBranchInst(Value *Cond, BasicBlock *T, BasicBlock *F) {
265
7.62k
  auto *CBI = new CondBranchInst(getInsertionBlock(), Cond, T, F);
266
7.62k
  insert(CBI);
267
7.62k
  return CBI;
268
7.62k
}
269
270
46.2k
ReturnInst *IRBuilder::createReturnInst(Value *Val) {
271
46.2k
  auto *RI = new ReturnInst(Val);
272
46.2k
  insert(RI);
273
46.2k
  return RI;
274
46.2k
}
275
276
1.64k
CatchInst *IRBuilder::createCatchInst() {
277
1.64k
  auto *CI = new CatchInst();
278
1.64k
  insert(CI);
279
1.64k
  return CI;
280
1.64k
}
281
282
775
ThrowInst *IRBuilder::createThrowInst(Value *thrownValue) {
283
775
  auto *TI = new ThrowInst(thrownValue);
284
775
  insert(TI);
285
775
  return TI;
286
775
}
287
288
CheckHasInstanceInst *IRBuilder::createCheckHasInstanceInst(
289
    AllocStackInst *result,
290
    Value *left,
291
    Value *right,
292
    BasicBlock *onTrue,
293
0
    BasicBlock *onFalse) {
294
0
  auto *TI = new CheckHasInstanceInst(result, left, right, onTrue, onFalse);
295
0
  insert(TI);
296
0
  return TI;
297
0
}
298
299
TryStartInst *IRBuilder::createTryStartInst(
300
    BasicBlock *tryBodyBlock,
301
1.64k
    BasicBlock *catchTargetBlock) {
302
1.64k
  auto *I = new TryStartInst(tryBodyBlock, catchTargetBlock);
303
1.64k
  insert(I);
304
1.64k
  return I;
305
1.64k
}
306
307
1.64k
TryEndInst *IRBuilder::createTryEndInst() {
308
1.64k
  auto *I = new TryEndInst();
309
1.64k
  insert(I);
310
1.64k
  return I;
311
1.64k
}
312
313
9
AllocStackInst *IRBuilder::createAllocStackInst(llvh::StringRef varName) {
314
9
  Identifier Iden = createIdentifier(varName);
315
9
  return createAllocStackInst(Iden);
316
9
}
317
318
5.03k
AllocStackInst *IRBuilder::createAllocStackInst(Identifier varName) {
319
5.03k
  auto *AHI = new AllocStackInst(varName);
320
5.03k
  insert(AHI);
321
5.03k
  return AHI;
322
5.03k
}
323
324
474
AsNumberInst *IRBuilder::createAsNumberInst(Value *val) {
325
474
  auto *ANI = new AsNumberInst(val);
326
474
  insert(ANI);
327
474
  return ANI;
328
474
}
329
330
1
AsNumericInst *IRBuilder::createAsNumericInst(Value *val) {
331
1
  auto *ANI = new AsNumericInst(val);
332
1
  insert(ANI);
333
1
  return ANI;
334
1
}
335
336
0
AsInt32Inst *IRBuilder::createAsInt32Inst(Value *val) {
337
0
  auto *AII = new AsInt32Inst(val);
338
0
  insert(AII);
339
0
  return AII;
340
0
}
341
342
0
AddEmptyStringInst *IRBuilder::createAddEmptyStringInst(Value *val) {
343
0
  auto *I = new AddEmptyStringInst(val);
344
0
  insert(I);
345
0
  return I;
346
0
}
347
348
ThrowIfHasRestrictedGlobalPropertyInst *
349
IRBuilder::createThrowIfHasRestrictedGlobalPropertyInst(
350
0
    llvh::StringRef property) {
351
0
  auto *HRGP =
352
0
      new ThrowIfHasRestrictedGlobalPropertyInst(getLiteralString(property));
353
0
  insert(HRGP);
354
0
  return HRGP;
355
0
}
356
357
23.1k
CreateScopeInst *IRBuilder::createCreateScopeInst(ScopeDesc *scopeDesc) {
358
23.1k
  auto CII = new CreateScopeInst(scopeDesc);
359
23.1k
  insert(CII);
360
23.1k
  return CII;
361
23.1k
}
362
363
CreateInnerScopeInst *IRBuilder::createCreateInnerScopeInst(
364
    ScopeCreationInst *parentScope,
365
0
    ScopeDesc *scopeDesc) {
366
0
  auto CISI = new CreateInnerScopeInst(parentScope, scopeDesc);
367
0
  insert(CISI);
368
0
  return CISI;
369
0
}
370
371
CreateFunctionInst *IRBuilder::createCreateFunctionInst(
372
    Function *code,
373
23.1k
    ScopeCreationInst *environment) {
374
23.1k
  auto CFI = new CreateFunctionInst(code, environment);
375
23.1k
  insert(CFI);
376
23.1k
  return CFI;
377
23.1k
}
378
379
LoadFrameInst *IRBuilder::createLoadFrameInst(
380
    Variable *ptr,
381
14.0k
    ScopeCreationInst *scope) {
382
14.0k
  auto LI = new LoadFrameInst(ptr, scope);
383
14.0k
  insert(LI);
384
14.0k
  return LI;
385
14.0k
}
386
387
5.12k
LoadStackInst *IRBuilder::createLoadStackInst(AllocStackInst *ptr) {
388
5.12k
  auto LI = new LoadStackInst(ptr);
389
5.12k
  insert(LI);
390
5.12k
  return LI;
391
5.12k
}
392
393
StoreFrameInst *IRBuilder::createStoreFrameInst(
394
    Value *storedValue,
395
    Variable *ptr,
396
23.4k
    ScopeCreationInst *scope) {
397
23.4k
  auto SI = new StoreFrameInst(storedValue, ptr, scope);
398
23.4k
  insert(SI);
399
23.4k
  return SI;
400
23.4k
}
401
402
StoreStackInst *IRBuilder::createStoreStackInst(
403
    Value *storedValue,
404
280k
    AllocStackInst *ptr) {
405
280k
  auto SI = new StoreStackInst(storedValue, ptr);
406
280k
  insert(SI);
407
280k
  return SI;
408
280k
}
409
410
CallInst *IRBuilder::createCallInst(
411
    LiteralString *textifiedCallee,
412
    Value *callee,
413
    Value *thisValue,
414
4.58k
    ArrayRef<Value *> args) {
415
4.58k
  LiteralUndefined *newTarget = getLiteralUndefined();
416
4.58k
  auto CI = new CallInst(textifiedCallee, callee, newTarget, thisValue, args);
417
4.58k
  insert(CI);
418
4.58k
  return CI;
419
4.58k
}
420
421
HBCCallNInst *IRBuilder::createHBCCallNInst(
422
    LiteralString *textifiedCallee,
423
    Value *callee,
424
    Value *thisValue,
425
0
    ArrayRef<Value *> args) {
426
0
  LiteralUndefined *newTarget = getLiteralUndefined();
427
0
  auto CI =
428
0
      new HBCCallNInst(textifiedCallee, callee, newTarget, thisValue, args);
429
0
  insert(CI);
430
0
  return CI;
431
0
}
432
433
ConstructInst *IRBuilder::createConstructInst(
434
    Value *constructor,
435
    Value *newTarget,
436
70
    ArrayRef<Value *> args) {
437
70
  LiteralUndefined *thisValue = getLiteralUndefined();
438
70
  auto *inst = new ConstructInst(constructor, newTarget, thisValue, args);
439
70
  insert(inst);
440
70
  return inst;
441
70
}
442
443
LoadPropertyInst *IRBuilder::createLoadPropertyInst(
444
    Value *object,
445
13.8k
    Value *property) {
446
13.8k
  auto LPI = new LoadPropertyInst(object, property);
447
13.8k
  insert(LPI);
448
13.8k
  return LPI;
449
13.8k
}
450
451
TryLoadGlobalPropertyInst *IRBuilder::createTryLoadGlobalPropertyInst(
452
295k
    LiteralString *property) {
453
295k
  auto *inst = new TryLoadGlobalPropertyInst(getGlobalObject(), property);
454
295k
  insert(inst);
455
295k
  return inst;
456
295k
}
457
458
TryLoadGlobalPropertyInst *IRBuilder::createTryLoadGlobalPropertyInst(
459
295k
    GlobalObjectProperty *property) {
460
295k
  return createTryLoadGlobalPropertyInst(property->getName());
461
295k
}
462
463
DeletePropertyInst *IRBuilder::createDeletePropertyInst(
464
    Value *object,
465
18.6k
    Value *property) {
466
18.6k
  auto DPI = new DeletePropertyInst(object, property);
467
18.6k
  insert(DPI);
468
18.6k
  return DPI;
469
18.6k
}
470
471
StorePropertyInst *IRBuilder::createStorePropertyInst(
472
    Value *storedValue,
473
    Value *object,
474
4.19k
    Value *property) {
475
4.19k
  auto SPI = new StorePropertyInst(storedValue, object, property);
476
4.19k
  insert(SPI);
477
4.19k
  return SPI;
478
4.19k
}
479
TryStoreGlobalPropertyInst *IRBuilder::createTryStoreGlobalPropertyInst(
480
    Value *storedValue,
481
0
    LiteralString *property) {
482
0
  auto *inst =
483
0
      new TryStoreGlobalPropertyInst(storedValue, getGlobalObject(), property);
484
0
  insert(inst);
485
0
  return inst;
486
0
}
487
TryStoreGlobalPropertyInst *IRBuilder::createTryStoreGlobalPropertyInst(
488
    Value *storedValue,
489
0
    GlobalObjectProperty *property) {
490
0
  return createTryStoreGlobalPropertyInst(storedValue, property->getName());
491
0
}
492
493
StoreOwnPropertyInst *IRBuilder::createStoreOwnPropertyInst(
494
    Value *storedValue,
495
    Value *object,
496
    Value *property,
497
247k
    PropEnumerable isEnumerable) {
498
247k
  auto SPI = new StoreOwnPropertyInst(
499
247k
      storedValue,
500
247k
      object,
501
247k
      property,
502
247k
      getLiteralBool(isEnumerable == PropEnumerable::Yes));
503
247k
  insert(SPI);
504
247k
  return SPI;
505
247k
}
506
StoreNewOwnPropertyInst *IRBuilder::createStoreNewOwnPropertyInst(
507
    Value *storedValue,
508
    Value *object,
509
    Literal *property,
510
0
    PropEnumerable isEnumerable) {
511
0
  auto *inst = new StoreNewOwnPropertyInst(
512
0
      storedValue,
513
0
      object,
514
0
      property,
515
0
      getLiteralBool(isEnumerable == PropEnumerable::Yes));
516
0
  insert(inst);
517
0
  return inst;
518
0
}
519
520
StoreGetterSetterInst *IRBuilder::createStoreGetterSetterInst(
521
    Value *storedGetter,
522
    Value *storedSetter,
523
    Value *object,
524
    Value *property,
525
0
    PropEnumerable isEnumerable) {
526
0
  auto *SGSI = new StoreGetterSetterInst(
527
0
      storedGetter,
528
0
      storedSetter,
529
0
      object,
530
0
      property,
531
0
      getLiteralBool(isEnumerable == PropEnumerable::Yes));
532
0
  insert(SGSI);
533
0
  return SGSI;
534
0
}
535
536
DeletePropertyInst *IRBuilder::createDeletePropertyInst(
537
    Value *object,
538
0
    llvh::StringRef property) {
539
0
  Identifier Iden = createIdentifier(property);
540
0
  return createDeletePropertyInst(object, Iden);
541
0
}
542
543
LoadPropertyInst *IRBuilder::createLoadPropertyInst(
544
    Value *object,
545
1
    llvh::StringRef property) {
546
1
  Identifier Iden = createIdentifier(property);
547
1
  return createLoadPropertyInst(object, Iden);
548
1
}
549
550
TryLoadGlobalPropertyInst *IRBuilder::createTryLoadGlobalPropertyInst(
551
1
    llvh::StringRef property) {
552
1
  return createTryLoadGlobalPropertyInst(createIdentifier(property));
553
1
}
554
555
StorePropertyInst *IRBuilder::createStorePropertyInst(
556
    Value *storedValue,
557
    Value *object,
558
0
    llvh::StringRef property) {
559
0
  Identifier Iden = createIdentifier(property);
560
0
  return createStorePropertyInst(storedValue, object, Iden);
561
0
}
562
563
LoadPropertyInst *IRBuilder::createLoadPropertyInst(
564
    Value *object,
565
1
    Identifier property) {
566
1
  auto L = getLiteralString(property);
567
1
  return createLoadPropertyInst(object, L);
568
1
}
569
570
TryLoadGlobalPropertyInst *IRBuilder::createTryLoadGlobalPropertyInst(
571
1
    Identifier property) {
572
1
  auto *inst = new TryLoadGlobalPropertyInst(
573
1
      getGlobalObject(), getLiteralString(property));
574
1
  insert(inst);
575
1
  return inst;
576
1
}
577
578
DeletePropertyInst *IRBuilder::createDeletePropertyInst(
579
    Value *object,
580
0
    Identifier property) {
581
0
  auto L = getLiteralString(property);
582
0
  return createDeletePropertyInst(object, L);
583
0
}
584
585
StorePropertyInst *IRBuilder::createStorePropertyInst(
586
    Value *storedValue,
587
    Value *object,
588
0
    Identifier property) {
589
0
  auto L = getLiteralString(property);
590
0
  return createStorePropertyInst(storedValue, object, L);
591
0
}
592
593
TryStoreGlobalPropertyInst *IRBuilder::createTryStoreGlobalPropertyInst(
594
    Value *storedValue,
595
0
    Identifier property) {
596
0
  auto *inst = new TryStoreGlobalPropertyInst(
597
0
      storedValue, getGlobalObject(), getLiteralString(property));
598
0
  insert(inst);
599
0
  return inst;
600
0
}
601
602
AllocObjectInst *IRBuilder::createAllocObjectInst(
603
    uint32_t size,
604
0
    Value *parent) {
605
0
  auto AOI = new AllocObjectInst(
606
0
      M->getLiteralNumber(size), parent ? parent : getEmptySentinel());
607
0
  insert(AOI);
608
0
  return AOI;
609
0
}
610
611
AllocArrayInst *IRBuilder::createAllocArrayInst(
612
    LiteralNumber *sizeHint,
613
67
    AllocArrayInst::ArrayValueList val_list) {
614
67
  auto AAI = new AllocArrayInst(val_list, sizeHint);
615
67
  insert(AAI);
616
67
  return AAI;
617
67
}
618
619
AllocArrayInst *IRBuilder::createAllocArrayInst(
620
    AllocArrayInst::ArrayValueList val_list,
621
67
    unsigned sizeHint) {
622
67
  return createAllocArrayInst(this->getLiteralNumber(sizeHint), val_list);
623
67
}
624
625
23.1k
CreateArgumentsInst *IRBuilder::createCreateArgumentsInst() {
626
23.1k
  auto CAI = new CreateArgumentsInst();
627
23.1k
  insert(CAI);
628
23.1k
  return CAI;
629
23.1k
}
630
631
19
GetNewTargetInst *IRBuilder::createGetNewTargetInst() {
632
19
  auto *inst = new GetNewTargetInst();
633
19
  insert(inst);
634
19
  return inst;
635
19
}
636
637
0
ThrowIfEmptyInst *IRBuilder::createThrowIfEmptyInst(Value *checkedValue) {
638
0
  auto *inst = new ThrowIfEmptyInst(checkedValue);
639
0
  insert(inst);
640
0
  return inst;
641
0
}
642
643
318k
HBCGetGlobalObjectInst *IRBuilder::createHBCGetGlobalObjectInst() {
644
318k
  auto inst = new HBCGetGlobalObjectInst();
645
318k
  insert(inst);
646
318k
  return inst;
647
318k
}
648
649
CreateRegExpInst *IRBuilder::createRegExpInst(
650
    Identifier pattern,
651
1.43k
    Identifier flags) {
652
1.43k
  auto res =
653
1.43k
      new CreateRegExpInst(getLiteralString(pattern), getLiteralString(flags));
654
1.43k
  insert(res);
655
1.43k
  return res;
656
1.43k
}
657
658
UnaryOperatorInst *IRBuilder::createUnaryOperatorInst(
659
    Value *value,
660
8.20k
    UnaryOperatorInst::OpKind opKind) {
661
8.20k
  auto UOI = new UnaryOperatorInst(value, opKind);
662
8.20k
  insert(UOI);
663
8.20k
  return UOI;
664
8.20k
}
665
666
BinaryOperatorInst *IRBuilder::createBinaryOperatorInst(
667
    Value *left,
668
    Value *right,
669
161k
    BinaryOperatorInst::OpKind opKind) {
670
161k
  auto BOI = new BinaryOperatorInst(left, right, opKind);
671
161k
  insert(BOI);
672
161k
  return BOI;
673
161k
}
674
675
SwitchInst *IRBuilder::createSwitchInst(
676
    Value *input,
677
    BasicBlock *defaultBlock,
678
    const SwitchInst::ValueListType &values,
679
0
    const SwitchInst::BasicBlockListType &blocks) {
680
0
  auto SI = new SwitchInst(input, defaultBlock, values, blocks);
681
0
  insert(SI);
682
0
  return SI;
683
0
}
684
685
0
PhiInst *IRBuilder::createPhiInst() {
686
0
  PhiInst::ValueListType values;
687
0
  PhiInst::BasicBlockListType blocks;
688
689
0
  return createPhiInst(values, blocks);
690
0
}
691
692
PhiInst *IRBuilder::createPhiInst(
693
    const PhiInst::ValueListType &values,
694
3.40k
    const PhiInst::BasicBlockListType &blocks) {
695
3.40k
  auto PI = new PhiInst(values, blocks);
696
3.40k
  insert(PI);
697
3.40k
  return PI;
698
3.40k
}
699
700
GetPNamesInst *IRBuilder::createGetPNamesInst(
701
    Value *iteratorAddr,
702
    Value *baseAddr,
703
    Value *indexAddr,
704
    Value *sizeAddr,
705
    BasicBlock *onEmpty,
706
9
    BasicBlock *onSome) {
707
9
  auto GP = new GetPNamesInst(
708
9
      getInsertionBlock(),
709
9
      iteratorAddr,
710
9
      baseAddr,
711
9
      indexAddr,
712
9
      sizeAddr,
713
9
      onEmpty,
714
9
      onSome);
715
9
  insert(GP);
716
9
  return GP;
717
9
}
718
719
GetNextPNameInst *IRBuilder::createGetNextPNameInst(
720
    Value *propertyAddr,
721
    Value *baseAddr,
722
    Value *indexAddr,
723
    Value *sizeAddr,
724
    Value *iteratorAddr,
725
    BasicBlock *onLast,
726
9
    BasicBlock *onSome) {
727
9
  auto GNP = new GetNextPNameInst(
728
9
      getInsertionBlock(),
729
9
      propertyAddr,
730
9
      baseAddr,
731
9
      indexAddr,
732
9
      sizeAddr,
733
9
      iteratorAddr,
734
9
      onLast,
735
9
      onSome);
736
9
  insert(GNP);
737
9
  return GNP;
738
9
}
739
740
542k
MovInst *IRBuilder::createMovInst(Value *input) {
741
542k
  auto MI = new MovInst(input);
742
542k
  insert(MI);
743
542k
  return MI;
744
542k
}
745
746
14.7k
ImplicitMovInst *IRBuilder::createImplicitMovInst(Value *input) {
747
14.7k
  auto IMI = new ImplicitMovInst(input);
748
14.7k
  insert(IMI);
749
14.7k
  return IMI;
750
14.7k
}
751
752
0
CoerceThisNSInst *IRBuilder::createCoerceThisNSInst(Value *input) {
753
0
  auto *inst = new CoerceThisNSInst(input);
754
0
  insert(inst);
755
0
  return inst;
756
0
}
757
758
40
DebuggerInst *IRBuilder::createDebuggerInst() {
759
40
  auto DI = new DebuggerInst();
760
40
  insert(DI);
761
40
  return DI;
762
40
}
763
764
SaveAndYieldInst *IRBuilder::createSaveAndYieldInst(
765
    Value *result,
766
0
    BasicBlock *nextBlock) {
767
0
  auto *I = new SaveAndYieldInst(result, nextBlock);
768
0
  insert(I);
769
0
  return I;
770
0
}
771
772
CreateGeneratorInst *IRBuilder::createCreateGeneratorInst(
773
    Function *innerFn,
774
0
    ScopeCreationInst *environment) {
775
0
  auto *I = new CreateGeneratorInst(innerFn, environment);
776
0
  insert(I);
777
0
  return I;
778
0
}
779
780
0
StartGeneratorInst *IRBuilder::createStartGeneratorInst() {
781
0
  auto *I = new StartGeneratorInst();
782
0
  insert(I);
783
0
  return I;
784
0
}
785
786
0
ResumeGeneratorInst *IRBuilder::createResumeGeneratorInst(Value *isReturn) {
787
0
  auto *I = new ResumeGeneratorInst(isReturn);
788
0
  insert(I);
789
0
  return I;
790
0
}
791
792
HBCResolveEnvironment *IRBuilder::createHBCResolveEnvironment(
793
    ScopeDesc *originScopeDesc,
794
595
    ScopeDesc *targetScopeDesc) {
795
595
  auto RSC = new HBCResolveEnvironment(originScopeDesc, targetScopeDesc);
796
595
  insert(RSC);
797
595
  return RSC;
798
595
}
799
800
HBCStoreToEnvironmentInst *IRBuilder::createHBCStoreToEnvironmentInst(
801
    Value *env,
802
    Value *toPut,
803
23.4k
    Variable *var) {
804
23.4k
  auto PSI = new HBCStoreToEnvironmentInst(env, toPut, var);
805
23.4k
  insert(PSI);
806
23.4k
  return PSI;
807
23.4k
}
808
809
HBCLoadFromEnvironmentInst *IRBuilder::createHBCLoadFromEnvironmentInst(
810
    Value *env,
811
14.0k
    Variable *var) {
812
14.0k
  auto GSI = new HBCLoadFromEnvironmentInst(env, var);
813
14.0k
  insert(GSI);
814
14.0k
  return GSI;
815
14.0k
}
816
817
SwitchImmInst *IRBuilder::createSwitchImmInst(
818
    Value *input,
819
    BasicBlock *defaultBlock,
820
    LiteralNumber *minValue,
821
    LiteralNumber *size,
822
    const SwitchImmInst::ValueListType &values,
823
0
    const SwitchImmInst::BasicBlockListType &blocks) {
824
0
  auto inst =
825
0
      new SwitchImmInst(input, defaultBlock, minValue, size, values, blocks);
826
0
  insert(inst);
827
0
  return inst;
828
0
}
829
830
DirectEvalInst *IRBuilder::createDirectEvalInst(
831
    Value *operand,
832
0
    LiteralBool *isStrict) {
833
0
  auto *inst = new DirectEvalInst(operand, isStrict);
834
0
  insert(inst);
835
0
  return inst;
836
0
}
837
838
611k
HBCLoadConstInst *IRBuilder::createHBCLoadConstInst(Literal *value) {
839
611k
  auto inst = new HBCLoadConstInst(value);
840
611k
  insert(inst);
841
611k
  return inst;
842
611k
}
843
844
23.0k
HBCLoadParamInst *IRBuilder::createHBCLoadParamInst(LiteralNumber *value) {
845
23.0k
  auto inst = new HBCLoadParamInst(value);
846
23.0k
  insert(inst);
847
23.0k
  return inst;
848
23.0k
}
849
850
HBCCreateEnvironmentInst *IRBuilder::createHBCCreateEnvironmentInst(
851
23.1k
    ScopeDesc *scopeDesc) {
852
23.1k
  auto inst = new HBCCreateEnvironmentInst(scopeDesc);
853
23.1k
  insert(inst);
854
23.1k
  return inst;
855
23.1k
}
856
857
HBCCreateInnerEnvironmentInst *IRBuilder::createHBCCreateInnerEnvironmentInst(
858
    ScopeCreationInst *parentScope,
859
0
    ScopeDesc *scopeDesc) {
860
0
  auto inst = new HBCCreateInnerEnvironmentInst(parentScope, scopeDesc);
861
0
  insert(inst);
862
0
  return inst;
863
0
}
864
865
19
HBCGetThisNSInst *IRBuilder::createHBCGetThisNSInst() {
866
19
  auto inst = new HBCGetThisNSInst();
867
19
  insert(inst);
868
19
  return inst;
869
19
}
870
HBCGetArgumentsPropByValInst *IRBuilder::createHBCGetArgumentsPropByValInst(
871
    Value *index,
872
1
    AllocStackInst *lazyReg) {
873
1
  auto inst = new HBCGetArgumentsPropByValInst(index, lazyReg);
874
1
  insert(inst);
875
1
  return inst;
876
1
}
877
HBCGetArgumentsLengthInst *IRBuilder::createHBCGetArgumentsLengthInst(
878
0
    AllocStackInst *lazyReg) {
879
0
  auto inst = new HBCGetArgumentsLengthInst(lazyReg);
880
0
  insert(inst);
881
0
  return inst;
882
0
}
883
HBCReifyArgumentsInst *IRBuilder::createHBCReifyArgumentsInst(
884
13
    AllocStackInst *lazyReg) {
885
13
  auto inst = new HBCReifyArgumentsInst(lazyReg);
886
13
  insert(inst);
887
13
  return inst;
888
13
}
889
HBCCreateThisInst *IRBuilder::createHBCCreateThisInst(
890
    Value *prototype,
891
70
    Value *closure) {
892
70
  auto inst = new HBCCreateThisInst(prototype, closure);
893
70
  insert(inst);
894
70
  return inst;
895
70
}
896
HBCConstructInst *IRBuilder::createHBCConstructInst(
897
    Value *closure,
898
    Value *newTarget,
899
    Value *thisValue,
900
70
    ArrayRef<Value *> arguments) {
901
70
  auto inst = new HBCConstructInst(closure, newTarget, thisValue, arguments);
902
70
  insert(inst);
903
70
  return inst;
904
70
}
905
HBCGetConstructedObjectInst *IRBuilder::createHBCGetConstructedObjectInst(
906
    HBCCreateThisInst *thisValue,
907
70
    HBCConstructInst *constructorReturnValue) {
908
70
  auto inst =
909
70
      new HBCGetConstructedObjectInst(thisValue, constructorReturnValue);
910
70
  insert(inst);
911
70
  return inst;
912
70
}
913
914
0
HBCProfilePointInst *IRBuilder::createHBCProfilePointInst(uint16_t pointIndex) {
915
0
  auto inst = new HBCProfilePointInst(pointIndex);
916
0
  insert(inst);
917
0
  return inst;
918
0
}
919
920
CallBuiltinInst *IRBuilder::createCallBuiltinInst(
921
    BuiltinMethod::Enum builtinIndex,
922
14.7k
    ArrayRef<Value *> arguments) {
923
14.7k
  LiteralUndefined *undefined = getLiteralUndefined();
924
14.7k
  LiteralUndefined *newTarget = undefined;
925
14.7k
  LiteralUndefined *thisValue = undefined;
926
14.7k
  auto *inst = new CallBuiltinInst(
927
14.7k
      getLiteralNumber(builtinIndex), newTarget, thisValue, arguments);
928
14.7k
  insert(inst);
929
14.7k
  return inst;
930
14.7k
}
931
932
GetBuiltinClosureInst *IRBuilder::createGetBuiltinClosureInst(
933
0
    BuiltinMethod::Enum builtinIndex) {
934
0
  auto *inst = new GetBuiltinClosureInst(getLiteralNumber(builtinIndex));
935
0
  insert(inst);
936
0
  return inst;
937
0
}
938
939
#ifdef HERMES_RUN_WASM
940
CallIntrinsicInst *IRBuilder::createCallIntrinsicInst(
941
    WasmIntrinsics::Enum intrinsicsIndex,
942
    ArrayRef<Value *> arguments) {
943
  auto *inst =
944
      new CallIntrinsicInst(getLiteralNumber(intrinsicsIndex), arguments);
945
  insert(inst);
946
  return inst;
947
}
948
#endif
949
950
HBCCallDirectInst *IRBuilder::createHBCCallDirectInst(
951
    LiteralString *textifiedCallee,
952
    Function *callee,
953
    Value *thisValue,
954
0
    ArrayRef<Value *> arguments) {
955
0
  LiteralUndefined *newTarget = getLiteralUndefined();
956
0
  auto *inst = new HBCCallDirectInst(
957
0
      textifiedCallee, callee, newTarget, thisValue, arguments);
958
0
  insert(inst);
959
0
  return inst;
960
0
}
961
962
HBCCreateFunctionInst *IRBuilder::createHBCCreateFunctionInst(
963
    Function *function,
964
23.1k
    Value *env) {
965
23.1k
  auto inst = new HBCCreateFunctionInst(function, env);
966
23.1k
  insert(inst);
967
23.1k
  return inst;
968
23.1k
}
969
970
946k
HBCSpillMovInst *IRBuilder::createHBCSpillMovInst(Instruction *value) {
971
946k
  auto *inst = new HBCSpillMovInst(value);
972
946k
  insert(inst);
973
946k
  return inst;
974
946k
}
975
976
HBCCreateGeneratorInst *IRBuilder::createHBCCreateGeneratorInst(
977
    Function *function,
978
0
    Value *env) {
979
0
  auto *inst = new HBCCreateGeneratorInst(function, env);
980
0
  insert(inst);
981
0
  return inst;
982
0
}
983
984
HBCAllocObjectFromBufferInst *IRBuilder::createHBCAllocObjectFromBufferInst(
985
    HBCAllocObjectFromBufferInst::ObjectPropertyMap prop_map,
986
0
    uint32_t size) {
987
0
  auto *inst =
988
0
      new HBCAllocObjectFromBufferInst(M->getLiteralNumber(size), prop_map);
989
0
  insert(inst);
990
0
  return inst;
991
0
}
992
993
CompareBranchInst *IRBuilder::createCompareBranchInst(
994
    Value *left,
995
    Value *right,
996
    BinaryOperatorInst::OpKind opKind,
997
    BasicBlock *trueBlock,
998
0
    BasicBlock *falseBlock) {
999
0
  auto *inst =
1000
0
      new CompareBranchInst(left, right, opKind, trueBlock, falseBlock);
1001
0
  insert(inst);
1002
0
  return inst;
1003
0
}
1004
1005
IteratorBeginInst *IRBuilder::createIteratorBeginInst(
1006
819
    AllocStackInst *sourceOrNext) {
1007
819
  auto *I = new IteratorBeginInst(sourceOrNext);
1008
819
  insert(I);
1009
819
  return I;
1010
819
}
1011
1012
IteratorNextInst *IRBuilder::createIteratorNextInst(
1013
    AllocStackInst *iterator,
1014
902
    AllocStackInst *sourceOrNext) {
1015
902
  auto *I = new IteratorNextInst(iterator, sourceOrNext);
1016
902
  insert(I);
1017
902
  return I;
1018
902
}
1019
1020
IteratorCloseInst *IRBuilder::createIteratorCloseInst(
1021
    AllocStackInst *iterator,
1022
1.59k
    bool ignoreInnerException) {
1023
1.59k
  auto *I =
1024
1.59k
      new IteratorCloseInst(iterator, getLiteralBool(ignoreInnerException));
1025
1.59k
  insert(I);
1026
1.59k
  return I;
1027
1.59k
}
1028
1029
0
UnreachableInst *IRBuilder::createUnreachableInst() {
1030
0
  auto *I = new UnreachableInst();
1031
0
  insert(I);
1032
0
  return I;
1033
0
}
1034
1035
3.83M
inline void IRBuilder::justInsert(Instruction *Inst) {
1036
3.83M
  assert(!Inst->getParent() && "Instr that's already inserted elsewhere");
1037
3.83M
  Inst->setParent(Block);
1038
3.83M
  Block->getInstList().insert(InsertionPoint, Inst);
1039
3.83M
}
1040
1041
3.83M
void IRBuilder::insert(Instruction *Inst) {
1042
  // Set the statement of the new instruction based on the current function's
1043
  // statement counter.
1044
3.83M
  OptValue<uint32_t> statementOpt = getFunction()->getStatementCount();
1045
3.83M
  uint32_t statement;
1046
3.83M
  if (LLVM_LIKELY(statementOpt.hasValue())) {
1047
1.28M
    statement = *statementOpt;
1048
2.55M
  } else {
1049
    // If we've cleared the statement count,
1050
    // then just set the new instruction's statement to the statement of the
1051
    // instruction we're inserting at (0 if it doesn't exist).
1052
2.55M
    statement = InsertionPoint != Block->getInstList().end()
1053
2.55M
        ? InsertionPoint->getStatementIndex()
1054
2.55M
        : 0;
1055
2.55M
  }
1056
3.83M
  Inst->setStatementIndex(statement);
1057
1058
3.83M
  Inst->setLocation(Location);
1059
3.83M
  Inst->setSourceLevelScope(CurrentSourceLevelScope);
1060
1061
3.83M
  return justInsert(Inst);
1062
3.83M
}
1063
1064
166k
void IRBuilder::setInsertionBlock(BasicBlock *BB) {
1065
166k
  if (BB) {
1066
166k
    InsertionPoint = BB->end();
1067
166k
    Block = BB;
1068
166k
  } else {
1069
147
    InsertionPoint = BasicBlock::iterator(nullptr);
1070
147
    Block = nullptr;
1071
147
  }
1072
166k
}
1073
1074
127k
BasicBlock *IRBuilder::getInsertionBlock() {
1075
127k
  return Block;
1076
127k
}
1077
1078
6
void IRBuilder::setInsertionPointAfter(Instruction *IP) {
1079
6
  InsertionPoint = IP->getIterator();
1080
6
  InsertionPoint++;
1081
6
  Block = IP->getParent();
1082
6
}
1083
1084
2.32M
void IRBuilder::setInsertionPoint(Instruction *IP) {
1085
2.32M
  InsertionPoint = IP->getIterator();
1086
2.32M
  Block = IP->getParent();
1087
2.32M
}
1088
1089
0
bool IRBuilder::isInsertionPointValid() {
1090
0
  return InsertionPoint.getNodePtr();
1091
0
}
1092
1093
0
void IRBuilder::resetInsertionPoint() {
1094
0
  InsertionPoint = BasicBlock::iterator();
1095
0
  Block = nullptr;
1096
0
}
1097
1098
0
void IRBuilder::transferInstructionToCurrentBlock(Instruction *inst) {
1099
0
  auto *oldBlock = inst->getParent();
1100
0
  inst->removeFromParent();
1101
0
  inst->setParent(Block);
1102
0
  Block->getInstList().insert(InsertionPoint, inst);
1103
1104
0
  if (oldBlock == Block || !llvh::isa<TerminatorInst>(inst))
1105
0
    return;
1106
1107
  // If we moved the terminator, we want to update all successors' phi-nodes.
1108
0
  for (auto *use : oldBlock->getUsers()) {
1109
0
    auto *phi = llvh::dyn_cast<PhiInst>(use);
1110
0
    if (!phi)
1111
0
      continue;
1112
0
    for (unsigned i = 0, e = phi->getNumOperands(); i != e; ++i) {
1113
0
      if (phi->getOperand(i) == oldBlock)
1114
0
        phi->setOperand(Block, i);
1115
0
    }
1116
0
  }
1117
0
}
1118
1119
Instruction *IRBuilder::cloneInst(
1120
    const Instruction *source,
1121
0
    llvh::ArrayRef<Value *> operands) {
1122
0
  Instruction *inst;
1123
0
  switch (source->getKind()) {
1124
0
#define INCLUDE_ALL_INSTRS
1125
0
#define DEF_VALUE(name, parent)                    \
1126
0
  case ValueKind::name##Kind:                      \
1127
0
    inst = new name(cast<name>(source), operands); \
1128
0
    break;
1129
1130
0
#include "hermes/IR/Instrs.def"
1131
0
#undef INCLUDE_ALL_INSTRS
1132
0
    default:
1133
0
      llvm_unreachable("invalid kind");
1134
0
  }
1135
1136
0
  inst->setSourceLevelScope(CurrentSourceLevelScope);
1137
0
  justInsert(inst);
1138
0
  return inst;
1139
0
}