OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 // -- r1 : constructor function | 57 // -- r1 : constructor function |
58 // -- lr : return address | 58 // -- lr : return address |
59 // -- sp[...]: constructor arguments | 59 // -- sp[...]: constructor arguments |
60 // ----------------------------------- | 60 // ----------------------------------- |
61 | 61 |
62 Label non_function_call; | 62 Label non_function_call; |
63 // Check that the function is not a smi. | 63 // Check that the function is not a smi. |
64 __ tst(r1, Operand(kSmiTagMask)); | 64 __ tst(r1, Operand(kSmiTagMask)); |
65 __ b(eq, &non_function_call); | 65 __ b(eq, &non_function_call); |
66 // Check that the function is a JSFunction. | 66 // Check that the function is a JSFunction. |
67 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); | 67 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); |
68 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); | |
69 __ cmp(r2, Operand(JS_FUNCTION_TYPE)); | |
70 __ b(ne, &non_function_call); | 68 __ b(ne, &non_function_call); |
71 | 69 |
72 // Enter a construct frame. | 70 // Enter a construct frame. |
73 __ EnterConstructFrame(); | 71 __ EnterConstructFrame(); |
74 | 72 |
75 // Preserve the two incoming parameters | 73 // Preserve the two incoming parameters |
76 __ mov(r0, Operand(r0, LSL, kSmiTagSize)); | 74 __ mov(r0, Operand(r0, LSL, kSmiTagSize)); |
77 __ push(r0); // smi-tagged arguments count | 75 __ push(r0); // smi-tagged arguments count |
78 __ push(r1); // constructor function | 76 __ push(r1); // constructor function |
79 | 77 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 // If the result is a smi, it is *not* an object in the ECMA sense. | 150 // If the result is a smi, it is *not* an object in the ECMA sense. |
153 // r0: result | 151 // r0: result |
154 // sp[0]: receiver (newly allocated object) | 152 // sp[0]: receiver (newly allocated object) |
155 // sp[1]: constructor function | 153 // sp[1]: constructor function |
156 // sp[2]: number of arguments (smi-tagged) | 154 // sp[2]: number of arguments (smi-tagged) |
157 __ tst(r0, Operand(kSmiTagMask)); | 155 __ tst(r0, Operand(kSmiTagMask)); |
158 __ b(eq, &use_receiver); | 156 __ b(eq, &use_receiver); |
159 | 157 |
160 // If the type of the result (stored in its map) is less than | 158 // If the type of the result (stored in its map) is less than |
161 // FIRST_JS_OBJECT_TYPE, it is not an object in the ECMA sense. | 159 // FIRST_JS_OBJECT_TYPE, it is not an object in the ECMA sense. |
162 __ ldr(r3, FieldMemOperand(r0, HeapObject::kMapOffset)); | 160 __ CompareObjectType(r0, r3, r3, FIRST_JS_OBJECT_TYPE); |
163 __ ldrb(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset)); | |
164 __ cmp(r3, Operand(FIRST_JS_OBJECT_TYPE)); | |
165 __ b(ge, &exit); | 161 __ b(ge, &exit); |
166 | 162 |
167 // Throw away the result of the constructor invocation and use the | 163 // Throw away the result of the constructor invocation and use the |
168 // on-stack receiver as the result. | 164 // on-stack receiver as the result. |
169 __ bind(&use_receiver); | 165 __ bind(&use_receiver); |
170 __ ldr(r0, MemOperand(sp)); | 166 __ ldr(r0, MemOperand(sp)); |
171 | 167 |
172 // Remove receiver from the stack, remove caller arguments, and | 168 // Remove receiver from the stack, remove caller arguments, and |
173 // return. | 169 // return. |
174 __ bind(&exit); | 170 __ bind(&exit); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 __ add(r0, r0, Operand(1)); | 279 __ add(r0, r0, Operand(1)); |
284 __ bind(&done); | 280 __ bind(&done); |
285 } | 281 } |
286 | 282 |
287 // 2. Get the function to call from the stack. | 283 // 2. Get the function to call from the stack. |
288 // r0: actual number of argument | 284 // r0: actual number of argument |
289 { Label done, non_function, function; | 285 { Label done, non_function, function; |
290 __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); | 286 __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); |
291 __ tst(r1, Operand(kSmiTagMask)); | 287 __ tst(r1, Operand(kSmiTagMask)); |
292 __ b(eq, &non_function); | 288 __ b(eq, &non_function); |
293 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); | 289 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); |
294 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); | |
295 __ cmp(r2, Operand(JS_FUNCTION_TYPE)); | |
296 __ b(eq, &function); | 290 __ b(eq, &function); |
297 | 291 |
298 // Non-function called: Clear the function to force exception. | 292 // Non-function called: Clear the function to force exception. |
299 __ bind(&non_function); | 293 __ bind(&non_function); |
300 __ mov(r1, Operand(0)); | 294 __ mov(r1, Operand(0)); |
301 __ b(&done); | 295 __ b(&done); |
302 | 296 |
303 // Change the context eagerly because it will be used below to get the | 297 // Change the context eagerly because it will be used below to get the |
304 // right global object. | 298 // right global object. |
305 __ bind(&function); | 299 __ bind(&function); |
(...skipping 15 matching lines...) Expand all Loading... |
321 __ tst(r2, Operand(kSmiTagMask)); | 315 __ tst(r2, Operand(kSmiTagMask)); |
322 __ b(eq, &call_to_object); | 316 __ b(eq, &call_to_object); |
323 | 317 |
324 __ mov(r3, Operand(Factory::null_value())); | 318 __ mov(r3, Operand(Factory::null_value())); |
325 __ cmp(r2, r3); | 319 __ cmp(r2, r3); |
326 __ b(eq, &use_global_receiver); | 320 __ b(eq, &use_global_receiver); |
327 __ mov(r3, Operand(Factory::undefined_value())); | 321 __ mov(r3, Operand(Factory::undefined_value())); |
328 __ cmp(r2, r3); | 322 __ cmp(r2, r3); |
329 __ b(eq, &use_global_receiver); | 323 __ b(eq, &use_global_receiver); |
330 | 324 |
331 __ ldr(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); | 325 __ CompareObjectType(r2, r3, r3, FIRST_JS_OBJECT_TYPE); |
332 __ ldrb(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset)); | |
333 __ cmp(r3, Operand(FIRST_JS_OBJECT_TYPE)); | |
334 __ b(lt, &call_to_object); | 326 __ b(lt, &call_to_object); |
335 __ cmp(r3, Operand(LAST_JS_OBJECT_TYPE)); | 327 __ cmp(r3, Operand(LAST_JS_OBJECT_TYPE)); |
336 __ b(le, &done); | 328 __ b(le, &done); |
337 | 329 |
338 __ bind(&call_to_object); | 330 __ bind(&call_to_object); |
339 __ EnterInternalFrame(); | 331 __ EnterInternalFrame(); |
340 | 332 |
341 // Store number of arguments and function across the call into the runtime. | 333 // Store number of arguments and function across the call into the runtime. |
342 __ mov(r0, Operand(r0, LSL, kSmiTagSize)); | 334 __ mov(r0, Operand(r0, LSL, kSmiTagSize)); |
343 __ push(r0); | 335 __ push(r0); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 __ b(eq, &call_to_object); | 486 __ b(eq, &call_to_object); |
495 __ mov(r1, Operand(Factory::null_value())); | 487 __ mov(r1, Operand(Factory::null_value())); |
496 __ cmp(r0, r1); | 488 __ cmp(r0, r1); |
497 __ b(eq, &use_global_receiver); | 489 __ b(eq, &use_global_receiver); |
498 __ mov(r1, Operand(Factory::undefined_value())); | 490 __ mov(r1, Operand(Factory::undefined_value())); |
499 __ cmp(r0, r1); | 491 __ cmp(r0, r1); |
500 __ b(eq, &use_global_receiver); | 492 __ b(eq, &use_global_receiver); |
501 | 493 |
502 // Check if the receiver is already a JavaScript object. | 494 // Check if the receiver is already a JavaScript object. |
503 // r0: receiver | 495 // r0: receiver |
504 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); | 496 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE); |
505 __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset)); | |
506 __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE)); | |
507 __ b(lt, &call_to_object); | 497 __ b(lt, &call_to_object); |
508 __ cmp(r1, Operand(LAST_JS_OBJECT_TYPE)); | 498 __ cmp(r1, Operand(LAST_JS_OBJECT_TYPE)); |
509 __ b(le, &push_receiver); | 499 __ b(le, &push_receiver); |
510 | 500 |
511 // Convert the receiver to a regular object. | 501 // Convert the receiver to a regular object. |
512 // r0: receiver | 502 // r0: receiver |
513 __ bind(&call_to_object); | 503 __ bind(&call_to_object); |
514 __ push(r0); | 504 __ push(r0); |
515 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS); | 505 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS); |
516 __ b(&push_receiver); | 506 __ b(&push_receiver); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
691 // Dont adapt arguments. | 681 // Dont adapt arguments. |
692 // ------------------------------------------- | 682 // ------------------------------------------- |
693 __ bind(&dont_adapt_arguments); | 683 __ bind(&dont_adapt_arguments); |
694 __ Jump(r3); | 684 __ Jump(r3); |
695 } | 685 } |
696 | 686 |
697 | 687 |
698 #undef __ | 688 #undef __ |
699 | 689 |
700 } } // namespace v8::internal | 690 } } // namespace v8::internal |
OLD | NEW |