[interpreter] Support for ES6 super keyword.

Adds support for ES6 super keyword and performing loads, stores, and
calls to super class members.

Implements SetHomeObject and enables ThisFunctionVariable.

BUG=v8:4280,v8:4682
LOG=N

Review URL: https://codereview.chromium.org/1689573004

Cr-Commit-Position: refs/heads/master@{#33977}
This commit is contained in:
oth 2016-02-15 00:18:16 -08:00 committed by Commit bot
parent f0561ac5d9
commit e768bcca24
14 changed files with 520 additions and 176 deletions

View File

@ -1136,33 +1136,34 @@ void BytecodeGraphBuilder::VisitCallRuntimeForPairWide() {
BuildCallRuntimeForPair();
}
Node* BytecodeGraphBuilder::ProcessCallNewArguments(
const Operator* call_new_op, interpreter::Register callee,
const Operator* call_new_op, Node* callee, Node* new_target,
interpreter::Register first_arg, size_t arity) {
Node** all = info()->zone()->NewArray<Node*>(arity);
all[0] = environment()->LookupRegister(callee);
all[0] = new_target;
int first_arg_index = first_arg.index();
for (int i = 1; i < static_cast<int>(arity) - 1; ++i) {
all[i] = environment()->LookupRegister(
interpreter::Register(first_arg_index + i - 1));
}
// Original constructor is the same as the callee.
all[arity - 1] = environment()->LookupRegister(callee);
all[arity - 1] = callee;
Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false);
return value;
}
void BytecodeGraphBuilder::BuildCallConstruct() {
FrameStateBeforeAndAfter states(this);
interpreter::Register callee = bytecode_iterator().GetRegisterOperand(0);
interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
Node* new_target = environment()->LookupAccumulator();
Node* callee = environment()->LookupRegister(callee_reg);
// TODO(turbofan): Pass the feedback here.
const Operator* call = javascript()->CallConstruct(
static_cast<int>(arg_count) + 2, VectorSlotPair());
Node* value = ProcessCallNewArguments(call, callee, first_arg, arg_count + 2);
Node* value = ProcessCallNewArguments(call, callee, new_target, first_arg,
arg_count + 2);
environment()->BindAccumulator(value, &states);
}

View File

