Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(380)

Side by Side Diff: src/codegen-arm.cc

Issue 20218: A bunch of changes to get the ARM port compiling again. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/codegen-arm.h ('k') | src/jump-target-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 function_return_is_shadowed_(false) {
87 } 87 }
88 88
89 89
90 void CodeGenerator::SetFrame(VirtualFrame* new_frame) {
91 frame_ = new_frame;
92 }
93
94
95 void CodeGenerator::DeleteFrame() {
96 delete frame_;
97 frame_ = NULL;
98 }
99
100
90 // Calling conventions: 101 // Calling conventions:
91 // r0: the number of arguments 102 // r0: the number of arguments
92 // fp: frame pointer 103 // fp: frame pointer
93 // sp: stack pointer 104 // sp: stack pointer
94 // pp: caller's parameter pointer 105 // pp: caller's parameter pointer
95 // cp: callee's context 106 // cp: callee's context
96 107
97 void CodeGenerator::GenCode(FunctionLiteral* fun) { 108 void CodeGenerator::GenCode(FunctionLiteral* fun) {
98 ZoneList<Statement*>* body = fun->body(); 109 ZoneList<Statement*>* body = fun->body();
99 110
100 // Initialize state. 111 // Initialize state.
101 ASSERT(scope_ == NULL); 112 ASSERT(scope_ == NULL);
102 scope_ = fun->scope(); 113 scope_ = fun->scope();
103 ASSERT(frame_ == NULL); 114 ASSERT(frame_ == NULL);
104 set_frame(new VirtualFrame(this)); 115 frame_ = new VirtualFrame(this);
105 cc_reg_ = al; 116 cc_reg_ = al;
106 function_return_.set_code_generator(this); 117 function_return_.Initialize(this, JumpTarget::BIDIRECTIONAL);
107 function_return_is_shadowed_ = false; 118 function_return_is_shadowed_ = false;
108 { 119 {
109 CodeGenState state(this); 120 CodeGenState state(this);
110 121
111 // Entry 122 // Entry
112 // stack: function, receiver, arguments, return address 123 // stack: function, receiver, arguments, return address
113 // r0: number of arguments 124 // r0: number of arguments
114 // sp: stack pointer 125 // sp: stack pointer
115 // fp: frame pointer 126 // fp: frame pointer
116 // pp: caller's parameter pointer 127 // pp: caller's parameter pointer
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 775
765 JumpTarget exit(this); 776 JumpTarget exit(this);
766 frame_->Pop(r0); 777 frame_->Pop(r0);
767 778
768 switch (op) { 779 switch (op) {
769 case Token::ADD: { 780 case Token::ADD: {
770 DeferredCode* deferred = 781 DeferredCode* deferred =
771 new DeferredInlinedSmiOperation(this, op, int_value, reversed); 782 new DeferredInlinedSmiOperation(this, op, int_value, reversed);
772 783
773 __ add(r0, r0, Operand(value), SetCC); 784 __ add(r0, r0, Operand(value), SetCC);
774 __ b(vs, deferred->enter()); 785 deferred->enter()->Branch(vs);
775 __ tst(r0, Operand(kSmiTagMask)); 786 __ tst(r0, Operand(kSmiTagMask));
776 __ b(ne, deferred->enter()); 787 deferred->enter()->Branch(ne);
777 __ bind(deferred->exit()); 788 deferred->exit()->Bind();
778 break; 789 break;
779 } 790 }
780 791
781 case Token::SUB: { 792 case Token::SUB: {
782 DeferredCode* deferred = 793 DeferredCode* deferred =
783 new DeferredInlinedSmiOperation(this, op, int_value, reversed); 794 new DeferredInlinedSmiOperation(this, op, int_value, reversed);
784 795
785 if (!reversed) { 796 if (!reversed) {
786 __ sub(r0, r0, Operand(value), SetCC); 797 __ sub(r0, r0, Operand(value), SetCC);
787 } else { 798 } else {
788 __ rsb(r0, r0, Operand(value), SetCC); 799 __ rsb(r0, r0, Operand(value), SetCC);
789 } 800 }
790 __ b(vs, deferred->enter()); 801 deferred->enter()->Branch(vs);
791 __ tst(r0, Operand(kSmiTagMask)); 802 __ tst(r0, Operand(kSmiTagMask));
792 __ b(ne, deferred->enter()); 803 deferred->enter()->Branch(ne);
793 __ bind(deferred->exit()); 804 deferred->exit()->Bind();
794 break; 805 break;
795 } 806 }
796 807
797 case Token::BIT_OR: 808 case Token::BIT_OR:
798 case Token::BIT_XOR: 809 case Token::BIT_XOR:
799 case Token::BIT_AND: { 810 case Token::BIT_AND: {
800 DeferredCode* deferred = 811 DeferredCode* deferred =
801 new DeferredInlinedSmiOperation(this, op, int_value, reversed); 812 new DeferredInlinedSmiOperation(this, op, int_value, reversed);
802 __ tst(r0, Operand(kSmiTagMask)); 813 __ tst(r0, Operand(kSmiTagMask));
803 __ b(ne, deferred->enter()); 814 deferred->enter()->Branch(ne);
804 switch (op) { 815 switch (op) {
805 case Token::BIT_OR: __ orr(r0, r0, Operand(value)); break; 816 case Token::BIT_OR: __ orr(r0, r0, Operand(value)); break;
806 case Token::BIT_XOR: __ eor(r0, r0, Operand(value)); break; 817 case Token::BIT_XOR: __ eor(r0, r0, Operand(value)); break;
807 case Token::BIT_AND: __ and_(r0, r0, Operand(value)); break; 818 case Token::BIT_AND: __ and_(r0, r0, Operand(value)); break;
808 default: UNREACHABLE(); 819 default: UNREACHABLE();
809 } 820 }
810 __ bind(deferred->exit()); 821 deferred->exit()->Bind();
811 break; 822 break;
812 } 823 }
813 824
814 case Token::SHL: 825 case Token::SHL:
815 case Token::SHR: 826 case Token::SHR:
816 case Token::SAR: { 827 case Token::SAR: {
817 if (reversed) { 828 if (reversed) {
818 __ mov(ip, Operand(value)); 829 __ mov(ip, Operand(value));
819 frame_->EmitPush(ip); 830 frame_->EmitPush(ip);
820 frame_->EmitPush(r0); 831 frame_->EmitPush(r0);
821 GenericBinaryOperation(op); 832 GenericBinaryOperation(op);
822 833
823 } else { 834 } else {
824 int shift_value = int_value & 0x1f; // least significant 5 bits 835 int shift_value = int_value & 0x1f; // least significant 5 bits
825 DeferredCode* deferred = 836 DeferredCode* deferred =
826 new DeferredInlinedSmiOperation(this, op, shift_value, false); 837 new DeferredInlinedSmiOperation(this, op, shift_value, false);
827 __ tst(r0, Operand(kSmiTagMask)); 838 __ tst(r0, Operand(kSmiTagMask));
828 __ b(ne, deferred->enter()); 839 deferred->enter()->Branch(ne);
829 __ mov(r2, Operand(r0, ASR, kSmiTagSize)); // remove tags 840 __ mov(r2, Operand(r0, ASR, kSmiTagSize)); // remove tags
830 switch (op) { 841 switch (op) {
831 case Token::SHL: { 842 case Token::SHL: {
832 __ mov(r2, Operand(r2, LSL, shift_value)); 843 __ mov(r2, Operand(r2, LSL, shift_value));
833 // check that the *unsigned* result fits in a smi 844 // check that the *unsigned* result fits in a smi
834 __ add(r3, r2, Operand(0x40000000), SetCC); 845 __ add(r3, r2, Operand(0x40000000), SetCC);
835 __ b(mi, deferred->enter()); 846 deferred->enter()->Branch(mi);
836 break; 847 break;
837 } 848 }
838 case Token::SHR: { 849 case Token::SHR: {
839 // LSR by immediate 0 means shifting 32 bits. 850 // LSR by immediate 0 means shifting 32 bits.
840 if (shift_value != 0) { 851 if (shift_value != 0) {
841 __ mov(r2, Operand(r2, LSR, shift_value)); 852 __ mov(r2, Operand(r2, LSR, shift_value));
842 } 853 }
843 // check that the *unsigned* result fits in a smi 854 // check that the *unsigned* result fits in a smi
844 // neither of the two high-order bits can be set: 855 // neither of the two high-order bits can be set:
845 // - 0x80000000: high bit would be lost when smi tagging 856 // - 0x80000000: high bit would be lost when smi tagging
846 // - 0x40000000: this number would convert to negative when 857 // - 0x40000000: this number would convert to negative when
847 // smi tagging these two cases can only happen with shifts 858 // smi tagging these two cases can only happen with shifts
848 // by 0 or 1 when handed a valid smi 859 // by 0 or 1 when handed a valid smi
849 __ and_(r3, r2, Operand(0xc0000000), SetCC); 860 __ and_(r3, r2, Operand(0xc0000000), SetCC);
850 __ b(ne, deferred->enter()); 861 deferred->enter()->Branch(ne);
851 break; 862 break;
852 } 863 }
853 case Token::SAR: { 864 case Token::SAR: {
854 if (shift_value != 0) { 865 if (shift_value != 0) {
855 // ASR by immediate 0 means shifting 32 bits. 866 // ASR by immediate 0 means shifting 32 bits.
856 __ mov(r2, Operand(r2, ASR, shift_value)); 867 __ mov(r2, Operand(r2, ASR, shift_value));
857 } 868 }
858 break; 869 break;
859 } 870 }
860 default: UNREACHABLE(); 871 default: UNREACHABLE();
861 } 872 }
862 __ mov(r0, Operand(r2, LSL, kSmiTagSize)); 873 __ mov(r0, Operand(r2, LSL, kSmiTagSize));
863 __ bind(deferred->exit()); 874 deferred->exit()->Bind();
864 } 875 }
865 break; 876 break;
866 } 877 }
867 878
868 default: 879 default:
869 if (!reversed) { 880 if (!reversed) {
870 frame_->EmitPush(r0); 881 frame_->EmitPush(r0);
871 __ mov(r0, Operand(value)); 882 __ mov(r0, Operand(value));
872 frame_->EmitPush(r0); 883 frame_->EmitPush(r0);
873 } else { 884 } else {
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 1015
1005 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { 1016 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
1006 for (int i = 0; frame_ != NULL && i < statements->length(); i++) { 1017 for (int i = 0; frame_ != NULL && i < statements->length(); i++) {
1007 Visit(statements->at(i)); 1018 Visit(statements->at(i));
1008 } 1019 }
1009 } 1020 }
1010 1021
1011 1022
1012 void CodeGenerator::VisitBlock(Block* node) { 1023 void CodeGenerator::VisitBlock(Block* node) {
1013 Comment cmnt(masm_, "[ Block"); 1024 Comment cmnt(masm_, "[ Block");
1014 CodeForStatement(node); 1025 CodeForStatementPosition(node);
1015 node->set_break_stack_height(break_stack_height_); 1026 node->set_break_stack_height(break_stack_height_);
1016 node->break_target()->set_code_generator(this); 1027 node->break_target()->Initialize(this);
1017 VisitStatements(node->statements()); 1028 VisitStatements(node->statements());
1018 if (node->break_target()->is_linked()) { 1029 node->break_target()->Bind();
1019 node->break_target()->Bind();
1020 }
1021 } 1030 }
1022 1031
1023 1032
1024 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 1033 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
1025 __ mov(r0, Operand(pairs)); 1034 __ mov(r0, Operand(pairs));
1026 frame_->EmitPush(r0); 1035 frame_->EmitPush(r0);
1027 frame_->EmitPush(cp); 1036 frame_->EmitPush(cp);
1028 __ mov(r0, Operand(Smi::FromInt(is_eval() ? 1 : 0))); 1037 __ mov(r0, Operand(Smi::FromInt(is_eval() ? 1 : 0)));
1029 frame_->EmitPush(r0); 1038 frame_->EmitPush(r0);
1030 frame_->CallRuntime(Runtime::kDeclareGlobals, 3); 1039 frame_->CallRuntime(Runtime::kDeclareGlobals, 3);
1031 // The result is discarded. 1040 // The result is discarded.
1032 } 1041 }
1033 1042
1034 1043
1035 void CodeGenerator::VisitDeclaration(Declaration* node) { 1044 void CodeGenerator::VisitDeclaration(Declaration* node) {
1036 Comment cmnt(masm_, "[ Declaration"); 1045 Comment cmnt(masm_, "[ Declaration");
1037 CodeForStatement(node); 1046 CodeForStatementPosition(node);
1038 Variable* var = node->proxy()->var(); 1047 Variable* var = node->proxy()->var();
1039 ASSERT(var != NULL); // must have been resolved 1048 ASSERT(var != NULL); // must have been resolved
1040 Slot* slot = var->slot(); 1049 Slot* slot = var->slot();
1041 1050
1042 // If it was not possible to allocate the variable at compile time, 1051 // If it was not possible to allocate the variable at compile time,
1043 // we need to "declare" it at runtime to make sure it actually 1052 // we need to "declare" it at runtime to make sure it actually
1044 // exists in the local context. 1053 // exists in the local context.
1045 if (slot != NULL && slot->type() == Slot::LOOKUP) { 1054 if (slot != NULL && slot->type() == Slot::LOOKUP) {
1046 // Variables with a "LOOKUP" slot were introduced as non-locals 1055 // Variables with a "LOOKUP" slot were introduced as non-locals
1047 // during variable resolution and must have mode DYNAMIC. 1056 // during variable resolution and must have mode DYNAMIC.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1093 // safe to pop the value lying on top of the reference before unloading 1102 // safe to pop the value lying on top of the reference before unloading
1094 // the reference itself (which preserves the top of stack) because we 1103 // the reference itself (which preserves the top of stack) because we
1095 // know it is a zero-sized reference. 1104 // know it is a zero-sized reference.
1096 frame_->Drop(); 1105 frame_->Drop();
1097 } 1106 }
1098 } 1107 }
1099 1108
1100 1109
1101 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) { 1110 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) {
1102 Comment cmnt(masm_, "[ ExpressionStatement"); 1111 Comment cmnt(masm_, "[ ExpressionStatement");
1103 CodeForStatement(node); 1112 CodeForStatementPosition(node);
1104 Expression* expression = node->expression(); 1113 Expression* expression = node->expression();
1105 expression->MarkAsStatement(); 1114 expression->MarkAsStatement();
1106 Load(expression); 1115 Load(expression);
1107 frame_->Drop(); 1116 frame_->Drop();
1108 } 1117 }
1109 1118
1110 1119
1111 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) { 1120 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) {
1112 Comment cmnt(masm_, "// EmptyStatement"); 1121 Comment cmnt(masm_, "// EmptyStatement");
1113 CodeForStatement(node); 1122 CodeForStatementPosition(node);
1114 // nothing to do 1123 // nothing to do
1115 } 1124 }
1116 1125
1117 1126
1118 void CodeGenerator::VisitIfStatement(IfStatement* node) { 1127 void CodeGenerator::VisitIfStatement(IfStatement* node) {
1119 Comment cmnt(masm_, "[ IfStatement"); 1128 Comment cmnt(masm_, "[ IfStatement");
1120 // Generate different code depending on which parts of the if statement 1129 // Generate different code depending on which parts of the if statement
1121 // are present or not. 1130 // are present or not.
1122 bool has_then_stm = node->HasThenStatement(); 1131 bool has_then_stm = node->HasThenStatement();
1123 bool has_else_stm = node->HasElseStatement(); 1132 bool has_else_stm = node->HasElseStatement();
1124 1133
1125 CodeForStatement(node); 1134 CodeForStatementPosition(node);
1126 1135
1127 JumpTarget exit(this); 1136 JumpTarget exit(this);
1128 if (has_then_stm && has_else_stm) { 1137 if (has_then_stm && has_else_stm) {
1129 Comment cmnt(masm_, "[ IfThenElse"); 1138 Comment cmnt(masm_, "[ IfThenElse");
1130 JumpTarget then(this); 1139 JumpTarget then(this);
1131 JumpTarget else_(this); 1140 JumpTarget else_(this);
1132 // if (cond) 1141 // if (cond)
1133 LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &then, &else_, true); 1142 LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &then, &else_, true);
1134 if (frame_ != NULL) { 1143 if (frame_ != NULL) {
1135 Branch(false, &else_); 1144 Branch(false, &else_);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1200 1209
1201 1210
1202 void CodeGenerator::CleanStack(int num_bytes) { 1211 void CodeGenerator::CleanStack(int num_bytes) {
1203 ASSERT(num_bytes % kPointerSize == 0); 1212 ASSERT(num_bytes % kPointerSize == 0);
1204 frame_->Drop(num_bytes / kPointerSize); 1213 frame_->Drop(num_bytes / kPointerSize);
1205 } 1214 }
1206 1215
1207 1216
1208 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) { 1217 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) {
1209 Comment cmnt(masm_, "[ ContinueStatement"); 1218 Comment cmnt(masm_, "[ ContinueStatement");
1210 CodeForStatement(node); 1219 CodeForStatementPosition(node);
1211 CleanStack(break_stack_height_ - node->target()->break_stack_height()); 1220 CleanStack(break_stack_height_ - node->target()->break_stack_height());
1212 node->target()->continue_target()->Jump(); 1221 node->target()->continue_target()->Jump();
1213 } 1222 }
1214 1223
1215 1224
1216 void CodeGenerator::VisitBreakStatement(BreakStatement* node) { 1225 void CodeGenerator::VisitBreakStatement(BreakStatement* node) {
1217 Comment cmnt(masm_, "[ BreakStatement"); 1226 Comment cmnt(masm_, "[ BreakStatement");
1218 CodeForStatement(node); 1227 CodeForStatementPosition(node);
1219 CleanStack(break_stack_height_ - node->target()->break_stack_height()); 1228 CleanStack(break_stack_height_ - node->target()->break_stack_height());
1220 node->target()->break_target()->Jump(); 1229 node->target()->break_target()->Jump();
1221 } 1230 }
1222 1231
1223 1232
1224 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) { 1233 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) {
1225 Comment cmnt(masm_, "[ ReturnStatement"); 1234 Comment cmnt(masm_, "[ ReturnStatement");
1226 CodeForStatement(node); 1235 CodeForStatementPosition(node);
1227 Load(node->expression()); 1236 Load(node->expression());
1228 // Move the function result into r0. 1237 // Move the function result into r0.
1229 frame_->Pop(r0); 1238 frame_->Pop(r0);
1230 1239
1231 function_return_.Jump(); 1240 function_return_.Jump();
1232 } 1241 }
1233 1242
1234 1243
1235 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) { 1244 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
1236 Comment cmnt(masm_, "[ WithEnterStatement"); 1245 Comment cmnt(masm_, "[ WithEnterStatement");
1237 CodeForStatement(node); 1246 CodeForStatementPosition(node);
1238 Load(node->expression()); 1247 Load(node->expression());
1239 if (node->is_catch_block()) { 1248 if (node->is_catch_block()) {
1240 frame_->CallRuntime(Runtime::kPushCatchContext, 1); 1249 frame_->CallRuntime(Runtime::kPushCatchContext, 1);
1241 } else { 1250 } else {
1242 frame_->CallRuntime(Runtime::kPushContext, 1); 1251 frame_->CallRuntime(Runtime::kPushContext, 1);
1243 } 1252 }
1244 if (kDebug) { 1253 if (kDebug) {
1245 JumpTarget verified_true(this); 1254 JumpTarget verified_true(this);
1246 __ cmp(r0, Operand(cp)); 1255 __ cmp(r0, Operand(cp));
1247 verified_true.Branch(eq); 1256 verified_true.Branch(eq);
1248 __ stop("PushContext: r0 is expected to be the same as cp"); 1257 __ stop("PushContext: r0 is expected to be the same as cp");
1249 verified_true.Bind(); 1258 verified_true.Bind();
1250 } 1259 }
1251 // Update context local. 1260 // Update context local.
1252 __ str(cp, frame_->Context()); 1261 __ str(cp, frame_->Context());
1253 } 1262 }
1254 1263
1255 1264
1256 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) { 1265 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) {
1257 Comment cmnt(masm_, "[ WithExitStatement"); 1266 Comment cmnt(masm_, "[ WithExitStatement");
1258 CodeForStatement(node); 1267 CodeForStatementPosition(node);
1259 // Pop context. 1268 // Pop context.
1260 __ ldr(cp, ContextOperand(cp, Context::PREVIOUS_INDEX)); 1269 __ ldr(cp, ContextOperand(cp, Context::PREVIOUS_INDEX));
1261 // Update context local. 1270 // Update context local.
1262 __ str(cp, frame_->Context()); 1271 __ str(cp, frame_->Context());
1263 } 1272 }
1264 1273
1265 1274
1266 int CodeGenerator::FastCaseSwitchMaxOverheadFactor() { 1275 int CodeGenerator::FastCaseSwitchMaxOverheadFactor() {
1267 return kFastSwitchMaxOverheadFactor; 1276 return kFastSwitchMaxOverheadFactor;
1268 } 1277 }
1269 1278
1270 int CodeGenerator::FastCaseSwitchMinCaseCount() { 1279 int CodeGenerator::FastCaseSwitchMinCaseCount() {
1271 return kFastSwitchMinCaseCount; 1280 return kFastSwitchMinCaseCount;
1272 } 1281 }
1273 1282
1274 1283
1275 void CodeGenerator::GenerateFastCaseSwitchJumpTable( 1284 void CodeGenerator::GenerateFastCaseSwitchJumpTable(
1276 SwitchStatement* node, 1285 SwitchStatement* node,
1277 int min_index, 1286 int min_index,
1278 int range, 1287 int range,
1279 JumpTarget* fail_label, 1288 Label* default_label,
1280 Vector<JumpTarget*> case_targets, 1289 Vector<Label*> case_targets,
1281 Vector<JumpTarget> case_labels) { 1290 Vector<Label> case_labels) {
1282 1291
1283 ASSERT(kSmiTag == 0 && kSmiTagSize <= 2); 1292 ASSERT(kSmiTag == 0 && kSmiTagSize <= 2);
1284 1293
1285 frame_->Pop(r0); 1294 frame_->Pop(r0);
1286 1295
1287 // Test for a Smi value in a HeapNumber. 1296 // Test for a Smi value in a HeapNumber.
1288 JumpTarget is_smi(this); 1297 JumpTarget is_smi(this);
1289 __ tst(r0, Operand(kSmiTagMask)); 1298 __ tst(r0, Operand(kSmiTagMask));
1290 is_smi.Branch(eq); 1299 is_smi.Branch(eq);
1291 __ ldr(r1, MemOperand(r0, HeapObject::kMapOffset - kHeapObjectTag)); 1300 __ ldr(r1, MemOperand(r0, HeapObject::kMapOffset - kHeapObjectTag));
1292 __ ldrb(r1, MemOperand(r1, Map::kInstanceTypeOffset - kHeapObjectTag)); 1301 __ ldrb(r1, MemOperand(r1, Map::kInstanceTypeOffset - kHeapObjectTag));
1293 __ cmp(r1, Operand(HEAP_NUMBER_TYPE)); 1302 __ cmp(r1, Operand(HEAP_NUMBER_TYPE));
1294 fail_label->Branch(ne); 1303 __ b(ne, default_label);
1295 frame_->EmitPush(r0); 1304 frame_->EmitPush(r0);
1296 frame_->CallRuntime(Runtime::kNumberToSmi, 1); 1305 frame_->CallRuntime(Runtime::kNumberToSmi, 1);
1297 is_smi.Bind(); 1306 is_smi.Bind();
1298 1307
1299 if (min_index != 0) { 1308 if (min_index != 0) {
1300 // Small positive numbers can be immediate operands. 1309 // Small positive numbers can be immediate operands.
1301 if (min_index < 0) { 1310 if (min_index < 0) {
1302 // If min_index is Smi::kMinValue, -min_index is not a Smi. 1311 // If min_index is Smi::kMinValue, -min_index is not a Smi.
1303 if (Smi::IsValid(-min_index)) { 1312 if (Smi::IsValid(-min_index)) {
1304 __ add(r0, r0, Operand(Smi::FromInt(-min_index))); 1313 __ add(r0, r0, Operand(Smi::FromInt(-min_index)));
1305 } else { 1314 } else {
1306 __ add(r0, r0, Operand(Smi::FromInt(-min_index - 1))); 1315 __ add(r0, r0, Operand(Smi::FromInt(-min_index - 1)));
1307 __ add(r0, r0, Operand(Smi::FromInt(1))); 1316 __ add(r0, r0, Operand(Smi::FromInt(1)));
1308 } 1317 }
1309 } else { 1318 } else {
1310 __ sub(r0, r0, Operand(Smi::FromInt(min_index))); 1319 __ sub(r0, r0, Operand(Smi::FromInt(min_index)));
1311 } 1320 }
1312 } 1321 }
1313 __ tst(r0, Operand(0x80000000 | kSmiTagMask)); 1322 __ tst(r0, Operand(0x80000000 | kSmiTagMask));
1314 fail_label->Branch(ne); 1323 __ b(ne, default_label);
1315 __ cmp(r0, Operand(Smi::FromInt(range))); 1324 __ cmp(r0, Operand(Smi::FromInt(range)));
1316 fail_label->Branch(ge); 1325 __ b(ge, default_label);
1317 __ SmiJumpTable(r0, case_targets); 1326 __ SmiJumpTable(r0, case_targets);
1318 1327
1319 JumpTarget table_start(this); 1328 frame_->MakeMergable();
1320 table_start.Bind(); 1329 VirtualFrame* start_frame = new VirtualFrame(frame_);
1321 // Table containing branch operations. 1330 // Table containing branch operations.
1322 for (int i = 0; i < range; i++) { 1331 for (int i = 0; i < range; i++) {
1323 case_targets[i]->Jump(); 1332 __ jmp(case_targets[i]);
1324 frame_ = new VirtualFrame(table_start.expected_frame());
1325 } 1333 }
1326 GenerateFastCaseSwitchCases(node, case_labels, &table_start); 1334 GenerateFastCaseSwitchCases(node, case_labels, start_frame);
1335 delete start_frame;
1327 } 1336 }
1328 1337
1329 1338
1330 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) { 1339 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
1331 Comment cmnt(masm_, "[ SwitchStatement"); 1340 Comment cmnt(masm_, "[ SwitchStatement");
1332 CodeForStatement(node); 1341 CodeForStatementPosition(node);
1333 node->set_break_stack_height(break_stack_height_); 1342 node->set_break_stack_height(break_stack_height_);
1334 node->break_target()->set_code_generator(this); 1343 node->break_target()->Initialize(this);
1335 1344
1336 Load(node->tag()); 1345 Load(node->tag());
1337
1338 if (TryGenerateFastCaseSwitchStatement(node)) { 1346 if (TryGenerateFastCaseSwitchStatement(node)) {
1339 return; 1347 return;
1340 } 1348 }
1341 1349
1342 JumpTarget next_test(this); 1350 JumpTarget next_test(this);
1343 JumpTarget fall_through(this); 1351 JumpTarget fall_through(this);
1344 JumpTarget default_entry(this); 1352 JumpTarget default_entry(this);
1345 JumpTarget default_exit(this); 1353 JumpTarget default_exit(this);
1346 ZoneList<CaseClause*>* cases = node->cases(); 1354 ZoneList<CaseClause*>* cases = node->cases();
1347 int length = cases->length(); 1355 int length = cases->length();
1348 CaseClause* default_clause = NULL; 1356 CaseClause* default_clause = NULL;
1349 1357
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1411 } 1419 }
1412 1420
1413 if (node->break_target()->is_linked()) { 1421 if (node->break_target()->is_linked()) {
1414 node->break_target()->Bind(); 1422 node->break_target()->Bind();
1415 } 1423 }
1416 } 1424 }
1417 1425
1418 1426
1419 void CodeGenerator::VisitLoopStatement(LoopStatement* node) { 1427 void CodeGenerator::VisitLoopStatement(LoopStatement* node) {
1420 Comment cmnt(masm_, "[ LoopStatement"); 1428 Comment cmnt(masm_, "[ LoopStatement");
1421 CodeForStatement(node); 1429 CodeForStatementPosition(node);
1422 node->set_break_stack_height(break_stack_height_); 1430 node->set_break_stack_height(break_stack_height_);
1423 node->break_target()->set_code_generator(this); 1431 node->break_target()->Initialize(this);
1424 node->continue_target()->set_code_generator(this); 1432 node->continue_target()->Initialize(this);
1425 1433
1426 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a 1434 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a
1427 // known result for the test expression, with no side effects. 1435 // known result for the test expression, with no side effects.
1428 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW; 1436 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW;
1429 if (node->cond() == NULL) { 1437 if (node->cond() == NULL) {
1430 ASSERT(node->type() == LoopStatement::FOR_LOOP); 1438 ASSERT(node->type() == LoopStatement::FOR_LOOP);
1431 info = ALWAYS_TRUE; 1439 info = ALWAYS_TRUE;
1432 } else { 1440 } else {
1433 Literal* lit = node->cond()->AsLiteral(); 1441 Literal* lit = node->cond()->AsLiteral();
1434 if (lit != NULL) { 1442 if (lit != NULL) {
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1565 } 1573 }
1566 } else { 1574 } else {
1567 // If there is an update statement and control flow can reach it 1575 // If there is an update statement and control flow can reach it
1568 // via falling out of the body of the loop or continuing, we 1576 // via falling out of the body of the loop or continuing, we
1569 // compile the update statement. 1577 // compile the update statement.
1570 if (frame_ != NULL || node->continue_target()->is_linked()) { 1578 if (frame_ != NULL || node->continue_target()->is_linked()) {
1571 node->continue_target()->Bind(); 1579 node->continue_target()->Bind();
1572 // Record source position of the statement as this code which is 1580 // Record source position of the statement as this code which is
1573 // after the code for the body actually belongs to the loop 1581 // after the code for the body actually belongs to the loop
1574 // statement and not the body. 1582 // statement and not the body.
1575 CodeForStatement(node); 1583 CodeForStatementPosition(node);
1576 1584
1577
1578 ASSERT(node->type() == LoopStatement::FOR_LOOP);
1579 Visit(node->next()); 1585 Visit(node->next());
1580 loop.Jump(); 1586 loop.Jump();
1581 } 1587 }
1582 } 1588 }
1583 } 1589 }
1584 break; 1590 break;
1585 } 1591 }
1586 } 1592 }
1587 1593
1588 if (node->break_target()->is_linked()) { 1594 if (node->break_target()->is_linked()) {
1589 node->break_target()->Bind(); 1595 node->break_target()->Bind();
1590 } 1596 }
1591 } 1597 }
1592 1598
1593 1599
1594 void CodeGenerator::VisitForInStatement(ForInStatement* node) { 1600 void CodeGenerator::VisitForInStatement(ForInStatement* node) {
1595 Comment cmnt(masm_, "[ ForInStatement"); 1601 Comment cmnt(masm_, "[ ForInStatement");
1596 CodeForStatement(node); 1602 CodeForStatementPosition(node);
1597 1603
1598 // We keep stuff on the stack while the body is executing. 1604 // We keep stuff on the stack while the body is executing.
1599 // Record it, so that a break/continue crossing this statement 1605 // Record it, so that a break/continue crossing this statement
1600 // can restore the stack. 1606 // can restore the stack.
1601 const int kForInStackSize = 5 * kPointerSize; 1607 const int kForInStackSize = 5 * kPointerSize;
1602 break_stack_height_ += kForInStackSize; 1608 break_stack_height_ += kForInStackSize;
1603 node->set_break_stack_height(break_stack_height_); 1609 node->set_break_stack_height(break_stack_height_);
1604 node->break_target()->set_code_generator(this); 1610 node->break_target()->Initialize(this);
1605 node->continue_target()->set_code_generator(this); 1611 node->continue_target()->Initialize(this);
1606 1612
1607 JumpTarget primitive(this); 1613 JumpTarget primitive(this);
1608 JumpTarget jsobject(this); 1614 JumpTarget jsobject(this);
1609 JumpTarget fixed_array(this); 1615 JumpTarget fixed_array(this);
1610 JumpTarget entry(this); 1616 JumpTarget entry(this);
1611 JumpTarget end_del_check(this); 1617 JumpTarget end_del_check(this);
1612 JumpTarget cleanup(this); 1618 JumpTarget cleanup(this);
1613 JumpTarget exit(this); 1619 JumpTarget exit(this);
1614 1620
1615 // Get the object to enumerate over (converted to JSObject). 1621 // Get the object to enumerate over (converted to JSObject).
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1775 1781
1776 // Exit. 1782 // Exit.
1777 exit.Bind(); 1783 exit.Bind();
1778 1784
1779 break_stack_height_ -= kForInStackSize; 1785 break_stack_height_ -= kForInStackSize;
1780 } 1786 }
1781 1787
1782 1788
1783 void CodeGenerator::VisitTryCatch(TryCatch* node) { 1789 void CodeGenerator::VisitTryCatch(TryCatch* node) {
1784 Comment cmnt(masm_, "[ TryCatch"); 1790 Comment cmnt(masm_, "[ TryCatch");
1785 CodeForStatement(node); 1791 CodeForStatementPosition(node);
1786 1792
1787 JumpTarget try_block(this); 1793 JumpTarget try_block(this);
1788 JumpTarget exit(this); 1794 JumpTarget exit(this);
1789 1795
1790 try_block.Call(); 1796 try_block.Call();
1791 // --- Catch block --- 1797 // --- Catch block ---
1792 frame_->EmitPush(r0); 1798 frame_->EmitPush(r0);
1793 1799
1794 // Store the caught exception in the catch variable. 1800 // Store the caught exception in the catch variable.
1795 { Reference ref(this, node->catch_var()); 1801 { Reference ref(this, node->catch_var());
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1875 __ mov(r3, Operand(ExternalReference(Top::k_handler_address))); 1881 __ mov(r3, Operand(ExternalReference(Top::k_handler_address)));
1876 __ ldr(sp, MemOperand(r3)); 1882 __ ldr(sp, MemOperand(r3));
1877 frame_->Forget(frame_->height() - handler_height); 1883 frame_->Forget(frame_->height() - handler_height);
1878 1884
1879 __ ldr(r1, frame_->ElementAt(kNextIndex)); 1885 __ ldr(r1, frame_->ElementAt(kNextIndex));
1880 __ str(r1, MemOperand(r3)); 1886 __ str(r1, MemOperand(r3));
1881 ASSERT(StackHandlerConstants::kCodeOffset == 0); // first field is code 1887 ASSERT(StackHandlerConstants::kCodeOffset == 0); // first field is code
1882 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); 1888 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
1883 // Code slot popped. 1889 // Code slot popped.
1884 frame_->Forget(1); 1890 frame_->Forget(1);
1885 shadows[i]->original_target()->Jump(); 1891 shadows[i]->other_target()->Jump();
1886 } 1892 }
1887 } 1893 }
1888 1894
1889 exit.Bind(); 1895 exit.Bind();
1890 } 1896 }
1891 1897
1892 1898
1893 void CodeGenerator::VisitTryFinally(TryFinally* node) { 1899 void CodeGenerator::VisitTryFinally(TryFinally* node) {
1894 Comment cmnt(masm_, "[ TryFinally"); 1900 Comment cmnt(masm_, "[ TryFinally");
1895 CodeForStatement(node); 1901 CodeForStatementPosition(node);
1896 1902
1897 // State: Used to keep track of reason for entering the finally 1903 // State: Used to keep track of reason for entering the finally
1898 // block. Should probably be extended to hold information for 1904 // block. Should probably be extended to hold information for
1899 // break/continue from within the try block. 1905 // break/continue from within the try block.
1900 enum { FALLING, THROWING, JUMPING }; 1906 enum { FALLING, THROWING, JUMPING };
1901 1907
1902 JumpTarget unlink(this); 1908 JumpTarget unlink(this);
1903 JumpTarget try_block(this); 1909 JumpTarget try_block(this);
1904 JumpTarget finally_block(this); 1910 JumpTarget finally_block(this);
1905 1911
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1954 if (nof_unlinks > 0) { 1960 if (nof_unlinks > 0) {
1955 unlink.Jump(); 1961 unlink.Jump();
1956 } 1962 }
1957 } 1963 }
1958 1964
1959 // Generate code to set the state for the (formerly) shadowing labels that 1965 // Generate code to set the state for the (formerly) shadowing labels that
1960 // have been jumped to. 1966 // have been jumped to.
1961 for (int i = 0; i <= nof_escapes; i++) { 1967 for (int i = 0; i <= nof_escapes; i++) {
1962 if (shadows[i]->is_linked()) { 1968 if (shadows[i]->is_linked()) {
1963 shadows[i]->Bind(); 1969 shadows[i]->Bind();
1964 if (shadows[i]->original_target() == &function_return_) { 1970 if (shadows[i]->other_target() == &function_return_) {
1965 // If this label shadowed the function return, materialize the 1971 // If this label shadowed the function return, materialize the
1966 // return value on the stack. 1972 // return value on the stack.
1967 frame_->EmitPush(r0); 1973 frame_->EmitPush(r0);
1968 } else { 1974 } else {
1969 // Fake TOS for labels that shadowed breaks and continues. 1975 // Fake TOS for labels that shadowed breaks and continues.
1970 __ mov(r0, Operand(Factory::undefined_value())); 1976 __ mov(r0, Operand(Factory::undefined_value()));
1971 frame_->EmitPush(r0); 1977 frame_->EmitPush(r0);
1972 } 1978 }
1973 __ mov(r2, Operand(Smi::FromInt(JUMPING + i))); 1979 __ mov(r2, Operand(Smi::FromInt(JUMPING + i)));
1974 unlink.Jump(); 1980 unlink.Jump();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2016 JumpTarget exit(this); 2022 JumpTarget exit(this);
2017 // Restore state and return value or faked TOS. 2023 // Restore state and return value or faked TOS.
2018 frame_->Pop(r2); 2024 frame_->Pop(r2);
2019 frame_->Pop(r0); 2025 frame_->Pop(r0);
2020 2026
2021 // Generate code to jump to the right destination for all used (formerly) 2027 // Generate code to jump to the right destination for all used (formerly)
2022 // shadowing labels. 2028 // shadowing labels.
2023 for (int i = 0; i <= nof_escapes; i++) { 2029 for (int i = 0; i <= nof_escapes; i++) {
2024 if (shadows[i]->is_bound()) { 2030 if (shadows[i]->is_bound()) {
2025 __ cmp(r2, Operand(Smi::FromInt(JUMPING + i))); 2031 __ cmp(r2, Operand(Smi::FromInt(JUMPING + i)));
2026 if (shadows[i]->original_target() != &function_return_) { 2032 if (shadows[i]->other_target() != &function_return_) {
2027 JumpTarget next(this); 2033 JumpTarget next(this);
2028 next.Branch(ne); 2034 next.Branch(ne);
2029 shadows[i]->original_target()->Jump(); 2035 shadows[i]->other_target()->Jump();
2030 next.Bind(); 2036 next.Bind();
2031 } else { 2037 } else {
2032 shadows[i]->original_target()->Branch(eq); 2038 shadows[i]->other_target()->Branch(eq);
2033 } 2039 }
2034 } 2040 }
2035 } 2041 }
2036 2042
2037 // Check if we need to rethrow the exception. 2043 // Check if we need to rethrow the exception.
2038 __ cmp(r2, Operand(Smi::FromInt(THROWING))); 2044 __ cmp(r2, Operand(Smi::FromInt(THROWING)));
2039 exit.Branch(ne); 2045 exit.Branch(ne);
2040 2046
2041 // Rethrow exception. 2047 // Rethrow exception.
2042 frame_->EmitPush(r0); 2048 frame_->EmitPush(r0);
2043 frame_->CallRuntime(Runtime::kReThrow, 1); 2049 frame_->CallRuntime(Runtime::kReThrow, 1);
2044 2050
2045 // Done. 2051 // Done.
2046 exit.Bind(); 2052 exit.Bind();
2047 } 2053 }
2048 } 2054 }
2049 2055
2050 2056
2051 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) { 2057 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) {
2052 Comment cmnt(masm_, "[ DebuggerStatament"); 2058 Comment cmnt(masm_, "[ DebuggerStatament");
2053 CodeForStatement(node); 2059 CodeForStatementPosition(node);
2054 frame_->CallRuntime(Runtime::kDebugBreak, 0); 2060 frame_->CallRuntime(Runtime::kDebugBreak, 0);
2055 // Ignore the return value. 2061 // Ignore the return value.
2056 } 2062 }
2057 2063
2058 2064
2059 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) { 2065 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) {
2060 ASSERT(boilerplate->IsBoilerplate()); 2066 ASSERT(boilerplate->IsBoilerplate());
2061 2067
2062 // Push the boilerplate on the stack. 2068 // Push the boilerplate on the stack.
2063 __ mov(r0, Operand(boilerplate)); 2069 __ mov(r0, Operand(boilerplate));
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
2255 __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset)); 2261 __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset));
2256 2262
2257 // Load the literal at the ast saved index. 2263 // Load the literal at the ast saved index.
2258 int literal_offset = 2264 int literal_offset =
2259 FixedArray::kHeaderSize + node->literal_index() * kPointerSize; 2265 FixedArray::kHeaderSize + node->literal_index() * kPointerSize;
2260 __ ldr(r2, FieldMemOperand(r1, literal_offset)); 2266 __ ldr(r2, FieldMemOperand(r1, literal_offset));
2261 2267
2262 // Check whether we need to materialize the object literal boilerplate. 2268 // Check whether we need to materialize the object literal boilerplate.
2263 // If so, jump to the deferred code. 2269 // If so, jump to the deferred code.
2264 __ cmp(r2, Operand(Factory::undefined_value())); 2270 __ cmp(r2, Operand(Factory::undefined_value()));
2265 __ b(eq, deferred->enter()); 2271 deferred->enter()->Branch(eq);
2266 __ bind(deferred->exit()); 2272 deferred->exit()->Bind();
2267 2273
2268 // Push the object literal boilerplate. 2274 // Push the object literal boilerplate.
2269 frame_->EmitPush(r2); 2275 frame_->EmitPush(r2);
2270 2276
2271 // Clone the boilerplate object. 2277 // Clone the boilerplate object.
2272 frame_->CallRuntime(Runtime::kCloneObjectLiteralBoilerplate, 1); 2278 frame_->CallRuntime(Runtime::kCloneObjectLiteralBoilerplate, 1);
2273 frame_->EmitPush(r0); // save the result 2279 frame_->EmitPush(r0); // save the result
2274 // r0: cloned object literal 2280 // r0: cloned object literal
2275 2281
2276 for (int i = 0; i < node->properties()->length(); i++) { 2282 for (int i = 0; i < node->properties()->length(); i++) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2358 } 2364 }
2359 2365
2360 2366
2361 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) { 2367 void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) {
2362 // Call runtime routine to allocate the catch extension object and 2368 // Call runtime routine to allocate the catch extension object and
2363 // assign the exception value to the catch variable. 2369 // assign the exception value to the catch variable.
2364 Comment cmnt(masm_, "[CatchExtensionObject "); 2370 Comment cmnt(masm_, "[CatchExtensionObject ");
2365 Load(node->key()); 2371 Load(node->key());
2366 Load(node->value()); 2372 Load(node->value());
2367 __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2); 2373 __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2);
2368 frame_->Push(r0); 2374 frame_->EmitPush(r0);
2369 } 2375 }
2370 2376
2371 2377
2372 void CodeGenerator::VisitAssignment(Assignment* node) { 2378 void CodeGenerator::VisitAssignment(Assignment* node) {
2373 Comment cmnt(masm_, "[ Assignment"); 2379 Comment cmnt(masm_, "[ Assignment");
2374 CodeForStatement(node); 2380 CodeForStatementPosition(node);
2375 2381
2376 Reference target(this, node->target()); 2382 Reference target(this, node->target());
2377 if (target.is_illegal()) { 2383 if (target.is_illegal()) {
2378 // Fool the virtual frame into thinking that we left the assignment's 2384 // Fool the virtual frame into thinking that we left the assignment's
2379 // value on the frame. 2385 // value on the frame.
2380 __ mov(r0, Operand(Smi::FromInt(0))); 2386 __ mov(r0, Operand(Smi::FromInt(0)));
2381 frame_->EmitPush(r0); 2387 frame_->EmitPush(r0);
2382 return; 2388 return;
2383 } 2389 }
2384 2390
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2437 Reference property(this, node); 2443 Reference property(this, node);
2438 property.GetValue(typeof_state()); 2444 property.GetValue(typeof_state());
2439 } 2445 }
2440 2446
2441 2447
2442 void CodeGenerator::VisitCall(Call* node) { 2448 void CodeGenerator::VisitCall(Call* node) {
2443 Comment cmnt(masm_, "[ Call"); 2449 Comment cmnt(masm_, "[ Call");
2444 2450
2445 ZoneList<Expression*>* args = node->arguments(); 2451 ZoneList<Expression*>* args = node->arguments();
2446 2452
2447 CodeForStatement(node); 2453 CodeForStatementPosition(node);
2448 // Standard function call. 2454 // Standard function call.
2449 2455
2450 // Check if the function is a variable or a property. 2456 // Check if the function is a variable or a property.
2451 Expression* function = node->expression(); 2457 Expression* function = node->expression();
2452 Variable* var = function->AsVariableProxy()->AsVariable(); 2458 Variable* var = function->AsVariableProxy()->AsVariable();
2453 Property* property = function->AsProperty(); 2459 Property* property = function->AsProperty();
2454 2460
2455 // ------------------------------------------------------------------------ 2461 // ------------------------------------------------------------------------
2456 // Fast-case: Use inline caching. 2462 // Fast-case: Use inline caching.
2457 // --- 2463 // ---
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
2581 void CodeGenerator::VisitCallEval(CallEval* node) { 2587 void CodeGenerator::VisitCallEval(CallEval* node) {
2582 Comment cmnt(masm_, "[ CallEval"); 2588 Comment cmnt(masm_, "[ CallEval");
2583 2589
2584 // In a call to eval, we first call %ResolvePossiblyDirectEval to resolve 2590 // In a call to eval, we first call %ResolvePossiblyDirectEval to resolve
2585 // the function we need to call and the receiver of the call. 2591 // the function we need to call and the receiver of the call.
2586 // Then we call the resolved function using the given arguments. 2592 // Then we call the resolved function using the given arguments.
2587 2593
2588 ZoneList<Expression*>* args = node->arguments(); 2594 ZoneList<Expression*>* args = node->arguments();
2589 Expression* function = node->expression(); 2595 Expression* function = node->expression();
2590 2596
2591 CodeForStatement(node); 2597 CodeForStatementPosition(node);
2592 2598
2593 // Prepare stack for call to resolved function. 2599 // Prepare stack for call to resolved function.
2594 Load(function); 2600 Load(function);
2595 __ mov(r2, Operand(Factory::undefined_value())); 2601 __ mov(r2, Operand(Factory::undefined_value()));
2596 __ push(r2); // Slot for receiver 2602 __ push(r2); // Slot for receiver
2597 for (int i = 0; i < args->length(); i++) { 2603 for (int i = 0; i < args->length(); i++) {
2598 Load(args->at(i)); 2604 Load(args->at(i));
2599 } 2605 }
2600 2606
2601 // Prepare stack for call to ResolvePossiblyDirectEval. 2607 // Prepare stack for call to ResolvePossiblyDirectEval.
(...skipping 16 matching lines...) Expand all
2618 __ str(r1, MemOperand(sp, args->length() * kPointerSize)); 2624 __ str(r1, MemOperand(sp, args->length() * kPointerSize));
2619 2625
2620 // Call the function. 2626 // Call the function.
2621 CodeForSourcePosition(node->position()); 2627 CodeForSourcePosition(node->position());
2622 2628
2623 CallFunctionStub call_function(args->length()); 2629 CallFunctionStub call_function(args->length());
2624 __ CallStub(&call_function); 2630 __ CallStub(&call_function);
2625 2631
2626 __ ldr(cp, frame_->Context()); 2632 __ ldr(cp, frame_->Context());
2627 // Remove the function from the stack. 2633 // Remove the function from the stack.
2628 frame_->Pop(); 2634 frame_->Drop();
2629 frame_->Push(r0); 2635 frame_->EmitPush(r0);
2630 } 2636 }
2631 2637
2632 2638
2633 void CodeGenerator::VisitCallNew(CallNew* node) { 2639 void CodeGenerator::VisitCallNew(CallNew* node) {
2634 Comment cmnt(masm_, "[ CallNew"); 2640 Comment cmnt(masm_, "[ CallNew");
2635 CodeForStatement(node); 2641 CodeForStatementPosition(node);
2636 2642
2637 // According to ECMA-262, section 11.2.2, page 44, the function 2643 // According to ECMA-262, section 11.2.2, page 44, the function
2638 // expression in new calls must be evaluated before the 2644 // expression in new calls must be evaluated before the
2639 // arguments. This is different from ordinary calls, where the 2645 // arguments. This is different from ordinary calls, where the
2640 // actual function to call is resolved after the arguments have been 2646 // actual function to call is resolved after the arguments have been
2641 // evaluated. 2647 // evaluated.
2642 2648
2643 // Compute function to call and use the global object as the 2649 // Compute function to call and use the global object as the
2644 // receiver. There is no need to use the global proxy here because 2650 // receiver. There is no need to use the global proxy here because
2645 // it will always be replaced with a newly allocated object. 2651 // it will always be replaced with a newly allocated object.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
2731 // See comment in CodeGenerator::GenerateLog in codegen-ia32.cc. 2737 // See comment in CodeGenerator::GenerateLog in codegen-ia32.cc.
2732 ASSERT_EQ(args->length(), 3); 2738 ASSERT_EQ(args->length(), 3);
2733 #ifdef ENABLE_LOGGING_AND_PROFILING 2739 #ifdef ENABLE_LOGGING_AND_PROFILING
2734 if (ShouldGenerateLog(args->at(0))) { 2740 if (ShouldGenerateLog(args->at(0))) {
2735 Load(args->at(1)); 2741 Load(args->at(1));
2736 Load(args->at(2)); 2742 Load(args->at(2));
2737 __ CallRuntime(Runtime::kLog, 2); 2743 __ CallRuntime(Runtime::kLog, 2);
2738 } 2744 }
2739 #endif 2745 #endif
2740 __ mov(r0, Operand(Factory::undefined_value())); 2746 __ mov(r0, Operand(Factory::undefined_value()));
2741 frame_->Push(r0); 2747 frame_->EmitPush(r0);
2742 } 2748 }
2743 2749
2744 2750
2745 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) { 2751 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) {
2746 ASSERT(args->length() == 1); 2752 ASSERT(args->length() == 1);
2747 Load(args->at(0)); 2753 Load(args->at(0));
2748 frame_->Pop(r0); 2754 frame_->Pop(r0);
2749 __ tst(r0, Operand(kSmiTagMask | 0x80000000)); 2755 __ tst(r0, Operand(kSmiTagMask | 0x80000000));
2750 cc_reg_ = eq; 2756 cc_reg_ = eq;
2751 } 2757 }
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after
3394 __ tst(r0, Operand(r0)); 3400 __ tst(r0, Operand(r0));
3395 cc_reg_ = eq; 3401 cc_reg_ = eq;
3396 break; 3402 break;
3397 3403
3398 default: 3404 default:
3399 UNREACHABLE(); 3405 UNREACHABLE();
3400 } 3406 }
3401 } 3407 }
3402 3408
3403 3409
3410 #ifdef DEBUG
3411 bool CodeGenerator::HasValidEntryRegisters() { return true; }
3412 #endif
3413
3414
3404 bool CodeGenerator::IsActualFunctionReturn(JumpTarget* target) { 3415 bool CodeGenerator::IsActualFunctionReturn(JumpTarget* target) {
3405 return (target == &function_return_ && !function_return_is_shadowed_); 3416 return (target == &function_return_ && !function_return_is_shadowed_);
3406 } 3417 }
3407 3418
3408 3419
3409 #undef __ 3420 #undef __
3410 #define __ masm-> 3421 #define __ masm->
3411 3422
3412 Handle<String> Reference::GetName() { 3423 Handle<String> Reference::GetName() {
3413 ASSERT(type_ == NAMED); 3424 ASSERT(type_ == NAMED);
(...skipping 1110 matching lines...) Expand 10 before | Expand all | Expand 10 after
4524 __ mov(r2, Operand(0)); 4535 __ mov(r2, Operand(0));
4525 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); 4536 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
4526 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), 4537 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)),
4527 RelocInfo::CODE_TARGET); 4538 RelocInfo::CODE_TARGET);
4528 } 4539 }
4529 4540
4530 4541
4531 #undef __ 4542 #undef __
4532 4543
4533 } } // namespace v8::internal 4544 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/codegen-arm.h ('k') | src/jump-target-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698