[class] implement static private methods

This patch refactors the declaration and allocation of the class variable, and
implements static private methods:


- The class variable is declared in the class scope with an explicit
  reference through class_scope->class_variable(). Anonymous classes
  whose class variable may be accessed transitively through static
  private method access use the dot string as the class name. Whether
  the class variable is allocated depending on whether it is used.
  Other references of the class variable in the ClassLiteral AST node
  and the ClassInfo structure are removed in favor of the reference
  through the class scope.
- Previously the class variable was always (stack- or context-)
  allocated if the class is named. Now if the class variable is only
  referenced by name, it's stack allocated. If it's used transitively
  by access to static private methods, or may be used through eval,
  it's context allocated. Therefore we now use 1 less context slots
  in the class context if it's a named class without anyone referencing
  it by name in inner scopes.
- Explicit access to static private methods or potential access to
  static private methods through eval results in forced context
  allocation of the class variables. In those cases, we save its index
  in context locals in the ScopeInfo and deserialize it later, so that
  we can check that the receiver of static private methods is the class
  constructor at run time. This flag is recorded as
  HasSavedClassVariableIndexField in the scope info.
- Classes that need the class variable to be saved due to
  access to static private methods now save a
  ShouldSaveClassVariableIndexField in the preparse data so that the
  bits on the variables can be updated during a reparse. In the case
  of anonymous classes that need the class variables to be saved,
  we also re-declare the class variable after the reparse since
  the inner functions are skipped and we need to rely on the preparse
  data flags to remember declaring it.

Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit

Bug: v8:8330
Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011
Commit-Queue: Joyee Cheung <joyee@igalia.com>
Reviewed-by: Mythri Alle <mythria@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64219}
This commit is contained in:
Joyee Cheung 2019-10-10 22:33:02 +08:00 committed by Commit Bot
parent 939e18feac
commit 4e8c62819a
27 changed files with 1642 additions and 936 deletions

View File

