| 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 |