| 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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 CodeGenerator::CodeGenerator(int buffer_size, Handle<Script> script, | 75 CodeGenerator::CodeGenerator(int buffer_size, Handle<Script> script, |
| 76 bool is_eval) | 76 bool is_eval) |
| 77 : is_eval_(is_eval), | 77 : is_eval_(is_eval), |
| 78 script_(script), | 78 script_(script), |
| 79 deferred_(8), | 79 deferred_(8), |
| 80 masm_(new MacroAssembler(NULL, buffer_size)), | 80 masm_(new MacroAssembler(NULL, buffer_size)), |
| 81 scope_(NULL), | 81 scope_(NULL), |
| 82 frame_(NULL), | 82 frame_(NULL), |
| 83 cc_reg_(al), | 83 cc_reg_(al), |
| 84 state_(NULL), | 84 state_(NULL), |
| 85 break_stack_height_(0) { | 85 break_stack_height_(0), |
| 86 function_return_is_shadowed_(false) { |
| 86 } | 87 } |
| 87 | 88 |
| 88 | 89 |
| 89 // Calling conventions: | 90 // Calling conventions: |
| 90 // r0: the number of arguments | 91 // r0: the number of arguments |
| 91 // fp: frame pointer | 92 // fp: frame pointer |
| 92 // sp: stack pointer | 93 // sp: stack pointer |
| 93 // pp: caller's parameter pointer | 94 // pp: caller's parameter pointer |
| 94 // cp: callee's context | 95 // cp: callee's context |
| 95 | 96 |
| 96 void CodeGenerator::GenCode(FunctionLiteral* fun) { | 97 void CodeGenerator::GenCode(FunctionLiteral* fun) { |
| 97 ZoneList<Statement*>* body = fun->body(); | 98 ZoneList<Statement*>* body = fun->body(); |
| 98 | 99 |
| 99 // Initialize state. | 100 // Initialize state. |
| 100 ASSERT(scope_ == NULL); | 101 ASSERT(scope_ == NULL); |
| 101 scope_ = fun->scope(); | 102 scope_ = fun->scope(); |
| 102 ASSERT(frame_ == NULL); | 103 ASSERT(frame_ == NULL); |
| 103 set_frame(new VirtualFrame(this)); | 104 set_frame(new VirtualFrame(this)); |
| 104 cc_reg_ = al; | 105 cc_reg_ = al; |
| 105 function_return_.set_code_generator(this); | 106 function_return_.set_code_generator(this); |
| 107 function_return_is_shadowed_ = false; |
| 106 { | 108 { |
| 107 CodeGenState state(this); | 109 CodeGenState state(this); |
| 108 | 110 |
| 109 // Entry | 111 // Entry |
| 110 // stack: function, receiver, arguments, return address | 112 // stack: function, receiver, arguments, return address |
| 111 // r0: number of arguments | 113 // r0: number of arguments |
| 112 // sp: stack pointer | 114 // sp: stack pointer |
| 113 // fp: frame pointer | 115 // fp: frame pointer |
| 114 // pp: caller's parameter pointer | 116 // pp: caller's parameter pointer |
| 115 // cp: callee's context | 117 // cp: callee's context |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 | 262 |
| 261 // Tear down the frame which will restore the caller's frame pointer and | 263 // Tear down the frame which will restore the caller's frame pointer and |
| 262 // the link register. | 264 // the link register. |
| 263 frame_->Exit(); | 265 frame_->Exit(); |
| 264 | 266 |
| 265 __ add(sp, sp, Operand((scope_->num_parameters() + 1) * kPointerSize)); | 267 __ add(sp, sp, Operand((scope_->num_parameters() + 1) * kPointerSize)); |
| 266 __ mov(pc, lr); | 268 __ mov(pc, lr); |
| 267 } | 269 } |
| 268 | 270 |
| 269 // Code generation state must be reset. | 271 // Code generation state must be reset. |
| 272 ASSERT(!function_return_is_shadowed_); |
| 273 function_return_.Unuse(); |
| 270 scope_ = NULL; | 274 scope_ = NULL; |
| 271 frame_ = NULL; | 275 frame_ = NULL; |
| 272 ASSERT(!has_cc()); | 276 ASSERT(!has_cc()); |
| 273 ASSERT(state_ == NULL); | 277 ASSERT(state_ == NULL); |
| 274 } | 278 } |
| 275 | 279 |
| 276 | 280 |
| 277 MemOperand CodeGenerator::SlotOperand(Slot* slot, Register tmp) { | 281 MemOperand CodeGenerator::SlotOperand(Slot* slot, Register tmp) { |
| 278 // Currently, this assertion will fail if we try to assign to | 282 // Currently, this assertion will fail if we try to assign to |
| 279 // a constant variable that is constant because it is read-only | 283 // a constant variable that is constant because it is read-only |
| (...skipping 1532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1812 // shadowing label. | 1816 // shadowing label. |
| 1813 // | 1817 // |
| 1814 // We should probably try to unify the escaping labels and the return | 1818 // We should probably try to unify the escaping labels and the return |
| 1815 // label. | 1819 // label. |
| 1816 int nof_escapes = node->escaping_targets()->length(); | 1820 int nof_escapes = node->escaping_targets()->length(); |
| 1817 List<ShadowTarget*> shadows(1 + nof_escapes); | 1821 List<ShadowTarget*> shadows(1 + nof_escapes); |
| 1818 shadows.Add(new ShadowTarget(&function_return_)); | 1822 shadows.Add(new ShadowTarget(&function_return_)); |
| 1819 for (int i = 0; i < nof_escapes; i++) { | 1823 for (int i = 0; i < nof_escapes; i++) { |
| 1820 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); | 1824 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); |
| 1821 } | 1825 } |
| 1826 bool function_return_was_shadowed = function_return_is_shadowed_; |
| 1827 function_return_is_shadowed_ = true; |
| 1822 | 1828 |
| 1823 // Generate code for the statements in the try block. | 1829 // Generate code for the statements in the try block. |
| 1824 VisitStatements(node->try_block()->statements()); | 1830 VisitStatements(node->try_block()->statements()); |
| 1825 if (frame_ != NULL) { | 1831 if (frame_ != NULL) { |
| 1826 frame_->Drop(); // Discard the result. | 1832 frame_->Drop(); // Discard the result. |
| 1827 } | 1833 } |
| 1828 | 1834 |
| 1829 // Stop the introduced shadowing and count the number of required unlinks. | 1835 // Stop the introduced shadowing and count the number of required unlinks. |
| 1830 // After shadowing stops, the original labels are unshadowed and the | 1836 // After shadowing stops, the original labels are unshadowed and the |
| 1831 // LabelShadows represent the formerly shadowing labels. | 1837 // LabelShadows represent the formerly shadowing labels. |
| 1832 int nof_unlinks = 0; | 1838 int nof_unlinks = 0; |
| 1833 for (int i = 0; i <= nof_escapes; i++) { | 1839 for (int i = 0; i <= nof_escapes; i++) { |
| 1834 shadows[i]->StopShadowing(); | 1840 shadows[i]->StopShadowing(); |
| 1835 if (shadows[i]->is_linked()) nof_unlinks++; | 1841 if (shadows[i]->is_linked()) nof_unlinks++; |
| 1836 } | 1842 } |
| 1843 function_return_is_shadowed_ = function_return_was_shadowed; |
| 1837 | 1844 |
| 1838 const int kNextIndex = (StackHandlerConstants::kNextOffset | 1845 const int kNextIndex = (StackHandlerConstants::kNextOffset |
| 1839 + StackHandlerConstants::kAddressDisplacement) | 1846 + StackHandlerConstants::kAddressDisplacement) |
| 1840 / kPointerSize; | 1847 / kPointerSize; |
| 1841 // If we can fall off the end of the try block, unlink from try chain. | 1848 // If we can fall off the end of the try block, unlink from try chain. |
| 1842 if (frame_ != NULL) { | 1849 if (frame_ != NULL) { |
| 1843 __ ldr(r1, frame_->ElementAt(kNextIndex)); // read next_sp | 1850 __ ldr(r1, frame_->ElementAt(kNextIndex)); // read next_sp |
| 1844 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); | 1851 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); |
| 1845 __ str(r1, MemOperand(r3)); | 1852 __ str(r1, MemOperand(r3)); |
| 1846 ASSERT(StackHandlerConstants::kCodeOffset == 0); // first field is code | 1853 ASSERT(StackHandlerConstants::kCodeOffset == 0); // first field is code |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1909 // operations on the original actually affect the shadowing label. | 1916 // operations on the original actually affect the shadowing label. |
| 1910 // | 1917 // |
| 1911 // We should probably try to unify the escaping labels and the return | 1918 // We should probably try to unify the escaping labels and the return |
| 1912 // label. | 1919 // label. |
| 1913 int nof_escapes = node->escaping_targets()->length(); | 1920 int nof_escapes = node->escaping_targets()->length(); |
| 1914 List<ShadowTarget*> shadows(1 + nof_escapes); | 1921 List<ShadowTarget*> shadows(1 + nof_escapes); |
| 1915 shadows.Add(new ShadowTarget(&function_return_)); | 1922 shadows.Add(new ShadowTarget(&function_return_)); |
| 1916 for (int i = 0; i < nof_escapes; i++) { | 1923 for (int i = 0; i < nof_escapes; i++) { |
| 1917 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); | 1924 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); |
| 1918 } | 1925 } |
| 1926 bool function_return_was_shadowed = function_return_is_shadowed_; |
| 1927 function_return_is_shadowed_ = true; |
| 1919 | 1928 |
| 1920 // Generate code for the statements in the try block. | 1929 // Generate code for the statements in the try block. |
| 1921 VisitStatements(node->try_block()->statements()); | 1930 VisitStatements(node->try_block()->statements()); |
| 1922 | 1931 |
| 1923 // Stop the introduced shadowing and count the number of required unlinks. | 1932 // Stop the introduced shadowing and count the number of required unlinks. |
| 1924 // After shadowing stops, the original labels are unshadowed and the | 1933 // After shadowing stops, the original labels are unshadowed and the |
| 1925 // LabelShadows represent the formerly shadowing labels. | 1934 // LabelShadows represent the formerly shadowing labels. |
| 1926 int nof_unlinks = 0; | 1935 int nof_unlinks = 0; |
| 1927 for (int i = 0; i <= nof_escapes; i++) { | 1936 for (int i = 0; i <= nof_escapes; i++) { |
| 1928 shadows[i]->StopShadowing(); | 1937 shadows[i]->StopShadowing(); |
| 1929 if (shadows[i]->is_linked()) nof_unlinks++; | 1938 if (shadows[i]->is_linked()) nof_unlinks++; |
| 1930 } | 1939 } |
| 1940 function_return_is_shadowed_ = function_return_was_shadowed; |
| 1931 | 1941 |
| 1932 // If we can fall off the end of the try block, set the state on the stack | 1942 // If we can fall off the end of the try block, set the state on the stack |
| 1933 // to FALLING. | 1943 // to FALLING. |
| 1934 if (frame_ != NULL) { | 1944 if (frame_ != NULL) { |
| 1935 __ mov(r0, Operand(Factory::undefined_value())); // fake TOS | 1945 __ mov(r0, Operand(Factory::undefined_value())); // fake TOS |
| 1936 frame_->Push(r0); | 1946 frame_->Push(r0); |
| 1937 __ mov(r2, Operand(Smi::FromInt(FALLING))); | 1947 __ mov(r2, Operand(Smi::FromInt(FALLING))); |
| 1938 if (nof_unlinks > 0) { | 1948 if (nof_unlinks > 0) { |
| 1939 unlink.Jump(); | 1949 unlink.Jump(); |
| 1940 } | 1950 } |
| (...skipping 1376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3317 | 3327 |
| 3318 void CodeGenerator::RecordStatementPosition(Node* node) { | 3328 void CodeGenerator::RecordStatementPosition(Node* node) { |
| 3319 if (FLAG_debug_info) { | 3329 if (FLAG_debug_info) { |
| 3320 int statement_pos = node->statement_pos(); | 3330 int statement_pos = node->statement_pos(); |
| 3321 if (statement_pos == RelocInfo::kNoPosition) return; | 3331 if (statement_pos == RelocInfo::kNoPosition) return; |
| 3322 __ RecordStatementPosition(statement_pos); | 3332 __ RecordStatementPosition(statement_pos); |
| 3323 } | 3333 } |
| 3324 } | 3334 } |
| 3325 | 3335 |
| 3326 | 3336 |
| 3337 bool CodeGenerator::IsActualFunctionReturn(JumpTarget* target) { |
| 3338 return (target == &function_return_ && !function_return_is_shadowed_); |
| 3339 } |
| 3340 |
| 3341 |
| 3327 #undef __ | 3342 #undef __ |
| 3328 #define __ masm-> | 3343 #define __ masm-> |
| 3329 | 3344 |
| 3330 Handle<String> Reference::GetName() { | 3345 Handle<String> Reference::GetName() { |
| 3331 ASSERT(type_ == NAMED); | 3346 ASSERT(type_ == NAMED); |
| 3332 Property* property = expression_->AsProperty(); | 3347 Property* property = expression_->AsProperty(); |
| 3333 if (property == NULL) { | 3348 if (property == NULL) { |
| 3334 // Global variable reference treated as a named property reference. | 3349 // Global variable reference treated as a named property reference. |
| 3335 VariableProxy* proxy = expression_->AsVariableProxy(); | 3350 VariableProxy* proxy = expression_->AsVariableProxy(); |
| 3336 ASSERT(proxy->AsVariable() != NULL); | 3351 ASSERT(proxy->AsVariable() != NULL); |
| (...skipping 1093 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4430 __ mov(r2, Operand(0)); | 4445 __ mov(r2, Operand(0)); |
| 4431 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); | 4446 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); |
| 4432 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), | 4447 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), |
| 4433 RelocInfo::CODE_TARGET); | 4448 RelocInfo::CODE_TARGET); |
| 4434 } | 4449 } |
| 4435 | 4450 |
| 4436 | 4451 |
| 4437 #undef __ | 4452 #undef __ |
| 4438 | 4453 |
| 4439 } } // namespace v8::internal | 4454 } } // namespace v8::internal |
| OLD | NEW |