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