@ -2490,7 +2490,6 @@ class ClassLiteral final : public Expression {
using Property = ClassLiteralProperty;
ClassScope* scope() const { return scope_; }
Variable* class_variable() const { return class_variable_; }
Expression* extends() const { return extends_; }
FunctionLiteral* constructor() const { return constructor_; }
ZonePtrList<Property>* properties() const { return properties_; }
@ -2521,7 +2520,7 @@ class ClassLiteral final : public Expression {
private:
friend class AstNodeFactory;
ClassLiteral(ClassScope* scope, Variable* class_variable, Expression* extends,
ClassLiteral(ClassScope* scope, Expression* extends,
FunctionLiteral* constructor, ZonePtrList<Property>* properties,
FunctionLiteral* static_fields_initializer,
FunctionLiteral* instance_members_initializer_function,
@ -2531,7 +2530,6 @@ class ClassLiteral final : public Expression {
: Expression(start_position, kClassLiteral),
end_position_(end_position),
scope_(scope),
class_variable_(class_variable),
extends_(extends),
constructor_(constructor),
properties_(properties),
@ -2545,7 +2543,6 @@ class ClassLiteral final : public Expression {
int end_position_;
ClassScope* scope_;
Variable* class_variable_;
Expression* extends_;
FunctionLiteral* constructor_;
ZonePtrList<Property>* properties_;
@ -3259,18 +3256,16 @@ class AstNodeFactory final {
}
ClassLiteral* NewClassLiteral(
ClassScope* scope, Variable* variable, Expression* extends,
FunctionLiteral* constructor,
ClassScope* scope, Expression* extends, FunctionLiteral* constructor,
ZonePtrList<ClassLiteral::Property>* properties,
FunctionLiteral* static_fields_initializer,
FunctionLiteral* instance_members_initializer_function,
int start_position, int end_position, bool has_name_static_property,
bool has_static_computed_names, bool is_anonymous) {
return new (zone_) ClassLiteral(
scope, variable, extends, constructor, properties,
static_fields_initializer, instance_members_initializer_function,
start_position, end_position, has_name_static_property,
has_static_computed_names, is_anonymous);
scope, extends, constructor, properties, static_fields_initializer,
instance_members_initializer_function, start_position, end_position,
has_name_static_property, has_static_computed_names, is_anonymous);
}
NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name,

View File

@ -144,13 +144,15 @@ ModuleScope::ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info,
set_language_mode(LanguageMode::kStrict);
}
ClassScope::ClassScope(Zone* zone, Scope* outer_scope)
ClassScope::ClassScope(Zone* zone, Scope* outer_scope, bool is_anonymous)
: Scope(zone, outer_scope, CLASS_SCOPE),
rare_data_and_is_parsing_heritage_(nullptr) {
rare_data_and_is_parsing_heritage_(nullptr),
is_anonymous_class_(is_anonymous) {
set_language_mode(LanguageMode::kStrict);
}
ClassScope::ClassScope(Zone* zone, AstValueFactory* ast_value_factory,
ClassScope::ClassScope(Isolate* isolate, Zone* zone,
AstValueFactory* ast_value_factory,
Handle<ScopeInfo> scope_info)
: Scope(zone, CLASS_SCOPE, scope_info),
rare_data_and_is_parsing_heritage_(nullptr) {
@ -161,6 +163,25 @@ ClassScope::ClassScope(Zone* zone, AstValueFactory* ast_value_factory,
DCHECK_NOT_NULL(brand);
EnsureRareData()->brand = brand;
}
// If the class variable is context-allocated and its index is
// saved for deserialization, deserialize it.
if (scope_info->HasSavedClassVariableIndex()) {
int index = scope_info->SavedClassVariableContextLocalIndex();
DCHECK_GE(index, 0);
DCHECK_LT(index, scope_info->ContextLocalCount());
String name = scope_info->ContextLocalName(index);
DCHECK_EQ(scope_info->ContextLocalMode(index), VariableMode::kConst);
DCHECK_EQ(scope_info->ContextLocalInitFlag(index),
InitializationFlag::kNeedsInitialization);
DCHECK_EQ(scope_info->ContextLocalMaybeAssignedFlag(index),
MaybeAssignedFlag::kMaybeAssigned);
Variable* var = DeclareClassVariable(
ast_value_factory, ast_value_factory->GetString(handle(name, isolate)),
kNoSourcePosition);
var->AllocateTo(VariableLocation::CONTEXT,
Context::MIN_CONTEXT_SLOTS + index);
}
}
Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info)
@ -358,8 +379,8 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
outer_scope = new (zone)
DeclarationScope(zone, EVAL_SCOPE, handle(scope_info, isolate));
} else if (scope_info.scope_type() == CLASS_SCOPE) {
outer_scope = new (zone)
ClassScope(zone, ast_value_factory, handle(scope_info, isolate));
outer_scope = new (zone) ClassScope(isolate, zone, ast_value_factory,
handle(scope_info, isolate));
} else if (scope_info.scope_type() == BLOCK_SCOPE) {
if (scope_info.is_declaration_scope()) {
outer_scope = new (zone)
@ -561,7 +582,8 @@ bool DeclarationScope::Analyze(ParseInfo* info) {
if (scope->must_use_preparsed_scope_data_) {
DCHECK_EQ(scope->scope_type_, ScopeType::FUNCTION_SCOPE);
allow_deref.emplace();
info->consumed_preparse_data()->RestoreScopeAllocationData(scope);
info->consumed_preparse_data()->RestoreScopeAllocationData(
scope, info->ast_value_factory());
}
if (!scope->AllocateVariables(info)) return false;
@ -1750,6 +1772,15 @@ void Scope::Print(int n) {
PrintVar(n1, brand);
}
}
if (class_scope->class_variable() != nullptr) {
Indent(n1, "// class var");
PrintF("%s%s:\n",
class_scope->class_variable()->is_used() ? ", used" : ", unused",
class_scope->should_save_class_variable_index()
? ", index saved"
: ", index not saved");
PrintVar(n1, class_scope->class_variable());
}
}
// Print inner scopes (disable by providing negative n).
@ -2115,8 +2146,7 @@ bool Scope::MustAllocateInContext(Variable* var) {
if (mode == VariableMode::kTemporary) return false;
if (is_catch_scope()) return true;
if (is_script_scope() || is_eval_scope()) {
if (IsLexicalVariableMode(mode) ||
IsPrivateMethodOrAccessorVariableMode(mode)) {
if (IsLexicalVariableMode(mode)) {
return true;
}
}
@ -2424,6 +2454,9 @@ Variable* ClassScope::DeclarePrivateName(const AstRawString* name,
MaybeAssignedFlag::kMaybeAssigned, is_static_flag, was_added);
if (*was_added) {
locals_.Add(result);
has_static_private_methods_ |=
(result->is_static() &&
IsPrivateMethodOrAccessorVariableMode(result->mode()));
} else if (IsComplementaryAccessorPair(result->mode(), mode) &&
result->is_static_flag() == is_static_flag) {
*was_added = true;
@ -2554,13 +2587,15 @@ bool ClassScope::ResolvePrivateNames(ParseInfo* info) {
for (VariableProxy* proxy : list) {
Variable* var = LookupPrivateName(proxy);
if (var == nullptr) {
// It's only possible to fail to resolve private names here if
// this is at the top level or the private name is accessed through eval.
DCHECK(info->is_eval() || outer_scope_->is_script_scope());
Scanner::Location loc = proxy->location();
info->pending_error_handler()->ReportMessageAt(
loc.beg_pos, loc.end_pos,
MessageTemplate::kInvalidPrivateFieldResolution, proxy->raw_name());
return false;
} else {
var->set_is_used();
proxy->BindTo(var);
}
}
@ -2603,6 +2638,12 @@ VariableProxy* ClassScope::ResolvePrivateNamesPartially() {
if (var != nullptr) {
var->set_is_used();
proxy->BindTo(var);
// If the variable being accessed is a static private method, we need to
// save the class variable in the context to check that the receiver is
// the class during runtime.
has_explicit_static_private_methods_access_ |=
(var->is_static() &&
IsPrivateMethodOrAccessorVariableMode(var->mode()));
}
}
@ -2645,6 +2686,21 @@ Variable* ClassScope::DeclareBrandVariable(AstValueFactory* ast_value_factory,
return brand;
}
Variable* ClassScope::DeclareClassVariable(AstValueFactory* ast_value_factory,
const AstRawString* name,
int class_token_pos) {
DCHECK_NULL(class_variable_);
bool was_added;
class_variable_ =
Declare(zone(), name == nullptr ? ast_value_factory->dot_string() : name,
VariableMode::kConst, NORMAL_VARIABLE,
InitializationFlag::kNeedsInitialization,
MaybeAssignedFlag::kMaybeAssigned, &was_added);
DCHECK(was_added);
class_variable_->set_initializer_position(class_token_pos);
return class_variable_;
}
PrivateNameScopeIterator::PrivateNameScopeIterator(Scope* start)
: start_scope_(start), current_scope_(start) {
if (!start->is_class_scope() || start->AsClassScope()->IsParsingHeritage()) {

View File

@ -1246,9 +1246,9 @@ class ModuleScope final : public DeclarationScope {
class V8_EXPORT_PRIVATE ClassScope : public Scope {
public:
ClassScope(Zone* zone, Scope* outer_scope);
ClassScope(Zone* zone, Scope* outer_scope, bool is_anonymous);
// Deserialization.
ClassScope(Zone* zone, AstValueFactory* ast_value_factory,
ClassScope(Isolate* isolate, Zone* zone, AstValueFactory* ast_value_factory,
Handle<ScopeInfo> scope_info);
struct HeritageParsingScope {
@ -1298,14 +1298,47 @@ class V8_EXPORT_PRIVATE ClassScope : public Scope {
Variable* DeclareBrandVariable(AstValueFactory* ast_value_factory,
IsStaticFlag is_static_flag,
int class_token_pos);
Variable* DeclareClassVariable(AstValueFactory* ast_value_factory,
const AstRawString* name, int class_token_pos);
Variable* brand() {
return GetRareData() == nullptr ? nullptr : GetRareData()->brand;
}
Variable* class_variable() { return class_variable_; }
V8_INLINE bool IsParsingHeritage() {
return rare_data_and_is_parsing_heritage_.GetPayload();
}
// Only maintained when the scope is parsed, not when the scope is
// deserialized.
bool has_static_private_methods() const {
return has_static_private_methods_;
}
// Returns whether the index of class variable of this class scope should be
// recorded in the ScopeInfo.
// If any inner scope accesses static private names directly, the class
// variable will be forced to be context-allocated.
// The inner scope may also calls eval which may results in access to
// static private names.
// Only maintained when the scope is parsed.
bool should_save_class_variable_index() const {
return should_save_class_variable_index_ ||
has_explicit_static_private_methods_access_ ||
(has_static_private_methods_ && inner_scope_calls_eval_);
}
// Only maintained when the scope is parsed.
bool is_anonymous_class() const { return is_anonymous_class_; }
// Overriden during reparsing
void set_should_save_class_variable_index() {
should_save_class_variable_index_ = true;
}
private:
friend class Scope;
friend class PrivateNameScopeIterator;
@ -1342,6 +1375,15 @@ class V8_EXPORT_PRIVATE ClassScope : public Scope {
}
PointerWithPayload<RareData, bool, 1> rare_data_and_is_parsing_heritage_;
Variable* class_variable_ = nullptr;
// These are only maintained when the scope is parsed, not when the
// scope is deserialized.
bool has_static_private_methods_ = false;
bool has_explicit_static_private_methods_access_ = false;
bool is_anonymous_class_ = false;
// This is only maintained during reparsing, restored from the
// preparsed data.
bool should_save_class_variable_index_ = false;
};
// Iterate over the private name scope chain. The iteration proceeds from the

View File

@ -2285,6 +2285,7 @@ void ScopeInfo::ScopeInfoPrint(std::ostream& os) { // NOLINT
os << "\n - receiver: " << ReceiverVariableField::decode(flags);
}
if (HasClassBrand()) os << "\n - has class brand";
if (HasSavedClassVariableIndex()) os << "\n - has saved class variable index";
if (HasNewTarget()) os << "\n - needs new target";
if (HasFunctionName()) {
os << "\n - function name(" << FunctionVariableField::decode(flags)

View File

@ -2160,22 +2160,22 @@ void BytecodeGenerator::BuildClassLiteral(ClassLiteral* expr, Register name) {
builder()->StoreAccumulatorInRegister(prototype);
// Assign to class variable.
if (expr->class_variable() != nullptr) {
DCHECK(expr->class_variable()->IsStackLocal() ||
expr->class_variable()->IsContextSlot());
Variable* class_variable = expr->scope()->class_variable();
if (class_variable != nullptr && class_variable->is_used()) {
DCHECK(class_variable->IsStackLocal() || class_variable->IsContextSlot());
builder()->LoadAccumulatorWithRegister(class_constructor);
BuildVariableAssignment(expr->class_variable(), Token::INIT,
BuildVariableAssignment(class_variable, Token::INIT,
HoleCheckMode::kElided);
}
// Create the class brand symbol and store it on the context
// during class evaluation. This will be stored in the
// receiver later in the constructor.
// during class evaluation. The instance brand will be stored in the
// instance later in the constructor.
if (expr->scope()->brand() != nullptr) {
Register brand = register_allocator()->NewRegister();
const AstRawString* class_name =
expr->class_variable() != nullptr
? expr->class_variable()->raw_name()
expr->scope()->class_variable() != nullptr
? expr->scope()->class_variable()->raw_name()
: ast_string_constants()->empty_string();
builder()
->LoadLiteral(class_name)
@ -2183,37 +2183,41 @@ void BytecodeGenerator::BuildClassLiteral(ClassLiteral* expr, Register name) {
.CallRuntime(Runtime::kCreatePrivateNameSymbol, brand);
BuildVariableAssignment(expr->scope()->brand(), Token::INIT,
HoleCheckMode::kElided);
// Store the home object for any private methods that need
// them. We do this here once the prototype and brand symbol has
// been created. Private accessors have their home object set later
// when they are defined.
for (int i = 0; i < expr->properties()->length(); i++) {
}
// Store the home object for any private methods that need
// them. We do this here once the prototype and brand symbol has
// been created. Private accessors have their home object set later
// when they are defined.
for (int i = 0; i < expr->properties()->length(); i++) {
ClassLiteral::Property* property = expr->properties()->at(i);
if (property->NeedsHomeObjectOnClassPrototype()) {
RegisterAllocationScope register_scope(this);
ClassLiteral::Property* property = expr->properties()->at(i);
if (property->NeedsHomeObjectOnClassPrototype()) {
Register func = register_allocator()->NewRegister();
BuildVariableLoad(property->private_name_var(), HoleCheckMode::kElided);
builder()->StoreAccumulatorInRegister(func);
VisitSetHomeObject(func, prototype, property);
}
Register home_object =
property->is_static() ? class_constructor : prototype;
Register func = register_allocator()->NewRegister();
BuildVariableLoad(property->private_name_var(), HoleCheckMode::kElided);
builder()->StoreAccumulatorInRegister(func);
VisitSetHomeObject(func, home_object, property);
}
}
// Define accessors, using only a single call to the runtime for each pair
// of corresponding getters and setters.
for (auto accessors : private_accessors.ordered_accessors()) {
RegisterAllocationScope inner_register_scope(this);
RegisterList accessors_reg = register_allocator()->NewRegisterList(2);
ClassLiteral::Property* getter = accessors.second->getter;
ClassLiteral::Property* setter = accessors.second->setter;
VisitLiteralAccessor(prototype, getter, accessors_reg[0]);
VisitLiteralAccessor(prototype, setter, accessors_reg[1]);
builder()->CallRuntime(Runtime::kCreatePrivateAccessors, accessors_reg);
Variable* var = getter != nullptr ? getter->private_name_var()
: setter->private_name_var();
DCHECK_NOT_NULL(var);
BuildVariableAssignment(var, Token::INIT, HoleCheckMode::kElided);
}
// Define accessors, using only a single call to the runtime for each pair
// of corresponding getters and setters.
for (auto accessors : private_accessors.ordered_accessors()) {
RegisterAllocationScope inner_register_scope(this);
RegisterList accessors_reg = register_allocator()->NewRegisterList(2);
ClassLiteral::Property* getter = accessors.second->getter;
ClassLiteral::Property* setter = accessors.second->setter;
bool is_static =
getter != nullptr ? getter->is_static() : setter->is_static();
Register home_object = is_static ? class_constructor : prototype;
VisitLiteralAccessor(home_object, getter, accessors_reg[0]);
VisitLiteralAccessor(home_object, setter, accessors_reg[1]);
builder()->CallRuntime(Runtime::kCreatePrivateAccessors, accessors_reg);
Variable* var = getter != nullptr ? getter->private_name_var()
: setter->private_name_var();
DCHECK_NOT_NULL(var);
BuildVariableAssignment(var, Token::INIT, HoleCheckMode::kElided);
}
if (expr->instance_members_initializer_function() != nullptr) {
@ -3922,7 +3926,8 @@ void BytecodeGenerator::BuildAssignment(
Property* property = lhs_data.expr()->AsProperty();
Register object = VisitForRegisterValue(property->obj());
Register key = VisitForRegisterValue(property->key());
BuildPrivateBrandCheck(property, object);
BuildPrivateBrandCheck(property, object,
MessageTemplate::kInvalidPrivateMemberWrite);
BuildPrivateSetterAccess(object, key, value);
if (!execution_result()->IsEffect()) {
builder()->LoadAccumulatorWithRegister(value);
@ -4455,12 +4460,14 @@ void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* property) {
case PRIVATE_GETTER_ONLY:
case PRIVATE_GETTER_AND_SETTER: {
Register key = VisitForRegisterValue(property->key());
BuildPrivateBrandCheck(property, obj);
BuildPrivateBrandCheck(property, obj,
MessageTemplate::kInvalidPrivateMemberRead);
BuildPrivateGetterAccess(obj, key);
break;
}
case PRIVATE_METHOD: {
BuildPrivateBrandCheck(property, obj);
BuildPrivateBrandCheck(property, obj,
MessageTemplate::kInvalidPrivateMemberRead);
// In the case of private methods, property->key() is the function to be
// loaded (stored in a context slot), so load this directly.
VisitForAccumulatorValue(property->key());
@ -4500,15 +4507,29 @@ void BytecodeGenerator::BuildPrivateSetterAccess(Register object,
}
void BytecodeGenerator::BuildPrivateBrandCheck(Property* property,
Register object) {
Register object,
MessageTemplate tmpl) {
Variable* private_name = property->key()->AsVariableProxy()->var();
DCHECK(private_name->requires_brand_check());
DCHECK(IsPrivateMethodOrAccessorVariableMode(private_name->mode()));
ClassScope* scope = private_name->scope()->AsClassScope();
Variable* brand = scope->brand();
BuildVariableLoadForAccumulatorValue(brand, HoleCheckMode::kElided);
builder()->SetExpressionPosition(property);
builder()->LoadKeyedProperty(
object, feedback_index(feedback_spec()->AddKeyedLoadICSlot()));
if (private_name->is_static()) {
DCHECK_NOT_NULL(scope->class_variable());
// For static private methods, the only valid receiver is the class.
// Load the class constructor.
BuildVariableLoadForAccumulatorValue(scope->class_variable(),
HoleCheckMode::kElided);
BytecodeLabel return_check;
builder()->CompareReference(object).JumpIfTrue(
ToBooleanMode::kAlreadyBoolean, &return_check);
BuildInvalidPropertyAccess(tmpl, property);
builder()->Bind(&return_check);
} else {
BuildVariableLoadForAccumulatorValue(scope->brand(),
HoleCheckMode::kElided);
builder()->SetExpressionPosition(property);
builder()->LoadKeyedProperty(
object, feedback_index(feedback_spec()->AddKeyedLoadICSlot()));
}
}
void BytecodeGenerator::VisitPropertyLoadForRegister(Register obj,
@ -5114,7 +5135,8 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
case PRIVATE_GETTER_AND_SETTER: {
object = VisitForRegisterValue(property->obj());
key = VisitForRegisterValue(property->key());
BuildPrivateBrandCheck(property, object);
BuildPrivateBrandCheck(property, object,
MessageTemplate::kInvalidPrivateMemberRead);
BuildPrivateGetterAccess(object, key);
break;
}

View File

@ -301,10 +301,13 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
void VisitRestArgumentsArray(Variable* rest);
void VisitCallSuper(Call* call);
void BuildInvalidPropertyAccess(MessageTemplate tmpl, Property* property);
void BuildPrivateBrandCheck(Property* property, Register object);
void BuildPrivateBrandCheck(Property* property, Register object,
MessageTemplate tmpl);
void BuildPrivateGetterAccess(Register obj, Register access_pair);
void BuildPrivateSetterAccess(Register obj, Register access_pair,
Register value);
void BuildPrivateMethods(ClassLiteral* expr, bool is_static,
Register home_object);
void BuildClassLiteral(ClassLiteral* expr, Register name);
void VisitClassLiteral(ClassLiteral* expr, Register name);
void VisitNewTargetVariable(Variable* variable);

View File

@ -138,6 +138,10 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
const bool has_brand = scope->is_class_scope()
? scope->AsClassScope()->brand() != nullptr
: false;
const bool should_save_class_variable_index =
scope->is_class_scope()
? scope->AsClassScope()->should_save_class_variable_index()
: false;
const bool has_function_name = function_name_info != NONE;
const bool has_position_info = NeedsPositionInfo(scope->scope_type());
const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT;
@ -148,6 +152,7 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
const bool has_outer_scope_info = !outer_scope.is_null();
const int length = kVariablePartIndex + 2 * context_local_count +
(should_save_class_variable_index ? 1 : 0) +
(has_receiver ? 1 : 0) +
(has_function_name ? kFunctionNameEntries : 0) +
(has_inferred_function_name ? 1 : 0) +
@ -191,6 +196,8 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
DeclarationScopeField::encode(scope->is_declaration_scope()) |
ReceiverVariableField::encode(receiver_info) |
HasClassBrandField::encode(has_brand) |
HasSavedClassVariableIndexField::encode(
should_save_class_variable_index) |
HasNewTargetField::encode(has_new_target) |
FunctionVariableField::encode(function_name_info) |
HasInferredFunctionNameField::encode(has_inferred_function_name) |
@ -293,6 +300,16 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
index += 2 * context_local_count;
DCHECK_EQ(index, scope_info.SavedClassVariableInfoIndex());
// If the scope is a class scope and has used static private methods, save
// the context slot index of the class variable.
// Store the class variable index.
if (should_save_class_variable_index) {
Variable* class_variable = scope->AsClassScope()->class_variable();
DCHECK_EQ(class_variable->location(), VariableLocation::CONTEXT);
scope_info.set(index++, Smi::FromInt(class_variable->index()));
}
// If the receiver is allocated, add its index.
DCHECK_EQ(index, scope_info.ReceiverInfoIndex());
if (has_receiver) {
@ -372,6 +389,7 @@ Handle<ScopeInfo> ScopeInfo::CreateForWithScope(
LanguageModeField::encode(LanguageMode::kSloppy) |
DeclarationScopeField::encode(false) |
ReceiverVariableField::encode(NONE) | HasClassBrandField::encode(false) |
HasSavedClassVariableIndexField::encode(false) |
HasNewTargetField::encode(false) | FunctionVariableField::encode(NONE) |
IsAsmModuleField::encode(false) | HasSimpleParametersField::encode(true) |
FunctionKindField::encode(kNormalFunction) |
@ -438,7 +456,9 @@ Handle<ScopeInfo> ScopeInfo::CreateForBootstrapping(Isolate* isolate,
LanguageModeField::encode(LanguageMode::kSloppy) |
DeclarationScopeField::encode(true) |
ReceiverVariableField::encode(is_empty_function ? UNUSED : CONTEXT) |
HasClassBrandField::encode(false) | HasNewTargetField::encode(false) |
HasClassBrandField::encode(false) |
HasSavedClassVariableIndexField::encode(false) |
HasNewTargetField::encode(false) |
FunctionVariableField::encode(is_empty_function ? UNUSED : NONE) |
HasInferredFunctionNameField::encode(has_inferred_function_name) |
IsAsmModuleField::encode(false) | HasSimpleParametersField::encode(true) |
@ -566,6 +586,10 @@ bool ScopeInfo::HasClassBrand() const {
return HasClassBrandField::decode(Flags());
}
bool ScopeInfo::HasSavedClassVariableIndex() const {
return HasSavedClassVariableIndexField::decode(Flags());
}
bool ScopeInfo::HasNewTarget() const {
return HasNewTargetField::decode(Flags());
}
@ -807,6 +831,14 @@ int ScopeInfo::ContextSlotIndex(ScopeInfo scope_info, String name,
return -1;
}
int ScopeInfo::SavedClassVariableContextLocalIndex() const {
if (length() > 0 && HasSavedClassVariableIndexField::decode(Flags())) {
int index = Smi::ToInt(get(SavedClassVariableInfoIndex()));
return index - Context::MIN_CONTEXT_SLOTS;
}
return -1;
}
int ScopeInfo::ReceiverContextSlotIndex() const {
if (length() > 0 && ReceiverVariableField::decode(Flags()) == CONTEXT) {
return Smi::ToInt(get(ReceiverInfoIndex()));
@ -838,10 +870,14 @@ int ScopeInfo::ContextLocalInfosIndex() const {
return ContextLocalNamesIndex() + ContextLocalCount();
}
int ScopeInfo::ReceiverInfoIndex() const {
int ScopeInfo::SavedClassVariableInfoIndex() const {
return ContextLocalInfosIndex() + ContextLocalCount();
}
int ScopeInfo::ReceiverInfoIndex() const {
return SavedClassVariableInfoIndex() + (HasSavedClassVariableIndex() ? 1 : 0);
}
int ScopeInfo::FunctionNameInfoIndex() const {
return ReceiverInfoIndex() + (HasAllocatedReceiver() ? 1 : 0);
}

View File

@ -75,6 +75,10 @@ class ScopeInfo : public FixedArray {
// Does this scope has class brand (for private methods)?
bool HasClassBrand() const;
// Does this scope contains a saved class variable context local slot index
// for checking receivers of static private methods?
bool HasSavedClassVariableIndex() const;
// Does this scope declare a "new.target" binding?
bool HasNewTarget() const;
@ -168,6 +172,12 @@ class ScopeInfo : public FixedArray {
// context-allocated. Otherwise returns a value < 0.
int ReceiverContextSlotIndex() const;
// Lookup support for serialized scope info. Returns the index of the
// saved class variable in context local slots if scope is a class scope
// and it contains static private methods that may be accessed.
// Otherwise returns a value < 0.
int SavedClassVariableContextLocalIndex() const;
FunctionKind function_kind() const;
// Returns true if this ScopeInfo is linked to a outer ScopeInfo.
@ -239,7 +249,8 @@ class ScopeInfo : public FixedArray {
using ReceiverVariableField =
DeclarationScopeField::Next<VariableAllocationInfo, 2>;
using HasClassBrandField = ReceiverVariableField::Next<bool, 1>;
using HasNewTargetField = HasClassBrandField::Next<bool, 1>;
using HasSavedClassVariableIndexField = HasClassBrandField::Next<bool, 1>;
using HasNewTargetField = HasSavedClassVariableIndexField::Next<bool, 1>;
using FunctionVariableField =
HasNewTargetField::Next<VariableAllocationInfo, 2>;
// TODO(cbruni): Combine with function variable field when only storing the
@ -271,27 +282,32 @@ class ScopeInfo : public FixedArray {
// the context locals in ContextLocalNames. One slot is used per
// context local, so in total this part occupies ContextLocalCount()
// slots in the array.
// 3. ReceiverInfo:
// 3. SavedClassVariableInfo:
// If the scope is a class scope and it has static private methods that
// may be accessed directly or through eval, one slot is reserved to hold
// the context slot index for the class variable.
// 4. ReceiverInfo:
// If the scope binds a "this" value, one slot is reserved to hold the
// context or stack slot index for the variable.
// 4. FunctionNameInfo:
// 5. FunctionNameInfo:
// If the scope belongs to a named function expression this part contains
// information about the function variable. It always occupies two array
// slots: a. The name of the function variable.
// b. The context or stack slot index for the variable.
// 5. InferredFunctionName:
// 6. InferredFunctionName:
// Contains the function's inferred name.
// 6. SourcePosition:
// 7. SourcePosition:
// Contains two slots with a) the startPosition and b) the endPosition if
// the scope belongs to a function or script.
// 7. OuterScopeInfoIndex:
// 8. OuterScopeInfoIndex:
// The outer scope's ScopeInfo or the hole if there's none.
// 8. SourceTextModuleInfo, ModuleVariableCount, and ModuleVariables:
// 9. SourceTextModuleInfo, ModuleVariableCount, and ModuleVariables:
// For a module scope, this part contains the SourceTextModuleInfo, the
// number of MODULE-allocated variables, and the metadata of those
// variables. For non-module scopes it is empty.
int ContextLocalNamesIndex() const;
int ContextLocalInfosIndex() const;
int SavedClassVariableInfoIndex() const;
int ReceiverInfoIndex() const;
int FunctionNameInfoIndex() const;
int InferredFunctionNameIndex() const;

View File

@ -529,8 +529,7 @@ class ParserBase {
struct ClassInfo {
public:
explicit ClassInfo(ParserBase* parser)
: variable(nullptr),
extends(parser->impl()->NullExpression()),
: extends(parser->impl()->NullExpression()),
properties(parser->impl()->NewClassPropertyList(4)),
static_fields(parser->impl()->NewClassPropertyList(4)),
instance_fields(parser->impl()->NewClassPropertyList(4)),
@ -545,7 +544,6 @@ class ParserBase {
static_fields_scope(nullptr),
instance_members_scope(nullptr),
computed_field_count(0) {}
Variable* variable;
ExpressionT extends;
ClassPropertyListT properties;
ClassPropertyListT static_fields;
@ -672,8 +670,8 @@ class ParserBase {
return new (zone()) DeclarationScope(zone(), parent, EVAL_SCOPE);
}
ClassScope* NewClassScope(Scope* parent) const {
return new (zone()) ClassScope(zone(), parent);
ClassScope* NewClassScope(Scope* parent, bool is_anonymous) const {
return new (zone()) ClassScope(zone(), parent, is_anonymous);
}
Scope* NewScope(ScopeType scope_type) const {
@ -4392,13 +4390,12 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
}
}
ClassScope* class_scope = NewClassScope(scope());
ClassScope* class_scope = NewClassScope(scope(), is_anonymous);
BlockState block_state(&scope_, class_scope);
RaiseLanguageMode(LanguageMode::kStrict);
ClassInfo class_info(this);
class_info.is_anonymous = is_anonymous;
impl()->DeclareClassVariable(name, &class_info, class_token_pos);
scope()->set_start_position(end_position());
if (Check(Token::EXTENDS)) {
@ -4437,7 +4434,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
if (V8_UNLIKELY(prop_info.is_private)) {
DCHECK(!is_constructor);
class_info.requires_brand |= !is_field;
class_info.requires_brand |= (!is_field && !prop_info.is_static);
impl()->DeclarePrivateClassMember(class_scope, prop_info.name, property,
property_kind, prop_info.is_static,
&class_info);
@ -4481,6 +4478,17 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
ast_value_factory(), IsStaticFlag::kNotStatic, kNoSourcePosition);
}
bool should_save_class_variable_index =
class_scope->should_save_class_variable_index();
if (!is_anonymous || should_save_class_variable_index) {
impl()->DeclareClassVariable(class_scope, name, &class_info,
class_token_pos);
if (should_save_class_variable_index) {
class_scope->class_variable()->set_is_used();
class_scope->class_variable()->ForceContextAllocation();
}
}
return impl()->RewriteClassLiteral(class_scope, name, &class_info,
class_token_pos, end_pos);
}

View File

@ -2773,17 +2773,20 @@ void Parser::ParseFunction(
*suspend_count = function_state.suspend_count();
}
void Parser::DeclareClassVariable(const AstRawString* name,
void Parser::DeclareClassVariable(ClassScope* scope, const AstRawString* name,
ClassInfo* class_info, int class_token_pos) {
#ifdef DEBUG
scope()->SetScopeName(name);
scope->SetScopeName(name);
#endif
if (name != nullptr) {
VariableProxy* proxy =
DeclareBoundVariable(name, VariableMode::kConst, class_token_pos);
class_info->variable = proxy->var();
}
DCHECK_IMPLIES(name == nullptr, class_info->is_anonymous);
// Declare a special class variable for anonymous classes with the dot
// if we need to save it for static private method access.
Variable* class_variable =
scope->DeclareClassVariable(ast_value_factory(), name, class_token_pos);
Declaration* declaration = factory()->NewVariableDeclaration(class_token_pos);
scope->declarations()->Add(declaration);
declaration->set_var(class_variable);
}
// TODO(gsathya): Ideally, this should just bypass scope analysis and
@ -2932,8 +2935,8 @@ Expression* Parser::RewriteClassLiteral(ClassScope* block_scope,
}
if (name != nullptr) {
DCHECK_NOT_NULL(class_info->variable);
class_info->variable->set_initializer_position(end_pos);
DCHECK_NOT_NULL(block_scope->class_variable());
block_scope->class_variable()->set_initializer_position(end_pos);
}
FunctionLiteral* static_fields_initializer = nullptr;
@ -2954,10 +2957,10 @@ Expression* Parser::RewriteClassLiteral(ClassScope* block_scope,
}
ClassLiteral* class_literal = factory()->NewClassLiteral(
block_scope, class_info->variable, class_info->extends,
class_info->constructor, class_info->properties,
static_fields_initializer, instance_members_initializer_function, pos,
end_pos, class_info->has_name_static_property,
block_scope, class_info->extends, class_info->constructor,
class_info->properties, static_fields_initializer,
instance_members_initializer_function, pos, end_pos,
class_info->has_name_static_property,
class_info->has_static_computed_names, class_info->is_anonymous);
AddFunctionForNameInference(class_info->constructor);

View File

@ -316,8 +316,8 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
Statement* DeclareClass(const AstRawString* variable_name, Expression* value,
ZonePtrList<const AstRawString>* names,
int class_token_pos, int end_pos);
void DeclareClassVariable(const AstRawString* name, ClassInfo* class_info,
int class_token_pos);
void DeclareClassVariable(ClassScope* scope, const AstRawString* name,
ClassInfo* class_info, int class_token_pos);
void DeclareClassBrandVariable(ClassScope* scope, ClassInfo* class_info,
int class_token_pos);
void DeclarePrivateClassMember(ClassScope* scope,

View File

@ -157,16 +157,18 @@ class BaseConsumedPreparseData : public ConsumedPreparseData {
int* function_length, int* num_inner_functions, bool* uses_super_property,
LanguageMode* language_mode) final;
void RestoreScopeAllocationData(DeclarationScope* scope) final;
void RestoreScopeAllocationData(DeclarationScope* scope,
AstValueFactory* ast_value_factory) final;
#ifdef DEBUG
bool VerifyDataStart();
#endif
private:
void RestoreDataForScope(Scope* scope);
void RestoreDataForScope(Scope* scope, AstValueFactory* ast_value_factory);
void RestoreDataForVariable(Variable* var);
void RestoreDataForInnerScopes(Scope* scope);
void RestoreDataForInnerScopes(Scope* scope,
AstValueFactory* ast_value_factory);
std::unique_ptr<ByteData> scope_data_;
// When consuming the data, these indexes point to the data we're going to

View File

@ -28,6 +28,7 @@ using NeedsPrivateNameContextChainRecalcField =
InnerScopeCallsEvalField::Next<bool, 1>;
using CanElideThisHoleChecks =
NeedsPrivateNameContextChainRecalcField::Next<bool, 1>;
using ShouldSaveClassVariableIndexField = CanElideThisHoleChecks::Next<bool, 1>;
using VariableMaybeAssignedField = BitField8<bool, 0, 1>;
using VariableContextAllocatedField = VariableMaybeAssignedField::Next<bool, 1>;
@ -367,7 +368,10 @@ void PreparseDataBuilder::SaveDataForScope(Scope* scope) {
->needs_private_name_context_chain_recalc()) |
CanElideThisHoleChecks::encode(
scope->is_declaration_scope() &&
scope->AsDeclarationScope()->can_elide_this_hole_checks());
scope->AsDeclarationScope()->can_elide_this_hole_checks()) |
ShouldSaveClassVariableIndexField::encode(
scope->is_class_scope() &&
scope->AsClassScope()->should_save_class_variable_index());
byte_data_.Reserve(kUint8Size);
byte_data_.WriteUint8(scope_data_flags);
@ -573,7 +577,7 @@ BaseConsumedPreparseData<Data>::GetDataForSkippableFunction(
template <class Data>
void BaseConsumedPreparseData<Data>::RestoreScopeAllocationData(
DeclarationScope* scope) {
DeclarationScope* scope, AstValueFactory* ast_value_factory) {
DCHECK_EQ(scope->scope_type(), ScopeType::FUNCTION_SCOPE);
typename ByteData::ReadingScope reading_scope(this);
@ -588,14 +592,15 @@ void BaseConsumedPreparseData<Data>::RestoreScopeAllocationData(
DCHECK_EQ(end_position_from_data, scope->end_position());
#endif
RestoreDataForScope(scope);
RestoreDataForScope(scope, ast_value_factory);
// Check that we consumed all scope data.
DCHECK_EQ(scope_data_->RemainingBytes(), 0);
}
template <typename Data>
void BaseConsumedPreparseData<Data>::RestoreDataForScope(Scope* scope) {
void BaseConsumedPreparseData<Data>::RestoreDataForScope(
Scope* scope, AstValueFactory* ast_value_factory) {
if (scope->is_declaration_scope() &&
scope->AsDeclarationScope()->is_skipped_function()) {
return;
@ -623,17 +628,38 @@ void BaseConsumedPreparseData<Data>::RestoreDataForScope(Scope* scope) {
if (CanElideThisHoleChecks::decode(scope_data_flags)) {
scope->AsDeclarationScope()->set_can_elide_this_hole_checks();
}
if (ShouldSaveClassVariableIndexField::decode(scope_data_flags)) {
Variable* var;
// An anonymous class whose class variable needs to be saved do not
// have the class variable created during reparse since we skip parsing
// the inner scopes that contain potential access to static private
// methods. So create it now.
if (scope->AsClassScope()->is_anonymous_class()) {
var = scope->AsClassScope()->DeclareClassVariable(
ast_value_factory, nullptr, kNoSourcePosition);
AstNodeFactory factory(ast_value_factory, ast_value_factory->zone());
Declaration* declaration =
factory.NewVariableDeclaration(kNoSourcePosition);
scope->declarations()->Add(declaration);
declaration->set_var(var);
} else {
var = scope->AsClassScope()->class_variable();
DCHECK_NOT_NULL(var);
}
var->set_is_used();
var->ForceContextAllocation();
scope->AsClassScope()->set_should_save_class_variable_index();
}
if (scope->is_function_scope()) {
Variable* function = scope->AsDeclarationScope()->function_var();
if (function != nullptr) RestoreDataForVariable(function);
}
for (Variable* var : *scope->locals()) {
if (IsSerializableVariableMode(var->mode())) RestoreDataForVariable(var);
}
RestoreDataForInnerScopes(scope);
RestoreDataForInnerScopes(scope, ast_value_factory);
}
template <typename Data>
@ -672,10 +698,11 @@ void BaseConsumedPreparseData<Data>::RestoreDataForVariable(Variable* var) {
}
template <typename Data>
void BaseConsumedPreparseData<Data>::RestoreDataForInnerScopes(Scope* scope) {
void BaseConsumedPreparseData<Data>::RestoreDataForInnerScopes(
Scope* scope, AstValueFactory* ast_value_factory) {
for (Scope* inner = scope->inner_scope(); inner != nullptr;
inner = inner->sibling()) {
RestoreDataForScope(inner);
RestoreDataForScope(inner, ast_value_factory);
}
}

View File

@ -24,6 +24,7 @@ class Parser;
class PreParser;
class PreparseData;
class ZonePreparseData;
class AstValueFactory;
/*
@ -288,7 +289,8 @@ class ConsumedPreparseData {
// Restores the information needed for allocating the Scope's (and its
// subscopes') variables.
virtual void RestoreScopeAllocationData(DeclarationScope* scope) = 0;
virtual void RestoreScopeAllocationData(
DeclarationScope* scope, AstValueFactory* ast_value_factory) = 0;
protected:
ConsumedPreparseData() = default;

View File

@ -1227,14 +1227,15 @@ class PreParser : public ParserBase<PreParser> {
&was_added);
return PreParserStatement::Default();
}
V8_INLINE void DeclareClassVariable(const PreParserIdentifier& name,
V8_INLINE void DeclareClassVariable(ClassScope* scope,
const PreParserIdentifier& name,
ClassInfo* class_info,
int class_token_pos) {
if (!IsNull(name)) {
bool was_added;
DeclareVariableName(name.string_, VariableMode::kConst, scope(),
&was_added);
}
DCHECK_IMPLIES(IsNull(name), class_info->is_anonymous);
// Declare a special class variable for anonymous classes with the dot
// if we need to save it for static private method access.
scope->DeclareClassVariable(ast_value_factory(), name.string_,
class_token_pos);
}
V8_INLINE void DeclarePublicClassMethod(const PreParserIdentifier& class_name,
const PreParserExpression& property,

View File

@ -12,27 +12,26 @@ snippet: "
speak() { console.log(this.name + ' is speaking.'); }
}
"
frame size: 8
frame size: 7
parameter count: 1
bytecode array length: 44
bytecode array length: 41
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(2),
B(PushContext), R(1),
B(LdaTheHole),
B(Star), R(6),
B(Star), R(5),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(3),
B(Star), R(2),
B(LdaConstant), U8(1),
B(Star), R(4),
B(Star), R(3),
B(CreateClosure), U8(3), U8(1), U8(2),
B(Star), R(7),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4),
B(Star), R(4),
B(Mov), R(5), R(1),
B(PopContext), R(2),
B(Mov), R(1), R(0),
B(Star), R(6),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4),
B(Star), R(3),
B(PopContext), R(1),
B(Mov), R(4), R(0),
B(LdaUndefined),
/* 149 S> */ B(Return),
]
@ -52,27 +51,26 @@ snippet: "
speak() { console.log(this.name + ' is speaking.'); }
}
"
frame size: 8
frame size: 7
parameter count: 1
bytecode array length: 44
bytecode array length: 41
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(2),
B(PushContext), R(1),
B(LdaTheHole),
B(Star), R(6),
B(Star), R(5),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(3),
B(Star), R(2),
B(LdaConstant), U8(1),
B(Star), R(4),
B(Star), R(3),
B(CreateClosure), U8(3), U8(1), U8(2),
B(Star), R(7),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4),
B(Star), R(4),
B(Mov), R(5), R(1),
B(PopContext), R(2),
B(Mov), R(1), R(0),
B(Star), R(6),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4),
B(Star), R(3),
B(PopContext), R(1),
B(Mov), R(4), R(0),
B(LdaUndefined),
/* 149 S> */ B(Return),
]
@ -94,43 +92,42 @@ snippet: "
static [n1]() { return n1; }
}
"
frame size: 12
frame size: 11
parameter count: 1
bytecode array length: 87
bytecode array length: 84
bytecodes: [
B(CreateFunctionContext), U8(0), U8(2),
B(PushContext), R(2),
B(PushContext), R(1),
/* 30 E> */ B(StackCheck),
/* 43 S> */ B(LdaConstant), U8(1),
/* 43 E> */ B(StaCurrentContextSlot), U8(4),
/* 57 S> */ B(LdaConstant), U8(2),
/* 57 E> */ B(StaCurrentContextSlot), U8(5),
B(CreateBlockContext), U8(3),
B(PushContext), R(3),
B(PushContext), R(2),
B(LdaTheHole),
B(Star), R(7),
B(Star), R(6),
B(CreateClosure), U8(5), U8(0), U8(2),
B(Star), R(4),
B(Star), R(3),
B(LdaConstant), U8(4),
B(Star), R(5),
/* 75 S> */ B(LdaImmutableContextSlot), R(3), U8(4), U8(0),
B(ToName), R(8),
B(Star), R(4),
/* 75 S> */ B(LdaImmutableContextSlot), R(2), U8(4), U8(0),
B(ToName), R(7),
B(CreateClosure), U8(6), U8(1), U8(2),
B(Star), R(9),
/* 106 S> */ B(LdaImmutableContextSlot), R(3), U8(5), U8(0),
B(ToName), R(10),
B(Star), R(8),
/* 106 S> */ B(LdaImmutableContextSlot), R(2), U8(5), U8(0),
B(ToName), R(9),
B(LdaConstant), U8(7),
B(TestEqualStrict), R(10), U8(0),
B(Mov), R(4), R(6),
B(TestEqualStrict), R(9), U8(0),
B(Mov), R(3), R(5),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0),
B(CreateClosure), U8(8), U8(2), U8(2),
B(Star), R(11),
B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(7),
B(Star), R(5),
B(Mov), R(4), R(1),
B(PopContext), R(3),
B(Mov), R(1), R(0),
B(Star), R(10),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(7),
B(Star), R(4),
B(PopContext), R(2),
B(Mov), R(3), R(0),
B(LdaUndefined),
/* 129 S> */ B(Return),
]
@ -154,29 +151,28 @@ snippet: "
class C { constructor() { count++; }}
return new C();
"
frame size: 8
frame size: 7
parameter count: 1
bytecode array length: 52
bytecode array length: 49
bytecodes: [
B(CreateFunctionContext), U8(0), U8(1),
B(PushContext), R(2),
B(PushContext), R(1),
/* 30 E> */ B(StackCheck),
/* 46 S> */ B(LdaZero),
/* 46 E> */ B(StaCurrentContextSlot), U8(4),
B(CreateBlockContext), U8(1),
B(PushContext), R(3),
B(PushContext), R(2),
B(LdaTheHole),
B(Star), R(7),
B(Star), R(6),
B(CreateClosure), U8(3), U8(0), U8(2),
B(Star), R(4),
B(Star), R(3),
B(LdaConstant), U8(2),
B(Star), R(5),
B(Mov), R(4), R(6),
B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3),
B(Star), R(5),
B(Mov), R(6), R(1),
B(PopContext), R(3),
B(Mov), R(1), R(0),
B(Star), R(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(PopContext), R(2),
B(Mov), R(5), R(0),
/* 87 S> */ B(Ldar), R(0),
/* 94 E> */ B(Construct), R(0), R(0), U8(0), U8(0),
/* 102 S> */ B(Return),
@ -195,39 +191,38 @@ snippet: "
(class {})
class E { static name () {}}
"
frame size: 8
frame size: 7
parameter count: 1
bytecode array length: 73
bytecode array length: 70
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateBlockContext), U8(0),
B(PushContext), R(2),
B(PushContext), R(1),
B(LdaTheHole),
B(Star), R(6),
B(Star), R(5),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(3),
B(Star), R(2),
B(LdaConstant), U8(1),
B(Star), R(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(PopContext), R(2),
B(CreateBlockContext), U8(3),
B(PushContext), R(2),
B(LdaTheHole),
B(Star), R(6),
B(CreateClosure), U8(5), U8(1), U8(2),
B(Star), R(3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3),
B(Star), R(3),
B(PopContext), R(1),
B(CreateBlockContext), U8(3),
B(PushContext), R(1),
B(LdaTheHole),
B(Star), R(5),
B(CreateClosure), U8(5), U8(1), U8(2),
B(Star), R(2),
B(LdaConstant), U8(4),
B(Star), R(4),
B(Star), R(3),
B(CreateClosure), U8(6), U8(2), U8(2),
B(Star), R(7),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4),
B(Star), R(4),
B(Mov), R(5), R(1),
B(PopContext), R(2),
B(Mov), R(1), R(0),
B(Star), R(6),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4),
B(Star), R(3),
B(PopContext), R(1),
B(Mov), R(4), R(0),
B(LdaUndefined),
/* 74 S> */ B(Return),
]

View File

@ -10,29 +10,28 @@ snippet: "
class A { constructor(...args) { this.args = args; } }
new A(...[1, 2, 3]);
"
frame size: 7
frame size: 6
parameter count: 1
bytecode array length: 51
bytecode array length: 48
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(2),
B(PushContext), R(1),
B(LdaTheHole),
B(Star), R(6),
B(Star), R(5),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(3),
B(Star), R(2),
B(LdaConstant), U8(1),
B(Star), R(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(Mov), R(5), R(1),
B(PopContext), R(2),
B(Mov), R(1), R(0),
/* 89 S> */ B(CreateArrayLiteral), U8(3), U8(0), U8(37),
B(Star), R(3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3),
B(Star), R(3),
B(PopContext), R(1),
B(Mov), R(4), R(0),
/* 89 S> */ B(CreateArrayLiteral), U8(3), U8(0), U8(37),
B(Star), R(2),
B(Ldar), R(0),
/* 89 E> */ B(ConstructWithSpread), R(0), R(3), U8(1), U8(1),
/* 89 E> */ B(ConstructWithSpread), R(0), R(2), U8(1), U8(1),
B(LdaUndefined),
/* 110 S> */ B(Return),
]
@ -50,31 +49,30 @@ snippet: "
class A { constructor(...args) { this.args = args; } }
new A(0, ...[1, 2, 3]);
"
frame size: 7
frame size: 6
parameter count: 1
bytecode array length: 54
bytecode array length: 51
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(2),
B(PushContext), R(1),
B(LdaTheHole),
B(Star), R(6),
B(Star), R(5),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(3),
B(Star), R(2),
B(LdaConstant), U8(1),
B(Star), R(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(Mov), R(5), R(1),
B(PopContext), R(2),
B(Mov), R(1), R(0),
/* 89 S> */ B(LdaZero),
B(Star), R(3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3),
B(Star), R(3),
B(PopContext), R(1),
B(Mov), R(4), R(0),
/* 89 S> */ B(LdaZero),
B(Star), R(2),
B(CreateArrayLiteral), U8(3), U8(0), U8(37),
B(Star), R(4),
B(Star), R(3),
B(Ldar), R(0),
/* 89 E> */ B(ConstructWithSpread), R(0), R(3), U8(2), U8(1),
/* 89 E> */ B(ConstructWithSpread), R(0), R(2), U8(2), U8(1),
B(LdaUndefined),
/* 113 S> */ B(Return),
]
@ -92,52 +90,51 @@ snippet: "
class A { constructor(...args) { this.args = args; } }
new A(0, ...[1, 2, 3], 4);
"
frame size: 8
frame size: 7
parameter count: 1
bytecode array length: 118
bytecode array length: 115
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(2),
B(PushContext), R(1),
B(LdaTheHole),
B(Star), R(6),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(3),
B(LdaConstant), U8(1),
B(Star), R(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(Mov), R(5), R(1),
B(PopContext), R(2),
B(Mov), R(1), R(0),
/* 89 S> */ B(CreateArrayLiteral), U8(3), U8(0), U8(37),
B(Star), R(4),
B(LdaConstant), U8(4),
B(Star), R(3),
/* 101 S> */ B(CreateArrayLiteral), U8(5), U8(1), U8(37),
B(Star), R(7),
B(GetIterator), R(7), U8(2), U8(4),
B(Star), R(6),
B(LdaNamedProperty), R(6), U8(6), U8(6),
B(Star), R(5),
B(Mov), R(1), R(2),
B(CallProperty0), R(5), R(6), U8(15),
B(Star), R(7),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1),
B(LdaNamedProperty), R(7), U8(7), U8(17),
B(JumpIfToBooleanTrue), U8(19),
B(LdaNamedProperty), R(7), U8(8), U8(8),
B(StaInArrayLiteral), R(4), R(3), U8(13),
B(Ldar), R(3),
B(Inc), U8(12),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(2),
B(LdaConstant), U8(1),
B(Star), R(3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3),
B(Star), R(3),
B(PopContext), R(1),
B(Mov), R(4), R(0),
/* 89 S> */ B(CreateArrayLiteral), U8(3), U8(0), U8(37),
B(Star), R(3),
B(LdaConstant), U8(4),
B(Star), R(2),
/* 101 S> */ B(CreateArrayLiteral), U8(5), U8(1), U8(37),
B(Star), R(6),
B(GetIterator), R(6), U8(2), U8(4),
B(Star), R(5),
B(LdaNamedProperty), R(5), U8(6), U8(6),
B(Star), R(4),
B(Mov), R(0), R(1),
B(CallProperty0), R(4), R(5), U8(15),
B(Star), R(6),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
B(LdaNamedProperty), R(6), U8(7), U8(17),
B(JumpIfToBooleanTrue), U8(19),
B(LdaNamedProperty), R(6), U8(8), U8(8),
B(StaInArrayLiteral), R(3), R(2), U8(13),
B(Ldar), R(2),
B(Inc), U8(12),
B(Star), R(2),
B(JumpLoop), U8(33), I8(0),
B(LdaSmi), I8(4),
B(StaInArrayLiteral), R(4), R(3), U8(13),
B(Mov), R(4), R(3),
B(CallJSRuntime), U8(%reflect_construct), R(2), U8(2),
B(StaInArrayLiteral), R(3), R(2), U8(13),
B(Mov), R(3), R(2),
B(CallJSRuntime), U8(%reflect_construct), R(1), U8(2),
B(LdaUndefined),
/* 116 S> */ B(Return),
]

View File

@ -15,35 +15,34 @@ snippet: "
}
}
"
frame size: 8
frame size: 7
parameter count: 1
bytecode array length: 68
bytecode array length: 65
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(2),
B(PushContext), R(1),
B(LdaTheHole),
B(Star), R(6),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(3),
B(LdaConstant), U8(1),
B(Star), R(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(Mov), R(5), R(1),
B(LdaConstant), U8(3),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(2),
B(LdaConstant), U8(1),
B(Star), R(3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3),
B(Star), R(3),
B(LdaConstant), U8(3),
B(Star), R(4),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1),
B(StaCurrentContextSlot), U8(5),
B(CreateClosure), U8(4), U8(1), U8(2),
B(Star), R(6),
B(Star), R(5),
B(CreateClosure), U8(5), U8(2), U8(2),
B(Star), R(7),
B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2),
B(Star), R(6),
B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(5), U8(2),
B(StaCurrentContextSlot), U8(4),
B(PopContext), R(2),
B(Mov), R(1), R(0),
B(PopContext), R(1),
B(Mov), R(2), R(0),
B(LdaUndefined),
/* 101 S> */ B(Return),
]
@ -66,35 +65,34 @@ snippet: "
}
}
"
frame size: 8
frame size: 7
parameter count: 1
bytecode array length: 65
bytecode array length: 62
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(2),
B(PushContext), R(1),
B(LdaTheHole),
B(Star), R(6),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(3),
B(LdaConstant), U8(1),
B(Star), R(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(Mov), R(5), R(1),
B(LdaConstant), U8(3),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(2),
B(LdaConstant), U8(1),
B(Star), R(3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3),
B(Star), R(3),
B(LdaConstant), U8(3),
B(Star), R(4),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1),
B(StaCurrentContextSlot), U8(5),
B(CreateClosure), U8(4), U8(1), U8(2),
B(Star), R(6),
B(Star), R(5),
B(LdaNull),
B(Star), R(7),
B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2),
B(Star), R(6),
B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(5), U8(2),
B(StaCurrentContextSlot), U8(4),
B(PopContext), R(2),
B(Mov), R(1), R(0),
B(PopContext), R(1),
B(Mov), R(2), R(0),
B(LdaUndefined),
/* 81 S> */ B(Return),
]
@ -116,35 +114,34 @@ snippet: "
}
}
"
frame size: 8
frame size: 7
parameter count: 1
bytecode array length: 65
bytecode array length: 62
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(2),
B(PushContext), R(1),
B(LdaTheHole),
B(Star), R(6),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(3),
B(LdaConstant), U8(1),
B(Star), R(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(Mov), R(5), R(1),
B(LdaConstant), U8(3),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(2),
B(LdaConstant), U8(1),
B(Star), R(3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3),
B(Star), R(3),
B(LdaConstant), U8(3),
B(Star), R(4),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1),
B(StaCurrentContextSlot), U8(5),
B(LdaNull),
B(Star), R(6),
B(Star), R(5),
B(CreateClosure), U8(4), U8(1), U8(2),
B(Star), R(7),
B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2),
B(Star), R(6),
B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(5), U8(2),
B(StaCurrentContextSlot), U8(4),
B(PopContext), R(2),
B(Mov), R(1), R(0),
B(PopContext), R(1),
B(Mov), R(2), R(0),
B(LdaUndefined),
/* 74 S> */ B(Return),
]
@ -172,58 +169,56 @@ snippet: "
}
}
"
frame size: 10
frame size: 8
parameter count: 1
bytecode array length: 133
bytecode array length: 127
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(4),
B(PushContext), R(2),
B(LdaTheHole),
B(Star), R(8),
B(Star), R(6),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(5),
B(Star), R(3),
B(LdaConstant), U8(1),
B(Star), R(6),
B(Mov), R(5), R(7),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3),
B(Star), R(6),
B(Mov), R(7), R(3),
B(Star), R(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(LdaConstant), U8(3),
B(Star), R(7),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1),
B(StaCurrentContextSlot), U8(5),
B(CreateClosure), U8(4), U8(1), U8(2),
B(Star), R(8),
B(Star), R(6),
B(CreateClosure), U8(5), U8(2), U8(2),
B(Star), R(9),
B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(8), U8(2),
B(Star), R(7),
B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2),
B(StaCurrentContextSlot), U8(4),
B(PopContext), R(4),
B(PopContext), R(2),
B(Mov), R(3), R(0),
/* 38 E> */ B(CreateBlockContext), U8(6),
B(PushContext), R(4),
B(PushContext), R(2),
/* 118 E> */ B(CreateClosure), U8(8), U8(3), U8(2),
B(Star), R(5),
B(Star), R(3),
B(LdaConstant), U8(7),
B(Star), R(6),
B(Mov), R(5), R(7),
B(Mov), R(3), R(8),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3),
B(Star), R(6),
B(Mov), R(7), R(2),
B(Star), R(4),
B(Mov), R(3), R(5),
B(Mov), R(0), R(6),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(LdaConstant), U8(9),
B(Star), R(7),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1),
B(StaCurrentContextSlot), U8(5),
B(CreateClosure), U8(10), U8(4), U8(2),
B(Star), R(8),
B(Star), R(6),
B(CreateClosure), U8(11), U8(5), U8(2),
B(Star), R(9),
B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(8), U8(2),
B(Star), R(7),
B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2),
B(StaCurrentContextSlot), U8(4),
B(PopContext), R(4),
B(Mov), R(2), R(1),
B(PopContext), R(2),
B(Mov), R(3), R(1),
B(LdaUndefined),
/* 175 S> */ B(Return),
]
@ -254,52 +249,50 @@ snippet: "
new C();
}
"
frame size: 10
frame size: 8
parameter count: 1
bytecode array length: 119
bytecode array length: 113
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(4),
B(PushContext), R(2),
B(LdaTheHole),
B(Star), R(8),
B(Star), R(6),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(5),
B(Star), R(3),
B(LdaConstant), U8(1),
B(Star), R(6),
B(Star), R(4),
B(CreateClosure), U8(3), U8(1), U8(2),
B(Star), R(9),
B(Mov), R(5), R(7),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(4),
B(Star), R(6),
B(Mov), R(7), R(3),
B(PopContext), R(4),
B(Mov), R(3), R(0),
/* 38 E> */ B(CreateBlockContext), U8(4),
B(PushContext), R(4),
/* 77 E> */ B(CreateClosure), U8(6), U8(2), U8(2),
B(Star), R(5),
B(LdaConstant), U8(5),
B(Star), R(6),
B(Mov), R(5), R(7),
B(Mov), R(3), R(8),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3),
B(Star), R(6),
B(Mov), R(7), R(2),
B(LdaConstant), U8(7),
B(Star), R(7),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4),
B(Star), R(4),
B(PopContext), R(2),
B(Mov), R(5), R(0),
/* 38 E> */ B(CreateBlockContext), U8(4),
B(PushContext), R(2),
/* 77 E> */ B(CreateClosure), U8(6), U8(2), U8(2),
B(Star), R(3),
B(LdaConstant), U8(5),
B(Star), R(4),
B(Mov), R(3), R(5),
B(Mov), R(0), R(6),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(LdaConstant), U8(7),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1),
B(StaCurrentContextSlot), U8(5),
B(CreateClosure), U8(8), U8(3), U8(2),
B(Star), R(8),
B(Ldar), R(6),
B(StaNamedProperty), R(8), U8(9), U8(0),
B(Star), R(6),
B(Ldar), R(4),
B(StaNamedProperty), R(6), U8(9), U8(0),
B(LdaNull),
B(Star), R(9),
B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(8), U8(2),
B(Star), R(7),
B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2),
B(StaCurrentContextSlot), U8(4),
B(PopContext), R(4),
B(Mov), R(2), R(1),
B(PopContext), R(2),
B(Mov), R(3), R(1),
/* 122 S> */ B(Ldar), R(1),
/* 122 E> */ B(Construct), R(1), R(0), U8(0), U8(2),
B(LdaUndefined),
@ -330,52 +323,50 @@ snippet: "
new C();
}
"
frame size: 10
frame size: 8
parameter count: 1
bytecode array length: 119
bytecode array length: 113
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(4),
B(PushContext), R(2),
B(LdaTheHole),
B(Star), R(8),
B(Star), R(6),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(5),
B(Star), R(3),
B(LdaConstant), U8(1),
B(Star), R(6),
B(Star), R(4),
B(CreateClosure), U8(3), U8(1), U8(2),
B(Star), R(9),
B(Mov), R(5), R(7),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(4),
B(Star), R(6),
B(Mov), R(7), R(3),
B(PopContext), R(4),
B(Mov), R(3), R(0),
/* 38 E> */ B(CreateBlockContext), U8(4),
B(PushContext), R(4),
/* 80 E> */ B(CreateClosure), U8(6), U8(2), U8(2),
B(Star), R(5),
B(LdaConstant), U8(5),
B(Star), R(6),
B(Mov), R(5), R(7),
B(Mov), R(3), R(8),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3),
B(Star), R(6),
B(Mov), R(7), R(2),
B(LdaConstant), U8(7),
B(Star), R(7),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4),
B(Star), R(4),
B(PopContext), R(2),
B(Mov), R(5), R(0),
/* 38 E> */ B(CreateBlockContext), U8(4),
B(PushContext), R(2),
/* 80 E> */ B(CreateClosure), U8(6), U8(2), U8(2),
B(Star), R(3),
B(LdaConstant), U8(5),
B(Star), R(4),
B(Mov), R(3), R(5),
B(Mov), R(0), R(6),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(LdaConstant), U8(7),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1),
B(StaCurrentContextSlot), U8(5),
B(LdaNull),
B(Star), R(8),
B(Star), R(6),
B(CreateClosure), U8(8), U8(3), U8(2),
B(Star), R(9),
B(Ldar), R(6),
B(StaNamedProperty), R(9), U8(9), U8(0),
B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(8), U8(2),
B(Star), R(7),
B(Ldar), R(4),
B(StaNamedProperty), R(7), U8(9), U8(0),
B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2),
B(StaCurrentContextSlot), U8(4),
B(PopContext), R(4),
B(Mov), R(2), R(1),
B(PopContext), R(2),
B(Mov), R(3), R(1),
/* 126 S> */ B(Ldar), R(1),
/* 126 E> */ B(Construct), R(1), R(0), U8(0), U8(2),
B(LdaUndefined),

View File

@ -22,61 +22,59 @@ snippet: "
new B;
}
"
frame size: 10
frame size: 8
parameter count: 1
bytecode array length: 137
bytecode array length: 131
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(4),
B(PushContext), R(2),
B(LdaTheHole),
B(Star), R(8),
B(Star), R(6),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(5),
B(Star), R(3),
B(LdaConstant), U8(1),
B(Star), R(6),
B(Star), R(4),
B(LdaConstant), U8(3),
B(Star), R(9),
B(LdaConstant), U8(3),
B(Star), R(9),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(9), U8(1),
B(StaCurrentContextSlot), U8(4),
B(Mov), R(5), R(7),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3),
B(Star), R(6),
B(Mov), R(7), R(3),
B(CreateClosure), U8(4), U8(1), U8(2),
B(Star), R(7),
B(StaNamedProperty), R(5), U8(5), U8(0),
B(PopContext), R(4),
B(LdaConstant), U8(3),
B(Star), R(7),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1),
B(StaCurrentContextSlot), U8(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(CreateClosure), U8(4), U8(1), U8(2),
B(Star), R(5),
B(StaNamedProperty), R(3), U8(5), U8(0),
B(PopContext), R(2),
B(Mov), R(3), R(0),
/* 38 E> */ B(CreateBlockContext), U8(6),
B(PushContext), R(4),
B(PushContext), R(2),
B(LdaTheHole),
B(Star), R(8),
B(Star), R(6),
B(CreateClosure), U8(8), U8(2), U8(2),
B(Star), R(5),
B(Star), R(3),
B(LdaConstant), U8(7),
B(Star), R(6),
B(Star), R(4),
B(LdaConstant), U8(3),
B(Star), R(9),
B(LdaConstant), U8(3),
B(Star), R(9),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(9), U8(1),
B(StaCurrentContextSlot), U8(4),
B(Mov), R(5), R(7),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3),
B(Star), R(6),
B(Mov), R(7), R(2),
B(CreateClosure), U8(9), U8(3), U8(2),
B(Star), R(7),
B(StaNamedProperty), R(5), U8(5), U8(2),
B(PopContext), R(4),
B(Mov), R(2), R(1),
/* 136 S> */ B(Ldar), R(3),
/* 136 E> */ B(Construct), R(3), R(0), U8(0), U8(4),
/* 145 S> */ B(Ldar), R(2),
/* 145 E> */ B(Construct), R(2), R(0), U8(0), U8(6),
B(LdaConstant), U8(3),
B(Star), R(7),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1),
B(StaCurrentContextSlot), U8(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(CreateClosure), U8(9), U8(3), U8(2),
B(Star), R(5),
B(StaNamedProperty), R(3), U8(5), U8(2),
B(PopContext), R(2),
B(Mov), R(3), R(1),
/* 136 S> */ B(Ldar), R(0),
/* 136 E> */ B(Construct), R(0), R(0), U8(0), U8(4),
/* 145 S> */ B(Ldar), R(1),
/* 145 E> */ B(Construct), R(1), R(0), U8(0), U8(6),
B(LdaUndefined),
/* 154 S> */ B(Return),
]
@ -130,111 +128,108 @@ snippet: "
new C;
};
"
frame size: 15
frame size: 12
parameter count: 1
bytecode array length: 277
bytecode array length: 268
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(6),
B(PushContext), R(3),
B(LdaTheHole),
B(Star), R(14),
B(Star), R(11),
B(CreateClosure), U8(3), U8(0), U8(2),
B(Star), R(11),
B(Star), R(8),
B(LdaConstant), U8(2),
B(Star), R(12),
B(Mov), R(11), R(13),
B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3),
B(Star), R(12),
B(CreateClosure), U8(4), U8(1), U8(2),
B(Star), R(7),
B(LdaConstant), U8(1),
B(Star), R(8),
B(LdaConstant), U8(5),
B(Star), R(11),
B(LdaConstant), U8(5),
B(Star), R(11),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(11), U8(1),
B(StaCurrentContextSlot), U8(4),
B(Mov), R(7), R(9),
B(Mov), R(13), R(10),
B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(3),
B(Star), R(8),
B(Mov), R(9), R(5),
B(CreateClosure), U8(6), U8(2), U8(2),
B(Star), R(9),
B(StaNamedProperty), R(7), U8(7), U8(0),
B(PopContext), R(6),
B(Mov), R(5), R(0),
/* 38 E> */ B(CreateBlockContext), U8(8),
B(PushContext), R(6),
B(LdaTheHole),
B(Star), R(14),
B(CreateClosure), U8(11), U8(3), U8(2),
B(Star), R(11),
B(LdaConstant), U8(10),
B(Star), R(12),
B(Mov), R(11), R(13),
B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3),
B(Star), R(12),
B(CreateClosure), U8(12), U8(4), U8(2),
B(Star), R(7),
B(LdaConstant), U8(9),
B(Mov), R(8), R(10),
B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3),
B(Star), R(9),
B(CreateClosure), U8(4), U8(1), U8(2),
B(Star), R(4),
B(LdaConstant), U8(1),
B(Star), R(5),
B(LdaConstant), U8(5),
B(Star), R(8),
B(LdaConstant), U8(5),
B(Star), R(8),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(8), U8(1),
B(StaCurrentContextSlot), U8(4),
B(Mov), R(4), R(6),
B(Mov), R(10), R(7),
B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3),
B(Star), R(5),
B(CreateClosure), U8(6), U8(2), U8(2),
B(Star), R(6),
B(StaNamedProperty), R(4), U8(7), U8(0),
B(PopContext), R(3),
B(Mov), R(4), R(0),
/* 38 E> */ B(CreateBlockContext), U8(8),
B(PushContext), R(3),
B(LdaTheHole),
B(Star), R(11),
B(CreateClosure), U8(11), U8(3), U8(2),
B(Star), R(8),
B(LdaConstant), U8(10),
B(Star), R(9),
B(Mov), R(8), R(10),
B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3),
B(Star), R(9),
B(CreateClosure), U8(12), U8(4), U8(2),
B(Star), R(4),
B(LdaConstant), U8(9),
B(Star), R(5),
B(LdaConstant), U8(5),
B(Star), R(11),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(11), U8(1),
B(Star), R(8),
B(LdaConstant), U8(5),
B(Star), R(8),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(8), U8(1),
B(StaCurrentContextSlot), U8(4),
B(LdaConstant), U8(13),
B(Star), R(11),
B(Star), R(8),
B(LdaConstant), U8(13),
B(Star), R(11),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(11), U8(1),
B(Star), R(8),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(8), U8(1),
B(StaCurrentContextSlot), U8(5),
B(CreateClosure), U8(14), U8(5), U8(2),
B(Star), R(11),
B(CreateClosure), U8(15), U8(6), U8(2),
B(Star), R(12),
B(Mov), R(7), R(9),
B(Mov), R(13), R(10),
B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(5),
B(Star), R(8),
B(Mov), R(9), R(4),
B(CreateClosure), U8(16), U8(7), U8(2),
B(CreateClosure), U8(15), U8(6), U8(2),
B(Star), R(9),
B(StaNamedProperty), R(7), U8(7), U8(2),
B(PopContext), R(6),
B(Mov), R(4), R(6),
B(Mov), R(10), R(7),
B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(5),
B(Star), R(5),
B(CreateClosure), U8(16), U8(7), U8(2),
B(Star), R(6),
B(StaNamedProperty), R(4), U8(7), U8(2),
B(PopContext), R(3),
B(Mov), R(4), R(1),
/* 140 E> */ B(CreateBlockContext), U8(17),
B(PushContext), R(6),
B(PushContext), R(3),
/* 356 E> */ B(CreateClosure), U8(19), U8(8), U8(2),
B(Star), R(7),
B(Star), R(4),
B(LdaConstant), U8(18),
B(Star), R(5),
B(LdaConstant), U8(5),
B(Star), R(8),
B(LdaConstant), U8(5),
B(Star), R(11),
B(LdaConstant), U8(5),
B(Star), R(11),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(11), U8(1),
B(Star), R(8),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(8), U8(1),
B(StaCurrentContextSlot), U8(4),
B(Mov), R(7), R(9),
B(Mov), R(4), R(10),
B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(3),
B(Star), R(8),
B(Mov), R(9), R(3),
B(Mov), R(4), R(6),
B(Mov), R(1), R(7),
B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3),
B(Star), R(5),
B(CreateClosure), U8(20), U8(9), U8(2),
B(Star), R(9),
B(StaNamedProperty), R(7), U8(7), U8(4),
B(PopContext), R(6),
B(Mov), R(3), R(2),
/* 430 S> */ B(Ldar), R(5),
/* 430 E> */ B(Construct), R(5), R(0), U8(0), U8(6),
/* 439 S> */ B(Ldar), R(4),
/* 439 E> */ B(Construct), R(4), R(0), U8(0), U8(8),
/* 448 S> */ B(Ldar), R(3),
/* 448 E> */ B(Construct), R(3), R(0), U8(0), U8(10),
B(Star), R(6),
B(StaNamedProperty), R(4), U8(7), U8(4),
B(PopContext), R(3),
B(Mov), R(4), R(2),
/* 430 S> */ B(Ldar), R(0),
/* 430 E> */ B(Construct), R(0), R(0), U8(0), U8(6),
/* 439 S> */ B(Ldar), R(1),
/* 439 E> */ B(Construct), R(1), R(0), U8(0), U8(8),
/* 448 S> */ B(Ldar), R(2),
/* 448 E> */ B(Construct), R(2), R(0), U8(0), U8(10),
B(LdaUndefined),
/* 458 S> */ B(Return),
]

