Commit 815f91c0 authored by henrique.ferreiro's avatar henrique.ferreiro Committed by Commit bot

[es6] Perform the IsConstructor test in GetSuperConstructor.

This is so that a NotSuperConstructor error is thrown before evaluating the
arguments to the super constructor. Besides updating the runtime function, a
new bytecode GetSuperConstructor is introduced.

BUG=v8:5336

Review-Url: https://codereview.chromium.org/2504553003
Cr-Commit-Position: refs/heads/master@{#41788}
parent b695c388
......@@ -1078,5 +1078,17 @@ void Builtins::Generate_OrdinaryHasInstance(
assembler.Return(assembler.OrdinaryHasInstance(context, constructor, object));
}
void Builtins::Generate_GetSuperConstructor(
compiler::CodeAssemblerState* state) {
typedef compiler::Node Node;
typedef TypeofDescriptor Descriptor;
CodeStubAssembler assembler(state);
Node* object = assembler.Parameter(Descriptor::kObject);
Node* context = assembler.Parameter(Descriptor::kContext);
assembler.Return(assembler.GetSuperConstructor(object, context));
}
} // namespace internal
} // namespace v8
......@@ -179,6 +179,7 @@ namespace internal {
TFS(ToInteger, BUILTIN, kNoExtraICState, TypeConversion) \
TFS(ToLength, BUILTIN, kNoExtraICState, TypeConversion) \
TFS(Typeof, BUILTIN, kNoExtraICState, Typeof) \
TFS(GetSuperConstructor, BUILTIN, kNoExtraICState, TypeConversion) \
\
/* Handlers */ \
TFS(KeyedLoadIC_Megamorphic_TF, KEYED_LOAD_IC, kNoExtraICState, \
......
......@@ -251,6 +251,7 @@ TFS_BUILTIN(ForInFilter)
TFS_BUILTIN(NewUnmappedArgumentsElements)
TFS_BUILTIN(NewRestParameterElements)
TFS_BUILTIN(PromiseHandleReject)
TFS_BUILTIN(GetSuperConstructor)
#undef TFS_BUILTIN
......
......@@ -128,6 +128,7 @@ class V8_EXPORT_PRIVATE CodeFactory final {
static Callable SubString(Isolate* isolate);
static Callable Typeof(Isolate* isolate);
static Callable GetSuperConstructor(Isolate* isolate);
static Callable FastCloneRegExp(Isolate* isolate);
static Callable FastCloneShallowArray(Isolate* isolate);
......
......@@ -2896,6 +2896,13 @@ Node* CodeStubAssembler::IsCallableMap(Node* map) {
Int32Constant(0));
}
Node* CodeStubAssembler::IsConstructorMap(Node* map) {
CSA_ASSERT(this, IsMap(map));
return Word32NotEqual(
Word32And(LoadMapBitField(map), Int32Constant(1 << Map::kIsConstructor)),
Int32Constant(0));
}
Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) {
STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE);
return Int32LessThanOrEqual(instance_type,
......@@ -2992,6 +2999,10 @@ Node* CodeStubAssembler::IsUnseededNumberDictionary(Node* object) {
LoadRoot(Heap::kUnseededNumberDictionaryMapRootIndex));
}
Node* CodeStubAssembler::IsJSFunction(Node* object) {
return HasInstanceType(object, JS_FUNCTION_TYPE);
}
Node* CodeStubAssembler::StringCharCodeAt(Node* string, Node* index) {
CSA_ASSERT(this, IsString(string));
// Translate the {index} into a Word.
......@@ -7846,6 +7857,32 @@ Node* CodeStubAssembler::Typeof(Node* value, Node* context) {
return result_var.value();
}
Node* CodeStubAssembler::GetSuperConstructor(Node* active_function,
Node* context) {
CSA_ASSERT(this, IsJSFunction(active_function));
Label is_not_constructor(this, Label::kDeferred), out(this);
Variable result(this, MachineRepresentation::kTagged);
Node* map = LoadMap(active_function);
Node* prototype = LoadMapPrototype(map);
Node* prototype_map = LoadMap(prototype);
GotoUnless(IsConstructorMap(prototype_map), &is_not_constructor);
result.Bind(prototype);
Goto(&out);
Bind(&is_not_constructor);
{
result.Bind(CallRuntime(Runtime::kThrowNotSuperConstructor, context,
prototype, active_function));
Goto(&out);
}
Bind(&out);
return result.value();
}
Node* CodeStubAssembler::InstanceOf(Node* object, Node* callable,
Node* context) {
Label return_runtime(this, Label::kDeferred), end(this);
......
......@@ -658,6 +658,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Node* IsHashTable(Node* object);
Node* IsDictionary(Node* object);
Node* IsUnseededNumberDictionary(Node* object);
Node* IsConstructorMap(Node* map);
Node* IsJSFunction(Node* object);
// ElementsKind helpers:
Node* IsFastElementsKind(Node* elements_kind);
......@@ -1078,6 +1080,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Node* Typeof(Node* value, Node* context);
Node* GetSuperConstructor(Node* value, Node* context);
Node* InstanceOf(Node* object, Node* callable, Node* context);
// Debug helpers
......
......@@ -1626,6 +1626,13 @@ void BytecodeGraphBuilder::VisitDeletePropertySloppy() {
BuildDelete(LanguageMode::SLOPPY);
}
void BytecodeGraphBuilder::VisitGetSuperConstructor() {
Node* node = NewNode(javascript()->GetSuperConstructor(),
environment()->LookupAccumulator());
environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), node,
Environment::kAttachFrameState);
}
void BytecodeGraphBuilder::BuildCompareOp(const Operator* js_op) {
PrepareEagerCheckpoint();
Node* left =
......
......@@ -273,6 +273,12 @@ void JSGenericLowering::LowerJSDeleteProperty(Node* node) {
: Runtime::kDeleteProperty_Sloppy);
}
void JSGenericLowering::LowerJSGetSuperConstructor(Node* node) {
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
Callable callable = CodeFactory::GetSuperConstructor(isolate());
ReplaceWithStubCall(node, callable, flags);
}
void JSGenericLowering::LowerJSInstanceOf(Node* node) {
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
Callable callable = CodeFactory::InstanceOf(isolate());
......
......@@ -480,6 +480,7 @@ CompareOperationHint CompareOperationHintOf(const Operator* op) {
V(StoreMessage, Operator::kNoThrow, 1, 0) \
V(GeneratorRestoreContinuation, Operator::kNoThrow, 1, 1) \
V(StackCheck, Operator::kNoWrite, 0, 0) \
V(GetSuperConstructor, Operator::kNoWrite, 1, 1) \
V(StoreDataPropertyInLiteral, Operator::kNoProperties, 5, 0)
#define BINARY_OP_LIST(V) \
......
......@@ -521,6 +521,8 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
const Operator* HasProperty();
const Operator* GetSuperConstructor();
const Operator* LoadGlobal(const Handle<Name>& name,
const VectorSlotPair& feedback,
TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
......
......@@ -151,7 +151,6 @@ bool Linkage::NeedsFrameStateInput(Runtime::FunctionId function) {
case Runtime::kDefineGetterPropertyUnchecked: // TODO(jarin): Is it safe?
case Runtime::kDefineSetterPropertyUnchecked: // TODO(jarin): Is it safe?
case Runtime::kGeneratorGetContinuation:
case Runtime::kGetSuperConstructor:
case Runtime::kIsFunction:
case Runtime::kNewClosure:
case Runtime::kNewClosure_Tenured:
......@@ -178,7 +177,6 @@ bool Linkage::NeedsFrameStateInput(Runtime::FunctionId function) {
case Runtime::kInlineGeneratorClose:
case Runtime::kInlineGeneratorGetInputOrDebugPos:
case Runtime::kInlineGeneratorGetResumeMode:
case Runtime::kInlineGetSuperConstructor:
case Runtime::kInlineIsArray:
case Runtime::kInlineIsJSReceiver:
case Runtime::kInlineIsRegExp:
......
......@@ -144,7 +144,8 @@
V(JSStoreGlobal) \
V(JSStoreDataPropertyInLiteral) \
V(JSDeleteProperty) \
V(JSHasProperty)
V(JSHasProperty) \
V(JSGetSuperConstructor)
#define JS_CONTEXT_OP_LIST(V) \
V(JSLoadContext) \
......
......@@ -102,6 +102,7 @@ bool OperatorProperties::HasFrameStateInput(const Operator* op) {
case IrOpcode::kJSForInNext:
case IrOpcode::kJSForInPrepare:
case IrOpcode::kJSStackCheck:
case IrOpcode::kJSGetSuperConstructor:
return true;
default:
......
......@@ -1259,6 +1259,10 @@ Type* Typer::Visitor::JSOrdinaryHasInstanceTyper(Type* lhs, Type* rhs,
return Type::Boolean();
}
Type* Typer::Visitor::TypeJSGetSuperConstructor(Node* node) {
return Type::Callable();
}
// JS context operators.
......
......@@ -640,6 +640,13 @@ void Verifier::Visitor::Check(Node* node) {
// Type is String.
CheckTypeIs(node, Type::String());
break;
case IrOpcode::kJSGetSuperConstructor:
// We don't check the input for Type::Function because
// this_function can be context-allocated.
// Any -> Callable.
CheckValueInputIs(node, 0, Type::Any());
CheckTypeIs(node, Type::Callable());
break;
case IrOpcode::kJSLoadContext:
// Type can be anything.
......
......@@ -324,6 +324,11 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() {
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::GetSuperConstructor(Register out) {
OutputGetSuperConstructor(out);
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(
Token::Value op, Register reg, int feedback_slot) {
switch (op) {
......
......@@ -259,6 +259,11 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final
BytecodeArrayBuilder& LogicalNot();
BytecodeArrayBuilder& TypeOf();
// Expects a heap object in the accumulator. Returns its super constructor in
// the register |out| if it passes the IsConstructor test. Otherwise, it
// throws a TypeError exception.
BytecodeArrayBuilder& GetSuperConstructor(Register out);
// Deletes property from an object. This expects that accumulator contains
// the key to be deleted and the register contains a reference to the object.
BytecodeArrayBuilder& Delete(Register object, LanguageMode language_mode);
......
......@@ -2513,11 +2513,9 @@ void BytecodeGenerator::VisitCallSuper(Call* expr) {
SuperCallReference* super = expr->expression()->AsSuperCallReference();
// Prepare the constructor to the super call.
Register this_function = VisitForRegisterValue(super->this_function_var());
builder()->CallRuntime(Runtime::kInlineGetSuperConstructor, this_function);
Register constructor = this_function; // Re-use dead this_function register.
builder()->StoreAccumulatorInRegister(constructor);
VisitForAccumulatorValue(super->this_function_var());
Register constructor = register_allocator()->NewRegister();
builder()->GetSuperConstructor(constructor);
ZoneList<Expression*>* args = expr->arguments();
......
......@@ -143,6 +143,9 @@ namespace interpreter {
V(DeletePropertyStrict, AccumulatorUse::kReadWrite, OperandType::kReg) \
V(DeletePropertySloppy, AccumulatorUse::kReadWrite, OperandType::kReg) \
\
/* GetSuperConstructor operator */ \
V(GetSuperConstructor, AccumulatorUse::kRead, OperandType::kRegOut) \
\
/* Call operations */ \
V(Call, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kRegList, \
OperandType::kRegCount, OperandType::kIdx) \
......
......@@ -1675,6 +1675,19 @@ void Interpreter::DoDeletePropertySloppy(InterpreterAssembler* assembler) {
DoDelete(Runtime::kDeleteProperty_Sloppy, assembler);
}
// GetSuperConstructor
//
// Get the super constructor from the object referenced by the accumulator.
// The result is stored in register |reg|.
void Interpreter::DoGetSuperConstructor(InterpreterAssembler* assembler) {
Node* active_function = __ GetAccumulator();
Node* context = __ GetContext();
Node* result = __ GetSuperConstructor(active_function, context);
Node* reg = __ BytecodeOperandReg(0);
__ StoreRegister(result, reg);
__ Dispatch();
}
void Interpreter::DoJSCall(InterpreterAssembler* assembler,
TailCallMode tail_call_mode) {
Node* function_reg = __ BytecodeOperandReg(0);
......
......@@ -342,7 +342,9 @@ class ErrorUtils : public AllStatic {
T(NotIterable, "% is not iterable") \
T(NotPropertyName, "% is not a valid property name") \
T(NotTypedArray, "this is not a typed array.") \
T(NotSharedTypedArray, "% is not a shared typed array.") \
T(NotSuperConstructor, "Super constructor % of % is not a constructor") \
T(NotSuperConstructorAnonymousClass, \
"Super constructor % of anonymous class is not a constructor") \
T(NotIntegerSharedTypedArray, "% is not an integer shared typed array.") \
T(NotInt32SharedTypedArray, "% is not an int32 shared typed array.") \
T(ObjectGetterExpectingFunction, \
......
......@@ -27,7 +27,6 @@ RUNTIME_FUNCTION(Runtime_ThrowNonMethodError) {
isolate, NewReferenceError(MessageTemplate::kNonMethod));
}
RUNTIME_FUNCTION(Runtime_ThrowUnsupportedSuperError) {
HandleScope scope(isolate);
DCHECK(args.length() == 0);
......@@ -60,6 +59,47 @@ RUNTIME_FUNCTION(Runtime_ThrowStaticPrototypeError) {
isolate, NewTypeError(MessageTemplate::kStaticPrototype));
}
namespace {
Object* ThrowNotSuperConstructor(Isolate* isolate, Handle<Object> constructor,
Handle<JSFunction> function) {
Handle<Object> super_name;
if (constructor->IsJSFunction()) {
super_name = handle(Handle<JSFunction>::cast(constructor)->shared()->name(),
isolate);
} else if (constructor->IsOddball()) {
DCHECK(constructor->IsNull(isolate));
super_name = isolate->factory()->null_string();
} else {
super_name = Object::NoSideEffectsToString(isolate, constructor);
}
// null constructor
if (Handle<String>::cast(super_name)->length() == 0) {
super_name = isolate->factory()->null_string();
}
Handle<Object> function_name(function->shared()->name(), isolate);
// anonymous class
if (Handle<String>::cast(function_name)->length() == 0) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate,
NewTypeError(MessageTemplate::kNotSuperConstructorAnonymousClass,
super_name));
}
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kNotSuperConstructor, super_name,
function_name));
}
} // namespace
RUNTIME_FUNCTION(Runtime_ThrowNotSuperConstructor) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 0);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 1);
return ThrowNotSuperConstructor(isolate, constructor, function);
}
RUNTIME_FUNCTION(Runtime_HomeObjectSymbol) {
DCHECK(args.length() == 0);
return isolate->heap()->home_object_symbol();
......@@ -422,8 +462,14 @@ RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Sloppy) {
RUNTIME_FUNCTION(Runtime_GetSuperConstructor) {
SealHandleScope shs(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_CHECKED(JSFunction, active_function, 0);
return active_function->map()->prototype();
CONVERT_ARG_HANDLE_CHECKED(JSFunction, active_function, 0);
Object* prototype = active_function->map()->prototype();
if (!prototype->IsConstructor()) {
return ThrowNotSuperConstructor(
isolate, Handle<JSFunction>::cast(handle(prototype, isolate)),
active_function);
}
return prototype;
}
RUNTIME_FUNCTION(Runtime_NewWithSpread) {
......
......@@ -80,6 +80,7 @@ namespace internal {
F(ThrowConstructorNonCallableError, 1, 1) \
F(ThrowArrayNotSubclassableError, 0, 1) \
F(ThrowStaticPrototypeError, 0, 1) \
F(ThrowNotSuperConstructor, 2, 1) \
F(HomeObjectSymbol, 0, 1) \
F(DefineClass, 4, 1) \
F(InstallClassNameAccessor, 1, 1) \
......
......@@ -107,14 +107,14 @@ snippet: "
"
frame size: 4
parameter count: 1
bytecode array length: 82
bytecode array length: 79
bytecodes: [
B(Mov), R(closure), R(1),
B(Mov), R(new_target), R(0),
B(Ldar), R(new_target),
/* 113 E> */ B(StackCheck),
/* 118 S> */ B(CallRuntime), U16(Runtime::k_GetSuperConstructor), R(1), U8(1),
B(Star), R(2),
/* 118 S> */ B(Ldar), R(1),
B(GetSuperConstructor), R(2),
B(LdaSmi), U8(1),
B(Star), R(3),
B(Ldar), R(0),
......@@ -164,14 +164,14 @@ snippet: "
"
frame size: 4
parameter count: 1
bytecode array length: 78
bytecode array length: 75
bytecodes: [
B(Mov), R(closure), R(1),
B(Mov), R(new_target), R(0),
B(Ldar), R(new_target),
/* 112 E> */ B(StackCheck),
/* 117 S> */ B(CallRuntime), U16(Runtime::k_GetSuperConstructor), R(1), U8(1),
B(Star), R(2),
/* 117 S> */ B(Ldar), R(1),
B(GetSuperConstructor), R(2),
B(Ldar), R(0),
/* 117 E> */ B(New), R(2), R(0), U8(0), U8(2),
B(Star), R(2),
......
......@@ -88,7 +88,7 @@ bytecodes: [
B(TestEqualStrict), R(12), U8(20),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(130),
B(Wide), B(LdaSmi), U16(131),
B(Star), R(12),
B(LdaConstant), U8(9),
B(Star), R(13),
......@@ -233,7 +233,7 @@ bytecodes: [
B(TestEqualStrict), R(13), U8(20),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(130),
B(Wide), B(LdaSmi), U16(131),
B(Star), R(13),
B(LdaConstant), U8(9),
B(Star), R(14),
......@@ -391,7 +391,7 @@ bytecodes: [
B(TestEqualStrict), R(12), U8(22),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(130),
B(Wide), B(LdaSmi), U16(131),
B(Star), R(12),
B(LdaConstant), U8(9),
B(Star), R(13),
......@@ -539,7 +539,7 @@ bytecodes: [
B(TestEqualStrict), R(11), U8(24),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(130),
B(Wide), B(LdaSmi), U16(131),
B(Star), R(11),
B(LdaConstant), U8(11),
B(Star), R(12),
......
......@@ -491,7 +491,7 @@ bytecodes: [
B(TestEqualStrict), R(10), U8(20),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(130),
B(Wide), B(LdaSmi), U16(131),
B(Star), R(10),
B(LdaConstant), U8(14),
B(Star), R(11),
......
......@@ -19,7 +19,7 @@ snippet: "
"
frame size: 7
parameter count: 1
bytecode array length: 32
bytecode array length: 29
bytecodes: [
B(CreateRestParameter),
B(Star), R(2),
......@@ -27,8 +27,8 @@ bytecodes: [
B(Mov), R(new_target), R(0),
B(Ldar), R(new_target),
/* 93 E> */ B(StackCheck),
/* 93 S> */ B(CallRuntime), U16(Runtime::k_GetSuperConstructor), R(1), U8(1),
B(Star), R(3),
/* 93 S> */ B(Ldar), R(1),
B(GetSuperConstructor), R(3),
B(Mov), R(3), R(4),
B(Mov), R(0), R(5),
B(Mov), R(2), R(6),
......@@ -55,7 +55,7 @@ snippet: "
"
frame size: 8
parameter count: 1
bytecode array length: 69
bytecode array length: 66
bytecodes: [
B(CreateRestParameter),
B(Star), R(2),
......@@ -63,8 +63,8 @@ bytecodes: [
B(Mov), R(new_target), R(0),
B(Ldar), R(new_target),
/* 128 E> */ B(StackCheck),
/* 140 S> */ B(CallRuntime), U16(Runtime::k_GetSuperConstructor), R(1), U8(1),
B(Star), R(3),
/* 140 S> */ B(Ldar), R(1),
B(GetSuperConstructor), R(3),
B(LdaSmi), U8(1),
B(Star), R(6),
B(Mov), R(3), R(4),
......
......@@ -415,9 +415,6 @@
'annexB/language/eval-code/direct/func-switch-case-eval-func-no-skip-try': [FAIL],
'annexB/language/eval-code/direct/func-switch-dflt-eval-func-no-skip-try': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=5336
'language/expressions/super/call-proto-not-ctor': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=5546
'language/expressions/tagged-template/invalid-escape-sequences': [FAIL],
......
......@@ -213,6 +213,9 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.ConvertAccumulatorToObject(reg)
.ConvertAccumulatorToName(reg);
// Emit GetSuperConstructor.
builder.GetSuperConstructor(reg);
// Short jumps with Imm8 operands
{
BytecodeLabel start, after_jump1, after_jump2, after_jump3, after_jump4,
......
......@@ -9,7 +9,7 @@ PASS new B did not throw exception.
PASS B() threw exception TypeError: Class constructor B cannot be invoked without 'new'.
PASS new (class { constructor() {} })() did not throw exception.
PASS (class { constructor() {} })() threw exception TypeError: Class constructor cannot be invoked without 'new'.
PASS new (class extends null { constructor() { super() } })() threw exception TypeError: super is not a constructor.
PASS new (class extends null { constructor() { super() } })() threw exception TypeError: Super constructor null of anonymous class is not a constructor.
PASS (class extends null { constructor() { super() } })() threw exception TypeError: Class constructor cannot be invoked without 'new'.
PASS successfullyParsed is true
......
......@@ -32,7 +32,7 @@ shouldNotThrow('new B');
shouldThrow('B()', '"TypeError: Class constructor B cannot be invoked without \'new\'"');
shouldNotThrow('new (class { constructor() {} })()');
shouldThrow('(class { constructor() {} })()', '"TypeError: Class constructor cannot be invoked without \'new\'"');
shouldThrow('new (class extends null { constructor() { super() } })()', '"TypeError: super is not a constructor"');
shouldThrow('new (class extends null { constructor() { super() } })()', '"TypeError: Super constructor null of anonymous class is not a constructor"');
shouldThrow('(class extends null { constructor() { super() } })()', '"TypeError: Class constructor cannot be invoked without \'new\'"');
var successfullyParsed = true;
......@@ -60,7 +60,7 @@ PASS x = {}; new (class extends undefined { constructor () { return x; } }) thre
PASS y = 12; new (class extends undefined { constructor () { return y; } }) threw exception TypeError: Class extends value undefined is not a constructor or null.
PASS class x {}; new (class extends null { constructor () { return new x; } }) instanceof x is true
PASS new (class extends null { constructor () { this; } }) threw exception ReferenceError: this is not defined.
PASS new (class extends null { constructor () { super(); } }) threw exception TypeError: super is not a constructor.
PASS new (class extends null { constructor () { super(); } }) threw exception TypeError: Super constructor null of anonymous class is not a constructor.
PASS x = {}; new (class extends null { constructor () { return x } }) is x
PASS y = 12; new (class extends null { constructor () { return y; } }) threw exception TypeError: Derived constructors may only return object or undefined.
PASS class x {}; new (class extends null { constructor () { return new x; } }) instanceof x is true
......
......@@ -98,7 +98,7 @@ shouldThrow('x = {}; new (class extends undefined { constructor () { return x; }
shouldThrow('y = 12; new (class extends undefined { constructor () { return y; } })', '"TypeError: Class extends value undefined is not a constructor or null"');
shouldBeTrue ('class x {}; new (class extends null { constructor () { return new x; } }) instanceof x');
shouldThrow('new (class extends null { constructor () { this; } })', '"ReferenceError: this is not defined"');
shouldThrow('new (class extends null { constructor () { super(); } })', '"TypeError: super is not a constructor"');
shouldThrow('new (class extends null { constructor () { super(); } })', '"TypeError: Super constructor null of anonymous class is not a constructor"');
shouldBe('x = {}; new (class extends null { constructor () { return x } })', 'x');
shouldThrow('y = 12; new (class extends null { constructor () { return y; } })', '"TypeError: Derived constructors may only return object or undefined"');
shouldBeTrue ('class x {}; new (class extends null { constructor () { return new x; } }) instanceof x');
......
......@@ -29,12 +29,12 @@ PASS x instanceof Base is false
PASS new (class extends Base { constructor() { } }) threw exception ReferenceError: this is not defined.
PASS new (class extends Base { constructor() { return 1; } }) threw exception TypeError: Derived constructors may only return object or undefined.
PASS new (class extends null { constructor() { return undefined } }) threw exception ReferenceError: this is not defined.
PASS new (class extends null { constructor() { super(); return undefined } }) threw exception TypeError: super is not a constructor.
PASS new (class extends null { constructor() { super(); return undefined } }) threw exception TypeError: Super constructor null of anonymous class is not a constructor.
PASS x = { }; new (class extends null { constructor() { return x } }); is x
PASS x instanceof Object is true
PASS new (class extends null { constructor() { } }) threw exception ReferenceError: this is not defined.
PASS new (class extends null { constructor() { return 1; } }) threw exception TypeError: Derived constructors may only return object or undefined.
PASS new (class extends null { constructor() { super() } }) threw exception TypeError: super is not a constructor.
PASS new (class extends null { constructor() { super() } }) threw exception TypeError: Super constructor null of anonymous class is not a constructor.
PASS new (class { constructor() { super() } }) threw exception SyntaxError: 'super' keyword unexpected here.
PASS function x() { super(); } threw exception SyntaxError: 'super' keyword unexpected here.
PASS new (class extends Object { constructor() { function x() { super() } } }) threw exception SyntaxError: 'super' keyword unexpected here.
......
......@@ -78,12 +78,12 @@ shouldBeFalse('x instanceof Base');
shouldThrow('new (class extends Base { constructor() { } })', '"ReferenceError: this is not defined"');
shouldThrow('new (class extends Base { constructor() { return 1; } })', '"TypeError: Derived constructors may only return object or undefined"');
shouldThrow('new (class extends null { constructor() { return undefined } })');
shouldThrow('new (class extends null { constructor() { super(); return undefined } })', '"TypeError: super is not a constructor"');
shouldThrow('new (class extends null { constructor() { super(); return undefined } })', '"TypeError: Super constructor null of anonymous class is not a constructor"');
shouldBe('x = { }; new (class extends null { constructor() { return x } });', 'x');
shouldBeTrue('x instanceof Object');
shouldThrow('new (class extends null { constructor() { } })', '"ReferenceError: this is not defined"');
shouldThrow('new (class extends null { constructor() { return 1; } })', '"TypeError: Derived constructors may only return object or undefined"');
shouldThrow('new (class extends null { constructor() { super() } })', '"TypeError: super is not a constructor"');
shouldThrow('new (class extends null { constructor() { super() } })', '"TypeError: Super constructor null of anonymous class is not a constructor"');
shouldThrow('new (class { constructor() { super() } })', '"SyntaxError: \'super\' keyword unexpected here"');
shouldThrow('function x() { super(); }', '"SyntaxError: \'super\' keyword unexpected here"');
shouldThrow('new (class extends Object { constructor() { function x() { super() } } })', '"SyntaxError: \'super\' keyword unexpected here"');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment