| 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 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 | 273 |
| 274 // Preserve values across call to resolving. | 274 // Preserve values across call to resolving. |
| 275 // Stack at this point: | 275 // Stack at this point: |
| 276 // TOS + 0: PC marker => RawInstruction object. | 276 // TOS + 0: PC marker => RawInstruction object. |
| 277 // TOS + 1: Saved EBP of previous frame. <== EBP | 277 // TOS + 1: Saved EBP of previous frame. <== EBP |
| 278 // TOS + 2: Dart code return address | 278 // TOS + 2: Dart code return address |
| 279 // TOS + 3: Last argument of caller. | 279 // TOS + 3: Last argument of caller. |
| 280 // .... | 280 // .... |
| 281 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 281 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
| 282 __ movl(EAX, Address(EBP, EAX, TIMES_2, kWordSize)); // Get receiver. | 282 __ movl(EAX, Address(EBP, EAX, TIMES_2, kWordSize)); // Get receiver. |
| 283 __ pushl(EDX); // Preserve arguments descriptor array. | |
| 284 __ pushl(EAX); // Preserve receiver. | |
| 285 __ pushl(ECX); // Preserve ic-data. | |
| 286 // First resolve the function to get the function object. | |
| 287 | |
| 288 __ pushl(raw_null); // Setup space on stack for return value. | |
| 289 __ pushl(EAX); // Pass receiver. | |
| 290 __ pushl(ECX); // Pass IC data object. | |
| 291 __ pushl(EDX); // Pass arguments descriptor array. | |
| 292 __ CallRuntime(kResolveCompileInstanceFunctionRuntimeEntry); | |
| 293 __ popl(EAX); // Remove arguments pushed earlier. | |
| 294 __ popl(EAX); | |
| 295 __ popl(EAX); | |
| 296 __ popl(ECX); // Pop returned code object into ECX. | |
| 297 // Pop preserved values. | |
| 298 __ popl(EDX); // Restore ic-data. | |
| 299 __ popl(EAX); // Restore receiver. | |
| 300 __ popl(EDI); // Restore arguments descriptor array. | |
| 301 | |
| 302 __ cmpl(ECX, raw_null); | |
| 303 Label check_implicit_closure; | |
| 304 __ j(EQUAL, &check_implicit_closure, Assembler::kNearJump); | |
| 305 | |
| 306 // Remove the stub frame as we are about to jump to the dart function. | |
| 307 __ LeaveFrame(); | |
| 308 | |
| 309 __ movl(EDX, EDI); | |
| 310 __ movl(ECX, FieldAddress(ECX, Code::instructions_offset())); | |
| 311 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | |
| 312 __ jmp(ECX); | |
| 313 | |
| 314 __ Bind(&check_implicit_closure); | |
| 315 // EAX: receiver. | 283 // EAX: receiver. |
| 316 // EDX: ic-data. | 284 // ECX: ic-data. |
| 317 // ECX: raw_null. | 285 // EDX: arguments descriptor array. |
| 318 // EDI: arguments descriptor array. | |
| 319 // The target function was not found. | 286 // The target function was not found. |
| 320 // First check to see if this is a getter function and we are | 287 // First check to see if this is a getter function and we are |
| 321 // trying to create a closure of an instance function. | 288 // trying to create a closure of an instance function. |
| 322 // Push values that need to be preserved across runtime call. | 289 // Push values that need to be preserved across runtime call. |
| 323 __ pushl(EAX); // Preserve receiver. | 290 __ pushl(EAX); // Preserve receiver. |
| 324 __ pushl(EDX); // Preserve ic-data. | 291 __ pushl(ECX); // Preserve ic-data. |
| 325 __ pushl(EDI); // Preserve arguments descriptor array. | 292 __ pushl(EDX); // Preserve arguments descriptor array. |
| 326 | 293 |
| 327 __ pushl(raw_null); // Setup space on stack for return value. | 294 __ pushl(raw_null); // Setup space on stack for return value. |
| 328 __ pushl(EAX); // Push receiver. | 295 __ pushl(EAX); // Push receiver. |
| 329 __ pushl(EDX); // Ic-data. | 296 __ pushl(ECX); // Ic-data. |
| 330 __ CallRuntime(kResolveImplicitClosureFunctionRuntimeEntry); | 297 __ CallRuntime(kResolveImplicitClosureFunctionRuntimeEntry); |
| 331 __ popl(EAX); | 298 __ popl(EAX); |
| 332 __ popl(EAX); | 299 __ popl(EAX); |
| 333 __ popl(ECX); // Get return value into ECX, might be Closure object. | 300 __ popl(EBX); // Get return value into EBX, might be Closure object. |
| 334 | 301 |
| 335 // Pop preserved values. | 302 // Pop preserved values. |
| 336 __ popl(EDI); // Restore arguments descriptor array. | 303 __ popl(EDX); // Restore arguments descriptor array. |
| 337 __ popl(EDX); // Restore ic-data. | 304 __ popl(ECX); // Restore ic-data. |
| 338 __ popl(EAX); // Restore receiver. | 305 __ popl(EAX); // Restore receiver. |
| 339 | 306 |
| 340 __ cmpl(ECX, raw_null); | 307 __ cmpl(EBX, raw_null); |
| 341 Label check_implicit_closure_through_getter; | 308 Label check_implicit_closure_through_getter; |
| 342 __ j(EQUAL, &check_implicit_closure_through_getter, Assembler::kNearJump); | 309 __ j(EQUAL, &check_implicit_closure_through_getter, Assembler::kNearJump); |
| 343 | 310 |
| 344 __ movl(EAX, ECX); // Return value is the closure object. | 311 __ movl(EAX, EBX); // Return value is the closure object. |
| 345 // Remove the stub frame as we are about return. | 312 // Remove the stub frame as we are about return. |
| 346 __ LeaveFrame(); | 313 __ LeaveFrame(); |
| 347 __ ret(); | 314 __ ret(); |
| 348 | 315 |
| 349 __ Bind(&check_implicit_closure_through_getter); | 316 __ Bind(&check_implicit_closure_through_getter); |
| 350 // EAX: receiver. | 317 // EAX: receiver. |
| 351 // EDX: ic-data. | 318 // ECX: ic-data. |
| 352 // ECX: raw_null. | 319 // EDX: arguments descriptor array. |
| 353 // EDI: arguments descriptor array. | |
| 354 // This is not the case of an instance so invoke the getter of the | 320 // This is not the case of an instance so invoke the getter of the |
| 355 // same name and see if we get a closure back which we are then | 321 // same name and see if we get a closure back which we are then |
| 356 // supposed to invoke. | 322 // supposed to invoke. |
| 357 // Push values that need to be preserved across runtime call. | 323 // Push values that need to be preserved across runtime call. |
| 358 __ pushl(EAX); // Preserve receiver. | 324 __ pushl(EAX); // Preserve receiver. |
| 359 __ pushl(EDX); // Preserve ic-data. | 325 __ pushl(ECX); // Preserve ic-data. |
| 360 __ pushl(EDI); // Preserve arguments descriptor array. | 326 __ pushl(EDX); // Preserve arguments descriptor array. |
| 361 | 327 |
| 362 __ pushl(raw_null); // Setup space on stack for return value. | 328 __ pushl(raw_null); // Setup space on stack for return value. |
| 363 __ pushl(EAX); // Push receiver. | 329 __ pushl(EAX); // Push receiver. |
| 364 __ pushl(EDX); // Ic-data. | 330 __ pushl(ECX); // Ic-data. |
| 365 __ CallRuntime(kResolveImplicitClosureThroughGetterRuntimeEntry); | 331 __ CallRuntime(kResolveImplicitClosureThroughGetterRuntimeEntry); |
| 366 __ popl(EDX); // Pop argument. | |
| 367 __ popl(EAX); // Pop argument. | 332 __ popl(EAX); // Pop argument. |
| 368 __ popl(ECX); // get return value into ECX, might be Closure object. | 333 __ popl(EAX); // Pop argument. |
| 334 __ popl(EBX); // get return value into EBX, might be Closure object. |
| 369 | 335 |
| 370 // Pop preserved values. | 336 // Pop preserved values. |
| 371 __ popl(EDI); // Restore arguments descriptor array. | 337 __ popl(EDX); // Restore arguments descriptor array. |
| 372 __ popl(EDX); // Restore ic-data. | 338 __ popl(ECX); // Restore ic-data. |
| 373 __ popl(EAX); // Restore receiver. | 339 __ popl(EAX); // Restore receiver. |
| 374 | 340 |
| 375 __ cmpl(ECX, raw_null); | 341 __ cmpl(EBX, raw_null); |
| 376 Label function_not_found; | 342 Label function_not_found; |
| 377 __ j(EQUAL, &function_not_found, Assembler::kNearJump); | 343 __ j(EQUAL, &function_not_found, Assembler::kNearJump); |
| 378 | 344 |
| 379 // ECX: Closure object. | 345 // EBX: Closure object. |
| 380 // EDI: Arguments descriptor array. | 346 // EDX: Arguments descriptor array. |
| 381 __ 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. |
| 382 __ pushl(ECX); // Closure object. | 348 __ pushl(EBX); // Closure object. |
| 383 __ pushl(EDI); // Arguments descriptor. | 349 __ pushl(EDX); // Arguments descriptor. |
| 384 __ movl(EDI, FieldAddress(EDI, ArgumentsDescriptor::count_offset())); | 350 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
| 385 __ SmiUntag(EDI); | 351 __ SmiUntag(EDI); |
| 386 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver. | 352 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver. |
| 387 PushArgumentsArray(assembler, (kWordSize * 6)); | 353 PushArgumentsArray(assembler, (kWordSize * 6)); |
| 388 // Stack layout explaining "(kWordSize * 6)" offset. | 354 // Stack layout explaining "(kWordSize * 6)" offset. |
| 389 // TOS + 0: Argument array. | 355 // TOS + 0: Argument array. |
| 390 // TOS + 1: Arguments descriptor array. | 356 // TOS + 1: Arguments descriptor array. |
| 391 // TOS + 2: Closure object. | 357 // TOS + 2: Closure object. |
| 392 // TOS + 3: Place for result from closure function. | 358 // TOS + 3: Place for result from closure function. |
| 393 // TOS + 4: PC marker => RawInstruction object. | 359 // TOS + 4: PC marker => RawInstruction object. |
| 394 // TOS + 5: Saved EBP of previous frame. <== EBP | 360 // TOS + 5: Saved EBP of previous frame. <== EBP |
| 395 // TOS + 6: Dart code return address | 361 // TOS + 6: Dart code return address |
| 396 // TOS + 7: Last argument of caller. | 362 // TOS + 7: Last argument of caller. |
| 397 // .... | 363 // .... |
| 398 | 364 |
| 399 __ CallRuntime(kInvokeImplicitClosureFunctionRuntimeEntry); | 365 __ CallRuntime(kInvokeImplicitClosureFunctionRuntimeEntry); |
| 400 // Remove arguments. | 366 // Remove arguments. |
| 401 __ popl(EAX); | 367 __ popl(EAX); |
| 402 __ popl(EAX); | 368 __ popl(EAX); |
| 403 __ popl(EAX); | 369 __ popl(EAX); |
| 404 __ popl(EAX); // Get result into EAX. | 370 __ popl(EAX); // Get result into EAX. |
| 405 | 371 |
| 406 // Remove the stub frame as we are about to return. | 372 // Remove the stub frame as we are about to return. |
| 407 __ LeaveFrame(); | 373 __ LeaveFrame(); |
| 408 __ ret(); | 374 __ ret(); |
| 409 | 375 |
| 410 __ Bind(&function_not_found); | 376 __ Bind(&function_not_found); |
| 411 // The target function was not found, so invoke method | 377 // The target function was not found, so invoke method |
| 412 // "void noSuchMethod(function_name, args_array)". | 378 // "void noSuchMethod(function_name, args_array)". |
| 413 // EAX: receiver. | 379 // EAX: receiver. |
| 414 // EDX: ic-data. | 380 // ECX: ic-data. |
| 415 // ECX: raw_null. | 381 // EDX: arguments descriptor array. |
| 416 // EDI: arguments descriptor array. | |
| 417 | 382 |
| 418 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod. | 383 __ pushl(raw_null); // Setup space on stack for result from noSuchMethod. |
| 419 __ pushl(EAX); // Receiver. | 384 __ pushl(EAX); // Receiver. |
| 420 __ pushl(EDX); // IC-data. | 385 __ pushl(ECX); // IC-data. |
| 421 __ pushl(EDI); // Arguments descriptor array. | 386 __ pushl(EDX); // Arguments descriptor array. |
| 422 __ movl(EDI, FieldAddress(EDI, ArgumentsDescriptor::count_offset())); | 387 __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
| 423 __ SmiUntag(EDI); | 388 __ SmiUntag(EDI); |
| 424 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver. | 389 __ subl(EDI, Immediate(1)); // Arguments array length, minus the receiver. |
| 425 // See stack layout below explaining "wordSize * 7" offset. | 390 // See stack layout below explaining "wordSize * 7" offset. |
| 426 PushArgumentsArray(assembler, (kWordSize * 7)); | 391 PushArgumentsArray(assembler, (kWordSize * 7)); |
| 427 | 392 |
| 428 // Stack: | 393 // Stack: |
| 429 // TOS + 0: Arguments array. | 394 // TOS + 0: Arguments array. |
| 430 // TOS + 1: Arguments descriptor array. | 395 // TOS + 1: Arguments descriptor array. |
| 431 // TOS + 2: IC-data. | 396 // TOS + 2: IC-data. |
| 432 // TOS + 3: Receiver | 397 // TOS + 3: Receiver |
| (...skipping 1783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2216 __ Bind(&done); | 2181 __ Bind(&done); |
| 2217 __ popl(temp); | 2182 __ popl(temp); |
| 2218 __ popl(right); | 2183 __ popl(right); |
| 2219 __ popl(left); | 2184 __ popl(left); |
| 2220 __ ret(); | 2185 __ ret(); |
| 2221 } | 2186 } |
| 2222 | 2187 |
| 2223 } // namespace dart | 2188 } // namespace dart |
| 2224 | 2189 |
| 2225 #endif // defined TARGET_ARCH_IA32 | 2190 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |