Install ConstructNonConstructable as construct stub for non-constructables.
BUG= Review URL: https://codereview.chromium.org/1467473002 Cr-Commit-Position: refs/heads/master@{#32223}
This commit is contained in:
parent
515093630a
commit
8e28e851ee
@ -445,7 +445,9 @@ Handle<JSFunction> ApiNatives::CreateApiFunction(
|
||||
} else {
|
||||
code = isolate->builtins()->HandleApiCall();
|
||||
}
|
||||
Handle<Code> construct_stub = isolate->builtins()->JSConstructStubApi();
|
||||
Handle<Code> construct_stub =
|
||||
prototype.is_null() ? isolate->builtins()->ConstructedNonConstructable()
|
||||
: isolate->builtins()->JSConstructStubApi();
|
||||
|
||||
obj->set_instantiated(true);
|
||||
Handle<JSFunction> result;
|
||||
|
@ -647,6 +647,13 @@ void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) {
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
__ push(r1);
|
||||
__ CallRuntime(Runtime::kThrowConstructedNonConstructable, 1);
|
||||
}
|
||||
|
||||
|
||||
enum IsTagged { kArgcIsSmiTagged, kArgcIsUntaggedInt };
|
||||
|
||||
|
||||
@ -1685,7 +1692,8 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
|
||||
__ bind(&class_constructor);
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::INTERNAL);
|
||||
__ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0);
|
||||
__ push(r1);
|
||||
__ CallRuntime(Runtime::kThrowConstructorNonCallableError, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1813,11 +1821,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
// Called Construct on an Object that doesn't have a [[Construct]] internal
|
||||
// method.
|
||||
__ bind(&non_constructor);
|
||||
{
|
||||
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
|
||||
__ Push(r1);
|
||||
__ CallRuntime(Runtime::kThrowCalledNonCallable, 1);
|
||||
}
|
||||
__ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
|
||||
|
@ -654,6 +654,13 @@ void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) {
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
__ Push(x1);
|
||||
__ CallRuntime(Runtime::kThrowConstructedNonConstructable, 1);
|
||||
}
|
||||
|
||||
|
||||
enum IsTagged { kArgcIsSmiTagged, kArgcIsUntaggedInt };
|
||||
|
||||
|
||||
@ -1673,7 +1680,8 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
|
||||
__ bind(&class_constructor);
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::INTERNAL);
|
||||
__ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0);
|
||||
__ Push(x1);
|
||||
__ CallRuntime(Runtime::kThrowConstructorNonCallableError, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1800,11 +1808,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
// Called Construct on an Object that doesn't have a [[Construct]] internal
|
||||
// method.
|
||||
__ bind(&non_constructor);
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
__ Push(x1);
|
||||
__ CallRuntime(Runtime::kThrowCalledNonCallable, 1);
|
||||
}
|
||||
__ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
|
||||
|
@ -395,7 +395,7 @@ Handle<JSFunction> InstallFunction(Handle<JSObject> target, Handle<Name> name,
|
||||
Isolate* isolate = target->GetIsolate();
|
||||
Factory* factory = isolate->factory();
|
||||
Handle<String> name_string = Name::ToFunctionName(name).ToHandleChecked();
|
||||
Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call));
|
||||
Handle<Code> call_code(isolate->builtins()->builtin(call));
|
||||
Handle<JSObject> prototype;
|
||||
static const bool kReadOnlyPrototype = false;
|
||||
static const bool kInstallConstructor = false;
|
||||
@ -557,7 +557,7 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
|
||||
}
|
||||
|
||||
// Allocate the empty function as the prototype for function - ES6 19.2.3
|
||||
Handle<Code> code(isolate->builtins()->builtin(Builtins::kEmptyFunction));
|
||||
Handle<Code> code(isolate->builtins()->EmptyFunction());
|
||||
Handle<JSFunction> empty_function =
|
||||
factory->NewFunctionWithoutPrototype(factory->empty_string(), code);
|
||||
|
||||
@ -973,8 +973,7 @@ Handle<JSGlobalObject> Genesis::CreateNewGlobals(
|
||||
|
||||
if (js_global_object_template.is_null()) {
|
||||
Handle<String> name = Handle<String>(heap()->empty_string());
|
||||
Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
|
||||
Builtins::kIllegal));
|
||||
Handle<Code> code = isolate()->builtins()->Illegal();
|
||||
Handle<JSObject> prototype =
|
||||
factory()->NewFunctionPrototype(isolate()->object_function());
|
||||
js_global_object_function = factory()->NewFunction(
|
||||
@ -1004,8 +1003,7 @@ Handle<JSGlobalObject> Genesis::CreateNewGlobals(
|
||||
Handle<JSFunction> global_proxy_function;
|
||||
if (global_proxy_template.IsEmpty()) {
|
||||
Handle<String> name = Handle<String>(heap()->empty_string());
|
||||
Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
|
||||
Builtins::kIllegal));
|
||||
Handle<Code> code = isolate()->builtins()->Illegal();
|
||||
global_proxy_function = factory()->NewFunction(
|
||||
name, code, JS_GLOBAL_PROXY_TYPE, JSGlobalProxy::kSize);
|
||||
} else {
|
||||
@ -1103,7 +1101,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
function_function->initial_map()->set_is_callable();
|
||||
function_function->initial_map()->set_is_constructor(true);
|
||||
function_function->shared()->set_construct_stub(
|
||||
isolate->builtins()->builtin(Builtins::kJSBuiltinsConstructStub));
|
||||
*isolate->builtins()->JSBuiltinsConstructStub());
|
||||
|
||||
{ // --- A r r a y ---
|
||||
Handle<JSFunction> array_function =
|
||||
@ -1161,7 +1159,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
Builtins::kIllegal);
|
||||
native_context()->set_number_function(*number_fun);
|
||||
number_fun->shared()->set_construct_stub(
|
||||
isolate->builtins()->builtin(Builtins::kJSBuiltinsConstructStub));
|
||||
*isolate->builtins()->JSBuiltinsConstructStub());
|
||||
}
|
||||
|
||||
{ // --- B o o l e a n ---
|
||||
@ -1176,8 +1174,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
Handle<JSFunction> string_fun = InstallFunction(
|
||||
global, "String", JS_VALUE_TYPE, JSValue::kSize,
|
||||
isolate->initial_object_prototype(), Builtins::kStringConstructor);
|
||||
string_fun->shared()->set_construct_stub(isolate->builtins()->builtin(
|
||||
Builtins::kStringConstructor_ConstructStub));
|
||||
string_fun->shared()->set_construct_stub(
|
||||
*isolate->builtins()->StringConstructor_ConstructStub());
|
||||
string_fun->shared()->DontAdaptArguments();
|
||||
string_fun->shared()->set_length(1);
|
||||
native_context()->set_string_function(*string_fun);
|
||||
@ -1203,8 +1201,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
Handle<JSFunction> symbol_fun = InstallFunction(
|
||||
global, "Symbol", JS_VALUE_TYPE, JSValue::kSize,
|
||||
isolate->initial_object_prototype(), Builtins::kSymbolConstructor);
|
||||
symbol_fun->shared()->set_construct_stub(isolate->builtins()->builtin(
|
||||
Builtins::kSymbolConstructor_ConstructStub));
|
||||
symbol_fun->shared()->set_construct_stub(
|
||||
*isolate->builtins()->SymbolConstructor_ConstructStub());
|
||||
symbol_fun->shared()->set_internal_formal_parameter_count(1);
|
||||
symbol_fun->shared()->set_length(1);
|
||||
native_context()->set_symbol_function(*symbol_fun);
|
||||
@ -1216,7 +1214,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
global, "Date", JS_DATE_TYPE, JSDate::kSize,
|
||||
isolate->initial_object_prototype(), Builtins::kIllegal);
|
||||
date_fun->shared()->set_construct_stub(
|
||||
isolate->builtins()->builtin(Builtins::kJSBuiltinsConstructStub));
|
||||
*isolate->builtins()->JSBuiltinsConstructStub());
|
||||
}
|
||||
|
||||
{ // -- R e g E x p
|
||||
@ -1227,7 +1225,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
Builtins::kIllegal);
|
||||
native_context()->set_regexp_function(*regexp_fun);
|
||||
regexp_fun->shared()->set_construct_stub(
|
||||
isolate->builtins()->builtin(Builtins::kJSBuiltinsConstructStub));
|
||||
*isolate->builtins()->JSBuiltinsConstructStub());
|
||||
|
||||
DCHECK(regexp_fun->has_initial_map());
|
||||
Handle<Map> initial_map(regexp_fun->initial_map());
|
||||
@ -1308,7 +1306,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
Builtins::kIllegal);
|
||||
native_context()->set_data_view_fun(*data_view_fun);
|
||||
data_view_fun->shared()->set_construct_stub(
|
||||
isolate->builtins()->builtin(Builtins::kJSBuiltinsConstructStub));
|
||||
*isolate->builtins()->JSBuiltinsConstructStub());
|
||||
}
|
||||
|
||||
{ // -- M a p
|
||||
@ -1359,7 +1357,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
// This is done by introducing an anonymous function with
|
||||
// class_name equals 'Arguments'.
|
||||
Handle<String> arguments_string = factory->Arguments_string();
|
||||
Handle<Code> code(isolate->builtins()->builtin(Builtins::kIllegal));
|
||||
Handle<Code> code = isolate->builtins()->Illegal();
|
||||
Handle<JSFunction> function = factory->NewFunctionWithoutPrototype(
|
||||
arguments_string, code);
|
||||
function->shared()->set_instance_class_name(*arguments_string);
|
||||
@ -1464,8 +1462,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
|
||||
{ // --- context extension
|
||||
// Create a function for the context extension objects.
|
||||
Handle<Code> code = Handle<Code>(
|
||||
isolate->builtins()->builtin(Builtins::kIllegal));
|
||||
Handle<Code> code = isolate->builtins()->Illegal();
|
||||
Handle<JSFunction> context_extension_fun = factory->NewFunction(
|
||||
factory->empty_string(), code, JS_CONTEXT_EXTENSION_OBJECT_TYPE,
|
||||
JSObject::kHeaderSize);
|
||||
@ -1479,9 +1476,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
|
||||
{
|
||||
// Set up the call-as-function delegate.
|
||||
Handle<Code> code =
|
||||
Handle<Code>(isolate->builtins()->builtin(
|
||||
Builtins::kHandleApiCallAsFunction));
|
||||
Handle<Code> code = isolate->builtins()->HandleApiCallAsFunction();
|
||||
Handle<JSFunction> delegate = factory->NewFunction(
|
||||
factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize);
|
||||
native_context()->set_call_as_function_delegate(*delegate);
|
||||
@ -1490,9 +1485,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
|
||||
{
|
||||
// Set up the call-as-constructor delegate.
|
||||
Handle<Code> code =
|
||||
Handle<Code>(isolate->builtins()->builtin(
|
||||
Builtins::kHandleApiCallAsConstructor));
|
||||
Handle<Code> code = isolate->builtins()->HandleApiCallAsConstructor();
|
||||
Handle<JSFunction> delegate = factory->NewFunction(
|
||||
factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize);
|
||||
native_context()->set_call_as_constructor_delegate(*delegate);
|
||||
@ -1835,7 +1828,7 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate,
|
||||
generator_function_function->initial_map()->set_is_callable();
|
||||
generator_function_function->initial_map()->set_is_constructor(true);
|
||||
generator_function_function->shared()->set_construct_stub(
|
||||
isolate->builtins()->builtin(Builtins::kJSBuiltinsConstructStub));
|
||||
*isolate->builtins()->JSBuiltinsConstructStub());
|
||||
}
|
||||
|
||||
{ // -- S e t I t e r a t o r
|
||||
@ -2194,7 +2187,7 @@ void Genesis::InitializeGlobal_harmony_proxies() {
|
||||
// TODO(verwaest): Set to null in InstallFunction.
|
||||
proxy_fun->initial_map()->set_prototype(isolate->heap()->null_value());
|
||||
proxy_fun->shared()->set_construct_stub(
|
||||
isolate->builtins()->builtin(Builtins::kJSBuiltinsConstructStub));
|
||||
*isolate->builtins()->JSBuiltinsConstructStub());
|
||||
native_context()->set_proxy_function(*proxy_fun);
|
||||
}
|
||||
|
||||
@ -2450,7 +2443,7 @@ bool Genesis::InstallNatives(ContextType context_type) {
|
||||
JSFunction::EnsureHasInitialMap(function);
|
||||
function->initial_map()->set_instance_type(JS_PROMISE_TYPE);
|
||||
function->shared()->set_construct_stub(
|
||||
isolate()->builtins()->builtin(Builtins::kJSBuiltinsConstructStub));
|
||||
*isolate()->builtins()->JSBuiltinsConstructStub());
|
||||
}
|
||||
|
||||
InstallBuiltinFunctionIds();
|
||||
|
@ -86,6 +86,8 @@ enum BuiltinExtraArguments {
|
||||
#define BUILTIN_LIST_A(V) \
|
||||
V(ArgumentsAdaptorTrampoline, BUILTIN, UNINITIALIZED, kNoExtraICState) \
|
||||
\
|
||||
V(ConstructedNonConstructable, BUILTIN, UNINITIALIZED, kNoExtraICState) \
|
||||
\
|
||||
V(CallFunction_ReceiverIsNullOrUndefined, BUILTIN, UNINITIALIZED, \
|
||||
kNoExtraICState) \
|
||||
V(CallFunction_ReceiverIsNotNullOrUndefined, BUILTIN, UNINITIALIZED, \
|
||||
@ -283,6 +285,7 @@ class Builtins {
|
||||
static void Generate_Adaptor(MacroAssembler* masm,
|
||||
CFunctionId id,
|
||||
BuiltinExtraArguments extra_args);
|
||||
static void Generate_ConstructedNonConstructable(MacroAssembler* masm);
|
||||
static void Generate_CompileLazy(MacroAssembler* masm);
|
||||
static void Generate_InOptimizationQueue(MacroAssembler* masm);
|
||||
static void Generate_CompileOptimized(MacroAssembler* masm);
|
||||
|
@ -746,7 +746,7 @@ MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon(
|
||||
if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>();
|
||||
Handle<SharedFunctionInfo> shared = info->shared_info();
|
||||
FunctionLiteral* lit = info->literal();
|
||||
shared->set_language_mode(lit->language_mode());
|
||||
DCHECK_EQ(shared->language_mode(), lit->language_mode());
|
||||
SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count());
|
||||
MaybeDisableOptimization(shared, lit->dont_optimize_reason());
|
||||
|
||||
|
@ -216,10 +216,10 @@ Reduction JSCallReducer::ReduceJSCallFunction(Node* node) {
|
||||
// Raise a TypeError if the {target} is a "classConstructor".
|
||||
if (IsClassConstructor(shared->kind())) {
|
||||
NodeProperties::RemoveFrameStateInput(node, 0);
|
||||
NodeProperties::RemoveValueInputs(node);
|
||||
NodeProperties::ReplaceValueInputs(node, target);
|
||||
NodeProperties::ChangeOp(
|
||||
node, javascript()->CallRuntime(
|
||||
Runtime::kThrowConstructorNonCallableError, 0));
|
||||
Runtime::kThrowConstructorNonCallableError, 1));
|
||||
return Changed(node);
|
||||
}
|
||||
|
||||
|
@ -291,6 +291,15 @@ Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) {
|
||||
return NoChange();
|
||||
}
|
||||
|
||||
if (node->opcode() == IrOpcode::kJSCallConstruct &&
|
||||
!function->IsConstructor()) {
|
||||
// Constructor must be constructable.
|
||||
TRACE("Not inlining %s into %s since constructor is not constructable.\n",
|
||||
function->shared()->DebugName()->ToCString().get(),
|
||||
info_->shared_info()->DebugName()->ToCString().get());
|
||||
return NoChange();
|
||||
}
|
||||
|
||||
// Class constructors are callable, but [[Call]] will raise an exception.
|
||||
// See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList ).
|
||||
if (IsClassConstructor(function->shared()->kind())) {
|
||||
@ -418,6 +427,8 @@ Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) {
|
||||
// constructor dispatch and turn the constructor call into a regular call.
|
||||
// This models the behavior usually accomplished by our {JSConstructStub}.
|
||||
// Note that the context has to be the callers context (input to call node).
|
||||
// TODO(4544): Once we support inlining builtins, make sure no implicit
|
||||
// receiver is created for builtins that don't expect any.
|
||||
if (node->opcode() == IrOpcode::kJSCallConstruct) {
|
||||
Node* effect = NodeProperties::GetEffectInput(node);
|
||||
Node* context = NodeProperties::GetContextInput(node);
|
||||
|
@ -1398,8 +1398,7 @@ Reduction JSTypedLowering::ReduceJSCreate(Node* node) {
|
||||
target_type->AsConstant()->Value()->IsJSFunction()) {
|
||||
Handle<JSFunction> constructor =
|
||||
Handle<JSFunction>::cast(target_type->AsConstant()->Value());
|
||||
// Check that function is a constructor.
|
||||
if (!constructor->IsConstructor()) return NoChange();
|
||||
DCHECK(constructor->IsConstructor());
|
||||
// Force completion of inobject slack tracking before
|
||||
// generating code to finalize the instance size.
|
||||
if (constructor->IsInobjectSlackTrackingInProgress()) {
|
||||
|
@ -1146,9 +1146,6 @@ void LiveEdit::ReplaceFunctionCode(
|
||||
|
||||
LiteralFixer::PatchLiterals(&compile_info_wrapper, shared_info, isolate);
|
||||
|
||||
shared_info->set_construct_stub(
|
||||
isolate->builtins()->builtin(Builtins::kJSConstructStubGeneric));
|
||||
|
||||
DeoptimizeDependentFunctions(*shared_info);
|
||||
isolate->compilation_cache()->Remove(shared_info);
|
||||
}
|
||||
|
@ -1202,7 +1202,8 @@ Handle<JSFunction> Factory::NewFunction(Handle<Map> map,
|
||||
Handle<String> name,
|
||||
MaybeHandle<Code> code) {
|
||||
Handle<Context> context(isolate()->native_context());
|
||||
Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name, code);
|
||||
Handle<SharedFunctionInfo> info =
|
||||
NewSharedFunctionInfo(name, code, map->is_constructor());
|
||||
DCHECK(is_sloppy(info->language_mode()) &&
|
||||
(map.is_identical_to(isolate()->sloppy_function_map()) ||
|
||||
map.is_identical_to(
|
||||
@ -2022,7 +2023,8 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
|
||||
Handle<Code> code, Handle<ScopeInfo> scope_info,
|
||||
Handle<TypeFeedbackVector> feedback_vector) {
|
||||
DCHECK(IsValidFunctionKind(kind));
|
||||
Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(name, code);
|
||||
Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(
|
||||
name, code, IsConstructable(kind, scope_info->language_mode()));
|
||||
shared->set_scope_info(*scope_info);
|
||||
shared->set_feedback_vector(*feedback_vector);
|
||||
shared->set_kind(kind);
|
||||
@ -2055,8 +2057,7 @@ Handle<JSMessageObject> Factory::NewJSMessageObject(
|
||||
|
||||
|
||||
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
|
||||
Handle<String> name,
|
||||
MaybeHandle<Code> maybe_code) {
|
||||
Handle<String> name, MaybeHandle<Code> maybe_code, bool is_constructor) {
|
||||
Handle<Map> map = shared_function_info_map();
|
||||
Handle<SharedFunctionInfo> share = New<SharedFunctionInfo>(map, OLD_SPACE);
|
||||
|
||||
@ -2064,14 +2065,15 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
|
||||
share->set_name(*name);
|
||||
Handle<Code> code;
|
||||
if (!maybe_code.ToHandle(&code)) {
|
||||
code = handle(isolate()->builtins()->builtin(Builtins::kIllegal));
|
||||
code = isolate()->builtins()->Illegal();
|
||||
}
|
||||
share->set_code(*code);
|
||||
share->set_optimized_code_map(*cleared_optimized_code_map());
|
||||
share->set_scope_info(ScopeInfo::Empty(isolate()));
|
||||
Code* construct_stub =
|
||||
isolate()->builtins()->builtin(Builtins::kJSConstructStubGeneric);
|
||||
share->set_construct_stub(construct_stub);
|
||||
Handle<Code> construct_stub =
|
||||
is_constructor ? isolate()->builtins()->JSConstructStubGeneric()
|
||||
: isolate()->builtins()->ConstructedNonConstructable();
|
||||
share->set_construct_stub(*construct_stub);
|
||||
share->set_instance_class_name(*Object_string());
|
||||
share->set_function_data(*undefined_value(), SKIP_WRITE_BARRIER);
|
||||
share->set_script(*undefined_value(), SKIP_WRITE_BARRIER);
|
||||
|
@ -627,7 +627,8 @@ class Factory final {
|
||||
Handle<Code> code, Handle<ScopeInfo> scope_info,
|
||||
Handle<TypeFeedbackVector> feedback_vector);
|
||||
Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name,
|
||||
MaybeHandle<Code> code);
|
||||
MaybeHandle<Code> code,
|
||||
bool is_constructor);
|
||||
|
||||
// Allocates a new JSMessageObject object.
|
||||
Handle<JSMessageObject> NewJSMessageObject(MessageTemplate::Template message,
|
||||
|
@ -1022,6 +1022,15 @@ inline bool IsClassConstructor(FunctionKind kind) {
|
||||
}
|
||||
|
||||
|
||||
inline bool IsConstructable(FunctionKind kind, LanguageMode mode) {
|
||||
if (IsAccessorFunction(kind)) return false;
|
||||
if (IsConciseMethod(kind) && !IsGeneratorFunction(kind)) return false;
|
||||
if (IsArrowFunction(kind)) return false;
|
||||
if (is_strong(mode)) return IsClassConstructor(kind);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline bool IsInObjectLiteral(FunctionKind kind) {
|
||||
DCHECK(IsValidFunctionKind(kind));
|
||||
return kind & FunctionKind::kInObjectLiteral;
|
||||
|
@ -410,6 +410,13 @@ void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) {
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
__ push(edi);
|
||||
__ CallRuntime(Runtime::kThrowConstructedNonConstructable, 1);
|
||||
}
|
||||
|
||||
|
||||
enum IsTagged { kEaxIsSmiTagged, kEaxIsUntaggedInt };
|
||||
|
||||
|
||||
@ -1543,7 +1550,8 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
|
||||
__ bind(&class_constructor);
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::INTERNAL);
|
||||
__ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0);
|
||||
__ push(edi);
|
||||
__ CallRuntime(Runtime::kThrowConstructorNonCallableError, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1670,11 +1678,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
// Called Construct on an Object that doesn't have a [[Construct]] internal
|
||||
// method.
|
||||
__ bind(&non_constructor);
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
__ Push(edi);
|
||||
__ CallRuntime(Runtime::kThrowCalledNonCallable, 1);
|
||||
}
|
||||
__ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
|
||||
|
@ -100,7 +100,7 @@ class CallSite {
|
||||
T(CircularStructure, "Converting circular structure to JSON") \
|
||||
T(ConstAssign, "Assignment to constant variable.") \
|
||||
T(ConstructorNonCallable, \
|
||||
"Class constructors cannot be invoked without 'new'") \
|
||||
"Class constructor % cannot be invoked without 'new'") \
|
||||
T(ConstructorNotFunction, "Constructor % requires 'new'") \
|
||||
T(CurrencyCode, "Currency code is required with currency style.") \
|
||||
T(DataViewNotArrayBuffer, \
|
||||
|
@ -650,6 +650,13 @@ void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) {
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
__ Push(a1);
|
||||
__ CallRuntime(Runtime::kThrowConstructedNonConstructable, 1);
|
||||
}
|
||||
|
||||
|
||||
enum IsTagged { kArgcIsSmiTagged, kArgcIsUntaggedInt };
|
||||
|
||||
|
||||
@ -1700,7 +1707,8 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
|
||||
__ bind(&class_constructor);
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::INTERNAL);
|
||||
__ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0);
|
||||
__ Push(a1);
|
||||
__ CallRuntime(Runtime::kThrowConstructorNonCallableError, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1832,11 +1840,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
// Called Construct on an Object that doesn't have a [[Construct]] internal
|
||||
// method.
|
||||
__ bind(&non_constructor);
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
__ Push(a1);
|
||||
__ CallRuntime(Runtime::kThrowCalledNonCallable, 1);
|
||||
}
|
||||
__ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
|
||||
|
@ -646,6 +646,13 @@ void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) {
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
__ Push(a1);
|
||||
__ CallRuntime(Runtime::kThrowConstructedNonConstructable, 1);
|
||||
}
|
||||
|
||||
|
||||
enum IsTagged { kArgcIsSmiTagged, kArgcIsUntaggedInt };
|
||||
|
||||
|
||||
@ -1694,7 +1701,8 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
|
||||
__ bind(&class_constructor);
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::INTERNAL);
|
||||
__ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0);
|
||||
__ Push(a1);
|
||||
__ CallRuntime(Runtime::kThrowConstructorNonCallableError, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1825,11 +1833,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
// Called Construct on an Object that doesn't have a [[Construct]] internal
|
||||
// method.
|
||||
__ bind(&non_constructor);
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
__ Push(a1);
|
||||
__ CallRuntime(Runtime::kThrowCalledNonCallable, 1);
|
||||
}
|
||||
__ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
|
||||
|
@ -12732,6 +12732,10 @@ void SharedFunctionInfo::InitFromFunctionLiteral(
|
||||
shared_info->set_dont_crankshaft(lit->flags() &
|
||||
AstProperties::kDontCrankshaft);
|
||||
shared_info->set_kind(lit->kind());
|
||||
if (!IsConstructable(lit->kind(), lit->language_mode())) {
|
||||
shared_info->set_construct_stub(
|
||||
*shared_info->GetIsolate()->builtins()->ConstructedNonConstructable());
|
||||
}
|
||||
shared_info->set_needs_home_object(lit->scope()->NeedsHomeObject());
|
||||
shared_info->set_asm_function(lit->scope()->asm_function());
|
||||
}
|
||||
|
@ -3337,7 +3337,8 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
|
||||
return this->EmptyExpression();
|
||||
}
|
||||
int pos;
|
||||
if (scanner()->current_token() == Token::IDENTIFIER) {
|
||||
if (scanner()->current_token() == Token::IDENTIFIER ||
|
||||
scanner()->current_token() == Token::SUPER) {
|
||||
// For call of an identifier we want to report position of
|
||||
// the identifier as position of the call in the stack trace.
|
||||
pos = position();
|
||||
@ -3677,8 +3678,8 @@ typename ParserBase<Traits>::ExpressionT
|
||||
ParserBase<Traits>::ParseSuperExpression(bool is_new,
|
||||
ExpressionClassifier* classifier,
|
||||
bool* ok) {
|
||||
int pos = position();
|
||||
Expect(Token::SUPER, CHECK_OK);
|
||||
int pos = position();
|
||||
|
||||
Scope* scope = scope_->ReceiverScope();
|
||||
FunctionKind kind = scope->function_kind();
|
||||
|
@ -321,6 +321,13 @@ void CallPrinter::VisitCallNew(CallNew* node) {
|
||||
|
||||
|
||||
void CallPrinter::VisitCallRuntime(CallRuntime* node) {
|
||||
if (node->function() ==
|
||||
Runtime::FunctionForId(Runtime::kInlineDefaultConstructorCallSuper)) {
|
||||
found_ = true;
|
||||
Print("super");
|
||||
done_ = true;
|
||||
return;
|
||||
}
|
||||
FindArguments(node->arguments());
|
||||
}
|
||||
|
||||
@ -380,7 +387,9 @@ void CallPrinter::VisitThisFunction(ThisFunction* node) {}
|
||||
void CallPrinter::VisitSuperPropertyReference(SuperPropertyReference* node) {}
|
||||
|
||||
|
||||
void CallPrinter::VisitSuperCallReference(SuperCallReference* node) {}
|
||||
void CallPrinter::VisitSuperCallReference(SuperCallReference* node) {
|
||||
Print("super");
|
||||
}
|
||||
|
||||
|
||||
void CallPrinter::FindStatements(ZoneList<Statement*>* statements) {
|
||||
|
@ -36,9 +36,11 @@ RUNTIME_FUNCTION(Runtime_ThrowUnsupportedSuperError) {
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_ThrowConstructorNonCallableError) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK(args.length() == 0);
|
||||
DCHECK(args.length() == 1);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
|
||||
Handle<Object> name(constructor->shared()->name(), isolate);
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kConstructorNonCallable));
|
||||
isolate, NewTypeError(MessageTemplate::kConstructorNonCallable, name));
|
||||
}
|
||||
|
||||
|
||||
|
@ -107,6 +107,8 @@ RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
|
||||
|
||||
CONVERT_ARG_CHECKED(JSFunction, f, 0);
|
||||
RUNTIME_ASSERT(f->RemovePrototype());
|
||||
f->shared()->set_construct_stub(
|
||||
*isolate->builtins()->ConstructedNonConstructable());
|
||||
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
@ -395,6 +397,8 @@ RUNTIME_FUNCTION(Runtime_FunctionBindArguments) {
|
||||
bound_function->shared()->set_optimized_code_map(
|
||||
isolate->heap()->cleared_optimized_code_map());
|
||||
bound_function->shared()->set_inferred_name(isolate->heap()->empty_string());
|
||||
bound_function->shared()->set_construct_stub(
|
||||
*isolate->builtins()->JSBuiltinsConstructStub());
|
||||
// Get all arguments of calling function (Function.prototype.bind).
|
||||
int argc = 0;
|
||||
base::SmartArrayPointer<Handle<Object>> arguments =
|
||||
|
@ -443,5 +443,15 @@ RUNTIME_FUNCTION(Runtime_ThrowCalledNonCallable) {
|
||||
isolate, NewTypeError(MessageTemplate::kCalledNonCallable, callsite));
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_ThrowConstructedNonConstructable) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
|
||||
Handle<String> callsite = RenderCallSite(isolate, object);
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kNotConstructor, callsite));
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -1044,11 +1044,7 @@ RUNTIME_FUNCTION(Runtime_NewObject) {
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, new_target, 1);
|
||||
|
||||
// TODO(verwaest): Make sure |constructor| is guaranteed to be a constructor.
|
||||
if (!constructor->IsConstructor()) {
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kNotConstructor, constructor));
|
||||
}
|
||||
DCHECK(constructor->IsConstructor());
|
||||
|
||||
// If called through new, new.target can be:
|
||||
// - a subclass of constructor,
|
||||
|
@ -73,24 +73,24 @@ namespace internal {
|
||||
F(AtomicsFutexNumWaitersForTesting, 2, 1)
|
||||
|
||||
|
||||
#define FOR_EACH_INTRINSIC_CLASSES(F) \
|
||||
F(ThrowNonMethodError, 0, 1) \
|
||||
F(ThrowUnsupportedSuperError, 0, 1) \
|
||||
F(ThrowConstructorNonCallableError, 0, 1) \
|
||||
F(ThrowArrayNotSubclassableError, 0, 1) \
|
||||
F(ThrowStaticPrototypeError, 0, 1) \
|
||||
F(ThrowIfStaticPrototype, 1, 1) \
|
||||
F(HomeObjectSymbol, 0, 1) \
|
||||
F(DefineClass, 5, 1) \
|
||||
F(FinalizeClassDefinition, 2, 1) \
|
||||
F(DefineClassMethod, 3, 1) \
|
||||
F(ClassGetSourceCode, 1, 1) \
|
||||
F(LoadFromSuper, 4, 1) \
|
||||
F(LoadKeyedFromSuper, 4, 1) \
|
||||
F(StoreToSuper_Strict, 4, 1) \
|
||||
F(StoreToSuper_Sloppy, 4, 1) \
|
||||
F(StoreKeyedToSuper_Strict, 4, 1) \
|
||||
F(StoreKeyedToSuper_Sloppy, 4, 1) \
|
||||
#define FOR_EACH_INTRINSIC_CLASSES(F) \
|
||||
F(ThrowNonMethodError, 0, 1) \
|
||||
F(ThrowUnsupportedSuperError, 0, 1) \
|
||||
F(ThrowConstructorNonCallableError, 1, 1) \
|
||||
F(ThrowArrayNotSubclassableError, 0, 1) \
|
||||
F(ThrowStaticPrototypeError, 0, 1) \
|
||||
F(ThrowIfStaticPrototype, 1, 1) \
|
||||
F(HomeObjectSymbol, 0, 1) \
|
||||
F(DefineClass, 5, 1) \
|
||||
F(FinalizeClassDefinition, 2, 1) \
|
||||
F(DefineClassMethod, 3, 1) \
|
||||
F(ClassGetSourceCode, 1, 1) \
|
||||
F(LoadFromSuper, 4, 1) \
|
||||
F(LoadKeyedFromSuper, 4, 1) \
|
||||
F(StoreToSuper_Strict, 4, 1) \
|
||||
F(StoreToSuper_Sloppy, 4, 1) \
|
||||
F(StoreKeyedToSuper_Strict, 4, 1) \
|
||||
F(StoreKeyedToSuper_Sloppy, 4, 1) \
|
||||
F(DefaultConstructorCallSuper, 2, 1)
|
||||
|
||||
|
||||
@ -356,6 +356,7 @@ namespace internal {
|
||||
F(GetTypeFeedbackVector, 1, 1) \
|
||||
F(GetCallerJSFunction, 0, 1) \
|
||||
F(GetCodeStubExportsObject, 0, 1) \
|
||||
F(ThrowConstructedNonConstructable, 1, 1) \
|
||||
F(ThrowCalledNonCallable, 1, 1)
|
||||
|
||||
|
||||
|
@ -401,6 +401,13 @@ void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) {
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
__ Push(rdi);
|
||||
__ CallRuntime(Runtime::kThrowConstructedNonConstructable, 1);
|
||||
}
|
||||
|
||||
|
||||
enum IsTagged { kRaxIsSmiTagged, kRaxIsUntaggedInt };
|
||||
|
||||
|
||||
@ -1735,7 +1742,8 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
|
||||
__ bind(&class_constructor);
|
||||
{
|
||||
FrameScope frame(masm, StackFrame::INTERNAL);
|
||||
__ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0);
|
||||
__ Push(rdi);
|
||||
__ CallRuntime(Runtime::kThrowConstructorNonCallableError, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1866,11 +1874,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
// Called Construct on an Object that doesn't have a [[Construct]] internal
|
||||
// method.
|
||||
__ bind(&non_constructor);
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
__ Push(rdi);
|
||||
__ CallRuntime(Runtime::kThrowCalledNonCallable, 1);
|
||||
}
|
||||
__ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
|
||||
|
@ -9858,15 +9858,16 @@ THREADED_TEST(ConstructorForObject) {
|
||||
value = CompileRun("new obj2(28)");
|
||||
CHECK(try_catch.HasCaught());
|
||||
String::Utf8Value exception_value1(try_catch.Exception());
|
||||
CHECK_EQ(0, strcmp("TypeError: obj2 is not a function", *exception_value1));
|
||||
CHECK_EQ(0,
|
||||
strcmp("TypeError: obj2 is not a constructor", *exception_value1));
|
||||
try_catch.Reset();
|
||||
|
||||
Local<Value> args[] = {v8_num(29)};
|
||||
value = instance->CallAsConstructor(1, args);
|
||||
CHECK(try_catch.HasCaught());
|
||||
String::Utf8Value exception_value2(try_catch.Exception());
|
||||
CHECK_EQ(0,
|
||||
strcmp("TypeError: object is not a function", *exception_value2));
|
||||
CHECK_EQ(
|
||||
0, strcmp("TypeError: object is not a constructor", *exception_value2));
|
||||
try_catch.Reset();
|
||||
}
|
||||
|
||||
|
19
test/mjsunit/regress/regress-inline-arrow-as-construct.js
Normal file
19
test/mjsunit/regress/regress-inline-arrow-as-construct.js
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright 2015 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --allow-natives-syntax
|
||||
|
||||
// This tests that inlining a constructor call to a function which cannot be
|
||||
// used as a constructor (e.g. arrow function) still throws correctly.
|
||||
|
||||
var g = () => {}
|
||||
|
||||
function f() {
|
||||
return new g();
|
||||
}
|
||||
|
||||
assertThrows(f);
|
||||
assertThrows(f);
|
||||
%OptimizeFunctionOnNextCall(f);
|
||||
assertThrows(f);
|
@ -78,7 +78,7 @@ Graph* BytecodeGraphBuilderTest::GetCompletedGraph(
|
||||
Handle<String> name = factory()->NewStringFromStaticChars("test");
|
||||
Handle<String> script = factory()->NewStringFromStaticChars("test() {}");
|
||||
Handle<SharedFunctionInfo> shared_info =
|
||||
factory()->NewSharedFunctionInfo(name, MaybeHandle<Code>());
|
||||
factory()->NewSharedFunctionInfo(name, MaybeHandle<Code>(), true);
|
||||
shared_info->set_script(*factory()->NewScript(script));
|
||||
if (!feedback_vector.is_null()) {
|
||||
shared_info->set_feedback_vector(*feedback_vector.ToHandleChecked());
|
||||
|
@ -4,13 +4,13 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
|
||||
|
||||
|
||||
PASS new A did not throw exception.
|
||||
PASS A() threw exception TypeError: Class constructors cannot be invoked without 'new'.
|
||||
PASS A() threw exception TypeError: Class constructor A cannot be invoked without 'new'.
|
||||
PASS new B did not throw exception.
|
||||
PASS B() threw exception TypeError: Class constructors cannot be invoked without 'new'.
|
||||
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 constructors cannot be invoked without 'new'.
|
||||
PASS new (class extends null { constructor() { super() } })() threw exception TypeError: function () {} is not a constructor.
|
||||
PASS (class extends null { constructor() { super() } })() threw exception TypeError: Class constructors cannot be invoked without 'new'.
|
||||
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 (class extends null { constructor() { super() } })() threw exception TypeError: Class constructor cannot be invoked without 'new'.
|
||||
PASS successfullyParsed is true
|
||||
|
||||
TEST COMPLETE
|
||||
|
@ -29,12 +29,12 @@ class A { constructor() {} };
|
||||
class B extends A { constructor() { super() } };
|
||||
|
||||
shouldNotThrow('new A');
|
||||
shouldThrow('A()', '"TypeError: Class constructors cannot be invoked without \'new\'"');
|
||||
shouldThrow('A()', '"TypeError: Class constructor A cannot be invoked without \'new\'"');
|
||||
shouldNotThrow('new B');
|
||||
shouldThrow('B()', '"TypeError: Class constructors cannot be invoked without \'new\'"');
|
||||
shouldThrow('B()', '"TypeError: Class constructor B cannot be invoked without \'new\'"');
|
||||
shouldNotThrow('new (class { constructor() {} })()');
|
||||
shouldThrow('(class { constructor() {} })()', '"TypeError: Class constructors cannot be invoked without \'new\'"');
|
||||
shouldThrow('new (class extends null { constructor() { super() } })()', '"TypeError: function () {} is not a constructor"');
|
||||
shouldThrow('(class extends null { constructor() { super() } })()', '"TypeError: Class constructors cannot be invoked without \'new\'"');
|
||||
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('(class extends null { constructor() { super() } })()', '"TypeError: Class constructor cannot be invoked without \'new\'"');
|
||||
|
||||
var successfullyParsed = true;
|
||||
|
@ -4,11 +4,11 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
|
||||
|
||||
|
||||
PASS new A instanceof A is true
|
||||
PASS A() threw exception TypeError: Class constructors cannot be invoked without 'new'.
|
||||
PASS A() threw exception TypeError: Class constructor A cannot be invoked without 'new'.
|
||||
PASS A.prototype.constructor instanceof Function is true
|
||||
PASS A.prototype.constructor.name is "A"
|
||||
PASS new B instanceof A; new B instanceof A is true
|
||||
PASS B() threw exception TypeError: Class constructors cannot be invoked without 'new'.
|
||||
PASS B() threw exception TypeError: Class constructor B cannot be invoked without 'new'.
|
||||
PASS B.prototype.constructor.name is "B"
|
||||
PASS A !== B is true
|
||||
PASS A.prototype.constructor !== B.prototype.constructor is true
|
||||
|
@ -29,11 +29,11 @@ class A { };
|
||||
class B extends A { };
|
||||
|
||||
shouldBeTrue('new A instanceof A');
|
||||
shouldThrow('A()', '"TypeError: Class constructors cannot be invoked without \'new\'"');
|
||||
shouldThrow('A()', '"TypeError: Class constructor A cannot be invoked without \'new\'"');
|
||||
shouldBeTrue('A.prototype.constructor instanceof Function');
|
||||
shouldBe('A.prototype.constructor.name', '"A"');
|
||||
shouldBeTrue('new B instanceof A; new B instanceof A');
|
||||
shouldThrow('B()', '"TypeError: Class constructors cannot be invoked without \'new\'"');
|
||||
shouldThrow('B()', '"TypeError: Class constructor B cannot be invoked without \'new\'"');
|
||||
shouldBe('B.prototype.constructor.name', '"B"');
|
||||
shouldBeTrue('A !== B');
|
||||
shouldBeTrue('A.prototype.constructor !== B.prototype.constructor');
|
||||
|
@ -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 function 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: function () {} is not a constructor.
|
||||
PASS new (class extends null { constructor () { super(); } }) threw exception TypeError: super 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
|
||||
|
@ -100,7 +100,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 function 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: function () {} is not a constructor"');
|
||||
shouldThrow('new (class extends null { constructor () { super(); } })', '"TypeError: super 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: function () {} is not a constructor.
|
||||
PASS new (class extends null { constructor() { super(); return undefined } }) threw exception TypeError: super 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: function () {} is not a constructor.
|
||||
PASS new (class extends null { constructor() { super() } }) threw exception TypeError: super 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.
|
||||
|
@ -80,12 +80,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: function () {} is not a constructor"');
|
||||
shouldThrow('new (class extends null { constructor() { super(); return undefined } })', '"TypeError: super 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: function () {} is not a constructor"');
|
||||
shouldThrow('new (class extends null { constructor() { super() } })', '"TypeError: super 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"');
|
||||
|
@ -26,7 +26,7 @@ Test for correct handling of exceptions from instanceof and 'new' expressions
|
||||
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
|
||||
|
||||
|
||||
PASS new {}.undefined threw exception TypeError: (intermediate value).undefined is not a function.
|
||||
PASS new {}.undefined threw exception TypeError: (intermediate value).undefined is not a constructor.
|
||||
PASS 1 instanceof {}.undefined threw exception TypeError: Expecting a function in instanceof check, but got undefined.
|
||||
PASS successfullyParsed is true
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user