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_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
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 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 // derived constructors with super calls. | 238 // derived constructors with super calls. |
239 Variable* this_function_var = scope()->this_function_var(); | 239 Variable* this_function_var = scope()->this_function_var(); |
240 if (this_function_var != nullptr) { | 240 if (this_function_var != nullptr) { |
241 Comment cmnt(masm_, "[ This function"); | 241 Comment cmnt(masm_, "[ This function"); |
242 SetVar(this_function_var, edi, ebx, edx); | 242 SetVar(this_function_var, edi, ebx, edx); |
243 } | 243 } |
244 | 244 |
245 Variable* new_target_var = scope()->new_target_var(); | 245 Variable* new_target_var = scope()->new_target_var(); |
246 if (new_target_var != nullptr) { | 246 if (new_target_var != nullptr) { |
247 Comment cmnt(masm_, "[ new.target"); | 247 Comment cmnt(masm_, "[ new.target"); |
248 // new.target is parameter -2. | 248 __ mov(eax, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
249 int offset = 2 * kPointerSize + kFPOnStackSize + kPCOnStackSize + | 249 Label non_adaptor_frame; |
250 (info_->scope()->num_parameters() - 1) * kPointerSize; | 250 __ cmp(Operand(eax, StandardFrameConstants::kContextOffset), |
251 __ mov(eax, Operand(ebp, offset)); | 251 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 252 __ j(not_equal, &non_adaptor_frame); |
| 253 __ mov(eax, Operand(eax, StandardFrameConstants::kCallerFPOffset)); |
| 254 |
| 255 __ bind(&non_adaptor_frame); |
| 256 __ cmp(Operand(eax, StandardFrameConstants::kMarkerOffset), |
| 257 Immediate(Smi::FromInt(StackFrame::CONSTRUCT))); |
| 258 |
| 259 Label non_construct_frame, done; |
| 260 __ j(not_equal, &non_construct_frame); |
| 261 |
| 262 // Construct frame |
| 263 __ mov(eax, Operand(eax, StandardFrameConstants::kExpressionsOffset - |
| 264 2 * kPointerSize)); |
| 265 __ jmp(&done); |
| 266 |
| 267 // Non-construct frame |
| 268 __ bind(&non_construct_frame); |
| 269 __ mov(eax, Immediate(isolate()->factory()->undefined_value())); |
| 270 |
| 271 __ bind(&done); |
252 SetVar(new_target_var, eax, ebx, edx); | 272 SetVar(new_target_var, eax, ebx, edx); |
253 } | 273 } |
254 | 274 |
255 ArgumentsAccessStub::HasNewTarget has_new_target = | |
256 IsSubclassConstructor(info->function()->kind()) | |
257 ? ArgumentsAccessStub::HAS_NEW_TARGET | |
258 : ArgumentsAccessStub::NO_NEW_TARGET; | |
259 | 275 |
260 // Possibly allocate RestParameters | 276 // Possibly allocate RestParameters |
261 int rest_index; | 277 int rest_index; |
262 Variable* rest_param = scope()->rest_parameter(&rest_index); | 278 Variable* rest_param = scope()->rest_parameter(&rest_index); |
263 if (rest_param) { | 279 if (rest_param) { |
264 Comment cmnt(masm_, "[ Allocate rest parameter array"); | 280 Comment cmnt(masm_, "[ Allocate rest parameter array"); |
265 | 281 |
266 int num_parameters = info->scope()->num_parameters(); | 282 int num_parameters = info->scope()->num_parameters(); |
267 int offset = num_parameters * kPointerSize; | 283 int offset = num_parameters * kPointerSize; |
268 if (has_new_target == ArgumentsAccessStub::HAS_NEW_TARGET) { | |
269 --num_parameters; | |
270 ++rest_index; | |
271 } | |
272 | 284 |
273 __ lea(edx, | 285 __ lea(edx, |
274 Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset)); | 286 Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset)); |
275 __ push(edx); | 287 __ push(edx); |
276 __ push(Immediate(Smi::FromInt(num_parameters))); | 288 __ push(Immediate(Smi::FromInt(num_parameters))); |
277 __ push(Immediate(Smi::FromInt(rest_index))); | 289 __ push(Immediate(Smi::FromInt(rest_index))); |
278 __ push(Immediate(Smi::FromInt(language_mode()))); | 290 __ push(Immediate(Smi::FromInt(language_mode()))); |
279 | 291 |
280 RestParamAccessStub stub(isolate()); | 292 RestParamAccessStub stub(isolate()); |
281 __ CallStub(&stub); | 293 __ CallStub(&stub); |
(...skipping 23 matching lines...) Expand all Loading... |
305 // stack frame was an arguments adapter frame. | 317 // stack frame was an arguments adapter frame. |
306 ArgumentsAccessStub::Type type; | 318 ArgumentsAccessStub::Type type; |
307 if (is_strict(language_mode()) || !is_simple_parameter_list()) { | 319 if (is_strict(language_mode()) || !is_simple_parameter_list()) { |
308 type = ArgumentsAccessStub::NEW_STRICT; | 320 type = ArgumentsAccessStub::NEW_STRICT; |
309 } else if (function()->has_duplicate_parameters()) { | 321 } else if (function()->has_duplicate_parameters()) { |
310 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; | 322 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; |
311 } else { | 323 } else { |
312 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; | 324 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; |
313 } | 325 } |
314 | 326 |
315 ArgumentsAccessStub stub(isolate(), type, has_new_target); | 327 ArgumentsAccessStub stub(isolate(), type); |
316 __ CallStub(&stub); | 328 __ CallStub(&stub); |
317 | 329 |
318 SetVar(arguments, eax, ebx, edx); | 330 SetVar(arguments, eax, ebx, edx); |
319 } | 331 } |
320 | 332 |
321 if (FLAG_trace) { | 333 if (FLAG_trace) { |
322 __ CallRuntime(Runtime::kTraceEnter, 0); | 334 __ CallRuntime(Runtime::kTraceEnter, 0); |
323 } | 335 } |
324 | 336 |
325 // Visit the declarations and body unless there is an illegal | 337 // Visit the declarations and body unless there is an illegal |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 #endif | 467 #endif |
456 SetSourcePosition(function()->end_position() - 1); | 468 SetSourcePosition(function()->end_position() - 1); |
457 __ RecordJSReturn(); | 469 __ RecordJSReturn(); |
458 // Do not use the leave instruction here because it is too short to | 470 // Do not use the leave instruction here because it is too short to |
459 // patch with the code required by the debugger. | 471 // patch with the code required by the debugger. |
460 __ mov(esp, ebp); | 472 __ mov(esp, ebp); |
461 int no_frame_start = masm_->pc_offset(); | 473 int no_frame_start = masm_->pc_offset(); |
462 __ pop(ebp); | 474 __ pop(ebp); |
463 | 475 |
464 int arg_count = info_->scope()->num_parameters() + 1; | 476 int arg_count = info_->scope()->num_parameters() + 1; |
465 if (IsSubclassConstructor(info_->function()->kind())) { | |
466 arg_count++; | |
467 } | |
468 int arguments_bytes = arg_count * kPointerSize; | 477 int arguments_bytes = arg_count * kPointerSize; |
469 __ Ret(arguments_bytes, ecx); | 478 __ Ret(arguments_bytes, ecx); |
470 // Check that the size of the code used for returning is large enough | 479 // Check that the size of the code used for returning is large enough |
471 // for the debugger's requirements. | 480 // for the debugger's requirements. |
472 DCHECK(Assembler::kJSReturnSequenceLength <= | 481 DCHECK(Assembler::kJSReturnSequenceLength <= |
473 masm_->SizeOfCodeGeneratedSince(&check_exit_codesize)); | 482 masm_->SizeOfCodeGeneratedSince(&check_exit_codesize)); |
474 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); | 483 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); |
475 } | 484 } |
476 } | 485 } |
477 | 486 |
(...skipping 2531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3009 // Do the runtime call. | 3018 // Do the runtime call. |
3010 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); | 3019 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); |
3011 } | 3020 } |
3012 | 3021 |
3013 | 3022 |
3014 void FullCodeGenerator::EmitInitializeThisAfterSuper( | 3023 void FullCodeGenerator::EmitInitializeThisAfterSuper( |
3015 SuperCallReference* super_call_ref, FeedbackVectorICSlot slot) { | 3024 SuperCallReference* super_call_ref, FeedbackVectorICSlot slot) { |
3016 Variable* this_var = super_call_ref->this_var()->var(); | 3025 Variable* this_var = super_call_ref->this_var()->var(); |
3017 GetVar(ecx, this_var); | 3026 GetVar(ecx, this_var); |
3018 __ cmp(ecx, isolate()->factory()->the_hole_value()); | 3027 __ cmp(ecx, isolate()->factory()->the_hole_value()); |
| 3028 |
3019 Label uninitialized_this; | 3029 Label uninitialized_this; |
3020 __ j(equal, &uninitialized_this); | 3030 __ j(equal, &uninitialized_this); |
3021 __ push(Immediate(this_var->name())); | 3031 __ push(Immediate(this_var->name())); |
3022 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 3032 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
3023 __ bind(&uninitialized_this); | 3033 __ bind(&uninitialized_this); |
3024 | 3034 |
3025 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); | 3035 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); |
3026 } | 3036 } |
3027 | 3037 |
3028 | 3038 |
(...skipping 1144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4173 // default constructor has no arguments, so no adaptor frame means no args. | 4183 // default constructor has no arguments, so no adaptor frame means no args. |
4174 __ mov(eax, Immediate(0)); | 4184 __ mov(eax, Immediate(0)); |
4175 __ jmp(&args_set_up); | 4185 __ jmp(&args_set_up); |
4176 | 4186 |
4177 // Copy arguments from adaptor frame. | 4187 // Copy arguments from adaptor frame. |
4178 { | 4188 { |
4179 __ bind(&adaptor_frame); | 4189 __ bind(&adaptor_frame); |
4180 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 4190 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
4181 __ SmiUntag(ecx); | 4191 __ SmiUntag(ecx); |
4182 | 4192 |
4183 // Subtract 1 from arguments count, for new.target. | |
4184 __ sub(ecx, Immediate(1)); | |
4185 __ mov(eax, ecx); | 4193 __ mov(eax, ecx); |
4186 __ lea(edx, Operand(edx, ecx, times_pointer_size, | 4194 __ lea(edx, Operand(edx, ecx, times_pointer_size, |
4187 StandardFrameConstants::kCallerSPOffset)); | 4195 StandardFrameConstants::kCallerSPOffset)); |
4188 Label loop; | 4196 Label loop; |
4189 __ bind(&loop); | 4197 __ bind(&loop); |
4190 __ push(Operand(edx, -1 * kPointerSize)); | 4198 __ push(Operand(edx, -1 * kPointerSize)); |
4191 __ sub(edx, Immediate(kPointerSize)); | 4199 __ sub(edx, Immediate(kPointerSize)); |
4192 __ dec(ecx); | 4200 __ dec(ecx); |
4193 __ j(not_zero, &loop); | 4201 __ j(not_zero, &loop); |
4194 } | 4202 } |
(...skipping 1280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5475 Assembler::target_address_at(call_target_address, | 5483 Assembler::target_address_at(call_target_address, |
5476 unoptimized_code)); | 5484 unoptimized_code)); |
5477 return OSR_AFTER_STACK_CHECK; | 5485 return OSR_AFTER_STACK_CHECK; |
5478 } | 5486 } |
5479 | 5487 |
5480 | 5488 |
5481 } // namespace internal | 5489 } // namespace internal |
5482 } // namespace v8 | 5490 } // namespace v8 |
5483 | 5491 |
5484 #endif // V8_TARGET_ARCH_IA32 | 5492 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |