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 |