OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1039 | 1039 |
1040 | 1040 |
1041 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 1041 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
1042 Comment cmnt(masm_, "[ ForInStatement"); | 1042 Comment cmnt(masm_, "[ ForInStatement"); |
1043 SetStatementPosition(stmt); | 1043 SetStatementPosition(stmt); |
1044 | 1044 |
1045 Label loop, exit; | 1045 Label loop, exit; |
1046 ForIn loop_statement(this, stmt); | 1046 ForIn loop_statement(this, stmt); |
1047 increment_loop_depth(); | 1047 increment_loop_depth(); |
1048 | 1048 |
1049 // Get the object to enumerate over. Both SpiderMonkey and JSC | 1049 // Get the object to enumerate over. If the object is null or undefined, skip |
1050 // ignore null and undefined in contrast to the specification; see | 1050 // over the loop. See ECMA-262 version 5, section 12.6.4. |
1051 // ECMA-262 section 12.6.4. | |
1052 VisitForAccumulatorValue(stmt->enumerable()); | 1051 VisitForAccumulatorValue(stmt->enumerable()); |
1053 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); | 1052 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); |
1054 __ j(equal, &exit); | 1053 __ j(equal, &exit); |
1055 Register null_value = rdi; | 1054 Register null_value = rdi; |
1056 __ LoadRoot(null_value, Heap::kNullValueRootIndex); | 1055 __ LoadRoot(null_value, Heap::kNullValueRootIndex); |
1057 __ cmpq(rax, null_value); | 1056 __ cmpq(rax, null_value); |
1058 __ j(equal, &exit); | 1057 __ j(equal, &exit); |
1059 | 1058 |
1060 PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); | 1059 PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); |
1061 | 1060 |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1217 __ bind(loop_statement.break_label()); | 1216 __ bind(loop_statement.break_label()); |
1218 __ addq(rsp, Immediate(5 * kPointerSize)); | 1217 __ addq(rsp, Immediate(5 * kPointerSize)); |
1219 | 1218 |
1220 // Exit and decrement the loop depth. | 1219 // Exit and decrement the loop depth. |
1221 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 1220 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
1222 __ bind(&exit); | 1221 __ bind(&exit); |
1223 decrement_loop_depth(); | 1222 decrement_loop_depth(); |
1224 } | 1223 } |
1225 | 1224 |
1226 | 1225 |
| 1226 void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { |
| 1227 Comment cmnt(masm_, "[ ForOfStatement"); |
| 1228 SetStatementPosition(stmt); |
| 1229 |
| 1230 Iteration loop_statement(this, stmt); |
| 1231 increment_loop_depth(); |
| 1232 |
| 1233 // var iterator = iterable[@@iterator]() |
| 1234 VisitForAccumulatorValue(stmt->assign_iterator()); |
| 1235 |
| 1236 // As with for-in, skip the loop if the iterator is null or undefined. |
| 1237 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); |
| 1238 __ j(equal, loop_statement.break_label()); |
| 1239 __ CompareRoot(rax, Heap::kNullValueRootIndex); |
| 1240 __ j(equal, loop_statement.break_label()); |
| 1241 |
| 1242 // Convert the iterator to a JS object. |
| 1243 Label convert, done_convert; |
| 1244 __ JumpIfSmi(rax, &convert); |
| 1245 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx); |
| 1246 __ j(above_equal, &done_convert); |
| 1247 __ bind(&convert); |
| 1248 __ push(rax); |
| 1249 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); |
| 1250 __ bind(&done_convert); |
| 1251 |
| 1252 // Loop entry. |
| 1253 __ bind(loop_statement.continue_label()); |
| 1254 |
| 1255 // result = iterator.next() |
| 1256 VisitForEffect(stmt->next_result()); |
| 1257 |
| 1258 // if (result.done) break; |
| 1259 Label result_not_done; |
| 1260 VisitForControl(stmt->result_done(), |
| 1261 loop_statement.break_label(), |
| 1262 &result_not_done, |
| 1263 &result_not_done); |
| 1264 __ bind(&result_not_done); |
| 1265 |
| 1266 // each = result.value |
| 1267 VisitForEffect(stmt->assign_each()); |
| 1268 |
| 1269 // Generate code for the body of the loop. |
| 1270 Visit(stmt->body()); |
| 1271 |
| 1272 // Check stack before looping. |
| 1273 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); |
| 1274 EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label()); |
| 1275 __ jmp(loop_statement.continue_label()); |
| 1276 |
| 1277 // Exit and decrement the loop depth. |
| 1278 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
| 1279 __ bind(loop_statement.break_label()); |
| 1280 decrement_loop_depth(); |
| 1281 } |
| 1282 |
| 1283 |
1227 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, | 1284 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, |
1228 bool pretenure) { | 1285 bool pretenure) { |
1229 // Use the fast case closure allocation code that allocates in new | 1286 // Use the fast case closure allocation code that allocates in new |
1230 // space for nested functions that don't need literals cloning. If | 1287 // space for nested functions that don't need literals cloning. If |
1231 // we're running with the --always-opt or the --prepare-always-opt | 1288 // we're running with the --always-opt or the --prepare-always-opt |
1232 // flag, we need to use the runtime function so that the new function | 1289 // flag, we need to use the runtime function so that the new function |
1233 // we are creating here gets a chance to have its code optimized and | 1290 // we are creating here gets a chance to have its code optimized and |
1234 // doesn't just get a copy of the existing unoptimized code. | 1291 // doesn't just get a copy of the existing unoptimized code. |
1235 if (!FLAG_always_opt && | 1292 if (!FLAG_always_opt && |
1236 !FLAG_prepare_always_opt && | 1293 !FLAG_prepare_always_opt && |
(...skipping 3622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4859 *context_length = 0; | 4916 *context_length = 0; |
4860 return previous_; | 4917 return previous_; |
4861 } | 4918 } |
4862 | 4919 |
4863 | 4920 |
4864 #undef __ | 4921 #undef __ |
4865 | 4922 |
4866 } } // namespace v8::internal | 4923 } } // namespace v8::internal |
4867 | 4924 |
4868 #endif // V8_TARGET_ARCH_X64 | 4925 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |