• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/torque/instructions.h"
6 #include "src/torque/cfg.h"
7 #include "src/torque/type-oracle.h"
8 
9 namespace v8 {
10 namespace internal {
11 namespace torque {
12 
13 #define TORQUE_INSTRUCTION_BOILERPLATE_DEFINITIONS(Name)        \
14   const InstructionKind Name::kKind = InstructionKind::k##Name; \
15   std::unique_ptr<InstructionBase> Name::Clone() const {        \
16     return std::unique_ptr<InstructionBase>(new Name(*this));   \
17   }                                                             \
18   void Name::Assign(const InstructionBase& other) {             \
19     *this = static_cast<const Name&>(other);                    \
20   }
21 TORQUE_INSTRUCTION_LIST(TORQUE_INSTRUCTION_BOILERPLATE_DEFINITIONS)
22 #undef TORQUE_INSTRUCTION_BOILERPLATE_DEFINITIONS
23 
24 namespace {
ExpectType(const Type * expected,const Type * actual)25 void ExpectType(const Type* expected, const Type* actual) {
26   if (expected != actual) {
27     ReportError("expected type ", *expected, " but found ", *actual);
28   }
29 }
ExpectSubtype(const Type * subtype,const Type * supertype)30 void ExpectSubtype(const Type* subtype, const Type* supertype) {
31   if (!subtype->IsSubtypeOf(supertype)) {
32     ReportError("type ", *subtype, " is not a subtype of ", *supertype);
33   }
34 }
35 }  // namespace
36 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const37 void PeekInstruction::TypeInstruction(Stack<const Type*>* stack,
38                                       ControlFlowGraph* cfg) const {
39   const Type* type = stack->Peek(slot);
40   if (widened_type) {
41     if (type->IsTopType()) {
42       const TopType* top_type = TopType::cast(type);
43       ReportError("use of " + top_type->reason());
44     }
45     ExpectSubtype(type, *widened_type);
46     type = *widened_type;
47   }
48   stack->Push(type);
49 }
50 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const51 void PeekInstruction::RecomputeDefinitionLocations(
52     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
53   locations->Push(locations->Peek(slot));
54 }
55 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const56 void PokeInstruction::TypeInstruction(Stack<const Type*>* stack,
57                                       ControlFlowGraph* cfg) const {
58   const Type* type = stack->Top();
59   if (widened_type) {
60     ExpectSubtype(type, *widened_type);
61     type = *widened_type;
62   }
63   stack->Poke(slot, type);
64   stack->Pop();
65 }
66 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const67 void PokeInstruction::RecomputeDefinitionLocations(
68     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
69   locations->Poke(slot, locations->Pop());
70 }
71 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const72 void DeleteRangeInstruction::TypeInstruction(Stack<const Type*>* stack,
73                                              ControlFlowGraph* cfg) const {
74   stack->DeleteRange(range);
75 }
76 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const77 void DeleteRangeInstruction::RecomputeDefinitionLocations(
78     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
79   locations->DeleteRange(range);
80 }
81 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const82 void PushUninitializedInstruction::TypeInstruction(
83     Stack<const Type*>* stack, ControlFlowGraph* cfg) const {
84   stack->Push(type);
85 }
86 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const87 void PushUninitializedInstruction::RecomputeDefinitionLocations(
88     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
89   locations->Push(GetValueDefinition());
90 }
91 
GetValueDefinition() const92 DefinitionLocation PushUninitializedInstruction::GetValueDefinition() const {
93   return DefinitionLocation::Instruction(this, 0);
94 }
95 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const96 void PushBuiltinPointerInstruction::TypeInstruction(
97     Stack<const Type*>* stack, ControlFlowGraph* cfg) const {
98   stack->Push(type);
99 }
100 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const101 void PushBuiltinPointerInstruction::RecomputeDefinitionLocations(
102     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
103   locations->Push(GetValueDefinition());
104 }
105 
GetValueDefinition() const106 DefinitionLocation PushBuiltinPointerInstruction::GetValueDefinition() const {
107   return DefinitionLocation::Instruction(this, 0);
108 }
109 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const110 void NamespaceConstantInstruction::TypeInstruction(
111     Stack<const Type*>* stack, ControlFlowGraph* cfg) const {
112   stack->PushMany(LowerType(constant->type()));
113 }
114 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const115 void NamespaceConstantInstruction::RecomputeDefinitionLocations(
116     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
117   for (std::size_t i = 0; i < GetValueDefinitionCount(); ++i) {
118     locations->Push(GetValueDefinition(i));
119   }
120 }
121 
GetValueDefinitionCount() const122 std::size_t NamespaceConstantInstruction::GetValueDefinitionCount() const {
123   return LowerType(constant->type()).size();
124 }
125 
GetValueDefinition(std::size_t index) const126 DefinitionLocation NamespaceConstantInstruction::GetValueDefinition(
127     std::size_t index) const {
128   DCHECK_LT(index, GetValueDefinitionCount());
129   return DefinitionLocation::Instruction(this, index);
130 }
131 
InvalidateTransientTypes(Stack<const Type * > * stack) const132 void InstructionBase::InvalidateTransientTypes(
133     Stack<const Type*>* stack) const {
134   auto current = stack->begin();
135   while (current != stack->end()) {
136     if ((*current)->IsTransient()) {
137       std::stringstream stream;
138       stream << "type " << **current
139              << " is made invalid by transitioning callable invocation at "
140              << PositionAsString(pos);
141       *current = TypeOracle::GetTopType(stream.str(), *current);
142     }
143     ++current;
144   }
145 }
146 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const147 void CallIntrinsicInstruction::TypeInstruction(Stack<const Type*>* stack,
148                                                ControlFlowGraph* cfg) const {
149   std::vector<const Type*> parameter_types =
150       LowerParameterTypes(intrinsic->signature().parameter_types);
151   for (intptr_t i = parameter_types.size() - 1; i >= 0; --i) {
152     const Type* arg_type = stack->Pop();
153     const Type* parameter_type = parameter_types.back();
154     parameter_types.pop_back();
155     if (arg_type != parameter_type) {
156       ReportError("parameter ", i, ": expected type ", *parameter_type,
157                   " but found type ", *arg_type);
158     }
159   }
160   if (intrinsic->IsTransitioning()) {
161     InvalidateTransientTypes(stack);
162   }
163   stack->PushMany(LowerType(intrinsic->signature().return_type));
164 }
165 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const166 void CallIntrinsicInstruction::RecomputeDefinitionLocations(
167     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
168   auto parameter_types =
169       LowerParameterTypes(intrinsic->signature().parameter_types);
170   locations->PopMany(parameter_types.size());
171   for (std::size_t i = 0; i < GetValueDefinitionCount(); ++i) {
172     locations->Push(DefinitionLocation::Instruction(this, i));
173   }
174 }
175 
GetValueDefinitionCount() const176 std::size_t CallIntrinsicInstruction::GetValueDefinitionCount() const {
177   return LowerType(intrinsic->signature().return_type).size();
178 }
179 
GetValueDefinition(std::size_t index) const180 DefinitionLocation CallIntrinsicInstruction::GetValueDefinition(
181     std::size_t index) const {
182   DCHECK_LT(index, GetValueDefinitionCount());
183   return DefinitionLocation::Instruction(this, index);
184 }
185 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const186 void CallCsaMacroInstruction::TypeInstruction(Stack<const Type*>* stack,
187                                               ControlFlowGraph* cfg) const {
188   std::vector<const Type*> parameter_types =
189       LowerParameterTypes(macro->signature().parameter_types);
190   for (intptr_t i = parameter_types.size() - 1; i >= 0; --i) {
191     const Type* arg_type = stack->Pop();
192     const Type* parameter_type = parameter_types.back();
193     parameter_types.pop_back();
194     if (arg_type != parameter_type) {
195       ReportError("parameter ", i, ": expected type ", *parameter_type,
196                   " but found type ", *arg_type);
197     }
198   }
199 
200   if (macro->IsTransitioning()) {
201     InvalidateTransientTypes(stack);
202   }
203 
204   if (catch_block) {
205     Stack<const Type*> catch_stack = *stack;
206     catch_stack.Push(TypeOracle::GetJSAnyType());
207     (*catch_block)->SetInputTypes(catch_stack);
208   }
209 
210   stack->PushMany(LowerType(macro->signature().return_type));
211 }
212 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const213 void CallCsaMacroInstruction::RecomputeDefinitionLocations(
214     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
215   auto parameter_types =
216       LowerParameterTypes(macro->signature().parameter_types);
217   locations->PopMany(parameter_types.size());
218 
219   if (catch_block) {
220     locations->Push(*GetExceptionObjectDefinition());
221     (*catch_block)->MergeInputDefinitions(*locations, worklist);
222     locations->Pop();
223   }
224 
225   for (std::size_t i = 0; i < GetValueDefinitionCount(); ++i) {
226     locations->Push(GetValueDefinition(i));
227   }
228 }
229 
230 base::Optional<DefinitionLocation>
GetExceptionObjectDefinition() const231 CallCsaMacroInstruction::GetExceptionObjectDefinition() const {
232   if (!catch_block) return base::nullopt;
233   return DefinitionLocation::Instruction(this, GetValueDefinitionCount());
234 }
235 
GetValueDefinitionCount() const236 std::size_t CallCsaMacroInstruction::GetValueDefinitionCount() const {
237   return LowerType(macro->signature().return_type).size();
238 }
239 
GetValueDefinition(std::size_t index) const240 DefinitionLocation CallCsaMacroInstruction::GetValueDefinition(
241     std::size_t index) const {
242   DCHECK_LT(index, GetValueDefinitionCount());
243   return DefinitionLocation::Instruction(this, index);
244 }
245 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const246 void CallCsaMacroAndBranchInstruction::TypeInstruction(
247     Stack<const Type*>* stack, ControlFlowGraph* cfg) const {
248   std::vector<const Type*> parameter_types =
249       LowerParameterTypes(macro->signature().parameter_types);
250   for (intptr_t i = parameter_types.size() - 1; i >= 0; --i) {
251     const Type* arg_type = stack->Pop();
252     const Type* parameter_type = parameter_types.back();
253     parameter_types.pop_back();
254     if (arg_type != parameter_type) {
255       ReportError("parameter ", i, ": expected type ", *parameter_type,
256                   " but found type ", *arg_type);
257     }
258   }
259 
260   if (label_blocks.size() != macro->signature().labels.size()) {
261     ReportError("wrong number of labels");
262   }
263   for (size_t i = 0; i < label_blocks.size(); ++i) {
264     Stack<const Type*> continuation_stack = *stack;
265     continuation_stack.PushMany(
266         LowerParameterTypes(macro->signature().labels[i].types));
267     label_blocks[i]->SetInputTypes(std::move(continuation_stack));
268   }
269 
270   if (macro->IsTransitioning()) {
271     InvalidateTransientTypes(stack);
272   }
273 
274   if (catch_block) {
275     Stack<const Type*> catch_stack = *stack;
276     catch_stack.Push(TypeOracle::GetJSAnyType());
277     (*catch_block)->SetInputTypes(catch_stack);
278   }
279 
280   if (macro->signature().return_type != TypeOracle::GetNeverType()) {
281     Stack<const Type*> return_stack = *stack;
282     return_stack.PushMany(LowerType(macro->signature().return_type));
283     if (return_continuation == base::nullopt) {
284       ReportError("missing return continuation.");
285     }
286     (*return_continuation)->SetInputTypes(return_stack);
287   } else {
288     if (return_continuation != base::nullopt) {
289       ReportError("unreachable return continuation.");
290     }
291   }
292 }
293 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const294 void CallCsaMacroAndBranchInstruction::RecomputeDefinitionLocations(
295     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
296   auto parameter_types =
297       LowerParameterTypes(macro->signature().parameter_types);
298   locations->PopMany(parameter_types.size());
299 
300   for (std::size_t label_index = 0; label_index < label_blocks.size();
301        ++label_index) {
302     const std::size_t count = GetLabelValueDefinitionCount(label_index);
303     for (std::size_t i = 0; i < count; ++i) {
304       locations->Push(GetLabelValueDefinition(label_index, i));
305     }
306     label_blocks[label_index]->MergeInputDefinitions(*locations, worklist);
307     locations->PopMany(count);
308   }
309 
310   if (catch_block) {
311     locations->Push(*GetExceptionObjectDefinition());
312     (*catch_block)->MergeInputDefinitions(*locations, worklist);
313     locations->Pop();
314   }
315 
316   if (macro->signature().return_type != TypeOracle::GetNeverType()) {
317     if (return_continuation) {
318       const std::size_t count = GetValueDefinitionCount();
319       for (std::size_t i = 0; i < count; ++i) {
320         locations->Push(GetValueDefinition(i));
321       }
322       (*return_continuation)->MergeInputDefinitions(*locations, worklist);
323       locations->PopMany(count);
324     }
325   }
326 }
327 
GetLabelCount() const328 std::size_t CallCsaMacroAndBranchInstruction::GetLabelCount() const {
329   return label_blocks.size();
330 }
331 
GetLabelValueDefinitionCount(std::size_t label) const332 std::size_t CallCsaMacroAndBranchInstruction::GetLabelValueDefinitionCount(
333     std::size_t label) const {
334   DCHECK_LT(label, GetLabelCount());
335   return LowerParameterTypes(macro->signature().labels[label].types).size();
336 }
337 
GetLabelValueDefinition(std::size_t label,std::size_t index) const338 DefinitionLocation CallCsaMacroAndBranchInstruction::GetLabelValueDefinition(
339     std::size_t label, std::size_t index) const {
340   DCHECK_LT(index, GetLabelValueDefinitionCount(label));
341   std::size_t offset = GetValueDefinitionCount() + (catch_block ? 1 : 0);
342   for (std::size_t label_index = 0; label_index < label; ++label_index) {
343     offset += GetLabelValueDefinitionCount(label_index);
344   }
345   return DefinitionLocation::Instruction(this, offset + index);
346 }
347 
GetValueDefinitionCount() const348 std::size_t CallCsaMacroAndBranchInstruction::GetValueDefinitionCount() const {
349   if (macro->signature().return_type == TypeOracle::GetNeverType()) return 0;
350   if (!return_continuation) return 0;
351   return LowerType(macro->signature().return_type).size();
352 }
353 
GetValueDefinition(std::size_t index) const354 DefinitionLocation CallCsaMacroAndBranchInstruction::GetValueDefinition(
355     std::size_t index) const {
356   DCHECK_LT(index, GetValueDefinitionCount());
357   return DefinitionLocation::Instruction(this, index);
358 }
359 
360 base::Optional<DefinitionLocation>
GetExceptionObjectDefinition() const361 CallCsaMacroAndBranchInstruction::GetExceptionObjectDefinition() const {
362   if (!catch_block) return base::nullopt;
363   return DefinitionLocation::Instruction(this, GetValueDefinitionCount());
364 }
365 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const366 void CallBuiltinInstruction::TypeInstruction(Stack<const Type*>* stack,
367                                              ControlFlowGraph* cfg) const {
368   std::vector<const Type*> argument_types = stack->PopMany(argc);
369   if (argument_types !=
370       LowerParameterTypes(builtin->signature().parameter_types)) {
371     ReportError("wrong argument types");
372   }
373   if (builtin->IsTransitioning()) {
374     InvalidateTransientTypes(stack);
375   }
376 
377   if (catch_block) {
378     Stack<const Type*> catch_stack = *stack;
379     catch_stack.Push(TypeOracle::GetJSAnyType());
380     (*catch_block)->SetInputTypes(catch_stack);
381   }
382 
383   stack->PushMany(LowerType(builtin->signature().return_type));
384 }
385 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const386 void CallBuiltinInstruction::RecomputeDefinitionLocations(
387     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
388   locations->PopMany(argc);
389 
390   if (catch_block) {
391     locations->Push(*GetExceptionObjectDefinition());
392     (*catch_block)->MergeInputDefinitions(*locations, worklist);
393     locations->Pop();
394   }
395 
396   for (std::size_t i = 0; i < GetValueDefinitionCount(); ++i) {
397     locations->Push(GetValueDefinition(i));
398   }
399 }
400 
GetValueDefinitionCount() const401 std::size_t CallBuiltinInstruction::GetValueDefinitionCount() const {
402   return LowerType(builtin->signature().return_type).size();
403 }
404 
GetValueDefinition(std::size_t index) const405 DefinitionLocation CallBuiltinInstruction::GetValueDefinition(
406     std::size_t index) const {
407   DCHECK_LT(index, GetValueDefinitionCount());
408   return DefinitionLocation::Instruction(this, index);
409 }
410 
411 base::Optional<DefinitionLocation>
GetExceptionObjectDefinition() const412 CallBuiltinInstruction::GetExceptionObjectDefinition() const {
413   if (!catch_block) return base::nullopt;
414   return DefinitionLocation::Instruction(this, GetValueDefinitionCount());
415 }
416 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const417 void CallBuiltinPointerInstruction::TypeInstruction(
418     Stack<const Type*>* stack, ControlFlowGraph* cfg) const {
419   std::vector<const Type*> argument_types = stack->PopMany(argc);
420   const BuiltinPointerType* f = BuiltinPointerType::DynamicCast(stack->Pop());
421   if (!f) ReportError("expected function pointer type");
422   if (argument_types != LowerParameterTypes(f->parameter_types())) {
423     ReportError("wrong argument types");
424   }
425   DCHECK_EQ(type, f);
426   // TODO(tebbi): Only invalidate transient types if the function pointer type
427   // is transitioning.
428   InvalidateTransientTypes(stack);
429   stack->PushMany(LowerType(f->return_type()));
430 }
431 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const432 void CallBuiltinPointerInstruction::RecomputeDefinitionLocations(
433     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
434   locations->PopMany(argc + 1);
435   for (std::size_t i = 0; i < GetValueDefinitionCount(); ++i) {
436     locations->Push(GetValueDefinition(i));
437   }
438 }
439 
GetValueDefinitionCount() const440 std::size_t CallBuiltinPointerInstruction::GetValueDefinitionCount() const {
441   return LowerType(type->return_type()).size();
442 }
443 
GetValueDefinition(std::size_t index) const444 DefinitionLocation CallBuiltinPointerInstruction::GetValueDefinition(
445     std::size_t index) const {
446   DCHECK_LT(index, GetValueDefinitionCount());
447   return DefinitionLocation::Instruction(this, index);
448 }
449 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const450 void CallRuntimeInstruction::TypeInstruction(Stack<const Type*>* stack,
451                                              ControlFlowGraph* cfg) const {
452   std::vector<const Type*> argument_types = stack->PopMany(argc);
453   if (argument_types !=
454       LowerParameterTypes(runtime_function->signature().parameter_types,
455                           argc)) {
456     ReportError("wrong argument types");
457   }
458   if (runtime_function->IsTransitioning()) {
459     InvalidateTransientTypes(stack);
460   }
461 
462   if (catch_block) {
463     Stack<const Type*> catch_stack = *stack;
464     catch_stack.Push(TypeOracle::GetJSAnyType());
465     (*catch_block)->SetInputTypes(catch_stack);
466   }
467 
468   const Type* return_type = runtime_function->signature().return_type;
469   if (return_type != TypeOracle::GetNeverType()) {
470     stack->PushMany(LowerType(return_type));
471   }
472 }
473 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const474 void CallRuntimeInstruction::RecomputeDefinitionLocations(
475     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
476   locations->PopMany(argc);
477 
478   if (catch_block) {
479     locations->Push(*GetExceptionObjectDefinition());
480     (*catch_block)->MergeInputDefinitions(*locations, worklist);
481     locations->Pop();
482   }
483 
484   const Type* return_type = runtime_function->signature().return_type;
485   if (return_type != TypeOracle::GetNeverType()) {
486     for (std::size_t i = 0; i < GetValueDefinitionCount(); ++i) {
487       locations->Push(GetValueDefinition(i));
488     }
489   }
490 }
491 
GetValueDefinitionCount() const492 std::size_t CallRuntimeInstruction::GetValueDefinitionCount() const {
493   const Type* return_type = runtime_function->signature().return_type;
494   if (return_type == TypeOracle::GetNeverType()) return 0;
495   return LowerType(return_type).size();
496 }
497 
GetValueDefinition(std::size_t index) const498 DefinitionLocation CallRuntimeInstruction::GetValueDefinition(
499     std::size_t index) const {
500   DCHECK_LT(index, GetValueDefinitionCount());
501   return DefinitionLocation::Instruction(this, index);
502 }
503 
504 base::Optional<DefinitionLocation>
GetExceptionObjectDefinition() const505 CallRuntimeInstruction::GetExceptionObjectDefinition() const {
506   if (!catch_block) return base::nullopt;
507   return DefinitionLocation::Instruction(this, GetValueDefinitionCount());
508 }
509 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const510 void BranchInstruction::TypeInstruction(Stack<const Type*>* stack,
511                                         ControlFlowGraph* cfg) const {
512   const Type* condition_type = stack->Pop();
513   if (condition_type != TypeOracle::GetBoolType()) {
514     ReportError("condition has to have type bool");
515   }
516   if_true->SetInputTypes(*stack);
517   if_false->SetInputTypes(*stack);
518 }
519 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const520 void BranchInstruction::RecomputeDefinitionLocations(
521     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
522   locations->Pop();
523   if_true->MergeInputDefinitions(*locations, worklist);
524   if_false->MergeInputDefinitions(*locations, worklist);
525 }
526 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const527 void ConstexprBranchInstruction::TypeInstruction(Stack<const Type*>* stack,
528                                                  ControlFlowGraph* cfg) const {
529   if_true->SetInputTypes(*stack);
530   if_false->SetInputTypes(*stack);
531 }
532 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const533 void ConstexprBranchInstruction::RecomputeDefinitionLocations(
534     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
535   if_true->MergeInputDefinitions(*locations, worklist);
536   if_false->MergeInputDefinitions(*locations, worklist);
537 }
538 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const539 void GotoInstruction::TypeInstruction(Stack<const Type*>* stack,
540                                       ControlFlowGraph* cfg) const {
541   destination->SetInputTypes(*stack);
542 }
543 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const544 void GotoInstruction::RecomputeDefinitionLocations(
545     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
546   destination->MergeInputDefinitions(*locations, worklist);
547 }
548 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const549 void GotoExternalInstruction::TypeInstruction(Stack<const Type*>* stack,
550                                               ControlFlowGraph* cfg) const {
551   if (variable_names.size() != stack->Size()) {
552     ReportError("goto external label with wrong parameter count.");
553   }
554 }
555 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const556 void GotoExternalInstruction::RecomputeDefinitionLocations(
557     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {}
558 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const559 void ReturnInstruction::TypeInstruction(Stack<const Type*>* stack,
560                                         ControlFlowGraph* cfg) const {
561   cfg->SetReturnType(stack->Pop());
562 }
563 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const564 void ReturnInstruction::RecomputeDefinitionLocations(
565     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
566   locations->Pop();
567 }
568 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const569 void PrintConstantStringInstruction::TypeInstruction(
570     Stack<const Type*>* stack, ControlFlowGraph* cfg) const {}
571 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const572 void PrintConstantStringInstruction::RecomputeDefinitionLocations(
573     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {}
574 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const575 void AbortInstruction::TypeInstruction(Stack<const Type*>* stack,
576                                        ControlFlowGraph* cfg) const {}
577 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const578 void AbortInstruction::RecomputeDefinitionLocations(
579     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {}
580 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const581 void UnsafeCastInstruction::TypeInstruction(Stack<const Type*>* stack,
582                                             ControlFlowGraph* cfg) const {
583   stack->Poke(stack->AboveTop() - 1, destination_type);
584 }
585 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const586 void UnsafeCastInstruction::RecomputeDefinitionLocations(
587     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
588   locations->Poke(locations->AboveTop() - 1, GetValueDefinition());
589 }
590 
GetValueDefinition() const591 DefinitionLocation UnsafeCastInstruction::GetValueDefinition() const {
592   return DefinitionLocation::Instruction(this, 0);
593 }
594 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const595 void LoadReferenceInstruction::TypeInstruction(Stack<const Type*>* stack,
596                                                ControlFlowGraph* cfg) const {
597   ExpectType(TypeOracle::GetIntPtrType(), stack->Pop());
598   ExpectSubtype(stack->Pop(), TypeOracle::GetHeapObjectType());
599   DCHECK_EQ(std::vector<const Type*>{type}, LowerType(type));
600   stack->Push(type);
601 }
602 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const603 void LoadReferenceInstruction::RecomputeDefinitionLocations(
604     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
605   locations->Pop();
606   locations->Pop();
607   locations->Push(GetValueDefinition());
608 }
609 
GetValueDefinition() const610 DefinitionLocation LoadReferenceInstruction::GetValueDefinition() const {
611   return DefinitionLocation::Instruction(this, 0);
612 }
613 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const614 void StoreReferenceInstruction::TypeInstruction(Stack<const Type*>* stack,
615                                                 ControlFlowGraph* cfg) const {
616   ExpectSubtype(stack->Pop(), type);
617   ExpectType(TypeOracle::GetIntPtrType(), stack->Pop());
618   ExpectSubtype(stack->Pop(), TypeOracle::GetHeapObjectType());
619 }
620 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const621 void StoreReferenceInstruction::RecomputeDefinitionLocations(
622     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
623   locations->Pop();
624   locations->Pop();
625   locations->Pop();
626 }
627 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const628 void LoadBitFieldInstruction::TypeInstruction(Stack<const Type*>* stack,
629                                               ControlFlowGraph* cfg) const {
630   ExpectType(bit_field_struct_type, stack->Pop());
631   stack->Push(bit_field.name_and_type.type);
632 }
633 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const634 void LoadBitFieldInstruction::RecomputeDefinitionLocations(
635     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
636   locations->Pop();
637   locations->Push(GetValueDefinition());
638 }
639 
GetValueDefinition() const640 DefinitionLocation LoadBitFieldInstruction::GetValueDefinition() const {
641   return DefinitionLocation::Instruction(this, 0);
642 }
643 
TypeInstruction(Stack<const Type * > * stack,ControlFlowGraph * cfg) const644 void StoreBitFieldInstruction::TypeInstruction(Stack<const Type*>* stack,
645                                                ControlFlowGraph* cfg) const {
646   ExpectSubtype(bit_field.name_and_type.type, stack->Pop());
647   ExpectType(bit_field_struct_type, stack->Pop());
648   stack->Push(bit_field_struct_type);
649 }
650 
RecomputeDefinitionLocations(Stack<DefinitionLocation> * locations,Worklist<Block * > * worklist) const651 void StoreBitFieldInstruction::RecomputeDefinitionLocations(
652     Stack<DefinitionLocation>* locations, Worklist<Block*>* worklist) const {
653   locations->Pop();
654   locations->Pop();
655   locations->Push(GetValueDefinition());
656 }
657 
GetValueDefinition() const658 DefinitionLocation StoreBitFieldInstruction::GetValueDefinition() const {
659   return DefinitionLocation::Instruction(this, 0);
660 }
661 
IsBlockTerminator() const662 bool CallRuntimeInstruction::IsBlockTerminator() const {
663   return is_tailcall || runtime_function->signature().return_type ==
664                             TypeOracle::GetNeverType();
665 }
666 
667 }  // namespace torque
668 }  // namespace internal
669 }  // namespace v8
670