View File

@ -14,31 +14,30 @@ snippet: "
}
}
"
frame size: 7
frame size: 6
parameter count: 1
bytecode array length: 55
bytecode array length: 52
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(2),
B(PushContext), R(1),
B(LdaTheHole),
B(Star), R(6),
B(Star), R(5),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(3),
B(Star), R(2),
B(LdaConstant), U8(1),
B(Star), R(4),
B(Star), R(3),
B(CreateClosure), U8(3), U8(1), U8(2),
B(StaCurrentContextSlot), U8(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(Mov), R(5), R(1),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3),
B(Star), R(3),
B(LdaConstant), U8(4),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1),
B(Star), R(4),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1),
B(StaCurrentContextSlot), U8(5),
B(PopContext), R(2),
B(Mov), R(1), R(0),
B(PopContext), R(1),
B(Mov), R(2), R(0),
B(LdaUndefined),
/* 77 S> */ B(Return),
]
@ -63,50 +62,48 @@ snippet: "
}
}
"
frame size: 9
frame size: 7
parameter count: 1
bytecode array length: 107
bytecode array length: 101
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(4),
B(PushContext), R(2),
B(LdaTheHole),
B(Star), R(8),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(5),
B(LdaConstant), U8(1),
B(Star), R(6),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(3),
B(LdaConstant), U8(1),
B(Star), R(4),
B(CreateClosure), U8(3), U8(1), U8(2),
B(StaCurrentContextSlot), U8(4),
B(Mov), R(5), R(7),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3),
B(Star), R(6),
B(Mov), R(7), R(3),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(LdaConstant), U8(4),
B(Star), R(7),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1),
B(StaCurrentContextSlot), U8(5),
B(PopContext), R(4),
B(PopContext), R(2),
B(Mov), R(3), R(0),
/* 38 E> */ B(CreateBlockContext), U8(5),
B(PushContext), R(4),
B(PushContext), R(2),
/* 93 E> */ B(CreateClosure), U8(7), U8(2), U8(2),
B(Star), R(5),
B(Star), R(3),
B(LdaConstant), U8(6),
B(Star), R(6),
B(Star), R(4),
B(CreateClosure), U8(8), U8(3), U8(2),
B(StaCurrentContextSlot), U8(4),
B(Mov), R(5), R(7),
B(Mov), R(3), R(8),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3),
B(Star), R(6),
B(Mov), R(7), R(2),
B(Mov), R(3), R(5),
B(Mov), R(0), R(6),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(LdaConstant), U8(9),
B(Star), R(7),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1),
B(StaCurrentContextSlot), U8(5),
B(PopContext), R(4),
B(Mov), R(2), R(1),
B(PopContext), R(2),
B(Mov), R(3), R(1),
B(LdaUndefined),
/* 126 S> */ B(Return),
]
@ -134,50 +131,48 @@ snippet: "
}
}
"
frame size: 10
frame size: 8
parameter count: 1
bytecode array length: 106
bytecode array length: 100
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(4),
B(PushContext), R(2),
B(LdaTheHole),
B(Star), R(8),
B(Star), R(6),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(5),
B(Star), R(3),
B(LdaConstant), U8(1),
B(Star), R(6),
B(Star), R(4),
B(CreateClosure), U8(3), U8(1), U8(2),
B(Star), R(9),
B(Mov), R(5), R(7),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(4),
B(Star), R(6),
B(Mov), R(7), R(3),
B(PopContext), R(4),
B(Mov), R(3), R(0),
B(Star), R(7),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4),
B(Star), R(4),
B(PopContext), R(2),
B(Mov), R(5), R(0),
/* 38 E> */ B(CreateBlockContext), U8(4),
B(PushContext), R(4),
B(PushContext), R(2),
/* 77 E> */ B(CreateClosure), U8(6), U8(2), U8(2),
B(Star), R(5),
B(Star), R(3),
B(LdaConstant), U8(5),
B(Star), R(6),
B(Star), R(4),
B(CreateClosure), U8(7), U8(3), U8(2),
B(StaCurrentContextSlot), U8(4),
B(Mov), R(5), R(7),
B(Mov), R(3), R(8),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3),
B(Star), R(6),
B(Mov), R(7), R(2),
B(Mov), R(3), R(5),
B(Mov), R(0), R(6),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(LdaConstant), U8(8),
B(Star), R(7),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1),
B(StaCurrentContextSlot), U8(5),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(8),
B(Ldar), R(6),
B(StaNamedProperty), R(8), U8(9), U8(0),
B(PopContext), R(4),
B(Mov), R(2), R(1),
B(Star), R(6),
B(Ldar), R(4),
B(StaNamedProperty), R(6), U8(9), U8(0),
B(PopContext), R(2),
B(Mov), R(3), R(1),
B(LdaUndefined),
/* 118 S> */ B(Return),
]

View File

@ -21,59 +21,57 @@ snippet: "
new B;
}
"
frame size: 10
frame size: 8
parameter count: 1
bytecode array length: 125
bytecode array length: 119
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(4),
B(PushContext), R(2),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
B(LdaTheHole),
B(Star), R(8),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(5),
B(LdaConstant), U8(1),
B(Star), R(6),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(3),
B(LdaConstant), U8(1),
B(Star), R(4),
/* 60 S> */ B(LdaConstant), U8(3),
B(StaCurrentContextSlot), U8(4),
B(Star), R(9),
B(Mov), R(5), R(7),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(4),
B(Star), R(6),
B(Mov), R(7), R(3),
B(CreateClosure), U8(4), U8(1), U8(2),
B(Star), R(7),
B(StaNamedProperty), R(5), U8(5), U8(0),
B(PopContext), R(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4),
B(Star), R(4),
B(CreateClosure), U8(4), U8(1), U8(2),
B(Star), R(5),
B(StaNamedProperty), R(3), U8(5), U8(0),
B(PopContext), R(2),
B(Mov), R(3), R(0),
/* 38 E> */ B(CreateBlockContext), U8(6),
B(PushContext), R(4),
B(PushContext), R(2),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
B(LdaTheHole),
B(Star), R(8),
B(CreateClosure), U8(8), U8(2), U8(2),
B(Star), R(5),
B(LdaConstant), U8(7),
B(Star), R(6),
B(CreateClosure), U8(8), U8(2), U8(2),
B(Star), R(3),
B(LdaConstant), U8(7),
B(Star), R(4),
/* 99 S> */ B(LdaConstant), U8(3),
B(StaCurrentContextSlot), U8(4),
B(Star), R(9),
B(Mov), R(5), R(7),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(4),
B(Star), R(6),
B(Mov), R(7), R(2),
B(CreateClosure), U8(9), U8(3), U8(2),
B(Star), R(7),
B(StaNamedProperty), R(5), U8(5), U8(2),
B(PopContext), R(4),
B(Mov), R(2), R(1),
/* 120 S> */ B(Ldar), R(3),
/* 120 E> */ B(Construct), R(3), R(0), U8(0), U8(4),
/* 129 S> */ B(Ldar), R(2),
/* 129 E> */ B(Construct), R(2), R(0), U8(0), U8(6),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4),
B(Star), R(4),
B(CreateClosure), U8(9), U8(3), U8(2),
B(Star), R(5),
B(StaNamedProperty), R(3), U8(5), U8(2),
B(PopContext), R(2),
B(Mov), R(3), R(1),
/* 120 S> */ B(Ldar), R(0),
/* 120 E> */ B(Construct), R(0), R(0), U8(0), U8(4),
/* 129 S> */ B(Ldar), R(1),
/* 129 E> */ B(Construct), R(1), R(0), U8(0), U8(6),
B(LdaUndefined),
/* 138 S> */ B(Return),
]
@ -122,100 +120,97 @@ snippet: "
new C;
}
"
frame size: 15
frame size: 12
parameter count: 1
bytecode array length: 238
bytecode array length: 229
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(6),
B(PushContext), R(3),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
B(LdaTheHole),
B(Star), R(14),
B(CreateClosure), U8(3), U8(0), U8(2),
B(Star), R(11),
B(LdaConstant), U8(2),
B(Star), R(12),
B(Mov), R(11), R(13),
B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3),
B(Star), R(12),
B(CreateClosure), U8(4), U8(1), U8(2),
B(Star), R(7),
B(LdaConstant), U8(1),
B(CreateClosure), U8(3), U8(0), U8(2),
B(Star), R(8),
B(LdaConstant), U8(2),
B(Star), R(9),
B(Mov), R(8), R(10),
B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3),
B(Star), R(9),
B(CreateClosure), U8(4), U8(1), U8(2),
B(Star), R(4),
B(LdaConstant), U8(1),
B(Star), R(5),
/* 77 S> */ B(LdaConstant), U8(5),
B(StaCurrentContextSlot), U8(4),
B(Star), R(11),
B(Mov), R(7), R(9),
B(Mov), R(13), R(10),
B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(4),
B(Star), R(8),
B(Mov), R(9), R(5),
B(Mov), R(4), R(6),
B(Mov), R(10), R(7),
B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(4),
B(Star), R(5),
B(CreateClosure), U8(6), U8(2), U8(2),
B(Star), R(9),
B(StaNamedProperty), R(7), U8(7), U8(0),
B(PopContext), R(6),
B(Mov), R(5), R(0),
B(Star), R(6),
B(StaNamedProperty), R(4), U8(7), U8(0),
B(PopContext), R(3),
B(Mov), R(4), R(0),
/* 38 E> */ B(CreateBlockContext), U8(8),
B(PushContext), R(6),
B(PushContext), R(3),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
B(LdaTheHole),
B(Star), R(14),
B(CreateClosure), U8(11), U8(3), U8(2),
B(Star), R(11),
B(LdaConstant), U8(10),
B(Star), R(12),
B(Mov), R(11), R(13),
B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3),
B(Star), R(12),
B(CreateClosure), U8(12), U8(4), U8(2),
B(Star), R(7),
B(LdaConstant), U8(9),
B(CreateClosure), U8(11), U8(3), U8(2),
B(Star), R(8),
B(LdaConstant), U8(10),
B(Star), R(9),
B(Mov), R(8), R(10),
B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3),
B(Star), R(9),
B(CreateClosure), U8(12), U8(4), U8(2),
B(Star), R(4),
B(LdaConstant), U8(9),
B(Star), R(5),
/* 133 S> */ B(LdaConstant), U8(5),
B(StaCurrentContextSlot), U8(4),
B(Star), R(11),
B(CreateClosure), U8(13), U8(5), U8(2),
B(Star), R(12),
B(Mov), R(7), R(9),
B(Mov), R(13), R(10),
B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(5),
B(Star), R(8),
B(Mov), R(9), R(4),
B(CreateClosure), U8(14), U8(6), U8(2),
B(CreateClosure), U8(13), U8(5), U8(2),
B(Star), R(9),
B(StaNamedProperty), R(7), U8(7), U8(2),
B(PopContext), R(6),
B(Mov), R(4), R(6),
B(Mov), R(10), R(7),
B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(5),
B(Star), R(5),
B(CreateClosure), U8(14), U8(6), U8(2),
B(Star), R(6),
B(StaNamedProperty), R(4), U8(7), U8(2),
B(PopContext), R(3),
B(Mov), R(4), R(1),
/* 90 E> */ B(CreateBlockContext), U8(15),
B(PushContext), R(6),
B(PushContext), R(3),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
/* 236 E> */ B(CreateClosure), U8(17), U8(7), U8(2),
B(Star), R(7),
B(Star), R(4),
B(LdaConstant), U8(16),
B(Star), R(8),
B(Star), R(5),
/* 256 S> */ B(LdaConstant), U8(5),
B(StaCurrentContextSlot), U8(4),
B(Star), R(11),
B(Mov), R(7), R(9),
B(Mov), R(4), R(10),
B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(4),
B(Star), R(8),
B(Mov), R(9), R(3),
B(Mov), R(4), R(6),
B(Mov), R(1), R(7),
B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(4),
B(Star), R(5),
B(CreateClosure), U8(18), U8(8), U8(2),
B(Star), R(9),
B(StaNamedProperty), R(7), U8(7), U8(4),
B(PopContext), R(6),
B(Mov), R(3), R(2),
/* 329 S> */ B(Ldar), R(5),
/* 329 E> */ B(Construct), R(5), R(0), U8(0), U8(6),
/* 338 S> */ B(Ldar), R(4),
/* 338 E> */ B(Construct), R(4), R(0), U8(0), U8(8),
/* 347 S> */ B(Ldar), R(3),
/* 347 E> */ B(Construct), R(3), R(0), U8(0), U8(10),
B(Star), R(6),
B(StaNamedProperty), R(4), U8(7), U8(4),
B(PopContext), R(3),
B(Mov), R(4), R(2),
/* 329 S> */ B(Ldar), R(0),
/* 329 E> */ B(Construct), R(0), R(0), U8(0), U8(6),
/* 338 S> */ B(Ldar), R(1),
/* 338 E> */ B(Construct), R(1), R(0), U8(0), U8(8),
/* 347 S> */ B(Ldar), R(2),
/* 347 E> */ B(Construct), R(2), R(0), U8(0), U8(10),
B(LdaUndefined),
/* 356 S> */ B(Return),
]

