Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(345)

Side by Side Diff: src/runtime.cc

Issue 18842: Experimental: periodic merge of the bleeding_edge branch to the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/runtime.h ('k') | src/scanner.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/scanner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698