OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/builtins/builtins.h" | 5 #include "src/builtins/builtins.h" |
6 #include "src/builtins/builtins-utils.h" | 6 #include "src/builtins/builtins-utils.h" |
7 | 7 |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1021 typedef compiler::Node Node; | 1021 typedef compiler::Node Node; |
1022 | 1022 |
1023 Node* receiver = assembler->Parameter(0); | 1023 Node* receiver = assembler->Parameter(0); |
1024 Node* context = assembler->Parameter(3); | 1024 Node* context = assembler->Parameter(3); |
1025 | 1025 |
1026 Node* result = assembler->ToThisValue( | 1026 Node* result = assembler->ToThisValue( |
1027 context, receiver, PrimitiveType::kString, "String.prototype.valueOf"); | 1027 context, receiver, PrimitiveType::kString, "String.prototype.valueOf"); |
1028 assembler->Return(result); | 1028 assembler->Return(result); |
1029 } | 1029 } |
1030 | 1030 |
1031 BUILTIN(StringPrototypeIterator) { | 1031 void Builtins::Generate_StringPrototypeIterator(CodeStubAssembler* assembler) { |
1032 HandleScope scope(isolate); | 1032 typedef CodeStubAssembler::Label Label; |
1033 TO_THIS_STRING(object, "String.prototype[Symbol.iterator]"); | 1033 typedef compiler::Node Node; |
1034 | 1034 typedef CodeStubAssembler::Variable Variable; |
1035 Handle<String> string; | 1035 |
1036 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string, | 1036 Variable var_string(assembler, MachineRepresentation::kTagged); |
1037 Object::ToString(isolate, object)); | 1037 Variable var_index(assembler, MachineRepresentation::kTagged); |
1038 | 1038 |
1039 return *isolate->factory()->NewJSStringIterator(string); | 1039 Variable* loop_inputs[] = {&var_string, &var_index}; |
| 1040 Label loop(assembler, 2, loop_inputs); |
| 1041 Label allocate_iterator(assembler); |
| 1042 |
| 1043 Node* receiver = assembler->Parameter(0); |
| 1044 Node* context = assembler->Parameter(3); |
| 1045 |
| 1046 var_string.Bind(assembler->ToThisString(context, receiver, |
| 1047 "String.prototype[Symbol.iterator]")); |
| 1048 var_index.Bind(assembler->SmiConstant(Smi::FromInt(0))); |
| 1049 |
| 1050 assembler->Goto(&loop); |
| 1051 assembler->Bind(&loop); |
| 1052 { |
| 1053 Node* string = var_string.value(); |
| 1054 // Load the instance type of the {string}. |
| 1055 Node* string_instance_type = assembler->LoadInstanceType(string); |
| 1056 |
| 1057 // Check if the {string} is a SeqString. |
| 1058 Label if_stringisnotsequential(assembler); |
| 1059 assembler->Branch(assembler->Word32Equal( |
| 1060 assembler->Word32And(string_instance_type, |
| 1061 assembler->Int32Constant( |
| 1062 kStringRepresentationMask)), |
| 1063 assembler->Int32Constant(kSeqStringTag)), |
| 1064 &allocate_iterator, &if_stringisnotsequential); |
| 1065 |
| 1066 assembler->Bind(&if_stringisnotsequential); |
| 1067 { |
| 1068 // Check if the {string} is a ConsString. |
| 1069 Label if_stringiscons(assembler), if_stringisnotcons(assembler); |
| 1070 assembler->Branch( |
| 1071 assembler->Word32Equal( |
| 1072 assembler->Word32And( |
| 1073 string_instance_type, |
| 1074 assembler->Int32Constant(kStringRepresentationMask)), |
| 1075 assembler->Int32Constant(kConsStringTag)), |
| 1076 &if_stringiscons, &if_stringisnotcons); |
| 1077 |
| 1078 assembler->Bind(&if_stringiscons); |
| 1079 { |
| 1080 // Flatten cons-string and finish. |
| 1081 var_string.Bind(assembler->CallRuntime( |
| 1082 Runtime::kFlattenString, assembler->NoContextConstant(), string)); |
| 1083 assembler->Goto(&allocate_iterator); |
| 1084 } |
| 1085 |
| 1086 assembler->Bind(&if_stringisnotcons); |
| 1087 { |
| 1088 // Check if the {string} is an ExternalString. |
| 1089 Label if_stringisnotexternal(assembler); |
| 1090 assembler->Branch( |
| 1091 assembler->Word32Equal( |
| 1092 assembler->Word32And( |
| 1093 string_instance_type, |
| 1094 assembler->Int32Constant(kStringRepresentationMask)), |
| 1095 assembler->Int32Constant(kExternalStringTag)), |
| 1096 &allocate_iterator, &if_stringisnotexternal); |
| 1097 |
| 1098 assembler->Bind(&if_stringisnotexternal); |
| 1099 { |
| 1100 // The {string} is a SlicedString, continue with its parent. |
| 1101 Node* index = var_index.value(); |
| 1102 Node* string_offset = |
| 1103 assembler->LoadObjectField(string, SlicedString::kOffsetOffset); |
| 1104 Node* string_parent = |
| 1105 assembler->LoadObjectField(string, SlicedString::kParentOffset); |
| 1106 var_index.Bind(assembler->SmiAdd(index, string_offset)); |
| 1107 var_string.Bind(string_parent); |
| 1108 assembler->Goto(&loop); |
| 1109 } |
| 1110 } |
| 1111 } |
| 1112 } |
| 1113 |
| 1114 assembler->Bind(&allocate_iterator); |
| 1115 { |
| 1116 Node* native_context = assembler->LoadNativeContext(context); |
| 1117 Node* map = assembler->LoadFixedArrayElement( |
| 1118 native_context, |
| 1119 assembler->IntPtrConstant(Context::STRING_ITERATOR_MAP_INDEX), 0, |
| 1120 CodeStubAssembler::INTPTR_PARAMETERS); |
| 1121 Node* iterator = assembler->Allocate(JSStringIterator::kSize); |
| 1122 assembler->StoreMapNoWriteBarrier(iterator, map); |
| 1123 assembler->StoreObjectFieldRoot(iterator, JSValue::kPropertiesOffset, |
| 1124 Heap::kEmptyFixedArrayRootIndex); |
| 1125 assembler->StoreObjectFieldRoot(iterator, JSObject::kElementsOffset, |
| 1126 Heap::kEmptyFixedArrayRootIndex); |
| 1127 assembler->StoreObjectFieldNoWriteBarrier( |
| 1128 iterator, JSStringIterator::kStringOffset, var_string.value()); |
| 1129 |
| 1130 assembler->StoreObjectFieldNoWriteBarrier( |
| 1131 iterator, JSStringIterator::kNextIndexOffset, var_index.value()); |
| 1132 assembler->Return(iterator); |
| 1133 } |
1040 } | 1134 } |
1041 | 1135 |
1042 BUILTIN(StringIteratorPrototypeNext) { | 1136 namespace { |
1043 HandleScope scope(isolate); | 1137 |
1044 | 1138 // Return the |word32| codepoint at {index}. Supports SeqStrings and |
1045 if (!args.receiver()->IsJSStringIterator()) { | 1139 // ExternalStrings. |
1046 Handle<String> reason = isolate->factory()->NewStringFromAsciiChecked( | 1140 compiler::Node* LoadSurrogatePairInternal(CodeStubAssembler* assembler, |
1047 "String Iterator.prototype.next"); | 1141 compiler::Node* string, |
1048 THROW_NEW_ERROR_RETURN_FAILURE( | 1142 compiler::Node* length, |
1049 isolate, | 1143 compiler::Node* index, |
1050 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, reason)); | 1144 UnicodeEncoding encoding) { |
1051 } | 1145 typedef CodeStubAssembler::Label Label; |
1052 Handle<JSStringIterator> iterator = | 1146 typedef compiler::Node Node; |
1053 Handle<JSStringIterator>::cast(args.receiver()); | 1147 typedef CodeStubAssembler::Variable Variable; |
1054 Handle<String> string(iterator->string()); | 1148 Label handle_surrogate_pair(assembler), return_result(assembler); |
1055 | 1149 Variable var_result(assembler, MachineRepresentation::kWord32); |
1056 int position = iterator->index(); | 1150 Variable var_trail(assembler, MachineRepresentation::kWord16); |
1057 int length = string->length(); | 1151 var_result.Bind(assembler->Int32Constant(0)); |
1058 | 1152 var_trail.Bind(assembler->Int32Constant(0)); |
1059 if (position < length) { | 1153 |
1060 uint16_t lead = string->Get(position); | 1154 Node* string_instance_type = assembler->LoadInstanceType(string); |
1061 if (lead >= 0xD800 && lead <= 0xDBFF && position + 1 < length) { | 1155 |
1062 uint16_t trail = string->Get(position + 1); | 1156 Label if_stringissequential(assembler), if_stringisexternal(assembler); |
1063 if (V8_LIKELY(trail >= 0xDC00 && trail <= 0xDFFF)) { | 1157 assembler->Branch(assembler->Word32Equal( |
1064 // Return surrogate pair code units | 1158 assembler->Word32And(string_instance_type, |
1065 iterator->set_index(position + 2); | 1159 assembler->Int32Constant( |
1066 Handle<String> value = | 1160 kStringRepresentationMask)), |
1067 isolate->factory()->NewSurrogatePairString(lead, trail); | 1161 assembler->Int32Constant(kSeqStringTag)), |
1068 return *isolate->factory()->NewJSIteratorResult(value, false); | 1162 &if_stringissequential, &if_stringisexternal); |
1069 } | 1163 |
1070 } | 1164 assembler->Bind(&if_stringissequential); |
1071 | 1165 { |
1072 // Return single code unit | 1166 Label if_stringisonebyte(assembler), if_stringistwobyte(assembler); |
1073 iterator->set_index(position + 1); | 1167 assembler->Branch( |
1074 Handle<String> value = | 1168 assembler->Word32Equal( |
1075 isolate->factory()->LookupSingleCharacterStringFromCode(lead); | 1169 assembler->Word32And(string_instance_type, |
1076 return *isolate->factory()->NewJSIteratorResult(value, false); | 1170 assembler->Int32Constant(kStringEncodingMask)), |
1077 } | 1171 assembler->Int32Constant(kOneByteStringTag)), |
1078 | 1172 &if_stringisonebyte, &if_stringistwobyte); |
1079 iterator->set_string(isolate->heap()->empty_string()); | 1173 |
1080 | 1174 assembler->Bind(&if_stringisonebyte); |
1081 return *isolate->factory()->NewJSIteratorResult( | 1175 { |
1082 isolate->factory()->undefined_value(), true); | 1176 var_result.Bind(assembler->Load( |
| 1177 MachineType::Uint8(), string, |
| 1178 assembler->IntPtrAdd( |
| 1179 index, assembler->IntPtrConstant(SeqOneByteString::kHeaderSize - |
| 1180 kHeapObjectTag)))); |
| 1181 assembler->Goto(&return_result); |
| 1182 } |
| 1183 |
| 1184 assembler->Bind(&if_stringistwobyte); |
| 1185 { |
| 1186 Node* lead = assembler->Load( |
| 1187 MachineType::Uint16(), string, |
| 1188 assembler->IntPtrAdd( |
| 1189 assembler->WordShl(index, assembler->IntPtrConstant(1)), |
| 1190 assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize - |
| 1191 kHeapObjectTag))); |
| 1192 var_result.Bind(lead); |
| 1193 Node* next_pos = assembler->Int32Add(index, assembler->Int32Constant(1)); |
| 1194 |
| 1195 Label if_isdoublecodeunit(assembler); |
| 1196 assembler->GotoIf(assembler->Int32GreaterThanOrEqual(next_pos, length), |
| 1197 &return_result); |
| 1198 assembler->GotoIf( |
| 1199 assembler->Uint32LessThan(lead, assembler->Int32Constant(0xD800)), |
| 1200 &return_result); |
| 1201 assembler->Branch( |
| 1202 assembler->Uint32LessThan(lead, assembler->Int32Constant(0xDC00)), |
| 1203 &if_isdoublecodeunit, &return_result); |
| 1204 |
| 1205 assembler->Bind(&if_isdoublecodeunit); |
| 1206 { |
| 1207 Node* trail = assembler->Load( |
| 1208 MachineType::Uint16(), string, |
| 1209 assembler->IntPtrAdd( |
| 1210 assembler->WordShl(next_pos, assembler->IntPtrConstant(1)), |
| 1211 assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize - |
| 1212 kHeapObjectTag))); |
| 1213 assembler->GotoIf( |
| 1214 assembler->Uint32LessThan(trail, assembler->Int32Constant(0xDC00)), |
| 1215 &return_result); |
| 1216 assembler->GotoIf(assembler->Uint32GreaterThanOrEqual( |
| 1217 trail, assembler->Int32Constant(0xE000)), |
| 1218 &return_result); |
| 1219 |
| 1220 var_trail.Bind(trail); |
| 1221 assembler->Goto(&handle_surrogate_pair); |
| 1222 } |
| 1223 } |
| 1224 } |
| 1225 |
| 1226 assembler->Bind(&if_stringisexternal); |
| 1227 { |
| 1228 assembler->Assert(assembler->Word32Equal( |
| 1229 assembler->Word32And( |
| 1230 string_instance_type, |
| 1231 assembler->Int32Constant(kStringRepresentationMask)), |
| 1232 assembler->Int32Constant(kExternalStringTag))); |
| 1233 Label if_stringisshort(assembler), if_stringisnotshort(assembler); |
| 1234 |
| 1235 assembler->Branch(assembler->Word32Equal( |
| 1236 assembler->Word32And(string_instance_type, |
| 1237 assembler->Int32Constant( |
| 1238 kShortExternalStringMask)), |
| 1239 assembler->Int32Constant(0)), |
| 1240 &if_stringisshort, &if_stringisnotshort); |
| 1241 |
| 1242 assembler->Bind(&if_stringisshort); |
| 1243 { |
| 1244 // Load the actual resource data from the {string}. |
| 1245 Node* string_resource_data = assembler->LoadObjectField( |
| 1246 string, ExternalString::kResourceDataOffset, MachineType::Pointer()); |
| 1247 |
| 1248 Label if_stringistwobyte(assembler), if_stringisonebyte(assembler); |
| 1249 assembler->Branch(assembler->Word32Equal( |
| 1250 assembler->Word32And( |
| 1251 string_instance_type, |
| 1252 assembler->Int32Constant(kStringEncodingMask)), |
| 1253 assembler->Int32Constant(kTwoByteStringTag)), |
| 1254 &if_stringistwobyte, &if_stringisonebyte); |
| 1255 |
| 1256 assembler->Bind(&if_stringisonebyte); |
| 1257 { |
| 1258 var_result.Bind( |
| 1259 assembler->Load(MachineType::Uint8(), string_resource_data, index)); |
| 1260 assembler->Goto(&return_result); |
| 1261 } |
| 1262 |
| 1263 assembler->Bind(&if_stringistwobyte); |
| 1264 { |
| 1265 Label if_isdoublecodeunit(assembler); |
| 1266 Node* lead = assembler->Load( |
| 1267 MachineType::Uint16(), string_resource_data, |
| 1268 assembler->WordShl(index, assembler->IntPtrConstant(1))); |
| 1269 var_result.Bind(lead); |
| 1270 Node* next_pos = |
| 1271 assembler->Int32Add(index, assembler->Int32Constant(1)); |
| 1272 |
| 1273 assembler->GotoIf(assembler->Int32GreaterThanOrEqual(next_pos, length), |
| 1274 &return_result); |
| 1275 assembler->GotoIf( |
| 1276 assembler->Uint32LessThan(lead, assembler->Int32Constant(0xD800)), |
| 1277 &return_result); |
| 1278 assembler->Branch( |
| 1279 assembler->Uint32LessThan(lead, assembler->Int32Constant(0xDC00)), |
| 1280 &if_isdoublecodeunit, &return_result); |
| 1281 |
| 1282 assembler->Bind(&if_isdoublecodeunit); |
| 1283 { |
| 1284 Node* trail = assembler->Load( |
| 1285 MachineType::Uint16(), string, |
| 1286 assembler->IntPtrAdd( |
| 1287 assembler->WordShl(next_pos, assembler->IntPtrConstant(1)), |
| 1288 assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize - |
| 1289 kHeapObjectTag))); |
| 1290 assembler->GotoIf(assembler->Uint32LessThan( |
| 1291 trail, assembler->Int32Constant(0xDC00)), |
| 1292 &return_result); |
| 1293 assembler->GotoIf(assembler->Uint32GreaterThanOrEqual( |
| 1294 trail, assembler->Int32Constant(0xE000)), |
| 1295 &return_result); |
| 1296 |
| 1297 var_trail.Bind(trail); |
| 1298 assembler->Goto(&handle_surrogate_pair); |
| 1299 } |
| 1300 } |
| 1301 } |
| 1302 |
| 1303 assembler->Bind(&if_stringisnotshort); |
| 1304 { |
| 1305 Label if_isdoublecodeunit(assembler); |
| 1306 Node* lead = assembler->SmiToWord32(assembler->CallRuntime( |
| 1307 Runtime::kExternalStringGetChar, assembler->NoContextConstant(), |
| 1308 string, assembler->SmiTag(index))); |
| 1309 var_result.Bind(lead); |
| 1310 Node* next_pos = assembler->Int32Add(index, assembler->Int32Constant(1)); |
| 1311 |
| 1312 assembler->GotoIf(assembler->Int32GreaterThanOrEqual(next_pos, length), |
| 1313 &return_result); |
| 1314 assembler->GotoIf( |
| 1315 assembler->Uint32LessThan(lead, assembler->Int32Constant(0xD800)), |
| 1316 &return_result); |
| 1317 assembler->Branch(assembler->Uint32GreaterThanOrEqual( |
| 1318 lead, assembler->Int32Constant(0xDC00)), |
| 1319 &return_result, &if_isdoublecodeunit); |
| 1320 |
| 1321 assembler->Bind(&if_isdoublecodeunit); |
| 1322 { |
| 1323 Node* trail = assembler->SmiToWord32(assembler->CallRuntime( |
| 1324 Runtime::kExternalStringGetChar, assembler->NoContextConstant(), |
| 1325 string, assembler->SmiTag(next_pos))); |
| 1326 assembler->GotoIf( |
| 1327 assembler->Uint32LessThan(trail, assembler->Int32Constant(0xDC00)), |
| 1328 &return_result); |
| 1329 assembler->GotoIf(assembler->Uint32GreaterThanOrEqual( |
| 1330 trail, assembler->Int32Constant(0xE000)), |
| 1331 &return_result); |
| 1332 var_trail.Bind(trail); |
| 1333 assembler->Goto(&handle_surrogate_pair); |
| 1334 } |
| 1335 } |
| 1336 } |
| 1337 |
| 1338 assembler->Bind(&handle_surrogate_pair); |
| 1339 { |
| 1340 Node* lead = var_result.value(); |
| 1341 Node* trail = var_trail.value(); |
| 1342 #ifdef ENABLE_SLOW_DCHECKS |
| 1343 // Check that this path is only taken if a surrogate pair is found |
| 1344 assembler->Assert(assembler->Uint32GreaterThanOrEqual( |
| 1345 lead, assembler->Int32Constant(0xD800))); |
| 1346 assembler->Assert( |
| 1347 assembler->Uint32LessThan(lead, assembler->Int32Constant(0xDC00))); |
| 1348 assembler->Assert(assembler->Uint32GreaterThanOrEqual( |
| 1349 trail, assembler->Int32Constant(0xDC00))); |
| 1350 assembler->Assert( |
| 1351 assembler->Uint32LessThan(trail, assembler->Int32Constant(0xE000))); |
| 1352 #endif |
| 1353 |
| 1354 switch (encoding) { |
| 1355 case UnicodeEncoding::UTF16: |
| 1356 var_result.Bind(assembler->WordOr( |
| 1357 assembler->WordShl(trail, assembler->Int32Constant(16)), lead)); |
| 1358 break; |
| 1359 |
| 1360 case UnicodeEncoding::UTF32: { |
| 1361 // Convert UTF16 surrogate pair into |word32| code point, encoded as |
| 1362 // UTF32. |
| 1363 Node* surrogate_offset = |
| 1364 assembler->Int32Constant(0x10000 - (0xD800 << 10) - 0xDC00); |
| 1365 |
| 1366 // (lead << 10) + trail + SURROGATE_OFFSET |
| 1367 var_result.Bind(assembler->Int32Add( |
| 1368 assembler->WordShl(lead, assembler->Int32Constant(10)), |
| 1369 assembler->Int32Add(trail, surrogate_offset))); |
| 1370 break; |
| 1371 } |
| 1372 } |
| 1373 assembler->Goto(&return_result); |
| 1374 } |
| 1375 |
| 1376 assembler->Bind(&return_result); |
| 1377 return var_result.value(); |
1083 } | 1378 } |
1084 | 1379 |
| 1380 compiler::Node* LoadSurrogatePairAt(CodeStubAssembler* assembler, |
| 1381 compiler::Node* string, |
| 1382 compiler::Node* length, |
| 1383 compiler::Node* index) { |
| 1384 return LoadSurrogatePairInternal(assembler, string, length, index, |
| 1385 UnicodeEncoding::UTF16); |
| 1386 } |
| 1387 |
| 1388 } // namespace |
| 1389 |
| 1390 void Builtins::Generate_StringIteratorPrototypeNext( |
| 1391 CodeStubAssembler* assembler) { |
| 1392 typedef CodeStubAssembler::Label Label; |
| 1393 typedef compiler::Node Node; |
| 1394 typedef CodeStubAssembler::Variable Variable; |
| 1395 |
| 1396 Variable var_value(assembler, MachineRepresentation::kTagged); |
| 1397 Variable var_done(assembler, MachineRepresentation::kTagged); |
| 1398 |
| 1399 var_value.Bind(assembler->UndefinedConstant()); |
| 1400 var_done.Bind(assembler->BooleanConstant(true)); |
| 1401 |
| 1402 Label throw_bad_receiver(assembler), next_codepoint(assembler), |
| 1403 return_result(assembler); |
| 1404 |
| 1405 Node* iterator = assembler->Parameter(0); |
| 1406 Node* context = assembler->Parameter(3); |
| 1407 |
| 1408 assembler->GotoIf(assembler->WordIsSmi(iterator), &throw_bad_receiver); |
| 1409 assembler->GotoUnless( |
| 1410 assembler->WordEqual(assembler->LoadInstanceType(iterator), |
| 1411 assembler->Int32Constant(JS_STRING_ITERATOR_TYPE)), |
| 1412 &throw_bad_receiver); |
| 1413 |
| 1414 Node* string = |
| 1415 assembler->LoadObjectField(iterator, JSStringIterator::kStringOffset); |
| 1416 Node* position = |
| 1417 assembler->LoadObjectField(iterator, JSStringIterator::kNextIndexOffset); |
| 1418 Node* length = assembler->LoadObjectField(string, String::kLengthOffset); |
| 1419 |
| 1420 assembler->Branch(assembler->SmiLessThan(position, length), &next_codepoint, |
| 1421 &return_result); |
| 1422 |
| 1423 assembler->Bind(&next_codepoint); |
| 1424 { |
| 1425 Node* ch = |
| 1426 LoadSurrogatePairAt(assembler, string, assembler->SmiUntag(length), |
| 1427 assembler->SmiUntag(position)); |
| 1428 Node* value = assembler->StringFromCodePoint(ch, UnicodeEncoding::UTF16); |
| 1429 var_value.Bind(value); |
| 1430 Node* length = assembler->LoadObjectField(value, String::kLengthOffset); |
| 1431 assembler->StoreObjectFieldNoWriteBarrier( |
| 1432 iterator, JSStringIterator::kNextIndexOffset, |
| 1433 assembler->SmiAdd(position, length)); |
| 1434 var_done.Bind(assembler->BooleanConstant(false)); |
| 1435 assembler->Goto(&return_result); |
| 1436 } |
| 1437 |
| 1438 assembler->Bind(&return_result); |
| 1439 { |
| 1440 Node* native_context = assembler->LoadNativeContext(context); |
| 1441 Node* map = assembler->LoadFixedArrayElement( |
| 1442 native_context, |
| 1443 assembler->IntPtrConstant(Context::ITERATOR_RESULT_MAP_INDEX), 0, |
| 1444 CodeStubAssembler::INTPTR_PARAMETERS); |
| 1445 Node* result = assembler->Allocate(JSIteratorResult::kSize); |
| 1446 assembler->StoreMapNoWriteBarrier(result, map); |
| 1447 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset, |
| 1448 Heap::kEmptyFixedArrayRootIndex); |
| 1449 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset, |
| 1450 Heap::kEmptyFixedArrayRootIndex); |
| 1451 assembler->StoreObjectFieldNoWriteBarrier( |
| 1452 result, JSIteratorResult::kValueOffset, var_value.value()); |
| 1453 assembler->StoreObjectFieldNoWriteBarrier( |
| 1454 result, JSIteratorResult::kDoneOffset, var_done.value()); |
| 1455 assembler->Return(result); |
| 1456 } |
| 1457 |
| 1458 assembler->Bind(&throw_bad_receiver); |
| 1459 { |
| 1460 // The {receiver} is not a valid JSGeneratorObject. |
| 1461 Node* result = assembler->CallRuntime( |
| 1462 Runtime::kThrowIncompatibleMethodReceiver, context, |
| 1463 assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked( |
| 1464 "String Iterator.prototype.next", TENURED)), |
| 1465 iterator); |
| 1466 assembler->Return(result); // Never reached. |
| 1467 } |
| 1468 } |
| 1469 |
1085 } // namespace internal | 1470 } // namespace internal |
1086 } // namespace v8 | 1471 } // namespace v8 |
OLD | NEW |