OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X87 | 7 #if V8_TARGET_ARCH_X87 |
8 | 8 |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 // derived constructors with super calls. | 235 // derived constructors with super calls. |
236 Variable* this_function_var = scope()->this_function_var(); | 236 Variable* this_function_var = scope()->this_function_var(); |
237 if (this_function_var != nullptr) { | 237 if (this_function_var != nullptr) { |
238 Comment cmnt(masm_, "[ This function"); | 238 Comment cmnt(masm_, "[ This function"); |
239 SetVar(this_function_var, edi, ebx, edx); | 239 SetVar(this_function_var, edi, ebx, edx); |
240 } | 240 } |
241 | 241 |
242 Variable* new_target_var = scope()->new_target_var(); | 242 Variable* new_target_var = scope()->new_target_var(); |
243 if (new_target_var != nullptr) { | 243 if (new_target_var != nullptr) { |
244 Comment cmnt(masm_, "[ new.target"); | 244 Comment cmnt(masm_, "[ new.target"); |
245 // new.target is parameter -2. | 245 __ mov(eax, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
246 int offset = 2 * kPointerSize + kFPOnStackSize + kPCOnStackSize + | 246 Label non_adaptor_frame; |
247 (info_->scope()->num_parameters() - 1) * kPointerSize; | 247 __ cmp(Operand(eax, StandardFrameConstants::kContextOffset), |
248 __ mov(eax, Operand(ebp, offset)); | 248 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 249 __ j(not_equal, &non_adaptor_frame); |
| 250 __ mov(eax, Operand(eax, StandardFrameConstants::kCallerFPOffset)); |
| 251 |
| 252 __ bind(&non_adaptor_frame); |
| 253 __ cmp(Operand(eax, StandardFrameConstants::kMarkerOffset), |
| 254 Immediate(Smi::FromInt(StackFrame::CONSTRUCT))); |
| 255 |
| 256 Label non_construct_frame, done; |
| 257 __ j(not_equal, &non_construct_frame); |
| 258 |
| 259 // Construct frame |
| 260 __ mov(eax, Operand(eax, StandardFrameConstants::kExpressionsOffset - |
| 261 2 * kPointerSize)); |
| 262 __ jmp(&done); |
| 263 |
| 264 // Non-construct frame |
| 265 __ bind(&non_construct_frame); |
| 266 __ mov(eax, Immediate(isolate()->factory()->undefined_value())); |
| 267 |
| 268 __ bind(&done); |
249 SetVar(new_target_var, eax, ebx, edx); | 269 SetVar(new_target_var, eax, ebx, edx); |
250 } | 270 } |
251 | 271 |
252 ArgumentsAccessStub::HasNewTarget has_new_target = | |
253 IsSubclassConstructor(info->function()->kind()) | |
254 ? ArgumentsAccessStub::HAS_NEW_TARGET | |
255 : ArgumentsAccessStub::NO_NEW_TARGET; | |
256 | 272 |
257 // Possibly allocate RestParameters | 273 // Possibly allocate RestParameters |
258 int rest_index; | 274 int rest_index; |
259 Variable* rest_param = scope()->rest_parameter(&rest_index); | 275 Variable* rest_param = scope()->rest_parameter(&rest_index); |
260 if (rest_param) { | 276 if (rest_param) { |
261 Comment cmnt(masm_, "[ Allocate rest parameter array"); | 277 Comment cmnt(masm_, "[ Allocate rest parameter array"); |
262 | 278 |
263 int num_parameters = info->scope()->num_parameters(); | 279 int num_parameters = info->scope()->num_parameters(); |
264 int offset = num_parameters * kPointerSize; | 280 int offset = num_parameters * kPointerSize; |
265 if (has_new_target == ArgumentsAccessStub::HAS_NEW_TARGET) { | |
266 --num_parameters; | |
267 ++rest_index; | |
268 } | |
269 | 281 |
270 __ lea(edx, | 282 __ lea(edx, |
271 Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset)); | 283 Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset)); |
272 __ push(edx); | 284 __ push(edx); |
273 __ push(Immediate(Smi::FromInt(num_parameters))); | 285 __ push(Immediate(Smi::FromInt(num_parameters))); |
274 __ push(Immediate(Smi::FromInt(rest_index))); | 286 __ push(Immediate(Smi::FromInt(rest_index))); |
275 __ push(Immediate(Smi::FromInt(language_mode()))); | 287 __ push(Immediate(Smi::FromInt(language_mode()))); |
276 | 288 |
277 RestParamAccessStub stub(isolate()); | 289 RestParamAccessStub stub(isolate()); |
278 __ CallStub(&stub); | 290 __ CallStub(&stub); |
(...skipping 23 matching lines...) Expand all Loading... |
302 // stack frame was an arguments adapter frame. | 314 // stack frame was an arguments adapter frame. |
303 ArgumentsAccessStub::Type type; | 315 ArgumentsAccessStub::Type type; |
304 if (is_strict(language_mode()) || !is_simple_parameter_list()) { | 316 if (is_strict(language_mode()) || !is_simple_parameter_list()) { |
305 type = ArgumentsAccessStub::NEW_STRICT; | 317 type = ArgumentsAccessStub::NEW_STRICT; |
306 } else if (function()->has_duplicate_parameters()) { | 318 } else if (function()->has_duplicate_parameters()) { |
307 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; | 319 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; |
308 } else { | 320 } else { |
309 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; | 321 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; |
310 } | 322 } |
311 | 323 |
312 ArgumentsAccessStub stub(isolate(), type, has_new_target); | 324 ArgumentsAccessStub stub(isolate(), type); |
313 __ CallStub(&stub); | 325 __ CallStub(&stub); |
314 | 326 |
315 SetVar(arguments, eax, ebx, edx); | 327 SetVar(arguments, eax, ebx, edx); |
316 } | 328 } |
317 | 329 |
318 if (FLAG_trace) { | 330 if (FLAG_trace) { |
319 __ CallRuntime(Runtime::kTraceEnter, 0); | 331 __ CallRuntime(Runtime::kTraceEnter, 0); |
320 } | 332 } |
321 | 333 |
322 // Visit the declarations and body unless there is an illegal | 334 // Visit the declarations and body unless there is an illegal |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 #endif | 464 #endif |
453 SetSourcePosition(function()->end_position() - 1); | 465 SetSourcePosition(function()->end_position() - 1); |
454 __ RecordJSReturn(); | 466 __ RecordJSReturn(); |
455 // Do not use the leave instruction here because it is too short to | 467 // Do not use the leave instruction here because it is too short to |
456 // patch with the code required by the debugger. | 468 // patch with the code required by the debugger. |
457 __ mov(esp, ebp); | 469 __ mov(esp, ebp); |
458 int no_frame_start = masm_->pc_offset(); | 470 int no_frame_start = masm_->pc_offset(); |
459 __ pop(ebp); | 471 __ pop(ebp); |
460 | 472 |
461 int arg_count = info_->scope()->num_parameters() + 1; | 473 int arg_count = info_->scope()->num_parameters() + 1; |
462 if (IsSubclassConstructor(info_->function()->kind())) { | |
463 arg_count++; | |
464 } | |
465 int arguments_bytes = arg_count * kPointerSize; | 474 int arguments_bytes = arg_count * kPointerSize; |
466 __ Ret(arguments_bytes, ecx); | 475 __ Ret(arguments_bytes, ecx); |
467 // Check that the size of the code used for returning is large enough | 476 // Check that the size of the code used for returning is large enough |
468 // for the debugger's requirements. | 477 // for the debugger's requirements. |
469 DCHECK(Assembler::kJSReturnSequenceLength <= | 478 DCHECK(Assembler::kJSReturnSequenceLength <= |
470 masm_->SizeOfCodeGeneratedSince(&check_exit_codesize)); | 479 masm_->SizeOfCodeGeneratedSince(&check_exit_codesize)); |
471 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); | 480 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); |
472 } | 481 } |
473 } | 482 } |
474 | 483 |
(...skipping 2525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3000 // Do the runtime call. | 3009 // Do the runtime call. |
3001 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); | 3010 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); |
3002 } | 3011 } |
3003 | 3012 |
3004 | 3013 |
3005 void FullCodeGenerator::EmitInitializeThisAfterSuper( | 3014 void FullCodeGenerator::EmitInitializeThisAfterSuper( |
3006 SuperCallReference* super_call_ref, FeedbackVectorICSlot slot) { | 3015 SuperCallReference* super_call_ref, FeedbackVectorICSlot slot) { |
3007 Variable* this_var = super_call_ref->this_var()->var(); | 3016 Variable* this_var = super_call_ref->this_var()->var(); |
3008 GetVar(ecx, this_var); | 3017 GetVar(ecx, this_var); |
3009 __ cmp(ecx, isolate()->factory()->the_hole_value()); | 3018 __ cmp(ecx, isolate()->factory()->the_hole_value()); |
| 3019 |
3010 Label uninitialized_this; | 3020 Label uninitialized_this; |
3011 __ j(equal, &uninitialized_this); | 3021 __ j(equal, &uninitialized_this); |
3012 __ push(Immediate(this_var->name())); | 3022 __ push(Immediate(this_var->name())); |
3013 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 3023 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
3014 __ bind(&uninitialized_this); | 3024 __ bind(&uninitialized_this); |
3015 | 3025 |
3016 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); | 3026 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); |
3017 } | 3027 } |
3018 | 3028 |
3019 | 3029 |
(...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4163 // default constructor has no arguments, so no adaptor frame means no args. | 4173 // default constructor has no arguments, so no adaptor frame means no args. |
4164 __ mov(eax, Immediate(0)); | 4174 __ mov(eax, Immediate(0)); |
4165 __ jmp(&args_set_up); | 4175 __ jmp(&args_set_up); |
4166 | 4176 |
4167 // Copy arguments from adaptor frame. | 4177 // Copy arguments from adaptor frame. |
4168 { | 4178 { |
4169 __ bind(&adaptor_frame); | 4179 __ bind(&adaptor_frame); |
4170 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 4180 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
4171 __ SmiUntag(ecx); | 4181 __ SmiUntag(ecx); |
4172 | 4182 |
4173 // Subtract 1 from arguments count, for new.target. | |
4174 __ sub(ecx, Immediate(1)); | |
4175 __ mov(eax, ecx); | 4183 __ mov(eax, ecx); |
4176 __ lea(edx, Operand(edx, ecx, times_pointer_size, | 4184 __ lea(edx, Operand(edx, ecx, times_pointer_size, |
4177 StandardFrameConstants::kCallerSPOffset)); | 4185 StandardFrameConstants::kCallerSPOffset)); |
4178 Label loop; | 4186 Label loop; |
4179 __ bind(&loop); | 4187 __ bind(&loop); |
4180 __ push(Operand(edx, -1 * kPointerSize)); | 4188 __ push(Operand(edx, -1 * kPointerSize)); |
4181 __ sub(edx, Immediate(kPointerSize)); | 4189 __ sub(edx, Immediate(kPointerSize)); |
4182 __ dec(ecx); | 4190 __ dec(ecx); |
4183 __ j(not_zero, &loop); | 4191 __ j(not_zero, &loop); |
4184 } | 4192 } |
(...skipping 1280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5465 Assembler::target_address_at(call_target_address, | 5473 Assembler::target_address_at(call_target_address, |
5466 unoptimized_code)); | 5474 unoptimized_code)); |
5467 return OSR_AFTER_STACK_CHECK; | 5475 return OSR_AFTER_STACK_CHECK; |
5468 } | 5476 } |
5469 | 5477 |
5470 | 5478 |
5471 } // namespace internal | 5479 } // namespace internal |
5472 } // namespace v8 | 5480 } // namespace v8 |
5473 | 5481 |
5474 #endif // V8_TARGET_ARCH_X87 | 5482 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |