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" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/assembler_macros.h" | 9 #include "vm/assembler_macros.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 __ cmpl(EBX, raw_null); | 341 __ cmpl(EBX, raw_null); |
342 Label function_not_found; | 342 Label function_not_found; |
343 __ j(EQUAL, &function_not_found, Assembler::kNearJump); | 343 __ j(EQUAL, &function_not_found, Assembler::kNearJump); |
344 | 344 |
345 // EBX: Closure object. | 345 // EBX: Closure object. |
346 // EDX: Arguments descriptor array. | 346 // EDX: Arguments descriptor array. |
347 __ pushl(raw_null); // Setup space on stack for result from invoking Closure. | 347 __ pushl(raw_null); // Setup space on stack for result from invoking Closure. |
348 __ pushl(EBX); // Closure object. | 348 __ pushl(EBX); // Closure object. |
349 __ pushl(EDX); // Arguments descriptor. | 349 __ pushl(EDX); // Arguments descriptor. |
350 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 350 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
351 __ SmiUntag(EDI); | 351 __ SmiUntag(EDI); // Arguments array length, including the original receiver. |
352 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver. | |
353 PushArgumentsArray(assembler, (kWordSize * 6)); | 352 PushArgumentsArray(assembler, (kWordSize * 6)); |
354 // Stack layout explaining "(kWordSize * 6)" offset. | 353 // Stack layout explaining "(kWordSize * 6)" offset. |
355 // TOS + 0: Argument array. | 354 // TOS + 0: Argument array. |
356 // TOS + 1: Arguments descriptor array. | 355 // TOS + 1: Arguments descriptor array. |
357 // TOS + 2: Closure object. | 356 // TOS + 2: Closure object. |
358 // TOS + 3: Place for result from closure function. | 357 // TOS + 3: Place for result from closure function. |
359 // TOS + 4: PC marker => RawInstruction object. | 358 // TOS + 4: PC marker => RawInstruction object. |
360 // TOS + 5: Saved EBP of previous frame. <== EBP | 359 // TOS + 5: Saved EBP of previous frame. <== EBP |
361 // TOS + 6: Dart code return address | 360 // TOS + 6: Dart code return address |
362 // TOS + 7: Last argument of caller. | 361 // TOS + 7: Last argument of caller. |
363 // .... | 362 // .... |
364 | 363 |
365 __ CallRuntime(kInvokeImplicitClosureFunctionRuntimeEntry); | 364 __ CallRuntime(kInvokeImplicitClosureFunctionRuntimeEntry); |
366 // Remove arguments. | 365 // Remove arguments. |
367 __ popl(EAX); | 366 __ popl(EAX); |
368 __ popl(EAX); | 367 __ popl(EAX); |
369 __ popl(EAX); | 368 __ popl(EAX); |
370 __ popl(EAX); // Get result into EAX. | 369 __ popl(EAX); // Get result into EAX. |
371 | 370 |
372 // Remove the stub frame as we are about to return. | 371 // Remove the stub frame as we are about to return. |
373 __ LeaveFrame(); | 372 __ LeaveFrame(); |
374 __ ret(); | 373 __ ret(); |
375 | 374 |
376 __ Bind(&function_not_found); | 375 __ Bind(&function_not_found); |
377 // The target function was not found, so invoke method | 376 // The target function was not found, so invoke method |
378 // "void noSuchMethod(function_name, args_array)". | 377 // "dynamic noSuchMethod(InvocationMirror invocation)". |
379 // EAX: receiver. | 378 // EAX: receiver. |
380 // ECX: ic-data. | 379 // ECX: ic-data. |
381 // EDX: arguments descriptor array. | 380 // EDX: arguments descriptor array. |
382 | 381 |
383 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod. | 382 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod. |
384 __ pushl(EAX); // Receiver. | 383 __ pushl(EAX); // Receiver. |
385 __ pushl(ECX); // IC-data. | 384 __ pushl(ECX); // IC-data. |
386 __ pushl(EDX); // Arguments descriptor array. | 385 __ pushl(EDX); // Arguments descriptor array. |
387 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 386 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
388 __ SmiUntag(EDI); | 387 __ SmiUntag(EDI); // Arguments array length, including the original receiver. |
389 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver. | |
390 // See stack layout below explaining "wordSize * 7" offset. | 388 // See stack layout below explaining "wordSize * 7" offset. |
391 PushArgumentsArray(assembler, (kWordSize * 7)); | 389 PushArgumentsArray(assembler, (kWordSize * 7)); |
392 | 390 |
393 // Stack: | 391 // Stack: |
394 // TOS + 0: Arguments array. | 392 // TOS + 0: Arguments array. |
395 // TOS + 1: Arguments descriptor array. | 393 // TOS + 1: Arguments descriptor array. |
396 // TOS + 2: IC-data. | 394 // TOS + 2: IC-data. |
397 // TOS + 3: Receiver | 395 // TOS + 3: Receiver |
398 // TOS + 4: Place for result from noSuchMethod. | 396 // TOS + 4: Place for result from noSuchMethod. |
399 // TOS + 5: PC marker => RawInstruction object. | 397 // TOS + 5: PC marker => RawInstruction object. |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 // EDX: arguments descriptor array. | 781 // EDX: arguments descriptor array. |
784 | 782 |
785 // Create a stub frame as we are pushing some objects on the stack before | 783 // Create a stub frame as we are pushing some objects on the stack before |
786 // calling into the runtime. | 784 // calling into the runtime. |
787 AssemblerMacros::EnterStubFrame(assembler); | 785 AssemblerMacros::EnterStubFrame(assembler); |
788 | 786 |
789 __ pushl(raw_null); // Setup space on stack for result from error reporting. | 787 __ pushl(raw_null); // Setup space on stack for result from error reporting. |
790 __ pushl(EDI); // Non-closure object. | 788 __ pushl(EDI); // Non-closure object. |
791 // Load num_args. | 789 // Load num_args. |
792 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 790 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
793 __ SmiUntag(EDI); | 791 __ SmiUntag(EDI); // Arguments array length, including the non-closure. |
794 __ subl(EDI, Immediate(1)); // Arguments array length, minus the closure. | |
795 // See stack layout below explaining "wordSize * 5" offset. | 792 // See stack layout below explaining "wordSize * 5" offset. |
796 PushArgumentsArray(assembler, (kWordSize * 5)); | 793 PushArgumentsArray(assembler, (kWordSize * 5)); |
797 | 794 |
798 // Stack: | 795 // Stack: |
799 // TOS + 0: Argument array. | 796 // TOS + 0: Argument array. |
800 // TOS + 1: Non-closure object. | 797 // TOS + 1: Non-closure object. |
801 // TOS + 2: Place for result from reporting the error. | 798 // TOS + 2: Place for result from reporting the error. |
802 // TOS + 3: PC marker => RawInstruction object. | 799 // TOS + 3: PC marker => RawInstruction object. |
803 // TOS + 4: Saved EBP of previous frame. <== EBP | 800 // TOS + 4: Saved EBP of previous frame. <== EBP |
804 // TOS + 5: Dart code return address | 801 // TOS + 5: Dart code return address |
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1438 // EBP - 4 : PC marker => RawInstruction object. | 1435 // EBP - 4 : PC marker => RawInstruction object. |
1439 // EBP : points to previous frame pointer. | 1436 // EBP : points to previous frame pointer. |
1440 // EBP + 4 : points to return address. | 1437 // EBP + 4 : points to return address. |
1441 // EBP + 8 : address of last argument (arg n-1). | 1438 // EBP + 8 : address of last argument (arg n-1). |
1442 // EBP + 8 + 4*(n-1) : address of first argument (arg 0). | 1439 // EBP + 8 + 4*(n-1) : address of first argument (arg 0). |
1443 // ECX : ic-data. | 1440 // ECX : ic-data. |
1444 // EDX : arguments descriptor array. | 1441 // EDX : arguments descriptor array. |
1445 // Uses EAX, EBX, EDI as temporary registers. | 1442 // Uses EAX, EBX, EDI as temporary registers. |
1446 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { | 1443 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { |
1447 // The target function was not found, so invoke method | 1444 // The target function was not found, so invoke method |
1448 // "void noSuchMethod(function_name, Array arguments)". | 1445 // "dynamic noSuchMethod(InvocationMirror invocation)". |
1449 // TODO(regis): For now, we simply pass the actual arguments, both positional | |
1450 // and named, as the argument array. This is not correct if out-of-order | |
1451 // named arguments were passed. | |
1452 // The signature of the "noSuchMethod" method has to change from | |
1453 // noSuchMethod(String name, Array arguments) to something like | |
1454 // noSuchMethod(InvocationMirror call). | |
1455 // Also, the class NoSuchMethodError has to be modified accordingly. | |
1456 const Immediate raw_null = | 1446 const Immediate raw_null = |
1457 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1447 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
1458 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 1448 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
1459 __ SmiUntag(EDI); | 1449 __ SmiUntag(EDI); |
1460 __ movl(EAX, Address(EBP, EDI, TIMES_4, kWordSize)); // Get receiver. | 1450 __ movl(EAX, Address(EBP, EDI, TIMES_4, kWordSize)); // Get receiver. |
1461 | 1451 |
1462 // Create a stub frame as we are pushing some objects on the stack before | 1452 // Create a stub frame as we are pushing some objects on the stack before |
1463 // calling into the runtime. | 1453 // calling into the runtime. |
1464 AssemblerMacros::EnterStubFrame(assembler); | 1454 AssemblerMacros::EnterStubFrame(assembler); |
1465 | 1455 |
1466 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod. | 1456 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod. |
1467 __ pushl(EAX); // Receiver. | 1457 __ pushl(EAX); // Receiver. |
1468 __ pushl(ECX); // IC data array. | 1458 __ pushl(ECX); // IC data array. |
1469 __ pushl(EDX); // Arguments descriptor array. | 1459 __ pushl(EDX); // Arguments descriptor array. |
1470 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver. | 1460 // EDI: Arguments array length, including the receiver. |
1471 // See stack layout below explaining "wordSize * 10" offset. | 1461 // See stack layout below explaining "wordSize * 10" offset. |
1472 PushArgumentsArray(assembler, (kWordSize * 10)); | 1462 PushArgumentsArray(assembler, (kWordSize * 10)); |
1473 | 1463 |
1474 // Stack: | 1464 // Stack: |
1475 // TOS + 0: Argument array. | 1465 // TOS + 0: Argument array. |
1476 // TOS + 1: Arguments descriptor array. | 1466 // TOS + 1: Arguments descriptor array. |
1477 // TOS + 2: Ic-data. | 1467 // TOS + 2: Ic-data. |
1478 // TOS + 3: Receiver. | 1468 // TOS + 3: Receiver. |
1479 // TOS + 4: Place for result from noSuchMethod. | 1469 // TOS + 4: Place for result from noSuchMethod. |
1480 // TOS + 5: PC marker => RawInstruction object. | 1470 // TOS + 5: PC marker => RawInstruction object. |
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2219 __ Bind(&done); | 2209 __ Bind(&done); |
2220 __ popl(temp); | 2210 __ popl(temp); |
2221 __ popl(right); | 2211 __ popl(right); |
2222 __ popl(left); | 2212 __ popl(left); |
2223 __ ret(); | 2213 __ ret(); |
2224 } | 2214 } |
2225 | 2215 |
2226 } // namespace dart | 2216 } // namespace dart |
2227 | 2217 |
2228 #endif // defined TARGET_ARCH_IA32 | 2218 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |