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 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 ASSERT(!has_cc()); | 408 ASSERT(!has_cc()); |
409 } | 409 } |
410 | 410 |
411 | 411 |
412 void CodeGenerator::LoadGlobal() { | 412 void CodeGenerator::LoadGlobal() { |
413 __ ldr(r0, GlobalObject()); | 413 __ ldr(r0, GlobalObject()); |
414 __ push(r0); | 414 __ push(r0); |
415 } | 415 } |
416 | 416 |
417 | 417 |
| 418 void CodeGenerator::LoadGlobalReceiver(Register s) { |
| 419 __ ldr(s, ContextOperand(cp, Context::GLOBAL_INDEX)); |
| 420 __ ldr(s, FieldMemOperand(s, GlobalObject::kGlobalReceiverOffset)); |
| 421 __ push(s); |
| 422 } |
| 423 |
| 424 |
418 // TODO(1241834): Get rid of this function in favor of just using Load, now | 425 // TODO(1241834): Get rid of this function in favor of just using Load, now |
419 // that we have the INSIDE_TYPEOF typeof state. => Need to handle global | 426 // that we have the INSIDE_TYPEOF typeof state. => Need to handle global |
420 // variables w/o reference errors elsewhere. | 427 // variables w/o reference errors elsewhere. |
421 void CodeGenerator::LoadTypeofExpression(Expression* x) { | 428 void CodeGenerator::LoadTypeofExpression(Expression* x) { |
422 Variable* variable = x->AsVariableProxy()->AsVariable(); | 429 Variable* variable = x->AsVariableProxy()->AsVariable(); |
423 if (variable != NULL && !variable->is_this() && variable->is_global()) { | 430 if (variable != NULL && !variable->is_this() && variable->is_global()) { |
424 // NOTE: This is somewhat nasty. We force the compiler to load | 431 // NOTE: This is somewhat nasty. We force the compiler to load |
425 // the variable as if through '<global>.<variable>' to make sure we | 432 // the variable as if through '<global>.<variable>' to make sure we |
426 // do not get reference errors. | 433 // do not get reference errors. |
427 Slot global(variable, Slot::CONTEXT, Context::GLOBAL_INDEX); | 434 Slot global(variable, Slot::CONTEXT, Context::GLOBAL_INDEX); |
(...skipping 1785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2213 // ------------------------------------------------------------------------ | 2220 // ------------------------------------------------------------------------ |
2214 | 2221 |
2215 if (var != NULL && !var->is_this() && var->is_global()) { | 2222 if (var != NULL && !var->is_this() && var->is_global()) { |
2216 // ---------------------------------- | 2223 // ---------------------------------- |
2217 // JavaScript example: 'foo(1, 2, 3)' // foo is global | 2224 // JavaScript example: 'foo(1, 2, 3)' // foo is global |
2218 // ---------------------------------- | 2225 // ---------------------------------- |
2219 | 2226 |
2220 // Push the name of the function and the receiver onto the stack. | 2227 // Push the name of the function and the receiver onto the stack. |
2221 __ mov(r0, Operand(var->name())); | 2228 __ mov(r0, Operand(var->name())); |
2222 __ push(r0); | 2229 __ push(r0); |
2223 LoadGlobal(); | 2230 |
| 2231 // TODO(120): use JSGlobalObject for function lookup and inline cache, |
| 2232 // and use global proxy as 'this' for invocation. |
| 2233 LoadGlobalReceiver(r0); |
2224 | 2234 |
2225 // Load the arguments. | 2235 // Load the arguments. |
2226 for (int i = 0; i < args->length(); i++) Load(args->at(i)); | 2236 for (int i = 0; i < args->length(); i++) Load(args->at(i)); |
2227 | 2237 |
2228 // Setup the receiver register and call the IC initialization code. | 2238 // Setup the receiver register and call the IC initialization code. |
2229 Handle<Code> stub = ComputeCallInitialize(args->length()); | 2239 Handle<Code> stub = ComputeCallInitialize(args->length()); |
2230 __ RecordPosition(node->position()); | 2240 __ RecordPosition(node->position()); |
2231 __ Call(stub, RelocInfo::CODE_TARGET_CONTEXT); | 2241 __ Call(stub, RelocInfo::CODE_TARGET_CONTEXT); |
2232 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2242 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2233 // Remove the function from the stack. | 2243 // Remove the function from the stack. |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2301 } | 2311 } |
2302 | 2312 |
2303 } else { | 2313 } else { |
2304 // ---------------------------------- | 2314 // ---------------------------------- |
2305 // JavaScript example: 'foo(1, 2, 3)' // foo is not global | 2315 // JavaScript example: 'foo(1, 2, 3)' // foo is not global |
2306 // ---------------------------------- | 2316 // ---------------------------------- |
2307 | 2317 |
2308 // Load the function. | 2318 // Load the function. |
2309 Load(function); | 2319 Load(function); |
2310 // Pass the global object as the receiver. | 2320 // Pass the global object as the receiver. |
2311 LoadGlobal(); | 2321 |
| 2322 // TODO(120): use JSGlobalObject for function lookup and inline cache, |
| 2323 // and use global proxy as 'this' for invocation. |
| 2324 LoadGlobalReceiver(r0); |
2312 // Call the function. | 2325 // Call the function. |
2313 CallWithArguments(args, node->position()); | 2326 CallWithArguments(args, node->position()); |
2314 __ push(r0); | 2327 __ push(r0); |
2315 } | 2328 } |
2316 } | 2329 } |
2317 | 2330 |
2318 | 2331 |
2319 void CodeGenerator::VisitCallNew(CallNew* node) { | 2332 void CodeGenerator::VisitCallNew(CallNew* node) { |
2320 Comment cmnt(masm_, "[ CallNew"); | 2333 Comment cmnt(masm_, "[ CallNew"); |
2321 | 2334 |
2322 // According to ECMA-262, section 11.2.2, page 44, the function | 2335 // According to ECMA-262, section 11.2.2, page 44, the function |
2323 // expression in new calls must be evaluated before the | 2336 // expression in new calls must be evaluated before the |
2324 // arguments. This is different from ordinary calls, where the | 2337 // arguments. This is different from ordinary calls, where the |
2325 // actual function to call is resolved after the arguments have been | 2338 // actual function to call is resolved after the arguments have been |
2326 // evaluated. | 2339 // evaluated. |
2327 | 2340 |
2328 // Compute function to call and use the global object as the | 2341 // Compute function to call and use the global object as the |
2329 // receiver. | 2342 // receiver. |
2330 Load(node->expression()); | 2343 Load(node->expression()); |
2331 LoadGlobal(); | 2344 LoadGlobalReceiver(r0); |
2332 | 2345 |
2333 // Push the arguments ("left-to-right") on the stack. | 2346 // Push the arguments ("left-to-right") on the stack. |
2334 ZoneList<Expression*>* args = node->arguments(); | 2347 ZoneList<Expression*>* args = node->arguments(); |
2335 for (int i = 0; i < args->length(); i++) Load(args->at(i)); | 2348 for (int i = 0; i < args->length(); i++) Load(args->at(i)); |
2336 | 2349 |
2337 // r0: the number of arguments. | 2350 // r0: the number of arguments. |
2338 __ mov(r0, Operand(args->length())); | 2351 __ mov(r0, Operand(args->length())); |
2339 | 2352 |
2340 // Load the function into r1 as per calling convention. | 2353 // Load the function into r1 as per calling convention. |
2341 __ ldr(r1, MemOperand(sp, (args->length() + 1) * kPointerSize)); | 2354 __ ldr(r1, MemOperand(sp, (args->length() + 1) * kPointerSize)); |
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2866 // Get the expressions from the node. | 2879 // Get the expressions from the node. |
2867 Expression* left = node->left(); | 2880 Expression* left = node->left(); |
2868 Expression* right = node->right(); | 2881 Expression* right = node->right(); |
2869 Token::Value op = node->op(); | 2882 Token::Value op = node->op(); |
2870 | 2883 |
2871 // NOTE: To make null checks efficient, we check if either left or | 2884 // NOTE: To make null checks efficient, we check if either left or |
2872 // right is the literal 'null'. If so, we optimize the code by | 2885 // right is the literal 'null'. If so, we optimize the code by |
2873 // inlining a null check instead of calling the (very) general | 2886 // inlining a null check instead of calling the (very) general |
2874 // runtime routine for checking equality. | 2887 // runtime routine for checking equality. |
2875 | 2888 |
2876 bool left_is_null = | |
2877 left->AsLiteral() != NULL && left->AsLiteral()->IsNull(); | |
2878 bool right_is_null = | |
2879 right->AsLiteral() != NULL && right->AsLiteral()->IsNull(); | |
2880 | |
2881 if (op == Token::EQ || op == Token::EQ_STRICT) { | 2889 if (op == Token::EQ || op == Token::EQ_STRICT) { |
| 2890 bool left_is_null = |
| 2891 left->AsLiteral() != NULL && left->AsLiteral()->IsNull(); |
| 2892 bool right_is_null = |
| 2893 right->AsLiteral() != NULL && right->AsLiteral()->IsNull(); |
2882 // The 'null' value is only equal to 'null' or 'undefined'. | 2894 // The 'null' value is only equal to 'null' or 'undefined'. |
2883 if (left_is_null || right_is_null) { | 2895 if (left_is_null || right_is_null) { |
2884 Load(left_is_null ? right : left); | 2896 Load(left_is_null ? right : left); |
2885 Label exit, undetectable; | 2897 Label exit, undetectable; |
2886 __ pop(r0); | 2898 __ pop(r0); |
2887 __ cmp(r0, Operand(Factory::null_value())); | 2899 __ cmp(r0, Operand(Factory::null_value())); |
2888 | 2900 |
2889 // The 'null' value is only equal to 'undefined' if using | 2901 // The 'null' value is only equal to 'undefined' if using |
2890 // non-strict comparisons. | 2902 // non-strict comparisons. |
2891 if (op != Token::EQ_STRICT) { | 2903 if (op != Token::EQ_STRICT) { |
(...skipping 1268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4160 // Slow-case: Non-function called. | 4172 // Slow-case: Non-function called. |
4161 __ bind(&slow); | 4173 __ bind(&slow); |
4162 __ mov(r0, Operand(argc_)); // Setup the number of arguments. | 4174 __ mov(r0, Operand(argc_)); // Setup the number of arguments. |
4163 __ InvokeBuiltin(Builtins::CALL_NON_FUNCTION, JUMP_JS); | 4175 __ InvokeBuiltin(Builtins::CALL_NON_FUNCTION, JUMP_JS); |
4164 } | 4176 } |
4165 | 4177 |
4166 | 4178 |
4167 #undef __ | 4179 #undef __ |
4168 | 4180 |
4169 } } // namespace v8::internal | 4181 } } // namespace v8::internal |
OLD | NEW |