9#include <unordered_map>
10#include <unordered_set>
45namespace interpreter {
57 register_(
Register::current_context()),
61 depth_ = outer_->depth_ + 1;
64 if (!outer_context_reg.is_valid()) {
65 outer_context_reg =
generator_->register_allocator()->NewRegister();
67 outer_->set_register(outer_context_reg);
68 generator_->builder()->PushContext(outer_context_reg);
75 DCHECK_EQ(register_.index(), Register::current_context().index());
76 generator_->builder()->PopContext(outer_->reg());
77 outer_->set_register(register_);
87 return scope_->ContextChainLength(scope);
98 for (
int i = depth;
i > 0; --
i) {
124 outer_(generator->execution_control()),
125 context_(generator->execution_context()) {
139 PerformCommand(CMD_RETURN,
nullptr, source_position);
142 PerformCommand(CMD_ASYNC_RETURN,
nullptr, source_position);
145 class DeferredCommands;
156 return command != CMD_BREAK && command != CMD_CONTINUE;
160 int source_position);
162 int source_position) = 0;
167 void PopContextToExpectedDepth();
188 deferred_(generator->zone()),
189 token_register_(token_register),
190 result_register_(result_register),
191 message_register_(message_register),
193 async_return_token_(-1),
194 fallthrough_from_try_block_needed_(false) {
199 static_cast<int>(TryFinallyContinuationToken::kRethrowToken) == 0);
201 {CMD_RETHROW,
nullptr,
202 static_cast<int>(TryFinallyContinuationToken::kRethrowToken)});
216 int token = GetTokenForCommand(command,
statement);
219 DCHECK_EQ(deferred_[token].command, command);
221 DCHECK_EQ(deferred_[token].token, token);
223 if (CommandUsesAccumulator(command)) {
224 builder()->StoreAccumulatorInRegister(result_register_);
226 builder()->LoadLiteral(Smi::FromInt(token));
227 builder()->StoreAccumulatorInRegister(token_register_);
228 if (!CommandUsesAccumulator(command)) {
233 builder()->StoreAccumulatorInRegister(result_register_);
235 if (command == CMD_RETHROW) {
238 builder()->LoadTheHole().SetPendingMessage().StoreAccumulatorInRegister(
248 RecordCommand(CMD_RETHROW,
nullptr);
254 fallthrough_from_try_block_needed_ =
true;
255 builder()->LoadLiteral(Smi::FromInt(
256 static_cast<int>(TryFinallyContinuationToken::kFallthroughToken)));
257 builder()->StoreAccumulatorInRegister(token_register_);
262 builder()->StoreAccumulatorInRegister(result_register_);
266 if (entry.
command == CMD_RETHROW) {
269 ->LoadAccumulatorWithRegister(message_register_)
270 .SetPendingMessage();
273 if (CommandUsesAccumulator(entry.
command)) {
274 builder()->LoadAccumulatorWithRegister(result_register_);
283 if (deferred_.empty())
return;
287 if (deferred_.size() == 1) {
290 const Entry& entry = deferred_[0];
292 if (fallthrough_from_try_block_needed_) {
294 ->LoadLiteral(Smi::FromInt(entry.
token))
295 .CompareReference(token_register_)
296 .JumpIfFalse(ToBooleanMode::kAlreadyBoolean,
297 &fall_through_from_try_block);
300 ApplyDeferredCommand(entry);
308 const int jump_table_base_value =
309 fallthrough_from_try_block_needed_ ? 0 : 1;
310 const int jump_table_size =
311 static_cast<int>(deferred_.size() - jump_table_base_value);
313 if (jump_table_size == 1) {
316 const Entry& first_entry = deferred_[0];
317 const Entry& final_entry = deferred_[1];
319 ->LoadLiteral(Smi::FromInt(first_entry.
token))
320 .CompareReference(token_register_)
321 .JumpIfFalse(ToBooleanMode::kAlreadyBoolean,
322 &fall_through_to_final_entry);
323 ApplyDeferredCommand(first_entry);
324 builder()->Bind(&fall_through_to_final_entry);
325 ApplyDeferredCommand(final_entry);
328 jump_table_size, jump_table_base_value);
330 ->LoadAccumulatorWithRegister(token_register_)
331 .SwitchOnSmiNoFeedback(jump_table);
333 const Entry& first_entry = deferred_.front();
334 if (fallthrough_from_try_block_needed_) {
335 builder()->Jump(&fall_through_from_try_block);
336 builder()->Bind(jump_table, first_entry.
token);
338 ApplyDeferredCommand(first_entry);
340 for (
const Entry& entry : base::IterateWithoutFirst(deferred_)) {
341 builder()->Bind(jump_table, entry.token);
342 ApplyDeferredCommand(entry);
347 if (fallthrough_from_try_block_needed_) {
348 builder()->Bind(&fall_through_from_try_block);
359 return GetReturnToken();
360 case CMD_ASYNC_RETURN:
361 return GetAsyncReturnToken();
363 return static_cast<int>(TryFinallyContinuationToken::kRethrowToken);
367 return GetNewTokenForCommand(command,
statement);
372 if (return_token_ == -1) {
373 return_token_ = GetNewTokenForCommand(CMD_RETURN,
nullptr);
375 return return_token_;
379 if (async_return_token_ == -1) {
380 async_return_token_ = GetNewTokenForCommand(CMD_ASYNC_RETURN,
nullptr);
382 return async_return_token_;
386 int token =
static_cast<int>(deferred_.size());
387 deferred_.push_back({command,
statement, token});
414 int source_position)
override {
449 int source_position)
override {
484 int source_position)
override {
518 int source_position)
override {
548 int source_position)
override {
588 int source_position)
override {
633 int source_position) {
636 if (current->Execute(command,
statement, source_position)) {
639 current = current->outer();
640 }
while (current !=
nullptr);
648 generator()->builder()->PopContext(
context()->
reg());
656 outer_next_register_index_(
657 generator->register_allocator()->next_register_index()) {}
660 generator_->register_allocator()->ReleaseRegisters(
661 outer_next_register_index_);
679 if (mode == AccumulatorPreservingMode::kPreserve) {
680 saved_accumulator_register_ =
681 generator_->register_allocator()->NewRegister();
682 generator_->builder()->StoreAccumulatorInRegister(
683 saved_accumulator_register_);
688 if (saved_accumulator_register_.is_valid()) {
689 generator_->builder()->LoadAccumulatorWithRegister(
690 saved_accumulator_register_);
708 : outer_(generator->execution_result()),
712 generator->set_execution_result(
this);
716 allocator_.generator()->set_execution_result(outer_);
733 DCHECK_EQ(type_hint_, TypeHint::kUnknown);
734 type_hint_ = TypeHint::kBoolean;
738 DCHECK_EQ(type_hint_, TypeHint::kUnknown);
739 type_hint_ = TypeHint::kString;
743 DCHECK_EQ(type_hint_, TypeHint::kUnknown);
744 type_hint_ = TypeHint::kInternalizedString;
782 result_consumed_by_test_(false),
783 fallthrough_(fallthrough),
784 then_labels_(then_labels),
785 else_labels_(else_labels) {}
798 std::swap(then_labels_, else_labels_);
799 fallthrough_ = inverted_fallthrough();
809 then_labels_ = then_labels;
812 else_labels_ = else_labels;
817 switch (fallthrough_) {
818 case TestFallthrough::kThen:
819 return TestFallthrough::kElse;
820 case TestFallthrough::kElse:
821 return TestFallthrough::kThen;
823 return TestFallthrough::kNone;
827 fallthrough_ = fallthrough;
840 template <
typename IsolateT>
845 DCHECK(has_constant_pool_entry_);
848 isolate->factory()->NewFixedArray(entry_slots_, AllocationType::kOld);
851 if (info->scope()->is_module_scope()) {
852 for (
Declaration* decl : *info->scope()->declarations()) {
854 if (!var->is_used())
continue;
855 if (var->location() != VariableLocation::MODULE)
continue;
857 int start = array_index;
859 if (decl->IsFunctionDeclaration()) {
862 Compiler::GetSharedFunctionInfo(f, script, isolate));
866 data->set(array_index++, *sfi);
867 int literal_index = generator->GetCachedCreateClosureSlot(f);
868 data->set(array_index++, Smi::FromInt(literal_index));
870 data->set(array_index++, Smi::FromInt(var->index()));
872 }
else if (var->IsExport() && var->binding_needs_init()) {
873 data->set(array_index++, Smi::FromInt(var->index()));
878 for (
Declaration* decl : *info->scope()->declarations()) {
880 if (!var->is_used())
continue;
881 if (var->location() != VariableLocation::UNALLOCATED)
continue;
883 int start = array_index;
885 if (decl->IsVariableDeclaration()) {
886 data->set(array_index++, *var->raw_name()->string());
891 Compiler::GetSharedFunctionInfo(f, script, isolate));
895 data->set(array_index++, *sfi);
896 int literal_index = generator->GetCachedCreateClosureSlot(f);
897 data->set(array_index++, Smi::FromInt(literal_index));
907 DCHECK(has_constant_pool_entry_);
908 return constant_pool_entry_;
912 DCHECK(has_top_level_declaration());
913 DCHECK(!has_constant_pool_entry_);
914 constant_pool_entry_ = constant_pool_entry;
915 has_constant_pool_entry_ =
true;
919 entry_slots_ += kGlobalVariableDeclarationSize;
922 entry_slots_ += kGlobalFunctionDeclarationSize;
925 entry_slots_ += kModuleVariableDeclarationSize;
928 entry_slots_ += kModuleFunctionDeclarationSize;
935 const int kGlobalVariableDeclarationSize = 1;
936 const int kGlobalFunctionDeclarationSize = 2;
937 const int kModuleVariableDeclarationSize = 1;
938 const int kModuleFunctionDeclarationSize = 3;
940 size_t constant_pool_entry_ = 0;
941 int entry_slots_ = 0;
942 bool has_constant_pool_entry_ =
false;
943 bool processed_ =
false;
949 :
generator_(generator), outer_scope_(generator->current_scope()) {
950 if (scope !=
nullptr) {
956 if (outer_scope_ !=
generator_->current_scope()) {
973 inner_context_ = generator->register_allocator()->NewRegister();
974 outer_context_ = generator->register_allocator()->NewRegister();
975 generator->BuildNewLocalBlockContext(
scope_);
976 generator->builder()->StoreAccumulatorInRegister(inner_context_);
998 DCHECK(inner_context_.is_valid());
999 DCHECK(outer_context_.is_valid());
1001 generator_->builder()->LoadAccumulatorWithRegister(inner_context_);
1004 is_in_scope_ =
true;
1008 DCHECK(inner_context_.is_valid());
1009 DCHECK(outer_context_.is_valid());
1011 context_scope_ = std::nullopt;
1012 current_scope_ = std::nullopt;
1013 is_in_scope_ =
false;
1036 kClosureFeedbackCell
1042 PutImpl(slot_kind, 0, variable, slot_index);
1045 PutImpl(slot_kind, 0, node, slot_index);
1049 PutImpl(slot_kind, variable_index, name, slot_index);
1052 PutImpl(slot_kind, 0, name, slot_index);
1056 return GetImpl(slot_kind, 0, variable);
1059 return GetImpl(slot_kind, 0, node);
1063 return GetImpl(slot_kind, variable_index, name);
1066 return GetImpl(slot_kind, 0, name);
1070 using Key = std::tuple<SlotKind, int, const void*>;
1074 Key key = std::make_tuple(slot_kind, index, node);
1075 auto entry = std::make_pair(
key, slot_index);
1080 Key key = std::make_tuple(slot_kind, index, node);
1082 if (iter !=
map_.end()) {
1083 return iter->second;
1109 :
bitmap_(bitmap), prev_bitmap_value_(*bitmap) {}
1144 :
bitmap_(&bytecode_generator->hole_check_bitmap_) {}
1155 merge_called_ =
true;
1162 merge_called_ =
true;
1170 merge_into_bitmap_(&merge_into.merge_value_) {}
1180 Variable::HoleCheckBitmap merge_value_ = UINT64_MAX;
1183 bool merge_called_ =
false;
1191 :
type_(type),
object_(object_register), next_(next_register) {
1208 : bytecode_generator_(bytecode_generator),
1209 labels_(bytecode_generator->zone()) {
1210 prev_ = bytecode_generator_->optional_chaining_null_labels_;
1211 bytecode_generator_->optional_chaining_null_labels_ = &labels_;
1215 bytecode_generator_->optional_chaining_null_labels_ =
prev_;
1233 : bytecode_generator_(bytecode_generator),
1234 parent_loop_scope_(bytecode_generator_->current_loop_scope()),
1235 loop_builder_(loop) {
1236 loop_builder_->LoopHeader();
1237 bytecode_generator_->set_current_loop_scope(
this);
1238 bytecode_generator_->loop_depth_++;
1242 bytecode_generator_->loop_depth_--;
1243 bytecode_generator_->set_current_loop_scope(parent_loop_scope_);
1244 DCHECK_GE(bytecode_generator_->loop_depth_, 0);
1245 loop_builder_->JumpToHeader(
1246 bytecode_generator_->loop_depth_,
1247 parent_loop_scope_ ? parent_loop_scope_->loop_builder_ :
nullptr);
1261 : bytecode_generator_(bytecode_generator),
1262 parent_for_in_scope_(bytecode_generator_->current_for_in_scope()),
1264 enum_index_(enum_index),
1265 cache_type_(cache_type) {
1266 if (
v8_flags.enable_enumerated_keyed_access_bytecode) {
1267 Expression* each = stmt->each();
1268 if (each->IsVariableProxy()) {
1269 Variable* each_var = each->AsVariableProxy()->var();
1270 if (each_var->IsStackLocal()) {
1271 each_var_ = each_var;
1272 bytecode_generator_->SetVariableInRegister(
1274 bytecode_generator_->builder()->Local(each_var_->index()));
1277 bytecode_generator_->set_current_for_in_scope(
this);
1282 if (
v8_flags.enable_enumerated_keyed_access_bytecode) {
1283 bytecode_generator_->set_current_for_in_scope(parent_for_in_scope_);
1294 }
while (scope !=
nullptr);
1312 : bytecode_generator_(bytecode_generator),
1313 prev_disposables_stack_(
1314 bytecode_generator_->current_disposables_stack_) {
1315 bytecode_generator_->set_current_disposables_stack(
1318 Runtime::kInitializeDisposableStack);
1320 bytecode_generator_->current_disposables_stack());
1324 bytecode_generator_->set_current_disposables_stack(prev_disposables_stack_);
1334template <
typename PropertyT>
1344template <
typename PropertyT>
1346 :
public base::TemplateHashMap<Literal, Accessors<PropertyT>,
1347 bool (*)(void*, void*),
1348 ZoneAllocationPolicy> {
1350 explicit AccessorTable(
Zone* zone)
1351 : base::TemplateHashMap<Literal, Accessors<PropertyT>,
1352 bool (*)(
void*,
void*), ZoneAllocationPolicy>(
1356 Accessors<PropertyT>* LookupOrInsert(Literal*
key) {
1357 auto it = this->find(
key,
true);
1358 if (it->second ==
nullptr) {
1359 it->second =
zone_->New<Accessors<PropertyT>>();
1365 const std::vector<std::pair<Literal*, Accessors<PropertyT>*>>&
1366 ordered_accessors() {
1380static bool IsInEagerLiterals(
1382 const std::vector<FunctionLiteral*>& eager_literals) {
1383 for (FunctionLiteral* eager_literal : eager_literals) {
1384 if (
literal == eager_literal)
return true;
1395 std::vector<FunctionLiteral*>* eager_inner_literals,
Handle<Script> script)
1397 zone_(compile_zone),
1398 builder_(zone(), info->num_parameters_including_this(),
1399 info->scope()->num_stack_slots(), info->feedback_vector_spec(),
1400 info->SourcePositionRecordingMode()),
1402 ast_string_constants_(ast_string_constants),
1404 current_scope_(info->scope()),
1405 eager_inner_literals_(eager_inner_literals),
1409 block_coverage_builder_(nullptr),
1410 function_literals_(0, zone()),
1411 native_function_literals_(0, zone()),
1412 object_literals_(0, zone()),
1413 array_literals_(0, zone()),
1414 class_literals_(0, zone()),
1415 template_objects_(0, zone()),
1416 vars_in_hole_check_bitmap_(0, zone()),
1417 eval_calls_(0, zone()),
1418 execution_control_(nullptr),
1419 execution_context_(nullptr),
1420 execution_result_(nullptr),
1421 incoming_new_target_or_generator_(),
1422 current_disposables_stack_(),
1423 optional_chaining_null_labels_(nullptr),
1425 generator_jump_table_(nullptr),
1428 hole_check_bitmap_(0),
1429 current_loop_scope_(nullptr),
1430 current_for_in_scope_(nullptr),
1433 if (info->has_source_range_map()) {
1441template <
typename Isolate>
1442struct NullContextScopeHelper;
1445struct NullContextScopeHelper<
Isolate> {
1455 using Type = DummyNullContextScope;
1458template <
typename Isolate>
1459using NullContextScopeFor =
typename NullContextScopeHelper<Isolate>::Type;
1463template <
typename IsolateT>
1470 NullContextScopeFor<IsolateT> null_context_scope(isolate);
1479 if (
v8_flags.trace_block_coverage) {
1481 coverage_info->CoverageInfoPrint(os,
info()->
literal()->GetDebugName());
1489 bytecode_array->set_incoming_new_target_or_generator_register(
1493 return bytecode_array;
1501template <
typename IsolateT>
1503 IsolateT* isolate) {
1508 NullContextScopeFor<IsolateT> null_context_scope(isolate);
1515 CodeLinePosInfoRecordEvent(
1519 return source_position_table;
1529 return builder()->CheckBytecodeMatches(bytecode);
1533template <
typename IsolateT>
1539 info(),
this, script, isolate);
1540 if (declarations.
is_null())
return SetStackOverflow();
1550 if (shared_info.
is_null())
return SetStackOverflow();
1556 for (std::pair<NativeFunctionLiteral*, size_t>
literal :
1559 DCHECK((std::is_same<Isolate, v8::internal::Isolate>::value));
1567 v8_isolate, Utils::ToLocal(expr->
name()));
1577 for (std::pair<Call*, Scope*> call :
eval_calls_) {
1578 script->infos()->set(call.first->eval_scope_info_index(),
1579 MakeWeak(*call.second->scope_info()));
1583 for (std::pair<ObjectLiteralBoilerplateBuilder*, size_t>
literal :
1593 constant_properties);
1598 for (std::pair<ArrayLiteralBoilerplateBuilder*, size_t>
literal :
1636 InitializeAstVisitor(stack_limit);
1644 v8_flags.stress_lazy_compilation) == 0;
1677 var->ResetHoleCheckBitmapIndex();
1751 if (
literal->class_scope_has_private_brand()) {
1757 if (
literal->requires_instance_members_initializer()) {
1804 if (check_return_value.
empty()) {
1805 if (!
builder()->RemainderOfBlockIsDead()) {
1812 if (!
builder()->RemainderOfBlockIsDead()) {
1863 if (!
literal->scope()->is_repl_mode_scope()) {
1906 if (stmt->IsBlock()) {
1908 if (block->is_initialization_block_for_parameters()) {
1937 .
CallRuntime(Runtime::kInlineGeneratorClose, arg);
1950 if (!
builder()->RemainderOfBlockIsDead()) {
2013void BytecodeGenerator::VisitBlock(
Block* stmt) {
2016 if (stmt->scope() !=
nullptr && stmt->scope()->NeedsContext()) {
2018 ContextScope scope(
this, stmt->scope());
2026 if (
v8_flags.js_explicit_resource_management && stmt->scope() !=
nullptr &&
2027 (stmt->scope()->has_using_declaration() ||
2028 stmt->scope()->has_await_using_declaration())) {
2030 stmt->scope()->has_await_using_declaration());
2039 if (stmt->scope() !=
nullptr) {
2062 if (!variable->is_used())
return;
2064 switch (variable->location()) {
2069 if (variable->binding_needs_init()) {
2075 if (variable->binding_needs_init()) {
2084 if (variable->binding_needs_init()) {
2092 DCHECK(!variable->binding_needs_init());
2105void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
2111 if (!variable->is_used())
return;
2113 switch (variable->location()) {
2119 VisitFunctionLiteral(decl->fun());
2126 VisitFunctionLiteral(decl->fun());
2135 VisitFunctionLiteral(decl->fun());
2137 Runtime::kDeclareEvalFunction,
args);
2158 .
CallRuntime(Runtime::kGetModuleNamespace, module_request);
2169 builder()->AllocateDeferredConstantPoolEntry());
2186 if (!var->is_used())
continue;
2188 if (decl->IsFunctionDeclaration()) {
2193 }
else if (var->IsExport() && var->binding_needs_init()) {
2194 DCHECK(decl->IsVariableDeclaration());
2212 if (decl->IsFunctionDeclaration()) {
2221 DCHECK(decl->IsVariableDeclaration());
2243 if (
builder()->RemainderOfBlockIsDead())
break;
2252void BytecodeGenerator::VisitEmptyStatement(
EmptyStatement* stmt) {}
2254void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) {
2255 ConditionalControlFlowBuilder conditional_builder(
2259 if (stmt->condition()->ToBooleanIsTrue()) {
2261 conditional_builder.Then();
2262 Visit(stmt->then_statement());
2263 }
else if (stmt->condition()->ToBooleanIsFalse()) {
2265 if (stmt->HasElseStatement()) {
2266 conditional_builder.Else();
2267 Visit(stmt->else_statement());
2273 VisitForTest(stmt->condition(), conditional_builder.then_labels(),
2276 HoleCheckElisionMergeScope merge_elider(
this);
2278 HoleCheckElisionMergeScope::Branch branch(merge_elider);
2279 conditional_builder.Then();
2280 Visit(stmt->then_statement());
2284 HoleCheckElisionMergeScope::Branch branch(merge_elider);
2285 if (stmt->HasElseStatement()) {
2286 conditional_builder.JumpToEnd();
2287 conditional_builder.Else();
2288 Visit(stmt->else_statement());
2292 merge_elider.Merge();
2296void BytecodeGenerator::VisitSloppyBlockFunctionStatement(
2297 SloppyBlockFunctionStatement* stmt) {
2298 Visit(stmt->statement());
2301void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
2307void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
2313void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
2317 int return_position = stmt->end_position();
2321 if (stmt->is_async_return()) {
2328void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) {
2337bool IsSmiLiteralSwitchCaseValue(Expression* expr) {
2338 if (expr->IsSmiLiteral() ||
2339 (expr->IsLiteral() && expr->AsLiteral()->IsNumber() &&
2340 expr->AsLiteral()->AsNumber() == 0.0)) {
2343 }
else if (expr->IsLiteral() && expr->AsLiteral()->IsNumber()) {
2351inline int ReduceToSmiSwitchCaseValue(Expression* expr) {
2353 return expr->AsLiteral()->AsSmiLiteral().value();
2356 DCHECK(expr->IsLiteral() && expr->AsLiteral()->IsNumber() &&
2357 expr->AsLiteral()->AsNumber() == -0.0);
2363inline bool IsSpreadAcceptable(
int spread,
int ncases) {
2364 return spread <
v8_flags.switch_table_spread_threshold * ncases;
2376 bool CaseExists(
int j) {
2379 bool CaseExists(Expression* expr) {
2380 return IsSmiLiteralSwitchCaseValue(expr)
2381 ? CaseExists(ReduceToSmiSwitchCaseValue(expr))
2386 bool IsDuplicate(CaseClause* clause) {
2387 return IsSmiLiteralSwitchCaseValue(clause->label()) &&
2388 CaseExists(clause->label()) &&
2389 clause != GetClause(ReduceToSmiSwitchCaseValue(clause->label()));
2398 std::cout <<
"Covered_cases: " <<
'\n';
2401 std::cout << iter->first <<
"->" << iter->second <<
'\n';
2408bool IsSwitchOptimizable(SwitchStatement* stmt, SwitchInfo* info) {
2411 for (
int i = 0;
i < cases->
length(); ++
i) {
2412 CaseClause* clause = cases->at(
i);
2413 if (clause->is_default()) {
2415 }
else if (!(clause->label()->IsLiteral())) {
2419 }
else if (IsSmiLiteralSwitchCaseValue(clause->label())) {
2420 int value = ReduceToSmiSwitchCaseValue(clause->label());
2421 info->covered_cases.insert({
value, clause});
2426 if (
static_cast<int>(info->covered_cases.size()) >=
2432 int64_t min =
static_cast<int64_t
>(info->MinCase());
2433 int64_t max =
static_cast<int64_t
>(info->MaxCase());
2434 int64_t spread = max - min + 1;
2439 if (spread <= INT_MAX &&
2440 IsSpreadAcceptable(
static_cast<int>(spread), cases->length())) {
2446 info->covered_cases.clear();
2518void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
2524 BytecodeJumpTable* jump_table =
nullptr;
2525 bool use_jump_table = IsSwitchOptimizable(stmt, &info);
2530 int n_comp_cases = clauses->length();
2531 if (use_jump_table) {
2532 n_comp_cases -=
static_cast<int>(info.covered_cases.size());
2534 info.MaxCase() - info.MinCase() + 1, info.MinCase());
2538 bool use_jumps = n_comp_cases != 0;
2541 bool jump_comparison_needs_hole_check_elision_scope =
false;
2544 n_comp_cases, jump_table);
2545 ControlScopeForBreakable scope(
this, stmt, &switch_builder);
2550 if (use_jump_table) {
2552 RegisterAllocationScope allocation_scope(
this);
2560 switch_builder.JumpToFallThroughIfFalse();
2569 Token::kGreaterThanEq, r1,
2572 switch_builder.JumpToFallThroughIfFalse();
2578 Token::kLessThanEq, r1,
2581 switch_builder.JumpToFallThroughIfFalse();
2590 Token::kEqStrict, r1,
2593 switch_builder.JumpToFallThroughIfFalse();
2596 switch_builder.EmitJumpTableIfExists(info.MinCase(), info.MaxCase(),
2597 info.covered_cases);
2603 jump_comparison_needs_hole_check_elision_scope =
true;
2608 int case_compare_ctr = 0;
2610 std::unordered_map<int, int> case_ctr_checker;
2615 FeedbackSlot slot = clauses->length() > 0
2623 std::optional<HoleCheckElisionScope> elider;
2624 for (
int i = 0;
i < clauses->
length(); ++
i) {
2625 CaseClause* clause = clauses->at(
i);
2626 if (clause->is_default()) {
2627 info.default_case =
i;
2628 }
else if (!info.CaseExists(clause->label())) {
2629 if (jump_comparison_needs_hole_check_elision_scope && !elider) {
2630 elider.emplace(
this);
2638 case_ctr_checker[
i] = case_compare_ctr;
2640 switch_builder.JumpToCaseIfTrue(ToBooleanMode::kAlreadyBoolean,
2641 case_compare_ctr++);
2644 jump_comparison_needs_hole_check_elision_scope =
true;
2653 if (info.DefaultExists()) {
2654 switch_builder.JumpToDefault();
2656 switch_builder.Break();
2661 HoleCheckElisionMergeScope merge_elider(
this);
2663 case_compare_ctr = 0;
2664 for (
int i = 0;
i < clauses->
length(); ++
i) {
2665 CaseClause* clause = clauses->at(
i);
2666 if (
i != info.default_case) {
2667 if (!info.IsDuplicate(clause)) {
2668 bool use_table = use_jump_table && info.CaseExists(clause->label());
2672 DCHECK(case_ctr_checker[
i] == case_compare_ctr);
2674 switch_builder.BindCaseTargetForCompareJump(case_compare_ctr++,
2678 switch_builder.BindCaseTargetForJumpTable(
2679 ReduceToSmiSwitchCaseValue(clause->label()), clause);
2683 switch_builder.BindDefault(clause);
2686 HoleCheckElisionMergeScope::Branch branch_elider(merge_elider);
2690 merge_elider.MergeIf(info.DefaultExists());
2693template <
typename TryBodyFunc,
typename CatchBodyFunc>
2695 TryBodyFunc try_body_func, CatchBodyFunc catch_body_func,
2698 if (
builder()->RemainderOfBlockIsDead())
return;
2713 try_control_builder.
BeginTry(context);
2734 try_control_builder.
EndTry();
2738 catch_body_func(context);
2741 merge_elider.
Merge();
2746template <
typename TryBodyFunc,
typename FinallyBodyFunc>
2748 TryBodyFunc try_body_func, FinallyBodyFunc finally_body_func,
2751 if (
builder()->RemainderOfBlockIsDead())
return;
2789 try_control_builder.
BeginTry(context);
2798 try_control_builder.
EndTry();
2801 if (!
builder()->RemainderOfBlockIsDead()) {
2811 finally_body_func(token,
result, message);
2818template <
typename WrappedFunc>
2820 bool has_await_using) {
2823 if (has_await_using) {
2831 [&]() { wrapped_func(); },
2835 if (has_await_using) {
2837 Register disposable_stack_register =
2840 disposable_stack_register);
2843 LoopScope loop_scope(
this, &loop_builder);
2864 loop_builder.
BreakIfTrue(ToBooleanMode::kConvertToBoolean);
2878 Runtime::kHandleExceptionsInDisposeDisposableStack,
2882 disposable_stack_register);
2927 LoopScope loop_scope(
this, &loop_builder);
2930 LoopScope loop_scope(
this, &loop_builder);
2933 BytecodeLabels loop_backbranch(
zone());
2934 if (!loop_builder.break_labels()->empty()) {
2937 HoleCheckElisionScope elider(
this);
2944 loop_backbranch.Bind(
builder());
2948void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
2952 if (stmt->cond()->ToBooleanIsFalse()) {
2957 LoopScope loop_scope(
this, &loop_builder);
2958 if (!stmt->cond()->ToBooleanIsTrue()) {
2960 BytecodeLabels loop_body(
zone());
2961 VisitForTest(stmt->cond(), &loop_body, loop_builder.break_labels(),
2968void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
2969 if (stmt->init() !=
nullptr) {
2970 Visit(stmt->init());
2975 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) {
2981 LoopScope loop_scope(
this, &loop_builder);
2982 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) {
2984 BytecodeLabels loop_body(
zone());
2985 VisitForTest(stmt->cond(), &loop_body, loop_builder.break_labels(),
3006 HoleCheckElisionScope elider(
this);
3008 if (stmt->next() !=
nullptr) {
3010 Visit(stmt->next());
3014void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
3015 if (stmt->subject()->IsNullLiteral() ||
3016 stmt->subject()->IsUndefinedLiteral()) {
3021 BytecodeLabel subject_undefined_label;
3049 LoopScope loop_scope(
this, &loop_builder);
3050 HoleCheckElisionScope elider(
this);
3052 loop_builder.BreakIfForInDone(index, cache_length);
3055 loop_builder.ContinueIfUndefined();
3059 EffectResultScope scope(
this);
3070 ForInScope scope(
this, stmt, index, cache_type);
3105void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
3106 EffectResultScope effect_scope(
this);
3127 LoopScope loop_scope(
this, &loop_builder);
3135 RegisterAllocationScope allocation_scope(
this);
3146 loop_builder.BreakIfTrue(ToBooleanMode::kConvertToBoolean);
3170 [&](
Register iteration_continuation_token,
3178void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
3188 Visit(stmt->try_block());
3193 if (stmt->scope()) {
3200 if (stmt->ShouldClearException(outer_catch_prediction)) {
3208 if (stmt->scope()) {
3211 VisitBlock(stmt->catch_block());
3217void BytecodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
3220 [&]() {
Visit(stmt->try_block()); },
3227void BytecodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
3232void BytecodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
3234 expr->function_literal_id());
3238 info()->
flags().might_always_turbofan());
3252 literal->ShouldEagerCompile(),
3253 info()->
flags().post_parallel_compile_tasks_for_eager_toplevel());
3257 DCHECK(
info()->character_stream()->can_be_cloned_for_parallel_access());
3266 if (!shared_info->is_compiled()) {
3269 info()->character_stream()->Clone());
3279 size_t class_boilerplate_entry =
3281 class_literals_.push_back(std::make_pair(expr, class_boilerplate_entry));
3299 .
CallRuntime(Runtime::kCreatePrivateBrandSymbol, brand);
3306 AccessorTable<ClassLiteral::Property> private_accessors(
zone());
3309 DCHECK(property->is_private());
3310 switch (property->kind()) {
3320 ->
LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName())
3322 .
CallRuntime(Runtime::kCreatePrivateNameSymbol, private_name);
3340 private_accessors.LookupOrInsert(
key)->getter =
property;
3346 private_accessors.LookupOrInsert(
key)->setter =
property;
3352 Register accessor_storage_private_name =
3354 Variable* accessor_storage_private_name_var =
3355 property->auto_accessor_info()
3356 ->accessor_storage_name_proxy()
3371 ->
LoadLiteral(accessor_storage_private_name_var->raw_name())
3374 accessor_storage_private_name);
3377 auto* accessor_pair = private_accessors.LookupOrInsert(
key);
3394 Register class_constructor_in_args =
3398 args.register_count());
3406 .
MoveRegister(class_constructor, class_constructor_in_args)
3413 if (property->is_computed_name()) {
3418 if (property->is_static()) {
3429 .
JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &done)
3435 DCHECK(!property->is_private());
3444 DCHECK(!property->is_private());
3456 Variable* accessor_storage_private_name_var =
3457 property->auto_accessor_info()
3458 ->accessor_storage_name_proxy()
3461 ->
LoadLiteral(accessor_storage_private_name_var->raw_name())
3463 .
CallRuntime(Runtime::kCreatePrivateNameSymbol, name_register);
3486 if (home_object_variable !=
nullptr) {
3487 DCHECK(home_object_variable->is_used());
3488 DCHECK(home_object_variable->IsContextSlot());
3493 if (static_home_object_variable !=
nullptr) {
3494 DCHECK(static_home_object_variable->is_used());
3495 DCHECK(static_home_object_variable->IsContextSlot());
3503 if (class_variable !=
nullptr && class_variable->is_used()) {
3504 DCHECK(class_variable->IsStackLocal() || class_variable->IsContextSlot());
3513 for (
auto accessors : private_accessors.ordered_accessors()) {
3531 accessor_pair_var =
getter !=
nullptr ?
getter->private_name_var()
3532 :
setter->private_name_var();
3556 if (name.is_valid()) {
3596 std::optional<BytecodeSourceInfo> source_info =
3599 ContextScope scope(
this, expr->
scope());
3614 property->is_auto_accessor());
3617 bool is_literal_store =
3618 property->key()->IsPropertyName() && !property->is_computed_name() &&
3619 !property->is_private() && !property->is_auto_accessor();
3621 if (!is_literal_store) {
3623 if (property->is_auto_accessor()) {
3625 property->auto_accessor_info()->accessor_storage_name_proxy()->var();
3629 }
else if (property->is_computed_name()) {
3631 DCHECK(!property->is_private());
3632 Variable* var = property->computed_name_var();
3638 }
else if (property->is_private()) {
3639 Variable* private_name_var = property->private_name_var();
3650 if (is_literal_store) {
3655 property->key()->AsLiteral()->AsRawPropertyName(),
3659 if (property->NeedsSetFunctionName()) {
3663 if (property->value()->IsClassLiteral() &&
3664 property->value()->AsClassLiteral()->static_initializer() !=
3680void BytecodeGenerator::VisitInitializeClassMembersStatement(
3687void BytecodeGenerator::VisitInitializeClassStaticElementsStatement(
3688 InitializeClassStaticElementsStatement* stmt) {
3689 for (
int i = 0;
i < stmt->elements()->
length();
i++) {
3691 switch (element->kind()) {
3696 VisitBlock(element->static_block());
3702void BytecodeGenerator::VisitAutoAccessorGetterBody(
3703 AutoAccessorGetterBody* stmt) {
3711void BytecodeGenerator::VisitAutoAccessorSetterBody(
3712 AutoAccessorSetterBody* stmt) {
3728 const AstRawString* name = property->key()->AsVariableProxy()->raw_name();
3744 if (class_context) {
3766 .
CallRuntime(Runtime::kAddPrivateBrand, brand_args);
3791void BytecodeGenerator::VisitNativeFunctionLiteral(
3804 ConditionalChainControlFlowBuilder conditional_builder(
3808 HoleCheckElisionMergeScope merge_elider(
this);
3810 bool should_visit_else_expression =
true;
3811 HoleCheckElisionScope elider(
this);
3815 should_visit_else_expression =
false;
3816 HoleCheckElisionMergeScope::Branch branch(merge_elider);
3817 conditional_builder.ThenAt(
i);
3822 HoleCheckElisionMergeScope::Branch branch(merge_elider);
3823 conditional_builder.ElseAt(
i);
3829 HoleCheckElisionMergeScope::Branch branch(merge_elider);
3830 conditional_builder.ThenAt(
i);
3833 conditional_builder.JumpToEnd();
3835 HoleCheckElisionMergeScope::Branch branch(merge_elider);
3836 conditional_builder.ElseAt(
i);
3841 if (should_visit_else_expression) {
3845 merge_elider.Merge();
3848void BytecodeGenerator::VisitConditional(Conditional* expr) {
3849 ConditionalControlFlowBuilder conditional_builder(
3852 if (expr->condition()->ToBooleanIsTrue()) {
3854 conditional_builder.Then();
3856 }
else if (expr->condition()->ToBooleanIsFalse()) {
3858 conditional_builder.Else();
3861 VisitForTest(expr->condition(), conditional_builder.then_labels(),
3864 HoleCheckElisionMergeScope merge_elider(
this);
3865 conditional_builder.Then();
3867 HoleCheckElisionMergeScope::Branch branch_elider(merge_elider);
3870 conditional_builder.JumpToEnd();
3872 conditional_builder.Else();
3874 HoleCheckElisionMergeScope::Branch branch_elider(merge_elider);
3878 merge_elider.Merge();
3882void BytecodeGenerator::VisitLiteral(Literal* expr) {
3884 switch (expr->type()) {
3917void BytecodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
3925 uint8_t flags,
size_t entry) {
3935void BytecodeGenerator::VisitObjectLiteral(
ObjectLiteral* expr) {
3936 expr->
builder()->InitDepthAndFlags();
3940 if (expr->
builder()->IsEmptyObjectLiteral()) {
3947 if (home_object !=
nullptr) {
3951 MultipleEntryBlockContextScope object_literal_context_scope(
3952 this, home_object ? home_object->
scope() :
nullptr);
3956 expr->
builder()->ComputeFlags(),
3957 expr->
builder()->IsFastCloningSupported());
3962 int property_index = 0;
3963 bool clone_object_spread =
3965 if (clone_object_spread) {
3970 RegisterAllocationScope register_scope(
this);
3971 Expression* property = expr->
properties()->first()->value();
3981 if (expr->
builder()->properties_count() == 0) {
3982 entry =
builder()->EmptyObjectBoilerplateDescriptionConstantPoolEntry();
3991 AccessorTable<ObjectLiteral::Property> accessor_table(
zone());
3994 if (property->is_computed_name())
break;
3995 if (!clone_object_spread && property->IsCompileTimeValue())
continue;
3997 RegisterAllocationScope inner_register_scope(
this);
3998 Literal*
key = property->key()->AsLiteral();
3999 switch (property->kind()) {
4004 DCHECK(clone_object_spread || !property->value()->IsCompileTimeValue());
4010 if (
key->IsStringLiteral()) {
4018 object_literal_context_scope.SetEnteredIf(
4019 property->value()->IsConciseMethodDefinition());
4022 if (property->emit_store()) {
4024 if (
key->IsStringLiteral()) {
4041 if (property->IsNullPrototype())
break;
4042 DCHECK(property->emit_store());
4043 DCHECK(!property->NeedsSetFunctionName());
4046 object_literal_context_scope.SetEnteredIf(
false);
4053 if (property->emit_store()) {
4054 accessor_table.LookupOrInsert(
key)->getter =
property;
4058 if (property->emit_store()) {
4059 accessor_table.LookupOrInsert(
key)->setter =
property;
4067 object_literal_context_scope.SetEnteredIf(
true);
4068 for (
auto accessors : accessor_table.ordered_accessors()) {
4069 RegisterAllocationScope inner_register_scope(
this);
4092 RegisterAllocationScope inner_register_scope(
this);
4094 bool should_be_in_object_literal_scope =
4095 (property->value()->IsConciseMethodDefinition() ||
4096 property->value()->IsAccessorFunctionDefinition());
4098 if (property->IsPrototype()) {
4100 if (property->IsNullPrototype())
continue;
4101 DCHECK(property->emit_store());
4102 DCHECK(!property->NeedsSetFunctionName());
4106 DCHECK(!should_be_in_object_literal_scope);
4107 object_literal_context_scope.SetEnteredIf(
false);
4114 switch (property->kind()) {
4120 if (property->is_computed_name()) {
4121 object_literal_context_scope.SetEnteredIf(
false);
4126 object_literal_context_scope.SetEnteredIf(
4127 should_be_in_object_literal_scope);
4132 if (property->NeedsSetFunctionName()) {
4136 if (property->value()->IsClassLiteral() &&
4137 property->value()->AsClassLiteral()->static_initializer() !=
4141 data_property_flags |=
4159 if (property->is_computed_name()) {
4160 object_literal_context_scope.SetEnteredIf(
false);
4166 DCHECK(should_be_in_object_literal_scope);
4167 object_literal_context_scope.SetEnteredIf(
true);
4175 ? Runtime::kDefineGetterPropertyUnchecked
4176 : Runtime::kDefineSetterPropertyUnchecked;
4186 object_literal_context_scope.SetEnteredIf(
false);
4196 if (home_object !=
nullptr) {
4197 object_literal_context_scope.SetEnteredIf(
true);
4203 object_literal_context_scope.SetEnteredIf(
false);
4223 DCHECK(array.is_valid());
4224 DCHECK(index.is_valid());
4225 DCHECK(value.is_valid());
4228 LoopScope loop_scope(
this, &loop_builder);
4237 loop_builder.
BreakIfTrue(ToBooleanMode::kConvertToBoolean);
4266 if (!
is_empty && (*current)->IsSpread()) {
4273 if (++current !=
end) {
4293 if (expr !=
nullptr) {
4294 array_literal_builder = expr->
builder();
4299 int first_spread_index = -1;
4300 for (
auto iter = elements->
begin(); iter != elements->
end(); iter++) {
4301 if ((*iter)->IsSpread()) {
4302 first_spread_index =
static_cast<int>(iter - elements->
begin());
4308 elements, first_spread_index);
4312 DCHECK(array_literal_builder !=
nullptr);
4324 array_literals_.push_back(std::make_pair(array_literal_builder, entry));
4339 int array_index = 0;
4340 for (; current != first_spread_or_end; ++
current, array_index++) {
4342 DCHECK(!subexpr->IsSpread());
4354 if (current !=
end) {
4369 if (subexpr->IsSpread()) {
4382 next_value_load_slot, next_done_load_slot,
4383 real_index_slot, real_element_slot);
4392 if (current + 1 !=
end) {
4413void BytecodeGenerator::VisitArrayLiteral(
ArrayLiteral* expr) {
4414 expr->
builder()->InitDepthAndFlags();
4418void BytecodeGenerator::VisitVariableProxy(
VariableProxy* proxy) {
4449 switch (variable->location()) {
4463 if (variable->IsReceiver()) {
4495 context_reg = context->reg();
4521 switch (variable->mode()) {
4523 Variable* local_variable = variable->local_if_not_shadowed();
4526 ContextKind context_kind = (local_variable->scope()->is_script_scope()
4531 local_variable->index(), depth);
4553 DCHECK(!variable->raw_name()->IsPrivateName());
4569 DCHECK(variable->IsReplGlobal());
4590 Runtime::kTraceExit,
result);
4623 if (!
v8_flags.ignition_elide_redundant_tdz_checks)
return;
4647 if (variable->is_this()) {
4666 op == Token::kInit);
4674 if (variable->is_this()) {
4696 switch (variable->location()) {
4701 if (variable->IsReceiver()) {
4723 op == Token::kInit) {
4724 if (op == Token::kInit) {
4725 if (variable->HasHoleCheckUseInSameClosureScope()) {
4745 }
else if (variable->throw_on_const_assignment(
language_mode()) &&
4748 }
else if (variable->throw_on_const_assignment(
language_mode()) &&
4764 context_reg = context->reg();
4784 if (op == Token::kInit &&
4785 variable->HasHoleCheckUseInSameClosureScope()) {
4791 }
else if (variable->throw_on_const_assignment(
language_mode())) {
4798 lookup_hoisting_mode);
4812 DCHECK(variable->IsExport());
4839 DCHECK(variable->IsReplGlobal());
4840 if (op == Token::kInit) {
4847 Runtime::kStoreGlobalNoHoleCheckForReplLetOrConst, store_args);
4902 if (
v8_flags.enable_enumerated_keyed_access_bytecode &&
4905 if (
key !=
nullptr) {
4907 if (scope !=
nullptr) {
4973 Property* property = lhs->AsProperty();
4977 switch (assign_type) {
4984 property->key()->AsLiteral()->AsRawPropertyName();
4997 DCHECK(!property->IsSuperAccess());
5018 property->obj()->AsSuperPropertyReference()->home_object()->var(),
5022 ->
LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName())
5033 property->obj()->AsSuperPropertyReference()->home_object()->var(),
5066 Register iteration_continuation_token) {
5072 ToBooleanMode::kConvertToBoolean, iterator_is_done.
New());
5107 .
CallRuntime(Runtime::kThrowIteratorResultNotAnObject,
5127 &suppress_close_exception)
5130 .
Bind(&suppress_close_exception);
5149 if ((*target)->IsAssignment()) {
5150 Assignment* default_init = (*target)->AsAssignment();
5152 default_value = default_init->
value();
5153 *target = default_init->
target();
5154 DCHECK((*target)->IsValidReferenceExpression() || (*target)->IsPattern());
5156 return default_value;
5220 Spread* spread =
nullptr;
5222 if (target->IsSpread()) {
5223 spread = target->AsSpread();
5257 .
JumpIfTrue(ToBooleanMode::kConvertToBoolean, is_done.
New());
5260 if (!target->IsTheHoleLiteral()) {
5275 if (default_value) {
5330 next_value_load_slot, next_done_load_slot,
5331 index_slot, element_slot);
5340 [&](
Register iteration_continuation_token,
5379 if (
pattern->builder()->has_rest_property()) {
5380 rest_runtime_callargs =
5382 value = rest_runtime_callargs[0];
5398 if (
pattern->properties()->is_empty() ||
5399 (
pattern->properties()->at(0)->is_computed_name() &&
5404 .
Jump(¬_null_or_undefined);
5423 Expression* pattern_key = pattern_property->key();
5424 Expression* target = pattern_property->value();
5438 value_name = pattern_key->AsLiteral()->AsRawPropertyName();
5440 if (
pattern->builder()->has_rest_property() || !value_name) {
5441 if (
pattern->builder()->has_rest_property()) {
5442 value_key = rest_runtime_callargs[
i + 1];
5446 if (pattern_property->is_computed_name()) {
5459 (
pattern->builder()->has_rest_property() &&
5474 Runtime::kInlineCopyDataPropertiesWithExcludedPropertiesOnStack,
5475 rest_runtime_callargs);
5476 }
else if (value_name) {
5489 if (default_value) {
5513 lhs_data.
expr()->AsObjectLiteral()) {
5516 lookup_hoisting_mode);
5518 lhs_data.
expr()->AsArrayLiteral()) {
5521 lookup_hoisting_mode);
5526 lookup_hoisting_mode);
5566 lhs_data.
expr()->AsProperty());
5573 lhs_data.
expr()->AsProperty());
5601void BytecodeGenerator::VisitAssignment(
Assignment* expr) {
5615 switch (lhs_data.assign_type()) {
5634 lhs_data.super_property_args().Truncate(3));
5639 lhs_data.super_property_args().Truncate(3));
5645 Property* property = lhs_data.expr()->AsProperty();
5654 Property* property = lhs_data.expr()->AsProperty();
5662 Property* property = lhs_data.expr()->AsProperty();
5665 lhs_data.expr()->AsProperty());
5669 Property* property = lhs_data.expr()->AsProperty();
5677 BytecodeLabel short_circuit;
5678 if (binop->op() == Token::kNullish) {
5679 BytecodeLabel nullish;
5682 .
Jump(&short_circuit)
5685 }
else if (binop->op() == Token::kOr) {
5688 }
else if (binop->op() == Token::kAnd) {
5693 binop->op(), expr->
value()->AsLiteral()->AsSmiLiteral(),
5714 if (
builder()->RemainderOfBlockIsDead()) {
5734void BytecodeGenerator::VisitYield(
Yield* expr) {
5748 RegisterAllocationScope register_scope(
this);
5757 RegisterAllocationScope register_scope(
this);
5785 BytecodeJumpTable* jump_table =
5894void BytecodeGenerator::VisitYieldStar(YieldStar* expr) {
5902 RegisterAllocationScope register_scope(
this);
5907 iterator_and_input[0], iterator_type);
5909 Register input = iterator_and_input[1];
5929 LoopScope loop_scope(
this, &loop_builder);
5932 BytecodeLabels after_switch(
zone());
5933 BytecodeJumpTable* switch_jump_table =
5954 const AstRawString* return_string =
5956 BytecodeLabels no_return_method(
zone());
5959 iterator_and_input, after_switch.New(),
5961 no_return_method.Bind(
builder());
5975 const AstRawString* throw_string =
5977 BytecodeLabels no_throw_method(
zone());
5979 iterator_and_input, after_switch.New(),
5984 no_throw_method.Bind(
builder());
5998 BytecodeLabel check_if_done;
6002 .
CallRuntime(Runtime::kThrowIteratorResultNotAnObject, output);
6010 loop_builder.BreakIfTrue(ToBooleanMode::kConvertToBoolean);
6016 RegisterAllocationScope inner_register_scope(
this);
6038 ->
CallRuntime(Runtime::kInlineGeneratorGetResumeMode,
6042 loop_builder.BindContinueTarget();
6048 BytecodeLabel completion_is_output_value;
6056 .
JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &completion_is_output_value)
6078 info()->scope()->is_repl_mode_scope());
6086 await_intrinsic_id = Runtime::kInlineAsyncGeneratorAwait;
6088 await_intrinsic_id = Runtime::kInlineAsyncFunctionAwait;
6110 .
JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &resume_next);
6122void BytecodeGenerator::VisitAwait(
Await* expr) {
6130void BytecodeGenerator::VisitThrow(
Throw* expr) {
6138 if (property->is_optional_chain_link()) {
6149 switch (property_kind) {
6155 property->key()->AsLiteral()->AsRawPropertyName();
6203 Variable* private_name = property->key()->AsVariableProxy()->var();
6217 Variable* private_name = property->key()->AsVariableProxy()->var();
6233 ->
CallRuntime(Runtime::kLoadPrivateGetter, accessor_pair)
6248 ->
CallRuntime(Runtime::kLoadPrivateSetter, accessor_pair)
6259 ClassScope* scope = private_name->scope()->AsClassScope();
6260 if (private_name->is_static()) {
6271 kInvalidUnusedPrivateStaticMethodAccessedByDebugger))
6317 Variable* private_name = property->key()->AsVariableProxy()->var();
6319 ClassScope* scope = private_name->scope()->AsClassScope();
6321 if (private_name->is_static()) {
6338 kInvalidUnusedPrivateStaticMethodAccessedByDebugger))
6349 ToBooleanMode::kAlreadyBoolean, &return_check);
6387 property->obj()->AsSuperPropertyReference()->home_object()->var(),
6390 auto name = property->key()->AsLiteral()->AsRawPropertyName();
6401 property->obj()->AsSuperPropertyReference()->home_object()->var(),
6406 ->
LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName())
6423 property->obj()->AsSuperPropertyReference()->home_object()->var(),
6436template <
typename ExpressionFunc>
6450void BytecodeGenerator::VisitOptionalChain(
OptionalChain* expr) {
6454void BytecodeGenerator::VisitProperty(Property* expr) {
6469 for (
int i = 0; i < static_cast<int>(
args->length());
i++) {
6474void BytecodeGenerator::VisitCall(
Call* expr) {
6505 bool implicit_undefined_receiver =
false;
6513 switch (call_type) {
6517 Property* property = callee_expr->AsProperty();
6525 implicit_undefined_receiver =
true;
6532 VariableProxy* proxy = callee_expr->AsVariableProxy();
6534 proxy->hole_check_mode());
6540 DCHECK(callee_expr->AsVariableProxy()->var()->IsLookupSlot());
6542 RegisterAllocationScope inner_register_scope(
this);
6547 Variable* variable = callee_expr->AsVariableProxy()->var();
6561 implicit_undefined_receiver =
true;
6572 Property* property = callee_expr->AsProperty();
6579 Property* property = callee_expr->AsProperty();
6587 OptionalChain* chain = callee_expr->AsOptionalChain();
6588 Property* property = chain->expression()->AsProperty();
6609 int receiver_arg_count = -1;
6613 DCHECK(!implicit_undefined_receiver);
6624 receiver_arg_count = implicit_undefined_receiver ? 0 : 1;
6626 args.register_count());
6632 RegisterAllocationScope inner_register_scope(
this);
6640 int feedback_slot_index =
6653 if (!scope_with_context->NeedsContext()) {
6654 scope_with_context = scope_with_context->GetOuterScopeWithContext();
6656 if (scope_with_context) {
6657 eval_calls_.emplace_back(expr, scope_with_context);
6671 ->
CallRuntime(Runtime::kResolvePossiblyDirectEval, runtime_call_args)
6678 DCHECK(!implicit_undefined_receiver);
6685 DCHECK(!implicit_undefined_receiver);
6688 }
else if (implicit_undefined_receiver) {
6729 RegisterList construct_args(constructor_then_instance);
6730 const Register& constructor = constructor_then_instance;
6743 &super_ctor_call_done);
6757 const Register& constructor = constructor_then_instance;
6759 &super_ctor_call_done);
6768 feedback_slot_index);
6783 const Register& instance = constructor_then_instance;
6844 bool omit_super_ctor =
v8_flags.omit_default_ctors &&
6847 if (omit_super_ctor) {
6849 super_ctor_call_done);
6869 ToBooleanMode::kAlreadyBoolean, super_ctor_call_done);
6872void BytecodeGenerator::VisitCallNew(
CallNew* expr) {
6920void BytecodeGenerator::VisitSuperCallForwardArgs(SuperCallForwardArgs* expr) {
6921 RegisterAllocationScope register_scope(
this);
6923 SuperCallReference* super = expr->expression();
6930 BytecodeLabel super_ctor_call_done;
6933 const Register& constructor = constructor_then_instance;
6935 &super_ctor_call_done);
6945 const Register& instance = constructor_then_instance;
6953void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) {
6967 if (expr->IsVariableProxy()) {
6996 if (unary_op && unary_op->
op() == Token::kNot) {
7010void BytecodeGenerator::VisitUnaryOperation(
UnaryOperation* expr) {
7011 switch (expr->
op()) {
7015 case Token::kTypeOf:
7021 case Token::kDelete:
7026 case Token::kBitNot:
7039 if (expr->IsProperty()) {
7042 Property* property = expr->AsProperty();
7043 DCHECK(!property->IsPrivateReference());
7044 if (property->IsSuperAccess()) {
7053 }
else if (expr->IsOptionalChain()) {
7054 Expression* expr_inner = expr->AsOptionalChain()->expression();
7055 if (expr_inner->IsProperty()) {
7056 Property* property = expr_inner->AsProperty();
7057 DCHECK(!property->IsPrivateReference());
7061 if (property->is_optional_chain_link()) {
7069 if (property->is_optional_chain_link()) {
7083 }
else if (expr->IsVariableProxy() &&
7084 !expr->AsVariableProxy()->is_new_target()) {
7088 Variable* variable = expr->AsVariableProxy()->var();
7089 switch (variable->location()) {
7111 .
CallRuntime(Runtime::kDeleteLookupSlot, name_reg);
7126void BytecodeGenerator::VisitCountOperation(
CountOperation* expr) {
7139 switch (assign_type) {
7148 name = property->key()->AsLiteral()->AsRawPropertyName();
7166 RegisterList load_super_args = super_property_args.
Truncate(3);
7170 property->obj()->AsSuperPropertyReference()->home_object()->var(),
7174 ->
LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName())
7176 .
CallRuntime(Runtime::kLoadFromSuper, load_super_args);
7181 RegisterList load_super_args = super_property_args.
Truncate(3);
7185 property->obj()->AsSuperPropertyReference()->home_object()->var(),
7244 switch (assign_type) {
7246 VariableProxy* proxy = expr->
expression()->AsVariableProxy();
7248 proxy->hole_check_mode());
7282 .
CallRuntime(Runtime::kStoreToSuper, super_property_args);
7288 .
CallRuntime(Runtime::kStoreKeyedToSuper, super_property_args);
7319void BytecodeGenerator::VisitBinaryOperation(BinaryOperation* binop) {
7320 switch (binop->op()) {
7330 case Token::kNullish:
7339void BytecodeGenerator::VisitNaryOperation(NaryOperation* expr) {
7340 switch (expr->op()) {
7350 case Token::kNullish:
7392 return proxy !=
nullptr && proxy->
is_resolved() &&
7395 TypeHint::kInternalizedString;
7400 return maybe_unary !=
nullptr && maybe_unary->
op() == Token::kTypeOf;
7417 }
else if (expr->
op() == Token::kGreaterThan &&
7423 *flag = TestTypeOfFlags::LiteralFlag::kUndefined;
7428 *sub_expr = expr->
left()->AsUnaryOperation()->expression();
7438 }
else if (expr->
op() == Token::kLessThan &&
7441 *flag = TestTypeOfFlags::LiteralFlag::kUndefined;
7446 *sub_expr = expr->
right()->AsUnaryOperation()->expression();
7462 if (flag == TestTypeOfFlags::LiteralFlag::kOther) {
7468 DCHECK(expr->
op() == Token::kEqStrict);
7487 Variable* var = expr->
left()->AsVariableProxy()->var();
7499 if (expr->
op() == Token::kIn) {
7501 }
else if (expr->
op() == Token::kInstanceOf) {
7529 if (expr->
op() == Token::kAdd &&
7548 expr->
op(), expr->
subsequent(
i)->AsLiteral()->AsSmiLiteral(),
7576void BytecodeGenerator::VisitImportCallExpression(ImportCallExpression* expr) {
7577 const int register_count = expr->import_options() ? 4 : 3;
7587 if (expr->import_options()) {
7633 Runtime::kInlineCreateAsyncFromSyncIterator, sync_iter);
7641 int load_feedback_index =
7643 int call_feedback_index =
7650 obj, load_feedback_index, call_feedback_index);
7691 .
CallRuntime(Runtime::kThrowIteratorResultNotAnObject, next_result)
7735 .
CallRuntime(Runtime::kThrowIteratorResultNotAnObject, return_result);
7761 bool last_part_valid =
false;
7764 for (
int i = 0;
i < substitutions.
length(); ++
i) {
7767 last_part_valid =
true;
7770 if (!parts[
i]->IsEmpty()) {
7772 if (last_part_valid) {
7777 last_part_valid =
true;
7784 if (last_part_valid) {
7787 last_part_valid =
false;
7790 if (!parts.
last()->IsEmpty()) {
7808void BytecodeGenerator::VisitThisExpression(
ThisExpression* expr) {
7817void BytecodeGenerator::VisitSuperPropertyReference(
7818 SuperPropertyReference* expr) {
7846 DCHECK(token == Token::kOr || token == Token::kAnd ||
7847 token == Token::kNullish);
7850 if (token == Token::kOr) {
7852 }
else if (token == Token::kAnd) {
7865 int right_coverage_slot) {
7866 DCHECK(token == Token::kOr || token == Token::kAnd ||
7867 token == Token::kNullish);
7874 right_coverage_slot);
7877 VisitForTest(right, then_labels, else_labels, fallthrough);
7883 DCHECK(token == Token::kOr || token == Token::kAnd ||
7884 token == Token::kNullish);
7902 else_labels, fallthrough);
7907 int coverage_slot) {
7925 int coverage_slot) {
7943 int coverage_slot) {
7966 int right_coverage_slot =
7998 if (first->ToBooleanIsTrue()) {
8029 int right_coverage_slot =
8061 if (first->ToBooleanIsFalse()) {
8091 int right_coverage_slot =
8099 right->IsNullOrUndefinedLiteral()) {
8124 if (first->IsLiteralButNotNullOrUndefined() && first->ToBooleanIsTrue()) {
8172 Runtime::kNewFunctionContext, arg);
8191 for (
int i = 0;
i < num_parameters;
i++) {
8193 if (!variable->IsContextSlot())
continue;
8233 if (property ==
nullptr) {
8241 if (variable ==
nullptr)
return;
8243 DCHECK(variable->IsContextSlot() || variable->IsStackAllocated());
8252 if (rest ==
nullptr)
return;
8257 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated());
8262 if (variable ==
nullptr)
return;
8270 if (variable ==
nullptr)
return;
8300 ? Runtime::kInlineAsyncFunctionEnter
8301 : Runtime::kInlineCreateJSGeneratorObject;
8327 if (property->key()->IsStringLiteral()) {
8329 ->
LoadLiteral(property->key()->AsLiteral()->AsRawString())
8368 int coverage_array_slot) {
8382 if (optimizer && type_hint != TypeHint::kUnknown) {
8389 if (expr ==
nullptr) {
8440 switch (fallthrough) {
8460 bool result_consumed;
8466 TestResultScope test_result(
this, then_labels, else_labels, fallthrough);
8476 if (!result_consumed) {
8495 if (mode != ToBooleanMode::kAlreadyBoolean) {
8523template <
typename T>
8548 return TypeHint::kAny;
8612 DCHECK(!expr->IsSuperPropertyReference());
8613 if (!
v8_flags.ignition_share_named_property_feedback) {
8618 if (!expr->IsVariableProxy()) {
8635 if (!
v8_flags.ignition_share_named_property_feedback) {
8652 if (!
v8_flags.ignition_share_named_property_feedback) {
8658 if (!expr->IsVariableProxy()) {
RegisterAllocator * allocator_
union v8::internal::@341::BuiltinMetadata::KindSpecificData data
std::vector< std::pair< Literal *, Accessors< PropertyT > * > > ordered_accessors_
std::map< int, CaseClause * > covered_cases
static const int kDefaultNotFound
#define SBXCHECK(condition)
virtual Local< FunctionTemplate > GetNativeFunctionTemplate(Isolate *isolate, Local< String > name)
static v8::internal::DirectHandle< To > OpenDirectHandle(v8::Local< From > handle)
V8_INLINE int NextInt() V8_WARN_UNUSED_RESULT
int first_spread_index() const
bool IsFastCloningSupported() const
int ComputeFlags(bool disable_mementos=false) const
Handle< ArrayBoilerplateDescription > GetOrBuildBoilerplateDescription(IsolateT *isolate)
const ArrayLiteralBoilerplateBuilder * builder() const
const ZonePtrList< Expression > * values() const
Expression * target() const
Expression * value() const
LookupHoistingMode lookup_hoisting_mode() const
uint16_t FirstCharacter() const
void Visit(AstNode *node)
FunctionLiteral * generated_getter() const
FunctionLiteral * generated_setter() const
VariableProxy * property_private_name_proxy() const
Expression * right() const
Expression * left() const
bool IsSmiLiteralOperation(Expression **subexpr, Tagged< Smi > *literal)
SpreadPosition spread_position() const
const ZonePtrList< Expression > * arguments() const
Expression * expression() const
bool is_optional_chain_link() const
bool is_possibly_eval() const
CallType GetCallType() const
@ PRIVATE_OPTIONAL_CHAIN_CALL
@ KEYED_OPTIONAL_CHAIN_PROPERTY_CALL
@ NAMED_SUPER_PROPERTY_CALL
@ KEYED_SUPER_PROPERTY_CALL
@ NAMED_OPTIONAL_CHAIN_PROPERTY_CALL
uint32_t eval_scope_info_index() const
static Handle< ClassBoilerplate > New(IsolateT *isolate, ClassLiteral *expr, AllocationType allocation=AllocationType::kYoung)
@ kFirstDynamicArgumentIndex
Variable * static_home_object() const
ZonePtrList< Property > * public_members() const
FunctionLiteral * instance_members_initializer_function() const
ZonePtrList< Property > * private_members() const
Variable * home_object() const
ClassScope * scope() const
Expression * extends() const
FunctionLiteral * static_initializer() const
FunctionLiteral * constructor() const
ClassLiteralStaticElement StaticElement
Variable * class_variable()
bool IsLiteralCompareEqualVariable(Expression **expr, Literal **literal)
Expression * left() const
bool IsLiteralStrictCompareBoolean(Expression **expr, Literal **literal)
bool IsLiteralCompareUndefined(Expression **expr)
bool IsLiteralCompareNull(Expression **expr)
Expression * right() const
static DirectHandle< SharedFunctionInfo > GetSharedFunctionInfo(FunctionLiteral *node, DirectHandle< Script > script, IsolateT *isolate)
BinaryOperation * binary_operation() const
Expression * else_expression() const
Expression * condition_at(size_t index) const
size_t conditional_chain_length() const
Expression * then_expression_at(size_t index) const
static int MaximumFunctionContextSlots()
Expression * expression() const
FunctionKind function_kind() const
bool class_scope_has_private_brand() const
Variable * new_target_var()
Variable * LookupInModule(const AstRawString *name)
Variable * parameter(int index) const
int num_parameters() const
Variable * generator_object_var() const
bool has_this_declaration() const
Variable * rest_parameter() const
V8_INLINE bool is_null() const
Expression * cond() const
Expression * expression() const
bool ToBooleanIsFalse() const
bool IsValidReferenceExpression() const
bool IsPrivateName() const
bool IsNullOrUndefinedLiteral() const
bool IsCompileTimeValue()
V8_EXPORT_PRIVATE bool IsNumberLiteral() const
bool IsStringLiteral() const
bool ToBooleanIsTrue() const
bool IsTheHoleLiteral() const
bool IsLiteralButNotNullOrUndefined() const
bool IsSmiLiteral() const
bool IsPropertyName() const
static FeedbackSlot Invalid()
FeedbackSlot AddDefineKeyedOwnPropertyInLiteralICSlot()
FeedbackSlot AddStoreInArrayLiteralICSlot()
FeedbackSlot AddCallICSlot()
FeedbackSlot AddForInSlot()
FeedbackSlot AddInstanceOfSlot()
FeedbackSlot AddLoadICSlot()
FeedbackSlot AddKeyedStoreICSlot(LanguageMode language_mode)
FeedbackSlot AddCompareICSlot()
FeedbackSlot AddLiteralSlot()
FeedbackSlot AddStoreICSlot(LanguageMode language_mode)
FeedbackSlot AddBinaryOpICSlot()
FeedbackSlot AddLoadGlobalICSlot(TypeofMode typeof_mode)
int AddCreateClosureParameterCount(uint16_t parameter_count)
FeedbackSlot AddStoreGlobalICSlot(LanguageMode language_mode)
FeedbackSlot AddKeyedHasICSlot()
FeedbackSlot AddDefineKeyedOwnICSlot()
FeedbackSlot AddDefineNamedOwnICSlot()
FeedbackSlot AddKeyedLoadICSlot()
static int GetIndex(FeedbackSlot slot)
FunctionLiteral * fun() const
FunctionKind kind() const
int function_literal_id() const
ZonePtrList< Statement > * body()
static Handle< SharedFunctionInfo > GetOrCreateSharedFunctionInfo(Isolate *isolate, DirectHandle< FunctionTemplateInfo > info, MaybeDirectHandle< Name > maybe_name)
Handle< TemplateObjectDescription > GetOrBuildDescription(IsolateT *isolate)
V8_INLINE bool is_null() const
Bootstrapper * bootstrapper()
void Enqueue(LocalIsolate *isolate, Handle< SharedFunctionInfo > shared_info, std::unique_ptr< Utf16CharacterStream > character_stream)
static bool Match(void *literal1, void *literal2)
const AstRawString * AsRawString()
base::RandomNumberGenerator * fuzzer_rng() const
bool is_main_thread() const
SourceTextModuleDescriptor * module() const
Expression * subsequent(size_t index) const
int subsequent_op_position(size_t index) const
size_t subsequent_length() const
Expression * first() const
v8::Extension * extension() const
DirectHandle< String > name() const
int properties_count() const
Handle< ObjectBoilerplateDescription > GetOrBuildBoilerplateDescription(IsolateT *isolate)
const ObjectLiteralBoilerplateBuilder * builder() const
ObjectLiteralProperty Property
ZoneList< Property * > * properties()
Variable * home_object() const
Expression * expression() const
static AssignType GetAssignType(Property *property)
static constexpr int kFunctionLiteralReturnPosition
int num_heap_slots() const
base::ThreadedList< Declaration > * declarations()
Variable * catch_variable() const
Scope * outer_scope() const
int ContextChainLength(Scope *scope) const
ClassScope * AsClassScope()
bool is_script_scope() const
ModuleScope * AsModuleScope()
DeclarationScope * GetReceiverScope()
bool is_class_scope() const
bool is_eval_scope() const
bool is_function_scope() const
ScopeType scope_type() const
bool has_await_using_declaration() const
bool NeedsContext() const
bool is_block_scope() const
int ContextChainLengthUntilOutermostSloppyEval() const
LanguageMode language_mode() const
DeclarationScope * GetConstructorScope()
int start_position() const
bool is_module_scope() const
static constexpr Tagged< Smi > FromEnum(E value)
static constexpr Tagged< Smi > FromInt(int value)
static constexpr int kMinValue
static constexpr Tagged< Smi > zero()
static constexpr int kMaxValue
const ZoneVector< const Entry * > & namespace_imports() const
Expression * expression() const
VariableProxy * new_target_var() const
VariableProxy * this_function_var() const
Expression * expression() const
OnAbruptResume on_abrupt_resume() const
const ZonePtrList< const AstRawString > * string_parts() const
const ZonePtrList< Expression > * substitutions() const
static ThreadId Current()
Expression * exception() const
static bool IsEqualityOp(Value op)
Expression * expression() const
FunctionLiteral * literal() const
void set_coverage_info(Handle< CoverageInfo > coverage_info)
FeedbackVectorSpec * feedback_vector_spec()
Handle< BytecodeArray > bytecode_array() const
LazyCompileDispatcher * dispatcher()
DeclarationScope * scope() const
HoleCheckMode hole_check_mode() const
bool IsStackLocal() const
const AstRawString * raw_name() const
bool IsContextSlot() const
V8_INLINE int length() const
V8_INLINE bool is_empty() const
const ZoneVector< SourceRange > & slots() const
void IncrementBlockCounter(int coverage_array_slot)
static constexpr int kNoCoverageArraySlot
int AllocateNaryBlockCoverageSlot(NaryOperation *node, size_t index)
int AllocateConditionalChainBlockCoverageSlot(ConditionalChain *node, SourceRangeKind kind, size_t index)
int AllocateBlockCoverageSlot(ZoneObject *node, SourceRangeKind kind)
void BreakIfTrue(BytecodeArrayBuilder::ToBooleanMode mode)
BytecodeArrayBuilder & LoadLookupSlot(const AstRawString *name, TypeofMode typeof_mode)
BytecodeArrayBuilder & ThrowIfNotSuperConstructor(Register constructor)
BytecodeArrayBuilder & UnaryOperation(Token::Value op, int feedback_slot)
BytecodeArrayBuilder & ForInStep(Register index)
BytecodeArrayBuilder & StoreInArrayLiteral(Register array, Register index, int feedback_slot)
BytecodeArrayBuilder & CreateEmptyObjectLiteral()
BytecodeArrayBuilder & CallJSRuntime(int context_index, RegisterList args)
BytecodeArrayBuilder & SetNamedProperty(Register object, const AstRawString *name, int feedback_slot, LanguageMode language_mode)
BytecodeArrayBuilder & TypeOf(int feedback_slot)
BytecodeArrayBuilder & ForInNext(Register receiver, Register index, RegisterList cache_type_array_pair, int feedback_slot)
BytecodeArrayBuilder & ReThrow()
BytecodeArrayBuilder & CallAnyReceiver(Register callable, RegisterList args, int feedback_slot)
BytecodeArrayBuilder & CreateCatchContext(Register exception, const Scope *scope)
BytecodeArrayBuilder & LoadIteratorProperty(Register object, int feedback_slot)
BytecodeArrayBuilder & GetTemplateObject(size_t template_object_description_entry, int feedback_slot)
BytecodeArrayBuilder & LoadAsyncIteratorProperty(Register object, int feedback_slot)
BytecodeArrayBuilder & ForInPrepare(RegisterList cache_info_triple, int feedback_slot)
BytecodeArrayBuilder & LoadClassFieldsInitializer(Register constructor, int feedback_slot)
BytecodeArrayBuilder & CreateBlockContext(const Scope *scope)
BytecodeArrayBuilder & LoadTheHole()
BytecodeArrayBuilder & Delete(Register object, LanguageMode language_mode)
BytecodeArrayBuilder & StoreContextSlot(Register context, Variable *variable, int depth)
BytecodeArrayBuilder & ToBoolean(ToBooleanMode mode)
BytecodeArrayBuilder & LoadGlobal(const AstRawString *name, int feedback_slot, TypeofMode typeof_mode)
BytecodeArrayBuilder & CallUndefinedReceiver(Register callable, RegisterList args, int feedback_slot)
BytecodeArrayBuilder & LoadModuleVariable(int cell_index, int depth)
BytecodeArrayBuilder & ToObject(Register out)
BytecodeArrayBuilder & SuspendGenerator(Register generator, RegisterList registers, int suspend_id)
BytecodeArrayBuilder & CreateClosure(size_t shared_function_info_entry, int slot, int flags)
BytecodeArrayBuilder & GetIterator(Register object, int load_feedback_slot, int call_feedback_slot)
BytecodeArrayBuilder & JumpIfNotNil(BytecodeLabel *label, Token::Value op, NilValue nil)
void SetExpressionPosition(Expression *expr)
Register Local(int index) const
BytecodeArrayBuilder & LoadContextSlot(Register context, Variable *variable, int depth, ContextSlotMutability immutable)
void PushSourcePosition(BytecodeSourceInfo source_info)
BytecodeArrayBuilder & ThrowSuperNotCalledIfHole()
void UpdateMaxArguments(uint16_t max_arguments)
BytecodeArrayBuilder & ThrowSuperAlreadyCalledIfNotHole()
BytecodeArrayBuilder & DefineKeyedOwnPropertyInLiteral(Register object, Register name, DefineKeyedOwnPropertyInLiteralFlags flags, int feedback_slot)
BytecodeArrayBuilder & LoadUndefined()
BytecodeArrayBuilder & CompareNil(Token::Value op, NilValue nil)
BytecodeJumpTable * AllocateJumpTable(int size, int case_value_base)
BytecodeArrayBuilder & ToNumeric(int feedback_slot)
BytecodeArrayBuilder & LoadLiteral(Tagged< Smi > value)
BytecodeArrayBuilder & StoreAccumulatorInRegister(Register reg)
BytecodeRegisterOptimizer * GetRegisterOptimizer()
BytecodeArrayBuilder & LogicalNot(ToBooleanMode mode)
BytecodeArrayBuilder & Return()
BytecodeArrayBuilder & CreateRegExpLiteral(const AstRawString *pattern, int literal_index, int flags)
BytecodeArrayBuilder & CompareReference(Register reg)
Register Receiver() const
BytecodeArrayBuilder & LoadTrue()
BytecodeArrayBuilder & LoadNamedProperty(Register object, const AstRawString *name, int feedback_slot)
BytecodeArrayBuilder & JumpIfFalse(ToBooleanMode mode, BytecodeLabel *label)
BytecodeArrayBuilder & ResumeGenerator(Register generator, RegisterList registers)
BytecodeArrayBuilder & Bind(BytecodeLabel *label)
BytecodeArrayBuilder & JumpIfUndefined(BytecodeLabel *label)
void EmitFunctionStartSourcePosition(int position)
BytecodeArrayBuilder & SwitchOnSmiNoFeedback(BytecodeJumpTable *jump_table)
BytecodeArrayBuilder & JumpIfTrue(ToBooleanMode mode, BytecodeLabel *label)
BytecodeArrayBuilder & CallRuntimeForPair(Runtime::FunctionId function_id, RegisterList args, RegisterList return_pair)
BytecodeArrayBuilder & CompareOperation(Token::Value op, Register reg, int feedback_slot)
BytecodeArrayBuilder & SetPendingMessage()
BytecodeArrayBuilder & ForInEnumerate(Register receiver)
BytecodeArrayBuilder & CreateEvalContext(const Scope *scope, int slots)
Register Parameter(int parameter_index) const
BytecodeArrayBuilder & LoadNull()
BytecodeArrayBuilder & FindNonDefaultConstructorOrConstruct(Register this_function, Register new_target, RegisterList output)
BytecodeArrayBuilder & LoadKeyedProperty(Register object, int feedback_slot)
BytecodeArrayBuilder & CreateFunctionContext(const Scope *scope, int slots)
BytecodeArrayBuilder & ThrowReferenceErrorIfHole(const AstRawString *name)
BytecodeArrayBuilder & CloneObject(Register source, int flags, int feedback_slot)
BytecodeArrayBuilder & LoadLookupContextSlot(const AstRawString *name, TypeofMode typeof_mode, ContextKind context_kind, int slot_index, int depth)
BytecodeArrayBuilder & MoveRegister(Register from, Register to)
BytecodeArrayBuilder & BinaryOperationSmiLiteral(Token::Value binop, Tagged< Smi > literal, int feedback_slot)
std::optional< BytecodeSourceInfo > MaybePopSourcePosition(int scope_start)
BytecodeArrayBuilder & JumpIfNotUndefined(BytecodeLabel *label)
size_t AllocateDeferredConstantPoolEntry()
BytecodeArrayBuilder & StoreClassFieldsInitializer(Register constructor, int feedback_slot)
BytecodeArrayBuilder & CreateEmptyArrayLiteral(int literal_index)
BytecodeArrayBuilder & StoreLookupSlot(const AstRawString *name, LanguageMode language_mode, LookupHoistingMode lookup_hoisting_mode)
BytecodeArrayBuilder & CreateArrayFromIterable()
BytecodeArrayBuilder & StoreModuleVariable(int cell_index, int depth)
BytecodeArrayBuilder & ConstructForwardAllArgs(Register constructor, int feedback_slot)
BytecodeArrayBuilder & ToName()
BytecodeArrayBuilder & SwitchOnGeneratorState(Register generator, BytecodeJumpTable *jump_table)
BytecodeArrayBuilder & CallWithSpread(Register callable, RegisterList args, int feedback_slot)
BytecodeArrayBuilder & GetSuperConstructor(Register out)
BytecodeArrayBuilder & ConstructWithSpread(Register constructor, RegisterList args, int feedback_slot)
BytecodeArrayBuilder & LoadEnumeratedKeyedProperty(Register object, Register enum_index, Register cache_type, int feedback_slot)
BytecodeArrayBuilder & DefineNamedOwnProperty(Register object, const AstRawString *name, int feedback_slot)
BytecodeArrayBuilder & LoadFalse()
BytecodeArrayBuilder & BinaryOperation(Token::Value binop, Register reg, int feedback_slot)
BytecodeArrayBuilder & LoadBoolean(bool value)
BytecodeArrayBuilder & StoreGlobal(const AstRawString *name, int feedback_slot)
BytecodeArrayBuilder & SetKeyedProperty(Register object, Register key, int feedback_slot, LanguageMode language_mode)
DirectHandle< TrustedByteArray > ToSourcePositionTable(IsolateT *isolate)
BytecodeArrayBuilder & CreateObjectLiteral(size_t constant_properties_entry, int literal_index, int flags)
void SetExpressionAsStatementPosition(Expression *expr)
BytecodeArrayBuilder & LoadAccumulatorWithRegister(Register reg)
BytecodeArrayBuilder & Jump(BytecodeLabel *label)
BytecodeArrayBuilder & CallProperty(Register callable, RegisterList args, int feedback_slot)
Handle< BytecodeArray > ToBytecodeArray(IsolateT *isolate)
BytecodeArrayBuilder & LoadLookupGlobalSlot(const AstRawString *name, TypeofMode typeof_mode, int feedback_slot, int depth)
BytecodeArrayBuilder & DefineKeyedOwnProperty(Register object, Register key, DefineKeyedOwnPropertyFlags flags, int feedback_slot)
BytecodeArrayBuilder & ToString()
BytecodeArrayBuilder & LoadConstantPoolEntry(size_t entry)
BytecodeArrayBuilder & Throw()
BytecodeArrayBuilder & CreateWithContext(Register object, const Scope *scope)
BytecodeArrayBuilder & Construct(Register constructor, RegisterList args, int feedback_slot)
BytecodeArrayBuilder & CreateArguments(CreateArgumentsType type)
BytecodeArrayBuilder & JumpIfJSReceiver(BytecodeLabel *label)
BytecodeArrayBuilder & Debugger()
BytecodeArrayBuilder & LoadNamedPropertyFromSuper(Register object, const AstRawString *name, int feedback_slot)
BytecodeArrayBuilder & JumpIfUndefinedOrNull(BytecodeLabel *label)
BytecodeArrayBuilder & CompareTypeOf(TestTypeOfFlags::LiteralFlag literal_flag)
BytecodeArrayBuilder & CreateArrayLiteral(size_t constant_elements_entry, int literal_index, int flags)
BytecodeArrayBuilder & JumpIfNil(BytecodeLabel *label, Token::Value op, NilValue nil)
void SetDeferredConstantPoolEntry(size_t entry, Handle< Object > object)
BytecodeArrayBuilder & CallRuntime(Runtime::FunctionId function_id, RegisterList args)
void SetStatementPosition(Statement *stmt)
AccumulatorPreservingScope(const AccumulatorPreservingScope &)=delete
Register saved_accumulator_register_
~AccumulatorPreservingScope()
AccumulatorPreservingScope & operator=(const AccumulatorPreservingScope &)=delete
AccumulatorPreservingScope(BytecodeGenerator *generator, AccumulatorPreservingMode mode)
BytecodeGenerator * generator_
Expression * object_expr() const
AssignmentLhsData(AssignType assign_type, Expression *expr, RegisterList super_property_args, Register object, Register key, Expression *object_expr, const AstRawString *name)
static AssignmentLhsData PrivateMethodOrAccessor(AssignType type, Property *property, Register object, Register key)
AssignType assign_type() const
static AssignmentLhsData NamedProperty(Expression *object_expr, Register object, const AstRawString *name)
Expression * expr() const
static AssignmentLhsData PrivateDebugEvaluate(AssignType type, Property *property, Register object)
RegisterList super_property_args() const
static AssignmentLhsData NonProperty(Expression *expr)
static AssignmentLhsData KeyedSuperProperty(RegisterList super_property_args)
const AstRawString * name() const
static AssignmentLhsData NamedSuperProperty(RegisterList super_property_args)
static AssignmentLhsData KeyedProperty(Register object, Register key)
BytecodeGenerator * generator_
ContextScope(BytecodeGenerator *generator, Scope *scope, Register outer_context_reg=Register())
const BytecodeArrayBuilder * builder() const
void set_register(Register reg)
int ContextChainDepth(Scope *scope)
ContextScope * Previous(int depth)
ContextScope & operator=(const ContextScope &)=delete
ContextScope(const ContextScope &)=delete
ControlScopeForBreakable(BytecodeGenerator *generator, BreakableStatement *statement, BreakableControlFlowBuilder *control_builder)
bool Execute(Command command, Statement *statement, int source_position) override
BreakableControlFlowBuilder * control_builder_
Register result_register_
ControlScopeForDerivedConstructor(BytecodeGenerator *generator, Register result_register, BytecodeLabels *check_return_value_labels)
bool Execute(Command command, Statement *statement, int source_position) override
BytecodeLabels * check_return_value_labels_
LoopBuilder * loop_builder_
ControlScopeForIteration(BytecodeGenerator *generator, IterationStatement *statement, LoopBuilder *loop_builder)
bool Execute(Command command, Statement *statement, int source_position) override
ControlScopeForTopLevel(BytecodeGenerator *generator)
bool Execute(Command command, Statement *statement, int source_position) override
ControlScopeForTryCatch(BytecodeGenerator *generator, TryCatchBuilder *try_catch_builder)
bool Execute(Command command, Statement *statement, int source_position) override
DeferredCommands * commands_
TryFinallyBuilder * try_finally_builder_
ControlScopeForTryFinally(BytecodeGenerator *generator, TryFinallyBuilder *try_finally_builder, DeferredCommands *commands)
bool Execute(Command command, Statement *statement, int source_position) override
void RecordHandlerReThrowPath()
int GetAsyncReturnToken()
bool fallthrough_from_try_block_needed_
void ApplyDeferredCommand(const Entry &entry)
int GetNewTokenForCommand(Command command, Statement *statement)
ControlScope * execution_control()
void RecordCommand(Command command, Statement *statement)
void RecordFallThroughPath()
BytecodeArrayBuilder * builder()
ZoneVector< Entry > deferred_
int GetTokenForCommand(Command command, Statement *statement)
BytecodeGenerator * generator_
DeferredCommands(BytecodeGenerator *generator, Register token_register, Register result_register, Register message_register)
void ApplyDeferredCommands()
Register result_register_
Register message_register_
void PerformCommand(Command command, Statement *statement, int source_position)
ControlScope * outer() const
BytecodeGenerator * generator() const
virtual bool Execute(Command command, Statement *statement, int source_position)=0
ContextScope * context() const
void Continue(Statement *stmt)
ControlScope(BytecodeGenerator *generator)
void PopContextToExpectedDepth()
static constexpr bool CommandUsesAccumulator(Command command)
void ReturnAccumulator(int source_position)
void Break(Statement *stmt)
ControlScope(const ControlScope &)=delete
ControlScope & operator=(const ControlScope &)=delete
void AsyncReturnAccumulator(int source_position)
BytecodeGenerator * generator_
CurrentScope(const CurrentScope &)=delete
CurrentScope(BytecodeGenerator *generator, Scope *scope)
CurrentScope & operator=(const CurrentScope &)=delete
BytecodeGenerator * generator_
BytecodeGenerator *const bytecode_generator_
Register prev_disposables_stack_
DisposablesStackScope(BytecodeGenerator *bytecode_generator)
EffectResultScope(BytecodeGenerator *generator)
RegisterAllocationScope allocator_
Expression::Context kind_
ExpressionResultScope(BytecodeGenerator *generator, Expression::Context kind)
TestResultScope * AsTest()
ExpressionResultScope & operator=(const ExpressionResultScope &)=delete
void SetResultIsBoolean()
TypeHint type_hint() const
ExpressionResultScope(const ExpressionResultScope &)=delete
void SetResultIsInternalizedString()
ExpressionResultScope * outer_
int Get(SlotKind slot_kind, const AstRawString *name) const
void Put(SlotKind slot_kind, const AstRawString *name, int slot_index)
void Put(SlotKind slot_kind, Variable *variable, int slot_index)
int Get(SlotKind slot_kind, AstNode *node) const
int Get(SlotKind slot_kind, Variable *variable) const
FeedbackSlotCache(Zone *zone)
@ kLoadGlobalNotInsideTypeof
@ kLoadGlobalInsideTypeof
int Get(SlotKind slot_kind, int variable_index, const AstRawString *name) const
std::tuple< SlotKind, int, const void * > Key
void Put(SlotKind slot_kind, int variable_index, const AstRawString *name, int slot_index)
int GetImpl(SlotKind slot_kind, int index, const void *node) const
void PutImpl(SlotKind slot_kind, int index, const void *node, int slot_index)
void Put(SlotKind slot_kind, AstNode *node, int slot_index)
ForInScope *const parent_for_in_scope_
BytecodeGenerator *const bytecode_generator_
ForInScope * GetForInScope(Variable *each)
ForInScope(BytecodeGenerator *bytecode_generator, ForInStatement *stmt, Register enum_index, Register cache_type)
Branch(HoleCheckElisionMergeScope &merge_into)
Variable::HoleCheckBitmap * merge_into_bitmap_
Variable::HoleCheckBitmap * bitmap_
~HoleCheckElisionMergeScope()
HoleCheckElisionMergeScope(BytecodeGenerator *bytecode_generator)
HoleCheckElisionScope(Variable::HoleCheckBitmap *bitmap)
Variable::HoleCheckBitmap prev_bitmap_value_
Variable::HoleCheckBitmap * bitmap_
HoleCheckElisionScope(BytecodeGenerator *bytecode_generator)
IteratorRecord(Register object_register, Register next_register, IteratorType type=IteratorType::kNormal)
IteratorType type() const
LoopScope *const parent_loop_scope_
LoopScope(BytecodeGenerator *bytecode_generator, LoopBuilder *loop)
LoopBuilder *const loop_builder_
BytecodeGenerator *const bytecode_generator_
MultipleEntryBlockContextScope(const MultipleEntryBlockContextScope &)=delete
std::optional< ContextScope > context_scope_
void SetEnteredIf(bool condition)
MultipleEntryBlockContextScope & operator=(const MultipleEntryBlockContextScope &)=delete
BytecodeGenerator * generator_
std::optional< CurrentScope > current_scope_
MultipleEntryBlockContextScope(BytecodeGenerator *generator, Scope *scope)
~MultipleEntryBlockContextScope()
int GetSlotFor(size_t subsequent_expr_index) const
std::vector< int > coverage_slots_
NaryCodeCoverageSlots(BytecodeGenerator *generator, NaryOperation *expr)
BytecodeGenerator * generator_
~OptionalChainNullLabelScope()
OptionalChainNullLabelScope(BytecodeGenerator *bytecode_generator)
BytecodeGenerator * bytecode_generator_
BytecodeLabels * labels()
~RegisterAllocationScope()
RegisterAllocationScope & operator=(const RegisterAllocationScope &)=delete
RegisterAllocationScope(const RegisterAllocationScope &)=delete
BytecodeGenerator * generator_
int outer_next_register_index_
RegisterAllocationScope(BytecodeGenerator *generator)
BytecodeGenerator * generator() const
BytecodeLabels * else_labels_
TestResultScope(BytecodeGenerator *generator, BytecodeLabels *then_labels, BytecodeLabels *else_labels, TestFallthrough fallthrough)
void SetResultConsumedByTest()
BytecodeLabel * NewThenLabel()
BytecodeLabels * then_labels_
TestFallthrough fallthrough() const
void set_fallthrough(TestFallthrough fallthrough)
void set_else_labels(BytecodeLabels *else_labels)
bool result_consumed_by_test_
TestResultScope(const TestResultScope &)=delete
void set_then_labels(BytecodeLabels *then_labels)
TestResultScope & operator=(const TestResultScope &)=delete
bool result_consumed_by_test()
TestFallthrough fallthrough_
TestFallthrough inverted_fallthrough() const
BytecodeLabels * else_labels() const
BytecodeLabel * NewElseLabel()
BytecodeLabels * then_labels() const
size_t constant_pool_entry()
bool has_top_level_declaration()
void record_module_function_declaration()
void set_constant_pool_entry(size_t constant_pool_entry)
void record_global_function_declaration()
void record_module_variable_declaration()
Handle< FixedArray > AllocateDeclarations(UnoptimizedCompilationInfo *info, BytecodeGenerator *generator, Handle< Script > script, IsolateT *isolate)
void record_global_variable_declaration()
ValueResultScope(BytecodeGenerator *generator)
SharedFeedbackSlot dummy_feedback_slot_
void BuildAsyncReturn(int source_position)
void VisitNot(UnaryOperation *expr)
void GenerateDerivedConstructorBody()
ForInScope * current_for_in_scope() const
void BuildVariableLoadForAccumulatorValue(Variable *variable, HoleCheckMode hole_check_mode, TypeofMode typeof_mode=TypeofMode::kNotInside)
void SetVariableInRegister(Variable *var, Register reg)
void VisitCommaExpression(BinaryOperation *binop)
void BuildHoleCheckForVariableAssignment(Variable *variable, Token::Value op)
void BuildFillArrayWithIterator(IteratorRecord iterator, Register array, Register index, Register value, FeedbackSlot next_value_slot, FeedbackSlot next_done_slot, FeedbackSlot index_slot, FeedbackSlot element_slot)
void VisitBlockMaybeDispose(Block *stmt)
UnoptimizedCompilationInfo * info() const
void BuildDisposeScope(WrappedFunc wrapped_func, bool has_await_using)
ContextScope * execution_context() const
void BuildCreateObjectLiteral(Register literal, uint8_t flags, size_t entry)
void GenerateBytecode(uintptr_t stack_limit)
void BuildPrivateBrandInitialization(Register receiver, Variable *brand)
Variable::HoleCheckBitmap hole_check_bitmap_
void VisitGlobalDeclarations(Declaration::List *declarations)
void AllocateTopLevelRegisters()
DirectHandle< TrustedByteArray > FinalizeSourcePositionTable(IsolateT *isolate)
void GenerateBodyStatements(int start=0)
BlockCoverageBuilder * block_coverage_builder_
void VisitNullishExpression(BinaryOperation *binop)
void VisitIterationBody(IterationStatement *stmt, LoopBuilder *loop_builder)
void GenerateBaseConstructorBody()
Register current_disposables_stack() const
FeedbackSlot GetCachedStoreICSlot(const Expression *expr, const AstRawString *name)
ZoneVector< std::pair< Call *, Scope * > > eval_calls_
TypeHint GetTypeHintForLocalVariable(Variable *variable)
ZoneVector< Variable * > vars_in_hole_check_bitmap_
ZoneVector< std::pair< ObjectLiteralBoilerplateBuilder *, size_t > > object_literals_
int feedback_index(FeedbackSlot slot) const
void VisitArguments(const ZonePtrList< Expression > *args, RegisterList *arg_regs)
void BuildClassProperty(ClassLiteral::Property *property)
ZoneVector< std::pair< ClassLiteral *, size_t > > class_literals_
Variable * GetPotentialVariableInAccumulator()
void VisitLogicalTestSubExpression(Token::Value token, Expression *expr, BytecodeLabels *then_labels, BytecodeLabels *else_labels, int coverage_slot)
void BuildTryCatch(TryBodyFunc try_body_func, CatchBodyFunc catch_body_func, HandlerTable::CatchPrediction catch_prediction, TryCatchStatement *stmt_for_coverage=nullptr)
void BuildDestructuringArrayAssignment(ArrayLiteral *pattern, Token::Value op, LookupHoistingMode lookup_hoisting_mode)
void BuildCreateArrayLiteral(const ZonePtrList< Expression > *elements, ArrayLiteral *expr)
void BuildTest(ToBooleanMode mode, BytecodeLabels *then_labels, BytecodeLabels *else_labels, TestFallthrough fallthrough)
void VisitBlockDeclarationsAndStatements(Block *stmt)
V8_WARN_UNUSED_RESULT Register VisitForRegisterValue(Expression *expr)
void set_catch_prediction(HandlerTable::CatchPrediction value)
void VisitNaryCommaExpression(NaryOperation *expr)
IteratorRecord BuildGetIteratorRecord(Register iterator_next, Register iterator_object, IteratorType hint)
void VisitCallSuper(Call *call)
FunctionKind function_kind() const
void BuildNewLocalWithContext(Scope *scope)
void BuildLoadNamedProperty(const Expression *object_expr, Register object, const AstRawString *name)
int AllocateConditionalChainBlockCoverageSlotIfEnabled(ConditionalChain *node, SourceRangeKind kind, size_t index)
void VisitForAccumulatorValueOrTheHole(Expression *expr)
Register GetRegisterForLocalVariable(Variable *variable)
void VisitNaryArithmeticExpression(NaryOperation *expr)
void BuildLocalActivationContextInitialization()
const AstStringConstants * ast_string_constants() const
void BuildCallIteratorMethod(Register iterator, const AstRawString *method, RegisterList receiver_and_args, BytecodeLabel *if_called, BytecodeLabels *if_notcalled)
BytecodeJumpTable * generator_jump_table_
void BuildLiteralCompareNil(Token::Value compare_op, BytecodeArrayBuilder::NilValue nil)
void VisitPropertyLoad(Register obj, Property *expr)
void VisitLogicalTest(Token::Value token, Expression *left, Expression *right, int right_coverage_slot)
ControlScope * execution_control() const
void VisitInHoleCheckElisionScope(T *node)
ZoneVector< std::pair< FunctionLiteral *, size_t > > function_literals_
void BuildGetIterator(IteratorType hint)
void VisitForNullishTest(Expression *expr, BytecodeLabels *then_labels, BytecodeLabels *test_next_labels, BytecodeLabels *else_labels)
void BuildTryFinally(TryBodyFunc try_body_func, FinallyBodyFunc finally_body_func, HandlerTable::CatchPrediction catch_prediction, TryFinallyStatement *stmt_for_coverage=nullptr)
void VisitLiteralAccessor(LiteralProperty *property, Register value_out)
bool VisitLogicalOrSubExpression(Expression *expr, BytecodeLabels *end_labels, int coverage_slot)
TypeHint VisitForAccumulatorValue(Expression *expr)
void VisitLogicalOrExpression(BinaryOperation *binop)
void GenerateBodyPrologue()
void VisitNaryLogicalOrExpression(NaryOperation *expr)
void VisitKeyedSuperPropertyLoad(Property *property, Register opt_receiver_out)
void VisitIterationBodyInHoleCheckElisionScope(IterationStatement *stmt, LoopBuilder *loop_builder)
Register incoming_new_target_or_generator_
BytecodeLabels * optional_chaining_null_labels_
void BuildGetAndCheckSuperConstructor(Register this_function, Register new_target, Register constructor, BytecodeLabel *super_ctor_call_done)
void VisitTypeOf(UnaryOperation *expr)
void BuildLoadPropertyKey(LiteralProperty *property, Register out_reg)
FeedbackSlot GetCachedLoadICSlot(const Expression *expr, const AstRawString *name)
int AllocateBlockCoverageSlotIfEnabled(AstNode *node, SourceRangeKind kind)
void VisitArithmeticExpression(BinaryOperation *binop)
void BuildDeclareCall(Runtime::FunctionId id)
void VisitForTest(Expression *expr, BytecodeLabels *then_labels, BytecodeLabels *else_labels, TestFallthrough fallthrough)
void BuildAwait(int position=kNoSourcePosition)
Scope * current_scope() const
void VisitRestArgumentsArray(Variable *rest)
void GenerateBytecodeBody()
void VisitNaryNullishExpression(NaryOperation *expr)
FeedbackSlot GetCachedLoadSuperICSlot(const AstRawString *name)
void BuildVariableLoad(Variable *variable, HoleCheckMode hole_check_mode, TypeofMode typeof_mode=TypeofMode::kNotInside)
bool IsLocalVariableWithInternalizedStringHint(Expression *expr)
void VisitModuleNamespaceImports()
void BuildPrivateBrandCheck(Property *property, Register object)
int GetCachedCreateClosureSlot(FunctionLiteral *literal)
void GenerateAsyncGeneratorFunctionBody()
LocalIsolate * local_isolate_
void BuildIteratorClose(const IteratorRecord &iterator, Expression *expr=nullptr)
void BuildAssignment(const AssignmentLhsData &data, Token::Value op, LookupHoistingMode lookup_hoisting_mode)
TopLevelDeclarationsBuilder * top_level_builder()
void VisitClassLiteral(ClassLiteral *expr, Register name)
void AddToEagerLiteralsIfEager(FunctionLiteral *literal)
void GenerateAsyncFunctionBody()
void BuildSetNamedProperty(const Expression *object_expr, Register object, const AstRawString *name)
FeedbackSlot GetCachedLoadGlobalICSlot(TypeofMode typeof_mode, Variable *variable)
void BuildVariableAssignment(Variable *variable, Token::Value op, HoleCheckMode hole_check_mode, LookupHoistingMode lookup_hoisting_mode=LookupHoistingMode::kNormal)
void BuildSuspendPoint(int position)
void RememberHoleCheckInCurrentBlock(Variable *variable)
void BuildPrivateDebugDynamicSet(Property *property, Register obj, Register value)
void BuildNewLocalActivationContext()
LanguageMode language_mode() const
void BuildIncrementBlockCoverageCounterIfEnabled(AstNode *node, SourceRangeKind kind)
void BuildInstanceMemberInitialization(Register constructor, Register instance)
Register generator_object() const
void VisitAndPushIntoRegisterList(Expression *expr, RegisterList *reg_list)
void BuildOptionalChain(ExpressionFunc expression_func)
void BuildInstanceInitializationAfterSuperCall(Register this_function, Register instance)
void BuildPushUndefinedIntoRegisterList(RegisterList *reg_list)
void BuildNewLocalCatchContext(Scope *scope)
FeedbackSlotCache * feedback_slot_cache()
HandlerTable::CatchPrediction catch_prediction() const
BytecodeGenerator(LocalIsolate *local_isolate, Zone *zone, UnoptimizedCompilationInfo *info, const AstStringConstants *ast_string_constants, std::vector< FunctionLiteral * > *eager_inner_literals, Handle< Script > script)
bool IsVariableInRegister(Variable *var, Register reg)
ExpressionResultScope * execution_result() const
void BuildSuperCallOptimization(Register this_function, Register new_target, Register constructor_then_instance, BytecodeLabel *super_ctor_call_done)
void BuildStoreGlobal(Variable *variable)
bool VisitNullishSubExpression(Expression *expr, BytecodeLabels *end_labels, int coverage_slot)
Expression * GetDestructuringDefaultValue(Expression **target)
void VisitDelete(UnaryOperation *expr)
bool VariableNeedsHoleCheckInCurrentBlockForAssignment(Variable *variable, Token::Value op, HoleCheckMode hole_check_mode)
static constexpr ToBooleanMode ToBooleanModeFromTypeHint(TypeHint type_hint)
std::vector< FunctionLiteral * > * eager_inner_literals_
void VisitNaryLogicalAndExpression(NaryOperation *expr)
bool VariableNeedsHoleCheckInCurrentBlock(Variable *variable, HoleCheckMode hole_check_mode)
void BuildPrivateMethodIn(Variable *private_name, Expression *object_expression)
void BuildIteratorNext(const IteratorRecord &iterator, Register next_result)
int AllocateNaryBlockCoverageSlotIfEnabled(NaryOperation *node, size_t index)
void BuildGeneratorObjectVariableInitialization()
void BuildDestructuringObjectAssignment(ObjectLiteral *pattern, Token::Value op, LookupHoistingMode lookup_hoisting_mode)
void VisitPropertyLoadForRegister(Register obj, Property *expr, Register destination)
UnoptimizedCompilationInfo * info_
FeedbackSlot GetDummyCompareICSlot()
BytecodeArrayBuilder * builder()
void BuildReturn(int source_position)
FeedbackVectorSpec * feedback_spec()
void BuildThisVariableLoad()
void BuildPrivateGetterAccess(Register obj, Register access_pair)
AccumulatorPreservingMode
void BuildClassLiteral(ClassLiteral *expr, Register name)
void VisitNewTargetVariable(Variable *variable)
FeedbackSlot GetCachedStoreGlobalICSlot(LanguageMode language_mode, Variable *variable)
void BuildPrivateDebugDynamicGet(Property *property, Register obj)
void VisitModuleDeclarations(Declaration::List *declarations)
BytecodeRegisterAllocator * register_allocator()
void VisitNamedSuperPropertyLoad(Property *property, Register opt_receiver_out)
void GenerateBodyStatementsWithoutImplicitFinalReturn(int start=0)
ZoneVector< std::pair< GetTemplateObject *, size_t > > template_objects_
void VisitArgumentsObject(Variable *variable)
ZoneVector< std::pair< NativeFunctionLiteral *, size_t > > native_function_literals_
void VisitLogicalAndExpression(BinaryOperation *binop)
Register incoming_new_target() const
void VisitDeclarations(Declaration::List *declarations)
AssignmentLhsData PrepareAssignmentLhs(Expression *lhs, AccumulatorPreservingMode accumulator_preserving_mode=AccumulatorPreservingMode::kNone)
void VisitInScope(Statement *stmt, Scope *scope)
void BuildFinalizeIteration(IteratorRecord iterator, Register done, Register iteration_continuation_token)
void VisitStatements(const ZonePtrList< Statement > *statments, int start=0)
void BuildLiteralStrictCompareBoolean(Literal *literal)
void BuildLoadKeyedProperty(Register object, FeedbackSlot slot)
TypeHint VisitInHoleCheckElisionScopeForAccumulatorValue(Expression *expr)
DeclarationScope * closure_scope() const
ZoneVector< std::pair< ArrayLiteralBoilerplateBuilder *, size_t > > array_literals_
void BuildThrowIfHole(Variable *variable)
void BuildGeneratorPrologue()
void VisitVoid(UnaryOperation *expr)
void BuildInvalidPropertyAccess(MessageTemplate tmpl, Property *property)
Handle< BytecodeArray > FinalizeBytecode(IsolateT *isolate, Handle< Script > script)
void VisitInSameTestExecutionScope(Expression *expr)
void AllocateDeferredConstants(IsolateT *isolate, Handle< Script > script)
void BuildNewLocalBlockContext(Scope *scope)
void VisitForEffect(Expression *expr)
void BuildPrivateSetterAccess(Register obj, Register access_pair, Register value)
static bool IsStringTypeHint(TypeHint hint)
bool VisitLogicalAndSubExpression(Expression *expr, BytecodeLabels *end_labels, int coverage_slot)
void VisitNaryLogicalTest(Token::Value token, NaryOperation *expr, const NaryCodeCoverageSlots *coverage_slots)
void VisitForTypeOfValue(Expression *expr)
void VisitThisFunctionVariable(Variable *variable)
void Bind(BytecodeArrayBuilder *builder)
void ReleaseRegister(Register reg)
RegisterList AllLiveRegisters() const
RegisterList NewGrowableRegisterList()
RegisterList NewRegisterList(int count)
Register GrowRegisterList(RegisterList *reg_list)
TypeHint GetTypeHint(Register reg)
void SetTypeHintForAccumulator(TypeHint hint)
void SetVariableInRegister(Variable *var, Register reg)
bool IsVariableInRegister(Variable *var, Register reg)
Variable * GetPotentialVariableInAccumulator()
static uint8_t Encode(bool use_fast_shallow_clone, int runtime_flags)
static uint8_t Encode(bool pretenure, bool is_function_scope, bool might_always_turbofan)
static uint8_t Encode(int runtime_flags, bool fast_clone_supported)
void BindContinueTarget()
const RegisterList Truncate(int new_count)
static constexpr Register virtual_accumulator()
static constexpr Register current_context()
static constexpr Register invalid_value()
static constexpr Register function_closure()
constexpr bool is_valid() const
static LiteralFlag GetFlagForLiteral(const AstStringConstants *ast_constants, Literal *literal)
void BeginTry(Register context)
void BeginTry(Register context)
PlatformAwareObjectStartBitmap * bitmap_
DeclarationScope * scope_
Handle< Context > context_
DeclarationScope * closure_scope_
base::Vector< const DirectHandle< Object > > args
DirectHandle< Object > new_target
std::unique_ptr< icu::DateTimePatternGenerator > generator_
ZoneVector< RpoNumber > & result
FunctionLiteral * literal
#define LOG_CODE_EVENT(isolate, Call)
LocalIsolate * local_isolate_
RegListBase< RegisterT > registers
InstructionOperand source
InstructionOperand destination
V8_INLINE const Operation & Get(const Graph &graph, OpIndex index)
SnapshotTable< OpIndex, VariableData >::Key Variable
static bool IsTypeof(Expression *expr)
static bool IsLiteralCompareTypeof(CompareOperation *expr, Expression **sub_expr, TestTypeOfFlags::LiteralFlag *flag, const AstStringConstants *ast_constants)
static bool IsCharU(const AstRawString *str)
bool is_sloppy(LanguageMode language_mode)
constexpr int kNoSourcePosition
bool IsLexicalVariableMode(VariableMode mode)
bool IsDeclaredVariableMode(VariableMode mode)
bool IsSmiDouble(double value)
bool IsDerivedConstructor(FunctionKind kind)
@ PRIVATE_GETTER_AND_SETTER
bool IsResumableFunction(FunctionKind kind)
V8_INLINE IndirectHandle< T > indirect_handle(DirectHandle< T > handle)
constexpr uint16_t kDontAdaptArgumentsSentinel
@ kLoadGlobalNotInsideTypeof
@ kLoadGlobalInsideTypeof
bool IsAsyncFunction(FunctionKind kind)
bool IsModuleWithTopLevelAwait(FunctionKind kind)
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in name
void Print(Tagged< Object > obj)
bool IsBaseConstructor(FunctionKind kind)
bool IsAsyncGeneratorFunction(FunctionKind kind)
Tagged< MaybeWeak< T > > MakeWeak(Tagged< T > value)
base::Flags< DefineKeyedOwnPropertyInLiteralFlag > DefineKeyedOwnPropertyInLiteralFlags
bool is_strict(LanguageMode language_mode)
V8_EXPORT_PRIVATE FlagValues v8_flags
constexpr int JSParameterCount(int param_count_without_receiver)
bool IsPrivateMethodOrAccessorVariableMode(VariableMode mode)
SharedFunctionInfo::HasStaticPrivateMethodsOrAccessorsBit SharedFunctionInfo::MaglevCompilationFailedBit SharedFunctionInfo::FunctionSyntaxKindBits SharedFunctionInfo::HasDuplicateParametersBit requires_instance_members_initializer
bool IsDefaultConstructor(FunctionKind kind)
ZoneList< T * > ZonePtrList
TorqueStructIteratorRecord IteratorRecord
OptimizedCompilationInfo * info_
#define CHECK_LT(lhs, rhs)
#define DCHECK_NOT_NULL(val)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK_NE(v1, v2)
#define DCHECK_GE(v1, v2)
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
#define V8_LIKELY(condition)
#define V8_UNLIKELY(condition)
std::unique_ptr< ValueMirror > key