| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 // which we should not have access to. | 147 // which we should not have access to. |
| 148 Handle<Context> context = | 148 Handle<Context> context = |
| 149 Handle<Context>(JSFunction::GlobalContextFromLiterals(*literals)); | 149 Handle<Context>(JSFunction::GlobalContextFromLiterals(*literals)); |
| 150 | 150 |
| 151 bool is_result_from_cache; | 151 bool is_result_from_cache; |
| 152 Handle<Map> map = ComputeObjectLiteralMap(context, | 152 Handle<Map> map = ComputeObjectLiteralMap(context, |
| 153 constant_properties, | 153 constant_properties, |
| 154 &is_result_from_cache); | 154 &is_result_from_cache); |
| 155 | 155 |
| 156 Handle<JSObject> boilerplate = Factory::NewJSObjectFromMap(map); | 156 Handle<JSObject> boilerplate = Factory::NewJSObjectFromMap(map); |
| 157 { // Add the constant propeties to the boilerplate. | 157 { // Add the constant properties to the boilerplate. |
| 158 int length = constant_properties->length(); | 158 int length = constant_properties->length(); |
| 159 OptimizedObjectForAddingMultipleProperties opt(boilerplate, | 159 OptimizedObjectForAddingMultipleProperties opt(boilerplate, |
| 160 !is_result_from_cache); | 160 !is_result_from_cache); |
| 161 for (int index = 0; index < length; index +=2) { | 161 for (int index = 0; index < length; index +=2) { |
| 162 Handle<Object> key(constant_properties->get(index+0)); | 162 Handle<Object> key(constant_properties->get(index+0)); |
| 163 Handle<Object> value(constant_properties->get(index+1)); | 163 Handle<Object> value(constant_properties->get(index+1)); |
| 164 Handle<Object> result; |
| 164 uint32_t element_index = 0; | 165 uint32_t element_index = 0; |
| 165 if (key->IsSymbol()) { | 166 if (key->IsSymbol()) { |
| 166 // If key is a symbol it is not an array element. | 167 // If key is a symbol it is not an array element. |
| 167 Handle<String> name(String::cast(*key)); | 168 Handle<String> name(String::cast(*key)); |
| 168 ASSERT(!name->AsArrayIndex(&element_index)); | 169 ASSERT(!name->AsArrayIndex(&element_index)); |
| 169 SetProperty(boilerplate, name, value, NONE); | 170 result = SetProperty(boilerplate, name, value, NONE); |
| 170 } else if (Array::IndexFromObject(*key, &element_index)) { | 171 } else if (Array::IndexFromObject(*key, &element_index)) { |
| 171 // Array index (uint32). | 172 // Array index (uint32). |
| 172 SetElement(boilerplate, element_index, value); | 173 result = SetElement(boilerplate, element_index, value); |
| 173 } else { | 174 } else { |
| 174 // Non-uint32 number. | 175 // Non-uint32 number. |
| 175 ASSERT(key->IsNumber()); | 176 ASSERT(key->IsNumber()); |
| 176 double num = key->Number(); | 177 double num = key->Number(); |
| 177 char arr[100]; | 178 char arr[100]; |
| 178 Vector<char> buffer(arr, ARRAY_SIZE(arr)); | 179 Vector<char> buffer(arr, ARRAY_SIZE(arr)); |
| 179 const char* str = DoubleToCString(num, buffer); | 180 const char* str = DoubleToCString(num, buffer); |
| 180 Handle<String> name = Factory::NewStringFromAscii(CStrVector(str)); | 181 Handle<String> name = Factory::NewStringFromAscii(CStrVector(str)); |
| 181 SetProperty(boilerplate, name, value, NONE); | 182 result = SetProperty(boilerplate, name, value, NONE); |
| 182 } | 183 } |
| 184 // If setting the property on the boilerplate throws an |
| 185 // exception, the exception is converted to an empty handle in |
| 186 // the handle based operations. In that case, we need to |
| 187 // convert back to an exception. |
| 188 if (result.is_null()) return Failure::Exception(); |
| 183 } | 189 } |
| 184 } | 190 } |
| 185 | 191 |
| 186 // Update the functions literal and return the boilerplate. | 192 // Update the functions literal and return the boilerplate. |
| 187 literals->set(literals_index, *boilerplate); | 193 literals->set(literals_index, *boilerplate); |
| 188 | 194 |
| 189 return *boilerplate; | 195 return *boilerplate; |
| 190 } | 196 } |
| 191 | 197 |
| 192 | 198 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 208 // Copy the elements. | 214 // Copy the elements. |
| 209 Object* content = elements->Copy(); | 215 Object* content = elements->Copy(); |
| 210 if (content->IsFailure()) return content; | 216 if (content->IsFailure()) return content; |
| 211 | 217 |
| 212 // Set the elements. | 218 // Set the elements. |
| 213 JSArray::cast(object)->SetContent(FixedArray::cast(content)); | 219 JSArray::cast(object)->SetContent(FixedArray::cast(content)); |
| 214 return object; | 220 return object; |
| 215 } | 221 } |
| 216 | 222 |
| 217 | 223 |
| 224 static Object* Runtime_CreateCatchExtensionObject(Arguments args) { |
| 225 ASSERT(args.length() == 2); |
| 226 CONVERT_CHECKED(String, key, args[0]); |
| 227 Object* value = args[1]; |
| 228 // Create a catch context extension object. |
| 229 JSFunction* constructor = |
| 230 Top::context()->global_context()->context_extension_function(); |
| 231 Object* object = Heap::AllocateJSObject(constructor); |
| 232 if (object->IsFailure()) return object; |
| 233 // Assign the exception value to the catch variable and make sure |
| 234 // that the catch variable is DontDelete. |
| 235 value = JSObject::cast(object)->SetProperty(key, value, DONT_DELETE); |
| 236 if (value->IsFailure()) return value; |
| 237 return object; |
| 238 } |
| 239 |
| 240 |
| 218 static Object* Runtime_ClassOf(Arguments args) { | 241 static Object* Runtime_ClassOf(Arguments args) { |
| 219 NoHandleAllocation ha; | 242 NoHandleAllocation ha; |
| 220 ASSERT(args.length() == 1); | 243 ASSERT(args.length() == 1); |
| 221 Object* obj = args[0]; | 244 Object* obj = args[0]; |
| 222 if (!obj->IsJSObject()) return Heap::null_value(); | 245 if (!obj->IsJSObject()) return Heap::null_value(); |
| 223 return JSObject::cast(obj)->class_name(); | 246 return JSObject::cast(obj)->class_name(); |
| 224 } | 247 } |
| 225 | 248 |
| 226 | 249 |
| 227 static Object* Runtime_HasStringClass(Arguments args) { | 250 static Object* Runtime_HasStringClass(Arguments args) { |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 } else { | 359 } else { |
| 337 RUNTIME_ASSERT(offset < ObjectTemplateInfo::kSize); | 360 RUNTIME_ASSERT(offset < ObjectTemplateInfo::kSize); |
| 338 } | 361 } |
| 339 return *HeapObject::RawField(templ, offset); | 362 return *HeapObject::RawField(templ, offset); |
| 340 } | 363 } |
| 341 | 364 |
| 342 | 365 |
| 343 static Object* Runtime_DisableAccessChecks(Arguments args) { | 366 static Object* Runtime_DisableAccessChecks(Arguments args) { |
| 344 ASSERT(args.length() == 1); | 367 ASSERT(args.length() == 1); |
| 345 CONVERT_CHECKED(HeapObject, object, args[0]); | 368 CONVERT_CHECKED(HeapObject, object, args[0]); |
| 346 bool needs_access_checks = object->map()->is_access_check_needed(); | 369 Map* old_map = object->map(); |
| 347 object->map()->set_is_access_check_needed(false); | 370 bool needs_access_checks = old_map->is_access_check_needed(); |
| 371 if (needs_access_checks) { |
| 372 // Copy map so it won't interfere constructor's initial map. |
| 373 Object* new_map = old_map->CopyDropTransitions(); |
| 374 if (new_map->IsFailure()) return new_map; |
| 375 |
| 376 Map::cast(new_map)->set_is_access_check_needed(false); |
| 377 object->set_map(Map::cast(new_map)); |
| 378 } |
| 348 return needs_access_checks ? Heap::true_value() : Heap::false_value(); | 379 return needs_access_checks ? Heap::true_value() : Heap::false_value(); |
| 349 } | 380 } |
| 350 | 381 |
| 351 | 382 |
| 352 static Object* Runtime_EnableAccessChecks(Arguments args) { | 383 static Object* Runtime_EnableAccessChecks(Arguments args) { |
| 353 ASSERT(args.length() == 1); | 384 ASSERT(args.length() == 1); |
| 354 CONVERT_CHECKED(HeapObject, object, args[0]); | 385 CONVERT_CHECKED(HeapObject, object, args[0]); |
| 355 object->map()->set_is_access_check_needed(true); | 386 Map* old_map = object->map(); |
| 387 if (!old_map->is_access_check_needed()) { |
| 388 // Copy map so it won't interfere constructor's initial map. |
| 389 Object* new_map = old_map->CopyDropTransitions(); |
| 390 if (new_map->IsFailure()) return new_map; |
| 391 |
| 392 Map::cast(new_map)->set_is_access_check_needed(true); |
| 393 object->set_map(Map::cast(new_map)); |
| 394 } |
| 356 return Heap::undefined_value(); | 395 return Heap::undefined_value(); |
| 357 } | 396 } |
| 358 | 397 |
| 359 | 398 |
| 360 static Object* ThrowRedeclarationError(const char* type, Handle<String> name) { | 399 static Object* ThrowRedeclarationError(const char* type, Handle<String> name) { |
| 361 HandleScope scope; | 400 HandleScope scope; |
| 362 Handle<Object> type_handle = Factory::NewStringFromAscii(CStrVector(type)); | 401 Handle<Object> type_handle = Factory::NewStringFromAscii(CStrVector(type)); |
| 363 Handle<Object> args[2] = { type_handle, name }; | 402 Handle<Object> args[2] = { type_handle, name }; |
| 364 Handle<Object> error = | 403 Handle<Object> error = |
| 365 Factory::NewTypeError("redeclaration", HandleVector(args, 2)); | 404 Factory::NewTypeError("redeclaration", HandleVector(args, 2)); |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 718 Handle<Object> value(args[0]); | 757 Handle<Object> value(args[0]); |
| 719 ASSERT(!value->IsTheHole()); | 758 ASSERT(!value->IsTheHole()); |
| 720 CONVERT_ARG_CHECKED(Context, context, 1); | 759 CONVERT_ARG_CHECKED(Context, context, 1); |
| 721 Handle<String> name(String::cast(args[2])); | 760 Handle<String> name(String::cast(args[2])); |
| 722 | 761 |
| 723 // Initializations are always done in the function context. | 762 // Initializations are always done in the function context. |
| 724 context = Handle<Context>(context->fcontext()); | 763 context = Handle<Context>(context->fcontext()); |
| 725 | 764 |
| 726 int index; | 765 int index; |
| 727 PropertyAttributes attributes; | 766 PropertyAttributes attributes; |
| 728 ContextLookupFlags flags = DONT_FOLLOW_CHAINS; | 767 ContextLookupFlags flags = FOLLOW_CHAINS; |
| 729 Handle<Object> holder = | 768 Handle<Object> holder = |
| 730 context->Lookup(name, flags, &index, &attributes); | 769 context->Lookup(name, flags, &index, &attributes); |
| 731 | 770 |
| 732 // The property should always be present. It is always declared | 771 // In most situations, the property introduced by the const |
| 733 // before being initialized through DeclareContextSlot. | 772 // declaration should be present in the context extension object. |
| 734 ASSERT(attributes != ABSENT && (attributes & READ_ONLY) != 0); | 773 // However, because declaration and initialization are separate, the |
| 735 | 774 // property might have been deleted (if it was introduced by eval) |
| 736 // If the slot is in the context, we set it but only if it hasn't | 775 // before we reach the initialization point. |
| 737 // been set before. | 776 // |
| 777 // Example: |
| 778 // |
| 779 // function f() { eval("delete x; const x;"); } |
| 780 // |
| 781 // In that case, the initialization behaves like a normal assignment |
| 782 // to property 'x'. |
| 738 if (index >= 0) { | 783 if (index >= 0) { |
| 739 // The constant context slot should always be in the function | 784 // Property was found in a context. |
| 740 // context; not in any outer context nor in the arguments object. | 785 if (holder->IsContext()) { |
| 741 ASSERT(holder.is_identical_to(context)); | 786 // The holder cannot be the function context. If it is, there |
| 742 if (context->get(index)->IsTheHole()) { | 787 // should have been a const redeclaration error when declaring |
| 743 context->set(index, *value); | 788 // the const property. |
| 789 ASSERT(!holder.is_identical_to(context)); |
| 790 if ((attributes & READ_ONLY) == 0) { |
| 791 Handle<Context>::cast(holder)->set(index, *value); |
| 792 } |
| 793 } else { |
| 794 // The holder is an arguments object. |
| 795 ASSERT((attributes & READ_ONLY) == 0); |
| 796 Handle<JSObject>::cast(holder)->SetElement(index, *value); |
| 744 } | 797 } |
| 745 return *value; | 798 return *value; |
| 746 } | 799 } |
| 747 | 800 |
| 748 // Otherwise, the slot must be in a JS object extension. | 801 // The property could not be found, we introduce it in the global |
| 749 Handle<JSObject> context_ext(JSObject::cast(*holder)); | 802 // context. |
| 803 if (attributes == ABSENT) { |
| 804 Handle<JSObject> global = Handle<JSObject>(Top::context()->global()); |
| 805 SetProperty(global, name, value, NONE); |
| 806 return *value; |
| 807 } |
| 750 | 808 |
| 751 // We must initialize the value only if it wasn't initialized | 809 // The property was present in a context extension object. |
| 752 // before, e.g. for const declarations in a loop. The property has | 810 Handle<JSObject> context_ext = Handle<JSObject>::cast(holder); |
| 753 // the hole value if it wasn't initialized yet. NOTE: We cannot use | |
| 754 // GetProperty() to get the current value as it 'unholes' the value. | |
| 755 LookupResult lookup; | |
| 756 context_ext->LocalLookupRealNamedProperty(*name, &lookup); | |
| 757 ASSERT(lookup.IsProperty()); // the property was declared | |
| 758 ASSERT(lookup.IsReadOnly()); // and it was declared as read-only | |
| 759 | 811 |
| 760 PropertyType type = lookup.type(); | 812 if (*context_ext == context->extension()) { |
| 761 if (type == FIELD) { | 813 // This is the property that was introduced by the const |
| 762 FixedArray* properties = context_ext->properties(); | 814 // declaration. Set it if it hasn't been set before. NOTE: We |
| 763 int index = lookup.GetFieldIndex(); | 815 // cannot use GetProperty() to get the current value as it |
| 764 if (properties->get(index)->IsTheHole()) { | 816 // 'unholes' the value. |
| 765 properties->set(index, *value); | 817 LookupResult lookup; |
| 766 } | 818 context_ext->LocalLookupRealNamedProperty(*name, &lookup); |
| 767 } else if (type == NORMAL) { | 819 ASSERT(lookup.IsProperty()); // the property was declared |
| 768 Dictionary* dictionary = context_ext->property_dictionary(); | 820 ASSERT(lookup.IsReadOnly()); // and it was declared as read-only |
| 769 int entry = lookup.GetDictionaryEntry(); | 821 |
| 770 if (dictionary->ValueAt(entry)->IsTheHole()) { | 822 PropertyType type = lookup.type(); |
| 771 dictionary->ValueAtPut(entry, *value); | 823 if (type == FIELD) { |
| 824 FixedArray* properties = context_ext->properties(); |
| 825 int index = lookup.GetFieldIndex(); |
| 826 if (properties->get(index)->IsTheHole()) { |
| 827 properties->set(index, *value); |
| 828 } |
| 829 } else if (type == NORMAL) { |
| 830 Dictionary* dictionary = context_ext->property_dictionary(); |
| 831 int entry = lookup.GetDictionaryEntry(); |
| 832 if (dictionary->ValueAt(entry)->IsTheHole()) { |
| 833 dictionary->ValueAtPut(entry, *value); |
| 834 } |
| 835 } else { |
| 836 // We should not reach here. Any real, named property should be |
| 837 // either a field or a dictionary slot. |
| 838 UNREACHABLE(); |
| 772 } | 839 } |
| 773 } else { | 840 } else { |
| 774 // We should not reach here. Any real, named property should be | 841 // The property was found in a different context extension object. |
| 775 // either a field or a dictionary slot. | 842 // Set it if it is not a read-only property. |
| 776 UNREACHABLE(); | 843 if ((attributes & READ_ONLY) == 0) { |
| 844 Handle<Object> set = SetProperty(context_ext, name, value, attributes); |
| 845 // Setting a property might throw an exception. Exceptions |
| 846 // are converted to empty handles in handle operations. We |
| 847 // need to convert back to exceptions here. |
| 848 if (set.is_null()) { |
| 849 ASSERT(Top::has_pending_exception()); |
| 850 return Failure::Exception(); |
| 851 } |
| 852 } |
| 777 } | 853 } |
| 854 |
| 778 return *value; | 855 return *value; |
| 779 } | 856 } |
| 780 | 857 |
| 781 | 858 |
| 782 static Object* Runtime_RegExpExec(Arguments args) { | 859 static Object* Runtime_RegExpExec(Arguments args) { |
| 783 HandleScope scope; | 860 HandleScope scope; |
| 784 ASSERT(args.length() == 3); | 861 ASSERT(args.length() == 3); |
| 785 CONVERT_CHECKED(JSRegExp, raw_regexp, args[0]); | 862 CONVERT_CHECKED(JSRegExp, raw_regexp, args[0]); |
| 786 Handle<JSRegExp> regexp(raw_regexp); | 863 Handle<JSRegExp> regexp(raw_regexp); |
| 787 CONVERT_CHECKED(String, raw_subject, args[1]); | 864 CONVERT_CHECKED(String, raw_subject, args[1]); |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 return *target; | 1059 return *target; |
| 983 } | 1060 } |
| 984 | 1061 |
| 985 | 1062 |
| 986 static Object* CharCodeAt(String* subject, Object* index) { | 1063 static Object* CharCodeAt(String* subject, Object* index) { |
| 987 uint32_t i = 0; | 1064 uint32_t i = 0; |
| 988 if (!Array::IndexFromObject(index, &i)) return Heap::nan_value(); | 1065 if (!Array::IndexFromObject(index, &i)) return Heap::nan_value(); |
| 989 // Flatten the string. If someone wants to get a char at an index | 1066 // Flatten the string. If someone wants to get a char at an index |
| 990 // in a cons string, it is likely that more indices will be | 1067 // in a cons string, it is likely that more indices will be |
| 991 // accessed. | 1068 // accessed. |
| 992 subject->TryFlatten(StringShape(subject)); | 1069 subject->TryFlattenIfNotFlat(StringShape(subject)); |
| 993 StringShape shape(subject); | 1070 StringShape shape(subject); |
| 994 if (i >= static_cast<uint32_t>(subject->length(shape))) { | 1071 if (i >= static_cast<uint32_t>(subject->length(shape))) { |
| 995 return Heap::nan_value(); | 1072 return Heap::nan_value(); |
| 996 } | 1073 } |
| 997 return Smi::FromInt(subject->Get(shape, i)); | 1074 return Smi::FromInt(subject->Get(shape, i)); |
| 998 } | 1075 } |
| 999 | 1076 |
| 1000 | 1077 |
| 1001 static Object* Runtime_StringCharCodeAt(Arguments args) { | 1078 static Object* Runtime_StringCharCodeAt(Arguments args) { |
| 1002 NoHandleAllocation ha; | 1079 NoHandleAllocation ha; |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1453 | 1530 |
| 1454 | 1531 |
| 1455 static Object* Runtime_StringLastIndexOf(Arguments args) { | 1532 static Object* Runtime_StringLastIndexOf(Arguments args) { |
| 1456 NoHandleAllocation ha; | 1533 NoHandleAllocation ha; |
| 1457 ASSERT(args.length() == 3); | 1534 ASSERT(args.length() == 3); |
| 1458 | 1535 |
| 1459 CONVERT_CHECKED(String, sub, args[0]); | 1536 CONVERT_CHECKED(String, sub, args[0]); |
| 1460 CONVERT_CHECKED(String, pat, args[1]); | 1537 CONVERT_CHECKED(String, pat, args[1]); |
| 1461 Object* index = args[2]; | 1538 Object* index = args[2]; |
| 1462 | 1539 |
| 1463 sub->TryFlatten(StringShape(sub)); | 1540 sub->TryFlattenIfNotFlat(StringShape(sub)); |
| 1464 pat->TryFlatten(StringShape(pat)); | 1541 pat->TryFlattenIfNotFlat(StringShape(pat)); |
| 1465 | 1542 |
| 1466 StringShape sub_shape(sub); | 1543 StringShape sub_shape(sub); |
| 1467 StringShape pat_shape(pat); | 1544 StringShape pat_shape(pat); |
| 1468 | 1545 |
| 1469 uint32_t start_index; | 1546 uint32_t start_index; |
| 1470 if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1); | 1547 if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1); |
| 1471 | 1548 |
| 1472 uint32_t pattern_length = pat->length(pat_shape); | 1549 uint32_t pattern_length = pat->length(pat_shape); |
| 1473 uint32_t sub_length = sub->length(sub_shape); | 1550 uint32_t sub_length = sub->length(sub_shape); |
| 1474 | 1551 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1513 } | 1590 } |
| 1514 | 1591 |
| 1515 int end = str1_length < str2_length ? str1_length : str2_length; | 1592 int end = str1_length < str2_length ? str1_length : str2_length; |
| 1516 | 1593 |
| 1517 // No need to flatten if we are going to find the answer on the first | 1594 // No need to flatten if we are going to find the answer on the first |
| 1518 // character. At this point we know there is at least one character | 1595 // character. At this point we know there is at least one character |
| 1519 // in each string, due to the trivial case handling above. | 1596 // in each string, due to the trivial case handling above. |
| 1520 int d = str1->Get(shape1, 0) - str2->Get(shape2, 0); | 1597 int d = str1->Get(shape1, 0) - str2->Get(shape2, 0); |
| 1521 if (d != 0) return Smi::FromInt(d); | 1598 if (d != 0) return Smi::FromInt(d); |
| 1522 | 1599 |
| 1523 str1->TryFlatten(shape1); // Shapes are no longer valid now! | 1600 str1->TryFlattenIfNotFlat(shape1); // Shapes are no longer valid now! |
| 1524 str2->TryFlatten(shape2); | 1601 str2->TryFlattenIfNotFlat(shape2); |
| 1525 | 1602 |
| 1526 static StringInputBuffer buf1; | 1603 static StringInputBuffer buf1; |
| 1527 static StringInputBuffer buf2; | 1604 static StringInputBuffer buf2; |
| 1528 | 1605 |
| 1529 buf1.Reset(str1); | 1606 buf1.Reset(str1); |
| 1530 buf2.Reset(str2); | 1607 buf2.Reset(str2); |
| 1531 | 1608 |
| 1532 for (int i = 0; i < end; i++) { | 1609 for (int i = 0; i < end; i++) { |
| 1533 uint16_t char1 = buf1.GetNext(); | 1610 uint16_t char1 = buf1.GetNext(); |
| 1534 uint16_t char2 = buf2.GetNext(); | 1611 uint16_t char2 = buf2.GetNext(); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1651 DeleteArray(str); | 1728 DeleteArray(str); |
| 1652 return res; | 1729 return res; |
| 1653 } | 1730 } |
| 1654 | 1731 |
| 1655 | 1732 |
| 1656 // Returns a single character string where first character equals | 1733 // Returns a single character string where first character equals |
| 1657 // string->Get(index). | 1734 // string->Get(index). |
| 1658 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) { | 1735 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) { |
| 1659 StringShape shape(*string); | 1736 StringShape shape(*string); |
| 1660 if (index < static_cast<uint32_t>(string->length(shape))) { | 1737 if (index < static_cast<uint32_t>(string->length(shape))) { |
| 1661 string->TryFlatten(shape); // Invalidates shape! | 1738 string->TryFlattenIfNotFlat(shape); // Invalidates shape! |
| 1662 return LookupSingleCharacterStringFromCode( | 1739 return LookupSingleCharacterStringFromCode( |
| 1663 string->Get(StringShape(*string), index)); | 1740 string->Get(StringShape(*string), index)); |
| 1664 } | 1741 } |
| 1665 return Execution::CharAt(string, index); | 1742 return Execution::CharAt(string, index); |
| 1666 } | 1743 } |
| 1667 | 1744 |
| 1668 | 1745 |
| 1669 Object* Runtime::GetElementOrCharAt(Handle<Object> object, uint32_t index) { | 1746 Object* Runtime::GetElementOrCharAt(Handle<Object> object, uint32_t index) { |
| 1670 // Handle [] indexing on Strings | 1747 // Handle [] indexing on Strings |
| 1671 if (object->IsString()) { | 1748 if (object->IsString()) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1712 if (key->IsString()) { | 1789 if (key->IsString()) { |
| 1713 name = Handle<String>::cast(key); | 1790 name = Handle<String>::cast(key); |
| 1714 } else { | 1791 } else { |
| 1715 bool has_pending_exception = false; | 1792 bool has_pending_exception = false; |
| 1716 Handle<Object> converted = | 1793 Handle<Object> converted = |
| 1717 Execution::ToString(key, &has_pending_exception); | 1794 Execution::ToString(key, &has_pending_exception); |
| 1718 if (has_pending_exception) return Failure::Exception(); | 1795 if (has_pending_exception) return Failure::Exception(); |
| 1719 name = Handle<String>::cast(converted); | 1796 name = Handle<String>::cast(converted); |
| 1720 } | 1797 } |
| 1721 | 1798 |
| 1722 // Check if the name is trivially convertable to an index and get | 1799 // Check if the name is trivially convertible to an index and get |
| 1723 // the element if so. | 1800 // the element if so. |
| 1724 if (name->AsArrayIndex(&index)) { | 1801 if (name->AsArrayIndex(&index)) { |
| 1725 return GetElementOrCharAt(object, index); | 1802 return GetElementOrCharAt(object, index); |
| 1726 } else { | 1803 } else { |
| 1727 PropertyAttributes attr; | 1804 PropertyAttributes attr; |
| 1728 return object->GetProperty(*name, &attr); | 1805 return object->GetProperty(*name, &attr); |
| 1729 } | 1806 } |
| 1730 } | 1807 } |
| 1731 | 1808 |
| 1732 | 1809 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1744 | 1821 |
| 1745 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric. | 1822 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric. |
| 1746 static Object* Runtime_KeyedGetProperty(Arguments args) { | 1823 static Object* Runtime_KeyedGetProperty(Arguments args) { |
| 1747 NoHandleAllocation ha; | 1824 NoHandleAllocation ha; |
| 1748 ASSERT(args.length() == 2); | 1825 ASSERT(args.length() == 2); |
| 1749 | 1826 |
| 1750 // Fast cases for getting named properties of the receiver JSObject | 1827 // Fast cases for getting named properties of the receiver JSObject |
| 1751 // itself. | 1828 // itself. |
| 1752 // | 1829 // |
| 1753 // The global proxy objects has to be excluded since LocalLookup on | 1830 // The global proxy objects has to be excluded since LocalLookup on |
| 1754 // the global proxy object can return a valid result eventhough the | 1831 // the global proxy object can return a valid result even though the |
| 1755 // global proxy object never has properties. This is the case | 1832 // global proxy object never has properties. This is the case |
| 1756 // because the global proxy object forwards everything to its hidden | 1833 // because the global proxy object forwards everything to its hidden |
| 1757 // prototype including local lookups. | 1834 // prototype including local lookups. |
| 1758 // | 1835 // |
| 1759 // Additionally, we need to make sure that we do not cache results | 1836 // Additionally, we need to make sure that we do not cache results |
| 1760 // for objects that require access checks. | 1837 // for objects that require access checks. |
| 1761 if (args[0]->IsJSObject() && | 1838 if (args[0]->IsJSObject() && |
| 1762 !args[0]->IsJSGlobalProxy() && | 1839 !args[0]->IsJSGlobalProxy() && |
| 1763 !args[0]->IsAccessCheckNeeded() && | 1840 !args[0]->IsAccessCheckNeeded() && |
| 1764 args[1]->IsString()) { | 1841 args[1]->IsString()) { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1844 return *value; | 1921 return *value; |
| 1845 } | 1922 } |
| 1846 | 1923 |
| 1847 if (key->IsString()) { | 1924 if (key->IsString()) { |
| 1848 Handle<Object> result; | 1925 Handle<Object> result; |
| 1849 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { | 1926 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { |
| 1850 ASSERT(attr == NONE); | 1927 ASSERT(attr == NONE); |
| 1851 result = SetElement(js_object, index, value); | 1928 result = SetElement(js_object, index, value); |
| 1852 } else { | 1929 } else { |
| 1853 Handle<String> key_string = Handle<String>::cast(key); | 1930 Handle<String> key_string = Handle<String>::cast(key); |
| 1854 key_string->TryFlatten(StringShape(*key_string)); | 1931 key_string->TryFlattenIfNotFlat(StringShape(*key_string)); |
| 1855 result = SetProperty(js_object, key_string, value, attr); | 1932 result = SetProperty(js_object, key_string, value, attr); |
| 1856 } | 1933 } |
| 1857 if (result.is_null()) return Failure::Exception(); | 1934 if (result.is_null()) return Failure::Exception(); |
| 1858 return *value; | 1935 return *value; |
| 1859 } | 1936 } |
| 1860 | 1937 |
| 1861 // Call-back into JavaScript to convert the key to a string. | 1938 // Call-back into JavaScript to convert the key to a string. |
| 1862 bool has_pending_exception = false; | 1939 bool has_pending_exception = false; |
| 1863 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); | 1940 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); |
| 1864 if (has_pending_exception) return Failure::Exception(); | 1941 if (has_pending_exception) return Failure::Exception(); |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2116 // host objects gives that it is okay to return "object" | 2193 // host objects gives that it is okay to return "object" |
| 2117 return Heap::object_symbol(); | 2194 return Heap::object_symbol(); |
| 2118 } | 2195 } |
| 2119 } | 2196 } |
| 2120 | 2197 |
| 2121 | 2198 |
| 2122 static Object* Runtime_StringToNumber(Arguments args) { | 2199 static Object* Runtime_StringToNumber(Arguments args) { |
| 2123 NoHandleAllocation ha; | 2200 NoHandleAllocation ha; |
| 2124 ASSERT(args.length() == 1); | 2201 ASSERT(args.length() == 1); |
| 2125 CONVERT_CHECKED(String, subject, args[0]); | 2202 CONVERT_CHECKED(String, subject, args[0]); |
| 2126 subject->TryFlatten(StringShape(subject)); | 2203 subject->TryFlattenIfNotFlat(StringShape(subject)); |
| 2127 return Heap::NumberFromDouble(StringToDouble(subject, ALLOW_HEX)); | 2204 return Heap::NumberFromDouble(StringToDouble(subject, ALLOW_HEX)); |
| 2128 } | 2205 } |
| 2129 | 2206 |
| 2130 | 2207 |
| 2131 static Object* Runtime_StringFromCharCodeArray(Arguments args) { | 2208 static Object* Runtime_StringFromCharCodeArray(Arguments args) { |
| 2132 NoHandleAllocation ha; | 2209 NoHandleAllocation ha; |
| 2133 ASSERT(args.length() == 1); | 2210 ASSERT(args.length() == 1); |
| 2134 | 2211 |
| 2135 CONVERT_CHECKED(JSArray, codes, args[0]); | 2212 CONVERT_CHECKED(JSArray, codes, args[0]); |
| 2136 int length = Smi::cast(codes->length())->value(); | 2213 int length = Smi::cast(codes->length())->value(); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2199 return kNotEscaped[character] != 0; | 2276 return kNotEscaped[character] != 0; |
| 2200 } | 2277 } |
| 2201 | 2278 |
| 2202 | 2279 |
| 2203 static Object* Runtime_URIEscape(Arguments args) { | 2280 static Object* Runtime_URIEscape(Arguments args) { |
| 2204 const char hex_chars[] = "0123456789ABCDEF"; | 2281 const char hex_chars[] = "0123456789ABCDEF"; |
| 2205 NoHandleAllocation ha; | 2282 NoHandleAllocation ha; |
| 2206 ASSERT(args.length() == 1); | 2283 ASSERT(args.length() == 1); |
| 2207 CONVERT_CHECKED(String, source, args[0]); | 2284 CONVERT_CHECKED(String, source, args[0]); |
| 2208 | 2285 |
| 2209 source->TryFlatten(StringShape(source)); | 2286 source->TryFlattenIfNotFlat(StringShape(source)); |
| 2210 | 2287 |
| 2211 int escaped_length = 0; | 2288 int escaped_length = 0; |
| 2212 int length = source->length(); | 2289 int length = source->length(); |
| 2213 { | 2290 { |
| 2214 Access<StringInputBuffer> buffer(&string_input_buffer); | 2291 Access<StringInputBuffer> buffer(&string_input_buffer); |
| 2215 buffer->Reset(source); | 2292 buffer->Reset(source); |
| 2216 while (buffer->has_more()) { | 2293 while (buffer->has_more()) { |
| 2217 uint16_t character = buffer->GetNext(); | 2294 uint16_t character = buffer->GetNext(); |
| 2218 if (character >= 256) { | 2295 if (character >= 256) { |
| 2219 escaped_length += 6; | 2296 escaped_length += 6; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2313 return character; | 2390 return character; |
| 2314 } | 2391 } |
| 2315 } | 2392 } |
| 2316 | 2393 |
| 2317 | 2394 |
| 2318 static Object* Runtime_URIUnescape(Arguments args) { | 2395 static Object* Runtime_URIUnescape(Arguments args) { |
| 2319 NoHandleAllocation ha; | 2396 NoHandleAllocation ha; |
| 2320 ASSERT(args.length() == 1); | 2397 ASSERT(args.length() == 1); |
| 2321 CONVERT_CHECKED(String, source, args[0]); | 2398 CONVERT_CHECKED(String, source, args[0]); |
| 2322 | 2399 |
| 2323 source->TryFlatten(StringShape(source)); | 2400 source->TryFlattenIfNotFlat(StringShape(source)); |
| 2324 StringShape source_shape(source); | 2401 StringShape source_shape(source); |
| 2325 | 2402 |
| 2326 bool ascii = true; | 2403 bool ascii = true; |
| 2327 int length = source->length(source_shape); | 2404 int length = source->length(source_shape); |
| 2328 | 2405 |
| 2329 int unescaped_length = 0; | 2406 int unescaped_length = 0; |
| 2330 for (int i = 0; i < length; unescaped_length++) { | 2407 for (int i = 0; i < length; unescaped_length++) { |
| 2331 int step; | 2408 int step; |
| 2332 if (Unescape(source, | 2409 if (Unescape(source, |
| 2333 source_shape, | 2410 source_shape, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2362 } | 2439 } |
| 2363 | 2440 |
| 2364 | 2441 |
| 2365 static Object* Runtime_StringParseInt(Arguments args) { | 2442 static Object* Runtime_StringParseInt(Arguments args) { |
| 2366 NoHandleAllocation ha; | 2443 NoHandleAllocation ha; |
| 2367 | 2444 |
| 2368 CONVERT_CHECKED(String, s, args[0]); | 2445 CONVERT_CHECKED(String, s, args[0]); |
| 2369 CONVERT_DOUBLE_CHECKED(n, args[1]); | 2446 CONVERT_DOUBLE_CHECKED(n, args[1]); |
| 2370 int radix = FastD2I(n); | 2447 int radix = FastD2I(n); |
| 2371 | 2448 |
| 2372 s->TryFlatten(StringShape(s)); | 2449 s->TryFlattenIfNotFlat(StringShape(s)); |
| 2373 | 2450 |
| 2374 StringShape shape(s); | 2451 StringShape shape(s); |
| 2375 | 2452 |
| 2376 int len = s->length(shape); | 2453 int len = s->length(shape); |
| 2377 int i; | 2454 int i; |
| 2378 | 2455 |
| 2379 // Skip leading white space. | 2456 // Skip leading white space. |
| 2380 for (i = 0; i < len && Scanner::kIsWhiteSpace.get(s->Get(shape, i)); i++) ; | 2457 for (i = 0; i < len && Scanner::kIsWhiteSpace.get(s->Get(shape, i)); i++) ; |
| 2381 if (i == len) return Heap::nan_value(); | 2458 if (i == len) return Heap::nan_value(); |
| 2382 | 2459 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2435 static unibrow::Mapping<unibrow::ToUppercase, 128> to_upper_mapping; | 2512 static unibrow::Mapping<unibrow::ToUppercase, 128> to_upper_mapping; |
| 2436 static unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping; | 2513 static unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping; |
| 2437 | 2514 |
| 2438 | 2515 |
| 2439 template <class Converter> | 2516 template <class Converter> |
| 2440 static Object* ConvertCase(Arguments args, | 2517 static Object* ConvertCase(Arguments args, |
| 2441 unibrow::Mapping<Converter, 128>* mapping) { | 2518 unibrow::Mapping<Converter, 128>* mapping) { |
| 2442 NoHandleAllocation ha; | 2519 NoHandleAllocation ha; |
| 2443 | 2520 |
| 2444 CONVERT_CHECKED(String, s, args[0]); | 2521 CONVERT_CHECKED(String, s, args[0]); |
| 2445 s->TryFlatten(StringShape(s)); | 2522 s->TryFlattenIfNotFlat(StringShape(s)); |
| 2446 StringShape shape(s); | 2523 StringShape shape(s); |
| 2447 | 2524 |
| 2448 int raw_string_length = s->length(shape); | 2525 int raw_string_length = s->length(shape); |
| 2449 // Assume that the string is not empty; we need this assumption later | 2526 // Assume that the string is not empty; we need this assumption later |
| 2450 if (raw_string_length == 0) return s; | 2527 if (raw_string_length == 0) return s; |
| 2451 int length = raw_string_length; | 2528 int length = raw_string_length; |
| 2452 | 2529 |
| 2453 | 2530 |
| 2454 // We try this twice, once with the assumption that the result is | 2531 // We try this twice, once with the assumption that the result is |
| 2455 // no longer than the input and, if that assumption breaks, again | 2532 // no longer than the input and, if that assumption breaks, again |
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2980 int x_value = x->value(); | 3057 int x_value = x->value(); |
| 2981 int y_value = y->value(); | 3058 int y_value = y->value(); |
| 2982 | 3059 |
| 2983 // If the integers are equal so are the string representations. | 3060 // If the integers are equal so are the string representations. |
| 2984 if (x_value == y_value) return Smi::FromInt(EQUAL); | 3061 if (x_value == y_value) return Smi::FromInt(EQUAL); |
| 2985 | 3062 |
| 2986 // If one of the integers are zero the normal integer order is the | 3063 // If one of the integers are zero the normal integer order is the |
| 2987 // same as the lexicographic order of the string representations. | 3064 // same as the lexicographic order of the string representations. |
| 2988 if (x_value == 0 || y_value == 0) return Smi::FromInt(x_value - y_value); | 3065 if (x_value == 0 || y_value == 0) return Smi::FromInt(x_value - y_value); |
| 2989 | 3066 |
| 2990 // If only one of the intergers is negative the negative number is | 3067 // If only one of the integers is negative the negative number is |
| 2991 // smallest because the char code of '-' is less than the char code | 3068 // smallest because the char code of '-' is less than the char code |
| 2992 // of any digit. Otherwise, we make both values positive. | 3069 // of any digit. Otherwise, we make both values positive. |
| 2993 if (x_value < 0 || y_value < 0) { | 3070 if (x_value < 0 || y_value < 0) { |
| 2994 if (y_value >= 0) return Smi::FromInt(LESS); | 3071 if (y_value >= 0) return Smi::FromInt(LESS); |
| 2995 if (x_value >= 0) return Smi::FromInt(GREATER); | 3072 if (x_value >= 0) return Smi::FromInt(GREATER); |
| 2996 x_value = -x_value; | 3073 x_value = -x_value; |
| 2997 y_value = -y_value; | 3074 y_value = -y_value; |
| 2998 } | 3075 } |
| 2999 | 3076 |
| 3000 // Convert the integers to arrays of their decimal digits. | 3077 // Convert the integers to arrays of their decimal digits. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3039 if (x->length(x_shape) == 0) return Smi::FromInt(EQUAL); | 3116 if (x->length(x_shape) == 0) return Smi::FromInt(EQUAL); |
| 3040 return Smi::FromInt(GREATER); | 3117 return Smi::FromInt(GREATER); |
| 3041 } else if (x->length(x_shape) == 0) { | 3118 } else if (x->length(x_shape) == 0) { |
| 3042 return Smi::FromInt(LESS); | 3119 return Smi::FromInt(LESS); |
| 3043 } | 3120 } |
| 3044 | 3121 |
| 3045 int d = x->Get(x_shape, 0) - y->Get(y_shape, 0); | 3122 int d = x->Get(x_shape, 0) - y->Get(y_shape, 0); |
| 3046 if (d < 0) return Smi::FromInt(LESS); | 3123 if (d < 0) return Smi::FromInt(LESS); |
| 3047 else if (d > 0) return Smi::FromInt(GREATER); | 3124 else if (d > 0) return Smi::FromInt(GREATER); |
| 3048 | 3125 |
| 3049 x->TryFlatten(x_shape); // Shapes are no longer valid! | 3126 x->TryFlattenIfNotFlat(x_shape); // Shapes are no longer valid! |
| 3050 y->TryFlatten(y_shape); | 3127 y->TryFlattenIfNotFlat(y_shape); |
| 3051 | 3128 |
| 3052 static StringInputBuffer bufx; | 3129 static StringInputBuffer bufx; |
| 3053 static StringInputBuffer bufy; | 3130 static StringInputBuffer bufy; |
| 3054 bufx.Reset(x); | 3131 bufx.Reset(x); |
| 3055 bufy.Reset(y); | 3132 bufy.Reset(y); |
| 3056 while (bufx.has_more() && bufy.has_more()) { | 3133 while (bufx.has_more() && bufy.has_more()) { |
| 3057 int d = bufx.GetNext() - bufy.GetNext(); | 3134 int d = bufx.GetNext() - bufy.GetNext(); |
| 3058 if (d < 0) return Smi::FromInt(LESS); | 3135 if (d < 0) return Smi::FromInt(LESS); |
| 3059 else if (d > 0) return Smi::FromInt(GREATER); | 3136 else if (d > 0) return Smi::FromInt(GREATER); |
| 3060 } | 3137 } |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3318 | 3395 |
| 3319 | 3396 |
| 3320 static Object* Runtime_NewObject(Arguments args) { | 3397 static Object* Runtime_NewObject(Arguments args) { |
| 3321 NoHandleAllocation ha; | 3398 NoHandleAllocation ha; |
| 3322 ASSERT(args.length() == 1); | 3399 ASSERT(args.length() == 1); |
| 3323 | 3400 |
| 3324 Object* constructor = args[0]; | 3401 Object* constructor = args[0]; |
| 3325 if (constructor->IsJSFunction()) { | 3402 if (constructor->IsJSFunction()) { |
| 3326 JSFunction* function = JSFunction::cast(constructor); | 3403 JSFunction* function = JSFunction::cast(constructor); |
| 3327 | 3404 |
| 3328 // Handle steping into constructors if step into is active. | 3405 // Handle stepping into constructors if step into is active. |
| 3329 if (Debug::StepInActive()) { | 3406 if (Debug::StepInActive()) { |
| 3330 HandleScope scope; | 3407 HandleScope scope; |
| 3331 Debug::HandleStepIn(Handle<JSFunction>(function), 0, true); | 3408 Debug::HandleStepIn(Handle<JSFunction>(function), 0, true); |
| 3332 } | 3409 } |
| 3333 | 3410 |
| 3334 if (function->has_initial_map() && | 3411 if (function->has_initial_map() && |
| 3335 function->initial_map()->instance_type() == JS_FUNCTION_TYPE) { | 3412 function->initial_map()->instance_type() == JS_FUNCTION_TYPE) { |
| 3336 // The 'Function' function ignores the receiver object when | 3413 // The 'Function' function ignores the receiver object when |
| 3337 // called using 'new' and creates a new JSFunction object that | 3414 // called using 'new' and creates a new JSFunction object that |
| 3338 // is returned. The receiver object is only used for error | 3415 // is returned. The receiver object is only used for error |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3694 static Object* Runtime_DebugBreak(Arguments args) { | 3771 static Object* Runtime_DebugBreak(Arguments args) { |
| 3695 ASSERT(args.length() == 0); | 3772 ASSERT(args.length() == 0); |
| 3696 return Execution::DebugBreakHelper(); | 3773 return Execution::DebugBreakHelper(); |
| 3697 } | 3774 } |
| 3698 | 3775 |
| 3699 | 3776 |
| 3700 static Object* Runtime_StackGuard(Arguments args) { | 3777 static Object* Runtime_StackGuard(Arguments args) { |
| 3701 ASSERT(args.length() == 1); | 3778 ASSERT(args.length() == 1); |
| 3702 | 3779 |
| 3703 // First check if this is a real stack overflow. | 3780 // First check if this is a real stack overflow. |
| 3704 if (StackGuard::IsStackOverflow()) return Runtime_StackOverflow(args); | 3781 if (StackGuard::IsStackOverflow()) { |
| 3782 return Runtime_StackOverflow(args); |
| 3783 } |
| 3705 | 3784 |
| 3706 return Execution::HandleStackGuardInterrupt(); | 3785 return Execution::HandleStackGuardInterrupt(); |
| 3707 } | 3786 } |
| 3708 | 3787 |
| 3709 | 3788 |
| 3710 // NOTE: These PrintXXX functions are defined for all builds (not just | 3789 // NOTE: These PrintXXX functions are defined for all builds (not just |
| 3711 // DEBUG builds) because we may want to be able to trace function | 3790 // DEBUG builds) because we may want to be able to trace function |
| 3712 // calls in all modes. | 3791 // calls in all modes. |
| 3713 static void PrintString(String* str) { | 3792 static void PrintString(String* str) { |
| 3714 // not uncommon to have empty strings | 3793 // not uncommon to have empty strings |
| (...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4496 } | 4575 } |
| 4497 | 4576 |
| 4498 | 4577 |
| 4499 static Object* Runtime_Break(Arguments args) { | 4578 static Object* Runtime_Break(Arguments args) { |
| 4500 ASSERT(args.length() == 0); | 4579 ASSERT(args.length() == 0); |
| 4501 StackGuard::DebugBreak(); | 4580 StackGuard::DebugBreak(); |
| 4502 return Heap::undefined_value(); | 4581 return Heap::undefined_value(); |
| 4503 } | 4582 } |
| 4504 | 4583 |
| 4505 | 4584 |
| 4506 static Object* DebugLookupResultValue(Object* obj, String* name, | 4585 // Find the length of the prototype chain that is to to handled as one. If a |
| 4507 LookupResult* result, | 4586 // prototype object is hidden it is to be viewed as part of the the object it |
| 4587 // is prototype for. |
| 4588 static int LocalPrototypeChainLength(JSObject* obj) { |
| 4589 int count = 1; |
| 4590 Object* proto = obj->GetPrototype(); |
| 4591 while (proto->IsJSObject() && |
| 4592 JSObject::cast(proto)->map()->is_hidden_prototype()) { |
| 4593 count++; |
| 4594 proto = JSObject::cast(proto)->GetPrototype(); |
| 4595 } |
| 4596 return count; |
| 4597 } |
| 4598 |
| 4599 |
| 4600 static Object* DebugLookupResultValue(Object* receiver, LookupResult* result, |
| 4508 bool* caught_exception) { | 4601 bool* caught_exception) { |
| 4602 Object* value; |
| 4509 switch (result->type()) { | 4603 switch (result->type()) { |
| 4510 case NORMAL: | 4604 case NORMAL: { |
| 4511 case FIELD: | 4605 Dictionary* dict = |
| 4512 case CONSTANT_FUNCTION: | 4606 JSObject::cast(result->holder())->property_dictionary(); |
| 4513 return obj->GetProperty(name); | 4607 value = dict->ValueAt(result->GetDictionaryEntry()); |
| 4514 case CALLBACKS: { | 4608 if (value->IsTheHole()) { |
| 4515 // Get the property value. If there is an exception it must be thown from | 4609 return Heap::undefined_value(); |
| 4516 // a JavaScript getter. | |
| 4517 Object* value; | |
| 4518 value = obj->GetProperty(name); | |
| 4519 if (value->IsException()) { | |
| 4520 if (caught_exception != NULL) { | |
| 4521 *caught_exception = true; | |
| 4522 } | |
| 4523 value = Top::pending_exception(); | |
| 4524 Top::optional_reschedule_exception(true); | |
| 4525 } | 4610 } |
| 4526 ASSERT(!Top::has_pending_exception()); | |
| 4527 ASSERT(!Top::external_caught_exception()); | |
| 4528 return value; | 4611 return value; |
| 4529 } | 4612 } |
| 4613 case FIELD: |
| 4614 value = |
| 4615 JSObject::cast( |
| 4616 result->holder())->FastPropertyAt(result->GetFieldIndex()); |
| 4617 if (value->IsTheHole()) { |
| 4618 return Heap::undefined_value(); |
| 4619 } |
| 4620 return value; |
| 4621 case CONSTANT_FUNCTION: |
| 4622 return result->GetConstantFunction(); |
| 4623 case CALLBACKS: { |
| 4624 Object* structure = result->GetCallbackObject(); |
| 4625 if (structure->IsProxy()) { |
| 4626 AccessorDescriptor* callback = |
| 4627 reinterpret_cast<AccessorDescriptor*>( |
| 4628 Proxy::cast(structure)->proxy()); |
| 4629 value = (callback->getter)(receiver, callback->data); |
| 4630 if (value->IsFailure()) { |
| 4631 value = Top::pending_exception(); |
| 4632 Top::clear_pending_exception(); |
| 4633 if (caught_exception != NULL) { |
| 4634 *caught_exception = true; |
| 4635 } |
| 4636 } |
| 4637 return value; |
| 4638 } else { |
| 4639 return Heap::undefined_value(); |
| 4640 } |
| 4641 } |
| 4530 case INTERCEPTOR: | 4642 case INTERCEPTOR: |
| 4531 return obj->GetProperty(name); | |
| 4532 case MAP_TRANSITION: | 4643 case MAP_TRANSITION: |
| 4533 case CONSTANT_TRANSITION: | 4644 case CONSTANT_TRANSITION: |
| 4534 case NULL_DESCRIPTOR: | 4645 case NULL_DESCRIPTOR: |
| 4535 return Heap::undefined_value(); | 4646 return Heap::undefined_value(); |
| 4536 default: | 4647 default: |
| 4537 UNREACHABLE(); | 4648 UNREACHABLE(); |
| 4538 } | 4649 } |
| 4539 UNREACHABLE(); | 4650 UNREACHABLE(); |
| 4540 return Heap::undefined_value(); | 4651 return Heap::undefined_value(); |
| 4541 } | 4652 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 4554 // Items 2-4 are only filled if the property has either a getter or a setter | 4665 // Items 2-4 are only filled if the property has either a getter or a setter |
| 4555 // defined through __defineGetter__ and/or __defineSetter__. | 4666 // defined through __defineGetter__ and/or __defineSetter__. |
| 4556 static Object* Runtime_DebugGetPropertyDetails(Arguments args) { | 4667 static Object* Runtime_DebugGetPropertyDetails(Arguments args) { |
| 4557 HandleScope scope; | 4668 HandleScope scope; |
| 4558 | 4669 |
| 4559 ASSERT(args.length() == 2); | 4670 ASSERT(args.length() == 2); |
| 4560 | 4671 |
| 4561 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 4672 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 4562 CONVERT_ARG_CHECKED(String, name, 1); | 4673 CONVERT_ARG_CHECKED(String, name, 1); |
| 4563 | 4674 |
| 4675 // Skip the global proxy as it has no properties and always delegates to the |
| 4676 // real global object. |
| 4677 if (obj->IsJSGlobalProxy()) { |
| 4678 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); |
| 4679 } |
| 4680 |
| 4681 |
| 4564 // Check if the name is trivially convertible to an index and get the element | 4682 // Check if the name is trivially convertible to an index and get the element |
| 4565 // if so. | 4683 // if so. |
| 4566 uint32_t index; | 4684 uint32_t index; |
| 4567 if (name->AsArrayIndex(&index)) { | 4685 if (name->AsArrayIndex(&index)) { |
| 4568 Handle<FixedArray> details = Factory::NewFixedArray(2); | 4686 Handle<FixedArray> details = Factory::NewFixedArray(2); |
| 4569 details->set(0, Runtime::GetElementOrCharAt(obj, index)); | 4687 details->set(0, Runtime::GetElementOrCharAt(obj, index)); |
| 4570 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); | 4688 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); |
| 4571 return *Factory::NewJSArrayWithElements(details); | 4689 return *Factory::NewJSArrayWithElements(details); |
| 4572 } | 4690 } |
| 4573 | 4691 |
| 4574 // Perform standard local lookup on the object. | 4692 // Find the number of objects making up this. |
| 4693 int length = LocalPrototypeChainLength(*obj); |
| 4694 |
| 4695 // Try local lookup on each of the objects. |
| 4575 LookupResult result; | 4696 LookupResult result; |
| 4576 obj->LocalLookup(*name, &result); | 4697 Handle<JSObject> jsproto = obj; |
| 4698 for (int i = 0; i < length; i++) { |
| 4699 jsproto->LocalLookup(*name, &result); |
| 4700 if (result.IsProperty()) { |
| 4701 break; |
| 4702 } |
| 4703 if (i < length - 1) { |
| 4704 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); |
| 4705 } |
| 4706 } |
| 4707 |
| 4577 if (result.IsProperty()) { | 4708 if (result.IsProperty()) { |
| 4578 bool caught_exception = false; | 4709 bool caught_exception = false; |
| 4579 Handle<Object> value(DebugLookupResultValue(*obj, *name, &result, | 4710 Handle<Object> value(DebugLookupResultValue(*obj, &result, |
| 4580 &caught_exception)); | 4711 &caught_exception)); |
| 4581 // If the callback object is a fixed array then it contains JavaScript | 4712 // If the callback object is a fixed array then it contains JavaScript |
| 4582 // getter and/or setter. | 4713 // getter and/or setter. |
| 4583 bool hasJavaScriptAccessors = result.type() == CALLBACKS && | 4714 bool hasJavaScriptAccessors = result.type() == CALLBACKS && |
| 4584 result.GetCallbackObject()->IsFixedArray(); | 4715 result.GetCallbackObject()->IsFixedArray(); |
| 4585 Handle<FixedArray> details = | 4716 Handle<FixedArray> details = |
| 4586 Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2); | 4717 Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2); |
| 4587 details->set(0, *value); | 4718 details->set(0, *value); |
| 4588 details->set(1, result.GetPropertyDetails().AsSmi()); | 4719 details->set(1, result.GetPropertyDetails().AsSmi()); |
| 4589 if (hasJavaScriptAccessors) { | 4720 if (hasJavaScriptAccessors) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 4603 HandleScope scope; | 4734 HandleScope scope; |
| 4604 | 4735 |
| 4605 ASSERT(args.length() == 2); | 4736 ASSERT(args.length() == 2); |
| 4606 | 4737 |
| 4607 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 4738 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 4608 CONVERT_ARG_CHECKED(String, name, 1); | 4739 CONVERT_ARG_CHECKED(String, name, 1); |
| 4609 | 4740 |
| 4610 LookupResult result; | 4741 LookupResult result; |
| 4611 obj->Lookup(*name, &result); | 4742 obj->Lookup(*name, &result); |
| 4612 if (result.IsProperty()) { | 4743 if (result.IsProperty()) { |
| 4613 return DebugLookupResultValue(*obj, *name, &result, NULL); | 4744 return DebugLookupResultValue(*obj, &result, NULL); |
| 4614 } | 4745 } |
| 4615 return Heap::undefined_value(); | 4746 return Heap::undefined_value(); |
| 4616 } | 4747 } |
| 4617 | 4748 |
| 4618 | 4749 |
| 4619 // Return the names of the local named properties. | 4750 // Return the names of the local named properties. |
| 4620 // args[0]: object | 4751 // args[0]: object |
| 4621 static Object* Runtime_DebugLocalPropertyNames(Arguments args) { | 4752 static Object* Runtime_DebugLocalPropertyNames(Arguments args) { |
| 4622 HandleScope scope; | 4753 HandleScope scope; |
| 4623 ASSERT(args.length() == 1); | 4754 ASSERT(args.length() == 1); |
| 4624 if (!args[0]->IsJSObject()) { | 4755 if (!args[0]->IsJSObject()) { |
| 4625 return Heap::undefined_value(); | 4756 return Heap::undefined_value(); |
| 4626 } | 4757 } |
| 4627 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 4758 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 4628 | 4759 |
| 4629 int n = obj->NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE)); | 4760 // Skip the global proxy as it has no properties and always delegates to the |
| 4630 Handle<FixedArray> names = Factory::NewFixedArray(n); | 4761 // real global object. |
| 4631 obj->GetLocalPropertyNames(*names); | 4762 if (obj->IsJSGlobalProxy()) { |
| 4763 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); |
| 4764 } |
| 4765 |
| 4766 // Find the number of objects making up this. |
| 4767 int length = LocalPrototypeChainLength(*obj); |
| 4768 |
| 4769 // Find the number of local properties for each of the objects. |
| 4770 int* local_property_count = NewArray<int>(length); |
| 4771 int total_property_count = 0; |
| 4772 Handle<JSObject> jsproto = obj; |
| 4773 for (int i = 0; i < length; i++) { |
| 4774 int n; |
| 4775 n = jsproto->NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE)); |
| 4776 local_property_count[i] = n; |
| 4777 total_property_count += n; |
| 4778 if (i < length - 1) { |
| 4779 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); |
| 4780 } |
| 4781 } |
| 4782 |
| 4783 // Allocate an array with storage for all the property names. |
| 4784 Handle<FixedArray> names = Factory::NewFixedArray(total_property_count); |
| 4785 |
| 4786 // Get the property names. |
| 4787 jsproto = obj; |
| 4788 for (int i = 0; i < length; i++) { |
| 4789 jsproto->GetLocalPropertyNames(*names, |
| 4790 i == 0 ? 0 : local_property_count[i - 1]); |
| 4791 if (i < length - 1) { |
| 4792 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); |
| 4793 } |
| 4794 } |
| 4795 |
| 4796 DeleteArray(local_property_count); |
| 4632 return *Factory::NewJSArrayWithElements(names); | 4797 return *Factory::NewJSArrayWithElements(names); |
| 4633 } | 4798 } |
| 4634 | 4799 |
| 4635 | 4800 |
| 4636 // Return the names of the local indexed properties. | 4801 // Return the names of the local indexed properties. |
| 4637 // args[0]: object | 4802 // args[0]: object |
| 4638 static Object* Runtime_DebugLocalElementNames(Arguments args) { | 4803 static Object* Runtime_DebugLocalElementNames(Arguments args) { |
| 4639 HandleScope scope; | 4804 HandleScope scope; |
| 4640 ASSERT(args.length() == 1); | 4805 ASSERT(args.length() == 1); |
| 4641 if (!args[0]->IsJSObject()) { | 4806 if (!args[0]->IsJSObject()) { |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5084 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(obj)); | 5249 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(obj)); |
| 5085 if (shared->script() == *script) { | 5250 if (shared->script() == *script) { |
| 5086 // If the SharedFunctionInfo found has the requested script data and | 5251 // If the SharedFunctionInfo found has the requested script data and |
| 5087 // contains the source position it is a candidate. | 5252 // contains the source position it is a candidate. |
| 5088 int start_position = shared->function_token_position(); | 5253 int start_position = shared->function_token_position(); |
| 5089 if (start_position == RelocInfo::kNoPosition) { | 5254 if (start_position == RelocInfo::kNoPosition) { |
| 5090 start_position = shared->start_position(); | 5255 start_position = shared->start_position(); |
| 5091 } | 5256 } |
| 5092 if (start_position <= position && | 5257 if (start_position <= position && |
| 5093 position <= shared->end_position()) { | 5258 position <= shared->end_position()) { |
| 5094 // If there is no candidate or this function is within the currrent | 5259 // If there is no candidate or this function is within the current |
| 5095 // candidate this is the new candidate. | 5260 // candidate this is the new candidate. |
| 5096 if (target.is_null()) { | 5261 if (target.is_null()) { |
| 5097 target_start_position = start_position; | 5262 target_start_position = start_position; |
| 5098 target = shared; | 5263 target = shared; |
| 5099 } else { | 5264 } else { |
| 5100 if (target_start_position < start_position && | 5265 if (target_start_position < start_position && |
| 5101 shared->end_position() < target->end_position()) { | 5266 shared->end_position() < target->end_position()) { |
| 5102 target_start_position = start_position; | 5267 target_start_position = start_position; |
| 5103 target = shared; | 5268 target = shared; |
| 5104 } | 5269 } |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5302 WriteBarrierMode mode = array->GetWriteBarrierMode(); | 5467 WriteBarrierMode mode = array->GetWriteBarrierMode(); |
| 5303 for (int i = 0; i < length; i++) { | 5468 for (int i = 0; i < length; i++) { |
| 5304 array->set(i, frame->GetParameter(i), mode); | 5469 array->set(i, frame->GetParameter(i), mode); |
| 5305 } | 5470 } |
| 5306 arguments->set_elements(*array); | 5471 arguments->set_elements(*array); |
| 5307 return arguments; | 5472 return arguments; |
| 5308 } | 5473 } |
| 5309 | 5474 |
| 5310 | 5475 |
| 5311 // Evaluate a piece of JavaScript in the context of a stack frame for | 5476 // Evaluate a piece of JavaScript in the context of a stack frame for |
| 5312 // debugging. This is acomplished by creating a new context which in its | 5477 // debugging. This is accomplished by creating a new context which in its |
| 5313 // extension part has all the parameters and locals of the function on the | 5478 // extension part has all the parameters and locals of the function on the |
| 5314 // stack frame. A function which calls eval with the code to evaluate is then | 5479 // stack frame. A function which calls eval with the code to evaluate is then |
| 5315 // compiled in this context and called in this context. As this context | 5480 // compiled in this context and called in this context. As this context |
| 5316 // replaces the context of the function on the stack frame a new (empty) | 5481 // replaces the context of the function on the stack frame a new (empty) |
| 5317 // function is created as well to be used as the closure for the context. | 5482 // function is created as well to be used as the closure for the context. |
| 5318 // This function and the context acts as replacements for the function on the | 5483 // This function and the context acts as replacements for the function on the |
| 5319 // stack frame presenting the same view of the values of parameters and | 5484 // stack frame presenting the same view of the values of parameters and |
| 5320 // local variables as if the piece of JavaScript was evaluated at the point | 5485 // local variables as if the piece of JavaScript was evaluated at the point |
| 5321 // where the function on the stack frame is currently stopped. | 5486 // where the function on the stack frame is currently stopped. |
| 5322 static Object* Runtime_DebugEvaluate(Arguments args) { | 5487 static Object* Runtime_DebugEvaluate(Arguments args) { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5413 // object build. | 5578 // object build. |
| 5414 Handle<Context> context = | 5579 Handle<Context> context = |
| 5415 Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, go_between); | 5580 Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, go_between); |
| 5416 context->set_extension(*context_ext); | 5581 context->set_extension(*context_ext); |
| 5417 // Copy any with contexts present and chain them in front of this context. | 5582 // Copy any with contexts present and chain them in front of this context. |
| 5418 context = CopyWithContextChain(frame_context, context); | 5583 context = CopyWithContextChain(frame_context, context); |
| 5419 | 5584 |
| 5420 // Wrap the evaluation statement in a new function compiled in the newly | 5585 // Wrap the evaluation statement in a new function compiled in the newly |
| 5421 // created context. The function has one parameter which has to be called | 5586 // created context. The function has one parameter which has to be called |
| 5422 // 'arguments'. This it to have access to what would have been 'arguments' in | 5587 // 'arguments'. This it to have access to what would have been 'arguments' in |
| 5423 // the function beeing debugged. | 5588 // the function being debugged. |
| 5424 // function(arguments,__source__) {return eval(__source__);} | 5589 // function(arguments,__source__) {return eval(__source__);} |
| 5425 static const char* source_str = | 5590 static const char* source_str = |
| 5426 "function(arguments,__source__){return eval(__source__);}"; | 5591 "function(arguments,__source__){return eval(__source__);}"; |
| 5427 static const int source_str_length = strlen(source_str); | 5592 static const int source_str_length = strlen(source_str); |
| 5428 Handle<String> function_source = | 5593 Handle<String> function_source = |
| 5429 Factory::NewStringFromAscii(Vector<const char>(source_str, | 5594 Factory::NewStringFromAscii(Vector<const char>(source_str, |
| 5430 source_str_length)); | 5595 source_str_length)); |
| 5431 Handle<JSFunction> boilerplate = | 5596 Handle<JSFunction> boilerplate = |
| 5432 Compiler::CompileEval(function_source, 0, context->IsGlobalContext()); | 5597 Compiler::CompileEval(function_source, 0, context->IsGlobalContext()); |
| 5433 if (boilerplate.is_null()) return Failure::Exception(); | 5598 if (boilerplate.is_null()) return Failure::Exception(); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5528 | 5693 |
| 5529 return count; | 5694 return count; |
| 5530 } | 5695 } |
| 5531 | 5696 |
| 5532 | 5697 |
| 5533 static Object* Runtime_DebugGetLoadedScripts(Arguments args) { | 5698 static Object* Runtime_DebugGetLoadedScripts(Arguments args) { |
| 5534 HandleScope scope; | 5699 HandleScope scope; |
| 5535 ASSERT(args.length() == 0); | 5700 ASSERT(args.length() == 0); |
| 5536 | 5701 |
| 5537 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets | 5702 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets |
| 5538 // rid of all the cached script wrappes and the second gets rid of the | 5703 // rid of all the cached script wrappers and the second gets rid of the |
| 5539 // scripts which is no longer referenced. | 5704 // scripts which is no longer referenced. |
| 5540 Heap::CollectAllGarbage(); | 5705 Heap::CollectAllGarbage(); |
| 5541 Heap::CollectAllGarbage(); | 5706 Heap::CollectAllGarbage(); |
| 5542 | 5707 |
| 5543 // Get the number of scripts. | 5708 // Get the number of scripts. |
| 5544 int count; | 5709 int count; |
| 5545 count = DebugGetLoadedScripts(NULL, 0); | 5710 count = DebugGetLoadedScripts(NULL, 0); |
| 5546 | 5711 |
| 5547 // Allocate an array to hold the result. | 5712 // Allocate an array to hold the result. |
| 5548 Handle<FixedArray> instances = Factory::NewFixedArray(count); | 5713 Handle<FixedArray> instances = Factory::NewFixedArray(count); |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5749 | 5914 |
| 5750 // Return result as JS array. | 5915 // Return result as JS array. |
| 5751 Object* result = | 5916 Object* result = |
| 5752 Heap::AllocateJSObject( | 5917 Heap::AllocateJSObject( |
| 5753 Top::context()->global_context()->array_function()); | 5918 Top::context()->global_context()->array_function()); |
| 5754 if (!result->IsFailure()) JSArray::cast(result)->SetContent(instances); | 5919 if (!result->IsFailure()) JSArray::cast(result)->SetContent(instances); |
| 5755 return result; | 5920 return result; |
| 5756 } | 5921 } |
| 5757 | 5922 |
| 5758 | 5923 |
| 5759 static Object* Runtime_GetPrototype(Arguments args) { | 5924 // Find the effective prototype object as returned by __proto__. |
| 5925 // args[0]: the object to find the prototype for. |
| 5926 static Object* Runtime_DebugGetPrototype(Arguments args) { |
| 5760 ASSERT(args.length() == 1); | 5927 ASSERT(args.length() == 1); |
| 5761 | 5928 |
| 5762 CONVERT_CHECKED(JSObject, obj, args[0]); | 5929 CONVERT_CHECKED(JSObject, obj, args[0]); |
| 5763 | 5930 |
| 5764 return obj->GetPrototype(); | 5931 // Use the __proto__ accessor. |
| 5932 return Accessors::ObjectPrototype.getter(obj, NULL); |
| 5765 } | 5933 } |
| 5766 | 5934 |
| 5767 | 5935 |
| 5768 static Object* Runtime_SystemBreak(Arguments args) { | 5936 static Object* Runtime_SystemBreak(Arguments args) { |
| 5769 ASSERT(args.length() == 0); | 5937 ASSERT(args.length() == 0); |
| 5770 CPU::DebugBreak(); | 5938 CPU::DebugBreak(); |
| 5771 return Heap::undefined_value(); | 5939 return Heap::undefined_value(); |
| 5772 } | 5940 } |
| 5773 | 5941 |
| 5774 | 5942 |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5928 } else { | 6096 } else { |
| 5929 // Handle last resort GC and make sure to allow future allocations | 6097 // Handle last resort GC and make sure to allow future allocations |
| 5930 // to grow the heap without causing GCs (if possible). | 6098 // to grow the heap without causing GCs (if possible). |
| 5931 Counters::gc_last_resort_from_js.Increment(); | 6099 Counters::gc_last_resort_from_js.Increment(); |
| 5932 Heap::CollectAllGarbage(); | 6100 Heap::CollectAllGarbage(); |
| 5933 } | 6101 } |
| 5934 } | 6102 } |
| 5935 | 6103 |
| 5936 | 6104 |
| 5937 } } // namespace v8::internal | 6105 } } // namespace v8::internal |
| OLD | NEW |