OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
7 | 7 |
8 #include "vm/code_generator.h" | 8 #include "vm/code_generator.h" |
9 | 9 |
10 #include "lib/error.h" | 10 #include "lib/error.h" |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 if (function.IsClosureFunction()) { | 416 if (function.IsClosureFunction()) { |
417 GenerateCallRuntime(AstNode::kNoId, | 417 GenerateCallRuntime(AstNode::kNoId, |
418 0, | 418 0, |
419 kClosureArgumentMismatchRuntimeEntry); | 419 kClosureArgumentMismatchRuntimeEntry); |
420 } else { | 420 } else { |
421 __ Stop("Wrong number of arguments"); | 421 __ Stop("Wrong number of arguments"); |
422 } | 422 } |
423 __ Bind(&argc_in_range); | 423 __ Bind(&argc_in_range); |
424 } | 424 } |
425 } else { | 425 } else { |
| 426 int implicit_this_param_pos = is_instance_native_closure ? -1 : 0; |
426 ASSERT(parsed_function_.first_parameter_index() == | 427 ASSERT(parsed_function_.first_parameter_index() == |
427 ParsedFunction::kFirstLocalSlotIndex); | 428 (ParsedFunction::kFirstLocalSlotIndex + implicit_this_param_pos)); |
428 // Copy positional arguments. | 429 // Copy positional arguments. |
429 // Check that no fewer than num_fixed_params positional arguments are passed | 430 // Check that no fewer than num_fixed_params positional arguments are passed |
430 // in and that no more than num_params arguments are passed in. | 431 // in and that no more than num_params arguments are passed in. |
431 // Passed argument i at fp[1 + argc - i] copied to | 432 // Passed argument i at fp[1 + argc - i] copied to |
432 // fp[ParsedFunction::kFirstLocalSlotIndex - i]. | 433 // fp[ParsedFunction::kFirstLocalSlotIndex - i]. |
433 const int num_params = num_fixed_params + num_opt_params; | 434 const int num_params = num_fixed_params + num_opt_params; |
434 | 435 |
435 // Total number of args is the first Smi in args descriptor array (EDX). | 436 // Total number of args is the first Smi in args descriptor array (EDX). |
436 __ movl(EBX, FieldAddress(EDX, Array::data_offset())); | 437 __ movl(EBX, FieldAddress(EDX, Array::data_offset())); |
437 // Check that num_args <= num_params. | 438 // Check that num_args <= num_params. |
438 Label wrong_num_arguments; | 439 Label wrong_num_arguments; |
439 __ cmpl(EBX, Immediate(Smi::RawValue(num_params))); | 440 __ cmpl(EBX, Immediate(Smi::RawValue(num_params))); |
440 __ j(GREATER, &wrong_num_arguments); | 441 __ j(GREATER, &wrong_num_arguments); |
441 // Number of positional args is the second Smi in descriptor array (EDX). | 442 // Number of positional args is the second Smi in descriptor array (EDX). |
442 __ movl(ECX, FieldAddress(EDX, Array::data_offset() + (1 * kWordSize))); | 443 __ movl(ECX, FieldAddress(EDX, Array::data_offset() + (1 * kWordSize))); |
443 // Check that num_pos_args >= num_fixed_params. | 444 // Check that num_pos_args >= num_fixed_params. |
444 __ cmpl(ECX, Immediate(Smi::RawValue(num_fixed_params))); | 445 __ cmpl(ECX, Immediate(Smi::RawValue(num_fixed_params))); |
445 __ j(LESS, &wrong_num_arguments); | 446 __ j(LESS, &wrong_num_arguments); |
446 | 447 |
447 // Since EBX and ECX are Smi, use TIMES_2 instead of TIMES_4. | 448 // Since EBX and ECX are Smi, use TIMES_2 instead of TIMES_4. |
448 // Let EBX point to the last passed positional argument, i.e. to | 449 // Let EBX point to the last passed positional argument, i.e. to |
449 // fp[1 + num_args - (num_pos_args - 1)]. | 450 // fp[1 + num_args - (num_pos_args - 1)]. |
450 __ subl(EBX, ECX); | 451 __ subl(EBX, ECX); |
451 __ leal(EBX, Address(EBP, EBX, TIMES_2, 2 * kWordSize)); | 452 __ leal(EBX, Address(EBP, EBX, TIMES_2, 2 * kWordSize)); |
452 // Let EDI point to the last copied positional argument, i.e. to | 453 // Let EDI point to the last copied positional argument, i.e. to |
453 // fp[ParsedFunction::kFirstLocalSlotIndex - (num_pos_args - 1)]. | 454 // fp[ParsedFunction::kFirstLocalSlotIndex - (num_pos_args - 1)]. |
454 int implicit_this_param_pos = is_instance_native_closure ? -1 : 0; | |
455 const int index = | 455 const int index = |
456 ParsedFunction::kFirstLocalSlotIndex + 1 + implicit_this_param_pos; | 456 ParsedFunction::kFirstLocalSlotIndex + 1 + implicit_this_param_pos; |
457 // First copy captured receiver if function is an implicit native closure. | 457 // First copy captured receiver if function is an implicit native closure. |
458 if (is_instance_native_closure) { | 458 if (is_instance_native_closure) { |
459 __ movl(EAX, FieldAddress(CTX, Context::variable_offset(0))); | 459 __ movl(EAX, FieldAddress(CTX, Context::variable_offset(0))); |
460 __ movl(Address(EBP, (index * kWordSize)), EAX); | 460 __ movl(Address(EBP, (index * kWordSize)), EAX); |
461 } | 461 } |
462 __ leal(EDI, Address(EBP, (index * kWordSize))); | 462 __ leal(EDI, Address(EBP, (index * kWordSize))); |
463 __ subl(EDI, ECX); // ECX is a Smi, subtract twice for TIMES_4 scaling. | 463 __ subl(EDI, ECX); // ECX is a Smi, subtract twice for TIMES_4 scaling. |
464 __ subl(EDI, ECX); | 464 __ subl(EDI, ECX); |
(...skipping 2499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2964 const Error& error = Error::Handle( | 2964 const Error& error = Error::Handle( |
2965 Parser::FormatError(script, token_index, "Error", format, args)); | 2965 Parser::FormatError(script, token_index, "Error", format, args)); |
2966 va_end(args); | 2966 va_end(args); |
2967 Isolate::Current()->long_jump_base()->Jump(1, error); | 2967 Isolate::Current()->long_jump_base()->Jump(1, error); |
2968 UNREACHABLE(); | 2968 UNREACHABLE(); |
2969 } | 2969 } |
2970 | 2970 |
2971 } // namespace dart | 2971 } // namespace dart |
2972 | 2972 |
2973 #endif // defined TARGET_ARCH_IA32 | 2973 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |