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 1066 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1077 | 1077 |
1078 | 1078 |
1079 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 1079 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
1080 Comment cmnt(masm_, "[ ForInStatement"); | 1080 Comment cmnt(masm_, "[ ForInStatement"); |
1081 SetStatementPosition(stmt); | 1081 SetStatementPosition(stmt); |
1082 | 1082 |
1083 Label loop, exit; | 1083 Label loop, exit; |
1084 ForIn loop_statement(this, stmt); | 1084 ForIn loop_statement(this, stmt); |
1085 increment_loop_depth(); | 1085 increment_loop_depth(); |
1086 | 1086 |
1087 // Get the object to enumerate over. Both SpiderMonkey and JSC | 1087 // Get the object to enumerate over. If the object is null or undefined, skip |
1088 // ignore null and undefined in contrast to the specification; see | 1088 // over the loop. See ECMA-262 version 5, section 12.6.4. |
1089 // ECMA-262 section 12.6.4. | |
1090 VisitForAccumulatorValue(stmt->enumerable()); | 1089 VisitForAccumulatorValue(stmt->enumerable()); |
1091 __ mov(a0, result_register()); // Result as param to InvokeBuiltin below. | 1090 __ mov(a0, result_register()); // Result as param to InvokeBuiltin below. |
1092 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 1091 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
1093 __ Branch(&exit, eq, a0, Operand(at)); | 1092 __ Branch(&exit, eq, a0, Operand(at)); |
1094 Register null_value = t1; | 1093 Register null_value = t1; |
1095 __ LoadRoot(null_value, Heap::kNullValueRootIndex); | 1094 __ LoadRoot(null_value, Heap::kNullValueRootIndex); |
1096 __ Branch(&exit, eq, a0, Operand(null_value)); | 1095 __ Branch(&exit, eq, a0, Operand(null_value)); |
1097 PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); | 1096 PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); |
1098 __ mov(a0, v0); | 1097 __ mov(a0, v0); |
1099 // Convert the object to a JS object. | 1098 // Convert the object to a JS object. |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1253 __ bind(loop_statement.break_label()); | 1252 __ bind(loop_statement.break_label()); |
1254 __ Drop(5); | 1253 __ Drop(5); |
1255 | 1254 |
1256 // Exit and decrement the loop depth. | 1255 // Exit and decrement the loop depth. |
1257 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 1256 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
1258 __ bind(&exit); | 1257 __ bind(&exit); |
1259 decrement_loop_depth(); | 1258 decrement_loop_depth(); |
1260 } | 1259 } |
1261 | 1260 |
1262 | 1261 |
| 1262 void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { |
| 1263 Comment cmnt(masm_, "[ ForOfStatement"); |
| 1264 SetStatementPosition(stmt); |
| 1265 |
| 1266 Iteration loop_statement(this, stmt); |
| 1267 increment_loop_depth(); |
| 1268 |
| 1269 // var iterator = iterable[@@iterator]() |
| 1270 VisitForAccumulatorValue(stmt->assign_iterator()); |
| 1271 __ mov(a0, v0); |
| 1272 |
| 1273 // As with for-in, skip the loop if the iterator is null or undefined. |
| 1274 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 1275 __ Branch(loop_statement.break_label(), eq, a0, Operand(at)); |
| 1276 __ LoadRoot(at, Heap::kNullValueRootIndex); |
| 1277 __ Branch(loop_statement.break_label(), eq, a0, Operand(at)); |
| 1278 |
| 1279 // Convert the iterator to a JS object. |
| 1280 Label convert, done_convert; |
| 1281 __ JumpIfSmi(a0, &convert); |
| 1282 __ GetObjectType(a0, a1, a1); |
| 1283 __ Branch(&done_convert, ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE)); |
| 1284 __ bind(&convert); |
| 1285 __ push(a0); |
| 1286 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); |
| 1287 __ mov(a0, v0); |
| 1288 __ bind(&done_convert); |
| 1289 __ push(a0); |
| 1290 |
| 1291 // Loop entry. |
| 1292 __ bind(loop_statement.continue_label()); |
| 1293 |
| 1294 // result = iterator.next() |
| 1295 VisitForEffect(stmt->next_result()); |
| 1296 |
| 1297 // if (result.done) break; |
| 1298 Label result_not_done; |
| 1299 VisitForControl(stmt->result_done(), |
| 1300 loop_statement.break_label(), |
| 1301 &result_not_done, |
| 1302 &result_not_done); |
| 1303 __ bind(&result_not_done); |
| 1304 |
| 1305 // each = result.value |
| 1306 VisitForEffect(stmt->assign_each()); |
| 1307 |
| 1308 // Generate code for the body of the loop. |
| 1309 Visit(stmt->body()); |
| 1310 |
| 1311 // Check stack before looping. |
| 1312 PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); |
| 1313 EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label()); |
| 1314 __ jmp(loop_statement.continue_label()); |
| 1315 |
| 1316 // Exit and decrement the loop depth. |
| 1317 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
| 1318 __ bind(loop_statement.break_label()); |
| 1319 decrement_loop_depth(); |
| 1320 } |
| 1321 |
| 1322 |
1263 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, | 1323 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, |
1264 bool pretenure) { | 1324 bool pretenure) { |
1265 // Use the fast case closure allocation code that allocates in new | 1325 // Use the fast case closure allocation code that allocates in new |
1266 // space for nested functions that don't need literals cloning. If | 1326 // space for nested functions that don't need literals cloning. If |
1267 // we're running with the --always-opt or the --prepare-always-opt | 1327 // we're running with the --always-opt or the --prepare-always-opt |
1268 // flag, we need to use the runtime function so that the new function | 1328 // flag, we need to use the runtime function so that the new function |
1269 // we are creating here gets a chance to have its code optimized and | 1329 // we are creating here gets a chance to have its code optimized and |
1270 // doesn't just get a copy of the existing unoptimized code. | 1330 // doesn't just get a copy of the existing unoptimized code. |
1271 if (!FLAG_always_opt && | 1331 if (!FLAG_always_opt && |
1272 !FLAG_prepare_always_opt && | 1332 !FLAG_prepare_always_opt && |
(...skipping 3639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4912 *context_length = 0; | 4972 *context_length = 0; |
4913 return previous_; | 4973 return previous_; |
4914 } | 4974 } |
4915 | 4975 |
4916 | 4976 |
4917 #undef __ | 4977 #undef __ |
4918 | 4978 |
4919 } } // namespace v8::internal | 4979 } } // namespace v8::internal |
4920 | 4980 |
4921 #endif // V8_TARGET_ARCH_MIPS | 4981 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |