summaryrefslogtreecommitdiff
path: root/deps/v8/src/interpreter/bytecode-generator.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/interpreter/bytecode-generator.cc')
-rw-r--r--deps/v8/src/interpreter/bytecode-generator.cc208
1 files changed, 152 insertions, 56 deletions
diff --git a/deps/v8/src/interpreter/bytecode-generator.cc b/deps/v8/src/interpreter/bytecode-generator.cc
index 706d897d8a..acaa1dae45 100644
--- a/deps/v8/src/interpreter/bytecode-generator.cc
+++ b/deps/v8/src/interpreter/bytecode-generator.cc
@@ -896,6 +896,8 @@ class V8_NODISCARD BytecodeGenerator::MultipleEntryBlockContextScope {
}
}
+ ~MultipleEntryBlockContextScope() { DCHECK(!is_in_scope_); }
+
MultipleEntryBlockContextScope(const MultipleEntryBlockContextScope&) =
delete;
MultipleEntryBlockContextScope& operator=(
@@ -906,12 +908,9 @@ class V8_NODISCARD BytecodeGenerator::MultipleEntryBlockContextScope {
DCHECK(inner_context_.is_valid());
DCHECK(outer_context_.is_valid());
DCHECK(!is_in_scope_);
- Register temp = generator_->register_allocator()->NewRegister();
- generator_->builder()->StoreAccumulatorInRegister(temp);
generator_->builder()->LoadAccumulatorWithRegister(inner_context_);
current_scope_.emplace(generator_, scope_);
context_scope_.emplace(generator_, scope_, outer_context_);
- generator_->builder()->LoadAccumulatorWithRegister(temp);
is_in_scope_ = true;
}
@@ -919,11 +918,8 @@ class V8_NODISCARD BytecodeGenerator::MultipleEntryBlockContextScope {
DCHECK(inner_context_.is_valid());
DCHECK(outer_context_.is_valid());
DCHECK(is_in_scope_);
- Register temp = generator_->register_allocator()->NewRegister();
- generator_->builder()->StoreAccumulatorInRegister(temp);
context_scope_ = base::nullopt;
current_scope_ = base::nullopt;
- generator_->builder()->LoadAccumulatorWithRegister(temp);
is_in_scope_ = false;
}
@@ -2454,7 +2450,7 @@ void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
// Finish the iteration in the finally block.
BuildFinalizeIteration(iterator, done, iteration_continuation_token);
},
- HandlerTable::UNCAUGHT);
+ catch_prediction());
}
void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
@@ -2747,13 +2743,11 @@ void BytecodeGenerator::BuildClassLiteral(ClassLiteral* expr, Register name) {
}
if (expr->instance_members_initializer_function() != nullptr) {
- Register initializer =
- VisitForRegisterValue(expr->instance_members_initializer_function());
+ VisitForAccumulatorValue(expr->instance_members_initializer_function());
FeedbackSlot slot = feedback_spec()->AddStoreICSlot(language_mode());
builder()
- ->LoadAccumulatorWithRegister(initializer)
- .StoreClassFieldsInitializer(class_constructor, feedback_index(slot))
+ ->StoreClassFieldsInitializer(class_constructor, feedback_index(slot))
.LoadAccumulatorWithRegister(class_constructor);
}
@@ -2762,23 +2756,18 @@ void BytecodeGenerator::BuildClassLiteral(ClassLiteral* expr, Register name) {
// class boilerplate in the future. The name argument can be
// passed to the DefineClass runtime function and have it set
// there.
+ // TODO(v8:13451): Alternatively, port SetFunctionName to an ic so that we
+ // can replace the runtime call to a dedicate bytecode here.
if (name.is_valid()) {
- Register key = register_allocator()->NewRegister();
- builder()
- ->LoadLiteral(ast_string_constants()->name_string())
- .StoreAccumulatorInRegister(key);
-
- DefineKeyedOwnPropertyInLiteralFlags data_property_flags =
- DefineKeyedOwnPropertyInLiteralFlag::kNoFlags;
- FeedbackSlot slot =
- feedback_spec()->AddDefineKeyedOwnPropertyInLiteralICSlot();
+ RegisterAllocationScope inner_register_scope(this);
+ RegisterList args = register_allocator()->NewRegisterList(2);
builder()
- ->LoadAccumulatorWithRegister(name)
- .DefineKeyedOwnPropertyInLiteral(class_constructor, key,
- data_property_flags,
- feedback_index(slot));
+ ->MoveRegister(class_constructor, args[0])
+ .MoveRegister(name, args[1])
+ .CallRuntime(Runtime::kSetFunctionName, args);
}
+ RegisterAllocationScope inner_register_scope(this);
RegisterList args = register_allocator()->NewRegisterList(1);
Register initializer = VisitForRegisterValue(expr->static_initializer());
@@ -2855,17 +2844,33 @@ void BytecodeGenerator::BuildClassProperty(ClassLiteral::Property* property) {
}
builder()->SetExpressionAsStatementPosition(property->value());
- VisitForAccumulatorValue(property->value());
if (is_literal_store) {
+ VisitForAccumulatorValue(property->value());
FeedbackSlot slot = feedback_spec()->AddDefineNamedOwnICSlot();
builder()->DefineNamedOwnProperty(
builder()->Receiver(),
property->key()->AsLiteral()->AsRawPropertyName(),
feedback_index(slot));
} else {
+ DefineKeyedOwnPropertyFlags flags = DefineKeyedOwnPropertyFlag::kNoFlags;
+ if (property->NeedsSetFunctionName()) {
+ // Static class fields require the name property to be set on
+ // the class, meaning we can't wait until the
+ // DefineKeyedOwnProperty call later to set the name.
+ if (property->value()->IsClassLiteral() &&
+ property->value()->AsClassLiteral()->static_initializer() !=
+ nullptr) {
+ VisitClassLiteral(property->value()->AsClassLiteral(), key);
+ } else {
+ VisitForAccumulatorValue(property->value());
+ flags |= DefineKeyedOwnPropertyFlag::kSetFunctionName;
+ }
+ } else {
+ VisitForAccumulatorValue(property->value());
+ }
FeedbackSlot slot = feedback_spec()->AddDefineKeyedOwnICSlot();
- builder()->DefineKeyedOwnProperty(builder()->Receiver(), key,
+ builder()->DefineKeyedOwnProperty(builder()->Receiver(), key, flags,
feedback_index(slot));
}
}
@@ -2917,7 +2922,9 @@ void BytecodeGenerator::BuildPrivateBrandInitialization(Register receiver,
builder()
->StoreAccumulatorInRegister(brand_reg)
.LoadAccumulatorWithRegister(class_context->reg())
- .DefineKeyedOwnProperty(receiver, brand_reg, feedback_index(slot));
+ .DefineKeyedOwnProperty(receiver, brand_reg,
+ DefineKeyedOwnPropertyFlag::kNoFlags,
+ feedback_index(slot));
} else {
// We are in the slow case where super() is called from a nested
// arrow function or a eval(), so the class scope context isn't
@@ -3135,8 +3142,9 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
feedback_index(slot));
} else {
FeedbackSlot slot = feedback_spec()->AddDefineKeyedOwnICSlot();
- builder()->DefineKeyedOwnProperty(literal, key_reg,
- feedback_index(slot));
+ builder()->DefineKeyedOwnProperty(
+ literal, key_reg, DefineKeyedOwnPropertyFlag::kNoFlags,
+ feedback_index(slot));
}
} else {
VisitForEffect(property->value());
@@ -3233,34 +3241,30 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
object_literal_context_scope.SetEnteredIf(
should_be_in_object_literal_scope);
builder()->SetExpressionPosition(property->value());
- Register value;
-
- // Static class fields require the name property to be set on
- // the class, meaning we can't wait until the
- // DefineKeyedOwnPropertyInLiteral call later to set the name.
- if (property->value()->IsClassLiteral() &&
- property->value()->AsClassLiteral()->static_initializer() !=
- nullptr) {
- value = register_allocator()->NewRegister();
- VisitClassLiteral(property->value()->AsClassLiteral(), key);
- builder()->StoreAccumulatorInRegister(value);
- } else {
- value = VisitForRegisterValue(property->value());
- }
DefineKeyedOwnPropertyInLiteralFlags data_property_flags =
DefineKeyedOwnPropertyInLiteralFlag::kNoFlags;
if (property->NeedsSetFunctionName()) {
- data_property_flags |=
- DefineKeyedOwnPropertyInLiteralFlag::kSetFunctionName;
+ // Static class fields require the name property to be set on
+ // the class, meaning we can't wait until the
+ // DefineKeyedOwnPropertyInLiteral call later to set the name.
+ if (property->value()->IsClassLiteral() &&
+ property->value()->AsClassLiteral()->static_initializer() !=
+ nullptr) {
+ VisitClassLiteral(property->value()->AsClassLiteral(), key);
+ } else {
+ data_property_flags |=
+ DefineKeyedOwnPropertyInLiteralFlag::kSetFunctionName;
+ VisitForAccumulatorValue(property->value());
+ }
+ } else {
+ VisitForAccumulatorValue(property->value());
}
FeedbackSlot slot =
feedback_spec()->AddDefineKeyedOwnPropertyInLiteralICSlot();
- builder()
- ->LoadAccumulatorWithRegister(value)
- .DefineKeyedOwnPropertyInLiteral(literal, key, data_property_flags,
- feedback_index(slot));
+ builder()->DefineKeyedOwnPropertyInLiteral(
+ literal, key, data_property_flags, feedback_index(slot));
break;
}
case ObjectLiteral::Property::GETTER:
@@ -3302,11 +3306,15 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
}
}
- builder()->LoadAccumulatorWithRegister(literal);
if (home_object != nullptr) {
object_literal_context_scope.SetEnteredIf(true);
+ builder()->LoadAccumulatorWithRegister(literal);
BuildVariableAssignment(home_object, Token::INIT, HoleCheckMode::kElided);
}
+ // Make sure to exit the scope before materialising the value into the
+ // accumulator, to prevent the context scope from clobbering it.
+ object_literal_context_scope.SetEnteredIf(false);
+ builder()->LoadAccumulatorWithRegister(literal);
}
// Fill an array with values from an iterator, starting at a given index. It is
@@ -3638,8 +3646,15 @@ void BytecodeGenerator::BuildVariableLoad(Variable* variable,
feedback_index(slot), depth);
break;
}
- default:
+ default: {
+ // Normally, private names should not be looked up dynamically,
+ // but we make an exception in debug-evaluate, in that case the
+ // lookup will be done in %SetPrivateMember() and %GetPrivateMember()
+ // calls, not here.
+ DCHECK(!variable->raw_name()->IsPrivateName());
builder()->LoadLookupSlot(variable->raw_name(), typeof_mode);
+ break;
+ }
}
break;
}
@@ -3944,6 +3959,14 @@ BytecodeGenerator::AssignmentLhsData::PrivateMethodOrAccessor(
}
// static
BytecodeGenerator::AssignmentLhsData
+BytecodeGenerator::AssignmentLhsData::PrivateDebugEvaluate(AssignType type,
+ Property* property,
+ Register object) {
+ return AssignmentLhsData(type, property, RegisterList(), object, Register(),
+ nullptr, nullptr);
+}
+// static
+BytecodeGenerator::AssignmentLhsData
BytecodeGenerator::AssignmentLhsData::KeyedSuperProperty(
RegisterList super_property_args) {
return AssignmentLhsData(KEYED_SUPER_PROPERTY, nullptr, super_property_args,
@@ -3984,6 +4007,13 @@ BytecodeGenerator::AssignmentLhsData BytecodeGenerator::PrepareAssignmentLhs(
return AssignmentLhsData::PrivateMethodOrAccessor(assign_type, property,
object, key);
}
+ case PRIVATE_DEBUG_DYNAMIC: {
+ AccumulatorPreservingScope scope(this, accumulator_preserving_mode);
+ Register object = VisitForRegisterValue(property->obj());
+ // Do not visit the key here, instead we will look them up at run time.
+ return AssignmentLhsData::PrivateDebugEvaluate(assign_type, property,
+ object);
+ }
case NAMED_SUPER_PROPERTY: {
AccumulatorPreservingScope scope(this, accumulator_preserving_mode);
RegisterList super_property_args =
@@ -4105,7 +4135,7 @@ void BytecodeGenerator::BuildFinalizeIteration(
.ReThrow()
.Bind(&suppress_close_exception);
},
- HandlerTable::UNCAUGHT);
+ catch_prediction());
}
iterator_is_done.Bind(builder());
@@ -4560,6 +4590,16 @@ void BytecodeGenerator::BuildAssignment(
}
break;
}
+ case PRIVATE_DEBUG_DYNAMIC: {
+ Register value = register_allocator()->NewRegister();
+ builder()->StoreAccumulatorInRegister(value);
+ Property* property = lhs_data.expr()->AsProperty();
+ BuildPrivateDebugDynamicSet(property, lhs_data.object(), value);
+ if (!execution_result()->IsEffect()) {
+ builder()->LoadAccumulatorWithRegister(value);
+ }
+ break;
+ }
}
}
@@ -4631,6 +4671,11 @@ void BytecodeGenerator::VisitCompoundAssignment(CompoundAssignment* expr) {
lhs_data.expr()->AsProperty());
break;
}
+ case PRIVATE_DEBUG_DYNAMIC: {
+ Property* property = lhs_data.expr()->AsProperty();
+ BuildPrivateDebugDynamicGet(property, lhs_data.object());
+ break;
+ }
}
BinaryOperation* binop = expr->binary_operation();
@@ -5143,9 +5188,41 @@ void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* property) {
VisitForAccumulatorValue(property->key());
break;
}
+ case PRIVATE_DEBUG_DYNAMIC: {
+ BuildPrivateDebugDynamicGet(property, obj);
+ break;
+ }
}
}
+void BytecodeGenerator::BuildPrivateDebugDynamicGet(Property* property,
+ Register obj) {
+ RegisterAllocationScope scope(this);
+ RegisterList args = register_allocator()->NewRegisterList(2);
+
+ Variable* private_name = property->key()->AsVariableProxy()->var();
+ builder()
+ ->MoveRegister(obj, args[0])
+ .LoadLiteral(private_name->raw_name())
+ .StoreAccumulatorInRegister(args[1])
+ .CallRuntime(Runtime::kGetPrivateMember, args);
+}
+
+void BytecodeGenerator::BuildPrivateDebugDynamicSet(Property* property,
+ Register obj,
+ Register value) {
+ RegisterAllocationScope scope(this);
+ RegisterList args = register_allocator()->NewRegisterList(3);
+
+ Variable* private_name = property->key()->AsVariableProxy()->var();
+ builder()
+ ->MoveRegister(obj, args[0])
+ .LoadLiteral(private_name->raw_name())
+ .StoreAccumulatorInRegister(args[1])
+ .MoveRegister(value, args[2])
+ .CallRuntime(Runtime::kSetPrivateMember, args);
+}
+
void BytecodeGenerator::BuildPrivateGetterAccess(Register object,
Register accessor_pair) {
RegisterAllocationScope scope(this);
@@ -5915,9 +5992,15 @@ void BytecodeGenerator::VisitDelete(UnaryOperation* unary) {
// and strict modes.
Property* property = expr->AsProperty();
DCHECK(!property->IsPrivateReference());
- Register object = VisitForRegisterValue(property->obj());
- VisitForAccumulatorValue(property->key());
- builder()->Delete(object, language_mode());
+ if (property->IsSuperAccess()) {
+ // Delete of super access is not allowed.
+ VisitForEffect(property->key());
+ builder()->CallRuntime(Runtime::kThrowUnsupportedSuperError);
+ } else {
+ Register object = VisitForRegisterValue(property->obj());
+ VisitForAccumulatorValue(property->key());
+ builder()->Delete(object, language_mode());
+ }
} else if (expr->IsOptionalChain()) {
Expression* expr_inner = expr->AsOptionalChain()->expression();
if (expr_inner->IsProperty()) {
@@ -6081,6 +6164,11 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
BuildPrivateGetterAccess(object, key);
break;
}
+ case PRIVATE_DEBUG_DYNAMIC: {
+ object = VisitForRegisterValue(property->obj());
+ BuildPrivateDebugDynamicGet(property, object);
+ break;
+ }
}
// Save result for postfix expressions.
@@ -6161,6 +6249,12 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
}
break;
}
+ case PRIVATE_DEBUG_DYNAMIC: {
+ Register value = register_allocator()->NewRegister();
+ builder()->StoreAccumulatorInRegister(value);
+ BuildPrivateDebugDynamicSet(property, object, value);
+ break;
+ }
}
// Restore old value for postfix expressions.
@@ -6594,7 +6688,9 @@ void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) {
void BytecodeGenerator::VisitSuperPropertyReference(
SuperPropertyReference* expr) {
- builder()->CallRuntime(Runtime::kThrowUnsupportedSuperError);
+ // Handled by VisitAssignment(), VisitCall(), VisitDelete() and
+ // VisitPropertyLoad().
+ UNREACHABLE();
}
void BytecodeGenerator::VisitCommaExpression(BinaryOperation* binop) {