| 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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 return Factory::ObjectLiteralMapFromCache(context, keys); | 124 return Factory::ObjectLiteralMapFromCache(context, keys); |
| 125 } | 125 } |
| 126 } | 126 } |
| 127 *is_result_from_cache = false; | 127 *is_result_from_cache = false; |
| 128 return Factory::CopyMap( | 128 return Factory::CopyMap( |
| 129 Handle<Map>(context->object_function()->initial_map()), | 129 Handle<Map>(context->object_function()->initial_map()), |
| 130 number_of_properties); | 130 number_of_properties); |
| 131 } | 131 } |
| 132 | 132 |
| 133 | 133 |
| 134 static Object* Runtime_CreateObjectLiteralBoilerplate(Arguments args) { | 134 static Handle<Object> CreateObjectLiteralBoilerplate( |
| 135 HandleScope scope; | 135 Handle<FixedArray> literals, |
| 136 ASSERT(args.length() == 3); | 136 Handle<FixedArray> constant_properties) { |
| 137 // Copy the arguments. | |
| 138 Handle<FixedArray> literals = args.at<FixedArray>(0); | |
| 139 int literals_index = Smi::cast(args[1])->value(); | |
| 140 Handle<FixedArray> constant_properties = args.at<FixedArray>(2); | |
| 141 | |
| 142 // Get the global context from the literals array. This is the | 137 // Get the global context from the literals array. This is the |
| 143 // context in which the function was created and we use the object | 138 // context in which the function was created and we use the object |
| 144 // function from this context to create the object literal. We do | 139 // function from this context to create the object literal. We do |
| 145 // not use the object function from the current global context | 140 // not use the object function from the current global context |
| 146 // because this might be the object function from another context | 141 // because this might be the object function from another context |
| 147 // which we should not have access to. | 142 // which we should not have access to. |
| 148 Handle<Context> context = | 143 Handle<Context> context = |
| 149 Handle<Context>(JSFunction::GlobalContextFromLiterals(*literals)); | 144 Handle<Context>(JSFunction::GlobalContextFromLiterals(*literals)); |
| 150 | 145 |
| 151 bool is_result_from_cache; | 146 bool is_result_from_cache; |
| 152 Handle<Map> map = ComputeObjectLiteralMap(context, | 147 Handle<Map> map = ComputeObjectLiteralMap(context, |
| 153 constant_properties, | 148 constant_properties, |
| 154 &is_result_from_cache); | 149 &is_result_from_cache); |
| 155 | 150 |
| 156 Handle<JSObject> boilerplate = Factory::NewJSObjectFromMap(map); | 151 Handle<JSObject> boilerplate = Factory::NewJSObjectFromMap(map); |
| 157 { // Add the constant properties to the boilerplate. | 152 { // Add the constant properties to the boilerplate. |
| 158 int length = constant_properties->length(); | 153 int length = constant_properties->length(); |
| 159 OptimizedObjectForAddingMultipleProperties opt(boilerplate, | 154 OptimizedObjectForAddingMultipleProperties opt(boilerplate, |
| 160 !is_result_from_cache); | 155 !is_result_from_cache); |
| 161 for (int index = 0; index < length; index +=2) { | 156 for (int index = 0; index < length; index +=2) { |
| 162 Handle<Object> key(constant_properties->get(index+0)); | 157 Handle<Object> key(constant_properties->get(index+0)); |
| 163 Handle<Object> value(constant_properties->get(index+1)); | 158 Handle<Object> value(constant_properties->get(index+1)); |
| 159 if (value->IsFixedArray()) { |
| 160 // The value contains the constant_properties of a |
| 161 // simple object literal. |
| 162 Handle<FixedArray> array = Handle<FixedArray>::cast(value); |
| 163 value = CreateObjectLiteralBoilerplate(literals, array); |
| 164 } |
| 164 Handle<Object> result; | 165 Handle<Object> result; |
| 165 uint32_t element_index = 0; | 166 uint32_t element_index = 0; |
| 166 if (key->IsSymbol()) { | 167 if (key->IsSymbol()) { |
| 167 // If key is a symbol it is not an array element. | 168 // If key is a symbol it is not an array element. |
| 168 Handle<String> name(String::cast(*key)); | 169 Handle<String> name(String::cast(*key)); |
| 169 ASSERT(!name->AsArrayIndex(&element_index)); | 170 ASSERT(!name->AsArrayIndex(&element_index)); |
| 170 result = SetProperty(boilerplate, name, value, NONE); | 171 result = SetProperty(boilerplate, name, value, NONE); |
| 171 } else if (Array::IndexFromObject(*key, &element_index)) { | 172 } else if (Array::IndexFromObject(*key, &element_index)) { |
| 172 // Array index (uint32). | 173 // Array index (uint32). |
| 173 result = SetElement(boilerplate, element_index, value); | 174 result = SetElement(boilerplate, element_index, value); |
| 174 } else { | 175 } else { |
| 175 // Non-uint32 number. | 176 // Non-uint32 number. |
| 176 ASSERT(key->IsNumber()); | 177 ASSERT(key->IsNumber()); |
| 177 double num = key->Number(); | 178 double num = key->Number(); |
| 178 char arr[100]; | 179 char arr[100]; |
| 179 Vector<char> buffer(arr, ARRAY_SIZE(arr)); | 180 Vector<char> buffer(arr, ARRAY_SIZE(arr)); |
| 180 const char* str = DoubleToCString(num, buffer); | 181 const char* str = DoubleToCString(num, buffer); |
| 181 Handle<String> name = Factory::NewStringFromAscii(CStrVector(str)); | 182 Handle<String> name = Factory::NewStringFromAscii(CStrVector(str)); |
| 182 result = SetProperty(boilerplate, name, value, NONE); | 183 result = SetProperty(boilerplate, name, value, NONE); |
| 183 } | 184 } |
| 184 // If setting the property on the boilerplate throws an | 185 // If setting the property on the boilerplate throws an |
| 185 // exception, the exception is converted to an empty handle in | 186 // exception, the exception is converted to an empty handle in |
| 186 // the handle based operations. In that case, we need to | 187 // the handle based operations. In that case, we need to |
| 187 // convert back to an exception. | 188 // convert back to an exception. |
| 188 if (result.is_null()) return Failure::Exception(); | 189 if (result.is_null()) return result; |
| 189 } | 190 } |
| 190 } | 191 } |
| 191 | 192 |
| 192 // Update the functions literal and return the boilerplate. | 193 return boilerplate; |
| 193 literals->set(literals_index, *boilerplate); | |
| 194 | |
| 195 return *boilerplate; | |
| 196 } | 194 } |
| 197 | 195 |
| 198 | 196 |
| 197 static Object* Runtime_CreateObjectLiteralBoilerplate(Arguments args) { |
| 198 HandleScope scope; |
| 199 ASSERT(args.length() == 3); |
| 200 // Copy the arguments. |
| 201 Handle<FixedArray> literals = args.at<FixedArray>(0); |
| 202 int literals_index = Smi::cast(args[1])->value(); |
| 203 Handle<FixedArray> constant_properties = args.at<FixedArray>(2); |
| 204 |
| 205 Handle<Object> result = |
| 206 CreateObjectLiteralBoilerplate(literals, constant_properties); |
| 207 |
| 208 if (result.is_null()) return Failure::Exception(); |
| 209 |
| 210 // Update the functions literal and return the boilerplate. |
| 211 literals->set(literals_index, *result); |
| 212 |
| 213 return *result; |
| 214 } |
| 215 |
| 216 |
| 199 static Object* Runtime_CreateArrayLiteral(Arguments args) { | 217 static Object* Runtime_CreateArrayLiteral(Arguments args) { |
| 200 // Takes a FixedArray of elements containing the literal elements of | 218 // Takes a FixedArray of elements containing the literal elements of |
| 201 // the array literal and produces JSArray with those elements. | 219 // the array literal and produces JSArray with those elements. |
| 202 // Additionally takes the literals array of the surrounding function | 220 // Additionally takes the literals array of the surrounding function |
| 203 // which contains the context from which to get the Array function | 221 // which contains the context from which to get the Array function |
| 204 // to use for creating the array literal. | 222 // to use for creating the array literal. |
| 205 ASSERT(args.length() == 2); | 223 ASSERT(args.length() == 2); |
| 206 CONVERT_CHECKED(FixedArray, elements, args[0]); | 224 CONVERT_CHECKED(FixedArray, elements, args[0]); |
| 207 CONVERT_CHECKED(FixedArray, literals, args[1]); | 225 CONVERT_CHECKED(FixedArray, literals, args[1]); |
| 208 JSFunction* constructor = | 226 JSFunction* constructor = |
| (...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 844 } | 862 } |
| 845 } | 863 } |
| 846 } | 864 } |
| 847 | 865 |
| 848 return *value; | 866 return *value; |
| 849 } | 867 } |
| 850 | 868 |
| 851 | 869 |
| 852 static Object* Runtime_RegExpExec(Arguments args) { | 870 static Object* Runtime_RegExpExec(Arguments args) { |
| 853 HandleScope scope; | 871 HandleScope scope; |
| 854 ASSERT(args.length() == 4); | 872 ASSERT(args.length() == 3); |
| 855 CONVERT_CHECKED(JSRegExp, raw_regexp, args[0]); | 873 CONVERT_CHECKED(JSRegExp, raw_regexp, args[0]); |
| 856 Handle<JSRegExp> regexp(raw_regexp); | 874 Handle<JSRegExp> regexp(raw_regexp); |
| 857 CONVERT_CHECKED(String, raw_subject, args[1]); | 875 CONVERT_CHECKED(String, raw_subject, args[1]); |
| 858 Handle<String> subject(raw_subject); | 876 Handle<String> subject(raw_subject); |
| 859 // Due to the way the JS files are constructed this must be less than the | 877 Handle<Object> index(args[2]); |
| 860 // length of a string, i.e. it is always a Smi. We check anyway for security. | 878 ASSERT(index->IsNumber()); |
| 861 CONVERT_CHECKED(Smi, index, args[2]); | 879 Handle<Object> result = RegExpImpl::Exec(regexp, subject, index); |
| 862 CONVERT_CHECKED(JSArray, raw_last_match_info, args[3]); | |
| 863 Handle<JSArray> last_match_info(raw_last_match_info); | |
| 864 CHECK(last_match_info->HasFastElements()); | |
| 865 Handle<Object> result = RegExpImpl::Exec(regexp, | |
| 866 subject, | |
| 867 index->value(), | |
| 868 last_match_info); | |
| 869 if (result.is_null()) return Failure::Exception(); | 880 if (result.is_null()) return Failure::Exception(); |
| 870 return *result; | 881 return *result; |
| 871 } | 882 } |
| 872 | 883 |
| 873 | 884 |
| 874 static Object* Runtime_RegExpExecGlobal(Arguments args) { | 885 static Object* Runtime_RegExpExecGlobal(Arguments args) { |
| 875 HandleScope scope; | 886 HandleScope scope; |
| 876 ASSERT(args.length() == 3); | 887 ASSERT(args.length() == 2); |
| 877 CONVERT_CHECKED(JSRegExp, raw_regexp, args[0]); | 888 CONVERT_CHECKED(JSRegExp, raw_regexp, args[0]); |
| 878 Handle<JSRegExp> regexp(raw_regexp); | 889 Handle<JSRegExp> regexp(raw_regexp); |
| 879 CONVERT_CHECKED(String, raw_subject, args[1]); | 890 CONVERT_CHECKED(String, raw_subject, args[1]); |
| 880 Handle<String> subject(raw_subject); | 891 Handle<String> subject(raw_subject); |
| 881 CONVERT_CHECKED(JSArray, raw_last_match_info, args[2]); | 892 Handle<Object> result = RegExpImpl::ExecGlobal(regexp, subject); |
| 882 Handle<JSArray> last_match_info(raw_last_match_info); | |
| 883 CHECK(last_match_info->HasFastElements()); | |
| 884 Handle<Object> result = | |
| 885 RegExpImpl::ExecGlobal(regexp, subject, last_match_info); | |
| 886 if (result.is_null()) return Failure::Exception(); | 893 if (result.is_null()) return Failure::Exception(); |
| 887 return *result; | 894 return *result; |
| 888 } | 895 } |
| 889 | 896 |
| 890 | 897 |
| 891 static Object* Runtime_MaterializeRegExpLiteral(Arguments args) { | 898 static Object* Runtime_MaterializeRegExpLiteral(Arguments args) { |
| 892 HandleScope scope; | 899 HandleScope scope; |
| 893 ASSERT(args.length() == 4); | 900 ASSERT(args.length() == 4); |
| 894 CONVERT_ARG_CHECKED(FixedArray, literals, 0); | 901 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
| 895 int index = Smi::cast(args[1])->value(); | 902 int index = Smi::cast(args[1])->value(); |
| (...skipping 1258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2154 if (key->Equals(Heap::length_symbol())) return Smi::FromInt(n); | 2161 if (key->Equals(Heap::length_symbol())) return Smi::FromInt(n); |
| 2155 if (key->Equals(Heap::callee_symbol())) return frame->function(); | 2162 if (key->Equals(Heap::callee_symbol())) return frame->function(); |
| 2156 | 2163 |
| 2157 // Lookup in the initial Object.prototype object. | 2164 // Lookup in the initial Object.prototype object. |
| 2158 return Top::initial_object_prototype()->GetProperty(*key); | 2165 return Top::initial_object_prototype()->GetProperty(*key); |
| 2159 } | 2166 } |
| 2160 | 2167 |
| 2161 | 2168 |
| 2162 static Object* Runtime_ToFastProperties(Arguments args) { | 2169 static Object* Runtime_ToFastProperties(Arguments args) { |
| 2163 ASSERT(args.length() == 1); | 2170 ASSERT(args.length() == 1); |
| 2164 CONVERT_ARG_CHECKED(JSObject, object, 0); | 2171 Handle<Object> object = args.at<Object>(0); |
| 2165 object->TransformToFastProperties(0); | 2172 if (object->IsJSObject()) { |
| 2173 Handle<JSObject> js_object = Handle<JSObject>::cast(object); |
| 2174 js_object->TransformToFastProperties(0); |
| 2175 } |
| 2166 return *object; | 2176 return *object; |
| 2167 } | 2177 } |
| 2168 | 2178 |
| 2169 | 2179 |
| 2170 static Object* Runtime_ToSlowProperties(Arguments args) { | 2180 static Object* Runtime_ToSlowProperties(Arguments args) { |
| 2171 ASSERT(args.length() == 1); | 2181 ASSERT(args.length() == 1); |
| 2172 CONVERT_ARG_CHECKED(JSObject, object, 0); | 2182 Handle<Object> object = args.at<Object>(0); |
| 2173 object->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); | 2183 if (object->IsJSObject()) { |
| 2184 Handle<JSObject> js_object = Handle<JSObject>::cast(object); |
| 2185 js_object->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); |
| 2186 } |
| 2174 return *object; | 2187 return *object; |
| 2175 } | 2188 } |
| 2176 | 2189 |
| 2177 | 2190 |
| 2178 static Object* Runtime_ToBool(Arguments args) { | 2191 static Object* Runtime_ToBool(Arguments args) { |
| 2179 NoHandleAllocation ha; | 2192 NoHandleAllocation ha; |
| 2180 ASSERT(args.length() == 1); | 2193 ASSERT(args.length() == 1); |
| 2181 | 2194 |
| 2182 return args[0]->ToBoolean(); | 2195 return args[0]->ToBoolean(); |
| 2183 } | 2196 } |
| (...skipping 2758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4942 CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]); | 4955 CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]); |
| 4943 | 4956 |
| 4944 return obj->GetElementWithInterceptor(*obj, index); | 4957 return obj->GetElementWithInterceptor(*obj, index); |
| 4945 } | 4958 } |
| 4946 | 4959 |
| 4947 | 4960 |
| 4948 static Object* Runtime_CheckExecutionState(Arguments args) { | 4961 static Object* Runtime_CheckExecutionState(Arguments args) { |
| 4949 ASSERT(args.length() >= 1); | 4962 ASSERT(args.length() >= 1); |
| 4950 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); | 4963 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); |
| 4951 // Check that the break id is valid. | 4964 // Check that the break id is valid. |
| 4952 if (Top::break_id() == 0 || break_id != Top::break_id()) { | 4965 if (Debug::break_id() == 0 || break_id != Debug::break_id()) { |
| 4953 return Top::Throw(Heap::illegal_execution_state_symbol()); | 4966 return Top::Throw(Heap::illegal_execution_state_symbol()); |
| 4954 } | 4967 } |
| 4955 | 4968 |
| 4956 return Heap::true_value(); | 4969 return Heap::true_value(); |
| 4957 } | 4970 } |
| 4958 | 4971 |
| 4959 | 4972 |
| 4960 static Object* Runtime_GetFrameCount(Arguments args) { | 4973 static Object* Runtime_GetFrameCount(Arguments args) { |
| 4961 HandleScope scope; | 4974 HandleScope scope; |
| 4962 ASSERT(args.length() == 1); | 4975 ASSERT(args.length() == 1); |
| 4963 | 4976 |
| 4964 // Check arguments. | 4977 // Check arguments. |
| 4965 Object* result = Runtime_CheckExecutionState(args); | 4978 Object* result = Runtime_CheckExecutionState(args); |
| 4966 if (result->IsFailure()) return result; | 4979 if (result->IsFailure()) return result; |
| 4967 | 4980 |
| 4968 // Count all frames which are relevant to debugging stack trace. | 4981 // Count all frames which are relevant to debugging stack trace. |
| 4969 int n = 0; | 4982 int n = 0; |
| 4970 StackFrame::Id id = Top::break_frame_id(); | 4983 StackFrame::Id id = Debug::break_frame_id(); |
| 4971 if (id == StackFrame::NO_ID) { | 4984 if (id == StackFrame::NO_ID) { |
| 4972 // If there is no JavaScript stack frame count is 0. | 4985 // If there is no JavaScript stack frame count is 0. |
| 4973 return Smi::FromInt(0); | 4986 return Smi::FromInt(0); |
| 4974 } | 4987 } |
| 4975 for (JavaScriptFrameIterator it(id); !it.done(); it.Advance()) n++; | 4988 for (JavaScriptFrameIterator it(id); !it.done(); it.Advance()) n++; |
| 4976 return Smi::FromInt(n); | 4989 return Smi::FromInt(n); |
| 4977 } | 4990 } |
| 4978 | 4991 |
| 4979 | 4992 |
| 4980 static const int kFrameDetailsFrameIdIndex = 0; | 4993 static const int kFrameDetailsFrameIdIndex = 0; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 5005 static Object* Runtime_GetFrameDetails(Arguments args) { | 5018 static Object* Runtime_GetFrameDetails(Arguments args) { |
| 5006 HandleScope scope; | 5019 HandleScope scope; |
| 5007 ASSERT(args.length() == 2); | 5020 ASSERT(args.length() == 2); |
| 5008 | 5021 |
| 5009 // Check arguments. | 5022 // Check arguments. |
| 5010 Object* check = Runtime_CheckExecutionState(args); | 5023 Object* check = Runtime_CheckExecutionState(args); |
| 5011 if (check->IsFailure()) return check; | 5024 if (check->IsFailure()) return check; |
| 5012 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); | 5025 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); |
| 5013 | 5026 |
| 5014 // Find the relevant frame with the requested index. | 5027 // Find the relevant frame with the requested index. |
| 5015 StackFrame::Id id = Top::break_frame_id(); | 5028 StackFrame::Id id = Debug::break_frame_id(); |
| 5016 if (id == StackFrame::NO_ID) { | 5029 if (id == StackFrame::NO_ID) { |
| 5017 // If there are no JavaScript stack frames return undefined. | 5030 // If there are no JavaScript stack frames return undefined. |
| 5018 return Heap::undefined_value(); | 5031 return Heap::undefined_value(); |
| 5019 } | 5032 } |
| 5020 int count = 0; | 5033 int count = 0; |
| 5021 JavaScriptFrameIterator it(id); | 5034 JavaScriptFrameIterator it(id); |
| 5022 for (; !it.done(); it.Advance()) { | 5035 for (; !it.done(); it.Advance()) { |
| 5023 if (count == index) break; | 5036 if (count == index) break; |
| 5024 count++; | 5037 count++; |
| 5025 } | 5038 } |
| (...skipping 1092 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6118 } else { | 6131 } else { |
| 6119 // Handle last resort GC and make sure to allow future allocations | 6132 // Handle last resort GC and make sure to allow future allocations |
| 6120 // to grow the heap without causing GCs (if possible). | 6133 // to grow the heap without causing GCs (if possible). |
| 6121 Counters::gc_last_resort_from_js.Increment(); | 6134 Counters::gc_last_resort_from_js.Increment(); |
| 6122 Heap::CollectAllGarbage(); | 6135 Heap::CollectAllGarbage(); |
| 6123 } | 6136 } |
| 6124 } | 6137 } |
| 6125 | 6138 |
| 6126 | 6139 |
| 6127 } } // namespace v8::internal | 6140 } } // namespace v8::internal |
| OLD | NEW |