| 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 |