OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 static const int kSmiOnlyLiteralMinimumLength = 1024; | 425 static const int kSmiOnlyLiteralMinimumLength = 1024; |
426 | 426 |
427 | 427 |
428 static Handle<Object> CreateArrayLiteralBoilerplate( | 428 static Handle<Object> CreateArrayLiteralBoilerplate( |
429 Isolate* isolate, | 429 Isolate* isolate, |
430 Handle<FixedArray> literals, | 430 Handle<FixedArray> literals, |
431 Handle<FixedArray> elements) { | 431 Handle<FixedArray> elements) { |
432 // Create the JSArray. | 432 // Create the JSArray. |
433 Handle<JSFunction> constructor( | 433 Handle<JSFunction> constructor( |
434 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); | 434 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); |
435 Handle<Object> object = isolate->factory()->NewJSObject(constructor); | 435 Handle<JSArray> object = |
| 436 Handle<JSArray>::cast(isolate->factory()->NewJSObject(constructor)); |
436 | 437 |
437 if (elements->length() > kSmiOnlyLiteralMinimumLength) { | 438 ElementsKind constant_elements_kind = |
438 Handle<Map> smi_array_map = isolate->factory()->GetElementsTransitionMap( | 439 static_cast<ElementsKind>(Smi::cast(elements->get(0))->value()); |
439 Handle<JSObject>::cast(object), | 440 Handle<FixedArrayBase> constant_elements_values( |
440 FAST_SMI_ONLY_ELEMENTS); | 441 FixedArrayBase::cast(elements->get(1))); |
441 HeapObject::cast(*object)->set_map(*smi_array_map); | 442 |
| 443 ASSERT(FLAG_smi_only_arrays || constant_elements_kind == FAST_ELEMENTS || |
| 444 constant_elements_kind == FAST_SMI_ONLY_ELEMENTS); |
| 445 bool allow_literal_kind_transition = FLAG_smi_only_arrays && |
| 446 constant_elements_kind > object->GetElementsKind(); |
| 447 |
| 448 if (!FLAG_smi_only_arrays && |
| 449 constant_elements_values->length() > kSmiOnlyLiteralMinimumLength && |
| 450 constant_elements_kind != object->GetElementsKind()) { |
| 451 allow_literal_kind_transition = true; |
442 } | 452 } |
443 | 453 |
444 const bool is_cow = | 454 // If the ElementsKind of the constant values of the array literal are less |
445 (elements->map() == isolate->heap()->fixed_cow_array_map()); | 455 // specific than the ElementsKind of the boilerplate array object, change the |
446 Handle<FixedArray> copied_elements = | 456 // boilerplate array object's map to reflect that kind. |
447 is_cow ? elements : isolate->factory()->CopyFixedArray(elements); | 457 if (allow_literal_kind_transition) { |
| 458 Handle<Map> transitioned_array_map = |
| 459 isolate->factory()->GetElementsTransitionMap(object, |
| 460 constant_elements_kind); |
| 461 object->set_map(*transitioned_array_map); |
| 462 } |
448 | 463 |
449 Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements); | 464 Handle<FixedArrayBase> copied_elements_values; |
450 bool has_non_smi = false; | 465 if (constant_elements_kind == FAST_DOUBLE_ELEMENTS) { |
451 if (is_cow) { | 466 ASSERT(FLAG_smi_only_arrays); |
452 // Copy-on-write arrays must be shallow (and simple). | 467 copied_elements_values = isolate->factory()->CopyFixedDoubleArray( |
453 for (int i = 0; i < content->length(); i++) { | 468 Handle<FixedDoubleArray>::cast(constant_elements_values)); |
454 Object* current = content->get(i); | 469 } else { |
455 ASSERT(!current->IsFixedArray()); | 470 ASSERT(constant_elements_kind == FAST_SMI_ONLY_ELEMENTS || |
456 if (!current->IsSmi() && !current->IsTheHole()) { | 471 constant_elements_kind == FAST_ELEMENTS); |
457 has_non_smi = true; | 472 const bool is_cow = |
| 473 (constant_elements_values->map() == |
| 474 isolate->heap()->fixed_cow_array_map()); |
| 475 if (is_cow) { |
| 476 copied_elements_values = constant_elements_values; |
| 477 #if DEBUG |
| 478 Handle<FixedArray> fixed_array_values = |
| 479 Handle<FixedArray>::cast(copied_elements_values); |
| 480 for (int i = 0; i < fixed_array_values->length(); i++) { |
| 481 ASSERT(!fixed_array_values->get(i)->IsFixedArray()); |
458 } | 482 } |
459 } | |
460 #if DEBUG | |
461 for (int i = 0; i < content->length(); i++) { | |
462 ASSERT(!content->get(i)->IsFixedArray()); | |
463 } | |
464 #endif | 483 #endif |
465 } else { | 484 } else { |
466 for (int i = 0; i < content->length(); i++) { | 485 Handle<FixedArray> fixed_array_values = |
467 Object* current = content->get(i); | 486 Handle<FixedArray>::cast(constant_elements_values); |
468 if (current->IsFixedArray()) { | 487 Handle<FixedArray> fixed_array_values_copy = |
469 // The value contains the constant_properties of a | 488 isolate->factory()->CopyFixedArray(fixed_array_values); |
470 // simple object or array literal. | 489 copied_elements_values = fixed_array_values_copy; |
471 Handle<FixedArray> fa(FixedArray::cast(content->get(i))); | 490 for (int i = 0; i < fixed_array_values->length(); i++) { |
472 Handle<Object> result = | 491 Object* current = fixed_array_values->get(i); |
473 CreateLiteralBoilerplate(isolate, literals, fa); | 492 if (current->IsFixedArray()) { |
474 if (result.is_null()) return result; | 493 // The value contains the constant_properties of a |
475 content->set(i, *result); | 494 // simple object or array literal. |
476 has_non_smi = true; | 495 Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i))); |
477 } else { | 496 Handle<Object> result = |
478 if (!current->IsSmi() && !current->IsTheHole()) { | 497 CreateLiteralBoilerplate(isolate, literals, fa); |
479 has_non_smi = true; | 498 if (result.is_null()) return result; |
| 499 fixed_array_values_copy->set(i, *result); |
480 } | 500 } |
481 } | 501 } |
482 } | 502 } |
483 } | 503 } |
484 | 504 object->set_elements(*copied_elements_values); |
485 // Set the elements. | 505 object->set_length(Smi::FromInt(copied_elements_values->length())); |
486 Handle<JSArray> js_object(Handle<JSArray>::cast(object)); | |
487 isolate->factory()->SetContent(js_object, content); | |
488 | |
489 if (has_non_smi && js_object->HasFastSmiOnlyElements()) { | |
490 isolate->factory()->EnsureCanContainNonSmiElements(js_object); | |
491 } | |
492 | |
493 return object; | 506 return object; |
494 } | 507 } |
495 | 508 |
496 | 509 |
497 static Handle<Object> CreateLiteralBoilerplate( | 510 static Handle<Object> CreateLiteralBoilerplate( |
498 Isolate* isolate, | 511 Isolate* isolate, |
499 Handle<FixedArray> literals, | 512 Handle<FixedArray> literals, |
500 Handle<FixedArray> array) { | 513 Handle<FixedArray> array) { |
501 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); | 514 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); |
502 const bool kHasNoFunctionLiteral = false; | 515 const bool kHasNoFunctionLiteral = false; |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
697 | 710 |
698 | 711 |
699 RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) { | 712 RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) { |
700 ASSERT(args.length() == 1); | 713 ASSERT(args.length() == 1); |
701 CONVERT_CHECKED(JSProxy, proxy, args[0]); | 714 CONVERT_CHECKED(JSProxy, proxy, args[0]); |
702 proxy->Fix(); | 715 proxy->Fix(); |
703 return isolate->heap()->undefined_value(); | 716 return isolate->heap()->undefined_value(); |
704 } | 717 } |
705 | 718 |
706 | 719 |
| 720 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInitialize) { |
| 721 HandleScope scope(isolate); |
| 722 ASSERT(args.length() == 1); |
| 723 CONVERT_ARG_CHECKED(JSSet, holder, 0); |
| 724 Handle<ObjectHashSet> table = isolate->factory()->NewObjectHashSet(0); |
| 725 holder->set_table(*table); |
| 726 return *holder; |
| 727 } |
| 728 |
| 729 |
| 730 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAdd) { |
| 731 HandleScope scope(isolate); |
| 732 ASSERT(args.length() == 2); |
| 733 CONVERT_ARG_CHECKED(JSSet, holder, 0); |
| 734 Handle<Object> key(args[1]); |
| 735 Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table())); |
| 736 table = ObjectHashSetAdd(table, key); |
| 737 holder->set_table(*table); |
| 738 return isolate->heap()->undefined_symbol(); |
| 739 } |
| 740 |
| 741 |
| 742 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetHas) { |
| 743 HandleScope scope(isolate); |
| 744 ASSERT(args.length() == 2); |
| 745 CONVERT_ARG_CHECKED(JSSet, holder, 0); |
| 746 Handle<Object> key(args[1]); |
| 747 Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table())); |
| 748 return isolate->heap()->ToBoolean(table->Contains(*key)); |
| 749 } |
| 750 |
| 751 |
| 752 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDelete) { |
| 753 HandleScope scope(isolate); |
| 754 ASSERT(args.length() == 2); |
| 755 CONVERT_ARG_CHECKED(JSSet, holder, 0); |
| 756 Handle<Object> key(args[1]); |
| 757 Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table())); |
| 758 table = ObjectHashSetRemove(table, key); |
| 759 holder->set_table(*table); |
| 760 return isolate->heap()->undefined_symbol(); |
| 761 } |
| 762 |
| 763 |
| 764 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapInitialize) { |
| 765 HandleScope scope(isolate); |
| 766 ASSERT(args.length() == 1); |
| 767 CONVERT_ARG_CHECKED(JSMap, holder, 0); |
| 768 Handle<ObjectHashTable> table = isolate->factory()->NewObjectHashTable(0); |
| 769 holder->set_table(*table); |
| 770 return *holder; |
| 771 } |
| 772 |
| 773 |
| 774 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapGet) { |
| 775 HandleScope scope(isolate); |
| 776 ASSERT(args.length() == 2); |
| 777 CONVERT_ARG_CHECKED(JSMap, holder, 0); |
| 778 Handle<Object> key(args[1]); |
| 779 return ObjectHashTable::cast(holder->table())->Lookup(*key); |
| 780 } |
| 781 |
| 782 |
| 783 RUNTIME_FUNCTION(MaybeObject*, Runtime_MapSet) { |
| 784 HandleScope scope(isolate); |
| 785 ASSERT(args.length() == 3); |
| 786 CONVERT_ARG_CHECKED(JSMap, holder, 0); |
| 787 Handle<Object> key(args[1]); |
| 788 Handle<Object> value(args[2]); |
| 789 Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table())); |
| 790 Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value); |
| 791 holder->set_table(*new_table); |
| 792 return *value; |
| 793 } |
| 794 |
| 795 |
707 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapInitialize) { | 796 RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapInitialize) { |
708 HandleScope scope(isolate); | 797 HandleScope scope(isolate); |
709 ASSERT(args.length() == 1); | 798 ASSERT(args.length() == 1); |
710 CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0); | 799 CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0); |
711 ASSERT(weakmap->map()->inobject_properties() == 0); | 800 ASSERT(weakmap->map()->inobject_properties() == 0); |
712 Handle<ObjectHashTable> table = isolate->factory()->NewObjectHashTable(0); | 801 Handle<ObjectHashTable> table = isolate->factory()->NewObjectHashTable(0); |
713 weakmap->set_table(*table); | 802 weakmap->set_table(*table); |
714 weakmap->set_next(Smi::FromInt(0)); | 803 weakmap->set_next(Smi::FromInt(0)); |
715 return *weakmap; | 804 return *weakmap; |
716 } | 805 } |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
954 // if args[1] is a data property on args[0] | 1043 // if args[1] is a data property on args[0] |
955 // [false, value, Writeable, Enumerable, Configurable] | 1044 // [false, value, Writeable, Enumerable, Configurable] |
956 // if args[1] is an accessor on args[0] | 1045 // if args[1] is an accessor on args[0] |
957 // [true, GetFunction, SetFunction, Enumerable, Configurable] | 1046 // [true, GetFunction, SetFunction, Enumerable, Configurable] |
958 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) { | 1047 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) { |
959 ASSERT(args.length() == 2); | 1048 ASSERT(args.length() == 2); |
960 Heap* heap = isolate->heap(); | 1049 Heap* heap = isolate->heap(); |
961 HandleScope scope(isolate); | 1050 HandleScope scope(isolate); |
962 Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE); | 1051 Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE); |
963 Handle<JSArray> desc = isolate->factory()->NewJSArrayWithElements(elms); | 1052 Handle<JSArray> desc = isolate->factory()->NewJSArrayWithElements(elms); |
964 LookupResult result; | 1053 LookupResult result(isolate); |
965 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 1054 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
966 CONVERT_ARG_CHECKED(String, name, 1); | 1055 CONVERT_ARG_CHECKED(String, name, 1); |
967 | 1056 |
968 // This could be an element. | 1057 // This could be an element. |
969 uint32_t index; | 1058 uint32_t index; |
970 if (name->AsArrayIndex(&index)) { | 1059 if (name->AsArrayIndex(&index)) { |
971 switch (obj->HasLocalElement(index)) { | 1060 switch (obj->HasLocalElement(index)) { |
972 case JSObject::UNDEFINED_ELEMENT: | 1061 case JSObject::UNDEFINED_ELEMENT: |
973 return heap->undefined_value(); | 1062 return heap->undefined_value(); |
974 | 1063 |
(...skipping 10 matching lines...) Expand all Loading... |
985 elms->set(VALUE_INDEX, *substr); | 1074 elms->set(VALUE_INDEX, *substr); |
986 elms->set(WRITABLE_INDEX, heap->false_value()); | 1075 elms->set(WRITABLE_INDEX, heap->false_value()); |
987 elms->set(ENUMERABLE_INDEX, heap->false_value()); | 1076 elms->set(ENUMERABLE_INDEX, heap->false_value()); |
988 elms->set(CONFIGURABLE_INDEX, heap->false_value()); | 1077 elms->set(CONFIGURABLE_INDEX, heap->false_value()); |
989 return *desc; | 1078 return *desc; |
990 } | 1079 } |
991 | 1080 |
992 case JSObject::INTERCEPTED_ELEMENT: | 1081 case JSObject::INTERCEPTED_ELEMENT: |
993 case JSObject::FAST_ELEMENT: { | 1082 case JSObject::FAST_ELEMENT: { |
994 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); | 1083 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); |
995 Handle<Object> value = GetElement(obj, index); | 1084 Handle<Object> value = Object::GetElement(obj, index); |
996 RETURN_IF_EMPTY_HANDLE(isolate, value); | 1085 RETURN_IF_EMPTY_HANDLE(isolate, value); |
997 elms->set(VALUE_INDEX, *value); | 1086 elms->set(VALUE_INDEX, *value); |
998 elms->set(WRITABLE_INDEX, heap->true_value()); | 1087 elms->set(WRITABLE_INDEX, heap->true_value()); |
999 elms->set(ENUMERABLE_INDEX, heap->true_value()); | 1088 elms->set(ENUMERABLE_INDEX, heap->true_value()); |
1000 elms->set(CONFIGURABLE_INDEX, heap->true_value()); | 1089 elms->set(CONFIGURABLE_INDEX, heap->true_value()); |
1001 return *desc; | 1090 return *desc; |
1002 } | 1091 } |
1003 | 1092 |
1004 case JSObject::DICTIONARY_ELEMENT: { | 1093 case JSObject::DICTIONARY_ELEMENT: { |
1005 Handle<JSObject> holder = obj; | 1094 Handle<JSObject> holder = obj; |
(...skipping 23 matching lines...) Expand all Loading... |
1029 elms->set(GETTER_INDEX, callbacks->get(0)); | 1118 elms->set(GETTER_INDEX, callbacks->get(0)); |
1030 } | 1119 } |
1031 if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) { | 1120 if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) { |
1032 elms->set(SETTER_INDEX, callbacks->get(1)); | 1121 elms->set(SETTER_INDEX, callbacks->get(1)); |
1033 } | 1122 } |
1034 break; | 1123 break; |
1035 } | 1124 } |
1036 case NORMAL: { | 1125 case NORMAL: { |
1037 // This is a data property. | 1126 // This is a data property. |
1038 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); | 1127 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); |
1039 Handle<Object> value = GetElement(obj, index); | 1128 Handle<Object> value = Object::GetElement(obj, index); |
1040 ASSERT(!value.is_null()); | 1129 ASSERT(!value.is_null()); |
1041 elms->set(VALUE_INDEX, *value); | 1130 elms->set(VALUE_INDEX, *value); |
1042 elms->set(WRITABLE_INDEX, heap->ToBoolean(!details.IsReadOnly())); | 1131 elms->set(WRITABLE_INDEX, heap->ToBoolean(!details.IsReadOnly())); |
1043 break; | 1132 break; |
1044 } | 1133 } |
1045 default: | 1134 default: |
1046 UNREACHABLE(); | 1135 UNREACHABLE(); |
1047 break; | 1136 break; |
1048 } | 1137 } |
1049 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!details.IsDontEnum())); | 1138 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!details.IsDontEnum())); |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1233 Handle<Object> value(pairs->get(i + 1), isolate); | 1322 Handle<Object> value(pairs->get(i + 1), isolate); |
1234 | 1323 |
1235 // We have to declare a global const property. To capture we only | 1324 // We have to declare a global const property. To capture we only |
1236 // assign to it when evaluating the assignment for "const x = | 1325 // assign to it when evaluating the assignment for "const x = |
1237 // <expr>" the initial value is the hole. | 1326 // <expr>" the initial value is the hole. |
1238 bool is_const_property = value->IsTheHole(); | 1327 bool is_const_property = value->IsTheHole(); |
1239 bool is_function_declaration = false; | 1328 bool is_function_declaration = false; |
1240 if (value->IsUndefined() || is_const_property) { | 1329 if (value->IsUndefined() || is_const_property) { |
1241 // Lookup the property in the global object, and don't set the | 1330 // Lookup the property in the global object, and don't set the |
1242 // value of the variable if the property is already there. | 1331 // value of the variable if the property is already there. |
1243 LookupResult lookup; | 1332 LookupResult lookup(isolate); |
1244 global->Lookup(*name, &lookup); | 1333 global->Lookup(*name, &lookup); |
1245 if (lookup.IsProperty()) { | 1334 if (lookup.IsProperty()) { |
1246 // We found an existing property. Unless it was an interceptor | 1335 // We found an existing property. Unless it was an interceptor |
1247 // that claims the property is absent, skip this declaration. | 1336 // that claims the property is absent, skip this declaration. |
1248 if (lookup.type() != INTERCEPTOR) { | 1337 if (lookup.type() != INTERCEPTOR) { |
1249 continue; | 1338 continue; |
1250 } | 1339 } |
1251 PropertyAttributes attributes = global->GetPropertyAttribute(*name); | 1340 PropertyAttributes attributes = global->GetPropertyAttribute(*name); |
1252 if (attributes != ABSENT) { | 1341 if (attributes != ABSENT) { |
1253 continue; | 1342 continue; |
1254 } | 1343 } |
1255 // Fall-through and introduce the absent property by using | 1344 // Fall-through and introduce the absent property by using |
1256 // SetProperty. | 1345 // SetProperty. |
1257 } | 1346 } |
1258 } else { | 1347 } else { |
1259 is_function_declaration = true; | 1348 is_function_declaration = true; |
1260 // Copy the function and update its context. Use it as value. | 1349 // Copy the function and update its context. Use it as value. |
1261 Handle<SharedFunctionInfo> shared = | 1350 Handle<SharedFunctionInfo> shared = |
1262 Handle<SharedFunctionInfo>::cast(value); | 1351 Handle<SharedFunctionInfo>::cast(value); |
1263 Handle<JSFunction> function = | 1352 Handle<JSFunction> function = |
1264 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, | 1353 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, |
1265 context, | 1354 context, |
1266 TENURED); | 1355 TENURED); |
1267 value = function; | 1356 value = function; |
1268 } | 1357 } |
1269 | 1358 |
1270 LookupResult lookup; | 1359 LookupResult lookup(isolate); |
1271 global->LocalLookup(*name, &lookup); | 1360 global->LocalLookup(*name, &lookup); |
1272 | 1361 |
1273 // Compute the property attributes. According to ECMA-262, section | 1362 // Compute the property attributes. According to ECMA-262, section |
1274 // 13, page 71, the property must be read-only and | 1363 // 13, page 71, the property must be read-only and |
1275 // non-deletable. However, neither SpiderMonkey nor KJS creates the | 1364 // non-deletable. However, neither SpiderMonkey nor KJS creates the |
1276 // property as read-only, so we don't either. | 1365 // property as read-only, so we don't either. |
1277 int attr = NONE; | 1366 int attr = NONE; |
1278 if ((flags & kDeclareGlobalsEvalFlag) == 0) { | 1367 if (!DeclareGlobalsEvalFlag::decode(flags)) { |
1279 attr |= DONT_DELETE; | 1368 attr |= DONT_DELETE; |
1280 } | 1369 } |
1281 bool is_native = (flags & kDeclareGlobalsNativeFlag) != 0; | 1370 bool is_native = DeclareGlobalsNativeFlag::decode(flags); |
1282 if (is_const_property || (is_native && is_function_declaration)) { | 1371 if (is_const_property || (is_native && is_function_declaration)) { |
1283 attr |= READ_ONLY; | 1372 attr |= READ_ONLY; |
1284 } | 1373 } |
1285 | 1374 |
1286 // Safari does not allow the invocation of callback setters for | 1375 // Safari does not allow the invocation of callback setters for |
1287 // function declarations. To mimic this behavior, we do not allow | 1376 // function declarations. To mimic this behavior, we do not allow |
1288 // the invocation of setters for function values. This makes a | 1377 // the invocation of setters for function values. This makes a |
1289 // difference for global functions with the same names as event | 1378 // difference for global functions with the same names as event |
1290 // handlers such as "function onload() {}". Firefox does call the | 1379 // handlers such as "function onload() {}". Firefox does call the |
1291 // onload setter in those case and Safari does not. We follow | 1380 // onload setter in those case and Safari does not. We follow |
1292 // Safari for compatibility. | 1381 // Safari for compatibility. |
1293 if (value->IsJSFunction()) { | 1382 if (value->IsJSFunction()) { |
1294 // Do not change DONT_DELETE to false from true. | 1383 // Do not change DONT_DELETE to false from true. |
1295 if (lookup.IsProperty() && (lookup.type() != INTERCEPTOR)) { | 1384 if (lookup.IsProperty() && (lookup.type() != INTERCEPTOR)) { |
1296 attr |= lookup.GetAttributes() & DONT_DELETE; | 1385 attr |= lookup.GetAttributes() & DONT_DELETE; |
1297 } | 1386 } |
1298 PropertyAttributes attributes = static_cast<PropertyAttributes>(attr); | 1387 PropertyAttributes attributes = static_cast<PropertyAttributes>(attr); |
1299 | 1388 |
1300 RETURN_IF_EMPTY_HANDLE(isolate, | 1389 RETURN_IF_EMPTY_HANDLE(isolate, |
1301 SetLocalPropertyIgnoreAttributes(global, | 1390 SetLocalPropertyIgnoreAttributes(global, |
1302 name, | 1391 name, |
1303 value, | 1392 value, |
1304 attributes)); | 1393 attributes)); |
1305 } else { | 1394 } else { |
1306 StrictModeFlag strict_mode = | 1395 StrictModeFlag strict_mode = DeclareGlobalsStrictModeFlag::decode(flags); |
1307 ((flags & kDeclareGlobalsStrictModeFlag) != 0) ? kStrictMode | |
1308 : kNonStrictMode; | |
1309 RETURN_IF_EMPTY_HANDLE(isolate, | 1396 RETURN_IF_EMPTY_HANDLE(isolate, |
1310 SetProperty(global, | 1397 SetProperty(global, |
1311 name, | 1398 name, |
1312 value, | 1399 value, |
1313 static_cast<PropertyAttributes>(attr), | 1400 static_cast<PropertyAttributes>(attr), |
1314 strict_mode)); | 1401 strict_mode)); |
1315 } | 1402 } |
1316 } | 1403 } |
1317 | 1404 |
1318 ASSERT(!isolate->has_pending_exception()); | 1405 ASSERT(!isolate->has_pending_exception()); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1392 Handle<Object> value(isolate->heap()->undefined_value(), isolate); | 1479 Handle<Object> value(isolate->heap()->undefined_value(), isolate); |
1393 if (*initial_value != NULL) value = initial_value; | 1480 if (*initial_value != NULL) value = initial_value; |
1394 // Declaring a const context slot is a conflicting declaration if | 1481 // Declaring a const context slot is a conflicting declaration if |
1395 // there is a callback with that name in a prototype. It is | 1482 // there is a callback with that name in a prototype. It is |
1396 // allowed to introduce const variables in | 1483 // allowed to introduce const variables in |
1397 // JSContextExtensionObjects. They are treated specially in | 1484 // JSContextExtensionObjects. They are treated specially in |
1398 // SetProperty and no setters are invoked for those since they are | 1485 // SetProperty and no setters are invoked for those since they are |
1399 // not real JSObjects. | 1486 // not real JSObjects. |
1400 if (initial_value->IsTheHole() && | 1487 if (initial_value->IsTheHole() && |
1401 !object->IsJSContextExtensionObject()) { | 1488 !object->IsJSContextExtensionObject()) { |
1402 LookupResult lookup; | 1489 LookupResult lookup(isolate); |
1403 object->Lookup(*name, &lookup); | 1490 object->Lookup(*name, &lookup); |
1404 if (lookup.IsProperty() && (lookup.type() == CALLBACKS)) { | 1491 if (lookup.IsProperty() && (lookup.type() == CALLBACKS)) { |
1405 return ThrowRedeclarationError(isolate, "const", name); | 1492 return ThrowRedeclarationError(isolate, "const", name); |
1406 } | 1493 } |
1407 } | 1494 } |
1408 RETURN_IF_EMPTY_HANDLE(isolate, | 1495 RETURN_IF_EMPTY_HANDLE(isolate, |
1409 SetProperty(object, name, value, mode, | 1496 SetProperty(object, name, value, mode, |
1410 kNonStrictMode)); | 1497 kNonStrictMode)); |
1411 } | 1498 } |
1412 | 1499 |
(...skipping 23 matching lines...) Expand all Loading... |
1436 PropertyAttributes attributes = DONT_DELETE; | 1523 PropertyAttributes attributes = DONT_DELETE; |
1437 | 1524 |
1438 // Lookup the property locally in the global object. If it isn't | 1525 // Lookup the property locally in the global object. If it isn't |
1439 // there, there is a property with this name in the prototype chain. | 1526 // there, there is a property with this name in the prototype chain. |
1440 // We follow Safari and Firefox behavior and only set the property | 1527 // We follow Safari and Firefox behavior and only set the property |
1441 // locally if there is an explicit initialization value that we have | 1528 // locally if there is an explicit initialization value that we have |
1442 // to assign to the property. | 1529 // to assign to the property. |
1443 // Note that objects can have hidden prototypes, so we need to traverse | 1530 // Note that objects can have hidden prototypes, so we need to traverse |
1444 // the whole chain of hidden prototypes to do a 'local' lookup. | 1531 // the whole chain of hidden prototypes to do a 'local' lookup. |
1445 Object* object = global; | 1532 Object* object = global; |
1446 LookupResult lookup; | 1533 LookupResult lookup(isolate); |
1447 while (object->IsJSObject() && | 1534 while (object->IsJSObject() && |
1448 JSObject::cast(object)->map()->is_hidden_prototype()) { | 1535 JSObject::cast(object)->map()->is_hidden_prototype()) { |
1449 JSObject* raw_holder = JSObject::cast(object); | 1536 JSObject* raw_holder = JSObject::cast(object); |
1450 raw_holder->LocalLookup(*name, &lookup); | 1537 raw_holder->LocalLookup(*name, &lookup); |
1451 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) { | 1538 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) { |
1452 HandleScope handle_scope(isolate); | 1539 HandleScope handle_scope(isolate); |
1453 Handle<JSObject> holder(raw_holder); | 1540 Handle<JSObject> holder(raw_holder); |
1454 PropertyAttributes intercepted = holder->GetPropertyAttribute(*name); | 1541 PropertyAttributes intercepted = holder->GetPropertyAttribute(*name); |
1455 // Update the raw pointer in case it's changed due to GC. | 1542 // Update the raw pointer in case it's changed due to GC. |
1456 raw_holder = *holder; | 1543 raw_holder = *holder; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1490 // According to ECMA-262, section 12.2, page 62, the property must | 1577 // According to ECMA-262, section 12.2, page 62, the property must |
1491 // not be deletable. Since it's a const, it must be READ_ONLY too. | 1578 // not be deletable. Since it's a const, it must be READ_ONLY too. |
1492 PropertyAttributes attributes = | 1579 PropertyAttributes attributes = |
1493 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | 1580 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
1494 | 1581 |
1495 // Lookup the property locally in the global object. If it isn't | 1582 // Lookup the property locally in the global object. If it isn't |
1496 // there, we add the property and take special precautions to always | 1583 // there, we add the property and take special precautions to always |
1497 // add it as a local property even in case of callbacks in the | 1584 // add it as a local property even in case of callbacks in the |
1498 // prototype chain (this rules out using SetProperty). | 1585 // prototype chain (this rules out using SetProperty). |
1499 // We use SetLocalPropertyIgnoreAttributes instead | 1586 // We use SetLocalPropertyIgnoreAttributes instead |
1500 LookupResult lookup; | 1587 LookupResult lookup(isolate); |
1501 global->LocalLookup(*name, &lookup); | 1588 global->LocalLookup(*name, &lookup); |
1502 if (!lookup.IsProperty()) { | 1589 if (!lookup.IsProperty()) { |
1503 return global->SetLocalPropertyIgnoreAttributes(*name, | 1590 return global->SetLocalPropertyIgnoreAttributes(*name, |
1504 *value, | 1591 *value, |
1505 attributes); | 1592 attributes); |
1506 } | 1593 } |
1507 | 1594 |
1508 if (!lookup.IsReadOnly()) { | 1595 if (!lookup.IsReadOnly()) { |
1509 // Restore global object from context (in case of GC) and continue | 1596 // Restore global object from context (in case of GC) and continue |
1510 // with setting the value. | 1597 // with setting the value. |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1607 // | 1694 // |
1608 // function f() { eval("delete x; const x;"); } | 1695 // function f() { eval("delete x; const x;"); } |
1609 // | 1696 // |
1610 // In that case, the initialization behaves like a normal assignment. | 1697 // In that case, the initialization behaves like a normal assignment. |
1611 Handle<JSObject> object = Handle<JSObject>::cast(holder); | 1698 Handle<JSObject> object = Handle<JSObject>::cast(holder); |
1612 | 1699 |
1613 if (*object == context->extension()) { | 1700 if (*object == context->extension()) { |
1614 // This is the property that was introduced by the const declaration. | 1701 // This is the property that was introduced by the const declaration. |
1615 // Set it if it hasn't been set before. NOTE: We cannot use | 1702 // Set it if it hasn't been set before. NOTE: We cannot use |
1616 // GetProperty() to get the current value as it 'unholes' the value. | 1703 // GetProperty() to get the current value as it 'unholes' the value. |
1617 LookupResult lookup; | 1704 LookupResult lookup(isolate); |
1618 object->LocalLookupRealNamedProperty(*name, &lookup); | 1705 object->LocalLookupRealNamedProperty(*name, &lookup); |
1619 ASSERT(lookup.IsProperty()); // the property was declared | 1706 ASSERT(lookup.IsProperty()); // the property was declared |
1620 ASSERT(lookup.IsReadOnly()); // and it was declared as read-only | 1707 ASSERT(lookup.IsReadOnly()); // and it was declared as read-only |
1621 | 1708 |
1622 PropertyType type = lookup.type(); | 1709 PropertyType type = lookup.type(); |
1623 if (type == FIELD) { | 1710 if (type == FIELD) { |
1624 FixedArray* properties = object->properties(); | 1711 FixedArray* properties = object->properties(); |
1625 int index = lookup.GetFieldIndex(); | 1712 int index = lookup.GetFieldIndex(); |
1626 if (properties->get(index)->IsTheHole()) { | 1713 if (properties->get(index)->IsTheHole()) { |
1627 properties->set(index, *value); | 1714 properties->set(index, *value); |
(...skipping 28 matching lines...) Expand all Loading... |
1656 ASSERT(args.length() == 2); | 1743 ASSERT(args.length() == 2); |
1657 CONVERT_ARG_CHECKED(JSObject, object, 0); | 1744 CONVERT_ARG_CHECKED(JSObject, object, 0); |
1658 CONVERT_SMI_ARG_CHECKED(properties, 1); | 1745 CONVERT_SMI_ARG_CHECKED(properties, 1); |
1659 if (object->HasFastProperties()) { | 1746 if (object->HasFastProperties()) { |
1660 NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); | 1747 NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); |
1661 } | 1748 } |
1662 return *object; | 1749 return *object; |
1663 } | 1750 } |
1664 | 1751 |
1665 | 1752 |
1666 RUNTIME_FUNCTION(MaybeObject*, Runtime_NonSmiElementStored) { | |
1667 ASSERT(args.length() == 1); | |
1668 CONVERT_ARG_CHECKED(JSObject, object, 0); | |
1669 if (object->HasFastSmiOnlyElements()) { | |
1670 MaybeObject* maybe_map = object->GetElementsTransitionMap(FAST_ELEMENTS); | |
1671 Map* map; | |
1672 if (!maybe_map->To<Map>(&map)) return maybe_map; | |
1673 object->set_map(Map::cast(map)); | |
1674 } | |
1675 return *object; | |
1676 } | |
1677 | |
1678 | |
1679 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) { | 1753 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) { |
1680 HandleScope scope(isolate); | 1754 HandleScope scope(isolate); |
1681 ASSERT(args.length() == 4); | 1755 ASSERT(args.length() == 4); |
1682 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); | 1756 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); |
1683 CONVERT_ARG_CHECKED(String, subject, 1); | 1757 CONVERT_ARG_CHECKED(String, subject, 1); |
1684 // Due to the way the JS calls are constructed this must be less than the | 1758 // Due to the way the JS calls are constructed this must be less than the |
1685 // length of a string, i.e. it is always a Smi. We check anyway for security. | 1759 // length of a string, i.e. it is always a Smi. We check anyway for security. |
1686 CONVERT_SMI_ARG_CHECKED(index, 2); | 1760 CONVERT_SMI_ARG_CHECKED(index, 2); |
1687 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3); | 1761 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3); |
1688 RUNTIME_ASSERT(last_match_info->HasFastElements()); | 1762 RUNTIME_ASSERT(last_match_info->HasFastElements()); |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1923 | 1997 |
1924 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionMarkNameShouldPrintAsAnonymous) { | 1998 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionMarkNameShouldPrintAsAnonymous) { |
1925 NoHandleAllocation ha; | 1999 NoHandleAllocation ha; |
1926 ASSERT(args.length() == 1); | 2000 ASSERT(args.length() == 1); |
1927 CONVERT_CHECKED(JSFunction, f, args[0]); | 2001 CONVERT_CHECKED(JSFunction, f, args[0]); |
1928 f->shared()->set_name_should_print_as_anonymous(true); | 2002 f->shared()->set_name_should_print_as_anonymous(true); |
1929 return isolate->heap()->undefined_value(); | 2003 return isolate->heap()->undefined_value(); |
1930 } | 2004 } |
1931 | 2005 |
1932 | 2006 |
1933 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetBound) { | |
1934 HandleScope scope(isolate); | |
1935 ASSERT(args.length() == 1); | |
1936 | |
1937 CONVERT_CHECKED(JSFunction, fun, args[0]); | |
1938 fun->shared()->set_bound(true); | |
1939 return isolate->heap()->undefined_value(); | |
1940 } | |
1941 | |
1942 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionRemovePrototype) { | 2007 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionRemovePrototype) { |
1943 NoHandleAllocation ha; | 2008 NoHandleAllocation ha; |
1944 ASSERT(args.length() == 1); | 2009 ASSERT(args.length() == 1); |
1945 | 2010 |
1946 CONVERT_CHECKED(JSFunction, f, args[0]); | 2011 CONVERT_CHECKED(JSFunction, f, args[0]); |
1947 Object* obj = f->RemovePrototype(); | 2012 Object* obj = f->RemovePrototype(); |
1948 if (obj->IsFailure()) return obj; | 2013 if (obj->IsFailure()) return obj; |
1949 | 2014 |
1950 return isolate->heap()->undefined_value(); | 2015 return isolate->heap()->undefined_value(); |
1951 } | 2016 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2010 NoHandleAllocation ha; | 2075 NoHandleAllocation ha; |
2011 ASSERT(args.length() == 2); | 2076 ASSERT(args.length() == 2); |
2012 | 2077 |
2013 CONVERT_CHECKED(JSFunction, fun, args[0]); | 2078 CONVERT_CHECKED(JSFunction, fun, args[0]); |
2014 CONVERT_CHECKED(Smi, length, args[1]); | 2079 CONVERT_CHECKED(Smi, length, args[1]); |
2015 fun->shared()->set_length(length->value()); | 2080 fun->shared()->set_length(length->value()); |
2016 return length; | 2081 return length; |
2017 } | 2082 } |
2018 | 2083 |
2019 | 2084 |
2020 // Creates a local, readonly, property called length with the correct | |
2021 // length (when read by the user). This effectively overwrites the | |
2022 // interceptor used to normally provide the length. | |
2023 RUNTIME_FUNCTION(MaybeObject*, Runtime_BoundFunctionSetLength) { | |
2024 NoHandleAllocation ha; | |
2025 ASSERT(args.length() == 2); | |
2026 CONVERT_CHECKED(JSFunction, fun, args[0]); | |
2027 CONVERT_CHECKED(Smi, length, args[1]); | |
2028 MaybeObject* maybe_name = | |
2029 isolate->heap()->AllocateStringFromAscii(CStrVector("length")); | |
2030 String* name; | |
2031 if (!maybe_name->To(&name)) return maybe_name; | |
2032 PropertyAttributes attr = | |
2033 static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY); | |
2034 return fun->AddProperty(name, length, attr, kNonStrictMode); | |
2035 } | |
2036 | |
2037 | |
2038 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetPrototype) { | 2085 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetPrototype) { |
2039 NoHandleAllocation ha; | 2086 NoHandleAllocation ha; |
2040 ASSERT(args.length() == 2); | 2087 ASSERT(args.length() == 2); |
2041 | 2088 |
2042 CONVERT_CHECKED(JSFunction, fun, args[0]); | 2089 CONVERT_CHECKED(JSFunction, fun, args[0]); |
2043 ASSERT(fun->should_have_prototype()); | 2090 ASSERT(fun->should_have_prototype()); |
2044 Object* obj; | 2091 Object* obj; |
2045 { MaybeObject* maybe_obj = | 2092 { MaybeObject* maybe_obj = |
2046 Accessors::FunctionSetPrototype(fun, args[1], NULL); | 2093 Accessors::FunctionSetPrototype(fun, args[1], NULL); |
2047 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2094 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2130 CONVERT_ARG_CHECKED(JSFunction, target, 0); | 2177 CONVERT_ARG_CHECKED(JSFunction, target, 0); |
2131 Handle<Object> code = args.at<Object>(1); | 2178 Handle<Object> code = args.at<Object>(1); |
2132 | 2179 |
2133 Handle<Context> context(target->context()); | 2180 Handle<Context> context(target->context()); |
2134 | 2181 |
2135 if (!code->IsNull()) { | 2182 if (!code->IsNull()) { |
2136 RUNTIME_ASSERT(code->IsJSFunction()); | 2183 RUNTIME_ASSERT(code->IsJSFunction()); |
2137 Handle<JSFunction> fun = Handle<JSFunction>::cast(code); | 2184 Handle<JSFunction> fun = Handle<JSFunction>::cast(code); |
2138 Handle<SharedFunctionInfo> shared(fun->shared()); | 2185 Handle<SharedFunctionInfo> shared(fun->shared()); |
2139 | 2186 |
2140 if (!EnsureCompiled(shared, KEEP_EXCEPTION)) { | 2187 if (!SharedFunctionInfo::EnsureCompiled(shared, KEEP_EXCEPTION)) { |
2141 return Failure::Exception(); | 2188 return Failure::Exception(); |
2142 } | 2189 } |
2143 // Since we don't store the source for this we should never | 2190 // Since we don't store the source for this we should never |
2144 // optimize this. | 2191 // optimize this. |
2145 shared->code()->set_optimizable(false); | 2192 shared->code()->set_optimizable(false); |
2146 | |
2147 // Set the code, scope info, formal parameter count, | 2193 // Set the code, scope info, formal parameter count, |
2148 // and the length of the target function. | 2194 // and the length of the target function. |
2149 target->shared()->set_code(shared->code()); | 2195 target->shared()->set_code(shared->code()); |
2150 target->ReplaceCode(shared->code()); | 2196 target->ReplaceCode(shared->code()); |
2151 target->shared()->set_scope_info(shared->scope_info()); | 2197 target->shared()->set_scope_info(shared->scope_info()); |
2152 target->shared()->set_length(shared->length()); | 2198 target->shared()->set_length(shared->length()); |
2153 target->shared()->set_formal_parameter_count( | 2199 target->shared()->set_formal_parameter_count( |
2154 shared->formal_parameter_count()); | 2200 shared->formal_parameter_count()); |
2155 // Set the source code of the target function to undefined. | 2201 // Set the source code of the target function to undefined. |
2156 // SetCode is only used for built-in constructors like String, | 2202 // SetCode is only used for built-in constructors like String, |
(...skipping 1905 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4062 Handle<Object> result = | 4108 Handle<Object> result = |
4063 GetCharAt(Handle<String>(String::cast(js_value->value())), index); | 4109 GetCharAt(Handle<String>(String::cast(js_value->value())), index); |
4064 if (!result->IsUndefined()) return *result; | 4110 if (!result->IsUndefined()) return *result; |
4065 } | 4111 } |
4066 | 4112 |
4067 if (object->IsString() || object->IsNumber() || object->IsBoolean()) { | 4113 if (object->IsString() || object->IsNumber() || object->IsBoolean()) { |
4068 Handle<Object> prototype = GetPrototype(object); | 4114 Handle<Object> prototype = GetPrototype(object); |
4069 return prototype->GetElement(index); | 4115 return prototype->GetElement(index); |
4070 } | 4116 } |
4071 | 4117 |
4072 return GetElement(object, index); | |
4073 } | |
4074 | |
4075 | |
4076 MaybeObject* Runtime::GetElement(Handle<Object> object, uint32_t index) { | |
4077 return object->GetElement(index); | 4118 return object->GetElement(index); |
4078 } | 4119 } |
4079 | 4120 |
4080 | 4121 |
4081 MaybeObject* Runtime::GetObjectProperty(Isolate* isolate, | 4122 MaybeObject* Runtime::GetObjectProperty(Isolate* isolate, |
4082 Handle<Object> object, | 4123 Handle<Object> object, |
4083 Handle<Object> key) { | 4124 Handle<Object> key) { |
4084 HandleScope scope(isolate); | 4125 HandleScope scope(isolate); |
4085 | 4126 |
4086 if (object->IsUndefined() || object->IsNull()) { | 4127 if (object->IsUndefined() || object->IsNull()) { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4155 if (receiver->HasFastProperties()) { | 4196 if (receiver->HasFastProperties()) { |
4156 // Attempt to use lookup cache. | 4197 // Attempt to use lookup cache. |
4157 Map* receiver_map = receiver->map(); | 4198 Map* receiver_map = receiver->map(); |
4158 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache(); | 4199 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache(); |
4159 int offset = keyed_lookup_cache->Lookup(receiver_map, key); | 4200 int offset = keyed_lookup_cache->Lookup(receiver_map, key); |
4160 if (offset != -1) { | 4201 if (offset != -1) { |
4161 Object* value = receiver->FastPropertyAt(offset); | 4202 Object* value = receiver->FastPropertyAt(offset); |
4162 return value->IsTheHole() ? isolate->heap()->undefined_value() : value; | 4203 return value->IsTheHole() ? isolate->heap()->undefined_value() : value; |
4163 } | 4204 } |
4164 // Lookup cache miss. Perform lookup and update the cache if appropriate. | 4205 // Lookup cache miss. Perform lookup and update the cache if appropriate. |
4165 LookupResult result; | 4206 LookupResult result(isolate); |
4166 receiver->LocalLookup(key, &result); | 4207 receiver->LocalLookup(key, &result); |
4167 if (result.IsProperty() && result.type() == FIELD) { | 4208 if (result.IsProperty() && result.type() == FIELD) { |
4168 int offset = result.GetFieldIndex(); | 4209 int offset = result.GetFieldIndex(); |
4169 keyed_lookup_cache->Update(receiver_map, key, offset); | 4210 keyed_lookup_cache->Update(receiver_map, key, offset); |
4170 return receiver->FastPropertyAt(offset); | 4211 return receiver->FastPropertyAt(offset); |
4171 } | 4212 } |
4172 } else { | 4213 } else { |
4173 // Attempt dictionary lookup. | 4214 // Attempt dictionary lookup. |
4174 StringDictionary* dictionary = receiver->property_dictionary(); | 4215 StringDictionary* dictionary = receiver->property_dictionary(); |
4175 int entry = dictionary->FindEntry(key); | 4216 int entry = dictionary->FindEntry(key); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4210 HandleScope scope(isolate); | 4251 HandleScope scope(isolate); |
4211 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 4252 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
4212 CONVERT_CHECKED(String, name, args[1]); | 4253 CONVERT_CHECKED(String, name, args[1]); |
4213 CONVERT_CHECKED(Smi, flag_setter, args[2]); | 4254 CONVERT_CHECKED(Smi, flag_setter, args[2]); |
4214 Object* fun = args[3]; | 4255 Object* fun = args[3]; |
4215 RUNTIME_ASSERT(fun->IsSpecFunction() || fun->IsUndefined()); | 4256 RUNTIME_ASSERT(fun->IsSpecFunction() || fun->IsUndefined()); |
4216 CONVERT_CHECKED(Smi, flag_attr, args[4]); | 4257 CONVERT_CHECKED(Smi, flag_attr, args[4]); |
4217 int unchecked = flag_attr->value(); | 4258 int unchecked = flag_attr->value(); |
4218 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 4259 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
4219 RUNTIME_ASSERT(!obj->IsNull()); | 4260 RUNTIME_ASSERT(!obj->IsNull()); |
4220 LookupResult result; | 4261 LookupResult result(isolate); |
4221 obj->LocalLookupRealNamedProperty(name, &result); | 4262 obj->LocalLookupRealNamedProperty(name, &result); |
4222 | 4263 |
4223 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); | 4264 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
4224 // If an existing property is either FIELD, NORMAL or CONSTANT_FUNCTION | 4265 // If an existing property is either FIELD, NORMAL or CONSTANT_FUNCTION |
4225 // delete it to avoid running into trouble in DefineAccessor, which | 4266 // delete it to avoid running into trouble in DefineAccessor, which |
4226 // handles this incorrectly if the property is readonly (does nothing) | 4267 // handles this incorrectly if the property is readonly (does nothing) |
4227 if (result.IsProperty() && | 4268 if (result.IsProperty() && |
4228 (result.type() == FIELD || result.type() == NORMAL | 4269 (result.type() == FIELD || result.type() == NORMAL |
4229 || result.type() == CONSTANT_FUNCTION)) { | 4270 || result.type() == CONSTANT_FUNCTION)) { |
4230 Object* ok; | 4271 Object* ok; |
(...skipping 21 matching lines...) Expand all Loading... |
4252 CONVERT_CHECKED(Smi, flag, args[3]); | 4293 CONVERT_CHECKED(Smi, flag, args[3]); |
4253 int unchecked = flag->value(); | 4294 int unchecked = flag->value(); |
4254 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 4295 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
4255 | 4296 |
4256 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); | 4297 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
4257 | 4298 |
4258 // Check if this is an element. | 4299 // Check if this is an element. |
4259 uint32_t index; | 4300 uint32_t index; |
4260 bool is_element = name->AsArrayIndex(&index); | 4301 bool is_element = name->AsArrayIndex(&index); |
4261 | 4302 |
4262 // Special case for elements if any of the flags are true. | 4303 // Special case for elements if any of the flags might be involved. |
4263 // If elements are in fast case we always implicitly assume that: | 4304 // If elements are in fast case we always implicitly assume that: |
4264 // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false. | 4305 // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false. |
4265 if (((unchecked & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) && | 4306 if (is_element && (attr != NONE || |
4266 is_element) { | 4307 js_object->HasLocalElement(index) == JSObject::DICTIONARY_ELEMENT)) { |
4267 // Normalize the elements to enable attributes on the property. | 4308 // Normalize the elements to enable attributes on the property. |
4268 if (js_object->IsJSGlobalProxy()) { | 4309 if (js_object->IsJSGlobalProxy()) { |
4269 // We do not need to do access checks here since these has already | 4310 // We do not need to do access checks here since these has already |
4270 // been performed by the call to GetOwnProperty. | 4311 // been performed by the call to GetOwnProperty. |
4271 Handle<Object> proto(js_object->GetPrototype()); | 4312 Handle<Object> proto(js_object->GetPrototype()); |
4272 // If proxy is detached, ignore the assignment. Alternatively, | 4313 // If proxy is detached, ignore the assignment. Alternatively, |
4273 // we could throw an exception. | 4314 // we could throw an exception. |
4274 if (proto->IsNull()) return *obj_value; | 4315 if (proto->IsNull()) return *obj_value; |
4275 js_object = Handle<JSObject>::cast(proto); | 4316 js_object = Handle<JSObject>::cast(proto); |
4276 } | 4317 } |
(...skipping 17 matching lines...) Expand all Loading... |
4294 if (*extended_dictionary != *dictionary) { | 4335 if (*extended_dictionary != *dictionary) { |
4295 if (js_object->GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS) { | 4336 if (js_object->GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS) { |
4296 FixedArray::cast(js_object->elements())->set(1, *extended_dictionary); | 4337 FixedArray::cast(js_object->elements())->set(1, *extended_dictionary); |
4297 } else { | 4338 } else { |
4298 js_object->set_elements(*extended_dictionary); | 4339 js_object->set_elements(*extended_dictionary); |
4299 } | 4340 } |
4300 } | 4341 } |
4301 return *obj_value; | 4342 return *obj_value; |
4302 } | 4343 } |
4303 | 4344 |
4304 LookupResult result; | 4345 LookupResult result(isolate); |
4305 js_object->LocalLookupRealNamedProperty(*name, &result); | 4346 js_object->LocalLookupRealNamedProperty(*name, &result); |
4306 | 4347 |
4307 // To be compatible with safari we do not change the value on API objects | 4348 // To be compatible with safari we do not change the value on API objects |
4308 // in defineProperty. Firefox disagrees here, and actually changes the value. | 4349 // in defineProperty. Firefox disagrees here, and actually changes the value. |
4309 if (result.IsProperty() && | 4350 if (result.IsProperty() && |
4310 (result.type() == CALLBACKS) && | 4351 (result.type() == CALLBACKS) && |
4311 result.GetCallbackObject()->IsAccessorInfo()) { | 4352 result.GetCallbackObject()->IsAccessorInfo()) { |
4312 return isolate->heap()->undefined_value(); | 4353 return isolate->heap()->undefined_value(); |
4313 } | 4354 } |
4314 | 4355 |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4561 | 4602 |
4562 return Runtime::SetObjectProperty(isolate, | 4603 return Runtime::SetObjectProperty(isolate, |
4563 object, | 4604 object, |
4564 key, | 4605 key, |
4565 value, | 4606 value, |
4566 attributes, | 4607 attributes, |
4567 strict_mode); | 4608 strict_mode); |
4568 } | 4609 } |
4569 | 4610 |
4570 | 4611 |
| 4612 MaybeObject* TransitionElements(Handle<Object> object, |
| 4613 ElementsKind to_kind, |
| 4614 Isolate* isolate) { |
| 4615 HandleScope scope(isolate); |
| 4616 if (!object->IsJSObject()) return isolate->ThrowIllegalOperation(); |
| 4617 ElementsKind from_kind = |
| 4618 Handle<JSObject>::cast(object)->map()->elements_kind(); |
| 4619 if (Map::IsValidElementsTransition(from_kind, to_kind)) { |
| 4620 Handle<Object> result = |
| 4621 TransitionElementsKind(Handle<JSObject>::cast(object), to_kind); |
| 4622 if (result.is_null()) return isolate->ThrowIllegalOperation(); |
| 4623 return *result; |
| 4624 } |
| 4625 return isolate->ThrowIllegalOperation(); |
| 4626 } |
| 4627 |
| 4628 |
| 4629 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsSmiToDouble) { |
| 4630 NoHandleAllocation ha; |
| 4631 RUNTIME_ASSERT(args.length() == 1); |
| 4632 Handle<Object> object = args.at<Object>(0); |
| 4633 return TransitionElements(object, FAST_DOUBLE_ELEMENTS, isolate); |
| 4634 } |
| 4635 |
| 4636 |
| 4637 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsDoubleToObject) { |
| 4638 NoHandleAllocation ha; |
| 4639 RUNTIME_ASSERT(args.length() == 1); |
| 4640 Handle<Object> object = args.at<Object>(0); |
| 4641 return TransitionElements(object, FAST_ELEMENTS, isolate); |
| 4642 } |
| 4643 |
| 4644 |
4571 // Set the native flag on the function. | 4645 // Set the native flag on the function. |
4572 // This is used to decide if we should transform null and undefined | 4646 // This is used to decide if we should transform null and undefined |
4573 // into the global object when doing call and apply. | 4647 // into the global object when doing call and apply. |
4574 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) { | 4648 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) { |
4575 NoHandleAllocation ha; | 4649 NoHandleAllocation ha; |
4576 RUNTIME_ASSERT(args.length() == 1); | 4650 RUNTIME_ASSERT(args.length() == 1); |
4577 | 4651 |
4578 Handle<Object> object = args.at<Object>(0); | 4652 Handle<Object> object = args.at<Object>(0); |
4579 | 4653 |
4580 if (object->IsJSFunction()) { | 4654 if (object->IsJSFunction()) { |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4744 } | 4818 } |
4745 | 4819 |
4746 PropertyAttributes att = object->GetLocalPropertyAttribute(key); | 4820 PropertyAttributes att = object->GetLocalPropertyAttribute(key); |
4747 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); | 4821 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); |
4748 } | 4822 } |
4749 | 4823 |
4750 | 4824 |
4751 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) { | 4825 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) { |
4752 HandleScope scope(isolate); | 4826 HandleScope scope(isolate); |
4753 ASSERT(args.length() == 1); | 4827 ASSERT(args.length() == 1); |
4754 CONVERT_ARG_CHECKED(JSObject, object, 0); | 4828 CONVERT_ARG_CHECKED(JSReceiver, object, 0); |
4755 return *GetKeysFor(object); | 4829 bool threw = false; |
| 4830 Handle<JSArray> result = GetKeysFor(object, &threw); |
| 4831 if (threw) return Failure::Exception(); |
| 4832 return *result; |
4756 } | 4833 } |
4757 | 4834 |
4758 | 4835 |
4759 // Returns either a FixedArray as Runtime_GetPropertyNames, | 4836 // Returns either a FixedArray as Runtime_GetPropertyNames, |
4760 // or, if the given object has an enum cache that contains | 4837 // or, if the given object has an enum cache that contains |
4761 // all enumerable properties of the object and its prototypes | 4838 // all enumerable properties of the object and its prototypes |
4762 // have none, the map of the object. This is used to speed up | 4839 // have none, the map of the object. This is used to speed up |
4763 // the check for deletions during a for-in. | 4840 // the check for deletions during a for-in. |
4764 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesFast) { | 4841 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNamesFast) { |
4765 ASSERT(args.length() == 1); | 4842 ASSERT(args.length() == 1); |
4766 | 4843 |
4767 CONVERT_CHECKED(JSObject, raw_object, args[0]); | 4844 CONVERT_CHECKED(JSReceiver, raw_object, args[0]); |
4768 | 4845 |
4769 if (raw_object->IsSimpleEnum()) return raw_object->map(); | 4846 if (raw_object->IsSimpleEnum()) return raw_object->map(); |
4770 | 4847 |
4771 HandleScope scope(isolate); | 4848 HandleScope scope(isolate); |
4772 Handle<JSObject> object(raw_object); | 4849 Handle<JSReceiver> object(raw_object); |
4773 Handle<FixedArray> content = GetKeysInFixedArrayFor(object, | 4850 bool threw = false; |
4774 INCLUDE_PROTOS); | 4851 Handle<FixedArray> content = |
| 4852 GetKeysInFixedArrayFor(object, INCLUDE_PROTOS, &threw); |
| 4853 if (threw) return Failure::Exception(); |
4775 | 4854 |
4776 // Test again, since cache may have been built by preceding call. | 4855 // Test again, since cache may have been built by preceding call. |
4777 if (object->IsSimpleEnum()) return object->map(); | 4856 if (object->IsSimpleEnum()) return object->map(); |
4778 | 4857 |
4779 return *content; | 4858 return *content; |
4780 } | 4859 } |
4781 | 4860 |
4782 | 4861 |
4783 // Find the length of the prototype chain that is to to handled as one. If a | 4862 // Find the length of the prototype chain that is to to handled as one. If a |
4784 // prototype object is hidden it is to be viewed as part of the the object it | 4863 // prototype object is hidden it is to be viewed as part of the the object it |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4961 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); | 5040 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); |
4962 return *isolate->factory()->NewJSArray(0); | 5041 return *isolate->factory()->NewJSArray(0); |
4963 } | 5042 } |
4964 | 5043 |
4965 Handle<Object> proto(object->GetPrototype()); | 5044 Handle<Object> proto(object->GetPrototype()); |
4966 // If proxy is detached we simply return an empty array. | 5045 // If proxy is detached we simply return an empty array. |
4967 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); | 5046 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); |
4968 object = Handle<JSObject>::cast(proto); | 5047 object = Handle<JSObject>::cast(proto); |
4969 } | 5048 } |
4970 | 5049 |
4971 Handle<FixedArray> contents = GetKeysInFixedArrayFor(object, | 5050 bool threw = false; |
4972 LOCAL_ONLY); | 5051 Handle<FixedArray> contents = |
| 5052 GetKeysInFixedArrayFor(object, LOCAL_ONLY, &threw); |
| 5053 if (threw) return Failure::Exception(); |
| 5054 |
4973 // Some fast paths through GetKeysInFixedArrayFor reuse a cached | 5055 // Some fast paths through GetKeysInFixedArrayFor reuse a cached |
4974 // property array and since the result is mutable we have to create | 5056 // property array and since the result is mutable we have to create |
4975 // a fresh clone on each invocation. | 5057 // a fresh clone on each invocation. |
4976 int length = contents->length(); | 5058 int length = contents->length(); |
4977 Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length); | 5059 Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length); |
4978 for (int i = 0; i < length; i++) { | 5060 for (int i = 0; i < length; i++) { |
4979 Object* entry = contents->get(i); | 5061 Object* entry = contents->get(i); |
4980 if (entry->IsString()) { | 5062 if (entry->IsString()) { |
4981 copy->set(i, entry); | 5063 copy->set(i, entry); |
4982 } else { | 5064 } else { |
(...skipping 2772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7755 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateYMDFromTime) { | 7837 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateYMDFromTime) { |
7756 NoHandleAllocation ha; | 7838 NoHandleAllocation ha; |
7757 ASSERT(args.length() == 2); | 7839 ASSERT(args.length() == 2); |
7758 | 7840 |
7759 CONVERT_DOUBLE_ARG_CHECKED(t, 0); | 7841 CONVERT_DOUBLE_ARG_CHECKED(t, 0); |
7760 CONVERT_CHECKED(JSArray, res_array, args[1]); | 7842 CONVERT_CHECKED(JSArray, res_array, args[1]); |
7761 | 7843 |
7762 int year, month, day; | 7844 int year, month, day; |
7763 DateYMDFromTime(static_cast<int>(floor(t / 86400000)), year, month, day); | 7845 DateYMDFromTime(static_cast<int>(floor(t / 86400000)), year, month, day); |
7764 | 7846 |
7765 RUNTIME_ASSERT(res_array->elements()->map() == | 7847 FixedArrayBase* elms_base = FixedArrayBase::cast(res_array->elements()); |
7766 isolate->heap()->fixed_array_map()); | 7848 RUNTIME_ASSERT(elms_base->length() == 3); |
7767 FixedArray* elms = FixedArray::cast(res_array->elements()); | 7849 RUNTIME_ASSERT(res_array->GetElementsKind() <= FAST_DOUBLE_ELEMENTS); |
7768 RUNTIME_ASSERT(elms->length() == 3); | |
7769 | 7850 |
7770 elms->set(0, Smi::FromInt(year)); | 7851 if (res_array->HasFastDoubleElements()) { |
7771 elms->set(1, Smi::FromInt(month)); | 7852 FixedDoubleArray* elms = FixedDoubleArray::cast(res_array->elements()); |
7772 elms->set(2, Smi::FromInt(day)); | 7853 elms->set(0, year); |
| 7854 elms->set(1, month); |
| 7855 elms->set(2, day); |
| 7856 } else { |
| 7857 FixedArray* elms = FixedArray::cast(res_array->elements()); |
| 7858 elms->set(0, Smi::FromInt(year)); |
| 7859 elms->set(1, Smi::FromInt(month)); |
| 7860 elms->set(2, Smi::FromInt(day)); |
| 7861 } |
7773 | 7862 |
7774 return isolate->heap()->undefined_value(); | 7863 return isolate->heap()->undefined_value(); |
7775 } | 7864 } |
7776 | 7865 |
7777 | 7866 |
7778 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) { | 7867 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) { |
7779 HandleScope scope(isolate); | 7868 HandleScope scope(isolate); |
7780 ASSERT(args.length() == 3); | 7869 ASSERT(args.length() == 3); |
7781 | 7870 |
7782 Handle<JSFunction> callee = args.at<JSFunction>(0); | 7871 Handle<JSFunction> callee = args.at<JSFunction>(0); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7919 // directly to properties. | 8008 // directly to properties. |
7920 PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED; | 8009 PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED; |
7921 Handle<JSFunction> result = | 8010 Handle<JSFunction> result = |
7922 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, | 8011 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, |
7923 context, | 8012 context, |
7924 pretenure_flag); | 8013 pretenure_flag); |
7925 return *result; | 8014 return *result; |
7926 } | 8015 } |
7927 | 8016 |
7928 | 8017 |
7929 static SmartArrayPointer<Handle<Object> > GetNonBoundArguments( | 8018 // Find the arguments of the JavaScript function invocation that called |
7930 int bound_argc, | 8019 // into C++ code. Collect these in a newly allocated array of handles (possibly |
| 8020 // prefixed by a number of empty handles). |
| 8021 static SmartArrayPointer<Handle<Object> > GetCallerArguments( |
| 8022 int prefix_argc, |
7931 int* total_argc) { | 8023 int* total_argc) { |
7932 // Find frame containing arguments passed to the caller. | 8024 // Find frame containing arguments passed to the caller. |
7933 JavaScriptFrameIterator it; | 8025 JavaScriptFrameIterator it; |
7934 JavaScriptFrame* frame = it.frame(); | 8026 JavaScriptFrame* frame = it.frame(); |
7935 List<JSFunction*> functions(2); | 8027 List<JSFunction*> functions(2); |
7936 frame->GetFunctions(&functions); | 8028 frame->GetFunctions(&functions); |
7937 if (functions.length() > 1) { | 8029 if (functions.length() > 1) { |
7938 int inlined_frame_index = functions.length() - 1; | 8030 int inlined_frame_index = functions.length() - 1; |
7939 JSFunction* inlined_function = functions[inlined_frame_index]; | 8031 JSFunction* inlined_function = functions[inlined_frame_index]; |
7940 int args_count = inlined_function->shared()->formal_parameter_count(); | 8032 int args_count = inlined_function->shared()->formal_parameter_count(); |
7941 ScopedVector<SlotRef> args_slots(args_count); | 8033 ScopedVector<SlotRef> args_slots(args_count); |
7942 SlotRef::ComputeSlotMappingForArguments(frame, | 8034 SlotRef::ComputeSlotMappingForArguments(frame, |
7943 inlined_frame_index, | 8035 inlined_frame_index, |
7944 &args_slots); | 8036 &args_slots); |
7945 | 8037 |
7946 *total_argc = bound_argc + args_count; | 8038 *total_argc = prefix_argc + args_count; |
7947 SmartArrayPointer<Handle<Object> > param_data( | 8039 SmartArrayPointer<Handle<Object> > param_data( |
7948 NewArray<Handle<Object> >(*total_argc)); | 8040 NewArray<Handle<Object> >(*total_argc)); |
7949 for (int i = 0; i < args_count; i++) { | 8041 for (int i = 0; i < args_count; i++) { |
7950 Handle<Object> val = args_slots[i].GetValue(); | 8042 Handle<Object> val = args_slots[i].GetValue(); |
7951 param_data[bound_argc + i] = val; | 8043 param_data[prefix_argc + i] = val; |
7952 } | 8044 } |
7953 return param_data; | 8045 return param_data; |
7954 } else { | 8046 } else { |
7955 it.AdvanceToArgumentsFrame(); | 8047 it.AdvanceToArgumentsFrame(); |
7956 frame = it.frame(); | 8048 frame = it.frame(); |
7957 int args_count = frame->ComputeParametersCount(); | 8049 int args_count = frame->ComputeParametersCount(); |
7958 | 8050 |
7959 *total_argc = bound_argc + args_count; | 8051 *total_argc = prefix_argc + args_count; |
7960 SmartArrayPointer<Handle<Object> > param_data( | 8052 SmartArrayPointer<Handle<Object> > param_data( |
7961 NewArray<Handle<Object> >(*total_argc)); | 8053 NewArray<Handle<Object> >(*total_argc)); |
7962 for (int i = 0; i < args_count; i++) { | 8054 for (int i = 0; i < args_count; i++) { |
7963 Handle<Object> val = Handle<Object>(frame->GetParameter(i)); | 8055 Handle<Object> val = Handle<Object>(frame->GetParameter(i)); |
7964 param_data[bound_argc + i] = val; | 8056 param_data[prefix_argc + i] = val; |
7965 } | 8057 } |
7966 return param_data; | 8058 return param_data; |
7967 } | 8059 } |
7968 } | 8060 } |
7969 | 8061 |
7970 | 8062 |
| 8063 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionBindArguments) { |
| 8064 HandleScope scope(isolate); |
| 8065 ASSERT(args.length() == 4); |
| 8066 CONVERT_ARG_CHECKED(JSFunction, bound_function, 0); |
| 8067 RUNTIME_ASSERT(args[3]->IsNumber()); |
| 8068 Handle<Object> bindee = args.at<Object>(1); |
| 8069 |
| 8070 // TODO(lrn): Create bound function in C++ code from premade shared info. |
| 8071 bound_function->shared()->set_bound(true); |
| 8072 // Get all arguments of calling function (Function.prototype.bind). |
| 8073 int argc = 0; |
| 8074 SmartArrayPointer<Handle<Object> > arguments = GetCallerArguments(0, &argc); |
| 8075 // Don't count the this-arg. |
| 8076 if (argc > 0) { |
| 8077 ASSERT(*arguments[0] == args[2]); |
| 8078 argc--; |
| 8079 } else { |
| 8080 ASSERT(args[2]->IsUndefined()); |
| 8081 } |
| 8082 // Initialize array of bindings (function, this, and any existing arguments |
| 8083 // if the function was already bound). |
| 8084 Handle<FixedArray> new_bindings; |
| 8085 int i; |
| 8086 if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) { |
| 8087 Handle<FixedArray> old_bindings( |
| 8088 JSFunction::cast(*bindee)->function_bindings()); |
| 8089 new_bindings = |
| 8090 isolate->factory()->NewFixedArray(old_bindings->length() + argc); |
| 8091 bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex)); |
| 8092 i = 0; |
| 8093 for (int n = old_bindings->length(); i < n; i++) { |
| 8094 new_bindings->set(i, old_bindings->get(i)); |
| 8095 } |
| 8096 } else { |
| 8097 int array_size = JSFunction::kBoundArgumentsStartIndex + argc; |
| 8098 new_bindings = isolate->factory()->NewFixedArray(array_size); |
| 8099 new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee); |
| 8100 new_bindings->set(JSFunction::kBoundThisIndex, args[2]); |
| 8101 i = 2; |
| 8102 } |
| 8103 // Copy arguments, skipping the first which is "this_arg". |
| 8104 for (int j = 0; j < argc; j++, i++) { |
| 8105 new_bindings->set(i, *arguments[j + 1]); |
| 8106 } |
| 8107 new_bindings->set_map(isolate->heap()->fixed_cow_array_map()); |
| 8108 bound_function->set_function_bindings(*new_bindings); |
| 8109 |
| 8110 // Update length. |
| 8111 Handle<String> length_symbol = isolate->factory()->length_symbol(); |
| 8112 Handle<Object> new_length(args.at<Object>(3)); |
| 8113 PropertyAttributes attr = |
| 8114 static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY); |
| 8115 ForceSetProperty(bound_function, length_symbol, new_length, attr); |
| 8116 return *bound_function; |
| 8117 } |
| 8118 |
| 8119 |
| 8120 RUNTIME_FUNCTION(MaybeObject*, Runtime_BoundFunctionGetBindings) { |
| 8121 HandleScope handles(isolate); |
| 8122 ASSERT(args.length() == 1); |
| 8123 CONVERT_ARG_CHECKED(JSObject, callable, 0); |
| 8124 if (callable->IsJSFunction()) { |
| 8125 Handle<JSFunction> function = Handle<JSFunction>::cast(callable); |
| 8126 if (function->shared()->bound()) { |
| 8127 Handle<FixedArray> bindings(function->function_bindings()); |
| 8128 ASSERT(bindings->map() == isolate->heap()->fixed_cow_array_map()); |
| 8129 return *isolate->factory()->NewJSArrayWithElements(bindings); |
| 8130 } |
| 8131 } |
| 8132 return isolate->heap()->undefined_value(); |
| 8133 } |
| 8134 |
| 8135 |
7971 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObjectFromBound) { | 8136 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObjectFromBound) { |
7972 HandleScope scope(isolate); | 8137 HandleScope scope(isolate); |
7973 ASSERT(args.length() == 2); | 8138 ASSERT(args.length() == 1); |
7974 // First argument is a function to use as a constructor. | 8139 // First argument is a function to use as a constructor. |
7975 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 8140 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
| 8141 RUNTIME_ASSERT(function->shared()->bound()); |
7976 | 8142 |
7977 // Second argument is either null or an array of bound arguments. | 8143 // The argument is a bound function. Extract its bound arguments |
7978 Handle<FixedArray> bound_args; | 8144 // and callable. |
7979 int bound_argc = 0; | 8145 Handle<FixedArray> bound_args = |
7980 if (!args[1]->IsNull()) { | 8146 Handle<FixedArray>(FixedArray::cast(function->function_bindings())); |
7981 CONVERT_ARG_CHECKED(JSArray, params, 1); | 8147 int bound_argc = bound_args->length() - JSFunction::kBoundArgumentsStartIndex; |
7982 RUNTIME_ASSERT(params->HasFastTypeElements()); | 8148 Handle<Object> bound_function( |
7983 bound_args = Handle<FixedArray>(FixedArray::cast(params->elements())); | 8149 JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex))); |
7984 bound_argc = Smi::cast(params->length())->value(); | 8150 ASSERT(!bound_function->IsJSFunction() || |
7985 } | 8151 !Handle<JSFunction>::cast(bound_function)->shared()->bound()); |
7986 | 8152 |
7987 int total_argc = 0; | 8153 int total_argc = 0; |
7988 SmartArrayPointer<Handle<Object> > param_data = | 8154 SmartArrayPointer<Handle<Object> > param_data = |
7989 GetNonBoundArguments(bound_argc, &total_argc); | 8155 GetCallerArguments(bound_argc, &total_argc); |
7990 for (int i = 0; i < bound_argc; i++) { | 8156 for (int i = 0; i < bound_argc; i++) { |
7991 Handle<Object> val = Handle<Object>(bound_args->get(i)); | 8157 param_data[i] = Handle<Object>(bound_args->get( |
7992 param_data[i] = val; | 8158 JSFunction::kBoundArgumentsStartIndex + i)); |
7993 } | 8159 } |
7994 | 8160 |
| 8161 if (!bound_function->IsJSFunction()) { |
| 8162 bool exception_thrown; |
| 8163 bound_function = Execution::TryGetConstructorDelegate(bound_function, |
| 8164 &exception_thrown); |
| 8165 if (exception_thrown) return Failure::Exception(); |
| 8166 } |
| 8167 ASSERT(bound_function->IsJSFunction()); |
| 8168 |
7995 bool exception = false; | 8169 bool exception = false; |
7996 Handle<Object> result = | 8170 Handle<Object> result = |
7997 Execution::New(function, total_argc, *param_data, &exception); | 8171 Execution::New(Handle<JSFunction>::cast(bound_function), |
| 8172 total_argc, *param_data, &exception); |
7998 if (exception) { | 8173 if (exception) { |
7999 return Failure::Exception(); | 8174 return Failure::Exception(); |
8000 } | 8175 } |
8001 | |
8002 ASSERT(!result.is_null()); | 8176 ASSERT(!result.is_null()); |
8003 return *result; | 8177 return *result; |
8004 } | 8178 } |
8005 | 8179 |
8006 | 8180 |
8007 static void TrySettingInlineConstructStub(Isolate* isolate, | 8181 static void TrySettingInlineConstructStub(Isolate* isolate, |
8008 Handle<JSFunction> function) { | 8182 Handle<JSFunction> function) { |
8009 Handle<Object> prototype = isolate->factory()->null_value(); | 8183 Handle<Object> prototype = isolate->factory()->null_value(); |
8010 if (function->has_instance_prototype()) { | 8184 if (function->has_instance_prototype()) { |
8011 prototype = Handle<Object>(function->instance_prototype(), isolate); | 8185 prototype = Handle<Object>(function->instance_prototype(), isolate); |
8012 } | 8186 } |
8013 if (function->shared()->CanGenerateInlineConstructor(*prototype)) { | 8187 if (function->shared()->CanGenerateInlineConstructor(*prototype)) { |
8014 ConstructStubCompiler compiler; | 8188 HandleScope scope(isolate); |
| 8189 ConstructStubCompiler compiler(isolate); |
8015 MaybeObject* code = compiler.CompileConstructStub(*function); | 8190 MaybeObject* code = compiler.CompileConstructStub(*function); |
8016 if (!code->IsFailure()) { | 8191 if (!code->IsFailure()) { |
8017 function->shared()->set_construct_stub( | 8192 function->shared()->set_construct_stub( |
8018 Code::cast(code->ToObjectUnchecked())); | 8193 Code::cast(code->ToObjectUnchecked())); |
8019 } | 8194 } |
8020 } | 8195 } |
8021 } | 8196 } |
8022 | 8197 |
8023 | 8198 |
8024 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObject) { | 8199 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObject) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8068 // reported the same way whether or not 'Function' is called | 8243 // reported the same way whether or not 'Function' is called |
8069 // using 'new'. | 8244 // using 'new'. |
8070 return isolate->context()->global(); | 8245 return isolate->context()->global(); |
8071 } | 8246 } |
8072 } | 8247 } |
8073 | 8248 |
8074 // The function should be compiled for the optimization hints to be | 8249 // The function should be compiled for the optimization hints to be |
8075 // available. We cannot use EnsureCompiled because that forces a | 8250 // available. We cannot use EnsureCompiled because that forces a |
8076 // compilation through the shared function info which makes it | 8251 // compilation through the shared function info which makes it |
8077 // impossible for us to optimize. | 8252 // impossible for us to optimize. |
| 8253 if (!function->is_compiled()) { |
| 8254 JSFunction::CompileLazy(function, CLEAR_EXCEPTION); |
| 8255 } |
| 8256 |
8078 Handle<SharedFunctionInfo> shared(function->shared(), isolate); | 8257 Handle<SharedFunctionInfo> shared(function->shared(), isolate); |
8079 if (!function->is_compiled()) CompileLazy(function, CLEAR_EXCEPTION); | |
8080 | |
8081 if (!function->has_initial_map() && | 8258 if (!function->has_initial_map() && |
8082 shared->IsInobjectSlackTrackingInProgress()) { | 8259 shared->IsInobjectSlackTrackingInProgress()) { |
8083 // The tracking is already in progress for another function. We can only | 8260 // The tracking is already in progress for another function. We can only |
8084 // track one initial_map at a time, so we force the completion before the | 8261 // track one initial_map at a time, so we force the completion before the |
8085 // function is called as a constructor for the first time. | 8262 // function is called as a constructor for the first time. |
8086 shared->CompleteInobjectSlackTracking(); | 8263 shared->CompleteInobjectSlackTracking(); |
8087 } | 8264 } |
8088 | 8265 |
8089 bool first_allocation = !shared->live_objects_may_exist(); | 8266 bool first_allocation = !shared->live_objects_may_exist(); |
8090 Handle<JSObject> result = isolate->factory()->NewJSObject(function); | 8267 Handle<JSObject> result = isolate->factory()->NewJSObject(function); |
(...skipping 30 matching lines...) Expand all Loading... |
8121 #ifdef DEBUG | 8298 #ifdef DEBUG |
8122 if (FLAG_trace_lazy && !function->shared()->is_compiled()) { | 8299 if (FLAG_trace_lazy && !function->shared()->is_compiled()) { |
8123 PrintF("[lazy: "); | 8300 PrintF("[lazy: "); |
8124 function->PrintName(); | 8301 function->PrintName(); |
8125 PrintF("]\n"); | 8302 PrintF("]\n"); |
8126 } | 8303 } |
8127 #endif | 8304 #endif |
8128 | 8305 |
8129 // Compile the target function. | 8306 // Compile the target function. |
8130 ASSERT(!function->is_compiled()); | 8307 ASSERT(!function->is_compiled()); |
8131 if (!CompileLazy(function, KEEP_EXCEPTION)) { | 8308 if (!JSFunction::CompileLazy(function, KEEP_EXCEPTION)) { |
8132 return Failure::Exception(); | 8309 return Failure::Exception(); |
8133 } | 8310 } |
8134 | 8311 |
8135 // All done. Return the compiled code. | 8312 // All done. Return the compiled code. |
8136 ASSERT(function->is_compiled()); | 8313 ASSERT(function->is_compiled()); |
8137 return function->code(); | 8314 return function->code(); |
8138 } | 8315 } |
8139 | 8316 |
8140 | 8317 |
8141 RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) { | 8318 RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyRecompile) { |
(...skipping 16 matching lines...) Expand all Loading... |
8158 if (FLAG_trace_opt) { | 8335 if (FLAG_trace_opt) { |
8159 PrintF("[failed to optimize "); | 8336 PrintF("[failed to optimize "); |
8160 function->PrintName(); | 8337 function->PrintName(); |
8161 PrintF(": is code optimizable: %s, is debugger enabled: %s]\n", | 8338 PrintF(": is code optimizable: %s, is debugger enabled: %s]\n", |
8162 function->shared()->code()->optimizable() ? "T" : "F", | 8339 function->shared()->code()->optimizable() ? "T" : "F", |
8163 isolate->DebuggerHasBreakPoints() ? "T" : "F"); | 8340 isolate->DebuggerHasBreakPoints() ? "T" : "F"); |
8164 } | 8341 } |
8165 function->ReplaceCode(function->shared()->code()); | 8342 function->ReplaceCode(function->shared()->code()); |
8166 return function->code(); | 8343 return function->code(); |
8167 } | 8344 } |
8168 if (CompileOptimized(function, AstNode::kNoNumber, CLEAR_EXCEPTION)) { | 8345 if (JSFunction::CompileOptimized(function, |
| 8346 AstNode::kNoNumber, |
| 8347 CLEAR_EXCEPTION)) { |
8169 return function->code(); | 8348 return function->code(); |
8170 } | 8349 } |
8171 if (FLAG_trace_opt) { | 8350 if (FLAG_trace_opt) { |
8172 PrintF("[failed to optimize "); | 8351 PrintF("[failed to optimize "); |
8173 function->PrintName(); | 8352 function->PrintName(); |
8174 PrintF(": optimized compilation failed]\n"); | 8353 PrintF(": optimized compilation failed]\n"); |
8175 } | 8354 } |
8176 function->ReplaceCode(function->shared()->code()); | 8355 function->ReplaceCode(function->shared()->code()); |
8177 return function->code(); | 8356 return function->code(); |
8178 } | 8357 } |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8399 ASSERT(ast_id != AstNode::kNoNumber); | 8578 ASSERT(ast_id != AstNode::kNoNumber); |
8400 if (FLAG_trace_osr) { | 8579 if (FLAG_trace_osr) { |
8401 PrintF("[replacing on-stack at AST id %d in ", ast_id); | 8580 PrintF("[replacing on-stack at AST id %d in ", ast_id); |
8402 function->PrintName(); | 8581 function->PrintName(); |
8403 PrintF("]\n"); | 8582 PrintF("]\n"); |
8404 } | 8583 } |
8405 | 8584 |
8406 // Try to compile the optimized code. A true return value from | 8585 // Try to compile the optimized code. A true return value from |
8407 // CompileOptimized means that compilation succeeded, not necessarily | 8586 // CompileOptimized means that compilation succeeded, not necessarily |
8408 // that optimization succeeded. | 8587 // that optimization succeeded. |
8409 if (CompileOptimized(function, ast_id, CLEAR_EXCEPTION) && | 8588 if (JSFunction::CompileOptimized(function, ast_id, CLEAR_EXCEPTION) && |
8410 function->IsOptimized()) { | 8589 function->IsOptimized()) { |
8411 DeoptimizationInputData* data = DeoptimizationInputData::cast( | 8590 DeoptimizationInputData* data = DeoptimizationInputData::cast( |
8412 function->code()->deoptimization_data()); | 8591 function->code()->deoptimization_data()); |
8413 if (data->OsrPcOffset()->value() >= 0) { | 8592 if (data->OsrPcOffset()->value() >= 0) { |
8414 if (FLAG_trace_osr) { | 8593 if (FLAG_trace_osr) { |
8415 PrintF("[on-stack replacement offset %d in optimized code]\n", | 8594 PrintF("[on-stack replacement offset %d in optimized code]\n", |
8416 data->OsrPcOffset()->value()); | 8595 data->OsrPcOffset()->value()); |
8417 } | 8596 } |
8418 ASSERT(data->OsrAstId()->value() == ast_id); | 8597 ASSERT(data->OsrAstId()->value() == ast_id); |
8419 } else { | 8598 } else { |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8755 ASSERT(holder->IsContext()); | 8934 ASSERT(holder->IsContext()); |
8756 // If the "property" we were looking for is a local variable, the | 8935 // If the "property" we were looking for is a local variable, the |
8757 // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3. | 8936 // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3. |
8758 // | 8937 // |
8759 // Use the hole as the receiver to signal that the receiver is implicit | 8938 // Use the hole as the receiver to signal that the receiver is implicit |
8760 // and that the global receiver should be used (as distinguished from an | 8939 // and that the global receiver should be used (as distinguished from an |
8761 // explicit receiver that happens to be a global object). | 8940 // explicit receiver that happens to be a global object). |
8762 Handle<Object> receiver = isolate->factory()->the_hole_value(); | 8941 Handle<Object> receiver = isolate->factory()->the_hole_value(); |
8763 Object* value = Context::cast(*holder)->get(index); | 8942 Object* value = Context::cast(*holder)->get(index); |
8764 // Check for uninitialized bindings. | 8943 // Check for uninitialized bindings. |
8765 if (binding_flags == MUTABLE_CHECK_INITIALIZED && value->IsTheHole()) { | 8944 switch (binding_flags) { |
8766 Handle<Object> reference_error = | 8945 case MUTABLE_CHECK_INITIALIZED: |
8767 isolate->factory()->NewReferenceError("not_defined", | 8946 case IMMUTABLE_CHECK_INITIALIZED_HARMONY: |
8768 HandleVector(&name, 1)); | 8947 if (value->IsTheHole()) { |
8769 return MakePair(isolate->Throw(*reference_error), NULL); | 8948 Handle<Object> reference_error = |
8770 } else { | 8949 isolate->factory()->NewReferenceError("not_defined", |
8771 return MakePair(Unhole(isolate->heap(), value, attributes), *receiver); | 8950 HandleVector(&name, 1)); |
| 8951 return MakePair(isolate->Throw(*reference_error), NULL); |
| 8952 } |
| 8953 // FALLTHROUGH |
| 8954 case MUTABLE_IS_INITIALIZED: |
| 8955 case IMMUTABLE_IS_INITIALIZED: |
| 8956 case IMMUTABLE_IS_INITIALIZED_HARMONY: |
| 8957 ASSERT(!value->IsTheHole()); |
| 8958 return MakePair(value, *receiver); |
| 8959 case IMMUTABLE_CHECK_INITIALIZED: |
| 8960 return MakePair(Unhole(isolate->heap(), value, attributes), *receiver); |
| 8961 case MISSING_BINDING: |
| 8962 UNREACHABLE(); |
| 8963 return MakePair(NULL, NULL); |
8772 } | 8964 } |
8773 } | 8965 } |
8774 | 8966 |
8775 // Otherwise, if the slot was found the holder is a context extension | 8967 // Otherwise, if the slot was found the holder is a context extension |
8776 // object, subject of a with, or a global object. We read the named | 8968 // object, subject of a with, or a global object. We read the named |
8777 // property from it. | 8969 // property from it. |
8778 if (!holder.is_null()) { | 8970 if (!holder.is_null()) { |
8779 Handle<JSObject> object = Handle<JSObject>::cast(holder); | 8971 Handle<JSObject> object = Handle<JSObject>::cast(holder); |
8780 ASSERT(object->HasProperty(*name)); | 8972 ASSERT(object->HasProperty(*name)); |
8781 // GetProperty below can cause GC. | 8973 // GetProperty below can cause GC. |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8940 // First check if this is a real stack overflow. | 9132 // First check if this is a real stack overflow. |
8941 if (isolate->stack_guard()->IsStackOverflow()) { | 9133 if (isolate->stack_guard()->IsStackOverflow()) { |
8942 NoHandleAllocation na; | 9134 NoHandleAllocation na; |
8943 return isolate->StackOverflow(); | 9135 return isolate->StackOverflow(); |
8944 } | 9136 } |
8945 | 9137 |
8946 return Execution::HandleStackGuardInterrupt(); | 9138 return Execution::HandleStackGuardInterrupt(); |
8947 } | 9139 } |
8948 | 9140 |
8949 | 9141 |
8950 // NOTE: These PrintXXX functions are defined for all builds (not just | |
8951 // DEBUG builds) because we may want to be able to trace function | |
8952 // calls in all modes. | |
8953 static void PrintString(String* str) { | |
8954 // not uncommon to have empty strings | |
8955 if (str->length() > 0) { | |
8956 SmartArrayPointer<char> s = | |
8957 str->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | |
8958 PrintF("%s", *s); | |
8959 } | |
8960 } | |
8961 | |
8962 | |
8963 static void PrintObject(Object* obj) { | |
8964 if (obj->IsSmi()) { | |
8965 PrintF("%d", Smi::cast(obj)->value()); | |
8966 } else if (obj->IsString() || obj->IsSymbol()) { | |
8967 PrintString(String::cast(obj)); | |
8968 } else if (obj->IsNumber()) { | |
8969 PrintF("%g", obj->Number()); | |
8970 } else if (obj->IsFailure()) { | |
8971 PrintF("<failure>"); | |
8972 } else if (obj->IsUndefined()) { | |
8973 PrintF("<undefined>"); | |
8974 } else if (obj->IsNull()) { | |
8975 PrintF("<null>"); | |
8976 } else if (obj->IsTrue()) { | |
8977 PrintF("<true>"); | |
8978 } else if (obj->IsFalse()) { | |
8979 PrintF("<false>"); | |
8980 } else { | |
8981 PrintF("%p", reinterpret_cast<void*>(obj)); | |
8982 } | |
8983 } | |
8984 | |
8985 | |
8986 static int StackSize() { | 9142 static int StackSize() { |
8987 int n = 0; | 9143 int n = 0; |
8988 for (JavaScriptFrameIterator it; !it.done(); it.Advance()) n++; | 9144 for (JavaScriptFrameIterator it; !it.done(); it.Advance()) n++; |
8989 return n; | 9145 return n; |
8990 } | 9146 } |
8991 | 9147 |
8992 | 9148 |
8993 static void PrintTransition(Object* result) { | 9149 static void PrintTransition(Object* result) { |
8994 // indentation | 9150 // indentation |
8995 { const int nmax = 80; | 9151 { const int nmax = 80; |
8996 int n = StackSize(); | 9152 int n = StackSize(); |
8997 if (n <= nmax) | 9153 if (n <= nmax) |
8998 PrintF("%4d:%*s", n, n, ""); | 9154 PrintF("%4d:%*s", n, n, ""); |
8999 else | 9155 else |
9000 PrintF("%4d:%*s", n, nmax, "..."); | 9156 PrintF("%4d:%*s", n, nmax, "..."); |
9001 } | 9157 } |
9002 | 9158 |
9003 if (result == NULL) { | 9159 if (result == NULL) { |
9004 // constructor calls | 9160 JavaScriptFrame::PrintTop(stdout, true, false); |
9005 JavaScriptFrameIterator it; | 9161 PrintF(" {\n"); |
9006 JavaScriptFrame* frame = it.frame(); | |
9007 if (frame->IsConstructor()) PrintF("new "); | |
9008 // function name | |
9009 Object* fun = frame->function(); | |
9010 if (fun->IsJSFunction()) { | |
9011 PrintObject(JSFunction::cast(fun)->shared()->name()); | |
9012 } else { | |
9013 PrintObject(fun); | |
9014 } | |
9015 // function arguments | |
9016 // (we are intentionally only printing the actually | |
9017 // supplied parameters, not all parameters required) | |
9018 PrintF("(this="); | |
9019 PrintObject(frame->receiver()); | |
9020 const int length = frame->ComputeParametersCount(); | |
9021 for (int i = 0; i < length; i++) { | |
9022 PrintF(", "); | |
9023 PrintObject(frame->GetParameter(i)); | |
9024 } | |
9025 PrintF(") {\n"); | |
9026 | |
9027 } else { | 9162 } else { |
9028 // function result | 9163 // function result |
9029 PrintF("} -> "); | 9164 PrintF("} -> "); |
9030 PrintObject(result); | 9165 result->ShortPrint(); |
9031 PrintF("\n"); | 9166 PrintF("\n"); |
9032 } | 9167 } |
9033 } | 9168 } |
9034 | 9169 |
9035 | 9170 |
| 9171 RUNTIME_FUNCTION(MaybeObject*, Runtime_TraceElementsKindTransition) { |
| 9172 ASSERT(args.length() == 5); |
| 9173 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 9174 CONVERT_SMI_ARG_CHECKED(from_kind, 1); |
| 9175 CONVERT_ARG_CHECKED(FixedArrayBase, from_elements, 2); |
| 9176 CONVERT_SMI_ARG_CHECKED(to_kind, 3); |
| 9177 CONVERT_ARG_CHECKED(FixedArrayBase, to_elements, 4); |
| 9178 NoHandleAllocation ha; |
| 9179 PrintF("*"); |
| 9180 obj->PrintElementsTransition(stdout, |
| 9181 static_cast<ElementsKind>(from_kind), *from_elements, |
| 9182 static_cast<ElementsKind>(to_kind), *to_elements); |
| 9183 return isolate->heap()->undefined_value(); |
| 9184 } |
| 9185 |
| 9186 |
9036 RUNTIME_FUNCTION(MaybeObject*, Runtime_TraceEnter) { | 9187 RUNTIME_FUNCTION(MaybeObject*, Runtime_TraceEnter) { |
9037 ASSERT(args.length() == 0); | 9188 ASSERT(args.length() == 0); |
9038 NoHandleAllocation ha; | 9189 NoHandleAllocation ha; |
9039 PrintTransition(NULL); | 9190 PrintTransition(NULL); |
9040 return isolate->heap()->undefined_value(); | 9191 return isolate->heap()->undefined_value(); |
9041 } | 9192 } |
9042 | 9193 |
9043 | 9194 |
9044 RUNTIME_FUNCTION(MaybeObject*, Runtime_TraceExit) { | 9195 RUNTIME_FUNCTION(MaybeObject*, Runtime_TraceExit) { |
9045 NoHandleAllocation ha; | 9196 NoHandleAllocation ha; |
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9774 int fast_length = static_cast<int>(length); | 9925 int fast_length = static_cast<int>(length); |
9775 ASSERT(fast_length <= elements->length()); | 9926 ASSERT(fast_length <= elements->length()); |
9776 for (int j = 0; j < fast_length; j++) { | 9927 for (int j = 0; j < fast_length; j++) { |
9777 HandleScope loop_scope(isolate); | 9928 HandleScope loop_scope(isolate); |
9778 Handle<Object> element_value(elements->get(j), isolate); | 9929 Handle<Object> element_value(elements->get(j), isolate); |
9779 if (!element_value->IsTheHole()) { | 9930 if (!element_value->IsTheHole()) { |
9780 visitor->visit(j, element_value); | 9931 visitor->visit(j, element_value); |
9781 } else if (receiver->HasElement(j)) { | 9932 } else if (receiver->HasElement(j)) { |
9782 // Call GetElement on receiver, not its prototype, or getters won't | 9933 // Call GetElement on receiver, not its prototype, or getters won't |
9783 // have the correct receiver. | 9934 // have the correct receiver. |
9784 element_value = GetElement(receiver, j); | 9935 element_value = Object::GetElement(receiver, j); |
9785 if (element_value.is_null()) return false; | 9936 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false); |
9786 visitor->visit(j, element_value); | 9937 visitor->visit(j, element_value); |
9787 } | 9938 } |
9788 } | 9939 } |
9789 break; | 9940 break; |
9790 } | 9941 } |
9791 case DICTIONARY_ELEMENTS: { | 9942 case DICTIONARY_ELEMENTS: { |
9792 Handle<NumberDictionary> dict(receiver->element_dictionary()); | 9943 Handle<NumberDictionary> dict(receiver->element_dictionary()); |
9793 List<uint32_t> indices(dict->Capacity() / 2); | 9944 List<uint32_t> indices(dict->Capacity() / 2); |
9794 // Collect all indices in the object and the prototypes less | 9945 // Collect all indices in the object and the prototypes less |
9795 // than length. This might introduce duplicates in the indices list. | 9946 // than length. This might introduce duplicates in the indices list. |
9796 CollectElementIndices(receiver, length, &indices); | 9947 CollectElementIndices(receiver, length, &indices); |
9797 indices.Sort(&compareUInt32); | 9948 indices.Sort(&compareUInt32); |
9798 int j = 0; | 9949 int j = 0; |
9799 int n = indices.length(); | 9950 int n = indices.length(); |
9800 while (j < n) { | 9951 while (j < n) { |
9801 HandleScope loop_scope; | 9952 HandleScope loop_scope; |
9802 uint32_t index = indices[j]; | 9953 uint32_t index = indices[j]; |
9803 Handle<Object> element = GetElement(receiver, index); | 9954 Handle<Object> element = Object::GetElement(receiver, index); |
9804 if (element.is_null()) return false; | 9955 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element, false); |
9805 visitor->visit(index, element); | 9956 visitor->visit(index, element); |
9806 // Skip to next different index (i.e., omit duplicates). | 9957 // Skip to next different index (i.e., omit duplicates). |
9807 do { | 9958 do { |
9808 j++; | 9959 j++; |
9809 } while (j < n && indices[j] == index); | 9960 } while (j < n && indices[j] == index); |
9810 } | 9961 } |
9811 break; | 9962 break; |
9812 } | 9963 } |
9813 case EXTERNAL_PIXEL_ELEMENTS: { | 9964 case EXTERNAL_PIXEL_ELEMENTS: { |
9814 Handle<ExternalPixelArray> pixels(ExternalPixelArray::cast( | 9965 Handle<ExternalPixelArray> pixels(ExternalPixelArray::cast( |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10044 Handle<Object> key1 = args.at<Object>(1); | 10195 Handle<Object> key1 = args.at<Object>(1); |
10045 Handle<Object> key2 = args.at<Object>(2); | 10196 Handle<Object> key2 = args.at<Object>(2); |
10046 | 10197 |
10047 uint32_t index1, index2; | 10198 uint32_t index1, index2; |
10048 if (!key1->ToArrayIndex(&index1) | 10199 if (!key1->ToArrayIndex(&index1) |
10049 || !key2->ToArrayIndex(&index2)) { | 10200 || !key2->ToArrayIndex(&index2)) { |
10050 return isolate->ThrowIllegalOperation(); | 10201 return isolate->ThrowIllegalOperation(); |
10051 } | 10202 } |
10052 | 10203 |
10053 Handle<JSObject> jsobject = Handle<JSObject>::cast(object); | 10204 Handle<JSObject> jsobject = Handle<JSObject>::cast(object); |
10054 Handle<Object> tmp1 = GetElement(jsobject, index1); | 10205 Handle<Object> tmp1 = Object::GetElement(jsobject, index1); |
10055 RETURN_IF_EMPTY_HANDLE(isolate, tmp1); | 10206 RETURN_IF_EMPTY_HANDLE(isolate, tmp1); |
10056 Handle<Object> tmp2 = GetElement(jsobject, index2); | 10207 Handle<Object> tmp2 = Object::GetElement(jsobject, index2); |
10057 RETURN_IF_EMPTY_HANDLE(isolate, tmp2); | 10208 RETURN_IF_EMPTY_HANDLE(isolate, tmp2); |
10058 | 10209 |
10059 RETURN_IF_EMPTY_HANDLE(isolate, | 10210 RETURN_IF_EMPTY_HANDLE(isolate, |
10060 SetElement(jsobject, index1, tmp2, kStrictMode)); | 10211 SetElement(jsobject, index1, tmp2, kStrictMode)); |
10061 RETURN_IF_EMPTY_HANDLE(isolate, | 10212 RETURN_IF_EMPTY_HANDLE(isolate, |
10062 SetElement(jsobject, index2, tmp1, kStrictMode)); | 10213 SetElement(jsobject, index2, tmp1, kStrictMode)); |
10063 | 10214 |
10064 return isolate->heap()->undefined_value(); | 10215 return isolate->heap()->undefined_value(); |
10065 } | 10216 } |
10066 | 10217 |
10067 | 10218 |
10068 // Returns an array that tells you where in the [0, length) interval an array | 10219 // Returns an array that tells you where in the [0, length) interval an array |
10069 // might have elements. Can either return keys (positive integers) or | 10220 // might have elements. Can either return keys (positive integers) or |
10070 // intervals (pair of a negative integer (-start-1) followed by a | 10221 // intervals (pair of a negative integer (-start-1) followed by a |
10071 // positive (length)) or undefined values. | 10222 // positive (length)) or undefined values. |
10072 // Intervals can span over some keys that are not in the object. | 10223 // Intervals can span over some keys that are not in the object. |
10073 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) { | 10224 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) { |
10074 ASSERT(args.length() == 2); | 10225 ASSERT(args.length() == 2); |
10075 HandleScope scope(isolate); | 10226 HandleScope scope(isolate); |
10076 CONVERT_ARG_CHECKED(JSObject, array, 0); | 10227 CONVERT_ARG_CHECKED(JSObject, array, 0); |
10077 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); | 10228 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); |
10078 if (array->elements()->IsDictionary()) { | 10229 if (array->elements()->IsDictionary()) { |
10079 // Create an array and get all the keys into it, then remove all the | 10230 // Create an array and get all the keys into it, then remove all the |
10080 // keys that are not integers in the range 0 to length-1. | 10231 // keys that are not integers in the range 0 to length-1. |
10081 Handle<FixedArray> keys = GetKeysInFixedArrayFor(array, INCLUDE_PROTOS); | 10232 bool threw = false; |
| 10233 Handle<FixedArray> keys = |
| 10234 GetKeysInFixedArrayFor(array, INCLUDE_PROTOS, &threw); |
| 10235 if (threw) return Failure::Exception(); |
| 10236 |
10082 int keys_length = keys->length(); | 10237 int keys_length = keys->length(); |
10083 for (int i = 0; i < keys_length; i++) { | 10238 for (int i = 0; i < keys_length; i++) { |
10084 Object* key = keys->get(i); | 10239 Object* key = keys->get(i); |
10085 uint32_t index = 0; | 10240 uint32_t index = 0; |
10086 if (!key->ToArrayIndex(&index) || index >= length) { | 10241 if (!key->ToArrayIndex(&index) || index >= length) { |
10087 // Zap invalid keys. | 10242 // Zap invalid keys. |
10088 keys->set_undefined(i); | 10243 keys->set_undefined(i); |
10089 } | 10244 } |
10090 } | 10245 } |
10091 return *isolate->factory()->NewJSArrayWithElements(keys); | 10246 return *isolate->factory()->NewJSArrayWithElements(keys); |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10296 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); | 10451 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); |
10297 return *isolate->factory()->NewJSArrayWithElements(details); | 10452 return *isolate->factory()->NewJSArrayWithElements(details); |
10298 } | 10453 } |
10299 | 10454 |
10300 // Find the number of objects making up this. | 10455 // Find the number of objects making up this. |
10301 int length = LocalPrototypeChainLength(*obj); | 10456 int length = LocalPrototypeChainLength(*obj); |
10302 | 10457 |
10303 // Try local lookup on each of the objects. | 10458 // Try local lookup on each of the objects. |
10304 Handle<JSObject> jsproto = obj; | 10459 Handle<JSObject> jsproto = obj; |
10305 for (int i = 0; i < length; i++) { | 10460 for (int i = 0; i < length; i++) { |
10306 LookupResult result; | 10461 LookupResult result(isolate); |
10307 jsproto->LocalLookup(*name, &result); | 10462 jsproto->LocalLookup(*name, &result); |
10308 if (result.IsProperty()) { | 10463 if (result.IsProperty()) { |
10309 // LookupResult is not GC safe as it holds raw object pointers. | 10464 // LookupResult is not GC safe as it holds raw object pointers. |
10310 // GC can happen later in this code so put the required fields into | 10465 // GC can happen later in this code so put the required fields into |
10311 // local variables using handles when required for later use. | 10466 // local variables using handles when required for later use. |
10312 PropertyType result_type = result.type(); | 10467 PropertyType result_type = result.type(); |
10313 Handle<Object> result_callback_obj; | 10468 Handle<Object> result_callback_obj; |
10314 if (result_type == CALLBACKS) { | 10469 if (result_type == CALLBACKS) { |
10315 result_callback_obj = Handle<Object>(result.GetCallbackObject(), | 10470 result_callback_obj = Handle<Object>(result.GetCallbackObject(), |
10316 isolate); | 10471 isolate); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10353 | 10508 |
10354 | 10509 |
10355 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetProperty) { | 10510 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetProperty) { |
10356 HandleScope scope(isolate); | 10511 HandleScope scope(isolate); |
10357 | 10512 |
10358 ASSERT(args.length() == 2); | 10513 ASSERT(args.length() == 2); |
10359 | 10514 |
10360 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 10515 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
10361 CONVERT_ARG_CHECKED(String, name, 1); | 10516 CONVERT_ARG_CHECKED(String, name, 1); |
10362 | 10517 |
10363 LookupResult result; | 10518 LookupResult result(isolate); |
10364 obj->Lookup(*name, &result); | 10519 obj->Lookup(*name, &result); |
10365 if (result.IsProperty()) { | 10520 if (result.IsProperty()) { |
10366 return DebugLookupResultValue(isolate->heap(), *obj, *name, &result, NULL); | 10521 return DebugLookupResultValue(isolate->heap(), *obj, *name, &result, NULL); |
10367 } | 10522 } |
10368 return isolate->heap()->undefined_value(); | 10523 return isolate->heap()->undefined_value(); |
10369 } | 10524 } |
10370 | 10525 |
10371 | 10526 |
10372 // Return the property type calculated from the property details. | 10527 // Return the property type calculated from the property details. |
10373 // args[0]: smi with property details. | 10528 // args[0]: smi with property details. |
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10890 function_context, local_scope)) { | 11045 function_context, local_scope)) { |
10891 return Handle<JSObject>(); | 11046 return Handle<JSObject>(); |
10892 } | 11047 } |
10893 | 11048 |
10894 // Finally copy any properties from the function context extension. | 11049 // Finally copy any properties from the function context extension. |
10895 // These will be variables introduced by eval. | 11050 // These will be variables introduced by eval. |
10896 if (function_context->closure() == *function) { | 11051 if (function_context->closure() == *function) { |
10897 if (function_context->has_extension() && | 11052 if (function_context->has_extension() && |
10898 !function_context->IsGlobalContext()) { | 11053 !function_context->IsGlobalContext()) { |
10899 Handle<JSObject> ext(JSObject::cast(function_context->extension())); | 11054 Handle<JSObject> ext(JSObject::cast(function_context->extension())); |
10900 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS); | 11055 bool threw = false; |
| 11056 Handle<FixedArray> keys = |
| 11057 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw); |
| 11058 if (threw) return Handle<JSObject>(); |
| 11059 |
10901 for (int i = 0; i < keys->length(); i++) { | 11060 for (int i = 0; i < keys->length(); i++) { |
10902 // Names of variables introduced by eval are strings. | 11061 // Names of variables introduced by eval are strings. |
10903 ASSERT(keys->get(i)->IsString()); | 11062 ASSERT(keys->get(i)->IsString()); |
10904 Handle<String> key(String::cast(keys->get(i))); | 11063 Handle<String> key(String::cast(keys->get(i))); |
10905 RETURN_IF_EMPTY_HANDLE_VALUE( | 11064 RETURN_IF_EMPTY_HANDLE_VALUE( |
10906 isolate, | 11065 isolate, |
10907 SetProperty(local_scope, | 11066 SetProperty(local_scope, |
10908 key, | 11067 key, |
10909 GetProperty(ext, key), | 11068 GetProperty(ext, key), |
10910 NONE, | 11069 NONE, |
(...skipping 27 matching lines...) Expand all Loading... |
10938 if (!CopyContextLocalsToScopeObject(isolate, | 11097 if (!CopyContextLocalsToScopeObject(isolate, |
10939 serialized_scope_info, scope_info, | 11098 serialized_scope_info, scope_info, |
10940 context, closure_scope)) { | 11099 context, closure_scope)) { |
10941 return Handle<JSObject>(); | 11100 return Handle<JSObject>(); |
10942 } | 11101 } |
10943 | 11102 |
10944 // Finally copy any properties from the function context extension. This will | 11103 // Finally copy any properties from the function context extension. This will |
10945 // be variables introduced by eval. | 11104 // be variables introduced by eval. |
10946 if (context->has_extension()) { | 11105 if (context->has_extension()) { |
10947 Handle<JSObject> ext(JSObject::cast(context->extension())); | 11106 Handle<JSObject> ext(JSObject::cast(context->extension())); |
10948 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS); | 11107 bool threw = false; |
| 11108 Handle<FixedArray> keys = |
| 11109 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw); |
| 11110 if (threw) return Handle<JSObject>(); |
| 11111 |
10949 for (int i = 0; i < keys->length(); i++) { | 11112 for (int i = 0; i < keys->length(); i++) { |
10950 // Names of variables introduced by eval are strings. | 11113 // Names of variables introduced by eval are strings. |
10951 ASSERT(keys->get(i)->IsString()); | 11114 ASSERT(keys->get(i)->IsString()); |
10952 Handle<String> key(String::cast(keys->get(i))); | 11115 Handle<String> key(String::cast(keys->get(i))); |
10953 RETURN_IF_EMPTY_HANDLE_VALUE( | 11116 RETURN_IF_EMPTY_HANDLE_VALUE( |
10954 isolate, | 11117 isolate, |
10955 SetProperty(closure_scope, | 11118 SetProperty(closure_scope, |
10956 key, | 11119 key, |
10957 GetProperty(ext, key), | 11120 GetProperty(ext, key), |
10958 NONE, | 11121 NONE, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11003 serialized_scope_info, scope_info, | 11166 serialized_scope_info, scope_info, |
11004 context, block_scope)) { | 11167 context, block_scope)) { |
11005 return Handle<JSObject>(); | 11168 return Handle<JSObject>(); |
11006 } | 11169 } |
11007 } | 11170 } |
11008 | 11171 |
11009 return block_scope; | 11172 return block_scope; |
11010 } | 11173 } |
11011 | 11174 |
11012 | 11175 |
11013 // Iterate over the actual scopes visible from a stack frame. All scopes are | 11176 // Iterate over the actual scopes visible from a stack frame. The iteration |
| 11177 // proceeds from the innermost visible nested scope outwards. All scopes are |
11014 // backed by an actual context except the local scope, which is inserted | 11178 // backed by an actual context except the local scope, which is inserted |
11015 // "artifically" in the context chain. | 11179 // "artificially" in the context chain. |
11016 class ScopeIterator { | 11180 class ScopeIterator { |
11017 public: | 11181 public: |
11018 enum ScopeType { | 11182 enum ScopeType { |
11019 ScopeTypeGlobal = 0, | 11183 ScopeTypeGlobal = 0, |
11020 ScopeTypeLocal, | 11184 ScopeTypeLocal, |
11021 ScopeTypeWith, | 11185 ScopeTypeWith, |
11022 ScopeTypeClosure, | 11186 ScopeTypeClosure, |
11023 ScopeTypeCatch, | 11187 ScopeTypeCatch, |
11024 ScopeTypeBlock | 11188 ScopeTypeBlock |
11025 }; | 11189 }; |
11026 | 11190 |
11027 ScopeIterator(Isolate* isolate, | 11191 ScopeIterator(Isolate* isolate, |
11028 JavaScriptFrame* frame, | 11192 JavaScriptFrame* frame, |
11029 int inlined_frame_index) | 11193 int inlined_frame_index) |
11030 : isolate_(isolate), | 11194 : isolate_(isolate), |
11031 frame_(frame), | 11195 frame_(frame), |
11032 inlined_frame_index_(inlined_frame_index), | 11196 inlined_frame_index_(inlined_frame_index), |
11033 function_(JSFunction::cast(frame->function())), | 11197 function_(JSFunction::cast(frame->function())), |
11034 context_(Context::cast(frame->context())), | 11198 context_(Context::cast(frame->context())), |
11035 local_done_(false), | 11199 nested_scope_chain_(4) { |
11036 at_local_(false) { | |
11037 | 11200 |
11038 // Check whether the first scope is actually a local scope. | 11201 // Catch the case when the debugger stops in an internal function. |
11039 // If there is a stack slot for .result then this local scope has been | 11202 Handle<SharedFunctionInfo> shared_info(function_->shared()); |
11040 // created for evaluating top level code and it is not a real local scope. | 11203 if (shared_info->script() == isolate->heap()->undefined_value()) { |
| 11204 while (context_->closure() == *function_) { |
| 11205 context_ = Handle<Context>(context_->previous(), isolate_); |
| 11206 } |
| 11207 return; |
| 11208 } |
| 11209 |
| 11210 // Check whether we are in global code or function code. If there is a stack |
| 11211 // slot for .result then this function has been created for evaluating |
| 11212 // global code and it is not a real function. |
11041 // Checking for the existence of .result seems fragile, but the scope info | 11213 // Checking for the existence of .result seems fragile, but the scope info |
11042 // saved with the code object does not otherwise have that information. | 11214 // saved with the code object does not otherwise have that information. |
11043 int index = function_->shared()->scope_info()-> | 11215 int index = shared_info->scope_info()-> |
11044 StackSlotIndex(isolate_->heap()->result_symbol()); | 11216 StackSlotIndex(isolate_->heap()->result_symbol()); |
| 11217 |
| 11218 // Reparse the code and analyze the scopes. |
| 11219 ZoneScope zone_scope(isolate, DELETE_ON_EXIT); |
| 11220 Handle<Script> script(Script::cast(shared_info->script())); |
| 11221 Scope* scope; |
11045 if (index >= 0) { | 11222 if (index >= 0) { |
11046 local_done_ = true; | 11223 // Global code |
11047 } else if (context_->IsGlobalContext() || | 11224 CompilationInfo info(script); |
11048 context_->IsFunctionContext()) { | 11225 info.MarkAsGlobal(); |
11049 at_local_ = true; | 11226 bool result = ParserApi::Parse(&info); |
11050 } else if (context_->closure() != *function_) { | 11227 ASSERT(result); |
11051 // The context_ is a block or with or catch block from the outer function. | 11228 result = Scope::Analyze(&info); |
11052 ASSERT(context_->IsWithContext() || | 11229 ASSERT(result); |
11053 context_->IsCatchContext() || | 11230 scope = info.function()->scope(); |
11054 context_->IsBlockContext()); | 11231 } else { |
11055 at_local_ = true; | 11232 // Function code |
| 11233 CompilationInfo info(shared_info); |
| 11234 bool result = ParserApi::Parse(&info); |
| 11235 ASSERT(result); |
| 11236 result = Scope::Analyze(&info); |
| 11237 ASSERT(result); |
| 11238 scope = info.function()->scope(); |
11056 } | 11239 } |
| 11240 |
| 11241 // Retrieve the scope chain for the current position. |
| 11242 int statement_position = |
| 11243 shared_info->code()->SourceStatementPosition(frame_->pc()); |
| 11244 scope->GetNestedScopeChain(&nested_scope_chain_, statement_position); |
11057 } | 11245 } |
11058 | 11246 |
11059 // More scopes? | 11247 // More scopes? |
11060 bool Done() { return context_.is_null(); } | 11248 bool Done() { return context_.is_null(); } |
11061 | 11249 |
11062 // Move to the next scope. | 11250 // Move to the next scope. |
11063 void Next() { | 11251 void Next() { |
11064 // If at a local scope mark the local scope as passed. | 11252 ScopeType scope_type = Type(); |
11065 if (at_local_) { | 11253 if (scope_type == ScopeTypeGlobal) { |
11066 at_local_ = false; | 11254 // The global scope is always the last in the chain. |
11067 local_done_ = true; | 11255 ASSERT(context_->IsGlobalContext()); |
11068 | |
11069 // If the current context is not associated with the local scope the | |
11070 // current context is the next real scope, so don't move to the next | |
11071 // context in this case. | |
11072 if (context_->closure() != *function_) { | |
11073 return; | |
11074 } | |
11075 } | |
11076 | |
11077 // The global scope is always the last in the chain. | |
11078 if (context_->IsGlobalContext()) { | |
11079 context_ = Handle<Context>(); | 11256 context_ = Handle<Context>(); |
11080 return; | 11257 return; |
11081 } | 11258 } |
11082 | 11259 if (nested_scope_chain_.is_empty()) { |
11083 // Move to the next context. | 11260 context_ = Handle<Context>(context_->previous(), isolate_); |
11084 context_ = Handle<Context>(context_->previous(), isolate_); | 11261 } else { |
11085 | 11262 if (nested_scope_chain_.last()->HasContext()) { |
11086 // If passing the local scope indicate that the current scope is now the | 11263 context_ = Handle<Context>(context_->previous(), isolate_); |
11087 // local scope. | 11264 } |
11088 if (!local_done_ && | 11265 nested_scope_chain_.RemoveLast(); |
11089 (context_->IsGlobalContext() || context_->IsFunctionContext())) { | |
11090 at_local_ = true; | |
11091 } | 11266 } |
11092 } | 11267 } |
11093 | 11268 |
11094 // Return the type of the current scope. | 11269 // Return the type of the current scope. |
11095 ScopeType Type() { | 11270 ScopeType Type() { |
11096 if (at_local_) { | 11271 if (!nested_scope_chain_.is_empty()) { |
11097 return ScopeTypeLocal; | 11272 Handle<SerializedScopeInfo> scope_info = nested_scope_chain_.last(); |
| 11273 switch (scope_info->Type()) { |
| 11274 case FUNCTION_SCOPE: |
| 11275 ASSERT(context_->IsFunctionContext() || |
| 11276 !scope_info->HasContext()); |
| 11277 return ScopeTypeLocal; |
| 11278 case GLOBAL_SCOPE: |
| 11279 ASSERT(context_->IsGlobalContext()); |
| 11280 return ScopeTypeGlobal; |
| 11281 case WITH_SCOPE: |
| 11282 ASSERT(context_->IsWithContext()); |
| 11283 return ScopeTypeWith; |
| 11284 case CATCH_SCOPE: |
| 11285 ASSERT(context_->IsCatchContext()); |
| 11286 return ScopeTypeCatch; |
| 11287 case BLOCK_SCOPE: |
| 11288 ASSERT(!scope_info->HasContext() || |
| 11289 context_->IsBlockContext()); |
| 11290 return ScopeTypeBlock; |
| 11291 case EVAL_SCOPE: |
| 11292 UNREACHABLE(); |
| 11293 } |
11098 } | 11294 } |
11099 if (context_->IsGlobalContext()) { | 11295 if (context_->IsGlobalContext()) { |
11100 ASSERT(context_->global()->IsGlobalObject()); | 11296 ASSERT(context_->global()->IsGlobalObject()); |
11101 return ScopeTypeGlobal; | 11297 return ScopeTypeGlobal; |
11102 } | 11298 } |
11103 if (context_->IsFunctionContext()) { | 11299 if (context_->IsFunctionContext()) { |
11104 return ScopeTypeClosure; | 11300 return ScopeTypeClosure; |
11105 } | 11301 } |
11106 if (context_->IsCatchContext()) { | 11302 if (context_->IsCatchContext()) { |
11107 return ScopeTypeCatch; | 11303 return ScopeTypeCatch; |
11108 } | 11304 } |
11109 if (context_->IsBlockContext()) { | 11305 if (context_->IsBlockContext()) { |
11110 return ScopeTypeBlock; | 11306 return ScopeTypeBlock; |
11111 } | 11307 } |
11112 ASSERT(context_->IsWithContext()); | 11308 ASSERT(context_->IsWithContext()); |
11113 return ScopeTypeWith; | 11309 return ScopeTypeWith; |
11114 } | 11310 } |
11115 | 11311 |
11116 // Return the JavaScript object with the content of the current scope. | 11312 // Return the JavaScript object with the content of the current scope. |
11117 Handle<JSObject> ScopeObject() { | 11313 Handle<JSObject> ScopeObject() { |
11118 switch (Type()) { | 11314 switch (Type()) { |
11119 case ScopeIterator::ScopeTypeGlobal: | 11315 case ScopeIterator::ScopeTypeGlobal: |
11120 return Handle<JSObject>(CurrentContext()->global()); | 11316 return Handle<JSObject>(CurrentContext()->global()); |
11121 case ScopeIterator::ScopeTypeLocal: | 11317 case ScopeIterator::ScopeTypeLocal: |
11122 // Materialize the content of the local scope into a JSObject. | 11318 // Materialize the content of the local scope into a JSObject. |
| 11319 ASSERT(nested_scope_chain_.length() == 1); |
11123 return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_); | 11320 return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_); |
11124 case ScopeIterator::ScopeTypeWith: | 11321 case ScopeIterator::ScopeTypeWith: |
11125 // Return the with object. | 11322 // Return the with object. |
11126 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); | 11323 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); |
11127 case ScopeIterator::ScopeTypeCatch: | 11324 case ScopeIterator::ScopeTypeCatch: |
11128 return MaterializeCatchScope(isolate_, CurrentContext()); | 11325 return MaterializeCatchScope(isolate_, CurrentContext()); |
11129 case ScopeIterator::ScopeTypeClosure: | 11326 case ScopeIterator::ScopeTypeClosure: |
11130 // Materialize the content of the closure scope into a JSObject. | 11327 // Materialize the content of the closure scope into a JSObject. |
11131 return MaterializeClosure(isolate_, CurrentContext()); | 11328 return MaterializeClosure(isolate_, CurrentContext()); |
11132 case ScopeIterator::ScopeTypeBlock: | 11329 case ScopeIterator::ScopeTypeBlock: |
11133 return MaterializeBlockScope(isolate_, CurrentContext()); | 11330 return MaterializeBlockScope(isolate_, CurrentContext()); |
11134 } | 11331 } |
11135 UNREACHABLE(); | 11332 UNREACHABLE(); |
11136 return Handle<JSObject>(); | 11333 return Handle<JSObject>(); |
11137 } | 11334 } |
11138 | 11335 |
| 11336 Handle<SerializedScopeInfo> CurrentScopeInfo() { |
| 11337 if (!nested_scope_chain_.is_empty()) { |
| 11338 return nested_scope_chain_.last(); |
| 11339 } else if (context_->IsBlockContext()) { |
| 11340 return Handle<SerializedScopeInfo>( |
| 11341 SerializedScopeInfo::cast(context_->extension())); |
| 11342 } else if (context_->IsFunctionContext()) { |
| 11343 return Handle<SerializedScopeInfo>( |
| 11344 context_->closure()->shared()->scope_info()); |
| 11345 } |
| 11346 return Handle<SerializedScopeInfo>::null(); |
| 11347 } |
| 11348 |
11139 // Return the context for this scope. For the local context there might not | 11349 // Return the context for this scope. For the local context there might not |
11140 // be an actual context. | 11350 // be an actual context. |
11141 Handle<Context> CurrentContext() { | 11351 Handle<Context> CurrentContext() { |
11142 if (at_local_ && context_->closure() != *function_) { | 11352 if (Type() == ScopeTypeGlobal || |
| 11353 nested_scope_chain_.is_empty()) { |
| 11354 return context_; |
| 11355 } else if (nested_scope_chain_.last()->HasContext()) { |
| 11356 return context_; |
| 11357 } else { |
11143 return Handle<Context>(); | 11358 return Handle<Context>(); |
11144 } | 11359 } |
11145 return context_; | |
11146 } | 11360 } |
11147 | 11361 |
11148 #ifdef DEBUG | 11362 #ifdef DEBUG |
11149 // Debug print of the content of the current scope. | 11363 // Debug print of the content of the current scope. |
11150 void DebugPrint() { | 11364 void DebugPrint() { |
11151 switch (Type()) { | 11365 switch (Type()) { |
11152 case ScopeIterator::ScopeTypeGlobal: | 11366 case ScopeIterator::ScopeTypeGlobal: |
11153 PrintF("Global:\n"); | 11367 PrintF("Global:\n"); |
11154 CurrentContext()->Print(); | 11368 CurrentContext()->Print(); |
11155 break; | 11369 break; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11198 PrintF("\n"); | 11412 PrintF("\n"); |
11199 } | 11413 } |
11200 #endif | 11414 #endif |
11201 | 11415 |
11202 private: | 11416 private: |
11203 Isolate* isolate_; | 11417 Isolate* isolate_; |
11204 JavaScriptFrame* frame_; | 11418 JavaScriptFrame* frame_; |
11205 int inlined_frame_index_; | 11419 int inlined_frame_index_; |
11206 Handle<JSFunction> function_; | 11420 Handle<JSFunction> function_; |
11207 Handle<Context> context_; | 11421 Handle<Context> context_; |
11208 bool local_done_; | 11422 List<Handle<SerializedScopeInfo> > nested_scope_chain_; |
11209 bool at_local_; | |
11210 | 11423 |
11211 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); | 11424 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); |
11212 }; | 11425 }; |
11213 | 11426 |
11214 | 11427 |
11215 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) { | 11428 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) { |
11216 HandleScope scope(isolate); | 11429 HandleScope scope(isolate); |
11217 ASSERT(args.length() == 2); | 11430 ASSERT(args.length() == 2); |
11218 | 11431 |
11219 // Check arguments. | 11432 // Check arguments. |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11514 return isolate->heap()->undefined_value(); | 11727 return isolate->heap()->undefined_value(); |
11515 } | 11728 } |
11516 | 11729 |
11517 // If the candidate found is compiled we are done. NOTE: when lazy | 11730 // If the candidate found is compiled we are done. NOTE: when lazy |
11518 // compilation of inner functions is introduced some additional checking | 11731 // compilation of inner functions is introduced some additional checking |
11519 // needs to be done here to compile inner functions. | 11732 // needs to be done here to compile inner functions. |
11520 done = target->is_compiled(); | 11733 done = target->is_compiled(); |
11521 if (!done) { | 11734 if (!done) { |
11522 // If the candidate is not compiled compile it to reveal any inner | 11735 // If the candidate is not compiled compile it to reveal any inner |
11523 // functions which might contain the requested source position. | 11736 // functions which might contain the requested source position. |
11524 CompileLazyShared(target, KEEP_EXCEPTION); | 11737 SharedFunctionInfo::CompileLazy(target, KEEP_EXCEPTION); |
11525 } | 11738 } |
11526 } // End while loop. | 11739 } // End while loop. |
11527 | 11740 |
11528 return *target; | 11741 return *target; |
11529 } | 11742 } |
11530 | 11743 |
11531 | 11744 |
11532 // Changes the state of a break point in a script and returns source position | 11745 // Changes the state of a break point in a script and returns source position |
11533 // where break point was set. NOTE: Regarding performance see the NOTE for | 11746 // where break point was set. NOTE: Regarding performance see the NOTE for |
11534 // GetScriptFromScriptData. | 11747 // GetScriptFromScriptData. |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11662 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) { | 11875 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) { |
11663 HandleScope scope(isolate); | 11876 HandleScope scope(isolate); |
11664 ASSERT(args.length() == 0); | 11877 ASSERT(args.length() == 0); |
11665 isolate->debug()->ClearStepping(); | 11878 isolate->debug()->ClearStepping(); |
11666 return isolate->heap()->undefined_value(); | 11879 return isolate->heap()->undefined_value(); |
11667 } | 11880 } |
11668 | 11881 |
11669 | 11882 |
11670 // Creates a copy of the with context chain. The copy of the context chain is | 11883 // Creates a copy of the with context chain. The copy of the context chain is |
11671 // is linked to the function context supplied. | 11884 // is linked to the function context supplied. |
11672 static Handle<Context> CopyWithContextChain(Isolate* isolate, | 11885 static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate, |
11673 Handle<JSFunction> function, | 11886 Handle<JSFunction> function, |
11674 Handle<Context> current, | 11887 Handle<Context> base, |
11675 Handle<Context> base) { | 11888 JavaScriptFrame* frame, |
11676 // At the end of the chain. Return the base context to link to. | 11889 int inlined_frame_index) { |
11677 if (current->IsFunctionContext() || current->IsGlobalContext()) { | 11890 HandleScope scope(isolate); |
11678 return base; | 11891 List<Handle<SerializedScopeInfo> > scope_chain; |
| 11892 List<Handle<Context> > context_chain; |
| 11893 |
| 11894 ScopeIterator it(isolate, frame, inlined_frame_index); |
| 11895 for (; it.Type() != ScopeIterator::ScopeTypeGlobal && |
| 11896 it.Type() != ScopeIterator::ScopeTypeLocal ; it.Next()) { |
| 11897 ASSERT(!it.Done()); |
| 11898 scope_chain.Add(it.CurrentScopeInfo()); |
| 11899 context_chain.Add(it.CurrentContext()); |
11679 } | 11900 } |
11680 | 11901 |
11681 // Recursively copy the with and catch contexts. | 11902 // At the end of the chain. Return the base context to link to. |
11682 HandleScope scope(isolate); | 11903 Handle<Context> context = base; |
11683 Handle<Context> previous(current->previous()); | 11904 |
11684 Handle<Context> new_previous = | 11905 // Iteratively copy and or materialize the nested contexts. |
11685 CopyWithContextChain(isolate, function, previous, base); | 11906 while (!scope_chain.is_empty()) { |
11686 Handle<Context> new_current; | 11907 Handle<SerializedScopeInfo> scope_info = scope_chain.RemoveLast(); |
11687 if (current->IsCatchContext()) { | 11908 Handle<Context> current = context_chain.RemoveLast(); |
11688 Handle<String> name(String::cast(current->extension())); | 11909 ASSERT(!(scope_info->HasContext() & current.is_null())); |
11689 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); | 11910 |
11690 new_current = | 11911 if (scope_info->Type() == CATCH_SCOPE) { |
11691 isolate->factory()->NewCatchContext(function, | 11912 Handle<String> name(String::cast(current->extension())); |
11692 new_previous, | 11913 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); |
11693 name, | 11914 context = |
11694 thrown_object); | 11915 isolate->factory()->NewCatchContext(function, |
11695 } else if (current->IsBlockContext()) { | 11916 context, |
11696 Handle<SerializedScopeInfo> scope_info( | 11917 name, |
11697 SerializedScopeInfo::cast(current->extension())); | 11918 thrown_object); |
11698 new_current = | 11919 } else if (scope_info->Type() == BLOCK_SCOPE) { |
11699 isolate->factory()->NewBlockContext(function, new_previous, scope_info); | 11920 // Materialize the contents of the block scope into a JSObject. |
11700 // Copy context slots. | 11921 Handle<JSObject> block_scope_object = |
11701 int num_context_slots = scope_info->NumberOfContextSlots(); | 11922 MaterializeBlockScope(isolate, current); |
11702 for (int i = Context::MIN_CONTEXT_SLOTS; i < num_context_slots; ++i) { | 11923 if (block_scope_object.is_null()) { |
11703 new_current->set(i, current->get(i)); | 11924 return Handle<Context>::null(); |
| 11925 } |
| 11926 // Allocate a new function context for the debug evaluation and set the |
| 11927 // extension object. |
| 11928 Handle<Context> new_context = |
| 11929 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, |
| 11930 function); |
| 11931 new_context->set_extension(*block_scope_object); |
| 11932 new_context->set_previous(*context); |
| 11933 context = new_context; |
| 11934 } else { |
| 11935 ASSERT(scope_info->Type() == WITH_SCOPE); |
| 11936 ASSERT(current->IsWithContext()); |
| 11937 Handle<JSObject> extension(JSObject::cast(current->extension())); |
| 11938 context = |
| 11939 isolate->factory()->NewWithContext(function, context, extension); |
11704 } | 11940 } |
11705 } else { | |
11706 ASSERT(current->IsWithContext()); | |
11707 Handle<JSObject> extension(JSObject::cast(current->extension())); | |
11708 new_current = | |
11709 isolate->factory()->NewWithContext(function, new_previous, extension); | |
11710 } | 11941 } |
11711 return scope.CloseAndEscape(new_current); | 11942 |
| 11943 return scope.CloseAndEscape(context); |
11712 } | 11944 } |
11713 | 11945 |
11714 | 11946 |
11715 // Helper function to find or create the arguments object for | 11947 // Helper function to find or create the arguments object for |
11716 // Runtime_DebugEvaluate. | 11948 // Runtime_DebugEvaluate. |
11717 static Handle<Object> GetArgumentsObject(Isolate* isolate, | 11949 static Handle<Object> GetArgumentsObject(Isolate* isolate, |
11718 JavaScriptFrame* frame, | 11950 JavaScriptFrame* frame, |
11719 int inlined_frame_index, | 11951 int inlined_frame_index, |
11720 Handle<JSFunction> function, | 11952 Handle<JSFunction> function, |
11721 Handle<SerializedScopeInfo> scope_info, | 11953 Handle<SerializedScopeInfo> scope_info, |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11839 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, | 12071 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, |
11840 go_between); | 12072 go_between); |
11841 context->set_extension(*local_scope); | 12073 context->set_extension(*local_scope); |
11842 // Copy any with contexts present and chain them in front of this context. | 12074 // Copy any with contexts present and chain them in front of this context. |
11843 Handle<Context> frame_context(Context::cast(frame->context())); | 12075 Handle<Context> frame_context(Context::cast(frame->context())); |
11844 Handle<Context> function_context; | 12076 Handle<Context> function_context; |
11845 // Get the function's context if it has one. | 12077 // Get the function's context if it has one. |
11846 if (scope_info->HasHeapAllocatedLocals()) { | 12078 if (scope_info->HasHeapAllocatedLocals()) { |
11847 function_context = Handle<Context>(frame_context->declaration_context()); | 12079 function_context = Handle<Context>(frame_context->declaration_context()); |
11848 } | 12080 } |
11849 context = CopyWithContextChain(isolate, go_between, frame_context, context); | 12081 context = CopyNestedScopeContextChain(isolate, |
| 12082 go_between, |
| 12083 context, |
| 12084 frame, |
| 12085 inlined_frame_index); |
11850 | 12086 |
11851 if (additional_context->IsJSObject()) { | 12087 if (additional_context->IsJSObject()) { |
11852 Handle<JSObject> extension = Handle<JSObject>::cast(additional_context); | 12088 Handle<JSObject> extension = Handle<JSObject>::cast(additional_context); |
11853 context = | 12089 context = |
11854 isolate->factory()->NewWithContext(go_between, context, extension); | 12090 isolate->factory()->NewWithContext(go_between, context, extension); |
11855 } | 12091 } |
11856 | 12092 |
11857 // Wrap the evaluation statement in a new function compiled in the newly | 12093 // Wrap the evaluation statement in a new function compiled in the newly |
11858 // created context. The function has one parameter which has to be called | 12094 // created context. The function has one parameter which has to be called |
11859 // 'arguments'. This it to have access to what would have been 'arguments' in | 12095 // 'arguments'. This it to have access to what would have been 'arguments' in |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12238 } | 12474 } |
12239 | 12475 |
12240 | 12476 |
12241 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleFunction) { | 12477 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleFunction) { |
12242 #ifdef DEBUG | 12478 #ifdef DEBUG |
12243 HandleScope scope(isolate); | 12479 HandleScope scope(isolate); |
12244 ASSERT(args.length() == 1); | 12480 ASSERT(args.length() == 1); |
12245 // Get the function and make sure it is compiled. | 12481 // Get the function and make sure it is compiled. |
12246 CONVERT_ARG_CHECKED(JSFunction, func, 0); | 12482 CONVERT_ARG_CHECKED(JSFunction, func, 0); |
12247 Handle<SharedFunctionInfo> shared(func->shared()); | 12483 Handle<SharedFunctionInfo> shared(func->shared()); |
12248 if (!EnsureCompiled(shared, KEEP_EXCEPTION)) { | 12484 if (!SharedFunctionInfo::EnsureCompiled(shared, KEEP_EXCEPTION)) { |
12249 return Failure::Exception(); | 12485 return Failure::Exception(); |
12250 } | 12486 } |
12251 func->code()->PrintLn(); | 12487 func->code()->PrintLn(); |
12252 #endif // DEBUG | 12488 #endif // DEBUG |
12253 return isolate->heap()->undefined_value(); | 12489 return isolate->heap()->undefined_value(); |
12254 } | 12490 } |
12255 | 12491 |
12256 | 12492 |
12257 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleConstructor) { | 12493 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugDisassembleConstructor) { |
12258 #ifdef DEBUG | 12494 #ifdef DEBUG |
12259 HandleScope scope(isolate); | 12495 HandleScope scope(isolate); |
12260 ASSERT(args.length() == 1); | 12496 ASSERT(args.length() == 1); |
12261 // Get the function and make sure it is compiled. | 12497 // Get the function and make sure it is compiled. |
12262 CONVERT_ARG_CHECKED(JSFunction, func, 0); | 12498 CONVERT_ARG_CHECKED(JSFunction, func, 0); |
12263 Handle<SharedFunctionInfo> shared(func->shared()); | 12499 Handle<SharedFunctionInfo> shared(func->shared()); |
12264 if (!EnsureCompiled(shared, KEEP_EXCEPTION)) { | 12500 if (!SharedFunctionInfo::EnsureCompiled(shared, KEEP_EXCEPTION)) { |
12265 return Failure::Exception(); | 12501 return Failure::Exception(); |
12266 } | 12502 } |
12267 shared->construct_stub()->PrintLn(); | 12503 shared->construct_stub()->PrintLn(); |
12268 #endif // DEBUG | 12504 #endif // DEBUG |
12269 return isolate->heap()->undefined_value(); | 12505 return isolate->heap()->undefined_value(); |
12270 } | 12506 } |
12271 | 12507 |
12272 | 12508 |
12273 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetInferredName) { | 12509 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionGetInferredName) { |
12274 NoHandleAllocation ha; | 12510 NoHandleAllocation ha; |
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12860 // Determines whether the given stack frame should be displayed in | 13096 // Determines whether the given stack frame should be displayed in |
12861 // a stack trace. The caller is the error constructor that asked | 13097 // a stack trace. The caller is the error constructor that asked |
12862 // for the stack trace to be collected. The first time a construct | 13098 // for the stack trace to be collected. The first time a construct |
12863 // call to this function is encountered it is skipped. The seen_caller | 13099 // call to this function is encountered it is skipped. The seen_caller |
12864 // in/out parameter is used to remember if the caller has been seen | 13100 // in/out parameter is used to remember if the caller has been seen |
12865 // yet. | 13101 // yet. |
12866 static bool ShowFrameInStackTrace(StackFrame* raw_frame, | 13102 static bool ShowFrameInStackTrace(StackFrame* raw_frame, |
12867 Object* caller, | 13103 Object* caller, |
12868 bool* seen_caller) { | 13104 bool* seen_caller) { |
12869 // Only display JS frames. | 13105 // Only display JS frames. |
12870 if (!raw_frame->is_java_script()) | 13106 if (!raw_frame->is_java_script()) { |
12871 return false; | 13107 return false; |
| 13108 } |
12872 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame); | 13109 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame); |
12873 Object* raw_fun = frame->function(); | 13110 Object* raw_fun = frame->function(); |
12874 // Not sure when this can happen but skip it just in case. | 13111 // Not sure when this can happen but skip it just in case. |
12875 if (!raw_fun->IsJSFunction()) | 13112 if (!raw_fun->IsJSFunction()) { |
12876 return false; | 13113 return false; |
| 13114 } |
12877 if ((raw_fun == caller) && !(*seen_caller)) { | 13115 if ((raw_fun == caller) && !(*seen_caller)) { |
12878 *seen_caller = true; | 13116 *seen_caller = true; |
12879 return false; | 13117 return false; |
12880 } | 13118 } |
12881 // Skip all frames until we've seen the caller. | 13119 // Skip all frames until we've seen the caller. |
12882 if (!(*seen_caller)) return false; | 13120 if (!(*seen_caller)) return false; |
12883 // Also, skip the most obvious builtin calls. We recognize builtins | 13121 // Also, skip non-visible built-in functions and any call with the builtins |
12884 // as (1) functions called with the builtins object as the receiver and | 13122 // object as receiver, so as to not reveal either the builtins object or |
12885 // as (2) functions from native scripts called with undefined as the | 13123 // an internal function. |
12886 // receiver (direct calls to helper functions in the builtins | 13124 // The --builtins-in-stack-traces command line flag allows including |
12887 // code). Some builtin calls (such as Number.ADD which is invoked | 13125 // internal call sites in the stack trace for debugging purposes. |
12888 // using 'call') are very difficult to recognize so we're leaving | 13126 if (!FLAG_builtins_in_stack_traces) { |
12889 // them in for now. | 13127 JSFunction* fun = JSFunction::cast(raw_fun); |
12890 if (frame->receiver()->IsJSBuiltinsObject()) { | 13128 if (frame->receiver()->IsJSBuiltinsObject() || |
12891 return false; | 13129 (fun->IsBuiltin() && !fun->shared()->native())) { |
12892 } | 13130 return false; |
12893 JSFunction* fun = JSFunction::cast(raw_fun); | 13131 } |
12894 Object* raw_script = fun->shared()->script(); | |
12895 if (frame->receiver()->IsUndefined() && raw_script->IsScript()) { | |
12896 int script_type = Script::cast(raw_script)->type()->value(); | |
12897 return script_type != Script::TYPE_NATIVE; | |
12898 } | 13132 } |
12899 return true; | 13133 return true; |
12900 } | 13134 } |
12901 | 13135 |
12902 | 13136 |
12903 // Collect the raw data for a stack trace. Returns an array of 4 | 13137 // Collect the raw data for a stack trace. Returns an array of 4 |
12904 // element segments each containing a receiver, function, code and | 13138 // element segments each containing a receiver, function, code and |
12905 // native code offset. | 13139 // native code offset. |
12906 RUNTIME_FUNCTION(MaybeObject*, Runtime_CollectStackTrace) { | 13140 RUNTIME_FUNCTION(MaybeObject*, Runtime_CollectStackTrace) { |
12907 ASSERT_EQ(args.length(), 2); | 13141 ASSERT_EQ(args.length(), 2); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13034 bool pending_exception; | 13268 bool pending_exception; |
13035 value = Execution::Call(factory, | 13269 value = Execution::Call(factory, |
13036 receiver, | 13270 receiver, |
13037 ARRAY_SIZE(argv), | 13271 ARRAY_SIZE(argv), |
13038 argv, | 13272 argv, |
13039 &pending_exception); | 13273 &pending_exception); |
13040 if (pending_exception) return Failure::Exception(); | 13274 if (pending_exception) return Failure::Exception(); |
13041 } | 13275 } |
13042 | 13276 |
13043 #ifdef DEBUG | 13277 #ifdef DEBUG |
13044 cache_handle->JSFunctionResultCacheVerify(); | 13278 if (FLAG_verify_heap) { |
| 13279 cache_handle->JSFunctionResultCacheVerify(); |
| 13280 } |
13045 #endif | 13281 #endif |
13046 | 13282 |
13047 // Function invocation may have cleared the cache. Reread all the data. | 13283 // Function invocation may have cleared the cache. Reread all the data. |
13048 finger_index = cache_handle->finger_index(); | 13284 finger_index = cache_handle->finger_index(); |
13049 size = cache_handle->size(); | 13285 size = cache_handle->size(); |
13050 | 13286 |
13051 // If we have spare room, put new data into it, otherwise evict post finger | 13287 // If we have spare room, put new data into it, otherwise evict post finger |
13052 // entry which is likely to be the least recently used. | 13288 // entry which is likely to be the least recently used. |
13053 int index = -1; | 13289 int index = -1; |
13054 if (size < cache_handle->length()) { | 13290 if (size < cache_handle->length()) { |
13055 cache_handle->set_size(size + JSFunctionResultCache::kEntrySize); | 13291 cache_handle->set_size(size + JSFunctionResultCache::kEntrySize); |
13056 index = size; | 13292 index = size; |
13057 } else { | 13293 } else { |
13058 index = finger_index + JSFunctionResultCache::kEntrySize; | 13294 index = finger_index + JSFunctionResultCache::kEntrySize; |
13059 if (index == cache_handle->length()) { | 13295 if (index == cache_handle->length()) { |
13060 index = JSFunctionResultCache::kEntriesIndex; | 13296 index = JSFunctionResultCache::kEntriesIndex; |
13061 } | 13297 } |
13062 } | 13298 } |
13063 | 13299 |
13064 ASSERT(index % 2 == 0); | 13300 ASSERT(index % 2 == 0); |
13065 ASSERT(index >= JSFunctionResultCache::kEntriesIndex); | 13301 ASSERT(index >= JSFunctionResultCache::kEntriesIndex); |
13066 ASSERT(index < cache_handle->length()); | 13302 ASSERT(index < cache_handle->length()); |
13067 | 13303 |
13068 cache_handle->set(index, *key_handle); | 13304 cache_handle->set(index, *key_handle); |
13069 cache_handle->set(index + 1, *value); | 13305 cache_handle->set(index + 1, *value); |
13070 cache_handle->set_finger_index(index); | 13306 cache_handle->set_finger_index(index); |
13071 | 13307 |
13072 #ifdef DEBUG | 13308 #ifdef DEBUG |
13073 cache_handle->JSFunctionResultCacheVerify(); | 13309 if (FLAG_verify_heap) { |
| 13310 cache_handle->JSFunctionResultCacheVerify(); |
| 13311 } |
13074 #endif | 13312 #endif |
13075 | 13313 |
13076 return *value; | 13314 return *value; |
13077 } | 13315 } |
13078 | 13316 |
13079 | 13317 |
13080 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewMessageObject) { | 13318 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewMessageObject) { |
13081 HandleScope scope(isolate); | 13319 HandleScope scope(isolate); |
13082 CONVERT_ARG_CHECKED(String, type, 0); | 13320 CONVERT_ARG_CHECKED(String, type, 0); |
13083 CONVERT_ARG_CHECKED(JSArray, arguments, 1); | 13321 CONVERT_ARG_CHECKED(JSArray, arguments, 1); |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13288 } else { | 13526 } else { |
13289 // Handle last resort GC and make sure to allow future allocations | 13527 // Handle last resort GC and make sure to allow future allocations |
13290 // to grow the heap without causing GCs (if possible). | 13528 // to grow the heap without causing GCs (if possible). |
13291 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13529 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13292 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); | 13530 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); |
13293 } | 13531 } |
13294 } | 13532 } |
13295 | 13533 |
13296 | 13534 |
13297 } } // namespace v8::internal | 13535 } } // namespace v8::internal |
OLD | NEW |