@ -103,8 +103,8 @@ class BytecodeGraphBuilder {
Node* ProcessCallArguments(const Operator* call_op, Node* callee,
interpreter::Register receiver, size_t arity);
Node* ProcessCallNewArguments(const Operator* call_new_op,
interpreter::Register callee,
Node* ProcessCallNewArguments(const Operator* call_new_op, Node* callee,
Node* new_target,
interpreter::Register first_arg, size_t arity);
Node* ProcessCallRuntimeArguments(const Operator* call_runtime_op,
interpreter::Register first_arg,

View File

@ -484,9 +484,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot(
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty(
Register object, const Handle<String> name, int feedback_slot,
Register object, const Handle<Name> name, int feedback_slot,
LanguageMode language_mode) {
Bytecode bytecode = BytecodeForLoadIC(language_mode);
size_t name_index = GetConstantPoolEntry(name);
@ -520,9 +519,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty(
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
Register object, const Handle<String> name, int feedback_slot,
Register object, const Handle<Name> name, int feedback_slot,
LanguageMode language_mode) {
Bytecode bytecode = BytecodeForStoreIC(language_mode);
size_t name_index = GetConstantPoolEntry(name);
@ -1107,7 +1105,6 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor,
Register first_arg,
size_t arg_count) {

View File

@ -114,7 +114,7 @@ class BytecodeArrayBuilder final : public ZoneObject, private RegisterMover {
// Named load property.
BytecodeArrayBuilder& LoadNamedProperty(Register object,
const Handle<String> name,
const Handle<Name> name,
int feedback_slot,
LanguageMode language_mode);
// Keyed load property. The key should be in the accumulator.
@ -123,7 +123,7 @@ class BytecodeArrayBuilder final : public ZoneObject, private RegisterMover {
// Store properties. The value to be stored should be in the accumulator.
BytecodeArrayBuilder& StoreNamedProperty(Register object,
const Handle<String> name,
const Handle<Name> name,
int feedback_slot,
LanguageMode language_mode);
BytecodeArrayBuilder& StoreKeyedProperty(Register object, Register key,
@ -167,9 +167,10 @@ class BytecodeArrayBuilder final : public ZoneObject, private RegisterMover {
BytecodeArrayBuilder& Call(Register callable, Register receiver_args,
size_t receiver_arg_count, int feedback_slot);
// Call the new operator. The |constructor| register is followed by
// |arg_count| consecutive registers containing arguments to be
// applied to the constructor.
// Call the new operator. The accumulator holds the |new_target|.
// The |constructor| is in a register followed by |arg_count|
// consecutive arguments starting at |first_arg| for the constuctor
// invocation.
BytecodeArrayBuilder& New(Register constructor, Register first_arg,
size_t arg_count);

View File

@ -418,6 +418,11 @@ class BytecodeGenerator::RegisterAllocationScope {
return allocator_.NextConsecutiveRegister();
}
template <size_t N>
void PrepareAndInitializeConsecutiveAllocations(Register (&registers)[N]) {
return allocator_.PrepareAndInitializeConsecutiveAllocations(registers, N);
}
bool RegisterIsAllocatedInThisScope(Register reg) const {
return allocator_.RegisterIsAllocatedInThisScope(reg);
}
@ -543,6 +548,26 @@ class BytecodeGenerator::RegisterResultScope final
Register result_register_;
};
// Class for holding arguments for runtime calls relating to super
// properties.
class BytecodeGenerator::SuperPropertyArguments final {
public:
SuperPropertyArguments() {}
Register (&registers())[4] { return args_; }
Register receiver() const { return args_[0]; }
Register home_object() const { return args_[1]; }
Register name_or_key() const { return args_[2]; }
Register store_value() const { return args_[3]; }
Register language_mode() const { return args_[3]; }
size_t count() const { return arraysize(args_); }
private:
Register args_[4];
DISALLOW_COPY_AND_ASSIGN(SuperPropertyArguments);
};
BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone)
: isolate_(isolate),
zone_(zone),
@ -559,7 +584,6 @@ BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone)
InitializeAstVisitor(isolate);
}
Handle<BytecodeArray> BytecodeGenerator::MakeBytecode(CompilationInfo* info) {
set_info(info);
set_scope(info->scope());
@ -1050,9 +1074,30 @@ void BytecodeGenerator::VisitForInAssignment(Expression* expr,
language_mode());
break;
}
case NAMED_SUPER_PROPERTY:
case KEYED_SUPER_PROPERTY:
UNIMPLEMENTED();
case NAMED_SUPER_PROPERTY: {
RegisterAllocationScope register_scope(this);
SuperPropertyArguments super_args;
Register value = register_allocator()->NewRegister();
builder()->StoreAccumulatorInRegister(value);
PrepareNamedSuperPropertyArguments(
property->obj()->AsSuperPropertyReference(),
property->key()->AsLiteral()->AsPropertyName(), &super_args);
builder()->LoadAccumulatorWithRegister(value);
BuildNamedSuperPropertyStore(&super_args);
break;
}
case KEYED_SUPER_PROPERTY: {
RegisterAllocationScope register_scope(this);
SuperPropertyArguments super_args;
Register value = register_allocator()->NewRegister();
builder()->StoreAccumulatorInRegister(value);
PrepareKeyedSuperPropertyArguments(
property->obj()->AsSuperPropertyReference(), property->key(),
&super_args);
builder()->LoadAccumulatorWithRegister(value);
BuildKeyedSuperPropertyStore(&super_args);
break;
}
}
}
@ -1495,9 +1540,19 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
if (literal_key->value()->IsInternalizedString()) {
if (property->emit_store()) {
VisitForAccumulatorValue(property->value());
builder()->StoreNamedProperty(
literal, literal_key->AsPropertyName(),
feedback_index(property->GetSlot(0)), language_mode());
if (FunctionLiteral::NeedsHomeObject(property->value())) {
RegisterAllocationScope register_scope(this);
Register value = register_allocator()->NewRegister();
builder()->StoreAccumulatorInRegister(value);
builder()->StoreNamedProperty(
literal, literal_key->AsPropertyName(),
feedback_index(property->GetSlot(0)), language_mode());
VisitSetHomeObject(value, literal, property, 1);
} else {
builder()->StoreNamedProperty(
literal, literal_key->AsPropertyName(),
feedback_index(property->GetSlot(0)), language_mode());
}
} else {
VisitForEffect(property->value());
}
@ -1781,6 +1836,72 @@ Register BytecodeGenerator::VisitVariableLoadForRegisterValue(
return register_scope.ResultRegister();
}
void BytecodeGenerator::PrepareNamedSuperPropertyArguments(
SuperPropertyReference* super_property, Handle<Name> name,
SuperPropertyArguments* super_args) {
register_allocator()->PrepareAndInitializeConsecutiveAllocations(
super_args->registers());
VisitForAccumulatorValue(super_property->this_var());
builder()->StoreAccumulatorInRegister(super_args->receiver());
VisitForAccumulatorValue(super_property->home_object());
builder()->StoreAccumulatorInRegister(super_args->home_object());
builder()->LoadLiteral(name).StoreAccumulatorInRegister(
super_args->name_or_key());
}
void BytecodeGenerator::PrepareKeyedSuperPropertyArguments(
SuperPropertyReference* super_property, Expression* key,
SuperPropertyArguments* super_args) {
register_allocator()->PrepareAndInitializeConsecutiveAllocations(
super_args->registers());
VisitForAccumulatorValue(super_property->this_var());
builder()->StoreAccumulatorInRegister(super_args->receiver());
VisitForAccumulatorValue(super_property->home_object());
builder()->StoreAccumulatorInRegister(super_args->home_object());
VisitForAccumulatorValue(key);
builder()->StoreAccumulatorInRegister(super_args->name_or_key());
}
void BytecodeGenerator::BuildNamedSuperPropertyLoad(
SuperPropertyArguments* super_args) {
builder()
->LoadLiteral(Smi::FromInt(static_cast<int>(language_mode())))
.StoreAccumulatorInRegister(super_args->language_mode());
builder()->CallRuntime(Runtime::kLoadFromSuper, super_args->receiver(),
super_args->count());
}
void BytecodeGenerator::BuildKeyedSuperPropertyLoad(
SuperPropertyArguments* super_args) {
builder()
->LoadLiteral(Smi::FromInt(static_cast<int>(language_mode())))
.StoreAccumulatorInRegister(super_args->language_mode());
builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, super_args->receiver(),
super_args->count());
}
void BytecodeGenerator::BuildNamedSuperPropertyStore(
SuperPropertyArguments* super_args) {
builder()->StoreAccumulatorInRegister(super_args->store_value());
Runtime::FunctionId function_id = is_strict(language_mode())
? Runtime::kStoreToSuper_Strict
: Runtime::kStoreToSuper_Sloppy;
builder()->CallRuntime(function_id, super_args->receiver(),
super_args->count());
}
void BytecodeGenerator::BuildKeyedSuperPropertyStore(
SuperPropertyArguments* super_args) {
builder()->StoreAccumulatorInRegister(super_args->store_value());
Runtime::FunctionId function_id = is_strict(language_mode())
? Runtime::kStoreKeyedToSuper_Strict
: Runtime::kStoreKeyedToSuper_Sloppy;
builder()->CallRuntime(function_id, super_args->receiver(),
super_args->count());
}
void BytecodeGenerator::BuildThrowReferenceError(Handle<String> name) {
RegisterAllocationScope register_scope(this);
Register name_reg = register_allocator()->NewRegister();
@ -1836,7 +1957,7 @@ void BytecodeGenerator::BuildHoleCheckForVariableAssignment(Variable* variable,
// Perform an initialization check for 'this'. 'this' variable is the
// only variable able to trigger bind operations outside the TDZ
// via 'super' calls.
BuildThrowIfHole(variable->name());
BuildThrowIfNotHole(variable->name());
}
}
@ -1988,8 +2109,9 @@ void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
void BytecodeGenerator::VisitAssignment(Assignment* expr) {
DCHECK(expr->target()->IsValidReferenceExpression());
DCHECK(expr->target()->IsValidReferenceExpressionOrThis());
Register object, key;
SuperPropertyArguments super_args;
Handle<String> name;
// Left-hand side can only be a property, a global or a variable slot.
@ -2019,9 +2141,18 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
}
break;
}
case NAMED_SUPER_PROPERTY:
case KEYED_SUPER_PROPERTY:
UNIMPLEMENTED();
case NAMED_SUPER_PROPERTY: {
PrepareNamedSuperPropertyArguments(
property->obj()->AsSuperPropertyReference(),
property->key()->AsLiteral()->AsPropertyName(), &super_args);
break;
}
case KEYED_SUPER_PROPERTY: {
PrepareKeyedSuperPropertyArguments(
property->obj()->AsSuperPropertyReference(), property->key(),
&super_args);
break;
}
}
// Evaluate the value and potentially handle compound assignments by loading
@ -2054,10 +2185,18 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
.StoreAccumulatorInRegister(old_value);
break;
}
case NAMED_SUPER_PROPERTY:
case KEYED_SUPER_PROPERTY:
UNIMPLEMENTED();
case NAMED_SUPER_PROPERTY: {
old_value = register_allocator()->NewRegister();
BuildNamedSuperPropertyLoad(&super_args);
builder()->StoreAccumulatorInRegister(old_value);
break;
}
case KEYED_SUPER_PROPERTY: {
old_value = register_allocator()->NewRegister();
BuildKeyedSuperPropertyLoad(&super_args);
builder()->StoreAccumulatorInRegister(old_value);
break;
}
}
VisitForAccumulatorValue(expr->value());
builder()->BinaryOperation(expr->binary_op(), old_value,
@ -2084,9 +2223,14 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
builder()->StoreKeyedProperty(object, key, feedback_index(slot),
language_mode());
break;
case NAMED_SUPER_PROPERTY:
case KEYED_SUPER_PROPERTY:
UNIMPLEMENTED();
case NAMED_SUPER_PROPERTY: {
BuildNamedSuperPropertyStore(&super_args);
break;
}
case KEYED_SUPER_PROPERTY: {
BuildKeyedSuperPropertyStore(&super_args);
break;
}
}
execution_result()->SetResultInAccumulator();
}
@ -2124,25 +2268,57 @@ void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) {
break;
}
case NAMED_SUPER_PROPERTY:
VisitNamedSuperPropertyLoad(expr, Register::invalid_value());
break;
case KEYED_SUPER_PROPERTY:
UNIMPLEMENTED();
VisitKeyedSuperPropertyLoad(expr, Register::invalid_value());
break;
}
execution_result()->SetResultInAccumulator();
}
void BytecodeGenerator::VisitPropertyLoadForAccumulator(Register obj,
Property* expr) {
AccumulatorResultScope result_scope(this);
VisitPropertyLoad(obj, expr);
}
void BytecodeGenerator::VisitProperty(Property* expr) {
Register obj = VisitForRegisterValue(expr->obj());
VisitPropertyLoad(obj, expr);
void BytecodeGenerator::VisitNamedSuperPropertyLoad(Property* property,
Register opt_receiver_out) {
RegisterAllocationScope register_scope(this);
SuperPropertyArguments super_args;
PrepareNamedSuperPropertyArguments(
property->obj()->AsSuperPropertyReference(),
property->key()->AsLiteral()->AsPropertyName(), &super_args);
if (opt_receiver_out.is_valid()) {
builder()->MoveRegister(super_args.receiver(), opt_receiver_out);
}
BuildNamedSuperPropertyLoad(&super_args);
}
void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property,
Register opt_receiver_out) {
RegisterAllocationScope register_scope(this);
SuperPropertyArguments super_args;
PrepareKeyedSuperPropertyArguments(
property->obj()->AsSuperPropertyReference(), property->key(),
&super_args);
if (opt_receiver_out.is_valid()) {
builder()->MoveRegister(super_args.receiver(), opt_receiver_out);
}
BuildKeyedSuperPropertyLoad(&super_args);
}
void BytecodeGenerator::VisitProperty(Property* expr) {
LhsKind property_kind = Property::GetAssignType(expr);
if (property_kind != NAMED_SUPER_PROPERTY &&
property_kind != KEYED_SUPER_PROPERTY) {
Register obj = VisitForRegisterValue(expr->obj());
VisitPropertyLoad(obj, expr);
} else {
VisitPropertyLoad(Register::invalid_value(), expr);
}
}
Register BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args) {
if (args->length() == 0) {
@ -2176,11 +2352,14 @@ Register BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args) {
return first_arg;
}
void BytecodeGenerator::VisitCall(Call* expr) {
Expression* callee_expr = expr->expression();
Call::CallType call_type = expr->GetCallType(isolate());
if (call_type == Call::SUPER_CALL) {
return VisitCallSuper(expr);
}
// Prepare the callee and the receiver to the function call. This depends on
// the semantics of the underlying call type.
@ -2238,10 +2417,21 @@ void BytecodeGenerator::VisitCall(Call* expr) {
builder()->StoreAccumulatorInRegister(callee);
break;
}
case Call::NAMED_SUPER_PROPERTY_CALL:
case Call::KEYED_SUPER_PROPERTY_CALL:
case Call::NAMED_SUPER_PROPERTY_CALL: {
Property* property = callee_expr->AsProperty();
VisitNamedSuperPropertyLoad(property, receiver);
builder()->StoreAccumulatorInRegister(callee);
break;
}
case Call::KEYED_SUPER_PROPERTY_CALL: {
Property* property = callee_expr->AsProperty();
VisitKeyedSuperPropertyLoad(property, receiver);
builder()->StoreAccumulatorInRegister(callee);
break;
}
case Call::SUPER_CALL:
UNIMPLEMENTED();
UNREACHABLE();
break;
}
// Evaluate all arguments to the function call and store in sequential
@ -2285,6 +2475,32 @@ void BytecodeGenerator::VisitCall(Call* expr) {
execution_result()->SetResultInAccumulator();
}
void BytecodeGenerator::VisitCallSuper(Call* expr) {
RegisterAllocationScope register_scope(this);
SuperCallReference* super = expr->expression()->AsSuperCallReference();
// Prepare the constructor to the super call.
Register this_function = register_allocator()->NewRegister();
VisitForAccumulatorValue(super->this_function_var());
builder()
->StoreAccumulatorInRegister(this_function)
.CallRuntime(Runtime::kInlineGetSuperConstructor, this_function, 1);
Register constructor = this_function; // Re-use dead this_function register.
builder()->StoreAccumulatorInRegister(constructor);
ZoneList<Expression*>* args = expr->arguments();
Register first_arg = VisitArguments(args);
// The new target is loaded into the accumulator from the
// {new.target} variable.
VisitForAccumulatorValue(super->new_target_var());
// Call construct.
builder()->SetExpressionPosition(expr);
builder()->New(constructor, first_arg, args->length());
execution_result()->SetResultInAccumulator();
}
void BytecodeGenerator::VisitCallNew(CallNew* expr) {
Register constructor = register_allocator()->NewRegister();
@ -2293,8 +2509,13 @@ void BytecodeGenerator::VisitCallNew(CallNew* expr) {
ZoneList<Expression*>* args = expr->arguments();
Register first_arg = VisitArguments(args);
builder()->SetExpressionPosition(expr);
builder()->New(constructor, first_arg, args->length());
// The accumulator holds new target which is the same as the
// constructor for CallNew.
builder()
->LoadAccumulatorWithRegister(constructor)
.New(constructor, first_arg, args->length());
execution_result()->SetResultInAccumulator();
}
@ -2448,7 +2669,8 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
bool is_postfix = expr->is_postfix();
// Evaluate LHS expression and get old value.
Register obj, key, old_value;
Register object, key, old_value;
SuperPropertyArguments super_args;
Handle<String> name;
switch (assign_type) {
case VARIABLE: {
@ -2459,26 +2681,37 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
}
case NAMED_PROPERTY: {
FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
obj = VisitForRegisterValue(property->obj());
object = VisitForRegisterValue(property->obj());
name = property->key()->AsLiteral()->AsPropertyName();
builder()->LoadNamedProperty(obj, name, feedback_index(slot),
builder()->LoadNamedProperty(object, name, feedback_index(slot),
language_mode());
break;
}
case KEYED_PROPERTY: {
FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
obj = VisitForRegisterValue(property->obj());
object = VisitForRegisterValue(property->obj());
// Use visit for accumulator here since we need the key in the accumulator
// for the LoadKeyedProperty.
key = register_allocator()->NewRegister();
VisitForAccumulatorValue(property->key());
builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty(
obj, feedback_index(slot), language_mode());
object, feedback_index(slot), language_mode());
break;
}
case NAMED_SUPER_PROPERTY: {
PrepareNamedSuperPropertyArguments(
property->obj()->AsSuperPropertyReference(),
property->key()->AsLiteral()->AsPropertyName(), &super_args);
BuildNamedSuperPropertyLoad(&super_args);
break;
}
case KEYED_SUPER_PROPERTY: {
PrepareKeyedSuperPropertyArguments(
property->obj()->AsSuperPropertyReference(), property->key(),
&super_args);
BuildKeyedSuperPropertyLoad(&super_args);
break;
}
case NAMED_SUPER_PROPERTY:
case KEYED_SUPER_PROPERTY:
UNIMPLEMENTED();
}
// Convert old value into a number.
@ -2504,18 +2737,23 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
break;
}
case NAMED_PROPERTY: {
builder()->StoreNamedProperty(obj, name, feedback_index(feedback_slot),
builder()->StoreNamedProperty(object, name, feedback_index(feedback_slot),
language_mode());
break;
}
case KEYED_PROPERTY: {
builder()->StoreKeyedProperty(obj, key, feedback_index(feedback_slot),
builder()->StoreKeyedProperty(object, key, feedback_index(feedback_slot),
language_mode());
break;
}
case NAMED_SUPER_PROPERTY:
case KEYED_SUPER_PROPERTY:
UNIMPLEMENTED();
case NAMED_SUPER_PROPERTY: {
BuildNamedSuperPropertyStore(&super_args);
break;
}
case KEYED_SUPER_PROPERTY: {
BuildKeyedSuperPropertyStore(&super_args);
break;
}
}
// Restore old value for postfix expressions.
@ -2575,13 +2813,15 @@ void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) {
void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) {
UNIMPLEMENTED();
// Handled by VisitCall().
UNREACHABLE();
}
void BytecodeGenerator::VisitSuperPropertyReference(
SuperPropertyReference* expr) {
UNIMPLEMENTED();
builder()->CallRuntime(Runtime::kThrowUnsupportedSuperError, Register(0), 0);
execution_result()->SetResultInAccumulator();
}
@ -2754,14 +2994,17 @@ void BytecodeGenerator::VisitObjectLiteralAccessor(
}
}
void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object,
ObjectLiteralProperty* property,
int slot_number) {
Expression* expr = property->value();
if (!FunctionLiteral::NeedsHomeObject(expr)) return;
UNIMPLEMENTED();
if (FunctionLiteral::NeedsHomeObject(expr)) {
Handle<Name> name = isolate()->factory()->home_object_symbol();
FeedbackVectorSlot slot = property->GetSlot(slot_number);
builder()
->LoadAccumulatorWithRegister(home_object)
.StoreNamedProperty(value, name, feedback_index(slot), language_mode());
}
}
@ -2794,9 +3037,6 @@ void BytecodeGenerator::VisitRestArgumentsArray(Variable* rest) {
void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) {
if (variable == nullptr) return;
// TODO(rmcilroy): Remove once we have tests which exercise this code path.
UNIMPLEMENTED();
// Store the closure we were called with in the given variable.
builder()->LoadAccumulatorWithRegister(Register::function_closure());
VisitVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid());

View File

@ -42,6 +42,7 @@ class BytecodeGenerator final : public AstVisitor {
class AccumulatorResultScope;
class RegisterResultScope;
class RegisterAllocationScope;
class SuperPropertyArguments;
void MakeBytecodeBody();
@ -65,6 +66,20 @@ class BytecodeGenerator final : public AstVisitor {
// Helper visitors which perform common operations.
Register VisitArguments(ZoneList<Expression*>* arguments);
// Visit a keyed super property load. The optional
// |opt_receiver_out| register will have the receiver stored to it
// if it's a valid register. The loaded value is placed in the
// accumulator.
void VisitKeyedSuperPropertyLoad(Property* property,
Register opt_receiver_out);
// Visit a named super property load. The optional
// |opt_receiver_out| register will have the receiver stored to it
// if it's a valid register. The loaded value is placed in the
// accumulator.
void VisitNamedSuperPropertyLoad(Property* property,
Register opt_receiver_out);
void VisitPropertyLoad(Register obj, Property* expr);
void VisitPropertyLoadForAccumulator(Register obj, Property* expr);
@ -79,6 +94,19 @@ class BytecodeGenerator final : public AstVisitor {
void VisitVariableAssignment(Variable* variable, Token::Value op,
FeedbackVectorSlot slot);
void PrepareNamedSuperPropertyArguments(
SuperPropertyReference* super_property, Handle<Name> name,
SuperPropertyArguments* super_property_args);
void PrepareKeyedSuperPropertyArguments(
SuperPropertyReference* super_property, Expression* key,
SuperPropertyArguments* super_property_args);
void BuildNamedSuperPropertyLoad(SuperPropertyArguments* super_property_args);
void BuildKeyedSuperPropertyLoad(SuperPropertyArguments* super_property_args);
void BuildNamedSuperPropertyStore(
SuperPropertyArguments* super_property_args);
void BuildKeyedSuperPropertyStore(
SuperPropertyArguments* super_property_args);
void BuildThrowIfHole(Handle<String> name);
void BuildThrowIfNotHole(Handle<String> name);
void BuildThrowReassignConstant(Handle<String> name);
@ -88,6 +116,7 @@ class BytecodeGenerator final : public AstVisitor {
void VisitArgumentsObject(Variable* variable);
void VisitRestArgumentsArray(Variable* rest);
void VisitCallSuper(Call* call);
void VisitClassLiteralContents(ClassLiteral* expr);
void VisitClassLiteralForRuntimeDefinition(ClassLiteral* expr);
void VisitClassLiteralProperties(ClassLiteral* expr, Register literal,
@ -130,6 +159,10 @@ class BytecodeGenerator final : public AstVisitor {
bool IsInsideTryCatch() const { return try_catch_nesting_level_ > 0; }
bool IsInsideTryFinally() const { return try_finally_nesting_level_ > 0; }
// Initialize an array of temporary registers with consecutive registers.
template <size_t N>
void InitializeWithConsecutiveRegisters(Register (&registers)[N]);
inline void set_builder(BytecodeArrayBuilder* builder) { builder_ = builder; }
inline BytecodeArrayBuilder* builder() const { return builder_; }

View File

@ -224,6 +224,14 @@ Register BytecodeRegisterAllocator::NextConsecutiveRegister() {
return Register(next_consecutive_register_++);
}
void BytecodeRegisterAllocator::PrepareAndInitializeConsecutiveAllocations(
Register* registers, size_t count) {
PrepareForConsecutiveAllocations(count);
for (size_t i = 0; i < count; i++) {
registers[i] = NextConsecutiveRegister();
}
}
} // namespace interpreter
} // namespace internal
} // namespace v8

View File

@ -74,11 +74,22 @@ class BytecodeRegisterAllocator final {
~BytecodeRegisterAllocator();
Register NewRegister();
// Ensure |count| consecutive allocations are available.
void PrepareForConsecutiveAllocations(size_t count);
// Get the next consecutive allocation after calling
// PrepareForConsecutiveAllocations.
Register NextConsecutiveRegister();
// Prepare consecutive register allocations and initialize an array
// of registers with the allocations.
void PrepareAndInitializeConsecutiveAllocations(Register* registers,
size_t count);
// Returns true if |reg| is allocated in this allocator.
bool RegisterIsAllocatedInThisScope(Register reg) const;
// Returns true if unused consecutive allocations remain.
bool HasConsecutiveAllocations() const { return next_consecutive_count_ > 0; }
private:

View File

@ -1166,14 +1166,15 @@ void Interpreter::DoCallJSRuntimeWide(InterpreterAssembler* assembler) {
void Interpreter::DoCallConstruct(InterpreterAssembler* assembler) {
Callable ic = CodeFactory::InterpreterPushArgsAndConstruct(isolate_);
Node* new_target = __ GetAccumulator();
Node* constructor_reg = __ BytecodeOperandReg(0);
Node* constructor = __ LoadRegister(constructor_reg);
Node* first_arg_reg = __ BytecodeOperandReg(1);
Node* first_arg = __ RegisterLocation(first_arg_reg);
Node* args_count = __ BytecodeOperandCount(2);
Node* context = __ GetContext();
Node* result = __ CallConstruct(constructor, context, constructor, first_arg,
args_count);
Node* result =
__ CallConstruct(constructor, context, new_target, first_arg, args_count);
__ SetAccumulator(result);
__ Dispatch();
}
@ -1183,6 +1184,7 @@ void Interpreter::DoCallConstruct(InterpreterAssembler* assembler) {
//
// Call operator new with |constructor| and the first argument in
// register |first_arg| and |arg_count| arguments in subsequent
// registers. The new.target is in the accumulator.
//
void Interpreter::DoNew(InterpreterAssembler* assembler) {
DoCallConstruct(assembler);
@ -1193,6 +1195,7 @@ void Interpreter::DoNew(InterpreterAssembler* assembler) {
//
// Call operator new with |constructor| and the first argument in
// register |first_arg| and |arg_count| arguments in subsequent
// registers. The new.target is in the accumulator.
//
void Interpreter::DoNewWide(InterpreterAssembler* assembler) {
DoCallConstruct(assembler);

View File

@ -504,45 +504,6 @@
# TODO(rmcilroy,4680): Check failed: toplevel_test_code_event_found.
'test-serialize/SerializeToplevelIsolates': [FAIL],
# TODO(rmcilroy,4682): Requires support for classes.
'test-inobject-slack-tracking/SubclassBasicNoBaseClassInstancesNoInlineNew': [FAIL],
'test-inobject-slack-tracking/SubclassBasicNoBaseClassInstances': [FAIL],
'test-inobject-slack-tracking/LongSubclassChain2': [FAIL],
'test-inobject-slack-tracking/LongSubclassChain1': [FAIL],
'test-inobject-slack-tracking/LongSubclassChain3': [FAIL],
'test-inobject-slack-tracking/SubclassBasicNoInlineNew': [FAIL],
'test-inobject-slack-tracking/InobjectPropetiesCountOverflowInSubclass': [FAIL],
'test-inobject-slack-tracking/SlowModeSubclass': [FAIL],
'test-inobject-slack-tracking/SubclassObjectBuiltin': [FAIL],
'test-inobject-slack-tracking/SubclassObjectBuiltinNoInlineNew': [FAIL],
'test-inobject-slack-tracking/SubclassFunctionBuiltin': [FAIL],
'test-inobject-slack-tracking/SubclassBasic': [FAIL],
'test-inobject-slack-tracking/SubclassFunctionBuiltinNoInlineNew': [FAIL],
'test-inobject-slack-tracking/SubclassNumberBuiltin': [FAIL],
'test-inobject-slack-tracking/SubclassBooleanBuiltinNoInlineNew': [FAIL],
'test-inobject-slack-tracking/SubclassErrorBuiltinNoInlineNew': [FAIL],
'test-inobject-slack-tracking/SubclassErrorBuiltin': [FAIL],
'test-inobject-slack-tracking/SubclassStringBuiltin': [FAIL],
'test-inobject-slack-tracking/SubclassDateBuiltin': [FAIL],
'test-inobject-slack-tracking/SubclassRegExpBuiltin': [FAIL],
'test-inobject-slack-tracking/SubclassStringBuiltinNoInlineNew': [FAIL],
'test-inobject-slack-tracking/SubclassBooleanBuiltin': [FAIL],
'test-inobject-slack-tracking/SubclassDateBuiltinNoInlineNew': [FAIL],
'test-inobject-slack-tracking/SubclassArrayBuiltin': [FAIL],
'test-inobject-slack-tracking/SubclassRegExpBuiltinNoInlineNew': [FAIL],
'test-inobject-slack-tracking/SubclassNumberBuiltinNoInlineNew': [FAIL],
'test-inobject-slack-tracking/SubclassArrayBuiltinNoInlineNew': [FAIL],
'test-inobject-slack-tracking/SubclassTypedArrayBuiltin': [FAIL],
'test-inobject-slack-tracking/SubclassTypedArrayBuiltinNoInlineNew': [FAIL],
'test-inobject-slack-tracking/SubclassCollectionBuiltin': [FAIL],
'test-inobject-slack-tracking/SubclassCollectionBuiltinNoInlineNew': [FAIL],
'test-inobject-slack-tracking/SubclassArrayBufferBuiltin': [FAIL],
'test-inobject-slack-tracking/SubclassArrayBufferBuiltinNoInlineNew': [FAIL],
'test-inobject-slack-tracking/SubclassPromiseBuiltinNoInlineNew': [FAIL],
'test-inobject-slack-tracking/SubclassPromiseBuiltin': [FAIL],
'test-api/Regress470113': [FAIL],
'test-api/SubclassGetConstructorName': [FAIL],
# BUG(4333). Function name inferrer does not work for ES6 clases.
'test-func-name-inference/UpperCaseClass': [TIMEOUT],
'test-func-name-inference/LowerCaseClass': [TIMEOUT],
@ -649,6 +610,7 @@
['ignition == True and arch == arm64', {
# TODO(rmcilroy,4680): Arm64 specific crashes.
'test-api/ExternalWrap': [SKIP],
'test-api/Regress470113': [SKIP],
'test-heap/NoWeakHashTableLeakWithIncrementalMarking': [SKIP],
# TODO(rmcilroy,4680): Arm64 flakes.

View File

@ -5048,13 +5048,14 @@ TEST(CallNew) {
"f()",
2 * kPointerSize,
1,
15,
17,
{
B(StackCheck), //
B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)), //
B(Star), R(0), //
B(LdaSmi8), U8(3), //
B(Star), R(1), //
B(Ldar), R(0), //
B(New), R(0), R(1), U8(1), //
B(Return), //
},
@ -5070,7 +5071,7 @@ TEST(CallNew) {
"f()",
4 * kPointerSize,
1,
23,
25,
{
B(StackCheck), //
B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)), //
@ -5081,6 +5082,7 @@ TEST(CallNew) {
B(Star), R(2), //
B(LdaSmi8), U8(5), //
B(Star), R(3), //
B(Ldar), R(0), //
B(New), R(0), R(1), U8(3), //
B(Return), //
},
@ -9232,6 +9234,8 @@ TEST(ClassDeclarations) {
}
}
// TODO(oth): Add tests for super keyword.
} // namespace interpreter
} // namespace internal
} // namespace v8

View File

@ -3865,6 +3865,65 @@ TEST(InterpreterClassLiterals) {
}
}
TEST(InterpreterClassAndSuperClass) {
HandleAndZoneScope handles;
i::Isolate* isolate = handles.main_isolate();
std::pair<const char*, Handle<Object>> examples[] = {
{"class A {\n"
" constructor(x) { this.x_ = x; }\n"
" method() { return this.x_; }\n"
"}\n"
"class B extends A {\n"
" constructor(x, y) { super(x); this.y_ = y; }\n"
" method() { return super.method() + 1; }\n"
"}\n"
"return new B(998, 0).method();\n",
handle(Smi::FromInt(999), isolate)},
{"class A {\n"
" constructor() { this.x_ = 2; this.y_ = 3; }\n"
"}\n"
"class B extends A {\n"
" constructor() { super(); }"
" method() { this.x_++; this.y_++; return this.x_ + this.y_; }\n"
"}\n"
"return new B().method();\n",
handle(Smi::FromInt(7), isolate)},
{"var calls = 0;\n"
"class B {}\n"
"B.prototype.x = 42;\n"
"class C extends B {\n"
" constructor() {\n"
" super();\n"
" calls++;\n"
" }\n"
"}\n"
"new C;\n"
"return calls;\n",
handle(Smi::FromInt(1), isolate)},
{"class A {\n"
" method() { return 1; }\n"
" get x() { return 2; }\n"
"}\n"
"class B extends A {\n"
" method() { return super.x === 2 ? super.method() : -1; }\n"
"}\n"
"return new B().method();\n",
handle(Smi::FromInt(1), isolate)},
{"var object = { setY(v) { super.y = v; }};\n"
"object.setY(10);\n"
"return object.y;\n",
handle(Smi::FromInt(10), isolate)},
};
for (size_t i = 0; i < arraysize(examples); ++i) {
std::string source(InterpreterTester::SourceForBody(examples[i].first));
InterpreterTester tester(handles.main_isolate(), source.c_str());
auto callable = tester.GetCallable<>();
Handle<i::Object> return_value = callable().ToHandleChecked();
CHECK(return_value->SameValue(*examples[i].second));
}
}
TEST(InterpreterConstDeclaration) {
HandleAndZoneScope handles;
i::Isolate* isolate = handles.main_isolate();

View File

@ -800,6 +800,7 @@
'es6/iterator-prototype': [FAIL],
'es6/generators-mirror': [FAIL],
'es6/object-literals-method': [FAIL],
'es6/object-literals-super': [FAIL],
'es6/generators-relocation': [FAIL],
'es6/spread-array': [FAIL],
'es6/generators-debug-liveedit': [FAIL],
@ -828,46 +829,6 @@
'es6/promises': [FAIL],
'deserialize-optimize-inner': [FAIL],
# TODO(oth,4682): Requires VisitThisFunctionVariable support.
'es6/classes-maps': [FAIL],
'es6/array-concat': [FAIL],
'es6/classes-subclass-arrays': [FAIL],
'es6/classes-derived-return-type': [FAIL],
'es6/classes-experimental': [FAIL],
'es6/legacy-subclassing': [FAIL],
'es6/new-target': [FAIL],
'es6/promise-internal-setter': [FAIL],
'es6/regexp-constructor': [FAIL],
'es6/rest-params': [FAIL],
'es6/spread-call-new-class': [FAIL],
'es6/typedarray-of': [FAIL],
'harmony/array-species': [FAIL],
'harmony/arraybuffer-species': [FAIL],
'harmony/promise-species': [FAIL],
'es6/debug-break-default-constructor': [FAIL],
'harmony/typedarray-species': [FAIL],
'regress/regress-544991': [FAIL],
'regress/regress-crbug-498022': [FAIL],
'regress/regress-crbug-575080': [FAIL],
'regress/regress-crbug-580506': [FAIL],
'regress/regress-typedarray-length': [FAIL],
# TODO(oth,4682): Requires VisitSetHomeObject support.
'es6/class-computed-property-names-super': [FAIL],
'es6/classes-lazy-parsing': [FAIL],
'es6/computed-property-names-super': [FAIL],
'es6/classes': [FAIL],
'es6/object-literals-super': [FAIL],
'es6/spread-call-super-property': [FAIL],
'es6/super': [FAIL],
'es6/regress/regress-4097': [FAIL],
'es6/regress/regress-4466': [FAIL],
'es6/regress/regress-4522': [FAIL],
'es6/regress/regress-cr493566': [FAIL],
'harmony/regress/regress-4395': [FAIL],
'regress/regress-4525': [FAIL],
'regress/regress-4521': [FAIL],
# TODO(rmcilroy,4680): Check failed in
# BytecodeGenerator::VisitFunctionLiteral - !shared_info.is_null().
'regress/regress-crbug-429159': [FAIL],
@ -888,12 +849,10 @@
'es6/tail-call': [FAIL],
'es6/tail-call-simple': [FAIL],
'es6/mirror-collections': [FAIL],
'es6/block-const-assign': [FAIL],
'es6/regress/regress-468661': [FAIL],
'harmony/string-replace': [FAIL],
'harmony/string-match': [FAIL],
'harmony/string-split': [FAIL],
'harmony/block-const-assign-sloppy': [FAIL],
'regress/regress-2618': [FAIL],
'regress/regress-4121': [FAIL],
'regress/regress-4266': [FAIL],
@ -941,9 +900,9 @@
# TODO(rmcilroy,4680): Arm64 specific failures.
'apply': [SKIP],
'array-constructor': [SKIP],
'array-store-and-grow': [SKIP],
'array-functions-prototype-misc': [SKIP],
'array-sort': [SKIP],
'array-store-and-grow': [SKIP],
'asm/construct-double': [SKIP],
'compiler/division-by-constant': [SKIP],
'compiler/osr-big': [SKIP],
@ -952,17 +911,24 @@
'compiler/osr-two': [SKIP],
'copy-on-write-assert': [SKIP],
'es6/block-conflicts': [SKIP],
'es6/block-const-assign': [SKIP],
'es6/block-let-declaration': [SKIP],
'es6/block-scoping-top-level': [SKIP],
'es6/classes-derived-return-type': [SKIP],
'es6/regress/regress-2506': [SKIP],
'es6/regress/regress-474783': [SKIP],
'es6/typedarray-proto': [SKIP],
'es6/unscopables': [SKIP],
'harmony/arraybuffer-species': [SKIP],
'harmony/array-species': [SKIP],
'harmony/block-conflicts-sloppy': [SKIP],
'harmony/block-const-assign-sloppy': [SKIP],
'harmony/block-let-declaration-sloppy': [SKIP],
'harmony/block-scoping-top-level-sloppy': [SKIP],
'harmony/species': [SKIP],
'harmony/typedarray-species': [SKIP],
'mirror-object': [SKIP],
'mul-exhaustive-part*': [SKIP],
'readonly': [SKIP],
'regress/regress-165637': [SKIP],
'regress/regress-2185': [SKIP],
@ -972,20 +938,21 @@
'regress/regress-347914': [SKIP],
'regress/regress-411210': [SKIP],
'regress/regress-4509-Class-constructor-typeerror-realm': [SKIP],
'regress/regress-4521': [SKIP],
'regress/regress-568765': [SKIP],
'regress/regress-85177': [SKIP],
'regress/regress-crbug-405517': [SKIP],
'regress/regress-crbug-474297': [SKIP],
'regress/regress-crbug-498022': [SKIP],
'regress/regress-crbug-505007-1': [SKIP],
'regress/regress-crbug-505007-2': [SKIP],
'regress/regress-crbug-514081': [SKIP],
'regress/regress-crbug-513507': [SKIP],
'regress/regress-crbug-514081': [SKIP],
'regress/regress-deep-proto': [SKIP],
'regress/regress-put-prototype-transition': [SKIP],
'regress/regress-transcendental': [SKIP],
'stack-traces-overflow': [SKIP],
'try': [SKIP],
'mul-exhaustive-part*': [SKIP],
'unicodelctest': [SKIP],
'unicodelctest-no-optimization': [SKIP],
}], # ignition == True and arch == arm64

View File

@ -440,16 +440,14 @@
'built-ins/Array/prototype/reduceRight/*': [SKIP],
'built-ins/GeneratorFunction/*': [SKIP],
'built-ins/GeneratorPrototype/*': [SKIP],
'built-ins/Promise/prototype/then/capability-executor-called-twice': [SKIP],
'built-ins/Promise/prototype/then/capability-executor-not-callable': [SKIP],
'built-ins/Promise/prototype/then/deferred-is-resolved-value': [SKIP],
'built-ins/Reflect/enumerate/*': [SKIP],
'language/computed-property-names/class/*': [SKIP],
'language/computed-property-names/to-name-side-effects/*': [SKIP],
'language/directive-prologue/*': [SKIP],
'language/expressions/arrow-function/*': [SKIP],
'language/expressions/assignment/destructuring/*': [SKIP],
'language/expressions/class/*': [SKIP],
'language/expressions/class/subclass/builtin-objects/GeneratorFunction/*': [SKIP],
'language/expressions/generators/*': [SKIP],
'language/expressions/instanceof/primitive-prototype-with-object': [SKIP],
'language/expressions/instanceof/prototype-getter-with-object-throws': [SKIP],
@ -457,7 +455,18 @@
'language/expressions/object/method-definition/yield*': [SKIP],
'language/expressions/object/method-definition/generator*': [SKIP],
'language/expressions/yield/*': [SKIP],
'language/statements/class/*': [SKIP],
'language/statements/class/definition/methods-gen-no-yield': [SKIP],
'language/statements/class/definition/methods-gen-return': [SKIP],
'language/statements/class/definition/methods-gen-yield-as-expression-with-rhs': [SKIP],
'language/statements/class/definition/methods-gen-yield-as-generator-method-binding-identifier': [SKIP],
'language/statements/class/definition/methods-gen-yield-as-literal-property-name': [SKIP],
'language/statements/class/definition/methods-gen-yield-as-property-name': [SKIP],
'language/statements/class/definition/methods-gen-yield-as-statement': [SKIP],
'language/statements/class/definition/methods-gen-yield-as-expression-without-rhs': [SKIP],
'language/statements/class/definition/methods-gen-yield-as-yield-operand': [SKIP],
'language/statements/class/definition/methods-gen-yield-newline': [SKIP],
'language/statements/class/definition/methods-gen-yield-star-before-newline': [SKIP],
'language/statements/class/subclass/builtin-objects/GeneratorFunction/*': [SKIP],
'language/statements/generators/*': [SKIP],
'built-ins/Array/prototype/concat/Array.prototype.concat_non-array': [SKIP],
@ -472,12 +481,8 @@
'built-ins/Object/prototype/valueOf/S15.2.4.4_A12': [SKIP],
'built-ins/Object/prototype/valueOf/S15.2.4.4_A14': [SKIP],
'built-ins/Object/prototype/valueOf/S15.2.4.4_A15': [SKIP],
'built-ins/Promise/all/ctx-ctor': [SKIP],
'built-ins/Promise/all/S25.4.4.1_A4.1_T1': [SKIP],
'built-ins/Promise/prototype/then/on-rejected-throw': [SKIP],
'built-ins/Promise/race/ctx-ctor': [SKIP],
'built-ins/Promise/reject/ctx-ctor': [SKIP],
'built-ins/Promise/resolve/ctx-ctor': [SKIP],
'built-ins/Promise/reject/S25.4.4.4_A3.1_T1': [SKIP],
'built-ins/String/prototype/codePointAt/this-is-undefined-throws': [SKIP],
'built-ins/String/prototype/concat/S15.5.4.6_A2': [SKIP],
@ -485,20 +490,14 @@
'built-ins/String/prototype/includes/this-is-undefined-throws': [SKIP],
'built-ins/String/prototype/repeat/this-is-undefined-throws': [SKIP],
'built-ins/String/prototype/startsWith/this-is-undefined-throws': [SKIP],
'built-ins/Promise/prototype/then/ctor-custom': [SKIP],
'built-ins/String/prototype/trim/15.5.4.20-1-1': [SKIP],
'language/block-scope/leave/nested-block-let-declaration-only-shadows-outer-parameter-value-1': [SKIP],
'language/block-scope/leave/nested-block-let-declaration-only-shadows-outer-parameter-value-2': [SKIP],
'language/block-scope/leave/verify-context-in-labelled-block': [SKIP],
'language/block-scope/leave/x-after-break-to-label': [SKIP],
'language/computed-property-names/object/accessor/getter-super': [SKIP],
'language/computed-property-names/object/accessor/setter-super': [SKIP],
'language/computed-property-names/object/method/super': [SKIP],
'language/default-parameters/class-definitions': [SKIP],
'language/default-parameters/generators': [SKIP],
'language/expressions/object/method-definition/name-prop-name-yield-expr': [SKIP],
'language/expressions/object/method-definition/name-super-prop-param': [SKIP],
'language/expressions/object/method-definition/name-super-prop-body': [SKIP],
'language/expressions/tagged-template/call-expression-context-no-strict': [SKIP],
'language/expressions/tagged-template/call-expression-context-strict': [SKIP],
'language/expressions/template-literal/evaluation-order': [SKIP],
@ -538,22 +537,80 @@
'language/statements/for-of/yield-star-from-finally': [SKIP],
'language/statements/for-of/yield-star-from-try': [SKIP],
'language/object-literal/concise-generator': [SKIP],
'language/object-literal/getter': [SKIP],
'language/object-literal/method': [SKIP],
'language/object-literal/setter': [SKIP],
'language/rest-parameters/with-new-target': [SKIP],
'language/statements/do-while/S12.6.1_A4_T5': [SKIP],
'language/statements/while/S12.6.2_A4_T5': [SKIP],
}], # ignition == True
['ignition == True and (arch == arm or arch == arm64)', {
'built-ins/Promise/all/ctx-ctor': [SKIP],
'built-ins/Promise/race/ctx-ctor': [SKIP],
'built-ins/decodeURI/S15.1.3.1_A1.12_T3': [SKIP],
'built-ins/decodeURIComponent/S15.1.3.2_A1.10_T1': [SKIP],
'built-ins/decodeURIComponent/S15.1.3.2_A1.11_T2': [SKIP],
'built-ins/decodeURIComponent/S15.1.3.2_A1.12_T2': [SKIP],
'built-ins/decodeURIComponent/S15.1.3.2_A1.12_T3': [SKIP],
'intl402/9.2.2': [SKIP],
'language/statements/class/arguments/default-constructor': [SKIP],
'language/statements/class/definition/constructor-strict-by-default': [SKIP],
'language/statements/class/definition/fn-name-accessor-get': [SKIP],
'language/statements/class/definition/fn-name-accessor-set': [SKIP],
'language/statements/class/definition/fn-name-gen-method': [SKIP],
'language/statements/class/definition/fn-name-method': [SKIP],
'language/statements/class/definition/methods-restricted-properties': [SKIP],
'language/statements/class/definition/prototype-getter': [SKIP],
'language/statements/class/definition/prototype-wiring': [SKIP],
'language/statements/class/definition/this-access-restriction': [SKIP],
'language/statements/class/definition/this-access-restriction-2': [SKIP],
'language/statements/class/definition/this-check-ordering': [SKIP],
'language/statements/class/name': [SKIP],
'language/statements/class/restricted-properties': [SKIP],
'language/statements/class/subclass/binding': [SKIP],
'language/statements/class/subclass/builtin-objects/Array/super-must-be-called': [SKIP],
'language/statements/class/subclass/builtin-objects/ArrayBuffer/super-must-be-called': [SKIP],
'language/statements/class/subclass/builtin-objects/Boolean/super-must-be-called': [SKIP],
'language/statements/class/subclass/builtin-objects/DataView/regular-subclassing': [SKIP],
'language/statements/class/subclass/builtin-objects/DataView/super-must-be-called': [SKIP],
'language/statements/class/subclass/builtin-objects/Date/super-must-be-called': [SKIP],
'language/statements/class/subclass/builtin-objects/Error/regular-subclassing': [SKIP],
'language/statements/class/subclass/builtin-objects/Error/super-must-be-called': [SKIP],
'language/statements/class/subclass/builtin-objects/Function/instance-length': [SKIP],
'language/statements/class/subclass/builtin-objects/Function/instance-name': [SKIP],
'language/statements/class/subclass/builtin-objects/Function/super-must-be-called': [SKIP],
'language/statements/class/subclass/builtin-objects/Map/super-must-be-called': [SKIP],
'language/statements/class/subclass/builtin-objects/NativeError/EvalError-name': [SKIP],
'language/statements/class/subclass/builtin-objects/NativeError/EvalError-super': [SKIP],
'language/statements/class/subclass/builtin-objects/NativeError/RangeError-name': [SKIP],
'language/statements/class/subclass/builtin-objects/NativeError/RangeError-super': [SKIP],
'language/statements/class/subclass/builtin-objects/NativeError/ReferenceError-name': [SKIP],
'language/statements/class/subclass/builtin-objects/NativeError/ReferenceError-super': [SKIP],
'language/statements/class/subclass/builtin-objects/NativeError/SyntaxError-name': [SKIP],
'language/statements/class/subclass/builtin-objects/NativeError/SyntaxError-super': [SKIP],
'language/statements/class/subclass/builtin-objects/NativeError/TypeError-name': [SKIP],
'language/statements/class/subclass/builtin-objects/NativeError/TypeError-super': [SKIP],
'language/statements/class/subclass/builtin-objects/NativeError/URIError-name': [SKIP],
'language/statements/class/subclass/builtin-objects/NativeError/URIError-super': [SKIP],
'language/statements/class/subclass/builtin-objects/Number/super-must-be-called': [SKIP],
'language/statements/class/subclass/builtin-objects/Object/constructor-return-undefined-throws': [SKIP],
'language/statements/class/subclass/builtin-objects/Object/constructor-returns-non-object': [SKIP],
'language/statements/class/subclass/builtin-objects/Promise/regular-subclassing': [SKIP],
'language/statements/class/subclass/builtin-objects/Promise/super-must-be-called': [SKIP],
'language/statements/class/subclass/builtin-objects/RegExp/lastIndex': [SKIP],
'language/statements/class/subclass/builtin-objects/RegExp/super-must-be-called': [SKIP],
'language/statements/class/subclass/builtin-objects/Set/super-must-be-called': [SKIP],
'language/statements/class/subclass/builtin-objects/String/length': [SKIP],
'language/statements/class/subclass/builtin-objects/String/super-must-be-called': [SKIP],
'language/statements/class/subclass/builtin-objects/Symbol/new-symbol-with-super-throws': [SKIP],
'language/statements/class/subclass/builtin-objects/WeakMap/super-must-be-called': [SKIP],
'language/statements/class/subclass/builtin-objects/WeakSet/super-must-be-called': [SKIP],
'language/statements/class/subclass/class-definition-null-proto-missing-return-override': [SKIP],
'language/statements/class/subclass/default-constructor': [SKIP],
'language/statements/class/subclass/default-constructor-2': [SKIP],
'language/statements/class/subclass/derived-class-return-override-with-boolean': [SKIP],
'language/statements/class/subclass/derived-class-return-override-with-null': [SKIP],
'language/statements/class/subclass/derived-class-return-override-with-number': [SKIP],
'language/statements/class/subclass/derived-class-return-override-with-string': [SKIP],
'language/statements/class/subclass/derived-class-return-override-with-symbol': [SKIP],
'language/statements/const/fn-name-arrow': [SKIP],
'language/statements/const/fn-name-class': [SKIP],
'language/statements/const/fn-name-cover': [SKIP],
@ -564,6 +621,7 @@
'language/statements/let/fn-name-cover': [SKIP],
'language/statements/let/fn-name-fn': [SKIP],
'language/statements/let/fn-name-gen': [SKIP],
'test-api/Regress470113': [SKIP],
}], # ignition == True and (arch == arm or arch == arm64)
]