| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 Handle<JSFunction> boilerplate = | 655 Handle<JSFunction> boilerplate = |
| 656 Compiler::BuildBoilerplate(expr, script_, this); | 656 Compiler::BuildBoilerplate(expr, script_, this); |
| 657 if (HasStackOverflow()) return; | 657 if (HasStackOverflow()) return; |
| 658 | 658 |
| 659 ASSERT(boilerplate->IsBoilerplate()); | 659 ASSERT(boilerplate->IsBoilerplate()); |
| 660 | 660 |
| 661 // Create a new closure. | 661 // Create a new closure. |
| 662 __ mov(r0, Operand(boilerplate)); | 662 __ mov(r0, Operand(boilerplate)); |
| 663 __ stm(db_w, sp, cp.bit() | r0.bit()); | 663 __ stm(db_w, sp, cp.bit() | r0.bit()); |
| 664 __ CallRuntime(Runtime::kNewClosure, 2); | 664 __ CallRuntime(Runtime::kNewClosure, 2); |
| 665 Apply(expr->context(), r0); | 665 Apply(context_, r0); |
| 666 } | 666 } |
| 667 | 667 |
| 668 | 668 |
| 669 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { | 669 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { |
| 670 Comment cmnt(masm_, "[ VariableProxy"); | 670 Comment cmnt(masm_, "[ VariableProxy"); |
| 671 EmitVariableLoad(expr->var(), expr->context()); | 671 EmitVariableLoad(expr->var(), context_); |
| 672 } | 672 } |
| 673 | 673 |
| 674 | 674 |
| 675 void FastCodeGenerator::EmitVariableLoad(Variable* var, | 675 void FastCodeGenerator::EmitVariableLoad(Variable* var, |
| 676 Expression::Context context) { | 676 Expression::Context context) { |
| 677 Expression* rewrite = var->rewrite(); | 677 Expression* rewrite = var->rewrite(); |
| 678 if (rewrite == NULL) { | 678 if (rewrite == NULL) { |
| 679 ASSERT(var->is_global()); | 679 ASSERT(var->is_global()); |
| 680 Comment cmnt(masm_, "Global variable"); | 680 Comment cmnt(masm_, "Global variable"); |
| 681 // Use inline caching. Variable name is passed in r2 and the global | 681 // Use inline caching. Variable name is passed in r2 and the global |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 761 __ ldr(r0, FieldMemOperand(r4, literal_offset)); | 761 __ ldr(r0, FieldMemOperand(r4, literal_offset)); |
| 762 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 762 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 763 __ cmp(r0, ip); | 763 __ cmp(r0, ip); |
| 764 __ b(ne, &done); | 764 __ b(ne, &done); |
| 765 __ mov(r3, Operand(Smi::FromInt(expr->literal_index()))); | 765 __ mov(r3, Operand(Smi::FromInt(expr->literal_index()))); |
| 766 __ mov(r2, Operand(expr->pattern())); | 766 __ mov(r2, Operand(expr->pattern())); |
| 767 __ mov(r1, Operand(expr->flags())); | 767 __ mov(r1, Operand(expr->flags())); |
| 768 __ stm(db_w, sp, r4.bit() | r3.bit() | r2.bit() | r1.bit()); | 768 __ stm(db_w, sp, r4.bit() | r3.bit() | r2.bit() | r1.bit()); |
| 769 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); | 769 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); |
| 770 __ bind(&done); | 770 __ bind(&done); |
| 771 Apply(expr->context(), r0); | 771 Apply(context_, r0); |
| 772 } | 772 } |
| 773 | 773 |
| 774 | 774 |
| 775 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { | 775 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
| 776 Comment cmnt(masm_, "[ ObjectLiteral"); | 776 Comment cmnt(masm_, "[ ObjectLiteral"); |
| 777 __ ldr(r2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 777 __ ldr(r2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 778 __ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset)); | 778 __ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset)); |
| 779 __ mov(r1, Operand(Smi::FromInt(expr->literal_index()))); | 779 __ mov(r1, Operand(Smi::FromInt(expr->literal_index()))); |
| 780 __ mov(r0, Operand(expr->constant_properties())); | 780 __ mov(r0, Operand(expr->constant_properties())); |
| 781 __ stm(db_w, sp, r2.bit() | r1.bit() | r0.bit()); | 781 __ stm(db_w, sp, r2.bit() | r1.bit() | r0.bit()); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 833 Smi::FromInt(1) : | 833 Smi::FromInt(1) : |
| 834 Smi::FromInt(0))); | 834 Smi::FromInt(0))); |
| 835 __ push(r1); | 835 __ push(r1); |
| 836 VisitForValue(value, kStack); | 836 VisitForValue(value, kStack); |
| 837 __ CallRuntime(Runtime::kDefineAccessor, 4); | 837 __ CallRuntime(Runtime::kDefineAccessor, 4); |
| 838 break; | 838 break; |
| 839 } | 839 } |
| 840 } | 840 } |
| 841 | 841 |
| 842 if (result_saved) { | 842 if (result_saved) { |
| 843 ApplyTOS(expr->context()); | 843 ApplyTOS(context_); |
| 844 } else { | 844 } else { |
| 845 Apply(expr->context(), r0); | 845 Apply(context_, r0); |
| 846 } | 846 } |
| 847 } | 847 } |
| 848 | 848 |
| 849 | 849 |
| 850 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 850 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
| 851 Comment cmnt(masm_, "[ ArrayLiteral"); | 851 Comment cmnt(masm_, "[ ArrayLiteral"); |
| 852 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 852 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 853 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); | 853 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); |
| 854 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); | 854 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); |
| 855 __ mov(r1, Operand(expr->constant_elements())); | 855 __ mov(r1, Operand(expr->constant_elements())); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 886 int offset = FixedArray::kHeaderSize + (i * kPointerSize); | 886 int offset = FixedArray::kHeaderSize + (i * kPointerSize); |
| 887 __ str(result_register(), FieldMemOperand(r1, offset)); | 887 __ str(result_register(), FieldMemOperand(r1, offset)); |
| 888 | 888 |
| 889 // Update the write barrier for the array store with r0 as the scratch | 889 // Update the write barrier for the array store with r0 as the scratch |
| 890 // register. | 890 // register. |
| 891 __ mov(r2, Operand(offset)); | 891 __ mov(r2, Operand(offset)); |
| 892 __ RecordWrite(r1, r2, result_register()); | 892 __ RecordWrite(r1, r2, result_register()); |
| 893 } | 893 } |
| 894 | 894 |
| 895 if (result_saved) { | 895 if (result_saved) { |
| 896 ApplyTOS(expr->context()); | 896 ApplyTOS(context_); |
| 897 } else { | 897 } else { |
| 898 Apply(expr->context(), r0); | 898 Apply(context_, r0); |
| 899 } | 899 } |
| 900 } | 900 } |
| 901 | 901 |
| 902 | 902 |
| 903 void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 903 void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 904 SetSourcePosition(prop->position()); | 904 SetSourcePosition(prop->position()); |
| 905 Literal* key = prop->key()->AsLiteral(); | 905 Literal* key = prop->key()->AsLiteral(); |
| 906 __ mov(r2, Operand(key->handle())); | 906 __ mov(r2, Operand(key->handle())); |
| 907 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 907 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 908 __ Call(ic, RelocInfo::CODE_TARGET); | 908 __ Call(ic, RelocInfo::CODE_TARGET); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1000 | 1000 |
| 1001 // If the assignment ends an initialization block, revert to fast case. | 1001 // If the assignment ends an initialization block, revert to fast case. |
| 1002 if (expr->ends_initialization_block()) { | 1002 if (expr->ends_initialization_block()) { |
| 1003 __ push(r0); // Result of assignment, saved even if not needed. | 1003 __ push(r0); // Result of assignment, saved even if not needed. |
| 1004 __ ldr(ip, MemOperand(sp, kPointerSize)); // Receiver is under value. | 1004 __ ldr(ip, MemOperand(sp, kPointerSize)); // Receiver is under value. |
| 1005 __ push(ip); | 1005 __ push(ip); |
| 1006 __ CallRuntime(Runtime::kToFastProperties, 1); | 1006 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1007 __ pop(r0); | 1007 __ pop(r0); |
| 1008 } | 1008 } |
| 1009 | 1009 |
| 1010 DropAndApply(1, expr->context(), r0); | 1010 DropAndApply(1, context_, r0); |
| 1011 } | 1011 } |
| 1012 | 1012 |
| 1013 | 1013 |
| 1014 void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 1014 void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 1015 // Assignment to a property, using a keyed store IC. | 1015 // Assignment to a property, using a keyed store IC. |
| 1016 | 1016 |
| 1017 // If the assignment starts a block of assignments to the same object, | 1017 // If the assignment starts a block of assignments to the same object, |
| 1018 // change to slow case to avoid the quadratic behavior of repeatedly | 1018 // change to slow case to avoid the quadratic behavior of repeatedly |
| 1019 // adding fast properties. | 1019 // adding fast properties. |
| 1020 if (expr->starts_initialization_block()) { | 1020 if (expr->starts_initialization_block()) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1035 if (expr->ends_initialization_block()) { | 1035 if (expr->ends_initialization_block()) { |
| 1036 __ push(r0); // Result of assignment, saved even if not needed. | 1036 __ push(r0); // Result of assignment, saved even if not needed. |
| 1037 // Receiver is under the key and value. | 1037 // Receiver is under the key and value. |
| 1038 __ ldr(ip, MemOperand(sp, 2 * kPointerSize)); | 1038 __ ldr(ip, MemOperand(sp, 2 * kPointerSize)); |
| 1039 __ push(ip); | 1039 __ push(ip); |
| 1040 __ CallRuntime(Runtime::kToFastProperties, 1); | 1040 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1041 __ pop(r0); | 1041 __ pop(r0); |
| 1042 } | 1042 } |
| 1043 | 1043 |
| 1044 // Receiver and key are still on stack. | 1044 // Receiver and key are still on stack. |
| 1045 DropAndApply(2, expr->context(), r0); | 1045 DropAndApply(2, context_, r0); |
| 1046 } | 1046 } |
| 1047 | 1047 |
| 1048 | 1048 |
| 1049 void FastCodeGenerator::VisitProperty(Property* expr) { | 1049 void FastCodeGenerator::VisitProperty(Property* expr) { |
| 1050 Comment cmnt(masm_, "[ Property"); | 1050 Comment cmnt(masm_, "[ Property"); |
| 1051 Expression* key = expr->key(); | 1051 Expression* key = expr->key(); |
| 1052 | 1052 |
| 1053 // Evaluate receiver. | 1053 // Evaluate receiver. |
| 1054 VisitForValue(expr->obj(), kStack); | 1054 VisitForValue(expr->obj(), kStack); |
| 1055 | 1055 |
| 1056 if (key->IsPropertyName()) { | 1056 if (key->IsPropertyName()) { |
| 1057 EmitNamedPropertyLoad(expr); | 1057 EmitNamedPropertyLoad(expr); |
| 1058 // Drop receiver left on the stack by IC. | 1058 // Drop receiver left on the stack by IC. |
| 1059 DropAndApply(1, expr->context(), r0); | 1059 DropAndApply(1, context_, r0); |
| 1060 } else { | 1060 } else { |
| 1061 VisitForValue(expr->key(), kStack); | 1061 VisitForValue(expr->key(), kStack); |
| 1062 EmitKeyedPropertyLoad(expr); | 1062 EmitKeyedPropertyLoad(expr); |
| 1063 // Drop key and receiver left on the stack by IC. | 1063 // Drop key and receiver left on the stack by IC. |
| 1064 DropAndApply(2, expr->context(), r0); | 1064 DropAndApply(2, context_, r0); |
| 1065 } | 1065 } |
| 1066 } | 1066 } |
| 1067 | 1067 |
| 1068 void FastCodeGenerator::EmitCallWithIC(Call* expr, | 1068 void FastCodeGenerator::EmitCallWithIC(Call* expr, |
| 1069 Handle<Object> ignored, | 1069 Handle<Object> ignored, |
| 1070 RelocInfo::Mode mode) { | 1070 RelocInfo::Mode mode) { |
| 1071 // Code common for calls using the IC. | 1071 // Code common for calls using the IC. |
| 1072 ZoneList<Expression*>* args = expr->arguments(); | 1072 ZoneList<Expression*>* args = expr->arguments(); |
| 1073 int arg_count = args->length(); | 1073 int arg_count = args->length(); |
| 1074 for (int i = 0; i < arg_count; i++) { | 1074 for (int i = 0; i < arg_count; i++) { |
| 1075 VisitForValue(args->at(i), kStack); | 1075 VisitForValue(args->at(i), kStack); |
| 1076 } | 1076 } |
| 1077 // Record source position for debugger. | 1077 // Record source position for debugger. |
| 1078 SetSourcePosition(expr->position()); | 1078 SetSourcePosition(expr->position()); |
| 1079 // Call the IC initialization code. | 1079 // Call the IC initialization code. |
| 1080 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, | 1080 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, |
| 1081 NOT_IN_LOOP); | 1081 NOT_IN_LOOP); |
| 1082 __ Call(ic, mode); | 1082 __ Call(ic, mode); |
| 1083 // Restore context register. | 1083 // Restore context register. |
| 1084 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1084 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 1085 // Discard the function left on TOS. | 1085 // Discard the function left on TOS. |
| 1086 DropAndApply(1, expr->context(), r0); | 1086 DropAndApply(1, context_, r0); |
| 1087 } | 1087 } |
| 1088 | 1088 |
| 1089 | 1089 |
| 1090 void FastCodeGenerator::EmitCallWithStub(Call* expr) { | 1090 void FastCodeGenerator::EmitCallWithStub(Call* expr) { |
| 1091 // Code common for calls using the call stub. | 1091 // Code common for calls using the call stub. |
| 1092 ZoneList<Expression*>* args = expr->arguments(); | 1092 ZoneList<Expression*>* args = expr->arguments(); |
| 1093 int arg_count = args->length(); | 1093 int arg_count = args->length(); |
| 1094 for (int i = 0; i < arg_count; i++) { | 1094 for (int i = 0; i < arg_count; i++) { |
| 1095 VisitForValue(args->at(i), kStack); | 1095 VisitForValue(args->at(i), kStack); |
| 1096 } | 1096 } |
| 1097 // Record source position for debugger. | 1097 // Record source position for debugger. |
| 1098 SetSourcePosition(expr->position()); | 1098 SetSourcePosition(expr->position()); |
| 1099 CallFunctionStub stub(arg_count, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE); | 1099 CallFunctionStub stub(arg_count, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE); |
| 1100 __ CallStub(&stub); | 1100 __ CallStub(&stub); |
| 1101 // Restore context register. | 1101 // Restore context register. |
| 1102 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1102 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 1103 // Discard the function left on TOS. | 1103 // Discard the function left on TOS. |
| 1104 DropAndApply(1, expr->context(), r0); | 1104 DropAndApply(1, context_, r0); |
| 1105 } | 1105 } |
| 1106 | 1106 |
| 1107 | 1107 |
| 1108 void FastCodeGenerator::VisitCall(Call* expr) { | 1108 void FastCodeGenerator::VisitCall(Call* expr) { |
| 1109 Comment cmnt(masm_, "[ Call"); | 1109 Comment cmnt(masm_, "[ Call"); |
| 1110 Expression* fun = expr->expression(); | 1110 Expression* fun = expr->expression(); |
| 1111 Variable* var = fun->AsVariableProxy()->AsVariable(); | 1111 Variable* var = fun->AsVariableProxy()->AsVariable(); |
| 1112 | 1112 |
| 1113 if (var != NULL && var->is_possibly_eval()) { | 1113 if (var != NULL && var->is_possibly_eval()) { |
| 1114 // Call to the identifier 'eval'. | 1114 // Call to the identifier 'eval'. |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1200 | 1200 |
| 1201 // Load function, arg_count into r1 and r0. | 1201 // Load function, arg_count into r1 and r0. |
| 1202 __ mov(r0, Operand(arg_count)); | 1202 __ mov(r0, Operand(arg_count)); |
| 1203 // Function is in sp[arg_count + 1]. | 1203 // Function is in sp[arg_count + 1]. |
| 1204 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 1204 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 1205 | 1205 |
| 1206 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); | 1206 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); |
| 1207 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); | 1207 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); |
| 1208 | 1208 |
| 1209 // Replace function on TOS with result in r0, or pop it. | 1209 // Replace function on TOS with result in r0, or pop it. |
| 1210 DropAndApply(1, expr->context(), r0); | 1210 DropAndApply(1, context_, r0); |
| 1211 } | 1211 } |
| 1212 | 1212 |
| 1213 | 1213 |
| 1214 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 1214 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
| 1215 Comment cmnt(masm_, "[ CallRuntime"); | 1215 Comment cmnt(masm_, "[ CallRuntime"); |
| 1216 ZoneList<Expression*>* args = expr->arguments(); | 1216 ZoneList<Expression*>* args = expr->arguments(); |
| 1217 | 1217 |
| 1218 if (expr->is_jsruntime()) { | 1218 if (expr->is_jsruntime()) { |
| 1219 // Prepare for calling JS runtime function. | 1219 // Prepare for calling JS runtime function. |
| 1220 __ mov(r1, Operand(expr->name())); | 1220 __ mov(r1, Operand(expr->name())); |
| 1221 __ ldr(r0, CodeGenerator::GlobalObject()); | 1221 __ ldr(r0, CodeGenerator::GlobalObject()); |
| 1222 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kBuiltinsOffset)); | 1222 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kBuiltinsOffset)); |
| 1223 __ stm(db_w, sp, r1.bit() | r0.bit()); | 1223 __ stm(db_w, sp, r1.bit() | r0.bit()); |
| 1224 } | 1224 } |
| 1225 | 1225 |
| 1226 // Push the arguments ("left-to-right"). | 1226 // Push the arguments ("left-to-right"). |
| 1227 int arg_count = args->length(); | 1227 int arg_count = args->length(); |
| 1228 for (int i = 0; i < arg_count; i++) { | 1228 for (int i = 0; i < arg_count; i++) { |
| 1229 VisitForValue(args->at(i), kStack); | 1229 VisitForValue(args->at(i), kStack); |
| 1230 } | 1230 } |
| 1231 | 1231 |
| 1232 if (expr->is_jsruntime()) { | 1232 if (expr->is_jsruntime()) { |
| 1233 // Call the JS runtime function. | 1233 // Call the JS runtime function. |
| 1234 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, | 1234 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, |
| 1235 NOT_IN_LOOP); | 1235 NOT_IN_LOOP); |
| 1236 __ Call(ic, RelocInfo::CODE_TARGET); | 1236 __ Call(ic, RelocInfo::CODE_TARGET); |
| 1237 // Restore context register. | 1237 // Restore context register. |
| 1238 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1238 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 1239 // Discard the function left on TOS. | 1239 // Discard the function left on TOS. |
| 1240 DropAndApply(1, expr->context(), r0); | 1240 DropAndApply(1, context_, r0); |
| 1241 } else { | 1241 } else { |
| 1242 // Call the C runtime function. | 1242 // Call the C runtime function. |
| 1243 __ CallRuntime(expr->function(), arg_count); | 1243 __ CallRuntime(expr->function(), arg_count); |
| 1244 Apply(expr->context(), r0); | 1244 Apply(context_, r0); |
| 1245 } | 1245 } |
| 1246 } | 1246 } |
| 1247 | 1247 |
| 1248 | 1248 |
| 1249 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 1249 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
| 1250 switch (expr->op()) { | 1250 switch (expr->op()) { |
| 1251 case Token::VOID: { | 1251 case Token::VOID: { |
| 1252 Comment cmnt(masm_, "[ UnaryOperation (VOID)"); | 1252 Comment cmnt(masm_, "[ UnaryOperation (VOID)"); |
| 1253 ASSERT_EQ(Expression::kEffect, expr->expression()->context()); | 1253 VisitForEffect(expr->expression()); |
| 1254 Visit(expr->expression()); | 1254 switch (context_) { |
| 1255 switch (expr->context()) { | |
| 1256 case Expression::kUninitialized: | 1255 case Expression::kUninitialized: |
| 1257 UNREACHABLE(); | 1256 UNREACHABLE(); |
| 1258 break; | 1257 break; |
| 1259 case Expression::kEffect: | 1258 case Expression::kEffect: |
| 1260 break; | 1259 break; |
| 1261 case Expression::kValue: | 1260 case Expression::kValue: |
| 1262 __ LoadRoot(result_register(), Heap::kUndefinedValueRootIndex); | 1261 __ LoadRoot(result_register(), Heap::kUndefinedValueRootIndex); |
| 1263 switch (location_) { | 1262 switch (location_) { |
| 1264 case kAccumulator: | 1263 case kAccumulator: |
| 1265 break; | 1264 break; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1282 case Expression::kTest: | 1281 case Expression::kTest: |
| 1283 case Expression::kValueTest: | 1282 case Expression::kValueTest: |
| 1284 __ jmp(false_label_); | 1283 __ jmp(false_label_); |
| 1285 break; | 1284 break; |
| 1286 } | 1285 } |
| 1287 break; | 1286 break; |
| 1288 } | 1287 } |
| 1289 | 1288 |
| 1290 case Token::NOT: { | 1289 case Token::NOT: { |
| 1291 Comment cmnt(masm_, "[ UnaryOperation (NOT)"); | 1290 Comment cmnt(masm_, "[ UnaryOperation (NOT)"); |
| 1292 ASSERT_EQ(Expression::kTest, expr->expression()->context()); | |
| 1293 | |
| 1294 Label materialize_true, materialize_false, done; | 1291 Label materialize_true, materialize_false, done; |
| 1295 // Initially assume a pure test context. Notice that the labels are | 1292 // Initially assume a pure test context. Notice that the labels are |
| 1296 // swapped. | 1293 // swapped. |
| 1297 Label* if_true = false_label_; | 1294 Label* if_true = false_label_; |
| 1298 Label* if_false = true_label_; | 1295 Label* if_false = true_label_; |
| 1299 switch (expr->context()) { | 1296 switch (context_) { |
| 1300 case Expression::kUninitialized: | 1297 case Expression::kUninitialized: |
| 1301 UNREACHABLE(); | 1298 UNREACHABLE(); |
| 1302 break; | 1299 break; |
| 1303 case Expression::kEffect: | 1300 case Expression::kEffect: |
| 1304 if_true = &done; | 1301 if_true = &done; |
| 1305 if_false = &done; | 1302 if_false = &done; |
| 1306 break; | 1303 break; |
| 1307 case Expression::kValue: | 1304 case Expression::kValue: |
| 1308 if_true = &materialize_false; | 1305 if_true = &materialize_false; |
| 1309 if_false = &materialize_true; | 1306 if_false = &materialize_true; |
| 1310 break; | 1307 break; |
| 1311 case Expression::kTest: | 1308 case Expression::kTest: |
| 1312 break; | 1309 break; |
| 1313 case Expression::kValueTest: | 1310 case Expression::kValueTest: |
| 1314 if_false = &materialize_true; | 1311 if_false = &materialize_true; |
| 1315 break; | 1312 break; |
| 1316 case Expression::kTestValue: | 1313 case Expression::kTestValue: |
| 1317 if_true = &materialize_false; | 1314 if_true = &materialize_false; |
| 1318 break; | 1315 break; |
| 1319 } | 1316 } |
| 1320 VisitForControl(expr->expression(), if_true, if_false); | 1317 VisitForControl(expr->expression(), if_true, if_false); |
| 1321 Apply(expr->context(), if_false, if_true); // Labels swapped. | 1318 Apply(context_, if_false, if_true); // Labels swapped. |
| 1322 break; | 1319 break; |
| 1323 } | 1320 } |
| 1324 | 1321 |
| 1325 case Token::TYPEOF: { | 1322 case Token::TYPEOF: { |
| 1326 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); | 1323 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); |
| 1327 ASSERT_EQ(Expression::kValue, expr->expression()->context()); | |
| 1328 | |
| 1329 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 1324 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 1330 if (proxy != NULL && | 1325 if (proxy != NULL && |
| 1331 !proxy->var()->is_this() && | 1326 !proxy->var()->is_this() && |
| 1332 proxy->var()->is_global()) { | 1327 proxy->var()->is_global()) { |
| 1333 Comment cmnt(masm_, "Global variable"); | 1328 Comment cmnt(masm_, "Global variable"); |
| 1334 __ ldr(r0, CodeGenerator::GlobalObject()); | 1329 __ ldr(r0, CodeGenerator::GlobalObject()); |
| 1335 __ push(r0); | 1330 __ push(r0); |
| 1336 __ mov(r2, Operand(proxy->name())); | 1331 __ mov(r2, Operand(proxy->name())); |
| 1337 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1332 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 1338 // Use a regular load, not a contextual load, to avoid a reference | 1333 // Use a regular load, not a contextual load, to avoid a reference |
| 1339 // error. | 1334 // error. |
| 1340 __ Call(ic, RelocInfo::CODE_TARGET); | 1335 __ Call(ic, RelocInfo::CODE_TARGET); |
| 1341 __ str(r0, MemOperand(sp)); | 1336 __ str(r0, MemOperand(sp)); |
| 1342 } else if (proxy != NULL && | 1337 } else if (proxy != NULL && |
| 1343 proxy->var()->slot() != NULL && | 1338 proxy->var()->slot() != NULL && |
| 1344 proxy->var()->slot()->type() == Slot::LOOKUP) { | 1339 proxy->var()->slot()->type() == Slot::LOOKUP) { |
| 1345 __ mov(r0, Operand(proxy->name())); | 1340 __ mov(r0, Operand(proxy->name())); |
| 1346 __ stm(db_w, sp, cp.bit() | r0.bit()); | 1341 __ stm(db_w, sp, cp.bit() | r0.bit()); |
| 1347 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); | 1342 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); |
| 1348 __ push(r0); | 1343 __ push(r0); |
| 1349 } else { | 1344 } else { |
| 1350 // This expression cannot throw a reference error at the top level. | 1345 // This expression cannot throw a reference error at the top level. |
| 1351 VisitForValue(expr->expression(), kStack); | 1346 VisitForValue(expr->expression(), kStack); |
| 1352 } | 1347 } |
| 1353 | 1348 |
| 1354 __ CallRuntime(Runtime::kTypeof, 1); | 1349 __ CallRuntime(Runtime::kTypeof, 1); |
| 1355 Apply(expr->context(), r0); | 1350 Apply(context_, r0); |
| 1356 break; | 1351 break; |
| 1357 } | 1352 } |
| 1358 | 1353 |
| 1359 default: | 1354 default: |
| 1360 UNREACHABLE(); | 1355 UNREACHABLE(); |
| 1361 } | 1356 } |
| 1362 } | 1357 } |
| 1363 | 1358 |
| 1364 | 1359 |
| 1365 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { | 1360 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { |
| 1366 Comment cmnt(masm_, "[ CountOperation"); | 1361 Comment cmnt(masm_, "[ CountOperation"); |
| 1367 | 1362 |
| 1368 // Expression can only be a property, a global or a (parameter or local) | 1363 // Expression can only be a property, a global or a (parameter or local) |
| 1369 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. | 1364 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. |
| 1370 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; | 1365 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; |
| 1371 LhsKind assign_type = VARIABLE; | 1366 LhsKind assign_type = VARIABLE; |
| 1372 Property* prop = expr->expression()->AsProperty(); | 1367 Property* prop = expr->expression()->AsProperty(); |
| 1373 // In case of a property we use the uninitialized expression context | 1368 // In case of a property we use the uninitialized expression context |
| 1374 // of the key to detect a named property. | 1369 // of the key to detect a named property. |
| 1375 if (prop != NULL) { | 1370 if (prop != NULL) { |
| 1376 assign_type = (prop->key()->context() == Expression::kUninitialized) | 1371 assign_type = |
| 1377 ? NAMED_PROPERTY | 1372 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; |
| 1378 : KEYED_PROPERTY; | |
| 1379 } | 1373 } |
| 1380 | 1374 |
| 1381 // Evaluate expression and get value. | 1375 // Evaluate expression and get value. |
| 1382 if (assign_type == VARIABLE) { | 1376 if (assign_type == VARIABLE) { |
| 1383 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); | 1377 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); |
| 1384 Location saved_location = location_; | 1378 Location saved_location = location_; |
| 1385 location_ = kStack; | 1379 location_ = kStack; |
| 1386 EmitVariableLoad(expr->expression()->AsVariableProxy()->var(), | 1380 EmitVariableLoad(expr->expression()->AsVariableProxy()->var(), |
| 1387 Expression::kValue); | 1381 Expression::kValue); |
| 1388 location_ = saved_location; | 1382 location_ = saved_location; |
| 1389 } else { | 1383 } else { |
| 1390 // Reserve space for result of postfix operation. | 1384 // Reserve space for result of postfix operation. |
| 1391 if (expr->is_postfix() && expr->context() != Expression::kEffect) { | 1385 if (expr->is_postfix() && context_ != Expression::kEffect) { |
| 1392 ASSERT(expr->context() != Expression::kUninitialized); | |
| 1393 __ mov(ip, Operand(Smi::FromInt(0))); | 1386 __ mov(ip, Operand(Smi::FromInt(0))); |
| 1394 __ push(ip); | 1387 __ push(ip); |
| 1395 } | 1388 } |
| 1396 VisitForValue(prop->obj(), kStack); | 1389 VisitForValue(prop->obj(), kStack); |
| 1397 if (assign_type == NAMED_PROPERTY) { | 1390 if (assign_type == NAMED_PROPERTY) { |
| 1398 EmitNamedPropertyLoad(prop); | 1391 EmitNamedPropertyLoad(prop); |
| 1399 } else { | 1392 } else { |
| 1400 VisitForValue(prop->key(), kStack); | 1393 VisitForValue(prop->key(), kStack); |
| 1401 EmitKeyedPropertyLoad(prop); | 1394 EmitKeyedPropertyLoad(prop); |
| 1402 } | 1395 } |
| 1403 __ push(r0); | 1396 __ push(r0); |
| 1404 } | 1397 } |
| 1405 | 1398 |
| 1406 // Convert to number. | 1399 // Convert to number. |
| 1407 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS); | 1400 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS); |
| 1408 | 1401 |
| 1409 // Save result for postfix expressions. | 1402 // Save result for postfix expressions. |
| 1410 if (expr->is_postfix()) { | 1403 if (expr->is_postfix()) { |
| 1411 switch (expr->context()) { | 1404 switch (context_) { |
| 1412 case Expression::kUninitialized: | 1405 case Expression::kUninitialized: |
| 1413 UNREACHABLE(); | 1406 UNREACHABLE(); |
| 1414 case Expression::kEffect: | 1407 case Expression::kEffect: |
| 1415 // Do not save result. | 1408 // Do not save result. |
| 1416 break; | 1409 break; |
| 1417 case Expression::kValue: | 1410 case Expression::kValue: |
| 1418 case Expression::kTest: | 1411 case Expression::kTest: |
| 1419 case Expression::kValueTest: | 1412 case Expression::kValueTest: |
| 1420 case Expression::kTestValue: | 1413 case Expression::kTestValue: |
| 1421 // Save the result on the stack. If we have a named or keyed property | 1414 // Save the result on the stack. If we have a named or keyed property |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1444 __ CallStub(&stub); | 1437 __ CallStub(&stub); |
| 1445 | 1438 |
| 1446 // Store the value returned in r0. | 1439 // Store the value returned in r0. |
| 1447 switch (assign_type) { | 1440 switch (assign_type) { |
| 1448 case VARIABLE: | 1441 case VARIABLE: |
| 1449 if (expr->is_postfix()) { | 1442 if (expr->is_postfix()) { |
| 1450 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 1443 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 1451 Expression::kEffect); | 1444 Expression::kEffect); |
| 1452 // For all contexts except kEffect: We have the result on | 1445 // For all contexts except kEffect: We have the result on |
| 1453 // top of the stack. | 1446 // top of the stack. |
| 1454 if (expr->context() != Expression::kEffect) { | 1447 if (context_ != Expression::kEffect) { |
| 1455 ApplyTOS(expr->context()); | 1448 ApplyTOS(context_); |
| 1456 } | 1449 } |
| 1457 } else { | 1450 } else { |
| 1458 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 1451 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 1459 expr->context()); | 1452 context_); |
| 1460 } | 1453 } |
| 1461 break; | 1454 break; |
| 1462 case NAMED_PROPERTY: { | 1455 case NAMED_PROPERTY: { |
| 1463 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); | 1456 __ mov(r2, Operand(prop->key()->AsLiteral()->handle())); |
| 1464 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1457 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 1465 __ Call(ic, RelocInfo::CODE_TARGET); | 1458 __ Call(ic, RelocInfo::CODE_TARGET); |
| 1466 if (expr->is_postfix()) { | 1459 if (expr->is_postfix()) { |
| 1467 __ Drop(1); // Result is on the stack under the receiver. | 1460 __ Drop(1); // Result is on the stack under the receiver. |
| 1468 if (expr->context() != Expression::kEffect) { | 1461 if (context_ != Expression::kEffect) { |
| 1469 ApplyTOS(expr->context()); | 1462 ApplyTOS(context_); |
| 1470 } | 1463 } |
| 1471 } else { | 1464 } else { |
| 1472 DropAndApply(1, expr->context(), r0); | 1465 DropAndApply(1, context_, r0); |
| 1473 } | 1466 } |
| 1474 break; | 1467 break; |
| 1475 } | 1468 } |
| 1476 case KEYED_PROPERTY: { | 1469 case KEYED_PROPERTY: { |
| 1477 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 1470 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
| 1478 __ Call(ic, RelocInfo::CODE_TARGET); | 1471 __ Call(ic, RelocInfo::CODE_TARGET); |
| 1479 if (expr->is_postfix()) { | 1472 if (expr->is_postfix()) { |
| 1480 __ Drop(2); // Result is on the stack under the key and the receiver. | 1473 __ Drop(2); // Result is on the stack under the key and the receiver. |
| 1481 if (expr->context() != Expression::kEffect) { | 1474 if (context_ != Expression::kEffect) { |
| 1482 ApplyTOS(expr->context()); | 1475 ApplyTOS(context_); |
| 1483 } | 1476 } |
| 1484 } else { | 1477 } else { |
| 1485 DropAndApply(2, expr->context(), r0); | 1478 DropAndApply(2, context_, r0); |
| 1486 } | 1479 } |
| 1487 break; | 1480 break; |
| 1488 } | 1481 } |
| 1489 } | 1482 } |
| 1490 } | 1483 } |
| 1491 | 1484 |
| 1492 | 1485 |
| 1493 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { | 1486 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { |
| 1494 Comment cmnt(masm_, "[ BinaryOperation"); | 1487 Comment cmnt(masm_, "[ BinaryOperation"); |
| 1495 switch (expr->op()) { | 1488 switch (expr->op()) { |
| 1496 case Token::COMMA: | 1489 case Token::COMMA: |
| 1497 ASSERT_EQ(Expression::kEffect, expr->left()->context()); | 1490 VisitForEffect(expr->left()); |
| 1498 ASSERT_EQ(expr->context(), expr->right()->context()); | |
| 1499 Visit(expr->left()); | |
| 1500 Visit(expr->right()); | 1491 Visit(expr->right()); |
| 1501 break; | 1492 break; |
| 1502 | 1493 |
| 1503 case Token::OR: | 1494 case Token::OR: |
| 1504 case Token::AND: | 1495 case Token::AND: |
| 1505 EmitLogicalOperation(expr); | 1496 EmitLogicalOperation(expr); |
| 1506 break; | 1497 break; |
| 1507 | 1498 |
| 1508 case Token::ADD: | 1499 case Token::ADD: |
| 1509 case Token::SUB: | 1500 case Token::SUB: |
| 1510 case Token::DIV: | 1501 case Token::DIV: |
| 1511 case Token::MOD: | 1502 case Token::MOD: |
| 1512 case Token::MUL: | 1503 case Token::MUL: |
| 1513 case Token::BIT_OR: | 1504 case Token::BIT_OR: |
| 1514 case Token::BIT_AND: | 1505 case Token::BIT_AND: |
| 1515 case Token::BIT_XOR: | 1506 case Token::BIT_XOR: |
| 1516 case Token::SHL: | 1507 case Token::SHL: |
| 1517 case Token::SHR: | 1508 case Token::SHR: |
| 1518 case Token::SAR: | 1509 case Token::SAR: |
| 1519 VisitForValue(expr->left(), kStack); | 1510 VisitForValue(expr->left(), kStack); |
| 1520 VisitForValue(expr->right(), kAccumulator); | 1511 VisitForValue(expr->right(), kAccumulator); |
| 1521 EmitBinaryOp(expr->op(), expr->context()); | 1512 EmitBinaryOp(expr->op(), context_); |
| 1522 break; | 1513 break; |
| 1523 | 1514 |
| 1524 default: | 1515 default: |
| 1525 UNREACHABLE(); | 1516 UNREACHABLE(); |
| 1526 } | 1517 } |
| 1527 } | 1518 } |
| 1528 | 1519 |
| 1529 | 1520 |
| 1530 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { | 1521 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
| 1531 Comment cmnt(masm_, "[ CompareOperation"); | 1522 Comment cmnt(masm_, "[ CompareOperation"); |
| 1532 | 1523 |
| 1533 // Always perform the comparison for its control flow. Pack the result | 1524 // Always perform the comparison for its control flow. Pack the result |
| 1534 // into the expression's context after the comparison is performed. | 1525 // into the expression's context after the comparison is performed. |
| 1535 Label materialize_true, materialize_false, done; | 1526 Label materialize_true, materialize_false, done; |
| 1536 // Initially assume we are in a test context. | 1527 // Initially assume we are in a test context. |
| 1537 Label* if_true = true_label_; | 1528 Label* if_true = true_label_; |
| 1538 Label* if_false = false_label_; | 1529 Label* if_false = false_label_; |
| 1539 switch (expr->context()) { | 1530 switch (context_) { |
| 1540 case Expression::kUninitialized: | 1531 case Expression::kUninitialized: |
| 1541 UNREACHABLE(); | 1532 UNREACHABLE(); |
| 1542 break; | 1533 break; |
| 1543 case Expression::kEffect: | 1534 case Expression::kEffect: |
| 1544 if_true = &done; | 1535 if_true = &done; |
| 1545 if_false = &done; | 1536 if_false = &done; |
| 1546 break; | 1537 break; |
| 1547 case Expression::kValue: | 1538 case Expression::kValue: |
| 1548 if_true = &materialize_true; | 1539 if_true = &materialize_true; |
| 1549 if_false = &materialize_false; | 1540 if_false = &materialize_false; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1631 CompareStub stub(cc, strict); | 1622 CompareStub stub(cc, strict); |
| 1632 __ CallStub(&stub); | 1623 __ CallStub(&stub); |
| 1633 __ cmp(r0, Operand(0)); | 1624 __ cmp(r0, Operand(0)); |
| 1634 __ b(cc, if_true); | 1625 __ b(cc, if_true); |
| 1635 __ jmp(if_false); | 1626 __ jmp(if_false); |
| 1636 } | 1627 } |
| 1637 } | 1628 } |
| 1638 | 1629 |
| 1639 // Convert the result of the comparison into one expected for this | 1630 // Convert the result of the comparison into one expected for this |
| 1640 // expression's context. | 1631 // expression's context. |
| 1641 Apply(expr->context(), if_true, if_false); | 1632 Apply(context_, if_true, if_false); |
| 1642 } | 1633 } |
| 1643 | 1634 |
| 1644 | 1635 |
| 1645 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { | 1636 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
| 1646 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1637 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1647 Apply(expr->context(), r0); | 1638 Apply(context_, r0); |
| 1648 } | 1639 } |
| 1649 | 1640 |
| 1650 | 1641 |
| 1651 Register FastCodeGenerator::result_register() { return r0; } | 1642 Register FastCodeGenerator::result_register() { return r0; } |
| 1652 | 1643 |
| 1653 | 1644 |
| 1654 Register FastCodeGenerator::context_register() { return cp; } | 1645 Register FastCodeGenerator::context_register() { return cp; } |
| 1655 | 1646 |
| 1656 | 1647 |
| 1657 void FastCodeGenerator::StoreToFrameField(int frame_offset, Register value) { | 1648 void FastCodeGenerator::StoreToFrameField(int frame_offset, Register value) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1689 __ pop(result_register()); | 1680 __ pop(result_register()); |
| 1690 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); | 1681 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); |
| 1691 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 1682 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
| 1692 __ add(pc, r1, Operand(masm_->CodeObject())); | 1683 __ add(pc, r1, Operand(masm_->CodeObject())); |
| 1693 } | 1684 } |
| 1694 | 1685 |
| 1695 | 1686 |
| 1696 #undef __ | 1687 #undef __ |
| 1697 | 1688 |
| 1698 } } // namespace v8::internal | 1689 } } // namespace v8::internal |
| OLD | NEW |