View File

@ -25,85 +25,83 @@ snippet: "
new B;
}
"
frame size: 11
frame size: 9
parameter count: 1
bytecode array length: 191
bytecode array length: 185
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(4),
B(PushContext), R(2),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(5),
B(LdaTheHole),
B(Star), R(8),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(5),
B(LdaConstant), U8(1),
B(Star), R(6),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(3),
B(LdaConstant), U8(1),
B(Star), R(4),
/* 60 S> */ B(LdaConstant), U8(3),
B(StaCurrentContextSlot), U8(4),
B(Star), R(9),
B(Star), R(7),
/* 92 S> */ B(LdaConstant), U8(4),
B(Star), R(10),
B(Star), R(8),
B(LdaConstant), U8(5),
B(TestEqualStrict), R(10), U8(0),
B(Mov), R(5), R(7),
B(TestEqualStrict), R(8), U8(0),
B(Mov), R(3), R(5),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0),
B(Ldar), R(10),
B(Ldar), R(8),
B(StaCurrentContextSlot), U8(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(5),
B(Star), R(6),
B(Mov), R(5), R(3),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(5),
B(Star), R(4),
B(CreateClosure), U8(6), U8(1), U8(2),
B(Star), R(7),
B(StaNamedProperty), R(5), U8(7), U8(1),
B(Star), R(5),
B(StaNamedProperty), R(3), U8(7), U8(1),
B(CreateClosure), U8(8), U8(2), U8(2),
B(Star), R(9),
B(CallProperty0), R(9), R(3), U8(3),
B(PopContext), R(4),
B(Star), R(7),
B(CallProperty0), R(7), R(3), U8(3),
B(PopContext), R(2),
B(Mov), R(3), R(0),
/* 38 E> */ B(CreateBlockContext), U8(9),
B(PushContext), R(4),
B(PushContext), R(2),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(5),
B(LdaTheHole),
B(Star), R(8),
B(CreateClosure), U8(11), U8(3), U8(2),
B(Star), R(5),
B(LdaConstant), U8(10),
B(Star), R(6),
B(CreateClosure), U8(11), U8(3), U8(2),
B(Star), R(3),
B(LdaConstant), U8(10),
B(Star), R(4),
/* 131 S> */ B(LdaConstant), U8(3),
B(StaCurrentContextSlot), U8(4),
B(Star), R(9),
B(Star), R(7),
/* 176 S> */ B(LdaConstant), U8(4),
B(Star), R(10),
B(Star), R(8),
B(LdaConstant), U8(5),
B(TestEqualStrict), R(10), U8(0),
B(Mov), R(5), R(7),
B(TestEqualStrict), R(8), U8(0),
B(Mov), R(3), R(5),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0),
B(Ldar), R(10),
B(Ldar), R(8),
B(StaCurrentContextSlot), U8(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(5),
B(Star), R(6),
B(Mov), R(5), R(2),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(5),
B(Star), R(4),
B(CreateClosure), U8(12), U8(4), U8(2),
B(Star), R(7),
B(StaNamedProperty), R(5), U8(7), U8(5),
B(Star), R(5),
B(StaNamedProperty), R(3), U8(7), U8(5),
B(CreateClosure), U8(13), U8(5), U8(2),
B(Star), R(9),
B(CallProperty0), R(9), R(2), U8(7),
B(PopContext), R(4),
B(Mov), R(2), R(1),
B(Star), R(7),
B(CallProperty0), R(7), R(3), U8(7),
B(PopContext), R(2),
B(Mov), R(3), R(1),
/* 197 S> */ B(Ldar), R(0),
/* 197 E> */ B(Construct), R(0), R(0), U8(0), U8(9),
/* 206 S> */ B(Ldar), R(2),
/* 206 E> */ B(Construct), R(2), R(0), U8(0), U8(11),
/* 206 S> */ B(Ldar), R(1),
/* 206 E> */ B(Construct), R(1), R(0), U8(0), U8(11),
B(LdaUndefined),
/* 215 S> */ B(Return),
]
@ -162,141 +160,138 @@ snippet: "
new C;
}
"
frame size: 15
frame size: 12
parameter count: 1
bytecode array length: 343
bytecode array length: 334
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(6),
B(PushContext), R(3),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(5),
B(LdaTheHole),
B(Star), R(14),
B(CreateClosure), U8(3), U8(0), U8(2),
B(Star), R(11),
B(LdaConstant), U8(2),
B(Star), R(12),
B(Mov), R(11), R(13),
B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3),
B(Star), R(12),
B(CreateClosure), U8(4), U8(1), U8(2),
B(Star), R(7),
B(LdaConstant), U8(1),
B(CreateClosure), U8(3), U8(0), U8(2),
B(Star), R(8),
B(LdaConstant), U8(2),
B(Star), R(9),
B(Mov), R(8), R(10),
B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3),
B(Star), R(9),
B(CreateClosure), U8(4), U8(1), U8(2),
B(Star), R(4),
B(LdaConstant), U8(1),
B(Star), R(5),
/* 77 S> */ B(LdaConstant), U8(5),
B(StaCurrentContextSlot), U8(4),
B(Star), R(11),
B(Star), R(8),
/* 109 S> */ B(LdaConstant), U8(6),
B(Star), R(12),
B(Star), R(9),
B(LdaConstant), U8(7),
B(TestEqualStrict), R(12), U8(0),
B(Mov), R(13), R(10),
B(Mov), R(7), R(9),
B(TestEqualStrict), R(9), U8(0),
B(Mov), R(10), R(7),
B(Mov), R(4), R(6),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0),
B(Ldar), R(12),
B(Ldar), R(9),
B(StaCurrentContextSlot), U8(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(5),
B(Star), R(8),
B(Mov), R(7), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(5),
B(Star), R(5),
B(CreateClosure), U8(8), U8(2), U8(2),
B(Star), R(9),
B(StaNamedProperty), R(7), U8(9), U8(1),
B(Star), R(6),
B(StaNamedProperty), R(4), U8(9), U8(1),
B(CreateClosure), U8(10), U8(3), U8(2),
B(Star), R(11),
B(CallProperty0), R(11), R(5), U8(3),
B(PopContext), R(6),
B(Mov), R(5), R(0),
B(Star), R(8),
B(CallProperty0), R(8), R(4), U8(3),
B(PopContext), R(3),
B(Mov), R(4), R(0),
/* 38 E> */ B(CreateBlockContext), U8(11),
B(PushContext), R(6),
B(PushContext), R(3),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(5),
B(LdaTheHole),
B(Star), R(14),
B(CreateClosure), U8(14), U8(4), U8(2),
B(Star), R(11),
B(LdaConstant), U8(13),
B(Star), R(12),
B(Mov), R(11), R(13),
B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3),
B(Star), R(12),
B(CreateClosure), U8(15), U8(5), U8(2),
B(Star), R(7),
B(LdaConstant), U8(12),
B(CreateClosure), U8(14), U8(4), U8(2),
B(Star), R(8),
B(LdaConstant), U8(13),
B(Star), R(9),
B(Mov), R(8), R(10),
B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3),
B(Star), R(9),
B(CreateClosure), U8(15), U8(5), U8(2),
B(Star), R(4),
B(LdaConstant), U8(12),
B(Star), R(5),
/* 165 S> */ B(LdaConstant), U8(5),
B(StaCurrentContextSlot), U8(4),
B(Star), R(11),
B(Star), R(8),
/* 210 S> */ B(LdaConstant), U8(6),
B(Star), R(12),
B(Star), R(9),
B(LdaConstant), U8(7),
B(TestEqualStrict), R(12), U8(0),
B(Mov), R(7), R(9),
B(Mov), R(13), R(10),
B(TestEqualStrict), R(9), U8(0),
B(Mov), R(4), R(6),
B(Mov), R(10), R(7),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0),
B(Ldar), R(12),
B(Ldar), R(9),
B(StaCurrentContextSlot), U8(5),
B(CreateClosure), U8(16), U8(6), U8(2),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(6),
B(Star), R(8),
B(Mov), R(7), R(4),
B(Star), R(10),
B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(6),
B(Star), R(5),
B(CreateClosure), U8(17), U8(7), U8(2),
B(Star), R(9),
B(StaNamedProperty), R(7), U8(9), U8(5),
B(Star), R(6),
B(StaNamedProperty), R(4), U8(9), U8(5),
B(CreateClosure), U8(18), U8(8), U8(2),
B(Star), R(11),
B(CallProperty0), R(11), R(4), U8(7),
B(PopContext), R(6),
B(Star), R(8),
B(CallProperty0), R(8), R(4), U8(7),
B(PopContext), R(3),
B(Mov), R(4), R(1),
/* 122 E> */ B(CreateBlockContext), U8(19),
B(PushContext), R(6),
B(PushContext), R(3),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(5),
/* 313 E> */ B(CreateClosure), U8(21), U8(9), U8(2),
B(Star), R(7),
B(Star), R(4),
B(LdaConstant), U8(20),
B(Star), R(8),
B(Star), R(5),
/* 333 S> */ B(LdaConstant), U8(5),
B(StaCurrentContextSlot), U8(4),
B(Star), R(11),
B(Star), R(8),
/* 378 S> */ B(LdaConstant), U8(6),
B(Star), R(12),
B(Star), R(9),
B(LdaConstant), U8(7),
B(TestEqualStrict), R(12), U8(0),
B(Mov), R(4), R(10),
B(Mov), R(7), R(9),
B(TestEqualStrict), R(9), U8(0),
B(Mov), R(4), R(6),
B(Mov), R(1), R(7),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0),
B(Ldar), R(12),
B(Ldar), R(9),
B(StaCurrentContextSlot), U8(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(5),
B(Star), R(8),
B(Mov), R(7), R(3),
B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(5),
B(Star), R(5),
B(CreateClosure), U8(22), U8(10), U8(2),
B(Star), R(9),
B(StaNamedProperty), R(7), U8(9), U8(9),
B(Star), R(6),
B(StaNamedProperty), R(4), U8(9), U8(9),
B(CreateClosure), U8(23), U8(11), U8(2),
B(Star), R(11),
B(Ldar), R(3),
B(StaNamedProperty), R(11), U8(24), U8(11),
B(CallProperty0), R(11), R(3), U8(13),
B(PopContext), R(6),
B(Mov), R(3), R(2),
B(Star), R(8),
B(Ldar), R(4),
B(StaNamedProperty), R(8), U8(24), U8(11),
B(CallProperty0), R(8), R(4), U8(13),
B(PopContext), R(3),
B(Mov), R(4), R(2),
/* 456 S> */ B(Ldar), R(0),
/* 456 E> */ B(Construct), R(0), R(0), U8(0), U8(15),
/* 465 S> */ B(Ldar), R(1),
/* 465 E> */ B(Construct), R(1), R(0), U8(0), U8(17),
/* 474 S> */ B(Ldar), R(3),
/* 474 E> */ B(Construct), R(3), R(0), U8(0), U8(19),
/* 474 S> */ B(Ldar), R(2),
/* 474 E> */ B(Construct), R(2), R(0), U8(0), U8(19),
B(LdaUndefined),
/* 483 S> */ B(Return),
]

View File

@ -0,0 +1,290 @@
#
# Autogenerated by generate-bytecode-expectations.
#
---
wrap: no
test function name: test
private methods: yes
---
snippet: "
class A {
static #a() { return 1; }
static test() { return this.#a(); }
}
var test = A.test;
test();
"
frame size: 4
parameter count: 1
bytecode array length: 36
bytecodes: [
/* 51 E> */ B(StackCheck),
/* 56 S> */ B(LdaCurrentContextSlot), U8(5),
B(TestReferenceEqual), R(this),
B(Mov), R(this), R(1),
B(JumpIfTrue), U8(18),
B(Wide), B(LdaSmi), I16(259),
B(Star), R(2),
B(LdaConstant), U8(0),
B(Star), R(3),
B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2),
B(Throw),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(0),
/* 70 E> */ B(CallAnyReceiver), R(0), R(1), U8(1), U8(0),
/* 73 S> */ B(Return),
]
constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["#a"],
]
handlers: [
]
---
snippet: "
class B {
static #b() { return 1; }
static test() { this.#b = 1; }
}
var test = B.test;
test();
"
frame size: 2
parameter count: 1
bytecode array length: 17
bytecodes: [
/* 51 E> */ B(StackCheck),
/* 56 S> */ B(Wide), B(LdaSmi), I16(261),
B(Star), R(0),
B(LdaConstant), U8(0),
B(Star), R(1),
/* 64 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(0), U8(2),
B(Throw),
]
constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["#b"],
]
handlers: [
]
---
snippet: "
class C {
static #c() { return 1; }
static test() { this.#c++; }
}
var test = C.test;
test();
"
frame size: 2
parameter count: 1
bytecode array length: 17
bytecodes: [
/* 51 E> */ B(StackCheck),
/* 56 S> */ B(Wide), B(LdaSmi), I16(261),
B(Star), R(0),
B(LdaConstant), U8(0),
B(Star), R(1),
B(CallRuntime), U16(Runtime::kNewTypeError), R(0), U8(2),
B(Throw),
]
constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["#c"],
]
handlers: [
]
---
snippet: "
class D {
static get #d() { return 1; }
static set #d(val) { }
static test() {
this.#d++;
this.#d = 1;
return this.#d;
}
}
var test = D.test;
test();
"
frame size: 5
parameter count: 1
bytecode array length: 143
bytecodes: [
/* 81 E> */ B(StackCheck),
/* 90 S> */ B(LdaCurrentContextSlot), U8(4),
B(Star), R(1),
B(LdaCurrentContextSlot), U8(5),
/* 94 E> */ B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(18),
B(Wide), B(LdaSmi), I16(259),
B(Star), R(2),
B(LdaConstant), U8(0),
B(Star), R(3),
B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2),
B(Throw),
B(CallRuntime), U16(Runtime::kLoadPrivateGetter), R(1), U8(1),
B(Star), R(2),
B(CallProperty0), R(2), R(0), U8(0),
B(Inc), U8(2),
B(Star), R(2),
/* 97 E> */ B(CallRuntime), U16(Runtime::kLoadPrivateSetter), R(1), U8(1),
B(Star), R(3),
B(CallProperty1), R(3), R(0), R(2), U8(3),
/* 105 S> */ B(LdaSmi), I8(1),
B(Star), R(0),
B(LdaCurrentContextSlot), U8(4),
B(Star), R(2),
B(LdaCurrentContextSlot), U8(5),
/* 109 E> */ B(TestReferenceEqual), R(this),
B(Mov), R(this), R(1),
B(JumpIfTrue), U8(18),
B(Wide), B(LdaSmi), I16(260),
B(Star), R(3),
B(LdaConstant), U8(0),
B(Star), R(4),
B(CallRuntime), U16(Runtime::kNewTypeError), R(3), U8(2),
B(Throw),
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(4),
B(Star), R(1),
B(LdaCurrentContextSlot), U8(5),
/* 133 E> */ B(TestReferenceEqual), R(this),
B(Mov), R(this), R(0),
B(JumpIfTrue), U8(18),
B(Wide), B(LdaSmi), I16(259),
B(Star), R(2),
B(LdaConstant), U8(0),
B(Star), R(3),
B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2),
B(Throw),
B(CallRuntime), U16(Runtime::kLoadPrivateGetter), R(1), U8(1),
B(Star), R(2),
B(CallProperty0), R(2), R(0), U8(7),
/* 137 S> */ B(Return),
]
constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["#d"],
]
handlers: [
]
---
snippet: "
class E {
static get #e() { return 1; }
static test() { this.#e++; }
}
var test = E.test;
test();
"
frame size: 2
parameter count: 1
bytecode array length: 17
bytecodes: [
/* 55 E> */ B(StackCheck),
/* 60 S> */ B(Wide), B(LdaSmi), I16(263),
B(Star), R(0),
B(LdaConstant), U8(0),
B(Star), R(1),
B(CallRuntime), U16(Runtime::kNewTypeError), R(0), U8(2),
B(Throw),
]
constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["#e"],
]
handlers: [
]
---
snippet: "
class F {
static set #f(val) { }
static test() { this.#f++; }
}
var test = F.test;
test();
"
frame size: 2
parameter count: 1
bytecode array length: 17
bytecodes: [
/* 48 E> */ B(StackCheck),
/* 53 S> */ B(Wide), B(LdaSmi), I16(262),
B(Star), R(0),
B(LdaConstant), U8(0),
B(Star), R(1),
B(CallRuntime), U16(Runtime::kNewTypeError), R(0), U8(2),
B(Throw),
]
constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["#f"],
]
handlers: [
]
---
snippet: "
class G {
static get #d() { return 1; }
static test() { this.#d = 1; }
}
var test = G.test;
test();
"
frame size: 2
parameter count: 1
bytecode array length: 17
bytecodes: [
/* 55 E> */ B(StackCheck),
/* 60 S> */ B(Wide), B(LdaSmi), I16(263),
B(Star), R(0),
B(LdaConstant), U8(0),
B(Star), R(1),
/* 68 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(0), U8(2),
B(Throw),
]
constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["#d"],
]
handlers: [
]
---
snippet: "
class H {
set #h(val) { }
static test() { this.#h; }
}
var test = H.test;
test();
"
frame size: 3
parameter count: 1
bytecode array length: 17
bytecodes: [
/* 41 E> */ B(StackCheck),
/* 46 S> */ B(Wide), B(LdaSmi), I16(262),
B(Star), R(1),
B(LdaConstant), U8(0),
B(Star), R(2),
B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2),
B(Throw),
]
constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["#h"],
]
handlers: [
]

View File

@ -14,31 +14,26 @@ snippet: "
}
}
"
frame size: 7
frame size: 6
parameter count: 1
bytecode array length: 55
bytecode array length: 41
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(2),
B(PushContext), R(1),
B(LdaTheHole),
B(Star), R(6),
B(Star), R(5),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(3),
B(Star), R(2),
B(LdaConstant), U8(1),
B(Star), R(4),
B(Star), R(3),
B(CreateClosure), U8(3), U8(1), U8(2),
B(StaCurrentContextSlot), U8(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(Mov), R(5), R(1),
B(LdaConstant), U8(4),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1),
B(StaCurrentContextSlot), U8(5),
B(PopContext), R(2),
B(Mov), R(1), R(0),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3),
B(Star), R(3),
B(PopContext), R(1),
B(Mov), R(4), R(0),
B(LdaUndefined),
/* 84 S> */ B(Return),
]
@ -47,7 +42,6 @@ constant pool: [
FIXED_ARRAY_TYPE,
SHARED_FUNCTION_INFO_TYPE,
SHARED_FUNCTION_INFO_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["A"],
]
handlers: [
]
@ -60,35 +54,30 @@ snippet: "
}
}
"
frame size: 8
frame size: 6
parameter count: 1
bytecode array length: 65
bytecode array length: 51
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(2),
B(PushContext), R(1),
B(LdaTheHole),
B(Star), R(6),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(3),
B(LdaConstant), U8(1),
B(Star), R(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(Mov), R(5), R(1),
B(LdaConstant), U8(3),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1),
B(StaCurrentContextSlot), U8(5),
B(CreateClosure), U8(4), U8(1), U8(2),
B(Star), R(6),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(2),
B(LdaConstant), U8(1),
B(Star), R(3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3),
B(Star), R(3),
B(CreateClosure), U8(3), U8(1), U8(2),
B(Star), R(4),
B(LdaNull),
B(Star), R(7),
B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(4), U8(2),
B(StaCurrentContextSlot), U8(4),
B(PopContext), R(2),
B(Mov), R(1), R(0),
B(PopContext), R(1),
B(Mov), R(2), R(0),
B(LdaUndefined),
/* 88 S> */ B(Return),
]
@ -96,7 +85,6 @@ constant pool: [
SCOPE_INFO_TYPE,
FIXED_ARRAY_TYPE,
SHARED_FUNCTION_INFO_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["A"],
SHARED_FUNCTION_INFO_TYPE,
]
handlers: [
@ -110,35 +98,30 @@ snippet: "
}
}
"
frame size: 8
frame size: 6
parameter count: 1
bytecode array length: 65
bytecode array length: 51
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(2),
B(PushContext), R(1),
B(LdaTheHole),
B(Star), R(6),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(3),
B(LdaConstant), U8(1),
B(Star), R(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(Mov), R(5), R(1),
B(LdaConstant), U8(3),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1),
B(StaCurrentContextSlot), U8(5),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(2),
B(LdaConstant), U8(1),
B(Star), R(3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3),
B(Star), R(3),
B(LdaNull),
B(Star), R(6),
B(CreateClosure), U8(4), U8(1), U8(2),
B(Star), R(7),
B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2),
B(Star), R(4),
B(CreateClosure), U8(3), U8(1), U8(2),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(4), U8(2),
B(StaCurrentContextSlot), U8(4),
B(PopContext), R(2),
B(Mov), R(1), R(0),
B(PopContext), R(1),
B(Mov), R(2), R(0),
B(LdaUndefined),
/* 81 S> */ B(Return),
]
@ -146,7 +129,6 @@ constant pool: [
SCOPE_INFO_TYPE,
FIXED_ARRAY_TYPE,
SHARED_FUNCTION_INFO_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["A"],
SHARED_FUNCTION_INFO_TYPE,
]
handlers: [
@ -161,35 +143,30 @@ snippet: "
}
}
"
frame size: 8
frame size: 6
parameter count: 1
bytecode array length: 68
bytecode array length: 54
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(2),
B(PushContext), R(1),
B(LdaTheHole),
B(Star), R(6),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(3),
B(LdaConstant), U8(1),
B(Star), R(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(Mov), R(5), R(1),
B(LdaConstant), U8(3),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1),
B(StaCurrentContextSlot), U8(5),
B(CreateClosure), U8(4), U8(1), U8(2),
B(Star), R(6),
B(CreateClosure), U8(5), U8(2), U8(2),
B(Star), R(7),
B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(2),
B(LdaConstant), U8(1),
B(Star), R(3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3),
B(Star), R(3),
B(CreateClosure), U8(3), U8(1), U8(2),
B(Star), R(4),
B(CreateClosure), U8(4), U8(2), U8(2),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(4), U8(2),
B(StaCurrentContextSlot), U8(4),
B(PopContext), R(2),
B(Mov), R(1), R(0),
B(PopContext), R(1),
B(Mov), R(2), R(0),
B(LdaUndefined),
/* 115 S> */ B(Return),
]
@ -197,7 +174,6 @@ constant pool: [
SCOPE_INFO_TYPE,
FIXED_ARRAY_TYPE,
SHARED_FUNCTION_INFO_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["A"],
SHARED_FUNCTION_INFO_TYPE,
SHARED_FUNCTION_INFO_TYPE,
]
@ -213,33 +189,32 @@ snippet: "
}
}
"
frame size: 7
frame size: 6
parameter count: 1
bytecode array length: 61
bytecode array length: 58
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
B(PushContext), R(2),
B(PushContext), R(1),
B(LdaTheHole),
B(Star), R(6),
B(Star), R(5),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(3),
B(Star), R(2),
B(LdaConstant), U8(1),
B(Star), R(4),
B(Star), R(3),
B(CreateClosure), U8(3), U8(1), U8(2),
B(StaCurrentContextSlot), U8(4),
B(CreateClosure), U8(4), U8(2), U8(2),
B(StaCurrentContextSlot), U8(5),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(Mov), R(5), R(1),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3),
B(Star), R(3),
B(LdaConstant), U8(5),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1),
B(Star), R(4),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1),
B(StaCurrentContextSlot), U8(6),
B(PopContext), R(2),
B(Mov), R(1), R(0),
B(PopContext), R(1),
B(Mov), R(2), R(0),
B(LdaUndefined),
/* 87 S> */ B(Return),
]

View File

@ -2928,6 +2928,86 @@ TEST(StaticPrivateMethodDeclaration) {
i::FLAG_harmony_private_methods = old_methods_flag;
}
TEST(StaticPrivateMethodAccess) {
bool old_methods_flag = i::FLAG_harmony_private_methods;
i::FLAG_harmony_private_methods = true;
InitializedIgnitionHandleScope scope;
BytecodeExpectationsPrinter printer(CcTest::isolate());
printer.set_wrap(false);
printer.set_test_function_name("test");
const char* snippets[] = {
"class A {\n"
" static #a() { return 1; }\n"
" static test() { return this.#a(); }\n"
"}\n"
"\n"
"var test = A.test;\n"
"test();\n",
"class B {\n"
" static #b() { return 1; }\n"
" static test() { this.#b = 1; }\n"
"}\n"
"\n"
"var test = B.test;\n"
"test();\n",
"class C {\n"
" static #c() { return 1; }\n"
" static test() { this.#c++; }\n"
"}\n"
"\n"
"var test = C.test;\n"
"test();\n",
"class D {\n"
" static get #d() { return 1; }\n"
" static set #d(val) { }\n"
"\n"
" static test() {\n"
" this.#d++;\n"
" this.#d = 1;\n"
" return this.#d;\n"
" }\n"
"}\n"
"\n"
"var test = D.test;\n"
"test();\n",
"class E {\n"
" static get #e() { return 1; }\n"
" static test() { this.#e++; }\n"
"}\n"
"var test = E.test;\n"
"test();\n",
"class F {\n"
" static set #f(val) { }\n"
" static test() { this.#f++; }\n"
"}\n"
"var test = F.test;\n"
"test();\n",
"class G {\n"
" static get #d() { return 1; }\n"
" static test() { this.#d = 1; }\n"
"}\n"
"var test = G.test;\n"
"test();\n",
"class H {\n"
" set #h(val) { }\n"
" static test() { this.#h; }\n"
"}\n"
"var test = H.test;\n"
"test();\n"};
CHECK(CompareTexts(BuildActual(printer, snippets),
LoadGolden("StaticPrivateMethodAccess.golden")));
i::FLAG_harmony_private_methods = old_methods_flag;
}
TEST(PrivateAccessorDeclaration) {
bool old_methods_flag = i::FLAG_harmony_private_methods;
i::FLAG_harmony_private_methods = true;

View File

@ -109,26 +109,6 @@ Running test: testScopesPaused
type : local
}
[1] : {
endLocation : {
columnNumber : 3
lineNumber : 15
scriptId : <scriptId>
}
name : run
object : {
className : Object
description : Object
objectId : <objectId>
type : object
}
startLocation : {
columnNumber : 9
lineNumber : 11
scriptId : <scriptId>
}
type : block
}
[2] : {
endLocation : {
columnNumber : 1
lineNumber : 19
@ -148,7 +128,7 @@ Running test: testScopesPaused
}
type : local
}
[3] : {
[2] : {
object : {
className : global
description : global

View File

@ -11,7 +11,10 @@
let store = 1;
class C {
static #a() { return store; }
static a() { return this.#a(); }
}
assertEquals(C.a(), store);
assertThrows(() => C.a.call(new C), TypeError);
}
// Complementary static private accessors.
@ -20,7 +23,208 @@
class C {
static get #a() { return store; }
static set #a(val) { store = val; }
static incA() { this.#a++; }
static getA() { return this.#a; }
static setA(val) { this.#a = val; }
}
assertEquals(C.getA(), 1);
C.incA();
assertEquals(store, 2);
C.setA(3);
assertEquals(store, 3);
assertThrows(() => C.incA.call(new C), TypeError);
assertThrows(() => C.getA.call(new C), TypeError);
assertThrows(() => C.setA.call(new C), TypeError);
assertThrows(() => { const incA = C.incA; incA(); }, TypeError);
assertThrows(() => { const getA = C.getA; getA(); }, TypeError);
assertThrows(() => { const setA = C.setA; setA(); }, TypeError);
}
// Static private methods accessed explicitly in an anonymous nested class.
{
class Outer {
#a() { return 'Outer'; }
a() { return this.#a(); }
test() {
return class {
static #a() { return 'Inner'; }
static a() { return this.#a(); }
};
}
}
const obj = new Outer;
const C = obj.test();
assertEquals(C.a(), 'Inner');
assertThrows(() => obj.a.call(C), TypeError);
assertThrows(() => obj.a.call(new C), TypeError);
}
// Static private methods accessed explicitly in a named nested class.
{
class Outer {
#a() { return 'Outer'; }
a() { return this.#a(); }
test() {
return class Inner {
static #a() { return 'Inner'; }
static a() { return this.#a(); }
};
}
}
const obj = new Outer;
const C = obj.test();
assertEquals(C.a(), 'Inner');
assertThrows(() => obj.a.call(C), TypeError);
assertThrows(() => obj.a.call(new C), TypeError);
}
// Static private methods accessed through eval in an anonymous nested class.
{
class Outer {
#a() { return 'Outer'; }
a() { return this.#a(); }
test() {
return class {
static #a() { return 'Inner'; }
static a(str) { return eval(str); }
};
}
}
const obj = new Outer;
const C = obj.test();
assertEquals(C.a('this.#a()'), 'Inner');
assertThrows(() => C.a('Outer.#a()'), TypeError);
}
// Static private methods accessed through eval in a named nested class.
{
class Outer {
#a() { return 'Outer'; }
a() { return this.#a(); }
test() {
return class Inner {
static #a() { return 'Inner'; }
static a(str) { return eval(str); }
};
}
}
const obj = new Outer;
const C = obj.test();
assertEquals(C.a('this.#a()'), 'Inner');
assertEquals(C.a('Inner.#a()'), 'Inner');
assertThrows(() => C.a('Outer.#a()'), TypeError);
assertThrows(() => C.run('(new Outer).#a()'), TypeError);
}
// Static private methods in the outer class accessed through eval
// in a named nested class.
{
class Outer {
static #a() { return 'Outer'; }
static test() {
return class Inner {
static run(str) { return eval(str); }
};
}
}
const C = Outer.test();
assertEquals(C.run('Outer.#a()'), 'Outer');
assertThrows(() => C.run('this.#a()'), TypeError);
assertThrows(() => C.run('Inner.#a()'), TypeError);
assertThrows(() => C.run('(new Outer).#a()'), TypeError);
}
// Static private methods in the outer class accessed explicitly
// in a named nested class.
{
class Outer {
static #a() { return 'Outer'; }
static test() {
return class Inner {
static getA(klass) { return klass.#a(); }
};
}
}
const C = Outer.test();
assertEquals(C.getA(Outer), 'Outer');
assertThrows(() => C.getA.call(C), TypeError);
assertThrows(() => C.getA.call(new Outer), TypeError);
}
// Static private methods in the outer class accessed explicitly
// in an anonymous nested class.
{
class Outer {
static #a() { return 'Outer'; }
static test() {
return class {
static getA(klass) { return klass.#a(); }
};
}
}
const C = Outer.test();
assertEquals(C.getA(Outer), 'Outer');
assertThrows(() => C.getA.call(C), TypeError);
assertThrows(() => C.getA.call(new Outer), TypeError);
}
// Super property access in static private methods
{
class A {
static a = 1;
}
class B extends A {
static #a() { return super.a; }
static getA() { return this.#a(); }
}
assertEquals(B.getA(), 1);
}
// Invalid super property access in static private methods
{
class A {
static #a() { return 1; }
static getA() { return this.#a(); }
}
class B extends A {
static getA() { return super.getA(); }
}
assertThrows(() => B.getA(), TypeError);
}
// Static private methods accessed in eval.
{
class C {
static #m(v) { return v; }
static test(str) {
return eval(str);
}
}
assertEquals(C.test('this.#m(1)'), 1);
}
// Test that the receiver is checked during run time.
{
const C = class {
static #a() { }
static test(klass) { return klass.#a; }
};
const test = C.test;
assertThrows(test, TypeError);
}
// Duplicate static private accessors and methods.