25 if (block->IsDead())
continue;
27 out() <<
" compiler::CodeAssemblerParameterizedLabel<";
29 DCHECK_EQ(block->InputTypes().Size(), block->InputDefinitions().Size());
31 if (block->InputDefinitions().Peek(
i).IsPhiFromBlock(block)) {
32 if (!first)
out() <<
", ";
33 out() << block->InputTypes().Peek(
i)->GetGeneratedTNodeTypeName();
37 out() <<
"> " <<
BlockName(block) <<
"(&ca_, compiler::CodeAssemblerLabel::"
38 << (block->IsDeferred() ?
"kDeferred" :
"kNonDeferred") <<
");\n";
43 if (
cfg_.end() && *
cfg_.end() == block)
continue;
44 if (block->IsDead())
continue;
49 std::stringstream out_buffer;
50 std::ostream* old_out =
out_;
53 out() <<
" if (" <<
BlockName(block) <<
".is_used()) {\n";
60 out() << out_buffer.str();
71 std::stringstream phi_names;
74 const auto& def = block->InputDefinitions().Peek(
i);
76 if (def.IsPhiFromBlock(block)) {
78 << block->InputTypes().Peek(
i)->GetGeneratedTNodeTypeName()
79 <<
"> " << stack.Top() <<
";\n";
80 phi_names <<
", &" << stack.Top();
83 out() <<
" ca_.Bind(&" <<
BlockName(block) << phi_names.str() <<
");\n";
85 for (
const Instruction& instruction : block->instructions()) {
96 out() <<
" ca_.SetSourcePosition(\"" << file <<
"\", "
97 << (
pos.start.line + 1) <<
");\n";
108 const std::string str =
"ca_.Uninitialized<" +
109 instruction.type->GetGeneratedTNodeTypeName() +
">()";
115 const PushBuiltinPointerInstruction& instruction,
116 Stack<std::string>* stack) {
117 const std::string str =
118 "ca_.UncheckedCast<BuiltinPtr>(ca_.SmiConstant(Builtin::k" +
119 instruction.external_name +
"))";
125 const NamespaceConstantInstruction& instruction,
126 Stack<std::string>* stack) {
127 const Type* type = instruction.constant->type();
128 std::vector<std::string> results;
131 for (std::size_t
i = 0;
i < lowered.
size(); ++
i) {
133 stack->Push(results.back());
134 decls() <<
" TNode<" << lowered[
i]->GetGeneratedTNodeTypeName() <<
"> "
135 << stack->Top() <<
";\n";
139 if (type->StructSupertype()) {
140 out() <<
"std::tie(";
143 }
else if (results.size() == 1) {
144 out() << results[0] <<
" = ";
146 out() << instruction.constant->external_name() <<
"(state_)";
147 if (type->StructSupertype()) {
148 out() <<
".Flatten();\n";
157 std::vector<std::string>
args;
158 for (
auto it = parameter_types.rbegin(); it != parameter_types.rend(); ++it) {
159 const Type* type = *it;
160 if (type->IsConstexpr()) {
161 args.push_back(std::move(constexpr_arguments.back()));
162 constexpr_arguments.pop_back();
168 args.push_back(s.str());
169 stack->PopMany(slot_count);
172 std::reverse(
args.begin(),
args.end());
179 instruction.intrinsic->signature().parameter_types.types;
181 parameter_types, instruction.constexpr_arguments, stack);
184 const Type* return_type = instruction.intrinsic->signature().return_type;
185 std::vector<std::string> results;
187 const auto lowered =
LowerType(return_type);
188 for (std::size_t
i = 0;
i < lowered.
size(); ++
i) {
190 stack->Push(results.back());
191 decls() <<
" TNode<" << lowered[
i]->GetGeneratedTNodeTypeName() <<
"> "
192 << stack->Top() <<
";\n";
197 out() <<
"std::tie(";
201 if (results.size() == 1) {
202 out() << results[0] <<
" = ";
206 if (instruction.intrinsic->ExternalName() ==
"%RawDownCast") {
207 if (parameter_types.size() != 1) {
208 ReportError(
"%RawDownCast must take a single parameter");
210 const Type* original_type = parameter_types[0];
216 ReportError(
"%RawDownCast error: ", *return_type,
" is not a subtype of ",
219 if (!original_type->StructSupertype() &&
221 original_type->GetGeneratedTNodeTypeName()) {
223 out() <<
"TORQUE_CAST";
225 out() <<
"ca_.UncheckedCast<"
229 }
else if (instruction.intrinsic->ExternalName() ==
"%GetClassMapConstant") {
230 if (!parameter_types.empty()) {
231 ReportError(
"%GetClassMapConstant must not take parameters");
233 if (instruction.specialization_types.size() != 1) {
235 "%GetClassMapConstant must take a single class as specialization "
238 const ClassType* class_type =
239 ClassType::DynamicCast(instruction.specialization_types[0]);
241 ReportError(
"%GetClassMapConstant must take a class type parameter");
247 std::string class_name =
248 class_type->name() != class_type->GetGeneratedTNodeTypeName()
249 ? std::string(
"void")
250 : class_type->name();
252 out() << std::string(
"CodeStubAssembler(state_).GetClassMapConstant<") +
254 }
else if (instruction.intrinsic->ExternalName() ==
"%FromConstexpr") {
255 if (parameter_types.size() != 1 || !parameter_types[0]->IsConstexpr()) {
257 "%FromConstexpr must take a single parameter with constexpr "
261 ReportError(
"%FromConstexpr must return a non-constexpr type");
264 out() <<
"ca_.SmiConstant";
266 out() <<
"ca_.NumberConstant";
268 out() <<
"ca_.StringConstant";
271 "%FromConstexpr cannot cast to subclass of HeapObject unless it's a "
274 out() <<
"ca_.IntPtrConstant";
276 out() <<
"ca_.UintPtrConstant";
278 out() <<
"ca_.Int32Constant";
280 out() <<
"TNode<Uint8T>::UncheckedCast(ca_.Uint32Constant";
282 out() <<
"ca_.Uint32Constant";
284 out() <<
"ca_.Int64Constant";
286 out() <<
"ca_.Uint64Constant";
288 out() <<
"ca_.BoolConstant";
291 s <<
"%FromConstexpr does not support return type " << *return_type;
296 out() <<
"(CastToUnderlyingTypeIfEnum";
299 instruction.intrinsic->ExternalName());
304 if (instruction.intrinsic->ExternalName() ==
"%FromConstexpr") {
311 out() <<
").Flatten();\n";
318 Stack<std::string>* stack) {
320 instruction.macro->signature().parameter_types.types;
322 parameter_types, instruction.constexpr_arguments, stack);
324 Stack<std::string> pre_call_stack = *
stack;
325 const Type* return_type = instruction.macro->signature().return_type;
326 std::vector<std::string> results;
328 const auto lowered =
LowerType(return_type);
329 for (std::size_t
i = 0;
i < lowered.
size(); ++
i) {
331 stack->Push(results.back());
332 decls() <<
" TNode<" << lowered[
i]->GetGeneratedTNodeTypeName() <<
"> "
333 << stack->Top() <<
";\n";
336 std::string catch_name =
339 bool needs_flattening = return_type->StructSupertype().has_value();
340 if (needs_flattening) {
341 out() <<
"std::tie(";
345 if (results.size() == 1) {
346 out() << results[0] <<
" = ";
351 if (ExternMacro* extern_macro = ExternMacro::DynamicCast(instruction.macro)) {
352 out() << extern_macro->external_assembler_name() <<
"(state_).";
354 args.insert(
args.begin(),
"state_");
356 out() << instruction.macro->ExternalName() <<
"(";
358 if (needs_flattening) {
359 out() <<
").Flatten();\n";
364 instruction.catch_block, &pre_call_stack,
365 instruction.GetExceptionObjectDefinition());
369 const CallCsaMacroAndBranchInstruction& instruction,
370 Stack<std::string>* stack) {
372 instruction.macro->signature().parameter_types.types;
374 parameter_types, instruction.constexpr_arguments, stack);
376 Stack<std::string> pre_call_stack = *
stack;
377 std::vector<std::string> results;
378 const Type* return_type = instruction.macro->signature().return_type;
381 const auto lowered =
LowerType(return_type);
382 for (std::size_t
i = 0;
i < lowered.
size(); ++
i) {
385 decls() <<
" TNode<" << lowered[
i]->GetGeneratedTNodeTypeName() <<
"> "
386 << results.back() <<
";\n";
390 std::vector<std::string> label_names;
391 std::vector<std::vector<std::string>> var_names;
393 DCHECK_EQ(labels.size(), instruction.label_blocks.size());
394 for (
size_t i = 0;
i < labels.
size(); ++
i) {
397 var_names.push_back({});
398 for (
size_t j = 0; j < label_parameters.size(); ++j) {
400 const auto def = instruction.GetLabelValueDefinition(
i, j);
402 decls() <<
" compiler::TypedCodeAssemblerVariable<"
403 << label_parameters[j]->GetGeneratedTNodeTypeName() <<
"> "
404 << var_names[
i][j] <<
"(&ca_);\n";
406 out() <<
" compiler::CodeAssemblerLabel " << label_names[
i]
410 std::string catch_name =
413 if (results.size() == 1) {
414 out() << results[0] <<
" = ";
415 }
else if (results.size() > 1) {
416 out() <<
"std::tie(";
420 if (ExternMacro* extern_macro = ExternMacro::DynamicCast(instruction.macro)) {
421 out() << extern_macro->external_assembler_name() <<
"(state_).";
423 args.insert(
args.begin(),
"state_");
425 out() << instruction.macro->ExternalName() <<
"(";
427 bool first =
args.empty();
428 for (
size_t i = 0;
i < label_names.size(); ++
i) {
429 if (!first)
out() <<
", ";
430 out() <<
"&" << label_names[
i];
432 for (
size_t j = 0; j < var_names[
i].size(); ++j) {
433 out() <<
", &" << var_names[
i][j];
436 if (return_type->StructSupertype()) {
437 out() <<
").Flatten();\n";
443 instruction.catch_block, &pre_call_stack,
444 instruction.GetExceptionObjectDefinition());
446 if (instruction.return_continuation) {
447 out() <<
" ca_.Goto(&" <<
BlockName(*instruction.return_continuation);
448 DCHECK_EQ(stack->Size() + results.size(),
449 (*instruction.return_continuation)->InputDefinitions().Size());
451 const auto& input_definitions =
452 (*instruction.return_continuation)->InputDefinitions();
453 for (BottomOffset
i = {0};
i < input_definitions.AboveTop(); ++
i) {
454 if (input_definitions.Peek(
i).IsPhiFromBlock(
455 *instruction.return_continuation)) {
457 << (
i < stack->AboveTop() ? stack->Peek(
i) : results[
i.offset]);
462 for (
size_t l = 0; l < label_names.size(); ++
l) {
463 out() <<
" if (" << label_names[
l] <<
".is_used()) {\n";
464 out() <<
" ca_.Bind(&" << label_names[
l] <<
");\n";
465 out() <<
" ca_.Goto(&" <<
BlockName(instruction.label_blocks[l]);
466 DCHECK_EQ(stack->Size() + var_names[l].size(),
467 instruction.label_blocks[l]->InputDefinitions().Size());
469 const auto& label_definitions =
470 instruction.label_blocks[
l]->InputDefinitions();
472 BottomOffset
i = {0};
473 for (;
i < stack->AboveTop(); ++
i) {
474 if (label_definitions.Peek(
i).IsPhiFromBlock(
475 instruction.label_blocks[l])) {
476 out() <<
", " << stack->Peek(
i);
479 for (std::size_t k = 0; k < var_names[
l].size(); ++k, ++
i) {
480 if (label_definitions.Peek(
i).IsPhiFromBlock(
481 instruction.label_blocks[l])) {
482 out() <<
", " << var_names[
l][k] <<
".value()";
491 Stack<std::string>* stack) {
493 instruction.macro->signature().parameter_types.types;
495 parameter_types, instruction.constexpr_arguments, stack);
497 std::string result_name =
500 stack->Push(result_name);
502 decls() <<
" " << instruction.result_type->GetGeneratedTypeName() <<
" "
503 << result_name <<
";\n";
508 out() <<
" " << result_name <<
" = [=] () { return ";
510 if (
const ExternMacro* extern_macro =
511 ExternMacro::DynamicCast(instruction.macro)) {
512 out() << extern_macro->external_assembler_name() <<
"(state_)."
513 << extern_macro->ExternalName() <<
"(";
515 out() << instruction.macro->ExternalName() <<
"(state_";
519 if (!first)
out() <<
", ";
526 Stack<std::string>* stack) {
527 std::vector<std::string> arguments = stack->PopMany(instruction.argc);
528 std::vector<const Type*> result_types =
529 LowerType(instruction.builtin->signature().return_type);
530 if (instruction.is_tailcall) {
531 if (instruction.builtin->IsJavaScript()) {
532 out() <<
" CodeStubAssembler(state_).TailCallJSBuiltin(Builtin::k"
533 << instruction.builtin->ExternalName();
535 out() <<
" CodeStubAssembler(state_).TailCallBuiltin(Builtin::k"
536 << instruction.builtin->ExternalName();
538 if (!instruction.builtin->signature().HasContextParameter()) {
540 out() <<
", TNode<Object>()";
542 for (
const std::string& argument : arguments) {
543 out() <<
", " << argument;
547 std::vector<std::string> result_names(result_types.size());
548 for (
size_t i = 0;
i < result_types.size(); ++
i) {
550 decls() <<
" TNode<" << result_types[
i]->GetGeneratedTNodeTypeName()
551 <<
"> " << result_names[
i] <<
";\n";
554 std::string lhs_name;
555 std::string lhs_type;
556 switch (result_types.size()) {
562 lhs_name = result_names[0];
563 lhs_type = result_types[0]->GetGeneratedTNodeTypeName();
569 lhs_name = result_names[0] +
"_and_" + result_names[1];
570 lhs_type =
"PairT<" + result_types[0]->GetGeneratedTNodeTypeName() +
571 ", " + result_types[1]->GetGeneratedTNodeTypeName() +
">";
572 decls() <<
" TNode<" << lhs_type <<
"> " << lhs_name <<
";\n";
576 "Torque can only call builtins that return one or two values, not ",
577 result_types.size());
580 std::string catch_name =
582 Stack<std::string> pre_call_stack = *
stack;
584 for (
const std::string& name : result_names) {
590 DCHECK(!instruction.builtin->IsJavaScript());
591 if (result_types.empty()) {
592 out() <<
"ca_.CallBuiltinVoid(Builtin::k"
593 << instruction.builtin->ExternalName();
595 out() <<
" " << lhs_name <<
" = ";
596 out() <<
"ca_.CallBuiltin<" << lhs_type <<
">(Builtin::k"
597 << instruction.builtin->ExternalName();
599 if (!instruction.builtin->signature().HasContextParameter()) {
601 out() <<
", TNode<Object>()";
603 for (
const std::string& argument : arguments) {
604 out() <<
", " << argument;
608 if (result_types.size() > 1) {
609 for (
size_t i = 0;
i < result_types.size(); ++
i) {
610 out() <<
" " << result_names[
i] <<
" = ca_.Projection<" <<
i <<
">("
611 << lhs_name <<
");\n";
618 instruction.catch_block, &pre_call_stack,
619 instruction.GetExceptionObjectDefinition());
624 const CallBuiltinPointerInstruction& instruction,
625 Stack<std::string>* stack) {
626 std::vector<std::string> arguments = stack->PopMany(instruction.argc);
627 std::string function = stack->Pop();
628 std::vector<const Type*> result_types =
629 LowerType(instruction.type->return_type());
630 if (result_types.size() != 1) {
631 ReportError(
"builtins must have exactly one result");
633 if (instruction.is_tailcall) {
634 ReportError(
"tail-calls to builtin pointers are not supported");
637 DCHECK_EQ(1, instruction.GetValueDefinitionCount());
639 std::string generated_type = result_types[0]->GetGeneratedTNodeTypeName();
640 decls() <<
" TNode<" << generated_type <<
"> " << stack->Top() <<
";\n";
641 out() << stack->Top() <<
" = ";
642 if (generated_type !=
"Object")
out() <<
"TORQUE_CAST(";
643 out() <<
"CodeStubAssembler(state_).CallBuiltinPointer(Builtins::"
644 "CallInterfaceDescriptorFor("
645 "ExampleBuiltinForTorqueFunctionPointerType("
646 << instruction.type->function_pointer_type_id() <<
")), " << function;
647 if (!instruction.type->HasContextParameter()) {
649 out() <<
", TNode<Object>()";
651 for (
const std::string& argument : arguments) {
652 out() <<
", " << argument;
655 if (generated_type !=
"Object")
out() <<
")";
660 std::optional<Block*> catch_block) {
661 std::string catch_name;
664 out() <<
" compiler::CodeAssemblerExceptionHandlerLabel " << catch_name
665 <<
"__label(&ca_, compiler::CodeAssemblerLabel::kDeferred);\n";
666 out() <<
" { compiler::ScopedExceptionHandler s(&ca_, &" << catch_name
673 const std::string& catch_name,
const Type* return_type,
675 const std::optional<DefinitionLocation>& exception_object_definition) {
677 DCHECK(exception_object_definition);
678 std::string block_name =
BlockName(*catch_block);
680 out() <<
" if (" << catch_name <<
"__label.is_used()) {\n";
681 out() <<
" compiler::CodeAssemblerLabel " << catch_name
684 out() <<
" ca_.Goto(&" << catch_name <<
"_skip);\n";
686 decls() <<
" TNode<JSAny> "
688 out() <<
" ca_.Bind(&" << catch_name <<
"__label, &"
690 out() <<
" ca_.Goto(&" << block_name;
692 DCHECK_EQ(stack->Size() + 1, (*catch_block)->InputDefinitions().Size());
693 const auto& input_definitions = (*catch_block)->InputDefinitions();
695 if (input_definitions.Peek(
i).IsPhiFromBlock(*catch_block)) {
696 if (i < stack->AboveTop()) {
697 out() <<
", " << stack->Peek(
i);
707 out() <<
" ca_.Bind(&" << catch_name <<
"_skip);\n";
715 std::vector<std::string> arguments = stack->PopMany(instruction.argc);
716 const Type* return_type =
717 instruction.runtime_function->signature().return_type;
718 std::vector<const Type*> result_types;
722 if (result_types.size() > 1) {
723 ReportError(
"runtime function must have at most one result");
725 if (instruction.is_tailcall) {
726 out() <<
" CodeStubAssembler(state_).TailCallRuntime(Runtime::k"
727 << instruction.runtime_function->ExternalName() <<
", ";
731 std::string result_name;
732 if (result_types.size() == 1) {
734 decls() <<
" TNode<" << result_types[0]->GetGeneratedTNodeTypeName()
735 <<
"> " << result_name <<
";\n";
737 std::string catch_name =
739 Stack<std::string> pre_call_stack = *
stack;
740 if (result_types.size() == 1) {
741 std::string generated_type = result_types[0]->GetGeneratedTNodeTypeName();
742 stack->Push(result_name);
743 out() <<
" " << result_name <<
" = ";
744 if (generated_type !=
"Object")
out() <<
"TORQUE_CAST(";
745 out() <<
"CodeStubAssembler(state_).CallRuntime(Runtime::k"
746 << instruction.runtime_function->ExternalName() <<
", ";
749 if (generated_type !=
"Object")
out() <<
")";
753 out() <<
" CodeStubAssembler(state_).CallRuntime(Runtime::k"
754 << instruction.runtime_function->ExternalName() <<
", ";
758 out() <<
" CodeStubAssembler(state_).Unreachable();\n";
764 catch_name, return_type, instruction.catch_block, &pre_call_stack,
765 instruction.GetExceptionObjectDefinition());
770 Stack<std::string>* stack) {
771 out() <<
" ca_.Branch(" << stack->Pop() <<
", &"
772 <<
BlockName(instruction.if_true) <<
", std::vector<compiler::Node*>{";
774 const auto& true_definitions = instruction.if_true->InputDefinitions();
775 DCHECK_EQ(stack->Size(), true_definitions.Size());
777 for (BottomOffset
i = {0};
i < stack->AboveTop(); ++
i) {
778 if (true_definitions.Peek(
i).IsPhiFromBlock(instruction.if_true)) {
779 if (!first)
out() <<
", ";
780 out() << stack->Peek(
i);
786 <<
", std::vector<compiler::Node*>{";
788 const auto& false_definitions = instruction.if_false->InputDefinitions();
789 DCHECK_EQ(stack->Size(), false_definitions.Size());
791 for (BottomOffset
i = {0};
i < stack->AboveTop(); ++
i) {
792 if (false_definitions.Peek(
i).IsPhiFromBlock(instruction.if_false)) {
793 if (!first)
out() <<
", ";
794 out() << stack->Peek(
i);
803 const ConstexprBranchInstruction& instruction, Stack<std::string>* stack) {
804 out() <<
" if ((" << instruction.condition <<
")) {\n";
805 out() <<
" ca_.Goto(&" <<
BlockName(instruction.if_true);
807 const auto& true_definitions = instruction.if_true->InputDefinitions();
808 DCHECK_EQ(stack->Size(), true_definitions.Size());
809 for (BottomOffset
i = {0};
i < stack->AboveTop(); ++
i) {
810 if (true_definitions.Peek(
i).IsPhiFromBlock(instruction.if_true)) {
811 out() <<
", " << stack->Peek(
i);
816 out() <<
" } else {\n";
817 out() <<
" ca_.Goto(&" <<
BlockName(instruction.if_false);
819 const auto& false_definitions = instruction.if_false->InputDefinitions();
820 DCHECK_EQ(stack->Size(), false_definitions.Size());
821 for (BottomOffset
i = {0};
i < stack->AboveTop(); ++
i) {
822 if (false_definitions.Peek(
i).IsPhiFromBlock(instruction.if_false)) {
823 out() <<
", " << stack->Peek(
i);
832 Stack<std::string>* stack) {
833 out() <<
" ca_.Goto(&" <<
BlockName(instruction.destination);
834 const auto& destination_definitions =
835 instruction.destination->InputDefinitions();
836 DCHECK_EQ(stack->Size(), destination_definitions.Size());
837 for (BottomOffset
i = {0};
i < stack->AboveTop(); ++
i) {
838 if (destination_definitions.Peek(
i).IsPhiFromBlock(
839 instruction.destination)) {
840 out() <<
", " << stack->Peek(
i);
847 Stack<std::string>* stack) {
848 for (
auto it = instruction.variable_names.rbegin();
849 it != instruction.variable_names.rend(); ++it) {
850 out() <<
" *" << *it <<
" = " << stack->Pop() <<
";\n";
852 out() <<
" ca_.Goto(" << instruction.destination <<
");\n";
856 Stack<std::string>* stack) {
860 out() <<
" CodeStubAssembler(state_).Return(";
862 std::vector<std::string> values = stack->PopMany(instruction.count);
868 Stack<std::string>* stack) {
869 out() <<
" CodeStubAssembler(state_).PrintErr("
874 Stack<std::string>* stack) {
875 switch (instruction.kind) {
877 DCHECK(instruction.message.empty());
878 out() <<
" CodeStubAssembler(state_).Unreachable();\n";
881 DCHECK(instruction.message.empty());
882 out() <<
" CodeStubAssembler(state_).DebugBreak();\n";
888 out() <<
" auto pos_stack = ca_.GetMacroSourcePositionStack();\n";
889 out() <<
" pos_stack.push_back({" << file <<
", "
890 << instruction.pos.start.line + 1 <<
"});\n";
891 out() <<
" CodeStubAssembler(state_).FailAssert("
900 Stack<std::string>* stack) {
901 const std::string str =
902 "ca_.UncheckedCast<" +
903 instruction.destination_type->GetGeneratedTNodeTypeName() +
">(" +
905 stack->Poke(stack->AboveTop() - 1, str);
910 Stack<std::string>* stack) {
913 CHECK(!instruction.type->IsBuiltinPointerType());
915 std::string result_name =
918 std::string
offset = stack->Pop();
919 std::string
object = stack->Pop();
920 stack->Push(result_name);
922 decls() <<
" " << instruction.type->GetGeneratedTypeName() <<
" "
923 << result_name <<
";\n";
924 out() <<
" " << result_name
925 <<
" = CodeStubAssembler(state_).LoadReference<"
926 << instruction.type->GetGeneratedTNodeTypeName()
927 <<
">(CodeStubAssembler::Reference{" <<
object <<
", " <<
offset
932 Stack<std::string>* stack) {
935 CHECK(!instruction.type->IsBuiltinPointerType());
937 std::string value = stack->Pop();
938 std::string
offset = stack->Pop();
939 std::string
object = stack->Pop();
941 out() <<
" CodeStubAssembler(state_).StoreReference<"
942 << instruction.type->GetGeneratedTNodeTypeName()
943 <<
">(CodeStubAssembler::"
945 <<
object <<
", " <<
offset <<
"}, " << value <<
");\n";
949std::string GetBitFieldSpecialization(
const Type* container,
950 const BitField& field) {
951 auto smi_tagged_type =
953 std::string container_type = smi_tagged_type
955 : container->GetConstexprGeneratedTypeName();
956 int offset = smi_tagged_type
959 std::stringstream stream;
960 stream <<
"base::BitField<"
961 << field.name_and_type.type->GetConstexprGeneratedTypeName() <<
", "
962 <<
offset <<
", " << field.num_bits <<
", " << container_type <<
">";
968 Stack<std::string>* stack) {
969 std::string result_name =
972 std::string bit_field_struct = stack->Pop();
973 stack->Push(result_name);
975 const Type* struct_type = instruction.bit_field_struct_type;
976 const Type* field_type = instruction.bit_field.name_and_type.type;
977 auto smi_tagged_type =
979 bool struct_is_pointer_size =
984 std::string struct_word_type = struct_is_pointer_size ?
"WordT" :
"Word32T";
985 std::string decoder =
986 struct_is_pointer_size
987 ? (field_is_pointer_size ?
"DecodeWord" :
"DecodeWord32FromWord")
988 : (field_is_pointer_size ?
"DecodeWordFromWord32" :
"DecodeWord32");
990 decls() <<
" " << field_type->GetGeneratedTypeName() <<
" " << result_name
993 if (smi_tagged_type) {
997 "ca_.BitcastTaggedToWordForTagAndSmiBits(" + bit_field_struct +
")";
1000 out() <<
" " << result_name <<
" = ca_.UncheckedCast<"
1001 << field_type->GetGeneratedTNodeTypeName()
1002 <<
">(CodeStubAssembler(state_)." << decoder <<
"<"
1003 << GetBitFieldSpecialization(struct_type, instruction.bit_field)
1004 <<
">(ca_.UncheckedCast<" << struct_word_type <<
">("
1005 << bit_field_struct <<
")));\n";
1009 Stack<std::string>* stack) {
1010 std::string result_name =
1013 std::string value = stack->Pop();
1014 std::string bit_field_struct = stack->Pop();
1015 stack->Push(result_name);
1017 const Type* struct_type = instruction.bit_field_struct_type;
1018 const Type* field_type = instruction.bit_field.name_and_type.type;
1019 auto smi_tagged_type =
1021 bool struct_is_pointer_size =
1026 std::string struct_word_type = struct_is_pointer_size ?
"WordT" :
"Word32T";
1027 std::string field_word_type = field_is_pointer_size ?
"UintPtrT" :
"Uint32T";
1028 std::string encoder =
1029 struct_is_pointer_size
1030 ? (field_is_pointer_size ?
"UpdateWord" :
"UpdateWord32InWord")
1031 : (field_is_pointer_size ?
"UpdateWordInWord32" :
"UpdateWord32");
1033 decls() <<
" " << struct_type->GetGeneratedTypeName() <<
" " << result_name
1036 if (smi_tagged_type) {
1040 "ca_.BitcastTaggedToWordForTagAndSmiBits(" + bit_field_struct +
")";
1043 std::string result_expression =
1044 "CodeStubAssembler(state_)." + encoder +
"<" +
1045 GetBitFieldSpecialization(struct_type, instruction.bit_field) +
1046 ">(ca_.UncheckedCast<" + struct_word_type +
">(" + bit_field_struct +
1047 "), ca_.UncheckedCast<" + field_word_type +
">(" + value +
")" +
1048 (instruction.starts_as_zero ?
", true" :
"") +
")";
1050 if (smi_tagged_type) {
1052 "ca_.BitcastWordToTaggedSigned(" + result_expression +
")";
1055 out() <<
" " << result_name <<
" = ca_.UncheckedCast<"
1056 << struct_type->GetGeneratedTNodeTypeName() <<
">(" << result_expression
1063 std::ostream& out) {
1064 if (!
result.IsOnStack()) {
1065 out <<
result.constexpr_value();
1066 }
else if (
auto struct_type =
result.type()->StructSupertype()) {
1067 out << (*struct_type)->GetGeneratedTypeName() <<
"{";
1069 for (
auto& field : (*struct_type)->fields()) {
1080 out <<
result.type()->GetGeneratedTypeName() <<
"{"
1081 << values.Peek(
result.stack_range().begin()) <<
"}";
std::optional< Stack< std::string > > EmitGraph(Stack< std::string > parameters)
std::optional< Builtin::Kind > linkage_
std::vector< std::string > ProcessArgumentsCommon(const TypeVector ¶meter_types, std::vector< std::string > constexpr_arguments, Stack< std::string > *stack)
void PostCallableExceptionPreparation(const std::string &catch_name, const Type *return_type, std::optional< Block * > catch_block, Stack< std::string > *stack, const std::optional< DefinitionLocation > &exception_object_definition)
static constexpr const char * ARGUMENTS_VARIABLE_STRING
Stack< std::string > EmitBlock(const Block *block)
static void EmitCSAValue(VisitResult result, const Stack< std::string > &values, std::ostream &out)
std::string PreCallableExceptionPreparation(std::optional< Block * > catch_block)
void EmitSourcePosition(SourcePosition pos, bool always_emit=false) override
static DefinitionLocation Parameter(std::size_t index)
static const std::string & PathFromV8Root(SourceId file)
static std::string AbsolutePath(SourceId file)
BottomOffset AboveTop() const
const T & Peek(BottomOffset from_bottom) const
static int SmiTagAndShiftSize()
std::string FreshLabelName()
SourcePosition previous_position_
std::string FreshNodeName()
void SetDefinitionVariable(const DefinitionLocation &definition, const std::string &str)
const ControlFlowGraph & cfg_
std::string DefinitionToVariable(const DefinitionLocation &location)
std::string BlockName(const Block *block)
void EmitInstruction(const Instruction &instruction, Stack< std::string > *stack)
std::string FreshCatchName()
static GenericType * GetSmiTaggedGeneric()
static const Type * GetUninitializedHeapObjectType()
static const Type * GetStringType()
static const Type * GetUint32Type()
static const Type * GetTaggedType()
static const Type * GetHeapObjectType()
static const Type * GetUint8Type()
static const Type * GetUint64Type()
static const Type * GetObjectType()
static const Type * GetVoidType()
static const Type * GetInt32Type()
static const Type * GetNumberType()
static const Type * GetInt64Type()
static const Type * GetUIntPtrType()
static const Type * GetIntPtrType()
static const Type * GetBoolType()
static const Type * GetSmiType()
static const Type * GetNeverType()
static std::optional< const Type * > MatchUnaryGeneric(const Type *type, GenericType *generic)
std::string GetGeneratedTNodeTypeName() const
virtual bool IsSubtypeOf(const Type *supertype) const
std::optional< const StructType * > StructSupertype() const
virtual bool IsConstexpr() const
base::Vector< const DirectHandle< Object > > args
ZoneVector< RpoNumber > & result
ZoneStack< RpoNumber > & stack
size_t LoweredSlotCount(const Type *type)
std::string StringLiteralQuote(const std::string &s)
void ReportError(Args &&... args)
std::vector< LabelDeclaration > LabelDeclarationVector
VisitResult ProjectStructField(VisitResult structure, const std::string &fieldname)
bool Is32BitIntegralType(const Type *type)
bool IsPointerSizeIntegralType(const Type *type)
std::vector< const Type * > TypeVector
TypeVector LowerType(const Type *type)
void PrintCommaSeparatedList(std::ostream &os, const T &list, C &&transform)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
bool CompareStartIgnoreColumn(const SourcePosition &pos) const