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 {
int byte_length() const { return literal_bytes_.length(); }
const unsigned char* raw_data() const { return literal_bytes_.begin(); }
bool IsPrivateName() const { return length() > 0 && FirstCharacter() == '#'; }
// For storing AstRawStrings in a hash map.
uint32_t hash_field() const { return hash_field_; }
uint32_t Hash() const { return hash_field_ >> Name::kHashShift; }
......
......@@ -1446,9 +1446,7 @@ class VariableProxy final : public Expression {
HoleCheckModeField::update(bit_field_, HoleCheckMode::kRequired);
}
bool IsPrivateName() const {
return raw_name()->length() > 0 && raw_name()->FirstCharacter() == '#';
}
bool IsPrivateName() const { return raw_name()->IsPrivateName(); }
// Bind this proxy to the variable var.
void BindTo(Variable* var);
......
......@@ -2586,8 +2586,8 @@ Variable* ClassScope::DeclarePrivateName(const AstRawString* name,
bool* was_added) {
Variable* result = EnsureRareData()->private_name_map.Declare(
zone(), this, name, mode, NORMAL_VARIABLE,
InitializationFlag::kNeedsInitialization,
MaybeAssignedFlag::kMaybeAssigned, is_static_flag, was_added);
InitializationFlag::kNeedsInitialization, MaybeAssignedFlag::kNotAssigned,
is_static_flag, was_added);
if (*was_added) {
locals_.Add(result);
has_static_private_methods_ |=
......@@ -2683,7 +2683,7 @@ Variable* ClassScope::LookupPrivateNameInScopeInfo(const AstRawString* name) {
DCHECK(IsConstVariableMode(mode));
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
// lookups for the same name.
......@@ -2812,7 +2812,7 @@ Variable* ClassScope::DeclareBrandVariable(AstValueFactory* ast_value_factory,
Variable* brand = Declare(zone(), ast_value_factory->dot_brand_string(),
VariableMode::kConst, NORMAL_VARIABLE,
InitializationFlag::kNeedsInitialization,
MaybeAssignedFlag::kMaybeAssigned, &was_added);
MaybeAssignedFlag::kNotAssigned, &was_added);
DCHECK(was_added);
brand->set_is_static_flag(is_static_flag);
brand->ForceContextAllocation();
......
......@@ -90,7 +90,10 @@ class Variable final : public ZoneObject {
}
void SetMaybeAssigned() {
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
// variable could also be assigned (in the non-shadowing case).
if (has_local_if_not_shadowed()) {
......
......@@ -26,14 +26,14 @@ frame size: 7
parameter count: 1
bytecode array length: 97
bytecodes: [
B(LdaCurrentContextSlot), U8(3),
B(LdaImmutableCurrentContextSlot), U8(3),
B(Star), R(1),
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
/* 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(LdaCurrentContextSlot), U8(3),
B(LdaImmutableCurrentContextSlot), U8(3),
/* 81 E> */ B(LdaKeyedProperty), R(this), U8(0),
B(CallRuntime), U16(Runtime::kLoadPrivateGetter), R(4), U8(1),
B(Star), R(5),
......@@ -45,16 +45,16 @@ bytecodes: [
B(CallProperty1), R(6), R(this), R(5), U8(5),
/* 91 S> */ B(LdaSmi), I8(1),
B(Star), R(3),
B(LdaCurrentContextSlot), U8(2),
B(LdaImmutableCurrentContextSlot), U8(2),
B(Star), R(5),
B(LdaCurrentContextSlot), U8(3),
B(LdaImmutableCurrentContextSlot), U8(3),
/* 96 E> */ B(LdaKeyedProperty), R(this), U8(7),
B(CallRuntime), U16(Runtime::kLoadPrivateSetter), R(5), U8(1),
B(Star), R(6),
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(LdaCurrentContextSlot), U8(3),
B(LdaImmutableCurrentContextSlot), U8(3),
/* 120 E> */ B(LdaKeyedProperty), R(this), U8(11),
B(CallRuntime), U16(Runtime::kLoadPrivateGetter), R(4), U8(1),
B(Star), R(5),
......@@ -79,7 +79,7 @@ frame size: 5
parameter count: 1
bytecode array length: 31
bytecodes: [
B(LdaCurrentContextSlot), U8(3),
B(LdaImmutableCurrentContextSlot), U8(3),
B(Star), R(1),
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
......@@ -110,7 +110,7 @@ frame size: 5
parameter count: 1
bytecode array length: 31
bytecodes: [
B(LdaCurrentContextSlot), U8(3),
B(LdaImmutableCurrentContextSlot), U8(3),
B(Star), R(1),
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
......@@ -141,7 +141,7 @@ frame size: 5
parameter count: 1
bytecode array length: 31
bytecodes: [
B(LdaCurrentContextSlot), U8(3),
B(LdaImmutableCurrentContextSlot), U8(3),
B(Star), R(1),
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
......@@ -172,7 +172,7 @@ frame size: 6
parameter count: 1
bytecode array length: 31
bytecodes: [
B(LdaCurrentContextSlot), U8(3),
B(LdaImmutableCurrentContextSlot), U8(3),
B(Star), R(1),
B(Mov), R(this), R(0),
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
parameter count: 1
bytecode array length: 30
bytecodes: [
B(LdaCurrentContextSlot), U8(3),
B(LdaImmutableCurrentContextSlot), U8(3),
B(Star), R(1),
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
/* 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),
B(LdaCurrentContextSlot), U8(2),
B(LdaImmutableCurrentContextSlot), U8(2),
B(Star), R(3),
/* 63 E> */ B(CallAnyReceiver), R(3), R(this), U8(1), U8(2),
/* 66 S> */ B(Return),
......@@ -52,7 +52,7 @@ frame size: 5
parameter count: 1
bytecode array length: 31
bytecodes: [
B(LdaCurrentContextSlot), U8(3),
B(LdaImmutableCurrentContextSlot), U8(3),
B(Star), R(1),
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
......@@ -84,7 +84,7 @@ frame size: 5
parameter count: 1
bytecode array length: 31
bytecodes: [
B(LdaCurrentContextSlot), U8(3),
B(LdaImmutableCurrentContextSlot), U8(3),
B(Star), R(1),
B(Mov), R(this), R(0),
B(Mov), R(context), R(2),
......@@ -120,7 +120,7 @@ bytecodes: [
B(PushContext), R(0),
B(Ldar), R(this),
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(Mov), R(this), R(1),
B(Mov), R(0), R(3),
......@@ -129,9 +129,9 @@ bytecodes: [
B(Star), R(5),
/* 61 E> */ B(CallUndefinedReceiver0), R(5), U8(0),
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),
B(LdaContextSlot), R(0), U8(2), U8(0),
B(LdaImmutableContextSlot), R(0), U8(2), U8(0),
B(Star), R(4),
/* 66 E> */ B(CallAnyReceiver), R(4), R(5), U8(1), U8(4),
B(LdaUndefined),
......
......@@ -31,7 +31,7 @@ bytecodes: [
B(Star), R(3),
B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2),
B(Throw),
B(LdaCurrentContextSlot), U8(2),
B(LdaImmutableCurrentContextSlot), U8(2),
B(Star), R(0),
/* 70 E> */ B(CallAnyReceiver), R(0), R(1), U8(1), U8(0),
/* 73 S> */ B(Return),
......@@ -116,7 +116,7 @@ frame size: 5
parameter count: 1
bytecode array length: 142
bytecodes: [
/* 90 S> */ B(LdaCurrentContextSlot), U8(2),
/* 90 S> */ B(LdaImmutableCurrentContextSlot), U8(2),
B(Star), R(1),
B(LdaCurrentContextSlot), U8(3),
/* 94 E> */ B(TestReferenceEqual), R(this),
......@@ -138,7 +138,7 @@ bytecodes: [
B(CallProperty1), R(3), R(0), R(2), U8(3),
/* 105 S> */ B(LdaSmi), I8(1),
B(Star), R(0),
B(LdaCurrentContextSlot), U8(2),
B(LdaImmutableCurrentContextSlot), U8(2),
B(Star), R(2),
B(LdaCurrentContextSlot), U8(3),
/* 109 E> */ B(TestReferenceEqual), R(this),
......@@ -153,7 +153,7 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kLoadPrivateSetter), R(2), U8(1),
B(Star), R(3),
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(LdaCurrentContextSlot), U8(3),
/* 133 E> */ B(TestReferenceEqual), R(this),
......
......@@ -2756,6 +2756,42 @@ TEST(PrivateClassFields) {
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) {
bool old_methods_flag = i::FLAG_harmony_private_methods;
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