Commit 90ddc99b authored by Joyee Cheung's avatar Joyee Cheung Committed by Commit Bot

[class] mark private name load as immutable

Bug: v8:5368, v8:8330
Change-Id: I237541223289546b8de031f905d42bb9234c8448
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2184649
Commit-Queue: Joyee Cheung <joyee@igalia.com>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67667}
parent 611d1bb9
...@@ -67,6 +67,8 @@ class AstRawString final : public ZoneObject { ...@@ -67,6 +67,8 @@ class AstRawString final : public ZoneObject {
int byte_length() const { return literal_bytes_.length(); } int byte_length() const { return literal_bytes_.length(); }
const unsigned char* raw_data() const { return literal_bytes_.begin(); } const unsigned char* raw_data() const { return literal_bytes_.begin(); }
bool IsPrivateName() const { return length() > 0 && FirstCharacter() == '#'; }
// For storing AstRawStrings in a hash map. // For storing AstRawStrings in a hash map.
uint32_t hash_field() const { return hash_field_; } uint32_t hash_field() const { return hash_field_; }
uint32_t Hash() const { return hash_field_ >> Name::kHashShift; } uint32_t Hash() const { return hash_field_ >> Name::kHashShift; }
......
...@@ -1446,9 +1446,7 @@ class VariableProxy final : public Expression { ...@@ -1446,9 +1446,7 @@ class VariableProxy final : public Expression {
HoleCheckModeField::update(bit_field_, HoleCheckMode::kRequired); HoleCheckModeField::update(bit_field_, HoleCheckMode::kRequired);
} }
bool IsPrivateName() const { bool IsPrivateName() const { return raw_name()->IsPrivateName(); }
return raw_name()->length() > 0 && raw_name()->FirstCharacter() == '#';
}
// Bind this proxy to the variable var. // Bind this proxy to the variable var.
void BindTo(Variable* var); void BindTo(Variable* var);
......
...@@ -2586,8 +2586,8 @@ Variable* ClassScope::DeclarePrivateName(const AstRawString* name, ...@@ -2586,8 +2586,8 @@ Variable* ClassScope::DeclarePrivateName(const AstRawString* name,
bool* was_added) { bool* was_added) {
Variable* result = EnsureRareData()->private_name_map.Declare( Variable* result = EnsureRareData()->private_name_map.Declare(
zone(), this, name, mode, NORMAL_VARIABLE, zone(), this, name, mode, NORMAL_VARIABLE,
InitializationFlag::kNeedsInitialization, InitializationFlag::kNeedsInitialization, MaybeAssignedFlag::kNotAssigned,
MaybeAssignedFlag::kMaybeAssigned, is_static_flag, was_added); is_static_flag, was_added);
if (*was_added) { if (*was_added) {
locals_.Add(result); locals_.Add(result);
has_static_private_methods_ |= has_static_private_methods_ |=
...@@ -2683,7 +2683,7 @@ Variable* ClassScope::LookupPrivateNameInScopeInfo(const AstRawString* name) { ...@@ -2683,7 +2683,7 @@ Variable* ClassScope::LookupPrivateNameInScopeInfo(const AstRawString* name) {
DCHECK(IsConstVariableMode(mode)); DCHECK(IsConstVariableMode(mode));
DCHECK_EQ(init_flag, InitializationFlag::kNeedsInitialization); DCHECK_EQ(init_flag, InitializationFlag::kNeedsInitialization);
DCHECK_EQ(maybe_assigned_flag, MaybeAssignedFlag::kMaybeAssigned); DCHECK_EQ(maybe_assigned_flag, MaybeAssignedFlag::kNotAssigned);
// Add the found private name to the map to speed up subsequent // Add the found private name to the map to speed up subsequent
// lookups for the same name. // lookups for the same name.
...@@ -2812,7 +2812,7 @@ Variable* ClassScope::DeclareBrandVariable(AstValueFactory* ast_value_factory, ...@@ -2812,7 +2812,7 @@ Variable* ClassScope::DeclareBrandVariable(AstValueFactory* ast_value_factory,
Variable* brand = Declare(zone(), ast_value_factory->dot_brand_string(), Variable* brand = Declare(zone(), ast_value_factory->dot_brand_string(),
VariableMode::kConst, NORMAL_VARIABLE, VariableMode::kConst, NORMAL_VARIABLE,
InitializationFlag::kNeedsInitialization, InitializationFlag::kNeedsInitialization,
MaybeAssignedFlag::kMaybeAssigned, &was_added); MaybeAssignedFlag::kNotAssigned, &was_added);
DCHECK(was_added); DCHECK(was_added);
brand->set_is_static_flag(is_static_flag); brand->set_is_static_flag(is_static_flag);
brand->ForceContextAllocation(); brand->ForceContextAllocation();
......
...@@ -90,7 +90,10 @@ class Variable final : public ZoneObject { ...@@ -90,7 +90,10 @@ class Variable final : public ZoneObject {
} }
void SetMaybeAssigned() { void SetMaybeAssigned() {
if (mode() == VariableMode::kConst) return; if (mode() == VariableMode::kConst) return;
// Private names are only initialized once by us.
if (name_->IsPrivateName()) {
return;
}
// If this variable is dynamically shadowing another variable, then that // If this variable is dynamically shadowing another variable, then that
// variable could also be assigned (in the non-shadowing case). // variable could also be assigned (in the non-shadowing case).
if (has_local_if_not_shadowed()) { if (has_local_if_not_shadowed()) {
......
...@@ -26,14 +26,14 @@ frame size: 7 ...@@ -26,14 +26,14 @@ frame size: 7
parameter count: 1 parameter count: 1
bytecode array length: 97 bytecode array length: 97
bytecodes: [ bytecodes: [
B(LdaCurrentContextSlot), U8(3), B(LdaImmutableCurrentContextSlot), U8(3),
B(Star), R(1), B(Star), R(1),
B(Mov), R(this), R(0), B(Mov), R(this), R(0),
B(Mov), R(context), R(2), B(Mov), R(context), R(2),
/* 67 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3), /* 67 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3),
/* 76 S> */ B(LdaCurrentContextSlot), U8(2), /* 76 S> */ B(LdaImmutableCurrentContextSlot), U8(2),
B(Star), R(4), B(Star), R(4),
B(LdaCurrentContextSlot), U8(3), B(LdaImmutableCurrentContextSlot), U8(3),
/* 81 E> */ B(LdaKeyedProperty), R(this), U8(0), /* 81 E> */ B(LdaKeyedProperty), R(this), U8(0),
B(CallRuntime), U16(Runtime::kLoadPrivateGetter), R(4), U8(1), B(CallRuntime), U16(Runtime::kLoadPrivateGetter), R(4), U8(1),
B(Star), R(5), B(Star), R(5),
...@@ -45,16 +45,16 @@ bytecodes: [ ...@@ -45,16 +45,16 @@ bytecodes: [
B(CallProperty1), R(6), R(this), R(5), U8(5), B(CallProperty1), R(6), R(this), R(5), U8(5),
/* 91 S> */ B(LdaSmi), I8(1), /* 91 S> */ B(LdaSmi), I8(1),
B(Star), R(3), B(Star), R(3),
B(LdaCurrentContextSlot), U8(2), B(LdaImmutableCurrentContextSlot), U8(2),
B(Star), R(5), B(Star), R(5),
B(LdaCurrentContextSlot), U8(3), B(LdaImmutableCurrentContextSlot), U8(3),
/* 96 E> */ B(LdaKeyedProperty), R(this), U8(7), /* 96 E> */ B(LdaKeyedProperty), R(this), U8(7),
B(CallRuntime), U16(Runtime::kLoadPrivateSetter), R(5), U8(1), B(CallRuntime), U16(Runtime::kLoadPrivateSetter), R(5), U8(1),
B(Star), R(6), B(Star), R(6),
B(CallProperty1), R(6), R(this), R(3), U8(9), B(CallProperty1), R(6), R(this), R(3), U8(9),
/* 108 S> */ B(LdaCurrentContextSlot), U8(2), /* 108 S> */ B(LdaImmutableCurrentContextSlot), U8(2),
B(Star), R(4), B(Star), R(4),
B(LdaCurrentContextSlot), U8(3), B(LdaImmutableCurrentContextSlot), U8(3),
/* 120 E> */ B(LdaKeyedProperty), R(this), U8(11), /* 120 E> */ B(LdaKeyedProperty), R(this), U8(11),
B(CallRuntime), U16(Runtime::kLoadPrivateGetter), R(4), U8(1), B(CallRuntime), U16(Runtime::kLoadPrivateGetter), R(4), U8(1),
B(Star), R(5), B(Star), R(5),
...@@ -79,7 +79,7 @@ frame size: 5 ...@@ -79,7 +79,7 @@ frame size: 5
parameter count: 1 parameter count: 1
bytecode array length: 31 bytecode array length: 31
bytecodes: [ bytecodes: [
B(LdaCurrentContextSlot), U8(3), B(LdaImmutableCurrentContextSlot), U8(3),
B(Star), R(1), B(Star), R(1),
B(Mov), R(this), R(0), B(Mov), R(this), R(0),
B(Mov), R(context), R(2), B(Mov), R(context), R(2),
...@@ -110,7 +110,7 @@ frame size: 5 ...@@ -110,7 +110,7 @@ frame size: 5
parameter count: 1 parameter count: 1
bytecode array length: 31 bytecode array length: 31
bytecodes: [ bytecodes: [
B(LdaCurrentContextSlot), U8(3), B(LdaImmutableCurrentContextSlot), U8(3),
B(Star), R(1), B(Star), R(1),
B(Mov), R(this), R(0), B(Mov), R(this), R(0),
B(Mov), R(context), R(2), B(Mov), R(context), R(2),
...@@ -141,7 +141,7 @@ frame size: 5 ...@@ -141,7 +141,7 @@ frame size: 5
parameter count: 1 parameter count: 1
bytecode array length: 31 bytecode array length: 31
bytecodes: [ bytecodes: [
B(LdaCurrentContextSlot), U8(3), B(LdaImmutableCurrentContextSlot), U8(3),
B(Star), R(1), B(Star), R(1),
B(Mov), R(this), R(0), B(Mov), R(this), R(0),
B(Mov), R(context), R(2), B(Mov), R(context), R(2),
...@@ -172,7 +172,7 @@ frame size: 6 ...@@ -172,7 +172,7 @@ frame size: 6
parameter count: 1 parameter count: 1
bytecode array length: 31 bytecode array length: 31
bytecodes: [ bytecodes: [
B(LdaCurrentContextSlot), U8(3), B(LdaImmutableCurrentContextSlot), U8(3),
B(Star), R(1), B(Star), R(1),
B(Mov), R(this), R(0), B(Mov), R(this), R(0),
B(Mov), R(context), R(2), B(Mov), R(context), R(2),
......
#
# Autogenerated by generate-bytecode-expectations.
#
---
wrap: no
test function name: test
private methods: yes
---
snippet: "
class A {
#a;
#b;
constructor() {
this.#a = this.#b;
}
}
var test = A;
new test;
"
frame size: 4
parameter count: 1
bytecode array length: 30
bytecodes: [
/* 35 E> */ B(LdaNamedProperty), R(closure), U8(0), U8(0),
B(JumpIfUndefined), U8(11),
B(Star), R(1),
B(CallProperty0), R(1), R(this), U8(2),
B(Mov), R(this), R(0),
/* 44 S> */ B(LdaImmutableCurrentContextSlot), U8(2),
B(Star), R(3),
B(LdaImmutableCurrentContextSlot), U8(3),
/* 59 E> */ B(LdaKeyedProperty), R(this), U8(4),
/* 52 E> */ B(StaKeyedProperty), R(this), R(3), U8(6),
B(LdaUndefined),
/* 65 S> */ B(Return),
]
constant pool: [
SYMBOL_TYPE,
]
handlers: [
]
---
snippet: "
class B {
#a;
#b;
constructor() {
this.#a = this.#b;
}
force(str) {
eval(str);
}
}
var test = B;
new test;
"
frame size: 4
parameter count: 1
bytecode array length: 30
bytecodes: [
/* 35 E> */ B(LdaNamedProperty), R(closure), U8(0), U8(0),
B(JumpIfUndefined), U8(11),
B(Star), R(1),
B(CallProperty0), R(1), R(this), U8(2),
B(Mov), R(this), R(0),
/* 44 S> */ B(LdaImmutableCurrentContextSlot), U8(2),
B(Star), R(3),
B(LdaImmutableCurrentContextSlot), U8(3),
/* 59 E> */ B(LdaKeyedProperty), R(this), U8(4),
/* 52 E> */ B(StaKeyedProperty), R(this), R(3), U8(6),
B(LdaUndefined),
/* 65 S> */ B(Return),
]
constant pool: [
SYMBOL_TYPE,
]
handlers: [
]
...@@ -21,14 +21,14 @@ frame size: 4 ...@@ -21,14 +21,14 @@ frame size: 4
parameter count: 1 parameter count: 1
bytecode array length: 30 bytecode array length: 30
bytecodes: [ bytecodes: [
B(LdaCurrentContextSlot), U8(3), B(LdaImmutableCurrentContextSlot), U8(3),
B(Star), R(1), B(Star), R(1),
B(Mov), R(this), R(0), B(Mov), R(this), R(0),
B(Mov), R(context), R(2), B(Mov), R(context), R(2),
/* 44 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3), /* 44 E> */ B(CallRuntime), U16(Runtime::kAddPrivateBrand), R(0), U8(3),
/* 49 S> */ B(LdaCurrentContextSlot), U8(3), /* 49 S> */ B(LdaImmutableCurrentContextSlot), U8(3),
/* 61 E> */ B(LdaKeyedProperty), R(this), U8(0), /* 61 E> */ B(LdaKeyedProperty), R(this), U8(0),
B(LdaCurrentContextSlot), U8(2), B(LdaImmutableCurrentContextSlot), U8(2),
B(Star), R(3), B(Star), R(3),
/* 63 E> */ B(CallAnyReceiver), R(3), R(this), U8(1), U8(2), /* 63 E> */ B(CallAnyReceiver), R(3), R(this), U8(1), U8(2),
/* 66 S> */ B(Return), /* 66 S> */ B(Return),
...@@ -52,7 +52,7 @@ frame size: 5 ...@@ -52,7 +52,7 @@ frame size: 5
parameter count: 1 parameter count: 1
bytecode array length: 31 bytecode array length: 31
bytecodes: [ bytecodes: [
B(LdaCurrentContextSlot), U8(3), B(LdaImmutableCurrentContextSlot), U8(3),
B(Star), R(1), B(Star), R(1),
B(Mov), R(this), R(0), B(Mov), R(this), R(0),
B(Mov), R(context), R(2), B(Mov), R(context), R(2),
...@@ -84,7 +84,7 @@ frame size: 5 ...@@ -84,7 +84,7 @@ frame size: 5
parameter count: 1 parameter count: 1
bytecode array length: 31 bytecode array length: 31
bytecodes: [ bytecodes: [
B(LdaCurrentContextSlot), U8(3), B(LdaImmutableCurrentContextSlot), U8(3),
B(Star), R(1), B(Star), R(1),
B(Mov), R(this), R(0), B(Mov), R(this), R(0),
B(Mov), R(context), R(2), B(Mov), R(context), R(2),
...@@ -120,7 +120,7 @@ bytecodes: [ ...@@ -120,7 +120,7 @@ bytecodes: [
B(PushContext), R(0), B(PushContext), R(0),
B(Ldar), R(this), B(Ldar), R(this),
B(StaCurrentContextSlot), U8(2), B(StaCurrentContextSlot), U8(2),
B(LdaContextSlot), R(0), U8(3), U8(0), B(LdaImmutableContextSlot), R(0), U8(3), U8(0),
B(Star), R(2), B(Star), R(2),
B(Mov), R(this), R(1), B(Mov), R(this), R(1),
B(Mov), R(0), R(3), B(Mov), R(0), R(3),
...@@ -129,9 +129,9 @@ bytecodes: [ ...@@ -129,9 +129,9 @@ bytecodes: [
B(Star), R(5), B(Star), R(5),
/* 61 E> */ B(CallUndefinedReceiver0), R(5), U8(0), /* 61 E> */ B(CallUndefinedReceiver0), R(5), U8(0),
B(Star), R(5), B(Star), R(5),
B(LdaContextSlot), R(0), U8(3), U8(0), B(LdaImmutableContextSlot), R(0), U8(3), U8(0),
/* 63 E> */ B(LdaKeyedProperty), R(5), U8(2), /* 63 E> */ B(LdaKeyedProperty), R(5), U8(2),
B(LdaContextSlot), R(0), U8(2), U8(0), B(LdaImmutableContextSlot), R(0), U8(2), U8(0),
B(Star), R(4), B(Star), R(4),
/* 66 E> */ B(CallAnyReceiver), R(4), R(5), U8(1), U8(4), /* 66 E> */ B(CallAnyReceiver), R(4), R(5), U8(1), U8(4),
B(LdaUndefined), B(LdaUndefined),
......
...@@ -31,7 +31,7 @@ bytecodes: [ ...@@ -31,7 +31,7 @@ bytecodes: [
B(Star), R(3), B(Star), R(3),
B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2), B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2),
B(Throw), B(Throw),
B(LdaCurrentContextSlot), U8(2), B(LdaImmutableCurrentContextSlot), U8(2),
B(Star), R(0), B(Star), R(0),
/* 70 E> */ B(CallAnyReceiver), R(0), R(1), U8(1), U8(0), /* 70 E> */ B(CallAnyReceiver), R(0), R(1), U8(1), U8(0),
/* 73 S> */ B(Return), /* 73 S> */ B(Return),
...@@ -116,7 +116,7 @@ frame size: 5 ...@@ -116,7 +116,7 @@ frame size: 5
parameter count: 1 parameter count: 1
bytecode array length: 142 bytecode array length: 142
bytecodes: [ bytecodes: [
/* 90 S> */ B(LdaCurrentContextSlot), U8(2), /* 90 S> */ B(LdaImmutableCurrentContextSlot), U8(2),
B(Star), R(1), B(Star), R(1),
B(LdaCurrentContextSlot), U8(3), B(LdaCurrentContextSlot), U8(3),
/* 94 E> */ B(TestReferenceEqual), R(this), /* 94 E> */ B(TestReferenceEqual), R(this),
...@@ -138,7 +138,7 @@ bytecodes: [ ...@@ -138,7 +138,7 @@ bytecodes: [
B(CallProperty1), R(3), R(0), R(2), U8(3), B(CallProperty1), R(3), R(0), R(2), U8(3),
/* 105 S> */ B(LdaSmi), I8(1), /* 105 S> */ B(LdaSmi), I8(1),
B(Star), R(0), B(Star), R(0),
B(LdaCurrentContextSlot), U8(2), B(LdaImmutableCurrentContextSlot), U8(2),
B(Star), R(2), B(Star), R(2),
B(LdaCurrentContextSlot), U8(3), B(LdaCurrentContextSlot), U8(3),
/* 109 E> */ B(TestReferenceEqual), R(this), /* 109 E> */ B(TestReferenceEqual), R(this),
...@@ -153,7 +153,7 @@ bytecodes: [ ...@@ -153,7 +153,7 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kLoadPrivateSetter), R(2), U8(1), B(CallRuntime), U16(Runtime::kLoadPrivateSetter), R(2), U8(1),
B(Star), R(3), B(Star), R(3),
B(CallProperty1), R(3), R(1), R(0), U8(5), B(CallProperty1), R(3), R(1), R(0), U8(5),
/* 122 S> */ B(LdaCurrentContextSlot), U8(2), /* 122 S> */ B(LdaImmutableCurrentContextSlot), U8(2),
B(Star), R(1), B(Star), R(1),
B(LdaCurrentContextSlot), U8(3), B(LdaCurrentContextSlot), U8(3),
/* 133 E> */ B(TestReferenceEqual), R(this), /* 133 E> */ B(TestReferenceEqual), R(this),
......
...@@ -2756,6 +2756,42 @@ TEST(PrivateClassFields) { ...@@ -2756,6 +2756,42 @@ TEST(PrivateClassFields) {
LoadGolden("PrivateClassFields.golden"))); LoadGolden("PrivateClassFields.golden")));
} }
TEST(PrivateClassFieldAccess) {
InitializedIgnitionHandleScope scope;
BytecodeExpectationsPrinter printer(CcTest::isolate());
printer.set_wrap(false);
printer.set_test_function_name("test");
const char* snippets[] = {
"class A {\n"
" #a;\n"
" #b;\n"
" constructor() {\n"
" this.#a = this.#b;\n"
" }\n"
"}\n"
"\n"
"var test = A;\n"
"new test;\n",
"class B {\n"
" #a;\n"
" #b;\n"
" constructor() {\n"
" this.#a = this.#b;\n"
" }\n"
" force(str) {\n"
" eval(str);\n"
" }\n"
"}\n"
"\n"
"var test = B;\n"
"new test;\n"};
CHECK(CompareTexts(BuildActual(printer, snippets),
LoadGolden("PrivateClassFieldAccess.golden")));
}
TEST(PrivateMethodDeclaration) { TEST(PrivateMethodDeclaration) {
bool old_methods_flag = i::FLAG_harmony_private_methods; bool old_methods_flag = i::FLAG_harmony_private_methods;
i::FLAG_harmony_private_methods = true; i::FLAG_harmony_private_methods = true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment