Revert of new classes: implement new.target passing to superclass constructor. (patch...
authordslomov <dslomov@chromium.org>
Wed, 11 Feb 2015 01:36:17 +0000 (17:36 -0800)
committerCommit bot <commit-bot@chromium.org>
Wed, 11 Feb 2015 01:36:32 +0000 (01:36 +0000)
Reason for revert:
Breaks Linux64 release

Original issue's description:
> new classes: implement new.target passing to superclass constructor.
>
> R=arv@chromium.org,rossberg@chromium.org
> BUG=v8:3834
> LOG=N
>
> Committed: https://crrev.com/8aed43e82c6d2742fe5988603cb8841324cc942b
> Cr-Commit-Position: refs/heads/master@{#26560}

TBR=arv@chromium.org,rossberg@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:3834

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

Cr-Commit-Position: refs/heads/master@{#26561}

40 files changed:
src/accessors.cc
src/arm/builtins-arm.cc
src/arm/code-stubs-arm.cc
src/arm/full-codegen-arm.cc
src/arm64/builtins-arm64.cc
src/arm64/code-stubs-arm64.cc
src/arm64/full-codegen-arm64.cc
src/ast-value-factory.h
src/bootstrapper.cc
src/code-stubs.h
src/code.h
src/compiler.cc
src/compiler/js-generic-lowering.cc
src/compiler/linkage.cc
src/compiler/pipeline.cc
src/deoptimizer.cc
src/factory.cc
src/frames.cc
src/full-codegen.cc
src/globals.h
src/hydrogen-instructions.h
src/hydrogen.cc
src/ia32/builtins-ia32.cc
src/ia32/code-stubs-ia32.cc
src/ia32/deoptimizer-ia32.cc
src/ia32/full-codegen-ia32.cc
src/ic/ic.cc
src/objects-inl.h
src/objects.h
src/runtime/runtime-classes.cc
src/runtime/runtime-function.cc
src/runtime/runtime-object.cc
src/runtime/runtime-scopes.cc
src/scopes.cc
src/scopes.h
src/variables.h
src/x64/builtins-x64.cc
src/x64/code-stubs-x64.cc
src/x64/full-codegen-x64.cc
test/mjsunit/harmony/classes-experimental.js

index 0e6a083910e01e5f5a089334b25b8546348805d3..cee26520772de48aedf616fe8c87b1225a3f8dd6 100644 (file)
@@ -1186,8 +1186,9 @@ static Handle<Object> ArgumentsForInlinedFunction(
   Isolate* isolate = inlined_function->GetIsolate();
   Factory* factory = isolate->factory();
   SlotRefValueBuilder slot_refs(
-      frame, inlined_frame_index,
-      inlined_function->shared()->internal_formal_parameter_count());
+      frame,
+      inlined_frame_index,
+      inlined_function->shared()->formal_parameter_count());
 
   int args_count = slot_refs.args_length();
   Handle<JSObject> arguments =
index 1203ec42b3d3523ce46f66f28a7aed4be271bf79..2c08b801018ef52663e09452a7f7bd18ad9c1860 100644 (file)
@@ -761,9 +761,6 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
     __ SmiTag(r4);
     __ push(r4);  // Smi-tagged arguments count.
 
-    // Push new.target.
-    __ push(r3);
-
     // receiver is the hole.
     __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
     __ push(ip);
@@ -777,8 +774,7 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
     // r2: address of last argument (caller sp)
     // r4: number of arguments (smi-tagged)
     // sp[0]: receiver
-    // sp[1]: new.target
-    // sp[2]: number of arguments (smi-tagged)
+    // sp[1]: number of arguments (smi-tagged)
     Label loop, entry;
     __ b(&entry);
     __ bind(&loop);
@@ -791,7 +787,6 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
     // Call the function.
     // r0: number of arguments
     // r1: constructor function
-    __ add(r0, r0, Operand(1));
     ParameterCount actual(r0);
     __ InvokeFunction(r1, actual, CALL_FUNCTION, NullCallWrapper());
 
index e55069a604947287589d3e71e3df57ed5183e7da..35f835bbd4149641080158762526611ab22494a8 100644 (file)
@@ -1488,7 +1488,6 @@ void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
 
 
 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
-  CHECK(!has_new_target());
   // The displacement is the offset of the last parameter (if any)
   // relative to the frame pointer.
   const int kDisplacement =
@@ -1546,8 +1545,6 @@ void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) {
   // sp[4] : receiver displacement
   // sp[8] : function
 
-  CHECK(!has_new_target());
-
   // Check if the calling frame is an arguments adaptor frame.
   Label runtime;
   __ ldr(r3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
@@ -1576,8 +1573,6 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
   //  r6 : allocated object (tagged)
   //  r9 : mapped parameter count (tagged)
 
-  CHECK(!has_new_target());
-
   __ ldr(r1, MemOperand(sp, 0 * kPointerSize));
   // r1 = parameter count (tagged)
 
@@ -1818,10 +1813,6 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
   // Patch the arguments.length and the parameters pointer.
   __ bind(&adaptor_frame);
   __ ldr(r1, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset));
-  if (has_new_target()) {
-    // Subtract 1 from smi-tagged arguments count.
-    __ sub(r1, r1, Operand(2));
-  }
   __ str(r1, MemOperand(sp, 0));
   __ add(r3, r2, Operand::PointerOffsetFromSmiKey(r1));
   __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset));
@@ -2573,13 +2564,7 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
   }
 
   // Pass function as original constructor.
-  if (IsSuperConstructorCall()) {
-    __ mov(r4, Operand(1 * kPointerSize));
-    __ add(r4, r4, Operand(r0, LSL, kPointerSizeLog2));
-    __ ldr(r3, MemOperand(sp, r4));
-  } else {
-    __ mov(r3, r1);
-  }
+  __ mov(r3, r1);
 
   // Jump to the function-specific construct stub.
   Register jmp_reg = r4;
index 599231ef7fb1f4f1a98bfd6233b7c216180e2394..7508c01e4998473eb00ffd20ab7ce4700241e6a3 100644 (file)
@@ -262,10 +262,6 @@ void FullCodeGenerator::Generate() {
     //   function, receiver address, parameter count.
     // The stub will rewrite receiever and parameter count if the previous
     // stack frame was an arguments adapter frame.
-    ArgumentsAccessStub::HasNewTarget has_new_target =
-        IsSubclassConstructor(info->function()->kind())
-            ? ArgumentsAccessStub::HAS_NEW_TARGET
-            : ArgumentsAccessStub::NO_NEW_TARGET;
     ArgumentsAccessStub::Type type;
     if (is_strict(language_mode())) {
       type = ArgumentsAccessStub::NEW_STRICT;
@@ -274,7 +270,7 @@ void FullCodeGenerator::Generate() {
     } else {
       type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
     }
-    ArgumentsAccessStub stub(isolate(), type, has_new_target);
+    ArgumentsAccessStub stub(isolate(), type);
     __ CallStub(&stub);
 
     SetVar(arguments, r0, r1, r2);
@@ -454,12 +450,7 @@ void FullCodeGenerator::EmitReturnSequence() {
     // Make sure that the constant pool is not emitted inside of the return
     // sequence.
     { Assembler::BlockConstPoolScope block_const_pool(masm_);
-      int32_t arg_count = info_->scope()->num_parameters() + 1;
-      if (FLAG_experimental_classes &&
-          IsSubclassConstructor(info_->function()->kind())) {
-        arg_count++;
-      }
-      int32_t sp_delta = arg_count * kPointerSize;
+      int32_t sp_delta = (info_->scope()->num_parameters() + 1) * kPointerSize;
       CodeGenerator::RecordPositions(masm_, function()->end_position() - 1);
       // TODO(svenpanne) The code below is sometimes 4 words, sometimes 5!
       PredictableCodeSizeScope predictable(masm_, -1);
@@ -3266,11 +3257,6 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
 
 
 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
-  Comment cmnt(masm_, "[ SuperConstructorCall");
-  Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
-  GetVar(result_register(), new_target_var);
-  __ Push(result_register());
-
   SuperReference* super_ref = expr->expression()->AsSuperReference();
   EmitLoadSuperConstructor(super_ref);
   __ push(result_register());
@@ -3314,11 +3300,10 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
   __ Move(r2, FeedbackVector());
   __ mov(r3, Operand(SmiFromSlot(expr->CallFeedbackSlot())));
 
-  CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET);
+  // TODO(dslomov): use a different stub and propagate new.target.
+  CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
   __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
 
-  __ Drop(1);
-
   RecordJSReturnSite(expr);
 
   EmitVariableAssignment(this_var, Token::INIT_CONST);
index 6dd1dff64bbc5375cb03f95a25aa08af02226d35..726e9847d2fee0053bfd36525c3c6ddf453d3a9a 100644 (file)
@@ -725,10 +725,9 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
     __ Mov(x4, x0);
     __ SmiTag(x4);
     __ LoadRoot(x10, Heap::kTheHoleValueRootIndex);
-    __ Push(x4, x3, x10);
+    __ Push(x4, x10);
     // sp[0]: number of arguments
-    // sp[1]: new.target
-    // sp[2]: receiver (the hole)
+    // sp[1]: receiver (the hole)
 
 
     // Set up pointer to last argument.
@@ -740,8 +739,7 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
     // x1: constructor function
     // x2: address of last argument (caller sp)
     // jssp[0]: receiver
-    // jssp[1]: new.target
-    // jssp[2]: number of arguments (smi-tagged)
+    // jssp[1]: number of arguments (smi-tagged)
     // Compute the start address of the copy in x4.
     __ Add(x4, x2, Operand(x0, LSL, kPointerSizeLog2));
     Label loop, entry, done_copying_arguments;
@@ -761,7 +759,6 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
     // Call the function.
     // x0: number of arguments
     // x1: constructor function
-    __ Add(x0, x0, Operand(1));  // new.target
     ParameterCount actual(x0);
     __ InvokeFunction(x1, actual, CALL_FUNCTION, NullCallWrapper());
 
index 28cbf7cde647fcc1afb7737d6fdd92ddd4b815a8..9a26c3d60b720c733870031ee79f9fc1f868d1ff 100644 (file)
@@ -1643,7 +1643,6 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
 
 
 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
-  CHECK(!has_new_target());
   Register arg_count = ArgumentsAccessReadDescriptor::parameter_count();
   Register key = ArgumentsAccessReadDescriptor::index();
   DCHECK(arg_count.is(x0));
@@ -1700,8 +1699,6 @@ void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) {
   //  jssp[8]:  address of receiver argument
   //  jssp[16]: function
 
-  CHECK(!has_new_target());
-
   // Check if the calling frame is an arguments adaptor frame.
   Label runtime;
   Register caller_fp = x10;
@@ -1733,8 +1730,6 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
   //
   // Returns pointer to result object in x0.
 
-  CHECK(!has_new_target());
-
   // Note: arg_count_smi is an alias of param_count_smi.
   Register arg_count_smi = x3;
   Register param_count_smi = x3;
@@ -2061,11 +2056,6 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
          MemOperand(caller_fp,
                     ArgumentsAdaptorFrameConstants::kLengthOffset));
   __ SmiUntag(param_count, param_count_smi);
-  if (has_new_target()) {
-    // Skip new.target: it is not a part of arguments.
-    __ Sub(param_count, param_count, Operand(1));
-    __ SmiTag(param_count_smi, param_count);
-  }
   __ Add(x10, caller_fp, Operand(param_count, LSL, kPointerSizeLog2));
   __ Add(params, x10, StandardFrameConstants::kCallerSPOffset);
 
@@ -2949,13 +2939,7 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
     __ AssertUndefinedOrAllocationSite(x2, x5);
   }
 
-  if (IsSuperConstructorCall()) {
-    __ Mov(x4, Operand(1 * kPointerSize));
-    __ Add(x4, x4, Operand(x0, LSL, kPointerSizeLog2));
-    __ Peek(x3, x4);
-  } else {
-    __ Mov(x3, function);
-  }
+  __ Mov(x3, function);
 
   // Jump to the function-specific construct stub.
   Register jump_reg = x4;
index d49b06b77b35cba9abd3e958f76359da0932902a..1d24b91dbb846fd0e85300c7405c2b143c41f2f0 100644 (file)
@@ -262,10 +262,6 @@ void FullCodeGenerator::Generate() {
     //   function, receiver address, parameter count.
     // The stub will rewrite receiver and parameter count if the previous
     // stack frame was an arguments adapter frame.
-    ArgumentsAccessStub::HasNewTarget has_new_target =
-        IsSubclassConstructor(info->function()->kind())
-            ? ArgumentsAccessStub::HAS_NEW_TARGET
-            : ArgumentsAccessStub::NO_NEW_TARGET;
     ArgumentsAccessStub::Type type;
     if (is_strict(language_mode())) {
       type = ArgumentsAccessStub::NEW_STRICT;
@@ -274,7 +270,7 @@ void FullCodeGenerator::Generate() {
     } else {
       type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
     }
-    ArgumentsAccessStub stub(isolate(), type, has_new_target);
+    ArgumentsAccessStub stub(isolate(), type);
     __ CallStub(&stub);
 
     SetVar(arguments, x0, x1, x2);
@@ -459,12 +455,7 @@ void FullCodeGenerator::EmitReturnSequence() {
       __ ldr_pcrel(ip0, (3 * kInstructionSize) >> kLoadLiteralScaleLog2);
       __ add(current_sp, current_sp, ip0);
       __ ret();
-      int32_t arg_count = info_->scope()->num_parameters() + 1;
-      if (FLAG_experimental_classes &&
-          IsSubclassConstructor(info_->function()->kind())) {
-        arg_count++;
-      }
-      __ dc64(kXRegSize * arg_count);
+      __ dc64(kXRegSize * (info_->scope()->num_parameters() + 1));
       info_->AddNoFrameRange(no_frame_start, masm_->pc_offset());
     }
   }
@@ -2955,11 +2946,6 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
 
 
 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
-  Comment cmnt(masm_, "[ SuperConstructorCall");
-  Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
-  GetVar(result_register(), new_target_var);
-  __ Push(result_register());
-
   SuperReference* super_ref = expr->expression()->AsSuperReference();
   EmitLoadSuperConstructor(super_ref);
   __ push(result_register());
@@ -3002,11 +2988,10 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
   __ LoadObject(x2, FeedbackVector());
   __ Mov(x3, SmiFromSlot(expr->CallFeedbackSlot()));
 
-  CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET);
+  // TODO(dslomov): use a different stub and propagate new.target.
+  CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
   __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
 
-  __ Drop(1);
-
   RecordJSReturnSite(expr);
 
   EmitVariableAssignment(this_var, Token::INIT_CONST);
index 294a2818590d6486e3e4c0a4d197ea5d57d3d27b..70a29f14e3d51c73f953a56c7bed2ef8c9598e07 100644 (file)
@@ -249,13 +249,11 @@ class AstValue : public ZoneObject {
   F(get_template_callsite, "GetTemplateCallSite")       \
   F(initialize_const_global, "initializeConstGlobal")   \
   F(initialize_var_global, "initializeVarGlobal")       \
-  F(is_construct_call, "_IsConstructCall")              \
   F(let, "let")                                         \
   F(make_reference_error, "MakeReferenceErrorEmbedded") \
   F(make_syntax_error, "MakeSyntaxErrorEmbedded")       \
   F(make_type_error, "MakeTypeErrorEmbedded")           \
   F(native, "native")                                   \
-  F(new_target, "new.target")                           \
   F(next, "next")                                       \
   F(proto, "__proto__")                                 \
   F(prototype, "prototype")                             \
@@ -263,7 +261,8 @@ class AstValue : public ZoneObject {
   F(use_asm, "use asm")                                 \
   F(use_strong, "use strong")                           \
   F(use_strict, "use strict")                           \
-  F(value, "value")
+  F(value, "value")                                     \
+  F(is_construct_call, "_IsConstructCall")
 
 #define OTHER_CONSTANTS(F) \
   F(true_value)            \
index 31d6e3e00c2cc355bc8b2caaface11a6989d55bd..4e3cfc48d7a991aa4d42c21f4b74c45194baeac8 100644 (file)
@@ -2102,7 +2102,7 @@ bool Genesis::InstallNatives() {
     DCHECK(call->is_compiled());
 
     // Set the expected parameters for apply to 2; required by builtin.
-    apply->shared()->set_internal_formal_parameter_count(2);
+    apply->shared()->set_formal_parameter_count(2);
 
     // Set the lengths for the functions to satisfy ECMA-262.
     call->shared()->set_length(1);
index fb2fbe55df5398d9ed4d7c0351b5a888e9b8d0c3..dbdd3c73577709f884ab1b8ef534edd0e905f2bd 100644 (file)
@@ -1590,13 +1590,8 @@ class ArgumentsAccessStub: public PlatformCodeStub {
     NEW_STRICT
   };
 
-  enum HasNewTarget { NO_NEW_TARGET, HAS_NEW_TARGET };
-
-  ArgumentsAccessStub(Isolate* isolate, Type type,
-                      HasNewTarget has_new_target = NO_NEW_TARGET)
-      : PlatformCodeStub(isolate) {
-    minor_key_ =
-        TypeBits::encode(type) | HasNewTargetBits::encode(has_new_target);
+  ArgumentsAccessStub(Isolate* isolate, Type type) : PlatformCodeStub(isolate) {
+    minor_key_ = TypeBits::encode(type);
   }
 
   CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE {
@@ -1608,9 +1603,6 @@ class ArgumentsAccessStub: public PlatformCodeStub {
 
  private:
   Type type() const { return TypeBits::decode(minor_key_); }
-  bool has_new_target() const {
-    return HasNewTargetBits::decode(minor_key_) == HAS_NEW_TARGET;
-  }
 
   void GenerateReadElement(MacroAssembler* masm);
   void GenerateNewStrict(MacroAssembler* masm);
@@ -1620,7 +1612,6 @@ class ArgumentsAccessStub: public PlatformCodeStub {
   void PrintName(std::ostream& os) const OVERRIDE;  // NOLINT
 
   class TypeBits : public BitField<Type, 0, 2> {};
-  class HasNewTargetBits : public BitField<HasNewTarget, 2, 1> {};
 
   DEFINE_PLATFORM_CODE_STUB(ArgumentsAccess, PlatformCodeStub);
 };
@@ -1702,13 +1693,9 @@ class CallConstructStub: public PlatformCodeStub {
     return (flags() & RECORD_CONSTRUCTOR_TARGET) != 0;
   }
 
-  bool IsSuperConstructorCall() const {
-    return (flags() & SUPER_CONSTRUCTOR_CALL) != 0;
-  }
-
   void PrintName(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  class FlagBits : public BitField<CallConstructorFlags, 0, 2> {};
+  class FlagBits : public BitField<CallConstructorFlags, 0, 1> {};
 
   DEFINE_CALL_INTERFACE_DESCRIPTOR(CallConstruct);
   DEFINE_PLATFORM_CODE_STUB(CallConstruct, PlatformCodeStub);
index a0639e8deb8ae4e946e1e35a330aea03eee7a895..d0a5fec61ffc6a70494a1520022313f6121f2801 100644 (file)
@@ -24,8 +24,7 @@ class ParameterCount BASE_EMBEDDED {
   explicit ParameterCount(int immediate)
       : reg_(no_reg), immediate_(immediate) { }
   explicit ParameterCount(Handle<JSFunction> f)
-      : reg_(no_reg),
-        immediate_(f->shared()->internal_formal_parameter_count()) {}
+      : reg_(no_reg), immediate_(f->shared()->formal_parameter_count()) { }
 
   bool is_reg() const { return !reg_.is(no_reg); }
   bool is_immediate() const { return !is_reg(); }
index d588f467d7ad87d33287c5d81cd0f26d47070ce2..8961debaab4055f5869c9df0d6b73b1b203b41fa 100644 (file)
@@ -619,12 +619,7 @@ static void SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
                             bool is_toplevel,
                             Handle<Script> script) {
   function_info->set_length(lit->parameter_count());
-  if (FLAG_experimental_classes && IsSubclassConstructor(lit->kind())) {
-    function_info->set_internal_formal_parameter_count(lit->parameter_count() +
-                                                       1);
-  } else {
-    function_info->set_internal_formal_parameter_count(lit->parameter_count());
-  }
+  function_info->set_formal_parameter_count(lit->parameter_count());
   function_info->set_script(*script);
   function_info->set_function_token_position(lit->function_token_position());
   function_info->set_start_position(lit->start_position());
index cf9ef1717177b593119b5326bc214938cbc91a95..d326e806078f83197c5734406a872fa5e360c3d3 100644 (file)
@@ -397,9 +397,7 @@ bool JSGenericLowering::TryLowerDirectJSCall(Node* node) {
   Handle<Object> func = function_const.Value().handle();
   if (!func->IsJSFunction()) return false;  // not a function.
   Handle<JSFunction> function = Handle<JSFunction>::cast(func);
-  if (arg_count != function->shared()->internal_formal_parameter_count()) {
-    return false;
-  }
+  if (arg_count != function->shared()->formal_parameter_count()) return false;
 
   // Check the receiver doesn't need to be wrapped.
   Node* receiver = node->InputAt(1);
index 71a669510bd9e44ed25fbb7f66d7982e7e1f6e7f..e0fd05d1c6bf84a98bdcb5afc547581ed1ac9c7b 100644 (file)
@@ -51,7 +51,7 @@ CallDescriptor* Linkage::ComputeIncoming(Zone* zone, CompilationInfo* info) {
     // plus the receiver.
     SharedFunctionInfo* shared = info->closure()->shared();
     return GetJSCallDescriptor(zone, info->is_osr(),
-                               1 + shared->internal_formal_parameter_count(),
+                               1 + shared->formal_parameter_count(),
                                CallDescriptor::kNoFlags);
   }
   if (info->code_stub() != NULL) {
index 2ddfbd053255f0049b753b37f59af0281c358252..59089e03d618efc5a0914e02e1ccb9aa06c4c58f 100644 (file)
@@ -810,12 +810,6 @@ Handle<Code> Pipeline::GenerateCode() {
     return Handle<Code>::null();
   }
 
-  // TODO(dslomov): support turbo optimization of subclass constructors.
-  if (IsSubclassConstructor(shared->kind())) {
-    shared->DisableOptimization(kSuperReference);
-    return Handle<Code>::null();
-  }
-
   ZonePool zone_pool;
   SmartPointer<PipelineStatistics> pipeline_statistics;
 
index 7c79c89078b98a74e8d65bfb766e2670a8850ba4..5ce3fa3aa4c069b77143491e058d26176131a9c5 100644 (file)
@@ -927,8 +927,7 @@ void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
   output_frame->SetTop(top_address);
 
   // Compute the incoming parameter translation.
-  int parameter_count =
-      function->shared()->internal_formal_parameter_count() + 1;
+  int parameter_count = function->shared()->formal_parameter_count() + 1;
   unsigned output_offset = output_frame_size;
   unsigned input_offset = input_frame_size;
   for (int i = 0; i < parameter_count; ++i) {
@@ -2725,8 +2724,7 @@ unsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const {
     CHECK_EQ(Smi::cast(function), Smi::FromInt(StackFrame::STUB));
     return 0;
   }
-  unsigned arguments =
-      function->shared()->internal_formal_parameter_count() + 1;
+  unsigned arguments = function->shared()->formal_parameter_count() + 1;
   return arguments * kPointerSize;
 }
 
@@ -2863,7 +2861,7 @@ unsigned FrameDescription::GetOffsetFromSlotIndex(int slot_index) {
 int FrameDescription::ComputeParametersCount() {
   switch (type_) {
     case StackFrame::JAVA_SCRIPT:
-      return function_->shared()->internal_formal_parameter_count();
+      return function_->shared()->formal_parameter_count();
     case StackFrame::ARGUMENTS_ADAPTOR: {
       // Last slot contains number of incomming arguments as a smi.
       // Can't use GetExpression(0) because it would cause infinite recursion.
index b888389926b88cd3d0b550ba708b5ba25eaaa235..b3779f291af96bf7cefd769c838fc1534aa9a665 100644 (file)
@@ -2103,7 +2103,7 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
 
   // Set integer fields (smi or int, depending on the architecture).
   share->set_length(0);
-  share->set_internal_formal_parameter_count(0);
+  share->set_formal_parameter_count(0);
   share->set_expected_nof_properties(0);
   share->set_num_literals(0);
   share->set_start_position_and_type(0);
index b7fba653d527eb3d788e72b5db64f618a60f2cb0..0ba8ea0020ed379dc2d70fe423b6ac00d983f6f1 100644 (file)
@@ -754,7 +754,7 @@ int JavaScriptFrame::GetNumberOfIncomingArguments() const {
   DCHECK(can_access_heap_objects() &&
          isolate()->heap()->gc_state() == Heap::NOT_IN_GC);
 
-  return function()->shared()->internal_formal_parameter_count();
+  return function()->shared()->formal_parameter_count();
 }
 
 
@@ -1310,7 +1310,7 @@ void ArgumentsAdaptorFrame::Print(StringStream* accumulator,
   int actual = ComputeParametersCount();
   int expected = -1;
   JSFunction* function = this->function();
-  expected = function->shared()->internal_formal_parameter_count();
+  expected = function->shared()->formal_parameter_count();
 
   PrintIndex(accumulator, mode, index);
   accumulator->Add("arguments adaptor frame: %d->%d", actual, expected);
index 44a04ef2a5d93eb7ca10f0bbc7a74f96625180a4..0896e429d6b1325274beb5f4abf0cf0e1c823b10 100644 (file)
@@ -1652,8 +1652,8 @@ void FullCodeGenerator::VisitNativeFunctionLiteral(
 
   // Copy the function data to the shared function info.
   shared->set_function_data(fun->shared()->function_data());
-  int parameters = fun->shared()->internal_formal_parameter_count();
-  shared->set_internal_formal_parameter_count(parameters);
+  int parameters = fun->shared()->formal_parameter_count();
+  shared->set_formal_parameter_count(parameters);
 
   EmitNewClosure(shared, false);
 }
index bb9a417867e927a9c247b33eefc520ddb9655979..740ccf8431e306c66c0f8aefffa00740d1c00e19 100644 (file)
@@ -527,11 +527,9 @@ enum CallFunctionFlags {
 
 
 enum CallConstructorFlags {
-  NO_CALL_CONSTRUCTOR_FLAGS = 0,
+  NO_CALL_CONSTRUCTOR_FLAGS,
   // The call target is cached in the instruction stream.
-  RECORD_CONSTRUCTOR_TARGET = 1,
-  SUPER_CONSTRUCTOR_CALL = 1 << 1,
-  SUPER_CALL_RECORD_TARGET = SUPER_CONSTRUCTOR_CALL | RECORD_CONSTRUCTOR_TARGET
+  RECORD_CONSTRUCTOR_TARGET
 };
 
 
index 6237fc94d7d4e89a7bc1e50f0f7f6642401305cd..1c54fa5ba6464f7cc052bf5ee356ebb565635e8e 100644 (file)
@@ -2393,10 +2393,8 @@ class HInvokeFunction FINAL : public HBinaryCall {
                   int argument_count)
       : HBinaryCall(context, function, argument_count),
         known_function_(known_function) {
-    formal_parameter_count_ =
-        known_function.is_null()
-            ? 0
-            : known_function->shared()->internal_formal_parameter_count();
+    formal_parameter_count_ = known_function.is_null()
+        ? 0 : known_function->shared()->formal_parameter_count();
     has_stack_check_ = !known_function.is_null() &&
         (known_function->code()->kind() == Code::FUNCTION ||
          known_function->code()->kind() == Code::OPTIMIZED_FUNCTION);
index 7d154642ceeef58a093bc4724a99a07d24f5ef28..d7619e411fc146cd1d443f26d94f3f331acb8c34 100644 (file)
@@ -4281,11 +4281,6 @@ void HOptimizedGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs,
 
 
 bool HOptimizedGraphBuilder::BuildGraph() {
-  if (IsSubclassConstructor(current_info()->function()->kind())) {
-    Bailout(kSuperReference);
-    return false;
-  }
-
   Scope* scope = current_info()->scope();
   SetUpScope(scope);
 
@@ -7570,8 +7565,7 @@ HInstruction* HOptimizedGraphBuilder::BuildCallConstantFunction(
   HValue* target = Add<HConstant>(jsfun);
   // For constant functions, we try to avoid calling the
   // argument adaptor and instead call the function directly
-  int formal_parameter_count =
-      jsfun->shared()->internal_formal_parameter_count();
+  int formal_parameter_count = jsfun->shared()->formal_parameter_count();
   bool dont_adapt_arguments =
       (formal_parameter_count ==
        SharedFunctionInfo::kDontAdaptArgumentsSentinel);
index b9a27c37b7d293982c2dda0c3e7964185fd338ed..18966c293f238569eeac345b75ec2d5a7c093bf4 100644 (file)
@@ -519,9 +519,6 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
     __ push(eax);
     __ SmiUntag(eax);
 
-    // Push new.target.
-    __ push(edx);
-
     // receiver is the hole.
     __ push(Immediate(masm->isolate()->factory()->the_hole_value()));
 
@@ -538,7 +535,6 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
     __ dec(ecx);
     __ j(greater_equal, &loop);
 
-    __ inc(eax);  // Pushed new.target.
     ParameterCount actual(eax);
     __ InvokeFunction(edi, actual, CALL_FUNCTION, NullCallWrapper());
 
index d42c0e4416e426407a60c866dedfb68d974f53c2..819a30587a791c03a80983815f44965d8584f0ad 100644 (file)
@@ -738,7 +738,6 @@ void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
 
 
 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
-  CHECK(!has_new_target());
   // The key is in edx and the parameter count is in eax.
   DCHECK(edx.is(ArgumentsAccessReadDescriptor::index()));
   DCHECK(eax.is(ArgumentsAccessReadDescriptor::parameter_count()));
@@ -805,8 +804,6 @@ void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) {
   // esp[8] : receiver displacement
   // esp[12] : function
 
-  CHECK(!has_new_target());
-
   // Check if the calling frame is an arguments adaptor frame.
   Label runtime;
   __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
@@ -835,8 +832,6 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
   // ebx = parameter count (tagged)
   __ mov(ebx, Operand(esp, 1 * kPointerSize));
 
-  CHECK(!has_new_target());
-
   // Check if the calling frame is an arguments adaptor frame.
   // TODO(rossberg): Factor out some of the bits that are shared with the other
   // Generate* functions.
@@ -1076,15 +1071,9 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
   // Patch the arguments.length and the parameters pointer.
   __ bind(&adaptor_frame);
   __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
-
-  if (has_new_target()) {
-    // Subtract 1 from smi-tagged arguments count.
-    __ sub(ecx, Immediate(2));
-  }
-
+  __ mov(Operand(esp, 1 * kPointerSize), ecx);
   __ lea(edx, Operand(edx, ecx, times_2,
                       StandardFrameConstants::kCallerSPOffset));
-  __ mov(Operand(esp, 1 * kPointerSize), ecx);
   __ mov(Operand(esp, 2 * kPointerSize), edx);
 
   // Try the new space allocation. Start out with computing the size of
@@ -2160,12 +2149,8 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
     __ AssertUndefinedOrAllocationSite(ebx);
   }
 
-  if (IsSuperConstructorCall()) {
-    __ mov(edx, Operand(esp, eax, times_pointer_size, 2 * kPointerSize));
-  } else {
-    // Pass original constructor to construct stub.
-    __ mov(edx, edi);
-  }
+  // Pass original constructor to construct stub.
+  __ mov(edx, edi);
 
   // Jump to the function-specific construct stub.
   Register jmp_reg = ecx;
index 27e308d2989c16d3e1205c16db23370fc60212f4..4c1475b9d25c17f82698a027effc88fd059c39bd 100644 (file)
@@ -212,8 +212,7 @@ void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) {
 
 
 bool Deoptimizer::HasAlignmentPadding(JSFunction* function) {
-  int parameter_count =
-      function->shared()->internal_formal_parameter_count() + 1;
+  int parameter_count = function->shared()->formal_parameter_count() + 1;
   unsigned input_frame_size = input_->GetFrameSize();
   unsigned alignment_state_offset =
       input_frame_size - parameter_count * kPointerSize -
index ca51dc32e64b52ded204a2028971eddf71550955..950a129499126f0e6f42d58afe7d08ee8571114f 100644 (file)
@@ -264,11 +264,7 @@ void FullCodeGenerator::Generate() {
     } else {
       type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
     }
-    ArgumentsAccessStub::HasNewTarget has_new_target =
-        IsSubclassConstructor(info->function()->kind())
-            ? ArgumentsAccessStub::HAS_NEW_TARGET
-            : ArgumentsAccessStub::NO_NEW_TARGET;
-    ArgumentsAccessStub stub(isolate(), type, has_new_target);
+    ArgumentsAccessStub stub(isolate(), type);
     __ CallStub(&stub);
 
     SetVar(arguments, eax, ebx, edx);
@@ -417,12 +413,7 @@ void FullCodeGenerator::EmitReturnSequence() {
     int no_frame_start = masm_->pc_offset();
     __ pop(ebp);
 
-    int arg_count = info_->scope()->num_parameters() + 1;
-    if (FLAG_experimental_classes &&
-        IsSubclassConstructor(info_->function()->kind())) {
-      arg_count++;
-    }
-    int arguments_bytes = arg_count * kPointerSize;
+    int arguments_bytes = (info_->scope()->num_parameters() + 1) * kPointerSize;
     __ Ret(arguments_bytes, ecx);
     // Check that the size of the code used for returning is large enough
     // for the debugger's requirements.
@@ -3146,10 +3137,6 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
 
 
 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
-  Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
-  GetVar(eax, new_target_var);
-  __ push(eax);
-
   SuperReference* super_ref = expr->expression()->AsSuperReference();
   EmitLoadSuperConstructor(super_ref);
   __ push(result_register());
@@ -3191,11 +3178,10 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
   __ LoadHeapObject(ebx, FeedbackVector());
   __ mov(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot())));
 
-  CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET);
+  // TODO(dslomov): use a different stub and propagate new.target.
+  CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
   __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
 
-  __ Drop(1);
-
   RecordJSReturnSite(expr);
 
   EmitVariableAssignment(this_var, Token::INIT_CONST);
index 5a25d26bba2176e4ced53b6eeafb5b86e81abe44..e8b2dbf9c98796d02a0e768466c4ab643d68d3dd 100644 (file)
@@ -1237,8 +1237,7 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
           return compiler.CompileLoadCallback(lookup->name(), call_optimization,
                                               lookup->GetAccessorIndex());
         }
-        int expected_arguments =
-            function->shared()->internal_formal_parameter_count();
+        int expected_arguments = function->shared()->formal_parameter_count();
         return compiler.CompileLoadViaGetter(
             lookup->name(), lookup->GetAccessorIndex(), expected_arguments);
       }
@@ -1744,8 +1743,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
                                                call_optimization,
                                                lookup->GetAccessorIndex());
         }
-        int expected_arguments =
-            function->shared()->internal_formal_parameter_count();
+        int expected_arguments = function->shared()->formal_parameter_count();
         return compiler.CompileStoreViaSetter(receiver, lookup->name(),
                                               lookup->GetAccessorIndex(),
                                               expected_arguments);
index bc530bc658eedcd62d917d61c4dde60d8413fe32..65e789f0328dd826f8db53a07b4672f623b84571 100644 (file)
@@ -5718,7 +5718,7 @@ BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, deserialized, kDeserialized)
 
 #if V8_HOST_ARCH_32_BIT
 SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
-SMI_ACCESSORS(SharedFunctionInfo, internal_formal_parameter_count,
+SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
               kFormalParameterCountOffset)
 SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
               kExpectedNofPropertiesOffset)
@@ -5766,7 +5766,8 @@ SMI_ACCESSORS(SharedFunctionInfo, profiler_ticks, kProfilerTicksOffset)
 
 
 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
-PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, internal_formal_parameter_count,
+PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
+                        formal_parameter_count,
                         kFormalParameterCountOffset)
 
 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
@@ -5898,7 +5899,7 @@ bool Script::HasValidSource() {
 
 void SharedFunctionInfo::DontAdaptArguments() {
   DCHECK(code()->kind() == Code::BUILTIN);
-  set_internal_formal_parameter_count(kDontAdaptArgumentsSentinel);
+  set_formal_parameter_count(kDontAdaptArgumentsSentinel);
 }
 
 
@@ -6079,8 +6080,8 @@ bool JSFunction::IsFromExtensionScript() {
 
 
 bool JSFunction::NeedsArgumentsAdaption() {
-  return shared()->internal_formal_parameter_count() !=
-         SharedFunctionInfo::kDontAdaptArgumentsSentinel;
+  return shared()->formal_parameter_count() !=
+      SharedFunctionInfo::kDontAdaptArgumentsSentinel;
 }
 
 
index 3265a981dd80bda320a3c8f8e2758bb1d1f35999..ef8416ae4382dc27e20774b04232e8f2af4ce28d 100644 (file)
@@ -6770,11 +6770,9 @@ class SharedFunctionInfo: public HeapObject {
   inline int length() const;
   inline void set_length(int value);
 
-  // [internal formal parameter count]: The declared number of parameters.
-  // For subclass constructors, also includes new.target.
-  // The size of function's frame is internal_formal_parameter_count + 1.
-  inline int internal_formal_parameter_count() const;
-  inline void set_internal_formal_parameter_count(int value);
+  // [formal parameter count]: The declared number of parameters.
+  inline int formal_parameter_count() const;
+  inline void set_formal_parameter_count(int value);
 
   // Set the formal parameter count so the function code will be
   // called without using argument adaptor frames.
index 077c3d5abee68d05655f5f87a7d053d1864633a1..ffd121e612ef4d3dd6572ce7dff205cf02139153 100644 (file)
@@ -117,7 +117,7 @@ RUNTIME_FUNCTION(Runtime_DefineClass) {
   constructor->shared()->set_name(*name_string);
 
   if (FLAG_experimental_classes) {
-    if (!super_class->IsTheHole()) {
+    if (!super_class->IsTheHole() && !super_class->IsNull()) {
       Handle<Code> stub(isolate->builtins()->JSConstructStubForDerived());
       constructor->shared()->set_construct_stub(*stub);
     }
index 18fe57738dc3276291248bd0da8c4672f5c74109..0a9cd6313f53fc505f5c671cb9219649d289006f 100644 (file)
@@ -271,8 +271,8 @@ RUNTIME_FUNCTION(Runtime_SetCode) {
   target_shared->set_scope_info(source_shared->scope_info());
   target_shared->set_length(source_shared->length());
   target_shared->set_feedback_vector(source_shared->feedback_vector());
-  target_shared->set_internal_formal_parameter_count(
-      source_shared->internal_formal_parameter_count());
+  target_shared->set_formal_parameter_count(
+      source_shared->formal_parameter_count());
   target_shared->set_script(source_shared->script());
   target_shared->set_start_position_and_type(
       source_shared->start_position_and_type());
@@ -383,7 +383,7 @@ static SmartArrayPointer<Handle<Object> > GetCallerArguments(Isolate* isolate,
     JSFunction* inlined_function = functions[inlined_jsframe_index];
     SlotRefValueBuilder slot_refs(
         frame, inlined_jsframe_index,
-        inlined_function->shared()->internal_formal_parameter_count());
+        inlined_function->shared()->formal_parameter_count());
 
     int args_count = slot_refs.args_length();
 
index 844c633bdb82d6438ac4a830be021251007b814c..bde3021df16653280c3576aa15552c39764d6bda 100644 (file)
@@ -1245,6 +1245,10 @@ static Object* Runtime_NewObjectHelper(Isolate* isolate,
                                        Handle<Object> constructor,
                                        Handle<Object> original_constructor,
                                        Handle<AllocationSite> site) {
+  // TODO(dslomov): implement prototype rewiring.
+  // The check below is a sanity check.
+  CHECK(*constructor == *original_constructor);
+
   // If the constructor isn't a proper function we throw a type error.
   if (!constructor->IsJSFunction()) {
     Vector<Handle<Object> > arguments = HandleVector(&constructor, 1);
@@ -1254,11 +1258,6 @@ static Object* Runtime_NewObjectHelper(Isolate* isolate,
 
   Handle<JSFunction> function = Handle<JSFunction>::cast(constructor);
 
-  CHECK(original_constructor->IsJSFunction());
-  Handle<JSFunction> original_function =
-      Handle<JSFunction>::cast(original_constructor);
-
-
   // If function should not have prototype, construction is not allowed. In this
   // case generated code bailouts here, since function has no initial_map.
   if (!function->should_have_prototype() && !function->shared()->bound()) {
@@ -1301,18 +1300,6 @@ static Object* Runtime_NewObjectHelper(Isolate* isolate,
     result = isolate->factory()->NewJSObjectWithMemento(function, site);
   }
 
-  // Set up the prototoype using original function.
-  // TODO(dslomov): instead of setting the __proto__,
-  // use and cache the correct map.
-  if (*original_function != *function) {
-    if (original_function->has_instance_prototype()) {
-      Handle<Object> prototype =
-          handle(original_function->instance_prototype(), isolate);
-      RETURN_FAILURE_ON_EXCEPTION(
-          isolate, JSObject::SetPrototype(result, prototype, false));
-    }
-  }
-
   isolate->counters()->constructed_objects()->Increment();
   isolate->counters()->constructed_objects_runtime()->Increment();
 
index b1c0fe33d95bba15b70810b8b9e7ab13b068555b..e3a0d52d569e13de5daf97473155c0cc7aef630e 100644 (file)
@@ -356,12 +356,11 @@ static Handle<JSObject> NewSloppyArguments(Isolate* isolate,
                                            Handle<JSFunction> callee,
                                            Object** parameters,
                                            int argument_count) {
-  CHECK(!IsSubclassConstructor(callee->shared()->kind()));
   Handle<JSObject> result =
       isolate->factory()->NewArgumentsObject(callee, argument_count);
 
   // Allocate the elements if needed.
-  int parameter_count = callee->shared()->internal_formal_parameter_count();
+  int parameter_count = callee->shared()->formal_parameter_count();
   if (argument_count > 0) {
     if (parameter_count > 0) {
       int mapped_count = Min(argument_count, parameter_count);
index 16d2c111b9a86b179562839e61a32dee928824aa..fa95bde2b2ff0f6062427003850bf94d2af5db8b 100644 (file)
@@ -148,7 +148,6 @@ void Scope::SetDefaults(ScopeType scope_type,
   scope_name_ = ast_value_factory_->empty_string();
   dynamics_ = NULL;
   receiver_ = NULL;
-  new_target_ = nullptr;
   function_ = NULL;
   arguments_ = NULL;
   illegal_redecl_ = NULL;
@@ -288,7 +287,7 @@ bool Scope::Analyze(CompilationInfo* info) {
 }
 
 
-void Scope::Initialize(bool subclass_constructor) {
+void Scope::Initialize(bool uninitialized_this) {
   DCHECK(!already_resolved());
 
   // Add this scope as a new inner scope of the outer scope.
@@ -308,22 +307,14 @@ void Scope::Initialize(bool subclass_constructor) {
   // such parameter is 'this' which is passed on the stack when
   // invoking scripts
   if (is_declaration_scope()) {
-    DCHECK(!subclass_constructor || is_function_scope());
-    DCHECK(FLAG_experimental_classes || !subclass_constructor);
+    DCHECK(!uninitialized_this || is_function_scope());
+    DCHECK(FLAG_experimental_classes || !uninitialized_this);
     Variable* var = variables_.Declare(
         this, ast_value_factory_->this_string(),
-        subclass_constructor ? CONST : VAR, false, Variable::THIS,
-        subclass_constructor ? kNeedsInitialization : kCreatedInitialized);
+        uninitialized_this ? CONST : VAR, false, Variable::THIS,
+        uninitialized_this ? kNeedsInitialization : kCreatedInitialized);
     var->AllocateTo(Variable::PARAMETER, -1);
     receiver_ = var;
-
-    if (subclass_constructor) {
-      new_target_ = variables_.Declare(
-          this, ast_value_factory_->new_target_string(), CONST, false,
-          Variable::NEW_TARGET, kCreatedInitialized);
-      new_target_->AllocateTo(Variable::PARAMETER, -2);
-      new_target_->set_is_used();
-    }
   } else {
     DCHECK(outer_scope() != NULL);
     receiver_ = outer_scope()->receiver();
@@ -1210,10 +1201,15 @@ bool Scope::MustAllocate(Variable* var) {
   // Give var a read/write use if there is a chance it might be accessed
   // via an eval() call.  This is only possible if the variable has a
   // visible name.
-  if ((var->is_this() || var->is_new_target() || !var->raw_name()->IsEmpty()) &&
-      (var->has_forced_context_allocation() || scope_calls_eval_ ||
-       inner_scope_calls_eval_ || scope_contains_with_ || is_catch_scope() ||
-       is_block_scope() || is_module_scope() || is_script_scope())) {
+  if ((var->is_this() || !var->raw_name()->IsEmpty()) &&
+      (var->has_forced_context_allocation() ||
+       scope_calls_eval_ ||
+       inner_scope_calls_eval_ ||
+       scope_contains_with_ ||
+       is_catch_scope() ||
+       is_block_scope() ||
+       is_module_scope() ||
+       is_script_scope())) {
     var->set_is_used();
     if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned();
   }
index 2cc8b3e9569bf80bc11d49dfdda733d134ef7f73..cd4658d37bca7ae3fbf7ac007323c90217074ed8 100644 (file)
@@ -88,7 +88,7 @@ class Scope: public ZoneObject {
     scope_name_ = scope_name;
   }
 
-  void Initialize(bool subclass_constructor = false);
+  void Initialize(bool uninitialized_this = false);
 
   // Checks if the block scope is redundant, i.e. it does not contain any
   // block scoped declarations. In that case it is removed from the scope
@@ -343,12 +343,9 @@ class Scope: public ZoneObject {
   // The language mode of this scope.
   LanguageMode language_mode() const { return language_mode_; }
 
-  // The variable corresponding to the 'this' value.
+  // The variable corresponding the 'this' value.
   Variable* receiver() { return receiver_; }
 
-  // The variable corresponding to the 'new.target' value.
-  Variable* new_target_var() { return new_target_; }
-
   // The variable holding the function literal for named function
   // literals, or NULL.  Only valid for function scopes.
   VariableDeclaration* function() const {
@@ -520,8 +517,6 @@ class Scope: public ZoneObject {
   Variable* receiver_;
   // Function variable, if any; function scopes only.
   VariableDeclaration* function_;
-  // new.target variable, function scopes only.
-  Variable* new_target_;
   // Convenience variable; function scopes only.
   Variable* arguments_;
   // Interface; module scopes only.
index e35ae7d1cc377f823cf57837574c00b1cf14f953..93bfb4a1816aeb3fb9f370c847ace86da6f2d6b3 100644 (file)
@@ -19,7 +19,11 @@ namespace internal {
 
 class Variable: public ZoneObject {
  public:
-  enum Kind { NORMAL, THIS, NEW_TARGET, ARGUMENTS };
+  enum Kind {
+    NORMAL,
+    THIS,
+    ARGUMENTS
+  };
 
   enum Location {
     // Before and during variable allocation, a variable whose location is
@@ -101,7 +105,6 @@ class Variable: public ZoneObject {
   }
 
   bool is_this() const { return kind_ == THIS; }
-  bool is_new_target() const { return kind_ == NEW_TARGET; }
   bool is_arguments() const { return kind_ == ARGUMENTS; }
 
   // True if the variable is named eval and not known to be shadowed.
index ca23b369234953fca11edbe9658e53f78f539969..80a41dde16c6d06b570347c9d2772fb1795db1b3 100644 (file)
@@ -516,9 +516,6 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
     __ Push(rax);
     __ SmiToInteger32(rax, rax);
 
-    // Push new.target
-    __ Push(rdx);
-
     // receiver is the hole.
     __ Push(masm->isolate()->factory()->the_hole_value());
 
@@ -536,7 +533,6 @@ void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
     __ j(greater_equal, &loop);
 
     // Call the function.
-    __ incp(rax);  // Pushed new.target.
     ParameterCount actual(rax);
     __ InvokeFunction(rdi, actual, CALL_FUNCTION, NullCallWrapper());
 
index 80ecc7e131bfbc11d3ba21d471b30e1d25cbf9a0..abb3d4a988e58c1cb7ab7e6b16deaaa4892b8007 100644 (file)
@@ -539,7 +539,6 @@ void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
 
 
 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
-  CHECK(!has_new_target());
   // The key is in rdx and the parameter count is in rax.
   DCHECK(rdx.is(ArgumentsAccessReadDescriptor::index()));
   DCHECK(rax.is(ArgumentsAccessReadDescriptor::parameter_count()));
@@ -607,8 +606,6 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
   //  rbx: the mapped parameter count (untagged)
   //  rax: the allocated object (tagged).
 
-  CHECK(!has_new_target());
-
   Factory* factory = isolate()->factory();
 
   StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER);
@@ -822,7 +819,6 @@ void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) {
   // rsp[8]  : number of parameters
   // rsp[16] : receiver displacement
   // rsp[24] : function
-  CHECK(!has_new_target());
 
   // Check if the calling frame is an arguments adaptor frame.
   Label runtime;
@@ -932,11 +928,6 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
   // Patch the arguments.length and the parameters pointer.
   __ bind(&adaptor_frame);
   __ movp(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset));
-
-  if (has_new_target()) {
-    // Subtract 1 from smi-tagged arguments count.
-    __ subp(rcx, Immediate(2));
-  }
   __ movp(args.GetArgumentOperand(2), rcx);
   __ SmiToInteger64(rcx, rcx);
   __ leap(rdx, Operand(rdx, rcx, times_pointer_size,
@@ -2027,11 +2018,7 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
   }
 
   // Pass original constructor to construct stub.
-  if (IsSuperConstructorCall()) {
-    __ movp(rdx, Operand(rsp, rax, times_pointer_size, 2 * kPointerSize));
-  } else {
-    __ movp(rdx, rdi);
-  }
+  __ movp(rdx, rdi);
 
   // Jump to the function-specific construct stub.
   Register jmp_reg = rcx;
index 63357e95f591de24f907152f0853e67dd8087cf9..65e60fb855368667302c9cab27e7dce5c1a3bca7 100644 (file)
@@ -254,11 +254,6 @@ void FullCodeGenerator::Generate() {
     //   function, receiver address, parameter count.
     // The stub will rewrite receiver and parameter count if the previous
     // stack frame was an arguments adapter frame.
-
-    ArgumentsAccessStub::HasNewTarget has_new_target =
-        IsSubclassConstructor(info->function()->kind())
-            ? ArgumentsAccessStub::HAS_NEW_TARGET
-            : ArgumentsAccessStub::NO_NEW_TARGET;
     ArgumentsAccessStub::Type type;
     if (is_strict(language_mode())) {
       type = ArgumentsAccessStub::NEW_STRICT;
@@ -267,7 +262,7 @@ void FullCodeGenerator::Generate() {
     } else {
       type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
     }
-    ArgumentsAccessStub stub(isolate(), type, has_new_target);
+    ArgumentsAccessStub stub(isolate(), type);
     __ CallStub(&stub);
 
     SetVar(arguments, rax, rbx, rdx);
@@ -421,12 +416,7 @@ void FullCodeGenerator::EmitReturnSequence() {
     __ popq(rbp);
     int no_frame_start = masm_->pc_offset();
 
-    int arg_count = info_->scope()->num_parameters() + 1;
-    if (FLAG_experimental_classes &&
-        IsSubclassConstructor(info_->function()->kind())) {
-      arg_count++;
-    }
-    int arguments_bytes = arg_count * kPointerSize;
+    int arguments_bytes = (info_->scope()->num_parameters() + 1) * kPointerSize;
     __ Ret(arguments_bytes, rcx);
 
     // Add padding that will be overwritten by a debugger breakpoint.  We
@@ -3152,10 +3142,6 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
 
 
 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
-  Variable* new_target_var = scope()->DeclarationScope()->new_target_var();
-  GetVar(result_register(), new_target_var);
-  __ Push(result_register());
-
   SuperReference* super_ref = expr->expression()->AsSuperReference();
   EmitLoadSuperConstructor(super_ref);
   __ Push(result_register());
@@ -3200,14 +3186,11 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
   __ Move(rdx, SmiFromSlot(expr->CallFeedbackSlot()));
 
   // TODO(dslomov): use a different stub and propagate new.target.
-  CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET);
+  CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
   __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
 
-  __ Drop(1);
-
   RecordJSReturnSite(expr);
 
-
   EmitVariableAssignment(this_var, Token::INIT_CONST);
   context()->Plug(rax);
 }
index 36c4dd82465130b767c460bf67fcae9f2077eabc..ed720d97b6275462e397d3f55e81746a450839f1 100644 (file)
 // Flags: --experimental-classes --harmony-classes
 
 'use strict';
-(function TestArgumentsAccess() {
-  class Base {
-    constructor() {
-      assertEquals(2, arguments.length);
-      assertEquals(1, arguments[0]);
-      assertEquals(2, arguments[1]);
-    }
-  }
-
-  let b = new Base(1,2);
-
-  class Subclass extends Base {
-    constructor() {
-      assertEquals(2, arguments.length);
-      assertEquals(3, arguments[0]);
-      assertEquals(4, arguments[1]);
-      super(1,2);
-    }
-  }
-
-  let s = new Subclass(3,4);
-  assertEquals(0, Subclass.length);
-
-  class Subclass2 extends Base {
-    constructor(x,y) {
-      assertEquals(2, arguments.length);
-      assertEquals(3, arguments[0]);
-      assertEquals(4, arguments[1]);
-      super(1,2);
-    }
-  }
-
-  let s2 = new Subclass2(3,4);
-  assertEquals(2, Subclass2.length);
-}());
-
-(function TestThisAccessRestriction() {
-  class Base {
-    constructor(a, b) {
-      let o = new Object();
-      o.prp = a + b;
-      return o;
-    }
-  }
-
-  class Subclass extends Base {
-    constructor(a, b) {
-      var exn;
-      try {
-        this.prp1 = 3;
-      } catch (e) {
-        exn = e;
-      }
-      assertTrue(exn instanceof ReferenceError);
-      super(a, b);
-      assertSame(a + b, this.prp);
-      assertSame(undefined, this.prp1);
-      assertFalse(this.hasOwnProperty("prp1"));
-      return this;
-    }
-  }
-
-  let b = new Base(1, 2);
-  assertSame(3, b.prp);
-
-
-  let s = new Subclass(2, -1);
-  assertSame(1, s.prp);
-  assertSame(undefined, s.prp1);
-  assertFalse(s.hasOwnProperty("prp1"));
-
-  class Subclass2 extends Base {
-    constructor(x) {
-      super(1,2);
-
-      if (x < 0) return;
-
-      let called = false;
-      function tmp() { called = true; return 3; }
-      var exn = null;
-      try {
-        super(tmp(),4);
-      } catch (e) { exn = e; }
-      assertTrue(exn instanceof ReferenceError);
-      // TODO(dslomov): should be 'true'.
-      assertFalse(called);
-    }
-  }
-
-  var s2 = new Subclass2(1);
-  assertSame(3, s2.prp);
 
-  var s3 = new Subclass2(-1);
-  assertSame(3, s3.prp);
-
-  assertThrows(function() { Subclass.call(new Object(), 1, 2); }, TypeError);
-  assertThrows(function() { Base.call(new Object(), 1, 2); }, TypeError);
-
-  class BadSubclass extends Base {
-    constructor() {}
-  }
-
-  assertThrows(function() { new BadSubclass(); }, ReferenceError);
-}());
-
-(function TestPrototypeWiring() {
-  class Base {
-    constructor(x) {
-      this.foobar = x;
-    }
-  }
-
-  class Subclass extends Base {
-    constructor(x) {
-      super(x);
-    }
-  }
-
-  let s = new Subclass(1);
-  assertSame(1, s.foobar);
-  assertSame(Subclass.prototype, s.__proto__);
-
-  let s1 = new Subclass(1, 2);
-  assertSame(1, s1.foobar);
-  assertTrue(s1.__proto__ === Subclass.prototype);
-
-  let s2 = new Subclass();
-  assertSame(undefined, s2.foobar);
-  assertSame(Subclass.prototype, s2.__proto__);
-  assertThrows(function() { Subclass(1); }, TypeError);
-  assertThrows(function() { Subclass(1,2,3,4); }, TypeError);
-
-  class Subclass2 extends Subclass {
-    constructor() {
-      super(5, 6, 7);
-    }
+class Base {
+  constructor(a, b) {
+    let o = new Object();
+    o.prp = a + b;
+    return o;
   }
-
-  let ss2 = new Subclass2();
-  assertSame(5, ss2.foobar);
-  assertSame(Subclass2.prototype, ss2.__proto__);
-
-  class Subclass3 extends Base {
-    constructor(x,y) {
-      super(x + y);
+}
+
+class Subclass extends Base {
+  constructor(a, b) {
+    var exn;
+    try {
+      this.prp1 = 3;
+    } catch (e) {
+      exn = e;
     }
+    assertTrue(exn instanceof ReferenceError);
+    super(a, b);
+    assertSame(a + b, this.prp);
+    assertSame(undefined, this.prp1);
+    assertFalse(this.hasOwnProperty("prp1"));
+    return this;
   }
+}
 
-  let ss3 = new Subclass3(27,42-27);
-  assertSame(42, ss3.foobar);
-  assertSame(Subclass3.prototype, ss3.__proto__);
-}());
+let b = new Base(1, 2);
+assertSame(3, b.prp);
 
-(function TestSublclassingBuiltins() {
-  class ExtendedUint8Array extends Uint8Array {
-    constructor() {
-      super(10);
-      this[0] = 255;
-      this[1] = 0xFFA;
-    }
-  }
 
-  var eua = new ExtendedUint8Array();
-  assertEquals(10, eua.length);
-  assertEquals(10, eua.byteLength);
-  assertEquals(0xFF, eua[0]);
-  assertEquals(0xFA, eua[1]);
-  assertTrue(eua.__proto__ === ExtendedUint8Array.prototype);
-  assertEquals("[object Uint8Array]", Object.prototype.toString.call(eua));
-}());
+let s = new Subclass(2, -1);
+assertSame(1, s.prp);
+assertSame(undefined, s.prp1);
+assertFalse(s.hasOwnProperty("prp1"));
 
-(function TestSubclassingNull() {
-  let N = null;
+class Subclass2 extends Base {
+  constructor(x) {
+    super(1,2);
 
-  class Foo extends N {
-    constructor(x,y) {
-      assertSame(1, x);
-      assertSame(2, y);
-      return {};
-    }
-  }
-
-  new Foo(1,2);
-}());
-
-(function TestSubclassBinding() {
-  class Base {
-    constructor(x, y) {
-      this.x = x;
-      this.y = y;
-    }
-  }
+    if (x < 0) return;
 
-  let obj = {};
-  class Subclass extends Base {
-    constructor(x,y) {
-      super(x,y);
-      assertTrue(this !== obj);
-    }
+    let called = false;
+    function tmp() { called = true; return 3; }
+    var exn = null;
+    try {
+      super(tmp(),4);
+    } catch(e) { exn = e; }
+    assertTrue(exn !== null);
+    assertFalse(called);
   }
+}
 
-  let f = Subclass.bind(obj);
-  assertThrows(function () { f(1, 2); }, TypeError);
-  let s = new f(1, 2);
-  assertSame(1, s.x);
-  assertSame(2, s.y);
-  assertSame(Subclass.prototype, s.__proto__);
+var s2 = new Subclass2(1);
+assertSame(3, s2.prp);
 
-  let s1 = new f(1);
-  assertSame(1, s1.x);
-  assertSame(undefined, s1.y);
-  assertSame(Subclass.prototype, s1.__proto__);
+var s3 = new Subclass2(-1);
+assertSame(3, s3.prp);
 
-  let g = Subclass.bind(obj, 1);
-  assertThrows(function () { g(8); }, TypeError);
-  let s2 = new g(8);
-  assertSame(1, s2.x);
-  assertSame(8, s2.y);
-  assertSame(Subclass.prototype, s.__proto__);
-}());
+assertThrows(function() { Subclass.call(new Object(), 1, 2); }, TypeError);
+assertThrows(function() { Base.call(new Object(), 1, 2); }, TypeError);