| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 | 29 |
| 30 #include "codegen-inl.h" | 30 #include "codegen-inl.h" |
| 31 | 31 |
| 32 namespace v8 { | 32 namespace v8 { |
| 33 namespace internal { | 33 namespace internal { |
| 34 | 34 |
| 35 | 35 |
| 36 #define __ ACCESS_MASM(masm) | 36 #define __ ACCESS_MASM(masm) |
| 37 | 37 |
| 38 | 38 |
| 39 void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) { | 39 void Builtins::Generate_Adaptor(MacroAssembler* masm, |
| 40 // TODO(428): Don't pass the function in a static variable. | 40 CFunctionId id, |
| 41 ExternalReference passed = ExternalReference::builtin_passed_function(); | 41 BuiltinExtraArguments extra_args) { |
| 42 __ mov(Operand::StaticVariable(passed), edi); | 42 // ----------- S t a t e ------------- |
| 43 // -- eax : number of arguments excluding receiver |
| 44 // -- edi : called function (only guaranteed when |
| 45 // extra_args requires it) |
| 46 // -- esi : context |
| 47 // -- esp[0] : return address |
| 48 // -- esp[4] : last argument |
| 49 // -- ... |
| 50 // -- esp[4 * argc] : first argument (argc == eax) |
| 51 // -- esp[4 * (argc +1)] : receiver |
| 52 // ----------------------------------- |
| 43 | 53 |
| 44 // The actual argument count has already been loaded into register | 54 // Insert extra arguments. |
| 45 // eax, but JumpToRuntime expects eax to contain the number of | 55 int num_extra_args = 0; |
| 46 // arguments including the receiver. | 56 if (extra_args == NEEDS_CALLED_FUNCTION) { |
| 47 __ inc(eax); | 57 num_extra_args = 1; |
| 58 Register scratch = ebx; |
| 59 __ pop(scratch); // Save return address. |
| 60 __ push(edi); |
| 61 __ push(scratch); // Restore return address. |
| 62 } else { |
| 63 ASSERT(extra_args == NO_EXTRA_ARGUMENTS); |
| 64 } |
| 65 |
| 66 // JumpToRuntime expects eax to contain the number of arguments |
| 67 // including the receiver and the extra arguments. |
| 68 __ add(Operand(eax), Immediate(num_extra_args + 1)); |
| 48 __ JumpToRuntime(ExternalReference(id)); | 69 __ JumpToRuntime(ExternalReference(id)); |
| 49 } | 70 } |
| 50 | 71 |
| 51 | 72 |
| 52 void Builtins::Generate_JSConstructCall(MacroAssembler* masm) { | 73 void Builtins::Generate_JSConstructCall(MacroAssembler* masm) { |
| 53 // ----------- S t a t e ------------- | 74 // ----------- S t a t e ------------- |
| 54 // -- eax: number of arguments | 75 // -- eax: number of arguments |
| 55 // -- edi: constructor function | 76 // -- edi: constructor function |
| 56 // ----------------------------------- | 77 // ----------------------------------- |
| 57 | 78 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 74 __ bind(&non_function_call); | 95 __ bind(&non_function_call); |
| 75 | 96 |
| 76 // Set expected number of arguments to zero (not changing eax). | 97 // Set expected number of arguments to zero (not changing eax). |
| 77 __ Set(ebx, Immediate(0)); | 98 __ Set(ebx, Immediate(0)); |
| 78 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); | 99 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); |
| 79 __ jmp(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), | 100 __ jmp(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), |
| 80 RelocInfo::CODE_TARGET); | 101 RelocInfo::CODE_TARGET); |
| 81 } | 102 } |
| 82 | 103 |
| 83 | 104 |
| 84 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { | 105 static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
| 106 bool is_api_function) { |
| 85 // Enter a construct frame. | 107 // Enter a construct frame. |
| 86 __ EnterConstructFrame(); | 108 __ EnterConstructFrame(); |
| 87 | 109 |
| 88 // Store a smi-tagged arguments count on the stack. | 110 // Store a smi-tagged arguments count on the stack. |
| 89 __ SmiTag(eax); | 111 __ SmiTag(eax); |
| 90 __ push(eax); | 112 __ push(eax); |
| 91 | 113 |
| 92 // Push the function to invoke on the stack. | 114 // Push the function to invoke on the stack. |
| 93 __ push(edi); | 115 __ push(edi); |
| 94 | 116 |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 Label loop, entry; | 292 Label loop, entry; |
| 271 __ mov(ecx, Operand(eax)); | 293 __ mov(ecx, Operand(eax)); |
| 272 __ jmp(&entry); | 294 __ jmp(&entry); |
| 273 __ bind(&loop); | 295 __ bind(&loop); |
| 274 __ push(Operand(ebx, ecx, times_4, 0)); | 296 __ push(Operand(ebx, ecx, times_4, 0)); |
| 275 __ bind(&entry); | 297 __ bind(&entry); |
| 276 __ dec(ecx); | 298 __ dec(ecx); |
| 277 __ j(greater_equal, &loop); | 299 __ j(greater_equal, &loop); |
| 278 | 300 |
| 279 // Call the function. | 301 // Call the function. |
| 280 ParameterCount actual(eax); | 302 if (is_api_function) { |
| 281 __ InvokeFunction(edi, actual, CALL_FUNCTION); | 303 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
| 304 Handle<Code> code = Handle<Code>( |
| 305 Builtins::builtin(Builtins::HandleApiCallConstruct)); |
| 306 ParameterCount expected(0); |
| 307 __ InvokeCode(code, expected, expected, |
| 308 RelocInfo::CODE_TARGET, CALL_FUNCTION); |
| 309 } else { |
| 310 ParameterCount actual(eax); |
| 311 __ InvokeFunction(edi, actual, CALL_FUNCTION); |
| 312 } |
| 282 | 313 |
| 283 // Restore context from the frame. | 314 // Restore context from the frame. |
| 284 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 315 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 285 | 316 |
| 286 // If the result is an object (in the ECMA sense), we should get rid | 317 // If the result is an object (in the ECMA sense), we should get rid |
| 287 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 | 318 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 |
| 288 // on page 74. | 319 // on page 74. |
| 289 Label use_receiver, exit; | 320 Label use_receiver, exit; |
| 290 | 321 |
| 291 // If the result is a smi, it is *not* an object in the ECMA sense. | 322 // If the result is a smi, it is *not* an object in the ECMA sense. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 312 // Remove caller arguments from the stack and return. | 343 // Remove caller arguments from the stack and return. |
| 313 ASSERT(kSmiTagSize == 1 && kSmiTag == 0); | 344 ASSERT(kSmiTagSize == 1 && kSmiTag == 0); |
| 314 __ pop(ecx); | 345 __ pop(ecx); |
| 315 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver | 346 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver |
| 316 __ push(ecx); | 347 __ push(ecx); |
| 317 __ IncrementCounter(&Counters::constructed_objects, 1); | 348 __ IncrementCounter(&Counters::constructed_objects, 1); |
| 318 __ ret(0); | 349 __ ret(0); |
| 319 } | 350 } |
| 320 | 351 |
| 321 | 352 |
| 353 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { |
| 354 Generate_JSConstructStubHelper(masm, false); |
| 355 } |
| 356 |
| 357 |
| 358 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { |
| 359 Generate_JSConstructStubHelper(masm, true); |
| 360 } |
| 361 |
| 362 |
| 322 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 363 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
| 323 bool is_construct) { | 364 bool is_construct) { |
| 324 // Clear the context before we push it when entering the JS frame. | 365 // Clear the context before we push it when entering the JS frame. |
| 325 __ xor_(esi, Operand(esi)); // clear esi | 366 __ xor_(esi, Operand(esi)); // clear esi |
| 326 | 367 |
| 327 // Enter an internal frame. | 368 // Enter an internal frame. |
| 328 __ EnterInternalFrame(); | 369 __ EnterInternalFrame(); |
| 329 | 370 |
| 330 // Load the previous frame pointer (ebx) to access C arguments | 371 // Load the previous frame pointer (ebx) to access C arguments |
| 331 __ mov(ebx, Operand(ebp, 0)); | 372 __ mov(ebx, Operand(ebp, 0)); |
| (...skipping 881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1213 // Dont adapt arguments. | 1254 // Dont adapt arguments. |
| 1214 // ------------------------------------------- | 1255 // ------------------------------------------- |
| 1215 __ bind(&dont_adapt_arguments); | 1256 __ bind(&dont_adapt_arguments); |
| 1216 __ jmp(Operand(edx)); | 1257 __ jmp(Operand(edx)); |
| 1217 } | 1258 } |
| 1218 | 1259 |
| 1219 | 1260 |
| 1220 #undef __ | 1261 #undef __ |
| 1221 | 1262 |
| 1222 } } // namespace v8::internal | 1263 } } // namespace v8::internal |
| OLD | NEW |