| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1091 // Due to some WebKit tests, we want to make sure that we do not log | 1091 // Due to some WebKit tests, we want to make sure that we do not log |
| 1092 // more than one access failure here. | 1092 // more than one access failure here. |
| 1093 switch (CheckPropertyAccess(*obj, *name, v8::ACCESS_HAS)) { | 1093 switch (CheckPropertyAccess(*obj, *name, v8::ACCESS_HAS)) { |
| 1094 case ACCESS_FORBIDDEN: return heap->false_value(); | 1094 case ACCESS_FORBIDDEN: return heap->false_value(); |
| 1095 case ACCESS_ALLOWED: break; | 1095 case ACCESS_ALLOWED: break; |
| 1096 case ACCESS_ABSENT: return heap->undefined_value(); | 1096 case ACCESS_ABSENT: return heap->undefined_value(); |
| 1097 } | 1097 } |
| 1098 | 1098 |
| 1099 PropertyAttributes attrs = obj->GetLocalPropertyAttribute(*name); | 1099 PropertyAttributes attrs = obj->GetLocalPropertyAttribute(*name); |
| 1100 if (attrs == ABSENT) return heap->undefined_value(); | 1100 if (attrs == ABSENT) return heap->undefined_value(); |
| 1101 AccessorPair* raw_accessors = obj->GetLocalPropertyAccessorPair(*name); | 1101 AccessorPair* accessors = obj->GetLocalPropertyAccessorPair(*name); |
| 1102 Handle<AccessorPair> accessors(raw_accessors, isolate); | |
| 1103 | 1102 |
| 1104 Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE); | 1103 Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE); |
| 1105 elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0)); | 1104 elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0)); |
| 1106 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0)); | 1105 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0)); |
| 1107 elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(raw_accessors != NULL)); | 1106 elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(accessors != NULL)); |
| 1108 | 1107 |
| 1109 if (raw_accessors == NULL) { | 1108 if (accessors == NULL) { |
| 1110 elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0)); | 1109 elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0)); |
| 1111 // GetProperty does access check. | 1110 // GetProperty does access check. |
| 1112 Handle<Object> value = GetProperty(obj, name); | 1111 Handle<Object> value = GetProperty(obj, name); |
| 1113 if (value.is_null()) return Failure::Exception(); | 1112 if (value.is_null()) return Failure::Exception(); |
| 1114 elms->set(VALUE_INDEX, *value); | 1113 elms->set(VALUE_INDEX, *value); |
| 1115 } else { | 1114 } else { |
| 1116 // Access checks are performed for both accessors separately. | 1115 // Access checks are performed for both accessors separately. |
| 1117 // When they fail, the respective field is not set in the descriptor. | 1116 // When they fail, the respective field is not set in the descriptor. |
| 1118 Object* getter = accessors->GetComponent(ACCESSOR_GETTER); | 1117 Object* getter = accessors->GetComponent(ACCESSOR_GETTER); |
| 1119 Object* setter = accessors->GetComponent(ACCESSOR_SETTER); | 1118 Object* setter = accessors->GetComponent(ACCESSOR_SETTER); |
| (...skipping 4677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5797 // become garbage; there is no reason to keep two identical strings | 5796 // become garbage; there is no reason to keep two identical strings |
| 5798 // alive. | 5797 // alive. |
| 5799 return s; | 5798 return s; |
| 5800 } | 5799 } |
| 5801 } | 5800 } |
| 5802 | 5801 |
| 5803 | 5802 |
| 5804 namespace { | 5803 namespace { |
| 5805 | 5804 |
| 5806 static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF; | 5805 static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF; |
| 5807 #ifdef ENABLE_LATIN_1 | 5806 |
| 5808 static const uintptr_t kAsciiMask = kOneInEveryByte << 7; | |
| 5809 #endif | |
| 5810 | 5807 |
| 5811 // Given a word and two range boundaries returns a word with high bit | 5808 // Given a word and two range boundaries returns a word with high bit |
| 5812 // set in every byte iff the corresponding input byte was strictly in | 5809 // set in every byte iff the corresponding input byte was strictly in |
| 5813 // the range (m, n). All the other bits in the result are cleared. | 5810 // the range (m, n). All the other bits in the result are cleared. |
| 5814 // This function is only useful when it can be inlined and the | 5811 // This function is only useful when it can be inlined and the |
| 5815 // boundaries are statically known. | 5812 // boundaries are statically known. |
| 5816 // Requires: all bytes in the input word and the boundaries must be | 5813 // Requires: all bytes in the input word and the boundaries must be |
| 5817 // ASCII (less than 0x7F). | 5814 // ASCII (less than 0x7F). |
| 5818 static inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) { | 5815 static inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) { |
| 5819 // Every byte in an ASCII string is less than or equal to 0x7F. | 5816 // Every byte in an ASCII string is less than or equal to 0x7F. |
| 5820 ASSERT((w & (kOneInEveryByte * 0x7F)) == w); | 5817 ASSERT((w & (kOneInEveryByte * 0x7F)) == w); |
| 5821 // Use strict inequalities since in edge cases the function could be | 5818 // Use strict inequalities since in edge cases the function could be |
| 5822 // further simplified. | 5819 // further simplified. |
| 5823 ASSERT(0 < m && m < n); | 5820 ASSERT(0 < m && m < n && n < 0x7F); |
| 5824 #ifndef ENABLE_LATIN_1 | |
| 5825 ASSERT(n < 0x7F); | |
| 5826 #endif | |
| 5827 // Has high bit set in every w byte less than n. | 5821 // Has high bit set in every w byte less than n. |
| 5828 uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w; | 5822 uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w; |
| 5829 // Has high bit set in every w byte greater than m. | 5823 // Has high bit set in every w byte greater than m. |
| 5830 uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m); | 5824 uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m); |
| 5831 return (tmp1 & tmp2 & (kOneInEveryByte * 0x80)); | 5825 return (tmp1 & tmp2 & (kOneInEveryByte * 0x80)); |
| 5832 } | 5826 } |
| 5833 | 5827 |
| 5834 | 5828 |
| 5835 enum AsciiCaseConversion { | 5829 enum AsciiCaseConversion { |
| 5836 ASCII_TO_LOWER, | 5830 ASCII_TO_LOWER, |
| 5837 ASCII_TO_UPPER | 5831 ASCII_TO_UPPER |
| 5838 }; | 5832 }; |
| 5839 | 5833 |
| 5840 | 5834 |
| 5841 template <AsciiCaseConversion dir> | 5835 template <AsciiCaseConversion dir> |
| 5842 struct FastAsciiConverter { | 5836 struct FastAsciiConverter { |
| 5843 #ifdef ENABLE_LATIN_1 | |
| 5844 static bool Convert(char* dst, char* src, int length, bool* changed_out) { | |
| 5845 #else | |
| 5846 static bool Convert(char* dst, char* src, int length) { | 5837 static bool Convert(char* dst, char* src, int length) { |
| 5847 #endif | |
| 5848 #ifdef DEBUG | 5838 #ifdef DEBUG |
| 5849 char* saved_dst = dst; | 5839 char* saved_dst = dst; |
| 5850 char* saved_src = src; | 5840 char* saved_src = src; |
| 5851 #endif | 5841 #endif |
| 5852 // We rely on the distance between upper and lower case letters | 5842 // We rely on the distance between upper and lower case letters |
| 5853 // being a known power of 2. | 5843 // being a known power of 2. |
| 5854 ASSERT('a' - 'A' == (1 << 5)); | 5844 ASSERT('a' - 'A' == (1 << 5)); |
| 5855 // Boundaries for the range of input characters than require conversion. | 5845 // Boundaries for the range of input characters than require conversion. |
| 5856 const char lo = (dir == ASCII_TO_LOWER) ? 'A' - 1 : 'a' - 1; | 5846 const char lo = (dir == ASCII_TO_LOWER) ? 'A' - 1 : 'a' - 1; |
| 5857 const char hi = (dir == ASCII_TO_LOWER) ? 'Z' + 1 : 'z' + 1; | 5847 const char hi = (dir == ASCII_TO_LOWER) ? 'Z' + 1 : 'z' + 1; |
| 5858 bool changed = false; | 5848 bool changed = false; |
| 5859 #ifdef ENABLE_LATIN_1 | |
| 5860 uintptr_t or_acc = 0; | |
| 5861 #endif | |
| 5862 char* const limit = src + length; | 5849 char* const limit = src + length; |
| 5863 #ifdef V8_HOST_CAN_READ_UNALIGNED | 5850 #ifdef V8_HOST_CAN_READ_UNALIGNED |
| 5864 // Process the prefix of the input that requires no conversion one | 5851 // Process the prefix of the input that requires no conversion one |
| 5865 // (machine) word at a time. | 5852 // (machine) word at a time. |
| 5866 while (src <= limit - sizeof(uintptr_t)) { | 5853 while (src <= limit - sizeof(uintptr_t)) { |
| 5867 uintptr_t w = *reinterpret_cast<uintptr_t*>(src); | 5854 uintptr_t w = *reinterpret_cast<uintptr_t*>(src); |
| 5868 #ifdef ENABLE_LATIN_1 | |
| 5869 or_acc |= w; | |
| 5870 #endif | |
| 5871 if (AsciiRangeMask(w, lo, hi) != 0) { | 5855 if (AsciiRangeMask(w, lo, hi) != 0) { |
| 5872 changed = true; | 5856 changed = true; |
| 5873 break; | 5857 break; |
| 5874 } | 5858 } |
| 5875 *reinterpret_cast<uintptr_t*>(dst) = w; | 5859 *reinterpret_cast<uintptr_t*>(dst) = w; |
| 5876 src += sizeof(uintptr_t); | 5860 src += sizeof(uintptr_t); |
| 5877 dst += sizeof(uintptr_t); | 5861 dst += sizeof(uintptr_t); |
| 5878 } | 5862 } |
| 5879 // Process the remainder of the input performing conversion when | 5863 // Process the remainder of the input performing conversion when |
| 5880 // required one word at a time. | 5864 // required one word at a time. |
| 5881 while (src <= limit - sizeof(uintptr_t)) { | 5865 while (src <= limit - sizeof(uintptr_t)) { |
| 5882 uintptr_t w = *reinterpret_cast<uintptr_t*>(src); | 5866 uintptr_t w = *reinterpret_cast<uintptr_t*>(src); |
| 5883 #ifdef ENABLE_LATIN_1 | |
| 5884 or_acc |= w; | |
| 5885 #endif | |
| 5886 uintptr_t m = AsciiRangeMask(w, lo, hi); | 5867 uintptr_t m = AsciiRangeMask(w, lo, hi); |
| 5887 // The mask has high (7th) bit set in every byte that needs | 5868 // The mask has high (7th) bit set in every byte that needs |
| 5888 // conversion and we know that the distance between cases is | 5869 // conversion and we know that the distance between cases is |
| 5889 // 1 << 5. | 5870 // 1 << 5. |
| 5890 *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2); | 5871 *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2); |
| 5891 src += sizeof(uintptr_t); | 5872 src += sizeof(uintptr_t); |
| 5892 dst += sizeof(uintptr_t); | 5873 dst += sizeof(uintptr_t); |
| 5893 } | 5874 } |
| 5894 #endif | 5875 #endif |
| 5895 // Process the last few bytes of the input (or the whole input if | 5876 // Process the last few bytes of the input (or the whole input if |
| 5896 // unaligned access is not supported). | 5877 // unaligned access is not supported). |
| 5897 while (src < limit) { | 5878 while (src < limit) { |
| 5898 char c = *src; | 5879 char c = *src; |
| 5899 #ifdef ENABLE_LATIN_1 | |
| 5900 or_acc |= c; | |
| 5901 #endif | |
| 5902 if (lo < c && c < hi) { | 5880 if (lo < c && c < hi) { |
| 5903 c ^= (1 << 5); | 5881 c ^= (1 << 5); |
| 5904 changed = true; | 5882 changed = true; |
| 5905 } | 5883 } |
| 5906 *dst = c; | 5884 *dst = c; |
| 5907 ++src; | 5885 ++src; |
| 5908 ++dst; | 5886 ++dst; |
| 5909 } | 5887 } |
| 5910 #ifdef ENABLE_LATIN_1 | |
| 5911 if ((or_acc & kAsciiMask) != 0) { | |
| 5912 return false; | |
| 5913 } | |
| 5914 #endif | |
| 5915 #ifdef DEBUG | 5888 #ifdef DEBUG |
| 5916 CheckConvert(saved_dst, saved_src, length, changed); | 5889 CheckConvert(saved_dst, saved_src, length, changed); |
| 5917 #endif | 5890 #endif |
| 5918 #ifdef ENABLE_LATIN_1 | |
| 5919 *changed_out = changed; | |
| 5920 return true; | |
| 5921 #else | |
| 5922 return changed; | 5891 return changed; |
| 5923 #endif | |
| 5924 } | 5892 } |
| 5925 | 5893 |
| 5926 #ifdef DEBUG | 5894 #ifdef DEBUG |
| 5927 static void CheckConvert(char* dst, char* src, int length, bool changed) { | 5895 static void CheckConvert(char* dst, char* src, int length, bool changed) { |
| 5928 bool expected_changed = false; | 5896 bool expected_changed = false; |
| 5929 for (int i = 0; i < length; i++) { | 5897 for (int i = 0; i < length; i++) { |
| 5930 if (dst[i] == src[i]) continue; | 5898 if (dst[i] == src[i]) continue; |
| 5931 expected_changed = true; | 5899 expected_changed = true; |
| 5932 if (dir == ASCII_TO_LOWER) { | 5900 if (dir == ASCII_TO_LOWER) { |
| 5933 ASSERT('A' <= src[i] && src[i] <= 'Z'); | 5901 ASSERT('A' <= src[i] && src[i] <= 'Z'); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5966 Isolate* isolate, | 5934 Isolate* isolate, |
| 5967 unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) { | 5935 unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) { |
| 5968 NoHandleAllocation ha; | 5936 NoHandleAllocation ha; |
| 5969 CONVERT_ARG_CHECKED(String, s, 0); | 5937 CONVERT_ARG_CHECKED(String, s, 0); |
| 5970 s = s->TryFlattenGetString(); | 5938 s = s->TryFlattenGetString(); |
| 5971 | 5939 |
| 5972 const int length = s->length(); | 5940 const int length = s->length(); |
| 5973 // Assume that the string is not empty; we need this assumption later | 5941 // Assume that the string is not empty; we need this assumption later |
| 5974 if (length == 0) return s; | 5942 if (length == 0) return s; |
| 5975 | 5943 |
| 5944 #ifndef ENABLE_LATIN_1 |
| 5976 // Simpler handling of ASCII strings. | 5945 // Simpler handling of ASCII strings. |
| 5977 // | 5946 // |
| 5978 // NOTE: This assumes that the upper/lower case of an ASCII | 5947 // NOTE: This assumes that the upper/lower case of an ASCII |
| 5979 // character is also ASCII. This is currently the case, but it | 5948 // character is also ASCII. This is currently the case, but it |
| 5980 // might break in the future if we implement more context and locale | 5949 // might break in the future if we implement more context and locale |
| 5981 // dependent upper/lower conversions. | 5950 // dependent upper/lower conversions. |
| 5982 if (s->IsSeqOneByteString()) { | 5951 if (s->IsSeqOneByteString()) { |
| 5983 Object* o; | 5952 Object* o; |
| 5984 { MaybeObject* maybe_o = isolate->heap()->AllocateRawOneByteString(length); | 5953 { MaybeObject* maybe_o = isolate->heap()->AllocateRawOneByteString(length); |
| 5985 if (!maybe_o->ToObject(&o)) return maybe_o; | 5954 if (!maybe_o->ToObject(&o)) return maybe_o; |
| 5986 } | 5955 } |
| 5987 SeqOneByteString* result = SeqOneByteString::cast(o); | 5956 SeqOneByteString* result = SeqOneByteString::cast(o); |
| 5988 #ifndef ENABLE_LATIN_1 | |
| 5989 bool has_changed_character = ConvertTraits::AsciiConverter::Convert( | 5957 bool has_changed_character = ConvertTraits::AsciiConverter::Convert( |
| 5990 reinterpret_cast<char*>(result->GetChars()), | 5958 reinterpret_cast<char*>(result->GetChars()), |
| 5991 reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()), | 5959 reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()), |
| 5992 length); | 5960 length); |
| 5993 return has_changed_character ? result : s; | 5961 return has_changed_character ? result : s; |
| 5994 #else | 5962 } |
| 5995 bool has_changed_character; | |
| 5996 bool is_ascii = ConvertTraits::AsciiConverter::Convert( | |
| 5997 reinterpret_cast<char*>(result->GetChars()), | |
| 5998 reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()), | |
| 5999 length, | |
| 6000 &has_changed_character); | |
| 6001 // If not ASCII, we discard the result and take the 2 byte path. | |
| 6002 if (is_ascii) { | |
| 6003 return has_changed_character ? result : s; | |
| 6004 } | |
| 6005 #endif | 5963 #endif |
| 6006 } | |
| 6007 | 5964 |
| 6008 Object* answer; | 5965 Object* answer; |
| 6009 { MaybeObject* maybe_answer = | 5966 { MaybeObject* maybe_answer = |
| 6010 ConvertCaseHelper(isolate, s, length, length, mapping); | 5967 ConvertCaseHelper(isolate, s, length, length, mapping); |
| 6011 if (!maybe_answer->ToObject(&answer)) return maybe_answer; | 5968 if (!maybe_answer->ToObject(&answer)) return maybe_answer; |
| 6012 } | 5969 } |
| 6013 if (answer->IsSmi()) { | 5970 if (answer->IsSmi()) { |
| 6014 // Retry with correct length. | 5971 // Retry with correct length. |
| 6015 { MaybeObject* maybe_answer = | 5972 { MaybeObject* maybe_answer = |
| 6016 ConvertCaseHelper(isolate, | 5973 ConvertCaseHelper(isolate, |
| (...skipping 7238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13255 CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[2]); | 13212 CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[2]); |
| 13256 | 13213 |
| 13257 HandleScope scope(isolate); | 13214 HandleScope scope(isolate); |
| 13258 // Optionally capture a more detailed stack trace for the message. | 13215 // Optionally capture a more detailed stack trace for the message. |
| 13259 isolate->CaptureAndSetDetailedStackTrace(error_object); | 13216 isolate->CaptureAndSetDetailedStackTrace(error_object); |
| 13260 // Capture a simple stack trace for the stack property. | 13217 // Capture a simple stack trace for the stack property. |
| 13261 return *isolate->CaptureSimpleStackTrace(error_object, caller, limit); | 13218 return *isolate->CaptureSimpleStackTrace(error_object, caller, limit); |
| 13262 } | 13219 } |
| 13263 | 13220 |
| 13264 | 13221 |
| 13265 // Mark a function to recognize when called after GC to format the stack trace. | 13222 // Retrieve the raw stack trace collected on stack overflow and delete |
| 13266 RUNTIME_FUNCTION(MaybeObject*, Runtime_MarkOneShotGetter) { | 13223 // it since it is used only once to avoid keeping it alive. |
| 13267 ASSERT_EQ(args.length(), 1); | 13224 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOverflowedRawStackTrace) { |
| 13268 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); | |
| 13269 HandleScope scope(isolate); | |
| 13270 Handle<String> key = isolate->factory()->hidden_stack_trace_symbol(); | |
| 13271 JSObject::SetHiddenProperty(fun, key, key); | |
| 13272 return *fun; | |
| 13273 } | |
| 13274 | |
| 13275 | |
| 13276 // Retrieve the stack trace. This could be the raw stack trace collected | |
| 13277 // on stack overflow or the already formatted stack trace string. | |
| 13278 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOverflowedStackTrace) { | |
| 13279 HandleScope scope(isolate); | |
| 13280 ASSERT_EQ(args.length(), 1); | 13225 ASSERT_EQ(args.length(), 1); |
| 13281 CONVERT_ARG_CHECKED(JSObject, error_object, 0); | 13226 CONVERT_ARG_CHECKED(JSObject, error_object, 0); |
| 13282 String* key = isolate->heap()->hidden_stack_trace_symbol(); | 13227 String* key = isolate->heap()->hidden_stack_trace_symbol(); |
| 13283 Object* result = error_object->GetHiddenProperty(key); | 13228 Object* result = error_object->GetHiddenProperty(key); |
| 13284 RUNTIME_ASSERT(result->IsJSArray() || | 13229 RUNTIME_ASSERT(result->IsJSArray() || result->IsUndefined()); |
| 13285 result->IsString() || | 13230 error_object->DeleteHiddenProperty(key); |
| 13286 result->IsUndefined()); | |
| 13287 return result; | 13231 return result; |
| 13288 } | 13232 } |
| 13289 | 13233 |
| 13290 | 13234 |
| 13291 // Set or clear the stack trace attached to an stack overflow error object. | |
| 13292 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetOverflowedStackTrace) { | |
| 13293 HandleScope scope(isolate); | |
| 13294 ASSERT_EQ(args.length(), 2); | |
| 13295 CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0); | |
| 13296 CONVERT_ARG_HANDLE_CHECKED(HeapObject, value, 1); | |
| 13297 Handle<String> key = isolate->factory()->hidden_stack_trace_symbol(); | |
| 13298 if (value->IsUndefined()) { | |
| 13299 error_object->DeleteHiddenProperty(*key); | |
| 13300 } else { | |
| 13301 RUNTIME_ASSERT(value->IsString()); | |
| 13302 JSObject::SetHiddenProperty(error_object, key, value); | |
| 13303 } | |
| 13304 return *error_object; | |
| 13305 } | |
| 13306 | |
| 13307 | |
| 13308 // Returns V8 version as a string. | 13235 // Returns V8 version as a string. |
| 13309 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) { | 13236 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) { |
| 13310 ASSERT_EQ(args.length(), 0); | 13237 ASSERT_EQ(args.length(), 0); |
| 13311 | 13238 |
| 13312 NoHandleAllocation ha; | 13239 NoHandleAllocation ha; |
| 13313 | 13240 |
| 13314 const char* version_string = v8::V8::GetVersion(); | 13241 const char* version_string = v8::V8::GetVersion(); |
| 13315 | 13242 |
| 13316 return isolate->heap()->AllocateStringFromOneByte(CStrVector(version_string), | 13243 return isolate->heap()->AllocateStringFromOneByte(CStrVector(version_string), |
| 13317 NOT_TENURED); | 13244 NOT_TENURED); |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13716 // Handle last resort GC and make sure to allow future allocations | 13643 // Handle last resort GC and make sure to allow future allocations |
| 13717 // to grow the heap without causing GCs (if possible). | 13644 // to grow the heap without causing GCs (if possible). |
| 13718 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13645 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 13719 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13646 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 13720 "Runtime::PerformGC"); | 13647 "Runtime::PerformGC"); |
| 13721 } | 13648 } |
| 13722 } | 13649 } |
| 13723 | 13650 |
| 13724 | 13651 |
| 13725 } } // namespace v8::internal | 13652 } } // namespace v8::internal |
| OLD | NEW |