| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 #include "smart-pointer.h" | 52 #include "smart-pointer.h" |
| 53 #include "stub-cache.h" | 53 #include "stub-cache.h" |
| 54 #include "v8threads.h" | 54 #include "v8threads.h" |
| 55 #include "string-search.h" | 55 #include "string-search.h" |
| 56 | 56 |
| 57 namespace v8 { | 57 namespace v8 { |
| 58 namespace internal { | 58 namespace internal { |
| 59 | 59 |
| 60 | 60 |
| 61 #define RUNTIME_ASSERT(value) \ | 61 #define RUNTIME_ASSERT(value) \ |
| 62 if (!(value)) return Top::ThrowIllegalOperation(); | 62 if (!(value)) return isolate->ThrowIllegalOperation(); |
| 63 | 63 |
| 64 // Cast the given object to a value of the specified type and store | 64 // Cast the given object to a value of the specified type and store |
| 65 // it in a variable with the given name. If the object is not of the | 65 // it in a variable with the given name. If the object is not of the |
| 66 // expected type call IllegalOperation and return. | 66 // expected type call IllegalOperation and return. |
| 67 #define CONVERT_CHECKED(Type, name, obj) \ | 67 #define CONVERT_CHECKED(Type, name, obj) \ |
| 68 RUNTIME_ASSERT(obj->Is##Type()); \ | 68 RUNTIME_ASSERT(obj->Is##Type()); \ |
| 69 Type* name = Type::cast(obj); | 69 Type* name = Type::cast(obj); |
| 70 | 70 |
| 71 #define CONVERT_ARG_CHECKED(Type, name, index) \ | 71 #define CONVERT_ARG_CHECKED(Type, name, index) \ |
| 72 RUNTIME_ASSERT(args[index]->Is##Type()); \ | 72 RUNTIME_ASSERT(args[index]->Is##Type()); \ |
| (...skipping 20 matching lines...) Expand all Loading... |
| 93 RUNTIME_ASSERT(obj->IsNumber()); \ | 93 RUNTIME_ASSERT(obj->IsNumber()); \ |
| 94 double name = (obj)->Number(); | 94 double name = (obj)->Number(); |
| 95 | 95 |
| 96 // Call the specified converter on the object *comand store the result in | 96 // Call the specified converter on the object *comand store the result in |
| 97 // a variable of the specified type with the given name. If the | 97 // a variable of the specified type with the given name. If the |
| 98 // object is not a Number call IllegalOperation and return. | 98 // object is not a Number call IllegalOperation and return. |
| 99 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj) \ | 99 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj) \ |
| 100 RUNTIME_ASSERT(obj->IsNumber()); \ | 100 RUNTIME_ASSERT(obj->IsNumber()); \ |
| 101 type name = NumberTo##Type(obj); | 101 type name = NumberTo##Type(obj); |
| 102 | 102 |
| 103 // Non-reentrant string buffer for efficient general use in this file. | |
| 104 static StaticResource<StringInputBuffer> runtime_string_input_buffer; | |
| 105 | 103 |
| 104 MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(Isolate* isolate, |
| 105 JSObject* boilerplate) { |
| 106 StackLimitCheck check(isolate); |
| 107 if (check.HasOverflowed()) return isolate->StackOverflow(); |
| 106 | 108 |
| 107 MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(JSObject* boilerplate) { | 109 Heap* heap = isolate->heap(); |
| 108 StackLimitCheck check; | |
| 109 if (check.HasOverflowed()) return Top::StackOverflow(); | |
| 110 | |
| 111 Object* result; | 110 Object* result; |
| 112 { MaybeObject* maybe_result = Heap::CopyJSObject(boilerplate); | 111 { MaybeObject* maybe_result = heap->CopyJSObject(boilerplate); |
| 113 if (!maybe_result->ToObject(&result)) return maybe_result; | 112 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 114 } | 113 } |
| 115 JSObject* copy = JSObject::cast(result); | 114 JSObject* copy = JSObject::cast(result); |
| 116 | 115 |
| 117 // Deep copy local properties. | 116 // Deep copy local properties. |
| 118 if (copy->HasFastProperties()) { | 117 if (copy->HasFastProperties()) { |
| 119 FixedArray* properties = copy->properties(); | 118 FixedArray* properties = copy->properties(); |
| 120 for (int i = 0; i < properties->length(); i++) { | 119 for (int i = 0; i < properties->length(); i++) { |
| 121 Object* value = properties->get(i); | 120 Object* value = properties->get(i); |
| 122 if (value->IsJSObject()) { | 121 if (value->IsJSObject()) { |
| 123 JSObject* js_object = JSObject::cast(value); | 122 JSObject* js_object = JSObject::cast(value); |
| 124 { MaybeObject* maybe_result = DeepCopyBoilerplate(js_object); | 123 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, js_object); |
| 125 if (!maybe_result->ToObject(&result)) return maybe_result; | 124 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 126 } | 125 } |
| 127 properties->set(i, result); | 126 properties->set(i, result); |
| 128 } | 127 } |
| 129 } | 128 } |
| 130 int nof = copy->map()->inobject_properties(); | 129 int nof = copy->map()->inobject_properties(); |
| 131 for (int i = 0; i < nof; i++) { | 130 for (int i = 0; i < nof; i++) { |
| 132 Object* value = copy->InObjectPropertyAt(i); | 131 Object* value = copy->InObjectPropertyAt(i); |
| 133 if (value->IsJSObject()) { | 132 if (value->IsJSObject()) { |
| 134 JSObject* js_object = JSObject::cast(value); | 133 JSObject* js_object = JSObject::cast(value); |
| 135 { MaybeObject* maybe_result = DeepCopyBoilerplate(js_object); | 134 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, js_object); |
| 136 if (!maybe_result->ToObject(&result)) return maybe_result; | 135 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 137 } | 136 } |
| 138 copy->InObjectPropertyAtPut(i, result); | 137 copy->InObjectPropertyAtPut(i, result); |
| 139 } | 138 } |
| 140 } | 139 } |
| 141 } else { | 140 } else { |
| 142 { MaybeObject* maybe_result = | 141 { MaybeObject* maybe_result = |
| 143 Heap::AllocateFixedArray(copy->NumberOfLocalProperties(NONE)); | 142 heap->AllocateFixedArray(copy->NumberOfLocalProperties(NONE)); |
| 144 if (!maybe_result->ToObject(&result)) return maybe_result; | 143 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 145 } | 144 } |
| 146 FixedArray* names = FixedArray::cast(result); | 145 FixedArray* names = FixedArray::cast(result); |
| 147 copy->GetLocalPropertyNames(names, 0); | 146 copy->GetLocalPropertyNames(names, 0); |
| 148 for (int i = 0; i < names->length(); i++) { | 147 for (int i = 0; i < names->length(); i++) { |
| 149 ASSERT(names->get(i)->IsString()); | 148 ASSERT(names->get(i)->IsString()); |
| 150 String* key_string = String::cast(names->get(i)); | 149 String* key_string = String::cast(names->get(i)); |
| 151 PropertyAttributes attributes = | 150 PropertyAttributes attributes = |
| 152 copy->GetLocalPropertyAttribute(key_string); | 151 copy->GetLocalPropertyAttribute(key_string); |
| 153 // Only deep copy fields from the object literal expression. | 152 // Only deep copy fields from the object literal expression. |
| 154 // In particular, don't try to copy the length attribute of | 153 // In particular, don't try to copy the length attribute of |
| 155 // an array. | 154 // an array. |
| 156 if (attributes != NONE) continue; | 155 if (attributes != NONE) continue; |
| 157 Object* value = | 156 Object* value = |
| 158 copy->GetProperty(key_string, &attributes)->ToObjectUnchecked(); | 157 copy->GetProperty(key_string, &attributes)->ToObjectUnchecked(); |
| 159 if (value->IsJSObject()) { | 158 if (value->IsJSObject()) { |
| 160 JSObject* js_object = JSObject::cast(value); | 159 JSObject* js_object = JSObject::cast(value); |
| 161 { MaybeObject* maybe_result = DeepCopyBoilerplate(js_object); | 160 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, js_object); |
| 162 if (!maybe_result->ToObject(&result)) return maybe_result; | 161 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 163 } | 162 } |
| 164 { MaybeObject* maybe_result = | 163 { MaybeObject* maybe_result = |
| 165 // Creating object copy for literals. No strict mode needed. | 164 // Creating object copy for literals. No strict mode needed. |
| 166 copy->SetProperty(key_string, result, NONE, kNonStrictMode); | 165 copy->SetProperty(key_string, result, NONE, kNonStrictMode); |
| 167 if (!maybe_result->ToObject(&result)) return maybe_result; | 166 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 168 } | 167 } |
| 169 } | 168 } |
| 170 } | 169 } |
| 171 } | 170 } |
| 172 | 171 |
| 173 // Deep copy local elements. | 172 // Deep copy local elements. |
| 174 // Pixel elements cannot be created using an object literal. | 173 // Pixel elements cannot be created using an object literal. |
| 175 ASSERT(!copy->HasExternalArrayElements()); | 174 ASSERT(!copy->HasExternalArrayElements()); |
| 176 switch (copy->GetElementsKind()) { | 175 switch (copy->GetElementsKind()) { |
| 177 case JSObject::FAST_ELEMENTS: { | 176 case JSObject::FAST_ELEMENTS: { |
| 178 FixedArray* elements = FixedArray::cast(copy->elements()); | 177 FixedArray* elements = FixedArray::cast(copy->elements()); |
| 179 if (elements->map() == Heap::fixed_cow_array_map()) { | 178 if (elements->map() == heap->fixed_cow_array_map()) { |
| 180 Counters::cow_arrays_created_runtime.Increment(); | 179 isolate->counters()->cow_arrays_created_runtime()->Increment(); |
| 181 #ifdef DEBUG | 180 #ifdef DEBUG |
| 182 for (int i = 0; i < elements->length(); i++) { | 181 for (int i = 0; i < elements->length(); i++) { |
| 183 ASSERT(!elements->get(i)->IsJSObject()); | 182 ASSERT(!elements->get(i)->IsJSObject()); |
| 184 } | 183 } |
| 185 #endif | 184 #endif |
| 186 } else { | 185 } else { |
| 187 for (int i = 0; i < elements->length(); i++) { | 186 for (int i = 0; i < elements->length(); i++) { |
| 188 Object* value = elements->get(i); | 187 Object* value = elements->get(i); |
| 189 if (value->IsJSObject()) { | 188 if (value->IsJSObject()) { |
| 190 JSObject* js_object = JSObject::cast(value); | 189 JSObject* js_object = JSObject::cast(value); |
| 191 { MaybeObject* maybe_result = DeepCopyBoilerplate(js_object); | 190 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, |
| 191 js_object); |
| 192 if (!maybe_result->ToObject(&result)) return maybe_result; | 192 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 193 } | 193 } |
| 194 elements->set(i, result); | 194 elements->set(i, result); |
| 195 } | 195 } |
| 196 } | 196 } |
| 197 } | 197 } |
| 198 break; | 198 break; |
| 199 } | 199 } |
| 200 case JSObject::DICTIONARY_ELEMENTS: { | 200 case JSObject::DICTIONARY_ELEMENTS: { |
| 201 NumberDictionary* element_dictionary = copy->element_dictionary(); | 201 NumberDictionary* element_dictionary = copy->element_dictionary(); |
| 202 int capacity = element_dictionary->Capacity(); | 202 int capacity = element_dictionary->Capacity(); |
| 203 for (int i = 0; i < capacity; i++) { | 203 for (int i = 0; i < capacity; i++) { |
| 204 Object* k = element_dictionary->KeyAt(i); | 204 Object* k = element_dictionary->KeyAt(i); |
| 205 if (element_dictionary->IsKey(k)) { | 205 if (element_dictionary->IsKey(k)) { |
| 206 Object* value = element_dictionary->ValueAt(i); | 206 Object* value = element_dictionary->ValueAt(i); |
| 207 if (value->IsJSObject()) { | 207 if (value->IsJSObject()) { |
| 208 JSObject* js_object = JSObject::cast(value); | 208 JSObject* js_object = JSObject::cast(value); |
| 209 { MaybeObject* maybe_result = DeepCopyBoilerplate(js_object); | 209 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, |
| 210 js_object); |
| 210 if (!maybe_result->ToObject(&result)) return maybe_result; | 211 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 211 } | 212 } |
| 212 element_dictionary->ValueAtPut(i, result); | 213 element_dictionary->ValueAtPut(i, result); |
| 213 } | 214 } |
| 214 } | 215 } |
| 215 } | 216 } |
| 216 break; | 217 break; |
| 217 } | 218 } |
| 218 default: | 219 default: |
| 219 UNREACHABLE(); | 220 UNREACHABLE(); |
| 220 break; | 221 break; |
| 221 } | 222 } |
| 222 return copy; | 223 return copy; |
| 223 } | 224 } |
| 224 | 225 |
| 225 | 226 |
| 226 static MaybeObject* Runtime_CloneLiteralBoilerplate(Arguments args) { | 227 static MaybeObject* Runtime_CloneLiteralBoilerplate( |
| 228 RUNTIME_CALLING_CONVENTION) { |
| 229 RUNTIME_GET_ISOLATE; |
| 227 CONVERT_CHECKED(JSObject, boilerplate, args[0]); | 230 CONVERT_CHECKED(JSObject, boilerplate, args[0]); |
| 228 return DeepCopyBoilerplate(boilerplate); | 231 return DeepCopyBoilerplate(isolate, boilerplate); |
| 229 } | 232 } |
| 230 | 233 |
| 231 | 234 |
| 232 static MaybeObject* Runtime_CloneShallowLiteralBoilerplate(Arguments args) { | 235 static MaybeObject* Runtime_CloneShallowLiteralBoilerplate( |
| 236 RUNTIME_CALLING_CONVENTION) { |
| 237 RUNTIME_GET_ISOLATE; |
| 233 CONVERT_CHECKED(JSObject, boilerplate, args[0]); | 238 CONVERT_CHECKED(JSObject, boilerplate, args[0]); |
| 234 return Heap::CopyJSObject(boilerplate); | 239 return isolate->heap()->CopyJSObject(boilerplate); |
| 235 } | 240 } |
| 236 | 241 |
| 237 | 242 |
| 238 static Handle<Map> ComputeObjectLiteralMap( | 243 static Handle<Map> ComputeObjectLiteralMap( |
| 239 Handle<Context> context, | 244 Handle<Context> context, |
| 240 Handle<FixedArray> constant_properties, | 245 Handle<FixedArray> constant_properties, |
| 241 bool* is_result_from_cache) { | 246 bool* is_result_from_cache) { |
| 247 Isolate* isolate = context->GetIsolate(); |
| 242 int properties_length = constant_properties->length(); | 248 int properties_length = constant_properties->length(); |
| 243 int number_of_properties = properties_length / 2; | 249 int number_of_properties = properties_length / 2; |
| 244 if (FLAG_canonicalize_object_literal_maps) { | 250 if (FLAG_canonicalize_object_literal_maps) { |
| 245 // Check that there are only symbols and array indices among keys. | 251 // Check that there are only symbols and array indices among keys. |
| 246 int number_of_symbol_keys = 0; | 252 int number_of_symbol_keys = 0; |
| 247 for (int p = 0; p != properties_length; p += 2) { | 253 for (int p = 0; p != properties_length; p += 2) { |
| 248 Object* key = constant_properties->get(p); | 254 Object* key = constant_properties->get(p); |
| 249 uint32_t element_index = 0; | 255 uint32_t element_index = 0; |
| 250 if (key->IsSymbol()) { | 256 if (key->IsSymbol()) { |
| 251 number_of_symbol_keys++; | 257 number_of_symbol_keys++; |
| 252 } else if (key->ToArrayIndex(&element_index)) { | 258 } else if (key->ToArrayIndex(&element_index)) { |
| 253 // An index key does not require space in the property backing store. | 259 // An index key does not require space in the property backing store. |
| 254 number_of_properties--; | 260 number_of_properties--; |
| 255 } else { | 261 } else { |
| 256 // Bail out as a non-symbol non-index key makes caching impossible. | 262 // Bail out as a non-symbol non-index key makes caching impossible. |
| 257 // ASSERT to make sure that the if condition after the loop is false. | 263 // ASSERT to make sure that the if condition after the loop is false. |
| 258 ASSERT(number_of_symbol_keys != number_of_properties); | 264 ASSERT(number_of_symbol_keys != number_of_properties); |
| 259 break; | 265 break; |
| 260 } | 266 } |
| 261 } | 267 } |
| 262 // If we only have symbols and array indices among keys then we can | 268 // If we only have symbols and array indices among keys then we can |
| 263 // use the map cache in the global context. | 269 // use the map cache in the global context. |
| 264 const int kMaxKeys = 10; | 270 const int kMaxKeys = 10; |
| 265 if ((number_of_symbol_keys == number_of_properties) && | 271 if ((number_of_symbol_keys == number_of_properties) && |
| 266 (number_of_symbol_keys < kMaxKeys)) { | 272 (number_of_symbol_keys < kMaxKeys)) { |
| 267 // Create the fixed array with the key. | 273 // Create the fixed array with the key. |
| 268 Handle<FixedArray> keys = Factory::NewFixedArray(number_of_symbol_keys); | 274 Handle<FixedArray> keys = |
| 275 isolate->factory()->NewFixedArray(number_of_symbol_keys); |
| 269 if (number_of_symbol_keys > 0) { | 276 if (number_of_symbol_keys > 0) { |
| 270 int index = 0; | 277 int index = 0; |
| 271 for (int p = 0; p < properties_length; p += 2) { | 278 for (int p = 0; p < properties_length; p += 2) { |
| 272 Object* key = constant_properties->get(p); | 279 Object* key = constant_properties->get(p); |
| 273 if (key->IsSymbol()) { | 280 if (key->IsSymbol()) { |
| 274 keys->set(index++, key); | 281 keys->set(index++, key); |
| 275 } | 282 } |
| 276 } | 283 } |
| 277 ASSERT(index == number_of_symbol_keys); | 284 ASSERT(index == number_of_symbol_keys); |
| 278 } | 285 } |
| 279 *is_result_from_cache = true; | 286 *is_result_from_cache = true; |
| 280 return Factory::ObjectLiteralMapFromCache(context, keys); | 287 return isolate->factory()->ObjectLiteralMapFromCache(context, keys); |
| 281 } | 288 } |
| 282 } | 289 } |
| 283 *is_result_from_cache = false; | 290 *is_result_from_cache = false; |
| 284 return Factory::CopyMap( | 291 return isolate->factory()->CopyMap( |
| 285 Handle<Map>(context->object_function()->initial_map()), | 292 Handle<Map>(context->object_function()->initial_map()), |
| 286 number_of_properties); | 293 number_of_properties); |
| 287 } | 294 } |
| 288 | 295 |
| 289 | 296 |
| 290 static Handle<Object> CreateLiteralBoilerplate( | 297 static Handle<Object> CreateLiteralBoilerplate( |
| 298 Isolate* isolate, |
| 291 Handle<FixedArray> literals, | 299 Handle<FixedArray> literals, |
| 292 Handle<FixedArray> constant_properties); | 300 Handle<FixedArray> constant_properties); |
| 293 | 301 |
| 294 | 302 |
| 295 static Handle<Object> CreateObjectLiteralBoilerplate( | 303 static Handle<Object> CreateObjectLiteralBoilerplate( |
| 304 Isolate* isolate, |
| 296 Handle<FixedArray> literals, | 305 Handle<FixedArray> literals, |
| 297 Handle<FixedArray> constant_properties, | 306 Handle<FixedArray> constant_properties, |
| 298 bool should_have_fast_elements) { | 307 bool should_have_fast_elements) { |
| 299 // Get the global context from the literals array. This is the | 308 // Get the global context from the literals array. This is the |
| 300 // context in which the function was created and we use the object | 309 // context in which the function was created and we use the object |
| 301 // function from this context to create the object literal. We do | 310 // function from this context to create the object literal. We do |
| 302 // not use the object function from the current global context | 311 // not use the object function from the current global context |
| 303 // because this might be the object function from another context | 312 // because this might be the object function from another context |
| 304 // which we should not have access to. | 313 // which we should not have access to. |
| 305 Handle<Context> context = | 314 Handle<Context> context = |
| 306 Handle<Context>(JSFunction::GlobalContextFromLiterals(*literals)); | 315 Handle<Context>(JSFunction::GlobalContextFromLiterals(*literals)); |
| 307 | 316 |
| 308 bool is_result_from_cache; | 317 bool is_result_from_cache; |
| 309 Handle<Map> map = ComputeObjectLiteralMap(context, | 318 Handle<Map> map = ComputeObjectLiteralMap(context, |
| 310 constant_properties, | 319 constant_properties, |
| 311 &is_result_from_cache); | 320 &is_result_from_cache); |
| 312 | 321 |
| 313 Handle<JSObject> boilerplate = Factory::NewJSObjectFromMap(map); | 322 Handle<JSObject> boilerplate = isolate->factory()->NewJSObjectFromMap(map); |
| 314 | 323 |
| 315 // Normalize the elements of the boilerplate to save space if needed. | 324 // Normalize the elements of the boilerplate to save space if needed. |
| 316 if (!should_have_fast_elements) NormalizeElements(boilerplate); | 325 if (!should_have_fast_elements) NormalizeElements(boilerplate); |
| 317 | 326 |
| 318 { // Add the constant properties to the boilerplate. | 327 { // Add the constant properties to the boilerplate. |
| 319 int length = constant_properties->length(); | 328 int length = constant_properties->length(); |
| 320 OptimizedObjectForAddingMultipleProperties opt(boilerplate, | 329 OptimizedObjectForAddingMultipleProperties opt(boilerplate, |
| 321 length / 2, | 330 length / 2, |
| 322 !is_result_from_cache); | 331 !is_result_from_cache); |
| 323 for (int index = 0; index < length; index +=2) { | 332 for (int index = 0; index < length; index +=2) { |
| 324 Handle<Object> key(constant_properties->get(index+0)); | 333 Handle<Object> key(constant_properties->get(index+0), isolate); |
| 325 Handle<Object> value(constant_properties->get(index+1)); | 334 Handle<Object> value(constant_properties->get(index+1), isolate); |
| 326 if (value->IsFixedArray()) { | 335 if (value->IsFixedArray()) { |
| 327 // The value contains the constant_properties of a | 336 // The value contains the constant_properties of a |
| 328 // simple object literal. | 337 // simple object literal. |
| 329 Handle<FixedArray> array = Handle<FixedArray>::cast(value); | 338 Handle<FixedArray> array = Handle<FixedArray>::cast(value); |
| 330 value = CreateLiteralBoilerplate(literals, array); | 339 value = CreateLiteralBoilerplate(isolate, literals, array); |
| 331 if (value.is_null()) return value; | 340 if (value.is_null()) return value; |
| 332 } | 341 } |
| 333 Handle<Object> result; | 342 Handle<Object> result; |
| 334 uint32_t element_index = 0; | 343 uint32_t element_index = 0; |
| 335 if (key->IsSymbol()) { | 344 if (key->IsSymbol()) { |
| 336 if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) { | 345 if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) { |
| 337 // Array index as string (uint32). | 346 // Array index as string (uint32). |
| 338 result = SetOwnElement(boilerplate, | 347 result = SetOwnElement(boilerplate, |
| 339 element_index, | 348 element_index, |
| 340 value, | 349 value, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 351 element_index, | 360 element_index, |
| 352 value, | 361 value, |
| 353 kNonStrictMode); | 362 kNonStrictMode); |
| 354 } else { | 363 } else { |
| 355 // Non-uint32 number. | 364 // Non-uint32 number. |
| 356 ASSERT(key->IsNumber()); | 365 ASSERT(key->IsNumber()); |
| 357 double num = key->Number(); | 366 double num = key->Number(); |
| 358 char arr[100]; | 367 char arr[100]; |
| 359 Vector<char> buffer(arr, ARRAY_SIZE(arr)); | 368 Vector<char> buffer(arr, ARRAY_SIZE(arr)); |
| 360 const char* str = DoubleToCString(num, buffer); | 369 const char* str = DoubleToCString(num, buffer); |
| 361 Handle<String> name = Factory::NewStringFromAscii(CStrVector(str)); | 370 Handle<String> name = |
| 371 isolate->factory()->NewStringFromAscii(CStrVector(str)); |
| 362 result = SetLocalPropertyIgnoreAttributes(boilerplate, name, | 372 result = SetLocalPropertyIgnoreAttributes(boilerplate, name, |
| 363 value, NONE); | 373 value, NONE); |
| 364 } | 374 } |
| 365 // If setting the property on the boilerplate throws an | 375 // If setting the property on the boilerplate throws an |
| 366 // exception, the exception is converted to an empty handle in | 376 // exception, the exception is converted to an empty handle in |
| 367 // the handle based operations. In that case, we need to | 377 // the handle based operations. In that case, we need to |
| 368 // convert back to an exception. | 378 // convert back to an exception. |
| 369 if (result.is_null()) return result; | 379 if (result.is_null()) return result; |
| 370 } | 380 } |
| 371 } | 381 } |
| 372 | 382 |
| 373 return boilerplate; | 383 return boilerplate; |
| 374 } | 384 } |
| 375 | 385 |
| 376 | 386 |
| 377 static Handle<Object> CreateArrayLiteralBoilerplate( | 387 static Handle<Object> CreateArrayLiteralBoilerplate( |
| 388 Isolate* isolate, |
| 378 Handle<FixedArray> literals, | 389 Handle<FixedArray> literals, |
| 379 Handle<FixedArray> elements) { | 390 Handle<FixedArray> elements) { |
| 380 // Create the JSArray. | 391 // Create the JSArray. |
| 381 Handle<JSFunction> constructor( | 392 Handle<JSFunction> constructor( |
| 382 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); | 393 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); |
| 383 Handle<Object> object = Factory::NewJSObject(constructor); | 394 Handle<Object> object = isolate->factory()->NewJSObject(constructor); |
| 384 | 395 |
| 385 const bool is_cow = (elements->map() == Heap::fixed_cow_array_map()); | 396 const bool is_cow = |
| 397 (elements->map() == isolate->heap()->fixed_cow_array_map()); |
| 386 Handle<FixedArray> copied_elements = | 398 Handle<FixedArray> copied_elements = |
| 387 is_cow ? elements : Factory::CopyFixedArray(elements); | 399 is_cow ? elements : isolate->factory()->CopyFixedArray(elements); |
| 388 | 400 |
| 389 Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements); | 401 Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements); |
| 390 if (is_cow) { | 402 if (is_cow) { |
| 391 #ifdef DEBUG | 403 #ifdef DEBUG |
| 392 // Copy-on-write arrays must be shallow (and simple). | 404 // Copy-on-write arrays must be shallow (and simple). |
| 393 for (int i = 0; i < content->length(); i++) { | 405 for (int i = 0; i < content->length(); i++) { |
| 394 ASSERT(!content->get(i)->IsFixedArray()); | 406 ASSERT(!content->get(i)->IsFixedArray()); |
| 395 } | 407 } |
| 396 #endif | 408 #endif |
| 397 } else { | 409 } else { |
| 398 for (int i = 0; i < content->length(); i++) { | 410 for (int i = 0; i < content->length(); i++) { |
| 399 if (content->get(i)->IsFixedArray()) { | 411 if (content->get(i)->IsFixedArray()) { |
| 400 // The value contains the constant_properties of a | 412 // The value contains the constant_properties of a |
| 401 // simple object literal. | 413 // simple object literal. |
| 402 Handle<FixedArray> fa(FixedArray::cast(content->get(i))); | 414 Handle<FixedArray> fa(FixedArray::cast(content->get(i))); |
| 403 Handle<Object> result = | 415 Handle<Object> result = |
| 404 CreateLiteralBoilerplate(literals, fa); | 416 CreateLiteralBoilerplate(isolate, literals, fa); |
| 405 if (result.is_null()) return result; | 417 if (result.is_null()) return result; |
| 406 content->set(i, *result); | 418 content->set(i, *result); |
| 407 } | 419 } |
| 408 } | 420 } |
| 409 } | 421 } |
| 410 | 422 |
| 411 // Set the elements. | 423 // Set the elements. |
| 412 Handle<JSArray>::cast(object)->SetContent(*content); | 424 Handle<JSArray>::cast(object)->SetContent(*content); |
| 413 return object; | 425 return object; |
| 414 } | 426 } |
| 415 | 427 |
| 416 | 428 |
| 417 static Handle<Object> CreateLiteralBoilerplate( | 429 static Handle<Object> CreateLiteralBoilerplate( |
| 430 Isolate* isolate, |
| 418 Handle<FixedArray> literals, | 431 Handle<FixedArray> literals, |
| 419 Handle<FixedArray> array) { | 432 Handle<FixedArray> array) { |
| 420 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); | 433 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); |
| 421 switch (CompileTimeValue::GetType(array)) { | 434 switch (CompileTimeValue::GetType(array)) { |
| 422 case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS: | 435 case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS: |
| 423 return CreateObjectLiteralBoilerplate(literals, elements, true); | 436 return CreateObjectLiteralBoilerplate(isolate, literals, elements, true); |
| 424 case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS: | 437 case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS: |
| 425 return CreateObjectLiteralBoilerplate(literals, elements, false); | 438 return CreateObjectLiteralBoilerplate(isolate, literals, elements, false); |
| 426 case CompileTimeValue::ARRAY_LITERAL: | 439 case CompileTimeValue::ARRAY_LITERAL: |
| 427 return CreateArrayLiteralBoilerplate(literals, elements); | 440 return CreateArrayLiteralBoilerplate(isolate, literals, elements); |
| 428 default: | 441 default: |
| 429 UNREACHABLE(); | 442 UNREACHABLE(); |
| 430 return Handle<Object>::null(); | 443 return Handle<Object>::null(); |
| 431 } | 444 } |
| 432 } | 445 } |
| 433 | 446 |
| 434 | 447 |
| 435 static MaybeObject* Runtime_CreateArrayLiteralBoilerplate(Arguments args) { | 448 static MaybeObject* Runtime_CreateArrayLiteralBoilerplate( |
| 449 RUNTIME_CALLING_CONVENTION) { |
| 450 RUNTIME_GET_ISOLATE; |
| 436 // Takes a FixedArray of elements containing the literal elements of | 451 // Takes a FixedArray of elements containing the literal elements of |
| 437 // the array literal and produces JSArray with those elements. | 452 // the array literal and produces JSArray with those elements. |
| 438 // Additionally takes the literals array of the surrounding function | 453 // Additionally takes the literals array of the surrounding function |
| 439 // which contains the context from which to get the Array function | 454 // which contains the context from which to get the Array function |
| 440 // to use for creating the array literal. | 455 // to use for creating the array literal. |
| 441 HandleScope scope; | 456 HandleScope scope(isolate); |
| 442 ASSERT(args.length() == 3); | 457 ASSERT(args.length() == 3); |
| 443 CONVERT_ARG_CHECKED(FixedArray, literals, 0); | 458 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
| 444 CONVERT_SMI_CHECKED(literals_index, args[1]); | 459 CONVERT_SMI_CHECKED(literals_index, args[1]); |
| 445 CONVERT_ARG_CHECKED(FixedArray, elements, 2); | 460 CONVERT_ARG_CHECKED(FixedArray, elements, 2); |
| 446 | 461 |
| 447 Handle<Object> object = CreateArrayLiteralBoilerplate(literals, elements); | 462 Handle<Object> object = |
| 463 CreateArrayLiteralBoilerplate(isolate, literals, elements); |
| 448 if (object.is_null()) return Failure::Exception(); | 464 if (object.is_null()) return Failure::Exception(); |
| 449 | 465 |
| 450 // Update the functions literal and return the boilerplate. | 466 // Update the functions literal and return the boilerplate. |
| 451 literals->set(literals_index, *object); | 467 literals->set(literals_index, *object); |
| 452 return *object; | 468 return *object; |
| 453 } | 469 } |
| 454 | 470 |
| 455 | 471 |
| 456 static MaybeObject* Runtime_CreateObjectLiteral(Arguments args) { | 472 static MaybeObject* Runtime_CreateObjectLiteral(RUNTIME_CALLING_CONVENTION) { |
| 457 HandleScope scope; | 473 RUNTIME_GET_ISOLATE; |
| 474 HandleScope scope(isolate); |
| 458 ASSERT(args.length() == 4); | 475 ASSERT(args.length() == 4); |
| 459 CONVERT_ARG_CHECKED(FixedArray, literals, 0); | 476 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
| 460 CONVERT_SMI_CHECKED(literals_index, args[1]); | 477 CONVERT_SMI_CHECKED(literals_index, args[1]); |
| 461 CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2); | 478 CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2); |
| 462 CONVERT_SMI_CHECKED(fast_elements, args[3]); | 479 CONVERT_SMI_CHECKED(fast_elements, args[3]); |
| 463 bool should_have_fast_elements = fast_elements == 1; | 480 bool should_have_fast_elements = fast_elements == 1; |
| 464 | 481 |
| 465 // Check if boilerplate exists. If not, create it first. | 482 // Check if boilerplate exists. If not, create it first. |
| 466 Handle<Object> boilerplate(literals->get(literals_index)); | 483 Handle<Object> boilerplate(literals->get(literals_index), isolate); |
| 467 if (*boilerplate == Heap::undefined_value()) { | 484 if (*boilerplate == isolate->heap()->undefined_value()) { |
| 468 boilerplate = CreateObjectLiteralBoilerplate(literals, | 485 boilerplate = CreateObjectLiteralBoilerplate(isolate, |
| 486 literals, |
| 469 constant_properties, | 487 constant_properties, |
| 470 should_have_fast_elements); | 488 should_have_fast_elements); |
| 471 if (boilerplate.is_null()) return Failure::Exception(); | 489 if (boilerplate.is_null()) return Failure::Exception(); |
| 472 // Update the functions literal and return the boilerplate. | 490 // Update the functions literal and return the boilerplate. |
| 473 literals->set(literals_index, *boilerplate); | 491 literals->set(literals_index, *boilerplate); |
| 474 } | 492 } |
| 475 return DeepCopyBoilerplate(JSObject::cast(*boilerplate)); | 493 return DeepCopyBoilerplate(isolate, JSObject::cast(*boilerplate)); |
| 476 } | 494 } |
| 477 | 495 |
| 478 | 496 |
| 479 static MaybeObject* Runtime_CreateObjectLiteralShallow(Arguments args) { | 497 static MaybeObject* Runtime_CreateObjectLiteralShallow( |
| 480 HandleScope scope; | 498 RUNTIME_CALLING_CONVENTION) { |
| 499 RUNTIME_GET_ISOLATE; |
| 500 HandleScope scope(isolate); |
| 481 ASSERT(args.length() == 4); | 501 ASSERT(args.length() == 4); |
| 482 CONVERT_ARG_CHECKED(FixedArray, literals, 0); | 502 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
| 483 CONVERT_SMI_CHECKED(literals_index, args[1]); | 503 CONVERT_SMI_CHECKED(literals_index, args[1]); |
| 484 CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2); | 504 CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2); |
| 485 CONVERT_SMI_CHECKED(fast_elements, args[3]); | 505 CONVERT_SMI_CHECKED(fast_elements, args[3]); |
| 486 bool should_have_fast_elements = fast_elements == 1; | 506 bool should_have_fast_elements = fast_elements == 1; |
| 487 | 507 |
| 488 // Check if boilerplate exists. If not, create it first. | 508 // Check if boilerplate exists. If not, create it first. |
| 489 Handle<Object> boilerplate(literals->get(literals_index)); | 509 Handle<Object> boilerplate(literals->get(literals_index), isolate); |
| 490 if (*boilerplate == Heap::undefined_value()) { | 510 if (*boilerplate == isolate->heap()->undefined_value()) { |
| 491 boilerplate = CreateObjectLiteralBoilerplate(literals, | 511 boilerplate = CreateObjectLiteralBoilerplate(isolate, |
| 512 literals, |
| 492 constant_properties, | 513 constant_properties, |
| 493 should_have_fast_elements); | 514 should_have_fast_elements); |
| 494 if (boilerplate.is_null()) return Failure::Exception(); | 515 if (boilerplate.is_null()) return Failure::Exception(); |
| 495 // Update the functions literal and return the boilerplate. | 516 // Update the functions literal and return the boilerplate. |
| 496 literals->set(literals_index, *boilerplate); | 517 literals->set(literals_index, *boilerplate); |
| 497 } | 518 } |
| 498 return Heap::CopyJSObject(JSObject::cast(*boilerplate)); | 519 return isolate->heap()->CopyJSObject(JSObject::cast(*boilerplate)); |
| 499 } | 520 } |
| 500 | 521 |
| 501 | 522 |
| 502 static MaybeObject* Runtime_CreateArrayLiteral(Arguments args) { | 523 static MaybeObject* Runtime_CreateArrayLiteral(RUNTIME_CALLING_CONVENTION) { |
| 503 HandleScope scope; | 524 RUNTIME_GET_ISOLATE; |
| 525 HandleScope scope(isolate); |
| 504 ASSERT(args.length() == 3); | 526 ASSERT(args.length() == 3); |
| 505 CONVERT_ARG_CHECKED(FixedArray, literals, 0); | 527 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
| 506 CONVERT_SMI_CHECKED(literals_index, args[1]); | 528 CONVERT_SMI_CHECKED(literals_index, args[1]); |
| 507 CONVERT_ARG_CHECKED(FixedArray, elements, 2); | 529 CONVERT_ARG_CHECKED(FixedArray, elements, 2); |
| 508 | 530 |
| 509 // Check if boilerplate exists. If not, create it first. | 531 // Check if boilerplate exists. If not, create it first. |
| 510 Handle<Object> boilerplate(literals->get(literals_index)); | 532 Handle<Object> boilerplate(literals->get(literals_index), isolate); |
| 511 if (*boilerplate == Heap::undefined_value()) { | 533 if (*boilerplate == isolate->heap()->undefined_value()) { |
| 512 boilerplate = CreateArrayLiteralBoilerplate(literals, elements); | 534 boilerplate = CreateArrayLiteralBoilerplate(isolate, literals, elements); |
| 513 if (boilerplate.is_null()) return Failure::Exception(); | 535 if (boilerplate.is_null()) return Failure::Exception(); |
| 514 // Update the functions literal and return the boilerplate. | 536 // Update the functions literal and return the boilerplate. |
| 515 literals->set(literals_index, *boilerplate); | 537 literals->set(literals_index, *boilerplate); |
| 516 } | 538 } |
| 517 return DeepCopyBoilerplate(JSObject::cast(*boilerplate)); | 539 return DeepCopyBoilerplate(isolate, JSObject::cast(*boilerplate)); |
| 518 } | 540 } |
| 519 | 541 |
| 520 | 542 |
| 521 static MaybeObject* Runtime_CreateArrayLiteralShallow(Arguments args) { | 543 static MaybeObject* Runtime_CreateArrayLiteralShallow( |
| 522 HandleScope scope; | 544 RUNTIME_CALLING_CONVENTION) { |
| 545 RUNTIME_GET_ISOLATE; |
| 546 HandleScope scope(isolate); |
| 523 ASSERT(args.length() == 3); | 547 ASSERT(args.length() == 3); |
| 524 CONVERT_ARG_CHECKED(FixedArray, literals, 0); | 548 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
| 525 CONVERT_SMI_CHECKED(literals_index, args[1]); | 549 CONVERT_SMI_CHECKED(literals_index, args[1]); |
| 526 CONVERT_ARG_CHECKED(FixedArray, elements, 2); | 550 CONVERT_ARG_CHECKED(FixedArray, elements, 2); |
| 527 | 551 |
| 528 // Check if boilerplate exists. If not, create it first. | 552 // Check if boilerplate exists. If not, create it first. |
| 529 Handle<Object> boilerplate(literals->get(literals_index)); | 553 Handle<Object> boilerplate(literals->get(literals_index), isolate); |
| 530 if (*boilerplate == Heap::undefined_value()) { | 554 if (*boilerplate == isolate->heap()->undefined_value()) { |
| 531 boilerplate = CreateArrayLiteralBoilerplate(literals, elements); | 555 boilerplate = CreateArrayLiteralBoilerplate(isolate, literals, elements); |
| 532 if (boilerplate.is_null()) return Failure::Exception(); | 556 if (boilerplate.is_null()) return Failure::Exception(); |
| 533 // Update the functions literal and return the boilerplate. | 557 // Update the functions literal and return the boilerplate. |
| 534 literals->set(literals_index, *boilerplate); | 558 literals->set(literals_index, *boilerplate); |
| 535 } | 559 } |
| 536 if (JSObject::cast(*boilerplate)->elements()->map() == | 560 if (JSObject::cast(*boilerplate)->elements()->map() == |
| 537 Heap::fixed_cow_array_map()) { | 561 isolate->heap()->fixed_cow_array_map()) { |
| 538 Counters::cow_arrays_created_runtime.Increment(); | 562 COUNTERS->cow_arrays_created_runtime()->Increment(); |
| 539 } | 563 } |
| 540 return Heap::CopyJSObject(JSObject::cast(*boilerplate)); | 564 return isolate->heap()->CopyJSObject(JSObject::cast(*boilerplate)); |
| 541 } | 565 } |
| 542 | 566 |
| 543 | 567 |
| 544 static MaybeObject* Runtime_CreateCatchExtensionObject(Arguments args) { | 568 static MaybeObject* Runtime_CreateCatchExtensionObject( |
| 569 RUNTIME_CALLING_CONVENTION) { |
| 570 RUNTIME_GET_ISOLATE; |
| 545 ASSERT(args.length() == 2); | 571 ASSERT(args.length() == 2); |
| 546 CONVERT_CHECKED(String, key, args[0]); | 572 CONVERT_CHECKED(String, key, args[0]); |
| 547 Object* value = args[1]; | 573 Object* value = args[1]; |
| 548 // Create a catch context extension object. | 574 // Create a catch context extension object. |
| 549 JSFunction* constructor = | 575 JSFunction* constructor = |
| 550 Top::context()->global_context()->context_extension_function(); | 576 isolate->context()->global_context()-> |
| 577 context_extension_function(); |
| 551 Object* object; | 578 Object* object; |
| 552 { MaybeObject* maybe_object = Heap::AllocateJSObject(constructor); | 579 { MaybeObject* maybe_object = isolate->heap()->AllocateJSObject(constructor); |
| 553 if (!maybe_object->ToObject(&object)) return maybe_object; | 580 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 554 } | 581 } |
| 555 // Assign the exception value to the catch variable and make sure | 582 // Assign the exception value to the catch variable and make sure |
| 556 // that the catch variable is DontDelete. | 583 // that the catch variable is DontDelete. |
| 557 { MaybeObject* maybe_value = | 584 { MaybeObject* maybe_value = |
| 558 // Passing non-strict per ECMA-262 5th Ed. 12.14. Catch, bullet #4. | 585 // Passing non-strict per ECMA-262 5th Ed. 12.14. Catch, bullet #4. |
| 559 JSObject::cast(object)->SetProperty( | 586 JSObject::cast(object)->SetProperty( |
| 560 key, value, DONT_DELETE, kNonStrictMode); | 587 key, value, DONT_DELETE, kNonStrictMode); |
| 561 if (!maybe_value->ToObject(&value)) return maybe_value; | 588 if (!maybe_value->ToObject(&value)) return maybe_value; |
| 562 } | 589 } |
| 563 return object; | 590 return object; |
| 564 } | 591 } |
| 565 | 592 |
| 566 | 593 |
| 567 static MaybeObject* Runtime_ClassOf(Arguments args) { | 594 static MaybeObject* Runtime_ClassOf(RUNTIME_CALLING_CONVENTION) { |
| 595 RUNTIME_GET_ISOLATE; |
| 568 NoHandleAllocation ha; | 596 NoHandleAllocation ha; |
| 569 ASSERT(args.length() == 1); | 597 ASSERT(args.length() == 1); |
| 570 Object* obj = args[0]; | 598 Object* obj = args[0]; |
| 571 if (!obj->IsJSObject()) return Heap::null_value(); | 599 if (!obj->IsJSObject()) return isolate->heap()->null_value(); |
| 572 return JSObject::cast(obj)->class_name(); | 600 return JSObject::cast(obj)->class_name(); |
| 573 } | 601 } |
| 574 | 602 |
| 575 | 603 |
| 576 static MaybeObject* Runtime_IsInPrototypeChain(Arguments args) { | 604 static MaybeObject* Runtime_IsInPrototypeChain(RUNTIME_CALLING_CONVENTION) { |
| 605 RUNTIME_GET_ISOLATE; |
| 577 NoHandleAllocation ha; | 606 NoHandleAllocation ha; |
| 578 ASSERT(args.length() == 2); | 607 ASSERT(args.length() == 2); |
| 579 // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8). | 608 // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8). |
| 580 Object* O = args[0]; | 609 Object* O = args[0]; |
| 581 Object* V = args[1]; | 610 Object* V = args[1]; |
| 582 while (true) { | 611 while (true) { |
| 583 Object* prototype = V->GetPrototype(); | 612 Object* prototype = V->GetPrototype(); |
| 584 if (prototype->IsNull()) return Heap::false_value(); | 613 if (prototype->IsNull()) return isolate->heap()->false_value(); |
| 585 if (O == prototype) return Heap::true_value(); | 614 if (O == prototype) return isolate->heap()->true_value(); |
| 586 V = prototype; | 615 V = prototype; |
| 587 } | 616 } |
| 588 } | 617 } |
| 589 | 618 |
| 590 | 619 |
| 591 // Inserts an object as the hidden prototype of another object. | 620 // Inserts an object as the hidden prototype of another object. |
| 592 static MaybeObject* Runtime_SetHiddenPrototype(Arguments args) { | 621 static MaybeObject* Runtime_SetHiddenPrototype(RUNTIME_CALLING_CONVENTION) { |
| 622 RUNTIME_GET_ISOLATE; |
| 593 NoHandleAllocation ha; | 623 NoHandleAllocation ha; |
| 594 ASSERT(args.length() == 2); | 624 ASSERT(args.length() == 2); |
| 595 CONVERT_CHECKED(JSObject, jsobject, args[0]); | 625 CONVERT_CHECKED(JSObject, jsobject, args[0]); |
| 596 CONVERT_CHECKED(JSObject, proto, args[1]); | 626 CONVERT_CHECKED(JSObject, proto, args[1]); |
| 597 | 627 |
| 598 // Sanity checks. The old prototype (that we are replacing) could | 628 // Sanity checks. The old prototype (that we are replacing) could |
| 599 // theoretically be null, but if it is not null then check that we | 629 // theoretically be null, but if it is not null then check that we |
| 600 // didn't already install a hidden prototype here. | 630 // didn't already install a hidden prototype here. |
| 601 RUNTIME_ASSERT(!jsobject->GetPrototype()->IsHeapObject() || | 631 RUNTIME_ASSERT(!jsobject->GetPrototype()->IsHeapObject() || |
| 602 !HeapObject::cast(jsobject->GetPrototype())->map()->is_hidden_prototype()); | 632 !HeapObject::cast(jsobject->GetPrototype())->map()->is_hidden_prototype()); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 620 | 650 |
| 621 // Set proto's prototype to be the old prototype of the object. | 651 // Set proto's prototype to be the old prototype of the object. |
| 622 new_proto_map->set_prototype(jsobject->GetPrototype()); | 652 new_proto_map->set_prototype(jsobject->GetPrototype()); |
| 623 proto->set_map(new_proto_map); | 653 proto->set_map(new_proto_map); |
| 624 new_proto_map->set_is_hidden_prototype(); | 654 new_proto_map->set_is_hidden_prototype(); |
| 625 | 655 |
| 626 // Set the object's prototype to proto. | 656 // Set the object's prototype to proto. |
| 627 new_map->set_prototype(proto); | 657 new_map->set_prototype(proto); |
| 628 jsobject->set_map(new_map); | 658 jsobject->set_map(new_map); |
| 629 | 659 |
| 630 return Heap::undefined_value(); | 660 return isolate->heap()->undefined_value(); |
| 631 } | 661 } |
| 632 | 662 |
| 633 | 663 |
| 634 static MaybeObject* Runtime_IsConstructCall(Arguments args) { | 664 static MaybeObject* Runtime_IsConstructCall(RUNTIME_CALLING_CONVENTION) { |
| 665 RUNTIME_GET_ISOLATE; |
| 635 NoHandleAllocation ha; | 666 NoHandleAllocation ha; |
| 636 ASSERT(args.length() == 0); | 667 ASSERT(args.length() == 0); |
| 637 JavaScriptFrameIterator it; | 668 JavaScriptFrameIterator it; |
| 638 return Heap::ToBoolean(it.frame()->IsConstructor()); | 669 return isolate->heap()->ToBoolean(it.frame()->IsConstructor()); |
| 639 } | 670 } |
| 640 | 671 |
| 641 | 672 |
| 642 // Recursively traverses hidden prototypes if property is not found | 673 // Recursively traverses hidden prototypes if property is not found |
| 643 static void GetOwnPropertyImplementation(JSObject* obj, | 674 static void GetOwnPropertyImplementation(JSObject* obj, |
| 644 String* name, | 675 String* name, |
| 645 LookupResult* result) { | 676 LookupResult* result) { |
| 646 obj->LocalLookupRealNamedProperty(name, result); | 677 obj->LocalLookupRealNamedProperty(name, result); |
| 647 | 678 |
| 648 if (!result->IsProperty()) { | 679 if (!result->IsProperty()) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 675 | 706 |
| 676 | 707 |
| 677 static bool CheckAccess(JSObject* obj, | 708 static bool CheckAccess(JSObject* obj, |
| 678 String* name, | 709 String* name, |
| 679 LookupResult* result, | 710 LookupResult* result, |
| 680 v8::AccessType access_type) { | 711 v8::AccessType access_type) { |
| 681 ASSERT(result->IsProperty()); | 712 ASSERT(result->IsProperty()); |
| 682 | 713 |
| 683 JSObject* holder = result->holder(); | 714 JSObject* holder = result->holder(); |
| 684 JSObject* current = obj; | 715 JSObject* current = obj; |
| 716 Isolate* isolate = obj->GetIsolate(); |
| 685 while (true) { | 717 while (true) { |
| 686 if (current->IsAccessCheckNeeded() && | 718 if (current->IsAccessCheckNeeded() && |
| 687 !Top::MayNamedAccess(current, name, access_type)) { | 719 !isolate->MayNamedAccess(current, name, access_type)) { |
| 688 // Access check callback denied the access, but some properties | 720 // Access check callback denied the access, but some properties |
| 689 // can have a special permissions which override callbacks descision | 721 // can have a special permissions which override callbacks descision |
| 690 // (currently see v8::AccessControl). | 722 // (currently see v8::AccessControl). |
| 691 break; | 723 break; |
| 692 } | 724 } |
| 693 | 725 |
| 694 if (current == holder) { | 726 if (current == holder) { |
| 695 return true; | 727 return true; |
| 696 } | 728 } |
| 697 | 729 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 714 if (CheckAccessException(result, access_type)) { | 746 if (CheckAccessException(result, access_type)) { |
| 715 return true; | 747 return true; |
| 716 } | 748 } |
| 717 } | 749 } |
| 718 break; | 750 break; |
| 719 } | 751 } |
| 720 default: | 752 default: |
| 721 break; | 753 break; |
| 722 } | 754 } |
| 723 | 755 |
| 724 Top::ReportFailedAccessCheck(current, access_type); | 756 isolate->ReportFailedAccessCheck(current, access_type); |
| 725 return false; | 757 return false; |
| 726 } | 758 } |
| 727 | 759 |
| 728 | 760 |
| 729 // TODO(1095): we should traverse hidden prototype hierachy as well. | 761 // TODO(1095): we should traverse hidden prototype hierachy as well. |
| 730 static bool CheckElementAccess(JSObject* obj, | 762 static bool CheckElementAccess(JSObject* obj, |
| 731 uint32_t index, | 763 uint32_t index, |
| 732 v8::AccessType access_type) { | 764 v8::AccessType access_type) { |
| 733 if (obj->IsAccessCheckNeeded() && | 765 if (obj->IsAccessCheckNeeded() && |
| 734 !Top::MayIndexedAccess(obj, index, access_type)) { | 766 !obj->GetIsolate()->MayIndexedAccess(obj, index, access_type)) { |
| 735 return false; | 767 return false; |
| 736 } | 768 } |
| 737 | 769 |
| 738 return true; | 770 return true; |
| 739 } | 771 } |
| 740 | 772 |
| 741 | 773 |
| 742 // Enumerator used as indices into the array returned from GetOwnProperty | 774 // Enumerator used as indices into the array returned from GetOwnProperty |
| 743 enum PropertyDescriptorIndices { | 775 enum PropertyDescriptorIndices { |
| 744 IS_ACCESSOR_INDEX, | 776 IS_ACCESSOR_INDEX, |
| 745 VALUE_INDEX, | 777 VALUE_INDEX, |
| 746 GETTER_INDEX, | 778 GETTER_INDEX, |
| 747 SETTER_INDEX, | 779 SETTER_INDEX, |
| 748 WRITABLE_INDEX, | 780 WRITABLE_INDEX, |
| 749 ENUMERABLE_INDEX, | 781 ENUMERABLE_INDEX, |
| 750 CONFIGURABLE_INDEX, | 782 CONFIGURABLE_INDEX, |
| 751 DESCRIPTOR_SIZE | 783 DESCRIPTOR_SIZE |
| 752 }; | 784 }; |
| 753 | 785 |
| 754 // Returns an array with the property description: | 786 // Returns an array with the property description: |
| 755 // if args[1] is not a property on args[0] | 787 // if args[1] is not a property on args[0] |
| 756 // returns undefined | 788 // returns undefined |
| 757 // if args[1] is a data property on args[0] | 789 // if args[1] is a data property on args[0] |
| 758 // [false, value, Writeable, Enumerable, Configurable] | 790 // [false, value, Writeable, Enumerable, Configurable] |
| 759 // if args[1] is an accessor on args[0] | 791 // if args[1] is an accessor on args[0] |
| 760 // [true, GetFunction, SetFunction, Enumerable, Configurable] | 792 // [true, GetFunction, SetFunction, Enumerable, Configurable] |
| 761 static MaybeObject* Runtime_GetOwnProperty(Arguments args) { | 793 static MaybeObject* Runtime_GetOwnProperty(RUNTIME_CALLING_CONVENTION) { |
| 794 RUNTIME_GET_ISOLATE; |
| 762 ASSERT(args.length() == 2); | 795 ASSERT(args.length() == 2); |
| 763 HandleScope scope; | 796 Heap* heap = isolate->heap(); |
| 764 Handle<FixedArray> elms = Factory::NewFixedArray(DESCRIPTOR_SIZE); | 797 HandleScope scope(isolate); |
| 765 Handle<JSArray> desc = Factory::NewJSArrayWithElements(elms); | 798 Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE); |
| 799 Handle<JSArray> desc = isolate->factory()->NewJSArrayWithElements(elms); |
| 766 LookupResult result; | 800 LookupResult result; |
| 767 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 801 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 768 CONVERT_ARG_CHECKED(String, name, 1); | 802 CONVERT_ARG_CHECKED(String, name, 1); |
| 769 | 803 |
| 770 // This could be an element. | 804 // This could be an element. |
| 771 uint32_t index; | 805 uint32_t index; |
| 772 if (name->AsArrayIndex(&index)) { | 806 if (name->AsArrayIndex(&index)) { |
| 773 switch (obj->HasLocalElement(index)) { | 807 switch (obj->HasLocalElement(index)) { |
| 774 case JSObject::UNDEFINED_ELEMENT: | 808 case JSObject::UNDEFINED_ELEMENT: |
| 775 return Heap::undefined_value(); | 809 return heap->undefined_value(); |
| 776 | 810 |
| 777 case JSObject::STRING_CHARACTER_ELEMENT: { | 811 case JSObject::STRING_CHARACTER_ELEMENT: { |
| 778 // Special handling of string objects according to ECMAScript 5 | 812 // Special handling of string objects according to ECMAScript 5 |
| 779 // 15.5.5.2. Note that this might be a string object with elements | 813 // 15.5.5.2. Note that this might be a string object with elements |
| 780 // other than the actual string value. This is covered by the | 814 // other than the actual string value. This is covered by the |
| 781 // subsequent cases. | 815 // subsequent cases. |
| 782 Handle<JSValue> js_value = Handle<JSValue>::cast(obj); | 816 Handle<JSValue> js_value = Handle<JSValue>::cast(obj); |
| 783 Handle<String> str(String::cast(js_value->value())); | 817 Handle<String> str(String::cast(js_value->value())); |
| 784 Handle<String> substr = SubString(str, index, index + 1, NOT_TENURED); | 818 Handle<String> substr = SubString(str, index, index + 1, NOT_TENURED); |
| 785 | 819 |
| 786 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); | 820 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); |
| 787 elms->set(VALUE_INDEX, *substr); | 821 elms->set(VALUE_INDEX, *substr); |
| 788 elms->set(WRITABLE_INDEX, Heap::false_value()); | 822 elms->set(WRITABLE_INDEX, heap->false_value()); |
| 789 elms->set(ENUMERABLE_INDEX, Heap::false_value()); | 823 elms->set(ENUMERABLE_INDEX, heap->false_value()); |
| 790 elms->set(CONFIGURABLE_INDEX, Heap::false_value()); | 824 elms->set(CONFIGURABLE_INDEX, heap->false_value()); |
| 791 return *desc; | 825 return *desc; |
| 792 } | 826 } |
| 793 | 827 |
| 794 case JSObject::INTERCEPTED_ELEMENT: | 828 case JSObject::INTERCEPTED_ELEMENT: |
| 795 case JSObject::FAST_ELEMENT: { | 829 case JSObject::FAST_ELEMENT: { |
| 796 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); | 830 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); |
| 797 Handle<Object> value = GetElement(obj, index); | 831 Handle<Object> value = GetElement(obj, index); |
| 798 RETURN_IF_EMPTY_HANDLE(value); | 832 RETURN_IF_EMPTY_HANDLE(isolate, value); |
| 799 elms->set(VALUE_INDEX, *value); | 833 elms->set(VALUE_INDEX, *value); |
| 800 elms->set(WRITABLE_INDEX, Heap::true_value()); | 834 elms->set(WRITABLE_INDEX, heap->true_value()); |
| 801 elms->set(ENUMERABLE_INDEX, Heap::true_value()); | 835 elms->set(ENUMERABLE_INDEX, heap->true_value()); |
| 802 elms->set(CONFIGURABLE_INDEX, Heap::true_value()); | 836 elms->set(CONFIGURABLE_INDEX, heap->true_value()); |
| 803 return *desc; | 837 return *desc; |
| 804 } | 838 } |
| 805 | 839 |
| 806 case JSObject::DICTIONARY_ELEMENT: { | 840 case JSObject::DICTIONARY_ELEMENT: { |
| 807 Handle<JSObject> holder = obj; | 841 Handle<JSObject> holder = obj; |
| 808 if (obj->IsJSGlobalProxy()) { | 842 if (obj->IsJSGlobalProxy()) { |
| 809 Object* proto = obj->GetPrototype(); | 843 Object* proto = obj->GetPrototype(); |
| 810 if (proto->IsNull()) return Heap::undefined_value(); | 844 if (proto->IsNull()) return heap->undefined_value(); |
| 811 ASSERT(proto->IsJSGlobalObject()); | 845 ASSERT(proto->IsJSGlobalObject()); |
| 812 holder = Handle<JSObject>(JSObject::cast(proto)); | 846 holder = Handle<JSObject>(JSObject::cast(proto)); |
| 813 } | 847 } |
| 814 NumberDictionary* dictionary = holder->element_dictionary(); | 848 NumberDictionary* dictionary = holder->element_dictionary(); |
| 815 int entry = dictionary->FindEntry(index); | 849 int entry = dictionary->FindEntry(index); |
| 816 ASSERT(entry != NumberDictionary::kNotFound); | 850 ASSERT(entry != NumberDictionary::kNotFound); |
| 817 PropertyDetails details = dictionary->DetailsAt(entry); | 851 PropertyDetails details = dictionary->DetailsAt(entry); |
| 818 switch (details.type()) { | 852 switch (details.type()) { |
| 819 case CALLBACKS: { | 853 case CALLBACKS: { |
| 820 // This is an accessor property with getter and/or setter. | 854 // This is an accessor property with getter and/or setter. |
| 821 FixedArray* callbacks = | 855 FixedArray* callbacks = |
| 822 FixedArray::cast(dictionary->ValueAt(entry)); | 856 FixedArray::cast(dictionary->ValueAt(entry)); |
| 823 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); | 857 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); |
| 824 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) { | 858 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) { |
| 825 elms->set(GETTER_INDEX, callbacks->get(0)); | 859 elms->set(GETTER_INDEX, callbacks->get(0)); |
| 826 } | 860 } |
| 827 if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) { | 861 if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) { |
| 828 elms->set(SETTER_INDEX, callbacks->get(1)); | 862 elms->set(SETTER_INDEX, callbacks->get(1)); |
| 829 } | 863 } |
| 830 break; | 864 break; |
| 831 } | 865 } |
| 832 case NORMAL: { | 866 case NORMAL: { |
| 833 // This is a data property. | 867 // This is a data property. |
| 834 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); | 868 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); |
| 835 Handle<Object> value = GetElement(obj, index); | 869 Handle<Object> value = GetElement(obj, index); |
| 836 ASSERT(!value.is_null()); | 870 ASSERT(!value.is_null()); |
| 837 elms->set(VALUE_INDEX, *value); | 871 elms->set(VALUE_INDEX, *value); |
| 838 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!details.IsReadOnly())); | 872 elms->set(WRITABLE_INDEX, heap->ToBoolean(!details.IsReadOnly())); |
| 839 break; | 873 break; |
| 840 } | 874 } |
| 841 default: | 875 default: |
| 842 UNREACHABLE(); | 876 UNREACHABLE(); |
| 843 break; | 877 break; |
| 844 } | 878 } |
| 845 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!details.IsDontEnum())); | 879 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!details.IsDontEnum())); |
| 846 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!details.IsDontDelete())); | 880 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!details.IsDontDelete())); |
| 847 return *desc; | 881 return *desc; |
| 848 } | 882 } |
| 849 } | 883 } |
| 850 } | 884 } |
| 851 | 885 |
| 852 // Use recursive implementation to also traverse hidden prototypes | 886 // Use recursive implementation to also traverse hidden prototypes |
| 853 GetOwnPropertyImplementation(*obj, *name, &result); | 887 GetOwnPropertyImplementation(*obj, *name, &result); |
| 854 | 888 |
| 855 if (!result.IsProperty()) { | 889 if (!result.IsProperty()) { |
| 856 return Heap::undefined_value(); | 890 return heap->undefined_value(); |
| 857 } | 891 } |
| 858 | 892 |
| 859 if (!CheckAccess(*obj, *name, &result, v8::ACCESS_HAS)) { | 893 if (!CheckAccess(*obj, *name, &result, v8::ACCESS_HAS)) { |
| 860 return Heap::false_value(); | 894 return heap->false_value(); |
| 861 } | 895 } |
| 862 | 896 |
| 863 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!result.IsDontEnum())); | 897 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!result.IsDontEnum())); |
| 864 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!result.IsDontDelete())); | 898 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!result.IsDontDelete())); |
| 865 | 899 |
| 866 bool is_js_accessor = (result.type() == CALLBACKS) && | 900 bool is_js_accessor = (result.type() == CALLBACKS) && |
| 867 (result.GetCallbackObject()->IsFixedArray()); | 901 (result.GetCallbackObject()->IsFixedArray()); |
| 868 | 902 |
| 869 if (is_js_accessor) { | 903 if (is_js_accessor) { |
| 870 // __defineGetter__/__defineSetter__ callback. | 904 // __defineGetter__/__defineSetter__ callback. |
| 871 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); | 905 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); |
| 872 | 906 |
| 873 FixedArray* structure = FixedArray::cast(result.GetCallbackObject()); | 907 FixedArray* structure = FixedArray::cast(result.GetCallbackObject()); |
| 874 if (CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) { | 908 if (CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) { |
| 875 elms->set(GETTER_INDEX, structure->get(0)); | 909 elms->set(GETTER_INDEX, structure->get(0)); |
| 876 } | 910 } |
| 877 if (CheckAccess(*obj, *name, &result, v8::ACCESS_SET)) { | 911 if (CheckAccess(*obj, *name, &result, v8::ACCESS_SET)) { |
| 878 elms->set(SETTER_INDEX, structure->get(1)); | 912 elms->set(SETTER_INDEX, structure->get(1)); |
| 879 } | 913 } |
| 880 } else { | 914 } else { |
| 881 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); | 915 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); |
| 882 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly())); | 916 elms->set(WRITABLE_INDEX, heap->ToBoolean(!result.IsReadOnly())); |
| 883 | 917 |
| 884 PropertyAttributes attrs; | 918 PropertyAttributes attrs; |
| 885 Object* value; | 919 Object* value; |
| 886 // GetProperty will check access and report any violations. | 920 // GetProperty will check access and report any violations. |
| 887 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs); | 921 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs); |
| 888 if (!maybe_value->ToObject(&value)) return maybe_value; | 922 if (!maybe_value->ToObject(&value)) return maybe_value; |
| 889 } | 923 } |
| 890 elms->set(VALUE_INDEX, value); | 924 elms->set(VALUE_INDEX, value); |
| 891 } | 925 } |
| 892 | 926 |
| 893 return *desc; | 927 return *desc; |
| 894 } | 928 } |
| 895 | 929 |
| 896 | 930 |
| 897 static MaybeObject* Runtime_PreventExtensions(Arguments args) { | 931 static MaybeObject* Runtime_PreventExtensions(RUNTIME_CALLING_CONVENTION) { |
| 932 RUNTIME_GET_ISOLATE; |
| 898 ASSERT(args.length() == 1); | 933 ASSERT(args.length() == 1); |
| 899 CONVERT_CHECKED(JSObject, obj, args[0]); | 934 CONVERT_CHECKED(JSObject, obj, args[0]); |
| 900 return obj->PreventExtensions(); | 935 return obj->PreventExtensions(); |
| 901 } | 936 } |
| 902 | 937 |
| 903 | 938 |
| 904 static MaybeObject* Runtime_IsExtensible(Arguments args) { | 939 static MaybeObject* Runtime_IsExtensible(RUNTIME_CALLING_CONVENTION) { |
| 940 RUNTIME_GET_ISOLATE; |
| 905 ASSERT(args.length() == 1); | 941 ASSERT(args.length() == 1); |
| 906 CONVERT_CHECKED(JSObject, obj, args[0]); | 942 CONVERT_CHECKED(JSObject, obj, args[0]); |
| 907 if (obj->IsJSGlobalProxy()) { | 943 if (obj->IsJSGlobalProxy()) { |
| 908 Object* proto = obj->GetPrototype(); | 944 Object* proto = obj->GetPrototype(); |
| 909 if (proto->IsNull()) return Heap::false_value(); | 945 if (proto->IsNull()) return isolate->heap()->false_value(); |
| 910 ASSERT(proto->IsJSGlobalObject()); | 946 ASSERT(proto->IsJSGlobalObject()); |
| 911 obj = JSObject::cast(proto); | 947 obj = JSObject::cast(proto); |
| 912 } | 948 } |
| 913 return obj->map()->is_extensible() ? Heap::true_value() | 949 return obj->map()->is_extensible() ? isolate->heap()->true_value() |
| 914 : Heap::false_value(); | 950 : isolate->heap()->false_value(); |
| 915 } | 951 } |
| 916 | 952 |
| 917 | 953 |
| 918 static MaybeObject* Runtime_RegExpCompile(Arguments args) { | 954 static MaybeObject* Runtime_RegExpCompile(RUNTIME_CALLING_CONVENTION) { |
| 919 HandleScope scope; | 955 RUNTIME_GET_ISOLATE; |
| 956 HandleScope scope(isolate); |
| 920 ASSERT(args.length() == 3); | 957 ASSERT(args.length() == 3); |
| 921 CONVERT_ARG_CHECKED(JSRegExp, re, 0); | 958 CONVERT_ARG_CHECKED(JSRegExp, re, 0); |
| 922 CONVERT_ARG_CHECKED(String, pattern, 1); | 959 CONVERT_ARG_CHECKED(String, pattern, 1); |
| 923 CONVERT_ARG_CHECKED(String, flags, 2); | 960 CONVERT_ARG_CHECKED(String, flags, 2); |
| 924 Handle<Object> result = RegExpImpl::Compile(re, pattern, flags); | 961 Handle<Object> result = RegExpImpl::Compile(re, pattern, flags); |
| 925 if (result.is_null()) return Failure::Exception(); | 962 if (result.is_null()) return Failure::Exception(); |
| 926 return *result; | 963 return *result; |
| 927 } | 964 } |
| 928 | 965 |
| 929 | 966 |
| 930 static MaybeObject* Runtime_CreateApiFunction(Arguments args) { | 967 static MaybeObject* Runtime_CreateApiFunction(RUNTIME_CALLING_CONVENTION) { |
| 931 HandleScope scope; | 968 RUNTIME_GET_ISOLATE; |
| 969 HandleScope scope(isolate); |
| 932 ASSERT(args.length() == 1); | 970 ASSERT(args.length() == 1); |
| 933 CONVERT_ARG_CHECKED(FunctionTemplateInfo, data, 0); | 971 CONVERT_ARG_CHECKED(FunctionTemplateInfo, data, 0); |
| 934 return *Factory::CreateApiFunction(data); | 972 return *isolate->factory()->CreateApiFunction(data); |
| 935 } | 973 } |
| 936 | 974 |
| 937 | 975 |
| 938 static MaybeObject* Runtime_IsTemplate(Arguments args) { | 976 static MaybeObject* Runtime_IsTemplate(RUNTIME_CALLING_CONVENTION) { |
| 977 RUNTIME_GET_ISOLATE; |
| 939 ASSERT(args.length() == 1); | 978 ASSERT(args.length() == 1); |
| 940 Object* arg = args[0]; | 979 Object* arg = args[0]; |
| 941 bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo(); | 980 bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo(); |
| 942 return Heap::ToBoolean(result); | 981 return isolate->heap()->ToBoolean(result); |
| 943 } | 982 } |
| 944 | 983 |
| 945 | 984 |
| 946 static MaybeObject* Runtime_GetTemplateField(Arguments args) { | 985 static MaybeObject* Runtime_GetTemplateField(RUNTIME_CALLING_CONVENTION) { |
| 986 RUNTIME_GET_ISOLATE; |
| 947 ASSERT(args.length() == 2); | 987 ASSERT(args.length() == 2); |
| 948 CONVERT_CHECKED(HeapObject, templ, args[0]); | 988 CONVERT_CHECKED(HeapObject, templ, args[0]); |
| 949 CONVERT_CHECKED(Smi, field, args[1]); | 989 CONVERT_CHECKED(Smi, field, args[1]); |
| 950 int index = field->value(); | 990 int index = field->value(); |
| 951 int offset = index * kPointerSize + HeapObject::kHeaderSize; | 991 int offset = index * kPointerSize + HeapObject::kHeaderSize; |
| 952 InstanceType type = templ->map()->instance_type(); | 992 InstanceType type = templ->map()->instance_type(); |
| 953 RUNTIME_ASSERT(type == FUNCTION_TEMPLATE_INFO_TYPE || | 993 RUNTIME_ASSERT(type == FUNCTION_TEMPLATE_INFO_TYPE || |
| 954 type == OBJECT_TEMPLATE_INFO_TYPE); | 994 type == OBJECT_TEMPLATE_INFO_TYPE); |
| 955 RUNTIME_ASSERT(offset > 0); | 995 RUNTIME_ASSERT(offset > 0); |
| 956 if (type == FUNCTION_TEMPLATE_INFO_TYPE) { | 996 if (type == FUNCTION_TEMPLATE_INFO_TYPE) { |
| 957 RUNTIME_ASSERT(offset < FunctionTemplateInfo::kSize); | 997 RUNTIME_ASSERT(offset < FunctionTemplateInfo::kSize); |
| 958 } else { | 998 } else { |
| 959 RUNTIME_ASSERT(offset < ObjectTemplateInfo::kSize); | 999 RUNTIME_ASSERT(offset < ObjectTemplateInfo::kSize); |
| 960 } | 1000 } |
| 961 return *HeapObject::RawField(templ, offset); | 1001 return *HeapObject::RawField(templ, offset); |
| 962 } | 1002 } |
| 963 | 1003 |
| 964 | 1004 |
| 965 static MaybeObject* Runtime_DisableAccessChecks(Arguments args) { | 1005 static MaybeObject* Runtime_DisableAccessChecks(RUNTIME_CALLING_CONVENTION) { |
| 1006 RUNTIME_GET_ISOLATE; |
| 966 ASSERT(args.length() == 1); | 1007 ASSERT(args.length() == 1); |
| 967 CONVERT_CHECKED(HeapObject, object, args[0]); | 1008 CONVERT_CHECKED(HeapObject, object, args[0]); |
| 968 Map* old_map = object->map(); | 1009 Map* old_map = object->map(); |
| 969 bool needs_access_checks = old_map->is_access_check_needed(); | 1010 bool needs_access_checks = old_map->is_access_check_needed(); |
| 970 if (needs_access_checks) { | 1011 if (needs_access_checks) { |
| 971 // Copy map so it won't interfere constructor's initial map. | 1012 // Copy map so it won't interfere constructor's initial map. |
| 972 Object* new_map; | 1013 Object* new_map; |
| 973 { MaybeObject* maybe_new_map = old_map->CopyDropTransitions(); | 1014 { MaybeObject* maybe_new_map = old_map->CopyDropTransitions(); |
| 974 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; | 1015 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
| 975 } | 1016 } |
| 976 | 1017 |
| 977 Map::cast(new_map)->set_is_access_check_needed(false); | 1018 Map::cast(new_map)->set_is_access_check_needed(false); |
| 978 object->set_map(Map::cast(new_map)); | 1019 object->set_map(Map::cast(new_map)); |
| 979 } | 1020 } |
| 980 return needs_access_checks ? Heap::true_value() : Heap::false_value(); | 1021 return needs_access_checks ? isolate->heap()->true_value() |
| 1022 : isolate->heap()->false_value(); |
| 981 } | 1023 } |
| 982 | 1024 |
| 983 | 1025 |
| 984 static MaybeObject* Runtime_EnableAccessChecks(Arguments args) { | 1026 static MaybeObject* Runtime_EnableAccessChecks(RUNTIME_CALLING_CONVENTION) { |
| 1027 RUNTIME_GET_ISOLATE; |
| 985 ASSERT(args.length() == 1); | 1028 ASSERT(args.length() == 1); |
| 986 CONVERT_CHECKED(HeapObject, object, args[0]); | 1029 CONVERT_CHECKED(HeapObject, object, args[0]); |
| 987 Map* old_map = object->map(); | 1030 Map* old_map = object->map(); |
| 988 if (!old_map->is_access_check_needed()) { | 1031 if (!old_map->is_access_check_needed()) { |
| 989 // Copy map so it won't interfere constructor's initial map. | 1032 // Copy map so it won't interfere constructor's initial map. |
| 990 Object* new_map; | 1033 Object* new_map; |
| 991 { MaybeObject* maybe_new_map = old_map->CopyDropTransitions(); | 1034 { MaybeObject* maybe_new_map = old_map->CopyDropTransitions(); |
| 992 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; | 1035 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
| 993 } | 1036 } |
| 994 | 1037 |
| 995 Map::cast(new_map)->set_is_access_check_needed(true); | 1038 Map::cast(new_map)->set_is_access_check_needed(true); |
| 996 object->set_map(Map::cast(new_map)); | 1039 object->set_map(Map::cast(new_map)); |
| 997 } | 1040 } |
| 998 return Heap::undefined_value(); | 1041 return isolate->heap()->undefined_value(); |
| 999 } | 1042 } |
| 1000 | 1043 |
| 1001 | 1044 |
| 1002 static Failure* ThrowRedeclarationError(const char* type, Handle<String> name) { | 1045 static Failure* ThrowRedeclarationError(Isolate* isolate, |
| 1003 HandleScope scope; | 1046 const char* type, |
| 1004 Handle<Object> type_handle = Factory::NewStringFromAscii(CStrVector(type)); | 1047 Handle<String> name) { |
| 1048 HandleScope scope(isolate); |
| 1049 Handle<Object> type_handle = |
| 1050 isolate->factory()->NewStringFromAscii(CStrVector(type)); |
| 1005 Handle<Object> args[2] = { type_handle, name }; | 1051 Handle<Object> args[2] = { type_handle, name }; |
| 1006 Handle<Object> error = | 1052 Handle<Object> error = |
| 1007 Factory::NewTypeError("redeclaration", HandleVector(args, 2)); | 1053 isolate->factory()->NewTypeError("redeclaration", HandleVector(args, 2)); |
| 1008 return Top::Throw(*error); | 1054 return isolate->Throw(*error); |
| 1009 } | 1055 } |
| 1010 | 1056 |
| 1011 | 1057 |
| 1012 static MaybeObject* Runtime_DeclareGlobals(Arguments args) { | 1058 static MaybeObject* Runtime_DeclareGlobals(RUNTIME_CALLING_CONVENTION) { |
| 1059 RUNTIME_GET_ISOLATE; |
| 1013 ASSERT(args.length() == 4); | 1060 ASSERT(args.length() == 4); |
| 1014 HandleScope scope; | 1061 HandleScope scope(isolate); |
| 1015 Handle<GlobalObject> global = Handle<GlobalObject>(Top::context()->global()); | 1062 Handle<GlobalObject> global = Handle<GlobalObject>( |
| 1063 isolate->context()->global()); |
| 1016 | 1064 |
| 1017 Handle<Context> context = args.at<Context>(0); | 1065 Handle<Context> context = args.at<Context>(0); |
| 1018 CONVERT_ARG_CHECKED(FixedArray, pairs, 1); | 1066 CONVERT_ARG_CHECKED(FixedArray, pairs, 1); |
| 1019 bool is_eval = Smi::cast(args[2])->value() == 1; | 1067 bool is_eval = Smi::cast(args[2])->value() == 1; |
| 1020 StrictModeFlag strict_mode = | 1068 StrictModeFlag strict_mode = |
| 1021 static_cast<StrictModeFlag>(Smi::cast(args[3])->value()); | 1069 static_cast<StrictModeFlag>(Smi::cast(args[3])->value()); |
| 1022 ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode); | 1070 ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode); |
| 1023 | 1071 |
| 1024 // Compute the property attributes. According to ECMA-262, section | 1072 // Compute the property attributes. According to ECMA-262, section |
| 1025 // 13, page 71, the property must be read-only and | 1073 // 13, page 71, the property must be read-only and |
| 1026 // non-deletable. However, neither SpiderMonkey nor KJS creates the | 1074 // non-deletable. However, neither SpiderMonkey nor KJS creates the |
| 1027 // property as read-only, so we don't either. | 1075 // property as read-only, so we don't either. |
| 1028 PropertyAttributes base = is_eval ? NONE : DONT_DELETE; | 1076 PropertyAttributes base = is_eval ? NONE : DONT_DELETE; |
| 1029 | 1077 |
| 1030 // Traverse the name/value pairs and set the properties. | 1078 // Traverse the name/value pairs and set the properties. |
| 1031 int length = pairs->length(); | 1079 int length = pairs->length(); |
| 1032 for (int i = 0; i < length; i += 2) { | 1080 for (int i = 0; i < length; i += 2) { |
| 1033 HandleScope scope; | 1081 HandleScope scope(isolate); |
| 1034 Handle<String> name(String::cast(pairs->get(i))); | 1082 Handle<String> name(String::cast(pairs->get(i))); |
| 1035 Handle<Object> value(pairs->get(i + 1)); | 1083 Handle<Object> value(pairs->get(i + 1), isolate); |
| 1036 | 1084 |
| 1037 // We have to declare a global const property. To capture we only | 1085 // We have to declare a global const property. To capture we only |
| 1038 // assign to it when evaluating the assignment for "const x = | 1086 // assign to it when evaluating the assignment for "const x = |
| 1039 // <expr>" the initial value is the hole. | 1087 // <expr>" the initial value is the hole. |
| 1040 bool is_const_property = value->IsTheHole(); | 1088 bool is_const_property = value->IsTheHole(); |
| 1041 | 1089 |
| 1042 if (value->IsUndefined() || is_const_property) { | 1090 if (value->IsUndefined() || is_const_property) { |
| 1043 // Lookup the property in the global object, and don't set the | 1091 // Lookup the property in the global object, and don't set the |
| 1044 // value of the variable if the property is already there. | 1092 // value of the variable if the property is already there. |
| 1045 LookupResult lookup; | 1093 LookupResult lookup; |
| 1046 global->Lookup(*name, &lookup); | 1094 global->Lookup(*name, &lookup); |
| 1047 if (lookup.IsProperty()) { | 1095 if (lookup.IsProperty()) { |
| 1048 // Determine if the property is local by comparing the holder | 1096 // Determine if the property is local by comparing the holder |
| 1049 // against the global object. The information will be used to | 1097 // against the global object. The information will be used to |
| 1050 // avoid throwing re-declaration errors when declaring | 1098 // avoid throwing re-declaration errors when declaring |
| 1051 // variables or constants that exist in the prototype chain. | 1099 // variables or constants that exist in the prototype chain. |
| 1052 bool is_local = (*global == lookup.holder()); | 1100 bool is_local = (*global == lookup.holder()); |
| 1053 // Get the property attributes and determine if the property is | 1101 // Get the property attributes and determine if the property is |
| 1054 // read-only. | 1102 // read-only. |
| 1055 PropertyAttributes attributes = global->GetPropertyAttribute(*name); | 1103 PropertyAttributes attributes = global->GetPropertyAttribute(*name); |
| 1056 bool is_read_only = (attributes & READ_ONLY) != 0; | 1104 bool is_read_only = (attributes & READ_ONLY) != 0; |
| 1057 if (lookup.type() == INTERCEPTOR) { | 1105 if (lookup.type() == INTERCEPTOR) { |
| 1058 // If the interceptor says the property is there, we | 1106 // If the interceptor says the property is there, we |
| 1059 // just return undefined without overwriting the property. | 1107 // just return undefined without overwriting the property. |
| 1060 // Otherwise, we continue to setting the property. | 1108 // Otherwise, we continue to setting the property. |
| 1061 if (attributes != ABSENT) { | 1109 if (attributes != ABSENT) { |
| 1062 // Check if the existing property conflicts with regards to const. | 1110 // Check if the existing property conflicts with regards to const. |
| 1063 if (is_local && (is_read_only || is_const_property)) { | 1111 if (is_local && (is_read_only || is_const_property)) { |
| 1064 const char* type = (is_read_only) ? "const" : "var"; | 1112 const char* type = (is_read_only) ? "const" : "var"; |
| 1065 return ThrowRedeclarationError(type, name); | 1113 return ThrowRedeclarationError(isolate, type, name); |
| 1066 }; | 1114 }; |
| 1067 // The property already exists without conflicting: Go to | 1115 // The property already exists without conflicting: Go to |
| 1068 // the next declaration. | 1116 // the next declaration. |
| 1069 continue; | 1117 continue; |
| 1070 } | 1118 } |
| 1071 // Fall-through and introduce the absent property by using | 1119 // Fall-through and introduce the absent property by using |
| 1072 // SetProperty. | 1120 // SetProperty. |
| 1073 } else { | 1121 } else { |
| 1074 // For const properties, we treat a callback with this name | 1122 // For const properties, we treat a callback with this name |
| 1075 // even in the prototype as a conflicting declaration. | 1123 // even in the prototype as a conflicting declaration. |
| 1076 if (is_const_property && (lookup.type() == CALLBACKS)) { | 1124 if (is_const_property && (lookup.type() == CALLBACKS)) { |
| 1077 return ThrowRedeclarationError("const", name); | 1125 return ThrowRedeclarationError(isolate, "const", name); |
| 1078 } | 1126 } |
| 1079 // Otherwise, we check for locally conflicting declarations. | 1127 // Otherwise, we check for locally conflicting declarations. |
| 1080 if (is_local && (is_read_only || is_const_property)) { | 1128 if (is_local && (is_read_only || is_const_property)) { |
| 1081 const char* type = (is_read_only) ? "const" : "var"; | 1129 const char* type = (is_read_only) ? "const" : "var"; |
| 1082 return ThrowRedeclarationError(type, name); | 1130 return ThrowRedeclarationError(isolate, type, name); |
| 1083 } | 1131 } |
| 1084 // The property already exists without conflicting: Go to | 1132 // The property already exists without conflicting: Go to |
| 1085 // the next declaration. | 1133 // the next declaration. |
| 1086 continue; | 1134 continue; |
| 1087 } | 1135 } |
| 1088 } | 1136 } |
| 1089 } else { | 1137 } else { |
| 1090 // Copy the function and update its context. Use it as value. | 1138 // Copy the function and update its context. Use it as value. |
| 1091 Handle<SharedFunctionInfo> shared = | 1139 Handle<SharedFunctionInfo> shared = |
| 1092 Handle<SharedFunctionInfo>::cast(value); | 1140 Handle<SharedFunctionInfo>::cast(value); |
| 1093 Handle<JSFunction> function = | 1141 Handle<JSFunction> function = |
| 1094 Factory::NewFunctionFromSharedFunctionInfo(shared, context, TENURED); | 1142 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, |
| 1143 context, |
| 1144 TENURED); |
| 1095 value = function; | 1145 value = function; |
| 1096 } | 1146 } |
| 1097 | 1147 |
| 1098 LookupResult lookup; | 1148 LookupResult lookup; |
| 1099 global->LocalLookup(*name, &lookup); | 1149 global->LocalLookup(*name, &lookup); |
| 1100 | 1150 |
| 1101 PropertyAttributes attributes = is_const_property | 1151 PropertyAttributes attributes = is_const_property |
| 1102 ? static_cast<PropertyAttributes>(base | READ_ONLY) | 1152 ? static_cast<PropertyAttributes>(base | READ_ONLY) |
| 1103 : base; | 1153 : base; |
| 1104 | 1154 |
| 1105 // There's a local property that we need to overwrite because | 1155 // There's a local property that we need to overwrite because |
| 1106 // we're either declaring a function or there's an interceptor | 1156 // we're either declaring a function or there's an interceptor |
| 1107 // that claims the property is absent. | 1157 // that claims the property is absent. |
| 1108 // | 1158 // |
| 1109 // Check for conflicting re-declarations. We cannot have | 1159 // Check for conflicting re-declarations. We cannot have |
| 1110 // conflicting types in case of intercepted properties because | 1160 // conflicting types in case of intercepted properties because |
| 1111 // they are absent. | 1161 // they are absent. |
| 1112 if (lookup.IsProperty() && | 1162 if (lookup.IsProperty() && |
| 1113 (lookup.type() != INTERCEPTOR) && | 1163 (lookup.type() != INTERCEPTOR) && |
| 1114 (lookup.IsReadOnly() || is_const_property)) { | 1164 (lookup.IsReadOnly() || is_const_property)) { |
| 1115 const char* type = (lookup.IsReadOnly()) ? "const" : "var"; | 1165 const char* type = (lookup.IsReadOnly()) ? "const" : "var"; |
| 1116 return ThrowRedeclarationError(type, name); | 1166 return ThrowRedeclarationError(isolate, type, name); |
| 1117 } | 1167 } |
| 1118 | 1168 |
| 1119 // Safari does not allow the invocation of callback setters for | 1169 // Safari does not allow the invocation of callback setters for |
| 1120 // function declarations. To mimic this behavior, we do not allow | 1170 // function declarations. To mimic this behavior, we do not allow |
| 1121 // the invocation of setters for function values. This makes a | 1171 // the invocation of setters for function values. This makes a |
| 1122 // difference for global functions with the same names as event | 1172 // difference for global functions with the same names as event |
| 1123 // handlers such as "function onload() {}". Firefox does call the | 1173 // handlers such as "function onload() {}". Firefox does call the |
| 1124 // onload setter in those case and Safari does not. We follow | 1174 // onload setter in those case and Safari does not. We follow |
| 1125 // Safari for compatibility. | 1175 // Safari for compatibility. |
| 1126 if (value->IsJSFunction()) { | 1176 if (value->IsJSFunction()) { |
| 1127 // Do not change DONT_DELETE to false from true. | 1177 // Do not change DONT_DELETE to false from true. |
| 1128 if (lookup.IsProperty() && (lookup.type() != INTERCEPTOR)) { | 1178 if (lookup.IsProperty() && (lookup.type() != INTERCEPTOR)) { |
| 1129 attributes = static_cast<PropertyAttributes>( | 1179 attributes = static_cast<PropertyAttributes>( |
| 1130 attributes | (lookup.GetAttributes() & DONT_DELETE)); | 1180 attributes | (lookup.GetAttributes() & DONT_DELETE)); |
| 1131 } | 1181 } |
| 1132 RETURN_IF_EMPTY_HANDLE(SetLocalPropertyIgnoreAttributes(global, | 1182 RETURN_IF_EMPTY_HANDLE(isolate, |
| 1183 SetLocalPropertyIgnoreAttributes(global, |
| 1133 name, | 1184 name, |
| 1134 value, | 1185 value, |
| 1135 attributes)); | 1186 attributes)); |
| 1136 } else { | 1187 } else { |
| 1137 RETURN_IF_EMPTY_HANDLE(SetProperty(global, | 1188 RETURN_IF_EMPTY_HANDLE(isolate, |
| 1189 SetProperty(global, |
| 1138 name, | 1190 name, |
| 1139 value, | 1191 value, |
| 1140 attributes, | 1192 attributes, |
| 1141 strict_mode)); | 1193 strict_mode)); |
| 1142 } | 1194 } |
| 1143 } | 1195 } |
| 1144 | 1196 |
| 1145 ASSERT(!Top::has_pending_exception()); | 1197 ASSERT(!isolate->has_pending_exception()); |
| 1146 return Heap::undefined_value(); | 1198 return isolate->heap()->undefined_value(); |
| 1147 } | 1199 } |
| 1148 | 1200 |
| 1149 | 1201 |
| 1150 static MaybeObject* Runtime_DeclareContextSlot(Arguments args) { | 1202 static MaybeObject* Runtime_DeclareContextSlot(RUNTIME_CALLING_CONVENTION) { |
| 1151 HandleScope scope; | 1203 RUNTIME_GET_ISOLATE; |
| 1204 HandleScope scope(isolate); |
| 1152 ASSERT(args.length() == 4); | 1205 ASSERT(args.length() == 4); |
| 1153 | 1206 |
| 1154 CONVERT_ARG_CHECKED(Context, context, 0); | 1207 CONVERT_ARG_CHECKED(Context, context, 0); |
| 1155 Handle<String> name(String::cast(args[1])); | 1208 Handle<String> name(String::cast(args[1])); |
| 1156 PropertyAttributes mode = | 1209 PropertyAttributes mode = |
| 1157 static_cast<PropertyAttributes>(Smi::cast(args[2])->value()); | 1210 static_cast<PropertyAttributes>(Smi::cast(args[2])->value()); |
| 1158 RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE); | 1211 RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE); |
| 1159 Handle<Object> initial_value(args[3]); | 1212 Handle<Object> initial_value(args[3], isolate); |
| 1160 | 1213 |
| 1161 // Declarations are always done in the function context. | 1214 // Declarations are always done in the function context. |
| 1162 context = Handle<Context>(context->fcontext()); | 1215 context = Handle<Context>(context->fcontext()); |
| 1163 | 1216 |
| 1164 int index; | 1217 int index; |
| 1165 PropertyAttributes attributes; | 1218 PropertyAttributes attributes; |
| 1166 ContextLookupFlags flags = DONT_FOLLOW_CHAINS; | 1219 ContextLookupFlags flags = DONT_FOLLOW_CHAINS; |
| 1167 Handle<Object> holder = | 1220 Handle<Object> holder = |
| 1168 context->Lookup(name, flags, &index, &attributes); | 1221 context->Lookup(name, flags, &index, &attributes); |
| 1169 | 1222 |
| 1170 if (attributes != ABSENT) { | 1223 if (attributes != ABSENT) { |
| 1171 // The name was declared before; check for conflicting | 1224 // The name was declared before; check for conflicting |
| 1172 // re-declarations: This is similar to the code in parser.cc in | 1225 // re-declarations: This is similar to the code in parser.cc in |
| 1173 // the AstBuildingParser::Declare function. | 1226 // the AstBuildingParser::Declare function. |
| 1174 if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) { | 1227 if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) { |
| 1175 // Functions are not read-only. | 1228 // Functions are not read-only. |
| 1176 ASSERT(mode != READ_ONLY || initial_value->IsTheHole()); | 1229 ASSERT(mode != READ_ONLY || initial_value->IsTheHole()); |
| 1177 const char* type = ((attributes & READ_ONLY) != 0) ? "const" : "var"; | 1230 const char* type = ((attributes & READ_ONLY) != 0) ? "const" : "var"; |
| 1178 return ThrowRedeclarationError(type, name); | 1231 return ThrowRedeclarationError(isolate, type, name); |
| 1179 } | 1232 } |
| 1180 | 1233 |
| 1181 // Initialize it if necessary. | 1234 // Initialize it if necessary. |
| 1182 if (*initial_value != NULL) { | 1235 if (*initial_value != NULL) { |
| 1183 if (index >= 0) { | 1236 if (index >= 0) { |
| 1184 // The variable or constant context slot should always be in | 1237 // The variable or constant context slot should always be in |
| 1185 // the function context or the arguments object. | 1238 // the function context or the arguments object. |
| 1186 if (holder->IsContext()) { | 1239 if (holder->IsContext()) { |
| 1187 ASSERT(holder.is_identical_to(context)); | 1240 ASSERT(holder.is_identical_to(context)); |
| 1188 if (((attributes & READ_ONLY) == 0) || | 1241 if (((attributes & READ_ONLY) == 0) || |
| 1189 context->get(index)->IsTheHole()) { | 1242 context->get(index)->IsTheHole()) { |
| 1190 context->set(index, *initial_value); | 1243 context->set(index, *initial_value); |
| 1191 } | 1244 } |
| 1192 } else { | 1245 } else { |
| 1193 // The holder is an arguments object. | 1246 // The holder is an arguments object. |
| 1194 Handle<JSObject> arguments(Handle<JSObject>::cast(holder)); | 1247 Handle<JSObject> arguments(Handle<JSObject>::cast(holder)); |
| 1195 Handle<Object> result = SetElement(arguments, index, initial_value, | 1248 Handle<Object> result = SetElement(arguments, index, initial_value, |
| 1196 kNonStrictMode); | 1249 kNonStrictMode); |
| 1197 if (result.is_null()) return Failure::Exception(); | 1250 if (result.is_null()) return Failure::Exception(); |
| 1198 } | 1251 } |
| 1199 } else { | 1252 } else { |
| 1200 // Slow case: The property is not in the FixedArray part of the context. | 1253 // Slow case: The property is not in the FixedArray part of the context. |
| 1201 Handle<JSObject> context_ext = Handle<JSObject>::cast(holder); | 1254 Handle<JSObject> context_ext = Handle<JSObject>::cast(holder); |
| 1202 RETURN_IF_EMPTY_HANDLE( | 1255 RETURN_IF_EMPTY_HANDLE( |
| 1256 isolate, |
| 1203 SetProperty(context_ext, name, initial_value, | 1257 SetProperty(context_ext, name, initial_value, |
| 1204 mode, kNonStrictMode)); | 1258 mode, kNonStrictMode)); |
| 1205 } | 1259 } |
| 1206 } | 1260 } |
| 1207 | 1261 |
| 1208 } else { | 1262 } else { |
| 1209 // The property is not in the function context. It needs to be | 1263 // The property is not in the function context. It needs to be |
| 1210 // "declared" in the function context's extension context, or in the | 1264 // "declared" in the function context's extension context, or in the |
| 1211 // global context. | 1265 // global context. |
| 1212 Handle<JSObject> context_ext; | 1266 Handle<JSObject> context_ext; |
| 1213 if (context->has_extension()) { | 1267 if (context->has_extension()) { |
| 1214 // The function context's extension context exists - use it. | 1268 // The function context's extension context exists - use it. |
| 1215 context_ext = Handle<JSObject>(context->extension()); | 1269 context_ext = Handle<JSObject>(context->extension()); |
| 1216 } else { | 1270 } else { |
| 1217 // The function context's extension context does not exists - allocate | 1271 // The function context's extension context does not exists - allocate |
| 1218 // it. | 1272 // it. |
| 1219 context_ext = Factory::NewJSObject(Top::context_extension_function()); | 1273 context_ext = isolate->factory()->NewJSObject( |
| 1274 isolate->context_extension_function()); |
| 1220 // And store it in the extension slot. | 1275 // And store it in the extension slot. |
| 1221 context->set_extension(*context_ext); | 1276 context->set_extension(*context_ext); |
| 1222 } | 1277 } |
| 1223 ASSERT(*context_ext != NULL); | 1278 ASSERT(*context_ext != NULL); |
| 1224 | 1279 |
| 1225 // Declare the property by setting it to the initial value if provided, | 1280 // Declare the property by setting it to the initial value if provided, |
| 1226 // or undefined, and use the correct mode (e.g. READ_ONLY attribute for | 1281 // or undefined, and use the correct mode (e.g. READ_ONLY attribute for |
| 1227 // constant declarations). | 1282 // constant declarations). |
| 1228 ASSERT(!context_ext->HasLocalProperty(*name)); | 1283 ASSERT(!context_ext->HasLocalProperty(*name)); |
| 1229 Handle<Object> value(Heap::undefined_value()); | 1284 Handle<Object> value(isolate->heap()->undefined_value(), isolate); |
| 1230 if (*initial_value != NULL) value = initial_value; | 1285 if (*initial_value != NULL) value = initial_value; |
| 1231 // Declaring a const context slot is a conflicting declaration if | 1286 // Declaring a const context slot is a conflicting declaration if |
| 1232 // there is a callback with that name in a prototype. It is | 1287 // there is a callback with that name in a prototype. It is |
| 1233 // allowed to introduce const variables in | 1288 // allowed to introduce const variables in |
| 1234 // JSContextExtensionObjects. They are treated specially in | 1289 // JSContextExtensionObjects. They are treated specially in |
| 1235 // SetProperty and no setters are invoked for those since they are | 1290 // SetProperty and no setters are invoked for those since they are |
| 1236 // not real JSObjects. | 1291 // not real JSObjects. |
| 1237 if (initial_value->IsTheHole() && | 1292 if (initial_value->IsTheHole() && |
| 1238 !context_ext->IsJSContextExtensionObject()) { | 1293 !context_ext->IsJSContextExtensionObject()) { |
| 1239 LookupResult lookup; | 1294 LookupResult lookup; |
| 1240 context_ext->Lookup(*name, &lookup); | 1295 context_ext->Lookup(*name, &lookup); |
| 1241 if (lookup.IsProperty() && (lookup.type() == CALLBACKS)) { | 1296 if (lookup.IsProperty() && (lookup.type() == CALLBACKS)) { |
| 1242 return ThrowRedeclarationError("const", name); | 1297 return ThrowRedeclarationError(isolate, "const", name); |
| 1243 } | 1298 } |
| 1244 } | 1299 } |
| 1245 RETURN_IF_EMPTY_HANDLE(SetProperty(context_ext, name, value, mode, | 1300 RETURN_IF_EMPTY_HANDLE(isolate, |
| 1301 SetProperty(context_ext, name, value, mode, |
| 1246 kNonStrictMode)); | 1302 kNonStrictMode)); |
| 1247 } | 1303 } |
| 1248 | 1304 |
| 1249 return Heap::undefined_value(); | 1305 return isolate->heap()->undefined_value(); |
| 1250 } | 1306 } |
| 1251 | 1307 |
| 1252 | 1308 |
| 1253 static MaybeObject* Runtime_InitializeVarGlobal(Arguments args) { | 1309 static MaybeObject* Runtime_InitializeVarGlobal(RUNTIME_CALLING_CONVENTION) { |
| 1310 RUNTIME_GET_ISOLATE; |
| 1254 NoHandleAllocation nha; | 1311 NoHandleAllocation nha; |
| 1255 // args[0] == name | 1312 // args[0] == name |
| 1256 // args[1] == strict_mode | 1313 // args[1] == strict_mode |
| 1257 // args[2] == value (optional) | 1314 // args[2] == value (optional) |
| 1258 | 1315 |
| 1259 // Determine if we need to assign to the variable if it already | 1316 // Determine if we need to assign to the variable if it already |
| 1260 // exists (based on the number of arguments). | 1317 // exists (based on the number of arguments). |
| 1261 RUNTIME_ASSERT(args.length() == 2 || args.length() == 3); | 1318 RUNTIME_ASSERT(args.length() == 2 || args.length() == 3); |
| 1262 bool assign = args.length() == 3; | 1319 bool assign = args.length() == 3; |
| 1263 | 1320 |
| 1264 CONVERT_ARG_CHECKED(String, name, 0); | 1321 CONVERT_ARG_CHECKED(String, name, 0); |
| 1265 GlobalObject* global = Top::context()->global(); | 1322 GlobalObject* global = isolate->context()->global(); |
| 1266 RUNTIME_ASSERT(args[1]->IsSmi()); | 1323 RUNTIME_ASSERT(args[1]->IsSmi()); |
| 1267 StrictModeFlag strict_mode = | 1324 StrictModeFlag strict_mode = |
| 1268 static_cast<StrictModeFlag>(Smi::cast(args[1])->value()); | 1325 static_cast<StrictModeFlag>(Smi::cast(args[1])->value()); |
| 1269 ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode); | 1326 ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode); |
| 1270 | 1327 |
| 1271 // According to ECMA-262, section 12.2, page 62, the property must | 1328 // According to ECMA-262, section 12.2, page 62, the property must |
| 1272 // not be deletable. | 1329 // not be deletable. |
| 1273 PropertyAttributes attributes = DONT_DELETE; | 1330 PropertyAttributes attributes = DONT_DELETE; |
| 1274 | 1331 |
| 1275 // Lookup the property locally in the global object. If it isn't | 1332 // Lookup the property locally in the global object. If it isn't |
| 1276 // there, there is a property with this name in the prototype chain. | 1333 // there, there is a property with this name in the prototype chain. |
| 1277 // We follow Safari and Firefox behavior and only set the property | 1334 // We follow Safari and Firefox behavior and only set the property |
| 1278 // locally if there is an explicit initialization value that we have | 1335 // locally if there is an explicit initialization value that we have |
| 1279 // to assign to the property. | 1336 // to assign to the property. |
| 1280 // Note that objects can have hidden prototypes, so we need to traverse | 1337 // Note that objects can have hidden prototypes, so we need to traverse |
| 1281 // the whole chain of hidden prototypes to do a 'local' lookup. | 1338 // the whole chain of hidden prototypes to do a 'local' lookup. |
| 1282 JSObject* real_holder = global; | 1339 JSObject* real_holder = global; |
| 1283 LookupResult lookup; | 1340 LookupResult lookup; |
| 1284 while (true) { | 1341 while (true) { |
| 1285 real_holder->LocalLookup(*name, &lookup); | 1342 real_holder->LocalLookup(*name, &lookup); |
| 1286 if (lookup.IsProperty()) { | 1343 if (lookup.IsProperty()) { |
| 1287 // Determine if this is a redeclaration of something read-only. | 1344 // Determine if this is a redeclaration of something read-only. |
| 1288 if (lookup.IsReadOnly()) { | 1345 if (lookup.IsReadOnly()) { |
| 1289 // If we found readonly property on one of hidden prototypes, | 1346 // If we found readonly property on one of hidden prototypes, |
| 1290 // just shadow it. | 1347 // just shadow it. |
| 1291 if (real_holder != Top::context()->global()) break; | 1348 if (real_holder != isolate->context()->global()) break; |
| 1292 return ThrowRedeclarationError("const", name); | 1349 return ThrowRedeclarationError(isolate, "const", name); |
| 1293 } | 1350 } |
| 1294 | 1351 |
| 1295 // Determine if this is a redeclaration of an intercepted read-only | 1352 // Determine if this is a redeclaration of an intercepted read-only |
| 1296 // property and figure out if the property exists at all. | 1353 // property and figure out if the property exists at all. |
| 1297 bool found = true; | 1354 bool found = true; |
| 1298 PropertyType type = lookup.type(); | 1355 PropertyType type = lookup.type(); |
| 1299 if (type == INTERCEPTOR) { | 1356 if (type == INTERCEPTOR) { |
| 1300 HandleScope handle_scope; | 1357 HandleScope handle_scope(isolate); |
| 1301 Handle<JSObject> holder(real_holder); | 1358 Handle<JSObject> holder(real_holder); |
| 1302 PropertyAttributes intercepted = holder->GetPropertyAttribute(*name); | 1359 PropertyAttributes intercepted = holder->GetPropertyAttribute(*name); |
| 1303 real_holder = *holder; | 1360 real_holder = *holder; |
| 1304 if (intercepted == ABSENT) { | 1361 if (intercepted == ABSENT) { |
| 1305 // The interceptor claims the property isn't there. We need to | 1362 // The interceptor claims the property isn't there. We need to |
| 1306 // make sure to introduce it. | 1363 // make sure to introduce it. |
| 1307 found = false; | 1364 found = false; |
| 1308 } else if ((intercepted & READ_ONLY) != 0) { | 1365 } else if ((intercepted & READ_ONLY) != 0) { |
| 1309 // The property is present, but read-only. Since we're trying to | 1366 // The property is present, but read-only. Since we're trying to |
| 1310 // overwrite it with a variable declaration we must throw a | 1367 // overwrite it with a variable declaration we must throw a |
| 1311 // re-declaration error. However if we found readonly property | 1368 // re-declaration error. However if we found readonly property |
| 1312 // on one of hidden prototypes, just shadow it. | 1369 // on one of hidden prototypes, just shadow it. |
| 1313 if (real_holder != Top::context()->global()) break; | 1370 if (real_holder != isolate->context()->global()) break; |
| 1314 return ThrowRedeclarationError("const", name); | 1371 return ThrowRedeclarationError(isolate, "const", name); |
| 1315 } | 1372 } |
| 1316 } | 1373 } |
| 1317 | 1374 |
| 1318 if (found && !assign) { | 1375 if (found && !assign) { |
| 1319 // The global property is there and we're not assigning any value | 1376 // The global property is there and we're not assigning any value |
| 1320 // to it. Just return. | 1377 // to it. Just return. |
| 1321 return Heap::undefined_value(); | 1378 return isolate->heap()->undefined_value(); |
| 1322 } | 1379 } |
| 1323 | 1380 |
| 1324 // Assign the value (or undefined) to the property. | 1381 // Assign the value (or undefined) to the property. |
| 1325 Object* value = (assign) ? args[2] : Heap::undefined_value(); | 1382 Object* value = (assign) ? args[2] : isolate->heap()->undefined_value(); |
| 1326 return real_holder->SetProperty( | 1383 return real_holder->SetProperty( |
| 1327 &lookup, *name, value, attributes, strict_mode); | 1384 &lookup, *name, value, attributes, strict_mode); |
| 1328 } | 1385 } |
| 1329 | 1386 |
| 1330 Object* proto = real_holder->GetPrototype(); | 1387 Object* proto = real_holder->GetPrototype(); |
| 1331 if (!proto->IsJSObject()) | 1388 if (!proto->IsJSObject()) |
| 1332 break; | 1389 break; |
| 1333 | 1390 |
| 1334 if (!JSObject::cast(proto)->map()->is_hidden_prototype()) | 1391 if (!JSObject::cast(proto)->map()->is_hidden_prototype()) |
| 1335 break; | 1392 break; |
| 1336 | 1393 |
| 1337 real_holder = JSObject::cast(proto); | 1394 real_holder = JSObject::cast(proto); |
| 1338 } | 1395 } |
| 1339 | 1396 |
| 1340 global = Top::context()->global(); | 1397 global = isolate->context()->global(); |
| 1341 if (assign) { | 1398 if (assign) { |
| 1342 return global->SetProperty(*name, args[2], attributes, strict_mode); | 1399 return global->SetProperty(*name, args[2], attributes, strict_mode); |
| 1343 } | 1400 } |
| 1344 return Heap::undefined_value(); | 1401 return isolate->heap()->undefined_value(); |
| 1345 } | 1402 } |
| 1346 | 1403 |
| 1347 | 1404 |
| 1348 static MaybeObject* Runtime_InitializeConstGlobal(Arguments args) { | 1405 static MaybeObject* Runtime_InitializeConstGlobal(RUNTIME_CALLING_CONVENTION) { |
| 1406 RUNTIME_GET_ISOLATE; |
| 1349 // All constants are declared with an initial value. The name | 1407 // All constants are declared with an initial value. The name |
| 1350 // of the constant is the first argument and the initial value | 1408 // of the constant is the first argument and the initial value |
| 1351 // is the second. | 1409 // is the second. |
| 1352 RUNTIME_ASSERT(args.length() == 2); | 1410 RUNTIME_ASSERT(args.length() == 2); |
| 1353 CONVERT_ARG_CHECKED(String, name, 0); | 1411 CONVERT_ARG_CHECKED(String, name, 0); |
| 1354 Handle<Object> value = args.at<Object>(1); | 1412 Handle<Object> value = args.at<Object>(1); |
| 1355 | 1413 |
| 1356 // Get the current global object from top. | 1414 // Get the current global object from top. |
| 1357 GlobalObject* global = Top::context()->global(); | 1415 GlobalObject* global = isolate->context()->global(); |
| 1358 | 1416 |
| 1359 // According to ECMA-262, section 12.2, page 62, the property must | 1417 // According to ECMA-262, section 12.2, page 62, the property must |
| 1360 // not be deletable. Since it's a const, it must be READ_ONLY too. | 1418 // not be deletable. Since it's a const, it must be READ_ONLY too. |
| 1361 PropertyAttributes attributes = | 1419 PropertyAttributes attributes = |
| 1362 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | 1420 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
| 1363 | 1421 |
| 1364 // Lookup the property locally in the global object. If it isn't | 1422 // Lookup the property locally in the global object. If it isn't |
| 1365 // there, we add the property and take special precautions to always | 1423 // there, we add the property and take special precautions to always |
| 1366 // add it as a local property even in case of callbacks in the | 1424 // add it as a local property even in case of callbacks in the |
| 1367 // prototype chain (this rules out using SetProperty). | 1425 // prototype chain (this rules out using SetProperty). |
| 1368 // We use SetLocalPropertyIgnoreAttributes instead | 1426 // We use SetLocalPropertyIgnoreAttributes instead |
| 1369 LookupResult lookup; | 1427 LookupResult lookup; |
| 1370 global->LocalLookup(*name, &lookup); | 1428 global->LocalLookup(*name, &lookup); |
| 1371 if (!lookup.IsProperty()) { | 1429 if (!lookup.IsProperty()) { |
| 1372 return global->SetLocalPropertyIgnoreAttributes(*name, | 1430 return global->SetLocalPropertyIgnoreAttributes(*name, |
| 1373 *value, | 1431 *value, |
| 1374 attributes); | 1432 attributes); |
| 1375 } | 1433 } |
| 1376 | 1434 |
| 1377 // Determine if this is a redeclaration of something not | 1435 // Determine if this is a redeclaration of something not |
| 1378 // read-only. In case the result is hidden behind an interceptor we | 1436 // read-only. In case the result is hidden behind an interceptor we |
| 1379 // need to ask it for the property attributes. | 1437 // need to ask it for the property attributes. |
| 1380 if (!lookup.IsReadOnly()) { | 1438 if (!lookup.IsReadOnly()) { |
| 1381 if (lookup.type() != INTERCEPTOR) { | 1439 if (lookup.type() != INTERCEPTOR) { |
| 1382 return ThrowRedeclarationError("var", name); | 1440 return ThrowRedeclarationError(isolate, "var", name); |
| 1383 } | 1441 } |
| 1384 | 1442 |
| 1385 PropertyAttributes intercepted = global->GetPropertyAttribute(*name); | 1443 PropertyAttributes intercepted = global->GetPropertyAttribute(*name); |
| 1386 | 1444 |
| 1387 // Throw re-declaration error if the intercepted property is present | 1445 // Throw re-declaration error if the intercepted property is present |
| 1388 // but not read-only. | 1446 // but not read-only. |
| 1389 if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) { | 1447 if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) { |
| 1390 return ThrowRedeclarationError("var", name); | 1448 return ThrowRedeclarationError(isolate, "var", name); |
| 1391 } | 1449 } |
| 1392 | 1450 |
| 1393 // Restore global object from context (in case of GC) and continue | 1451 // Restore global object from context (in case of GC) and continue |
| 1394 // with setting the value because the property is either absent or | 1452 // with setting the value because the property is either absent or |
| 1395 // read-only. We also have to do redo the lookup. | 1453 // read-only. We also have to do redo the lookup. |
| 1396 HandleScope handle_scope; | 1454 HandleScope handle_scope(isolate); |
| 1397 Handle<GlobalObject> global(Top::context()->global()); | 1455 Handle<GlobalObject> global(isolate->context()->global()); |
| 1398 | 1456 |
| 1399 // BUG 1213575: Handle the case where we have to set a read-only | 1457 // BUG 1213575: Handle the case where we have to set a read-only |
| 1400 // property through an interceptor and only do it if it's | 1458 // property through an interceptor and only do it if it's |
| 1401 // uninitialized, e.g. the hole. Nirk... | 1459 // uninitialized, e.g. the hole. Nirk... |
| 1402 // Passing non-strict mode because the property is writable. | 1460 // Passing non-strict mode because the property is writable. |
| 1403 RETURN_IF_EMPTY_HANDLE(SetProperty(global, | 1461 RETURN_IF_EMPTY_HANDLE(isolate, |
| 1462 SetProperty(global, |
| 1404 name, | 1463 name, |
| 1405 value, | 1464 value, |
| 1406 attributes, | 1465 attributes, |
| 1407 kNonStrictMode)); | 1466 kNonStrictMode)); |
| 1408 return *value; | 1467 return *value; |
| 1409 } | 1468 } |
| 1410 | 1469 |
| 1411 // Set the value, but only we're assigning the initial value to a | 1470 // Set the value, but only we're assigning the initial value to a |
| 1412 // constant. For now, we determine this by checking if the | 1471 // constant. For now, we determine this by checking if the |
| 1413 // current value is the hole. | 1472 // current value is the hole. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1427 // Ignore re-initialization of constants that have already been | 1486 // Ignore re-initialization of constants that have already been |
| 1428 // assigned a function value. | 1487 // assigned a function value. |
| 1429 ASSERT(lookup.IsReadOnly() && type == CONSTANT_FUNCTION); | 1488 ASSERT(lookup.IsReadOnly() && type == CONSTANT_FUNCTION); |
| 1430 } | 1489 } |
| 1431 | 1490 |
| 1432 // Use the set value as the result of the operation. | 1491 // Use the set value as the result of the operation. |
| 1433 return *value; | 1492 return *value; |
| 1434 } | 1493 } |
| 1435 | 1494 |
| 1436 | 1495 |
| 1437 static MaybeObject* Runtime_InitializeConstContextSlot(Arguments args) { | 1496 static MaybeObject* Runtime_InitializeConstContextSlot( |
| 1438 HandleScope scope; | 1497 RUNTIME_CALLING_CONVENTION) { |
| 1498 RUNTIME_GET_ISOLATE; |
| 1499 HandleScope scope(isolate); |
| 1439 ASSERT(args.length() == 3); | 1500 ASSERT(args.length() == 3); |
| 1440 | 1501 |
| 1441 Handle<Object> value(args[0]); | 1502 Handle<Object> value(args[0], isolate); |
| 1442 ASSERT(!value->IsTheHole()); | 1503 ASSERT(!value->IsTheHole()); |
| 1443 CONVERT_ARG_CHECKED(Context, context, 1); | 1504 CONVERT_ARG_CHECKED(Context, context, 1); |
| 1444 Handle<String> name(String::cast(args[2])); | 1505 Handle<String> name(String::cast(args[2])); |
| 1445 | 1506 |
| 1446 // Initializations are always done in the function context. | 1507 // Initializations are always done in the function context. |
| 1447 context = Handle<Context>(context->fcontext()); | 1508 context = Handle<Context>(context->fcontext()); |
| 1448 | 1509 |
| 1449 int index; | 1510 int index; |
| 1450 PropertyAttributes attributes; | 1511 PropertyAttributes attributes; |
| 1451 ContextLookupFlags flags = FOLLOW_CHAINS; | 1512 ContextLookupFlags flags = FOLLOW_CHAINS; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1472 // the const property. | 1533 // the const property. |
| 1473 ASSERT(!holder.is_identical_to(context)); | 1534 ASSERT(!holder.is_identical_to(context)); |
| 1474 if ((attributes & READ_ONLY) == 0) { | 1535 if ((attributes & READ_ONLY) == 0) { |
| 1475 Handle<Context>::cast(holder)->set(index, *value); | 1536 Handle<Context>::cast(holder)->set(index, *value); |
| 1476 } | 1537 } |
| 1477 } else { | 1538 } else { |
| 1478 // The holder is an arguments object. | 1539 // The holder is an arguments object. |
| 1479 ASSERT((attributes & READ_ONLY) == 0); | 1540 ASSERT((attributes & READ_ONLY) == 0); |
| 1480 Handle<JSObject> arguments(Handle<JSObject>::cast(holder)); | 1541 Handle<JSObject> arguments(Handle<JSObject>::cast(holder)); |
| 1481 RETURN_IF_EMPTY_HANDLE( | 1542 RETURN_IF_EMPTY_HANDLE( |
| 1543 isolate, |
| 1482 SetElement(arguments, index, value, kNonStrictMode)); | 1544 SetElement(arguments, index, value, kNonStrictMode)); |
| 1483 } | 1545 } |
| 1484 return *value; | 1546 return *value; |
| 1485 } | 1547 } |
| 1486 | 1548 |
| 1487 // The property could not be found, we introduce it in the global | 1549 // The property could not be found, we introduce it in the global |
| 1488 // context. | 1550 // context. |
| 1489 if (attributes == ABSENT) { | 1551 if (attributes == ABSENT) { |
| 1490 Handle<JSObject> global = Handle<JSObject>(Top::context()->global()); | 1552 Handle<JSObject> global = Handle<JSObject>( |
| 1553 isolate->context()->global()); |
| 1491 // Strict mode not needed (const disallowed in strict mode). | 1554 // Strict mode not needed (const disallowed in strict mode). |
| 1492 RETURN_IF_EMPTY_HANDLE( | 1555 RETURN_IF_EMPTY_HANDLE( |
| 1556 isolate, |
| 1493 SetProperty(global, name, value, NONE, kNonStrictMode)); | 1557 SetProperty(global, name, value, NONE, kNonStrictMode)); |
| 1494 return *value; | 1558 return *value; |
| 1495 } | 1559 } |
| 1496 | 1560 |
| 1497 // The property was present in a context extension object. | 1561 // The property was present in a context extension object. |
| 1498 Handle<JSObject> context_ext = Handle<JSObject>::cast(holder); | 1562 Handle<JSObject> context_ext = Handle<JSObject>::cast(holder); |
| 1499 | 1563 |
| 1500 if (*context_ext == context->extension()) { | 1564 if (*context_ext == context->extension()) { |
| 1501 // This is the property that was introduced by the const | 1565 // This is the property that was introduced by the const |
| 1502 // declaration. Set it if it hasn't been set before. NOTE: We | 1566 // declaration. Set it if it hasn't been set before. NOTE: We |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1522 // We should not reach here. Any real, named property should be | 1586 // We should not reach here. Any real, named property should be |
| 1523 // either a field or a dictionary slot. | 1587 // either a field or a dictionary slot. |
| 1524 UNREACHABLE(); | 1588 UNREACHABLE(); |
| 1525 } | 1589 } |
| 1526 } else { | 1590 } else { |
| 1527 // The property was found in a different context extension object. | 1591 // The property was found in a different context extension object. |
| 1528 // Set it if it is not a read-only property. | 1592 // Set it if it is not a read-only property. |
| 1529 if ((attributes & READ_ONLY) == 0) { | 1593 if ((attributes & READ_ONLY) == 0) { |
| 1530 // Strict mode not needed (const disallowed in strict mode). | 1594 // Strict mode not needed (const disallowed in strict mode). |
| 1531 RETURN_IF_EMPTY_HANDLE( | 1595 RETURN_IF_EMPTY_HANDLE( |
| 1596 isolate, |
| 1532 SetProperty(context_ext, name, value, attributes, kNonStrictMode)); | 1597 SetProperty(context_ext, name, value, attributes, kNonStrictMode)); |
| 1533 } | 1598 } |
| 1534 } | 1599 } |
| 1535 | 1600 |
| 1536 return *value; | 1601 return *value; |
| 1537 } | 1602 } |
| 1538 | 1603 |
| 1539 | 1604 |
| 1540 static MaybeObject* Runtime_OptimizeObjectForAddingMultipleProperties( | 1605 static MaybeObject* Runtime_OptimizeObjectForAddingMultipleProperties( |
| 1541 Arguments args) { | 1606 RUNTIME_CALLING_CONVENTION) { |
| 1542 HandleScope scope; | 1607 RUNTIME_GET_ISOLATE; |
| 1608 HandleScope scope(isolate); |
| 1543 ASSERT(args.length() == 2); | 1609 ASSERT(args.length() == 2); |
| 1544 CONVERT_ARG_CHECKED(JSObject, object, 0); | 1610 CONVERT_ARG_CHECKED(JSObject, object, 0); |
| 1545 CONVERT_SMI_CHECKED(properties, args[1]); | 1611 CONVERT_SMI_CHECKED(properties, args[1]); |
| 1546 if (object->HasFastProperties()) { | 1612 if (object->HasFastProperties()) { |
| 1547 NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); | 1613 NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); |
| 1548 } | 1614 } |
| 1549 return *object; | 1615 return *object; |
| 1550 } | 1616 } |
| 1551 | 1617 |
| 1552 | 1618 |
| 1553 static MaybeObject* Runtime_RegExpExec(Arguments args) { | 1619 static MaybeObject* Runtime_RegExpExec(RUNTIME_CALLING_CONVENTION) { |
| 1554 HandleScope scope; | 1620 RUNTIME_GET_ISOLATE; |
| 1621 HandleScope scope(isolate); |
| 1555 ASSERT(args.length() == 4); | 1622 ASSERT(args.length() == 4); |
| 1556 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); | 1623 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); |
| 1557 CONVERT_ARG_CHECKED(String, subject, 1); | 1624 CONVERT_ARG_CHECKED(String, subject, 1); |
| 1558 // Due to the way the JS calls are constructed this must be less than the | 1625 // Due to the way the JS calls are constructed this must be less than the |
| 1559 // length of a string, i.e. it is always a Smi. We check anyway for security. | 1626 // length of a string, i.e. it is always a Smi. We check anyway for security. |
| 1560 CONVERT_SMI_CHECKED(index, args[2]); | 1627 CONVERT_SMI_CHECKED(index, args[2]); |
| 1561 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3); | 1628 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3); |
| 1562 RUNTIME_ASSERT(last_match_info->HasFastElements()); | 1629 RUNTIME_ASSERT(last_match_info->HasFastElements()); |
| 1563 RUNTIME_ASSERT(index >= 0); | 1630 RUNTIME_ASSERT(index >= 0); |
| 1564 RUNTIME_ASSERT(index <= subject->length()); | 1631 RUNTIME_ASSERT(index <= subject->length()); |
| 1565 Counters::regexp_entry_runtime.Increment(); | 1632 isolate->counters()->regexp_entry_runtime()->Increment(); |
| 1566 Handle<Object> result = RegExpImpl::Exec(regexp, | 1633 Handle<Object> result = RegExpImpl::Exec(regexp, |
| 1567 subject, | 1634 subject, |
| 1568 index, | 1635 index, |
| 1569 last_match_info); | 1636 last_match_info); |
| 1570 if (result.is_null()) return Failure::Exception(); | 1637 if (result.is_null()) return Failure::Exception(); |
| 1571 return *result; | 1638 return *result; |
| 1572 } | 1639 } |
| 1573 | 1640 |
| 1574 | 1641 |
| 1575 static MaybeObject* Runtime_RegExpConstructResult(Arguments args) { | 1642 static MaybeObject* Runtime_RegExpConstructResult(RUNTIME_CALLING_CONVENTION) { |
| 1643 RUNTIME_GET_ISOLATE; |
| 1576 ASSERT(args.length() == 3); | 1644 ASSERT(args.length() == 3); |
| 1577 CONVERT_SMI_CHECKED(elements_count, args[0]); | 1645 CONVERT_SMI_CHECKED(elements_count, args[0]); |
| 1578 if (elements_count > JSArray::kMaxFastElementsLength) { | 1646 if (elements_count > JSArray::kMaxFastElementsLength) { |
| 1579 return Top::ThrowIllegalOperation(); | 1647 return isolate->ThrowIllegalOperation(); |
| 1580 } | 1648 } |
| 1581 Object* new_object; | 1649 Object* new_object; |
| 1582 { MaybeObject* maybe_new_object = | 1650 { MaybeObject* maybe_new_object = |
| 1583 Heap::AllocateFixedArrayWithHoles(elements_count); | 1651 isolate->heap()->AllocateFixedArrayWithHoles(elements_count); |
| 1584 if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object; | 1652 if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object; |
| 1585 } | 1653 } |
| 1586 FixedArray* elements = FixedArray::cast(new_object); | 1654 FixedArray* elements = FixedArray::cast(new_object); |
| 1587 { MaybeObject* maybe_new_object = Heap::AllocateRaw(JSRegExpResult::kSize, | 1655 { MaybeObject* maybe_new_object = isolate->heap()->AllocateRaw( |
| 1588 NEW_SPACE, | 1656 JSRegExpResult::kSize, NEW_SPACE, OLD_POINTER_SPACE); |
| 1589 OLD_POINTER_SPACE); | |
| 1590 if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object; | 1657 if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object; |
| 1591 } | 1658 } |
| 1592 { | 1659 { |
| 1593 AssertNoAllocation no_gc; | 1660 AssertNoAllocation no_gc; |
| 1594 HandleScope scope; | 1661 HandleScope scope(isolate); |
| 1595 reinterpret_cast<HeapObject*>(new_object)-> | 1662 reinterpret_cast<HeapObject*>(new_object)-> |
| 1596 set_map(Top::global_context()->regexp_result_map()); | 1663 set_map(isolate->global_context()->regexp_result_map()); |
| 1597 } | 1664 } |
| 1598 JSArray* array = JSArray::cast(new_object); | 1665 JSArray* array = JSArray::cast(new_object); |
| 1599 array->set_properties(Heap::empty_fixed_array()); | 1666 array->set_properties(isolate->heap()->empty_fixed_array()); |
| 1600 array->set_elements(elements); | 1667 array->set_elements(elements); |
| 1601 array->set_length(Smi::FromInt(elements_count)); | 1668 array->set_length(Smi::FromInt(elements_count)); |
| 1602 // Write in-object properties after the length of the array. | 1669 // Write in-object properties after the length of the array. |
| 1603 array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, args[1]); | 1670 array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, args[1]); |
| 1604 array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, args[2]); | 1671 array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, args[2]); |
| 1605 return array; | 1672 return array; |
| 1606 } | 1673 } |
| 1607 | 1674 |
| 1608 | 1675 |
| 1609 static MaybeObject* Runtime_RegExpInitializeObject(Arguments args) { | 1676 static MaybeObject* Runtime_RegExpInitializeObject(RUNTIME_CALLING_CONVENTION) { |
| 1677 RUNTIME_GET_ISOLATE; |
| 1610 AssertNoAllocation no_alloc; | 1678 AssertNoAllocation no_alloc; |
| 1611 ASSERT(args.length() == 5); | 1679 ASSERT(args.length() == 5); |
| 1612 CONVERT_CHECKED(JSRegExp, regexp, args[0]); | 1680 CONVERT_CHECKED(JSRegExp, regexp, args[0]); |
| 1613 CONVERT_CHECKED(String, source, args[1]); | 1681 CONVERT_CHECKED(String, source, args[1]); |
| 1614 | 1682 |
| 1615 Object* global = args[2]; | 1683 Object* global = args[2]; |
| 1616 if (!global->IsTrue()) global = Heap::false_value(); | 1684 if (!global->IsTrue()) global = isolate->heap()->false_value(); |
| 1617 | 1685 |
| 1618 Object* ignoreCase = args[3]; | 1686 Object* ignoreCase = args[3]; |
| 1619 if (!ignoreCase->IsTrue()) ignoreCase = Heap::false_value(); | 1687 if (!ignoreCase->IsTrue()) ignoreCase = isolate->heap()->false_value(); |
| 1620 | 1688 |
| 1621 Object* multiline = args[4]; | 1689 Object* multiline = args[4]; |
| 1622 if (!multiline->IsTrue()) multiline = Heap::false_value(); | 1690 if (!multiline->IsTrue()) multiline = isolate->heap()->false_value(); |
| 1623 | 1691 |
| 1624 Map* map = regexp->map(); | 1692 Map* map = regexp->map(); |
| 1625 Object* constructor = map->constructor(); | 1693 Object* constructor = map->constructor(); |
| 1626 if (constructor->IsJSFunction() && | 1694 if (constructor->IsJSFunction() && |
| 1627 JSFunction::cast(constructor)->initial_map() == map) { | 1695 JSFunction::cast(constructor)->initial_map() == map) { |
| 1628 // If we still have the original map, set in-object properties directly. | 1696 // If we still have the original map, set in-object properties directly. |
| 1629 regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source); | 1697 regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source); |
| 1630 // TODO(lrn): Consider skipping write barrier on booleans as well. | 1698 // TODO(lrn): Consider skipping write barrier on booleans as well. |
| 1631 // Both true and false should be in oldspace at all times. | 1699 // Both true and false should be in oldspace at all times. |
| 1632 regexp->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex, global); | 1700 regexp->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex, global); |
| 1633 regexp->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, ignoreCase); | 1701 regexp->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, ignoreCase); |
| 1634 regexp->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex, multiline); | 1702 regexp->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex, multiline); |
| 1635 regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, | 1703 regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, |
| 1636 Smi::FromInt(0), | 1704 Smi::FromInt(0), |
| 1637 SKIP_WRITE_BARRIER); | 1705 SKIP_WRITE_BARRIER); |
| 1638 return regexp; | 1706 return regexp; |
| 1639 } | 1707 } |
| 1640 | 1708 |
| 1641 // Map has changed, so use generic, but slower, method. Since these | 1709 // Map has changed, so use generic, but slower, method. |
| 1642 // properties were all added as DONT_DELETE they must be present and | |
| 1643 // normal so no failures can be expected. | |
| 1644 PropertyAttributes final = | 1710 PropertyAttributes final = |
| 1645 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); | 1711 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); |
| 1646 PropertyAttributes writable = | 1712 PropertyAttributes writable = |
| 1647 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); | 1713 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); |
| 1714 Heap* heap = isolate->heap(); |
| 1648 MaybeObject* result; | 1715 MaybeObject* result; |
| 1649 result = regexp->SetLocalPropertyIgnoreAttributes(Heap::source_symbol(), | 1716 result = regexp->SetLocalPropertyIgnoreAttributes(heap->source_symbol(), |
| 1650 source, | 1717 source, |
| 1651 final); | 1718 final); |
| 1652 ASSERT(!result->IsFailure()); | 1719 ASSERT(!result->IsFailure()); |
| 1653 result = regexp->SetLocalPropertyIgnoreAttributes(Heap::global_symbol(), | 1720 result = regexp->SetLocalPropertyIgnoreAttributes(heap->global_symbol(), |
| 1654 global, | 1721 global, |
| 1655 final); | 1722 final); |
| 1656 ASSERT(!result->IsFailure()); | 1723 ASSERT(!result->IsFailure()); |
| 1657 result = | 1724 result = |
| 1658 regexp->SetLocalPropertyIgnoreAttributes(Heap::ignore_case_symbol(), | 1725 regexp->SetLocalPropertyIgnoreAttributes(heap->ignore_case_symbol(), |
| 1659 ignoreCase, | 1726 ignoreCase, |
| 1660 final); | 1727 final); |
| 1661 ASSERT(!result->IsFailure()); | 1728 ASSERT(!result->IsFailure()); |
| 1662 result = regexp->SetLocalPropertyIgnoreAttributes(Heap::multiline_symbol(), | 1729 result = regexp->SetLocalPropertyIgnoreAttributes(heap->multiline_symbol(), |
| 1663 multiline, | 1730 multiline, |
| 1664 final); | 1731 final); |
| 1665 ASSERT(!result->IsFailure()); | 1732 ASSERT(!result->IsFailure()); |
| 1666 result = | 1733 result = |
| 1667 regexp->SetLocalPropertyIgnoreAttributes(Heap::last_index_symbol(), | 1734 regexp->SetLocalPropertyIgnoreAttributes(heap->last_index_symbol(), |
| 1668 Smi::FromInt(0), | 1735 Smi::FromInt(0), |
| 1669 writable); | 1736 writable); |
| 1670 ASSERT(!result->IsFailure()); | 1737 ASSERT(!result->IsFailure()); |
| 1671 USE(result); | 1738 USE(result); |
| 1672 return regexp; | 1739 return regexp; |
| 1673 } | 1740 } |
| 1674 | 1741 |
| 1675 | 1742 |
| 1676 static MaybeObject* Runtime_FinishArrayPrototypeSetup(Arguments args) { | 1743 static MaybeObject* Runtime_FinishArrayPrototypeSetup( |
| 1677 HandleScope scope; | 1744 RUNTIME_CALLING_CONVENTION) { |
| 1745 RUNTIME_GET_ISOLATE; |
| 1746 HandleScope scope(isolate); |
| 1678 ASSERT(args.length() == 1); | 1747 ASSERT(args.length() == 1); |
| 1679 CONVERT_ARG_CHECKED(JSArray, prototype, 0); | 1748 CONVERT_ARG_CHECKED(JSArray, prototype, 0); |
| 1680 // This is necessary to enable fast checks for absence of elements | 1749 // This is necessary to enable fast checks for absence of elements |
| 1681 // on Array.prototype and below. | 1750 // on Array.prototype and below. |
| 1682 prototype->set_elements(Heap::empty_fixed_array()); | 1751 prototype->set_elements(isolate->heap()->empty_fixed_array()); |
| 1683 return Smi::FromInt(0); | 1752 return Smi::FromInt(0); |
| 1684 } | 1753 } |
| 1685 | 1754 |
| 1686 | 1755 |
| 1687 static Handle<JSFunction> InstallBuiltin(Handle<JSObject> holder, | 1756 static Handle<JSFunction> InstallBuiltin(Isolate* isolate, |
| 1757 Handle<JSObject> holder, |
| 1688 const char* name, | 1758 const char* name, |
| 1689 Builtins::Name builtin_name) { | 1759 Builtins::Name builtin_name) { |
| 1690 Handle<String> key = Factory::LookupAsciiSymbol(name); | 1760 Handle<String> key = isolate->factory()->LookupAsciiSymbol(name); |
| 1691 Handle<Code> code(Builtins::builtin(builtin_name)); | 1761 Handle<Code> code(isolate->builtins()->builtin(builtin_name)); |
| 1692 Handle<JSFunction> optimized = Factory::NewFunction(key, | 1762 Handle<JSFunction> optimized = |
| 1693 JS_OBJECT_TYPE, | 1763 isolate->factory()->NewFunction(key, |
| 1694 JSObject::kHeaderSize, | 1764 JS_OBJECT_TYPE, |
| 1695 code, | 1765 JSObject::kHeaderSize, |
| 1696 false); | 1766 code, |
| 1767 false); |
| 1697 optimized->shared()->DontAdaptArguments(); | 1768 optimized->shared()->DontAdaptArguments(); |
| 1698 SetProperty(holder, key, optimized, NONE, kStrictMode); | 1769 SetProperty(holder, key, optimized, NONE, kStrictMode); |
| 1699 return optimized; | 1770 return optimized; |
| 1700 } | 1771 } |
| 1701 | 1772 |
| 1702 | 1773 |
| 1703 static MaybeObject* Runtime_SpecialArrayFunctions(Arguments args) { | 1774 static MaybeObject* Runtime_SpecialArrayFunctions(RUNTIME_CALLING_CONVENTION) { |
| 1704 HandleScope scope; | 1775 RUNTIME_GET_ISOLATE; |
| 1776 HandleScope scope(isolate); |
| 1705 ASSERT(args.length() == 1); | 1777 ASSERT(args.length() == 1); |
| 1706 CONVERT_ARG_CHECKED(JSObject, holder, 0); | 1778 CONVERT_ARG_CHECKED(JSObject, holder, 0); |
| 1707 | 1779 |
| 1708 InstallBuiltin(holder, "pop", Builtins::ArrayPop); | 1780 InstallBuiltin(isolate, holder, "pop", Builtins::ArrayPop); |
| 1709 InstallBuiltin(holder, "push", Builtins::ArrayPush); | 1781 InstallBuiltin(isolate, holder, "push", Builtins::ArrayPush); |
| 1710 InstallBuiltin(holder, "shift", Builtins::ArrayShift); | 1782 InstallBuiltin(isolate, holder, "shift", Builtins::ArrayShift); |
| 1711 InstallBuiltin(holder, "unshift", Builtins::ArrayUnshift); | 1783 InstallBuiltin(isolate, holder, "unshift", Builtins::ArrayUnshift); |
| 1712 InstallBuiltin(holder, "slice", Builtins::ArraySlice); | 1784 InstallBuiltin(isolate, holder, "slice", Builtins::ArraySlice); |
| 1713 InstallBuiltin(holder, "splice", Builtins::ArraySplice); | 1785 InstallBuiltin(isolate, holder, "splice", Builtins::ArraySplice); |
| 1714 InstallBuiltin(holder, "concat", Builtins::ArrayConcat); | 1786 InstallBuiltin(isolate, holder, "concat", Builtins::ArrayConcat); |
| 1715 | 1787 |
| 1716 return *holder; | 1788 return *holder; |
| 1717 } | 1789 } |
| 1718 | 1790 |
| 1719 | 1791 |
| 1720 static MaybeObject* Runtime_GetGlobalReceiver(Arguments args) { | 1792 static MaybeObject* Runtime_GetGlobalReceiver(RUNTIME_CALLING_CONVENTION) { |
| 1793 RUNTIME_GET_ISOLATE; |
| 1721 // Returns a real global receiver, not one of builtins object. | 1794 // Returns a real global receiver, not one of builtins object. |
| 1722 Context* global_context = Top::context()->global()->global_context(); | 1795 Context* global_context = |
| 1796 isolate->context()->global()->global_context(); |
| 1723 return global_context->global()->global_receiver(); | 1797 return global_context->global()->global_receiver(); |
| 1724 } | 1798 } |
| 1725 | 1799 |
| 1726 | 1800 |
| 1727 static MaybeObject* Runtime_MaterializeRegExpLiteral(Arguments args) { | 1801 static MaybeObject* Runtime_MaterializeRegExpLiteral( |
| 1728 HandleScope scope; | 1802 RUNTIME_CALLING_CONVENTION) { |
| 1803 RUNTIME_GET_ISOLATE; |
| 1804 HandleScope scope(isolate); |
| 1729 ASSERT(args.length() == 4); | 1805 ASSERT(args.length() == 4); |
| 1730 CONVERT_ARG_CHECKED(FixedArray, literals, 0); | 1806 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
| 1731 int index = Smi::cast(args[1])->value(); | 1807 int index = Smi::cast(args[1])->value(); |
| 1732 Handle<String> pattern = args.at<String>(2); | 1808 Handle<String> pattern = args.at<String>(2); |
| 1733 Handle<String> flags = args.at<String>(3); | 1809 Handle<String> flags = args.at<String>(3); |
| 1734 | 1810 |
| 1735 // Get the RegExp function from the context in the literals array. | 1811 // Get the RegExp function from the context in the literals array. |
| 1736 // This is the RegExp function from the context in which the | 1812 // This is the RegExp function from the context in which the |
| 1737 // function was created. We do not use the RegExp function from the | 1813 // function was created. We do not use the RegExp function from the |
| 1738 // current global context because this might be the RegExp function | 1814 // current global context because this might be the RegExp function |
| 1739 // from another context which we should not have access to. | 1815 // from another context which we should not have access to. |
| 1740 Handle<JSFunction> constructor = | 1816 Handle<JSFunction> constructor = |
| 1741 Handle<JSFunction>( | 1817 Handle<JSFunction>( |
| 1742 JSFunction::GlobalContextFromLiterals(*literals)->regexp_function()); | 1818 JSFunction::GlobalContextFromLiterals(*literals)->regexp_function()); |
| 1743 // Compute the regular expression literal. | 1819 // Compute the regular expression literal. |
| 1744 bool has_pending_exception; | 1820 bool has_pending_exception; |
| 1745 Handle<Object> regexp = | 1821 Handle<Object> regexp = |
| 1746 RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags, | 1822 RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags, |
| 1747 &has_pending_exception); | 1823 &has_pending_exception); |
| 1748 if (has_pending_exception) { | 1824 if (has_pending_exception) { |
| 1749 ASSERT(Top::has_pending_exception()); | 1825 ASSERT(isolate->has_pending_exception()); |
| 1750 return Failure::Exception(); | 1826 return Failure::Exception(); |
| 1751 } | 1827 } |
| 1752 literals->set(index, *regexp); | 1828 literals->set(index, *regexp); |
| 1753 return *regexp; | 1829 return *regexp; |
| 1754 } | 1830 } |
| 1755 | 1831 |
| 1756 | 1832 |
| 1757 static MaybeObject* Runtime_FunctionGetName(Arguments args) { | 1833 static MaybeObject* Runtime_FunctionGetName(RUNTIME_CALLING_CONVENTION) { |
| 1834 RUNTIME_GET_ISOLATE; |
| 1758 NoHandleAllocation ha; | 1835 NoHandleAllocation ha; |
| 1759 ASSERT(args.length() == 1); | 1836 ASSERT(args.length() == 1); |
| 1760 | 1837 |
| 1761 CONVERT_CHECKED(JSFunction, f, args[0]); | 1838 CONVERT_CHECKED(JSFunction, f, args[0]); |
| 1762 return f->shared()->name(); | 1839 return f->shared()->name(); |
| 1763 } | 1840 } |
| 1764 | 1841 |
| 1765 | 1842 |
| 1766 static MaybeObject* Runtime_FunctionSetName(Arguments args) { | 1843 static MaybeObject* Runtime_FunctionSetName(RUNTIME_CALLING_CONVENTION) { |
| 1844 RUNTIME_GET_ISOLATE; |
| 1767 NoHandleAllocation ha; | 1845 NoHandleAllocation ha; |
| 1768 ASSERT(args.length() == 2); | 1846 ASSERT(args.length() == 2); |
| 1769 | 1847 |
| 1770 CONVERT_CHECKED(JSFunction, f, args[0]); | 1848 CONVERT_CHECKED(JSFunction, f, args[0]); |
| 1771 CONVERT_CHECKED(String, name, args[1]); | 1849 CONVERT_CHECKED(String, name, args[1]); |
| 1772 f->shared()->set_name(name); | 1850 f->shared()->set_name(name); |
| 1773 return Heap::undefined_value(); | 1851 return isolate->heap()->undefined_value(); |
| 1774 } | 1852 } |
| 1775 | 1853 |
| 1776 | 1854 |
| 1777 static MaybeObject* Runtime_FunctionRemovePrototype(Arguments args) { | 1855 static MaybeObject* Runtime_FunctionRemovePrototype( |
| 1856 RUNTIME_CALLING_CONVENTION) { |
| 1857 RUNTIME_GET_ISOLATE; |
| 1778 NoHandleAllocation ha; | 1858 NoHandleAllocation ha; |
| 1779 ASSERT(args.length() == 1); | 1859 ASSERT(args.length() == 1); |
| 1780 | 1860 |
| 1781 CONVERT_CHECKED(JSFunction, f, args[0]); | 1861 CONVERT_CHECKED(JSFunction, f, args[0]); |
| 1782 Object* obj; | 1862 Object* obj = f->RemovePrototype(); |
| 1783 { MaybeObject* maybe_obj = f->RemovePrototype(); | 1863 if (obj->IsFailure()) return obj; |
| 1784 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
| 1785 } | |
| 1786 | 1864 |
| 1787 return Heap::undefined_value(); | 1865 return isolate->heap()->undefined_value(); |
| 1788 } | 1866 } |
| 1789 | 1867 |
| 1790 | 1868 |
| 1791 static MaybeObject* Runtime_FunctionGetScript(Arguments args) { | 1869 static MaybeObject* Runtime_FunctionGetScript(RUNTIME_CALLING_CONVENTION) { |
| 1792 HandleScope scope; | 1870 RUNTIME_GET_ISOLATE; |
| 1871 HandleScope scope(isolate); |
| 1793 ASSERT(args.length() == 1); | 1872 ASSERT(args.length() == 1); |
| 1794 | 1873 |
| 1795 CONVERT_CHECKED(JSFunction, fun, args[0]); | 1874 CONVERT_CHECKED(JSFunction, fun, args[0]); |
| 1796 Handle<Object> script = Handle<Object>(fun->shared()->script()); | 1875 Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate); |
| 1797 if (!script->IsScript()) return Heap::undefined_value(); | 1876 if (!script->IsScript()) return isolate->heap()->undefined_value(); |
| 1798 | 1877 |
| 1799 return *GetScriptWrapper(Handle<Script>::cast(script)); | 1878 return *GetScriptWrapper(Handle<Script>::cast(script)); |
| 1800 } | 1879 } |
| 1801 | 1880 |
| 1802 | 1881 |
| 1803 static MaybeObject* Runtime_FunctionGetSourceCode(Arguments args) { | 1882 static MaybeObject* Runtime_FunctionGetSourceCode(RUNTIME_CALLING_CONVENTION) { |
| 1883 RUNTIME_GET_ISOLATE; |
| 1804 NoHandleAllocation ha; | 1884 NoHandleAllocation ha; |
| 1805 ASSERT(args.length() == 1); | 1885 ASSERT(args.length() == 1); |
| 1806 | 1886 |
| 1807 CONVERT_CHECKED(JSFunction, f, args[0]); | 1887 CONVERT_CHECKED(JSFunction, f, args[0]); |
| 1808 return f->shared()->GetSourceCode(); | 1888 return f->shared()->GetSourceCode(); |
| 1809 } | 1889 } |
| 1810 | 1890 |
| 1811 | 1891 |
| 1812 static MaybeObject* Runtime_FunctionGetScriptSourcePosition(Arguments args) { | 1892 static MaybeObject* Runtime_FunctionGetScriptSourcePosition( |
| 1893 RUNTIME_CALLING_CONVENTION) { |
| 1894 RUNTIME_GET_ISOLATE; |
| 1813 NoHandleAllocation ha; | 1895 NoHandleAllocation ha; |
| 1814 ASSERT(args.length() == 1); | 1896 ASSERT(args.length() == 1); |
| 1815 | 1897 |
| 1816 CONVERT_CHECKED(JSFunction, fun, args[0]); | 1898 CONVERT_CHECKED(JSFunction, fun, args[0]); |
| 1817 int pos = fun->shared()->start_position(); | 1899 int pos = fun->shared()->start_position(); |
| 1818 return Smi::FromInt(pos); | 1900 return Smi::FromInt(pos); |
| 1819 } | 1901 } |
| 1820 | 1902 |
| 1821 | 1903 |
| 1822 static MaybeObject* Runtime_FunctionGetPositionForOffset(Arguments args) { | 1904 static MaybeObject* Runtime_FunctionGetPositionForOffset( |
| 1905 RUNTIME_CALLING_CONVENTION) { |
| 1906 RUNTIME_GET_ISOLATE; |
| 1823 ASSERT(args.length() == 2); | 1907 ASSERT(args.length() == 2); |
| 1824 | 1908 |
| 1825 CONVERT_CHECKED(Code, code, args[0]); | 1909 CONVERT_CHECKED(Code, code, args[0]); |
| 1826 CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]); | 1910 CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]); |
| 1827 | 1911 |
| 1828 RUNTIME_ASSERT(0 <= offset && offset < code->Size()); | 1912 RUNTIME_ASSERT(0 <= offset && offset < code->Size()); |
| 1829 | 1913 |
| 1830 Address pc = code->address() + offset; | 1914 Address pc = code->address() + offset; |
| 1831 return Smi::FromInt(code->SourcePosition(pc)); | 1915 return Smi::FromInt(code->SourcePosition(pc)); |
| 1832 } | 1916 } |
| 1833 | 1917 |
| 1834 | 1918 |
| 1835 | 1919 static MaybeObject* Runtime_FunctionSetInstanceClassName( |
| 1836 static MaybeObject* Runtime_FunctionSetInstanceClassName(Arguments args) { | 1920 RUNTIME_CALLING_CONVENTION) { |
| 1921 RUNTIME_GET_ISOLATE; |
| 1837 NoHandleAllocation ha; | 1922 NoHandleAllocation ha; |
| 1838 ASSERT(args.length() == 2); | 1923 ASSERT(args.length() == 2); |
| 1839 | 1924 |
| 1840 CONVERT_CHECKED(JSFunction, fun, args[0]); | 1925 CONVERT_CHECKED(JSFunction, fun, args[0]); |
| 1841 CONVERT_CHECKED(String, name, args[1]); | 1926 CONVERT_CHECKED(String, name, args[1]); |
| 1842 fun->SetInstanceClassName(name); | 1927 fun->SetInstanceClassName(name); |
| 1843 return Heap::undefined_value(); | 1928 return isolate->heap()->undefined_value(); |
| 1844 } | 1929 } |
| 1845 | 1930 |
| 1846 | 1931 |
| 1847 static MaybeObject* Runtime_FunctionSetLength(Arguments args) { | 1932 static MaybeObject* Runtime_FunctionSetLength(RUNTIME_CALLING_CONVENTION) { |
| 1933 RUNTIME_GET_ISOLATE; |
| 1848 NoHandleAllocation ha; | 1934 NoHandleAllocation ha; |
| 1849 ASSERT(args.length() == 2); | 1935 ASSERT(args.length() == 2); |
| 1850 | 1936 |
| 1851 CONVERT_CHECKED(JSFunction, fun, args[0]); | 1937 CONVERT_CHECKED(JSFunction, fun, args[0]); |
| 1852 CONVERT_CHECKED(Smi, length, args[1]); | 1938 CONVERT_CHECKED(Smi, length, args[1]); |
| 1853 fun->shared()->set_length(length->value()); | 1939 fun->shared()->set_length(length->value()); |
| 1854 return length; | 1940 return length; |
| 1855 } | 1941 } |
| 1856 | 1942 |
| 1857 | 1943 |
| 1858 static MaybeObject* Runtime_FunctionSetPrototype(Arguments args) { | 1944 static MaybeObject* Runtime_FunctionSetPrototype(RUNTIME_CALLING_CONVENTION) { |
| 1945 RUNTIME_GET_ISOLATE; |
| 1859 NoHandleAllocation ha; | 1946 NoHandleAllocation ha; |
| 1860 ASSERT(args.length() == 2); | 1947 ASSERT(args.length() == 2); |
| 1861 | 1948 |
| 1862 CONVERT_CHECKED(JSFunction, fun, args[0]); | 1949 CONVERT_CHECKED(JSFunction, fun, args[0]); |
| 1863 ASSERT(fun->should_have_prototype()); | 1950 ASSERT(fun->should_have_prototype()); |
| 1864 Object* obj; | 1951 Object* obj; |
| 1865 { MaybeObject* maybe_obj = | 1952 { MaybeObject* maybe_obj = |
| 1866 Accessors::FunctionSetPrototype(fun, args[1], NULL); | 1953 Accessors::FunctionSetPrototype(fun, args[1], NULL); |
| 1867 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1954 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1868 } | 1955 } |
| 1869 return args[0]; // return TOS | 1956 return args[0]; // return TOS |
| 1870 } | 1957 } |
| 1871 | 1958 |
| 1872 | 1959 |
| 1873 static MaybeObject* Runtime_FunctionIsAPIFunction(Arguments args) { | 1960 static MaybeObject* Runtime_FunctionIsAPIFunction(RUNTIME_CALLING_CONVENTION) { |
| 1961 RUNTIME_GET_ISOLATE; |
| 1874 NoHandleAllocation ha; | 1962 NoHandleAllocation ha; |
| 1875 ASSERT(args.length() == 1); | 1963 ASSERT(args.length() == 1); |
| 1876 | 1964 |
| 1877 CONVERT_CHECKED(JSFunction, f, args[0]); | 1965 CONVERT_CHECKED(JSFunction, f, args[0]); |
| 1878 return f->shared()->IsApiFunction() ? Heap::true_value() | 1966 return f->shared()->IsApiFunction() ? isolate->heap()->true_value() |
| 1879 : Heap::false_value(); | 1967 : isolate->heap()->false_value(); |
| 1880 } | 1968 } |
| 1881 | 1969 |
| 1882 static MaybeObject* Runtime_FunctionIsBuiltin(Arguments args) { | 1970 |
| 1971 static MaybeObject* Runtime_FunctionIsBuiltin(RUNTIME_CALLING_CONVENTION) { |
| 1972 RUNTIME_GET_ISOLATE; |
| 1883 NoHandleAllocation ha; | 1973 NoHandleAllocation ha; |
| 1884 ASSERT(args.length() == 1); | 1974 ASSERT(args.length() == 1); |
| 1885 | 1975 |
| 1886 CONVERT_CHECKED(JSFunction, f, args[0]); | 1976 CONVERT_CHECKED(JSFunction, f, args[0]); |
| 1887 return f->IsBuiltin() ? Heap::true_value() : Heap::false_value(); | 1977 return f->IsBuiltin() ? isolate->heap()->true_value() : |
| 1978 isolate->heap()->false_value(); |
| 1888 } | 1979 } |
| 1889 | 1980 |
| 1890 | 1981 |
| 1891 static MaybeObject* Runtime_SetCode(Arguments args) { | 1982 static MaybeObject* Runtime_SetCode(RUNTIME_CALLING_CONVENTION) { |
| 1892 HandleScope scope; | 1983 RUNTIME_GET_ISOLATE; |
| 1984 HandleScope scope(isolate); |
| 1893 ASSERT(args.length() == 2); | 1985 ASSERT(args.length() == 2); |
| 1894 | 1986 |
| 1895 CONVERT_ARG_CHECKED(JSFunction, target, 0); | 1987 CONVERT_ARG_CHECKED(JSFunction, target, 0); |
| 1896 Handle<Object> code = args.at<Object>(1); | 1988 Handle<Object> code = args.at<Object>(1); |
| 1897 | 1989 |
| 1898 Handle<Context> context(target->context()); | 1990 Handle<Context> context(target->context()); |
| 1899 | 1991 |
| 1900 if (!code->IsNull()) { | 1992 if (!code->IsNull()) { |
| 1901 RUNTIME_ASSERT(code->IsJSFunction()); | 1993 RUNTIME_ASSERT(code->IsJSFunction()); |
| 1902 Handle<JSFunction> fun = Handle<JSFunction>::cast(code); | 1994 Handle<JSFunction> fun = Handle<JSFunction>::cast(code); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1914 target->shared()->set_code(shared->code()); | 2006 target->shared()->set_code(shared->code()); |
| 1915 target->ReplaceCode(shared->code()); | 2007 target->ReplaceCode(shared->code()); |
| 1916 target->shared()->set_scope_info(shared->scope_info()); | 2008 target->shared()->set_scope_info(shared->scope_info()); |
| 1917 target->shared()->set_length(shared->length()); | 2009 target->shared()->set_length(shared->length()); |
| 1918 target->shared()->set_formal_parameter_count( | 2010 target->shared()->set_formal_parameter_count( |
| 1919 shared->formal_parameter_count()); | 2011 shared->formal_parameter_count()); |
| 1920 // Set the source code of the target function to undefined. | 2012 // Set the source code of the target function to undefined. |
| 1921 // SetCode is only used for built-in constructors like String, | 2013 // SetCode is only used for built-in constructors like String, |
| 1922 // Array, and Object, and some web code | 2014 // Array, and Object, and some web code |
| 1923 // doesn't like seeing source code for constructors. | 2015 // doesn't like seeing source code for constructors. |
| 1924 target->shared()->set_script(Heap::undefined_value()); | 2016 target->shared()->set_script(isolate->heap()->undefined_value()); |
| 1925 target->shared()->code()->set_optimizable(false); | 2017 target->shared()->code()->set_optimizable(false); |
| 1926 // Clear the optimization hints related to the compiled code as these are no | 2018 // Clear the optimization hints related to the compiled code as these are no |
| 1927 // longer valid when the code is overwritten. | 2019 // longer valid when the code is overwritten. |
| 1928 target->shared()->ClearThisPropertyAssignmentsInfo(); | 2020 target->shared()->ClearThisPropertyAssignmentsInfo(); |
| 1929 context = Handle<Context>(fun->context()); | 2021 context = Handle<Context>(fun->context()); |
| 1930 | 2022 |
| 1931 // Make sure we get a fresh copy of the literal vector to avoid | 2023 // Make sure we get a fresh copy of the literal vector to avoid |
| 1932 // cross context contamination. | 2024 // cross context contamination. |
| 1933 int number_of_literals = fun->NumberOfLiterals(); | 2025 int number_of_literals = fun->NumberOfLiterals(); |
| 1934 Handle<FixedArray> literals = | 2026 Handle<FixedArray> literals = |
| 1935 Factory::NewFixedArray(number_of_literals, TENURED); | 2027 isolate->factory()->NewFixedArray(number_of_literals, TENURED); |
| 1936 if (number_of_literals > 0) { | 2028 if (number_of_literals > 0) { |
| 1937 // Insert the object, regexp and array functions in the literals | 2029 // Insert the object, regexp and array functions in the literals |
| 1938 // array prefix. These are the functions that will be used when | 2030 // array prefix. These are the functions that will be used when |
| 1939 // creating object, regexp and array literals. | 2031 // creating object, regexp and array literals. |
| 1940 literals->set(JSFunction::kLiteralGlobalContextIndex, | 2032 literals->set(JSFunction::kLiteralGlobalContextIndex, |
| 1941 context->global_context()); | 2033 context->global_context()); |
| 1942 } | 2034 } |
| 1943 // It's okay to skip the write barrier here because the literals | 2035 // It's okay to skip the write barrier here because the literals |
| 1944 // are guaranteed to be in old space. | 2036 // are guaranteed to be in old space. |
| 1945 target->set_literals(*literals, SKIP_WRITE_BARRIER); | 2037 target->set_literals(*literals, SKIP_WRITE_BARRIER); |
| 1946 target->set_next_function_link(Heap::undefined_value()); | 2038 target->set_next_function_link(isolate->heap()->undefined_value()); |
| 1947 } | 2039 } |
| 1948 | 2040 |
| 1949 target->set_context(*context); | 2041 target->set_context(*context); |
| 1950 return *target; | 2042 return *target; |
| 1951 } | 2043 } |
| 1952 | 2044 |
| 1953 | 2045 |
| 1954 static MaybeObject* Runtime_SetExpectedNumberOfProperties(Arguments args) { | 2046 static MaybeObject* Runtime_SetExpectedNumberOfProperties( |
| 1955 HandleScope scope; | 2047 RUNTIME_CALLING_CONVENTION) { |
| 2048 RUNTIME_GET_ISOLATE; |
| 2049 HandleScope scope(isolate); |
| 1956 ASSERT(args.length() == 2); | 2050 ASSERT(args.length() == 2); |
| 1957 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 2051 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
| 1958 CONVERT_SMI_CHECKED(num, args[1]); | 2052 CONVERT_SMI_CHECKED(num, args[1]); |
| 1959 RUNTIME_ASSERT(num >= 0); | 2053 RUNTIME_ASSERT(num >= 0); |
| 1960 SetExpectedNofProperties(function, num); | 2054 SetExpectedNofProperties(function, num); |
| 1961 return Heap::undefined_value(); | 2055 return isolate->heap()->undefined_value(); |
| 1962 } | 2056 } |
| 1963 | 2057 |
| 1964 | 2058 |
| 1965 MUST_USE_RESULT static MaybeObject* CharFromCode(Object* char_code) { | 2059 MUST_USE_RESULT static MaybeObject* CharFromCode(Isolate* isolate, |
| 2060 Object* char_code) { |
| 1966 uint32_t code; | 2061 uint32_t code; |
| 1967 if (char_code->ToArrayIndex(&code)) { | 2062 if (char_code->ToArrayIndex(&code)) { |
| 1968 if (code <= 0xffff) { | 2063 if (code <= 0xffff) { |
| 1969 return Heap::LookupSingleCharacterStringFromCode(code); | 2064 return isolate->heap()->LookupSingleCharacterStringFromCode(code); |
| 1970 } | 2065 } |
| 1971 } | 2066 } |
| 1972 return Heap::empty_string(); | 2067 return isolate->heap()->empty_string(); |
| 1973 } | 2068 } |
| 1974 | 2069 |
| 1975 | 2070 |
| 1976 static MaybeObject* Runtime_StringCharCodeAt(Arguments args) { | 2071 static MaybeObject* Runtime_StringCharCodeAt(RUNTIME_CALLING_CONVENTION) { |
| 2072 RUNTIME_GET_ISOLATE; |
| 1977 NoHandleAllocation ha; | 2073 NoHandleAllocation ha; |
| 1978 ASSERT(args.length() == 2); | 2074 ASSERT(args.length() == 2); |
| 1979 | 2075 |
| 1980 CONVERT_CHECKED(String, subject, args[0]); | 2076 CONVERT_CHECKED(String, subject, args[0]); |
| 1981 Object* index = args[1]; | 2077 Object* index = args[1]; |
| 1982 RUNTIME_ASSERT(index->IsNumber()); | 2078 RUNTIME_ASSERT(index->IsNumber()); |
| 1983 | 2079 |
| 1984 uint32_t i = 0; | 2080 uint32_t i = 0; |
| 1985 if (index->IsSmi()) { | 2081 if (index->IsSmi()) { |
| 1986 int value = Smi::cast(index)->value(); | 2082 int value = Smi::cast(index)->value(); |
| 1987 if (value < 0) return Heap::nan_value(); | 2083 if (value < 0) return isolate->heap()->nan_value(); |
| 1988 i = value; | 2084 i = value; |
| 1989 } else { | 2085 } else { |
| 1990 ASSERT(index->IsHeapNumber()); | 2086 ASSERT(index->IsHeapNumber()); |
| 1991 double value = HeapNumber::cast(index)->value(); | 2087 double value = HeapNumber::cast(index)->value(); |
| 1992 i = static_cast<uint32_t>(DoubleToInteger(value)); | 2088 i = static_cast<uint32_t>(DoubleToInteger(value)); |
| 1993 } | 2089 } |
| 1994 | 2090 |
| 1995 // Flatten the string. If someone wants to get a char at an index | 2091 // Flatten the string. If someone wants to get a char at an index |
| 1996 // in a cons string, it is likely that more indices will be | 2092 // in a cons string, it is likely that more indices will be |
| 1997 // accessed. | 2093 // accessed. |
| 1998 Object* flat; | 2094 Object* flat; |
| 1999 { MaybeObject* maybe_flat = subject->TryFlatten(); | 2095 { MaybeObject* maybe_flat = subject->TryFlatten(); |
| 2000 if (!maybe_flat->ToObject(&flat)) return maybe_flat; | 2096 if (!maybe_flat->ToObject(&flat)) return maybe_flat; |
| 2001 } | 2097 } |
| 2002 subject = String::cast(flat); | 2098 subject = String::cast(flat); |
| 2003 | 2099 |
| 2004 if (i >= static_cast<uint32_t>(subject->length())) { | 2100 if (i >= static_cast<uint32_t>(subject->length())) { |
| 2005 return Heap::nan_value(); | 2101 return isolate->heap()->nan_value(); |
| 2006 } | 2102 } |
| 2007 | 2103 |
| 2008 return Smi::FromInt(subject->Get(i)); | 2104 return Smi::FromInt(subject->Get(i)); |
| 2009 } | 2105 } |
| 2010 | 2106 |
| 2011 | 2107 |
| 2012 static MaybeObject* Runtime_CharFromCode(Arguments args) { | 2108 static MaybeObject* Runtime_CharFromCode(RUNTIME_CALLING_CONVENTION) { |
| 2109 RUNTIME_GET_ISOLATE; |
| 2013 NoHandleAllocation ha; | 2110 NoHandleAllocation ha; |
| 2014 ASSERT(args.length() == 1); | 2111 ASSERT(args.length() == 1); |
| 2015 return CharFromCode(args[0]); | 2112 return CharFromCode(isolate, args[0]); |
| 2016 } | 2113 } |
| 2017 | 2114 |
| 2018 | 2115 |
| 2019 class FixedArrayBuilder { | 2116 class FixedArrayBuilder { |
| 2020 public: | 2117 public: |
| 2021 explicit FixedArrayBuilder(int initial_capacity) | 2118 explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity) |
| 2022 : array_(Factory::NewFixedArrayWithHoles(initial_capacity)), | 2119 : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)), |
| 2023 length_(0) { | 2120 length_(0) { |
| 2024 // Require a non-zero initial size. Ensures that doubling the size to | 2121 // Require a non-zero initial size. Ensures that doubling the size to |
| 2025 // extend the array will work. | 2122 // extend the array will work. |
| 2026 ASSERT(initial_capacity > 0); | 2123 ASSERT(initial_capacity > 0); |
| 2027 } | 2124 } |
| 2028 | 2125 |
| 2029 explicit FixedArrayBuilder(Handle<FixedArray> backing_store) | 2126 explicit FixedArrayBuilder(Handle<FixedArray> backing_store) |
| 2030 : array_(backing_store), | 2127 : array_(backing_store), |
| 2031 length_(0) { | 2128 length_(0) { |
| 2032 // Require a non-zero initial size. Ensures that doubling the size to | 2129 // Require a non-zero initial size. Ensures that doubling the size to |
| 2033 // extend the array will work. | 2130 // extend the array will work. |
| 2034 ASSERT(backing_store->length() > 0); | 2131 ASSERT(backing_store->length() > 0); |
| 2035 } | 2132 } |
| 2036 | 2133 |
| 2037 bool HasCapacity(int elements) { | 2134 bool HasCapacity(int elements) { |
| 2038 int length = array_->length(); | 2135 int length = array_->length(); |
| 2039 int required_length = length_ + elements; | 2136 int required_length = length_ + elements; |
| 2040 return (length >= required_length); | 2137 return (length >= required_length); |
| 2041 } | 2138 } |
| 2042 | 2139 |
| 2043 void EnsureCapacity(int elements) { | 2140 void EnsureCapacity(int elements) { |
| 2044 int length = array_->length(); | 2141 int length = array_->length(); |
| 2045 int required_length = length_ + elements; | 2142 int required_length = length_ + elements; |
| 2046 if (length < required_length) { | 2143 if (length < required_length) { |
| 2047 int new_length = length; | 2144 int new_length = length; |
| 2048 do { | 2145 do { |
| 2049 new_length *= 2; | 2146 new_length *= 2; |
| 2050 } while (new_length < required_length); | 2147 } while (new_length < required_length); |
| 2051 Handle<FixedArray> extended_array = | 2148 Handle<FixedArray> extended_array = |
| 2052 Factory::NewFixedArrayWithHoles(new_length); | 2149 array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length); |
| 2053 array_->CopyTo(0, *extended_array, 0, length_); | 2150 array_->CopyTo(0, *extended_array, 0, length_); |
| 2054 array_ = extended_array; | 2151 array_ = extended_array; |
| 2055 } | 2152 } |
| 2056 } | 2153 } |
| 2057 | 2154 |
| 2058 void Add(Object* value) { | 2155 void Add(Object* value) { |
| 2059 ASSERT(length_ < capacity()); | 2156 ASSERT(length_ < capacity()); |
| 2060 array_->set(length_, value); | 2157 array_->set(length_, value); |
| 2061 length_++; | 2158 length_++; |
| 2062 } | 2159 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2073 | 2170 |
| 2074 int length() { | 2171 int length() { |
| 2075 return length_; | 2172 return length_; |
| 2076 } | 2173 } |
| 2077 | 2174 |
| 2078 int capacity() { | 2175 int capacity() { |
| 2079 return array_->length(); | 2176 return array_->length(); |
| 2080 } | 2177 } |
| 2081 | 2178 |
| 2082 Handle<JSArray> ToJSArray() { | 2179 Handle<JSArray> ToJSArray() { |
| 2083 Handle<JSArray> result_array = Factory::NewJSArrayWithElements(array_); | 2180 Handle<JSArray> result_array = FACTORY->NewJSArrayWithElements(array_); |
| 2084 result_array->set_length(Smi::FromInt(length_)); | 2181 result_array->set_length(Smi::FromInt(length_)); |
| 2085 return result_array; | 2182 return result_array; |
| 2086 } | 2183 } |
| 2087 | 2184 |
| 2088 Handle<JSArray> ToJSArray(Handle<JSArray> target_array) { | 2185 Handle<JSArray> ToJSArray(Handle<JSArray> target_array) { |
| 2089 target_array->set_elements(*array_); | 2186 target_array->set_elements(*array_); |
| 2090 target_array->set_length(Smi::FromInt(length_)); | 2187 target_array->set_length(Smi::FromInt(length_)); |
| 2091 return target_array; | 2188 return target_array; |
| 2092 } | 2189 } |
| 2093 | 2190 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2110 typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits> | 2207 typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits> |
| 2111 StringBuilderSubstringLength; | 2208 StringBuilderSubstringLength; |
| 2112 typedef BitField<int, | 2209 typedef BitField<int, |
| 2113 kStringBuilderConcatHelperLengthBits, | 2210 kStringBuilderConcatHelperLengthBits, |
| 2114 kStringBuilderConcatHelperPositionBits> | 2211 kStringBuilderConcatHelperPositionBits> |
| 2115 StringBuilderSubstringPosition; | 2212 StringBuilderSubstringPosition; |
| 2116 | 2213 |
| 2117 | 2214 |
| 2118 class ReplacementStringBuilder { | 2215 class ReplacementStringBuilder { |
| 2119 public: | 2216 public: |
| 2120 ReplacementStringBuilder(Handle<String> subject, int estimated_part_count) | 2217 ReplacementStringBuilder(Heap* heap, |
| 2121 : array_builder_(estimated_part_count), | 2218 Handle<String> subject, |
| 2219 int estimated_part_count) |
| 2220 : heap_(heap), |
| 2221 array_builder_(heap->isolate(), estimated_part_count), |
| 2122 subject_(subject), | 2222 subject_(subject), |
| 2123 character_count_(0), | 2223 character_count_(0), |
| 2124 is_ascii_(subject->IsAsciiRepresentation()) { | 2224 is_ascii_(subject->IsAsciiRepresentation()) { |
| 2125 // Require a non-zero initial size. Ensures that doubling the size to | 2225 // Require a non-zero initial size. Ensures that doubling the size to |
| 2126 // extend the array will work. | 2226 // extend the array will work. |
| 2127 ASSERT(estimated_part_count > 0); | 2227 ASSERT(estimated_part_count > 0); |
| 2128 } | 2228 } |
| 2129 | 2229 |
| 2130 static inline void AddSubjectSlice(FixedArrayBuilder* builder, | 2230 static inline void AddSubjectSlice(FixedArrayBuilder* builder, |
| 2131 int from, | 2231 int from, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2163 AddElement(*string); | 2263 AddElement(*string); |
| 2164 if (!string->IsAsciiRepresentation()) { | 2264 if (!string->IsAsciiRepresentation()) { |
| 2165 is_ascii_ = false; | 2265 is_ascii_ = false; |
| 2166 } | 2266 } |
| 2167 IncrementCharacterCount(length); | 2267 IncrementCharacterCount(length); |
| 2168 } | 2268 } |
| 2169 | 2269 |
| 2170 | 2270 |
| 2171 Handle<String> ToString() { | 2271 Handle<String> ToString() { |
| 2172 if (array_builder_.length() == 0) { | 2272 if (array_builder_.length() == 0) { |
| 2173 return Factory::empty_string(); | 2273 return heap_->isolate()->factory()->empty_string(); |
| 2174 } | 2274 } |
| 2175 | 2275 |
| 2176 Handle<String> joined_string; | 2276 Handle<String> joined_string; |
| 2177 if (is_ascii_) { | 2277 if (is_ascii_) { |
| 2178 joined_string = NewRawAsciiString(character_count_); | 2278 joined_string = NewRawAsciiString(character_count_); |
| 2179 AssertNoAllocation no_alloc; | 2279 AssertNoAllocation no_alloc; |
| 2180 SeqAsciiString* seq = SeqAsciiString::cast(*joined_string); | 2280 SeqAsciiString* seq = SeqAsciiString::cast(*joined_string); |
| 2181 char* char_buffer = seq->GetChars(); | 2281 char* char_buffer = seq->GetChars(); |
| 2182 StringBuilderConcatHelper(*subject_, | 2282 StringBuilderConcatHelper(*subject_, |
| 2183 char_buffer, | 2283 char_buffer, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2204 } | 2304 } |
| 2205 character_count_ += by; | 2305 character_count_ += by; |
| 2206 } | 2306 } |
| 2207 | 2307 |
| 2208 Handle<JSArray> GetParts() { | 2308 Handle<JSArray> GetParts() { |
| 2209 return array_builder_.ToJSArray(); | 2309 return array_builder_.ToJSArray(); |
| 2210 } | 2310 } |
| 2211 | 2311 |
| 2212 private: | 2312 private: |
| 2213 Handle<String> NewRawAsciiString(int size) { | 2313 Handle<String> NewRawAsciiString(int size) { |
| 2214 CALL_HEAP_FUNCTION(Heap::AllocateRawAsciiString(size), String); | 2314 CALL_HEAP_FUNCTION(heap_->isolate(), |
| 2315 heap_->AllocateRawAsciiString(size), String); |
| 2215 } | 2316 } |
| 2216 | 2317 |
| 2217 | 2318 |
| 2218 Handle<String> NewRawTwoByteString(int size) { | 2319 Handle<String> NewRawTwoByteString(int size) { |
| 2219 CALL_HEAP_FUNCTION(Heap::AllocateRawTwoByteString(size), String); | 2320 CALL_HEAP_FUNCTION(heap_->isolate(), |
| 2321 heap_->AllocateRawTwoByteString(size), String); |
| 2220 } | 2322 } |
| 2221 | 2323 |
| 2222 | 2324 |
| 2223 void AddElement(Object* element) { | 2325 void AddElement(Object* element) { |
| 2224 ASSERT(element->IsSmi() || element->IsString()); | 2326 ASSERT(element->IsSmi() || element->IsString()); |
| 2225 ASSERT(array_builder_.capacity() > array_builder_.length()); | 2327 ASSERT(array_builder_.capacity() > array_builder_.length()); |
| 2226 array_builder_.Add(element); | 2328 array_builder_.Add(element); |
| 2227 } | 2329 } |
| 2228 | 2330 |
| 2331 Heap* heap_; |
| 2229 FixedArrayBuilder array_builder_; | 2332 FixedArrayBuilder array_builder_; |
| 2230 Handle<String> subject_; | 2333 Handle<String> subject_; |
| 2231 int character_count_; | 2334 int character_count_; |
| 2232 bool is_ascii_; | 2335 bool is_ascii_; |
| 2233 }; | 2336 }; |
| 2234 | 2337 |
| 2235 | 2338 |
| 2236 class CompiledReplacement { | 2339 class CompiledReplacement { |
| 2237 public: | 2340 public: |
| 2238 CompiledReplacement() | 2341 CompiledReplacement() |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2429 subject_length); | 2532 subject_length); |
| 2430 } else { | 2533 } else { |
| 2431 ASSERT(replacement->IsTwoByteRepresentation()); | 2534 ASSERT(replacement->IsTwoByteRepresentation()); |
| 2432 AssertNoAllocation no_alloc; | 2535 AssertNoAllocation no_alloc; |
| 2433 | 2536 |
| 2434 ParseReplacementPattern(&parts_, | 2537 ParseReplacementPattern(&parts_, |
| 2435 replacement->ToUC16Vector(), | 2538 replacement->ToUC16Vector(), |
| 2436 capture_count, | 2539 capture_count, |
| 2437 subject_length); | 2540 subject_length); |
| 2438 } | 2541 } |
| 2542 Isolate* isolate = replacement->GetIsolate(); |
| 2439 // Find substrings of replacement string and create them as String objects. | 2543 // Find substrings of replacement string and create them as String objects. |
| 2440 int substring_index = 0; | 2544 int substring_index = 0; |
| 2441 for (int i = 0, n = parts_.length(); i < n; i++) { | 2545 for (int i = 0, n = parts_.length(); i < n; i++) { |
| 2442 int tag = parts_[i].tag; | 2546 int tag = parts_[i].tag; |
| 2443 if (tag <= 0) { // A replacement string slice. | 2547 if (tag <= 0) { // A replacement string slice. |
| 2444 int from = -tag; | 2548 int from = -tag; |
| 2445 int to = parts_[i].data; | 2549 int to = parts_[i].data; |
| 2446 replacement_substrings_.Add(Factory::NewSubString(replacement, from, to)); | 2550 replacement_substrings_.Add( |
| 2551 isolate->factory()->NewSubString(replacement, from, to)); |
| 2447 parts_[i].tag = REPLACEMENT_SUBSTRING; | 2552 parts_[i].tag = REPLACEMENT_SUBSTRING; |
| 2448 parts_[i].data = substring_index; | 2553 parts_[i].data = substring_index; |
| 2449 substring_index++; | 2554 substring_index++; |
| 2450 } else if (tag == REPLACEMENT_STRING) { | 2555 } else if (tag == REPLACEMENT_STRING) { |
| 2451 replacement_substrings_.Add(replacement); | 2556 replacement_substrings_.Add(replacement); |
| 2452 parts_[i].data = substring_index; | 2557 parts_[i].data = substring_index; |
| 2453 substring_index++; | 2558 substring_index++; |
| 2454 } | 2559 } |
| 2455 } | 2560 } |
| 2456 } | 2561 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2489 break; | 2594 break; |
| 2490 default: | 2595 default: |
| 2491 UNREACHABLE(); | 2596 UNREACHABLE(); |
| 2492 } | 2597 } |
| 2493 } | 2598 } |
| 2494 } | 2599 } |
| 2495 | 2600 |
| 2496 | 2601 |
| 2497 | 2602 |
| 2498 MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithString( | 2603 MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithString( |
| 2604 Isolate* isolate, |
| 2499 String* subject, | 2605 String* subject, |
| 2500 JSRegExp* regexp, | 2606 JSRegExp* regexp, |
| 2501 String* replacement, | 2607 String* replacement, |
| 2502 JSArray* last_match_info) { | 2608 JSArray* last_match_info) { |
| 2503 ASSERT(subject->IsFlat()); | 2609 ASSERT(subject->IsFlat()); |
| 2504 ASSERT(replacement->IsFlat()); | 2610 ASSERT(replacement->IsFlat()); |
| 2505 | 2611 |
| 2506 HandleScope handles; | 2612 HandleScope handles(isolate); |
| 2507 | 2613 |
| 2508 int length = subject->length(); | 2614 int length = subject->length(); |
| 2509 Handle<String> subject_handle(subject); | 2615 Handle<String> subject_handle(subject); |
| 2510 Handle<JSRegExp> regexp_handle(regexp); | 2616 Handle<JSRegExp> regexp_handle(regexp); |
| 2511 Handle<String> replacement_handle(replacement); | 2617 Handle<String> replacement_handle(replacement); |
| 2512 Handle<JSArray> last_match_info_handle(last_match_info); | 2618 Handle<JSArray> last_match_info_handle(last_match_info); |
| 2513 Handle<Object> match = RegExpImpl::Exec(regexp_handle, | 2619 Handle<Object> match = RegExpImpl::Exec(regexp_handle, |
| 2514 subject_handle, | 2620 subject_handle, |
| 2515 0, | 2621 0, |
| 2516 last_match_info_handle); | 2622 last_match_info_handle); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2530 capture_count, | 2636 capture_count, |
| 2531 length); | 2637 length); |
| 2532 | 2638 |
| 2533 bool is_global = regexp_handle->GetFlags().is_global(); | 2639 bool is_global = regexp_handle->GetFlags().is_global(); |
| 2534 | 2640 |
| 2535 // Guessing the number of parts that the final result string is built | 2641 // Guessing the number of parts that the final result string is built |
| 2536 // from. Global regexps can match any number of times, so we guess | 2642 // from. Global regexps can match any number of times, so we guess |
| 2537 // conservatively. | 2643 // conservatively. |
| 2538 int expected_parts = | 2644 int expected_parts = |
| 2539 (compiled_replacement.parts() + 1) * (is_global ? 4 : 1) + 1; | 2645 (compiled_replacement.parts() + 1) * (is_global ? 4 : 1) + 1; |
| 2540 ReplacementStringBuilder builder(subject_handle, expected_parts); | 2646 ReplacementStringBuilder builder(isolate->heap(), |
| 2647 subject_handle, |
| 2648 expected_parts); |
| 2541 | 2649 |
| 2542 // Index of end of last match. | 2650 // Index of end of last match. |
| 2543 int prev = 0; | 2651 int prev = 0; |
| 2544 | 2652 |
| 2545 // Number of parts added by compiled replacement plus preceeding | 2653 // Number of parts added by compiled replacement plus preceeding |
| 2546 // string and possibly suffix after last match. It is possible for | 2654 // string and possibly suffix after last match. It is possible for |
| 2547 // all components to use two elements when encoded as two smis. | 2655 // all components to use two elements when encoded as two smis. |
| 2548 const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2); | 2656 const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2); |
| 2549 bool matched = true; | 2657 bool matched = true; |
| 2550 do { | 2658 do { |
| 2551 ASSERT(last_match_info_handle->HasFastElements()); | 2659 ASSERT(last_match_info_handle->HasFastElements()); |
| 2552 // Increase the capacity of the builder before entering local handle-scope, | 2660 // Increase the capacity of the builder before entering local handle-scope, |
| 2553 // so its internal buffer can safely allocate a new handle if it grows. | 2661 // so its internal buffer can safely allocate a new handle if it grows. |
| 2554 builder.EnsureCapacity(parts_added_per_loop); | 2662 builder.EnsureCapacity(parts_added_per_loop); |
| 2555 | 2663 |
| 2556 HandleScope loop_scope; | 2664 HandleScope loop_scope(isolate); |
| 2557 int start, end; | 2665 int start, end; |
| 2558 { | 2666 { |
| 2559 AssertNoAllocation match_info_array_is_not_in_a_handle; | 2667 AssertNoAllocation match_info_array_is_not_in_a_handle; |
| 2560 FixedArray* match_info_array = | 2668 FixedArray* match_info_array = |
| 2561 FixedArray::cast(last_match_info_handle->elements()); | 2669 FixedArray::cast(last_match_info_handle->elements()); |
| 2562 | 2670 |
| 2563 ASSERT_EQ(capture_count * 2 + 2, | 2671 ASSERT_EQ(capture_count * 2 + 2, |
| 2564 RegExpImpl::GetLastCaptureCount(match_info_array)); | 2672 RegExpImpl::GetLastCaptureCount(match_info_array)); |
| 2565 start = RegExpImpl::GetCapture(match_info_array, 0); | 2673 start = RegExpImpl::GetCapture(match_info_array, 0); |
| 2566 end = RegExpImpl::GetCapture(match_info_array, 1); | 2674 end = RegExpImpl::GetCapture(match_info_array, 1); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2598 if (prev < length) { | 2706 if (prev < length) { |
| 2599 builder.AddSubjectSlice(prev, length); | 2707 builder.AddSubjectSlice(prev, length); |
| 2600 } | 2708 } |
| 2601 | 2709 |
| 2602 return *(builder.ToString()); | 2710 return *(builder.ToString()); |
| 2603 } | 2711 } |
| 2604 | 2712 |
| 2605 | 2713 |
| 2606 template <typename ResultSeqString> | 2714 template <typename ResultSeqString> |
| 2607 MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString( | 2715 MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString( |
| 2716 Isolate* isolate, |
| 2608 String* subject, | 2717 String* subject, |
| 2609 JSRegExp* regexp, | 2718 JSRegExp* regexp, |
| 2610 JSArray* last_match_info) { | 2719 JSArray* last_match_info) { |
| 2611 ASSERT(subject->IsFlat()); | 2720 ASSERT(subject->IsFlat()); |
| 2612 | 2721 |
| 2613 HandleScope handles; | 2722 HandleScope handles(isolate); |
| 2614 | 2723 |
| 2615 Handle<String> subject_handle(subject); | 2724 Handle<String> subject_handle(subject); |
| 2616 Handle<JSRegExp> regexp_handle(regexp); | 2725 Handle<JSRegExp> regexp_handle(regexp); |
| 2617 Handle<JSArray> last_match_info_handle(last_match_info); | 2726 Handle<JSArray> last_match_info_handle(last_match_info); |
| 2618 Handle<Object> match = RegExpImpl::Exec(regexp_handle, | 2727 Handle<Object> match = RegExpImpl::Exec(regexp_handle, |
| 2619 subject_handle, | 2728 subject_handle, |
| 2620 0, | 2729 0, |
| 2621 last_match_info_handle); | 2730 last_match_info_handle); |
| 2622 if (match.is_null()) return Failure::Exception(); | 2731 if (match.is_null()) return Failure::Exception(); |
| 2623 if (match->IsNull()) return *subject_handle; | 2732 if (match->IsNull()) return *subject_handle; |
| 2624 | 2733 |
| 2625 ASSERT(last_match_info_handle->HasFastElements()); | 2734 ASSERT(last_match_info_handle->HasFastElements()); |
| 2626 | 2735 |
| 2627 HandleScope loop_scope; | |
| 2628 int start, end; | 2736 int start, end; |
| 2629 { | 2737 { |
| 2630 AssertNoAllocation match_info_array_is_not_in_a_handle; | 2738 AssertNoAllocation match_info_array_is_not_in_a_handle; |
| 2631 FixedArray* match_info_array = | 2739 FixedArray* match_info_array = |
| 2632 FixedArray::cast(last_match_info_handle->elements()); | 2740 FixedArray::cast(last_match_info_handle->elements()); |
| 2633 | 2741 |
| 2634 start = RegExpImpl::GetCapture(match_info_array, 0); | 2742 start = RegExpImpl::GetCapture(match_info_array, 0); |
| 2635 end = RegExpImpl::GetCapture(match_info_array, 1); | 2743 end = RegExpImpl::GetCapture(match_info_array, 1); |
| 2636 } | 2744 } |
| 2637 | 2745 |
| 2638 int length = subject->length(); | 2746 int length = subject->length(); |
| 2639 int new_length = length - (end - start); | 2747 int new_length = length - (end - start); |
| 2640 if (new_length == 0) { | 2748 if (new_length == 0) { |
| 2641 return Heap::empty_string(); | 2749 return isolate->heap()->empty_string(); |
| 2642 } | 2750 } |
| 2643 Handle<ResultSeqString> answer; | 2751 Handle<ResultSeqString> answer; |
| 2644 if (ResultSeqString::kHasAsciiEncoding) { | 2752 if (ResultSeqString::kHasAsciiEncoding) { |
| 2645 answer = | 2753 answer = Handle<ResultSeqString>::cast( |
| 2646 Handle<ResultSeqString>::cast(Factory::NewRawAsciiString(new_length)); | 2754 isolate->factory()->NewRawAsciiString(new_length)); |
| 2647 } else { | 2755 } else { |
| 2648 answer = | 2756 answer = Handle<ResultSeqString>::cast( |
| 2649 Handle<ResultSeqString>::cast(Factory::NewRawTwoByteString(new_length)); | 2757 isolate->factory()->NewRawTwoByteString(new_length)); |
| 2650 } | 2758 } |
| 2651 | 2759 |
| 2652 // If the regexp isn't global, only match once. | 2760 // If the regexp isn't global, only match once. |
| 2653 if (!regexp_handle->GetFlags().is_global()) { | 2761 if (!regexp_handle->GetFlags().is_global()) { |
| 2654 if (start > 0) { | 2762 if (start > 0) { |
| 2655 String::WriteToFlat(*subject_handle, | 2763 String::WriteToFlat(*subject_handle, |
| 2656 answer->GetChars(), | 2764 answer->GetChars(), |
| 2657 0, | 2765 0, |
| 2658 start); | 2766 start); |
| 2659 } | 2767 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2687 if (next > length) break; | 2795 if (next > length) break; |
| 2688 } | 2796 } |
| 2689 match = RegExpImpl::Exec(regexp_handle, | 2797 match = RegExpImpl::Exec(regexp_handle, |
| 2690 subject_handle, | 2798 subject_handle, |
| 2691 next, | 2799 next, |
| 2692 last_match_info_handle); | 2800 last_match_info_handle); |
| 2693 if (match.is_null()) return Failure::Exception(); | 2801 if (match.is_null()) return Failure::Exception(); |
| 2694 if (match->IsNull()) break; | 2802 if (match->IsNull()) break; |
| 2695 | 2803 |
| 2696 ASSERT(last_match_info_handle->HasFastElements()); | 2804 ASSERT(last_match_info_handle->HasFastElements()); |
| 2697 HandleScope loop_scope; | 2805 HandleScope loop_scope(isolate); |
| 2698 { | 2806 { |
| 2699 AssertNoAllocation match_info_array_is_not_in_a_handle; | 2807 AssertNoAllocation match_info_array_is_not_in_a_handle; |
| 2700 FixedArray* match_info_array = | 2808 FixedArray* match_info_array = |
| 2701 FixedArray::cast(last_match_info_handle->elements()); | 2809 FixedArray::cast(last_match_info_handle->elements()); |
| 2702 start = RegExpImpl::GetCapture(match_info_array, 0); | 2810 start = RegExpImpl::GetCapture(match_info_array, 0); |
| 2703 end = RegExpImpl::GetCapture(match_info_array, 1); | 2811 end = RegExpImpl::GetCapture(match_info_array, 1); |
| 2704 } | 2812 } |
| 2705 } while (true); | 2813 } while (true); |
| 2706 | 2814 |
| 2707 if (prev < length) { | 2815 if (prev < length) { |
| 2708 // Add substring subject[prev;length] to answer string. | 2816 // Add substring subject[prev;length] to answer string. |
| 2709 String::WriteToFlat(*subject_handle, | 2817 String::WriteToFlat(*subject_handle, |
| 2710 answer->GetChars() + position, | 2818 answer->GetChars() + position, |
| 2711 prev, | 2819 prev, |
| 2712 length); | 2820 length); |
| 2713 position += length - prev; | 2821 position += length - prev; |
| 2714 } | 2822 } |
| 2715 | 2823 |
| 2716 if (position == 0) { | 2824 if (position == 0) { |
| 2717 return Heap::empty_string(); | 2825 return isolate->heap()->empty_string(); |
| 2718 } | 2826 } |
| 2719 | 2827 |
| 2720 // Shorten string and fill | 2828 // Shorten string and fill |
| 2721 int string_size = ResultSeqString::SizeFor(position); | 2829 int string_size = ResultSeqString::SizeFor(position); |
| 2722 int allocated_string_size = ResultSeqString::SizeFor(new_length); | 2830 int allocated_string_size = ResultSeqString::SizeFor(new_length); |
| 2723 int delta = allocated_string_size - string_size; | 2831 int delta = allocated_string_size - string_size; |
| 2724 | 2832 |
| 2725 answer->set_length(position); | 2833 answer->set_length(position); |
| 2726 if (delta == 0) return *answer; | 2834 if (delta == 0) return *answer; |
| 2727 | 2835 |
| 2728 Address end_of_string = answer->address() + string_size; | 2836 Address end_of_string = answer->address() + string_size; |
| 2729 Heap::CreateFillerObjectAt(end_of_string, delta); | 2837 isolate->heap()->CreateFillerObjectAt(end_of_string, delta); |
| 2730 | 2838 |
| 2731 return *answer; | 2839 return *answer; |
| 2732 } | 2840 } |
| 2733 | 2841 |
| 2734 | 2842 |
| 2735 static MaybeObject* Runtime_StringReplaceRegExpWithString(Arguments args) { | 2843 static MaybeObject* Runtime_StringReplaceRegExpWithString( |
| 2844 RUNTIME_CALLING_CONVENTION) { |
| 2845 RUNTIME_GET_ISOLATE; |
| 2736 ASSERT(args.length() == 4); | 2846 ASSERT(args.length() == 4); |
| 2737 | 2847 |
| 2738 CONVERT_CHECKED(String, subject, args[0]); | 2848 CONVERT_CHECKED(String, subject, args[0]); |
| 2739 if (!subject->IsFlat()) { | 2849 if (!subject->IsFlat()) { |
| 2740 Object* flat_subject; | 2850 Object* flat_subject; |
| 2741 { MaybeObject* maybe_flat_subject = subject->TryFlatten(); | 2851 { MaybeObject* maybe_flat_subject = subject->TryFlatten(); |
| 2742 if (!maybe_flat_subject->ToObject(&flat_subject)) { | 2852 if (!maybe_flat_subject->ToObject(&flat_subject)) { |
| 2743 return maybe_flat_subject; | 2853 return maybe_flat_subject; |
| 2744 } | 2854 } |
| 2745 } | 2855 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2758 } | 2868 } |
| 2759 | 2869 |
| 2760 CONVERT_CHECKED(JSRegExp, regexp, args[1]); | 2870 CONVERT_CHECKED(JSRegExp, regexp, args[1]); |
| 2761 CONVERT_CHECKED(JSArray, last_match_info, args[3]); | 2871 CONVERT_CHECKED(JSArray, last_match_info, args[3]); |
| 2762 | 2872 |
| 2763 ASSERT(last_match_info->HasFastElements()); | 2873 ASSERT(last_match_info->HasFastElements()); |
| 2764 | 2874 |
| 2765 if (replacement->length() == 0) { | 2875 if (replacement->length() == 0) { |
| 2766 if (subject->HasOnlyAsciiChars()) { | 2876 if (subject->HasOnlyAsciiChars()) { |
| 2767 return StringReplaceRegExpWithEmptyString<SeqAsciiString>( | 2877 return StringReplaceRegExpWithEmptyString<SeqAsciiString>( |
| 2768 subject, regexp, last_match_info); | 2878 isolate, subject, regexp, last_match_info); |
| 2769 } else { | 2879 } else { |
| 2770 return StringReplaceRegExpWithEmptyString<SeqTwoByteString>( | 2880 return StringReplaceRegExpWithEmptyString<SeqTwoByteString>( |
| 2771 subject, regexp, last_match_info); | 2881 isolate, subject, regexp, last_match_info); |
| 2772 } | 2882 } |
| 2773 } | 2883 } |
| 2774 | 2884 |
| 2775 return StringReplaceRegExpWithString(subject, | 2885 return StringReplaceRegExpWithString(isolate, |
| 2886 subject, |
| 2776 regexp, | 2887 regexp, |
| 2777 replacement, | 2888 replacement, |
| 2778 last_match_info); | 2889 last_match_info); |
| 2779 } | 2890 } |
| 2780 | 2891 |
| 2781 | 2892 |
| 2782 // Perform string match of pattern on subject, starting at start index. | 2893 // Perform string match of pattern on subject, starting at start index. |
| 2783 // Caller must ensure that 0 <= start_index <= sub->length(), | 2894 // Caller must ensure that 0 <= start_index <= sub->length(), |
| 2784 // and should check that pat->length() + start_index <= sub->length(). | 2895 // and should check that pat->length() + start_index <= sub->length(). |
| 2785 int Runtime::StringMatch(Handle<String> sub, | 2896 int Runtime::StringMatch(Isolate* isolate, |
| 2897 Handle<String> sub, |
| 2786 Handle<String> pat, | 2898 Handle<String> pat, |
| 2787 int start_index) { | 2899 int start_index) { |
| 2788 ASSERT(0 <= start_index); | 2900 ASSERT(0 <= start_index); |
| 2789 ASSERT(start_index <= sub->length()); | 2901 ASSERT(start_index <= sub->length()); |
| 2790 | 2902 |
| 2791 int pattern_length = pat->length(); | 2903 int pattern_length = pat->length(); |
| 2792 if (pattern_length == 0) return start_index; | 2904 if (pattern_length == 0) return start_index; |
| 2793 | 2905 |
| 2794 int subject_length = sub->length(); | 2906 int subject_length = sub->length(); |
| 2795 if (start_index + pattern_length > subject_length) return -1; | 2907 if (start_index + pattern_length > subject_length) return -1; |
| 2796 | 2908 |
| 2797 if (!sub->IsFlat()) FlattenString(sub); | 2909 if (!sub->IsFlat()) FlattenString(sub); |
| 2798 if (!pat->IsFlat()) FlattenString(pat); | 2910 if (!pat->IsFlat()) FlattenString(pat); |
| 2799 | 2911 |
| 2800 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid | 2912 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid |
| 2801 // Extract flattened substrings of cons strings before determining asciiness. | 2913 // Extract flattened substrings of cons strings before determining asciiness. |
| 2802 String* seq_sub = *sub; | 2914 String* seq_sub = *sub; |
| 2803 if (seq_sub->IsConsString()) seq_sub = ConsString::cast(seq_sub)->first(); | 2915 if (seq_sub->IsConsString()) seq_sub = ConsString::cast(seq_sub)->first(); |
| 2804 String* seq_pat = *pat; | 2916 String* seq_pat = *pat; |
| 2805 if (seq_pat->IsConsString()) seq_pat = ConsString::cast(seq_pat)->first(); | 2917 if (seq_pat->IsConsString()) seq_pat = ConsString::cast(seq_pat)->first(); |
| 2806 | 2918 |
| 2807 // dispatch on type of strings | 2919 // dispatch on type of strings |
| 2808 if (seq_pat->IsAsciiRepresentation()) { | 2920 if (seq_pat->IsAsciiRepresentation()) { |
| 2809 Vector<const char> pat_vector = seq_pat->ToAsciiVector(); | 2921 Vector<const char> pat_vector = seq_pat->ToAsciiVector(); |
| 2810 if (seq_sub->IsAsciiRepresentation()) { | 2922 if (seq_sub->IsAsciiRepresentation()) { |
| 2811 return SearchString(seq_sub->ToAsciiVector(), pat_vector, start_index); | 2923 return SearchString(isolate, |
| 2924 seq_sub->ToAsciiVector(), |
| 2925 pat_vector, |
| 2926 start_index); |
| 2812 } | 2927 } |
| 2813 return SearchString(seq_sub->ToUC16Vector(), pat_vector, start_index); | 2928 return SearchString(isolate, |
| 2929 seq_sub->ToUC16Vector(), |
| 2930 pat_vector, |
| 2931 start_index); |
| 2814 } | 2932 } |
| 2815 Vector<const uc16> pat_vector = seq_pat->ToUC16Vector(); | 2933 Vector<const uc16> pat_vector = seq_pat->ToUC16Vector(); |
| 2816 if (seq_sub->IsAsciiRepresentation()) { | 2934 if (seq_sub->IsAsciiRepresentation()) { |
| 2817 return SearchString(seq_sub->ToAsciiVector(), pat_vector, start_index); | 2935 return SearchString(isolate, |
| 2936 seq_sub->ToAsciiVector(), |
| 2937 pat_vector, |
| 2938 start_index); |
| 2818 } | 2939 } |
| 2819 return SearchString(seq_sub->ToUC16Vector(), pat_vector, start_index); | 2940 return SearchString(isolate, |
| 2941 seq_sub->ToUC16Vector(), |
| 2942 pat_vector, |
| 2943 start_index); |
| 2820 } | 2944 } |
| 2821 | 2945 |
| 2822 | 2946 |
| 2823 static MaybeObject* Runtime_StringIndexOf(Arguments args) { | 2947 static MaybeObject* Runtime_StringIndexOf(RUNTIME_CALLING_CONVENTION) { |
| 2824 HandleScope scope; // create a new handle scope | 2948 RUNTIME_GET_ISOLATE; |
| 2949 HandleScope scope(isolate); // create a new handle scope |
| 2825 ASSERT(args.length() == 3); | 2950 ASSERT(args.length() == 3); |
| 2826 | 2951 |
| 2827 CONVERT_ARG_CHECKED(String, sub, 0); | 2952 CONVERT_ARG_CHECKED(String, sub, 0); |
| 2828 CONVERT_ARG_CHECKED(String, pat, 1); | 2953 CONVERT_ARG_CHECKED(String, pat, 1); |
| 2829 | 2954 |
| 2830 Object* index = args[2]; | 2955 Object* index = args[2]; |
| 2831 uint32_t start_index; | 2956 uint32_t start_index; |
| 2832 if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1); | 2957 if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1); |
| 2833 | 2958 |
| 2834 RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length())); | 2959 RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length())); |
| 2835 int position = Runtime::StringMatch(sub, pat, start_index); | 2960 int position = |
| 2961 Runtime::StringMatch(isolate, sub, pat, start_index); |
| 2836 return Smi::FromInt(position); | 2962 return Smi::FromInt(position); |
| 2837 } | 2963 } |
| 2838 | 2964 |
| 2839 | 2965 |
| 2840 template <typename schar, typename pchar> | 2966 template <typename schar, typename pchar> |
| 2841 static int StringMatchBackwards(Vector<const schar> subject, | 2967 static int StringMatchBackwards(Vector<const schar> subject, |
| 2842 Vector<const pchar> pattern, | 2968 Vector<const pchar> pattern, |
| 2843 int idx) { | 2969 int idx) { |
| 2844 int pattern_length = pattern.length(); | 2970 int pattern_length = pattern.length(); |
| 2845 ASSERT(pattern_length >= 1); | 2971 ASSERT(pattern_length >= 1); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2864 } | 2990 } |
| 2865 j++; | 2991 j++; |
| 2866 } | 2992 } |
| 2867 if (j == pattern_length) { | 2993 if (j == pattern_length) { |
| 2868 return i; | 2994 return i; |
| 2869 } | 2995 } |
| 2870 } | 2996 } |
| 2871 return -1; | 2997 return -1; |
| 2872 } | 2998 } |
| 2873 | 2999 |
| 2874 static MaybeObject* Runtime_StringLastIndexOf(Arguments args) { | 3000 static MaybeObject* Runtime_StringLastIndexOf(RUNTIME_CALLING_CONVENTION) { |
| 2875 HandleScope scope; // create a new handle scope | 3001 RUNTIME_GET_ISOLATE; |
| 3002 HandleScope scope(isolate); // create a new handle scope |
| 2876 ASSERT(args.length() == 3); | 3003 ASSERT(args.length() == 3); |
| 2877 | 3004 |
| 2878 CONVERT_ARG_CHECKED(String, sub, 0); | 3005 CONVERT_ARG_CHECKED(String, sub, 0); |
| 2879 CONVERT_ARG_CHECKED(String, pat, 1); | 3006 CONVERT_ARG_CHECKED(String, pat, 1); |
| 2880 | 3007 |
| 2881 Object* index = args[2]; | 3008 Object* index = args[2]; |
| 2882 uint32_t start_index; | 3009 uint32_t start_index; |
| 2883 if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1); | 3010 if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1); |
| 2884 | 3011 |
| 2885 uint32_t pat_length = pat->length(); | 3012 uint32_t pat_length = pat->length(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2921 position = StringMatchBackwards(sub->ToUC16Vector(), | 3048 position = StringMatchBackwards(sub->ToUC16Vector(), |
| 2922 pat_vector, | 3049 pat_vector, |
| 2923 start_index); | 3050 start_index); |
| 2924 } | 3051 } |
| 2925 } | 3052 } |
| 2926 | 3053 |
| 2927 return Smi::FromInt(position); | 3054 return Smi::FromInt(position); |
| 2928 } | 3055 } |
| 2929 | 3056 |
| 2930 | 3057 |
| 2931 static MaybeObject* Runtime_StringLocaleCompare(Arguments args) { | 3058 static MaybeObject* Runtime_StringLocaleCompare(RUNTIME_CALLING_CONVENTION) { |
| 3059 RUNTIME_GET_ISOLATE; |
| 2932 NoHandleAllocation ha; | 3060 NoHandleAllocation ha; |
| 2933 ASSERT(args.length() == 2); | 3061 ASSERT(args.length() == 2); |
| 2934 | 3062 |
| 2935 CONVERT_CHECKED(String, str1, args[0]); | 3063 CONVERT_CHECKED(String, str1, args[0]); |
| 2936 CONVERT_CHECKED(String, str2, args[1]); | 3064 CONVERT_CHECKED(String, str2, args[1]); |
| 2937 | 3065 |
| 2938 if (str1 == str2) return Smi::FromInt(0); // Equal. | 3066 if (str1 == str2) return Smi::FromInt(0); // Equal. |
| 2939 int str1_length = str1->length(); | 3067 int str1_length = str1->length(); |
| 2940 int str2_length = str2->length(); | 3068 int str2_length = str2->length(); |
| 2941 | 3069 |
| 2942 // Decide trivial cases without flattening. | 3070 // Decide trivial cases without flattening. |
| 2943 if (str1_length == 0) { | 3071 if (str1_length == 0) { |
| 2944 if (str2_length == 0) return Smi::FromInt(0); // Equal. | 3072 if (str2_length == 0) return Smi::FromInt(0); // Equal. |
| 2945 return Smi::FromInt(-str2_length); | 3073 return Smi::FromInt(-str2_length); |
| 2946 } else { | 3074 } else { |
| 2947 if (str2_length == 0) return Smi::FromInt(str1_length); | 3075 if (str2_length == 0) return Smi::FromInt(str1_length); |
| 2948 } | 3076 } |
| 2949 | 3077 |
| 2950 int end = str1_length < str2_length ? str1_length : str2_length; | 3078 int end = str1_length < str2_length ? str1_length : str2_length; |
| 2951 | 3079 |
| 2952 // No need to flatten if we are going to find the answer on the first | 3080 // No need to flatten if we are going to find the answer on the first |
| 2953 // character. At this point we know there is at least one character | 3081 // character. At this point we know there is at least one character |
| 2954 // in each string, due to the trivial case handling above. | 3082 // in each string, due to the trivial case handling above. |
| 2955 int d = str1->Get(0) - str2->Get(0); | 3083 int d = str1->Get(0) - str2->Get(0); |
| 2956 if (d != 0) return Smi::FromInt(d); | 3084 if (d != 0) return Smi::FromInt(d); |
| 2957 | 3085 |
| 2958 str1->TryFlatten(); | 3086 str1->TryFlatten(); |
| 2959 str2->TryFlatten(); | 3087 str2->TryFlatten(); |
| 2960 | 3088 |
| 2961 static StringInputBuffer buf1; | 3089 StringInputBuffer& buf1 = |
| 2962 static StringInputBuffer buf2; | 3090 *isolate->runtime_state()->string_locale_compare_buf1(); |
| 3091 StringInputBuffer& buf2 = |
| 3092 *isolate->runtime_state()->string_locale_compare_buf2(); |
| 2963 | 3093 |
| 2964 buf1.Reset(str1); | 3094 buf1.Reset(str1); |
| 2965 buf2.Reset(str2); | 3095 buf2.Reset(str2); |
| 2966 | 3096 |
| 2967 for (int i = 0; i < end; i++) { | 3097 for (int i = 0; i < end; i++) { |
| 2968 uint16_t char1 = buf1.GetNext(); | 3098 uint16_t char1 = buf1.GetNext(); |
| 2969 uint16_t char2 = buf2.GetNext(); | 3099 uint16_t char2 = buf2.GetNext(); |
| 2970 if (char1 != char2) return Smi::FromInt(char1 - char2); | 3100 if (char1 != char2) return Smi::FromInt(char1 - char2); |
| 2971 } | 3101 } |
| 2972 | 3102 |
| 2973 return Smi::FromInt(str1_length - str2_length); | 3103 return Smi::FromInt(str1_length - str2_length); |
| 2974 } | 3104 } |
| 2975 | 3105 |
| 2976 | 3106 |
| 2977 static MaybeObject* Runtime_SubString(Arguments args) { | 3107 static MaybeObject* Runtime_SubString(RUNTIME_CALLING_CONVENTION) { |
| 3108 RUNTIME_GET_ISOLATE; |
| 2978 NoHandleAllocation ha; | 3109 NoHandleAllocation ha; |
| 2979 ASSERT(args.length() == 3); | 3110 ASSERT(args.length() == 3); |
| 2980 | 3111 |
| 2981 CONVERT_CHECKED(String, value, args[0]); | 3112 CONVERT_CHECKED(String, value, args[0]); |
| 2982 Object* from = args[1]; | 3113 Object* from = args[1]; |
| 2983 Object* to = args[2]; | 3114 Object* to = args[2]; |
| 2984 int start, end; | 3115 int start, end; |
| 2985 // We have a fast integer-only case here to avoid a conversion to double in | 3116 // We have a fast integer-only case here to avoid a conversion to double in |
| 2986 // the common case where from and to are Smis. | 3117 // the common case where from and to are Smis. |
| 2987 if (from->IsSmi() && to->IsSmi()) { | 3118 if (from->IsSmi() && to->IsSmi()) { |
| 2988 start = Smi::cast(from)->value(); | 3119 start = Smi::cast(from)->value(); |
| 2989 end = Smi::cast(to)->value(); | 3120 end = Smi::cast(to)->value(); |
| 2990 } else { | 3121 } else { |
| 2991 CONVERT_DOUBLE_CHECKED(from_number, from); | 3122 CONVERT_DOUBLE_CHECKED(from_number, from); |
| 2992 CONVERT_DOUBLE_CHECKED(to_number, to); | 3123 CONVERT_DOUBLE_CHECKED(to_number, to); |
| 2993 start = FastD2I(from_number); | 3124 start = FastD2I(from_number); |
| 2994 end = FastD2I(to_number); | 3125 end = FastD2I(to_number); |
| 2995 } | 3126 } |
| 2996 RUNTIME_ASSERT(end >= start); | 3127 RUNTIME_ASSERT(end >= start); |
| 2997 RUNTIME_ASSERT(start >= 0); | 3128 RUNTIME_ASSERT(start >= 0); |
| 2998 RUNTIME_ASSERT(end <= value->length()); | 3129 RUNTIME_ASSERT(end <= value->length()); |
| 2999 Counters::sub_string_runtime.Increment(); | 3130 isolate->counters()->sub_string_runtime()->Increment(); |
| 3000 return value->SubString(start, end); | 3131 return value->SubString(start, end); |
| 3001 } | 3132 } |
| 3002 | 3133 |
| 3003 | 3134 |
| 3004 static MaybeObject* Runtime_StringMatch(Arguments args) { | 3135 static MaybeObject* Runtime_StringMatch(RUNTIME_CALLING_CONVENTION) { |
| 3136 RUNTIME_GET_ISOLATE; |
| 3005 ASSERT_EQ(3, args.length()); | 3137 ASSERT_EQ(3, args.length()); |
| 3006 | 3138 |
| 3007 CONVERT_ARG_CHECKED(String, subject, 0); | 3139 CONVERT_ARG_CHECKED(String, subject, 0); |
| 3008 CONVERT_ARG_CHECKED(JSRegExp, regexp, 1); | 3140 CONVERT_ARG_CHECKED(JSRegExp, regexp, 1); |
| 3009 CONVERT_ARG_CHECKED(JSArray, regexp_info, 2); | 3141 CONVERT_ARG_CHECKED(JSArray, regexp_info, 2); |
| 3010 HandleScope handles; | 3142 HandleScope handles; |
| 3011 | 3143 |
| 3012 Handle<Object> match = RegExpImpl::Exec(regexp, subject, 0, regexp_info); | 3144 Handle<Object> match = RegExpImpl::Exec(regexp, subject, 0, regexp_info); |
| 3013 | 3145 |
| 3014 if (match.is_null()) { | 3146 if (match.is_null()) { |
| 3015 return Failure::Exception(); | 3147 return Failure::Exception(); |
| 3016 } | 3148 } |
| 3017 if (match->IsNull()) { | 3149 if (match->IsNull()) { |
| 3018 return Heap::null_value(); | 3150 return isolate->heap()->null_value(); |
| 3019 } | 3151 } |
| 3020 int length = subject->length(); | 3152 int length = subject->length(); |
| 3021 | 3153 |
| 3022 CompilationZoneScope zone_space(DELETE_ON_EXIT); | 3154 CompilationZoneScope zone_space(DELETE_ON_EXIT); |
| 3023 ZoneList<int> offsets(8); | 3155 ZoneList<int> offsets(8); |
| 3024 do { | 3156 do { |
| 3025 int start; | 3157 int start; |
| 3026 int end; | 3158 int end; |
| 3027 { | 3159 { |
| 3028 AssertNoAllocation no_alloc; | 3160 AssertNoAllocation no_alloc; |
| 3029 FixedArray* elements = FixedArray::cast(regexp_info->elements()); | 3161 FixedArray* elements = FixedArray::cast(regexp_info->elements()); |
| 3030 start = Smi::cast(elements->get(RegExpImpl::kFirstCapture))->value(); | 3162 start = Smi::cast(elements->get(RegExpImpl::kFirstCapture))->value(); |
| 3031 end = Smi::cast(elements->get(RegExpImpl::kFirstCapture + 1))->value(); | 3163 end = Smi::cast(elements->get(RegExpImpl::kFirstCapture + 1))->value(); |
| 3032 } | 3164 } |
| 3033 offsets.Add(start); | 3165 offsets.Add(start); |
| 3034 offsets.Add(end); | 3166 offsets.Add(end); |
| 3035 int index = start < end ? end : end + 1; | 3167 int index = start < end ? end : end + 1; |
| 3036 if (index > length) break; | 3168 if (index > length) break; |
| 3037 match = RegExpImpl::Exec(regexp, subject, index, regexp_info); | 3169 match = RegExpImpl::Exec(regexp, subject, index, regexp_info); |
| 3038 if (match.is_null()) { | 3170 if (match.is_null()) { |
| 3039 return Failure::Exception(); | 3171 return Failure::Exception(); |
| 3040 } | 3172 } |
| 3041 } while (!match->IsNull()); | 3173 } while (!match->IsNull()); |
| 3042 int matches = offsets.length() / 2; | 3174 int matches = offsets.length() / 2; |
| 3043 Handle<FixedArray> elements = Factory::NewFixedArray(matches); | 3175 Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches); |
| 3044 for (int i = 0; i < matches ; i++) { | 3176 for (int i = 0; i < matches ; i++) { |
| 3045 int from = offsets.at(i * 2); | 3177 int from = offsets.at(i * 2); |
| 3046 int to = offsets.at(i * 2 + 1); | 3178 int to = offsets.at(i * 2 + 1); |
| 3047 Handle<String> match = Factory::NewSubString(subject, from, to); | 3179 Handle<String> match = isolate->factory()->NewSubString(subject, from, to); |
| 3048 elements->set(i, *match); | 3180 elements->set(i, *match); |
| 3049 } | 3181 } |
| 3050 Handle<JSArray> result = Factory::NewJSArrayWithElements(elements); | 3182 Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements); |
| 3051 result->set_length(Smi::FromInt(matches)); | 3183 result->set_length(Smi::FromInt(matches)); |
| 3052 return *result; | 3184 return *result; |
| 3053 } | 3185 } |
| 3054 | 3186 |
| 3055 | 3187 |
| 3056 // Two smis before and after the match, for very long strings. | 3188 // Two smis before and after the match, for very long strings. |
| 3057 const int kMaxBuilderEntriesPerRegExpMatch = 5; | 3189 const int kMaxBuilderEntriesPerRegExpMatch = 5; |
| 3058 | 3190 |
| 3059 | 3191 |
| 3060 static void SetLastMatchInfoNoCaptures(Handle<String> subject, | 3192 static void SetLastMatchInfoNoCaptures(Handle<String> subject, |
| 3061 Handle<JSArray> last_match_info, | 3193 Handle<JSArray> last_match_info, |
| 3062 int match_start, | 3194 int match_start, |
| 3063 int match_end) { | 3195 int match_end) { |
| 3064 // Fill last_match_info with a single capture. | 3196 // Fill last_match_info with a single capture. |
| 3065 last_match_info->EnsureSize(2 + RegExpImpl::kLastMatchOverhead); | 3197 last_match_info->EnsureSize(2 + RegExpImpl::kLastMatchOverhead); |
| 3066 AssertNoAllocation no_gc; | 3198 AssertNoAllocation no_gc; |
| 3067 FixedArray* elements = FixedArray::cast(last_match_info->elements()); | 3199 FixedArray* elements = FixedArray::cast(last_match_info->elements()); |
| 3068 RegExpImpl::SetLastCaptureCount(elements, 2); | 3200 RegExpImpl::SetLastCaptureCount(elements, 2); |
| 3069 RegExpImpl::SetLastInput(elements, *subject); | 3201 RegExpImpl::SetLastInput(elements, *subject); |
| 3070 RegExpImpl::SetLastSubject(elements, *subject); | 3202 RegExpImpl::SetLastSubject(elements, *subject); |
| 3071 RegExpImpl::SetCapture(elements, 0, match_start); | 3203 RegExpImpl::SetCapture(elements, 0, match_start); |
| 3072 RegExpImpl::SetCapture(elements, 1, match_end); | 3204 RegExpImpl::SetCapture(elements, 1, match_end); |
| 3073 } | 3205 } |
| 3074 | 3206 |
| 3075 | 3207 |
| 3076 template <typename SubjectChar, typename PatternChar> | 3208 template <typename SubjectChar, typename PatternChar> |
| 3077 static bool SearchStringMultiple(Vector<const SubjectChar> subject, | 3209 static bool SearchStringMultiple(Isolate* isolate, |
| 3210 Vector<const SubjectChar> subject, |
| 3078 Vector<const PatternChar> pattern, | 3211 Vector<const PatternChar> pattern, |
| 3079 String* pattern_string, | 3212 String* pattern_string, |
| 3080 FixedArrayBuilder* builder, | 3213 FixedArrayBuilder* builder, |
| 3081 int* match_pos) { | 3214 int* match_pos) { |
| 3082 int pos = *match_pos; | 3215 int pos = *match_pos; |
| 3083 int subject_length = subject.length(); | 3216 int subject_length = subject.length(); |
| 3084 int pattern_length = pattern.length(); | 3217 int pattern_length = pattern.length(); |
| 3085 int max_search_start = subject_length - pattern_length; | 3218 int max_search_start = subject_length - pattern_length; |
| 3086 StringSearch<PatternChar, SubjectChar> search(pattern); | 3219 StringSearch<PatternChar, SubjectChar> search(isolate, pattern); |
| 3087 while (pos <= max_search_start) { | 3220 while (pos <= max_search_start) { |
| 3088 if (!builder->HasCapacity(kMaxBuilderEntriesPerRegExpMatch)) { | 3221 if (!builder->HasCapacity(kMaxBuilderEntriesPerRegExpMatch)) { |
| 3089 *match_pos = pos; | 3222 *match_pos = pos; |
| 3090 return false; | 3223 return false; |
| 3091 } | 3224 } |
| 3092 // Position of end of previous match. | 3225 // Position of end of previous match. |
| 3093 int match_end = pos + pattern_length; | 3226 int match_end = pos + pattern_length; |
| 3094 int new_pos = search.Search(subject, match_end); | 3227 int new_pos = search.Search(subject, match_end); |
| 3095 if (new_pos >= 0) { | 3228 if (new_pos >= 0) { |
| 3096 // A match. | 3229 // A match. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3109 if (pos < max_search_start) { | 3242 if (pos < max_search_start) { |
| 3110 ReplacementStringBuilder::AddSubjectSlice(builder, | 3243 ReplacementStringBuilder::AddSubjectSlice(builder, |
| 3111 pos + pattern_length, | 3244 pos + pattern_length, |
| 3112 subject_length); | 3245 subject_length); |
| 3113 } | 3246 } |
| 3114 *match_pos = pos; | 3247 *match_pos = pos; |
| 3115 return true; | 3248 return true; |
| 3116 } | 3249 } |
| 3117 | 3250 |
| 3118 | 3251 |
| 3119 static bool SearchStringMultiple(Handle<String> subject, | 3252 static bool SearchStringMultiple(Isolate* isolate, |
| 3253 Handle<String> subject, |
| 3120 Handle<String> pattern, | 3254 Handle<String> pattern, |
| 3121 Handle<JSArray> last_match_info, | 3255 Handle<JSArray> last_match_info, |
| 3122 FixedArrayBuilder* builder) { | 3256 FixedArrayBuilder* builder) { |
| 3123 ASSERT(subject->IsFlat()); | 3257 ASSERT(subject->IsFlat()); |
| 3124 ASSERT(pattern->IsFlat()); | 3258 ASSERT(pattern->IsFlat()); |
| 3125 | 3259 |
| 3126 // Treating as if a previous match was before first character. | 3260 // Treating as if a previous match was before first character. |
| 3127 int match_pos = -pattern->length(); | 3261 int match_pos = -pattern->length(); |
| 3128 | 3262 |
| 3129 for (;;) { // Break when search complete. | 3263 for (;;) { // Break when search complete. |
| 3130 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); | 3264 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); |
| 3131 AssertNoAllocation no_gc; | 3265 AssertNoAllocation no_gc; |
| 3132 if (subject->IsAsciiRepresentation()) { | 3266 if (subject->IsAsciiRepresentation()) { |
| 3133 Vector<const char> subject_vector = subject->ToAsciiVector(); | 3267 Vector<const char> subject_vector = subject->ToAsciiVector(); |
| 3134 if (pattern->IsAsciiRepresentation()) { | 3268 if (pattern->IsAsciiRepresentation()) { |
| 3135 if (SearchStringMultiple(subject_vector, | 3269 if (SearchStringMultiple(isolate, |
| 3270 subject_vector, |
| 3136 pattern->ToAsciiVector(), | 3271 pattern->ToAsciiVector(), |
| 3137 *pattern, | 3272 *pattern, |
| 3138 builder, | 3273 builder, |
| 3139 &match_pos)) break; | 3274 &match_pos)) break; |
| 3140 } else { | 3275 } else { |
| 3141 if (SearchStringMultiple(subject_vector, | 3276 if (SearchStringMultiple(isolate, |
| 3277 subject_vector, |
| 3142 pattern->ToUC16Vector(), | 3278 pattern->ToUC16Vector(), |
| 3143 *pattern, | 3279 *pattern, |
| 3144 builder, | 3280 builder, |
| 3145 &match_pos)) break; | 3281 &match_pos)) break; |
| 3146 } | 3282 } |
| 3147 } else { | 3283 } else { |
| 3148 Vector<const uc16> subject_vector = subject->ToUC16Vector(); | 3284 Vector<const uc16> subject_vector = subject->ToUC16Vector(); |
| 3149 if (pattern->IsAsciiRepresentation()) { | 3285 if (pattern->IsAsciiRepresentation()) { |
| 3150 if (SearchStringMultiple(subject_vector, | 3286 if (SearchStringMultiple(isolate, |
| 3287 subject_vector, |
| 3151 pattern->ToAsciiVector(), | 3288 pattern->ToAsciiVector(), |
| 3152 *pattern, | 3289 *pattern, |
| 3153 builder, | 3290 builder, |
| 3154 &match_pos)) break; | 3291 &match_pos)) break; |
| 3155 } else { | 3292 } else { |
| 3156 if (SearchStringMultiple(subject_vector, | 3293 if (SearchStringMultiple(isolate, |
| 3294 subject_vector, |
| 3157 pattern->ToUC16Vector(), | 3295 pattern->ToUC16Vector(), |
| 3158 *pattern, | 3296 *pattern, |
| 3159 builder, | 3297 builder, |
| 3160 &match_pos)) break; | 3298 &match_pos)) break; |
| 3161 } | 3299 } |
| 3162 } | 3300 } |
| 3163 } | 3301 } |
| 3164 | 3302 |
| 3165 if (match_pos >= 0) { | 3303 if (match_pos >= 0) { |
| 3166 SetLastMatchInfoNoCaptures(subject, | 3304 SetLastMatchInfoNoCaptures(subject, |
| 3167 last_match_info, | 3305 last_match_info, |
| 3168 match_pos, | 3306 match_pos, |
| 3169 match_pos + pattern->length()); | 3307 match_pos + pattern->length()); |
| 3170 return true; | 3308 return true; |
| 3171 } | 3309 } |
| 3172 return false; // No matches at all. | 3310 return false; // No matches at all. |
| 3173 } | 3311 } |
| 3174 | 3312 |
| 3175 | 3313 |
| 3176 static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple( | 3314 static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple( |
| 3315 Isolate* isolate, |
| 3177 Handle<String> subject, | 3316 Handle<String> subject, |
| 3178 Handle<JSRegExp> regexp, | 3317 Handle<JSRegExp> regexp, |
| 3179 Handle<JSArray> last_match_array, | 3318 Handle<JSArray> last_match_array, |
| 3180 FixedArrayBuilder* builder) { | 3319 FixedArrayBuilder* builder) { |
| 3181 ASSERT(subject->IsFlat()); | 3320 ASSERT(subject->IsFlat()); |
| 3182 int match_start = -1; | 3321 int match_start = -1; |
| 3183 int match_end = 0; | 3322 int match_end = 0; |
| 3184 int pos = 0; | 3323 int pos = 0; |
| 3185 int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject); | 3324 int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject); |
| 3186 if (required_registers < 0) return RegExpImpl::RE_EXCEPTION; | 3325 if (required_registers < 0) return RegExpImpl::RE_EXCEPTION; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3197 register_vector); | 3336 register_vector); |
| 3198 if (result == RegExpImpl::RE_SUCCESS) { | 3337 if (result == RegExpImpl::RE_SUCCESS) { |
| 3199 match_start = register_vector[0]; | 3338 match_start = register_vector[0]; |
| 3200 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); | 3339 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); |
| 3201 if (match_end < match_start) { | 3340 if (match_end < match_start) { |
| 3202 ReplacementStringBuilder::AddSubjectSlice(builder, | 3341 ReplacementStringBuilder::AddSubjectSlice(builder, |
| 3203 match_end, | 3342 match_end, |
| 3204 match_start); | 3343 match_start); |
| 3205 } | 3344 } |
| 3206 match_end = register_vector[1]; | 3345 match_end = register_vector[1]; |
| 3207 HandleScope loop_scope; | 3346 HandleScope loop_scope(isolate); |
| 3208 builder->Add(*Factory::NewSubString(subject, match_start, match_end)); | 3347 builder->Add(*isolate->factory()->NewSubString(subject, |
| 3348 match_start, |
| 3349 match_end)); |
| 3209 if (match_start != match_end) { | 3350 if (match_start != match_end) { |
| 3210 pos = match_end; | 3351 pos = match_end; |
| 3211 } else { | 3352 } else { |
| 3212 pos = match_end + 1; | 3353 pos = match_end + 1; |
| 3213 if (pos > subject_length) break; | 3354 if (pos > subject_length) break; |
| 3214 } | 3355 } |
| 3215 } else if (result == RegExpImpl::RE_FAILURE) { | 3356 } else if (result == RegExpImpl::RE_FAILURE) { |
| 3216 break; | 3357 break; |
| 3217 } else { | 3358 } else { |
| 3218 ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION); | 3359 ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3231 match_start, | 3372 match_start, |
| 3232 match_end); | 3373 match_end); |
| 3233 return RegExpImpl::RE_SUCCESS; | 3374 return RegExpImpl::RE_SUCCESS; |
| 3234 } else { | 3375 } else { |
| 3235 return RegExpImpl::RE_FAILURE; // No matches at all. | 3376 return RegExpImpl::RE_FAILURE; // No matches at all. |
| 3236 } | 3377 } |
| 3237 } | 3378 } |
| 3238 | 3379 |
| 3239 | 3380 |
| 3240 static RegExpImpl::IrregexpResult SearchRegExpMultiple( | 3381 static RegExpImpl::IrregexpResult SearchRegExpMultiple( |
| 3382 Isolate* isolate, |
| 3241 Handle<String> subject, | 3383 Handle<String> subject, |
| 3242 Handle<JSRegExp> regexp, | 3384 Handle<JSRegExp> regexp, |
| 3243 Handle<JSArray> last_match_array, | 3385 Handle<JSArray> last_match_array, |
| 3244 FixedArrayBuilder* builder) { | 3386 FixedArrayBuilder* builder) { |
| 3245 | 3387 |
| 3246 ASSERT(subject->IsFlat()); | 3388 ASSERT(subject->IsFlat()); |
| 3247 int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject); | 3389 int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject); |
| 3248 if (required_registers < 0) return RegExpImpl::RE_EXCEPTION; | 3390 if (required_registers < 0) return RegExpImpl::RE_EXCEPTION; |
| 3249 | 3391 |
| 3250 OffsetsVector registers(required_registers); | 3392 OffsetsVector registers(required_registers); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 3274 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); | 3416 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); |
| 3275 if (match_end < match_start) { | 3417 if (match_end < match_start) { |
| 3276 ReplacementStringBuilder::AddSubjectSlice(builder, | 3418 ReplacementStringBuilder::AddSubjectSlice(builder, |
| 3277 match_end, | 3419 match_end, |
| 3278 match_start); | 3420 match_start); |
| 3279 } | 3421 } |
| 3280 match_end = register_vector[1]; | 3422 match_end = register_vector[1]; |
| 3281 | 3423 |
| 3282 { | 3424 { |
| 3283 // Avoid accumulating new handles inside loop. | 3425 // Avoid accumulating new handles inside loop. |
| 3284 HandleScope temp_scope; | 3426 HandleScope temp_scope(isolate); |
| 3285 // Arguments array to replace function is match, captures, index and | 3427 // Arguments array to replace function is match, captures, index and |
| 3286 // subject, i.e., 3 + capture count in total. | 3428 // subject, i.e., 3 + capture count in total. |
| 3287 Handle<FixedArray> elements = Factory::NewFixedArray(3 + capture_count); | 3429 Handle<FixedArray> elements = |
| 3288 Handle<String> match = Factory::NewSubString(subject, | 3430 isolate->factory()->NewFixedArray(3 + capture_count); |
| 3289 match_start, | 3431 Handle<String> match = isolate->factory()->NewSubString(subject, |
| 3290 match_end); | 3432 match_start, |
| 3433 match_end); |
| 3291 elements->set(0, *match); | 3434 elements->set(0, *match); |
| 3292 for (int i = 1; i <= capture_count; i++) { | 3435 for (int i = 1; i <= capture_count; i++) { |
| 3293 int start = register_vector[i * 2]; | 3436 int start = register_vector[i * 2]; |
| 3294 if (start >= 0) { | 3437 if (start >= 0) { |
| 3295 int end = register_vector[i * 2 + 1]; | 3438 int end = register_vector[i * 2 + 1]; |
| 3296 ASSERT(start <= end); | 3439 ASSERT(start <= end); |
| 3297 Handle<String> substring = Factory::NewSubString(subject, | 3440 Handle<String> substring = isolate->factory()->NewSubString(subject, |
| 3298 start, | 3441 start, |
| 3299 end); | 3442 end); |
| 3300 elements->set(i, *substring); | 3443 elements->set(i, *substring); |
| 3301 } else { | 3444 } else { |
| 3302 ASSERT(register_vector[i * 2 + 1] < 0); | 3445 ASSERT(register_vector[i * 2 + 1] < 0); |
| 3303 elements->set(i, Heap::undefined_value()); | 3446 elements->set(i, isolate->heap()->undefined_value()); |
| 3304 } | 3447 } |
| 3305 } | 3448 } |
| 3306 elements->set(capture_count + 1, Smi::FromInt(match_start)); | 3449 elements->set(capture_count + 1, Smi::FromInt(match_start)); |
| 3307 elements->set(capture_count + 2, *subject); | 3450 elements->set(capture_count + 2, *subject); |
| 3308 builder->Add(*Factory::NewJSArrayWithElements(elements)); | 3451 builder->Add(*isolate->factory()->NewJSArrayWithElements(elements)); |
| 3309 } | 3452 } |
| 3310 // Swap register vectors, so the last successful match is in | 3453 // Swap register vectors, so the last successful match is in |
| 3311 // prev_register_vector. | 3454 // prev_register_vector. |
| 3312 Vector<int32_t> tmp = prev_register_vector; | 3455 Vector<int32_t> tmp = prev_register_vector; |
| 3313 prev_register_vector = register_vector; | 3456 prev_register_vector = register_vector; |
| 3314 register_vector = tmp; | 3457 register_vector = tmp; |
| 3315 | 3458 |
| 3316 if (match_end > match_start) { | 3459 if (match_end > match_start) { |
| 3317 pos = match_end; | 3460 pos = match_end; |
| 3318 } else { | 3461 } else { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 3349 RegExpImpl::SetCapture(elements, i, prev_register_vector[i]); | 3492 RegExpImpl::SetCapture(elements, i, prev_register_vector[i]); |
| 3350 } | 3493 } |
| 3351 return RegExpImpl::RE_SUCCESS; | 3494 return RegExpImpl::RE_SUCCESS; |
| 3352 } | 3495 } |
| 3353 } | 3496 } |
| 3354 // No matches at all, return failure or exception result directly. | 3497 // No matches at all, return failure or exception result directly. |
| 3355 return result; | 3498 return result; |
| 3356 } | 3499 } |
| 3357 | 3500 |
| 3358 | 3501 |
| 3359 static MaybeObject* Runtime_RegExpExecMultiple(Arguments args) { | 3502 static MaybeObject* Runtime_RegExpExecMultiple(RUNTIME_CALLING_CONVENTION) { |
| 3503 RUNTIME_GET_ISOLATE; |
| 3360 ASSERT(args.length() == 4); | 3504 ASSERT(args.length() == 4); |
| 3361 HandleScope handles; | 3505 HandleScope handles(isolate); |
| 3362 | 3506 |
| 3363 CONVERT_ARG_CHECKED(String, subject, 1); | 3507 CONVERT_ARG_CHECKED(String, subject, 1); |
| 3364 if (!subject->IsFlat()) { FlattenString(subject); } | 3508 if (!subject->IsFlat()) { FlattenString(subject); } |
| 3365 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); | 3509 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); |
| 3366 CONVERT_ARG_CHECKED(JSArray, last_match_info, 2); | 3510 CONVERT_ARG_CHECKED(JSArray, last_match_info, 2); |
| 3367 CONVERT_ARG_CHECKED(JSArray, result_array, 3); | 3511 CONVERT_ARG_CHECKED(JSArray, result_array, 3); |
| 3368 | 3512 |
| 3369 ASSERT(last_match_info->HasFastElements()); | 3513 ASSERT(last_match_info->HasFastElements()); |
| 3370 ASSERT(regexp->GetFlags().is_global()); | 3514 ASSERT(regexp->GetFlags().is_global()); |
| 3371 Handle<FixedArray> result_elements; | 3515 Handle<FixedArray> result_elements; |
| 3372 if (result_array->HasFastElements()) { | 3516 if (result_array->HasFastElements()) { |
| 3373 result_elements = | 3517 result_elements = |
| 3374 Handle<FixedArray>(FixedArray::cast(result_array->elements())); | 3518 Handle<FixedArray>(FixedArray::cast(result_array->elements())); |
| 3375 } else { | 3519 } else { |
| 3376 result_elements = Factory::NewFixedArrayWithHoles(16); | 3520 result_elements = isolate->factory()->NewFixedArrayWithHoles(16); |
| 3377 } | 3521 } |
| 3378 FixedArrayBuilder builder(result_elements); | 3522 FixedArrayBuilder builder(result_elements); |
| 3379 | 3523 |
| 3380 if (regexp->TypeTag() == JSRegExp::ATOM) { | 3524 if (regexp->TypeTag() == JSRegExp::ATOM) { |
| 3381 Handle<String> pattern( | 3525 Handle<String> pattern( |
| 3382 String::cast(regexp->DataAt(JSRegExp::kAtomPatternIndex))); | 3526 String::cast(regexp->DataAt(JSRegExp::kAtomPatternIndex))); |
| 3383 ASSERT(pattern->IsFlat()); | 3527 ASSERT(pattern->IsFlat()); |
| 3384 if (SearchStringMultiple(subject, pattern, last_match_info, &builder)) { | 3528 if (SearchStringMultiple(isolate, subject, pattern, |
| 3529 last_match_info, &builder)) { |
| 3385 return *builder.ToJSArray(result_array); | 3530 return *builder.ToJSArray(result_array); |
| 3386 } | 3531 } |
| 3387 return Heap::null_value(); | 3532 return isolate->heap()->null_value(); |
| 3388 } | 3533 } |
| 3389 | 3534 |
| 3390 ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP); | 3535 ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP); |
| 3391 | 3536 |
| 3392 RegExpImpl::IrregexpResult result; | 3537 RegExpImpl::IrregexpResult result; |
| 3393 if (regexp->CaptureCount() == 0) { | 3538 if (regexp->CaptureCount() == 0) { |
| 3394 result = SearchRegExpNoCaptureMultiple(subject, | 3539 result = SearchRegExpNoCaptureMultiple(isolate, |
| 3540 subject, |
| 3395 regexp, | 3541 regexp, |
| 3396 last_match_info, | 3542 last_match_info, |
| 3397 &builder); | 3543 &builder); |
| 3398 } else { | 3544 } else { |
| 3399 result = SearchRegExpMultiple(subject, regexp, last_match_info, &builder); | 3545 result = SearchRegExpMultiple(isolate, |
| 3546 subject, |
| 3547 regexp, |
| 3548 last_match_info, |
| 3549 &builder); |
| 3400 } | 3550 } |
| 3401 if (result == RegExpImpl::RE_SUCCESS) return *builder.ToJSArray(result_array); | 3551 if (result == RegExpImpl::RE_SUCCESS) return *builder.ToJSArray(result_array); |
| 3402 if (result == RegExpImpl::RE_FAILURE) return Heap::null_value(); | 3552 if (result == RegExpImpl::RE_FAILURE) return isolate->heap()->null_value(); |
| 3403 ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION); | 3553 ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION); |
| 3404 return Failure::Exception(); | 3554 return Failure::Exception(); |
| 3405 } | 3555 } |
| 3406 | 3556 |
| 3407 | 3557 |
| 3408 static MaybeObject* Runtime_NumberToRadixString(Arguments args) { | 3558 static MaybeObject* Runtime_NumberToRadixString(RUNTIME_CALLING_CONVENTION) { |
| 3559 RUNTIME_GET_ISOLATE; |
| 3409 NoHandleAllocation ha; | 3560 NoHandleAllocation ha; |
| 3410 ASSERT(args.length() == 2); | 3561 ASSERT(args.length() == 2); |
| 3411 | 3562 |
| 3412 // Fast case where the result is a one character string. | 3563 // Fast case where the result is a one character string. |
| 3413 if (args[0]->IsSmi() && args[1]->IsSmi()) { | 3564 if (args[0]->IsSmi() && args[1]->IsSmi()) { |
| 3414 int value = Smi::cast(args[0])->value(); | 3565 int value = Smi::cast(args[0])->value(); |
| 3415 int radix = Smi::cast(args[1])->value(); | 3566 int radix = Smi::cast(args[1])->value(); |
| 3416 if (value >= 0 && value < radix) { | 3567 if (value >= 0 && value < radix) { |
| 3417 RUNTIME_ASSERT(radix <= 36); | 3568 RUNTIME_ASSERT(radix <= 36); |
| 3418 // Character array used for conversion. | 3569 // Character array used for conversion. |
| 3419 static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz"; | 3570 static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz"; |
| 3420 return Heap::LookupSingleCharacterStringFromCode(kCharTable[value]); | 3571 return isolate->heap()-> |
| 3572 LookupSingleCharacterStringFromCode(kCharTable[value]); |
| 3421 } | 3573 } |
| 3422 } | 3574 } |
| 3423 | 3575 |
| 3424 // Slow case. | 3576 // Slow case. |
| 3425 CONVERT_DOUBLE_CHECKED(value, args[0]); | 3577 CONVERT_DOUBLE_CHECKED(value, args[0]); |
| 3426 if (isnan(value)) { | 3578 if (isnan(value)) { |
| 3427 return Heap::AllocateStringFromAscii(CStrVector("NaN")); | 3579 return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN")); |
| 3428 } | 3580 } |
| 3429 if (isinf(value)) { | 3581 if (isinf(value)) { |
| 3430 if (value < 0) { | 3582 if (value < 0) { |
| 3431 return Heap::AllocateStringFromAscii(CStrVector("-Infinity")); | 3583 return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity")); |
| 3432 } | 3584 } |
| 3433 return Heap::AllocateStringFromAscii(CStrVector("Infinity")); | 3585 return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity")); |
| 3434 } | 3586 } |
| 3435 CONVERT_DOUBLE_CHECKED(radix_number, args[1]); | 3587 CONVERT_DOUBLE_CHECKED(radix_number, args[1]); |
| 3436 int radix = FastD2I(radix_number); | 3588 int radix = FastD2I(radix_number); |
| 3437 RUNTIME_ASSERT(2 <= radix && radix <= 36); | 3589 RUNTIME_ASSERT(2 <= radix && radix <= 36); |
| 3438 char* str = DoubleToRadixCString(value, radix); | 3590 char* str = DoubleToRadixCString(value, radix); |
| 3439 MaybeObject* result = Heap::AllocateStringFromAscii(CStrVector(str)); | 3591 MaybeObject* result = |
| 3592 isolate->heap()->AllocateStringFromAscii(CStrVector(str)); |
| 3440 DeleteArray(str); | 3593 DeleteArray(str); |
| 3441 return result; | 3594 return result; |
| 3442 } | 3595 } |
| 3443 | 3596 |
| 3444 | 3597 |
| 3445 static MaybeObject* Runtime_NumberToFixed(Arguments args) { | 3598 static MaybeObject* Runtime_NumberToFixed(RUNTIME_CALLING_CONVENTION) { |
| 3599 RUNTIME_GET_ISOLATE; |
| 3446 NoHandleAllocation ha; | 3600 NoHandleAllocation ha; |
| 3447 ASSERT(args.length() == 2); | 3601 ASSERT(args.length() == 2); |
| 3448 | 3602 |
| 3449 CONVERT_DOUBLE_CHECKED(value, args[0]); | 3603 CONVERT_DOUBLE_CHECKED(value, args[0]); |
| 3450 if (isnan(value)) { | 3604 if (isnan(value)) { |
| 3451 return Heap::AllocateStringFromAscii(CStrVector("NaN")); | 3605 return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN")); |
| 3452 } | 3606 } |
| 3453 if (isinf(value)) { | 3607 if (isinf(value)) { |
| 3454 if (value < 0) { | 3608 if (value < 0) { |
| 3455 return Heap::AllocateStringFromAscii(CStrVector("-Infinity")); | 3609 return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity")); |
| 3456 } | 3610 } |
| 3457 return Heap::AllocateStringFromAscii(CStrVector("Infinity")); | 3611 return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity")); |
| 3458 } | 3612 } |
| 3459 CONVERT_DOUBLE_CHECKED(f_number, args[1]); | 3613 CONVERT_DOUBLE_CHECKED(f_number, args[1]); |
| 3460 int f = FastD2I(f_number); | 3614 int f = FastD2I(f_number); |
| 3461 RUNTIME_ASSERT(f >= 0); | 3615 RUNTIME_ASSERT(f >= 0); |
| 3462 char* str = DoubleToFixedCString(value, f); | 3616 char* str = DoubleToFixedCString(value, f); |
| 3463 MaybeObject* result = Heap::AllocateStringFromAscii(CStrVector(str)); | 3617 MaybeObject* res = |
| 3618 isolate->heap()->AllocateStringFromAscii(CStrVector(str)); |
| 3464 DeleteArray(str); | 3619 DeleteArray(str); |
| 3465 return result; | 3620 return res; |
| 3466 } | 3621 } |
| 3467 | 3622 |
| 3468 | 3623 |
| 3469 static MaybeObject* Runtime_NumberToExponential(Arguments args) { | 3624 static MaybeObject* Runtime_NumberToExponential(RUNTIME_CALLING_CONVENTION) { |
| 3625 RUNTIME_GET_ISOLATE; |
| 3470 NoHandleAllocation ha; | 3626 NoHandleAllocation ha; |
| 3471 ASSERT(args.length() == 2); | 3627 ASSERT(args.length() == 2); |
| 3472 | 3628 |
| 3473 CONVERT_DOUBLE_CHECKED(value, args[0]); | 3629 CONVERT_DOUBLE_CHECKED(value, args[0]); |
| 3474 if (isnan(value)) { | 3630 if (isnan(value)) { |
| 3475 return Heap::AllocateStringFromAscii(CStrVector("NaN")); | 3631 return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN")); |
| 3476 } | 3632 } |
| 3477 if (isinf(value)) { | 3633 if (isinf(value)) { |
| 3478 if (value < 0) { | 3634 if (value < 0) { |
| 3479 return Heap::AllocateStringFromAscii(CStrVector("-Infinity")); | 3635 return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity")); |
| 3480 } | 3636 } |
| 3481 return Heap::AllocateStringFromAscii(CStrVector("Infinity")); | 3637 return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity")); |
| 3482 } | 3638 } |
| 3483 CONVERT_DOUBLE_CHECKED(f_number, args[1]); | 3639 CONVERT_DOUBLE_CHECKED(f_number, args[1]); |
| 3484 int f = FastD2I(f_number); | 3640 int f = FastD2I(f_number); |
| 3485 RUNTIME_ASSERT(f >= -1 && f <= 20); | 3641 RUNTIME_ASSERT(f >= -1 && f <= 20); |
| 3486 char* str = DoubleToExponentialCString(value, f); | 3642 char* str = DoubleToExponentialCString(value, f); |
| 3487 MaybeObject* result = Heap::AllocateStringFromAscii(CStrVector(str)); | 3643 MaybeObject* res = |
| 3644 isolate->heap()->AllocateStringFromAscii(CStrVector(str)); |
| 3488 DeleteArray(str); | 3645 DeleteArray(str); |
| 3489 return result; | 3646 return res; |
| 3490 } | 3647 } |
| 3491 | 3648 |
| 3492 | 3649 |
| 3493 static MaybeObject* Runtime_NumberToPrecision(Arguments args) { | 3650 static MaybeObject* Runtime_NumberToPrecision(RUNTIME_CALLING_CONVENTION) { |
| 3651 RUNTIME_GET_ISOLATE; |
| 3494 NoHandleAllocation ha; | 3652 NoHandleAllocation ha; |
| 3495 ASSERT(args.length() == 2); | 3653 ASSERT(args.length() == 2); |
| 3496 | 3654 |
| 3497 CONVERT_DOUBLE_CHECKED(value, args[0]); | 3655 CONVERT_DOUBLE_CHECKED(value, args[0]); |
| 3498 if (isnan(value)) { | 3656 if (isnan(value)) { |
| 3499 return Heap::AllocateStringFromAscii(CStrVector("NaN")); | 3657 return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN")); |
| 3500 } | 3658 } |
| 3501 if (isinf(value)) { | 3659 if (isinf(value)) { |
| 3502 if (value < 0) { | 3660 if (value < 0) { |
| 3503 return Heap::AllocateStringFromAscii(CStrVector("-Infinity")); | 3661 return isolate->heap()->AllocateStringFromAscii(CStrVector("-Infinity")); |
| 3504 } | 3662 } |
| 3505 return Heap::AllocateStringFromAscii(CStrVector("Infinity")); | 3663 return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity")); |
| 3506 } | 3664 } |
| 3507 CONVERT_DOUBLE_CHECKED(f_number, args[1]); | 3665 CONVERT_DOUBLE_CHECKED(f_number, args[1]); |
| 3508 int f = FastD2I(f_number); | 3666 int f = FastD2I(f_number); |
| 3509 RUNTIME_ASSERT(f >= 1 && f <= 21); | 3667 RUNTIME_ASSERT(f >= 1 && f <= 21); |
| 3510 char* str = DoubleToPrecisionCString(value, f); | 3668 char* str = DoubleToPrecisionCString(value, f); |
| 3511 MaybeObject* result = Heap::AllocateStringFromAscii(CStrVector(str)); | 3669 MaybeObject* res = |
| 3670 isolate->heap()->AllocateStringFromAscii(CStrVector(str)); |
| 3512 DeleteArray(str); | 3671 DeleteArray(str); |
| 3513 return result; | 3672 return res; |
| 3514 } | 3673 } |
| 3515 | 3674 |
| 3516 | 3675 |
| 3517 // Returns a single character string where first character equals | 3676 // Returns a single character string where first character equals |
| 3518 // string->Get(index). | 3677 // string->Get(index). |
| 3519 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) { | 3678 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) { |
| 3520 if (index < static_cast<uint32_t>(string->length())) { | 3679 if (index < static_cast<uint32_t>(string->length())) { |
| 3521 string->TryFlatten(); | 3680 string->TryFlatten(); |
| 3522 return LookupSingleCharacterStringFromCode( | 3681 return LookupSingleCharacterStringFromCode( |
| 3523 string->Get(index)); | 3682 string->Get(index)); |
| 3524 } | 3683 } |
| 3525 return Execution::CharAt(string, index); | 3684 return Execution::CharAt(string, index); |
| 3526 } | 3685 } |
| 3527 | 3686 |
| 3528 | 3687 |
| 3529 MaybeObject* Runtime::GetElementOrCharAt(Handle<Object> object, | 3688 MaybeObject* Runtime::GetElementOrCharAt(Isolate* isolate, |
| 3689 Handle<Object> object, |
| 3530 uint32_t index) { | 3690 uint32_t index) { |
| 3531 // Handle [] indexing on Strings | 3691 // Handle [] indexing on Strings |
| 3532 if (object->IsString()) { | 3692 if (object->IsString()) { |
| 3533 Handle<Object> result = GetCharAt(Handle<String>::cast(object), index); | 3693 Handle<Object> result = GetCharAt(Handle<String>::cast(object), index); |
| 3534 if (!result->IsUndefined()) return *result; | 3694 if (!result->IsUndefined()) return *result; |
| 3535 } | 3695 } |
| 3536 | 3696 |
| 3537 // Handle [] indexing on String objects | 3697 // Handle [] indexing on String objects |
| 3538 if (object->IsStringObjectWithCharacterAt(index)) { | 3698 if (object->IsStringObjectWithCharacterAt(index)) { |
| 3539 Handle<JSValue> js_value = Handle<JSValue>::cast(object); | 3699 Handle<JSValue> js_value = Handle<JSValue>::cast(object); |
| 3540 Handle<Object> result = | 3700 Handle<Object> result = |
| 3541 GetCharAt(Handle<String>(String::cast(js_value->value())), index); | 3701 GetCharAt(Handle<String>(String::cast(js_value->value())), index); |
| 3542 if (!result->IsUndefined()) return *result; | 3702 if (!result->IsUndefined()) return *result; |
| 3543 } | 3703 } |
| 3544 | 3704 |
| 3545 if (object->IsString() || object->IsNumber() || object->IsBoolean()) { | 3705 if (object->IsString() || object->IsNumber() || object->IsBoolean()) { |
| 3546 Handle<Object> prototype = GetPrototype(object); | 3706 Handle<Object> prototype = GetPrototype(object); |
| 3547 return prototype->GetElement(index); | 3707 return prototype->GetElement(index); |
| 3548 } | 3708 } |
| 3549 | 3709 |
| 3550 return GetElement(object, index); | 3710 return GetElement(object, index); |
| 3551 } | 3711 } |
| 3552 | 3712 |
| 3553 | 3713 |
| 3554 MaybeObject* Runtime::GetElement(Handle<Object> object, uint32_t index) { | 3714 MaybeObject* Runtime::GetElement(Handle<Object> object, uint32_t index) { |
| 3555 return object->GetElement(index); | 3715 return object->GetElement(index); |
| 3556 } | 3716 } |
| 3557 | 3717 |
| 3558 | 3718 |
| 3559 MaybeObject* Runtime::GetObjectProperty(Handle<Object> object, | 3719 MaybeObject* Runtime::GetObjectProperty(Isolate* isolate, |
| 3720 Handle<Object> object, |
| 3560 Handle<Object> key) { | 3721 Handle<Object> key) { |
| 3561 HandleScope scope; | 3722 HandleScope scope(isolate); |
| 3562 | 3723 |
| 3563 if (object->IsUndefined() || object->IsNull()) { | 3724 if (object->IsUndefined() || object->IsNull()) { |
| 3564 Handle<Object> args[2] = { key, object }; | 3725 Handle<Object> args[2] = { key, object }; |
| 3565 Handle<Object> error = | 3726 Handle<Object> error = |
| 3566 Factory::NewTypeError("non_object_property_load", | 3727 isolate->factory()->NewTypeError("non_object_property_load", |
| 3567 HandleVector(args, 2)); | 3728 HandleVector(args, 2)); |
| 3568 return Top::Throw(*error); | 3729 return isolate->Throw(*error); |
| 3569 } | 3730 } |
| 3570 | 3731 |
| 3571 // Check if the given key is an array index. | 3732 // Check if the given key is an array index. |
| 3572 uint32_t index; | 3733 uint32_t index; |
| 3573 if (key->ToArrayIndex(&index)) { | 3734 if (key->ToArrayIndex(&index)) { |
| 3574 return GetElementOrCharAt(object, index); | 3735 return GetElementOrCharAt(isolate, object, index); |
| 3575 } | 3736 } |
| 3576 | 3737 |
| 3577 // Convert the key to a string - possibly by calling back into JavaScript. | 3738 // Convert the key to a string - possibly by calling back into JavaScript. |
| 3578 Handle<String> name; | 3739 Handle<String> name; |
| 3579 if (key->IsString()) { | 3740 if (key->IsString()) { |
| 3580 name = Handle<String>::cast(key); | 3741 name = Handle<String>::cast(key); |
| 3581 } else { | 3742 } else { |
| 3582 bool has_pending_exception = false; | 3743 bool has_pending_exception = false; |
| 3583 Handle<Object> converted = | 3744 Handle<Object> converted = |
| 3584 Execution::ToString(key, &has_pending_exception); | 3745 Execution::ToString(key, &has_pending_exception); |
| 3585 if (has_pending_exception) return Failure::Exception(); | 3746 if (has_pending_exception) return Failure::Exception(); |
| 3586 name = Handle<String>::cast(converted); | 3747 name = Handle<String>::cast(converted); |
| 3587 } | 3748 } |
| 3588 | 3749 |
| 3589 // Check if the name is trivially convertible to an index and get | 3750 // Check if the name is trivially convertible to an index and get |
| 3590 // the element if so. | 3751 // the element if so. |
| 3591 if (name->AsArrayIndex(&index)) { | 3752 if (name->AsArrayIndex(&index)) { |
| 3592 return GetElementOrCharAt(object, index); | 3753 return GetElementOrCharAt(isolate, object, index); |
| 3593 } else { | 3754 } else { |
| 3594 PropertyAttributes attr; | 3755 PropertyAttributes attr; |
| 3595 return object->GetProperty(*name, &attr); | 3756 return object->GetProperty(*name, &attr); |
| 3596 } | 3757 } |
| 3597 } | 3758 } |
| 3598 | 3759 |
| 3599 | 3760 |
| 3600 static MaybeObject* Runtime_GetProperty(Arguments args) { | 3761 static MaybeObject* Runtime_GetProperty(RUNTIME_CALLING_CONVENTION) { |
| 3762 RUNTIME_GET_ISOLATE; |
| 3601 NoHandleAllocation ha; | 3763 NoHandleAllocation ha; |
| 3602 ASSERT(args.length() == 2); | 3764 ASSERT(args.length() == 2); |
| 3603 | 3765 |
| 3604 Handle<Object> object = args.at<Object>(0); | 3766 Handle<Object> object = args.at<Object>(0); |
| 3605 Handle<Object> key = args.at<Object>(1); | 3767 Handle<Object> key = args.at<Object>(1); |
| 3606 | 3768 |
| 3607 return Runtime::GetObjectProperty(object, key); | 3769 return Runtime::GetObjectProperty(isolate, object, key); |
| 3608 } | 3770 } |
| 3609 | 3771 |
| 3610 | 3772 |
| 3611 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric. | 3773 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric. |
| 3612 static MaybeObject* Runtime_KeyedGetProperty(Arguments args) { | 3774 static MaybeObject* Runtime_KeyedGetProperty(RUNTIME_CALLING_CONVENTION) { |
| 3775 RUNTIME_GET_ISOLATE; |
| 3613 NoHandleAllocation ha; | 3776 NoHandleAllocation ha; |
| 3614 ASSERT(args.length() == 2); | 3777 ASSERT(args.length() == 2); |
| 3615 | 3778 |
| 3616 // Fast cases for getting named properties of the receiver JSObject | 3779 // Fast cases for getting named properties of the receiver JSObject |
| 3617 // itself. | 3780 // itself. |
| 3618 // | 3781 // |
| 3619 // The global proxy objects has to be excluded since LocalLookup on | 3782 // The global proxy objects has to be excluded since LocalLookup on |
| 3620 // the global proxy object can return a valid result even though the | 3783 // the global proxy object can return a valid result even though the |
| 3621 // global proxy object never has properties. This is the case | 3784 // global proxy object never has properties. This is the case |
| 3622 // because the global proxy object forwards everything to its hidden | 3785 // because the global proxy object forwards everything to its hidden |
| 3623 // prototype including local lookups. | 3786 // prototype including local lookups. |
| 3624 // | 3787 // |
| 3625 // Additionally, we need to make sure that we do not cache results | 3788 // Additionally, we need to make sure that we do not cache results |
| 3626 // for objects that require access checks. | 3789 // for objects that require access checks. |
| 3627 if (args[0]->IsJSObject() && | 3790 if (args[0]->IsJSObject() && |
| 3628 !args[0]->IsJSGlobalProxy() && | 3791 !args[0]->IsJSGlobalProxy() && |
| 3629 !args[0]->IsAccessCheckNeeded() && | 3792 !args[0]->IsAccessCheckNeeded() && |
| 3630 args[1]->IsString()) { | 3793 args[1]->IsString()) { |
| 3631 JSObject* receiver = JSObject::cast(args[0]); | 3794 JSObject* receiver = JSObject::cast(args[0]); |
| 3632 String* key = String::cast(args[1]); | 3795 String* key = String::cast(args[1]); |
| 3633 if (receiver->HasFastProperties()) { | 3796 if (receiver->HasFastProperties()) { |
| 3634 // Attempt to use lookup cache. | 3797 // Attempt to use lookup cache. |
| 3635 Map* receiver_map = receiver->map(); | 3798 Map* receiver_map = receiver->map(); |
| 3636 int offset = KeyedLookupCache::Lookup(receiver_map, key); | 3799 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache(); |
| 3800 int offset = keyed_lookup_cache->Lookup(receiver_map, key); |
| 3637 if (offset != -1) { | 3801 if (offset != -1) { |
| 3638 Object* value = receiver->FastPropertyAt(offset); | 3802 Object* value = receiver->FastPropertyAt(offset); |
| 3639 return value->IsTheHole() ? Heap::undefined_value() : value; | 3803 return value->IsTheHole() ? isolate->heap()->undefined_value() : value; |
| 3640 } | 3804 } |
| 3641 // Lookup cache miss. Perform lookup and update the cache if appropriate. | 3805 // Lookup cache miss. Perform lookup and update the cache if appropriate. |
| 3642 LookupResult result; | 3806 LookupResult result; |
| 3643 receiver->LocalLookup(key, &result); | 3807 receiver->LocalLookup(key, &result); |
| 3644 if (result.IsProperty() && result.type() == FIELD) { | 3808 if (result.IsProperty() && result.type() == FIELD) { |
| 3645 int offset = result.GetFieldIndex(); | 3809 int offset = result.GetFieldIndex(); |
| 3646 KeyedLookupCache::Update(receiver_map, key, offset); | 3810 keyed_lookup_cache->Update(receiver_map, key, offset); |
| 3647 return receiver->FastPropertyAt(offset); | 3811 return receiver->FastPropertyAt(offset); |
| 3648 } | 3812 } |
| 3649 } else { | 3813 } else { |
| 3650 // Attempt dictionary lookup. | 3814 // Attempt dictionary lookup. |
| 3651 StringDictionary* dictionary = receiver->property_dictionary(); | 3815 StringDictionary* dictionary = receiver->property_dictionary(); |
| 3652 int entry = dictionary->FindEntry(key); | 3816 int entry = dictionary->FindEntry(key); |
| 3653 if ((entry != StringDictionary::kNotFound) && | 3817 if ((entry != StringDictionary::kNotFound) && |
| 3654 (dictionary->DetailsAt(entry).type() == NORMAL)) { | 3818 (dictionary->DetailsAt(entry).type() == NORMAL)) { |
| 3655 Object* value = dictionary->ValueAt(entry); | 3819 Object* value = dictionary->ValueAt(entry); |
| 3656 if (!receiver->IsGlobalObject()) return value; | 3820 if (!receiver->IsGlobalObject()) return value; |
| 3657 value = JSGlobalPropertyCell::cast(value)->value(); | 3821 value = JSGlobalPropertyCell::cast(value)->value(); |
| 3658 if (!value->IsTheHole()) return value; | 3822 if (!value->IsTheHole()) return value; |
| 3659 // If value is the hole do the general lookup. | 3823 // If value is the hole do the general lookup. |
| 3660 } | 3824 } |
| 3661 } | 3825 } |
| 3662 } else if (args[0]->IsString() && args[1]->IsSmi()) { | 3826 } else if (args[0]->IsString() && args[1]->IsSmi()) { |
| 3663 // Fast case for string indexing using [] with a smi index. | 3827 // Fast case for string indexing using [] with a smi index. |
| 3664 HandleScope scope; | 3828 HandleScope scope(isolate); |
| 3665 Handle<String> str = args.at<String>(0); | 3829 Handle<String> str = args.at<String>(0); |
| 3666 int index = Smi::cast(args[1])->value(); | 3830 int index = Smi::cast(args[1])->value(); |
| 3667 if (index >= 0 && index < str->length()) { | 3831 if (index >= 0 && index < str->length()) { |
| 3668 Handle<Object> result = GetCharAt(str, index); | 3832 Handle<Object> result = GetCharAt(str, index); |
| 3669 return *result; | 3833 return *result; |
| 3670 } | 3834 } |
| 3671 } | 3835 } |
| 3672 | 3836 |
| 3673 // Fall back to GetObjectProperty. | 3837 // Fall back to GetObjectProperty. |
| 3674 return Runtime::GetObjectProperty(args.at<Object>(0), | 3838 return Runtime::GetObjectProperty(isolate, |
| 3839 args.at<Object>(0), |
| 3675 args.at<Object>(1)); | 3840 args.at<Object>(1)); |
| 3676 } | 3841 } |
| 3677 | 3842 |
| 3678 // Implements part of 8.12.9 DefineOwnProperty. | 3843 // Implements part of 8.12.9 DefineOwnProperty. |
| 3679 // There are 3 cases that lead here: | 3844 // There are 3 cases that lead here: |
| 3680 // Step 4b - define a new accessor property. | 3845 // Step 4b - define a new accessor property. |
| 3681 // Steps 9c & 12 - replace an existing data property with an accessor property. | 3846 // Steps 9c & 12 - replace an existing data property with an accessor property. |
| 3682 // Step 12 - update an existing accessor property with an accessor or generic | 3847 // Step 12 - update an existing accessor property with an accessor or generic |
| 3683 // descriptor. | 3848 // descriptor. |
| 3684 static MaybeObject* Runtime_DefineOrRedefineAccessorProperty(Arguments args) { | 3849 static MaybeObject* Runtime_DefineOrRedefineAccessorProperty( |
| 3850 RUNTIME_CALLING_CONVENTION) { |
| 3851 RUNTIME_GET_ISOLATE; |
| 3685 ASSERT(args.length() == 5); | 3852 ASSERT(args.length() == 5); |
| 3686 HandleScope scope; | 3853 HandleScope scope(isolate); |
| 3687 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 3854 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 3688 CONVERT_CHECKED(String, name, args[1]); | 3855 CONVERT_CHECKED(String, name, args[1]); |
| 3689 CONVERT_CHECKED(Smi, flag_setter, args[2]); | 3856 CONVERT_CHECKED(Smi, flag_setter, args[2]); |
| 3690 Object* fun = args[3]; | 3857 Object* fun = args[3]; |
| 3691 RUNTIME_ASSERT(fun->IsJSFunction() || fun->IsUndefined()); | 3858 RUNTIME_ASSERT(fun->IsJSFunction() || fun->IsUndefined()); |
| 3692 CONVERT_CHECKED(Smi, flag_attr, args[4]); | 3859 CONVERT_CHECKED(Smi, flag_attr, args[4]); |
| 3693 int unchecked = flag_attr->value(); | 3860 int unchecked = flag_attr->value(); |
| 3694 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 3861 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
| 3695 RUNTIME_ASSERT(!obj->IsNull()); | 3862 RUNTIME_ASSERT(!obj->IsNull()); |
| 3696 LookupResult result; | 3863 LookupResult result; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3711 } | 3878 } |
| 3712 return obj->DefineAccessor(name, flag_setter->value() == 0, fun, attr); | 3879 return obj->DefineAccessor(name, flag_setter->value() == 0, fun, attr); |
| 3713 } | 3880 } |
| 3714 | 3881 |
| 3715 // Implements part of 8.12.9 DefineOwnProperty. | 3882 // Implements part of 8.12.9 DefineOwnProperty. |
| 3716 // There are 3 cases that lead here: | 3883 // There are 3 cases that lead here: |
| 3717 // Step 4a - define a new data property. | 3884 // Step 4a - define a new data property. |
| 3718 // Steps 9b & 12 - replace an existing accessor property with a data property. | 3885 // Steps 9b & 12 - replace an existing accessor property with a data property. |
| 3719 // Step 12 - update an existing data property with a data or generic | 3886 // Step 12 - update an existing data property with a data or generic |
| 3720 // descriptor. | 3887 // descriptor. |
| 3721 static MaybeObject* Runtime_DefineOrRedefineDataProperty(Arguments args) { | 3888 static MaybeObject* Runtime_DefineOrRedefineDataProperty( |
| 3889 RUNTIME_CALLING_CONVENTION) { |
| 3890 RUNTIME_GET_ISOLATE; |
| 3722 ASSERT(args.length() == 4); | 3891 ASSERT(args.length() == 4); |
| 3723 HandleScope scope; | 3892 HandleScope scope(isolate); |
| 3724 CONVERT_ARG_CHECKED(JSObject, js_object, 0); | 3893 CONVERT_ARG_CHECKED(JSObject, js_object, 0); |
| 3725 CONVERT_ARG_CHECKED(String, name, 1); | 3894 CONVERT_ARG_CHECKED(String, name, 1); |
| 3726 Handle<Object> obj_value = args.at<Object>(2); | 3895 Handle<Object> obj_value = args.at<Object>(2); |
| 3727 | 3896 |
| 3728 CONVERT_CHECKED(Smi, flag, args[3]); | 3897 CONVERT_CHECKED(Smi, flag, args[3]); |
| 3729 int unchecked = flag->value(); | 3898 int unchecked = flag->value(); |
| 3730 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 3899 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
| 3731 | 3900 |
| 3732 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); | 3901 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
| 3733 | 3902 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 3760 } | 3929 } |
| 3761 | 3930 |
| 3762 LookupResult result; | 3931 LookupResult result; |
| 3763 js_object->LookupRealNamedProperty(*name, &result); | 3932 js_object->LookupRealNamedProperty(*name, &result); |
| 3764 | 3933 |
| 3765 // To be compatible with safari we do not change the value on API objects | 3934 // To be compatible with safari we do not change the value on API objects |
| 3766 // in defineProperty. Firefox disagrees here, and actually changes the value. | 3935 // in defineProperty. Firefox disagrees here, and actually changes the value. |
| 3767 if (result.IsProperty() && | 3936 if (result.IsProperty() && |
| 3768 (result.type() == CALLBACKS) && | 3937 (result.type() == CALLBACKS) && |
| 3769 result.GetCallbackObject()->IsAccessorInfo()) { | 3938 result.GetCallbackObject()->IsAccessorInfo()) { |
| 3770 return Heap::undefined_value(); | 3939 return isolate->heap()->undefined_value(); |
| 3771 } | 3940 } |
| 3772 | 3941 |
| 3773 // Take special care when attributes are different and there is already | 3942 // Take special care when attributes are different and there is already |
| 3774 // a property. For simplicity we normalize the property which enables us | 3943 // a property. For simplicity we normalize the property which enables us |
| 3775 // to not worry about changing the instance_descriptor and creating a new | 3944 // to not worry about changing the instance_descriptor and creating a new |
| 3776 // map. The current version of SetObjectProperty does not handle attributes | 3945 // map. The current version of SetObjectProperty does not handle attributes |
| 3777 // correctly in the case where a property is a field and is reset with | 3946 // correctly in the case where a property is a field and is reset with |
| 3778 // new attributes. | 3947 // new attributes. |
| 3779 if (result.IsProperty() && | 3948 if (result.IsProperty() && |
| 3780 (attr != result.GetAttributes() || result.type() == CALLBACKS)) { | 3949 (attr != result.GetAttributes() || result.type() == CALLBACKS)) { |
| 3781 // New attributes - normalize to avoid writing to instance descriptor | 3950 // New attributes - normalize to avoid writing to instance descriptor |
| 3782 if (js_object->IsJSGlobalProxy()) { | 3951 if (js_object->IsJSGlobalProxy()) { |
| 3783 // Since the result is a property, the prototype will exist so | 3952 // Since the result is a property, the prototype will exist so |
| 3784 // we don't have to check for null. | 3953 // we don't have to check for null. |
| 3785 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); | 3954 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); |
| 3786 } | 3955 } |
| 3787 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); | 3956 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); |
| 3788 // Use IgnoreAttributes version since a readonly property may be | 3957 // Use IgnoreAttributes version since a readonly property may be |
| 3789 // overridden and SetProperty does not allow this. | 3958 // overridden and SetProperty does not allow this. |
| 3790 return js_object->SetLocalPropertyIgnoreAttributes(*name, | 3959 return js_object->SetLocalPropertyIgnoreAttributes(*name, |
| 3791 *obj_value, | 3960 *obj_value, |
| 3792 attr); | 3961 attr); |
| 3793 } | 3962 } |
| 3794 | 3963 |
| 3795 return Runtime::ForceSetObjectProperty(js_object, name, obj_value, attr); | 3964 return Runtime::ForceSetObjectProperty(isolate, |
| 3965 js_object, |
| 3966 name, |
| 3967 obj_value, |
| 3968 attr); |
| 3796 } | 3969 } |
| 3797 | 3970 |
| 3798 | 3971 |
| 3799 MaybeObject* Runtime::SetObjectProperty(Handle<Object> object, | 3972 MaybeObject* Runtime::SetObjectProperty(Isolate* isolate, |
| 3973 Handle<Object> object, |
| 3800 Handle<Object> key, | 3974 Handle<Object> key, |
| 3801 Handle<Object> value, | 3975 Handle<Object> value, |
| 3802 PropertyAttributes attr, | 3976 PropertyAttributes attr, |
| 3803 StrictModeFlag strict_mode) { | 3977 StrictModeFlag strict_mode) { |
| 3804 HandleScope scope; | 3978 HandleScope scope(isolate); |
| 3805 | 3979 |
| 3806 if (object->IsUndefined() || object->IsNull()) { | 3980 if (object->IsUndefined() || object->IsNull()) { |
| 3807 Handle<Object> args[2] = { key, object }; | 3981 Handle<Object> args[2] = { key, object }; |
| 3808 Handle<Object> error = | 3982 Handle<Object> error = |
| 3809 Factory::NewTypeError("non_object_property_store", | 3983 isolate->factory()->NewTypeError("non_object_property_store", |
| 3810 HandleVector(args, 2)); | 3984 HandleVector(args, 2)); |
| 3811 return Top::Throw(*error); | 3985 return isolate->Throw(*error); |
| 3812 } | 3986 } |
| 3813 | 3987 |
| 3814 // If the object isn't a JavaScript object, we ignore the store. | 3988 // If the object isn't a JavaScript object, we ignore the store. |
| 3815 if (!object->IsJSObject()) return *value; | 3989 if (!object->IsJSObject()) return *value; |
| 3816 | 3990 |
| 3817 Handle<JSObject> js_object = Handle<JSObject>::cast(object); | 3991 Handle<JSObject> js_object = Handle<JSObject>::cast(object); |
| 3818 | 3992 |
| 3819 // Check if the given key is an array index. | 3993 // Check if the given key is an array index. |
| 3820 uint32_t index; | 3994 uint32_t index; |
| 3821 if (key->ToArrayIndex(&index)) { | 3995 if (key->ToArrayIndex(&index)) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3855 Handle<String> name = Handle<String>::cast(converted); | 4029 Handle<String> name = Handle<String>::cast(converted); |
| 3856 | 4030 |
| 3857 if (name->AsArrayIndex(&index)) { | 4031 if (name->AsArrayIndex(&index)) { |
| 3858 return js_object->SetElement(index, *value, strict_mode); | 4032 return js_object->SetElement(index, *value, strict_mode); |
| 3859 } else { | 4033 } else { |
| 3860 return js_object->SetProperty(*name, *value, attr, strict_mode); | 4034 return js_object->SetProperty(*name, *value, attr, strict_mode); |
| 3861 } | 4035 } |
| 3862 } | 4036 } |
| 3863 | 4037 |
| 3864 | 4038 |
| 3865 MaybeObject* Runtime::ForceSetObjectProperty(Handle<JSObject> js_object, | 4039 MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate, |
| 4040 Handle<JSObject> js_object, |
| 3866 Handle<Object> key, | 4041 Handle<Object> key, |
| 3867 Handle<Object> value, | 4042 Handle<Object> value, |
| 3868 PropertyAttributes attr) { | 4043 PropertyAttributes attr) { |
| 3869 HandleScope scope; | 4044 HandleScope scope(isolate); |
| 3870 | 4045 |
| 3871 // Check if the given key is an array index. | 4046 // Check if the given key is an array index. |
| 3872 uint32_t index; | 4047 uint32_t index; |
| 3873 if (key->ToArrayIndex(&index)) { | 4048 if (key->ToArrayIndex(&index)) { |
| 3874 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters | 4049 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters |
| 3875 // of a string using [] notation. We need to support this too in | 4050 // of a string using [] notation. We need to support this too in |
| 3876 // JavaScript. | 4051 // JavaScript. |
| 3877 // In the case of a String object we just need to redirect the assignment to | 4052 // In the case of a String object we just need to redirect the assignment to |
| 3878 // the underlying string if the index is in range. Since the underlying | 4053 // the underlying string if the index is in range. Since the underlying |
| 3879 // string does nothing with the assignment then we can ignore such | 4054 // string does nothing with the assignment then we can ignore such |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3904 Handle<String> name = Handle<String>::cast(converted); | 4079 Handle<String> name = Handle<String>::cast(converted); |
| 3905 | 4080 |
| 3906 if (name->AsArrayIndex(&index)) { | 4081 if (name->AsArrayIndex(&index)) { |
| 3907 return js_object->SetElement(index, *value, kNonStrictMode); | 4082 return js_object->SetElement(index, *value, kNonStrictMode); |
| 3908 } else { | 4083 } else { |
| 3909 return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr); | 4084 return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr); |
| 3910 } | 4085 } |
| 3911 } | 4086 } |
| 3912 | 4087 |
| 3913 | 4088 |
| 3914 MaybeObject* Runtime::ForceDeleteObjectProperty(Handle<JSObject> js_object, | 4089 MaybeObject* Runtime::ForceDeleteObjectProperty(Isolate* isolate, |
| 4090 Handle<JSObject> js_object, |
| 3915 Handle<Object> key) { | 4091 Handle<Object> key) { |
| 3916 HandleScope scope; | 4092 HandleScope scope(isolate); |
| 3917 | 4093 |
| 3918 // Check if the given key is an array index. | 4094 // Check if the given key is an array index. |
| 3919 uint32_t index; | 4095 uint32_t index; |
| 3920 if (key->ToArrayIndex(&index)) { | 4096 if (key->ToArrayIndex(&index)) { |
| 3921 // In Firefox/SpiderMonkey, Safari and Opera you can access the | 4097 // In Firefox/SpiderMonkey, Safari and Opera you can access the |
| 3922 // characters of a string using [] notation. In the case of a | 4098 // characters of a string using [] notation. In the case of a |
| 3923 // String object we just need to redirect the deletion to the | 4099 // String object we just need to redirect the deletion to the |
| 3924 // underlying string if the index is in range. Since the | 4100 // underlying string if the index is in range. Since the |
| 3925 // underlying string does nothing with the deletion, we can ignore | 4101 // underlying string does nothing with the deletion, we can ignore |
| 3926 // such deletions. | 4102 // such deletions. |
| 3927 if (js_object->IsStringObjectWithCharacterAt(index)) { | 4103 if (js_object->IsStringObjectWithCharacterAt(index)) { |
| 3928 return Heap::true_value(); | 4104 return isolate->heap()->true_value(); |
| 3929 } | 4105 } |
| 3930 | 4106 |
| 3931 return js_object->DeleteElement(index, JSObject::FORCE_DELETION); | 4107 return js_object->DeleteElement(index, JSObject::FORCE_DELETION); |
| 3932 } | 4108 } |
| 3933 | 4109 |
| 3934 Handle<String> key_string; | 4110 Handle<String> key_string; |
| 3935 if (key->IsString()) { | 4111 if (key->IsString()) { |
| 3936 key_string = Handle<String>::cast(key); | 4112 key_string = Handle<String>::cast(key); |
| 3937 } else { | 4113 } else { |
| 3938 // Call-back into JavaScript to convert the key to a string. | 4114 // Call-back into JavaScript to convert the key to a string. |
| 3939 bool has_pending_exception = false; | 4115 bool has_pending_exception = false; |
| 3940 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); | 4116 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); |
| 3941 if (has_pending_exception) return Failure::Exception(); | 4117 if (has_pending_exception) return Failure::Exception(); |
| 3942 key_string = Handle<String>::cast(converted); | 4118 key_string = Handle<String>::cast(converted); |
| 3943 } | 4119 } |
| 3944 | 4120 |
| 3945 key_string->TryFlatten(); | 4121 key_string->TryFlatten(); |
| 3946 return js_object->DeleteProperty(*key_string, JSObject::FORCE_DELETION); | 4122 return js_object->DeleteProperty(*key_string, JSObject::FORCE_DELETION); |
| 3947 } | 4123 } |
| 3948 | 4124 |
| 3949 | 4125 |
| 3950 static MaybeObject* Runtime_SetProperty(Arguments args) { | 4126 static MaybeObject* Runtime_SetProperty(RUNTIME_CALLING_CONVENTION) { |
| 4127 RUNTIME_GET_ISOLATE; |
| 3951 NoHandleAllocation ha; | 4128 NoHandleAllocation ha; |
| 3952 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5); | 4129 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5); |
| 3953 | 4130 |
| 3954 Handle<Object> object = args.at<Object>(0); | 4131 Handle<Object> object = args.at<Object>(0); |
| 3955 Handle<Object> key = args.at<Object>(1); | 4132 Handle<Object> key = args.at<Object>(1); |
| 3956 Handle<Object> value = args.at<Object>(2); | 4133 Handle<Object> value = args.at<Object>(2); |
| 3957 CONVERT_SMI_CHECKED(unchecked_attributes, args[3]); | 4134 CONVERT_SMI_CHECKED(unchecked_attributes, args[3]); |
| 3958 RUNTIME_ASSERT( | 4135 RUNTIME_ASSERT( |
| 3959 (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 4136 (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
| 3960 // Compute attributes. | 4137 // Compute attributes. |
| 3961 PropertyAttributes attributes = | 4138 PropertyAttributes attributes = |
| 3962 static_cast<PropertyAttributes>(unchecked_attributes); | 4139 static_cast<PropertyAttributes>(unchecked_attributes); |
| 3963 | 4140 |
| 3964 StrictModeFlag strict_mode = kNonStrictMode; | 4141 StrictModeFlag strict_mode = kNonStrictMode; |
| 3965 if (args.length() == 5) { | 4142 if (args.length() == 5) { |
| 3966 CONVERT_SMI_CHECKED(strict_unchecked, args[4]); | 4143 CONVERT_SMI_CHECKED(strict_unchecked, args[4]); |
| 3967 RUNTIME_ASSERT(strict_unchecked == kStrictMode || | 4144 RUNTIME_ASSERT(strict_unchecked == kStrictMode || |
| 3968 strict_unchecked == kNonStrictMode); | 4145 strict_unchecked == kNonStrictMode); |
| 3969 strict_mode = static_cast<StrictModeFlag>(strict_unchecked); | 4146 strict_mode = static_cast<StrictModeFlag>(strict_unchecked); |
| 3970 } | 4147 } |
| 3971 | 4148 |
| 3972 return Runtime::SetObjectProperty(object, | 4149 return Runtime::SetObjectProperty(isolate, |
| 4150 object, |
| 3973 key, | 4151 key, |
| 3974 value, | 4152 value, |
| 3975 attributes, | 4153 attributes, |
| 3976 strict_mode); | 4154 strict_mode); |
| 3977 } | 4155 } |
| 3978 | 4156 |
| 3979 | 4157 |
| 3980 // Set a local property, even if it is READ_ONLY. If the property does not | 4158 // Set a local property, even if it is READ_ONLY. If the property does not |
| 3981 // exist, it will be added with attributes NONE. | 4159 // exist, it will be added with attributes NONE. |
| 3982 static MaybeObject* Runtime_IgnoreAttributesAndSetProperty(Arguments args) { | 4160 static MaybeObject* Runtime_IgnoreAttributesAndSetProperty( |
| 4161 RUNTIME_CALLING_CONVENTION) { |
| 4162 RUNTIME_GET_ISOLATE; |
| 3983 NoHandleAllocation ha; | 4163 NoHandleAllocation ha; |
| 3984 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); | 4164 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); |
| 3985 CONVERT_CHECKED(JSObject, object, args[0]); | 4165 CONVERT_CHECKED(JSObject, object, args[0]); |
| 3986 CONVERT_CHECKED(String, name, args[1]); | 4166 CONVERT_CHECKED(String, name, args[1]); |
| 3987 // Compute attributes. | 4167 // Compute attributes. |
| 3988 PropertyAttributes attributes = NONE; | 4168 PropertyAttributes attributes = NONE; |
| 3989 if (args.length() == 4) { | 4169 if (args.length() == 4) { |
| 3990 CONVERT_CHECKED(Smi, value_obj, args[3]); | 4170 CONVERT_CHECKED(Smi, value_obj, args[3]); |
| 3991 int unchecked_value = value_obj->value(); | 4171 int unchecked_value = value_obj->value(); |
| 3992 // Only attribute bits should be set. | 4172 // Only attribute bits should be set. |
| 3993 RUNTIME_ASSERT( | 4173 RUNTIME_ASSERT( |
| 3994 (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 4174 (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
| 3995 attributes = static_cast<PropertyAttributes>(unchecked_value); | 4175 attributes = static_cast<PropertyAttributes>(unchecked_value); |
| 3996 } | 4176 } |
| 3997 | 4177 |
| 3998 return object-> | 4178 return object-> |
| 3999 SetLocalPropertyIgnoreAttributes(name, args[2], attributes); | 4179 SetLocalPropertyIgnoreAttributes(name, args[2], attributes); |
| 4000 } | 4180 } |
| 4001 | 4181 |
| 4002 | 4182 |
| 4003 static MaybeObject* Runtime_DeleteProperty(Arguments args) { | 4183 static MaybeObject* Runtime_DeleteProperty(RUNTIME_CALLING_CONVENTION) { |
| 4184 RUNTIME_GET_ISOLATE; |
| 4004 NoHandleAllocation ha; | 4185 NoHandleAllocation ha; |
| 4005 ASSERT(args.length() == 3); | 4186 ASSERT(args.length() == 3); |
| 4006 | 4187 |
| 4007 CONVERT_CHECKED(JSObject, object, args[0]); | 4188 CONVERT_CHECKED(JSObject, object, args[0]); |
| 4008 CONVERT_CHECKED(String, key, args[1]); | 4189 CONVERT_CHECKED(String, key, args[1]); |
| 4009 CONVERT_SMI_CHECKED(strict, args[2]); | 4190 CONVERT_SMI_CHECKED(strict, args[2]); |
| 4010 return object->DeleteProperty(key, (strict == kStrictMode) | 4191 return object->DeleteProperty(key, (strict == kStrictMode) |
| 4011 ? JSObject::STRICT_DELETION | 4192 ? JSObject::STRICT_DELETION |
| 4012 : JSObject::NORMAL_DELETION); | 4193 : JSObject::NORMAL_DELETION); |
| 4013 } | 4194 } |
| 4014 | 4195 |
| 4015 | 4196 |
| 4016 static Object* HasLocalPropertyImplementation(Handle<JSObject> object, | 4197 static Object* HasLocalPropertyImplementation(Isolate* isolate, |
| 4198 Handle<JSObject> object, |
| 4017 Handle<String> key) { | 4199 Handle<String> key) { |
| 4018 if (object->HasLocalProperty(*key)) return Heap::true_value(); | 4200 if (object->HasLocalProperty(*key)) return isolate->heap()->true_value(); |
| 4019 // Handle hidden prototypes. If there's a hidden prototype above this thing | 4201 // Handle hidden prototypes. If there's a hidden prototype above this thing |
| 4020 // then we have to check it for properties, because they are supposed to | 4202 // then we have to check it for properties, because they are supposed to |
| 4021 // look like they are on this object. | 4203 // look like they are on this object. |
| 4022 Handle<Object> proto(object->GetPrototype()); | 4204 Handle<Object> proto(object->GetPrototype()); |
| 4023 if (proto->IsJSObject() && | 4205 if (proto->IsJSObject() && |
| 4024 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) { | 4206 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) { |
| 4025 return HasLocalPropertyImplementation(Handle<JSObject>::cast(proto), key); | 4207 return HasLocalPropertyImplementation(isolate, |
| 4208 Handle<JSObject>::cast(proto), |
| 4209 key); |
| 4026 } | 4210 } |
| 4027 return Heap::false_value(); | 4211 return isolate->heap()->false_value(); |
| 4028 } | 4212 } |
| 4029 | 4213 |
| 4030 | 4214 |
| 4031 static MaybeObject* Runtime_HasLocalProperty(Arguments args) { | 4215 static MaybeObject* Runtime_HasLocalProperty(RUNTIME_CALLING_CONVENTION) { |
| 4216 RUNTIME_GET_ISOLATE; |
| 4032 NoHandleAllocation ha; | 4217 NoHandleAllocation ha; |
| 4033 ASSERT(args.length() == 2); | 4218 ASSERT(args.length() == 2); |
| 4034 CONVERT_CHECKED(String, key, args[1]); | 4219 CONVERT_CHECKED(String, key, args[1]); |
| 4035 | 4220 |
| 4036 Object* obj = args[0]; | 4221 Object* obj = args[0]; |
| 4037 // Only JS objects can have properties. | 4222 // Only JS objects can have properties. |
| 4038 if (obj->IsJSObject()) { | 4223 if (obj->IsJSObject()) { |
| 4039 JSObject* object = JSObject::cast(obj); | 4224 JSObject* object = JSObject::cast(obj); |
| 4040 // Fast case - no interceptors. | 4225 // Fast case - no interceptors. |
| 4041 if (object->HasRealNamedProperty(key)) return Heap::true_value(); | 4226 if (object->HasRealNamedProperty(key)) return isolate->heap()->true_value(); |
| 4042 // Slow case. Either it's not there or we have an interceptor. We should | 4227 // Slow case. Either it's not there or we have an interceptor. We should |
| 4043 // have handles for this kind of deal. | 4228 // have handles for this kind of deal. |
| 4044 HandleScope scope; | 4229 HandleScope scope(isolate); |
| 4045 return HasLocalPropertyImplementation(Handle<JSObject>(object), | 4230 return HasLocalPropertyImplementation(isolate, |
| 4231 Handle<JSObject>(object), |
| 4046 Handle<String>(key)); | 4232 Handle<String>(key)); |
| 4047 } else if (obj->IsString()) { | 4233 } else if (obj->IsString()) { |
| 4048 // Well, there is one exception: Handle [] on strings. | 4234 // Well, there is one exception: Handle [] on strings. |
| 4049 uint32_t index; | 4235 uint32_t index; |
| 4050 if (key->AsArrayIndex(&index)) { | 4236 if (key->AsArrayIndex(&index)) { |
| 4051 String* string = String::cast(obj); | 4237 String* string = String::cast(obj); |
| 4052 if (index < static_cast<uint32_t>(string->length())) | 4238 if (index < static_cast<uint32_t>(string->length())) |
| 4053 return Heap::true_value(); | 4239 return isolate->heap()->true_value(); |
| 4054 } | 4240 } |
| 4055 } | 4241 } |
| 4056 return Heap::false_value(); | 4242 return isolate->heap()->false_value(); |
| 4057 } | 4243 } |
| 4058 | 4244 |
| 4059 | 4245 |
| 4060 static MaybeObject* Runtime_HasProperty(Arguments args) { | 4246 static MaybeObject* Runtime_HasProperty(RUNTIME_CALLING_CONVENTION) { |
| 4247 RUNTIME_GET_ISOLATE; |
| 4061 NoHandleAllocation na; | 4248 NoHandleAllocation na; |
| 4062 ASSERT(args.length() == 2); | 4249 ASSERT(args.length() == 2); |
| 4063 | 4250 |
| 4064 // Only JS objects can have properties. | 4251 // Only JS objects can have properties. |
| 4065 if (args[0]->IsJSObject()) { | 4252 if (args[0]->IsJSObject()) { |
| 4066 JSObject* object = JSObject::cast(args[0]); | 4253 JSObject* object = JSObject::cast(args[0]); |
| 4067 CONVERT_CHECKED(String, key, args[1]); | 4254 CONVERT_CHECKED(String, key, args[1]); |
| 4068 if (object->HasProperty(key)) return Heap::true_value(); | 4255 if (object->HasProperty(key)) return isolate->heap()->true_value(); |
| 4069 } | 4256 } |
| 4070 return Heap::false_value(); | 4257 return isolate->heap()->false_value(); |
| 4071 } | 4258 } |
| 4072 | 4259 |
| 4073 | 4260 |
| 4074 static MaybeObject* Runtime_HasElement(Arguments args) { | 4261 static MaybeObject* Runtime_HasElement(RUNTIME_CALLING_CONVENTION) { |
| 4262 RUNTIME_GET_ISOLATE; |
| 4075 NoHandleAllocation na; | 4263 NoHandleAllocation na; |
| 4076 ASSERT(args.length() == 2); | 4264 ASSERT(args.length() == 2); |
| 4077 | 4265 |
| 4078 // Only JS objects can have elements. | 4266 // Only JS objects can have elements. |
| 4079 if (args[0]->IsJSObject()) { | 4267 if (args[0]->IsJSObject()) { |
| 4080 JSObject* object = JSObject::cast(args[0]); | 4268 JSObject* object = JSObject::cast(args[0]); |
| 4081 CONVERT_CHECKED(Smi, index_obj, args[1]); | 4269 CONVERT_CHECKED(Smi, index_obj, args[1]); |
| 4082 uint32_t index = index_obj->value(); | 4270 uint32_t index = index_obj->value(); |
| 4083 if (object->HasElement(index)) return Heap::true_value(); | 4271 if (object->HasElement(index)) return isolate->heap()->true_value(); |
| 4084 } | 4272 } |
| 4085 return Heap::false_value(); | 4273 return isolate->heap()->false_value(); |
| 4086 } | 4274 } |
| 4087 | 4275 |
| 4088 | 4276 |
| 4089 static MaybeObject* Runtime_IsPropertyEnumerable(Arguments args) { | 4277 static MaybeObject* Runtime_IsPropertyEnumerable(RUNTIME_CALLING_CONVENTION) { |
| 4278 RUNTIME_GET_ISOLATE; |
| 4090 NoHandleAllocation ha; | 4279 NoHandleAllocation ha; |
| 4091 ASSERT(args.length() == 2); | 4280 ASSERT(args.length() == 2); |
| 4092 | 4281 |
| 4093 CONVERT_CHECKED(JSObject, object, args[0]); | 4282 CONVERT_CHECKED(JSObject, object, args[0]); |
| 4094 CONVERT_CHECKED(String, key, args[1]); | 4283 CONVERT_CHECKED(String, key, args[1]); |
| 4095 | 4284 |
| 4096 uint32_t index; | 4285 uint32_t index; |
| 4097 if (key->AsArrayIndex(&index)) { | 4286 if (key->AsArrayIndex(&index)) { |
| 4098 return Heap::ToBoolean(object->HasElement(index)); | 4287 return isolate->heap()->ToBoolean(object->HasElement(index)); |
| 4099 } | 4288 } |
| 4100 | 4289 |
| 4101 PropertyAttributes att = object->GetLocalPropertyAttribute(key); | 4290 PropertyAttributes att = object->GetLocalPropertyAttribute(key); |
| 4102 return Heap::ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); | 4291 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); |
| 4103 } | 4292 } |
| 4104 | 4293 |
| 4105 | 4294 |
| 4106 static MaybeObject* Runtime_GetPropertyNames(Arguments args) { | 4295 static MaybeObject* Runtime_GetPropertyNames(RUNTIME_CALLING_CONVENTION) { |
| 4107 HandleScope scope; | 4296 RUNTIME_GET_ISOLATE; |
| 4297 HandleScope scope(isolate); |
| 4108 ASSERT(args.length() == 1); | 4298 ASSERT(args.length() == 1); |
| 4109 CONVERT_ARG_CHECKED(JSObject, object, 0); | 4299 CONVERT_ARG_CHECKED(JSObject, object, 0); |
| 4110 return *GetKeysFor(object); | 4300 return *GetKeysFor(object); |
| 4111 } | 4301 } |
| 4112 | 4302 |
| 4113 | 4303 |
| 4114 // Returns either a FixedArray as Runtime_GetPropertyNames, | 4304 // Returns either a FixedArray as Runtime_GetPropertyNames, |
| 4115 // or, if the given object has an enum cache that contains | 4305 // or, if the given object has an enum cache that contains |
| 4116 // all enumerable properties of the object and its prototypes | 4306 // all enumerable properties of the object and its prototypes |
| 4117 // have none, the map of the object. This is used to speed up | 4307 // have none, the map of the object. This is used to speed up |
| 4118 // the check for deletions during a for-in. | 4308 // the check for deletions during a for-in. |
| 4119 static MaybeObject* Runtime_GetPropertyNamesFast(Arguments args) { | 4309 static MaybeObject* Runtime_GetPropertyNamesFast(RUNTIME_CALLING_CONVENTION) { |
| 4310 RUNTIME_GET_ISOLATE; |
| 4120 ASSERT(args.length() == 1); | 4311 ASSERT(args.length() == 1); |
| 4121 | 4312 |
| 4122 CONVERT_CHECKED(JSObject, raw_object, args[0]); | 4313 CONVERT_CHECKED(JSObject, raw_object, args[0]); |
| 4123 | 4314 |
| 4124 if (raw_object->IsSimpleEnum()) return raw_object->map(); | 4315 if (raw_object->IsSimpleEnum()) return raw_object->map(); |
| 4125 | 4316 |
| 4126 HandleScope scope; | 4317 HandleScope scope(isolate); |
| 4127 Handle<JSObject> object(raw_object); | 4318 Handle<JSObject> object(raw_object); |
| 4128 Handle<FixedArray> content = GetKeysInFixedArrayFor(object, | 4319 Handle<FixedArray> content = GetKeysInFixedArrayFor(object, |
| 4129 INCLUDE_PROTOS); | 4320 INCLUDE_PROTOS); |
| 4130 | 4321 |
| 4131 // Test again, since cache may have been built by preceding call. | 4322 // Test again, since cache may have been built by preceding call. |
| 4132 if (object->IsSimpleEnum()) return object->map(); | 4323 if (object->IsSimpleEnum()) return object->map(); |
| 4133 | 4324 |
| 4134 return *content; | 4325 return *content; |
| 4135 } | 4326 } |
| 4136 | 4327 |
| 4137 | 4328 |
| 4138 // Find the length of the prototype chain that is to to handled as one. If a | 4329 // Find the length of the prototype chain that is to to handled as one. If a |
| 4139 // prototype object is hidden it is to be viewed as part of the the object it | 4330 // prototype object is hidden it is to be viewed as part of the the object it |
| 4140 // is prototype for. | 4331 // is prototype for. |
| 4141 static int LocalPrototypeChainLength(JSObject* obj) { | 4332 static int LocalPrototypeChainLength(JSObject* obj) { |
| 4142 int count = 1; | 4333 int count = 1; |
| 4143 Object* proto = obj->GetPrototype(); | 4334 Object* proto = obj->GetPrototype(); |
| 4144 while (proto->IsJSObject() && | 4335 while (proto->IsJSObject() && |
| 4145 JSObject::cast(proto)->map()->is_hidden_prototype()) { | 4336 JSObject::cast(proto)->map()->is_hidden_prototype()) { |
| 4146 count++; | 4337 count++; |
| 4147 proto = JSObject::cast(proto)->GetPrototype(); | 4338 proto = JSObject::cast(proto)->GetPrototype(); |
| 4148 } | 4339 } |
| 4149 return count; | 4340 return count; |
| 4150 } | 4341 } |
| 4151 | 4342 |
| 4152 | 4343 |
| 4153 // Return the names of the local named properties. | 4344 // Return the names of the local named properties. |
| 4154 // args[0]: object | 4345 // args[0]: object |
| 4155 static MaybeObject* Runtime_GetLocalPropertyNames(Arguments args) { | 4346 static MaybeObject* Runtime_GetLocalPropertyNames(RUNTIME_CALLING_CONVENTION) { |
| 4156 HandleScope scope; | 4347 RUNTIME_GET_ISOLATE; |
| 4348 HandleScope scope(isolate); |
| 4157 ASSERT(args.length() == 1); | 4349 ASSERT(args.length() == 1); |
| 4158 if (!args[0]->IsJSObject()) { | 4350 if (!args[0]->IsJSObject()) { |
| 4159 return Heap::undefined_value(); | 4351 return isolate->heap()->undefined_value(); |
| 4160 } | 4352 } |
| 4161 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 4353 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 4162 | 4354 |
| 4163 // Skip the global proxy as it has no properties and always delegates to the | 4355 // Skip the global proxy as it has no properties and always delegates to the |
| 4164 // real global object. | 4356 // real global object. |
| 4165 if (obj->IsJSGlobalProxy()) { | 4357 if (obj->IsJSGlobalProxy()) { |
| 4166 // Only collect names if access is permitted. | 4358 // Only collect names if access is permitted. |
| 4167 if (obj->IsAccessCheckNeeded() && | 4359 if (obj->IsAccessCheckNeeded() && |
| 4168 !Top::MayNamedAccess(*obj, Heap::undefined_value(), v8::ACCESS_KEYS)) { | 4360 !isolate->MayNamedAccess(*obj, |
| 4169 Top::ReportFailedAccessCheck(*obj, v8::ACCESS_KEYS); | 4361 isolate->heap()->undefined_value(), |
| 4170 return *Factory::NewJSArray(0); | 4362 v8::ACCESS_KEYS)) { |
| 4363 isolate->ReportFailedAccessCheck(*obj, v8::ACCESS_KEYS); |
| 4364 return *isolate->factory()->NewJSArray(0); |
| 4171 } | 4365 } |
| 4172 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); | 4366 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); |
| 4173 } | 4367 } |
| 4174 | 4368 |
| 4175 // Find the number of objects making up this. | 4369 // Find the number of objects making up this. |
| 4176 int length = LocalPrototypeChainLength(*obj); | 4370 int length = LocalPrototypeChainLength(*obj); |
| 4177 | 4371 |
| 4178 // Find the number of local properties for each of the objects. | 4372 // Find the number of local properties for each of the objects. |
| 4179 ScopedVector<int> local_property_count(length); | 4373 ScopedVector<int> local_property_count(length); |
| 4180 int total_property_count = 0; | 4374 int total_property_count = 0; |
| 4181 Handle<JSObject> jsproto = obj; | 4375 Handle<JSObject> jsproto = obj; |
| 4182 for (int i = 0; i < length; i++) { | 4376 for (int i = 0; i < length; i++) { |
| 4183 // Only collect names if access is permitted. | 4377 // Only collect names if access is permitted. |
| 4184 if (jsproto->IsAccessCheckNeeded() && | 4378 if (jsproto->IsAccessCheckNeeded() && |
| 4185 !Top::MayNamedAccess(*jsproto, | 4379 !isolate->MayNamedAccess(*jsproto, |
| 4186 Heap::undefined_value(), | 4380 isolate->heap()->undefined_value(), |
| 4187 v8::ACCESS_KEYS)) { | 4381 v8::ACCESS_KEYS)) { |
| 4188 Top::ReportFailedAccessCheck(*jsproto, v8::ACCESS_KEYS); | 4382 isolate->ReportFailedAccessCheck(*jsproto, v8::ACCESS_KEYS); |
| 4189 return *Factory::NewJSArray(0); | 4383 return *isolate->factory()->NewJSArray(0); |
| 4190 } | 4384 } |
| 4191 int n; | 4385 int n; |
| 4192 n = jsproto->NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE)); | 4386 n = jsproto->NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE)); |
| 4193 local_property_count[i] = n; | 4387 local_property_count[i] = n; |
| 4194 total_property_count += n; | 4388 total_property_count += n; |
| 4195 if (i < length - 1) { | 4389 if (i < length - 1) { |
| 4196 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | 4390 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); |
| 4197 } | 4391 } |
| 4198 } | 4392 } |
| 4199 | 4393 |
| 4200 // Allocate an array with storage for all the property names. | 4394 // Allocate an array with storage for all the property names. |
| 4201 Handle<FixedArray> names = Factory::NewFixedArray(total_property_count); | 4395 Handle<FixedArray> names = |
| 4396 isolate->factory()->NewFixedArray(total_property_count); |
| 4202 | 4397 |
| 4203 // Get the property names. | 4398 // Get the property names. |
| 4204 jsproto = obj; | 4399 jsproto = obj; |
| 4205 int proto_with_hidden_properties = 0; | 4400 int proto_with_hidden_properties = 0; |
| 4206 for (int i = 0; i < length; i++) { | 4401 for (int i = 0; i < length; i++) { |
| 4207 jsproto->GetLocalPropertyNames(*names, | 4402 jsproto->GetLocalPropertyNames(*names, |
| 4208 i == 0 ? 0 : local_property_count[i - 1]); | 4403 i == 0 ? 0 : local_property_count[i - 1]); |
| 4209 if (!GetHiddenProperties(jsproto, false)->IsUndefined()) { | 4404 if (!GetHiddenProperties(jsproto, false)->IsUndefined()) { |
| 4210 proto_with_hidden_properties++; | 4405 proto_with_hidden_properties++; |
| 4211 } | 4406 } |
| 4212 if (i < length - 1) { | 4407 if (i < length - 1) { |
| 4213 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | 4408 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); |
| 4214 } | 4409 } |
| 4215 } | 4410 } |
| 4216 | 4411 |
| 4217 // Filter out name of hidden propeties object. | 4412 // Filter out name of hidden propeties object. |
| 4218 if (proto_with_hidden_properties > 0) { | 4413 if (proto_with_hidden_properties > 0) { |
| 4219 Handle<FixedArray> old_names = names; | 4414 Handle<FixedArray> old_names = names; |
| 4220 names = Factory::NewFixedArray( | 4415 names = isolate->factory()->NewFixedArray( |
| 4221 names->length() - proto_with_hidden_properties); | 4416 names->length() - proto_with_hidden_properties); |
| 4222 int dest_pos = 0; | 4417 int dest_pos = 0; |
| 4223 for (int i = 0; i < total_property_count; i++) { | 4418 for (int i = 0; i < total_property_count; i++) { |
| 4224 Object* name = old_names->get(i); | 4419 Object* name = old_names->get(i); |
| 4225 if (name == Heap::hidden_symbol()) { | 4420 if (name == isolate->heap()->hidden_symbol()) { |
| 4226 continue; | 4421 continue; |
| 4227 } | 4422 } |
| 4228 names->set(dest_pos++, name); | 4423 names->set(dest_pos++, name); |
| 4229 } | 4424 } |
| 4230 } | 4425 } |
| 4231 | 4426 |
| 4232 return *Factory::NewJSArrayWithElements(names); | 4427 return *isolate->factory()->NewJSArrayWithElements(names); |
| 4233 } | 4428 } |
| 4234 | 4429 |
| 4235 | 4430 |
| 4236 // Return the names of the local indexed properties. | 4431 // Return the names of the local indexed properties. |
| 4237 // args[0]: object | 4432 // args[0]: object |
| 4238 static MaybeObject* Runtime_GetLocalElementNames(Arguments args) { | 4433 static MaybeObject* Runtime_GetLocalElementNames(RUNTIME_CALLING_CONVENTION) { |
| 4239 HandleScope scope; | 4434 RUNTIME_GET_ISOLATE; |
| 4435 HandleScope scope(isolate); |
| 4240 ASSERT(args.length() == 1); | 4436 ASSERT(args.length() == 1); |
| 4241 if (!args[0]->IsJSObject()) { | 4437 if (!args[0]->IsJSObject()) { |
| 4242 return Heap::undefined_value(); | 4438 return isolate->heap()->undefined_value(); |
| 4243 } | 4439 } |
| 4244 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 4440 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 4245 | 4441 |
| 4246 int n = obj->NumberOfLocalElements(static_cast<PropertyAttributes>(NONE)); | 4442 int n = obj->NumberOfLocalElements(static_cast<PropertyAttributes>(NONE)); |
| 4247 Handle<FixedArray> names = Factory::NewFixedArray(n); | 4443 Handle<FixedArray> names = isolate->factory()->NewFixedArray(n); |
| 4248 obj->GetLocalElementKeys(*names, static_cast<PropertyAttributes>(NONE)); | 4444 obj->GetLocalElementKeys(*names, static_cast<PropertyAttributes>(NONE)); |
| 4249 return *Factory::NewJSArrayWithElements(names); | 4445 return *isolate->factory()->NewJSArrayWithElements(names); |
| 4250 } | 4446 } |
| 4251 | 4447 |
| 4252 | 4448 |
| 4253 // Return information on whether an object has a named or indexed interceptor. | 4449 // Return information on whether an object has a named or indexed interceptor. |
| 4254 // args[0]: object | 4450 // args[0]: object |
| 4255 static MaybeObject* Runtime_GetInterceptorInfo(Arguments args) { | 4451 static MaybeObject* Runtime_GetInterceptorInfo(RUNTIME_CALLING_CONVENTION) { |
| 4256 HandleScope scope; | 4452 RUNTIME_GET_ISOLATE; |
| 4453 HandleScope scope(isolate); |
| 4257 ASSERT(args.length() == 1); | 4454 ASSERT(args.length() == 1); |
| 4258 if (!args[0]->IsJSObject()) { | 4455 if (!args[0]->IsJSObject()) { |
| 4259 return Smi::FromInt(0); | 4456 return Smi::FromInt(0); |
| 4260 } | 4457 } |
| 4261 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 4458 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 4262 | 4459 |
| 4263 int result = 0; | 4460 int result = 0; |
| 4264 if (obj->HasNamedInterceptor()) result |= 2; | 4461 if (obj->HasNamedInterceptor()) result |= 2; |
| 4265 if (obj->HasIndexedInterceptor()) result |= 1; | 4462 if (obj->HasIndexedInterceptor()) result |= 1; |
| 4266 | 4463 |
| 4267 return Smi::FromInt(result); | 4464 return Smi::FromInt(result); |
| 4268 } | 4465 } |
| 4269 | 4466 |
| 4270 | 4467 |
| 4271 // Return property names from named interceptor. | 4468 // Return property names from named interceptor. |
| 4272 // args[0]: object | 4469 // args[0]: object |
| 4273 static MaybeObject* Runtime_GetNamedInterceptorPropertyNames(Arguments args) { | 4470 static MaybeObject* Runtime_GetNamedInterceptorPropertyNames( |
| 4274 HandleScope scope; | 4471 RUNTIME_CALLING_CONVENTION) { |
| 4472 RUNTIME_GET_ISOLATE; |
| 4473 HandleScope scope(isolate); |
| 4275 ASSERT(args.length() == 1); | 4474 ASSERT(args.length() == 1); |
| 4276 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 4475 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 4277 | 4476 |
| 4278 if (obj->HasNamedInterceptor()) { | 4477 if (obj->HasNamedInterceptor()) { |
| 4279 v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj); | 4478 v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj); |
| 4280 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); | 4479 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); |
| 4281 } | 4480 } |
| 4282 return Heap::undefined_value(); | 4481 return isolate->heap()->undefined_value(); |
| 4283 } | 4482 } |
| 4284 | 4483 |
| 4285 | 4484 |
| 4286 // Return element names from indexed interceptor. | 4485 // Return element names from indexed interceptor. |
| 4287 // args[0]: object | 4486 // args[0]: object |
| 4288 static MaybeObject* Runtime_GetIndexedInterceptorElementNames(Arguments args) { | 4487 static MaybeObject* Runtime_GetIndexedInterceptorElementNames( |
| 4289 HandleScope scope; | 4488 RUNTIME_CALLING_CONVENTION) { |
| 4489 RUNTIME_GET_ISOLATE; |
| 4490 HandleScope scope(isolate); |
| 4290 ASSERT(args.length() == 1); | 4491 ASSERT(args.length() == 1); |
| 4291 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 4492 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 4292 | 4493 |
| 4293 if (obj->HasIndexedInterceptor()) { | 4494 if (obj->HasIndexedInterceptor()) { |
| 4294 v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj); | 4495 v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj); |
| 4295 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); | 4496 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); |
| 4296 } | 4497 } |
| 4297 return Heap::undefined_value(); | 4498 return isolate->heap()->undefined_value(); |
| 4298 } | 4499 } |
| 4299 | 4500 |
| 4300 | 4501 |
| 4301 static MaybeObject* Runtime_LocalKeys(Arguments args) { | 4502 static MaybeObject* Runtime_LocalKeys(RUNTIME_CALLING_CONVENTION) { |
| 4503 RUNTIME_GET_ISOLATE; |
| 4302 ASSERT_EQ(args.length(), 1); | 4504 ASSERT_EQ(args.length(), 1); |
| 4303 CONVERT_CHECKED(JSObject, raw_object, args[0]); | 4505 CONVERT_CHECKED(JSObject, raw_object, args[0]); |
| 4304 HandleScope scope; | 4506 HandleScope scope(isolate); |
| 4305 Handle<JSObject> object(raw_object); | 4507 Handle<JSObject> object(raw_object); |
| 4306 | 4508 |
| 4307 if (object->IsJSGlobalProxy()) { | 4509 if (object->IsJSGlobalProxy()) { |
| 4308 // Do access checks before going to the global object. | 4510 // Do access checks before going to the global object. |
| 4309 if (object->IsAccessCheckNeeded() && | 4511 if (object->IsAccessCheckNeeded() && |
| 4310 !Top::MayNamedAccess(*object, Heap::undefined_value(), | 4512 !isolate->MayNamedAccess(*object, isolate->heap()->undefined_value(), |
| 4311 v8::ACCESS_KEYS)) { | 4513 v8::ACCESS_KEYS)) { |
| 4312 Top::ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); | 4514 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS); |
| 4313 return *Factory::NewJSArray(0); | 4515 return *isolate->factory()->NewJSArray(0); |
| 4314 } | 4516 } |
| 4315 | 4517 |
| 4316 Handle<Object> proto(object->GetPrototype()); | 4518 Handle<Object> proto(object->GetPrototype()); |
| 4317 // If proxy is detached we simply return an empty array. | 4519 // If proxy is detached we simply return an empty array. |
| 4318 if (proto->IsNull()) return *Factory::NewJSArray(0); | 4520 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0); |
| 4319 object = Handle<JSObject>::cast(proto); | 4521 object = Handle<JSObject>::cast(proto); |
| 4320 } | 4522 } |
| 4321 | 4523 |
| 4322 Handle<FixedArray> contents = GetKeysInFixedArrayFor(object, | 4524 Handle<FixedArray> contents = GetKeysInFixedArrayFor(object, |
| 4323 LOCAL_ONLY); | 4525 LOCAL_ONLY); |
| 4324 // Some fast paths through GetKeysInFixedArrayFor reuse a cached | 4526 // Some fast paths through GetKeysInFixedArrayFor reuse a cached |
| 4325 // property array and since the result is mutable we have to create | 4527 // property array and since the result is mutable we have to create |
| 4326 // a fresh clone on each invocation. | 4528 // a fresh clone on each invocation. |
| 4327 int length = contents->length(); | 4529 int length = contents->length(); |
| 4328 Handle<FixedArray> copy = Factory::NewFixedArray(length); | 4530 Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length); |
| 4329 for (int i = 0; i < length; i++) { | 4531 for (int i = 0; i < length; i++) { |
| 4330 Object* entry = contents->get(i); | 4532 Object* entry = contents->get(i); |
| 4331 if (entry->IsString()) { | 4533 if (entry->IsString()) { |
| 4332 copy->set(i, entry); | 4534 copy->set(i, entry); |
| 4333 } else { | 4535 } else { |
| 4334 ASSERT(entry->IsNumber()); | 4536 ASSERT(entry->IsNumber()); |
| 4335 HandleScope scope; | 4537 HandleScope scope(isolate); |
| 4336 Handle<Object> entry_handle(entry); | 4538 Handle<Object> entry_handle(entry, isolate); |
| 4337 Handle<Object> entry_str = Factory::NumberToString(entry_handle); | 4539 Handle<Object> entry_str = |
| 4540 isolate->factory()->NumberToString(entry_handle); |
| 4338 copy->set(i, *entry_str); | 4541 copy->set(i, *entry_str); |
| 4339 } | 4542 } |
| 4340 } | 4543 } |
| 4341 return *Factory::NewJSArrayWithElements(copy); | 4544 return *isolate->factory()->NewJSArrayWithElements(copy); |
| 4342 } | 4545 } |
| 4343 | 4546 |
| 4344 | 4547 |
| 4345 static MaybeObject* Runtime_GetArgumentsProperty(Arguments args) { | 4548 static MaybeObject* Runtime_GetArgumentsProperty(RUNTIME_CALLING_CONVENTION) { |
| 4549 RUNTIME_GET_ISOLATE; |
| 4346 NoHandleAllocation ha; | 4550 NoHandleAllocation ha; |
| 4347 ASSERT(args.length() == 1); | 4551 ASSERT(args.length() == 1); |
| 4348 | 4552 |
| 4349 // Compute the frame holding the arguments. | 4553 // Compute the frame holding the arguments. |
| 4350 JavaScriptFrameIterator it; | 4554 JavaScriptFrameIterator it; |
| 4351 it.AdvanceToArgumentsFrame(); | 4555 it.AdvanceToArgumentsFrame(); |
| 4352 JavaScriptFrame* frame = it.frame(); | 4556 JavaScriptFrame* frame = it.frame(); |
| 4353 | 4557 |
| 4354 // Get the actual number of provided arguments. | 4558 // Get the actual number of provided arguments. |
| 4355 const uint32_t n = frame->ComputeParametersCount(); | 4559 const uint32_t n = frame->ComputeParametersCount(); |
| 4356 | 4560 |
| 4357 // Try to convert the key to an index. If successful and within | 4561 // Try to convert the key to an index. If successful and within |
| 4358 // index return the the argument from the frame. | 4562 // index return the the argument from the frame. |
| 4359 uint32_t index; | 4563 uint32_t index; |
| 4360 if (args[0]->ToArrayIndex(&index) && index < n) { | 4564 if (args[0]->ToArrayIndex(&index) && index < n) { |
| 4361 return frame->GetParameter(index); | 4565 return frame->GetParameter(index); |
| 4362 } | 4566 } |
| 4363 | 4567 |
| 4364 // Convert the key to a string. | 4568 // Convert the key to a string. |
| 4365 HandleScope scope; | 4569 HandleScope scope(isolate); |
| 4366 bool exception = false; | 4570 bool exception = false; |
| 4367 Handle<Object> converted = | 4571 Handle<Object> converted = |
| 4368 Execution::ToString(args.at<Object>(0), &exception); | 4572 Execution::ToString(args.at<Object>(0), &exception); |
| 4369 if (exception) return Failure::Exception(); | 4573 if (exception) return Failure::Exception(); |
| 4370 Handle<String> key = Handle<String>::cast(converted); | 4574 Handle<String> key = Handle<String>::cast(converted); |
| 4371 | 4575 |
| 4372 // Try to convert the string key into an array index. | 4576 // Try to convert the string key into an array index. |
| 4373 if (key->AsArrayIndex(&index)) { | 4577 if (key->AsArrayIndex(&index)) { |
| 4374 if (index < n) { | 4578 if (index < n) { |
| 4375 return frame->GetParameter(index); | 4579 return frame->GetParameter(index); |
| 4376 } else { | 4580 } else { |
| 4377 return Top::initial_object_prototype()->GetElement(index); | 4581 return isolate->initial_object_prototype()->GetElement(index); |
| 4378 } | 4582 } |
| 4379 } | 4583 } |
| 4380 | 4584 |
| 4381 // Handle special arguments properties. | 4585 // Handle special arguments properties. |
| 4382 if (key->Equals(Heap::length_symbol())) return Smi::FromInt(n); | 4586 if (key->Equals(isolate->heap()->length_symbol())) return Smi::FromInt(n); |
| 4383 if (key->Equals(Heap::callee_symbol())) { | 4587 if (key->Equals(isolate->heap()->callee_symbol())) { |
| 4384 Object* function = frame->function(); | 4588 Object* function = frame->function(); |
| 4385 if (function->IsJSFunction() && | 4589 if (function->IsJSFunction() && |
| 4386 JSFunction::cast(function)->shared()->strict_mode()) { | 4590 JSFunction::cast(function)->shared()->strict_mode()) { |
| 4387 return Top::Throw(*Factory::NewTypeError("strict_arguments_callee", | 4591 return isolate->Throw(*isolate->factory()->NewTypeError( |
| 4388 HandleVector<Object>(NULL, 0))); | 4592 "strict_arguments_callee", HandleVector<Object>(NULL, 0))); |
| 4389 } | 4593 } |
| 4390 return function; | 4594 return function; |
| 4391 } | 4595 } |
| 4392 | 4596 |
| 4393 // Lookup in the initial Object.prototype object. | 4597 // Lookup in the initial Object.prototype object. |
| 4394 return Top::initial_object_prototype()->GetProperty(*key); | 4598 return isolate->initial_object_prototype()->GetProperty(*key); |
| 4395 } | 4599 } |
| 4396 | 4600 |
| 4397 | 4601 |
| 4398 static MaybeObject* Runtime_ToFastProperties(Arguments args) { | 4602 static MaybeObject* Runtime_ToFastProperties(RUNTIME_CALLING_CONVENTION) { |
| 4399 HandleScope scope; | 4603 RUNTIME_GET_ISOLATE; |
| 4604 HandleScope scope(isolate); |
| 4400 | 4605 |
| 4401 ASSERT(args.length() == 1); | 4606 ASSERT(args.length() == 1); |
| 4402 Handle<Object> object = args.at<Object>(0); | 4607 Handle<Object> object = args.at<Object>(0); |
| 4403 if (object->IsJSObject()) { | 4608 if (object->IsJSObject()) { |
| 4404 Handle<JSObject> js_object = Handle<JSObject>::cast(object); | 4609 Handle<JSObject> js_object = Handle<JSObject>::cast(object); |
| 4405 if (!js_object->HasFastProperties() && !js_object->IsGlobalObject()) { | 4610 if (!js_object->HasFastProperties() && !js_object->IsGlobalObject()) { |
| 4406 MaybeObject* ok = js_object->TransformToFastProperties(0); | 4611 MaybeObject* ok = js_object->TransformToFastProperties(0); |
| 4407 if (ok->IsRetryAfterGC()) return ok; | 4612 if (ok->IsRetryAfterGC()) return ok; |
| 4408 } | 4613 } |
| 4409 } | 4614 } |
| 4410 return *object; | 4615 return *object; |
| 4411 } | 4616 } |
| 4412 | 4617 |
| 4413 | 4618 |
| 4414 static MaybeObject* Runtime_ToSlowProperties(Arguments args) { | 4619 static MaybeObject* Runtime_ToSlowProperties(RUNTIME_CALLING_CONVENTION) { |
| 4415 HandleScope scope; | 4620 RUNTIME_GET_ISOLATE; |
| 4621 HandleScope scope(isolate); |
| 4416 | 4622 |
| 4417 ASSERT(args.length() == 1); | 4623 ASSERT(args.length() == 1); |
| 4418 Handle<Object> object = args.at<Object>(0); | 4624 Handle<Object> object = args.at<Object>(0); |
| 4419 if (object->IsJSObject() && !object->IsJSGlobalProxy()) { | 4625 if (object->IsJSObject() && !object->IsJSGlobalProxy()) { |
| 4420 Handle<JSObject> js_object = Handle<JSObject>::cast(object); | 4626 Handle<JSObject> js_object = Handle<JSObject>::cast(object); |
| 4421 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); | 4627 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); |
| 4422 } | 4628 } |
| 4423 return *object; | 4629 return *object; |
| 4424 } | 4630 } |
| 4425 | 4631 |
| 4426 | 4632 |
| 4427 static MaybeObject* Runtime_ToBool(Arguments args) { | 4633 static MaybeObject* Runtime_ToBool(RUNTIME_CALLING_CONVENTION) { |
| 4634 RUNTIME_GET_ISOLATE; |
| 4428 NoHandleAllocation ha; | 4635 NoHandleAllocation ha; |
| 4429 ASSERT(args.length() == 1); | 4636 ASSERT(args.length() == 1); |
| 4430 | 4637 |
| 4431 return args[0]->ToBoolean(); | 4638 return args[0]->ToBoolean(); |
| 4432 } | 4639 } |
| 4433 | 4640 |
| 4434 | 4641 |
| 4435 // Returns the type string of a value; see ECMA-262, 11.4.3 (p 47). | 4642 // Returns the type string of a value; see ECMA-262, 11.4.3 (p 47). |
| 4436 // Possible optimizations: put the type string into the oddballs. | 4643 // Possible optimizations: put the type string into the oddballs. |
| 4437 static MaybeObject* Runtime_Typeof(Arguments args) { | 4644 static MaybeObject* Runtime_Typeof(RUNTIME_CALLING_CONVENTION) { |
| 4645 RUNTIME_GET_ISOLATE; |
| 4438 NoHandleAllocation ha; | 4646 NoHandleAllocation ha; |
| 4439 | 4647 |
| 4440 Object* obj = args[0]; | 4648 Object* obj = args[0]; |
| 4441 if (obj->IsNumber()) return Heap::number_symbol(); | 4649 if (obj->IsNumber()) return isolate->heap()->number_symbol(); |
| 4442 HeapObject* heap_obj = HeapObject::cast(obj); | 4650 HeapObject* heap_obj = HeapObject::cast(obj); |
| 4443 | 4651 |
| 4444 // typeof an undetectable object is 'undefined' | 4652 // typeof an undetectable object is 'undefined' |
| 4445 if (heap_obj->map()->is_undetectable()) return Heap::undefined_symbol(); | 4653 if (heap_obj->map()->is_undetectable()) { |
| 4654 return isolate->heap()->undefined_symbol(); |
| 4655 } |
| 4446 | 4656 |
| 4447 InstanceType instance_type = heap_obj->map()->instance_type(); | 4657 InstanceType instance_type = heap_obj->map()->instance_type(); |
| 4448 if (instance_type < FIRST_NONSTRING_TYPE) { | 4658 if (instance_type < FIRST_NONSTRING_TYPE) { |
| 4449 return Heap::string_symbol(); | 4659 return isolate->heap()->string_symbol(); |
| 4450 } | 4660 } |
| 4451 | 4661 |
| 4452 switch (instance_type) { | 4662 switch (instance_type) { |
| 4453 case ODDBALL_TYPE: | 4663 case ODDBALL_TYPE: |
| 4454 if (heap_obj->IsTrue() || heap_obj->IsFalse()) { | 4664 if (heap_obj->IsTrue() || heap_obj->IsFalse()) { |
| 4455 return Heap::boolean_symbol(); | 4665 return isolate->heap()->boolean_symbol(); |
| 4456 } | 4666 } |
| 4457 if (heap_obj->IsNull()) { | 4667 if (heap_obj->IsNull()) { |
| 4458 return Heap::object_symbol(); | 4668 return isolate->heap()->object_symbol(); |
| 4459 } | 4669 } |
| 4460 ASSERT(heap_obj->IsUndefined()); | 4670 ASSERT(heap_obj->IsUndefined()); |
| 4461 return Heap::undefined_symbol(); | 4671 return isolate->heap()->undefined_symbol(); |
| 4462 case JS_FUNCTION_TYPE: case JS_REGEXP_TYPE: | 4672 case JS_FUNCTION_TYPE: case JS_REGEXP_TYPE: |
| 4463 return Heap::function_symbol(); | 4673 return isolate->heap()->function_symbol(); |
| 4464 default: | 4674 default: |
| 4465 // For any kind of object not handled above, the spec rule for | 4675 // For any kind of object not handled above, the spec rule for |
| 4466 // host objects gives that it is okay to return "object" | 4676 // host objects gives that it is okay to return "object" |
| 4467 return Heap::object_symbol(); | 4677 return isolate->heap()->object_symbol(); |
| 4468 } | 4678 } |
| 4469 } | 4679 } |
| 4470 | 4680 |
| 4471 | 4681 |
| 4472 static bool AreDigits(const char*s, int from, int to) { | 4682 static bool AreDigits(const char*s, int from, int to) { |
| 4473 for (int i = from; i < to; i++) { | 4683 for (int i = from; i < to; i++) { |
| 4474 if (s[i] < '0' || s[i] > '9') return false; | 4684 if (s[i] < '0' || s[i] > '9') return false; |
| 4475 } | 4685 } |
| 4476 | 4686 |
| 4477 return true; | 4687 return true; |
| 4478 } | 4688 } |
| 4479 | 4689 |
| 4480 | 4690 |
| 4481 static int ParseDecimalInteger(const char*s, int from, int to) { | 4691 static int ParseDecimalInteger(const char*s, int from, int to) { |
| 4482 ASSERT(to - from < 10); // Overflow is not possible. | 4692 ASSERT(to - from < 10); // Overflow is not possible. |
| 4483 ASSERT(from < to); | 4693 ASSERT(from < to); |
| 4484 int d = s[from] - '0'; | 4694 int d = s[from] - '0'; |
| 4485 | 4695 |
| 4486 for (int i = from + 1; i < to; i++) { | 4696 for (int i = from + 1; i < to; i++) { |
| 4487 d = 10 * d + (s[i] - '0'); | 4697 d = 10 * d + (s[i] - '0'); |
| 4488 } | 4698 } |
| 4489 | 4699 |
| 4490 return d; | 4700 return d; |
| 4491 } | 4701 } |
| 4492 | 4702 |
| 4493 | 4703 |
| 4494 static MaybeObject* Runtime_StringToNumber(Arguments args) { | 4704 static MaybeObject* Runtime_StringToNumber(RUNTIME_CALLING_CONVENTION) { |
| 4705 RUNTIME_GET_ISOLATE; |
| 4495 NoHandleAllocation ha; | 4706 NoHandleAllocation ha; |
| 4496 ASSERT(args.length() == 1); | 4707 ASSERT(args.length() == 1); |
| 4497 CONVERT_CHECKED(String, subject, args[0]); | 4708 CONVERT_CHECKED(String, subject, args[0]); |
| 4498 subject->TryFlatten(); | 4709 subject->TryFlatten(); |
| 4499 | 4710 |
| 4500 // Fast case: short integer or some sorts of junk values. | 4711 // Fast case: short integer or some sorts of junk values. |
| 4501 int len = subject->length(); | 4712 int len = subject->length(); |
| 4502 if (subject->IsSeqAsciiString()) { | 4713 if (subject->IsSeqAsciiString()) { |
| 4503 if (len == 0) return Smi::FromInt(0); | 4714 if (len == 0) return Smi::FromInt(0); |
| 4504 | 4715 |
| 4505 char const* data = SeqAsciiString::cast(subject)->GetChars(); | 4716 char const* data = SeqAsciiString::cast(subject)->GetChars(); |
| 4506 bool minus = (data[0] == '-'); | 4717 bool minus = (data[0] == '-'); |
| 4507 int start_pos = (minus ? 1 : 0); | 4718 int start_pos = (minus ? 1 : 0); |
| 4508 | 4719 |
| 4509 if (start_pos == len) { | 4720 if (start_pos == len) { |
| 4510 return Heap::nan_value(); | 4721 return isolate->heap()->nan_value(); |
| 4511 } else if (data[start_pos] > '9') { | 4722 } else if (data[start_pos] > '9') { |
| 4512 // Fast check for a junk value. A valid string may start from a | 4723 // Fast check for a junk value. A valid string may start from a |
| 4513 // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit or | 4724 // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit or |
| 4514 // the 'I' character ('Infinity'). All of that have codes not greater than | 4725 // the 'I' character ('Infinity'). All of that have codes not greater than |
| 4515 // '9' except 'I'. | 4726 // '9' except 'I'. |
| 4516 if (data[start_pos] != 'I') { | 4727 if (data[start_pos] != 'I') { |
| 4517 return Heap::nan_value(); | 4728 return isolate->heap()->nan_value(); |
| 4518 } | 4729 } |
| 4519 } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) { | 4730 } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) { |
| 4520 // The maximal/minimal smi has 10 digits. If the string has less digits we | 4731 // The maximal/minimal smi has 10 digits. If the string has less digits we |
| 4521 // know it will fit into the smi-data type. | 4732 // know it will fit into the smi-data type. |
| 4522 int d = ParseDecimalInteger(data, start_pos, len); | 4733 int d = ParseDecimalInteger(data, start_pos, len); |
| 4523 if (minus) { | 4734 if (minus) { |
| 4524 if (d == 0) return Heap::minus_zero_value(); | 4735 if (d == 0) return isolate->heap()->minus_zero_value(); |
| 4525 d = -d; | 4736 d = -d; |
| 4526 } else if (!subject->HasHashCode() && | 4737 } else if (!subject->HasHashCode() && |
| 4527 len <= String::kMaxArrayIndexSize && | 4738 len <= String::kMaxArrayIndexSize && |
| 4528 (len == 1 || data[0] != '0')) { | 4739 (len == 1 || data[0] != '0')) { |
| 4529 // String hash is not calculated yet but all the data are present. | 4740 // String hash is not calculated yet but all the data are present. |
| 4530 // Update the hash field to speed up sequential convertions. | 4741 // Update the hash field to speed up sequential convertions. |
| 4531 uint32_t hash = StringHasher::MakeArrayIndexHash(d, len); | 4742 uint32_t hash = StringHasher::MakeArrayIndexHash(d, len); |
| 4532 #ifdef DEBUG | 4743 #ifdef DEBUG |
| 4533 subject->Hash(); // Force hash calculation. | 4744 subject->Hash(); // Force hash calculation. |
| 4534 ASSERT_EQ(static_cast<int>(subject->hash_field()), | 4745 ASSERT_EQ(static_cast<int>(subject->hash_field()), |
| 4535 static_cast<int>(hash)); | 4746 static_cast<int>(hash)); |
| 4536 #endif | 4747 #endif |
| 4537 subject->set_hash_field(hash); | 4748 subject->set_hash_field(hash); |
| 4538 } | 4749 } |
| 4539 return Smi::FromInt(d); | 4750 return Smi::FromInt(d); |
| 4540 } | 4751 } |
| 4541 } | 4752 } |
| 4542 | 4753 |
| 4543 // Slower case. | 4754 // Slower case. |
| 4544 return Heap::NumberFromDouble(StringToDouble(subject, ALLOW_HEX)); | 4755 return isolate->heap()->NumberFromDouble(StringToDouble(subject, ALLOW_HEX)); |
| 4545 } | 4756 } |
| 4546 | 4757 |
| 4547 | 4758 |
| 4548 static MaybeObject* Runtime_StringFromCharCodeArray(Arguments args) { | 4759 static MaybeObject* Runtime_StringFromCharCodeArray( |
| 4760 RUNTIME_CALLING_CONVENTION) { |
| 4761 RUNTIME_GET_ISOLATE; |
| 4549 NoHandleAllocation ha; | 4762 NoHandleAllocation ha; |
| 4550 ASSERT(args.length() == 1); | 4763 ASSERT(args.length() == 1); |
| 4551 | 4764 |
| 4552 CONVERT_CHECKED(JSArray, codes, args[0]); | 4765 CONVERT_CHECKED(JSArray, codes, args[0]); |
| 4553 int length = Smi::cast(codes->length())->value(); | 4766 int length = Smi::cast(codes->length())->value(); |
| 4554 | 4767 |
| 4555 // Check if the string can be ASCII. | 4768 // Check if the string can be ASCII. |
| 4556 int i; | 4769 int i; |
| 4557 for (i = 0; i < length; i++) { | 4770 for (i = 0; i < length; i++) { |
| 4558 Object* element; | 4771 Object* element; |
| 4559 { MaybeObject* maybe_element = codes->GetElement(i); | 4772 { MaybeObject* maybe_element = codes->GetElement(i); |
| 4560 // We probably can't get an exception here, but just in order to enforce | 4773 // We probably can't get an exception here, but just in order to enforce |
| 4561 // the checking of inputs in the runtime calls we check here. | 4774 // the checking of inputs in the runtime calls we check here. |
| 4562 if (!maybe_element->ToObject(&element)) return maybe_element; | 4775 if (!maybe_element->ToObject(&element)) return maybe_element; |
| 4563 } | 4776 } |
| 4564 CONVERT_NUMBER_CHECKED(int, chr, Int32, element); | 4777 CONVERT_NUMBER_CHECKED(int, chr, Int32, element); |
| 4565 if ((chr & 0xffff) > String::kMaxAsciiCharCode) | 4778 if ((chr & 0xffff) > String::kMaxAsciiCharCode) |
| 4566 break; | 4779 break; |
| 4567 } | 4780 } |
| 4568 | 4781 |
| 4569 MaybeObject* maybe_object = NULL; | 4782 MaybeObject* maybe_object = NULL; |
| 4570 if (i == length) { // The string is ASCII. | 4783 if (i == length) { // The string is ASCII. |
| 4571 maybe_object = Heap::AllocateRawAsciiString(length); | 4784 maybe_object = isolate->heap()->AllocateRawAsciiString(length); |
| 4572 } else { // The string is not ASCII. | 4785 } else { // The string is not ASCII. |
| 4573 maybe_object = Heap::AllocateRawTwoByteString(length); | 4786 maybe_object = isolate->heap()->AllocateRawTwoByteString(length); |
| 4574 } | 4787 } |
| 4575 | 4788 |
| 4576 Object* object = NULL; | 4789 Object* object = NULL; |
| 4577 if (!maybe_object->ToObject(&object)) return maybe_object; | 4790 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 4578 String* result = String::cast(object); | 4791 String* result = String::cast(object); |
| 4579 for (int i = 0; i < length; i++) { | 4792 for (int i = 0; i < length; i++) { |
| 4580 Object* element; | 4793 Object* element; |
| 4581 { MaybeObject* maybe_element = codes->GetElement(i); | 4794 { MaybeObject* maybe_element = codes->GetElement(i); |
| 4582 if (!maybe_element->ToObject(&element)) return maybe_element; | 4795 if (!maybe_element->ToObject(&element)) return maybe_element; |
| 4583 } | 4796 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4618 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 4831 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 4619 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 4832 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 4620 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 4833 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 4621 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 4834 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 4622 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 4835 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 4623 }; | 4836 }; |
| 4624 return kNotEscaped[character] != 0; | 4837 return kNotEscaped[character] != 0; |
| 4625 } | 4838 } |
| 4626 | 4839 |
| 4627 | 4840 |
| 4628 static MaybeObject* Runtime_URIEscape(Arguments args) { | 4841 static MaybeObject* Runtime_URIEscape(RUNTIME_CALLING_CONVENTION) { |
| 4842 RUNTIME_GET_ISOLATE; |
| 4629 const char hex_chars[] = "0123456789ABCDEF"; | 4843 const char hex_chars[] = "0123456789ABCDEF"; |
| 4630 NoHandleAllocation ha; | 4844 NoHandleAllocation ha; |
| 4631 ASSERT(args.length() == 1); | 4845 ASSERT(args.length() == 1); |
| 4632 CONVERT_CHECKED(String, source, args[0]); | 4846 CONVERT_CHECKED(String, source, args[0]); |
| 4633 | 4847 |
| 4634 source->TryFlatten(); | 4848 source->TryFlatten(); |
| 4635 | 4849 |
| 4636 int escaped_length = 0; | 4850 int escaped_length = 0; |
| 4637 int length = source->length(); | 4851 int length = source->length(); |
| 4638 { | 4852 { |
| 4639 Access<StringInputBuffer> buffer(&runtime_string_input_buffer); | 4853 Access<StringInputBuffer> buffer( |
| 4854 isolate->runtime_state()->string_input_buffer()); |
| 4640 buffer->Reset(source); | 4855 buffer->Reset(source); |
| 4641 while (buffer->has_more()) { | 4856 while (buffer->has_more()) { |
| 4642 uint16_t character = buffer->GetNext(); | 4857 uint16_t character = buffer->GetNext(); |
| 4643 if (character >= 256) { | 4858 if (character >= 256) { |
| 4644 escaped_length += 6; | 4859 escaped_length += 6; |
| 4645 } else if (IsNotEscaped(character)) { | 4860 } else if (IsNotEscaped(character)) { |
| 4646 escaped_length++; | 4861 escaped_length++; |
| 4647 } else { | 4862 } else { |
| 4648 escaped_length += 3; | 4863 escaped_length += 3; |
| 4649 } | 4864 } |
| 4650 // We don't allow strings that are longer than a maximal length. | 4865 // We don't allow strings that are longer than a maximal length. |
| 4651 ASSERT(String::kMaxLength < 0x7fffffff - 6); // Cannot overflow. | 4866 ASSERT(String::kMaxLength < 0x7fffffff - 6); // Cannot overflow. |
| 4652 if (escaped_length > String::kMaxLength) { | 4867 if (escaped_length > String::kMaxLength) { |
| 4653 Top::context()->mark_out_of_memory(); | 4868 isolate->context()->mark_out_of_memory(); |
| 4654 return Failure::OutOfMemoryException(); | 4869 return Failure::OutOfMemoryException(); |
| 4655 } | 4870 } |
| 4656 } | 4871 } |
| 4657 } | 4872 } |
| 4658 // No length change implies no change. Return original string if no change. | 4873 // No length change implies no change. Return original string if no change. |
| 4659 if (escaped_length == length) { | 4874 if (escaped_length == length) { |
| 4660 return source; | 4875 return source; |
| 4661 } | 4876 } |
| 4662 Object* o; | 4877 Object* o; |
| 4663 { MaybeObject* maybe_o = Heap::AllocateRawAsciiString(escaped_length); | 4878 { MaybeObject* maybe_o = |
| 4879 isolate->heap()->AllocateRawAsciiString(escaped_length); |
| 4664 if (!maybe_o->ToObject(&o)) return maybe_o; | 4880 if (!maybe_o->ToObject(&o)) return maybe_o; |
| 4665 } | 4881 } |
| 4666 String* destination = String::cast(o); | 4882 String* destination = String::cast(o); |
| 4667 int dest_position = 0; | 4883 int dest_position = 0; |
| 4668 | 4884 |
| 4669 Access<StringInputBuffer> buffer(&runtime_string_input_buffer); | 4885 Access<StringInputBuffer> buffer( |
| 4886 isolate->runtime_state()->string_input_buffer()); |
| 4670 buffer->Rewind(); | 4887 buffer->Rewind(); |
| 4671 while (buffer->has_more()) { | 4888 while (buffer->has_more()) { |
| 4672 uint16_t chr = buffer->GetNext(); | 4889 uint16_t chr = buffer->GetNext(); |
| 4673 if (chr >= 256) { | 4890 if (chr >= 256) { |
| 4674 destination->Set(dest_position, '%'); | 4891 destination->Set(dest_position, '%'); |
| 4675 destination->Set(dest_position+1, 'u'); | 4892 destination->Set(dest_position+1, 'u'); |
| 4676 destination->Set(dest_position+2, hex_chars[chr >> 12]); | 4893 destination->Set(dest_position+2, hex_chars[chr >> 12]); |
| 4677 destination->Set(dest_position+3, hex_chars[(chr >> 8) & 0xf]); | 4894 destination->Set(dest_position+3, hex_chars[(chr >> 8) & 0xf]); |
| 4678 destination->Set(dest_position+4, hex_chars[(chr >> 4) & 0xf]); | 4895 destination->Set(dest_position+4, hex_chars[(chr >> 4) & 0xf]); |
| 4679 destination->Set(dest_position+5, hex_chars[chr & 0xf]); | 4896 destination->Set(dest_position+5, hex_chars[chr & 0xf]); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4734 source->Get(i + 2))) != -1) { | 4951 source->Get(i + 2))) != -1) { |
| 4735 *step = 3; | 4952 *step = 3; |
| 4736 return lo; | 4953 return lo; |
| 4737 } else { | 4954 } else { |
| 4738 *step = 1; | 4955 *step = 1; |
| 4739 return character; | 4956 return character; |
| 4740 } | 4957 } |
| 4741 } | 4958 } |
| 4742 | 4959 |
| 4743 | 4960 |
| 4744 static MaybeObject* Runtime_URIUnescape(Arguments args) { | 4961 static MaybeObject* Runtime_URIUnescape(RUNTIME_CALLING_CONVENTION) { |
| 4962 RUNTIME_GET_ISOLATE; |
| 4745 NoHandleAllocation ha; | 4963 NoHandleAllocation ha; |
| 4746 ASSERT(args.length() == 1); | 4964 ASSERT(args.length() == 1); |
| 4747 CONVERT_CHECKED(String, source, args[0]); | 4965 CONVERT_CHECKED(String, source, args[0]); |
| 4748 | 4966 |
| 4749 source->TryFlatten(); | 4967 source->TryFlatten(); |
| 4750 | 4968 |
| 4751 bool ascii = true; | 4969 bool ascii = true; |
| 4752 int length = source->length(); | 4970 int length = source->length(); |
| 4753 | 4971 |
| 4754 int unescaped_length = 0; | 4972 int unescaped_length = 0; |
| 4755 for (int i = 0; i < length; unescaped_length++) { | 4973 for (int i = 0; i < length; unescaped_length++) { |
| 4756 int step; | 4974 int step; |
| 4757 if (Unescape(source, i, length, &step) > String::kMaxAsciiCharCode) { | 4975 if (Unescape(source, i, length, &step) > String::kMaxAsciiCharCode) { |
| 4758 ascii = false; | 4976 ascii = false; |
| 4759 } | 4977 } |
| 4760 i += step; | 4978 i += step; |
| 4761 } | 4979 } |
| 4762 | 4980 |
| 4763 // No length change implies no change. Return original string if no change. | 4981 // No length change implies no change. Return original string if no change. |
| 4764 if (unescaped_length == length) | 4982 if (unescaped_length == length) |
| 4765 return source; | 4983 return source; |
| 4766 | 4984 |
| 4767 Object* o; | 4985 Object* o; |
| 4768 { MaybeObject* maybe_o = ascii ? | 4986 { MaybeObject* maybe_o = |
| 4769 Heap::AllocateRawAsciiString(unescaped_length) : | 4987 ascii ? |
| 4770 Heap::AllocateRawTwoByteString(unescaped_length); | 4988 isolate->heap()->AllocateRawAsciiString(unescaped_length) : |
| 4989 isolate->heap()->AllocateRawTwoByteString(unescaped_length); |
| 4771 if (!maybe_o->ToObject(&o)) return maybe_o; | 4990 if (!maybe_o->ToObject(&o)) return maybe_o; |
| 4772 } | 4991 } |
| 4773 String* destination = String::cast(o); | 4992 String* destination = String::cast(o); |
| 4774 | 4993 |
| 4775 int dest_position = 0; | 4994 int dest_position = 0; |
| 4776 for (int i = 0; i < length; dest_position++) { | 4995 for (int i = 0; i < length; dest_position++) { |
| 4777 int step; | 4996 int step; |
| 4778 destination->Set(dest_position, Unescape(source, i, length, &step)); | 4997 destination->Set(dest_position, Unescape(source, i, length, &step)); |
| 4779 i += step; | 4998 i += step; |
| 4780 } | 4999 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4850 1, 1, 1, 1, 1, 1, 1, 1, | 5069 1, 1, 1, 1, 1, 1, 1, 1, |
| 4851 }; | 5070 }; |
| 4852 | 5071 |
| 4853 | 5072 |
| 4854 template <typename StringType> | 5073 template <typename StringType> |
| 4855 MaybeObject* AllocateRawString(int length); | 5074 MaybeObject* AllocateRawString(int length); |
| 4856 | 5075 |
| 4857 | 5076 |
| 4858 template <> | 5077 template <> |
| 4859 MaybeObject* AllocateRawString<SeqTwoByteString>(int length) { | 5078 MaybeObject* AllocateRawString<SeqTwoByteString>(int length) { |
| 4860 return Heap::AllocateRawTwoByteString(length); | 5079 return HEAP->AllocateRawTwoByteString(length); |
| 4861 } | 5080 } |
| 4862 | 5081 |
| 4863 | 5082 |
| 4864 template <> | 5083 template <> |
| 4865 MaybeObject* AllocateRawString<SeqAsciiString>(int length) { | 5084 MaybeObject* AllocateRawString<SeqAsciiString>(int length) { |
| 4866 return Heap::AllocateRawAsciiString(length); | 5085 return HEAP->AllocateRawAsciiString(length); |
| 4867 } | 5086 } |
| 4868 | 5087 |
| 4869 | 5088 |
| 4870 template <typename Char, typename StringType, bool comma> | 5089 template <typename Char, typename StringType, bool comma> |
| 4871 static MaybeObject* SlowQuoteJsonString(Vector<const Char> characters) { | 5090 static MaybeObject* SlowQuoteJsonString(Vector<const Char> characters) { |
| 4872 int length = characters.length(); | 5091 int length = characters.length(); |
| 4873 const Char* read_cursor = characters.start(); | 5092 const Char* read_cursor = characters.start(); |
| 4874 const Char* end = read_cursor + length; | 5093 const Char* end = read_cursor + length; |
| 4875 const int kSpaceForQuotes = 2 + (comma ? 1 :0); | 5094 const int kSpaceForQuotes = 2 + (comma ? 1 :0); |
| 4876 int quoted_length = kSpaceForQuotes; | 5095 int quoted_length = kSpaceForQuotes; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4909 } | 5128 } |
| 4910 } | 5129 } |
| 4911 *(write_cursor++) = '"'; | 5130 *(write_cursor++) = '"'; |
| 4912 return new_string; | 5131 return new_string; |
| 4913 } | 5132 } |
| 4914 | 5133 |
| 4915 | 5134 |
| 4916 template <typename Char, typename StringType, bool comma> | 5135 template <typename Char, typename StringType, bool comma> |
| 4917 static MaybeObject* QuoteJsonString(Vector<const Char> characters) { | 5136 static MaybeObject* QuoteJsonString(Vector<const Char> characters) { |
| 4918 int length = characters.length(); | 5137 int length = characters.length(); |
| 4919 Counters::quote_json_char_count.Increment(length); | 5138 COUNTERS->quote_json_char_count()->Increment(length); |
| 4920 const int kSpaceForQuotes = 2 + (comma ? 1 :0); | 5139 const int kSpaceForQuotes = 2 + (comma ? 1 :0); |
| 4921 int worst_case_length = length * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes; | 5140 int worst_case_length = length * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes; |
| 4922 if (worst_case_length > kMaxGuaranteedNewSpaceString) { | 5141 if (worst_case_length > kMaxGuaranteedNewSpaceString) { |
| 4923 return SlowQuoteJsonString<Char, StringType, comma>(characters); | 5142 return SlowQuoteJsonString<Char, StringType, comma>(characters); |
| 4924 } | 5143 } |
| 4925 | 5144 |
| 4926 MaybeObject* new_alloc = AllocateRawString<StringType>(worst_case_length); | 5145 MaybeObject* new_alloc = AllocateRawString<StringType>(worst_case_length); |
| 4927 Object* new_object; | 5146 Object* new_object; |
| 4928 if (!new_alloc->ToObject(&new_object)) { | 5147 if (!new_alloc->ToObject(&new_object)) { |
| 4929 return new_alloc; | 5148 return new_alloc; |
| 4930 } | 5149 } |
| 4931 if (!Heap::new_space()->Contains(new_object)) { | 5150 if (!HEAP->new_space()->Contains(new_object)) { |
| 4932 // Even if our string is small enough to fit in new space we still have to | 5151 // Even if our string is small enough to fit in new space we still have to |
| 4933 // handle it being allocated in old space as may happen in the third | 5152 // handle it being allocated in old space as may happen in the third |
| 4934 // attempt. See CALL_AND_RETRY in heap-inl.h and similar code in | 5153 // attempt. See CALL_AND_RETRY in heap-inl.h and similar code in |
| 4935 // CEntryStub::GenerateCore. | 5154 // CEntryStub::GenerateCore. |
| 4936 return SlowQuoteJsonString<Char, StringType, comma>(characters); | 5155 return SlowQuoteJsonString<Char, StringType, comma>(characters); |
| 4937 } | 5156 } |
| 4938 StringType* new_string = StringType::cast(new_object); | 5157 StringType* new_string = StringType::cast(new_object); |
| 4939 ASSERT(Heap::new_space()->Contains(new_string)); | 5158 ASSERT(HEAP->new_space()->Contains(new_string)); |
| 4940 | 5159 |
| 4941 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize); | 5160 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize); |
| 4942 Char* write_cursor = reinterpret_cast<Char*>( | 5161 Char* write_cursor = reinterpret_cast<Char*>( |
| 4943 new_string->address() + SeqAsciiString::kHeaderSize); | 5162 new_string->address() + SeqAsciiString::kHeaderSize); |
| 4944 if (comma) *(write_cursor++) = ','; | 5163 if (comma) *(write_cursor++) = ','; |
| 4945 *(write_cursor++) = '"'; | 5164 *(write_cursor++) = '"'; |
| 4946 | 5165 |
| 4947 const Char* read_cursor = characters.start(); | 5166 const Char* read_cursor = characters.start(); |
| 4948 const Char* end = read_cursor + length; | 5167 const Char* end = read_cursor + length; |
| 4949 while (read_cursor < end) { | 5168 while (read_cursor < end) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 4966 } | 5185 } |
| 4967 } | 5186 } |
| 4968 write_cursor += len; | 5187 write_cursor += len; |
| 4969 } | 5188 } |
| 4970 } | 5189 } |
| 4971 *(write_cursor++) = '"'; | 5190 *(write_cursor++) = '"'; |
| 4972 | 5191 |
| 4973 int final_length = static_cast<int>( | 5192 int final_length = static_cast<int>( |
| 4974 write_cursor - reinterpret_cast<Char*>( | 5193 write_cursor - reinterpret_cast<Char*>( |
| 4975 new_string->address() + SeqAsciiString::kHeaderSize)); | 5194 new_string->address() + SeqAsciiString::kHeaderSize)); |
| 4976 Heap::new_space()->ShrinkStringAtAllocationBoundary<StringType>(new_string, | 5195 HEAP->new_space()->ShrinkStringAtAllocationBoundary<StringType>(new_string, |
| 4977 final_length); | 5196 final_length); |
| 4978 return new_string; | 5197 return new_string; |
| 4979 } | 5198 } |
| 4980 | 5199 |
| 4981 | 5200 |
| 4982 static MaybeObject* Runtime_QuoteJSONString(Arguments args) { | 5201 static MaybeObject* Runtime_QuoteJSONString(RUNTIME_CALLING_CONVENTION) { |
| 5202 RUNTIME_GET_ISOLATE; |
| 4983 NoHandleAllocation ha; | 5203 NoHandleAllocation ha; |
| 4984 CONVERT_CHECKED(String, str, args[0]); | 5204 CONVERT_CHECKED(String, str, args[0]); |
| 4985 if (!str->IsFlat()) { | 5205 if (!str->IsFlat()) { |
| 4986 MaybeObject* try_flatten = str->TryFlatten(); | 5206 MaybeObject* try_flatten = str->TryFlatten(); |
| 4987 Object* flat; | 5207 Object* flat; |
| 4988 if (!try_flatten->ToObject(&flat)) { | 5208 if (!try_flatten->ToObject(&flat)) { |
| 4989 return try_flatten; | 5209 return try_flatten; |
| 4990 } | 5210 } |
| 4991 str = String::cast(flat); | 5211 str = String::cast(flat); |
| 4992 ASSERT(str->IsFlat()); | 5212 ASSERT(str->IsFlat()); |
| 4993 } | 5213 } |
| 4994 if (str->IsTwoByteRepresentation()) { | 5214 if (str->IsTwoByteRepresentation()) { |
| 4995 return QuoteJsonString<uc16, SeqTwoByteString, false>(str->ToUC16Vector()); | 5215 return QuoteJsonString<uc16, SeqTwoByteString, false>(str->ToUC16Vector()); |
| 4996 } else { | 5216 } else { |
| 4997 return QuoteJsonString<char, SeqAsciiString, false>(str->ToAsciiVector()); | 5217 return QuoteJsonString<char, SeqAsciiString, false>(str->ToAsciiVector()); |
| 4998 } | 5218 } |
| 4999 } | 5219 } |
| 5000 | 5220 |
| 5001 | 5221 |
| 5002 static MaybeObject* Runtime_QuoteJSONStringComma(Arguments args) { | 5222 static MaybeObject* Runtime_QuoteJSONStringComma(RUNTIME_CALLING_CONVENTION) { |
| 5223 RUNTIME_GET_ISOLATE; |
| 5003 NoHandleAllocation ha; | 5224 NoHandleAllocation ha; |
| 5004 CONVERT_CHECKED(String, str, args[0]); | 5225 CONVERT_CHECKED(String, str, args[0]); |
| 5005 if (!str->IsFlat()) { | 5226 if (!str->IsFlat()) { |
| 5006 MaybeObject* try_flatten = str->TryFlatten(); | 5227 MaybeObject* try_flatten = str->TryFlatten(); |
| 5007 Object* flat; | 5228 Object* flat; |
| 5008 if (!try_flatten->ToObject(&flat)) { | 5229 if (!try_flatten->ToObject(&flat)) { |
| 5009 return try_flatten; | 5230 return try_flatten; |
| 5010 } | 5231 } |
| 5011 str = String::cast(flat); | 5232 str = String::cast(flat); |
| 5012 ASSERT(str->IsFlat()); | 5233 ASSERT(str->IsFlat()); |
| 5013 } | 5234 } |
| 5014 if (str->IsTwoByteRepresentation()) { | 5235 if (str->IsTwoByteRepresentation()) { |
| 5015 return QuoteJsonString<uc16, SeqTwoByteString, true>(str->ToUC16Vector()); | 5236 return QuoteJsonString<uc16, SeqTwoByteString, true>(str->ToUC16Vector()); |
| 5016 } else { | 5237 } else { |
| 5017 return QuoteJsonString<char, SeqAsciiString, true>(str->ToAsciiVector()); | 5238 return QuoteJsonString<char, SeqAsciiString, true>(str->ToAsciiVector()); |
| 5018 } | 5239 } |
| 5019 } | 5240 } |
| 5020 | 5241 |
| 5021 | 5242 static MaybeObject* Runtime_StringParseInt(RUNTIME_CALLING_CONVENTION) { |
| 5022 static MaybeObject* Runtime_StringParseInt(Arguments args) { | 5243 RUNTIME_GET_ISOLATE; |
| 5023 NoHandleAllocation ha; | 5244 NoHandleAllocation ha; |
| 5024 | 5245 |
| 5025 CONVERT_CHECKED(String, s, args[0]); | 5246 CONVERT_CHECKED(String, s, args[0]); |
| 5026 CONVERT_SMI_CHECKED(radix, args[1]); | 5247 CONVERT_SMI_CHECKED(radix, args[1]); |
| 5027 | 5248 |
| 5028 s->TryFlatten(); | 5249 s->TryFlatten(); |
| 5029 | 5250 |
| 5030 RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36)); | 5251 RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36)); |
| 5031 double value = StringToInt(s, radix); | 5252 double value = StringToInt(s, radix); |
| 5032 return Heap::NumberFromDouble(value); | 5253 return isolate->heap()->NumberFromDouble(value); |
| 5033 } | 5254 } |
| 5034 | 5255 |
| 5035 | 5256 |
| 5036 static MaybeObject* Runtime_StringParseFloat(Arguments args) { | 5257 static MaybeObject* Runtime_StringParseFloat(RUNTIME_CALLING_CONVENTION) { |
| 5258 RUNTIME_GET_ISOLATE; |
| 5037 NoHandleAllocation ha; | 5259 NoHandleAllocation ha; |
| 5038 CONVERT_CHECKED(String, str, args[0]); | 5260 CONVERT_CHECKED(String, str, args[0]); |
| 5039 | 5261 |
| 5040 // ECMA-262 section 15.1.2.3, empty string is NaN | 5262 // ECMA-262 section 15.1.2.3, empty string is NaN |
| 5041 double value = StringToDouble(str, ALLOW_TRAILING_JUNK, OS::nan_value()); | 5263 double value = StringToDouble(str, ALLOW_TRAILING_JUNK, OS::nan_value()); |
| 5042 | 5264 |
| 5043 // Create a number object from the value. | 5265 // Create a number object from the value. |
| 5044 return Heap::NumberFromDouble(value); | 5266 return isolate->heap()->NumberFromDouble(value); |
| 5045 } | 5267 } |
| 5046 | 5268 |
| 5047 | 5269 |
| 5048 static unibrow::Mapping<unibrow::ToUppercase, 128> to_upper_mapping; | |
| 5049 static unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping; | |
| 5050 | |
| 5051 | |
| 5052 template <class Converter> | 5270 template <class Converter> |
| 5053 MUST_USE_RESULT static MaybeObject* ConvertCaseHelper( | 5271 MUST_USE_RESULT static MaybeObject* ConvertCaseHelper( |
| 5272 Isolate* isolate, |
| 5054 String* s, | 5273 String* s, |
| 5055 int length, | 5274 int length, |
| 5056 int input_string_length, | 5275 int input_string_length, |
| 5057 unibrow::Mapping<Converter, 128>* mapping) { | 5276 unibrow::Mapping<Converter, 128>* mapping) { |
| 5058 // We try this twice, once with the assumption that the result is no longer | 5277 // We try this twice, once with the assumption that the result is no longer |
| 5059 // than the input and, if that assumption breaks, again with the exact | 5278 // than the input and, if that assumption breaks, again with the exact |
| 5060 // length. This may not be pretty, but it is nicer than what was here before | 5279 // length. This may not be pretty, but it is nicer than what was here before |
| 5061 // and I hereby claim my vaffel-is. | 5280 // and I hereby claim my vaffel-is. |
| 5062 // | 5281 // |
| 5063 // Allocate the resulting string. | 5282 // Allocate the resulting string. |
| 5064 // | 5283 // |
| 5065 // NOTE: This assumes that the upper/lower case of an ascii | 5284 // NOTE: This assumes that the upper/lower case of an ascii |
| 5066 // character is also ascii. This is currently the case, but it | 5285 // character is also ascii. This is currently the case, but it |
| 5067 // might break in the future if we implement more context and locale | 5286 // might break in the future if we implement more context and locale |
| 5068 // dependent upper/lower conversions. | 5287 // dependent upper/lower conversions. |
| 5069 Object* o; | 5288 Object* o; |
| 5070 { MaybeObject* maybe_o = s->IsAsciiRepresentation() | 5289 { MaybeObject* maybe_o = s->IsAsciiRepresentation() |
| 5071 ? Heap::AllocateRawAsciiString(length) | 5290 ? isolate->heap()->AllocateRawAsciiString(length) |
| 5072 : Heap::AllocateRawTwoByteString(length); | 5291 : isolate->heap()->AllocateRawTwoByteString(length); |
| 5073 if (!maybe_o->ToObject(&o)) return maybe_o; | 5292 if (!maybe_o->ToObject(&o)) return maybe_o; |
| 5074 } | 5293 } |
| 5075 String* result = String::cast(o); | 5294 String* result = String::cast(o); |
| 5076 bool has_changed_character = false; | 5295 bool has_changed_character = false; |
| 5077 | 5296 |
| 5078 // Convert all characters to upper case, assuming that they will fit | 5297 // Convert all characters to upper case, assuming that they will fit |
| 5079 // in the buffer | 5298 // in the buffer |
| 5080 Access<StringInputBuffer> buffer(&runtime_string_input_buffer); | 5299 Access<StringInputBuffer> buffer( |
| 5300 isolate->runtime_state()->string_input_buffer()); |
| 5081 buffer->Reset(s); | 5301 buffer->Reset(s); |
| 5082 unibrow::uchar chars[Converter::kMaxWidth]; | 5302 unibrow::uchar chars[Converter::kMaxWidth]; |
| 5083 // We can assume that the string is not empty | 5303 // We can assume that the string is not empty |
| 5084 uc32 current = buffer->GetNext(); | 5304 uc32 current = buffer->GetNext(); |
| 5085 for (int i = 0; i < length;) { | 5305 for (int i = 0; i < length;) { |
| 5086 bool has_next = buffer->has_more(); | 5306 bool has_next = buffer->has_more(); |
| 5087 uc32 next = has_next ? buffer->GetNext() : 0; | 5307 uc32 next = has_next ? buffer->GetNext() : 0; |
| 5088 int char_length = mapping->get(current, next, chars); | 5308 int char_length = mapping->get(current, next, chars); |
| 5089 if (char_length == 0) { | 5309 if (char_length == 0) { |
| 5090 // The case conversion of this character is the character itself. | 5310 // The case conversion of this character is the character itself. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 5117 while (buffer->has_more()) { | 5337 while (buffer->has_more()) { |
| 5118 current = buffer->GetNext(); | 5338 current = buffer->GetNext(); |
| 5119 // NOTE: we use 0 as the next character here because, while | 5339 // NOTE: we use 0 as the next character here because, while |
| 5120 // the next character may affect what a character converts to, | 5340 // the next character may affect what a character converts to, |
| 5121 // it does not in any case affect the length of what it convert | 5341 // it does not in any case affect the length of what it convert |
| 5122 // to. | 5342 // to. |
| 5123 int char_length = mapping->get(current, 0, chars); | 5343 int char_length = mapping->get(current, 0, chars); |
| 5124 if (char_length == 0) char_length = 1; | 5344 if (char_length == 0) char_length = 1; |
| 5125 current_length += char_length; | 5345 current_length += char_length; |
| 5126 if (current_length > Smi::kMaxValue) { | 5346 if (current_length > Smi::kMaxValue) { |
| 5127 Top::context()->mark_out_of_memory(); | 5347 isolate->context()->mark_out_of_memory(); |
| 5128 return Failure::OutOfMemoryException(); | 5348 return Failure::OutOfMemoryException(); |
| 5129 } | 5349 } |
| 5130 } | 5350 } |
| 5131 // Try again with the real length. | 5351 // Try again with the real length. |
| 5132 return Smi::FromInt(current_length); | 5352 return Smi::FromInt(current_length); |
| 5133 } else { | 5353 } else { |
| 5134 for (int j = 0; j < char_length; j++) { | 5354 for (int j = 0; j < char_length; j++) { |
| 5135 result->Set(i, chars[j]); | 5355 result->Set(i, chars[j]); |
| 5136 i++; | 5356 i++; |
| 5137 } | 5357 } |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5275 | 5495 |
| 5276 typedef FastAsciiConverter<ASCII_TO_UPPER> AsciiConverter; | 5496 typedef FastAsciiConverter<ASCII_TO_UPPER> AsciiConverter; |
| 5277 }; | 5497 }; |
| 5278 | 5498 |
| 5279 } // namespace | 5499 } // namespace |
| 5280 | 5500 |
| 5281 | 5501 |
| 5282 template <typename ConvertTraits> | 5502 template <typename ConvertTraits> |
| 5283 MUST_USE_RESULT static MaybeObject* ConvertCase( | 5503 MUST_USE_RESULT static MaybeObject* ConvertCase( |
| 5284 Arguments args, | 5504 Arguments args, |
| 5505 Isolate* isolate, |
| 5285 unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) { | 5506 unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) { |
| 5286 NoHandleAllocation ha; | 5507 NoHandleAllocation ha; |
| 5287 CONVERT_CHECKED(String, s, args[0]); | 5508 CONVERT_CHECKED(String, s, args[0]); |
| 5288 s = s->TryFlattenGetString(); | 5509 s = s->TryFlattenGetString(); |
| 5289 | 5510 |
| 5290 const int length = s->length(); | 5511 const int length = s->length(); |
| 5291 // Assume that the string is not empty; we need this assumption later | 5512 // Assume that the string is not empty; we need this assumption later |
| 5292 if (length == 0) return s; | 5513 if (length == 0) return s; |
| 5293 | 5514 |
| 5294 // Simpler handling of ascii strings. | 5515 // Simpler handling of ascii strings. |
| 5295 // | 5516 // |
| 5296 // NOTE: This assumes that the upper/lower case of an ascii | 5517 // NOTE: This assumes that the upper/lower case of an ascii |
| 5297 // character is also ascii. This is currently the case, but it | 5518 // character is also ascii. This is currently the case, but it |
| 5298 // might break in the future if we implement more context and locale | 5519 // might break in the future if we implement more context and locale |
| 5299 // dependent upper/lower conversions. | 5520 // dependent upper/lower conversions. |
| 5300 if (s->IsSeqAsciiString()) { | 5521 if (s->IsSeqAsciiString()) { |
| 5301 Object* o; | 5522 Object* o; |
| 5302 { MaybeObject* maybe_o = Heap::AllocateRawAsciiString(length); | 5523 { MaybeObject* maybe_o = isolate->heap()->AllocateRawAsciiString(length); |
| 5303 if (!maybe_o->ToObject(&o)) return maybe_o; | 5524 if (!maybe_o->ToObject(&o)) return maybe_o; |
| 5304 } | 5525 } |
| 5305 SeqAsciiString* result = SeqAsciiString::cast(o); | 5526 SeqAsciiString* result = SeqAsciiString::cast(o); |
| 5306 bool has_changed_character = ConvertTraits::AsciiConverter::Convert( | 5527 bool has_changed_character = ConvertTraits::AsciiConverter::Convert( |
| 5307 result->GetChars(), SeqAsciiString::cast(s)->GetChars(), length); | 5528 result->GetChars(), SeqAsciiString::cast(s)->GetChars(), length); |
| 5308 return has_changed_character ? result : s; | 5529 return has_changed_character ? result : s; |
| 5309 } | 5530 } |
| 5310 | 5531 |
| 5311 Object* answer; | 5532 Object* answer; |
| 5312 { MaybeObject* maybe_answer = ConvertCaseHelper(s, length, length, mapping); | 5533 { MaybeObject* maybe_answer = |
| 5534 ConvertCaseHelper(isolate, s, length, length, mapping); |
| 5313 if (!maybe_answer->ToObject(&answer)) return maybe_answer; | 5535 if (!maybe_answer->ToObject(&answer)) return maybe_answer; |
| 5314 } | 5536 } |
| 5315 if (answer->IsSmi()) { | 5537 if (answer->IsSmi()) { |
| 5316 // Retry with correct length. | 5538 // Retry with correct length. |
| 5317 { MaybeObject* maybe_answer = | 5539 { MaybeObject* maybe_answer = |
| 5318 ConvertCaseHelper(s, Smi::cast(answer)->value(), length, mapping); | 5540 ConvertCaseHelper(isolate, |
| 5541 s, Smi::cast(answer)->value(), length, mapping); |
| 5319 if (!maybe_answer->ToObject(&answer)) return maybe_answer; | 5542 if (!maybe_answer->ToObject(&answer)) return maybe_answer; |
| 5320 } | 5543 } |
| 5321 } | 5544 } |
| 5322 return answer; | 5545 return answer; |
| 5323 } | 5546 } |
| 5324 | 5547 |
| 5325 | 5548 |
| 5326 static MaybeObject* Runtime_StringToLowerCase(Arguments args) { | 5549 static MaybeObject* Runtime_StringToLowerCase(RUNTIME_CALLING_CONVENTION) { |
| 5327 return ConvertCase<ToLowerTraits>(args, &to_lower_mapping); | 5550 RUNTIME_GET_ISOLATE; |
| 5551 return ConvertCase<ToLowerTraits>( |
| 5552 args, isolate, isolate->runtime_state()->to_lower_mapping()); |
| 5328 } | 5553 } |
| 5329 | 5554 |
| 5330 | 5555 |
| 5331 static MaybeObject* Runtime_StringToUpperCase(Arguments args) { | 5556 static MaybeObject* Runtime_StringToUpperCase(RUNTIME_CALLING_CONVENTION) { |
| 5332 return ConvertCase<ToUpperTraits>(args, &to_upper_mapping); | 5557 RUNTIME_GET_ISOLATE; |
| 5558 return ConvertCase<ToUpperTraits>( |
| 5559 args, isolate, isolate->runtime_state()->to_upper_mapping()); |
| 5333 } | 5560 } |
| 5334 | 5561 |
| 5335 | 5562 |
| 5336 static inline bool IsTrimWhiteSpace(unibrow::uchar c) { | 5563 static inline bool IsTrimWhiteSpace(unibrow::uchar c) { |
| 5337 return unibrow::WhiteSpace::Is(c) || c == 0x200b; | 5564 return unibrow::WhiteSpace::Is(c) || c == 0x200b; |
| 5338 } | 5565 } |
| 5339 | 5566 |
| 5340 | 5567 |
| 5341 static MaybeObject* Runtime_StringTrim(Arguments args) { | 5568 static MaybeObject* Runtime_StringTrim(RUNTIME_CALLING_CONVENTION) { |
| 5569 RUNTIME_GET_ISOLATE; |
| 5342 NoHandleAllocation ha; | 5570 NoHandleAllocation ha; |
| 5343 ASSERT(args.length() == 3); | 5571 ASSERT(args.length() == 3); |
| 5344 | 5572 |
| 5345 CONVERT_CHECKED(String, s, args[0]); | 5573 CONVERT_CHECKED(String, s, args[0]); |
| 5346 CONVERT_BOOLEAN_CHECKED(trimLeft, args[1]); | 5574 CONVERT_BOOLEAN_CHECKED(trimLeft, args[1]); |
| 5347 CONVERT_BOOLEAN_CHECKED(trimRight, args[2]); | 5575 CONVERT_BOOLEAN_CHECKED(trimRight, args[2]); |
| 5348 | 5576 |
| 5349 s->TryFlatten(); | 5577 s->TryFlatten(); |
| 5350 int length = s->length(); | 5578 int length = s->length(); |
| 5351 | 5579 |
| 5352 int left = 0; | 5580 int left = 0; |
| 5353 if (trimLeft) { | 5581 if (trimLeft) { |
| 5354 while (left < length && IsTrimWhiteSpace(s->Get(left))) { | 5582 while (left < length && IsTrimWhiteSpace(s->Get(left))) { |
| 5355 left++; | 5583 left++; |
| 5356 } | 5584 } |
| 5357 } | 5585 } |
| 5358 | 5586 |
| 5359 int right = length; | 5587 int right = length; |
| 5360 if (trimRight) { | 5588 if (trimRight) { |
| 5361 while (right > left && IsTrimWhiteSpace(s->Get(right - 1))) { | 5589 while (right > left && IsTrimWhiteSpace(s->Get(right - 1))) { |
| 5362 right--; | 5590 right--; |
| 5363 } | 5591 } |
| 5364 } | 5592 } |
| 5365 return s->SubString(left, right); | 5593 return s->SubString(left, right); |
| 5366 } | 5594 } |
| 5367 | 5595 |
| 5368 | 5596 |
| 5369 template <typename SubjectChar, typename PatternChar> | 5597 template <typename SubjectChar, typename PatternChar> |
| 5370 void FindStringIndices(Vector<const SubjectChar> subject, | 5598 void FindStringIndices(Isolate* isolate, |
| 5599 Vector<const SubjectChar> subject, |
| 5371 Vector<const PatternChar> pattern, | 5600 Vector<const PatternChar> pattern, |
| 5372 ZoneList<int>* indices, | 5601 ZoneList<int>* indices, |
| 5373 unsigned int limit) { | 5602 unsigned int limit) { |
| 5374 ASSERT(limit > 0); | 5603 ASSERT(limit > 0); |
| 5375 // Collect indices of pattern in subject, and the end-of-string index. | 5604 // Collect indices of pattern in subject, and the end-of-string index. |
| 5376 // Stop after finding at most limit values. | 5605 // Stop after finding at most limit values. |
| 5377 StringSearch<PatternChar, SubjectChar> search(pattern); | 5606 StringSearch<PatternChar, SubjectChar> search(isolate, pattern); |
| 5378 int pattern_length = pattern.length(); | 5607 int pattern_length = pattern.length(); |
| 5379 int index = 0; | 5608 int index = 0; |
| 5380 while (limit > 0) { | 5609 while (limit > 0) { |
| 5381 index = search.Search(subject, index); | 5610 index = search.Search(subject, index); |
| 5382 if (index < 0) return; | 5611 if (index < 0) return; |
| 5383 indices->Add(index); | 5612 indices->Add(index); |
| 5384 index += pattern_length; | 5613 index += pattern_length; |
| 5385 limit--; | 5614 limit--; |
| 5386 } | 5615 } |
| 5387 } | 5616 } |
| 5388 | 5617 |
| 5389 | 5618 |
| 5390 static MaybeObject* Runtime_StringSplit(Arguments args) { | 5619 static MaybeObject* Runtime_StringSplit(RUNTIME_CALLING_CONVENTION) { |
| 5620 RUNTIME_GET_ISOLATE; |
| 5391 ASSERT(args.length() == 3); | 5621 ASSERT(args.length() == 3); |
| 5392 HandleScope handle_scope; | 5622 HandleScope handle_scope(isolate); |
| 5393 CONVERT_ARG_CHECKED(String, subject, 0); | 5623 CONVERT_ARG_CHECKED(String, subject, 0); |
| 5394 CONVERT_ARG_CHECKED(String, pattern, 1); | 5624 CONVERT_ARG_CHECKED(String, pattern, 1); |
| 5395 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]); | 5625 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]); |
| 5396 | 5626 |
| 5397 int subject_length = subject->length(); | 5627 int subject_length = subject->length(); |
| 5398 int pattern_length = pattern->length(); | 5628 int pattern_length = pattern->length(); |
| 5399 RUNTIME_ASSERT(pattern_length > 0); | 5629 RUNTIME_ASSERT(pattern_length > 0); |
| 5400 | 5630 |
| 5401 // The limit can be very large (0xffffffffu), but since the pattern | 5631 // The limit can be very large (0xffffffffu), but since the pattern |
| 5402 // isn't empty, we can never create more parts than ~half the length | 5632 // isn't empty, we can never create more parts than ~half the length |
| 5403 // of the subject. | 5633 // of the subject. |
| 5404 | 5634 |
| 5405 if (!subject->IsFlat()) FlattenString(subject); | 5635 if (!subject->IsFlat()) FlattenString(subject); |
| 5406 | 5636 |
| 5407 static const int kMaxInitialListCapacity = 16; | 5637 static const int kMaxInitialListCapacity = 16; |
| 5408 | 5638 |
| 5409 ZoneScope scope(DELETE_ON_EXIT); | 5639 ZoneScope scope(DELETE_ON_EXIT); |
| 5410 | 5640 |
| 5411 // Find (up to limit) indices of separator and end-of-string in subject | 5641 // Find (up to limit) indices of separator and end-of-string in subject |
| 5412 int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit); | 5642 int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit); |
| 5413 ZoneList<int> indices(initial_capacity); | 5643 ZoneList<int> indices(initial_capacity); |
| 5414 if (!pattern->IsFlat()) FlattenString(pattern); | 5644 if (!pattern->IsFlat()) FlattenString(pattern); |
| 5415 | 5645 |
| 5416 // No allocation block. | 5646 // No allocation block. |
| 5417 { | 5647 { |
| 5418 AssertNoAllocation nogc; | 5648 AssertNoAllocation nogc; |
| 5419 if (subject->IsAsciiRepresentation()) { | 5649 if (subject->IsAsciiRepresentation()) { |
| 5420 Vector<const char> subject_vector = subject->ToAsciiVector(); | 5650 Vector<const char> subject_vector = subject->ToAsciiVector(); |
| 5421 if (pattern->IsAsciiRepresentation()) { | 5651 if (pattern->IsAsciiRepresentation()) { |
| 5422 FindStringIndices(subject_vector, | 5652 FindStringIndices(isolate, |
| 5653 subject_vector, |
| 5423 pattern->ToAsciiVector(), | 5654 pattern->ToAsciiVector(), |
| 5424 &indices, | 5655 &indices, |
| 5425 limit); | 5656 limit); |
| 5426 } else { | 5657 } else { |
| 5427 FindStringIndices(subject_vector, | 5658 FindStringIndices(isolate, |
| 5659 subject_vector, |
| 5428 pattern->ToUC16Vector(), | 5660 pattern->ToUC16Vector(), |
| 5429 &indices, | 5661 &indices, |
| 5430 limit); | 5662 limit); |
| 5431 } | 5663 } |
| 5432 } else { | 5664 } else { |
| 5433 Vector<const uc16> subject_vector = subject->ToUC16Vector(); | 5665 Vector<const uc16> subject_vector = subject->ToUC16Vector(); |
| 5434 if (pattern->IsAsciiRepresentation()) { | 5666 if (pattern->IsAsciiRepresentation()) { |
| 5435 FindStringIndices(subject_vector, | 5667 FindStringIndices(isolate, |
| 5668 subject_vector, |
| 5436 pattern->ToAsciiVector(), | 5669 pattern->ToAsciiVector(), |
| 5437 &indices, | 5670 &indices, |
| 5438 limit); | 5671 limit); |
| 5439 } else { | 5672 } else { |
| 5440 FindStringIndices(subject_vector, | 5673 FindStringIndices(isolate, |
| 5674 subject_vector, |
| 5441 pattern->ToUC16Vector(), | 5675 pattern->ToUC16Vector(), |
| 5442 &indices, | 5676 &indices, |
| 5443 limit); | 5677 limit); |
| 5444 } | 5678 } |
| 5445 } | 5679 } |
| 5446 } | 5680 } |
| 5447 | 5681 |
| 5448 if (static_cast<uint32_t>(indices.length()) < limit) { | 5682 if (static_cast<uint32_t>(indices.length()) < limit) { |
| 5449 indices.Add(subject_length); | 5683 indices.Add(subject_length); |
| 5450 } | 5684 } |
| 5451 | 5685 |
| 5452 // The list indices now contains the end of each part to create. | 5686 // The list indices now contains the end of each part to create. |
| 5453 | 5687 |
| 5454 // Create JSArray of substrings separated by separator. | 5688 // Create JSArray of substrings separated by separator. |
| 5455 int part_count = indices.length(); | 5689 int part_count = indices.length(); |
| 5456 | 5690 |
| 5457 Handle<JSArray> result = Factory::NewJSArray(part_count); | 5691 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count); |
| 5458 result->set_length(Smi::FromInt(part_count)); | 5692 result->set_length(Smi::FromInt(part_count)); |
| 5459 | 5693 |
| 5460 ASSERT(result->HasFastElements()); | 5694 ASSERT(result->HasFastElements()); |
| 5461 | 5695 |
| 5462 if (part_count == 1 && indices.at(0) == subject_length) { | 5696 if (part_count == 1 && indices.at(0) == subject_length) { |
| 5463 FixedArray::cast(result->elements())->set(0, *subject); | 5697 FixedArray::cast(result->elements())->set(0, *subject); |
| 5464 return *result; | 5698 return *result; |
| 5465 } | 5699 } |
| 5466 | 5700 |
| 5467 Handle<FixedArray> elements(FixedArray::cast(result->elements())); | 5701 Handle<FixedArray> elements(FixedArray::cast(result->elements())); |
| 5468 int part_start = 0; | 5702 int part_start = 0; |
| 5469 for (int i = 0; i < part_count; i++) { | 5703 for (int i = 0; i < part_count; i++) { |
| 5470 HandleScope local_loop_handle; | 5704 HandleScope local_loop_handle; |
| 5471 int part_end = indices.at(i); | 5705 int part_end = indices.at(i); |
| 5472 Handle<String> substring = | 5706 Handle<String> substring = |
| 5473 Factory::NewSubString(subject, part_start, part_end); | 5707 isolate->factory()->NewSubString(subject, part_start, part_end); |
| 5474 elements->set(i, *substring); | 5708 elements->set(i, *substring); |
| 5475 part_start = part_end + pattern_length; | 5709 part_start = part_end + pattern_length; |
| 5476 } | 5710 } |
| 5477 | 5711 |
| 5478 return *result; | 5712 return *result; |
| 5479 } | 5713 } |
| 5480 | 5714 |
| 5481 | 5715 |
| 5482 // Copies ascii characters to the given fixed array looking up | 5716 // Copies ascii characters to the given fixed array looking up |
| 5483 // one-char strings in the cache. Gives up on the first char that is | 5717 // one-char strings in the cache. Gives up on the first char that is |
| 5484 // not in the cache and fills the remainder with smi zeros. Returns | 5718 // not in the cache and fills the remainder with smi zeros. Returns |
| 5485 // the length of the successfully copied prefix. | 5719 // the length of the successfully copied prefix. |
| 5486 static int CopyCachedAsciiCharsToArray(const char* chars, | 5720 static int CopyCachedAsciiCharsToArray(Heap* heap, |
| 5721 const char* chars, |
| 5487 FixedArray* elements, | 5722 FixedArray* elements, |
| 5488 int length) { | 5723 int length) { |
| 5489 AssertNoAllocation nogc; | 5724 AssertNoAllocation nogc; |
| 5490 FixedArray* ascii_cache = Heap::single_character_string_cache(); | 5725 FixedArray* ascii_cache = heap->single_character_string_cache(); |
| 5491 Object* undefined = Heap::undefined_value(); | 5726 Object* undefined = heap->undefined_value(); |
| 5492 int i; | 5727 int i; |
| 5493 for (i = 0; i < length; ++i) { | 5728 for (i = 0; i < length; ++i) { |
| 5494 Object* value = ascii_cache->get(chars[i]); | 5729 Object* value = ascii_cache->get(chars[i]); |
| 5495 if (value == undefined) break; | 5730 if (value == undefined) break; |
| 5496 ASSERT(!Heap::InNewSpace(value)); | 5731 ASSERT(!heap->InNewSpace(value)); |
| 5497 elements->set(i, value, SKIP_WRITE_BARRIER); | 5732 elements->set(i, value, SKIP_WRITE_BARRIER); |
| 5498 } | 5733 } |
| 5499 if (i < length) { | 5734 if (i < length) { |
| 5500 ASSERT(Smi::FromInt(0) == 0); | 5735 ASSERT(Smi::FromInt(0) == 0); |
| 5501 memset(elements->data_start() + i, 0, kPointerSize * (length - i)); | 5736 memset(elements->data_start() + i, 0, kPointerSize * (length - i)); |
| 5502 } | 5737 } |
| 5503 #ifdef DEBUG | 5738 #ifdef DEBUG |
| 5504 for (int j = 0; j < length; ++j) { | 5739 for (int j = 0; j < length; ++j) { |
| 5505 Object* element = elements->get(j); | 5740 Object* element = elements->get(j); |
| 5506 ASSERT(element == Smi::FromInt(0) || | 5741 ASSERT(element == Smi::FromInt(0) || |
| 5507 (element->IsString() && String::cast(element)->LooksValid())); | 5742 (element->IsString() && String::cast(element)->LooksValid())); |
| 5508 } | 5743 } |
| 5509 #endif | 5744 #endif |
| 5510 return i; | 5745 return i; |
| 5511 } | 5746 } |
| 5512 | 5747 |
| 5513 | 5748 |
| 5514 // Converts a String to JSArray. | 5749 // Converts a String to JSArray. |
| 5515 // For example, "foo" => ["f", "o", "o"]. | 5750 // For example, "foo" => ["f", "o", "o"]. |
| 5516 static MaybeObject* Runtime_StringToArray(Arguments args) { | 5751 static MaybeObject* Runtime_StringToArray(RUNTIME_CALLING_CONVENTION) { |
| 5517 HandleScope scope; | 5752 RUNTIME_GET_ISOLATE; |
| 5753 HandleScope scope(isolate); |
| 5518 ASSERT(args.length() == 2); | 5754 ASSERT(args.length() == 2); |
| 5519 CONVERT_ARG_CHECKED(String, s, 0); | 5755 CONVERT_ARG_CHECKED(String, s, 0); |
| 5520 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); | 5756 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); |
| 5521 | 5757 |
| 5522 s->TryFlatten(); | 5758 s->TryFlatten(); |
| 5523 const int length = static_cast<int>(Min<uint32_t>(s->length(), limit)); | 5759 const int length = static_cast<int>(Min<uint32_t>(s->length(), limit)); |
| 5524 | 5760 |
| 5525 Handle<FixedArray> elements; | 5761 Handle<FixedArray> elements; |
| 5526 if (s->IsFlat() && s->IsAsciiRepresentation()) { | 5762 if (s->IsFlat() && s->IsAsciiRepresentation()) { |
| 5527 Object* obj; | 5763 Object* obj; |
| 5528 { MaybeObject* maybe_obj = Heap::AllocateUninitializedFixedArray(length); | 5764 { MaybeObject* maybe_obj = |
| 5765 isolate->heap()->AllocateUninitializedFixedArray(length); |
| 5529 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 5766 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 5530 } | 5767 } |
| 5531 elements = Handle<FixedArray>(FixedArray::cast(obj)); | 5768 elements = Handle<FixedArray>(FixedArray::cast(obj), isolate); |
| 5532 | 5769 |
| 5533 Vector<const char> chars = s->ToAsciiVector(); | 5770 Vector<const char> chars = s->ToAsciiVector(); |
| 5534 // Note, this will initialize all elements (not only the prefix) | 5771 // Note, this will initialize all elements (not only the prefix) |
| 5535 // to prevent GC from seeing partially initialized array. | 5772 // to prevent GC from seeing partially initialized array. |
| 5536 int num_copied_from_cache = CopyCachedAsciiCharsToArray(chars.start(), | 5773 int num_copied_from_cache = CopyCachedAsciiCharsToArray(isolate->heap(), |
| 5774 chars.start(), |
| 5537 *elements, | 5775 *elements, |
| 5538 length); | 5776 length); |
| 5539 | 5777 |
| 5540 for (int i = num_copied_from_cache; i < length; ++i) { | 5778 for (int i = num_copied_from_cache; i < length; ++i) { |
| 5541 Handle<Object> str = LookupSingleCharacterStringFromCode(chars[i]); | 5779 Handle<Object> str = LookupSingleCharacterStringFromCode(chars[i]); |
| 5542 elements->set(i, *str); | 5780 elements->set(i, *str); |
| 5543 } | 5781 } |
| 5544 } else { | 5782 } else { |
| 5545 elements = Factory::NewFixedArray(length); | 5783 elements = isolate->factory()->NewFixedArray(length); |
| 5546 for (int i = 0; i < length; ++i) { | 5784 for (int i = 0; i < length; ++i) { |
| 5547 Handle<Object> str = LookupSingleCharacterStringFromCode(s->Get(i)); | 5785 Handle<Object> str = LookupSingleCharacterStringFromCode(s->Get(i)); |
| 5548 elements->set(i, *str); | 5786 elements->set(i, *str); |
| 5549 } | 5787 } |
| 5550 } | 5788 } |
| 5551 | 5789 |
| 5552 #ifdef DEBUG | 5790 #ifdef DEBUG |
| 5553 for (int i = 0; i < length; ++i) { | 5791 for (int i = 0; i < length; ++i) { |
| 5554 ASSERT(String::cast(elements->get(i))->length() == 1); | 5792 ASSERT(String::cast(elements->get(i))->length() == 1); |
| 5555 } | 5793 } |
| 5556 #endif | 5794 #endif |
| 5557 | 5795 |
| 5558 return *Factory::NewJSArrayWithElements(elements); | 5796 return *isolate->factory()->NewJSArrayWithElements(elements); |
| 5559 } | 5797 } |
| 5560 | 5798 |
| 5561 | 5799 |
| 5562 static MaybeObject* Runtime_NewStringWrapper(Arguments args) { | 5800 static MaybeObject* Runtime_NewStringWrapper(RUNTIME_CALLING_CONVENTION) { |
| 5801 RUNTIME_GET_ISOLATE; |
| 5563 NoHandleAllocation ha; | 5802 NoHandleAllocation ha; |
| 5564 ASSERT(args.length() == 1); | 5803 ASSERT(args.length() == 1); |
| 5565 CONVERT_CHECKED(String, value, args[0]); | 5804 CONVERT_CHECKED(String, value, args[0]); |
| 5566 return value->ToObject(); | 5805 return value->ToObject(); |
| 5567 } | 5806 } |
| 5568 | 5807 |
| 5569 | 5808 |
| 5570 bool Runtime::IsUpperCaseChar(uint16_t ch) { | 5809 bool Runtime::IsUpperCaseChar(RuntimeState* runtime_state, uint16_t ch) { |
| 5571 unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth]; | 5810 unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth]; |
| 5572 int char_length = to_upper_mapping.get(ch, 0, chars); | 5811 int char_length = runtime_state->to_upper_mapping()->get(ch, 0, chars); |
| 5573 return char_length == 0; | 5812 return char_length == 0; |
| 5574 } | 5813 } |
| 5575 | 5814 |
| 5576 | 5815 |
| 5577 static MaybeObject* Runtime_NumberToString(Arguments args) { | 5816 static MaybeObject* Runtime_NumberToString(RUNTIME_CALLING_CONVENTION) { |
| 5817 RUNTIME_GET_ISOLATE; |
| 5578 NoHandleAllocation ha; | 5818 NoHandleAllocation ha; |
| 5579 ASSERT(args.length() == 1); | 5819 ASSERT(args.length() == 1); |
| 5580 | 5820 |
| 5581 Object* number = args[0]; | 5821 Object* number = args[0]; |
| 5582 RUNTIME_ASSERT(number->IsNumber()); | 5822 RUNTIME_ASSERT(number->IsNumber()); |
| 5583 | 5823 |
| 5584 return Heap::NumberToString(number); | 5824 return isolate->heap()->NumberToString(number); |
| 5585 } | 5825 } |
| 5586 | 5826 |
| 5587 | 5827 |
| 5588 static MaybeObject* Runtime_NumberToStringSkipCache(Arguments args) { | 5828 static MaybeObject* Runtime_NumberToStringSkipCache( |
| 5829 RUNTIME_CALLING_CONVENTION) { |
| 5830 RUNTIME_GET_ISOLATE; |
| 5589 NoHandleAllocation ha; | 5831 NoHandleAllocation ha; |
| 5590 ASSERT(args.length() == 1); | 5832 ASSERT(args.length() == 1); |
| 5591 | 5833 |
| 5592 Object* number = args[0]; | 5834 Object* number = args[0]; |
| 5593 RUNTIME_ASSERT(number->IsNumber()); | 5835 RUNTIME_ASSERT(number->IsNumber()); |
| 5594 | 5836 |
| 5595 return Heap::NumberToString(number, false); | 5837 return isolate->heap()->NumberToString(number, false); |
| 5596 } | 5838 } |
| 5597 | 5839 |
| 5598 | 5840 |
| 5599 static MaybeObject* Runtime_NumberToInteger(Arguments args) { | 5841 static MaybeObject* Runtime_NumberToInteger(RUNTIME_CALLING_CONVENTION) { |
| 5842 RUNTIME_GET_ISOLATE; |
| 5600 NoHandleAllocation ha; | 5843 NoHandleAllocation ha; |
| 5601 ASSERT(args.length() == 1); | 5844 ASSERT(args.length() == 1); |
| 5602 | 5845 |
| 5603 CONVERT_DOUBLE_CHECKED(number, args[0]); | 5846 CONVERT_DOUBLE_CHECKED(number, args[0]); |
| 5604 | 5847 |
| 5605 // We do not include 0 so that we don't have to treat +0 / -0 cases. | 5848 // We do not include 0 so that we don't have to treat +0 / -0 cases. |
| 5606 if (number > 0 && number <= Smi::kMaxValue) { | 5849 if (number > 0 && number <= Smi::kMaxValue) { |
| 5607 return Smi::FromInt(static_cast<int>(number)); | 5850 return Smi::FromInt(static_cast<int>(number)); |
| 5608 } | 5851 } |
| 5609 return Heap::NumberFromDouble(DoubleToInteger(number)); | 5852 return isolate->heap()->NumberFromDouble(DoubleToInteger(number)); |
| 5610 } | 5853 } |
| 5611 | 5854 |
| 5612 | 5855 |
| 5613 static MaybeObject* Runtime_NumberToIntegerMapMinusZero(Arguments args) { | 5856 static MaybeObject* Runtime_NumberToIntegerMapMinusZero( |
| 5857 RUNTIME_CALLING_CONVENTION) { |
| 5858 RUNTIME_GET_ISOLATE; |
| 5614 NoHandleAllocation ha; | 5859 NoHandleAllocation ha; |
| 5615 ASSERT(args.length() == 1); | 5860 ASSERT(args.length() == 1); |
| 5616 | 5861 |
| 5617 CONVERT_DOUBLE_CHECKED(number, args[0]); | 5862 CONVERT_DOUBLE_CHECKED(number, args[0]); |
| 5618 | 5863 |
| 5619 // We do not include 0 so that we don't have to treat +0 / -0 cases. | 5864 // We do not include 0 so that we don't have to treat +0 / -0 cases. |
| 5620 if (number > 0 && number <= Smi::kMaxValue) { | 5865 if (number > 0 && number <= Smi::kMaxValue) { |
| 5621 return Smi::FromInt(static_cast<int>(number)); | 5866 return Smi::FromInt(static_cast<int>(number)); |
| 5622 } | 5867 } |
| 5623 | 5868 |
| 5624 double double_value = DoubleToInteger(number); | 5869 double double_value = DoubleToInteger(number); |
| 5625 // Map both -0 and +0 to +0. | 5870 // Map both -0 and +0 to +0. |
| 5626 if (double_value == 0) double_value = 0; | 5871 if (double_value == 0) double_value = 0; |
| 5627 | 5872 |
| 5628 return Heap::NumberFromDouble(double_value); | 5873 return isolate->heap()->NumberFromDouble(double_value); |
| 5629 } | 5874 } |
| 5630 | 5875 |
| 5631 | 5876 |
| 5632 static MaybeObject* Runtime_NumberToJSUint32(Arguments args) { | 5877 static MaybeObject* Runtime_NumberToJSUint32(RUNTIME_CALLING_CONVENTION) { |
| 5878 RUNTIME_GET_ISOLATE; |
| 5633 NoHandleAllocation ha; | 5879 NoHandleAllocation ha; |
| 5634 ASSERT(args.length() == 1); | 5880 ASSERT(args.length() == 1); |
| 5635 | 5881 |
| 5636 CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]); | 5882 CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]); |
| 5637 return Heap::NumberFromUint32(number); | 5883 return isolate->heap()->NumberFromUint32(number); |
| 5638 } | 5884 } |
| 5639 | 5885 |
| 5640 | 5886 |
| 5641 static MaybeObject* Runtime_NumberToJSInt32(Arguments args) { | 5887 static MaybeObject* Runtime_NumberToJSInt32(RUNTIME_CALLING_CONVENTION) { |
| 5888 RUNTIME_GET_ISOLATE; |
| 5642 NoHandleAllocation ha; | 5889 NoHandleAllocation ha; |
| 5643 ASSERT(args.length() == 1); | 5890 ASSERT(args.length() == 1); |
| 5644 | 5891 |
| 5645 CONVERT_DOUBLE_CHECKED(number, args[0]); | 5892 CONVERT_DOUBLE_CHECKED(number, args[0]); |
| 5646 | 5893 |
| 5647 // We do not include 0 so that we don't have to treat +0 / -0 cases. | 5894 // We do not include 0 so that we don't have to treat +0 / -0 cases. |
| 5648 if (number > 0 && number <= Smi::kMaxValue) { | 5895 if (number > 0 && number <= Smi::kMaxValue) { |
| 5649 return Smi::FromInt(static_cast<int>(number)); | 5896 return Smi::FromInt(static_cast<int>(number)); |
| 5650 } | 5897 } |
| 5651 return Heap::NumberFromInt32(DoubleToInt32(number)); | 5898 return isolate->heap()->NumberFromInt32(DoubleToInt32(number)); |
| 5652 } | 5899 } |
| 5653 | 5900 |
| 5654 | 5901 |
| 5655 // Converts a Number to a Smi, if possible. Returns NaN if the number is not | 5902 // Converts a Number to a Smi, if possible. Returns NaN if the number is not |
| 5656 // a small integer. | 5903 // a small integer. |
| 5657 static MaybeObject* Runtime_NumberToSmi(Arguments args) { | 5904 static MaybeObject* Runtime_NumberToSmi(RUNTIME_CALLING_CONVENTION) { |
| 5905 RUNTIME_GET_ISOLATE; |
| 5658 NoHandleAllocation ha; | 5906 NoHandleAllocation ha; |
| 5659 ASSERT(args.length() == 1); | 5907 ASSERT(args.length() == 1); |
| 5660 | 5908 |
| 5661 Object* obj = args[0]; | 5909 Object* obj = args[0]; |
| 5662 if (obj->IsSmi()) { | 5910 if (obj->IsSmi()) { |
| 5663 return obj; | 5911 return obj; |
| 5664 } | 5912 } |
| 5665 if (obj->IsHeapNumber()) { | 5913 if (obj->IsHeapNumber()) { |
| 5666 double value = HeapNumber::cast(obj)->value(); | 5914 double value = HeapNumber::cast(obj)->value(); |
| 5667 int int_value = FastD2I(value); | 5915 int int_value = FastD2I(value); |
| 5668 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) { | 5916 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) { |
| 5669 return Smi::FromInt(int_value); | 5917 return Smi::FromInt(int_value); |
| 5670 } | 5918 } |
| 5671 } | 5919 } |
| 5672 return Heap::nan_value(); | 5920 return isolate->heap()->nan_value(); |
| 5673 } | 5921 } |
| 5674 | 5922 |
| 5675 | 5923 |
| 5676 static MaybeObject* Runtime_AllocateHeapNumber(Arguments args) { | 5924 static MaybeObject* Runtime_AllocateHeapNumber(RUNTIME_CALLING_CONVENTION) { |
| 5925 RUNTIME_GET_ISOLATE; |
| 5677 NoHandleAllocation ha; | 5926 NoHandleAllocation ha; |
| 5678 ASSERT(args.length() == 0); | 5927 ASSERT(args.length() == 0); |
| 5679 return Heap::AllocateHeapNumber(0); | 5928 return isolate->heap()->AllocateHeapNumber(0); |
| 5680 } | 5929 } |
| 5681 | 5930 |
| 5682 | 5931 |
| 5683 static MaybeObject* Runtime_NumberAdd(Arguments args) { | 5932 static MaybeObject* Runtime_NumberAdd(RUNTIME_CALLING_CONVENTION) { |
| 5933 RUNTIME_GET_ISOLATE; |
| 5684 NoHandleAllocation ha; | 5934 NoHandleAllocation ha; |
| 5685 ASSERT(args.length() == 2); | 5935 ASSERT(args.length() == 2); |
| 5686 | 5936 |
| 5687 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5937 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5688 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5938 CONVERT_DOUBLE_CHECKED(y, args[1]); |
| 5689 return Heap::NumberFromDouble(x + y); | 5939 return isolate->heap()->NumberFromDouble(x + y); |
| 5690 } | 5940 } |
| 5691 | 5941 |
| 5692 | 5942 |
| 5693 static MaybeObject* Runtime_NumberSub(Arguments args) { | 5943 static MaybeObject* Runtime_NumberSub(RUNTIME_CALLING_CONVENTION) { |
| 5944 RUNTIME_GET_ISOLATE; |
| 5694 NoHandleAllocation ha; | 5945 NoHandleAllocation ha; |
| 5695 ASSERT(args.length() == 2); | 5946 ASSERT(args.length() == 2); |
| 5696 | 5947 |
| 5697 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5948 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5698 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5949 CONVERT_DOUBLE_CHECKED(y, args[1]); |
| 5699 return Heap::NumberFromDouble(x - y); | 5950 return isolate->heap()->NumberFromDouble(x - y); |
| 5700 } | 5951 } |
| 5701 | 5952 |
| 5702 | 5953 |
| 5703 static MaybeObject* Runtime_NumberMul(Arguments args) { | 5954 static MaybeObject* Runtime_NumberMul(RUNTIME_CALLING_CONVENTION) { |
| 5955 RUNTIME_GET_ISOLATE; |
| 5704 NoHandleAllocation ha; | 5956 NoHandleAllocation ha; |
| 5705 ASSERT(args.length() == 2); | 5957 ASSERT(args.length() == 2); |
| 5706 | 5958 |
| 5707 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5959 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5708 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5960 CONVERT_DOUBLE_CHECKED(y, args[1]); |
| 5709 return Heap::NumberFromDouble(x * y); | 5961 return isolate->heap()->NumberFromDouble(x * y); |
| 5710 } | 5962 } |
| 5711 | 5963 |
| 5712 | 5964 |
| 5713 static MaybeObject* Runtime_NumberUnaryMinus(Arguments args) { | 5965 static MaybeObject* Runtime_NumberUnaryMinus(RUNTIME_CALLING_CONVENTION) { |
| 5966 RUNTIME_GET_ISOLATE; |
| 5714 NoHandleAllocation ha; | 5967 NoHandleAllocation ha; |
| 5715 ASSERT(args.length() == 1); | 5968 ASSERT(args.length() == 1); |
| 5716 | 5969 |
| 5717 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5970 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5718 return Heap::NumberFromDouble(-x); | 5971 return isolate->heap()->NumberFromDouble(-x); |
| 5719 } | 5972 } |
| 5720 | 5973 |
| 5721 | 5974 |
| 5722 static MaybeObject* Runtime_NumberAlloc(Arguments args) { | 5975 static MaybeObject* Runtime_NumberAlloc(RUNTIME_CALLING_CONVENTION) { |
| 5976 RUNTIME_GET_ISOLATE; |
| 5723 NoHandleAllocation ha; | 5977 NoHandleAllocation ha; |
| 5724 ASSERT(args.length() == 0); | 5978 ASSERT(args.length() == 0); |
| 5725 | 5979 |
| 5726 return Heap::NumberFromDouble(9876543210.0); | 5980 return isolate->heap()->NumberFromDouble(9876543210.0); |
| 5727 } | 5981 } |
| 5728 | 5982 |
| 5729 | 5983 |
| 5730 static MaybeObject* Runtime_NumberDiv(Arguments args) { | 5984 static MaybeObject* Runtime_NumberDiv(RUNTIME_CALLING_CONVENTION) { |
| 5985 RUNTIME_GET_ISOLATE; |
| 5731 NoHandleAllocation ha; | 5986 NoHandleAllocation ha; |
| 5732 ASSERT(args.length() == 2); | 5987 ASSERT(args.length() == 2); |
| 5733 | 5988 |
| 5734 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5989 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5735 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5990 CONVERT_DOUBLE_CHECKED(y, args[1]); |
| 5736 return Heap::NumberFromDouble(x / y); | 5991 return isolate->heap()->NumberFromDouble(x / y); |
| 5737 } | 5992 } |
| 5738 | 5993 |
| 5739 | 5994 |
| 5740 static MaybeObject* Runtime_NumberMod(Arguments args) { | 5995 static MaybeObject* Runtime_NumberMod(RUNTIME_CALLING_CONVENTION) { |
| 5996 RUNTIME_GET_ISOLATE; |
| 5741 NoHandleAllocation ha; | 5997 NoHandleAllocation ha; |
| 5742 ASSERT(args.length() == 2); | 5998 ASSERT(args.length() == 2); |
| 5743 | 5999 |
| 5744 CONVERT_DOUBLE_CHECKED(x, args[0]); | 6000 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5745 CONVERT_DOUBLE_CHECKED(y, args[1]); | 6001 CONVERT_DOUBLE_CHECKED(y, args[1]); |
| 5746 | 6002 |
| 5747 x = modulo(x, y); | 6003 x = modulo(x, y); |
| 5748 // NumberFromDouble may return a Smi instead of a Number object | 6004 // NumberFromDouble may return a Smi instead of a Number object |
| 5749 return Heap::NumberFromDouble(x); | 6005 return isolate->heap()->NumberFromDouble(x); |
| 5750 } | 6006 } |
| 5751 | 6007 |
| 5752 | 6008 |
| 5753 static MaybeObject* Runtime_StringAdd(Arguments args) { | 6009 static MaybeObject* Runtime_StringAdd(RUNTIME_CALLING_CONVENTION) { |
| 6010 RUNTIME_GET_ISOLATE; |
| 5754 NoHandleAllocation ha; | 6011 NoHandleAllocation ha; |
| 5755 ASSERT(args.length() == 2); | 6012 ASSERT(args.length() == 2); |
| 5756 CONVERT_CHECKED(String, str1, args[0]); | 6013 CONVERT_CHECKED(String, str1, args[0]); |
| 5757 CONVERT_CHECKED(String, str2, args[1]); | 6014 CONVERT_CHECKED(String, str2, args[1]); |
| 5758 Counters::string_add_runtime.Increment(); | 6015 isolate->counters()->string_add_runtime()->Increment(); |
| 5759 return Heap::AllocateConsString(str1, str2); | 6016 return isolate->heap()->AllocateConsString(str1, str2); |
| 5760 } | 6017 } |
| 5761 | 6018 |
| 5762 | 6019 |
| 5763 template <typename sinkchar> | 6020 template <typename sinkchar> |
| 5764 static inline void StringBuilderConcatHelper(String* special, | 6021 static inline void StringBuilderConcatHelper(String* special, |
| 5765 sinkchar* sink, | 6022 sinkchar* sink, |
| 5766 FixedArray* fixed_array, | 6023 FixedArray* fixed_array, |
| 5767 int array_length) { | 6024 int array_length) { |
| 5768 int position = 0; | 6025 int position = 0; |
| 5769 for (int i = 0; i < array_length; i++) { | 6026 for (int i = 0; i < array_length; i++) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 5792 } else { | 6049 } else { |
| 5793 String* string = String::cast(element); | 6050 String* string = String::cast(element); |
| 5794 int element_length = string->length(); | 6051 int element_length = string->length(); |
| 5795 String::WriteToFlat(string, sink + position, 0, element_length); | 6052 String::WriteToFlat(string, sink + position, 0, element_length); |
| 5796 position += element_length; | 6053 position += element_length; |
| 5797 } | 6054 } |
| 5798 } | 6055 } |
| 5799 } | 6056 } |
| 5800 | 6057 |
| 5801 | 6058 |
| 5802 static MaybeObject* Runtime_StringBuilderConcat(Arguments args) { | 6059 static MaybeObject* Runtime_StringBuilderConcat(RUNTIME_CALLING_CONVENTION) { |
| 6060 RUNTIME_GET_ISOLATE; |
| 5803 NoHandleAllocation ha; | 6061 NoHandleAllocation ha; |
| 5804 ASSERT(args.length() == 3); | 6062 ASSERT(args.length() == 3); |
| 5805 CONVERT_CHECKED(JSArray, array, args[0]); | 6063 CONVERT_CHECKED(JSArray, array, args[0]); |
| 5806 if (!args[1]->IsSmi()) { | 6064 if (!args[1]->IsSmi()) { |
| 5807 Top::context()->mark_out_of_memory(); | 6065 isolate->context()->mark_out_of_memory(); |
| 5808 return Failure::OutOfMemoryException(); | 6066 return Failure::OutOfMemoryException(); |
| 5809 } | 6067 } |
| 5810 int array_length = Smi::cast(args[1])->value(); | 6068 int array_length = Smi::cast(args[1])->value(); |
| 5811 CONVERT_CHECKED(String, special, args[2]); | 6069 CONVERT_CHECKED(String, special, args[2]); |
| 5812 | 6070 |
| 5813 // This assumption is used by the slice encoding in one or two smis. | 6071 // This assumption is used by the slice encoding in one or two smis. |
| 5814 ASSERT(Smi::kMaxValue >= String::kMaxLength); | 6072 ASSERT(Smi::kMaxValue >= String::kMaxLength); |
| 5815 | 6073 |
| 5816 int special_length = special->length(); | 6074 int special_length = special->length(); |
| 5817 if (!array->HasFastElements()) { | 6075 if (!array->HasFastElements()) { |
| 5818 return Top::Throw(Heap::illegal_argument_symbol()); | 6076 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
| 5819 } | 6077 } |
| 5820 FixedArray* fixed_array = FixedArray::cast(array->elements()); | 6078 FixedArray* fixed_array = FixedArray::cast(array->elements()); |
| 5821 if (fixed_array->length() < array_length) { | 6079 if (fixed_array->length() < array_length) { |
| 5822 array_length = fixed_array->length(); | 6080 array_length = fixed_array->length(); |
| 5823 } | 6081 } |
| 5824 | 6082 |
| 5825 if (array_length == 0) { | 6083 if (array_length == 0) { |
| 5826 return Heap::empty_string(); | 6084 return isolate->heap()->empty_string(); |
| 5827 } else if (array_length == 1) { | 6085 } else if (array_length == 1) { |
| 5828 Object* first = fixed_array->get(0); | 6086 Object* first = fixed_array->get(0); |
| 5829 if (first->IsString()) return first; | 6087 if (first->IsString()) return first; |
| 5830 } | 6088 } |
| 5831 | 6089 |
| 5832 bool ascii = special->HasOnlyAsciiChars(); | 6090 bool ascii = special->HasOnlyAsciiChars(); |
| 5833 int position = 0; | 6091 int position = 0; |
| 5834 for (int i = 0; i < array_length; i++) { | 6092 for (int i = 0; i < array_length; i++) { |
| 5835 int increment = 0; | 6093 int increment = 0; |
| 5836 Object* elt = fixed_array->get(i); | 6094 Object* elt = fixed_array->get(i); |
| 5837 if (elt->IsSmi()) { | 6095 if (elt->IsSmi()) { |
| 5838 // Smi encoding of position and length. | 6096 // Smi encoding of position and length. |
| 5839 int smi_value = Smi::cast(elt)->value(); | 6097 int smi_value = Smi::cast(elt)->value(); |
| 5840 int pos; | 6098 int pos; |
| 5841 int len; | 6099 int len; |
| 5842 if (smi_value > 0) { | 6100 if (smi_value > 0) { |
| 5843 // Position and length encoded in one smi. | 6101 // Position and length encoded in one smi. |
| 5844 pos = StringBuilderSubstringPosition::decode(smi_value); | 6102 pos = StringBuilderSubstringPosition::decode(smi_value); |
| 5845 len = StringBuilderSubstringLength::decode(smi_value); | 6103 len = StringBuilderSubstringLength::decode(smi_value); |
| 5846 } else { | 6104 } else { |
| 5847 // Position and length encoded in two smis. | 6105 // Position and length encoded in two smis. |
| 5848 len = -smi_value; | 6106 len = -smi_value; |
| 5849 // Get the position and check that it is a positive smi. | 6107 // Get the position and check that it is a positive smi. |
| 5850 i++; | 6108 i++; |
| 5851 if (i >= array_length) { | 6109 if (i >= array_length) { |
| 5852 return Top::Throw(Heap::illegal_argument_symbol()); | 6110 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
| 5853 } | 6111 } |
| 5854 Object* next_smi = fixed_array->get(i); | 6112 Object* next_smi = fixed_array->get(i); |
| 5855 if (!next_smi->IsSmi()) { | 6113 if (!next_smi->IsSmi()) { |
| 5856 return Top::Throw(Heap::illegal_argument_symbol()); | 6114 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
| 5857 } | 6115 } |
| 5858 pos = Smi::cast(next_smi)->value(); | 6116 pos = Smi::cast(next_smi)->value(); |
| 5859 if (pos < 0) { | 6117 if (pos < 0) { |
| 5860 return Top::Throw(Heap::illegal_argument_symbol()); | 6118 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
| 5861 } | 6119 } |
| 5862 } | 6120 } |
| 5863 ASSERT(pos >= 0); | 6121 ASSERT(pos >= 0); |
| 5864 ASSERT(len >= 0); | 6122 ASSERT(len >= 0); |
| 5865 if (pos > special_length || len > special_length - pos) { | 6123 if (pos > special_length || len > special_length - pos) { |
| 5866 return Top::Throw(Heap::illegal_argument_symbol()); | 6124 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
| 5867 } | 6125 } |
| 5868 increment = len; | 6126 increment = len; |
| 5869 } else if (elt->IsString()) { | 6127 } else if (elt->IsString()) { |
| 5870 String* element = String::cast(elt); | 6128 String* element = String::cast(elt); |
| 5871 int element_length = element->length(); | 6129 int element_length = element->length(); |
| 5872 increment = element_length; | 6130 increment = element_length; |
| 5873 if (ascii && !element->HasOnlyAsciiChars()) { | 6131 if (ascii && !element->HasOnlyAsciiChars()) { |
| 5874 ascii = false; | 6132 ascii = false; |
| 5875 } | 6133 } |
| 5876 } else { | 6134 } else { |
| 5877 return Top::Throw(Heap::illegal_argument_symbol()); | 6135 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
| 5878 } | 6136 } |
| 5879 if (increment > String::kMaxLength - position) { | 6137 if (increment > String::kMaxLength - position) { |
| 5880 Top::context()->mark_out_of_memory(); | 6138 isolate->context()->mark_out_of_memory(); |
| 5881 return Failure::OutOfMemoryException(); | 6139 return Failure::OutOfMemoryException(); |
| 5882 } | 6140 } |
| 5883 position += increment; | 6141 position += increment; |
| 5884 } | 6142 } |
| 5885 | 6143 |
| 5886 int length = position; | 6144 int length = position; |
| 5887 Object* object; | 6145 Object* object; |
| 5888 | 6146 |
| 5889 if (ascii) { | 6147 if (ascii) { |
| 5890 { MaybeObject* maybe_object = Heap::AllocateRawAsciiString(length); | 6148 { MaybeObject* maybe_object = |
| 6149 isolate->heap()->AllocateRawAsciiString(length); |
| 5891 if (!maybe_object->ToObject(&object)) return maybe_object; | 6150 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 5892 } | 6151 } |
| 5893 SeqAsciiString* answer = SeqAsciiString::cast(object); | 6152 SeqAsciiString* answer = SeqAsciiString::cast(object); |
| 5894 StringBuilderConcatHelper(special, | 6153 StringBuilderConcatHelper(special, |
| 5895 answer->GetChars(), | 6154 answer->GetChars(), |
| 5896 fixed_array, | 6155 fixed_array, |
| 5897 array_length); | 6156 array_length); |
| 5898 return answer; | 6157 return answer; |
| 5899 } else { | 6158 } else { |
| 5900 { MaybeObject* maybe_object = Heap::AllocateRawTwoByteString(length); | 6159 { MaybeObject* maybe_object = |
| 6160 isolate->heap()->AllocateRawTwoByteString(length); |
| 5901 if (!maybe_object->ToObject(&object)) return maybe_object; | 6161 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 5902 } | 6162 } |
| 5903 SeqTwoByteString* answer = SeqTwoByteString::cast(object); | 6163 SeqTwoByteString* answer = SeqTwoByteString::cast(object); |
| 5904 StringBuilderConcatHelper(special, | 6164 StringBuilderConcatHelper(special, |
| 5905 answer->GetChars(), | 6165 answer->GetChars(), |
| 5906 fixed_array, | 6166 fixed_array, |
| 5907 array_length); | 6167 array_length); |
| 5908 return answer; | 6168 return answer; |
| 5909 } | 6169 } |
| 5910 } | 6170 } |
| 5911 | 6171 |
| 5912 | 6172 |
| 5913 static MaybeObject* Runtime_StringBuilderJoin(Arguments args) { | 6173 static MaybeObject* Runtime_StringBuilderJoin(RUNTIME_CALLING_CONVENTION) { |
| 6174 RUNTIME_GET_ISOLATE; |
| 5914 NoHandleAllocation ha; | 6175 NoHandleAllocation ha; |
| 5915 ASSERT(args.length() == 3); | 6176 ASSERT(args.length() == 3); |
| 5916 CONVERT_CHECKED(JSArray, array, args[0]); | 6177 CONVERT_CHECKED(JSArray, array, args[0]); |
| 5917 if (!args[1]->IsSmi()) { | 6178 if (!args[1]->IsSmi()) { |
| 5918 Top::context()->mark_out_of_memory(); | 6179 isolate->context()->mark_out_of_memory(); |
| 5919 return Failure::OutOfMemoryException(); | 6180 return Failure::OutOfMemoryException(); |
| 5920 } | 6181 } |
| 5921 int array_length = Smi::cast(args[1])->value(); | 6182 int array_length = Smi::cast(args[1])->value(); |
| 5922 CONVERT_CHECKED(String, separator, args[2]); | 6183 CONVERT_CHECKED(String, separator, args[2]); |
| 5923 | 6184 |
| 5924 if (!array->HasFastElements()) { | 6185 if (!array->HasFastElements()) { |
| 5925 return Top::Throw(Heap::illegal_argument_symbol()); | 6186 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
| 5926 } | 6187 } |
| 5927 FixedArray* fixed_array = FixedArray::cast(array->elements()); | 6188 FixedArray* fixed_array = FixedArray::cast(array->elements()); |
| 5928 if (fixed_array->length() < array_length) { | 6189 if (fixed_array->length() < array_length) { |
| 5929 array_length = fixed_array->length(); | 6190 array_length = fixed_array->length(); |
| 5930 } | 6191 } |
| 5931 | 6192 |
| 5932 if (array_length == 0) { | 6193 if (array_length == 0) { |
| 5933 return Heap::empty_string(); | 6194 return isolate->heap()->empty_string(); |
| 5934 } else if (array_length == 1) { | 6195 } else if (array_length == 1) { |
| 5935 Object* first = fixed_array->get(0); | 6196 Object* first = fixed_array->get(0); |
| 5936 if (first->IsString()) return first; | 6197 if (first->IsString()) return first; |
| 5937 } | 6198 } |
| 5938 | 6199 |
| 5939 int separator_length = separator->length(); | 6200 int separator_length = separator->length(); |
| 5940 int max_nof_separators = | 6201 int max_nof_separators = |
| 5941 (String::kMaxLength + separator_length - 1) / separator_length; | 6202 (String::kMaxLength + separator_length - 1) / separator_length; |
| 5942 if (max_nof_separators < (array_length - 1)) { | 6203 if (max_nof_separators < (array_length - 1)) { |
| 5943 Top::context()->mark_out_of_memory(); | 6204 isolate->context()->mark_out_of_memory(); |
| 5944 return Failure::OutOfMemoryException(); | 6205 return Failure::OutOfMemoryException(); |
| 5945 } | 6206 } |
| 5946 int length = (array_length - 1) * separator_length; | 6207 int length = (array_length - 1) * separator_length; |
| 5947 for (int i = 0; i < array_length; i++) { | 6208 for (int i = 0; i < array_length; i++) { |
| 5948 Object* element_obj = fixed_array->get(i); | 6209 Object* element_obj = fixed_array->get(i); |
| 5949 if (!element_obj->IsString()) { | 6210 if (!element_obj->IsString()) { |
| 5950 // TODO(1161): handle this case. | 6211 // TODO(1161): handle this case. |
| 5951 return Top::Throw(Heap::illegal_argument_symbol()); | 6212 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
| 5952 } | 6213 } |
| 5953 String* element = String::cast(element_obj); | 6214 String* element = String::cast(element_obj); |
| 5954 int increment = element->length(); | 6215 int increment = element->length(); |
| 5955 if (increment > String::kMaxLength - length) { | 6216 if (increment > String::kMaxLength - length) { |
| 5956 Top::context()->mark_out_of_memory(); | 6217 isolate->context()->mark_out_of_memory(); |
| 5957 return Failure::OutOfMemoryException(); | 6218 return Failure::OutOfMemoryException(); |
| 5958 } | 6219 } |
| 5959 length += increment; | 6220 length += increment; |
| 5960 } | 6221 } |
| 5961 | 6222 |
| 5962 Object* object; | 6223 Object* object; |
| 5963 { MaybeObject* maybe_object = Heap::AllocateRawTwoByteString(length); | 6224 { MaybeObject* maybe_object = |
| 6225 isolate->heap()->AllocateRawTwoByteString(length); |
| 5964 if (!maybe_object->ToObject(&object)) return maybe_object; | 6226 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 5965 } | 6227 } |
| 5966 SeqTwoByteString* answer = SeqTwoByteString::cast(object); | 6228 SeqTwoByteString* answer = SeqTwoByteString::cast(object); |
| 5967 | 6229 |
| 5968 uc16* sink = answer->GetChars(); | 6230 uc16* sink = answer->GetChars(); |
| 5969 #ifdef DEBUG | 6231 #ifdef DEBUG |
| 5970 uc16* end = sink + length; | 6232 uc16* end = sink + length; |
| 5971 #endif | 6233 #endif |
| 5972 | 6234 |
| 5973 String* first = String::cast(fixed_array->get(0)); | 6235 String* first = String::cast(fixed_array->get(0)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 5986 String::WriteToFlat(element, sink, 0, element_length); | 6248 String::WriteToFlat(element, sink, 0, element_length); |
| 5987 sink += element_length; | 6249 sink += element_length; |
| 5988 } | 6250 } |
| 5989 ASSERT(sink == end); | 6251 ASSERT(sink == end); |
| 5990 | 6252 |
| 5991 ASSERT(!answer->HasOnlyAsciiChars()); // Use %_FastAsciiArrayJoin instead. | 6253 ASSERT(!answer->HasOnlyAsciiChars()); // Use %_FastAsciiArrayJoin instead. |
| 5992 return answer; | 6254 return answer; |
| 5993 } | 6255 } |
| 5994 | 6256 |
| 5995 | 6257 |
| 5996 static MaybeObject* Runtime_NumberOr(Arguments args) { | 6258 static MaybeObject* Runtime_NumberOr(RUNTIME_CALLING_CONVENTION) { |
| 6259 RUNTIME_GET_ISOLATE; |
| 5997 NoHandleAllocation ha; | 6260 NoHandleAllocation ha; |
| 5998 ASSERT(args.length() == 2); | 6261 ASSERT(args.length() == 2); |
| 5999 | 6262 |
| 6000 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 6263 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
| 6001 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 6264 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
| 6002 return Heap::NumberFromInt32(x | y); | 6265 return isolate->heap()->NumberFromInt32(x | y); |
| 6003 } | 6266 } |
| 6004 | 6267 |
| 6005 | 6268 |
| 6006 static MaybeObject* Runtime_NumberAnd(Arguments args) { | 6269 static MaybeObject* Runtime_NumberAnd(RUNTIME_CALLING_CONVENTION) { |
| 6270 RUNTIME_GET_ISOLATE; |
| 6007 NoHandleAllocation ha; | 6271 NoHandleAllocation ha; |
| 6008 ASSERT(args.length() == 2); | 6272 ASSERT(args.length() == 2); |
| 6009 | 6273 |
| 6010 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 6274 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
| 6011 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 6275 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
| 6012 return Heap::NumberFromInt32(x & y); | 6276 return isolate->heap()->NumberFromInt32(x & y); |
| 6013 } | 6277 } |
| 6014 | 6278 |
| 6015 | 6279 |
| 6016 static MaybeObject* Runtime_NumberXor(Arguments args) { | 6280 static MaybeObject* Runtime_NumberXor(RUNTIME_CALLING_CONVENTION) { |
| 6281 RUNTIME_GET_ISOLATE; |
| 6017 NoHandleAllocation ha; | 6282 NoHandleAllocation ha; |
| 6018 ASSERT(args.length() == 2); | 6283 ASSERT(args.length() == 2); |
| 6019 | 6284 |
| 6020 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 6285 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
| 6021 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 6286 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
| 6022 return Heap::NumberFromInt32(x ^ y); | 6287 return isolate->heap()->NumberFromInt32(x ^ y); |
| 6023 } | 6288 } |
| 6024 | 6289 |
| 6025 | 6290 |
| 6026 static MaybeObject* Runtime_NumberNot(Arguments args) { | 6291 static MaybeObject* Runtime_NumberNot(RUNTIME_CALLING_CONVENTION) { |
| 6292 RUNTIME_GET_ISOLATE; |
| 6027 NoHandleAllocation ha; | 6293 NoHandleAllocation ha; |
| 6028 ASSERT(args.length() == 1); | 6294 ASSERT(args.length() == 1); |
| 6029 | 6295 |
| 6030 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 6296 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
| 6031 return Heap::NumberFromInt32(~x); | 6297 return isolate->heap()->NumberFromInt32(~x); |
| 6032 } | 6298 } |
| 6033 | 6299 |
| 6034 | 6300 |
| 6035 static MaybeObject* Runtime_NumberShl(Arguments args) { | 6301 static MaybeObject* Runtime_NumberShl(RUNTIME_CALLING_CONVENTION) { |
| 6302 RUNTIME_GET_ISOLATE; |
| 6036 NoHandleAllocation ha; | 6303 NoHandleAllocation ha; |
| 6037 ASSERT(args.length() == 2); | 6304 ASSERT(args.length() == 2); |
| 6038 | 6305 |
| 6039 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 6306 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
| 6040 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 6307 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
| 6041 return Heap::NumberFromInt32(x << (y & 0x1f)); | 6308 return isolate->heap()->NumberFromInt32(x << (y & 0x1f)); |
| 6042 } | 6309 } |
| 6043 | 6310 |
| 6044 | 6311 |
| 6045 static MaybeObject* Runtime_NumberShr(Arguments args) { | 6312 static MaybeObject* Runtime_NumberShr(RUNTIME_CALLING_CONVENTION) { |
| 6313 RUNTIME_GET_ISOLATE; |
| 6046 NoHandleAllocation ha; | 6314 NoHandleAllocation ha; |
| 6047 ASSERT(args.length() == 2); | 6315 ASSERT(args.length() == 2); |
| 6048 | 6316 |
| 6049 CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]); | 6317 CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]); |
| 6050 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 6318 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
| 6051 return Heap::NumberFromUint32(x >> (y & 0x1f)); | 6319 return isolate->heap()->NumberFromUint32(x >> (y & 0x1f)); |
| 6052 } | 6320 } |
| 6053 | 6321 |
| 6054 | 6322 |
| 6055 static MaybeObject* Runtime_NumberSar(Arguments args) { | 6323 static MaybeObject* Runtime_NumberSar(RUNTIME_CALLING_CONVENTION) { |
| 6324 RUNTIME_GET_ISOLATE; |
| 6056 NoHandleAllocation ha; | 6325 NoHandleAllocation ha; |
| 6057 ASSERT(args.length() == 2); | 6326 ASSERT(args.length() == 2); |
| 6058 | 6327 |
| 6059 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 6328 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
| 6060 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 6329 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
| 6061 return Heap::NumberFromInt32(ArithmeticShiftRight(x, y & 0x1f)); | 6330 return isolate->heap()->NumberFromInt32(ArithmeticShiftRight(x, y & 0x1f)); |
| 6062 } | 6331 } |
| 6063 | 6332 |
| 6064 | 6333 |
| 6065 static MaybeObject* Runtime_NumberEquals(Arguments args) { | 6334 static MaybeObject* Runtime_NumberEquals(RUNTIME_CALLING_CONVENTION) { |
| 6335 RUNTIME_GET_ISOLATE; |
| 6066 NoHandleAllocation ha; | 6336 NoHandleAllocation ha; |
| 6067 ASSERT(args.length() == 2); | 6337 ASSERT(args.length() == 2); |
| 6068 | 6338 |
| 6069 CONVERT_DOUBLE_CHECKED(x, args[0]); | 6339 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 6070 CONVERT_DOUBLE_CHECKED(y, args[1]); | 6340 CONVERT_DOUBLE_CHECKED(y, args[1]); |
| 6071 if (isnan(x)) return Smi::FromInt(NOT_EQUAL); | 6341 if (isnan(x)) return Smi::FromInt(NOT_EQUAL); |
| 6072 if (isnan(y)) return Smi::FromInt(NOT_EQUAL); | 6342 if (isnan(y)) return Smi::FromInt(NOT_EQUAL); |
| 6073 if (x == y) return Smi::FromInt(EQUAL); | 6343 if (x == y) return Smi::FromInt(EQUAL); |
| 6074 Object* result; | 6344 Object* result; |
| 6075 if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) { | 6345 if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) { |
| 6076 result = Smi::FromInt(EQUAL); | 6346 result = Smi::FromInt(EQUAL); |
| 6077 } else { | 6347 } else { |
| 6078 result = Smi::FromInt(NOT_EQUAL); | 6348 result = Smi::FromInt(NOT_EQUAL); |
| 6079 } | 6349 } |
| 6080 return result; | 6350 return result; |
| 6081 } | 6351 } |
| 6082 | 6352 |
| 6083 | 6353 |
| 6084 static MaybeObject* Runtime_StringEquals(Arguments args) { | 6354 static MaybeObject* Runtime_StringEquals(RUNTIME_CALLING_CONVENTION) { |
| 6355 RUNTIME_GET_ISOLATE; |
| 6085 NoHandleAllocation ha; | 6356 NoHandleAllocation ha; |
| 6086 ASSERT(args.length() == 2); | 6357 ASSERT(args.length() == 2); |
| 6087 | 6358 |
| 6088 CONVERT_CHECKED(String, x, args[0]); | 6359 CONVERT_CHECKED(String, x, args[0]); |
| 6089 CONVERT_CHECKED(String, y, args[1]); | 6360 CONVERT_CHECKED(String, y, args[1]); |
| 6090 | 6361 |
| 6091 bool not_equal = !x->Equals(y); | 6362 bool not_equal = !x->Equals(y); |
| 6092 // This is slightly convoluted because the value that signifies | 6363 // This is slightly convoluted because the value that signifies |
| 6093 // equality is 0 and inequality is 1 so we have to negate the result | 6364 // equality is 0 and inequality is 1 so we have to negate the result |
| 6094 // from String::Equals. | 6365 // from String::Equals. |
| 6095 ASSERT(not_equal == 0 || not_equal == 1); | 6366 ASSERT(not_equal == 0 || not_equal == 1); |
| 6096 STATIC_CHECK(EQUAL == 0); | 6367 STATIC_CHECK(EQUAL == 0); |
| 6097 STATIC_CHECK(NOT_EQUAL == 1); | 6368 STATIC_CHECK(NOT_EQUAL == 1); |
| 6098 return Smi::FromInt(not_equal); | 6369 return Smi::FromInt(not_equal); |
| 6099 } | 6370 } |
| 6100 | 6371 |
| 6101 | 6372 |
| 6102 static MaybeObject* Runtime_NumberCompare(Arguments args) { | 6373 static MaybeObject* Runtime_NumberCompare(RUNTIME_CALLING_CONVENTION) { |
| 6374 RUNTIME_GET_ISOLATE; |
| 6103 NoHandleAllocation ha; | 6375 NoHandleAllocation ha; |
| 6104 ASSERT(args.length() == 3); | 6376 ASSERT(args.length() == 3); |
| 6105 | 6377 |
| 6106 CONVERT_DOUBLE_CHECKED(x, args[0]); | 6378 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 6107 CONVERT_DOUBLE_CHECKED(y, args[1]); | 6379 CONVERT_DOUBLE_CHECKED(y, args[1]); |
| 6108 if (isnan(x) || isnan(y)) return args[2]; | 6380 if (isnan(x) || isnan(y)) return args[2]; |
| 6109 if (x == y) return Smi::FromInt(EQUAL); | 6381 if (x == y) return Smi::FromInt(EQUAL); |
| 6110 if (isless(x, y)) return Smi::FromInt(LESS); | 6382 if (isless(x, y)) return Smi::FromInt(LESS); |
| 6111 return Smi::FromInt(GREATER); | 6383 return Smi::FromInt(GREATER); |
| 6112 } | 6384 } |
| 6113 | 6385 |
| 6114 | 6386 |
| 6115 // Compare two Smis as if they were converted to strings and then | 6387 // Compare two Smis as if they were converted to strings and then |
| 6116 // compared lexicographically. | 6388 // compared lexicographically. |
| 6117 static MaybeObject* Runtime_SmiLexicographicCompare(Arguments args) { | 6389 static MaybeObject* Runtime_SmiLexicographicCompare( |
| 6390 RUNTIME_CALLING_CONVENTION) { |
| 6391 RUNTIME_GET_ISOLATE; |
| 6118 NoHandleAllocation ha; | 6392 NoHandleAllocation ha; |
| 6119 ASSERT(args.length() == 2); | 6393 ASSERT(args.length() == 2); |
| 6120 | 6394 |
| 6121 // Arrays for the individual characters of the two Smis. Smis are | |
| 6122 // 31 bit integers and 10 decimal digits are therefore enough. | |
| 6123 static int x_elms[10]; | |
| 6124 static int y_elms[10]; | |
| 6125 | |
| 6126 // Extract the integer values from the Smis. | 6395 // Extract the integer values from the Smis. |
| 6127 CONVERT_CHECKED(Smi, x, args[0]); | 6396 CONVERT_CHECKED(Smi, x, args[0]); |
| 6128 CONVERT_CHECKED(Smi, y, args[1]); | 6397 CONVERT_CHECKED(Smi, y, args[1]); |
| 6129 int x_value = x->value(); | 6398 int x_value = x->value(); |
| 6130 int y_value = y->value(); | 6399 int y_value = y->value(); |
| 6131 | 6400 |
| 6132 // If the integers are equal so are the string representations. | 6401 // If the integers are equal so are the string representations. |
| 6133 if (x_value == y_value) return Smi::FromInt(EQUAL); | 6402 if (x_value == y_value) return Smi::FromInt(EQUAL); |
| 6134 | 6403 |
| 6135 // If one of the integers are zero the normal integer order is the | 6404 // If one of the integers are zero the normal integer order is the |
| 6136 // same as the lexicographic order of the string representations. | 6405 // same as the lexicographic order of the string representations. |
| 6137 if (x_value == 0 || y_value == 0) return Smi::FromInt(x_value - y_value); | 6406 if (x_value == 0 || y_value == 0) return Smi::FromInt(x_value - y_value); |
| 6138 | 6407 |
| 6139 // If only one of the integers is negative the negative number is | 6408 // If only one of the integers is negative the negative number is |
| 6140 // smallest because the char code of '-' is less than the char code | 6409 // smallest because the char code of '-' is less than the char code |
| 6141 // of any digit. Otherwise, we make both values positive. | 6410 // of any digit. Otherwise, we make both values positive. |
| 6142 if (x_value < 0 || y_value < 0) { | 6411 if (x_value < 0 || y_value < 0) { |
| 6143 if (y_value >= 0) return Smi::FromInt(LESS); | 6412 if (y_value >= 0) return Smi::FromInt(LESS); |
| 6144 if (x_value >= 0) return Smi::FromInt(GREATER); | 6413 if (x_value >= 0) return Smi::FromInt(GREATER); |
| 6145 x_value = -x_value; | 6414 x_value = -x_value; |
| 6146 y_value = -y_value; | 6415 y_value = -y_value; |
| 6147 } | 6416 } |
| 6148 | 6417 |
| 6418 // Arrays for the individual characters of the two Smis. Smis are |
| 6419 // 31 bit integers and 10 decimal digits are therefore enough. |
| 6420 // TODO(isolates): maybe we should simply allocate 20 bytes on the stack. |
| 6421 int* x_elms = isolate->runtime_state()->smi_lexicographic_compare_x_elms(); |
| 6422 int* y_elms = isolate->runtime_state()->smi_lexicographic_compare_y_elms(); |
| 6423 |
| 6424 |
| 6149 // Convert the integers to arrays of their decimal digits. | 6425 // Convert the integers to arrays of their decimal digits. |
| 6150 int x_index = 0; | 6426 int x_index = 0; |
| 6151 int y_index = 0; | 6427 int y_index = 0; |
| 6152 while (x_value > 0) { | 6428 while (x_value > 0) { |
| 6153 x_elms[x_index++] = x_value % 10; | 6429 x_elms[x_index++] = x_value % 10; |
| 6154 x_value /= 10; | 6430 x_value /= 10; |
| 6155 } | 6431 } |
| 6156 while (y_value > 0) { | 6432 while (y_value > 0) { |
| 6157 y_elms[y_index++] = y_value % 10; | 6433 y_elms[y_index++] = y_value % 10; |
| 6158 y_value /= 10; | 6434 y_value /= 10; |
| 6159 } | 6435 } |
| 6160 | 6436 |
| 6161 // Loop through the arrays of decimal digits finding the first place | 6437 // Loop through the arrays of decimal digits finding the first place |
| 6162 // where they differ. | 6438 // where they differ. |
| 6163 while (--x_index >= 0 && --y_index >= 0) { | 6439 while (--x_index >= 0 && --y_index >= 0) { |
| 6164 int diff = x_elms[x_index] - y_elms[y_index]; | 6440 int diff = x_elms[x_index] - y_elms[y_index]; |
| 6165 if (diff != 0) return Smi::FromInt(diff); | 6441 if (diff != 0) return Smi::FromInt(diff); |
| 6166 } | 6442 } |
| 6167 | 6443 |
| 6168 // If one array is a suffix of the other array, the longest array is | 6444 // If one array is a suffix of the other array, the longest array is |
| 6169 // the representation of the largest of the Smis in the | 6445 // the representation of the largest of the Smis in the |
| 6170 // lexicographic ordering. | 6446 // lexicographic ordering. |
| 6171 return Smi::FromInt(x_index - y_index); | 6447 return Smi::FromInt(x_index - y_index); |
| 6172 } | 6448 } |
| 6173 | 6449 |
| 6174 | 6450 |
| 6175 static Object* StringInputBufferCompare(String* x, String* y) { | 6451 static Object* StringInputBufferCompare(RuntimeState* state, |
| 6176 static StringInputBuffer bufx; | 6452 String* x, |
| 6177 static StringInputBuffer bufy; | 6453 String* y) { |
| 6454 StringInputBuffer& bufx = *state->string_input_buffer_compare_bufx(); |
| 6455 StringInputBuffer& bufy = *state->string_input_buffer_compare_bufy(); |
| 6178 bufx.Reset(x); | 6456 bufx.Reset(x); |
| 6179 bufy.Reset(y); | 6457 bufy.Reset(y); |
| 6180 while (bufx.has_more() && bufy.has_more()) { | 6458 while (bufx.has_more() && bufy.has_more()) { |
| 6181 int d = bufx.GetNext() - bufy.GetNext(); | 6459 int d = bufx.GetNext() - bufy.GetNext(); |
| 6182 if (d < 0) return Smi::FromInt(LESS); | 6460 if (d < 0) return Smi::FromInt(LESS); |
| 6183 else if (d > 0) return Smi::FromInt(GREATER); | 6461 else if (d > 0) return Smi::FromInt(GREATER); |
| 6184 } | 6462 } |
| 6185 | 6463 |
| 6186 // x is (non-trivial) prefix of y: | 6464 // x is (non-trivial) prefix of y: |
| 6187 if (bufy.has_more()) return Smi::FromInt(LESS); | 6465 if (bufy.has_more()) return Smi::FromInt(LESS); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6220 Vector<const uc16> y_chars = y->ToUC16Vector(); | 6498 Vector<const uc16> y_chars = y->ToUC16Vector(); |
| 6221 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 6499 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); |
| 6222 } | 6500 } |
| 6223 } | 6501 } |
| 6224 Object* result; | 6502 Object* result; |
| 6225 if (r == 0) { | 6503 if (r == 0) { |
| 6226 result = equal_prefix_result; | 6504 result = equal_prefix_result; |
| 6227 } else { | 6505 } else { |
| 6228 result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER); | 6506 result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER); |
| 6229 } | 6507 } |
| 6230 ASSERT(result == StringInputBufferCompare(x, y)); | 6508 ASSERT(result == |
| 6509 StringInputBufferCompare(Isolate::Current()->runtime_state(), x, y)); |
| 6231 return result; | 6510 return result; |
| 6232 } | 6511 } |
| 6233 | 6512 |
| 6234 | 6513 |
| 6235 static MaybeObject* Runtime_StringCompare(Arguments args) { | 6514 static MaybeObject* Runtime_StringCompare(RUNTIME_CALLING_CONVENTION) { |
| 6515 RUNTIME_GET_ISOLATE; |
| 6236 NoHandleAllocation ha; | 6516 NoHandleAllocation ha; |
| 6237 ASSERT(args.length() == 2); | 6517 ASSERT(args.length() == 2); |
| 6238 | 6518 |
| 6239 CONVERT_CHECKED(String, x, args[0]); | 6519 CONVERT_CHECKED(String, x, args[0]); |
| 6240 CONVERT_CHECKED(String, y, args[1]); | 6520 CONVERT_CHECKED(String, y, args[1]); |
| 6241 | 6521 |
| 6242 Counters::string_compare_runtime.Increment(); | 6522 isolate->counters()->string_compare_runtime()->Increment(); |
| 6243 | 6523 |
| 6244 // A few fast case tests before we flatten. | 6524 // A few fast case tests before we flatten. |
| 6245 if (x == y) return Smi::FromInt(EQUAL); | 6525 if (x == y) return Smi::FromInt(EQUAL); |
| 6246 if (y->length() == 0) { | 6526 if (y->length() == 0) { |
| 6247 if (x->length() == 0) return Smi::FromInt(EQUAL); | 6527 if (x->length() == 0) return Smi::FromInt(EQUAL); |
| 6248 return Smi::FromInt(GREATER); | 6528 return Smi::FromInt(GREATER); |
| 6249 } else if (x->length() == 0) { | 6529 } else if (x->length() == 0) { |
| 6250 return Smi::FromInt(LESS); | 6530 return Smi::FromInt(LESS); |
| 6251 } | 6531 } |
| 6252 | 6532 |
| 6253 int d = x->Get(0) - y->Get(0); | 6533 int d = x->Get(0) - y->Get(0); |
| 6254 if (d < 0) return Smi::FromInt(LESS); | 6534 if (d < 0) return Smi::FromInt(LESS); |
| 6255 else if (d > 0) return Smi::FromInt(GREATER); | 6535 else if (d > 0) return Smi::FromInt(GREATER); |
| 6256 | 6536 |
| 6257 Object* obj; | 6537 Object* obj; |
| 6258 { MaybeObject* maybe_obj = Heap::PrepareForCompare(x); | 6538 { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(x); |
| 6259 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6539 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6260 } | 6540 } |
| 6261 { MaybeObject* maybe_obj = Heap::PrepareForCompare(y); | 6541 { MaybeObject* maybe_obj = isolate->heap()->PrepareForCompare(y); |
| 6262 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6542 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6263 } | 6543 } |
| 6264 | 6544 |
| 6265 return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y) | 6545 return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y) |
| 6266 : StringInputBufferCompare(x, y); | 6546 : StringInputBufferCompare(isolate->runtime_state(), x, y); |
| 6267 } | 6547 } |
| 6268 | 6548 |
| 6269 | 6549 |
| 6270 static MaybeObject* Runtime_Math_acos(Arguments args) { | 6550 static MaybeObject* Runtime_Math_acos(RUNTIME_CALLING_CONVENTION) { |
| 6551 RUNTIME_GET_ISOLATE; |
| 6271 NoHandleAllocation ha; | 6552 NoHandleAllocation ha; |
| 6272 ASSERT(args.length() == 1); | 6553 ASSERT(args.length() == 1); |
| 6273 Counters::math_acos.Increment(); | 6554 isolate->counters()->math_acos()->Increment(); |
| 6274 | 6555 |
| 6275 CONVERT_DOUBLE_CHECKED(x, args[0]); | 6556 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 6276 return TranscendentalCache::Get(TranscendentalCache::ACOS, x); | 6557 return isolate->transcendental_cache()->Get(TranscendentalCache::ACOS, x); |
| 6277 } | 6558 } |
| 6278 | 6559 |
| 6279 | 6560 |
| 6280 static MaybeObject* Runtime_Math_asin(Arguments args) { | 6561 static MaybeObject* Runtime_Math_asin(RUNTIME_CALLING_CONVENTION) { |
| 6562 RUNTIME_GET_ISOLATE; |
| 6281 NoHandleAllocation ha; | 6563 NoHandleAllocation ha; |
| 6282 ASSERT(args.length() == 1); | 6564 ASSERT(args.length() == 1); |
| 6283 Counters::math_asin.Increment(); | 6565 isolate->counters()->math_asin()->Increment(); |
| 6284 | 6566 |
| 6285 CONVERT_DOUBLE_CHECKED(x, args[0]); | 6567 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 6286 return TranscendentalCache::Get(TranscendentalCache::ASIN, x); | 6568 return isolate->transcendental_cache()->Get(TranscendentalCache::ASIN, x); |
| 6287 } | 6569 } |
| 6288 | 6570 |
| 6289 | 6571 |
| 6290 static MaybeObject* Runtime_Math_atan(Arguments args) { | 6572 static MaybeObject* Runtime_Math_atan(RUNTIME_CALLING_CONVENTION) { |
| 6573 RUNTIME_GET_ISOLATE; |
| 6291 NoHandleAllocation ha; | 6574 NoHandleAllocation ha; |
| 6292 ASSERT(args.length() == 1); | 6575 ASSERT(args.length() == 1); |
| 6293 Counters::math_atan.Increment(); | 6576 isolate->counters()->math_atan()->Increment(); |
| 6294 | 6577 |
| 6295 CONVERT_DOUBLE_CHECKED(x, args[0]); | 6578 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 6296 return TranscendentalCache::Get(TranscendentalCache::ATAN, x); | 6579 return isolate->transcendental_cache()->Get(TranscendentalCache::ATAN, x); |
| 6297 } | 6580 } |
| 6298 | 6581 |
| 6299 | 6582 |
| 6300 static MaybeObject* Runtime_Math_atan2(Arguments args) { | 6583 static const double kPiDividedBy4 = 0.78539816339744830962; |
| 6584 |
| 6585 |
| 6586 static MaybeObject* Runtime_Math_atan2(RUNTIME_CALLING_CONVENTION) { |
| 6587 RUNTIME_GET_ISOLATE; |
| 6301 NoHandleAllocation ha; | 6588 NoHandleAllocation ha; |
| 6302 ASSERT(args.length() == 2); | 6589 ASSERT(args.length() == 2); |
| 6303 Counters::math_atan2.Increment(); | 6590 isolate->counters()->math_atan2()->Increment(); |
| 6304 | 6591 |
| 6305 CONVERT_DOUBLE_CHECKED(x, args[0]); | 6592 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 6306 CONVERT_DOUBLE_CHECKED(y, args[1]); | 6593 CONVERT_DOUBLE_CHECKED(y, args[1]); |
| 6307 double result; | 6594 double result; |
| 6308 if (isinf(x) && isinf(y)) { | 6595 if (isinf(x) && isinf(y)) { |
| 6309 // Make sure that the result in case of two infinite arguments | 6596 // Make sure that the result in case of two infinite arguments |
| 6310 // is a multiple of Pi / 4. The sign of the result is determined | 6597 // is a multiple of Pi / 4. The sign of the result is determined |
| 6311 // by the first argument (x) and the sign of the second argument | 6598 // by the first argument (x) and the sign of the second argument |
| 6312 // determines the multiplier: one or three. | 6599 // determines the multiplier: one or three. |
| 6313 static double kPiDividedBy4 = 0.78539816339744830962; | |
| 6314 int multiplier = (x < 0) ? -1 : 1; | 6600 int multiplier = (x < 0) ? -1 : 1; |
| 6315 if (y < 0) multiplier *= 3; | 6601 if (y < 0) multiplier *= 3; |
| 6316 result = multiplier * kPiDividedBy4; | 6602 result = multiplier * kPiDividedBy4; |
| 6317 } else { | 6603 } else { |
| 6318 result = atan2(x, y); | 6604 result = atan2(x, y); |
| 6319 } | 6605 } |
| 6320 return Heap::AllocateHeapNumber(result); | 6606 return isolate->heap()->AllocateHeapNumber(result); |
| 6321 } | 6607 } |
| 6322 | 6608 |
| 6323 | 6609 |
| 6324 static MaybeObject* Runtime_Math_ceil(Arguments args) { | 6610 static MaybeObject* Runtime_Math_ceil(RUNTIME_CALLING_CONVENTION) { |
| 6611 RUNTIME_GET_ISOLATE; |
| 6325 NoHandleAllocation ha; | 6612 NoHandleAllocation ha; |
| 6326 ASSERT(args.length() == 1); | 6613 ASSERT(args.length() == 1); |
| 6327 Counters::math_ceil.Increment(); | 6614 isolate->counters()->math_ceil()->Increment(); |
| 6328 | 6615 |
| 6329 CONVERT_DOUBLE_CHECKED(x, args[0]); | 6616 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 6330 return Heap::NumberFromDouble(ceiling(x)); | 6617 return isolate->heap()->NumberFromDouble(ceiling(x)); |
| 6331 } | 6618 } |
| 6332 | 6619 |
| 6333 | 6620 |
| 6334 static MaybeObject* Runtime_Math_cos(Arguments args) { | 6621 static MaybeObject* Runtime_Math_cos(RUNTIME_CALLING_CONVENTION) { |
| 6622 RUNTIME_GET_ISOLATE; |
| 6335 NoHandleAllocation ha; | 6623 NoHandleAllocation ha; |
| 6336 ASSERT(args.length() == 1); | 6624 ASSERT(args.length() == 1); |
| 6337 Counters::math_cos.Increment(); | 6625 isolate->counters()->math_cos()->Increment(); |
| 6338 | 6626 |
| 6339 CONVERT_DOUBLE_CHECKED(x, args[0]); | 6627 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 6340 return TranscendentalCache::Get(TranscendentalCache::COS, x); | 6628 return isolate->transcendental_cache()->Get(TranscendentalCache::COS, x); |
| 6341 } | 6629 } |
| 6342 | 6630 |
| 6343 | 6631 |
| 6344 static MaybeObject* Runtime_Math_exp(Arguments args) { | 6632 static MaybeObject* Runtime_Math_exp(RUNTIME_CALLING_CONVENTION) { |
| 6633 RUNTIME_GET_ISOLATE; |
| 6345 NoHandleAllocation ha; | 6634 NoHandleAllocation ha; |
| 6346 ASSERT(args.length() == 1); | 6635 ASSERT(args.length() == 1); |
| 6347 Counters::math_exp.Increment(); | 6636 isolate->counters()->math_exp()->Increment(); |
| 6348 | 6637 |
| 6349 CONVERT_DOUBLE_CHECKED(x, args[0]); | 6638 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 6350 return TranscendentalCache::Get(TranscendentalCache::EXP, x); | 6639 return isolate->transcendental_cache()->Get(TranscendentalCache::EXP, x); |
| 6351 } | 6640 } |
| 6352 | 6641 |
| 6353 | 6642 |
| 6354 static MaybeObject* Runtime_Math_floor(Arguments args) { | 6643 static MaybeObject* Runtime_Math_floor(RUNTIME_CALLING_CONVENTION) { |
| 6644 RUNTIME_GET_ISOLATE; |
| 6355 NoHandleAllocation ha; | 6645 NoHandleAllocation ha; |
| 6356 ASSERT(args.length() == 1); | 6646 ASSERT(args.length() == 1); |
| 6357 Counters::math_floor.Increment(); | 6647 isolate->counters()->math_floor()->Increment(); |
| 6358 | 6648 |
| 6359 CONVERT_DOUBLE_CHECKED(x, args[0]); | 6649 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 6360 return Heap::NumberFromDouble(floor(x)); | 6650 return isolate->heap()->NumberFromDouble(floor(x)); |
| 6361 } | 6651 } |
| 6362 | 6652 |
| 6363 | 6653 |
| 6364 static MaybeObject* Runtime_Math_log(Arguments args) { | 6654 static MaybeObject* Runtime_Math_log(RUNTIME_CALLING_CONVENTION) { |
| 6655 RUNTIME_GET_ISOLATE; |
| 6365 NoHandleAllocation ha; | 6656 NoHandleAllocation ha; |
| 6366 ASSERT(args.length() == 1); | 6657 ASSERT(args.length() == 1); |
| 6367 Counters::math_log.Increment(); | 6658 isolate->counters()->math_log()->Increment(); |
| 6368 | 6659 |
| 6369 CONVERT_DOUBLE_CHECKED(x, args[0]); | 6660 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 6370 return TranscendentalCache::Get(TranscendentalCache::LOG, x); | 6661 return isolate->transcendental_cache()->Get(TranscendentalCache::LOG, x); |
| 6371 } | 6662 } |
| 6372 | 6663 |
| 6373 | 6664 |
| 6374 static MaybeObject* Runtime_Math_pow(Arguments args) { | 6665 static MaybeObject* Runtime_Math_pow(RUNTIME_CALLING_CONVENTION) { |
| 6666 RUNTIME_GET_ISOLATE; |
| 6375 NoHandleAllocation ha; | 6667 NoHandleAllocation ha; |
| 6376 ASSERT(args.length() == 2); | 6668 ASSERT(args.length() == 2); |
| 6377 Counters::math_pow.Increment(); | 6669 isolate->counters()->math_pow()->Increment(); |
| 6378 | 6670 |
| 6379 CONVERT_DOUBLE_CHECKED(x, args[0]); | 6671 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 6380 | 6672 |
| 6381 // If the second argument is a smi, it is much faster to call the | 6673 // If the second argument is a smi, it is much faster to call the |
| 6382 // custom powi() function than the generic pow(). | 6674 // custom powi() function than the generic pow(). |
| 6383 if (args[1]->IsSmi()) { | 6675 if (args[1]->IsSmi()) { |
| 6384 int y = Smi::cast(args[1])->value(); | 6676 int y = Smi::cast(args[1])->value(); |
| 6385 return Heap::NumberFromDouble(power_double_int(x, y)); | 6677 return isolate->heap()->NumberFromDouble(power_double_int(x, y)); |
| 6386 } | 6678 } |
| 6387 | 6679 |
| 6388 CONVERT_DOUBLE_CHECKED(y, args[1]); | 6680 CONVERT_DOUBLE_CHECKED(y, args[1]); |
| 6389 return Heap::AllocateHeapNumber(power_double_double(x, y)); | 6681 return isolate->heap()->AllocateHeapNumber(power_double_double(x, y)); |
| 6390 } | 6682 } |
| 6391 | 6683 |
| 6392 // Fast version of Math.pow if we know that y is not an integer and | 6684 // Fast version of Math.pow if we know that y is not an integer and |
| 6393 // y is not -0.5 or 0.5. Used as slowcase from codegen. | 6685 // y is not -0.5 or 0.5. Used as slowcase from codegen. |
| 6394 static MaybeObject* Runtime_Math_pow_cfunction(Arguments args) { | 6686 static MaybeObject* Runtime_Math_pow_cfunction(RUNTIME_CALLING_CONVENTION) { |
| 6687 RUNTIME_GET_ISOLATE; |
| 6395 NoHandleAllocation ha; | 6688 NoHandleAllocation ha; |
| 6396 ASSERT(args.length() == 2); | 6689 ASSERT(args.length() == 2); |
| 6397 CONVERT_DOUBLE_CHECKED(x, args[0]); | 6690 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 6398 CONVERT_DOUBLE_CHECKED(y, args[1]); | 6691 CONVERT_DOUBLE_CHECKED(y, args[1]); |
| 6399 if (y == 0) { | 6692 if (y == 0) { |
| 6400 return Smi::FromInt(1); | 6693 return Smi::FromInt(1); |
| 6401 } else if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) { | 6694 } else if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) { |
| 6402 return Heap::nan_value(); | 6695 return isolate->heap()->nan_value(); |
| 6403 } else { | 6696 } else { |
| 6404 return Heap::AllocateHeapNumber(pow(x, y)); | 6697 return isolate->heap()->AllocateHeapNumber(pow(x, y)); |
| 6405 } | 6698 } |
| 6406 } | 6699 } |
| 6407 | 6700 |
| 6408 | 6701 |
| 6409 static MaybeObject* Runtime_RoundNumber(Arguments args) { | 6702 static MaybeObject* Runtime_RoundNumber(RUNTIME_CALLING_CONVENTION) { |
| 6703 RUNTIME_GET_ISOLATE; |
| 6410 NoHandleAllocation ha; | 6704 NoHandleAllocation ha; |
| 6411 ASSERT(args.length() == 1); | 6705 ASSERT(args.length() == 1); |
| 6412 Counters::math_round.Increment(); | 6706 isolate->counters()->math_round()->Increment(); |
| 6413 | 6707 |
| 6414 if (!args[0]->IsHeapNumber()) { | 6708 if (!args[0]->IsHeapNumber()) { |
| 6415 // Must be smi. Return the argument unchanged for all the other types | 6709 // Must be smi. Return the argument unchanged for all the other types |
| 6416 // to make fuzz-natives test happy. | 6710 // to make fuzz-natives test happy. |
| 6417 return args[0]; | 6711 return args[0]; |
| 6418 } | 6712 } |
| 6419 | 6713 |
| 6420 HeapNumber* number = reinterpret_cast<HeapNumber*>(args[0]); | 6714 HeapNumber* number = reinterpret_cast<HeapNumber*>(args[0]); |
| 6421 | 6715 |
| 6422 double value = number->value(); | 6716 double value = number->value(); |
| 6423 int exponent = number->get_exponent(); | 6717 int exponent = number->get_exponent(); |
| 6424 int sign = number->get_sign(); | 6718 int sign = number->get_sign(); |
| 6425 | 6719 |
| 6426 // We compare with kSmiValueSize - 3 because (2^30 - 0.1) has exponent 29 and | 6720 // We compare with kSmiValueSize - 3 because (2^30 - 0.1) has exponent 29 and |
| 6427 // should be rounded to 2^30, which is not smi. | 6721 // should be rounded to 2^30, which is not smi. |
| 6428 if (!sign && exponent <= kSmiValueSize - 3) { | 6722 if (!sign && exponent <= kSmiValueSize - 3) { |
| 6429 return Smi::FromInt(static_cast<int>(value + 0.5)); | 6723 return Smi::FromInt(static_cast<int>(value + 0.5)); |
| 6430 } | 6724 } |
| 6431 | 6725 |
| 6432 // If the magnitude is big enough, there's no place for fraction part. If we | 6726 // If the magnitude is big enough, there's no place for fraction part. If we |
| 6433 // try to add 0.5 to this number, 1.0 will be added instead. | 6727 // try to add 0.5 to this number, 1.0 will be added instead. |
| 6434 if (exponent >= 52) { | 6728 if (exponent >= 52) { |
| 6435 return number; | 6729 return number; |
| 6436 } | 6730 } |
| 6437 | 6731 |
| 6438 if (sign && value >= -0.5) return Heap::minus_zero_value(); | 6732 if (sign && value >= -0.5) return isolate->heap()->minus_zero_value(); |
| 6439 | 6733 |
| 6440 // Do not call NumberFromDouble() to avoid extra checks. | 6734 // Do not call NumberFromDouble() to avoid extra checks. |
| 6441 return Heap::AllocateHeapNumber(floor(value + 0.5)); | 6735 return isolate->heap()->AllocateHeapNumber(floor(value + 0.5)); |
| 6442 } | 6736 } |
| 6443 | 6737 |
| 6444 | 6738 |
| 6445 static MaybeObject* Runtime_Math_sin(Arguments args) { | 6739 static MaybeObject* Runtime_Math_sin(RUNTIME_CALLING_CONVENTION) { |
| 6740 RUNTIME_GET_ISOLATE; |
| 6446 NoHandleAllocation ha; | 6741 NoHandleAllocation ha; |
| 6447 ASSERT(args.length() == 1); | 6742 ASSERT(args.length() == 1); |
| 6448 Counters::math_sin.Increment(); | 6743 isolate->counters()->math_sin()->Increment(); |
| 6449 | 6744 |
| 6450 CONVERT_DOUBLE_CHECKED(x, args[0]); | 6745 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 6451 return TranscendentalCache::Get(TranscendentalCache::SIN, x); | 6746 return isolate->transcendental_cache()->Get(TranscendentalCache::SIN, x); |
| 6452 } | 6747 } |
| 6453 | 6748 |
| 6454 | 6749 |
| 6455 static MaybeObject* Runtime_Math_sqrt(Arguments args) { | 6750 static MaybeObject* Runtime_Math_sqrt(RUNTIME_CALLING_CONVENTION) { |
| 6751 RUNTIME_GET_ISOLATE; |
| 6456 NoHandleAllocation ha; | 6752 NoHandleAllocation ha; |
| 6457 ASSERT(args.length() == 1); | 6753 ASSERT(args.length() == 1); |
| 6458 Counters::math_sqrt.Increment(); | 6754 isolate->counters()->math_sqrt()->Increment(); |
| 6459 | 6755 |
| 6460 CONVERT_DOUBLE_CHECKED(x, args[0]); | 6756 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 6461 return Heap::AllocateHeapNumber(sqrt(x)); | 6757 return isolate->heap()->AllocateHeapNumber(sqrt(x)); |
| 6462 } | 6758 } |
| 6463 | 6759 |
| 6464 | 6760 |
| 6465 static MaybeObject* Runtime_Math_tan(Arguments args) { | 6761 static MaybeObject* Runtime_Math_tan(RUNTIME_CALLING_CONVENTION) { |
| 6762 RUNTIME_GET_ISOLATE; |
| 6466 NoHandleAllocation ha; | 6763 NoHandleAllocation ha; |
| 6467 ASSERT(args.length() == 1); | 6764 ASSERT(args.length() == 1); |
| 6468 Counters::math_tan.Increment(); | 6765 isolate->counters()->math_tan()->Increment(); |
| 6469 | 6766 |
| 6470 CONVERT_DOUBLE_CHECKED(x, args[0]); | 6767 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 6471 return TranscendentalCache::Get(TranscendentalCache::TAN, x); | 6768 return isolate->transcendental_cache()->Get(TranscendentalCache::TAN, x); |
| 6472 } | 6769 } |
| 6473 | 6770 |
| 6474 | 6771 |
| 6475 static int MakeDay(int year, int month, int day) { | 6772 static int MakeDay(int year, int month, int day) { |
| 6476 static const int day_from_month[] = {0, 31, 59, 90, 120, 151, | 6773 static const int day_from_month[] = {0, 31, 59, 90, 120, 151, |
| 6477 181, 212, 243, 273, 304, 334}; | 6774 181, 212, 243, 273, 304, 334}; |
| 6478 static const int day_from_month_leap[] = {0, 31, 60, 91, 121, 152, | 6775 static const int day_from_month_leap[] = {0, 31, 60, 91, 121, 152, |
| 6479 182, 213, 244, 274, 305, 335}; | 6776 182, 213, 244, 274, 305, 335}; |
| 6480 | 6777 |
| 6481 year += month / 12; | 6778 year += month / 12; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 6510 base_day; | 6807 base_day; |
| 6511 | 6808 |
| 6512 if (year % 4 || (year % 100 == 0 && year % 400 != 0)) { | 6809 if (year % 4 || (year % 100 == 0 && year % 400 != 0)) { |
| 6513 return day_from_year + day_from_month[month] + day - 1; | 6810 return day_from_year + day_from_month[month] + day - 1; |
| 6514 } | 6811 } |
| 6515 | 6812 |
| 6516 return day_from_year + day_from_month_leap[month] + day - 1; | 6813 return day_from_year + day_from_month_leap[month] + day - 1; |
| 6517 } | 6814 } |
| 6518 | 6815 |
| 6519 | 6816 |
| 6520 static MaybeObject* Runtime_DateMakeDay(Arguments args) { | 6817 static MaybeObject* Runtime_DateMakeDay(RUNTIME_CALLING_CONVENTION) { |
| 6818 RUNTIME_GET_ISOLATE; |
| 6521 NoHandleAllocation ha; | 6819 NoHandleAllocation ha; |
| 6522 ASSERT(args.length() == 3); | 6820 ASSERT(args.length() == 3); |
| 6523 | 6821 |
| 6524 CONVERT_SMI_CHECKED(year, args[0]); | 6822 CONVERT_SMI_CHECKED(year, args[0]); |
| 6525 CONVERT_SMI_CHECKED(month, args[1]); | 6823 CONVERT_SMI_CHECKED(month, args[1]); |
| 6526 CONVERT_SMI_CHECKED(date, args[2]); | 6824 CONVERT_SMI_CHECKED(date, args[2]); |
| 6527 | 6825 |
| 6528 return Smi::FromInt(MakeDay(year, month, date)); | 6826 return Smi::FromInt(MakeDay(year, month, date)); |
| 6529 } | 6827 } |
| 6530 | 6828 |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6809 static inline void DateYMDFromTime(int date, | 7107 static inline void DateYMDFromTime(int date, |
| 6810 int& year, int& month, int& day) { | 7108 int& year, int& month, int& day) { |
| 6811 if (date >= 0 && date < 32 * kDaysIn4Years) { | 7109 if (date >= 0 && date < 32 * kDaysIn4Years) { |
| 6812 DateYMDFromTimeAfter1970(date, year, month, day); | 7110 DateYMDFromTimeAfter1970(date, year, month, day); |
| 6813 } else { | 7111 } else { |
| 6814 DateYMDFromTimeSlow(date, year, month, day); | 7112 DateYMDFromTimeSlow(date, year, month, day); |
| 6815 } | 7113 } |
| 6816 } | 7114 } |
| 6817 | 7115 |
| 6818 | 7116 |
| 6819 static MaybeObject* Runtime_DateYMDFromTime(Arguments args) { | 7117 static MaybeObject* Runtime_DateYMDFromTime(RUNTIME_CALLING_CONVENTION) { |
| 7118 RUNTIME_GET_ISOLATE; |
| 6820 NoHandleAllocation ha; | 7119 NoHandleAllocation ha; |
| 6821 ASSERT(args.length() == 2); | 7120 ASSERT(args.length() == 2); |
| 6822 | 7121 |
| 6823 CONVERT_DOUBLE_CHECKED(t, args[0]); | 7122 CONVERT_DOUBLE_CHECKED(t, args[0]); |
| 6824 CONVERT_CHECKED(JSArray, res_array, args[1]); | 7123 CONVERT_CHECKED(JSArray, res_array, args[1]); |
| 6825 | 7124 |
| 6826 int year, month, day; | 7125 int year, month, day; |
| 6827 DateYMDFromTime(static_cast<int>(floor(t / 86400000)), year, month, day); | 7126 DateYMDFromTime(static_cast<int>(floor(t / 86400000)), year, month, day); |
| 6828 | 7127 |
| 6829 RUNTIME_ASSERT(res_array->elements()->map() == Heap::fixed_array_map()); | 7128 RUNTIME_ASSERT(res_array->elements()->map() == |
| 7129 isolate->heap()->fixed_array_map()); |
| 6830 FixedArray* elms = FixedArray::cast(res_array->elements()); | 7130 FixedArray* elms = FixedArray::cast(res_array->elements()); |
| 6831 RUNTIME_ASSERT(elms->length() == 3); | 7131 RUNTIME_ASSERT(elms->length() == 3); |
| 6832 | 7132 |
| 6833 elms->set(0, Smi::FromInt(year)); | 7133 elms->set(0, Smi::FromInt(year)); |
| 6834 elms->set(1, Smi::FromInt(month)); | 7134 elms->set(1, Smi::FromInt(month)); |
| 6835 elms->set(2, Smi::FromInt(day)); | 7135 elms->set(2, Smi::FromInt(day)); |
| 6836 | 7136 |
| 6837 return Heap::undefined_value(); | 7137 return isolate->heap()->undefined_value(); |
| 6838 } | 7138 } |
| 6839 | 7139 |
| 6840 | 7140 |
| 6841 static MaybeObject* Runtime_NewArgumentsFast(Arguments args) { | 7141 static MaybeObject* Runtime_NewArgumentsFast(RUNTIME_CALLING_CONVENTION) { |
| 7142 RUNTIME_GET_ISOLATE; |
| 6842 NoHandleAllocation ha; | 7143 NoHandleAllocation ha; |
| 6843 ASSERT(args.length() == 3); | 7144 ASSERT(args.length() == 3); |
| 6844 | 7145 |
| 6845 JSFunction* callee = JSFunction::cast(args[0]); | 7146 JSFunction* callee = JSFunction::cast(args[0]); |
| 6846 Object** parameters = reinterpret_cast<Object**>(args[1]); | 7147 Object** parameters = reinterpret_cast<Object**>(args[1]); |
| 6847 const int length = Smi::cast(args[2])->value(); | 7148 const int length = Smi::cast(args[2])->value(); |
| 6848 | 7149 |
| 6849 Object* result; | 7150 Object* result; |
| 6850 { MaybeObject* maybe_result = Heap::AllocateArgumentsObject(callee, length); | 7151 { MaybeObject* maybe_result = |
| 7152 isolate->heap()->AllocateArgumentsObject(callee, length); |
| 6851 if (!maybe_result->ToObject(&result)) return maybe_result; | 7153 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 6852 } | 7154 } |
| 6853 // Allocate the elements if needed. | 7155 // Allocate the elements if needed. |
| 6854 if (length > 0) { | 7156 if (length > 0) { |
| 6855 // Allocate the fixed array. | 7157 // Allocate the fixed array. |
| 6856 Object* obj; | 7158 Object* obj; |
| 6857 { MaybeObject* maybe_obj = Heap::AllocateRawFixedArray(length); | 7159 { MaybeObject* maybe_obj = isolate->heap()->AllocateRawFixedArray(length); |
| 6858 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 7160 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6859 } | 7161 } |
| 6860 | 7162 |
| 6861 AssertNoAllocation no_gc; | 7163 AssertNoAllocation no_gc; |
| 6862 FixedArray* array = reinterpret_cast<FixedArray*>(obj); | 7164 FixedArray* array = reinterpret_cast<FixedArray*>(obj); |
| 6863 array->set_map(Heap::fixed_array_map()); | 7165 array->set_map(isolate->heap()->fixed_array_map()); |
| 6864 array->set_length(length); | 7166 array->set_length(length); |
| 6865 | 7167 |
| 6866 WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc); | 7168 WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc); |
| 6867 for (int i = 0; i < length; i++) { | 7169 for (int i = 0; i < length; i++) { |
| 6868 array->set(i, *--parameters, mode); | 7170 array->set(i, *--parameters, mode); |
| 6869 } | 7171 } |
| 6870 JSObject::cast(result)->set_elements(FixedArray::cast(obj)); | 7172 JSObject::cast(result)->set_elements(FixedArray::cast(obj)); |
| 6871 } | 7173 } |
| 6872 return result; | 7174 return result; |
| 6873 } | 7175 } |
| 6874 | 7176 |
| 6875 | 7177 |
| 6876 static MaybeObject* Runtime_NewClosure(Arguments args) { | 7178 static MaybeObject* Runtime_NewClosure(RUNTIME_CALLING_CONVENTION) { |
| 6877 HandleScope scope; | 7179 RUNTIME_GET_ISOLATE; |
| 7180 HandleScope scope(isolate); |
| 6878 ASSERT(args.length() == 3); | 7181 ASSERT(args.length() == 3); |
| 6879 CONVERT_ARG_CHECKED(Context, context, 0); | 7182 CONVERT_ARG_CHECKED(Context, context, 0); |
| 6880 CONVERT_ARG_CHECKED(SharedFunctionInfo, shared, 1); | 7183 CONVERT_ARG_CHECKED(SharedFunctionInfo, shared, 1); |
| 6881 CONVERT_BOOLEAN_CHECKED(pretenure, args[2]); | 7184 CONVERT_BOOLEAN_CHECKED(pretenure, args[2]); |
| 6882 | 7185 |
| 6883 // Allocate global closures in old space and allocate local closures | 7186 // Allocate global closures in old space and allocate local closures |
| 6884 // in new space. Additionally pretenure closures that are assigned | 7187 // in new space. Additionally pretenure closures that are assigned |
| 6885 // directly to properties. | 7188 // directly to properties. |
| 6886 pretenure = pretenure || (context->global_context() == *context); | 7189 pretenure = pretenure || (context->global_context() == *context); |
| 6887 PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED; | 7190 PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED; |
| 6888 Handle<JSFunction> result = | 7191 Handle<JSFunction> result = |
| 6889 Factory::NewFunctionFromSharedFunctionInfo(shared, | 7192 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, |
| 6890 context, | 7193 context, |
| 6891 pretenure_flag); | 7194 pretenure_flag); |
| 6892 return *result; | 7195 return *result; |
| 6893 } | 7196 } |
| 6894 | 7197 |
| 6895 | 7198 static MaybeObject* Runtime_NewObjectFromBound(RUNTIME_CALLING_CONVENTION) { |
| 6896 static MaybeObject* Runtime_NewObjectFromBound(Arguments args) { | 7199 RUNTIME_GET_ISOLATE; |
| 6897 HandleScope scope; | 7200 HandleScope scope(isolate); |
| 6898 ASSERT(args.length() == 2); | 7201 ASSERT(args.length() == 2); |
| 6899 // First argument is a function to use as a constructor. | 7202 // First argument is a function to use as a constructor. |
| 6900 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 7203 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
| 6901 | 7204 |
| 6902 // Second argument is either null or an array of bound arguments. | 7205 // Second argument is either null or an array of bound arguments. |
| 6903 FixedArray* bound_args = NULL; | 7206 FixedArray* bound_args = NULL; |
| 6904 int bound_argc = 0; | 7207 int bound_argc = 0; |
| 6905 if (!args[1]->IsNull()) { | 7208 if (!args[1]->IsNull()) { |
| 6906 CONVERT_ARG_CHECKED(JSArray, params, 1); | 7209 CONVERT_ARG_CHECKED(JSArray, params, 1); |
| 6907 RUNTIME_ASSERT(params->HasFastElements()); | 7210 RUNTIME_ASSERT(params->HasFastElements()); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 6934 Execution::New(function, total_argc, *param_data, &exception); | 7237 Execution::New(function, total_argc, *param_data, &exception); |
| 6935 if (exception) { | 7238 if (exception) { |
| 6936 return Failure::Exception(); | 7239 return Failure::Exception(); |
| 6937 } | 7240 } |
| 6938 | 7241 |
| 6939 ASSERT(!result.is_null()); | 7242 ASSERT(!result.is_null()); |
| 6940 return *result; | 7243 return *result; |
| 6941 } | 7244 } |
| 6942 | 7245 |
| 6943 | 7246 |
| 6944 static void TrySettingInlineConstructStub(Handle<JSFunction> function) { | 7247 static void TrySettingInlineConstructStub(Isolate* isolate, |
| 6945 Handle<Object> prototype = Factory::null_value(); | 7248 Handle<JSFunction> function) { |
| 7249 Handle<Object> prototype = isolate->factory()->null_value(); |
| 6946 if (function->has_instance_prototype()) { | 7250 if (function->has_instance_prototype()) { |
| 6947 prototype = Handle<Object>(function->instance_prototype()); | 7251 prototype = Handle<Object>(function->instance_prototype(), isolate); |
| 6948 } | 7252 } |
| 6949 if (function->shared()->CanGenerateInlineConstructor(*prototype)) { | 7253 if (function->shared()->CanGenerateInlineConstructor(*prototype)) { |
| 6950 ConstructStubCompiler compiler; | 7254 ConstructStubCompiler compiler; |
| 6951 MaybeObject* code = compiler.CompileConstructStub(*function); | 7255 MaybeObject* code = compiler.CompileConstructStub(*function); |
| 6952 if (!code->IsFailure()) { | 7256 if (!code->IsFailure()) { |
| 6953 function->shared()->set_construct_stub( | 7257 function->shared()->set_construct_stub( |
| 6954 Code::cast(code->ToObjectUnchecked())); | 7258 Code::cast(code->ToObjectUnchecked())); |
| 6955 } | 7259 } |
| 6956 } | 7260 } |
| 6957 } | 7261 } |
| 6958 | 7262 |
| 6959 | 7263 |
| 6960 static MaybeObject* Runtime_NewObject(Arguments args) { | 7264 static MaybeObject* Runtime_NewObject(RUNTIME_CALLING_CONVENTION) { |
| 6961 HandleScope scope; | 7265 RUNTIME_GET_ISOLATE; |
| 7266 HandleScope scope(isolate); |
| 6962 ASSERT(args.length() == 1); | 7267 ASSERT(args.length() == 1); |
| 6963 | 7268 |
| 6964 Handle<Object> constructor = args.at<Object>(0); | 7269 Handle<Object> constructor = args.at<Object>(0); |
| 6965 | 7270 |
| 6966 // If the constructor isn't a proper function we throw a type error. | 7271 // If the constructor isn't a proper function we throw a type error. |
| 6967 if (!constructor->IsJSFunction()) { | 7272 if (!constructor->IsJSFunction()) { |
| 6968 Vector< Handle<Object> > arguments = HandleVector(&constructor, 1); | 7273 Vector< Handle<Object> > arguments = HandleVector(&constructor, 1); |
| 6969 Handle<Object> type_error = | 7274 Handle<Object> type_error = |
| 6970 Factory::NewTypeError("not_constructor", arguments); | 7275 isolate->factory()->NewTypeError("not_constructor", arguments); |
| 6971 return Top::Throw(*type_error); | 7276 return isolate->Throw(*type_error); |
| 6972 } | 7277 } |
| 6973 | 7278 |
| 6974 Handle<JSFunction> function = Handle<JSFunction>::cast(constructor); | 7279 Handle<JSFunction> function = Handle<JSFunction>::cast(constructor); |
| 6975 | 7280 |
| 6976 // If function should not have prototype, construction is not allowed. In this | 7281 // If function should not have prototype, construction is not allowed. In this |
| 6977 // case generated code bailouts here, since function has no initial_map. | 7282 // case generated code bailouts here, since function has no initial_map. |
| 6978 if (!function->should_have_prototype()) { | 7283 if (!function->should_have_prototype()) { |
| 6979 Vector< Handle<Object> > arguments = HandleVector(&constructor, 1); | 7284 Vector< Handle<Object> > arguments = HandleVector(&constructor, 1); |
| 6980 Handle<Object> type_error = | 7285 Handle<Object> type_error = |
| 6981 Factory::NewTypeError("not_constructor", arguments); | 7286 isolate->factory()->NewTypeError("not_constructor", arguments); |
| 6982 return Top::Throw(*type_error); | 7287 return isolate->Throw(*type_error); |
| 6983 } | 7288 } |
| 6984 | 7289 |
| 6985 #ifdef ENABLE_DEBUGGER_SUPPORT | 7290 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 7291 Debug* debug = isolate->debug(); |
| 6986 // Handle stepping into constructors if step into is active. | 7292 // Handle stepping into constructors if step into is active. |
| 6987 if (Debug::StepInActive()) { | 7293 if (debug->StepInActive()) { |
| 6988 Debug::HandleStepIn(function, Handle<Object>::null(), 0, true); | 7294 debug->HandleStepIn(function, Handle<Object>::null(), 0, true); |
| 6989 } | 7295 } |
| 6990 #endif | 7296 #endif |
| 6991 | 7297 |
| 6992 if (function->has_initial_map()) { | 7298 if (function->has_initial_map()) { |
| 6993 if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) { | 7299 if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) { |
| 6994 // The 'Function' function ignores the receiver object when | 7300 // The 'Function' function ignores the receiver object when |
| 6995 // called using 'new' and creates a new JSFunction object that | 7301 // called using 'new' and creates a new JSFunction object that |
| 6996 // is returned. The receiver object is only used for error | 7302 // is returned. The receiver object is only used for error |
| 6997 // reporting if an error occurs when constructing the new | 7303 // reporting if an error occurs when constructing the new |
| 6998 // JSFunction. Factory::NewJSObject() should not be used to | 7304 // JSFunction. FACTORY->NewJSObject() should not be used to |
| 6999 // allocate JSFunctions since it does not properly initialize | 7305 // allocate JSFunctions since it does not properly initialize |
| 7000 // the shared part of the function. Since the receiver is | 7306 // the shared part of the function. Since the receiver is |
| 7001 // ignored anyway, we use the global object as the receiver | 7307 // ignored anyway, we use the global object as the receiver |
| 7002 // instead of a new JSFunction object. This way, errors are | 7308 // instead of a new JSFunction object. This way, errors are |
| 7003 // reported the same way whether or not 'Function' is called | 7309 // reported the same way whether or not 'Function' is called |
| 7004 // using 'new'. | 7310 // using 'new'. |
| 7005 return Top::context()->global(); | 7311 return isolate->context()->global(); |
| 7006 } | 7312 } |
| 7007 } | 7313 } |
| 7008 | 7314 |
| 7009 // The function should be compiled for the optimization hints to be | 7315 // The function should be compiled for the optimization hints to be |
| 7010 // available. We cannot use EnsureCompiled because that forces a | 7316 // available. We cannot use EnsureCompiled because that forces a |
| 7011 // compilation through the shared function info which makes it | 7317 // compilation through the shared function info which makes it |
| 7012 // impossible for us to optimize. | 7318 // impossible for us to optimize. |
| 7013 Handle<SharedFunctionInfo> shared(function->shared()); | 7319 Handle<SharedFunctionInfo> shared(function->shared(), isolate); |
| 7014 if (!function->is_compiled()) CompileLazy(function, CLEAR_EXCEPTION); | 7320 if (!function->is_compiled()) CompileLazy(function, CLEAR_EXCEPTION); |
| 7015 | 7321 |
| 7016 if (!function->has_initial_map() && | 7322 if (!function->has_initial_map() && |
| 7017 shared->IsInobjectSlackTrackingInProgress()) { | 7323 shared->IsInobjectSlackTrackingInProgress()) { |
| 7018 // The tracking is already in progress for another function. We can only | 7324 // The tracking is already in progress for another function. We can only |
| 7019 // track one initial_map at a time, so we force the completion before the | 7325 // track one initial_map at a time, so we force the completion before the |
| 7020 // function is called as a constructor for the first time. | 7326 // function is called as a constructor for the first time. |
| 7021 shared->CompleteInobjectSlackTracking(); | 7327 shared->CompleteInobjectSlackTracking(); |
| 7022 } | 7328 } |
| 7023 | 7329 |
| 7024 bool first_allocation = !shared->live_objects_may_exist(); | 7330 bool first_allocation = !shared->live_objects_may_exist(); |
| 7025 Handle<JSObject> result = Factory::NewJSObject(function); | 7331 Handle<JSObject> result = isolate->factory()->NewJSObject(function); |
| 7026 RETURN_IF_EMPTY_HANDLE(result); | 7332 RETURN_IF_EMPTY_HANDLE(isolate, result); |
| 7027 // Delay setting the stub if inobject slack tracking is in progress. | 7333 // Delay setting the stub if inobject slack tracking is in progress. |
| 7028 if (first_allocation && !shared->IsInobjectSlackTrackingInProgress()) { | 7334 if (first_allocation && !shared->IsInobjectSlackTrackingInProgress()) { |
| 7029 TrySettingInlineConstructStub(function); | 7335 TrySettingInlineConstructStub(isolate, function); |
| 7030 } | 7336 } |
| 7031 | 7337 |
| 7032 Counters::constructed_objects.Increment(); | 7338 isolate->counters()->constructed_objects()->Increment(); |
| 7033 Counters::constructed_objects_runtime.Increment(); | 7339 isolate->counters()->constructed_objects_runtime()->Increment(); |
| 7034 | 7340 |
| 7035 return *result; | 7341 return *result; |
| 7036 } | 7342 } |
| 7037 | 7343 |
| 7038 | 7344 |
| 7039 static MaybeObject* Runtime_FinalizeInstanceSize(Arguments args) { | 7345 static MaybeObject* Runtime_FinalizeInstanceSize(RUNTIME_CALLING_CONVENTION) { |
| 7040 HandleScope scope; | 7346 RUNTIME_GET_ISOLATE; |
| 7347 HandleScope scope(isolate); |
| 7041 ASSERT(args.length() == 1); | 7348 ASSERT(args.length() == 1); |
| 7042 | 7349 |
| 7043 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 7350 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
| 7044 function->shared()->CompleteInobjectSlackTracking(); | 7351 function->shared()->CompleteInobjectSlackTracking(); |
| 7045 TrySettingInlineConstructStub(function); | 7352 TrySettingInlineConstructStub(isolate, function); |
| 7046 | 7353 |
| 7047 return Heap::undefined_value(); | 7354 return isolate->heap()->undefined_value(); |
| 7048 } | 7355 } |
| 7049 | 7356 |
| 7050 | 7357 |
| 7051 static MaybeObject* Runtime_LazyCompile(Arguments args) { | 7358 static MaybeObject* Runtime_LazyCompile(RUNTIME_CALLING_CONVENTION) { |
| 7052 HandleScope scope; | 7359 RUNTIME_GET_ISOLATE; |
| 7360 HandleScope scope(isolate); |
| 7053 ASSERT(args.length() == 1); | 7361 ASSERT(args.length() == 1); |
| 7054 | 7362 |
| 7055 Handle<JSFunction> function = args.at<JSFunction>(0); | 7363 Handle<JSFunction> function = args.at<JSFunction>(0); |
| 7056 #ifdef DEBUG | 7364 #ifdef DEBUG |
| 7057 if (FLAG_trace_lazy && !function->shared()->is_compiled()) { | 7365 if (FLAG_trace_lazy && !function->shared()->is_compiled()) { |
| 7058 PrintF("[lazy: "); | 7366 PrintF("[lazy: "); |
| 7059 function->PrintName(); | 7367 function->PrintName(); |
| 7060 PrintF("]\n"); | 7368 PrintF("]\n"); |
| 7061 } | 7369 } |
| 7062 #endif | 7370 #endif |
| 7063 | 7371 |
| 7064 // Compile the target function. Here we compile using CompileLazyInLoop in | 7372 // Compile the target function. Here we compile using CompileLazyInLoop in |
| 7065 // order to get the optimized version. This helps code like delta-blue | 7373 // order to get the optimized version. This helps code like delta-blue |
| 7066 // that calls performance-critical routines through constructors. A | 7374 // that calls performance-critical routines through constructors. A |
| 7067 // constructor call doesn't use a CallIC, it uses a LoadIC followed by a | 7375 // constructor call doesn't use a CallIC, it uses a LoadIC followed by a |
| 7068 // direct call. Since the in-loop tracking takes place through CallICs | 7376 // direct call. Since the in-loop tracking takes place through CallICs |
| 7069 // this means that things called through constructors are never known to | 7377 // this means that things called through constructors are never known to |
| 7070 // be in loops. We compile them as if they are in loops here just in case. | 7378 // be in loops. We compile them as if they are in loops here just in case. |
| 7071 ASSERT(!function->is_compiled()); | 7379 ASSERT(!function->is_compiled()); |
| 7072 if (!CompileLazyInLoop(function, KEEP_EXCEPTION)) { | 7380 if (!CompileLazyInLoop(function, KEEP_EXCEPTION)) { |
| 7073 return Failure::Exception(); | 7381 return Failure::Exception(); |
| 7074 } | 7382 } |
| 7075 | 7383 |
| 7076 // All done. Return the compiled code. | 7384 // All done. Return the compiled code. |
| 7077 ASSERT(function->is_compiled()); | 7385 ASSERT(function->is_compiled()); |
| 7078 return function->code(); | 7386 return function->code(); |
| 7079 } | 7387 } |
| 7080 | 7388 |
| 7081 | 7389 |
| 7082 static MaybeObject* Runtime_LazyRecompile(Arguments args) { | 7390 static MaybeObject* Runtime_LazyRecompile(RUNTIME_CALLING_CONVENTION) { |
| 7083 HandleScope scope; | 7391 RUNTIME_GET_ISOLATE; |
| 7392 HandleScope scope(isolate); |
| 7084 ASSERT(args.length() == 1); | 7393 ASSERT(args.length() == 1); |
| 7085 Handle<JSFunction> function = args.at<JSFunction>(0); | 7394 Handle<JSFunction> function = args.at<JSFunction>(0); |
| 7086 // If the function is not optimizable or debugger is active continue using the | 7395 // If the function is not optimizable or debugger is active continue using the |
| 7087 // code from the full compiler. | 7396 // code from the full compiler. |
| 7088 if (!function->shared()->code()->optimizable() || | 7397 if (!function->shared()->code()->optimizable() || |
| 7089 Debug::has_break_points()) { | 7398 isolate->debug()->has_break_points()) { |
| 7090 if (FLAG_trace_opt) { | 7399 if (FLAG_trace_opt) { |
| 7091 PrintF("[failed to optimize "); | 7400 PrintF("[failed to optimize "); |
| 7092 function->PrintName(); | 7401 function->PrintName(); |
| 7093 PrintF(": is code optimizable: %s, is debugger enabled: %s]\n", | 7402 PrintF(": is code optimizable: %s, is debugger enabled: %s]\n", |
| 7094 function->shared()->code()->optimizable() ? "T" : "F", | 7403 function->shared()->code()->optimizable() ? "T" : "F", |
| 7095 Debug::has_break_points() ? "T" : "F"); | 7404 isolate->debug()->has_break_points() ? "T" : "F"); |
| 7096 } | 7405 } |
| 7097 function->ReplaceCode(function->shared()->code()); | 7406 function->ReplaceCode(function->shared()->code()); |
| 7098 return function->code(); | 7407 return function->code(); |
| 7099 } | 7408 } |
| 7100 if (CompileOptimized(function, AstNode::kNoNumber, CLEAR_EXCEPTION)) { | 7409 if (CompileOptimized(function, AstNode::kNoNumber, CLEAR_EXCEPTION)) { |
| 7101 return function->code(); | 7410 return function->code(); |
| 7102 } | 7411 } |
| 7103 if (FLAG_trace_opt) { | 7412 if (FLAG_trace_opt) { |
| 7104 PrintF("[failed to optimize "); | 7413 PrintF("[failed to optimize "); |
| 7105 function->PrintName(); | 7414 function->PrintName(); |
| 7106 PrintF(": optimized compilation failed]\n"); | 7415 PrintF(": optimized compilation failed]\n"); |
| 7107 } | 7416 } |
| 7108 function->ReplaceCode(function->shared()->code()); | 7417 function->ReplaceCode(function->shared()->code()); |
| 7109 return function->code(); | 7418 return function->code(); |
| 7110 } | 7419 } |
| 7111 | 7420 |
| 7112 | 7421 |
| 7113 static MaybeObject* Runtime_NotifyDeoptimized(Arguments args) { | 7422 static MaybeObject* Runtime_NotifyDeoptimized(RUNTIME_CALLING_CONVENTION) { |
| 7114 HandleScope scope; | 7423 RUNTIME_GET_ISOLATE; |
| 7424 HandleScope scope(isolate); |
| 7115 ASSERT(args.length() == 1); | 7425 ASSERT(args.length() == 1); |
| 7116 RUNTIME_ASSERT(args[0]->IsSmi()); | 7426 RUNTIME_ASSERT(args[0]->IsSmi()); |
| 7117 Deoptimizer::BailoutType type = | 7427 Deoptimizer::BailoutType type = |
| 7118 static_cast<Deoptimizer::BailoutType>(Smi::cast(args[0])->value()); | 7428 static_cast<Deoptimizer::BailoutType>(Smi::cast(args[0])->value()); |
| 7119 Deoptimizer* deoptimizer = Deoptimizer::Grab(); | 7429 Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); |
| 7120 ASSERT(Heap::IsAllocationAllowed()); | 7430 ASSERT(isolate->heap()->IsAllocationAllowed()); |
| 7121 int frames = deoptimizer->output_count(); | 7431 int frames = deoptimizer->output_count(); |
| 7122 | 7432 |
| 7123 JavaScriptFrameIterator it; | 7433 JavaScriptFrameIterator it; |
| 7124 JavaScriptFrame* frame = NULL; | 7434 JavaScriptFrame* frame = NULL; |
| 7125 for (int i = 0; i < frames; i++) { | 7435 for (int i = 0; i < frames; i++) { |
| 7126 if (i != 0) it.Advance(); | 7436 if (i != 0) it.Advance(); |
| 7127 frame = it.frame(); | 7437 frame = it.frame(); |
| 7128 deoptimizer->InsertHeapNumberValues(frames - i - 1, frame); | 7438 deoptimizer->InsertHeapNumberValues(frames - i - 1, frame); |
| 7129 } | 7439 } |
| 7130 delete deoptimizer; | 7440 delete deoptimizer; |
| 7131 | 7441 |
| 7132 RUNTIME_ASSERT(frame->function()->IsJSFunction()); | 7442 RUNTIME_ASSERT(frame->function()->IsJSFunction()); |
| 7133 Handle<JSFunction> function(JSFunction::cast(frame->function())); | 7443 Handle<JSFunction> function(JSFunction::cast(frame->function()), isolate); |
| 7134 Handle<Object> arguments; | 7444 Handle<Object> arguments; |
| 7135 for (int i = frame->ComputeExpressionsCount() - 1; i >= 0; --i) { | 7445 for (int i = frame->ComputeExpressionsCount() - 1; i >= 0; --i) { |
| 7136 if (frame->GetExpression(i) == Heap::arguments_marker()) { | 7446 if (frame->GetExpression(i) == isolate->heap()->arguments_marker()) { |
| 7137 if (arguments.is_null()) { | 7447 if (arguments.is_null()) { |
| 7138 // FunctionGetArguments can't throw an exception, so cast away the | 7448 // FunctionGetArguments can't throw an exception, so cast away the |
| 7139 // doubt with an assert. | 7449 // doubt with an assert. |
| 7140 arguments = Handle<Object>( | 7450 arguments = Handle<Object>( |
| 7141 Accessors::FunctionGetArguments(*function, | 7451 Accessors::FunctionGetArguments(*function, |
| 7142 NULL)->ToObjectUnchecked()); | 7452 NULL)->ToObjectUnchecked()); |
| 7143 ASSERT(*arguments != Heap::null_value()); | 7453 ASSERT(*arguments != isolate->heap()->null_value()); |
| 7144 ASSERT(*arguments != Heap::undefined_value()); | 7454 ASSERT(*arguments != isolate->heap()->undefined_value()); |
| 7145 } | 7455 } |
| 7146 frame->SetExpression(i, *arguments); | 7456 frame->SetExpression(i, *arguments); |
| 7147 } | 7457 } |
| 7148 } | 7458 } |
| 7149 | 7459 |
| 7150 CompilationCache::MarkForLazyOptimizing(function); | 7460 isolate->compilation_cache()->MarkForLazyOptimizing(function); |
| 7151 if (type == Deoptimizer::EAGER) { | 7461 if (type == Deoptimizer::EAGER) { |
| 7152 RUNTIME_ASSERT(function->IsOptimized()); | 7462 RUNTIME_ASSERT(function->IsOptimized()); |
| 7153 } else { | 7463 } else { |
| 7154 RUNTIME_ASSERT(!function->IsOptimized()); | 7464 RUNTIME_ASSERT(!function->IsOptimized()); |
| 7155 } | 7465 } |
| 7156 | 7466 |
| 7157 // Avoid doing too much work when running with --always-opt and keep | 7467 // Avoid doing too much work when running with --always-opt and keep |
| 7158 // the optimized code around. | 7468 // the optimized code around. |
| 7159 if (FLAG_always_opt || type == Deoptimizer::LAZY) { | 7469 if (FLAG_always_opt || type == Deoptimizer::LAZY) { |
| 7160 return Heap::undefined_value(); | 7470 return isolate->heap()->undefined_value(); |
| 7161 } | 7471 } |
| 7162 | 7472 |
| 7163 // Count the number of optimized activations of the function. | 7473 // Count the number of optimized activations of the function. |
| 7164 int activations = 0; | 7474 int activations = 0; |
| 7165 while (!it.done()) { | 7475 while (!it.done()) { |
| 7166 JavaScriptFrame* frame = it.frame(); | 7476 JavaScriptFrame* frame = it.frame(); |
| 7167 if (frame->is_optimized() && frame->function() == *function) { | 7477 if (frame->is_optimized() && frame->function() == *function) { |
| 7168 activations++; | 7478 activations++; |
| 7169 } | 7479 } |
| 7170 it.Advance(); | 7480 it.Advance(); |
| 7171 } | 7481 } |
| 7172 | 7482 |
| 7173 // TODO(kasperl): For now, we cannot support removing the optimized | 7483 // TODO(kasperl): For now, we cannot support removing the optimized |
| 7174 // code when we have recursive invocations of the same function. | 7484 // code when we have recursive invocations of the same function. |
| 7175 if (activations == 0) { | 7485 if (activations == 0) { |
| 7176 if (FLAG_trace_deopt) { | 7486 if (FLAG_trace_deopt) { |
| 7177 PrintF("[removing optimized code for: "); | 7487 PrintF("[removing optimized code for: "); |
| 7178 function->PrintName(); | 7488 function->PrintName(); |
| 7179 PrintF("]\n"); | 7489 PrintF("]\n"); |
| 7180 } | 7490 } |
| 7181 function->ReplaceCode(function->shared()->code()); | 7491 function->ReplaceCode(function->shared()->code()); |
| 7182 } | 7492 } |
| 7183 return Heap::undefined_value(); | 7493 return isolate->heap()->undefined_value(); |
| 7184 } | 7494 } |
| 7185 | 7495 |
| 7186 | 7496 |
| 7187 static MaybeObject* Runtime_NotifyOSR(Arguments args) { | 7497 static MaybeObject* Runtime_NotifyOSR(RUNTIME_CALLING_CONVENTION) { |
| 7188 Deoptimizer* deoptimizer = Deoptimizer::Grab(); | 7498 RUNTIME_GET_ISOLATE; |
| 7499 Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); |
| 7189 delete deoptimizer; | 7500 delete deoptimizer; |
| 7190 return Heap::undefined_value(); | 7501 return isolate->heap()->undefined_value(); |
| 7191 } | 7502 } |
| 7192 | 7503 |
| 7193 | 7504 |
| 7194 static MaybeObject* Runtime_DeoptimizeFunction(Arguments args) { | 7505 static MaybeObject* Runtime_DeoptimizeFunction(RUNTIME_CALLING_CONVENTION) { |
| 7195 HandleScope scope; | 7506 RUNTIME_GET_ISOLATE; |
| 7507 HandleScope scope(isolate); |
| 7196 ASSERT(args.length() == 1); | 7508 ASSERT(args.length() == 1); |
| 7197 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 7509 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
| 7198 if (!function->IsOptimized()) return Heap::undefined_value(); | 7510 if (!function->IsOptimized()) return isolate->heap()->undefined_value(); |
| 7199 | 7511 |
| 7200 Deoptimizer::DeoptimizeFunction(*function); | 7512 Deoptimizer::DeoptimizeFunction(*function); |
| 7201 | 7513 |
| 7202 return Heap::undefined_value(); | 7514 return isolate->heap()->undefined_value(); |
| 7203 } | 7515 } |
| 7204 | 7516 |
| 7205 | 7517 |
| 7206 static MaybeObject* Runtime_CompileForOnStackReplacement(Arguments args) { | 7518 static MaybeObject* Runtime_CompileForOnStackReplacement( |
| 7207 HandleScope scope; | 7519 RUNTIME_CALLING_CONVENTION) { |
| 7520 RUNTIME_GET_ISOLATE; |
| 7521 HandleScope scope(isolate); |
| 7208 ASSERT(args.length() == 1); | 7522 ASSERT(args.length() == 1); |
| 7209 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 7523 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
| 7210 | 7524 |
| 7211 // We're not prepared to handle a function with arguments object. | 7525 // We're not prepared to handle a function with arguments object. |
| 7212 ASSERT(!function->shared()->scope_info()->HasArgumentsShadow()); | 7526 ASSERT(!function->shared()->scope_info()->HasArgumentsShadow()); |
| 7213 | 7527 |
| 7214 // We have hit a back edge in an unoptimized frame for a function that was | 7528 // We have hit a back edge in an unoptimized frame for a function that was |
| 7215 // selected for on-stack replacement. Find the unoptimized code object. | 7529 // selected for on-stack replacement. Find the unoptimized code object. |
| 7216 Handle<Code> unoptimized(function->shared()->code()); | 7530 Handle<Code> unoptimized(function->shared()->code(), isolate); |
| 7217 // Keep track of whether we've succeeded in optimizing. | 7531 // Keep track of whether we've succeeded in optimizing. |
| 7218 bool succeeded = unoptimized->optimizable(); | 7532 bool succeeded = unoptimized->optimizable(); |
| 7219 if (succeeded) { | 7533 if (succeeded) { |
| 7220 // If we are trying to do OSR when there are already optimized | 7534 // If we are trying to do OSR when there are already optimized |
| 7221 // activations of the function, it means (a) the function is directly or | 7535 // activations of the function, it means (a) the function is directly or |
| 7222 // indirectly recursive and (b) an optimized invocation has been | 7536 // indirectly recursive and (b) an optimized invocation has been |
| 7223 // deoptimized so that we are currently in an unoptimized activation. | 7537 // deoptimized so that we are currently in an unoptimized activation. |
| 7224 // Check for optimized activations of this function. | 7538 // Check for optimized activations of this function. |
| 7225 JavaScriptFrameIterator it; | 7539 JavaScriptFrameIterator it; |
| 7226 while (succeeded && !it.done()) { | 7540 while (succeeded && !it.done()) { |
| 7227 JavaScriptFrame* frame = it.frame(); | 7541 JavaScriptFrame* frame = it.frame(); |
| 7228 succeeded = !frame->is_optimized() || frame->function() != *function; | 7542 succeeded = !frame->is_optimized() || frame->function() != *function; |
| 7229 it.Advance(); | 7543 it.Advance(); |
| 7230 } | 7544 } |
| 7231 } | 7545 } |
| 7232 | 7546 |
| 7233 int ast_id = AstNode::kNoNumber; | 7547 int ast_id = AstNode::kNoNumber; |
| 7234 if (succeeded) { | 7548 if (succeeded) { |
| 7235 // The top JS function is this one, the PC is somewhere in the | 7549 // The top JS function is this one, the PC is somewhere in the |
| 7236 // unoptimized code. | 7550 // unoptimized code. |
| 7237 JavaScriptFrameIterator it; | 7551 JavaScriptFrameIterator it; |
| 7238 JavaScriptFrame* frame = it.frame(); | 7552 JavaScriptFrame* frame = it.frame(); |
| 7239 ASSERT(frame->function() == *function); | 7553 ASSERT(frame->function() == *function); |
| 7240 ASSERT(frame->code() == *unoptimized); | 7554 ASSERT(frame->LookupCode(isolate) == *unoptimized); |
| 7241 ASSERT(unoptimized->contains(frame->pc())); | 7555 ASSERT(unoptimized->contains(frame->pc())); |
| 7242 | 7556 |
| 7243 // Use linear search of the unoptimized code's stack check table to find | 7557 // Use linear search of the unoptimized code's stack check table to find |
| 7244 // the AST id matching the PC. | 7558 // the AST id matching the PC. |
| 7245 Address start = unoptimized->instruction_start(); | 7559 Address start = unoptimized->instruction_start(); |
| 7246 unsigned target_pc_offset = static_cast<unsigned>(frame->pc() - start); | 7560 unsigned target_pc_offset = static_cast<unsigned>(frame->pc() - start); |
| 7247 Address table_cursor = start + unoptimized->stack_check_table_offset(); | 7561 Address table_cursor = start + unoptimized->stack_check_table_offset(); |
| 7248 uint32_t table_length = Memory::uint32_at(table_cursor); | 7562 uint32_t table_length = Memory::uint32_at(table_cursor); |
| 7249 table_cursor += kIntSize; | 7563 table_cursor += kIntSize; |
| 7250 for (unsigned i = 0; i < table_length; ++i) { | 7564 for (unsigned i = 0; i < table_length; ++i) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7288 | 7602 |
| 7289 // Revert to the original stack checks in the original unoptimized code. | 7603 // Revert to the original stack checks in the original unoptimized code. |
| 7290 if (FLAG_trace_osr) { | 7604 if (FLAG_trace_osr) { |
| 7291 PrintF("[restoring original stack checks in "); | 7605 PrintF("[restoring original stack checks in "); |
| 7292 function->PrintName(); | 7606 function->PrintName(); |
| 7293 PrintF("]\n"); | 7607 PrintF("]\n"); |
| 7294 } | 7608 } |
| 7295 StackCheckStub check_stub; | 7609 StackCheckStub check_stub; |
| 7296 Handle<Code> check_code = check_stub.GetCode(); | 7610 Handle<Code> check_code = check_stub.GetCode(); |
| 7297 Handle<Code> replacement_code( | 7611 Handle<Code> replacement_code( |
| 7298 Builtins::builtin(Builtins::OnStackReplacement)); | 7612 isolate->builtins()->builtin(Builtins::OnStackReplacement)); |
| 7299 Deoptimizer::RevertStackCheckCode(*unoptimized, | 7613 Deoptimizer::RevertStackCheckCode(*unoptimized, |
| 7300 *check_code, | 7614 *check_code, |
| 7301 *replacement_code); | 7615 *replacement_code); |
| 7302 | 7616 |
| 7303 // Allow OSR only at nesting level zero again. | 7617 // Allow OSR only at nesting level zero again. |
| 7304 unoptimized->set_allow_osr_at_loop_nesting_level(0); | 7618 unoptimized->set_allow_osr_at_loop_nesting_level(0); |
| 7305 | 7619 |
| 7306 // If the optimization attempt succeeded, return the AST id tagged as a | 7620 // If the optimization attempt succeeded, return the AST id tagged as a |
| 7307 // smi. This tells the builtin that we need to translate the unoptimized | 7621 // smi. This tells the builtin that we need to translate the unoptimized |
| 7308 // frame to an optimized one. | 7622 // frame to an optimized one. |
| 7309 if (succeeded) { | 7623 if (succeeded) { |
| 7310 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION); | 7624 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION); |
| 7311 return Smi::FromInt(ast_id); | 7625 return Smi::FromInt(ast_id); |
| 7312 } else { | 7626 } else { |
| 7313 if (function->IsMarkedForLazyRecompilation()) { | 7627 if (function->IsMarkedForLazyRecompilation()) { |
| 7314 function->ReplaceCode(function->shared()->code()); | 7628 function->ReplaceCode(function->shared()->code()); |
| 7315 } | 7629 } |
| 7316 return Smi::FromInt(-1); | 7630 return Smi::FromInt(-1); |
| 7317 } | 7631 } |
| 7318 } | 7632 } |
| 7319 | 7633 |
| 7320 | 7634 |
| 7321 static MaybeObject* Runtime_GetFunctionDelegate(Arguments args) { | 7635 static MaybeObject* Runtime_GetFunctionDelegate(RUNTIME_CALLING_CONVENTION) { |
| 7322 HandleScope scope; | 7636 RUNTIME_GET_ISOLATE; |
| 7637 HandleScope scope(isolate); |
| 7323 ASSERT(args.length() == 1); | 7638 ASSERT(args.length() == 1); |
| 7324 RUNTIME_ASSERT(!args[0]->IsJSFunction()); | 7639 RUNTIME_ASSERT(!args[0]->IsJSFunction()); |
| 7325 return *Execution::GetFunctionDelegate(args.at<Object>(0)); | 7640 return *Execution::GetFunctionDelegate(args.at<Object>(0)); |
| 7326 } | 7641 } |
| 7327 | 7642 |
| 7328 | 7643 |
| 7329 static MaybeObject* Runtime_GetConstructorDelegate(Arguments args) { | 7644 static MaybeObject* Runtime_GetConstructorDelegate(RUNTIME_CALLING_CONVENTION) { |
| 7330 HandleScope scope; | 7645 RUNTIME_GET_ISOLATE; |
| 7646 HandleScope scope(isolate); |
| 7331 ASSERT(args.length() == 1); | 7647 ASSERT(args.length() == 1); |
| 7332 RUNTIME_ASSERT(!args[0]->IsJSFunction()); | 7648 RUNTIME_ASSERT(!args[0]->IsJSFunction()); |
| 7333 return *Execution::GetConstructorDelegate(args.at<Object>(0)); | 7649 return *Execution::GetConstructorDelegate(args.at<Object>(0)); |
| 7334 } | 7650 } |
| 7335 | 7651 |
| 7336 | 7652 |
| 7337 static MaybeObject* Runtime_NewContext(Arguments args) { | 7653 static MaybeObject* Runtime_NewContext(RUNTIME_CALLING_CONVENTION) { |
| 7654 RUNTIME_GET_ISOLATE; |
| 7338 NoHandleAllocation ha; | 7655 NoHandleAllocation ha; |
| 7339 ASSERT(args.length() == 1); | 7656 ASSERT(args.length() == 1); |
| 7340 | 7657 |
| 7341 CONVERT_CHECKED(JSFunction, function, args[0]); | 7658 CONVERT_CHECKED(JSFunction, function, args[0]); |
| 7342 int length = function->shared()->scope_info()->NumberOfContextSlots(); | 7659 int length = function->shared()->scope_info()->NumberOfContextSlots(); |
| 7343 Object* result; | 7660 Object* result; |
| 7344 { MaybeObject* maybe_result = Heap::AllocateFunctionContext(length, function); | 7661 { MaybeObject* maybe_result = |
| 7662 isolate->heap()->AllocateFunctionContext(length, function); |
| 7345 if (!maybe_result->ToObject(&result)) return maybe_result; | 7663 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 7346 } | 7664 } |
| 7347 | 7665 |
| 7348 Top::set_context(Context::cast(result)); | 7666 isolate->set_context(Context::cast(result)); |
| 7349 | 7667 |
| 7350 return result; // non-failure | 7668 return result; // non-failure |
| 7351 } | 7669 } |
| 7352 | 7670 |
| 7353 | 7671 |
| 7354 MUST_USE_RESULT static MaybeObject* PushContextHelper(Object* object, | 7672 MUST_USE_RESULT static MaybeObject* PushContextHelper(Isolate* isolate, |
| 7673 Object* object, |
| 7355 bool is_catch_context) { | 7674 bool is_catch_context) { |
| 7356 // Convert the object to a proper JavaScript object. | 7675 // Convert the object to a proper JavaScript object. |
| 7357 Object* js_object = object; | 7676 Object* js_object = object; |
| 7358 if (!js_object->IsJSObject()) { | 7677 if (!js_object->IsJSObject()) { |
| 7359 MaybeObject* maybe_js_object = js_object->ToObject(); | 7678 MaybeObject* maybe_js_object = js_object->ToObject(); |
| 7360 if (!maybe_js_object->ToObject(&js_object)) { | 7679 if (!maybe_js_object->ToObject(&js_object)) { |
| 7361 if (!Failure::cast(maybe_js_object)->IsInternalError()) { | 7680 if (!Failure::cast(maybe_js_object)->IsInternalError()) { |
| 7362 return maybe_js_object; | 7681 return maybe_js_object; |
| 7363 } | 7682 } |
| 7364 HandleScope scope; | 7683 HandleScope scope(isolate); |
| 7365 Handle<Object> handle(object); | 7684 Handle<Object> handle(object, isolate); |
| 7366 Handle<Object> result = | 7685 Handle<Object> result = |
| 7367 Factory::NewTypeError("with_expression", HandleVector(&handle, 1)); | 7686 isolate->factory()->NewTypeError("with_expression", |
| 7368 return Top::Throw(*result); | 7687 HandleVector(&handle, 1)); |
| 7688 return isolate->Throw(*result); |
| 7369 } | 7689 } |
| 7370 } | 7690 } |
| 7371 | 7691 |
| 7372 Object* result; | 7692 Object* result; |
| 7373 { MaybeObject* maybe_result = | 7693 { MaybeObject* maybe_result = isolate->heap()->AllocateWithContext( |
| 7374 Heap::AllocateWithContext(Top::context(), | 7694 isolate->context(), JSObject::cast(js_object), is_catch_context); |
| 7375 JSObject::cast(js_object), | |
| 7376 is_catch_context); | |
| 7377 if (!maybe_result->ToObject(&result)) return maybe_result; | 7695 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 7378 } | 7696 } |
| 7379 | 7697 |
| 7380 Context* context = Context::cast(result); | 7698 Context* context = Context::cast(result); |
| 7381 Top::set_context(context); | 7699 isolate->set_context(context); |
| 7382 | 7700 |
| 7383 return result; | 7701 return result; |
| 7384 } | 7702 } |
| 7385 | 7703 |
| 7386 | 7704 |
| 7387 static MaybeObject* Runtime_PushContext(Arguments args) { | 7705 static MaybeObject* Runtime_PushContext(RUNTIME_CALLING_CONVENTION) { |
| 7706 RUNTIME_GET_ISOLATE; |
| 7388 NoHandleAllocation ha; | 7707 NoHandleAllocation ha; |
| 7389 ASSERT(args.length() == 1); | 7708 ASSERT(args.length() == 1); |
| 7390 return PushContextHelper(args[0], false); | 7709 return PushContextHelper(isolate, args[0], false); |
| 7391 } | 7710 } |
| 7392 | 7711 |
| 7393 | 7712 |
| 7394 static MaybeObject* Runtime_PushCatchContext(Arguments args) { | 7713 static MaybeObject* Runtime_PushCatchContext(RUNTIME_CALLING_CONVENTION) { |
| 7714 RUNTIME_GET_ISOLATE; |
| 7395 NoHandleAllocation ha; | 7715 NoHandleAllocation ha; |
| 7396 ASSERT(args.length() == 1); | 7716 ASSERT(args.length() == 1); |
| 7397 return PushContextHelper(args[0], true); | 7717 return PushContextHelper(isolate, args[0], true); |
| 7398 } | 7718 } |
| 7399 | 7719 |
| 7400 | 7720 |
| 7401 static MaybeObject* Runtime_DeleteContextSlot(Arguments args) { | 7721 static MaybeObject* Runtime_DeleteContextSlot(RUNTIME_CALLING_CONVENTION) { |
| 7402 HandleScope scope; | 7722 RUNTIME_GET_ISOLATE; |
| 7723 HandleScope scope(isolate); |
| 7403 ASSERT(args.length() == 2); | 7724 ASSERT(args.length() == 2); |
| 7404 | 7725 |
| 7405 CONVERT_ARG_CHECKED(Context, context, 0); | 7726 CONVERT_ARG_CHECKED(Context, context, 0); |
| 7406 CONVERT_ARG_CHECKED(String, name, 1); | 7727 CONVERT_ARG_CHECKED(String, name, 1); |
| 7407 | 7728 |
| 7408 int index; | 7729 int index; |
| 7409 PropertyAttributes attributes; | 7730 PropertyAttributes attributes; |
| 7410 ContextLookupFlags flags = FOLLOW_CHAINS; | 7731 ContextLookupFlags flags = FOLLOW_CHAINS; |
| 7411 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes); | 7732 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes); |
| 7412 | 7733 |
| 7413 // If the slot was not found the result is true. | 7734 // If the slot was not found the result is true. |
| 7414 if (holder.is_null()) { | 7735 if (holder.is_null()) { |
| 7415 return Heap::true_value(); | 7736 return isolate->heap()->true_value(); |
| 7416 } | 7737 } |
| 7417 | 7738 |
| 7418 // If the slot was found in a context, it should be DONT_DELETE. | 7739 // If the slot was found in a context, it should be DONT_DELETE. |
| 7419 if (holder->IsContext()) { | 7740 if (holder->IsContext()) { |
| 7420 return Heap::false_value(); | 7741 return isolate->heap()->false_value(); |
| 7421 } | 7742 } |
| 7422 | 7743 |
| 7423 // The slot was found in a JSObject, either a context extension object, | 7744 // The slot was found in a JSObject, either a context extension object, |
| 7424 // the global object, or an arguments object. Try to delete it | 7745 // the global object, or an arguments object. Try to delete it |
| 7425 // (respecting DONT_DELETE). For consistency with V8's usual behavior, | 7746 // (respecting DONT_DELETE). For consistency with V8's usual behavior, |
| 7426 // which allows deleting all parameters in functions that mention | 7747 // which allows deleting all parameters in functions that mention |
| 7427 // 'arguments', we do this even for the case of slots found on an | 7748 // 'arguments', we do this even for the case of slots found on an |
| 7428 // arguments object. The slot was found on an arguments object if the | 7749 // arguments object. The slot was found on an arguments object if the |
| 7429 // index is non-negative. | 7750 // index is non-negative. |
| 7430 Handle<JSObject> object = Handle<JSObject>::cast(holder); | 7751 Handle<JSObject> object = Handle<JSObject>::cast(holder); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 7458 } | 7779 } |
| 7459 #else | 7780 #else |
| 7460 typedef uint64_t ObjectPair; | 7781 typedef uint64_t ObjectPair; |
| 7461 static inline ObjectPair MakePair(MaybeObject* x, MaybeObject* y) { | 7782 static inline ObjectPair MakePair(MaybeObject* x, MaybeObject* y) { |
| 7462 return reinterpret_cast<uint32_t>(x) | | 7783 return reinterpret_cast<uint32_t>(x) | |
| 7463 (reinterpret_cast<ObjectPair>(y) << 32); | 7784 (reinterpret_cast<ObjectPair>(y) << 32); |
| 7464 } | 7785 } |
| 7465 #endif | 7786 #endif |
| 7466 | 7787 |
| 7467 | 7788 |
| 7468 static inline MaybeObject* Unhole(MaybeObject* x, | 7789 static inline MaybeObject* Unhole(Heap* heap, |
| 7790 MaybeObject* x, |
| 7469 PropertyAttributes attributes) { | 7791 PropertyAttributes attributes) { |
| 7470 ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0); | 7792 ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0); |
| 7471 USE(attributes); | 7793 USE(attributes); |
| 7472 return x->IsTheHole() ? Heap::undefined_value() : x; | 7794 return x->IsTheHole() ? heap->undefined_value() : x; |
| 7473 } | 7795 } |
| 7474 | 7796 |
| 7475 | 7797 |
| 7476 static JSObject* ComputeReceiverForNonGlobal(JSObject* holder) { | 7798 static JSObject* ComputeReceiverForNonGlobal(Isolate* isolate, |
| 7799 JSObject* holder) { |
| 7477 ASSERT(!holder->IsGlobalObject()); | 7800 ASSERT(!holder->IsGlobalObject()); |
| 7478 Context* top = Top::context(); | 7801 Context* top = isolate->context(); |
| 7479 // Get the context extension function. | 7802 // Get the context extension function. |
| 7480 JSFunction* context_extension_function = | 7803 JSFunction* context_extension_function = |
| 7481 top->global_context()->context_extension_function(); | 7804 top->global_context()->context_extension_function(); |
| 7482 // If the holder isn't a context extension object, we just return it | 7805 // If the holder isn't a context extension object, we just return it |
| 7483 // as the receiver. This allows arguments objects to be used as | 7806 // as the receiver. This allows arguments objects to be used as |
| 7484 // receivers, but only if they are put in the context scope chain | 7807 // receivers, but only if they are put in the context scope chain |
| 7485 // explicitly via a with-statement. | 7808 // explicitly via a with-statement. |
| 7486 Object* constructor = holder->map()->constructor(); | 7809 Object* constructor = holder->map()->constructor(); |
| 7487 if (constructor != context_extension_function) return holder; | 7810 if (constructor != context_extension_function) return holder; |
| 7488 // Fall back to using the global object as the receiver if the | 7811 // Fall back to using the global object as the receiver if the |
| 7489 // property turns out to be a local variable allocated in a context | 7812 // property turns out to be a local variable allocated in a context |
| 7490 // extension object - introduced via eval. | 7813 // extension object - introduced via eval. |
| 7491 return top->global()->global_receiver(); | 7814 return top->global()->global_receiver(); |
| 7492 } | 7815 } |
| 7493 | 7816 |
| 7494 | 7817 |
| 7495 static ObjectPair LoadContextSlotHelper(Arguments args, bool throw_error) { | 7818 static ObjectPair LoadContextSlotHelper(Arguments args, |
| 7496 HandleScope scope; | 7819 Isolate* isolate, |
| 7820 bool throw_error) { |
| 7821 HandleScope scope(isolate); |
| 7497 ASSERT_EQ(2, args.length()); | 7822 ASSERT_EQ(2, args.length()); |
| 7498 | 7823 |
| 7499 if (!args[0]->IsContext() || !args[1]->IsString()) { | 7824 if (!args[0]->IsContext() || !args[1]->IsString()) { |
| 7500 return MakePair(Top::ThrowIllegalOperation(), NULL); | 7825 return MakePair(isolate->ThrowIllegalOperation(), NULL); |
| 7501 } | 7826 } |
| 7502 Handle<Context> context = args.at<Context>(0); | 7827 Handle<Context> context = args.at<Context>(0); |
| 7503 Handle<String> name = args.at<String>(1); | 7828 Handle<String> name = args.at<String>(1); |
| 7504 | 7829 |
| 7505 int index; | 7830 int index; |
| 7506 PropertyAttributes attributes; | 7831 PropertyAttributes attributes; |
| 7507 ContextLookupFlags flags = FOLLOW_CHAINS; | 7832 ContextLookupFlags flags = FOLLOW_CHAINS; |
| 7508 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes); | 7833 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes); |
| 7509 | 7834 |
| 7510 // If the index is non-negative, the slot has been found in a local | 7835 // If the index is non-negative, the slot has been found in a local |
| 7511 // variable or a parameter. Read it from the context object or the | 7836 // variable or a parameter. Read it from the context object or the |
| 7512 // arguments object. | 7837 // arguments object. |
| 7513 if (index >= 0) { | 7838 if (index >= 0) { |
| 7514 // If the "property" we were looking for is a local variable or an | 7839 // If the "property" we were looking for is a local variable or an |
| 7515 // argument in a context, the receiver is the global object; see | 7840 // argument in a context, the receiver is the global object; see |
| 7516 // ECMA-262, 3rd., 10.1.6 and 10.2.3. | 7841 // ECMA-262, 3rd., 10.1.6 and 10.2.3. |
| 7517 JSObject* receiver = Top::context()->global()->global_receiver(); | 7842 JSObject* receiver = |
| 7843 isolate->context()->global()->global_receiver(); |
| 7518 MaybeObject* value = (holder->IsContext()) | 7844 MaybeObject* value = (holder->IsContext()) |
| 7519 ? Context::cast(*holder)->get(index) | 7845 ? Context::cast(*holder)->get(index) |
| 7520 : JSObject::cast(*holder)->GetElement(index); | 7846 : JSObject::cast(*holder)->GetElement(index); |
| 7521 return MakePair(Unhole(value, attributes), receiver); | 7847 return MakePair(Unhole(isolate->heap(), value, attributes), receiver); |
| 7522 } | 7848 } |
| 7523 | 7849 |
| 7524 // If the holder is found, we read the property from it. | 7850 // If the holder is found, we read the property from it. |
| 7525 if (!holder.is_null() && holder->IsJSObject()) { | 7851 if (!holder.is_null() && holder->IsJSObject()) { |
| 7526 ASSERT(Handle<JSObject>::cast(holder)->HasProperty(*name)); | 7852 ASSERT(Handle<JSObject>::cast(holder)->HasProperty(*name)); |
| 7527 JSObject* object = JSObject::cast(*holder); | 7853 JSObject* object = JSObject::cast(*holder); |
| 7528 JSObject* receiver; | 7854 JSObject* receiver; |
| 7529 if (object->IsGlobalObject()) { | 7855 if (object->IsGlobalObject()) { |
| 7530 receiver = GlobalObject::cast(object)->global_receiver(); | 7856 receiver = GlobalObject::cast(object)->global_receiver(); |
| 7531 } else if (context->is_exception_holder(*holder)) { | 7857 } else if (context->is_exception_holder(*holder)) { |
| 7532 receiver = Top::context()->global()->global_receiver(); | 7858 receiver = isolate->context()->global()->global_receiver(); |
| 7533 } else { | 7859 } else { |
| 7534 receiver = ComputeReceiverForNonGlobal(object); | 7860 receiver = ComputeReceiverForNonGlobal(isolate, object); |
| 7535 } | 7861 } |
| 7536 // No need to unhole the value here. This is taken care of by the | 7862 // No need to unhole the value here. This is taken care of by the |
| 7537 // GetProperty function. | 7863 // GetProperty function. |
| 7538 MaybeObject* value = object->GetProperty(*name); | 7864 MaybeObject* value = object->GetProperty(*name); |
| 7539 return MakePair(value, receiver); | 7865 return MakePair(value, receiver); |
| 7540 } | 7866 } |
| 7541 | 7867 |
| 7542 if (throw_error) { | 7868 if (throw_error) { |
| 7543 // The property doesn't exist - throw exception. | 7869 // The property doesn't exist - throw exception. |
| 7544 Handle<Object> reference_error = | 7870 Handle<Object> reference_error = |
| 7545 Factory::NewReferenceError("not_defined", HandleVector(&name, 1)); | 7871 isolate->factory()->NewReferenceError("not_defined", |
| 7546 return MakePair(Top::Throw(*reference_error), NULL); | 7872 HandleVector(&name, 1)); |
| 7873 return MakePair(isolate->Throw(*reference_error), NULL); |
| 7547 } else { | 7874 } else { |
| 7548 // The property doesn't exist - return undefined | 7875 // The property doesn't exist - return undefined |
| 7549 return MakePair(Heap::undefined_value(), Heap::undefined_value()); | 7876 return MakePair(isolate->heap()->undefined_value(), |
| 7877 isolate->heap()->undefined_value()); |
| 7550 } | 7878 } |
| 7551 } | 7879 } |
| 7552 | 7880 |
| 7553 | 7881 |
| 7554 static ObjectPair Runtime_LoadContextSlot(Arguments args) { | 7882 static ObjectPair Runtime_LoadContextSlot(RUNTIME_CALLING_CONVENTION) { |
| 7555 return LoadContextSlotHelper(args, true); | 7883 RUNTIME_GET_ISOLATE; |
| 7884 return LoadContextSlotHelper(args, isolate, true); |
| 7556 } | 7885 } |
| 7557 | 7886 |
| 7558 | 7887 |
| 7559 static ObjectPair Runtime_LoadContextSlotNoReferenceError(Arguments args) { | 7888 static ObjectPair Runtime_LoadContextSlotNoReferenceError( |
| 7560 return LoadContextSlotHelper(args, false); | 7889 RUNTIME_CALLING_CONVENTION) { |
| 7890 RUNTIME_GET_ISOLATE; |
| 7891 return LoadContextSlotHelper(args, isolate, false); |
| 7561 } | 7892 } |
| 7562 | 7893 |
| 7563 | 7894 |
| 7564 static MaybeObject* Runtime_StoreContextSlot(Arguments args) { | 7895 static MaybeObject* Runtime_StoreContextSlot(RUNTIME_CALLING_CONVENTION) { |
| 7565 HandleScope scope; | 7896 RUNTIME_GET_ISOLATE; |
| 7897 HandleScope scope(isolate); |
| 7566 ASSERT(args.length() == 4); | 7898 ASSERT(args.length() == 4); |
| 7567 | 7899 |
| 7568 Handle<Object> value(args[0]); | 7900 Handle<Object> value(args[0], isolate); |
| 7569 CONVERT_ARG_CHECKED(Context, context, 1); | 7901 CONVERT_ARG_CHECKED(Context, context, 1); |
| 7570 CONVERT_ARG_CHECKED(String, name, 2); | 7902 CONVERT_ARG_CHECKED(String, name, 2); |
| 7571 CONVERT_SMI_CHECKED(strict_unchecked, args[3]); | 7903 CONVERT_SMI_CHECKED(strict_unchecked, args[3]); |
| 7572 RUNTIME_ASSERT(strict_unchecked == kStrictMode || | 7904 RUNTIME_ASSERT(strict_unchecked == kStrictMode || |
| 7573 strict_unchecked == kNonStrictMode); | 7905 strict_unchecked == kNonStrictMode); |
| 7574 StrictModeFlag strict_mode = static_cast<StrictModeFlag>(strict_unchecked); | 7906 StrictModeFlag strict_mode = static_cast<StrictModeFlag>(strict_unchecked); |
| 7575 | 7907 |
| 7576 int index; | 7908 int index; |
| 7577 PropertyAttributes attributes; | 7909 PropertyAttributes attributes; |
| 7578 ContextLookupFlags flags = FOLLOW_CHAINS; | 7910 ContextLookupFlags flags = FOLLOW_CHAINS; |
| 7579 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes); | 7911 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes); |
| 7580 | 7912 |
| 7581 if (index >= 0) { | 7913 if (index >= 0) { |
| 7582 if (holder->IsContext()) { | 7914 if (holder->IsContext()) { |
| 7583 // Ignore if read_only variable. | 7915 // Ignore if read_only variable. |
| 7584 if ((attributes & READ_ONLY) == 0) { | 7916 if ((attributes & READ_ONLY) == 0) { |
| 7585 // Context is a fixed array and set cannot fail. | 7917 // Context is a fixed array and set cannot fail. |
| 7586 Context::cast(*holder)->set(index, *value); | 7918 Context::cast(*holder)->set(index, *value); |
| 7587 } else if (strict_mode == kStrictMode) { | 7919 } else if (strict_mode == kStrictMode) { |
| 7588 // Setting read only property in strict mode. | 7920 // Setting read only property in strict mode. |
| 7589 Handle<Object> error = | 7921 Handle<Object> error = |
| 7590 Factory::NewTypeError("strict_cannot_assign", | 7922 isolate->factory()->NewTypeError("strict_cannot_assign", |
| 7591 HandleVector(&name, 1)); | 7923 HandleVector(&name, 1)); |
| 7592 return Top::Throw(*error); | 7924 return isolate->Throw(*error); |
| 7593 } | 7925 } |
| 7594 } else { | 7926 } else { |
| 7595 ASSERT((attributes & READ_ONLY) == 0); | 7927 ASSERT((attributes & READ_ONLY) == 0); |
| 7596 Handle<Object> result = | 7928 Handle<Object> result = |
| 7597 SetElement(Handle<JSObject>::cast(holder), index, value, strict_mode); | 7929 SetElement(Handle<JSObject>::cast(holder), index, value, strict_mode); |
| 7598 if (result.is_null()) { | 7930 if (result.is_null()) { |
| 7599 ASSERT(Top::has_pending_exception()); | 7931 ASSERT(isolate->has_pending_exception()); |
| 7600 return Failure::Exception(); | 7932 return Failure::Exception(); |
| 7601 } | 7933 } |
| 7602 } | 7934 } |
| 7603 return *value; | 7935 return *value; |
| 7604 } | 7936 } |
| 7605 | 7937 |
| 7606 // Slow case: The property is not in a FixedArray context. | 7938 // Slow case: The property is not in a FixedArray context. |
| 7607 // It is either in an JSObject extension context or it was not found. | 7939 // It is either in an JSObject extension context or it was not found. |
| 7608 Handle<JSObject> context_ext; | 7940 Handle<JSObject> context_ext; |
| 7609 | 7941 |
| 7610 if (!holder.is_null()) { | 7942 if (!holder.is_null()) { |
| 7611 // The property exists in the extension context. | 7943 // The property exists in the extension context. |
| 7612 context_ext = Handle<JSObject>::cast(holder); | 7944 context_ext = Handle<JSObject>::cast(holder); |
| 7613 } else { | 7945 } else { |
| 7614 // The property was not found. It needs to be stored in the global context. | 7946 // The property was not found. It needs to be stored in the global context. |
| 7615 ASSERT(attributes == ABSENT); | 7947 ASSERT(attributes == ABSENT); |
| 7616 attributes = NONE; | 7948 attributes = NONE; |
| 7617 context_ext = Handle<JSObject>(Top::context()->global()); | 7949 context_ext = Handle<JSObject>(isolate->context()->global()); |
| 7618 } | 7950 } |
| 7619 | 7951 |
| 7620 // Set the property, but ignore if read_only variable on the context | 7952 // Set the property, but ignore if read_only variable on the context |
| 7621 // extension object itself. | 7953 // extension object itself. |
| 7622 if ((attributes & READ_ONLY) == 0 || | 7954 if ((attributes & READ_ONLY) == 0 || |
| 7623 (context_ext->GetLocalPropertyAttribute(*name) == ABSENT)) { | 7955 (context_ext->GetLocalPropertyAttribute(*name) == ABSENT)) { |
| 7624 RETURN_IF_EMPTY_HANDLE( | 7956 RETURN_IF_EMPTY_HANDLE( |
| 7957 isolate, |
| 7625 SetProperty(context_ext, name, value, NONE, strict_mode)); | 7958 SetProperty(context_ext, name, value, NONE, strict_mode)); |
| 7626 } else if (strict_mode == kStrictMode && (attributes & READ_ONLY) != 0) { | 7959 } else if (strict_mode == kStrictMode && (attributes & READ_ONLY) != 0) { |
| 7627 // Setting read only property in strict mode. | 7960 // Setting read only property in strict mode. |
| 7628 Handle<Object> error = | 7961 Handle<Object> error = |
| 7629 Factory::NewTypeError("strict_cannot_assign", HandleVector(&name, 1)); | 7962 isolate->factory()->NewTypeError( |
| 7630 return Top::Throw(*error); | 7963 "strict_cannot_assign", HandleVector(&name, 1)); |
| 7964 return isolate->Throw(*error); |
| 7631 } | 7965 } |
| 7632 return *value; | 7966 return *value; |
| 7633 } | 7967 } |
| 7634 | 7968 |
| 7635 | 7969 |
| 7636 static MaybeObject* Runtime_Throw(Arguments args) { | 7970 static MaybeObject* Runtime_Throw(RUNTIME_CALLING_CONVENTION) { |
| 7637 HandleScope scope; | 7971 RUNTIME_GET_ISOLATE; |
| 7972 HandleScope scope(isolate); |
| 7638 ASSERT(args.length() == 1); | 7973 ASSERT(args.length() == 1); |
| 7639 | 7974 |
| 7640 return Top::Throw(args[0]); | 7975 return isolate->Throw(args[0]); |
| 7641 } | 7976 } |
| 7642 | 7977 |
| 7643 | 7978 |
| 7644 static MaybeObject* Runtime_ReThrow(Arguments args) { | 7979 static MaybeObject* Runtime_ReThrow(RUNTIME_CALLING_CONVENTION) { |
| 7645 HandleScope scope; | 7980 RUNTIME_GET_ISOLATE; |
| 7981 HandleScope scope(isolate); |
| 7646 ASSERT(args.length() == 1); | 7982 ASSERT(args.length() == 1); |
| 7647 | 7983 |
| 7648 return Top::ReThrow(args[0]); | 7984 return isolate->ReThrow(args[0]); |
| 7649 } | 7985 } |
| 7650 | 7986 |
| 7651 | 7987 |
| 7652 static MaybeObject* Runtime_PromoteScheduledException(Arguments args) { | 7988 static MaybeObject* Runtime_PromoteScheduledException( |
| 7989 RUNTIME_CALLING_CONVENTION) { |
| 7990 RUNTIME_GET_ISOLATE; |
| 7653 ASSERT_EQ(0, args.length()); | 7991 ASSERT_EQ(0, args.length()); |
| 7654 return Top::PromoteScheduledException(); | 7992 return isolate->PromoteScheduledException(); |
| 7655 } | 7993 } |
| 7656 | 7994 |
| 7657 | 7995 |
| 7658 static MaybeObject* Runtime_ThrowReferenceError(Arguments args) { | 7996 static MaybeObject* Runtime_ThrowReferenceError(RUNTIME_CALLING_CONVENTION) { |
| 7659 HandleScope scope; | 7997 RUNTIME_GET_ISOLATE; |
| 7998 HandleScope scope(isolate); |
| 7660 ASSERT(args.length() == 1); | 7999 ASSERT(args.length() == 1); |
| 7661 | 8000 |
| 7662 Handle<Object> name(args[0]); | 8001 Handle<Object> name(args[0], isolate); |
| 7663 Handle<Object> reference_error = | 8002 Handle<Object> reference_error = |
| 7664 Factory::NewReferenceError("not_defined", HandleVector(&name, 1)); | 8003 isolate->factory()->NewReferenceError("not_defined", |
| 7665 return Top::Throw(*reference_error); | 8004 HandleVector(&name, 1)); |
| 8005 return isolate->Throw(*reference_error); |
| 7666 } | 8006 } |
| 7667 | 8007 |
| 7668 | 8008 |
| 7669 static MaybeObject* Runtime_StackOverflow(Arguments args) { | 8009 static MaybeObject* Runtime_StackGuard(RUNTIME_CALLING_CONVENTION) { |
| 7670 NoHandleAllocation na; | 8010 RUNTIME_GET_ISOLATE; |
| 7671 return Top::StackOverflow(); | |
| 7672 } | |
| 7673 | |
| 7674 | |
| 7675 static MaybeObject* Runtime_StackGuard(Arguments args) { | |
| 7676 ASSERT(args.length() == 0); | 8011 ASSERT(args.length() == 0); |
| 7677 | 8012 |
| 7678 // First check if this is a real stack overflow. | 8013 // First check if this is a real stack overflow. |
| 7679 if (StackGuard::IsStackOverflow()) { | 8014 if (isolate->stack_guard()->IsStackOverflow()) { |
| 7680 return Runtime_StackOverflow(args); | 8015 NoHandleAllocation na; |
| 8016 return isolate->StackOverflow(); |
| 7681 } | 8017 } |
| 7682 | 8018 |
| 7683 return Execution::HandleStackGuardInterrupt(); | 8019 return Execution::HandleStackGuardInterrupt(); |
| 7684 } | 8020 } |
| 7685 | 8021 |
| 7686 | 8022 |
| 7687 // NOTE: These PrintXXX functions are defined for all builds (not just | 8023 // NOTE: These PrintXXX functions are defined for all builds (not just |
| 7688 // DEBUG builds) because we may want to be able to trace function | 8024 // DEBUG builds) because we may want to be able to trace function |
| 7689 // calls in all modes. | 8025 // calls in all modes. |
| 7690 static void PrintString(String* str) { | 8026 static void PrintString(String* str) { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7763 | 8099 |
| 7764 } else { | 8100 } else { |
| 7765 // function result | 8101 // function result |
| 7766 PrintF("} -> "); | 8102 PrintF("} -> "); |
| 7767 PrintObject(result); | 8103 PrintObject(result); |
| 7768 PrintF("\n"); | 8104 PrintF("\n"); |
| 7769 } | 8105 } |
| 7770 } | 8106 } |
| 7771 | 8107 |
| 7772 | 8108 |
| 7773 static MaybeObject* Runtime_TraceEnter(Arguments args) { | 8109 static MaybeObject* Runtime_TraceEnter(RUNTIME_CALLING_CONVENTION) { |
| 8110 RUNTIME_GET_ISOLATE; |
| 7774 ASSERT(args.length() == 0); | 8111 ASSERT(args.length() == 0); |
| 7775 NoHandleAllocation ha; | 8112 NoHandleAllocation ha; |
| 7776 PrintTransition(NULL); | 8113 PrintTransition(NULL); |
| 7777 return Heap::undefined_value(); | 8114 return isolate->heap()->undefined_value(); |
| 7778 } | 8115 } |
| 7779 | 8116 |
| 7780 | 8117 |
| 7781 static MaybeObject* Runtime_TraceExit(Arguments args) { | 8118 static MaybeObject* Runtime_TraceExit(RUNTIME_CALLING_CONVENTION) { |
| 8119 RUNTIME_GET_ISOLATE; |
| 7782 NoHandleAllocation ha; | 8120 NoHandleAllocation ha; |
| 7783 PrintTransition(args[0]); | 8121 PrintTransition(args[0]); |
| 7784 return args[0]; // return TOS | 8122 return args[0]; // return TOS |
| 7785 } | 8123 } |
| 7786 | 8124 |
| 7787 | 8125 |
| 7788 static MaybeObject* Runtime_DebugPrint(Arguments args) { | 8126 static MaybeObject* Runtime_DebugPrint(RUNTIME_CALLING_CONVENTION) { |
| 8127 RUNTIME_GET_ISOLATE; |
| 7789 NoHandleAllocation ha; | 8128 NoHandleAllocation ha; |
| 7790 ASSERT(args.length() == 1); | 8129 ASSERT(args.length() == 1); |
| 7791 | 8130 |
| 7792 #ifdef DEBUG | 8131 #ifdef DEBUG |
| 7793 if (args[0]->IsString()) { | 8132 if (args[0]->IsString()) { |
| 7794 // If we have a string, assume it's a code "marker" | 8133 // If we have a string, assume it's a code "marker" |
| 7795 // and print some interesting cpu debugging info. | 8134 // and print some interesting cpu debugging info. |
| 7796 JavaScriptFrameIterator it; | 8135 JavaScriptFrameIterator it; |
| 7797 JavaScriptFrame* frame = it.frame(); | 8136 JavaScriptFrame* frame = it.frame(); |
| 7798 PrintF("fp = %p, sp = %p, caller_sp = %p: ", | 8137 PrintF("fp = %p, sp = %p, caller_sp = %p: ", |
| (...skipping 10 matching lines...) Expand all Loading... |
| 7809 // ShortPrint is available in release mode. Print is not. | 8148 // ShortPrint is available in release mode. Print is not. |
| 7810 args[0]->ShortPrint(); | 8149 args[0]->ShortPrint(); |
| 7811 #endif | 8150 #endif |
| 7812 PrintF("\n"); | 8151 PrintF("\n"); |
| 7813 Flush(); | 8152 Flush(); |
| 7814 | 8153 |
| 7815 return args[0]; // return TOS | 8154 return args[0]; // return TOS |
| 7816 } | 8155 } |
| 7817 | 8156 |
| 7818 | 8157 |
| 7819 static MaybeObject* Runtime_DebugTrace(Arguments args) { | 8158 static MaybeObject* Runtime_DebugTrace(RUNTIME_CALLING_CONVENTION) { |
| 8159 RUNTIME_GET_ISOLATE; |
| 7820 ASSERT(args.length() == 0); | 8160 ASSERT(args.length() == 0); |
| 7821 NoHandleAllocation ha; | 8161 NoHandleAllocation ha; |
| 7822 Top::PrintStack(); | 8162 isolate->PrintStack(); |
| 7823 return Heap::undefined_value(); | 8163 return isolate->heap()->undefined_value(); |
| 7824 } | 8164 } |
| 7825 | 8165 |
| 7826 | 8166 |
| 7827 static MaybeObject* Runtime_DateCurrentTime(Arguments args) { | 8167 static MaybeObject* Runtime_DateCurrentTime(RUNTIME_CALLING_CONVENTION) { |
| 8168 RUNTIME_GET_ISOLATE; |
| 7828 NoHandleAllocation ha; | 8169 NoHandleAllocation ha; |
| 7829 ASSERT(args.length() == 0); | 8170 ASSERT(args.length() == 0); |
| 7830 | 8171 |
| 7831 // According to ECMA-262, section 15.9.1, page 117, the precision of | 8172 // According to ECMA-262, section 15.9.1, page 117, the precision of |
| 7832 // the number in a Date object representing a particular instant in | 8173 // the number in a Date object representing a particular instant in |
| 7833 // time is milliseconds. Therefore, we floor the result of getting | 8174 // time is milliseconds. Therefore, we floor the result of getting |
| 7834 // the OS time. | 8175 // the OS time. |
| 7835 double millis = floor(OS::TimeCurrentMillis()); | 8176 double millis = floor(OS::TimeCurrentMillis()); |
| 7836 return Heap::NumberFromDouble(millis); | 8177 return isolate->heap()->NumberFromDouble(millis); |
| 7837 } | 8178 } |
| 7838 | 8179 |
| 7839 | 8180 |
| 7840 static MaybeObject* Runtime_DateParseString(Arguments args) { | 8181 static MaybeObject* Runtime_DateParseString(RUNTIME_CALLING_CONVENTION) { |
| 7841 HandleScope scope; | 8182 RUNTIME_GET_ISOLATE; |
| 8183 HandleScope scope(isolate); |
| 7842 ASSERT(args.length() == 2); | 8184 ASSERT(args.length() == 2); |
| 7843 | 8185 |
| 7844 CONVERT_ARG_CHECKED(String, str, 0); | 8186 CONVERT_ARG_CHECKED(String, str, 0); |
| 7845 FlattenString(str); | 8187 FlattenString(str); |
| 7846 | 8188 |
| 7847 CONVERT_ARG_CHECKED(JSArray, output, 1); | 8189 CONVERT_ARG_CHECKED(JSArray, output, 1); |
| 7848 RUNTIME_ASSERT(output->HasFastElements()); | 8190 RUNTIME_ASSERT(output->HasFastElements()); |
| 7849 | 8191 |
| 7850 AssertNoAllocation no_allocation; | 8192 AssertNoAllocation no_allocation; |
| 7851 | 8193 |
| 7852 FixedArray* output_array = FixedArray::cast(output->elements()); | 8194 FixedArray* output_array = FixedArray::cast(output->elements()); |
| 7853 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); | 8195 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); |
| 7854 bool result; | 8196 bool result; |
| 7855 if (str->IsAsciiRepresentation()) { | 8197 if (str->IsAsciiRepresentation()) { |
| 7856 result = DateParser::Parse(str->ToAsciiVector(), output_array); | 8198 result = DateParser::Parse(str->ToAsciiVector(), output_array); |
| 7857 } else { | 8199 } else { |
| 7858 ASSERT(str->IsTwoByteRepresentation()); | 8200 ASSERT(str->IsTwoByteRepresentation()); |
| 7859 result = DateParser::Parse(str->ToUC16Vector(), output_array); | 8201 result = DateParser::Parse(str->ToUC16Vector(), output_array); |
| 7860 } | 8202 } |
| 7861 | 8203 |
| 7862 if (result) { | 8204 if (result) { |
| 7863 return *output; | 8205 return *output; |
| 7864 } else { | 8206 } else { |
| 7865 return Heap::null_value(); | 8207 return isolate->heap()->null_value(); |
| 7866 } | 8208 } |
| 7867 } | 8209 } |
| 7868 | 8210 |
| 7869 | 8211 |
| 7870 static MaybeObject* Runtime_DateLocalTimezone(Arguments args) { | 8212 static MaybeObject* Runtime_DateLocalTimezone(RUNTIME_CALLING_CONVENTION) { |
| 8213 RUNTIME_GET_ISOLATE; |
| 7871 NoHandleAllocation ha; | 8214 NoHandleAllocation ha; |
| 7872 ASSERT(args.length() == 1); | 8215 ASSERT(args.length() == 1); |
| 7873 | 8216 |
| 7874 CONVERT_DOUBLE_CHECKED(x, args[0]); | 8217 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 7875 const char* zone = OS::LocalTimezone(x); | 8218 const char* zone = OS::LocalTimezone(x); |
| 7876 return Heap::AllocateStringFromUtf8(CStrVector(zone)); | 8219 return isolate->heap()->AllocateStringFromUtf8(CStrVector(zone)); |
| 7877 } | 8220 } |
| 7878 | 8221 |
| 7879 | 8222 |
| 7880 static MaybeObject* Runtime_DateLocalTimeOffset(Arguments args) { | 8223 static MaybeObject* Runtime_DateLocalTimeOffset(RUNTIME_CALLING_CONVENTION) { |
| 8224 RUNTIME_GET_ISOLATE; |
| 7881 NoHandleAllocation ha; | 8225 NoHandleAllocation ha; |
| 7882 ASSERT(args.length() == 0); | 8226 ASSERT(args.length() == 0); |
| 7883 | 8227 |
| 7884 return Heap::NumberFromDouble(OS::LocalTimeOffset()); | 8228 return isolate->heap()->NumberFromDouble(OS::LocalTimeOffset()); |
| 7885 } | 8229 } |
| 7886 | 8230 |
| 7887 | 8231 |
| 7888 static MaybeObject* Runtime_DateDaylightSavingsOffset(Arguments args) { | 8232 static MaybeObject* Runtime_DateDaylightSavingsOffset( |
| 8233 RUNTIME_CALLING_CONVENTION) { |
| 8234 RUNTIME_GET_ISOLATE; |
| 7889 NoHandleAllocation ha; | 8235 NoHandleAllocation ha; |
| 7890 ASSERT(args.length() == 1); | 8236 ASSERT(args.length() == 1); |
| 7891 | 8237 |
| 7892 CONVERT_DOUBLE_CHECKED(x, args[0]); | 8238 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 7893 return Heap::NumberFromDouble(OS::DaylightSavingsOffset(x)); | 8239 return isolate->heap()->NumberFromDouble(OS::DaylightSavingsOffset(x)); |
| 7894 } | 8240 } |
| 7895 | 8241 |
| 7896 | 8242 |
| 7897 static MaybeObject* Runtime_GlobalReceiver(Arguments args) { | 8243 static MaybeObject* Runtime_GlobalReceiver(RUNTIME_CALLING_CONVENTION) { |
| 8244 RUNTIME_GET_ISOLATE; |
| 7898 ASSERT(args.length() == 1); | 8245 ASSERT(args.length() == 1); |
| 7899 Object* global = args[0]; | 8246 Object* global = args[0]; |
| 7900 if (!global->IsJSGlobalObject()) return Heap::null_value(); | 8247 if (!global->IsJSGlobalObject()) return isolate->heap()->null_value(); |
| 7901 return JSGlobalObject::cast(global)->global_receiver(); | 8248 return JSGlobalObject::cast(global)->global_receiver(); |
| 7902 } | 8249 } |
| 7903 | 8250 |
| 7904 | 8251 |
| 7905 static MaybeObject* Runtime_ParseJson(Arguments args) { | 8252 static MaybeObject* Runtime_ParseJson(RUNTIME_CALLING_CONVENTION) { |
| 7906 HandleScope scope; | 8253 HandleScope scope(isolate); |
| 7907 ASSERT_EQ(1, args.length()); | 8254 ASSERT_EQ(1, args.length()); |
| 7908 CONVERT_ARG_CHECKED(String, source, 0); | 8255 CONVERT_ARG_CHECKED(String, source, 0); |
| 7909 | 8256 |
| 7910 Handle<Object> result = JsonParser::Parse(source); | 8257 Handle<Object> result = JsonParser::Parse(source); |
| 7911 if (result.is_null()) { | 8258 if (result.is_null()) { |
| 7912 // Syntax error or stack overflow in scanner. | 8259 // Syntax error or stack overflow in scanner. |
| 7913 ASSERT(Top::has_pending_exception()); | 8260 ASSERT(isolate->has_pending_exception()); |
| 7914 return Failure::Exception(); | 8261 return Failure::Exception(); |
| 7915 } | 8262 } |
| 7916 return *result; | 8263 return *result; |
| 7917 } | 8264 } |
| 7918 | 8265 |
| 7919 | 8266 |
| 7920 static MaybeObject* Runtime_CompileString(Arguments args) { | 8267 static MaybeObject* Runtime_CompileString(RUNTIME_CALLING_CONVENTION) { |
| 7921 HandleScope scope; | 8268 RUNTIME_GET_ISOLATE; |
| 8269 HandleScope scope(isolate); |
| 7922 ASSERT_EQ(1, args.length()); | 8270 ASSERT_EQ(1, args.length()); |
| 7923 CONVERT_ARG_CHECKED(String, source, 0); | 8271 CONVERT_ARG_CHECKED(String, source, 0); |
| 7924 | 8272 |
| 7925 // Compile source string in the global context. | 8273 // Compile source string in the global context. |
| 7926 Handle<Context> context(Top::context()->global_context()); | 8274 Handle<Context> context(isolate->context()->global_context()); |
| 7927 Handle<SharedFunctionInfo> shared = Compiler::CompileEval(source, | 8275 Handle<SharedFunctionInfo> shared = Compiler::CompileEval(source, |
| 7928 context, | 8276 context, |
| 7929 true, | 8277 true, |
| 7930 kNonStrictMode); | 8278 kNonStrictMode); |
| 7931 if (shared.is_null()) return Failure::Exception(); | 8279 if (shared.is_null()) return Failure::Exception(); |
| 7932 Handle<JSFunction> fun = | 8280 Handle<JSFunction> fun = |
| 7933 Factory::NewFunctionFromSharedFunctionInfo(shared, context, NOT_TENURED); | 8281 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, |
| 8282 context, |
| 8283 NOT_TENURED); |
| 7934 return *fun; | 8284 return *fun; |
| 7935 } | 8285 } |
| 7936 | 8286 |
| 7937 | 8287 |
| 7938 static ObjectPair CompileGlobalEval(Handle<String> source, | 8288 static ObjectPair CompileGlobalEval(Isolate* isolate, |
| 8289 Handle<String> source, |
| 7939 Handle<Object> receiver, | 8290 Handle<Object> receiver, |
| 7940 StrictModeFlag strict_mode) { | 8291 StrictModeFlag strict_mode) { |
| 7941 // Deal with a normal eval call with a string argument. Compile it | 8292 // Deal with a normal eval call with a string argument. Compile it |
| 7942 // and return the compiled function bound in the local context. | 8293 // and return the compiled function bound in the local context. |
| 7943 Handle<SharedFunctionInfo> shared = Compiler::CompileEval( | 8294 Handle<SharedFunctionInfo> shared = Compiler::CompileEval( |
| 7944 source, | 8295 source, |
| 7945 Handle<Context>(Top::context()), | 8296 Handle<Context>(isolate->context()), |
| 7946 Top::context()->IsGlobalContext(), | 8297 isolate->context()->IsGlobalContext(), |
| 7947 strict_mode); | 8298 strict_mode); |
| 7948 if (shared.is_null()) return MakePair(Failure::Exception(), NULL); | 8299 if (shared.is_null()) return MakePair(Failure::Exception(), NULL); |
| 7949 Handle<JSFunction> compiled = Factory::NewFunctionFromSharedFunctionInfo( | 8300 Handle<JSFunction> compiled = |
| 7950 shared, | 8301 isolate->factory()->NewFunctionFromSharedFunctionInfo( |
| 7951 Handle<Context>(Top::context()), | 8302 shared, Handle<Context>(isolate->context()), NOT_TENURED); |
| 7952 NOT_TENURED); | |
| 7953 return MakePair(*compiled, *receiver); | 8303 return MakePair(*compiled, *receiver); |
| 7954 } | 8304 } |
| 7955 | 8305 |
| 7956 | 8306 |
| 7957 static ObjectPair Runtime_ResolvePossiblyDirectEval(Arguments args) { | 8307 static ObjectPair Runtime_ResolvePossiblyDirectEval( |
| 8308 RUNTIME_CALLING_CONVENTION) { |
| 8309 RUNTIME_GET_ISOLATE; |
| 7958 ASSERT(args.length() == 4); | 8310 ASSERT(args.length() == 4); |
| 7959 | 8311 |
| 7960 HandleScope scope; | 8312 HandleScope scope(isolate); |
| 7961 Handle<Object> callee = args.at<Object>(0); | 8313 Handle<Object> callee = args.at<Object>(0); |
| 7962 Handle<Object> receiver; // Will be overwritten. | 8314 Handle<Object> receiver; // Will be overwritten. |
| 7963 | 8315 |
| 7964 // Compute the calling context. | 8316 // Compute the calling context. |
| 7965 Handle<Context> context = Handle<Context>(Top::context()); | 8317 Handle<Context> context = Handle<Context>(isolate->context(), isolate); |
| 7966 #ifdef DEBUG | 8318 #ifdef DEBUG |
| 7967 // Make sure Top::context() agrees with the old code that traversed | 8319 // Make sure Isolate::context() agrees with the old code that traversed |
| 7968 // the stack frames to compute the context. | 8320 // the stack frames to compute the context. |
| 7969 StackFrameLocator locator; | 8321 StackFrameLocator locator; |
| 7970 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); | 8322 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); |
| 7971 ASSERT(Context::cast(frame->context()) == *context); | 8323 ASSERT(Context::cast(frame->context()) == *context); |
| 7972 #endif | 8324 #endif |
| 7973 | 8325 |
| 7974 // Find where the 'eval' symbol is bound. It is unaliased only if | 8326 // Find where the 'eval' symbol is bound. It is unaliased only if |
| 7975 // it is bound in the global context. | 8327 // it is bound in the global context. |
| 7976 int index = -1; | 8328 int index = -1; |
| 7977 PropertyAttributes attributes = ABSENT; | 8329 PropertyAttributes attributes = ABSENT; |
| 7978 while (true) { | 8330 while (true) { |
| 7979 receiver = context->Lookup(Factory::eval_symbol(), FOLLOW_PROTOTYPE_CHAIN, | 8331 receiver = context->Lookup(isolate->factory()->eval_symbol(), |
| 8332 FOLLOW_PROTOTYPE_CHAIN, |
| 7980 &index, &attributes); | 8333 &index, &attributes); |
| 7981 // Stop search when eval is found or when the global context is | 8334 // Stop search when eval is found or when the global context is |
| 7982 // reached. | 8335 // reached. |
| 7983 if (attributes != ABSENT || context->IsGlobalContext()) break; | 8336 if (attributes != ABSENT || context->IsGlobalContext()) break; |
| 7984 if (context->is_function_context()) { | 8337 if (context->is_function_context()) { |
| 7985 context = Handle<Context>(Context::cast(context->closure()->context())); | 8338 context = Handle<Context>(Context::cast(context->closure()->context()), |
| 8339 isolate); |
| 7986 } else { | 8340 } else { |
| 7987 context = Handle<Context>(context->previous()); | 8341 context = Handle<Context>(context->previous(), isolate); |
| 7988 } | 8342 } |
| 7989 } | 8343 } |
| 7990 | 8344 |
| 7991 // If eval could not be resolved, it has been deleted and we need to | 8345 // If eval could not be resolved, it has been deleted and we need to |
| 7992 // throw a reference error. | 8346 // throw a reference error. |
| 7993 if (attributes == ABSENT) { | 8347 if (attributes == ABSENT) { |
| 7994 Handle<Object> name = Factory::eval_symbol(); | 8348 Handle<Object> name = isolate->factory()->eval_symbol(); |
| 7995 Handle<Object> reference_error = | 8349 Handle<Object> reference_error = |
| 7996 Factory::NewReferenceError("not_defined", HandleVector(&name, 1)); | 8350 isolate->factory()->NewReferenceError("not_defined", |
| 7997 return MakePair(Top::Throw(*reference_error), NULL); | 8351 HandleVector(&name, 1)); |
| 8352 return MakePair(isolate->Throw(*reference_error), NULL); |
| 7998 } | 8353 } |
| 7999 | 8354 |
| 8000 if (!context->IsGlobalContext()) { | 8355 if (!context->IsGlobalContext()) { |
| 8001 // 'eval' is not bound in the global context. Just call the function | 8356 // 'eval' is not bound in the global context. Just call the function |
| 8002 // with the given arguments. This is not necessarily the global eval. | 8357 // with the given arguments. This is not necessarily the global eval. |
| 8003 if (receiver->IsContext()) { | 8358 if (receiver->IsContext()) { |
| 8004 context = Handle<Context>::cast(receiver); | 8359 context = Handle<Context>::cast(receiver); |
| 8005 receiver = Handle<Object>(context->get(index)); | 8360 receiver = Handle<Object>(context->get(index), isolate); |
| 8006 } else if (receiver->IsJSContextExtensionObject()) { | 8361 } else if (receiver->IsJSContextExtensionObject()) { |
| 8007 receiver = Handle<JSObject>(Top::context()->global()->global_receiver()); | 8362 receiver = Handle<JSObject>( |
| 8363 isolate->context()->global()->global_receiver(), isolate); |
| 8008 } | 8364 } |
| 8009 return MakePair(*callee, *receiver); | 8365 return MakePair(*callee, *receiver); |
| 8010 } | 8366 } |
| 8011 | 8367 |
| 8012 // 'eval' is bound in the global context, but it may have been overwritten. | 8368 // 'eval' is bound in the global context, but it may have been overwritten. |
| 8013 // Compare it to the builtin 'GlobalEval' function to make sure. | 8369 // Compare it to the builtin 'GlobalEval' function to make sure. |
| 8014 if (*callee != Top::global_context()->global_eval_fun() || | 8370 if (*callee != isolate->global_context()->global_eval_fun() || |
| 8015 !args[1]->IsString()) { | 8371 !args[1]->IsString()) { |
| 8016 return MakePair(*callee, Top::context()->global()->global_receiver()); | 8372 return MakePair(*callee, |
| 8373 isolate->context()->global()->global_receiver()); |
| 8017 } | 8374 } |
| 8018 | 8375 |
| 8019 ASSERT(args[3]->IsSmi()); | 8376 ASSERT(args[3]->IsSmi()); |
| 8020 return CompileGlobalEval(args.at<String>(1), | 8377 return CompileGlobalEval(isolate, |
| 8378 args.at<String>(1), |
| 8021 args.at<Object>(2), | 8379 args.at<Object>(2), |
| 8022 static_cast<StrictModeFlag>( | 8380 static_cast<StrictModeFlag>( |
| 8023 Smi::cast(args[3])->value())); | 8381 Smi::cast(args[3])->value())); |
| 8024 } | 8382 } |
| 8025 | 8383 |
| 8026 | 8384 |
| 8027 static ObjectPair Runtime_ResolvePossiblyDirectEvalNoLookup(Arguments args) { | 8385 static ObjectPair Runtime_ResolvePossiblyDirectEvalNoLookup( |
| 8386 RUNTIME_CALLING_CONVENTION) { |
| 8387 RUNTIME_GET_ISOLATE; |
| 8028 ASSERT(args.length() == 4); | 8388 ASSERT(args.length() == 4); |
| 8029 | 8389 |
| 8030 HandleScope scope; | 8390 HandleScope scope(isolate); |
| 8031 Handle<Object> callee = args.at<Object>(0); | 8391 Handle<Object> callee = args.at<Object>(0); |
| 8032 | 8392 |
| 8033 // 'eval' is bound in the global context, but it may have been overwritten. | 8393 // 'eval' is bound in the global context, but it may have been overwritten. |
| 8034 // Compare it to the builtin 'GlobalEval' function to make sure. | 8394 // Compare it to the builtin 'GlobalEval' function to make sure. |
| 8035 if (*callee != Top::global_context()->global_eval_fun() || | 8395 if (*callee != isolate->global_context()->global_eval_fun() || |
| 8036 !args[1]->IsString()) { | 8396 !args[1]->IsString()) { |
| 8037 return MakePair(*callee, Top::context()->global()->global_receiver()); | 8397 return MakePair(*callee, |
| 8398 isolate->context()->global()->global_receiver()); |
| 8038 } | 8399 } |
| 8039 | 8400 |
| 8040 ASSERT(args[3]->IsSmi()); | 8401 ASSERT(args[3]->IsSmi()); |
| 8041 return CompileGlobalEval(args.at<String>(1), | 8402 return CompileGlobalEval(isolate, |
| 8403 args.at<String>(1), |
| 8042 args.at<Object>(2), | 8404 args.at<Object>(2), |
| 8043 static_cast<StrictModeFlag>( | 8405 static_cast<StrictModeFlag>( |
| 8044 Smi::cast(args[3])->value())); | 8406 Smi::cast(args[3])->value())); |
| 8045 } | 8407 } |
| 8046 | 8408 |
| 8047 | 8409 |
| 8048 static MaybeObject* Runtime_SetNewFunctionAttributes(Arguments args) { | 8410 static MaybeObject* Runtime_SetNewFunctionAttributes( |
| 8411 RUNTIME_CALLING_CONVENTION) { |
| 8412 RUNTIME_GET_ISOLATE; |
| 8049 // This utility adjusts the property attributes for newly created Function | 8413 // This utility adjusts the property attributes for newly created Function |
| 8050 // object ("new Function(...)") by changing the map. | 8414 // object ("new Function(...)") by changing the map. |
| 8051 // All it does is changing the prototype property to enumerable | 8415 // All it does is changing the prototype property to enumerable |
| 8052 // as specified in ECMA262, 15.3.5.2. | 8416 // as specified in ECMA262, 15.3.5.2. |
| 8053 HandleScope scope; | 8417 HandleScope scope(isolate); |
| 8054 ASSERT(args.length() == 1); | 8418 ASSERT(args.length() == 1); |
| 8055 CONVERT_ARG_CHECKED(JSFunction, func, 0); | 8419 CONVERT_ARG_CHECKED(JSFunction, func, 0); |
| 8056 | 8420 |
| 8057 Handle<Map> map = func->shared()->strict_mode() | 8421 Handle<Map> map = func->shared()->strict_mode() |
| 8058 ? Top::strict_mode_function_instance_map() | 8422 ? isolate->strict_mode_function_instance_map() |
| 8059 : Top::function_instance_map(); | 8423 : isolate->function_instance_map(); |
| 8060 | 8424 |
| 8061 ASSERT(func->map()->instance_type() == map->instance_type()); | 8425 ASSERT(func->map()->instance_type() == map->instance_type()); |
| 8062 ASSERT(func->map()->instance_size() == map->instance_size()); | 8426 ASSERT(func->map()->instance_size() == map->instance_size()); |
| 8063 func->set_map(*map); | 8427 func->set_map(*map); |
| 8064 return *func; | 8428 return *func; |
| 8065 } | 8429 } |
| 8066 | 8430 |
| 8067 | 8431 |
| 8068 static MaybeObject* Runtime_AllocateInNewSpace(Arguments args) { | 8432 static MaybeObject* Runtime_AllocateInNewSpace(RUNTIME_CALLING_CONVENTION) { |
| 8433 RUNTIME_GET_ISOLATE; |
| 8069 // Allocate a block of memory in NewSpace (filled with a filler). | 8434 // Allocate a block of memory in NewSpace (filled with a filler). |
| 8070 // Use as fallback for allocation in generated code when NewSpace | 8435 // Use as fallback for allocation in generated code when NewSpace |
| 8071 // is full. | 8436 // is full. |
| 8072 ASSERT(args.length() == 1); | 8437 ASSERT(args.length() == 1); |
| 8073 CONVERT_ARG_CHECKED(Smi, size_smi, 0); | 8438 CONVERT_ARG_CHECKED(Smi, size_smi, 0); |
| 8074 int size = size_smi->value(); | 8439 int size = size_smi->value(); |
| 8075 RUNTIME_ASSERT(IsAligned(size, kPointerSize)); | 8440 RUNTIME_ASSERT(IsAligned(size, kPointerSize)); |
| 8076 RUNTIME_ASSERT(size > 0); | 8441 RUNTIME_ASSERT(size > 0); |
| 8077 static const int kMinFreeNewSpaceAfterGC = | 8442 Heap* heap = isolate->heap(); |
| 8078 Heap::InitialSemiSpaceSize() * 3/4; | 8443 const int kMinFreeNewSpaceAfterGC = heap->InitialSemiSpaceSize() * 3/4; |
| 8079 RUNTIME_ASSERT(size <= kMinFreeNewSpaceAfterGC); | 8444 RUNTIME_ASSERT(size <= kMinFreeNewSpaceAfterGC); |
| 8080 Object* allocation; | 8445 Object* allocation; |
| 8081 { MaybeObject* maybe_allocation = Heap::new_space()->AllocateRaw(size); | 8446 { MaybeObject* maybe_allocation = heap->new_space()->AllocateRaw(size); |
| 8082 if (maybe_allocation->ToObject(&allocation)) { | 8447 if (maybe_allocation->ToObject(&allocation)) { |
| 8083 Heap::CreateFillerObjectAt(HeapObject::cast(allocation)->address(), size); | 8448 heap->CreateFillerObjectAt(HeapObject::cast(allocation)->address(), size); |
| 8084 } | 8449 } |
| 8085 return maybe_allocation; | 8450 return maybe_allocation; |
| 8086 } | 8451 } |
| 8087 } | 8452 } |
| 8088 | 8453 |
| 8089 | 8454 |
| 8090 // Push an object unto an array of objects if it is not already in the | 8455 // Push an object unto an array of objects if it is not already in the |
| 8091 // array. Returns true if the element was pushed on the stack and | 8456 // array. Returns true if the element was pushed on the stack and |
| 8092 // false otherwise. | 8457 // false otherwise. |
| 8093 static MaybeObject* Runtime_PushIfAbsent(Arguments args) { | 8458 static MaybeObject* Runtime_PushIfAbsent(RUNTIME_CALLING_CONVENTION) { |
| 8459 RUNTIME_GET_ISOLATE; |
| 8094 ASSERT(args.length() == 2); | 8460 ASSERT(args.length() == 2); |
| 8095 CONVERT_CHECKED(JSArray, array, args[0]); | 8461 CONVERT_CHECKED(JSArray, array, args[0]); |
| 8096 CONVERT_CHECKED(JSObject, element, args[1]); | 8462 CONVERT_CHECKED(JSObject, element, args[1]); |
| 8097 RUNTIME_ASSERT(array->HasFastElements()); | 8463 RUNTIME_ASSERT(array->HasFastElements()); |
| 8098 int length = Smi::cast(array->length())->value(); | 8464 int length = Smi::cast(array->length())->value(); |
| 8099 FixedArray* elements = FixedArray::cast(array->elements()); | 8465 FixedArray* elements = FixedArray::cast(array->elements()); |
| 8100 for (int i = 0; i < length; i++) { | 8466 for (int i = 0; i < length; i++) { |
| 8101 if (elements->get(i) == element) return Heap::false_value(); | 8467 if (elements->get(i) == element) return isolate->heap()->false_value(); |
| 8102 } | 8468 } |
| 8103 Object* obj; | 8469 Object* obj; |
| 8104 // Strict not needed. Used for cycle detection in Array join implementation. | 8470 // Strict not needed. Used for cycle detection in Array join implementation. |
| 8105 { MaybeObject* maybe_obj = array->SetFastElement(length, element, | 8471 { MaybeObject* maybe_obj = array->SetFastElement(length, element, |
| 8106 kNonStrictMode); | 8472 kNonStrictMode); |
| 8107 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 8473 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8108 } | 8474 } |
| 8109 return Heap::true_value(); | 8475 return isolate->heap()->true_value(); |
| 8110 } | 8476 } |
| 8111 | 8477 |
| 8112 | 8478 |
| 8113 /** | 8479 /** |
| 8114 * A simple visitor visits every element of Array's. | 8480 * A simple visitor visits every element of Array's. |
| 8115 * The backend storage can be a fixed array for fast elements case, | 8481 * The backend storage can be a fixed array for fast elements case, |
| 8116 * or a dictionary for sparse array. Since Dictionary is a subtype | 8482 * or a dictionary for sparse array. Since Dictionary is a subtype |
| 8117 * of FixedArray, the class can be used by both fast and slow cases. | 8483 * of FixedArray, the class can be used by both fast and slow cases. |
| 8118 * The second parameter of the constructor, fast_elements, specifies | 8484 * The second parameter of the constructor, fast_elements, specifies |
| 8119 * whether the storage is a FixedArray or Dictionary. | 8485 * whether the storage is a FixedArray or Dictionary. |
| 8120 * | 8486 * |
| 8121 * An index limit is used to deal with the situation that a result array | 8487 * An index limit is used to deal with the situation that a result array |
| 8122 * length overflows 32-bit non-negative integer. | 8488 * length overflows 32-bit non-negative integer. |
| 8123 */ | 8489 */ |
| 8124 class ArrayConcatVisitor { | 8490 class ArrayConcatVisitor { |
| 8125 public: | 8491 public: |
| 8126 ArrayConcatVisitor(Handle<FixedArray> storage, | 8492 ArrayConcatVisitor(Isolate* isolate, |
| 8493 Handle<FixedArray> storage, |
| 8127 bool fast_elements) : | 8494 bool fast_elements) : |
| 8128 storage_(Handle<FixedArray>::cast(GlobalHandles::Create(*storage))), | 8495 isolate_(isolate), |
| 8496 storage_(Handle<FixedArray>::cast( |
| 8497 isolate->global_handles()->Create(*storage))), |
| 8129 index_offset_(0u), | 8498 index_offset_(0u), |
| 8130 fast_elements_(fast_elements) { } | 8499 fast_elements_(fast_elements) { } |
| 8131 | 8500 |
| 8132 ~ArrayConcatVisitor() { | 8501 ~ArrayConcatVisitor() { |
| 8133 clear_storage(); | 8502 clear_storage(); |
| 8134 } | 8503 } |
| 8135 | 8504 |
| 8136 void visit(uint32_t i, Handle<Object> elm) { | 8505 void visit(uint32_t i, Handle<Object> elm) { |
| 8137 if (i >= JSObject::kMaxElementCount - index_offset_) return; | 8506 if (i >= JSObject::kMaxElementCount - index_offset_) return; |
| 8138 uint32_t index = index_offset_ + i; | 8507 uint32_t index = index_offset_ + i; |
| 8139 | 8508 |
| 8140 if (fast_elements_) { | 8509 if (fast_elements_) { |
| 8141 if (index < static_cast<uint32_t>(storage_->length())) { | 8510 if (index < static_cast<uint32_t>(storage_->length())) { |
| 8142 storage_->set(index, *elm); | 8511 storage_->set(index, *elm); |
| 8143 return; | 8512 return; |
| 8144 } | 8513 } |
| 8145 // Our initial estimate of length was foiled, possibly by | 8514 // Our initial estimate of length was foiled, possibly by |
| 8146 // getters on the arrays increasing the length of later arrays | 8515 // getters on the arrays increasing the length of later arrays |
| 8147 // during iteration. | 8516 // during iteration. |
| 8148 // This shouldn't happen in anything but pathological cases. | 8517 // This shouldn't happen in anything but pathological cases. |
| 8149 SetDictionaryMode(index); | 8518 SetDictionaryMode(index); |
| 8150 // Fall-through to dictionary mode. | 8519 // Fall-through to dictionary mode. |
| 8151 } | 8520 } |
| 8152 ASSERT(!fast_elements_); | 8521 ASSERT(!fast_elements_); |
| 8153 Handle<NumberDictionary> dict(NumberDictionary::cast(*storage_)); | 8522 Handle<NumberDictionary> dict(NumberDictionary::cast(*storage_)); |
| 8154 Handle<NumberDictionary> result = | 8523 Handle<NumberDictionary> result = |
| 8155 Factory::DictionaryAtNumberPut(dict, index, elm); | 8524 isolate_->factory()->DictionaryAtNumberPut(dict, index, elm); |
| 8156 if (!result.is_identical_to(dict)) { | 8525 if (!result.is_identical_to(dict)) { |
| 8157 // Dictionary needed to grow. | 8526 // Dictionary needed to grow. |
| 8158 clear_storage(); | 8527 clear_storage(); |
| 8159 set_storage(*result); | 8528 set_storage(*result); |
| 8160 } | 8529 } |
| 8161 } | 8530 } |
| 8162 | 8531 |
| 8163 void increase_index_offset(uint32_t delta) { | 8532 void increase_index_offset(uint32_t delta) { |
| 8164 if (JSObject::kMaxElementCount - index_offset_ < delta) { | 8533 if (JSObject::kMaxElementCount - index_offset_ < delta) { |
| 8165 index_offset_ = JSObject::kMaxElementCount; | 8534 index_offset_ = JSObject::kMaxElementCount; |
| 8166 } else { | 8535 } else { |
| 8167 index_offset_ += delta; | 8536 index_offset_ += delta; |
| 8168 } | 8537 } |
| 8169 } | 8538 } |
| 8170 | 8539 |
| 8171 Handle<JSArray> ToArray() { | 8540 Handle<JSArray> ToArray() { |
| 8172 Handle<JSArray> array = Factory::NewJSArray(0); | 8541 Handle<JSArray> array = isolate_->factory()->NewJSArray(0); |
| 8173 Handle<Object> length = | 8542 Handle<Object> length = |
| 8174 Factory::NewNumber(static_cast<double>(index_offset_)); | 8543 isolate_->factory()->NewNumber(static_cast<double>(index_offset_)); |
| 8175 Handle<Map> map; | 8544 Handle<Map> map; |
| 8176 if (fast_elements_) { | 8545 if (fast_elements_) { |
| 8177 map = Factory::GetFastElementsMap(Handle<Map>(array->map())); | 8546 map = isolate_->factory()->GetFastElementsMap(Handle<Map>(array->map())); |
| 8178 } else { | 8547 } else { |
| 8179 map = Factory::GetSlowElementsMap(Handle<Map>(array->map())); | 8548 map = isolate_->factory()->GetSlowElementsMap(Handle<Map>(array->map())); |
| 8180 } | 8549 } |
| 8181 array->set_map(*map); | 8550 array->set_map(*map); |
| 8182 array->set_length(*length); | 8551 array->set_length(*length); |
| 8183 array->set_elements(*storage_); | 8552 array->set_elements(*storage_); |
| 8184 return array; | 8553 return array; |
| 8185 } | 8554 } |
| 8186 | 8555 |
| 8187 private: | 8556 private: |
| 8188 // Convert storage to dictionary mode. | 8557 // Convert storage to dictionary mode. |
| 8189 void SetDictionaryMode(uint32_t index) { | 8558 void SetDictionaryMode(uint32_t index) { |
| 8190 ASSERT(fast_elements_); | 8559 ASSERT(fast_elements_); |
| 8191 Handle<FixedArray> current_storage(*storage_); | 8560 Handle<FixedArray> current_storage(*storage_); |
| 8192 Handle<NumberDictionary> slow_storage( | 8561 Handle<NumberDictionary> slow_storage( |
| 8193 Factory::NewNumberDictionary(current_storage->length())); | 8562 isolate_->factory()->NewNumberDictionary(current_storage->length())); |
| 8194 uint32_t current_length = static_cast<uint32_t>(current_storage->length()); | 8563 uint32_t current_length = static_cast<uint32_t>(current_storage->length()); |
| 8195 for (uint32_t i = 0; i < current_length; i++) { | 8564 for (uint32_t i = 0; i < current_length; i++) { |
| 8196 HandleScope loop_scope; | 8565 HandleScope loop_scope; |
| 8197 Handle<Object> element(current_storage->get(i)); | 8566 Handle<Object> element(current_storage->get(i)); |
| 8198 if (!element->IsTheHole()) { | 8567 if (!element->IsTheHole()) { |
| 8199 Handle<NumberDictionary> new_storage = | 8568 Handle<NumberDictionary> new_storage = |
| 8200 Factory::DictionaryAtNumberPut(slow_storage, i, element); | 8569 isolate_->factory()->DictionaryAtNumberPut(slow_storage, i, element); |
| 8201 if (!new_storage.is_identical_to(slow_storage)) { | 8570 if (!new_storage.is_identical_to(slow_storage)) { |
| 8202 slow_storage = loop_scope.CloseAndEscape(new_storage); | 8571 slow_storage = loop_scope.CloseAndEscape(new_storage); |
| 8203 } | 8572 } |
| 8204 } | 8573 } |
| 8205 } | 8574 } |
| 8206 clear_storage(); | 8575 clear_storage(); |
| 8207 set_storage(*slow_storage); | 8576 set_storage(*slow_storage); |
| 8208 fast_elements_ = false; | 8577 fast_elements_ = false; |
| 8209 } | 8578 } |
| 8210 | 8579 |
| 8211 inline void clear_storage() { | 8580 inline void clear_storage() { |
| 8212 GlobalHandles::Destroy(Handle<Object>::cast(storage_).location()); | 8581 isolate_->global_handles()->Destroy( |
| 8582 Handle<Object>::cast(storage_).location()); |
| 8213 } | 8583 } |
| 8214 | 8584 |
| 8215 inline void set_storage(FixedArray* storage) { | 8585 inline void set_storage(FixedArray* storage) { |
| 8216 storage_ = Handle<FixedArray>::cast(GlobalHandles::Create(storage)); | 8586 storage_ = Handle<FixedArray>::cast( |
| 8587 isolate_->global_handles()->Create(storage)); |
| 8217 } | 8588 } |
| 8218 | 8589 |
| 8590 Isolate* isolate_; |
| 8219 Handle<FixedArray> storage_; // Always a global handle. | 8591 Handle<FixedArray> storage_; // Always a global handle. |
| 8220 // Index after last seen index. Always less than or equal to | 8592 // Index after last seen index. Always less than or equal to |
| 8221 // JSObject::kMaxElementCount. | 8593 // JSObject::kMaxElementCount. |
| 8222 uint32_t index_offset_; | 8594 uint32_t index_offset_; |
| 8223 bool fast_elements_; | 8595 bool fast_elements_; |
| 8224 }; | 8596 }; |
| 8225 | 8597 |
| 8226 | 8598 |
| 8227 static uint32_t EstimateElementCount(Handle<JSArray> array) { | 8599 static uint32_t EstimateElementCount(Handle<JSArray> array) { |
| 8228 uint32_t length = static_cast<uint32_t>(array->length()->Number()); | 8600 uint32_t length = static_cast<uint32_t>(array->length()->Number()); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 8256 return length; | 8628 return length; |
| 8257 } | 8629 } |
| 8258 // As an estimate, we assume that the prototype doesn't contain any | 8630 // As an estimate, we assume that the prototype doesn't contain any |
| 8259 // inherited elements. | 8631 // inherited elements. |
| 8260 return element_count; | 8632 return element_count; |
| 8261 } | 8633 } |
| 8262 | 8634 |
| 8263 | 8635 |
| 8264 | 8636 |
| 8265 template<class ExternalArrayClass, class ElementType> | 8637 template<class ExternalArrayClass, class ElementType> |
| 8266 static void IterateExternalArrayElements(Handle<JSObject> receiver, | 8638 static void IterateExternalArrayElements(Isolate* isolate, |
| 8639 Handle<JSObject> receiver, |
| 8267 bool elements_are_ints, | 8640 bool elements_are_ints, |
| 8268 bool elements_are_guaranteed_smis, | 8641 bool elements_are_guaranteed_smis, |
| 8269 ArrayConcatVisitor* visitor) { | 8642 ArrayConcatVisitor* visitor) { |
| 8270 Handle<ExternalArrayClass> array( | 8643 Handle<ExternalArrayClass> array( |
| 8271 ExternalArrayClass::cast(receiver->elements())); | 8644 ExternalArrayClass::cast(receiver->elements())); |
| 8272 uint32_t len = static_cast<uint32_t>(array->length()); | 8645 uint32_t len = static_cast<uint32_t>(array->length()); |
| 8273 | 8646 |
| 8274 ASSERT(visitor != NULL); | 8647 ASSERT(visitor != NULL); |
| 8275 if (elements_are_ints) { | 8648 if (elements_are_ints) { |
| 8276 if (elements_are_guaranteed_smis) { | 8649 if (elements_are_guaranteed_smis) { |
| 8277 for (uint32_t j = 0; j < len; j++) { | 8650 for (uint32_t j = 0; j < len; j++) { |
| 8278 HandleScope loop_scope; | 8651 HandleScope loop_scope; |
| 8279 Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get(j)))); | 8652 Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get(j)))); |
| 8280 visitor->visit(j, e); | 8653 visitor->visit(j, e); |
| 8281 } | 8654 } |
| 8282 } else { | 8655 } else { |
| 8283 for (uint32_t j = 0; j < len; j++) { | 8656 for (uint32_t j = 0; j < len; j++) { |
| 8284 HandleScope loop_scope; | 8657 HandleScope loop_scope; |
| 8285 int64_t val = static_cast<int64_t>(array->get(j)); | 8658 int64_t val = static_cast<int64_t>(array->get(j)); |
| 8286 if (Smi::IsValid(static_cast<intptr_t>(val))) { | 8659 if (Smi::IsValid(static_cast<intptr_t>(val))) { |
| 8287 Handle<Smi> e(Smi::FromInt(static_cast<int>(val))); | 8660 Handle<Smi> e(Smi::FromInt(static_cast<int>(val))); |
| 8288 visitor->visit(j, e); | 8661 visitor->visit(j, e); |
| 8289 } else { | 8662 } else { |
| 8290 Handle<Object> e = | 8663 Handle<Object> e = |
| 8291 Factory::NewNumber(static_cast<ElementType>(val)); | 8664 isolate->factory()->NewNumber(static_cast<ElementType>(val)); |
| 8292 visitor->visit(j, e); | 8665 visitor->visit(j, e); |
| 8293 } | 8666 } |
| 8294 } | 8667 } |
| 8295 } | 8668 } |
| 8296 } else { | 8669 } else { |
| 8297 for (uint32_t j = 0; j < len; j++) { | 8670 for (uint32_t j = 0; j < len; j++) { |
| 8298 HandleScope loop_scope; | 8671 HandleScope loop_scope(isolate); |
| 8299 Handle<Object> e = Factory::NewNumber(array->get(j)); | 8672 Handle<Object> e = isolate->factory()->NewNumber(array->get(j)); |
| 8300 visitor->visit(j, e); | 8673 visitor->visit(j, e); |
| 8301 } | 8674 } |
| 8302 } | 8675 } |
| 8303 } | 8676 } |
| 8304 | 8677 |
| 8305 | 8678 |
| 8306 // Used for sorting indices in a List<uint32_t>. | 8679 // Used for sorting indices in a List<uint32_t>. |
| 8307 static int compareUInt32(const uint32_t* ap, const uint32_t* bp) { | 8680 static int compareUInt32(const uint32_t* ap, const uint32_t* bp) { |
| 8308 uint32_t a = *ap; | 8681 uint32_t a = *ap; |
| 8309 uint32_t b = *bp; | 8682 uint32_t b = *bp; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8418 /** | 8791 /** |
| 8419 * A helper function that visits elements of a JSArray in numerical | 8792 * A helper function that visits elements of a JSArray in numerical |
| 8420 * order. | 8793 * order. |
| 8421 * | 8794 * |
| 8422 * The visitor argument called for each existing element in the array | 8795 * The visitor argument called for each existing element in the array |
| 8423 * with the element index and the element's value. | 8796 * with the element index and the element's value. |
| 8424 * Afterwards it increments the base-index of the visitor by the array | 8797 * Afterwards it increments the base-index of the visitor by the array |
| 8425 * length. | 8798 * length. |
| 8426 * Returns false if any access threw an exception, otherwise true. | 8799 * Returns false if any access threw an exception, otherwise true. |
| 8427 */ | 8800 */ |
| 8428 static bool IterateElements(Handle<JSArray> receiver, | 8801 static bool IterateElements(Isolate* isolate, |
| 8802 Handle<JSArray> receiver, |
| 8429 ArrayConcatVisitor* visitor) { | 8803 ArrayConcatVisitor* visitor) { |
| 8430 uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); | 8804 uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); |
| 8431 switch (receiver->GetElementsKind()) { | 8805 switch (receiver->GetElementsKind()) { |
| 8432 case JSObject::FAST_ELEMENTS: { | 8806 case JSObject::FAST_ELEMENTS: { |
| 8433 // Run through the elements FixedArray and use HasElement and GetElement | 8807 // Run through the elements FixedArray and use HasElement and GetElement |
| 8434 // to check the prototype for missing elements. | 8808 // to check the prototype for missing elements. |
| 8435 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); | 8809 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); |
| 8436 int fast_length = static_cast<int>(length); | 8810 int fast_length = static_cast<int>(length); |
| 8437 ASSERT(fast_length <= elements->length()); | 8811 ASSERT(fast_length <= elements->length()); |
| 8438 for (int j = 0; j < fast_length; j++) { | 8812 for (int j = 0; j < fast_length; j++) { |
| 8439 HandleScope loop_scope; | 8813 HandleScope loop_scope(isolate); |
| 8440 Handle<Object> element_value(elements->get(j)); | 8814 Handle<Object> element_value(elements->get(j), isolate); |
| 8441 if (!element_value->IsTheHole()) { | 8815 if (!element_value->IsTheHole()) { |
| 8442 visitor->visit(j, element_value); | 8816 visitor->visit(j, element_value); |
| 8443 } else if (receiver->HasElement(j)) { | 8817 } else if (receiver->HasElement(j)) { |
| 8444 // Call GetElement on receiver, not its prototype, or getters won't | 8818 // Call GetElement on receiver, not its prototype, or getters won't |
| 8445 // have the correct receiver. | 8819 // have the correct receiver. |
| 8446 element_value = GetElement(receiver, j); | 8820 element_value = GetElement(receiver, j); |
| 8447 if (element_value.is_null()) return false; | 8821 if (element_value.is_null()) return false; |
| 8448 visitor->visit(j, element_value); | 8822 visitor->visit(j, element_value); |
| 8449 } | 8823 } |
| 8450 } | 8824 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 8476 Handle<ExternalPixelArray> pixels(ExternalPixelArray::cast( | 8850 Handle<ExternalPixelArray> pixels(ExternalPixelArray::cast( |
| 8477 receiver->elements())); | 8851 receiver->elements())); |
| 8478 for (uint32_t j = 0; j < length; j++) { | 8852 for (uint32_t j = 0; j < length; j++) { |
| 8479 Handle<Smi> e(Smi::FromInt(pixels->get(j))); | 8853 Handle<Smi> e(Smi::FromInt(pixels->get(j))); |
| 8480 visitor->visit(j, e); | 8854 visitor->visit(j, e); |
| 8481 } | 8855 } |
| 8482 break; | 8856 break; |
| 8483 } | 8857 } |
| 8484 case JSObject::EXTERNAL_BYTE_ELEMENTS: { | 8858 case JSObject::EXTERNAL_BYTE_ELEMENTS: { |
| 8485 IterateExternalArrayElements<ExternalByteArray, int8_t>( | 8859 IterateExternalArrayElements<ExternalByteArray, int8_t>( |
| 8486 receiver, true, true, visitor); | 8860 isolate, receiver, true, true, visitor); |
| 8487 break; | 8861 break; |
| 8488 } | 8862 } |
| 8489 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { | 8863 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { |
| 8490 IterateExternalArrayElements<ExternalUnsignedByteArray, uint8_t>( | 8864 IterateExternalArrayElements<ExternalUnsignedByteArray, uint8_t>( |
| 8491 receiver, true, true, visitor); | 8865 isolate, receiver, true, true, visitor); |
| 8492 break; | 8866 break; |
| 8493 } | 8867 } |
| 8494 case JSObject::EXTERNAL_SHORT_ELEMENTS: { | 8868 case JSObject::EXTERNAL_SHORT_ELEMENTS: { |
| 8495 IterateExternalArrayElements<ExternalShortArray, int16_t>( | 8869 IterateExternalArrayElements<ExternalShortArray, int16_t>( |
| 8496 receiver, true, true, visitor); | 8870 isolate, receiver, true, true, visitor); |
| 8497 break; | 8871 break; |
| 8498 } | 8872 } |
| 8499 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: { | 8873 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: { |
| 8500 IterateExternalArrayElements<ExternalUnsignedShortArray, uint16_t>( | 8874 IterateExternalArrayElements<ExternalUnsignedShortArray, uint16_t>( |
| 8501 receiver, true, true, visitor); | 8875 isolate, receiver, true, true, visitor); |
| 8502 break; | 8876 break; |
| 8503 } | 8877 } |
| 8504 case JSObject::EXTERNAL_INT_ELEMENTS: { | 8878 case JSObject::EXTERNAL_INT_ELEMENTS: { |
| 8505 IterateExternalArrayElements<ExternalIntArray, int32_t>( | 8879 IterateExternalArrayElements<ExternalIntArray, int32_t>( |
| 8506 receiver, true, false, visitor); | 8880 isolate, receiver, true, false, visitor); |
| 8507 break; | 8881 break; |
| 8508 } | 8882 } |
| 8509 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: { | 8883 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: { |
| 8510 IterateExternalArrayElements<ExternalUnsignedIntArray, uint32_t>( | 8884 IterateExternalArrayElements<ExternalUnsignedIntArray, uint32_t>( |
| 8511 receiver, true, false, visitor); | 8885 isolate, receiver, true, false, visitor); |
| 8512 break; | 8886 break; |
| 8513 } | 8887 } |
| 8514 case JSObject::EXTERNAL_FLOAT_ELEMENTS: { | 8888 case JSObject::EXTERNAL_FLOAT_ELEMENTS: { |
| 8515 IterateExternalArrayElements<ExternalFloatArray, float>( | 8889 IterateExternalArrayElements<ExternalFloatArray, float>( |
| 8516 receiver, false, false, visitor); | 8890 isolate, receiver, false, false, visitor); |
| 8517 break; | 8891 break; |
| 8518 } | 8892 } |
| 8519 default: | 8893 default: |
| 8520 UNREACHABLE(); | 8894 UNREACHABLE(); |
| 8521 break; | 8895 break; |
| 8522 } | 8896 } |
| 8523 visitor->increase_index_offset(length); | 8897 visitor->increase_index_offset(length); |
| 8524 return true; | 8898 return true; |
| 8525 } | 8899 } |
| 8526 | 8900 |
| 8527 | 8901 |
| 8528 /** | 8902 /** |
| 8529 * Array::concat implementation. | 8903 * Array::concat implementation. |
| 8530 * See ECMAScript 262, 15.4.4.4. | 8904 * See ECMAScript 262, 15.4.4.4. |
| 8531 * TODO(581): Fix non-compliance for very large concatenations and update to | 8905 * TODO(581): Fix non-compliance for very large concatenations and update to |
| 8532 * following the ECMAScript 5 specification. | 8906 * following the ECMAScript 5 specification. |
| 8533 */ | 8907 */ |
| 8534 static MaybeObject* Runtime_ArrayConcat(Arguments args) { | 8908 static MaybeObject* Runtime_ArrayConcat(RUNTIME_CALLING_CONVENTION) { |
| 8909 RUNTIME_GET_ISOLATE; |
| 8535 ASSERT(args.length() == 1); | 8910 ASSERT(args.length() == 1); |
| 8536 HandleScope handle_scope; | 8911 HandleScope handle_scope(isolate); |
| 8537 | 8912 |
| 8538 CONVERT_ARG_CHECKED(JSArray, arguments, 0); | 8913 CONVERT_ARG_CHECKED(JSArray, arguments, 0); |
| 8539 int argument_count = static_cast<int>(arguments->length()->Number()); | 8914 int argument_count = static_cast<int>(arguments->length()->Number()); |
| 8540 RUNTIME_ASSERT(arguments->HasFastElements()); | 8915 RUNTIME_ASSERT(arguments->HasFastElements()); |
| 8541 Handle<FixedArray> elements(FixedArray::cast(arguments->elements())); | 8916 Handle<FixedArray> elements(FixedArray::cast(arguments->elements())); |
| 8542 | 8917 |
| 8543 // Pass 1: estimate the length and number of elements of the result. | 8918 // Pass 1: estimate the length and number of elements of the result. |
| 8544 // The actual length can be larger if any of the arguments have getters | 8919 // The actual length can be larger if any of the arguments have getters |
| 8545 // that mutate other arguments (but will otherwise be precise). | 8920 // that mutate other arguments (but will otherwise be precise). |
| 8546 // The number of elements is precise if there are no inherited elements. | 8921 // The number of elements is precise if there are no inherited elements. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8581 | 8956 |
| 8582 // If estimated number of elements is more than half of length, a | 8957 // If estimated number of elements is more than half of length, a |
| 8583 // fixed array (fast case) is more time and space-efficient than a | 8958 // fixed array (fast case) is more time and space-efficient than a |
| 8584 // dictionary. | 8959 // dictionary. |
| 8585 bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length; | 8960 bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length; |
| 8586 | 8961 |
| 8587 Handle<FixedArray> storage; | 8962 Handle<FixedArray> storage; |
| 8588 if (fast_case) { | 8963 if (fast_case) { |
| 8589 // The backing storage array must have non-existing elements to | 8964 // The backing storage array must have non-existing elements to |
| 8590 // preserve holes across concat operations. | 8965 // preserve holes across concat operations. |
| 8591 storage = Factory::NewFixedArrayWithHoles(estimate_result_length); | 8966 storage = isolate->factory()->NewFixedArrayWithHoles( |
| 8967 estimate_result_length); |
| 8592 } else { | 8968 } else { |
| 8593 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate | 8969 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate |
| 8594 uint32_t at_least_space_for = estimate_nof_elements + | 8970 uint32_t at_least_space_for = estimate_nof_elements + |
| 8595 (estimate_nof_elements >> 2); | 8971 (estimate_nof_elements >> 2); |
| 8596 storage = Handle<FixedArray>::cast( | 8972 storage = Handle<FixedArray>::cast( |
| 8597 Factory::NewNumberDictionary(at_least_space_for)); | 8973 isolate->factory()->NewNumberDictionary(at_least_space_for)); |
| 8598 } | 8974 } |
| 8599 | 8975 |
| 8600 ArrayConcatVisitor visitor(storage, fast_case); | 8976 ArrayConcatVisitor visitor(isolate, storage, fast_case); |
| 8601 | 8977 |
| 8602 for (int i = 0; i < argument_count; i++) { | 8978 for (int i = 0; i < argument_count; i++) { |
| 8603 Handle<Object> obj(elements->get(i)); | 8979 Handle<Object> obj(elements->get(i)); |
| 8604 if (obj->IsJSArray()) { | 8980 if (obj->IsJSArray()) { |
| 8605 Handle<JSArray> array = Handle<JSArray>::cast(obj); | 8981 Handle<JSArray> array = Handle<JSArray>::cast(obj); |
| 8606 if (!IterateElements(array, &visitor)) { | 8982 if (!IterateElements(isolate, array, &visitor)) { |
| 8607 return Failure::Exception(); | 8983 return Failure::Exception(); |
| 8608 } | 8984 } |
| 8609 } else { | 8985 } else { |
| 8610 visitor.visit(0, obj); | 8986 visitor.visit(0, obj); |
| 8611 visitor.increase_index_offset(1); | 8987 visitor.increase_index_offset(1); |
| 8612 } | 8988 } |
| 8613 } | 8989 } |
| 8614 | 8990 |
| 8615 return *visitor.ToArray(); | 8991 return *visitor.ToArray(); |
| 8616 } | 8992 } |
| 8617 | 8993 |
| 8618 | 8994 |
| 8619 // This will not allocate (flatten the string), but it may run | 8995 // This will not allocate (flatten the string), but it may run |
| 8620 // very slowly for very deeply nested ConsStrings. For debugging use only. | 8996 // very slowly for very deeply nested ConsStrings. For debugging use only. |
| 8621 static MaybeObject* Runtime_GlobalPrint(Arguments args) { | 8997 static MaybeObject* Runtime_GlobalPrint(RUNTIME_CALLING_CONVENTION) { |
| 8998 RUNTIME_GET_ISOLATE; |
| 8622 NoHandleAllocation ha; | 8999 NoHandleAllocation ha; |
| 8623 ASSERT(args.length() == 1); | 9000 ASSERT(args.length() == 1); |
| 8624 | 9001 |
| 8625 CONVERT_CHECKED(String, string, args[0]); | 9002 CONVERT_CHECKED(String, string, args[0]); |
| 8626 StringInputBuffer buffer(string); | 9003 StringInputBuffer buffer(string); |
| 8627 while (buffer.has_more()) { | 9004 while (buffer.has_more()) { |
| 8628 uint16_t character = buffer.GetNext(); | 9005 uint16_t character = buffer.GetNext(); |
| 8629 PrintF("%c", character); | 9006 PrintF("%c", character); |
| 8630 } | 9007 } |
| 8631 return string; | 9008 return string; |
| 8632 } | 9009 } |
| 8633 | 9010 |
| 8634 // Moves all own elements of an object, that are below a limit, to positions | 9011 // Moves all own elements of an object, that are below a limit, to positions |
| 8635 // starting at zero. All undefined values are placed after non-undefined values, | 9012 // starting at zero. All undefined values are placed after non-undefined values, |
| 8636 // and are followed by non-existing element. Does not change the length | 9013 // and are followed by non-existing element. Does not change the length |
| 8637 // property. | 9014 // property. |
| 8638 // Returns the number of non-undefined elements collected. | 9015 // Returns the number of non-undefined elements collected. |
| 8639 static MaybeObject* Runtime_RemoveArrayHoles(Arguments args) { | 9016 static MaybeObject* Runtime_RemoveArrayHoles(RUNTIME_CALLING_CONVENTION) { |
| 9017 RUNTIME_GET_ISOLATE; |
| 8640 ASSERT(args.length() == 2); | 9018 ASSERT(args.length() == 2); |
| 8641 CONVERT_CHECKED(JSObject, object, args[0]); | 9019 CONVERT_CHECKED(JSObject, object, args[0]); |
| 8642 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); | 9020 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); |
| 8643 return object->PrepareElementsForSort(limit); | 9021 return object->PrepareElementsForSort(limit); |
| 8644 } | 9022 } |
| 8645 | 9023 |
| 8646 | 9024 |
| 8647 // Move contents of argument 0 (an array) to argument 1 (an array) | 9025 // Move contents of argument 0 (an array) to argument 1 (an array) |
| 8648 static MaybeObject* Runtime_MoveArrayContents(Arguments args) { | 9026 static MaybeObject* Runtime_MoveArrayContents(RUNTIME_CALLING_CONVENTION) { |
| 9027 RUNTIME_GET_ISOLATE; |
| 8649 ASSERT(args.length() == 2); | 9028 ASSERT(args.length() == 2); |
| 8650 CONVERT_CHECKED(JSArray, from, args[0]); | 9029 CONVERT_CHECKED(JSArray, from, args[0]); |
| 8651 CONVERT_CHECKED(JSArray, to, args[1]); | 9030 CONVERT_CHECKED(JSArray, to, args[1]); |
| 8652 HeapObject* new_elements = from->elements(); | 9031 HeapObject* new_elements = from->elements(); |
| 8653 MaybeObject* maybe_new_map; | 9032 MaybeObject* maybe_new_map; |
| 8654 if (new_elements->map() == Heap::fixed_array_map() || | 9033 if (new_elements->map() == isolate->heap()->fixed_array_map() || |
| 8655 new_elements->map() == Heap::fixed_cow_array_map()) { | 9034 new_elements->map() == isolate->heap()->fixed_cow_array_map()) { |
| 8656 maybe_new_map = to->map()->GetFastElementsMap(); | 9035 maybe_new_map = to->map()->GetFastElementsMap(); |
| 8657 } else { | 9036 } else { |
| 8658 maybe_new_map = to->map()->GetSlowElementsMap(); | 9037 maybe_new_map = to->map()->GetSlowElementsMap(); |
| 8659 } | 9038 } |
| 8660 Object* new_map; | 9039 Object* new_map; |
| 8661 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; | 9040 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
| 8662 to->set_map(Map::cast(new_map)); | 9041 to->set_map(Map::cast(new_map)); |
| 8663 to->set_elements(new_elements); | 9042 to->set_elements(new_elements); |
| 8664 to->set_length(from->length()); | 9043 to->set_length(from->length()); |
| 8665 Object* obj; | 9044 Object* obj; |
| 8666 { MaybeObject* maybe_obj = from->ResetElements(); | 9045 { MaybeObject* maybe_obj = from->ResetElements(); |
| 8667 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 9046 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8668 } | 9047 } |
| 8669 from->set_length(Smi::FromInt(0)); | 9048 from->set_length(Smi::FromInt(0)); |
| 8670 return to; | 9049 return to; |
| 8671 } | 9050 } |
| 8672 | 9051 |
| 8673 | 9052 |
| 8674 // How many elements does this object/array have? | 9053 // How many elements does this object/array have? |
| 8675 static MaybeObject* Runtime_EstimateNumberOfElements(Arguments args) { | 9054 static MaybeObject* Runtime_EstimateNumberOfElements( |
| 9055 RUNTIME_CALLING_CONVENTION) { |
| 9056 RUNTIME_GET_ISOLATE; |
| 8676 ASSERT(args.length() == 1); | 9057 ASSERT(args.length() == 1); |
| 8677 CONVERT_CHECKED(JSObject, object, args[0]); | 9058 CONVERT_CHECKED(JSObject, object, args[0]); |
| 8678 HeapObject* elements = object->elements(); | 9059 HeapObject* elements = object->elements(); |
| 8679 if (elements->IsDictionary()) { | 9060 if (elements->IsDictionary()) { |
| 8680 return Smi::FromInt(NumberDictionary::cast(elements)->NumberOfElements()); | 9061 return Smi::FromInt(NumberDictionary::cast(elements)->NumberOfElements()); |
| 8681 } else if (object->IsJSArray()) { | 9062 } else if (object->IsJSArray()) { |
| 8682 return JSArray::cast(object)->length(); | 9063 return JSArray::cast(object)->length(); |
| 8683 } else { | 9064 } else { |
| 8684 return Smi::FromInt(FixedArray::cast(elements)->length()); | 9065 return Smi::FromInt(FixedArray::cast(elements)->length()); |
| 8685 } | 9066 } |
| 8686 } | 9067 } |
| 8687 | 9068 |
| 8688 | 9069 |
| 8689 static MaybeObject* Runtime_SwapElements(Arguments args) { | 9070 static MaybeObject* Runtime_SwapElements(RUNTIME_CALLING_CONVENTION) { |
| 8690 HandleScope handle_scope; | 9071 RUNTIME_GET_ISOLATE; |
| 9072 HandleScope handle_scope(isolate); |
| 8691 | 9073 |
| 8692 ASSERT_EQ(3, args.length()); | 9074 ASSERT_EQ(3, args.length()); |
| 8693 | 9075 |
| 8694 CONVERT_ARG_CHECKED(JSObject, object, 0); | 9076 CONVERT_ARG_CHECKED(JSObject, object, 0); |
| 8695 Handle<Object> key1 = args.at<Object>(1); | 9077 Handle<Object> key1 = args.at<Object>(1); |
| 8696 Handle<Object> key2 = args.at<Object>(2); | 9078 Handle<Object> key2 = args.at<Object>(2); |
| 8697 | 9079 |
| 8698 uint32_t index1, index2; | 9080 uint32_t index1, index2; |
| 8699 if (!key1->ToArrayIndex(&index1) | 9081 if (!key1->ToArrayIndex(&index1) |
| 8700 || !key2->ToArrayIndex(&index2)) { | 9082 || !key2->ToArrayIndex(&index2)) { |
| 8701 return Top::ThrowIllegalOperation(); | 9083 return isolate->ThrowIllegalOperation(); |
| 8702 } | 9084 } |
| 8703 | 9085 |
| 8704 Handle<JSObject> jsobject = Handle<JSObject>::cast(object); | 9086 Handle<JSObject> jsobject = Handle<JSObject>::cast(object); |
| 8705 Handle<Object> tmp1 = GetElement(jsobject, index1); | 9087 Handle<Object> tmp1 = GetElement(jsobject, index1); |
| 8706 RETURN_IF_EMPTY_HANDLE(tmp1); | 9088 RETURN_IF_EMPTY_HANDLE(isolate, tmp1); |
| 8707 Handle<Object> tmp2 = GetElement(jsobject, index2); | 9089 Handle<Object> tmp2 = GetElement(jsobject, index2); |
| 8708 RETURN_IF_EMPTY_HANDLE(tmp2); | 9090 RETURN_IF_EMPTY_HANDLE(isolate, tmp2); |
| 8709 | 9091 |
| 8710 RETURN_IF_EMPTY_HANDLE(SetElement(jsobject, index1, tmp2, kStrictMode)); | 9092 RETURN_IF_EMPTY_HANDLE(isolate, |
| 8711 RETURN_IF_EMPTY_HANDLE(SetElement(jsobject, index2, tmp1, kStrictMode)); | 9093 SetElement(jsobject, index1, tmp2, kStrictMode)); |
| 9094 RETURN_IF_EMPTY_HANDLE(isolate, |
| 9095 SetElement(jsobject, index2, tmp1, kStrictMode)); |
| 8712 | 9096 |
| 8713 return Heap::undefined_value(); | 9097 return isolate->heap()->undefined_value(); |
| 8714 } | 9098 } |
| 8715 | 9099 |
| 8716 | 9100 |
| 8717 // Returns an array that tells you where in the [0, length) interval an array | 9101 // Returns an array that tells you where in the [0, length) interval an array |
| 8718 // might have elements. Can either return keys (positive integers) or | 9102 // might have elements. Can either return keys (positive integers) or |
| 8719 // intervals (pair of a negative integer (-start-1) followed by a | 9103 // intervals (pair of a negative integer (-start-1) followed by a |
| 8720 // positive (length)) or undefined values. | 9104 // positive (length)) or undefined values. |
| 8721 // Intervals can span over some keys that are not in the object. | 9105 // Intervals can span over some keys that are not in the object. |
| 8722 static MaybeObject* Runtime_GetArrayKeys(Arguments args) { | 9106 static MaybeObject* Runtime_GetArrayKeys(RUNTIME_CALLING_CONVENTION) { |
| 9107 RUNTIME_GET_ISOLATE; |
| 8723 ASSERT(args.length() == 2); | 9108 ASSERT(args.length() == 2); |
| 8724 HandleScope scope; | 9109 HandleScope scope(isolate); |
| 8725 CONVERT_ARG_CHECKED(JSObject, array, 0); | 9110 CONVERT_ARG_CHECKED(JSObject, array, 0); |
| 8726 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); | 9111 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); |
| 8727 if (array->elements()->IsDictionary()) { | 9112 if (array->elements()->IsDictionary()) { |
| 8728 // Create an array and get all the keys into it, then remove all the | 9113 // Create an array and get all the keys into it, then remove all the |
| 8729 // keys that are not integers in the range 0 to length-1. | 9114 // keys that are not integers in the range 0 to length-1. |
| 8730 Handle<FixedArray> keys = GetKeysInFixedArrayFor(array, INCLUDE_PROTOS); | 9115 Handle<FixedArray> keys = GetKeysInFixedArrayFor(array, INCLUDE_PROTOS); |
| 8731 int keys_length = keys->length(); | 9116 int keys_length = keys->length(); |
| 8732 for (int i = 0; i < keys_length; i++) { | 9117 for (int i = 0; i < keys_length; i++) { |
| 8733 Object* key = keys->get(i); | 9118 Object* key = keys->get(i); |
| 8734 uint32_t index = 0; | 9119 uint32_t index = 0; |
| 8735 if (!key->ToArrayIndex(&index) || index >= length) { | 9120 if (!key->ToArrayIndex(&index) || index >= length) { |
| 8736 // Zap invalid keys. | 9121 // Zap invalid keys. |
| 8737 keys->set_undefined(i); | 9122 keys->set_undefined(i); |
| 8738 } | 9123 } |
| 8739 } | 9124 } |
| 8740 return *Factory::NewJSArrayWithElements(keys); | 9125 return *isolate->factory()->NewJSArrayWithElements(keys); |
| 8741 } else { | 9126 } else { |
| 8742 ASSERT(array->HasFastElements()); | 9127 ASSERT(array->HasFastElements()); |
| 8743 Handle<FixedArray> single_interval = Factory::NewFixedArray(2); | 9128 Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2); |
| 8744 // -1 means start of array. | 9129 // -1 means start of array. |
| 8745 single_interval->set(0, Smi::FromInt(-1)); | 9130 single_interval->set(0, Smi::FromInt(-1)); |
| 8746 uint32_t actual_length = | 9131 uint32_t actual_length = |
| 8747 static_cast<uint32_t>(FixedArray::cast(array->elements())->length()); | 9132 static_cast<uint32_t>(FixedArray::cast(array->elements())->length()); |
| 8748 uint32_t min_length = actual_length < length ? actual_length : length; | 9133 uint32_t min_length = actual_length < length ? actual_length : length; |
| 8749 Handle<Object> length_object = | 9134 Handle<Object> length_object = |
| 8750 Factory::NewNumber(static_cast<double>(min_length)); | 9135 isolate->factory()->NewNumber(static_cast<double>(min_length)); |
| 8751 single_interval->set(1, *length_object); | 9136 single_interval->set(1, *length_object); |
| 8752 return *Factory::NewJSArrayWithElements(single_interval); | 9137 return *isolate->factory()->NewJSArrayWithElements(single_interval); |
| 8753 } | 9138 } |
| 8754 } | 9139 } |
| 8755 | 9140 |
| 8756 | 9141 |
| 8757 // DefineAccessor takes an optional final argument which is the | 9142 // DefineAccessor takes an optional final argument which is the |
| 8758 // property attributes (eg, DONT_ENUM, DONT_DELETE). IMPORTANT: due | 9143 // property attributes (eg, DONT_ENUM, DONT_DELETE). IMPORTANT: due |
| 8759 // to the way accessors are implemented, it is set for both the getter | 9144 // to the way accessors are implemented, it is set for both the getter |
| 8760 // and setter on the first call to DefineAccessor and ignored on | 9145 // and setter on the first call to DefineAccessor and ignored on |
| 8761 // subsequent calls. | 9146 // subsequent calls. |
| 8762 static MaybeObject* Runtime_DefineAccessor(Arguments args) { | 9147 static MaybeObject* Runtime_DefineAccessor(RUNTIME_CALLING_CONVENTION) { |
| 9148 RUNTIME_GET_ISOLATE; |
| 8763 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5); | 9149 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5); |
| 8764 // Compute attributes. | 9150 // Compute attributes. |
| 8765 PropertyAttributes attributes = NONE; | 9151 PropertyAttributes attributes = NONE; |
| 8766 if (args.length() == 5) { | 9152 if (args.length() == 5) { |
| 8767 CONVERT_CHECKED(Smi, attrs, args[4]); | 9153 CONVERT_CHECKED(Smi, attrs, args[4]); |
| 8768 int value = attrs->value(); | 9154 int value = attrs->value(); |
| 8769 // Only attribute bits should be set. | 9155 // Only attribute bits should be set. |
| 8770 ASSERT((value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 9156 ASSERT((value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
| 8771 attributes = static_cast<PropertyAttributes>(value); | 9157 attributes = static_cast<PropertyAttributes>(value); |
| 8772 } | 9158 } |
| 8773 | 9159 |
| 8774 CONVERT_CHECKED(JSObject, obj, args[0]); | 9160 CONVERT_CHECKED(JSObject, obj, args[0]); |
| 8775 CONVERT_CHECKED(String, name, args[1]); | 9161 CONVERT_CHECKED(String, name, args[1]); |
| 8776 CONVERT_CHECKED(Smi, flag, args[2]); | 9162 CONVERT_CHECKED(Smi, flag, args[2]); |
| 8777 CONVERT_CHECKED(JSFunction, fun, args[3]); | 9163 CONVERT_CHECKED(JSFunction, fun, args[3]); |
| 8778 return obj->DefineAccessor(name, flag->value() == 0, fun, attributes); | 9164 return obj->DefineAccessor(name, flag->value() == 0, fun, attributes); |
| 8779 } | 9165 } |
| 8780 | 9166 |
| 8781 | 9167 |
| 8782 static MaybeObject* Runtime_LookupAccessor(Arguments args) { | 9168 static MaybeObject* Runtime_LookupAccessor(RUNTIME_CALLING_CONVENTION) { |
| 9169 RUNTIME_GET_ISOLATE; |
| 8783 ASSERT(args.length() == 3); | 9170 ASSERT(args.length() == 3); |
| 8784 CONVERT_CHECKED(JSObject, obj, args[0]); | 9171 CONVERT_CHECKED(JSObject, obj, args[0]); |
| 8785 CONVERT_CHECKED(String, name, args[1]); | 9172 CONVERT_CHECKED(String, name, args[1]); |
| 8786 CONVERT_CHECKED(Smi, flag, args[2]); | 9173 CONVERT_CHECKED(Smi, flag, args[2]); |
| 8787 return obj->LookupAccessor(name, flag->value() == 0); | 9174 return obj->LookupAccessor(name, flag->value() == 0); |
| 8788 } | 9175 } |
| 8789 | 9176 |
| 8790 | 9177 |
| 8791 #ifdef ENABLE_DEBUGGER_SUPPORT | 9178 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 8792 static MaybeObject* Runtime_DebugBreak(Arguments args) { | 9179 static MaybeObject* Runtime_DebugBreak(RUNTIME_CALLING_CONVENTION) { |
| 9180 RUNTIME_GET_ISOLATE; |
| 8793 ASSERT(args.length() == 0); | 9181 ASSERT(args.length() == 0); |
| 8794 return Execution::DebugBreakHelper(); | 9182 return Execution::DebugBreakHelper(); |
| 8795 } | 9183 } |
| 8796 | 9184 |
| 8797 | 9185 |
| 8798 // Helper functions for wrapping and unwrapping stack frame ids. | 9186 // Helper functions for wrapping and unwrapping stack frame ids. |
| 8799 static Smi* WrapFrameId(StackFrame::Id id) { | 9187 static Smi* WrapFrameId(StackFrame::Id id) { |
| 8800 ASSERT(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4))); | 9188 ASSERT(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4))); |
| 8801 return Smi::FromInt(id >> 2); | 9189 return Smi::FromInt(id >> 2); |
| 8802 } | 9190 } |
| 8803 | 9191 |
| 8804 | 9192 |
| 8805 static StackFrame::Id UnwrapFrameId(Smi* wrapped) { | 9193 static StackFrame::Id UnwrapFrameId(Smi* wrapped) { |
| 8806 return static_cast<StackFrame::Id>(wrapped->value() << 2); | 9194 return static_cast<StackFrame::Id>(wrapped->value() << 2); |
| 8807 } | 9195 } |
| 8808 | 9196 |
| 8809 | 9197 |
| 8810 // Adds a JavaScript function as a debug event listener. | 9198 // Adds a JavaScript function as a debug event listener. |
| 8811 // args[0]: debug event listener function to set or null or undefined for | 9199 // args[0]: debug event listener function to set or null or undefined for |
| 8812 // clearing the event listener function | 9200 // clearing the event listener function |
| 8813 // args[1]: object supplied during callback | 9201 // args[1]: object supplied during callback |
| 8814 static MaybeObject* Runtime_SetDebugEventListener(Arguments args) { | 9202 static MaybeObject* Runtime_SetDebugEventListener(RUNTIME_CALLING_CONVENTION) { |
| 9203 RUNTIME_GET_ISOLATE; |
| 8815 ASSERT(args.length() == 2); | 9204 ASSERT(args.length() == 2); |
| 8816 RUNTIME_ASSERT(args[0]->IsJSFunction() || | 9205 RUNTIME_ASSERT(args[0]->IsJSFunction() || |
| 8817 args[0]->IsUndefined() || | 9206 args[0]->IsUndefined() || |
| 8818 args[0]->IsNull()); | 9207 args[0]->IsNull()); |
| 8819 Handle<Object> callback = args.at<Object>(0); | 9208 Handle<Object> callback = args.at<Object>(0); |
| 8820 Handle<Object> data = args.at<Object>(1); | 9209 Handle<Object> data = args.at<Object>(1); |
| 8821 Debugger::SetEventListener(callback, data); | 9210 isolate->debugger()->SetEventListener(callback, data); |
| 8822 | 9211 |
| 8823 return Heap::undefined_value(); | 9212 return isolate->heap()->undefined_value(); |
| 8824 } | 9213 } |
| 8825 | 9214 |
| 8826 | 9215 |
| 8827 static MaybeObject* Runtime_Break(Arguments args) { | 9216 static MaybeObject* Runtime_Break(RUNTIME_CALLING_CONVENTION) { |
| 9217 RUNTIME_GET_ISOLATE; |
| 8828 ASSERT(args.length() == 0); | 9218 ASSERT(args.length() == 0); |
| 8829 StackGuard::DebugBreak(); | 9219 isolate->stack_guard()->DebugBreak(); |
| 8830 return Heap::undefined_value(); | 9220 return isolate->heap()->undefined_value(); |
| 8831 } | 9221 } |
| 8832 | 9222 |
| 8833 | 9223 |
| 8834 static MaybeObject* DebugLookupResultValue(Object* receiver, String* name, | 9224 static MaybeObject* DebugLookupResultValue(Heap* heap, |
| 9225 Object* receiver, |
| 9226 String* name, |
| 8835 LookupResult* result, | 9227 LookupResult* result, |
| 8836 bool* caught_exception) { | 9228 bool* caught_exception) { |
| 8837 Object* value; | 9229 Object* value; |
| 8838 switch (result->type()) { | 9230 switch (result->type()) { |
| 8839 case NORMAL: | 9231 case NORMAL: |
| 8840 value = result->holder()->GetNormalizedProperty(result); | 9232 value = result->holder()->GetNormalizedProperty(result); |
| 8841 if (value->IsTheHole()) { | 9233 if (value->IsTheHole()) { |
| 8842 return Heap::undefined_value(); | 9234 return heap->undefined_value(); |
| 8843 } | 9235 } |
| 8844 return value; | 9236 return value; |
| 8845 case FIELD: | 9237 case FIELD: |
| 8846 value = | 9238 value = |
| 8847 JSObject::cast( | 9239 JSObject::cast( |
| 8848 result->holder())->FastPropertyAt(result->GetFieldIndex()); | 9240 result->holder())->FastPropertyAt(result->GetFieldIndex()); |
| 8849 if (value->IsTheHole()) { | 9241 if (value->IsTheHole()) { |
| 8850 return Heap::undefined_value(); | 9242 return heap->undefined_value(); |
| 8851 } | 9243 } |
| 8852 return value; | 9244 return value; |
| 8853 case CONSTANT_FUNCTION: | 9245 case CONSTANT_FUNCTION: |
| 8854 return result->GetConstantFunction(); | 9246 return result->GetConstantFunction(); |
| 8855 case CALLBACKS: { | 9247 case CALLBACKS: { |
| 8856 Object* structure = result->GetCallbackObject(); | 9248 Object* structure = result->GetCallbackObject(); |
| 8857 if (structure->IsProxy() || structure->IsAccessorInfo()) { | 9249 if (structure->IsProxy() || structure->IsAccessorInfo()) { |
| 8858 MaybeObject* maybe_value = receiver->GetPropertyWithCallback( | 9250 MaybeObject* maybe_value = receiver->GetPropertyWithCallback( |
| 8859 receiver, structure, name, result->holder()); | 9251 receiver, structure, name, result->holder()); |
| 8860 if (!maybe_value->ToObject(&value)) { | 9252 if (!maybe_value->ToObject(&value)) { |
| 8861 if (maybe_value->IsRetryAfterGC()) return maybe_value; | 9253 if (maybe_value->IsRetryAfterGC()) return maybe_value; |
| 8862 ASSERT(maybe_value->IsException()); | 9254 ASSERT(maybe_value->IsException()); |
| 8863 maybe_value = Top::pending_exception(); | 9255 maybe_value = heap->isolate()->pending_exception(); |
| 8864 Top::clear_pending_exception(); | 9256 heap->isolate()->clear_pending_exception(); |
| 8865 if (caught_exception != NULL) { | 9257 if (caught_exception != NULL) { |
| 8866 *caught_exception = true; | 9258 *caught_exception = true; |
| 8867 } | 9259 } |
| 8868 return maybe_value; | 9260 return maybe_value; |
| 8869 } | 9261 } |
| 8870 return value; | 9262 return value; |
| 8871 } else { | 9263 } else { |
| 8872 return Heap::undefined_value(); | 9264 return heap->undefined_value(); |
| 8873 } | 9265 } |
| 8874 } | 9266 } |
| 8875 case INTERCEPTOR: | 9267 case INTERCEPTOR: |
| 8876 case MAP_TRANSITION: | 9268 case MAP_TRANSITION: |
| 8877 case CONSTANT_TRANSITION: | 9269 case CONSTANT_TRANSITION: |
| 8878 case NULL_DESCRIPTOR: | 9270 case NULL_DESCRIPTOR: |
| 8879 return Heap::undefined_value(); | 9271 return heap->undefined_value(); |
| 8880 default: | 9272 default: |
| 8881 UNREACHABLE(); | 9273 UNREACHABLE(); |
| 8882 } | 9274 } |
| 8883 UNREACHABLE(); | 9275 UNREACHABLE(); |
| 8884 return Heap::undefined_value(); | 9276 return heap->undefined_value(); |
| 8885 } | 9277 } |
| 8886 | 9278 |
| 8887 | 9279 |
| 8888 // Get debugger related details for an object property. | 9280 // Get debugger related details for an object property. |
| 8889 // args[0]: object holding property | 9281 // args[0]: object holding property |
| 8890 // args[1]: name of the property | 9282 // args[1]: name of the property |
| 8891 // | 9283 // |
| 8892 // The array returned contains the following information: | 9284 // The array returned contains the following information: |
| 8893 // 0: Property value | 9285 // 0: Property value |
| 8894 // 1: Property details | 9286 // 1: Property details |
| 8895 // 2: Property value is exception | 9287 // 2: Property value is exception |
| 8896 // 3: Getter function if defined | 9288 // 3: Getter function if defined |
| 8897 // 4: Setter function if defined | 9289 // 4: Setter function if defined |
| 8898 // Items 2-4 are only filled if the property has either a getter or a setter | 9290 // Items 2-4 are only filled if the property has either a getter or a setter |
| 8899 // defined through __defineGetter__ and/or __defineSetter__. | 9291 // defined through __defineGetter__ and/or __defineSetter__. |
| 8900 static MaybeObject* Runtime_DebugGetPropertyDetails(Arguments args) { | 9292 static MaybeObject* Runtime_DebugGetPropertyDetails( |
| 8901 HandleScope scope; | 9293 RUNTIME_CALLING_CONVENTION) { |
| 9294 RUNTIME_GET_ISOLATE; |
| 9295 HandleScope scope(isolate); |
| 8902 | 9296 |
| 8903 ASSERT(args.length() == 2); | 9297 ASSERT(args.length() == 2); |
| 8904 | 9298 |
| 8905 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 9299 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 8906 CONVERT_ARG_CHECKED(String, name, 1); | 9300 CONVERT_ARG_CHECKED(String, name, 1); |
| 8907 | 9301 |
| 8908 // Make sure to set the current context to the context before the debugger was | 9302 // Make sure to set the current context to the context before the debugger was |
| 8909 // entered (if the debugger is entered). The reason for switching context here | 9303 // entered (if the debugger is entered). The reason for switching context here |
| 8910 // is that for some property lookups (accessors and interceptors) callbacks | 9304 // is that for some property lookups (accessors and interceptors) callbacks |
| 8911 // into the embedding application can occour, and the embedding application | 9305 // into the embedding application can occour, and the embedding application |
| 8912 // could have the assumption that its own global context is the current | 9306 // could have the assumption that its own global context is the current |
| 8913 // context and not some internal debugger context. | 9307 // context and not some internal debugger context. |
| 8914 SaveContext save; | 9308 SaveContext save(isolate); |
| 8915 if (Debug::InDebugger()) { | 9309 if (isolate->debug()->InDebugger()) { |
| 8916 Top::set_context(*Debug::debugger_entry()->GetContext()); | 9310 isolate->set_context(*isolate->debug()->debugger_entry()->GetContext()); |
| 8917 } | 9311 } |
| 8918 | 9312 |
| 8919 // Skip the global proxy as it has no properties and always delegates to the | 9313 // Skip the global proxy as it has no properties and always delegates to the |
| 8920 // real global object. | 9314 // real global object. |
| 8921 if (obj->IsJSGlobalProxy()) { | 9315 if (obj->IsJSGlobalProxy()) { |
| 8922 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); | 9316 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); |
| 8923 } | 9317 } |
| 8924 | 9318 |
| 8925 | 9319 |
| 8926 // Check if the name is trivially convertible to an index and get the element | 9320 // Check if the name is trivially convertible to an index and get the element |
| 8927 // if so. | 9321 // if so. |
| 8928 uint32_t index; | 9322 uint32_t index; |
| 8929 if (name->AsArrayIndex(&index)) { | 9323 if (name->AsArrayIndex(&index)) { |
| 8930 Handle<FixedArray> details = Factory::NewFixedArray(2); | 9324 Handle<FixedArray> details = isolate->factory()->NewFixedArray(2); |
| 8931 Object* element_or_char; | 9325 Object* element_or_char; |
| 8932 { MaybeObject* maybe_element_or_char = | 9326 { MaybeObject* maybe_element_or_char = |
| 8933 Runtime::GetElementOrCharAt(obj, index); | 9327 Runtime::GetElementOrCharAt(isolate, obj, index); |
| 8934 if (!maybe_element_or_char->ToObject(&element_or_char)) { | 9328 if (!maybe_element_or_char->ToObject(&element_or_char)) { |
| 8935 return maybe_element_or_char; | 9329 return maybe_element_or_char; |
| 8936 } | 9330 } |
| 8937 } | 9331 } |
| 8938 details->set(0, element_or_char); | 9332 details->set(0, element_or_char); |
| 8939 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); | 9333 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); |
| 8940 return *Factory::NewJSArrayWithElements(details); | 9334 return *isolate->factory()->NewJSArrayWithElements(details); |
| 8941 } | 9335 } |
| 8942 | 9336 |
| 8943 // Find the number of objects making up this. | 9337 // Find the number of objects making up this. |
| 8944 int length = LocalPrototypeChainLength(*obj); | 9338 int length = LocalPrototypeChainLength(*obj); |
| 8945 | 9339 |
| 8946 // Try local lookup on each of the objects. | 9340 // Try local lookup on each of the objects. |
| 8947 Handle<JSObject> jsproto = obj; | 9341 Handle<JSObject> jsproto = obj; |
| 8948 for (int i = 0; i < length; i++) { | 9342 for (int i = 0; i < length; i++) { |
| 8949 LookupResult result; | 9343 LookupResult result; |
| 8950 jsproto->LocalLookup(*name, &result); | 9344 jsproto->LocalLookup(*name, &result); |
| 8951 if (result.IsProperty()) { | 9345 if (result.IsProperty()) { |
| 8952 // LookupResult is not GC safe as it holds raw object pointers. | 9346 // LookupResult is not GC safe as it holds raw object pointers. |
| 8953 // GC can happen later in this code so put the required fields into | 9347 // GC can happen later in this code so put the required fields into |
| 8954 // local variables using handles when required for later use. | 9348 // local variables using handles when required for later use. |
| 8955 PropertyType result_type = result.type(); | 9349 PropertyType result_type = result.type(); |
| 8956 Handle<Object> result_callback_obj; | 9350 Handle<Object> result_callback_obj; |
| 8957 if (result_type == CALLBACKS) { | 9351 if (result_type == CALLBACKS) { |
| 8958 result_callback_obj = Handle<Object>(result.GetCallbackObject()); | 9352 result_callback_obj = Handle<Object>(result.GetCallbackObject(), |
| 9353 isolate); |
| 8959 } | 9354 } |
| 8960 Smi* property_details = result.GetPropertyDetails().AsSmi(); | 9355 Smi* property_details = result.GetPropertyDetails().AsSmi(); |
| 8961 // DebugLookupResultValue can cause GC so details from LookupResult needs | 9356 // DebugLookupResultValue can cause GC so details from LookupResult needs |
| 8962 // to be copied to handles before this. | 9357 // to be copied to handles before this. |
| 8963 bool caught_exception = false; | 9358 bool caught_exception = false; |
| 8964 Object* raw_value; | 9359 Object* raw_value; |
| 8965 { MaybeObject* maybe_raw_value = | 9360 { MaybeObject* maybe_raw_value = |
| 8966 DebugLookupResultValue(*obj, *name, &result, &caught_exception); | 9361 DebugLookupResultValue(isolate->heap(), *obj, *name, |
| 9362 &result, &caught_exception); |
| 8967 if (!maybe_raw_value->ToObject(&raw_value)) return maybe_raw_value; | 9363 if (!maybe_raw_value->ToObject(&raw_value)) return maybe_raw_value; |
| 8968 } | 9364 } |
| 8969 Handle<Object> value(raw_value); | 9365 Handle<Object> value(raw_value, isolate); |
| 8970 | 9366 |
| 8971 // If the callback object is a fixed array then it contains JavaScript | 9367 // If the callback object is a fixed array then it contains JavaScript |
| 8972 // getter and/or setter. | 9368 // getter and/or setter. |
| 8973 bool hasJavaScriptAccessors = result_type == CALLBACKS && | 9369 bool hasJavaScriptAccessors = result_type == CALLBACKS && |
| 8974 result_callback_obj->IsFixedArray(); | 9370 result_callback_obj->IsFixedArray(); |
| 8975 Handle<FixedArray> details = | 9371 Handle<FixedArray> details = |
| 8976 Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2); | 9372 isolate->factory()->NewFixedArray(hasJavaScriptAccessors ? 5 : 2); |
| 8977 details->set(0, *value); | 9373 details->set(0, *value); |
| 8978 details->set(1, property_details); | 9374 details->set(1, property_details); |
| 8979 if (hasJavaScriptAccessors) { | 9375 if (hasJavaScriptAccessors) { |
| 8980 details->set(2, | 9376 details->set(2, |
| 8981 caught_exception ? Heap::true_value() | 9377 caught_exception ? isolate->heap()->true_value() |
| 8982 : Heap::false_value()); | 9378 : isolate->heap()->false_value()); |
| 8983 details->set(3, FixedArray::cast(*result_callback_obj)->get(0)); | 9379 details->set(3, FixedArray::cast(*result_callback_obj)->get(0)); |
| 8984 details->set(4, FixedArray::cast(*result_callback_obj)->get(1)); | 9380 details->set(4, FixedArray::cast(*result_callback_obj)->get(1)); |
| 8985 } | 9381 } |
| 8986 | 9382 |
| 8987 return *Factory::NewJSArrayWithElements(details); | 9383 return *isolate->factory()->NewJSArrayWithElements(details); |
| 8988 } | 9384 } |
| 8989 if (i < length - 1) { | 9385 if (i < length - 1) { |
| 8990 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | 9386 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); |
| 8991 } | 9387 } |
| 8992 } | 9388 } |
| 8993 | 9389 |
| 8994 return Heap::undefined_value(); | 9390 return isolate->heap()->undefined_value(); |
| 8995 } | 9391 } |
| 8996 | 9392 |
| 8997 | 9393 |
| 8998 static MaybeObject* Runtime_DebugGetProperty(Arguments args) { | 9394 static MaybeObject* Runtime_DebugGetProperty(RUNTIME_CALLING_CONVENTION) { |
| 8999 HandleScope scope; | 9395 RUNTIME_GET_ISOLATE; |
| 9396 HandleScope scope(isolate); |
| 9000 | 9397 |
| 9001 ASSERT(args.length() == 2); | 9398 ASSERT(args.length() == 2); |
| 9002 | 9399 |
| 9003 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 9400 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 9004 CONVERT_ARG_CHECKED(String, name, 1); | 9401 CONVERT_ARG_CHECKED(String, name, 1); |
| 9005 | 9402 |
| 9006 LookupResult result; | 9403 LookupResult result; |
| 9007 obj->Lookup(*name, &result); | 9404 obj->Lookup(*name, &result); |
| 9008 if (result.IsProperty()) { | 9405 if (result.IsProperty()) { |
| 9009 return DebugLookupResultValue(*obj, *name, &result, NULL); | 9406 return DebugLookupResultValue(isolate->heap(), *obj, *name, &result, NULL); |
| 9010 } | 9407 } |
| 9011 return Heap::undefined_value(); | 9408 return isolate->heap()->undefined_value(); |
| 9012 } | 9409 } |
| 9013 | 9410 |
| 9014 | 9411 |
| 9015 // Return the property type calculated from the property details. | 9412 // Return the property type calculated from the property details. |
| 9016 // args[0]: smi with property details. | 9413 // args[0]: smi with property details. |
| 9017 static MaybeObject* Runtime_DebugPropertyTypeFromDetails(Arguments args) { | 9414 static MaybeObject* Runtime_DebugPropertyTypeFromDetails( |
| 9415 RUNTIME_CALLING_CONVENTION) { |
| 9416 RUNTIME_GET_ISOLATE; |
| 9018 ASSERT(args.length() == 1); | 9417 ASSERT(args.length() == 1); |
| 9019 CONVERT_CHECKED(Smi, details, args[0]); | 9418 CONVERT_CHECKED(Smi, details, args[0]); |
| 9020 PropertyType type = PropertyDetails(details).type(); | 9419 PropertyType type = PropertyDetails(details).type(); |
| 9021 return Smi::FromInt(static_cast<int>(type)); | 9420 return Smi::FromInt(static_cast<int>(type)); |
| 9022 } | 9421 } |
| 9023 | 9422 |
| 9024 | 9423 |
| 9025 // Return the property attribute calculated from the property details. | 9424 // Return the property attribute calculated from the property details. |
| 9026 // args[0]: smi with property details. | 9425 // args[0]: smi with property details. |
| 9027 static MaybeObject* Runtime_DebugPropertyAttributesFromDetails(Arguments args) { | 9426 static MaybeObject* Runtime_DebugPropertyAttributesFromDetails( |
| 9427 RUNTIME_CALLING_CONVENTION) { |
| 9428 RUNTIME_GET_ISOLATE; |
| 9028 ASSERT(args.length() == 1); | 9429 ASSERT(args.length() == 1); |
| 9029 CONVERT_CHECKED(Smi, details, args[0]); | 9430 CONVERT_CHECKED(Smi, details, args[0]); |
| 9030 PropertyAttributes attributes = PropertyDetails(details).attributes(); | 9431 PropertyAttributes attributes = PropertyDetails(details).attributes(); |
| 9031 return Smi::FromInt(static_cast<int>(attributes)); | 9432 return Smi::FromInt(static_cast<int>(attributes)); |
| 9032 } | 9433 } |
| 9033 | 9434 |
| 9034 | 9435 |
| 9035 // Return the property insertion index calculated from the property details. | 9436 // Return the property insertion index calculated from the property details. |
| 9036 // args[0]: smi with property details. | 9437 // args[0]: smi with property details. |
| 9037 static MaybeObject* Runtime_DebugPropertyIndexFromDetails(Arguments args) { | 9438 static MaybeObject* Runtime_DebugPropertyIndexFromDetails( |
| 9439 RUNTIME_CALLING_CONVENTION) { |
| 9440 RUNTIME_GET_ISOLATE; |
| 9038 ASSERT(args.length() == 1); | 9441 ASSERT(args.length() == 1); |
| 9039 CONVERT_CHECKED(Smi, details, args[0]); | 9442 CONVERT_CHECKED(Smi, details, args[0]); |
| 9040 int index = PropertyDetails(details).index(); | 9443 int index = PropertyDetails(details).index(); |
| 9041 return Smi::FromInt(index); | 9444 return Smi::FromInt(index); |
| 9042 } | 9445 } |
| 9043 | 9446 |
| 9044 | 9447 |
| 9045 // Return property value from named interceptor. | 9448 // Return property value from named interceptor. |
| 9046 // args[0]: object | 9449 // args[0]: object |
| 9047 // args[1]: property name | 9450 // args[1]: property name |
| 9048 static MaybeObject* Runtime_DebugNamedInterceptorPropertyValue(Arguments args) { | 9451 static MaybeObject* Runtime_DebugNamedInterceptorPropertyValue( |
| 9049 HandleScope scope; | 9452 RUNTIME_CALLING_CONVENTION) { |
| 9453 RUNTIME_GET_ISOLATE; |
| 9454 HandleScope scope(isolate); |
| 9050 ASSERT(args.length() == 2); | 9455 ASSERT(args.length() == 2); |
| 9051 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 9456 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 9052 RUNTIME_ASSERT(obj->HasNamedInterceptor()); | 9457 RUNTIME_ASSERT(obj->HasNamedInterceptor()); |
| 9053 CONVERT_ARG_CHECKED(String, name, 1); | 9458 CONVERT_ARG_CHECKED(String, name, 1); |
| 9054 | 9459 |
| 9055 PropertyAttributes attributes; | 9460 PropertyAttributes attributes; |
| 9056 return obj->GetPropertyWithInterceptor(*obj, *name, &attributes); | 9461 return obj->GetPropertyWithInterceptor(*obj, *name, &attributes); |
| 9057 } | 9462 } |
| 9058 | 9463 |
| 9059 | 9464 |
| 9060 // Return element value from indexed interceptor. | 9465 // Return element value from indexed interceptor. |
| 9061 // args[0]: object | 9466 // args[0]: object |
| 9062 // args[1]: index | 9467 // args[1]: index |
| 9063 static MaybeObject* Runtime_DebugIndexedInterceptorElementValue( | 9468 static MaybeObject* Runtime_DebugIndexedInterceptorElementValue( |
| 9064 Arguments args) { | 9469 RUNTIME_CALLING_CONVENTION) { |
| 9065 HandleScope scope; | 9470 RUNTIME_GET_ISOLATE; |
| 9471 HandleScope scope(isolate); |
| 9066 ASSERT(args.length() == 2); | 9472 ASSERT(args.length() == 2); |
| 9067 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 9473 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 9068 RUNTIME_ASSERT(obj->HasIndexedInterceptor()); | 9474 RUNTIME_ASSERT(obj->HasIndexedInterceptor()); |
| 9069 CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]); | 9475 CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]); |
| 9070 | 9476 |
| 9071 return obj->GetElementWithInterceptor(*obj, index); | 9477 return obj->GetElementWithInterceptor(*obj, index); |
| 9072 } | 9478 } |
| 9073 | 9479 |
| 9074 | 9480 |
| 9075 static MaybeObject* Runtime_CheckExecutionState(Arguments args) { | 9481 static MaybeObject* Runtime_CheckExecutionState(RUNTIME_CALLING_CONVENTION) { |
| 9482 RUNTIME_GET_ISOLATE; |
| 9076 ASSERT(args.length() >= 1); | 9483 ASSERT(args.length() >= 1); |
| 9077 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); | 9484 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); |
| 9078 // Check that the break id is valid. | 9485 // Check that the break id is valid. |
| 9079 if (Debug::break_id() == 0 || break_id != Debug::break_id()) { | 9486 if (isolate->debug()->break_id() == 0 || |
| 9080 return Top::Throw(Heap::illegal_execution_state_symbol()); | 9487 break_id != isolate->debug()->break_id()) { |
| 9488 return isolate->Throw( |
| 9489 isolate->heap()->illegal_execution_state_symbol()); |
| 9081 } | 9490 } |
| 9082 | 9491 |
| 9083 return Heap::true_value(); | 9492 return isolate->heap()->true_value(); |
| 9084 } | 9493 } |
| 9085 | 9494 |
| 9086 | 9495 |
| 9087 static MaybeObject* Runtime_GetFrameCount(Arguments args) { | 9496 static MaybeObject* Runtime_GetFrameCount(RUNTIME_CALLING_CONVENTION) { |
| 9088 HandleScope scope; | 9497 RUNTIME_GET_ISOLATE; |
| 9498 HandleScope scope(isolate); |
| 9089 ASSERT(args.length() == 1); | 9499 ASSERT(args.length() == 1); |
| 9090 | 9500 |
| 9091 // Check arguments. | 9501 // Check arguments. |
| 9092 Object* result; | 9502 Object* result; |
| 9093 { MaybeObject* maybe_result = Runtime_CheckExecutionState(args); | 9503 { MaybeObject* maybe_result = Runtime_CheckExecutionState(args, isolate); |
| 9094 if (!maybe_result->ToObject(&result)) return maybe_result; | 9504 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 9095 } | 9505 } |
| 9096 | 9506 |
| 9097 // Count all frames which are relevant to debugging stack trace. | 9507 // Count all frames which are relevant to debugging stack trace. |
| 9098 int n = 0; | 9508 int n = 0; |
| 9099 StackFrame::Id id = Debug::break_frame_id(); | 9509 StackFrame::Id id = isolate->debug()->break_frame_id(); |
| 9100 if (id == StackFrame::NO_ID) { | 9510 if (id == StackFrame::NO_ID) { |
| 9101 // If there is no JavaScript stack frame count is 0. | 9511 // If there is no JavaScript stack frame count is 0. |
| 9102 return Smi::FromInt(0); | 9512 return Smi::FromInt(0); |
| 9103 } | 9513 } |
| 9104 for (JavaScriptFrameIterator it(id); !it.done(); it.Advance()) n++; | 9514 for (JavaScriptFrameIterator it(id); !it.done(); it.Advance()) n++; |
| 9105 return Smi::FromInt(n); | 9515 return Smi::FromInt(n); |
| 9106 } | 9516 } |
| 9107 | 9517 |
| 9108 | 9518 |
| 9109 static const int kFrameDetailsFrameIdIndex = 0; | 9519 static const int kFrameDetailsFrameIdIndex = 0; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 9127 // 2: Function | 9537 // 2: Function |
| 9128 // 3: Argument count | 9538 // 3: Argument count |
| 9129 // 4: Local count | 9539 // 4: Local count |
| 9130 // 5: Source position | 9540 // 5: Source position |
| 9131 // 6: Constructor call | 9541 // 6: Constructor call |
| 9132 // 7: Is at return | 9542 // 7: Is at return |
| 9133 // 8: Debugger frame | 9543 // 8: Debugger frame |
| 9134 // Arguments name, value | 9544 // Arguments name, value |
| 9135 // Locals name, value | 9545 // Locals name, value |
| 9136 // Return value if any | 9546 // Return value if any |
| 9137 static MaybeObject* Runtime_GetFrameDetails(Arguments args) { | 9547 static MaybeObject* Runtime_GetFrameDetails(RUNTIME_CALLING_CONVENTION) { |
| 9138 HandleScope scope; | 9548 RUNTIME_GET_ISOLATE; |
| 9549 HandleScope scope(isolate); |
| 9139 ASSERT(args.length() == 2); | 9550 ASSERT(args.length() == 2); |
| 9140 | 9551 |
| 9141 // Check arguments. | 9552 // Check arguments. |
| 9142 Object* check; | 9553 Object* check; |
| 9143 { MaybeObject* maybe_check = Runtime_CheckExecutionState(args); | 9554 { MaybeObject* maybe_check = Runtime_CheckExecutionState(args, isolate); |
| 9144 if (!maybe_check->ToObject(&check)) return maybe_check; | 9555 if (!maybe_check->ToObject(&check)) return maybe_check; |
| 9145 } | 9556 } |
| 9146 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); | 9557 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); |
| 9558 Heap* heap = isolate->heap(); |
| 9147 | 9559 |
| 9148 // Find the relevant frame with the requested index. | 9560 // Find the relevant frame with the requested index. |
| 9149 StackFrame::Id id = Debug::break_frame_id(); | 9561 StackFrame::Id id = isolate->debug()->break_frame_id(); |
| 9150 if (id == StackFrame::NO_ID) { | 9562 if (id == StackFrame::NO_ID) { |
| 9151 // If there are no JavaScript stack frames return undefined. | 9563 // If there are no JavaScript stack frames return undefined. |
| 9152 return Heap::undefined_value(); | 9564 return heap->undefined_value(); |
| 9153 } | 9565 } |
| 9154 int count = 0; | 9566 int count = 0; |
| 9155 JavaScriptFrameIterator it(id); | 9567 JavaScriptFrameIterator it(id); |
| 9156 for (; !it.done(); it.Advance()) { | 9568 for (; !it.done(); it.Advance()) { |
| 9157 if (count == index) break; | 9569 if (count == index) break; |
| 9158 count++; | 9570 count++; |
| 9159 } | 9571 } |
| 9160 if (it.done()) return Heap::undefined_value(); | 9572 if (it.done()) return heap->undefined_value(); |
| 9161 | 9573 |
| 9162 bool is_optimized_frame = | 9574 bool is_optimized_frame = |
| 9163 it.frame()->code()->kind() == Code::OPTIMIZED_FUNCTION; | 9575 it.frame()->LookupCode(isolate)->kind() == Code::OPTIMIZED_FUNCTION; |
| 9164 | 9576 |
| 9165 // Traverse the saved contexts chain to find the active context for the | 9577 // Traverse the saved contexts chain to find the active context for the |
| 9166 // selected frame. | 9578 // selected frame. |
| 9167 SaveContext* save = Top::save_context(); | 9579 SaveContext* save = isolate->save_context(); |
| 9168 while (save != NULL && !save->below(it.frame())) { | 9580 while (save != NULL && !save->below(it.frame())) { |
| 9169 save = save->prev(); | 9581 save = save->prev(); |
| 9170 } | 9582 } |
| 9171 ASSERT(save != NULL); | 9583 ASSERT(save != NULL); |
| 9172 | 9584 |
| 9173 // Get the frame id. | 9585 // Get the frame id. |
| 9174 Handle<Object> frame_id(WrapFrameId(it.frame()->id())); | 9586 Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate); |
| 9175 | 9587 |
| 9176 // Find source position. | 9588 // Find source position. |
| 9177 int position = it.frame()->code()->SourcePosition(it.frame()->pc()); | 9589 int position = |
| 9590 it.frame()->LookupCode(isolate)->SourcePosition(it.frame()->pc()); |
| 9178 | 9591 |
| 9179 // Check for constructor frame. | 9592 // Check for constructor frame. |
| 9180 bool constructor = it.frame()->IsConstructor(); | 9593 bool constructor = it.frame()->IsConstructor(); |
| 9181 | 9594 |
| 9182 // Get scope info and read from it for local variable information. | 9595 // Get scope info and read from it for local variable information. |
| 9183 Handle<JSFunction> function(JSFunction::cast(it.frame()->function())); | 9596 Handle<JSFunction> function(JSFunction::cast(it.frame()->function())); |
| 9184 Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info()); | 9597 Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info()); |
| 9185 ScopeInfo<> info(*scope_info); | 9598 ScopeInfo<> info(*scope_info); |
| 9186 | 9599 |
| 9187 // Get the context. | 9600 // Get the context. |
| 9188 Handle<Context> context(Context::cast(it.frame()->context())); | 9601 Handle<Context> context(Context::cast(it.frame()->context())); |
| 9189 | 9602 |
| 9190 // Get the locals names and values into a temporary array. | 9603 // Get the locals names and values into a temporary array. |
| 9191 // | 9604 // |
| 9192 // TODO(1240907): Hide compiler-introduced stack variables | 9605 // TODO(1240907): Hide compiler-introduced stack variables |
| 9193 // (e.g. .result)? For users of the debugger, they will probably be | 9606 // (e.g. .result)? For users of the debugger, they will probably be |
| 9194 // confusing. | 9607 // confusing. |
| 9195 Handle<FixedArray> locals = Factory::NewFixedArray(info.NumberOfLocals() * 2); | 9608 Handle<FixedArray> locals = |
| 9609 isolate->factory()->NewFixedArray(info.NumberOfLocals() * 2); |
| 9196 | 9610 |
| 9197 // Fill in the names of the locals. | 9611 // Fill in the names of the locals. |
| 9198 for (int i = 0; i < info.NumberOfLocals(); i++) { | 9612 for (int i = 0; i < info.NumberOfLocals(); i++) { |
| 9199 locals->set(i * 2, *info.LocalName(i)); | 9613 locals->set(i * 2, *info.LocalName(i)); |
| 9200 } | 9614 } |
| 9201 | 9615 |
| 9202 // Fill in the values of the locals. | 9616 // Fill in the values of the locals. |
| 9203 for (int i = 0; i < info.NumberOfLocals(); i++) { | 9617 for (int i = 0; i < info.NumberOfLocals(); i++) { |
| 9204 if (is_optimized_frame) { | 9618 if (is_optimized_frame) { |
| 9205 // If we are inspecting an optimized frame use undefined as the | 9619 // If we are inspecting an optimized frame use undefined as the |
| 9206 // value for all locals. | 9620 // value for all locals. |
| 9207 // | 9621 // |
| 9208 // TODO(1140): We should be able to get the correct values | 9622 // TODO(1140): We should be able to get the correct values |
| 9209 // for locals in optimized frames. | 9623 // for locals in optimized frames. |
| 9210 locals->set(i * 2 + 1, Heap::undefined_value()); | 9624 locals->set(i * 2 + 1, isolate->heap()->undefined_value()); |
| 9211 } else if (i < info.number_of_stack_slots()) { | 9625 } else if (i < info.number_of_stack_slots()) { |
| 9212 // Get the value from the stack. | 9626 // Get the value from the stack. |
| 9213 locals->set(i * 2 + 1, it.frame()->GetExpression(i)); | 9627 locals->set(i * 2 + 1, it.frame()->GetExpression(i)); |
| 9214 } else { | 9628 } else { |
| 9215 // Traverse the context chain to the function context as all local | 9629 // Traverse the context chain to the function context as all local |
| 9216 // variables stored in the context will be on the function context. | 9630 // variables stored in the context will be on the function context. |
| 9217 Handle<String> name = info.LocalName(i); | 9631 Handle<String> name = info.LocalName(i); |
| 9218 while (!context->is_function_context()) { | 9632 while (!context->is_function_context()) { |
| 9219 context = Handle<Context>(context->previous()); | 9633 context = Handle<Context>(context->previous()); |
| 9220 } | 9634 } |
| 9221 ASSERT(context->is_function_context()); | 9635 ASSERT(context->is_function_context()); |
| 9222 locals->set(i * 2 + 1, | 9636 locals->set(i * 2 + 1, |
| 9223 context->get(scope_info->ContextSlotIndex(*name, NULL))); | 9637 context->get(scope_info->ContextSlotIndex(*name, NULL))); |
| 9224 } | 9638 } |
| 9225 } | 9639 } |
| 9226 | 9640 |
| 9227 // Check whether this frame is positioned at return. If not top | 9641 // Check whether this frame is positioned at return. If not top |
| 9228 // frame or if the frame is optimized it cannot be at a return. | 9642 // frame or if the frame is optimized it cannot be at a return. |
| 9229 bool at_return = false; | 9643 bool at_return = false; |
| 9230 if (!is_optimized_frame && index == 0) { | 9644 if (!is_optimized_frame && index == 0) { |
| 9231 at_return = Debug::IsBreakAtReturn(it.frame()); | 9645 at_return = isolate->debug()->IsBreakAtReturn(it.frame()); |
| 9232 } | 9646 } |
| 9233 | 9647 |
| 9234 // If positioned just before return find the value to be returned and add it | 9648 // If positioned just before return find the value to be returned and add it |
| 9235 // to the frame information. | 9649 // to the frame information. |
| 9236 Handle<Object> return_value = Factory::undefined_value(); | 9650 Handle<Object> return_value = isolate->factory()->undefined_value(); |
| 9237 if (at_return) { | 9651 if (at_return) { |
| 9238 StackFrameIterator it2; | 9652 StackFrameIterator it2; |
| 9239 Address internal_frame_sp = NULL; | 9653 Address internal_frame_sp = NULL; |
| 9240 while (!it2.done()) { | 9654 while (!it2.done()) { |
| 9241 if (it2.frame()->is_internal()) { | 9655 if (it2.frame()->is_internal()) { |
| 9242 internal_frame_sp = it2.frame()->sp(); | 9656 internal_frame_sp = it2.frame()->sp(); |
| 9243 } else { | 9657 } else { |
| 9244 if (it2.frame()->is_java_script()) { | 9658 if (it2.frame()->is_java_script()) { |
| 9245 if (it2.frame()->id() == it.frame()->id()) { | 9659 if (it2.frame()->id() == it.frame()->id()) { |
| 9246 // The internal frame just before the JavaScript frame contains the | 9660 // The internal frame just before the JavaScript frame contains the |
| 9247 // value to return on top. A debug break at return will create an | 9661 // value to return on top. A debug break at return will create an |
| 9248 // internal frame to store the return value (eax/rax/r0) before | 9662 // internal frame to store the return value (eax/rax/r0) before |
| 9249 // entering the debug break exit frame. | 9663 // entering the debug break exit frame. |
| 9250 if (internal_frame_sp != NULL) { | 9664 if (internal_frame_sp != NULL) { |
| 9251 return_value = | 9665 return_value = |
| 9252 Handle<Object>(Memory::Object_at(internal_frame_sp)); | 9666 Handle<Object>(Memory::Object_at(internal_frame_sp), |
| 9667 isolate); |
| 9253 break; | 9668 break; |
| 9254 } | 9669 } |
| 9255 } | 9670 } |
| 9256 } | 9671 } |
| 9257 | 9672 |
| 9258 // Indicate that the previous frame was not an internal frame. | 9673 // Indicate that the previous frame was not an internal frame. |
| 9259 internal_frame_sp = NULL; | 9674 internal_frame_sp = NULL; |
| 9260 } | 9675 } |
| 9261 it2.Advance(); | 9676 it2.Advance(); |
| 9262 } | 9677 } |
| 9263 } | 9678 } |
| 9264 | 9679 |
| 9265 // Now advance to the arguments adapter frame (if any). It contains all | 9680 // Now advance to the arguments adapter frame (if any). It contains all |
| 9266 // the provided parameters whereas the function frame always have the number | 9681 // the provided parameters whereas the function frame always have the number |
| 9267 // of arguments matching the functions parameters. The rest of the | 9682 // of arguments matching the functions parameters. The rest of the |
| 9268 // information (except for what is collected above) is the same. | 9683 // information (except for what is collected above) is the same. |
| 9269 it.AdvanceToArgumentsFrame(); | 9684 it.AdvanceToArgumentsFrame(); |
| 9270 | 9685 |
| 9271 // Find the number of arguments to fill. At least fill the number of | 9686 // Find the number of arguments to fill. At least fill the number of |
| 9272 // parameters for the function and fill more if more parameters are provided. | 9687 // parameters for the function and fill more if more parameters are provided. |
| 9273 int argument_count = info.number_of_parameters(); | 9688 int argument_count = info.number_of_parameters(); |
| 9274 if (argument_count < it.frame()->ComputeParametersCount()) { | 9689 if (argument_count < it.frame()->ComputeParametersCount()) { |
| 9275 argument_count = it.frame()->ComputeParametersCount(); | 9690 argument_count = it.frame()->ComputeParametersCount(); |
| 9276 } | 9691 } |
| 9277 | 9692 |
| 9278 // Calculate the size of the result. | 9693 // Calculate the size of the result. |
| 9279 int details_size = kFrameDetailsFirstDynamicIndex + | 9694 int details_size = kFrameDetailsFirstDynamicIndex + |
| 9280 2 * (argument_count + info.NumberOfLocals()) + | 9695 2 * (argument_count + info.NumberOfLocals()) + |
| 9281 (at_return ? 1 : 0); | 9696 (at_return ? 1 : 0); |
| 9282 Handle<FixedArray> details = Factory::NewFixedArray(details_size); | 9697 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); |
| 9283 | 9698 |
| 9284 // Add the frame id. | 9699 // Add the frame id. |
| 9285 details->set(kFrameDetailsFrameIdIndex, *frame_id); | 9700 details->set(kFrameDetailsFrameIdIndex, *frame_id); |
| 9286 | 9701 |
| 9287 // Add the function (same as in function frame). | 9702 // Add the function (same as in function frame). |
| 9288 details->set(kFrameDetailsFunctionIndex, it.frame()->function()); | 9703 details->set(kFrameDetailsFunctionIndex, it.frame()->function()); |
| 9289 | 9704 |
| 9290 // Add the arguments count. | 9705 // Add the arguments count. |
| 9291 details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count)); | 9706 details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count)); |
| 9292 | 9707 |
| 9293 // Add the locals count | 9708 // Add the locals count |
| 9294 details->set(kFrameDetailsLocalCountIndex, | 9709 details->set(kFrameDetailsLocalCountIndex, |
| 9295 Smi::FromInt(info.NumberOfLocals())); | 9710 Smi::FromInt(info.NumberOfLocals())); |
| 9296 | 9711 |
| 9297 // Add the source position. | 9712 // Add the source position. |
| 9298 if (position != RelocInfo::kNoPosition) { | 9713 if (position != RelocInfo::kNoPosition) { |
| 9299 details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position)); | 9714 details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position)); |
| 9300 } else { | 9715 } else { |
| 9301 details->set(kFrameDetailsSourcePositionIndex, Heap::undefined_value()); | 9716 details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value()); |
| 9302 } | 9717 } |
| 9303 | 9718 |
| 9304 // Add the constructor information. | 9719 // Add the constructor information. |
| 9305 details->set(kFrameDetailsConstructCallIndex, Heap::ToBoolean(constructor)); | 9720 details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor)); |
| 9306 | 9721 |
| 9307 // Add the at return information. | 9722 // Add the at return information. |
| 9308 details->set(kFrameDetailsAtReturnIndex, Heap::ToBoolean(at_return)); | 9723 details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return)); |
| 9309 | 9724 |
| 9310 // Add information on whether this frame is invoked in the debugger context. | 9725 // Add information on whether this frame is invoked in the debugger context. |
| 9311 details->set(kFrameDetailsDebuggerFrameIndex, | 9726 details->set(kFrameDetailsDebuggerFrameIndex, |
| 9312 Heap::ToBoolean(*save->context() == *Debug::debug_context())); | 9727 heap->ToBoolean(*save->context() == |
| 9728 *isolate->debug()->debug_context())); |
| 9313 | 9729 |
| 9314 // Fill the dynamic part. | 9730 // Fill the dynamic part. |
| 9315 int details_index = kFrameDetailsFirstDynamicIndex; | 9731 int details_index = kFrameDetailsFirstDynamicIndex; |
| 9316 | 9732 |
| 9317 // Add arguments name and value. | 9733 // Add arguments name and value. |
| 9318 for (int i = 0; i < argument_count; i++) { | 9734 for (int i = 0; i < argument_count; i++) { |
| 9319 // Name of the argument. | 9735 // Name of the argument. |
| 9320 if (i < info.number_of_parameters()) { | 9736 if (i < info.number_of_parameters()) { |
| 9321 details->set(details_index++, *info.parameter_name(i)); | 9737 details->set(details_index++, *info.parameter_name(i)); |
| 9322 } else { | 9738 } else { |
| 9323 details->set(details_index++, Heap::undefined_value()); | 9739 details->set(details_index++, heap->undefined_value()); |
| 9324 } | 9740 } |
| 9325 | 9741 |
| 9326 // Parameter value. If we are inspecting an optimized frame, use | 9742 // Parameter value. If we are inspecting an optimized frame, use |
| 9327 // undefined as the value. | 9743 // undefined as the value. |
| 9328 // | 9744 // |
| 9329 // TODO(3141533): We should be able to get the actual parameter | 9745 // TODO(3141533): We should be able to get the actual parameter |
| 9330 // value for optimized frames. | 9746 // value for optimized frames. |
| 9331 if (!is_optimized_frame && | 9747 if (!is_optimized_frame && |
| 9332 (i < it.frame()->ComputeParametersCount())) { | 9748 (i < it.frame()->ComputeParametersCount())) { |
| 9333 details->set(details_index++, it.frame()->GetParameter(i)); | 9749 details->set(details_index++, it.frame()->GetParameter(i)); |
| 9334 } else { | 9750 } else { |
| 9335 details->set(details_index++, Heap::undefined_value()); | 9751 details->set(details_index++, heap->undefined_value()); |
| 9336 } | 9752 } |
| 9337 } | 9753 } |
| 9338 | 9754 |
| 9339 // Add locals name and value from the temporary copy from the function frame. | 9755 // Add locals name and value from the temporary copy from the function frame. |
| 9340 for (int i = 0; i < info.NumberOfLocals() * 2; i++) { | 9756 for (int i = 0; i < info.NumberOfLocals() * 2; i++) { |
| 9341 details->set(details_index++, locals->get(i)); | 9757 details->set(details_index++, locals->get(i)); |
| 9342 } | 9758 } |
| 9343 | 9759 |
| 9344 // Add the value being returned. | 9760 // Add the value being returned. |
| 9345 if (at_return) { | 9761 if (at_return) { |
| 9346 details->set(details_index++, *return_value); | 9762 details->set(details_index++, *return_value); |
| 9347 } | 9763 } |
| 9348 | 9764 |
| 9349 // Add the receiver (same as in function frame). | 9765 // Add the receiver (same as in function frame). |
| 9350 // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE | 9766 // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE |
| 9351 // THE FRAME ITERATOR TO WRAP THE RECEIVER. | 9767 // THE FRAME ITERATOR TO WRAP THE RECEIVER. |
| 9352 Handle<Object> receiver(it.frame()->receiver()); | 9768 Handle<Object> receiver(it.frame()->receiver(), isolate); |
| 9353 if (!receiver->IsJSObject()) { | 9769 if (!receiver->IsJSObject()) { |
| 9354 // If the receiver is NOT a JSObject we have hit an optimization | 9770 // If the receiver is NOT a JSObject we have hit an optimization |
| 9355 // where a value object is not converted into a wrapped JS objects. | 9771 // where a value object is not converted into a wrapped JS objects. |
| 9356 // To hide this optimization from the debugger, we wrap the receiver | 9772 // To hide this optimization from the debugger, we wrap the receiver |
| 9357 // by creating correct wrapper object based on the calling frame's | 9773 // by creating correct wrapper object based on the calling frame's |
| 9358 // global context. | 9774 // global context. |
| 9359 it.Advance(); | 9775 it.Advance(); |
| 9360 Handle<Context> calling_frames_global_context( | 9776 Handle<Context> calling_frames_global_context( |
| 9361 Context::cast(Context::cast(it.frame()->context())->global_context())); | 9777 Context::cast(Context::cast(it.frame()->context())->global_context())); |
| 9362 receiver = Factory::ToObject(receiver, calling_frames_global_context); | 9778 receiver = |
| 9779 isolate->factory()->ToObject(receiver, calling_frames_global_context); |
| 9363 } | 9780 } |
| 9364 details->set(kFrameDetailsReceiverIndex, *receiver); | 9781 details->set(kFrameDetailsReceiverIndex, *receiver); |
| 9365 | 9782 |
| 9366 ASSERT_EQ(details_size, details_index); | 9783 ASSERT_EQ(details_size, details_index); |
| 9367 return *Factory::NewJSArrayWithElements(details); | 9784 return *isolate->factory()->NewJSArrayWithElements(details); |
| 9368 } | 9785 } |
| 9369 | 9786 |
| 9370 | 9787 |
| 9371 // Copy all the context locals into an object used to materialize a scope. | 9788 // Copy all the context locals into an object used to materialize a scope. |
| 9372 static bool CopyContextLocalsToScopeObject( | 9789 static bool CopyContextLocalsToScopeObject( |
| 9790 Isolate* isolate, |
| 9373 Handle<SerializedScopeInfo> serialized_scope_info, | 9791 Handle<SerializedScopeInfo> serialized_scope_info, |
| 9374 ScopeInfo<>& scope_info, | 9792 ScopeInfo<>& scope_info, |
| 9375 Handle<Context> context, | 9793 Handle<Context> context, |
| 9376 Handle<JSObject> scope_object) { | 9794 Handle<JSObject> scope_object) { |
| 9377 // Fill all context locals to the context extension. | 9795 // Fill all context locals to the context extension. |
| 9378 for (int i = Context::MIN_CONTEXT_SLOTS; | 9796 for (int i = Context::MIN_CONTEXT_SLOTS; |
| 9379 i < scope_info.number_of_context_slots(); | 9797 i < scope_info.number_of_context_slots(); |
| 9380 i++) { | 9798 i++) { |
| 9381 int context_index = serialized_scope_info->ContextSlotIndex( | 9799 int context_index = serialized_scope_info->ContextSlotIndex( |
| 9382 *scope_info.context_slot_name(i), NULL); | 9800 *scope_info.context_slot_name(i), NULL); |
| 9383 | 9801 |
| 9384 // Don't include the arguments shadow (.arguments) context variable. | 9802 // Don't include the arguments shadow (.arguments) context variable. |
| 9385 if (*scope_info.context_slot_name(i) != Heap::arguments_shadow_symbol()) { | 9803 if (*scope_info.context_slot_name(i) != |
| 9804 isolate->heap()->arguments_shadow_symbol()) { |
| 9386 RETURN_IF_EMPTY_HANDLE_VALUE( | 9805 RETURN_IF_EMPTY_HANDLE_VALUE( |
| 9806 isolate, |
| 9387 SetProperty(scope_object, | 9807 SetProperty(scope_object, |
| 9388 scope_info.context_slot_name(i), | 9808 scope_info.context_slot_name(i), |
| 9389 Handle<Object>(context->get(context_index)), | 9809 Handle<Object>(context->get(context_index), isolate), |
| 9390 NONE, | 9810 NONE, |
| 9391 kNonStrictMode), | 9811 kNonStrictMode), |
| 9392 false); | 9812 false); |
| 9393 } | 9813 } |
| 9394 } | 9814 } |
| 9395 | 9815 |
| 9396 return true; | 9816 return true; |
| 9397 } | 9817 } |
| 9398 | 9818 |
| 9399 | 9819 |
| 9400 // Create a plain JSObject which materializes the local scope for the specified | 9820 // Create a plain JSObject which materializes the local scope for the specified |
| 9401 // frame. | 9821 // frame. |
| 9402 static Handle<JSObject> MaterializeLocalScope(JavaScriptFrame* frame) { | 9822 static Handle<JSObject> MaterializeLocalScope(Isolate* isolate, |
| 9823 JavaScriptFrame* frame) { |
| 9403 Handle<JSFunction> function(JSFunction::cast(frame->function())); | 9824 Handle<JSFunction> function(JSFunction::cast(frame->function())); |
| 9404 Handle<SharedFunctionInfo> shared(function->shared()); | 9825 Handle<SharedFunctionInfo> shared(function->shared()); |
| 9405 Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info()); | 9826 Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info()); |
| 9406 ScopeInfo<> scope_info(*serialized_scope_info); | 9827 ScopeInfo<> scope_info(*serialized_scope_info); |
| 9407 | 9828 |
| 9408 // Allocate and initialize a JSObject with all the arguments, stack locals | 9829 // Allocate and initialize a JSObject with all the arguments, stack locals |
| 9409 // heap locals and extension properties of the debugged function. | 9830 // heap locals and extension properties of the debugged function. |
| 9410 Handle<JSObject> local_scope = Factory::NewJSObject(Top::object_function()); | 9831 Handle<JSObject> local_scope = |
| 9832 isolate->factory()->NewJSObject(isolate->object_function()); |
| 9411 | 9833 |
| 9412 // First fill all parameters. | 9834 // First fill all parameters. |
| 9413 for (int i = 0; i < scope_info.number_of_parameters(); ++i) { | 9835 for (int i = 0; i < scope_info.number_of_parameters(); ++i) { |
| 9414 RETURN_IF_EMPTY_HANDLE_VALUE( | 9836 RETURN_IF_EMPTY_HANDLE_VALUE( |
| 9837 isolate, |
| 9415 SetProperty(local_scope, | 9838 SetProperty(local_scope, |
| 9416 scope_info.parameter_name(i), | 9839 scope_info.parameter_name(i), |
| 9417 Handle<Object>(frame->GetParameter(i)), | 9840 Handle<Object>(frame->GetParameter(i), isolate), |
| 9418 NONE, | 9841 NONE, |
| 9419 kNonStrictMode), | 9842 kNonStrictMode), |
| 9420 Handle<JSObject>()); | 9843 Handle<JSObject>()); |
| 9421 } | 9844 } |
| 9422 | 9845 |
| 9423 // Second fill all stack locals. | 9846 // Second fill all stack locals. |
| 9424 for (int i = 0; i < scope_info.number_of_stack_slots(); i++) { | 9847 for (int i = 0; i < scope_info.number_of_stack_slots(); i++) { |
| 9425 RETURN_IF_EMPTY_HANDLE_VALUE( | 9848 RETURN_IF_EMPTY_HANDLE_VALUE( |
| 9849 isolate, |
| 9426 SetProperty(local_scope, | 9850 SetProperty(local_scope, |
| 9427 scope_info.stack_slot_name(i), | 9851 scope_info.stack_slot_name(i), |
| 9428 Handle<Object>(frame->GetExpression(i)), | 9852 Handle<Object>(frame->GetExpression(i), isolate), |
| 9429 NONE, | 9853 NONE, |
| 9430 kNonStrictMode), | 9854 kNonStrictMode), |
| 9431 Handle<JSObject>()); | 9855 Handle<JSObject>()); |
| 9432 } | 9856 } |
| 9433 | 9857 |
| 9434 // Third fill all context locals. | 9858 // Third fill all context locals. |
| 9435 Handle<Context> frame_context(Context::cast(frame->context())); | 9859 Handle<Context> frame_context(Context::cast(frame->context())); |
| 9436 Handle<Context> function_context(frame_context->fcontext()); | 9860 Handle<Context> function_context(frame_context->fcontext()); |
| 9437 if (!CopyContextLocalsToScopeObject(serialized_scope_info, scope_info, | 9861 if (!CopyContextLocalsToScopeObject(isolate, |
| 9862 serialized_scope_info, scope_info, |
| 9438 function_context, local_scope)) { | 9863 function_context, local_scope)) { |
| 9439 return Handle<JSObject>(); | 9864 return Handle<JSObject>(); |
| 9440 } | 9865 } |
| 9441 | 9866 |
| 9442 // Finally copy any properties from the function context extension. This will | 9867 // Finally copy any properties from the function context extension. This will |
| 9443 // be variables introduced by eval. | 9868 // be variables introduced by eval. |
| 9444 if (function_context->closure() == *function) { | 9869 if (function_context->closure() == *function) { |
| 9445 if (function_context->has_extension() && | 9870 if (function_context->has_extension() && |
| 9446 !function_context->IsGlobalContext()) { | 9871 !function_context->IsGlobalContext()) { |
| 9447 Handle<JSObject> ext(JSObject::cast(function_context->extension())); | 9872 Handle<JSObject> ext(JSObject::cast(function_context->extension())); |
| 9448 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS); | 9873 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS); |
| 9449 for (int i = 0; i < keys->length(); i++) { | 9874 for (int i = 0; i < keys->length(); i++) { |
| 9450 // Names of variables introduced by eval are strings. | 9875 // Names of variables introduced by eval are strings. |
| 9451 ASSERT(keys->get(i)->IsString()); | 9876 ASSERT(keys->get(i)->IsString()); |
| 9452 Handle<String> key(String::cast(keys->get(i))); | 9877 Handle<String> key(String::cast(keys->get(i))); |
| 9453 RETURN_IF_EMPTY_HANDLE_VALUE( | 9878 RETURN_IF_EMPTY_HANDLE_VALUE( |
| 9879 isolate, |
| 9454 SetProperty(local_scope, | 9880 SetProperty(local_scope, |
| 9455 key, | 9881 key, |
| 9456 GetProperty(ext, key), | 9882 GetProperty(ext, key), |
| 9457 NONE, | 9883 NONE, |
| 9458 kNonStrictMode), | 9884 kNonStrictMode), |
| 9459 Handle<JSObject>()); | 9885 Handle<JSObject>()); |
| 9460 } | 9886 } |
| 9461 } | 9887 } |
| 9462 } | 9888 } |
| 9463 return local_scope; | 9889 return local_scope; |
| 9464 } | 9890 } |
| 9465 | 9891 |
| 9466 | 9892 |
| 9467 // Create a plain JSObject which materializes the closure content for the | 9893 // Create a plain JSObject which materializes the closure content for the |
| 9468 // context. | 9894 // context. |
| 9469 static Handle<JSObject> MaterializeClosure(Handle<Context> context) { | 9895 static Handle<JSObject> MaterializeClosure(Isolate* isolate, |
| 9896 Handle<Context> context) { |
| 9470 ASSERT(context->is_function_context()); | 9897 ASSERT(context->is_function_context()); |
| 9471 | 9898 |
| 9472 Handle<SharedFunctionInfo> shared(context->closure()->shared()); | 9899 Handle<SharedFunctionInfo> shared(context->closure()->shared()); |
| 9473 Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info()); | 9900 Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info()); |
| 9474 ScopeInfo<> scope_info(*serialized_scope_info); | 9901 ScopeInfo<> scope_info(*serialized_scope_info); |
| 9475 | 9902 |
| 9476 // Allocate and initialize a JSObject with all the content of theis function | 9903 // Allocate and initialize a JSObject with all the content of theis function |
| 9477 // closure. | 9904 // closure. |
| 9478 Handle<JSObject> closure_scope = Factory::NewJSObject(Top::object_function()); | 9905 Handle<JSObject> closure_scope = |
| 9906 isolate->factory()->NewJSObject(isolate->object_function()); |
| 9479 | 9907 |
| 9480 // Check whether the arguments shadow object exists. | 9908 // Check whether the arguments shadow object exists. |
| 9481 int arguments_shadow_index = | 9909 int arguments_shadow_index = |
| 9482 shared->scope_info()->ContextSlotIndex(Heap::arguments_shadow_symbol(), | 9910 shared->scope_info()->ContextSlotIndex( |
| 9483 NULL); | 9911 isolate->heap()->arguments_shadow_symbol(), NULL); |
| 9484 if (arguments_shadow_index >= 0) { | 9912 if (arguments_shadow_index >= 0) { |
| 9485 // In this case all the arguments are available in the arguments shadow | 9913 // In this case all the arguments are available in the arguments shadow |
| 9486 // object. | 9914 // object. |
| 9487 Handle<JSObject> arguments_shadow( | 9915 Handle<JSObject> arguments_shadow( |
| 9488 JSObject::cast(context->get(arguments_shadow_index))); | 9916 JSObject::cast(context->get(arguments_shadow_index))); |
| 9489 for (int i = 0; i < scope_info.number_of_parameters(); ++i) { | 9917 for (int i = 0; i < scope_info.number_of_parameters(); ++i) { |
| 9490 // We don't expect exception-throwing getters on the arguments shadow. | 9918 // We don't expect exception-throwing getters on the arguments shadow. |
| 9491 Object* element = arguments_shadow->GetElement(i)->ToObjectUnchecked(); | 9919 Object* element = arguments_shadow->GetElement(i)->ToObjectUnchecked(); |
| 9492 RETURN_IF_EMPTY_HANDLE_VALUE( | 9920 RETURN_IF_EMPTY_HANDLE_VALUE( |
| 9921 isolate, |
| 9493 SetProperty(closure_scope, | 9922 SetProperty(closure_scope, |
| 9494 scope_info.parameter_name(i), | 9923 scope_info.parameter_name(i), |
| 9495 Handle<Object>(element), | 9924 Handle<Object>(element, isolate), |
| 9496 NONE, | 9925 NONE, |
| 9497 kNonStrictMode), | 9926 kNonStrictMode), |
| 9498 Handle<JSObject>()); | 9927 Handle<JSObject>()); |
| 9499 } | 9928 } |
| 9500 } | 9929 } |
| 9501 | 9930 |
| 9502 // Fill all context locals to the context extension. | 9931 // Fill all context locals to the context extension. |
| 9503 if (!CopyContextLocalsToScopeObject(serialized_scope_info, scope_info, | 9932 if (!CopyContextLocalsToScopeObject(isolate, |
| 9933 serialized_scope_info, scope_info, |
| 9504 context, closure_scope)) { | 9934 context, closure_scope)) { |
| 9505 return Handle<JSObject>(); | 9935 return Handle<JSObject>(); |
| 9506 } | 9936 } |
| 9507 | 9937 |
| 9508 // Finally copy any properties from the function context extension. This will | 9938 // Finally copy any properties from the function context extension. This will |
| 9509 // be variables introduced by eval. | 9939 // be variables introduced by eval. |
| 9510 if (context->has_extension()) { | 9940 if (context->has_extension()) { |
| 9511 Handle<JSObject> ext(JSObject::cast(context->extension())); | 9941 Handle<JSObject> ext(JSObject::cast(context->extension())); |
| 9512 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS); | 9942 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS); |
| 9513 for (int i = 0; i < keys->length(); i++) { | 9943 for (int i = 0; i < keys->length(); i++) { |
| 9514 // Names of variables introduced by eval are strings. | 9944 // Names of variables introduced by eval are strings. |
| 9515 ASSERT(keys->get(i)->IsString()); | 9945 ASSERT(keys->get(i)->IsString()); |
| 9516 Handle<String> key(String::cast(keys->get(i))); | 9946 Handle<String> key(String::cast(keys->get(i))); |
| 9517 RETURN_IF_EMPTY_HANDLE_VALUE( | 9947 RETURN_IF_EMPTY_HANDLE_VALUE( |
| 9948 isolate, |
| 9518 SetProperty(closure_scope, | 9949 SetProperty(closure_scope, |
| 9519 key, | 9950 key, |
| 9520 GetProperty(ext, key), | 9951 GetProperty(ext, key), |
| 9521 NONE, | 9952 NONE, |
| 9522 kNonStrictMode), | 9953 kNonStrictMode), |
| 9523 Handle<JSObject>()); | 9954 Handle<JSObject>()); |
| 9524 } | 9955 } |
| 9525 } | 9956 } |
| 9526 | 9957 |
| 9527 return closure_scope; | 9958 return closure_scope; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 9538 ScopeTypeLocal, | 9969 ScopeTypeLocal, |
| 9539 ScopeTypeWith, | 9970 ScopeTypeWith, |
| 9540 ScopeTypeClosure, | 9971 ScopeTypeClosure, |
| 9541 // Every catch block contains an implicit with block (its parameter is | 9972 // Every catch block contains an implicit with block (its parameter is |
| 9542 // a JSContextExtensionObject) that extends current scope with a variable | 9973 // a JSContextExtensionObject) that extends current scope with a variable |
| 9543 // holding exception object. Such with blocks are treated as scopes of their | 9974 // holding exception object. Such with blocks are treated as scopes of their |
| 9544 // own type. | 9975 // own type. |
| 9545 ScopeTypeCatch | 9976 ScopeTypeCatch |
| 9546 }; | 9977 }; |
| 9547 | 9978 |
| 9548 explicit ScopeIterator(JavaScriptFrame* frame) | 9979 ScopeIterator(Isolate* isolate, JavaScriptFrame* frame) |
| 9549 : frame_(frame), | 9980 : isolate_(isolate), |
| 9981 frame_(frame), |
| 9550 function_(JSFunction::cast(frame->function())), | 9982 function_(JSFunction::cast(frame->function())), |
| 9551 context_(Context::cast(frame->context())), | 9983 context_(Context::cast(frame->context())), |
| 9552 local_done_(false), | 9984 local_done_(false), |
| 9553 at_local_(false) { | 9985 at_local_(false) { |
| 9554 | 9986 |
| 9555 // Check whether the first scope is actually a local scope. | 9987 // Check whether the first scope is actually a local scope. |
| 9556 if (context_->IsGlobalContext()) { | 9988 if (context_->IsGlobalContext()) { |
| 9557 // If there is a stack slot for .result then this local scope has been | 9989 // If there is a stack slot for .result then this local scope has been |
| 9558 // created for evaluating top level code and it is not a real local scope. | 9990 // created for evaluating top level code and it is not a real local scope. |
| 9559 // Checking for the existence of .result seems fragile, but the scope info | 9991 // Checking for the existence of .result seems fragile, but the scope info |
| 9560 // saved with the code object does not otherwise have that information. | 9992 // saved with the code object does not otherwise have that information. |
| 9561 int index = function_->shared()->scope_info()-> | 9993 int index = function_->shared()->scope_info()-> |
| 9562 StackSlotIndex(Heap::result_symbol()); | 9994 StackSlotIndex(isolate_->heap()->result_symbol()); |
| 9563 at_local_ = index < 0; | 9995 at_local_ = index < 0; |
| 9564 } else if (context_->is_function_context()) { | 9996 } else if (context_->is_function_context()) { |
| 9565 at_local_ = true; | 9997 at_local_ = true; |
| 9566 } | 9998 } |
| 9567 } | 9999 } |
| 9568 | 10000 |
| 9569 // More scopes? | 10001 // More scopes? |
| 9570 bool Done() { return context_.is_null(); } | 10002 bool Done() { return context_.is_null(); } |
| 9571 | 10003 |
| 9572 // Move to the next scope. | 10004 // Move to the next scope. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9630 } | 10062 } |
| 9631 | 10063 |
| 9632 // Return the JavaScript object with the content of the current scope. | 10064 // Return the JavaScript object with the content of the current scope. |
| 9633 Handle<JSObject> ScopeObject() { | 10065 Handle<JSObject> ScopeObject() { |
| 9634 switch (Type()) { | 10066 switch (Type()) { |
| 9635 case ScopeIterator::ScopeTypeGlobal: | 10067 case ScopeIterator::ScopeTypeGlobal: |
| 9636 return Handle<JSObject>(CurrentContext()->global()); | 10068 return Handle<JSObject>(CurrentContext()->global()); |
| 9637 break; | 10069 break; |
| 9638 case ScopeIterator::ScopeTypeLocal: | 10070 case ScopeIterator::ScopeTypeLocal: |
| 9639 // Materialize the content of the local scope into a JSObject. | 10071 // Materialize the content of the local scope into a JSObject. |
| 9640 return MaterializeLocalScope(frame_); | 10072 return MaterializeLocalScope(isolate_, frame_); |
| 9641 break; | 10073 break; |
| 9642 case ScopeIterator::ScopeTypeWith: | 10074 case ScopeIterator::ScopeTypeWith: |
| 9643 case ScopeIterator::ScopeTypeCatch: | 10075 case ScopeIterator::ScopeTypeCatch: |
| 9644 // Return the with object. | 10076 // Return the with object. |
| 9645 return Handle<JSObject>(CurrentContext()->extension()); | 10077 return Handle<JSObject>(CurrentContext()->extension()); |
| 9646 break; | 10078 break; |
| 9647 case ScopeIterator::ScopeTypeClosure: | 10079 case ScopeIterator::ScopeTypeClosure: |
| 9648 // Materialize the content of the closure scope into a JSObject. | 10080 // Materialize the content of the closure scope into a JSObject. |
| 9649 return MaterializeClosure(CurrentContext()); | 10081 return MaterializeClosure(isolate_, CurrentContext()); |
| 9650 break; | 10082 break; |
| 9651 } | 10083 } |
| 9652 UNREACHABLE(); | 10084 UNREACHABLE(); |
| 9653 return Handle<JSObject>(); | 10085 return Handle<JSObject>(); |
| 9654 } | 10086 } |
| 9655 | 10087 |
| 9656 // Return the context for this scope. For the local context there might not | 10088 // Return the context for this scope. For the local context there might not |
| 9657 // be an actual context. | 10089 // be an actual context. |
| 9658 Handle<Context> CurrentContext() { | 10090 Handle<Context> CurrentContext() { |
| 9659 if (at_local_ && context_->closure() != *function_) { | 10091 if (at_local_ && context_->closure() != *function_) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9718 } | 10150 } |
| 9719 | 10151 |
| 9720 default: | 10152 default: |
| 9721 UNREACHABLE(); | 10153 UNREACHABLE(); |
| 9722 } | 10154 } |
| 9723 PrintF("\n"); | 10155 PrintF("\n"); |
| 9724 } | 10156 } |
| 9725 #endif | 10157 #endif |
| 9726 | 10158 |
| 9727 private: | 10159 private: |
| 10160 Isolate* isolate_; |
| 9728 JavaScriptFrame* frame_; | 10161 JavaScriptFrame* frame_; |
| 9729 Handle<JSFunction> function_; | 10162 Handle<JSFunction> function_; |
| 9730 Handle<Context> context_; | 10163 Handle<Context> context_; |
| 9731 bool local_done_; | 10164 bool local_done_; |
| 9732 bool at_local_; | 10165 bool at_local_; |
| 9733 | 10166 |
| 9734 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); | 10167 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); |
| 9735 }; | 10168 }; |
| 9736 | 10169 |
| 9737 | 10170 |
| 9738 static MaybeObject* Runtime_GetScopeCount(Arguments args) { | 10171 static MaybeObject* Runtime_GetScopeCount(RUNTIME_CALLING_CONVENTION) { |
| 9739 HandleScope scope; | 10172 RUNTIME_GET_ISOLATE; |
| 10173 HandleScope scope(isolate); |
| 9740 ASSERT(args.length() == 2); | 10174 ASSERT(args.length() == 2); |
| 9741 | 10175 |
| 9742 // Check arguments. | 10176 // Check arguments. |
| 9743 Object* check; | 10177 Object* check; |
| 9744 { MaybeObject* maybe_check = Runtime_CheckExecutionState(args); | 10178 { MaybeObject* maybe_check = Runtime_CheckExecutionState(args, isolate); |
| 9745 if (!maybe_check->ToObject(&check)) return maybe_check; | 10179 if (!maybe_check->ToObject(&check)) return maybe_check; |
| 9746 } | 10180 } |
| 9747 CONVERT_CHECKED(Smi, wrapped_id, args[1]); | 10181 CONVERT_CHECKED(Smi, wrapped_id, args[1]); |
| 9748 | 10182 |
| 9749 // Get the frame where the debugging is performed. | 10183 // Get the frame where the debugging is performed. |
| 9750 StackFrame::Id id = UnwrapFrameId(wrapped_id); | 10184 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
| 9751 JavaScriptFrameIterator it(id); | 10185 JavaScriptFrameIterator it(id); |
| 9752 JavaScriptFrame* frame = it.frame(); | 10186 JavaScriptFrame* frame = it.frame(); |
| 9753 | 10187 |
| 9754 // Count the visible scopes. | 10188 // Count the visible scopes. |
| 9755 int n = 0; | 10189 int n = 0; |
| 9756 for (ScopeIterator it(frame); !it.Done(); it.Next()) { | 10190 for (ScopeIterator it(isolate, frame); !it.Done(); it.Next()) { |
| 9757 n++; | 10191 n++; |
| 9758 } | 10192 } |
| 9759 | 10193 |
| 9760 return Smi::FromInt(n); | 10194 return Smi::FromInt(n); |
| 9761 } | 10195 } |
| 9762 | 10196 |
| 9763 | 10197 |
| 9764 static const int kScopeDetailsTypeIndex = 0; | 10198 static const int kScopeDetailsTypeIndex = 0; |
| 9765 static const int kScopeDetailsObjectIndex = 1; | 10199 static const int kScopeDetailsObjectIndex = 1; |
| 9766 static const int kScopeDetailsSize = 2; | 10200 static const int kScopeDetailsSize = 2; |
| 9767 | 10201 |
| 9768 // Return an array with scope details | 10202 // Return an array with scope details |
| 9769 // args[0]: number: break id | 10203 // args[0]: number: break id |
| 9770 // args[1]: number: frame index | 10204 // args[1]: number: frame index |
| 9771 // args[2]: number: scope index | 10205 // args[2]: number: scope index |
| 9772 // | 10206 // |
| 9773 // The array returned contains the following information: | 10207 // The array returned contains the following information: |
| 9774 // 0: Scope type | 10208 // 0: Scope type |
| 9775 // 1: Scope object | 10209 // 1: Scope object |
| 9776 static MaybeObject* Runtime_GetScopeDetails(Arguments args) { | 10210 static MaybeObject* Runtime_GetScopeDetails(RUNTIME_CALLING_CONVENTION) { |
| 9777 HandleScope scope; | 10211 RUNTIME_GET_ISOLATE; |
| 10212 HandleScope scope(isolate); |
| 9778 ASSERT(args.length() == 3); | 10213 ASSERT(args.length() == 3); |
| 9779 | 10214 |
| 9780 // Check arguments. | 10215 // Check arguments. |
| 9781 Object* check; | 10216 Object* check; |
| 9782 { MaybeObject* maybe_check = Runtime_CheckExecutionState(args); | 10217 { MaybeObject* maybe_check = Runtime_CheckExecutionState(args, isolate); |
| 9783 if (!maybe_check->ToObject(&check)) return maybe_check; | 10218 if (!maybe_check->ToObject(&check)) return maybe_check; |
| 9784 } | 10219 } |
| 9785 CONVERT_CHECKED(Smi, wrapped_id, args[1]); | 10220 CONVERT_CHECKED(Smi, wrapped_id, args[1]); |
| 9786 CONVERT_NUMBER_CHECKED(int, index, Int32, args[2]); | 10221 CONVERT_NUMBER_CHECKED(int, index, Int32, args[2]); |
| 9787 | 10222 |
| 9788 // Get the frame where the debugging is performed. | 10223 // Get the frame where the debugging is performed. |
| 9789 StackFrame::Id id = UnwrapFrameId(wrapped_id); | 10224 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
| 9790 JavaScriptFrameIterator frame_it(id); | 10225 JavaScriptFrameIterator frame_it(id); |
| 9791 JavaScriptFrame* frame = frame_it.frame(); | 10226 JavaScriptFrame* frame = frame_it.frame(); |
| 9792 | 10227 |
| 9793 // Find the requested scope. | 10228 // Find the requested scope. |
| 9794 int n = 0; | 10229 int n = 0; |
| 9795 ScopeIterator it(frame); | 10230 ScopeIterator it(isolate, frame); |
| 9796 for (; !it.Done() && n < index; it.Next()) { | 10231 for (; !it.Done() && n < index; it.Next()) { |
| 9797 n++; | 10232 n++; |
| 9798 } | 10233 } |
| 9799 if (it.Done()) { | 10234 if (it.Done()) { |
| 9800 return Heap::undefined_value(); | 10235 return isolate->heap()->undefined_value(); |
| 9801 } | 10236 } |
| 9802 | 10237 |
| 9803 // Calculate the size of the result. | 10238 // Calculate the size of the result. |
| 9804 int details_size = kScopeDetailsSize; | 10239 int details_size = kScopeDetailsSize; |
| 9805 Handle<FixedArray> details = Factory::NewFixedArray(details_size); | 10240 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); |
| 9806 | 10241 |
| 9807 // Fill in scope details. | 10242 // Fill in scope details. |
| 9808 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type())); | 10243 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type())); |
| 9809 Handle<JSObject> scope_object = it.ScopeObject(); | 10244 Handle<JSObject> scope_object = it.ScopeObject(); |
| 9810 RETURN_IF_EMPTY_HANDLE(scope_object); | 10245 RETURN_IF_EMPTY_HANDLE(isolate, scope_object); |
| 9811 details->set(kScopeDetailsObjectIndex, *scope_object); | 10246 details->set(kScopeDetailsObjectIndex, *scope_object); |
| 9812 | 10247 |
| 9813 return *Factory::NewJSArrayWithElements(details); | 10248 return *isolate->factory()->NewJSArrayWithElements(details); |
| 9814 } | 10249 } |
| 9815 | 10250 |
| 9816 | 10251 |
| 9817 static MaybeObject* Runtime_DebugPrintScopes(Arguments args) { | 10252 static MaybeObject* Runtime_DebugPrintScopes(RUNTIME_CALLING_CONVENTION) { |
| 9818 HandleScope scope; | 10253 RUNTIME_GET_ISOLATE; |
| 10254 HandleScope scope(isolate); |
| 9819 ASSERT(args.length() == 0); | 10255 ASSERT(args.length() == 0); |
| 9820 | 10256 |
| 9821 #ifdef DEBUG | 10257 #ifdef DEBUG |
| 9822 // Print the scopes for the top frame. | 10258 // Print the scopes for the top frame. |
| 9823 StackFrameLocator locator; | 10259 StackFrameLocator locator; |
| 9824 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); | 10260 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); |
| 9825 for (ScopeIterator it(frame); !it.Done(); it.Next()) { | 10261 for (ScopeIterator it(isolate, frame); !it.Done(); it.Next()) { |
| 9826 it.DebugPrint(); | 10262 it.DebugPrint(); |
| 9827 } | 10263 } |
| 9828 #endif | 10264 #endif |
| 9829 return Heap::undefined_value(); | 10265 return isolate->heap()->undefined_value(); |
| 9830 } | 10266 } |
| 9831 | 10267 |
| 9832 | 10268 |
| 9833 static MaybeObject* Runtime_GetThreadCount(Arguments args) { | 10269 static MaybeObject* Runtime_GetThreadCount(RUNTIME_CALLING_CONVENTION) { |
| 9834 HandleScope scope; | 10270 RUNTIME_GET_ISOLATE; |
| 10271 HandleScope scope(isolate); |
| 9835 ASSERT(args.length() == 1); | 10272 ASSERT(args.length() == 1); |
| 9836 | 10273 |
| 9837 // Check arguments. | 10274 // Check arguments. |
| 9838 Object* result; | 10275 Object* result; |
| 9839 { MaybeObject* maybe_result = Runtime_CheckExecutionState(args); | 10276 { MaybeObject* maybe_result = Runtime_CheckExecutionState(args, isolate); |
| 9840 if (!maybe_result->ToObject(&result)) return maybe_result; | 10277 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 9841 } | 10278 } |
| 9842 | 10279 |
| 9843 // Count all archived V8 threads. | 10280 // Count all archived V8 threads. |
| 9844 int n = 0; | 10281 int n = 0; |
| 9845 for (ThreadState* thread = ThreadState::FirstInUse(); | 10282 for (ThreadState* thread = |
| 10283 isolate->thread_manager()->FirstThreadStateInUse(); |
| 9846 thread != NULL; | 10284 thread != NULL; |
| 9847 thread = thread->Next()) { | 10285 thread = thread->Next()) { |
| 9848 n++; | 10286 n++; |
| 9849 } | 10287 } |
| 9850 | 10288 |
| 9851 // Total number of threads is current thread and archived threads. | 10289 // Total number of threads is current thread and archived threads. |
| 9852 return Smi::FromInt(n + 1); | 10290 return Smi::FromInt(n + 1); |
| 9853 } | 10291 } |
| 9854 | 10292 |
| 9855 | 10293 |
| 9856 static const int kThreadDetailsCurrentThreadIndex = 0; | 10294 static const int kThreadDetailsCurrentThreadIndex = 0; |
| 9857 static const int kThreadDetailsThreadIdIndex = 1; | 10295 static const int kThreadDetailsThreadIdIndex = 1; |
| 9858 static const int kThreadDetailsSize = 2; | 10296 static const int kThreadDetailsSize = 2; |
| 9859 | 10297 |
| 9860 // Return an array with thread details | 10298 // Return an array with thread details |
| 9861 // args[0]: number: break id | 10299 // args[0]: number: break id |
| 9862 // args[1]: number: thread index | 10300 // args[1]: number: thread index |
| 9863 // | 10301 // |
| 9864 // The array returned contains the following information: | 10302 // The array returned contains the following information: |
| 9865 // 0: Is current thread? | 10303 // 0: Is current thread? |
| 9866 // 1: Thread id | 10304 // 1: Thread id |
| 9867 static MaybeObject* Runtime_GetThreadDetails(Arguments args) { | 10305 static MaybeObject* Runtime_GetThreadDetails(RUNTIME_CALLING_CONVENTION) { |
| 9868 HandleScope scope; | 10306 RUNTIME_GET_ISOLATE; |
| 10307 HandleScope scope(isolate); |
| 9869 ASSERT(args.length() == 2); | 10308 ASSERT(args.length() == 2); |
| 9870 | 10309 |
| 9871 // Check arguments. | 10310 // Check arguments. |
| 9872 Object* check; | 10311 Object* check; |
| 9873 { MaybeObject* maybe_check = Runtime_CheckExecutionState(args); | 10312 { MaybeObject* maybe_check = Runtime_CheckExecutionState(args, isolate); |
| 9874 if (!maybe_check->ToObject(&check)) return maybe_check; | 10313 if (!maybe_check->ToObject(&check)) return maybe_check; |
| 9875 } | 10314 } |
| 9876 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); | 10315 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); |
| 9877 | 10316 |
| 9878 // Allocate array for result. | 10317 // Allocate array for result. |
| 9879 Handle<FixedArray> details = Factory::NewFixedArray(kThreadDetailsSize); | 10318 Handle<FixedArray> details = |
| 10319 isolate->factory()->NewFixedArray(kThreadDetailsSize); |
| 9880 | 10320 |
| 9881 // Thread index 0 is current thread. | 10321 // Thread index 0 is current thread. |
| 9882 if (index == 0) { | 10322 if (index == 0) { |
| 9883 // Fill the details. | 10323 // Fill the details. |
| 9884 details->set(kThreadDetailsCurrentThreadIndex, Heap::true_value()); | 10324 details->set(kThreadDetailsCurrentThreadIndex, |
| 10325 isolate->heap()->true_value()); |
| 9885 details->set(kThreadDetailsThreadIdIndex, | 10326 details->set(kThreadDetailsThreadIdIndex, |
| 9886 Smi::FromInt(ThreadManager::CurrentId())); | 10327 Smi::FromInt( |
| 10328 isolate->thread_manager()->CurrentId())); |
| 9887 } else { | 10329 } else { |
| 9888 // Find the thread with the requested index. | 10330 // Find the thread with the requested index. |
| 9889 int n = 1; | 10331 int n = 1; |
| 9890 ThreadState* thread = ThreadState::FirstInUse(); | 10332 ThreadState* thread = |
| 10333 isolate->thread_manager()->FirstThreadStateInUse(); |
| 9891 while (index != n && thread != NULL) { | 10334 while (index != n && thread != NULL) { |
| 9892 thread = thread->Next(); | 10335 thread = thread->Next(); |
| 9893 n++; | 10336 n++; |
| 9894 } | 10337 } |
| 9895 if (thread == NULL) { | 10338 if (thread == NULL) { |
| 9896 return Heap::undefined_value(); | 10339 return isolate->heap()->undefined_value(); |
| 9897 } | 10340 } |
| 9898 | 10341 |
| 9899 // Fill the details. | 10342 // Fill the details. |
| 9900 details->set(kThreadDetailsCurrentThreadIndex, Heap::false_value()); | 10343 details->set(kThreadDetailsCurrentThreadIndex, |
| 10344 isolate->heap()->false_value()); |
| 9901 details->set(kThreadDetailsThreadIdIndex, Smi::FromInt(thread->id())); | 10345 details->set(kThreadDetailsThreadIdIndex, Smi::FromInt(thread->id())); |
| 9902 } | 10346 } |
| 9903 | 10347 |
| 9904 // Convert to JS array and return. | 10348 // Convert to JS array and return. |
| 9905 return *Factory::NewJSArrayWithElements(details); | 10349 return *isolate->factory()->NewJSArrayWithElements(details); |
| 9906 } | 10350 } |
| 9907 | 10351 |
| 9908 | 10352 |
| 9909 // Sets the disable break state | 10353 // Sets the disable break state |
| 9910 // args[0]: disable break state | 10354 // args[0]: disable break state |
| 9911 static MaybeObject* Runtime_SetDisableBreak(Arguments args) { | 10355 static MaybeObject* Runtime_SetDisableBreak(RUNTIME_CALLING_CONVENTION) { |
| 9912 HandleScope scope; | 10356 RUNTIME_GET_ISOLATE; |
| 10357 HandleScope scope(isolate); |
| 9913 ASSERT(args.length() == 1); | 10358 ASSERT(args.length() == 1); |
| 9914 CONVERT_BOOLEAN_CHECKED(disable_break, args[0]); | 10359 CONVERT_BOOLEAN_CHECKED(disable_break, args[0]); |
| 9915 Debug::set_disable_break(disable_break); | 10360 isolate->debug()->set_disable_break(disable_break); |
| 9916 return Heap::undefined_value(); | 10361 return isolate->heap()->undefined_value(); |
| 9917 } | 10362 } |
| 9918 | 10363 |
| 9919 | 10364 |
| 9920 static MaybeObject* Runtime_GetBreakLocations(Arguments args) { | 10365 static MaybeObject* Runtime_GetBreakLocations(RUNTIME_CALLING_CONVENTION) { |
| 9921 HandleScope scope; | 10366 RUNTIME_GET_ISOLATE; |
| 10367 HandleScope scope(isolate); |
| 9922 ASSERT(args.length() == 1); | 10368 ASSERT(args.length() == 1); |
| 9923 | 10369 |
| 9924 CONVERT_ARG_CHECKED(JSFunction, fun, 0); | 10370 CONVERT_ARG_CHECKED(JSFunction, fun, 0); |
| 9925 Handle<SharedFunctionInfo> shared(fun->shared()); | 10371 Handle<SharedFunctionInfo> shared(fun->shared()); |
| 9926 // Find the number of break points | 10372 // Find the number of break points |
| 9927 Handle<Object> break_locations = Debug::GetSourceBreakLocations(shared); | 10373 Handle<Object> break_locations = Debug::GetSourceBreakLocations(shared); |
| 9928 if (break_locations->IsUndefined()) return Heap::undefined_value(); | 10374 if (break_locations->IsUndefined()) return isolate->heap()->undefined_value(); |
| 9929 // Return array as JS array | 10375 // Return array as JS array |
| 9930 return *Factory::NewJSArrayWithElements( | 10376 return *isolate->factory()->NewJSArrayWithElements( |
| 9931 Handle<FixedArray>::cast(break_locations)); | 10377 Handle<FixedArray>::cast(break_locations)); |
| 9932 } | 10378 } |
| 9933 | 10379 |
| 9934 | 10380 |
| 9935 // Set a break point in a function | 10381 // Set a break point in a function |
| 9936 // args[0]: function | 10382 // args[0]: function |
| 9937 // args[1]: number: break source position (within the function source) | 10383 // args[1]: number: break source position (within the function source) |
| 9938 // args[2]: number: break point object | 10384 // args[2]: number: break point object |
| 9939 static MaybeObject* Runtime_SetFunctionBreakPoint(Arguments args) { | 10385 static MaybeObject* Runtime_SetFunctionBreakPoint(RUNTIME_CALLING_CONVENTION) { |
| 9940 HandleScope scope; | 10386 RUNTIME_GET_ISOLATE; |
| 10387 HandleScope scope(isolate); |
| 9941 ASSERT(args.length() == 3); | 10388 ASSERT(args.length() == 3); |
| 9942 CONVERT_ARG_CHECKED(JSFunction, fun, 0); | 10389 CONVERT_ARG_CHECKED(JSFunction, fun, 0); |
| 9943 Handle<SharedFunctionInfo> shared(fun->shared()); | 10390 Handle<SharedFunctionInfo> shared(fun->shared()); |
| 9944 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); | 10391 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); |
| 9945 RUNTIME_ASSERT(source_position >= 0); | 10392 RUNTIME_ASSERT(source_position >= 0); |
| 9946 Handle<Object> break_point_object_arg = args.at<Object>(2); | 10393 Handle<Object> break_point_object_arg = args.at<Object>(2); |
| 9947 | 10394 |
| 9948 // Set break point. | 10395 // Set break point. |
| 9949 Debug::SetBreakPoint(shared, break_point_object_arg, &source_position); | 10396 isolate->debug()->SetBreakPoint(shared, break_point_object_arg, |
| 10397 &source_position); |
| 9950 | 10398 |
| 9951 return Smi::FromInt(source_position); | 10399 return Smi::FromInt(source_position); |
| 9952 } | 10400 } |
| 9953 | 10401 |
| 9954 | 10402 |
| 9955 Object* Runtime::FindSharedFunctionInfoInScript(Handle<Script> script, | 10403 Object* Runtime::FindSharedFunctionInfoInScript(Isolate* isolate, |
| 10404 Handle<Script> script, |
| 9956 int position) { | 10405 int position) { |
| 9957 // Iterate the heap looking for SharedFunctionInfo generated from the | 10406 // Iterate the heap looking for SharedFunctionInfo generated from the |
| 9958 // script. The inner most SharedFunctionInfo containing the source position | 10407 // script. The inner most SharedFunctionInfo containing the source position |
| 9959 // for the requested break point is found. | 10408 // for the requested break point is found. |
| 9960 // NOTE: This might require several heap iterations. If the SharedFunctionInfo | 10409 // NOTE: This might require several heap iterations. If the SharedFunctionInfo |
| 9961 // which is found is not compiled it is compiled and the heap is iterated | 10410 // which is found is not compiled it is compiled and the heap is iterated |
| 9962 // again as the compilation might create inner functions from the newly | 10411 // again as the compilation might create inner functions from the newly |
| 9963 // compiled function and the actual requested break point might be in one of | 10412 // compiled function and the actual requested break point might be in one of |
| 9964 // these functions. | 10413 // these functions. |
| 9965 bool done = false; | 10414 bool done = false; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10004 target_start_position = start_position; | 10453 target_start_position = start_position; |
| 10005 target = shared; | 10454 target = shared; |
| 10006 } | 10455 } |
| 10007 } | 10456 } |
| 10008 } | 10457 } |
| 10009 } | 10458 } |
| 10010 } | 10459 } |
| 10011 } | 10460 } |
| 10012 | 10461 |
| 10013 if (target.is_null()) { | 10462 if (target.is_null()) { |
| 10014 return Heap::undefined_value(); | 10463 return isolate->heap()->undefined_value(); |
| 10015 } | 10464 } |
| 10016 | 10465 |
| 10017 // If the candidate found is compiled we are done. NOTE: when lazy | 10466 // If the candidate found is compiled we are done. NOTE: when lazy |
| 10018 // compilation of inner functions is introduced some additional checking | 10467 // compilation of inner functions is introduced some additional checking |
| 10019 // needs to be done here to compile inner functions. | 10468 // needs to be done here to compile inner functions. |
| 10020 done = target->is_compiled(); | 10469 done = target->is_compiled(); |
| 10021 if (!done) { | 10470 if (!done) { |
| 10022 // If the candidate is not compiled compile it to reveal any inner | 10471 // If the candidate is not compiled compile it to reveal any inner |
| 10023 // functions which might contain the requested source position. | 10472 // functions which might contain the requested source position. |
| 10024 CompileLazyShared(target, KEEP_EXCEPTION); | 10473 CompileLazyShared(target, KEEP_EXCEPTION); |
| 10025 } | 10474 } |
| 10026 } | 10475 } |
| 10027 | 10476 |
| 10028 return *target; | 10477 return *target; |
| 10029 } | 10478 } |
| 10030 | 10479 |
| 10031 | 10480 |
| 10032 // Changes the state of a break point in a script and returns source position | 10481 // Changes the state of a break point in a script and returns source position |
| 10033 // where break point was set. NOTE: Regarding performance see the NOTE for | 10482 // where break point was set. NOTE: Regarding performance see the NOTE for |
| 10034 // GetScriptFromScriptData. | 10483 // GetScriptFromScriptData. |
| 10035 // args[0]: script to set break point in | 10484 // args[0]: script to set break point in |
| 10036 // args[1]: number: break source position (within the script source) | 10485 // args[1]: number: break source position (within the script source) |
| 10037 // args[2]: number: break point object | 10486 // args[2]: number: break point object |
| 10038 static MaybeObject* Runtime_SetScriptBreakPoint(Arguments args) { | 10487 static MaybeObject* Runtime_SetScriptBreakPoint(RUNTIME_CALLING_CONVENTION) { |
| 10039 HandleScope scope; | 10488 RUNTIME_GET_ISOLATE; |
| 10489 HandleScope scope(isolate); |
| 10040 ASSERT(args.length() == 3); | 10490 ASSERT(args.length() == 3); |
| 10041 CONVERT_ARG_CHECKED(JSValue, wrapper, 0); | 10491 CONVERT_ARG_CHECKED(JSValue, wrapper, 0); |
| 10042 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); | 10492 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); |
| 10043 RUNTIME_ASSERT(source_position >= 0); | 10493 RUNTIME_ASSERT(source_position >= 0); |
| 10044 Handle<Object> break_point_object_arg = args.at<Object>(2); | 10494 Handle<Object> break_point_object_arg = args.at<Object>(2); |
| 10045 | 10495 |
| 10046 // Get the script from the script wrapper. | 10496 // Get the script from the script wrapper. |
| 10047 RUNTIME_ASSERT(wrapper->value()->IsScript()); | 10497 RUNTIME_ASSERT(wrapper->value()->IsScript()); |
| 10048 Handle<Script> script(Script::cast(wrapper->value())); | 10498 Handle<Script> script(Script::cast(wrapper->value())); |
| 10049 | 10499 |
| 10050 Object* result = Runtime::FindSharedFunctionInfoInScript( | 10500 Object* result = Runtime::FindSharedFunctionInfoInScript( |
| 10051 script, source_position); | 10501 isolate, script, source_position); |
| 10052 if (!result->IsUndefined()) { | 10502 if (!result->IsUndefined()) { |
| 10053 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result)); | 10503 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result)); |
| 10054 // Find position within function. The script position might be before the | 10504 // Find position within function. The script position might be before the |
| 10055 // source position of the first function. | 10505 // source position of the first function. |
| 10056 int position; | 10506 int position; |
| 10057 if (shared->start_position() > source_position) { | 10507 if (shared->start_position() > source_position) { |
| 10058 position = 0; | 10508 position = 0; |
| 10059 } else { | 10509 } else { |
| 10060 position = source_position - shared->start_position(); | 10510 position = source_position - shared->start_position(); |
| 10061 } | 10511 } |
| 10062 Debug::SetBreakPoint(shared, break_point_object_arg, &position); | 10512 isolate->debug()->SetBreakPoint(shared, break_point_object_arg, &position); |
| 10063 position += shared->start_position(); | 10513 position += shared->start_position(); |
| 10064 return Smi::FromInt(position); | 10514 return Smi::FromInt(position); |
| 10065 } | 10515 } |
| 10066 return Heap::undefined_value(); | 10516 return isolate->heap()->undefined_value(); |
| 10067 } | 10517 } |
| 10068 | 10518 |
| 10069 | 10519 |
| 10070 // Clear a break point | 10520 // Clear a break point |
| 10071 // args[0]: number: break point object | 10521 // args[0]: number: break point object |
| 10072 static MaybeObject* Runtime_ClearBreakPoint(Arguments args) { | 10522 static MaybeObject* Runtime_ClearBreakPoint(RUNTIME_CALLING_CONVENTION) { |
| 10073 HandleScope scope; | 10523 RUNTIME_GET_ISOLATE; |
| 10524 HandleScope scope(isolate); |
| 10074 ASSERT(args.length() == 1); | 10525 ASSERT(args.length() == 1); |
| 10075 Handle<Object> break_point_object_arg = args.at<Object>(0); | 10526 Handle<Object> break_point_object_arg = args.at<Object>(0); |
| 10076 | 10527 |
| 10077 // Clear break point. | 10528 // Clear break point. |
| 10078 Debug::ClearBreakPoint(break_point_object_arg); | 10529 isolate->debug()->ClearBreakPoint(break_point_object_arg); |
| 10079 | 10530 |
| 10080 return Heap::undefined_value(); | 10531 return isolate->heap()->undefined_value(); |
| 10081 } | 10532 } |
| 10082 | 10533 |
| 10083 | 10534 |
| 10084 // Change the state of break on exceptions. | 10535 // Change the state of break on exceptions. |
| 10085 // args[0]: Enum value indicating whether to affect caught/uncaught exceptions. | 10536 // args[0]: Enum value indicating whether to affect caught/uncaught exceptions. |
| 10086 // args[1]: Boolean indicating on/off. | 10537 // args[1]: Boolean indicating on/off. |
| 10087 static MaybeObject* Runtime_ChangeBreakOnException(Arguments args) { | 10538 static MaybeObject* Runtime_ChangeBreakOnException(RUNTIME_CALLING_CONVENTION) { |
| 10088 HandleScope scope; | 10539 RUNTIME_GET_ISOLATE; |
| 10540 HandleScope scope(isolate); |
| 10089 ASSERT(args.length() == 2); | 10541 ASSERT(args.length() == 2); |
| 10090 RUNTIME_ASSERT(args[0]->IsNumber()); | 10542 RUNTIME_ASSERT(args[0]->IsNumber()); |
| 10091 CONVERT_BOOLEAN_CHECKED(enable, args[1]); | 10543 CONVERT_BOOLEAN_CHECKED(enable, args[1]); |
| 10092 | 10544 |
| 10093 // If the number doesn't match an enum value, the ChangeBreakOnException | 10545 // If the number doesn't match an enum value, the ChangeBreakOnException |
| 10094 // function will default to affecting caught exceptions. | 10546 // function will default to affecting caught exceptions. |
| 10095 ExceptionBreakType type = | 10547 ExceptionBreakType type = |
| 10096 static_cast<ExceptionBreakType>(NumberToUint32(args[0])); | 10548 static_cast<ExceptionBreakType>(NumberToUint32(args[0])); |
| 10097 // Update break point state. | 10549 // Update break point state. |
| 10098 Debug::ChangeBreakOnException(type, enable); | 10550 isolate->debug()->ChangeBreakOnException(type, enable); |
| 10099 return Heap::undefined_value(); | 10551 return isolate->heap()->undefined_value(); |
| 10100 } | 10552 } |
| 10101 | 10553 |
| 10102 | 10554 |
| 10103 // Returns the state of break on exceptions | 10555 // Returns the state of break on exceptions |
| 10104 // args[0]: boolean indicating uncaught exceptions | 10556 // args[0]: boolean indicating uncaught exceptions |
| 10105 static MaybeObject* Runtime_IsBreakOnException(Arguments args) { | 10557 static MaybeObject* Runtime_IsBreakOnException(RUNTIME_CALLING_CONVENTION) { |
| 10106 HandleScope scope; | 10558 RUNTIME_GET_ISOLATE; |
| 10559 HandleScope scope(isolate); |
| 10107 ASSERT(args.length() == 1); | 10560 ASSERT(args.length() == 1); |
| 10108 RUNTIME_ASSERT(args[0]->IsNumber()); | 10561 RUNTIME_ASSERT(args[0]->IsNumber()); |
| 10109 | 10562 |
| 10110 ExceptionBreakType type = | 10563 ExceptionBreakType type = |
| 10111 static_cast<ExceptionBreakType>(NumberToUint32(args[0])); | 10564 static_cast<ExceptionBreakType>(NumberToUint32(args[0])); |
| 10112 bool result = Debug::IsBreakOnException(type); | 10565 bool result = isolate->debug()->IsBreakOnException(type); |
| 10113 return Smi::FromInt(result); | 10566 return Smi::FromInt(result); |
| 10114 } | 10567 } |
| 10115 | 10568 |
| 10116 | 10569 |
| 10117 // Prepare for stepping | 10570 // Prepare for stepping |
| 10118 // args[0]: break id for checking execution state | 10571 // args[0]: break id for checking execution state |
| 10119 // args[1]: step action from the enumeration StepAction | 10572 // args[1]: step action from the enumeration StepAction |
| 10120 // args[2]: number of times to perform the step, for step out it is the number | 10573 // args[2]: number of times to perform the step, for step out it is the number |
| 10121 // of frames to step down. | 10574 // of frames to step down. |
| 10122 static MaybeObject* Runtime_PrepareStep(Arguments args) { | 10575 static MaybeObject* Runtime_PrepareStep(RUNTIME_CALLING_CONVENTION) { |
| 10123 HandleScope scope; | 10576 RUNTIME_GET_ISOLATE; |
| 10577 HandleScope scope(isolate); |
| 10124 ASSERT(args.length() == 3); | 10578 ASSERT(args.length() == 3); |
| 10125 // Check arguments. | 10579 // Check arguments. |
| 10126 Object* check; | 10580 Object* check; |
| 10127 { MaybeObject* maybe_check = Runtime_CheckExecutionState(args); | 10581 { MaybeObject* maybe_check = Runtime_CheckExecutionState(args, isolate); |
| 10128 if (!maybe_check->ToObject(&check)) return maybe_check; | 10582 if (!maybe_check->ToObject(&check)) return maybe_check; |
| 10129 } | 10583 } |
| 10130 if (!args[1]->IsNumber() || !args[2]->IsNumber()) { | 10584 if (!args[1]->IsNumber() || !args[2]->IsNumber()) { |
| 10131 return Top::Throw(Heap::illegal_argument_symbol()); | 10585 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
| 10132 } | 10586 } |
| 10133 | 10587 |
| 10134 // Get the step action and check validity. | 10588 // Get the step action and check validity. |
| 10135 StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1])); | 10589 StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1])); |
| 10136 if (step_action != StepIn && | 10590 if (step_action != StepIn && |
| 10137 step_action != StepNext && | 10591 step_action != StepNext && |
| 10138 step_action != StepOut && | 10592 step_action != StepOut && |
| 10139 step_action != StepInMin && | 10593 step_action != StepInMin && |
| 10140 step_action != StepMin) { | 10594 step_action != StepMin) { |
| 10141 return Top::Throw(Heap::illegal_argument_symbol()); | 10595 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
| 10142 } | 10596 } |
| 10143 | 10597 |
| 10144 // Get the number of steps. | 10598 // Get the number of steps. |
| 10145 int step_count = NumberToInt32(args[2]); | 10599 int step_count = NumberToInt32(args[2]); |
| 10146 if (step_count < 1) { | 10600 if (step_count < 1) { |
| 10147 return Top::Throw(Heap::illegal_argument_symbol()); | 10601 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
| 10148 } | 10602 } |
| 10149 | 10603 |
| 10150 // Clear all current stepping setup. | 10604 // Clear all current stepping setup. |
| 10151 Debug::ClearStepping(); | 10605 isolate->debug()->ClearStepping(); |
| 10152 | 10606 |
| 10153 // Prepare step. | 10607 // Prepare step. |
| 10154 Debug::PrepareStep(static_cast<StepAction>(step_action), step_count); | 10608 isolate->debug()->PrepareStep(static_cast<StepAction>(step_action), |
| 10155 return Heap::undefined_value(); | 10609 step_count); |
| 10610 return isolate->heap()->undefined_value(); |
| 10156 } | 10611 } |
| 10157 | 10612 |
| 10158 | 10613 |
| 10159 // Clear all stepping set by PrepareStep. | 10614 // Clear all stepping set by PrepareStep. |
| 10160 static MaybeObject* Runtime_ClearStepping(Arguments args) { | 10615 static MaybeObject* Runtime_ClearStepping(RUNTIME_CALLING_CONVENTION) { |
| 10161 HandleScope scope; | 10616 RUNTIME_GET_ISOLATE; |
| 10617 HandleScope scope(isolate); |
| 10162 ASSERT(args.length() == 0); | 10618 ASSERT(args.length() == 0); |
| 10163 Debug::ClearStepping(); | 10619 isolate->debug()->ClearStepping(); |
| 10164 return Heap::undefined_value(); | 10620 return isolate->heap()->undefined_value(); |
| 10165 } | 10621 } |
| 10166 | 10622 |
| 10167 | 10623 |
| 10168 // Creates a copy of the with context chain. The copy of the context chain is | 10624 // Creates a copy of the with context chain. The copy of the context chain is |
| 10169 // is linked to the function context supplied. | 10625 // is linked to the function context supplied. |
| 10170 static Handle<Context> CopyWithContextChain(Handle<Context> context_chain, | 10626 static Handle<Context> CopyWithContextChain(Handle<Context> context_chain, |
| 10171 Handle<Context> function_context) { | 10627 Handle<Context> function_context) { |
| 10172 // At the bottom of the chain. Return the function context to link to. | 10628 // At the bottom of the chain. Return the function context to link to. |
| 10173 if (context_chain->is_function_context()) { | 10629 if (context_chain->is_function_context()) { |
| 10174 return function_context; | 10630 return function_context; |
| 10175 } | 10631 } |
| 10176 | 10632 |
| 10177 // Recursively copy the with contexts. | 10633 // Recursively copy the with contexts. |
| 10178 Handle<Context> previous(context_chain->previous()); | 10634 Handle<Context> previous(context_chain->previous()); |
| 10179 Handle<JSObject> extension(JSObject::cast(context_chain->extension())); | 10635 Handle<JSObject> extension(JSObject::cast(context_chain->extension())); |
| 10180 Handle<Context> context = CopyWithContextChain(function_context, previous); | 10636 Handle<Context> context = CopyWithContextChain(function_context, previous); |
| 10181 return Factory::NewWithContext(context, | 10637 return context->GetIsolate()->factory()->NewWithContext( |
| 10182 extension, | 10638 context, extension, context_chain->IsCatchContext()); |
| 10183 context_chain->IsCatchContext()); | |
| 10184 } | 10639 } |
| 10185 | 10640 |
| 10186 | 10641 |
| 10187 // Helper function to find or create the arguments object for | 10642 // Helper function to find or create the arguments object for |
| 10188 // Runtime_DebugEvaluate. | 10643 // Runtime_DebugEvaluate. |
| 10189 static Handle<Object> GetArgumentsObject(JavaScriptFrame* frame, | 10644 static Handle<Object> GetArgumentsObject(Isolate* isolate, |
| 10645 JavaScriptFrame* frame, |
| 10190 Handle<JSFunction> function, | 10646 Handle<JSFunction> function, |
| 10191 Handle<SerializedScopeInfo> scope_info, | 10647 Handle<SerializedScopeInfo> scope_info, |
| 10192 const ScopeInfo<>* sinfo, | 10648 const ScopeInfo<>* sinfo, |
| 10193 Handle<Context> function_context) { | 10649 Handle<Context> function_context) { |
| 10194 // Try to find the value of 'arguments' to pass as parameter. If it is not | 10650 // Try to find the value of 'arguments' to pass as parameter. If it is not |
| 10195 // found (that is the debugged function does not reference 'arguments' and | 10651 // found (that is the debugged function does not reference 'arguments' and |
| 10196 // does not support eval) then create an 'arguments' object. | 10652 // does not support eval) then create an 'arguments' object. |
| 10197 int index; | 10653 int index; |
| 10198 if (sinfo->number_of_stack_slots() > 0) { | 10654 if (sinfo->number_of_stack_slots() > 0) { |
| 10199 index = scope_info->StackSlotIndex(Heap::arguments_symbol()); | 10655 index = scope_info->StackSlotIndex(isolate->heap()->arguments_symbol()); |
| 10200 if (index != -1) { | 10656 if (index != -1) { |
| 10201 return Handle<Object>(frame->GetExpression(index)); | 10657 return Handle<Object>(frame->GetExpression(index), isolate); |
| 10202 } | 10658 } |
| 10203 } | 10659 } |
| 10204 | 10660 |
| 10205 if (sinfo->number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) { | 10661 if (sinfo->number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) { |
| 10206 index = scope_info->ContextSlotIndex(Heap::arguments_symbol(), NULL); | 10662 index = scope_info->ContextSlotIndex(isolate->heap()->arguments_symbol(), |
| 10663 NULL); |
| 10207 if (index != -1) { | 10664 if (index != -1) { |
| 10208 return Handle<Object>(function_context->get(index)); | 10665 return Handle<Object>(function_context->get(index), isolate); |
| 10209 } | 10666 } |
| 10210 } | 10667 } |
| 10211 | 10668 |
| 10212 const int length = frame->ComputeParametersCount(); | 10669 const int length = frame->ComputeParametersCount(); |
| 10213 Handle<JSObject> arguments = Factory::NewArgumentsObject(function, length); | 10670 Handle<JSObject> arguments = |
| 10214 Handle<FixedArray> array = Factory::NewFixedArray(length); | 10671 isolate->factory()->NewArgumentsObject(function, length); |
| 10672 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); |
| 10215 | 10673 |
| 10216 AssertNoAllocation no_gc; | 10674 AssertNoAllocation no_gc; |
| 10217 WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc); | 10675 WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc); |
| 10218 for (int i = 0; i < length; i++) { | 10676 for (int i = 0; i < length; i++) { |
| 10219 array->set(i, frame->GetParameter(i), mode); | 10677 array->set(i, frame->GetParameter(i), mode); |
| 10220 } | 10678 } |
| 10221 arguments->set_elements(*array); | 10679 arguments->set_elements(*array); |
| 10222 return arguments; | 10680 return arguments; |
| 10223 } | 10681 } |
| 10224 | 10682 |
| 10225 | 10683 |
| 10684 static const char kSourceStr[] = |
| 10685 "(function(arguments,__source__){return eval(__source__);})"; |
| 10686 |
| 10687 |
| 10226 // Evaluate a piece of JavaScript in the context of a stack frame for | 10688 // Evaluate a piece of JavaScript in the context of a stack frame for |
| 10227 // debugging. This is accomplished by creating a new context which in its | 10689 // debugging. This is accomplished by creating a new context which in its |
| 10228 // extension part has all the parameters and locals of the function on the | 10690 // extension part has all the parameters and locals of the function on the |
| 10229 // stack frame. A function which calls eval with the code to evaluate is then | 10691 // stack frame. A function which calls eval with the code to evaluate is then |
| 10230 // compiled in this context and called in this context. As this context | 10692 // compiled in this context and called in this context. As this context |
| 10231 // replaces the context of the function on the stack frame a new (empty) | 10693 // replaces the context of the function on the stack frame a new (empty) |
| 10232 // function is created as well to be used as the closure for the context. | 10694 // function is created as well to be used as the closure for the context. |
| 10233 // This function and the context acts as replacements for the function on the | 10695 // This function and the context acts as replacements for the function on the |
| 10234 // stack frame presenting the same view of the values of parameters and | 10696 // stack frame presenting the same view of the values of parameters and |
| 10235 // local variables as if the piece of JavaScript was evaluated at the point | 10697 // local variables as if the piece of JavaScript was evaluated at the point |
| 10236 // where the function on the stack frame is currently stopped. | 10698 // where the function on the stack frame is currently stopped. |
| 10237 static MaybeObject* Runtime_DebugEvaluate(Arguments args) { | 10699 static MaybeObject* Runtime_DebugEvaluate(RUNTIME_CALLING_CONVENTION) { |
| 10238 HandleScope scope; | 10700 RUNTIME_GET_ISOLATE; |
| 10701 HandleScope scope(isolate); |
| 10239 | 10702 |
| 10240 // Check the execution state and decode arguments frame and source to be | 10703 // Check the execution state and decode arguments frame and source to be |
| 10241 // evaluated. | 10704 // evaluated. |
| 10242 ASSERT(args.length() == 5); | 10705 ASSERT(args.length() == 5); |
| 10243 Object* check_result; | 10706 Object* check_result; |
| 10244 { MaybeObject* maybe_check_result = Runtime_CheckExecutionState(args); | 10707 { MaybeObject* maybe_check_result = Runtime_CheckExecutionState(args, |
| 10708 isolate); |
| 10245 if (!maybe_check_result->ToObject(&check_result)) { | 10709 if (!maybe_check_result->ToObject(&check_result)) { |
| 10246 return maybe_check_result; | 10710 return maybe_check_result; |
| 10247 } | 10711 } |
| 10248 } | 10712 } |
| 10249 CONVERT_CHECKED(Smi, wrapped_id, args[1]); | 10713 CONVERT_CHECKED(Smi, wrapped_id, args[1]); |
| 10250 CONVERT_ARG_CHECKED(String, source, 2); | 10714 CONVERT_ARG_CHECKED(String, source, 2); |
| 10251 CONVERT_BOOLEAN_CHECKED(disable_break, args[3]); | 10715 CONVERT_BOOLEAN_CHECKED(disable_break, args[3]); |
| 10252 Handle<Object> additional_context(args[4]); | 10716 Handle<Object> additional_context(args[4]); |
| 10253 | 10717 |
| 10254 // Handle the processing of break. | 10718 // Handle the processing of break. |
| 10255 DisableBreak disable_break_save(disable_break); | 10719 DisableBreak disable_break_save(disable_break); |
| 10256 | 10720 |
| 10257 // Get the frame where the debugging is performed. | 10721 // Get the frame where the debugging is performed. |
| 10258 StackFrame::Id id = UnwrapFrameId(wrapped_id); | 10722 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
| 10259 JavaScriptFrameIterator it(id); | 10723 JavaScriptFrameIterator it(id); |
| 10260 JavaScriptFrame* frame = it.frame(); | 10724 JavaScriptFrame* frame = it.frame(); |
| 10261 Handle<JSFunction> function(JSFunction::cast(frame->function())); | 10725 Handle<JSFunction> function(JSFunction::cast(frame->function())); |
| 10262 Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info()); | 10726 Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info()); |
| 10263 ScopeInfo<> sinfo(*scope_info); | 10727 ScopeInfo<> sinfo(*scope_info); |
| 10264 | 10728 |
| 10265 // Traverse the saved contexts chain to find the active context for the | 10729 // Traverse the saved contexts chain to find the active context for the |
| 10266 // selected frame. | 10730 // selected frame. |
| 10267 SaveContext* save = Top::save_context(); | 10731 SaveContext* save = isolate->save_context(); |
| 10268 while (save != NULL && !save->below(frame)) { | 10732 while (save != NULL && !save->below(frame)) { |
| 10269 save = save->prev(); | 10733 save = save->prev(); |
| 10270 } | 10734 } |
| 10271 ASSERT(save != NULL); | 10735 ASSERT(save != NULL); |
| 10272 SaveContext savex; | 10736 SaveContext savex(isolate); |
| 10273 Top::set_context(*(save->context())); | 10737 isolate->set_context(*(save->context())); |
| 10274 | 10738 |
| 10275 // Create the (empty) function replacing the function on the stack frame for | 10739 // Create the (empty) function replacing the function on the stack frame for |
| 10276 // the purpose of evaluating in the context created below. It is important | 10740 // the purpose of evaluating in the context created below. It is important |
| 10277 // that this function does not describe any parameters and local variables | 10741 // that this function does not describe any parameters and local variables |
| 10278 // in the context. If it does then this will cause problems with the lookup | 10742 // in the context. If it does then this will cause problems with the lookup |
| 10279 // in Context::Lookup, where context slots for parameters and local variables | 10743 // in Context::Lookup, where context slots for parameters and local variables |
| 10280 // are looked at before the extension object. | 10744 // are looked at before the extension object. |
| 10281 Handle<JSFunction> go_between = | 10745 Handle<JSFunction> go_between = |
| 10282 Factory::NewFunction(Factory::empty_string(), Factory::undefined_value()); | 10746 isolate->factory()->NewFunction(isolate->factory()->empty_string(), |
| 10747 isolate->factory()->undefined_value()); |
| 10283 go_between->set_context(function->context()); | 10748 go_between->set_context(function->context()); |
| 10284 #ifdef DEBUG | 10749 #ifdef DEBUG |
| 10285 ScopeInfo<> go_between_sinfo(go_between->shared()->scope_info()); | 10750 ScopeInfo<> go_between_sinfo(go_between->shared()->scope_info()); |
| 10286 ASSERT(go_between_sinfo.number_of_parameters() == 0); | 10751 ASSERT(go_between_sinfo.number_of_parameters() == 0); |
| 10287 ASSERT(go_between_sinfo.number_of_context_slots() == 0); | 10752 ASSERT(go_between_sinfo.number_of_context_slots() == 0); |
| 10288 #endif | 10753 #endif |
| 10289 | 10754 |
| 10290 // Materialize the content of the local scope into a JSObject. | 10755 // Materialize the content of the local scope into a JSObject. |
| 10291 Handle<JSObject> local_scope = MaterializeLocalScope(frame); | 10756 Handle<JSObject> local_scope = MaterializeLocalScope(isolate, frame); |
| 10292 RETURN_IF_EMPTY_HANDLE(local_scope); | 10757 RETURN_IF_EMPTY_HANDLE(isolate, local_scope); |
| 10293 | 10758 |
| 10294 // Allocate a new context for the debug evaluation and set the extension | 10759 // Allocate a new context for the debug evaluation and set the extension |
| 10295 // object build. | 10760 // object build. |
| 10296 Handle<Context> context = | 10761 Handle<Context> context = |
| 10297 Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, go_between); | 10762 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, |
| 10763 go_between); |
| 10298 context->set_extension(*local_scope); | 10764 context->set_extension(*local_scope); |
| 10299 // Copy any with contexts present and chain them in front of this context. | 10765 // Copy any with contexts present and chain them in front of this context. |
| 10300 Handle<Context> frame_context(Context::cast(frame->context())); | 10766 Handle<Context> frame_context(Context::cast(frame->context())); |
| 10301 Handle<Context> function_context(frame_context->fcontext()); | 10767 Handle<Context> function_context(frame_context->fcontext()); |
| 10302 context = CopyWithContextChain(frame_context, context); | 10768 context = CopyWithContextChain(frame_context, context); |
| 10303 | 10769 |
| 10304 if (additional_context->IsJSObject()) { | 10770 if (additional_context->IsJSObject()) { |
| 10305 context = Factory::NewWithContext(context, | 10771 context = isolate->factory()->NewWithContext(context, |
| 10306 Handle<JSObject>::cast(additional_context), false); | 10772 Handle<JSObject>::cast(additional_context), false); |
| 10307 } | 10773 } |
| 10308 | 10774 |
| 10309 // Wrap the evaluation statement in a new function compiled in the newly | 10775 // Wrap the evaluation statement in a new function compiled in the newly |
| 10310 // created context. The function has one parameter which has to be called | 10776 // created context. The function has one parameter which has to be called |
| 10311 // 'arguments'. This it to have access to what would have been 'arguments' in | 10777 // 'arguments'. This it to have access to what would have been 'arguments' in |
| 10312 // the function being debugged. | 10778 // the function being debugged. |
| 10313 // function(arguments,__source__) {return eval(__source__);} | 10779 // function(arguments,__source__) {return eval(__source__);} |
| 10314 static const char* source_str = | 10780 |
| 10315 "(function(arguments,__source__){return eval(__source__);})"; | |
| 10316 static const int source_str_length = StrLength(source_str); | |
| 10317 Handle<String> function_source = | 10781 Handle<String> function_source = |
| 10318 Factory::NewStringFromAscii(Vector<const char>(source_str, | 10782 isolate->factory()->NewStringFromAscii( |
| 10319 source_str_length)); | 10783 Vector<const char>(kSourceStr, sizeof(kSourceStr) - 1)); |
| 10320 | 10784 |
| 10321 // Currently, the eval code will be executed in non-strict mode, | 10785 // Currently, the eval code will be executed in non-strict mode, |
| 10322 // even in the strict code context. | 10786 // even in the strict code context. |
| 10323 Handle<SharedFunctionInfo> shared = | 10787 Handle<SharedFunctionInfo> shared = |
| 10324 Compiler::CompileEval(function_source, | 10788 Compiler::CompileEval(function_source, |
| 10325 context, | 10789 context, |
| 10326 context->IsGlobalContext(), | 10790 context->IsGlobalContext(), |
| 10327 kNonStrictMode); | 10791 kNonStrictMode); |
| 10328 if (shared.is_null()) return Failure::Exception(); | 10792 if (shared.is_null()) return Failure::Exception(); |
| 10329 Handle<JSFunction> compiled_function = | 10793 Handle<JSFunction> compiled_function = |
| 10330 Factory::NewFunctionFromSharedFunctionInfo(shared, context); | 10794 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context); |
| 10331 | 10795 |
| 10332 // Invoke the result of the compilation to get the evaluation function. | 10796 // Invoke the result of the compilation to get the evaluation function. |
| 10333 bool has_pending_exception; | 10797 bool has_pending_exception; |
| 10334 Handle<Object> receiver(frame->receiver()); | 10798 Handle<Object> receiver(frame->receiver(), isolate); |
| 10335 Handle<Object> evaluation_function = | 10799 Handle<Object> evaluation_function = |
| 10336 Execution::Call(compiled_function, receiver, 0, NULL, | 10800 Execution::Call(compiled_function, receiver, 0, NULL, |
| 10337 &has_pending_exception); | 10801 &has_pending_exception); |
| 10338 if (has_pending_exception) return Failure::Exception(); | 10802 if (has_pending_exception) return Failure::Exception(); |
| 10339 | 10803 |
| 10340 Handle<Object> arguments = GetArgumentsObject(frame, function, scope_info, | 10804 Handle<Object> arguments = GetArgumentsObject(isolate, frame, |
| 10805 function, scope_info, |
| 10341 &sinfo, function_context); | 10806 &sinfo, function_context); |
| 10342 | 10807 |
| 10343 // Invoke the evaluation function and return the result. | 10808 // Invoke the evaluation function and return the result. |
| 10344 const int argc = 2; | 10809 const int argc = 2; |
| 10345 Object** argv[argc] = { arguments.location(), | 10810 Object** argv[argc] = { arguments.location(), |
| 10346 Handle<Object>::cast(source).location() }; | 10811 Handle<Object>::cast(source).location() }; |
| 10347 Handle<Object> result = | 10812 Handle<Object> result = |
| 10348 Execution::Call(Handle<JSFunction>::cast(evaluation_function), receiver, | 10813 Execution::Call(Handle<JSFunction>::cast(evaluation_function), receiver, |
| 10349 argc, argv, &has_pending_exception); | 10814 argc, argv, &has_pending_exception); |
| 10350 if (has_pending_exception) return Failure::Exception(); | 10815 if (has_pending_exception) return Failure::Exception(); |
| 10351 | 10816 |
| 10352 // Skip the global proxy as it has no properties and always delegates to the | 10817 // Skip the global proxy as it has no properties and always delegates to the |
| 10353 // real global object. | 10818 // real global object. |
| 10354 if (result->IsJSGlobalProxy()) { | 10819 if (result->IsJSGlobalProxy()) { |
| 10355 result = Handle<JSObject>(JSObject::cast(result->GetPrototype())); | 10820 result = Handle<JSObject>(JSObject::cast(result->GetPrototype())); |
| 10356 } | 10821 } |
| 10357 | 10822 |
| 10358 return *result; | 10823 return *result; |
| 10359 } | 10824 } |
| 10360 | 10825 |
| 10361 | 10826 |
| 10362 static MaybeObject* Runtime_DebugEvaluateGlobal(Arguments args) { | 10827 static MaybeObject* Runtime_DebugEvaluateGlobal(RUNTIME_CALLING_CONVENTION) { |
| 10363 HandleScope scope; | 10828 RUNTIME_GET_ISOLATE; |
| 10829 HandleScope scope(isolate); |
| 10364 | 10830 |
| 10365 // Check the execution state and decode arguments frame and source to be | 10831 // Check the execution state and decode arguments frame and source to be |
| 10366 // evaluated. | 10832 // evaluated. |
| 10367 ASSERT(args.length() == 4); | 10833 ASSERT(args.length() == 4); |
| 10368 Object* check_result; | 10834 Object* check_result; |
| 10369 { MaybeObject* maybe_check_result = Runtime_CheckExecutionState(args); | 10835 { MaybeObject* maybe_check_result = Runtime_CheckExecutionState(args, |
| 10836 isolate); |
| 10370 if (!maybe_check_result->ToObject(&check_result)) { | 10837 if (!maybe_check_result->ToObject(&check_result)) { |
| 10371 return maybe_check_result; | 10838 return maybe_check_result; |
| 10372 } | 10839 } |
| 10373 } | 10840 } |
| 10374 CONVERT_ARG_CHECKED(String, source, 1); | 10841 CONVERT_ARG_CHECKED(String, source, 1); |
| 10375 CONVERT_BOOLEAN_CHECKED(disable_break, args[2]); | 10842 CONVERT_BOOLEAN_CHECKED(disable_break, args[2]); |
| 10376 Handle<Object> additional_context(args[3]); | 10843 Handle<Object> additional_context(args[3]); |
| 10377 | 10844 |
| 10378 // Handle the processing of break. | 10845 // Handle the processing of break. |
| 10379 DisableBreak disable_break_save(disable_break); | 10846 DisableBreak disable_break_save(disable_break); |
| 10380 | 10847 |
| 10381 // Enter the top context from before the debugger was invoked. | 10848 // Enter the top context from before the debugger was invoked. |
| 10382 SaveContext save; | 10849 SaveContext save(isolate); |
| 10383 SaveContext* top = &save; | 10850 SaveContext* top = &save; |
| 10384 while (top != NULL && *top->context() == *Debug::debug_context()) { | 10851 while (top != NULL && *top->context() == *isolate->debug()->debug_context()) { |
| 10385 top = top->prev(); | 10852 top = top->prev(); |
| 10386 } | 10853 } |
| 10387 if (top != NULL) { | 10854 if (top != NULL) { |
| 10388 Top::set_context(*top->context()); | 10855 isolate->set_context(*top->context()); |
| 10389 } | 10856 } |
| 10390 | 10857 |
| 10391 // Get the global context now set to the top context from before the | 10858 // Get the global context now set to the top context from before the |
| 10392 // debugger was invoked. | 10859 // debugger was invoked. |
| 10393 Handle<Context> context = Top::global_context(); | 10860 Handle<Context> context = isolate->global_context(); |
| 10394 | 10861 |
| 10395 bool is_global = true; | 10862 bool is_global = true; |
| 10396 | 10863 |
| 10397 if (additional_context->IsJSObject()) { | 10864 if (additional_context->IsJSObject()) { |
| 10398 // Create a function context first, than put 'with' context on top of it. | 10865 // Create a function context first, than put 'with' context on top of it. |
| 10399 Handle<JSFunction> go_between = Factory::NewFunction( | 10866 Handle<JSFunction> go_between = isolate->factory()->NewFunction( |
| 10400 Factory::empty_string(), Factory::undefined_value()); | 10867 isolate->factory()->empty_string(), |
| 10868 isolate->factory()->undefined_value()); |
| 10401 go_between->set_context(*context); | 10869 go_between->set_context(*context); |
| 10402 context = | 10870 context = |
| 10403 Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, go_between); | 10871 isolate->factory()->NewFunctionContext( |
| 10872 Context::MIN_CONTEXT_SLOTS, go_between); |
| 10404 context->set_extension(JSObject::cast(*additional_context)); | 10873 context->set_extension(JSObject::cast(*additional_context)); |
| 10405 is_global = false; | 10874 is_global = false; |
| 10406 } | 10875 } |
| 10407 | 10876 |
| 10408 // Compile the source to be evaluated. | 10877 // Compile the source to be evaluated. |
| 10409 // Currently, the eval code will be executed in non-strict mode, | 10878 // Currently, the eval code will be executed in non-strict mode, |
| 10410 // even in the strict code context. | 10879 // even in the strict code context. |
| 10411 Handle<SharedFunctionInfo> shared = | 10880 Handle<SharedFunctionInfo> shared = |
| 10412 Compiler::CompileEval(source, context, is_global, kNonStrictMode); | 10881 Compiler::CompileEval(source, context, is_global, kNonStrictMode); |
| 10413 if (shared.is_null()) return Failure::Exception(); | 10882 if (shared.is_null()) return Failure::Exception(); |
| 10414 Handle<JSFunction> compiled_function = | 10883 Handle<JSFunction> compiled_function = |
| 10415 Handle<JSFunction>(Factory::NewFunctionFromSharedFunctionInfo(shared, | 10884 Handle<JSFunction>( |
| 10416 context)); | 10885 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, |
| 10886 context)); |
| 10417 | 10887 |
| 10418 // Invoke the result of the compilation to get the evaluation function. | 10888 // Invoke the result of the compilation to get the evaluation function. |
| 10419 bool has_pending_exception; | 10889 bool has_pending_exception; |
| 10420 Handle<Object> receiver = Top::global(); | 10890 Handle<Object> receiver = isolate->global(); |
| 10421 Handle<Object> result = | 10891 Handle<Object> result = |
| 10422 Execution::Call(compiled_function, receiver, 0, NULL, | 10892 Execution::Call(compiled_function, receiver, 0, NULL, |
| 10423 &has_pending_exception); | 10893 &has_pending_exception); |
| 10424 if (has_pending_exception) return Failure::Exception(); | 10894 if (has_pending_exception) return Failure::Exception(); |
| 10425 return *result; | 10895 return *result; |
| 10426 } | 10896 } |
| 10427 | 10897 |
| 10428 | 10898 |
| 10429 static MaybeObject* Runtime_DebugGetLoadedScripts(Arguments args) { | 10899 static MaybeObject* Runtime_DebugGetLoadedScripts(RUNTIME_CALLING_CONVENTION) { |
| 10430 HandleScope scope; | 10900 RUNTIME_GET_ISOLATE; |
| 10901 HandleScope scope(isolate); |
| 10431 ASSERT(args.length() == 0); | 10902 ASSERT(args.length() == 0); |
| 10432 | 10903 |
| 10433 // Fill the script objects. | 10904 // Fill the script objects. |
| 10434 Handle<FixedArray> instances = Debug::GetLoadedScripts(); | 10905 Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts(); |
| 10435 | 10906 |
| 10436 // Convert the script objects to proper JS objects. | 10907 // Convert the script objects to proper JS objects. |
| 10437 for (int i = 0; i < instances->length(); i++) { | 10908 for (int i = 0; i < instances->length(); i++) { |
| 10438 Handle<Script> script = Handle<Script>(Script::cast(instances->get(i))); | 10909 Handle<Script> script = Handle<Script>(Script::cast(instances->get(i))); |
| 10439 // Get the script wrapper in a local handle before calling GetScriptWrapper, | 10910 // Get the script wrapper in a local handle before calling GetScriptWrapper, |
| 10440 // because using | 10911 // because using |
| 10441 // instances->set(i, *GetScriptWrapper(script)) | 10912 // instances->set(i, *GetScriptWrapper(script)) |
| 10442 // is unsafe as GetScriptWrapper might call GC and the C++ compiler might | 10913 // is unsafe as GetScriptWrapper might call GC and the C++ compiler might |
| 10443 // already have deferenced the instances handle. | 10914 // already have deferenced the instances handle. |
| 10444 Handle<JSValue> wrapper = GetScriptWrapper(script); | 10915 Handle<JSValue> wrapper = GetScriptWrapper(script); |
| 10445 instances->set(i, *wrapper); | 10916 instances->set(i, *wrapper); |
| 10446 } | 10917 } |
| 10447 | 10918 |
| 10448 // Return result as a JS array. | 10919 // Return result as a JS array. |
| 10449 Handle<JSObject> result = Factory::NewJSObject(Top::array_function()); | 10920 Handle<JSObject> result = |
| 10921 isolate->factory()->NewJSObject(isolate->array_function()); |
| 10450 Handle<JSArray>::cast(result)->SetContent(*instances); | 10922 Handle<JSArray>::cast(result)->SetContent(*instances); |
| 10451 return *result; | 10923 return *result; |
| 10452 } | 10924 } |
| 10453 | 10925 |
| 10454 | 10926 |
| 10455 // Helper function used by Runtime_DebugReferencedBy below. | 10927 // Helper function used by Runtime_DebugReferencedBy below. |
| 10456 static int DebugReferencedBy(JSObject* target, | 10928 static int DebugReferencedBy(JSObject* target, |
| 10457 Object* instance_filter, int max_references, | 10929 Object* instance_filter, int max_references, |
| 10458 FixedArray* instances, int instances_size, | 10930 FixedArray* instances, int instances_size, |
| 10459 JSFunction* arguments_function) { | 10931 JSFunction* arguments_function) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10519 | 10991 |
| 10520 // Return the number of referencing objects found. | 10992 // Return the number of referencing objects found. |
| 10521 return count; | 10993 return count; |
| 10522 } | 10994 } |
| 10523 | 10995 |
| 10524 | 10996 |
| 10525 // Scan the heap for objects with direct references to an object | 10997 // Scan the heap for objects with direct references to an object |
| 10526 // args[0]: the object to find references to | 10998 // args[0]: the object to find references to |
| 10527 // args[1]: constructor function for instances to exclude (Mirror) | 10999 // args[1]: constructor function for instances to exclude (Mirror) |
| 10528 // args[2]: the the maximum number of objects to return | 11000 // args[2]: the the maximum number of objects to return |
| 10529 static MaybeObject* Runtime_DebugReferencedBy(Arguments args) { | 11001 static MaybeObject* Runtime_DebugReferencedBy(RUNTIME_CALLING_CONVENTION) { |
| 11002 RUNTIME_GET_ISOLATE; |
| 10530 ASSERT(args.length() == 3); | 11003 ASSERT(args.length() == 3); |
| 10531 | 11004 |
| 10532 // First perform a full GC in order to avoid references from dead objects. | 11005 // First perform a full GC in order to avoid references from dead objects. |
| 10533 Heap::CollectAllGarbage(false); | 11006 isolate->heap()->CollectAllGarbage(false); |
| 10534 | 11007 |
| 10535 // Check parameters. | 11008 // Check parameters. |
| 10536 CONVERT_CHECKED(JSObject, target, args[0]); | 11009 CONVERT_CHECKED(JSObject, target, args[0]); |
| 10537 Object* instance_filter = args[1]; | 11010 Object* instance_filter = args[1]; |
| 10538 RUNTIME_ASSERT(instance_filter->IsUndefined() || | 11011 RUNTIME_ASSERT(instance_filter->IsUndefined() || |
| 10539 instance_filter->IsJSObject()); | 11012 instance_filter->IsJSObject()); |
| 10540 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]); | 11013 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]); |
| 10541 RUNTIME_ASSERT(max_references >= 0); | 11014 RUNTIME_ASSERT(max_references >= 0); |
| 10542 | 11015 |
| 10543 // Get the constructor function for context extension and arguments array. | 11016 // Get the constructor function for context extension and arguments array. |
| 10544 JSObject* arguments_boilerplate = | 11017 JSObject* arguments_boilerplate = |
| 10545 Top::context()->global_context()->arguments_boilerplate(); | 11018 isolate->context()->global_context()->arguments_boilerplate(); |
| 10546 JSFunction* arguments_function = | 11019 JSFunction* arguments_function = |
| 10547 JSFunction::cast(arguments_boilerplate->map()->constructor()); | 11020 JSFunction::cast(arguments_boilerplate->map()->constructor()); |
| 10548 | 11021 |
| 10549 // Get the number of referencing objects. | 11022 // Get the number of referencing objects. |
| 10550 int count; | 11023 int count; |
| 10551 count = DebugReferencedBy(target, instance_filter, max_references, | 11024 count = DebugReferencedBy(target, instance_filter, max_references, |
| 10552 NULL, 0, arguments_function); | 11025 NULL, 0, arguments_function); |
| 10553 | 11026 |
| 10554 // Allocate an array to hold the result. | 11027 // Allocate an array to hold the result. |
| 10555 Object* object; | 11028 Object* object; |
| 10556 { MaybeObject* maybe_object = Heap::AllocateFixedArray(count); | 11029 { MaybeObject* maybe_object = isolate->heap()->AllocateFixedArray(count); |
| 10557 if (!maybe_object->ToObject(&object)) return maybe_object; | 11030 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 10558 } | 11031 } |
| 10559 FixedArray* instances = FixedArray::cast(object); | 11032 FixedArray* instances = FixedArray::cast(object); |
| 10560 | 11033 |
| 10561 // Fill the referencing objects. | 11034 // Fill the referencing objects. |
| 10562 count = DebugReferencedBy(target, instance_filter, max_references, | 11035 count = DebugReferencedBy(target, instance_filter, max_references, |
| 10563 instances, count, arguments_function); | 11036 instances, count, arguments_function); |
| 10564 | 11037 |
| 10565 // Return result as JS array. | 11038 // Return result as JS array. |
| 10566 Object* result; | 11039 Object* result; |
| 10567 { MaybeObject* maybe_result = Heap::AllocateJSObject( | 11040 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( |
| 10568 Top::context()->global_context()->array_function()); | 11041 isolate->context()->global_context()->array_function()); |
| 10569 if (!maybe_result->ToObject(&result)) return maybe_result; | 11042 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 10570 } | 11043 } |
| 10571 JSArray::cast(result)->SetContent(instances); | 11044 JSArray::cast(result)->SetContent(instances); |
| 10572 return result; | 11045 return result; |
| 10573 } | 11046 } |
| 10574 | 11047 |
| 10575 | 11048 |
| 10576 // Helper function used by Runtime_DebugConstructedBy below. | 11049 // Helper function used by Runtime_DebugConstructedBy below. |
| 10577 static int DebugConstructedBy(JSFunction* constructor, int max_references, | 11050 static int DebugConstructedBy(JSFunction* constructor, int max_references, |
| 10578 FixedArray* instances, int instances_size) { | 11051 FixedArray* instances, int instances_size) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 10599 } | 11072 } |
| 10600 | 11073 |
| 10601 // Return the number of referencing objects found. | 11074 // Return the number of referencing objects found. |
| 10602 return count; | 11075 return count; |
| 10603 } | 11076 } |
| 10604 | 11077 |
| 10605 | 11078 |
| 10606 // Scan the heap for objects constructed by a specific function. | 11079 // Scan the heap for objects constructed by a specific function. |
| 10607 // args[0]: the constructor to find instances of | 11080 // args[0]: the constructor to find instances of |
| 10608 // args[1]: the the maximum number of objects to return | 11081 // args[1]: the the maximum number of objects to return |
| 10609 static MaybeObject* Runtime_DebugConstructedBy(Arguments args) { | 11082 static MaybeObject* Runtime_DebugConstructedBy(RUNTIME_CALLING_CONVENTION) { |
| 11083 RUNTIME_GET_ISOLATE; |
| 10610 ASSERT(args.length() == 2); | 11084 ASSERT(args.length() == 2); |
| 10611 | 11085 |
| 10612 // First perform a full GC in order to avoid dead objects. | 11086 // First perform a full GC in order to avoid dead objects. |
| 10613 Heap::CollectAllGarbage(false); | 11087 isolate->heap()->CollectAllGarbage(false); |
| 10614 | 11088 |
| 10615 // Check parameters. | 11089 // Check parameters. |
| 10616 CONVERT_CHECKED(JSFunction, constructor, args[0]); | 11090 CONVERT_CHECKED(JSFunction, constructor, args[0]); |
| 10617 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]); | 11091 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]); |
| 10618 RUNTIME_ASSERT(max_references >= 0); | 11092 RUNTIME_ASSERT(max_references >= 0); |
| 10619 | 11093 |
| 10620 // Get the number of referencing objects. | 11094 // Get the number of referencing objects. |
| 10621 int count; | 11095 int count; |
| 10622 count = DebugConstructedBy(constructor, max_references, NULL, 0); | 11096 count = DebugConstructedBy(constructor, max_references, NULL, 0); |
| 10623 | 11097 |
| 10624 // Allocate an array to hold the result. | 11098 // Allocate an array to hold the result. |
| 10625 Object* object; | 11099 Object* object; |
| 10626 { MaybeObject* maybe_object = Heap::AllocateFixedArray(count); | 11100 { MaybeObject* maybe_object = isolate->heap()->AllocateFixedArray(count); |
| 10627 if (!maybe_object->ToObject(&object)) return maybe_object; | 11101 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 10628 } | 11102 } |
| 10629 FixedArray* instances = FixedArray::cast(object); | 11103 FixedArray* instances = FixedArray::cast(object); |
| 10630 | 11104 |
| 10631 // Fill the referencing objects. | 11105 // Fill the referencing objects. |
| 10632 count = DebugConstructedBy(constructor, max_references, instances, count); | 11106 count = DebugConstructedBy(constructor, max_references, instances, count); |
| 10633 | 11107 |
| 10634 // Return result as JS array. | 11108 // Return result as JS array. |
| 10635 Object* result; | 11109 Object* result; |
| 10636 { MaybeObject* maybe_result = Heap::AllocateJSObject( | 11110 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( |
| 10637 Top::context()->global_context()->array_function()); | 11111 isolate->context()->global_context()->array_function()); |
| 10638 if (!maybe_result->ToObject(&result)) return maybe_result; | 11112 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 10639 } | 11113 } |
| 10640 JSArray::cast(result)->SetContent(instances); | 11114 JSArray::cast(result)->SetContent(instances); |
| 10641 return result; | 11115 return result; |
| 10642 } | 11116 } |
| 10643 | 11117 |
| 10644 | 11118 |
| 10645 // Find the effective prototype object as returned by __proto__. | 11119 // Find the effective prototype object as returned by __proto__. |
| 10646 // args[0]: the object to find the prototype for. | 11120 // args[0]: the object to find the prototype for. |
| 10647 static MaybeObject* Runtime_DebugGetPrototype(Arguments args) { | 11121 static MaybeObject* Runtime_DebugGetPrototype(RUNTIME_CALLING_CONVENTION) { |
| 11122 RUNTIME_GET_ISOLATE; |
| 10648 ASSERT(args.length() == 1); | 11123 ASSERT(args.length() == 1); |
| 10649 | 11124 |
| 10650 CONVERT_CHECKED(JSObject, obj, args[0]); | 11125 CONVERT_CHECKED(JSObject, obj, args[0]); |
| 10651 | 11126 |
| 10652 // Use the __proto__ accessor. | 11127 // Use the __proto__ accessor. |
| 10653 return Accessors::ObjectPrototype.getter(obj, NULL); | 11128 return Accessors::ObjectPrototype.getter(obj, NULL); |
| 10654 } | 11129 } |
| 10655 | 11130 |
| 10656 | 11131 |
| 10657 static MaybeObject* Runtime_SystemBreak(Arguments args) { | 11132 static MaybeObject* Runtime_SystemBreak(RUNTIME_CALLING_CONVENTION) { |
| 11133 RUNTIME_GET_ISOLATE; |
| 10658 ASSERT(args.length() == 0); | 11134 ASSERT(args.length() == 0); |
| 10659 CPU::DebugBreak(); | 11135 CPU::DebugBreak(); |
| 10660 return Heap::undefined_value(); | 11136 return isolate->heap()->undefined_value(); |
| 10661 } | 11137 } |
| 10662 | 11138 |
| 10663 | 11139 |
| 10664 static MaybeObject* Runtime_DebugDisassembleFunction(Arguments args) { | 11140 static MaybeObject* Runtime_DebugDisassembleFunction( |
| 11141 RUNTIME_CALLING_CONVENTION) { |
| 11142 RUNTIME_GET_ISOLATE; |
| 10665 #ifdef DEBUG | 11143 #ifdef DEBUG |
| 10666 HandleScope scope; | 11144 HandleScope scope(isolate); |
| 10667 ASSERT(args.length() == 1); | 11145 ASSERT(args.length() == 1); |
| 10668 // Get the function and make sure it is compiled. | 11146 // Get the function and make sure it is compiled. |
| 10669 CONVERT_ARG_CHECKED(JSFunction, func, 0); | 11147 CONVERT_ARG_CHECKED(JSFunction, func, 0); |
| 10670 Handle<SharedFunctionInfo> shared(func->shared()); | 11148 Handle<SharedFunctionInfo> shared(func->shared()); |
| 10671 if (!EnsureCompiled(shared, KEEP_EXCEPTION)) { | 11149 if (!EnsureCompiled(shared, KEEP_EXCEPTION)) { |
| 10672 return Failure::Exception(); | 11150 return Failure::Exception(); |
| 10673 } | 11151 } |
| 10674 func->code()->PrintLn(); | 11152 func->code()->PrintLn(); |
| 10675 #endif // DEBUG | 11153 #endif // DEBUG |
| 10676 return Heap::undefined_value(); | 11154 return isolate->heap()->undefined_value(); |
| 10677 } | 11155 } |
| 10678 | 11156 |
| 10679 | 11157 |
| 10680 static MaybeObject* Runtime_DebugDisassembleConstructor(Arguments args) { | 11158 static MaybeObject* Runtime_DebugDisassembleConstructor( |
| 11159 RUNTIME_CALLING_CONVENTION) { |
| 11160 RUNTIME_GET_ISOLATE; |
| 10681 #ifdef DEBUG | 11161 #ifdef DEBUG |
| 10682 HandleScope scope; | 11162 HandleScope scope(isolate); |
| 10683 ASSERT(args.length() == 1); | 11163 ASSERT(args.length() == 1); |
| 10684 // Get the function and make sure it is compiled. | 11164 // Get the function and make sure it is compiled. |
| 10685 CONVERT_ARG_CHECKED(JSFunction, func, 0); | 11165 CONVERT_ARG_CHECKED(JSFunction, func, 0); |
| 10686 Handle<SharedFunctionInfo> shared(func->shared()); | 11166 Handle<SharedFunctionInfo> shared(func->shared()); |
| 10687 if (!EnsureCompiled(shared, KEEP_EXCEPTION)) { | 11167 if (!EnsureCompiled(shared, KEEP_EXCEPTION)) { |
| 10688 return Failure::Exception(); | 11168 return Failure::Exception(); |
| 10689 } | 11169 } |
| 10690 shared->construct_stub()->PrintLn(); | 11170 shared->construct_stub()->PrintLn(); |
| 10691 #endif // DEBUG | 11171 #endif // DEBUG |
| 10692 return Heap::undefined_value(); | 11172 return isolate->heap()->undefined_value(); |
| 10693 } | 11173 } |
| 10694 | 11174 |
| 10695 | 11175 |
| 10696 static MaybeObject* Runtime_FunctionGetInferredName(Arguments args) { | 11176 static MaybeObject* Runtime_FunctionGetInferredName( |
| 11177 RUNTIME_CALLING_CONVENTION) { |
| 11178 RUNTIME_GET_ISOLATE; |
| 10697 NoHandleAllocation ha; | 11179 NoHandleAllocation ha; |
| 10698 ASSERT(args.length() == 1); | 11180 ASSERT(args.length() == 1); |
| 10699 | 11181 |
| 10700 CONVERT_CHECKED(JSFunction, f, args[0]); | 11182 CONVERT_CHECKED(JSFunction, f, args[0]); |
| 10701 return f->shared()->inferred_name(); | 11183 return f->shared()->inferred_name(); |
| 10702 } | 11184 } |
| 10703 | 11185 |
| 10704 | 11186 |
| 10705 static int FindSharedFunctionInfosForScript(Script* script, | 11187 static int FindSharedFunctionInfosForScript(Script* script, |
| 10706 FixedArray* buffer) { | 11188 FixedArray* buffer) { |
| 10707 AssertNoAllocation no_allocations; | 11189 AssertNoAllocation no_allocations; |
| 10708 | 11190 |
| 10709 int counter = 0; | 11191 int counter = 0; |
| 10710 int buffer_size = buffer->length(); | 11192 int buffer_size = buffer->length(); |
| 10711 HeapIterator iterator; | 11193 HeapIterator iterator; |
| 10712 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 11194 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
| 10713 ASSERT(obj != NULL); | 11195 ASSERT(obj != NULL); |
| 10714 if (!obj->IsSharedFunctionInfo()) { | 11196 if (!obj->IsSharedFunctionInfo()) { |
| 10715 continue; | 11197 continue; |
| 10716 } | 11198 } |
| 10717 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); | 11199 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); |
| 10718 if (shared->script() != script) { | 11200 if (shared->script() != script) { |
| 10719 continue; | 11201 continue; |
| 10720 } | 11202 } |
| 10721 if (counter < buffer_size) { | 11203 if (counter < buffer_size) { |
| 10722 buffer->set(counter, shared); | 11204 buffer->set(counter, shared); |
| 10723 } | 11205 } |
| 10724 counter++; | 11206 counter++; |
| 10725 } | 11207 } |
| 10726 return counter; | 11208 return counter; |
| 10727 } | 11209 } |
| 10728 | 11210 |
| 10729 // For a script finds all SharedFunctionInfo's in the heap that points | 11211 // For a script finds all SharedFunctionInfo's in the heap that points |
| 10730 // to this script. Returns JSArray of SharedFunctionInfo wrapped | 11212 // to this script. Returns JSArray of SharedFunctionInfo wrapped |
| 10731 // in OpaqueReferences. | 11213 // in OpaqueReferences. |
| 10732 static MaybeObject* Runtime_LiveEditFindSharedFunctionInfosForScript( | 11214 static MaybeObject* Runtime_LiveEditFindSharedFunctionInfosForScript( |
| 10733 Arguments args) { | 11215 RUNTIME_CALLING_CONVENTION) { |
| 11216 RUNTIME_GET_ISOLATE; |
| 10734 ASSERT(args.length() == 1); | 11217 ASSERT(args.length() == 1); |
| 10735 HandleScope scope; | 11218 HandleScope scope(isolate); |
| 10736 CONVERT_CHECKED(JSValue, script_value, args[0]); | 11219 CONVERT_CHECKED(JSValue, script_value, args[0]); |
| 10737 | 11220 |
| 10738 Handle<Script> script = Handle<Script>(Script::cast(script_value->value())); | 11221 Handle<Script> script = Handle<Script>(Script::cast(script_value->value())); |
| 10739 | 11222 |
| 10740 const int kBufferSize = 32; | 11223 const int kBufferSize = 32; |
| 10741 | 11224 |
| 10742 Handle<FixedArray> array; | 11225 Handle<FixedArray> array; |
| 10743 array = Factory::NewFixedArray(kBufferSize); | 11226 array = isolate->factory()->NewFixedArray(kBufferSize); |
| 10744 int number = FindSharedFunctionInfosForScript(*script, *array); | 11227 int number = FindSharedFunctionInfosForScript(*script, *array); |
| 10745 if (number > kBufferSize) { | 11228 if (number > kBufferSize) { |
| 10746 array = Factory::NewFixedArray(number); | 11229 array = isolate->factory()->NewFixedArray(number); |
| 10747 FindSharedFunctionInfosForScript(*script, *array); | 11230 FindSharedFunctionInfosForScript(*script, *array); |
| 10748 } | 11231 } |
| 10749 | 11232 |
| 10750 Handle<JSArray> result = Factory::NewJSArrayWithElements(array); | 11233 Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(array); |
| 10751 result->set_length(Smi::FromInt(number)); | 11234 result->set_length(Smi::FromInt(number)); |
| 10752 | 11235 |
| 10753 LiveEdit::WrapSharedFunctionInfos(result); | 11236 LiveEdit::WrapSharedFunctionInfos(result); |
| 10754 | 11237 |
| 10755 return *result; | 11238 return *result; |
| 10756 } | 11239 } |
| 10757 | 11240 |
| 10758 // For a script calculates compilation information about all its functions. | 11241 // For a script calculates compilation information about all its functions. |
| 10759 // The script source is explicitly specified by the second argument. | 11242 // The script source is explicitly specified by the second argument. |
| 10760 // The source of the actual script is not used, however it is important that | 11243 // The source of the actual script is not used, however it is important that |
| 10761 // all generated code keeps references to this particular instance of script. | 11244 // all generated code keeps references to this particular instance of script. |
| 10762 // Returns a JSArray of compilation infos. The array is ordered so that | 11245 // Returns a JSArray of compilation infos. The array is ordered so that |
| 10763 // each function with all its descendant is always stored in a continues range | 11246 // each function with all its descendant is always stored in a continues range |
| 10764 // with the function itself going first. The root function is a script function. | 11247 // with the function itself going first. The root function is a script function. |
| 10765 static MaybeObject* Runtime_LiveEditGatherCompileInfo(Arguments args) { | 11248 static MaybeObject* Runtime_LiveEditGatherCompileInfo( |
| 11249 RUNTIME_CALLING_CONVENTION) { |
| 11250 RUNTIME_GET_ISOLATE; |
| 10766 ASSERT(args.length() == 2); | 11251 ASSERT(args.length() == 2); |
| 10767 HandleScope scope; | 11252 HandleScope scope(isolate); |
| 10768 CONVERT_CHECKED(JSValue, script, args[0]); | 11253 CONVERT_CHECKED(JSValue, script, args[0]); |
| 10769 CONVERT_ARG_CHECKED(String, source, 1); | 11254 CONVERT_ARG_CHECKED(String, source, 1); |
| 10770 Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); | 11255 Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); |
| 10771 | 11256 |
| 10772 JSArray* result = LiveEdit::GatherCompileInfo(script_handle, source); | 11257 JSArray* result = LiveEdit::GatherCompileInfo(script_handle, source); |
| 10773 | 11258 |
| 10774 if (Top::has_pending_exception()) { | 11259 if (isolate->has_pending_exception()) { |
| 10775 return Failure::Exception(); | 11260 return Failure::Exception(); |
| 10776 } | 11261 } |
| 10777 | 11262 |
| 10778 return result; | 11263 return result; |
| 10779 } | 11264 } |
| 10780 | 11265 |
| 10781 // Changes the source of the script to a new_source. | 11266 // Changes the source of the script to a new_source. |
| 10782 // If old_script_name is provided (i.e. is a String), also creates a copy of | 11267 // If old_script_name is provided (i.e. is a String), also creates a copy of |
| 10783 // the script with its original source and sends notification to debugger. | 11268 // the script with its original source and sends notification to debugger. |
| 10784 static MaybeObject* Runtime_LiveEditReplaceScript(Arguments args) { | 11269 static MaybeObject* Runtime_LiveEditReplaceScript(RUNTIME_CALLING_CONVENTION) { |
| 11270 RUNTIME_GET_ISOLATE; |
| 10785 ASSERT(args.length() == 3); | 11271 ASSERT(args.length() == 3); |
| 10786 HandleScope scope; | 11272 HandleScope scope(isolate); |
| 10787 CONVERT_CHECKED(JSValue, original_script_value, args[0]); | 11273 CONVERT_CHECKED(JSValue, original_script_value, args[0]); |
| 10788 CONVERT_ARG_CHECKED(String, new_source, 1); | 11274 CONVERT_ARG_CHECKED(String, new_source, 1); |
| 10789 Handle<Object> old_script_name(args[2]); | 11275 Handle<Object> old_script_name(args[2], isolate); |
| 10790 | 11276 |
| 10791 CONVERT_CHECKED(Script, original_script_pointer, | 11277 CONVERT_CHECKED(Script, original_script_pointer, |
| 10792 original_script_value->value()); | 11278 original_script_value->value()); |
| 10793 Handle<Script> original_script(original_script_pointer); | 11279 Handle<Script> original_script(original_script_pointer); |
| 10794 | 11280 |
| 10795 Object* old_script = LiveEdit::ChangeScriptSource(original_script, | 11281 Object* old_script = LiveEdit::ChangeScriptSource(original_script, |
| 10796 new_source, | 11282 new_source, |
| 10797 old_script_name); | 11283 old_script_name); |
| 10798 | 11284 |
| 10799 if (old_script->IsScript()) { | 11285 if (old_script->IsScript()) { |
| 10800 Handle<Script> script_handle(Script::cast(old_script)); | 11286 Handle<Script> script_handle(Script::cast(old_script)); |
| 10801 return *(GetScriptWrapper(script_handle)); | 11287 return *(GetScriptWrapper(script_handle)); |
| 10802 } else { | 11288 } else { |
| 10803 return Heap::null_value(); | 11289 return isolate->heap()->null_value(); |
| 10804 } | 11290 } |
| 10805 } | 11291 } |
| 10806 | 11292 |
| 10807 | 11293 |
| 10808 static MaybeObject* Runtime_LiveEditFunctionSourceUpdated(Arguments args) { | 11294 static MaybeObject* Runtime_LiveEditFunctionSourceUpdated( |
| 11295 RUNTIME_CALLING_CONVENTION) { |
| 11296 RUNTIME_GET_ISOLATE; |
| 10809 ASSERT(args.length() == 1); | 11297 ASSERT(args.length() == 1); |
| 10810 HandleScope scope; | 11298 HandleScope scope(isolate); |
| 10811 CONVERT_ARG_CHECKED(JSArray, shared_info, 0); | 11299 CONVERT_ARG_CHECKED(JSArray, shared_info, 0); |
| 10812 return LiveEdit::FunctionSourceUpdated(shared_info); | 11300 return LiveEdit::FunctionSourceUpdated(shared_info); |
| 10813 } | 11301 } |
| 10814 | 11302 |
| 10815 | 11303 |
| 10816 // Replaces code of SharedFunctionInfo with a new one. | 11304 // Replaces code of SharedFunctionInfo with a new one. |
| 10817 static MaybeObject* Runtime_LiveEditReplaceFunctionCode(Arguments args) { | 11305 static MaybeObject* Runtime_LiveEditReplaceFunctionCode( |
| 11306 RUNTIME_CALLING_CONVENTION) { |
| 11307 RUNTIME_GET_ISOLATE; |
| 10818 ASSERT(args.length() == 2); | 11308 ASSERT(args.length() == 2); |
| 10819 HandleScope scope; | 11309 HandleScope scope(isolate); |
| 10820 CONVERT_ARG_CHECKED(JSArray, new_compile_info, 0); | 11310 CONVERT_ARG_CHECKED(JSArray, new_compile_info, 0); |
| 10821 CONVERT_ARG_CHECKED(JSArray, shared_info, 1); | 11311 CONVERT_ARG_CHECKED(JSArray, shared_info, 1); |
| 10822 | 11312 |
| 10823 return LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info); | 11313 return LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info); |
| 10824 } | 11314 } |
| 10825 | 11315 |
| 10826 // Connects SharedFunctionInfo to another script. | 11316 // Connects SharedFunctionInfo to another script. |
| 10827 static MaybeObject* Runtime_LiveEditFunctionSetScript(Arguments args) { | 11317 static MaybeObject* Runtime_LiveEditFunctionSetScript( |
| 11318 RUNTIME_CALLING_CONVENTION) { |
| 11319 RUNTIME_GET_ISOLATE; |
| 10828 ASSERT(args.length() == 2); | 11320 ASSERT(args.length() == 2); |
| 10829 HandleScope scope; | 11321 HandleScope scope(isolate); |
| 10830 Handle<Object> function_object(args[0]); | 11322 Handle<Object> function_object(args[0], isolate); |
| 10831 Handle<Object> script_object(args[1]); | 11323 Handle<Object> script_object(args[1], isolate); |
| 10832 | 11324 |
| 10833 if (function_object->IsJSValue()) { | 11325 if (function_object->IsJSValue()) { |
| 10834 Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object); | 11326 Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object); |
| 10835 if (script_object->IsJSValue()) { | 11327 if (script_object->IsJSValue()) { |
| 10836 CONVERT_CHECKED(Script, script, JSValue::cast(*script_object)->value()); | 11328 CONVERT_CHECKED(Script, script, JSValue::cast(*script_object)->value()); |
| 10837 script_object = Handle<Object>(script); | 11329 script_object = Handle<Object>(script, isolate); |
| 10838 } | 11330 } |
| 10839 | 11331 |
| 10840 LiveEdit::SetFunctionScript(function_wrapper, script_object); | 11332 LiveEdit::SetFunctionScript(function_wrapper, script_object); |
| 10841 } else { | 11333 } else { |
| 10842 // Just ignore this. We may not have a SharedFunctionInfo for some functions | 11334 // Just ignore this. We may not have a SharedFunctionInfo for some functions |
| 10843 // and we check it in this function. | 11335 // and we check it in this function. |
| 10844 } | 11336 } |
| 10845 | 11337 |
| 10846 return Heap::undefined_value(); | 11338 return isolate->heap()->undefined_value(); |
| 10847 } | 11339 } |
| 10848 | 11340 |
| 10849 | 11341 |
| 10850 // In a code of a parent function replaces original function as embedded object | 11342 // In a code of a parent function replaces original function as embedded object |
| 10851 // with a substitution one. | 11343 // with a substitution one. |
| 10852 static MaybeObject* Runtime_LiveEditReplaceRefToNestedFunction(Arguments args) { | 11344 static MaybeObject* Runtime_LiveEditReplaceRefToNestedFunction( |
| 11345 RUNTIME_CALLING_CONVENTION) { |
| 11346 RUNTIME_GET_ISOLATE; |
| 10853 ASSERT(args.length() == 3); | 11347 ASSERT(args.length() == 3); |
| 10854 HandleScope scope; | 11348 HandleScope scope(isolate); |
| 10855 | 11349 |
| 10856 CONVERT_ARG_CHECKED(JSValue, parent_wrapper, 0); | 11350 CONVERT_ARG_CHECKED(JSValue, parent_wrapper, 0); |
| 10857 CONVERT_ARG_CHECKED(JSValue, orig_wrapper, 1); | 11351 CONVERT_ARG_CHECKED(JSValue, orig_wrapper, 1); |
| 10858 CONVERT_ARG_CHECKED(JSValue, subst_wrapper, 2); | 11352 CONVERT_ARG_CHECKED(JSValue, subst_wrapper, 2); |
| 10859 | 11353 |
| 10860 LiveEdit::ReplaceRefToNestedFunction(parent_wrapper, orig_wrapper, | 11354 LiveEdit::ReplaceRefToNestedFunction(parent_wrapper, orig_wrapper, |
| 10861 subst_wrapper); | 11355 subst_wrapper); |
| 10862 | 11356 |
| 10863 return Heap::undefined_value(); | 11357 return isolate->heap()->undefined_value(); |
| 10864 } | 11358 } |
| 10865 | 11359 |
| 10866 | 11360 |
| 10867 // Updates positions of a shared function info (first parameter) according | 11361 // Updates positions of a shared function info (first parameter) according |
| 10868 // to script source change. Text change is described in second parameter as | 11362 // to script source change. Text change is described in second parameter as |
| 10869 // array of groups of 3 numbers: | 11363 // array of groups of 3 numbers: |
| 10870 // (change_begin, change_end, change_end_new_position). | 11364 // (change_begin, change_end, change_end_new_position). |
| 10871 // Each group describes a change in text; groups are sorted by change_begin. | 11365 // Each group describes a change in text; groups are sorted by change_begin. |
| 10872 static MaybeObject* Runtime_LiveEditPatchFunctionPositions(Arguments args) { | 11366 static MaybeObject* Runtime_LiveEditPatchFunctionPositions( |
| 11367 RUNTIME_CALLING_CONVENTION) { |
| 11368 RUNTIME_GET_ISOLATE; |
| 10873 ASSERT(args.length() == 2); | 11369 ASSERT(args.length() == 2); |
| 10874 HandleScope scope; | 11370 HandleScope scope(isolate); |
| 10875 CONVERT_ARG_CHECKED(JSArray, shared_array, 0); | 11371 CONVERT_ARG_CHECKED(JSArray, shared_array, 0); |
| 10876 CONVERT_ARG_CHECKED(JSArray, position_change_array, 1); | 11372 CONVERT_ARG_CHECKED(JSArray, position_change_array, 1); |
| 10877 | 11373 |
| 10878 return LiveEdit::PatchFunctionPositions(shared_array, position_change_array); | 11374 return LiveEdit::PatchFunctionPositions(shared_array, position_change_array); |
| 10879 } | 11375 } |
| 10880 | 11376 |
| 10881 | 11377 |
| 10882 // For array of SharedFunctionInfo's (each wrapped in JSValue) | 11378 // For array of SharedFunctionInfo's (each wrapped in JSValue) |
| 10883 // checks that none of them have activations on stacks (of any thread). | 11379 // checks that none of them have activations on stacks (of any thread). |
| 10884 // Returns array of the same length with corresponding results of | 11380 // Returns array of the same length with corresponding results of |
| 10885 // LiveEdit::FunctionPatchabilityStatus type. | 11381 // LiveEdit::FunctionPatchabilityStatus type. |
| 10886 static MaybeObject* Runtime_LiveEditCheckAndDropActivations(Arguments args) { | 11382 static MaybeObject* Runtime_LiveEditCheckAndDropActivations( |
| 11383 RUNTIME_CALLING_CONVENTION) { |
| 11384 RUNTIME_GET_ISOLATE; |
| 10887 ASSERT(args.length() == 2); | 11385 ASSERT(args.length() == 2); |
| 10888 HandleScope scope; | 11386 HandleScope scope(isolate); |
| 10889 CONVERT_ARG_CHECKED(JSArray, shared_array, 0); | 11387 CONVERT_ARG_CHECKED(JSArray, shared_array, 0); |
| 10890 CONVERT_BOOLEAN_CHECKED(do_drop, args[1]); | 11388 CONVERT_BOOLEAN_CHECKED(do_drop, args[1]); |
| 10891 | 11389 |
| 10892 return *LiveEdit::CheckAndDropActivations(shared_array, do_drop); | 11390 return *LiveEdit::CheckAndDropActivations(shared_array, do_drop); |
| 10893 } | 11391 } |
| 10894 | 11392 |
| 10895 // Compares 2 strings line-by-line, then token-wise and returns diff in form | 11393 // Compares 2 strings line-by-line, then token-wise and returns diff in form |
| 10896 // of JSArray of triplets (pos1, pos1_end, pos2_end) describing list | 11394 // of JSArray of triplets (pos1, pos1_end, pos2_end) describing list |
| 10897 // of diff chunks. | 11395 // of diff chunks. |
| 10898 static MaybeObject* Runtime_LiveEditCompareStrings(Arguments args) { | 11396 static MaybeObject* Runtime_LiveEditCompareStrings(RUNTIME_CALLING_CONVENTION) { |
| 11397 RUNTIME_GET_ISOLATE; |
| 10899 ASSERT(args.length() == 2); | 11398 ASSERT(args.length() == 2); |
| 10900 HandleScope scope; | 11399 HandleScope scope(isolate); |
| 10901 CONVERT_ARG_CHECKED(String, s1, 0); | 11400 CONVERT_ARG_CHECKED(String, s1, 0); |
| 10902 CONVERT_ARG_CHECKED(String, s2, 1); | 11401 CONVERT_ARG_CHECKED(String, s2, 1); |
| 10903 | 11402 |
| 10904 return *LiveEdit::CompareStrings(s1, s2); | 11403 return *LiveEdit::CompareStrings(s1, s2); |
| 10905 } | 11404 } |
| 10906 | 11405 |
| 10907 | 11406 |
| 10908 | |
| 10909 // A testing entry. Returns statement position which is the closest to | 11407 // A testing entry. Returns statement position which is the closest to |
| 10910 // source_position. | 11408 // source_position. |
| 10911 static MaybeObject* Runtime_GetFunctionCodePositionFromSource(Arguments args) { | 11409 static MaybeObject* Runtime_GetFunctionCodePositionFromSource( |
| 11410 RUNTIME_CALLING_CONVENTION) { |
| 11411 RUNTIME_GET_ISOLATE; |
| 10912 ASSERT(args.length() == 2); | 11412 ASSERT(args.length() == 2); |
| 10913 HandleScope scope; | 11413 HandleScope scope(isolate); |
| 10914 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 11414 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
| 10915 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); | 11415 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); |
| 10916 | 11416 |
| 10917 Handle<Code> code(function->code()); | 11417 Handle<Code> code(function->code(), isolate); |
| 10918 | 11418 |
| 10919 if (code->kind() != Code::FUNCTION && | 11419 if (code->kind() != Code::FUNCTION && |
| 10920 code->kind() != Code::OPTIMIZED_FUNCTION) { | 11420 code->kind() != Code::OPTIMIZED_FUNCTION) { |
| 10921 return Heap::undefined_value(); | 11421 return isolate->heap()->undefined_value(); |
| 10922 } | 11422 } |
| 10923 | 11423 |
| 10924 RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION)); | 11424 RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION)); |
| 10925 int closest_pc = 0; | 11425 int closest_pc = 0; |
| 10926 int distance = kMaxInt; | 11426 int distance = kMaxInt; |
| 10927 while (!it.done()) { | 11427 while (!it.done()) { |
| 10928 int statement_position = static_cast<int>(it.rinfo()->data()); | 11428 int statement_position = static_cast<int>(it.rinfo()->data()); |
| 10929 // Check if this break point is closer that what was previously found. | 11429 // Check if this break point is closer that what was previously found. |
| 10930 if (source_position <= statement_position && | 11430 if (source_position <= statement_position && |
| 10931 statement_position - source_position < distance) { | 11431 statement_position - source_position < distance) { |
| 10932 closest_pc = | 11432 closest_pc = |
| 10933 static_cast<int>(it.rinfo()->pc() - code->instruction_start()); | 11433 static_cast<int>(it.rinfo()->pc() - code->instruction_start()); |
| 10934 distance = statement_position - source_position; | 11434 distance = statement_position - source_position; |
| 10935 // Check whether we can't get any closer. | 11435 // Check whether we can't get any closer. |
| 10936 if (distance == 0) break; | 11436 if (distance == 0) break; |
| 10937 } | 11437 } |
| 10938 it.next(); | 11438 it.next(); |
| 10939 } | 11439 } |
| 10940 | 11440 |
| 10941 return Smi::FromInt(closest_pc); | 11441 return Smi::FromInt(closest_pc); |
| 10942 } | 11442 } |
| 10943 | 11443 |
| 10944 | 11444 |
| 10945 // Calls specified function with or without entering the debugger. | 11445 // Calls specified function with or without entering the debugger. |
| 10946 // This is used in unit tests to run code as if debugger is entered or simply | 11446 // This is used in unit tests to run code as if debugger is entered or simply |
| 10947 // to have a stack with C++ frame in the middle. | 11447 // to have a stack with C++ frame in the middle. |
| 10948 static MaybeObject* Runtime_ExecuteInDebugContext(Arguments args) { | 11448 static MaybeObject* Runtime_ExecuteInDebugContext(RUNTIME_CALLING_CONVENTION) { |
| 11449 RUNTIME_GET_ISOLATE; |
| 10949 ASSERT(args.length() == 2); | 11450 ASSERT(args.length() == 2); |
| 10950 HandleScope scope; | 11451 HandleScope scope(isolate); |
| 10951 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 11452 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
| 10952 CONVERT_BOOLEAN_CHECKED(without_debugger, args[1]); | 11453 CONVERT_BOOLEAN_CHECKED(without_debugger, args[1]); |
| 10953 | 11454 |
| 10954 Handle<Object> result; | 11455 Handle<Object> result; |
| 10955 bool pending_exception; | 11456 bool pending_exception; |
| 10956 { | 11457 { |
| 10957 if (without_debugger) { | 11458 if (without_debugger) { |
| 10958 result = Execution::Call(function, Top::global(), 0, NULL, | 11459 result = Execution::Call(function, isolate->global(), 0, NULL, |
| 10959 &pending_exception); | 11460 &pending_exception); |
| 10960 } else { | 11461 } else { |
| 10961 EnterDebugger enter_debugger; | 11462 EnterDebugger enter_debugger; |
| 10962 result = Execution::Call(function, Top::global(), 0, NULL, | 11463 result = Execution::Call(function, isolate->global(), 0, NULL, |
| 10963 &pending_exception); | 11464 &pending_exception); |
| 10964 } | 11465 } |
| 10965 } | 11466 } |
| 10966 if (!pending_exception) { | 11467 if (!pending_exception) { |
| 10967 return *result; | 11468 return *result; |
| 10968 } else { | 11469 } else { |
| 10969 return Failure::Exception(); | 11470 return Failure::Exception(); |
| 10970 } | 11471 } |
| 10971 } | 11472 } |
| 10972 | 11473 |
| 10973 | 11474 |
| 10974 // Sets a v8 flag. | 11475 // Sets a v8 flag. |
| 10975 static MaybeObject* Runtime_SetFlags(Arguments args) { | 11476 static MaybeObject* Runtime_SetFlags(RUNTIME_CALLING_CONVENTION) { |
| 11477 RUNTIME_GET_ISOLATE; |
| 10976 CONVERT_CHECKED(String, arg, args[0]); | 11478 CONVERT_CHECKED(String, arg, args[0]); |
| 10977 SmartPointer<char> flags = | 11479 SmartPointer<char> flags = |
| 10978 arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); | 11480 arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); |
| 10979 FlagList::SetFlagsFromString(*flags, StrLength(*flags)); | 11481 FlagList::SetFlagsFromString(*flags, StrLength(*flags)); |
| 10980 return Heap::undefined_value(); | 11482 return isolate->heap()->undefined_value(); |
| 10981 } | 11483 } |
| 10982 | 11484 |
| 10983 | 11485 |
| 10984 // Performs a GC. | 11486 // Performs a GC. |
| 10985 // Presently, it only does a full GC. | 11487 // Presently, it only does a full GC. |
| 10986 static MaybeObject* Runtime_CollectGarbage(Arguments args) { | 11488 static MaybeObject* Runtime_CollectGarbage(RUNTIME_CALLING_CONVENTION) { |
| 10987 Heap::CollectAllGarbage(true); | 11489 RUNTIME_GET_ISOLATE; |
| 10988 return Heap::undefined_value(); | 11490 isolate->heap()->CollectAllGarbage(true); |
| 11491 return isolate->heap()->undefined_value(); |
| 10989 } | 11492 } |
| 10990 | 11493 |
| 10991 | 11494 |
| 10992 // Gets the current heap usage. | 11495 // Gets the current heap usage. |
| 10993 static MaybeObject* Runtime_GetHeapUsage(Arguments args) { | 11496 static MaybeObject* Runtime_GetHeapUsage(RUNTIME_CALLING_CONVENTION) { |
| 10994 int usage = static_cast<int>(Heap::SizeOfObjects()); | 11497 RUNTIME_GET_ISOLATE; |
| 11498 int usage = static_cast<int>(isolate->heap()->SizeOfObjects()); |
| 10995 if (!Smi::IsValid(usage)) { | 11499 if (!Smi::IsValid(usage)) { |
| 10996 return *Factory::NewNumberFromInt(usage); | 11500 return *isolate->factory()->NewNumberFromInt(usage); |
| 10997 } | 11501 } |
| 10998 return Smi::FromInt(usage); | 11502 return Smi::FromInt(usage); |
| 10999 } | 11503 } |
| 11000 | 11504 |
| 11001 | 11505 |
| 11002 // Captures a live object list from the present heap. | 11506 // Captures a live object list from the present heap. |
| 11003 static MaybeObject* Runtime_HasLOLEnabled(Arguments args) { | 11507 static MaybeObject* Runtime_HasLOLEnabled(RUNTIME_CALLING_CONVENTION) { |
| 11508 RUNTIME_GET_ISOLATE; |
| 11004 #ifdef LIVE_OBJECT_LIST | 11509 #ifdef LIVE_OBJECT_LIST |
| 11005 return Heap::true_value(); | 11510 return isolate->heap()->true_value(); |
| 11006 #else | 11511 #else |
| 11007 return Heap::false_value(); | 11512 return isolate->heap()->false_value(); |
| 11008 #endif | 11513 #endif |
| 11009 } | 11514 } |
| 11010 | 11515 |
| 11011 | 11516 |
| 11012 // Captures a live object list from the present heap. | 11517 // Captures a live object list from the present heap. |
| 11013 static MaybeObject* Runtime_CaptureLOL(Arguments args) { | 11518 static MaybeObject* Runtime_CaptureLOL(RUNTIME_CALLING_CONVENTION) { |
| 11519 RUNTIME_GET_ISOLATE; |
| 11014 #ifdef LIVE_OBJECT_LIST | 11520 #ifdef LIVE_OBJECT_LIST |
| 11015 return LiveObjectList::Capture(); | 11521 return LiveObjectList::Capture(); |
| 11016 #else | 11522 #else |
| 11017 return Heap::undefined_value(); | 11523 return isolate->heap()->undefined_value(); |
| 11018 #endif | 11524 #endif |
| 11019 } | 11525 } |
| 11020 | 11526 |
| 11021 | 11527 |
| 11022 // Deletes the specified live object list. | 11528 // Deletes the specified live object list. |
| 11023 static MaybeObject* Runtime_DeleteLOL(Arguments args) { | 11529 static MaybeObject* Runtime_DeleteLOL(RUNTIME_CALLING_CONVENTION) { |
| 11530 RUNTIME_GET_ISOLATE; |
| 11024 #ifdef LIVE_OBJECT_LIST | 11531 #ifdef LIVE_OBJECT_LIST |
| 11025 CONVERT_SMI_CHECKED(id, args[0]); | 11532 CONVERT_SMI_CHECKED(id, args[0]); |
| 11026 bool success = LiveObjectList::Delete(id); | 11533 bool success = LiveObjectList::Delete(id); |
| 11027 return success ? Heap::true_value() : Heap::false_value(); | 11534 return success ? isolate->heap()->true_value() : |
| 11535 isolate->heap()->false_value(); |
| 11028 #else | 11536 #else |
| 11029 return Heap::undefined_value(); | 11537 return isolate->heap()->undefined_value(); |
| 11030 #endif | 11538 #endif |
| 11031 } | 11539 } |
| 11032 | 11540 |
| 11033 | 11541 |
| 11034 // Generates the response to a debugger request for a dump of the objects | 11542 // Generates the response to a debugger request for a dump of the objects |
| 11035 // contained in the difference between the captured live object lists | 11543 // contained in the difference between the captured live object lists |
| 11036 // specified by id1 and id2. | 11544 // specified by id1 and id2. |
| 11037 // If id1 is 0 (i.e. not a valid lol), then the whole of lol id2 will be | 11545 // If id1 is 0 (i.e. not a valid lol), then the whole of lol id2 will be |
| 11038 // dumped. | 11546 // dumped. |
| 11039 static MaybeObject* Runtime_DumpLOL(Arguments args) { | 11547 static MaybeObject* Runtime_DumpLOL(RUNTIME_CALLING_CONVENTION) { |
| 11548 RUNTIME_GET_ISOLATE; |
| 11040 #ifdef LIVE_OBJECT_LIST | 11549 #ifdef LIVE_OBJECT_LIST |
| 11041 HandleScope scope; | 11550 HandleScope scope; |
| 11042 CONVERT_SMI_CHECKED(id1, args[0]); | 11551 CONVERT_SMI_CHECKED(id1, args[0]); |
| 11043 CONVERT_SMI_CHECKED(id2, args[1]); | 11552 CONVERT_SMI_CHECKED(id2, args[1]); |
| 11044 CONVERT_SMI_CHECKED(start, args[2]); | 11553 CONVERT_SMI_CHECKED(start, args[2]); |
| 11045 CONVERT_SMI_CHECKED(count, args[3]); | 11554 CONVERT_SMI_CHECKED(count, args[3]); |
| 11046 CONVERT_ARG_CHECKED(JSObject, filter_obj, 4); | 11555 CONVERT_ARG_CHECKED(JSObject, filter_obj, 4); |
| 11047 EnterDebugger enter_debugger; | 11556 EnterDebugger enter_debugger; |
| 11048 return LiveObjectList::Dump(id1, id2, start, count, filter_obj); | 11557 return LiveObjectList::Dump(id1, id2, start, count, filter_obj); |
| 11049 #else | 11558 #else |
| 11050 return Heap::undefined_value(); | 11559 return isolate->heap()->undefined_value(); |
| 11051 #endif | 11560 #endif |
| 11052 } | 11561 } |
| 11053 | 11562 |
| 11054 | 11563 |
| 11055 // Gets the specified object as requested by the debugger. | 11564 // Gets the specified object as requested by the debugger. |
| 11056 // This is only used for obj ids shown in live object lists. | 11565 // This is only used for obj ids shown in live object lists. |
| 11057 static MaybeObject* Runtime_GetLOLObj(Arguments args) { | 11566 static MaybeObject* Runtime_GetLOLObj(RUNTIME_CALLING_CONVENTION) { |
| 11567 RUNTIME_GET_ISOLATE; |
| 11058 #ifdef LIVE_OBJECT_LIST | 11568 #ifdef LIVE_OBJECT_LIST |
| 11059 CONVERT_SMI_CHECKED(obj_id, args[0]); | 11569 CONVERT_SMI_CHECKED(obj_id, args[0]); |
| 11060 Object* result = LiveObjectList::GetObj(obj_id); | 11570 Object* result = LiveObjectList::GetObj(obj_id); |
| 11061 return result; | 11571 return result; |
| 11062 #else | 11572 #else |
| 11063 return Heap::undefined_value(); | 11573 return isolate->heap()->undefined_value(); |
| 11064 #endif | 11574 #endif |
| 11065 } | 11575 } |
| 11066 | 11576 |
| 11067 | 11577 |
| 11068 // Gets the obj id for the specified address if valid. | 11578 // Gets the obj id for the specified address if valid. |
| 11069 // This is only used for obj ids shown in live object lists. | 11579 // This is only used for obj ids shown in live object lists. |
| 11070 static MaybeObject* Runtime_GetLOLObjId(Arguments args) { | 11580 static MaybeObject* Runtime_GetLOLObjId(RUNTIME_CALLING_CONVENTION) { |
| 11581 RUNTIME_GET_ISOLATE; |
| 11071 #ifdef LIVE_OBJECT_LIST | 11582 #ifdef LIVE_OBJECT_LIST |
| 11072 HandleScope scope; | 11583 HandleScope scope; |
| 11073 CONVERT_ARG_CHECKED(String, address, 0); | 11584 CONVERT_ARG_CHECKED(String, address, 0); |
| 11074 Object* result = LiveObjectList::GetObjId(address); | 11585 Object* result = LiveObjectList::GetObjId(address); |
| 11075 return result; | 11586 return result; |
| 11076 #else | 11587 #else |
| 11077 return Heap::undefined_value(); | 11588 return isolate->heap()->undefined_value(); |
| 11078 #endif | 11589 #endif |
| 11079 } | 11590 } |
| 11080 | 11591 |
| 11081 | 11592 |
| 11082 // Gets the retainers that references the specified object alive. | 11593 // Gets the retainers that references the specified object alive. |
| 11083 static MaybeObject* Runtime_GetLOLObjRetainers(Arguments args) { | 11594 static MaybeObject* Runtime_GetLOLObjRetainers(RUNTIME_CALLING_CONVENTION) { |
| 11595 RUNTIME_GET_ISOLATE; |
| 11084 #ifdef LIVE_OBJECT_LIST | 11596 #ifdef LIVE_OBJECT_LIST |
| 11085 HandleScope scope; | 11597 HandleScope scope; |
| 11086 CONVERT_SMI_CHECKED(obj_id, args[0]); | 11598 CONVERT_SMI_CHECKED(obj_id, args[0]); |
| 11087 RUNTIME_ASSERT(args[1]->IsUndefined() || args[1]->IsJSObject()); | 11599 RUNTIME_ASSERT(args[1]->IsUndefined() || args[1]->IsJSObject()); |
| 11088 RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsBoolean()); | 11600 RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsBoolean()); |
| 11089 RUNTIME_ASSERT(args[3]->IsUndefined() || args[3]->IsSmi()); | 11601 RUNTIME_ASSERT(args[3]->IsUndefined() || args[3]->IsSmi()); |
| 11090 RUNTIME_ASSERT(args[4]->IsUndefined() || args[4]->IsSmi()); | 11602 RUNTIME_ASSERT(args[4]->IsUndefined() || args[4]->IsSmi()); |
| 11091 CONVERT_ARG_CHECKED(JSObject, filter_obj, 5); | 11603 CONVERT_ARG_CHECKED(JSObject, filter_obj, 5); |
| 11092 | 11604 |
| 11093 Handle<JSObject> instance_filter; | 11605 Handle<JSObject> instance_filter; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 11107 limit = Smi::cast(args[4])->value(); | 11619 limit = Smi::cast(args[4])->value(); |
| 11108 } | 11620 } |
| 11109 | 11621 |
| 11110 return LiveObjectList::GetObjRetainers(obj_id, | 11622 return LiveObjectList::GetObjRetainers(obj_id, |
| 11111 instance_filter, | 11623 instance_filter, |
| 11112 verbose, | 11624 verbose, |
| 11113 start, | 11625 start, |
| 11114 limit, | 11626 limit, |
| 11115 filter_obj); | 11627 filter_obj); |
| 11116 #else | 11628 #else |
| 11117 return Heap::undefined_value(); | 11629 return isolate->heap()->undefined_value(); |
| 11118 #endif | 11630 #endif |
| 11119 } | 11631 } |
| 11120 | 11632 |
| 11121 | 11633 |
| 11122 // Gets the reference path between 2 objects. | 11634 // Gets the reference path between 2 objects. |
| 11123 static MaybeObject* Runtime_GetLOLPath(Arguments args) { | 11635 static MaybeObject* Runtime_GetLOLPath(RUNTIME_CALLING_CONVENTION) { |
| 11636 RUNTIME_GET_ISOLATE; |
| 11124 #ifdef LIVE_OBJECT_LIST | 11637 #ifdef LIVE_OBJECT_LIST |
| 11125 HandleScope scope; | 11638 HandleScope scope; |
| 11126 CONVERT_SMI_CHECKED(obj_id1, args[0]); | 11639 CONVERT_SMI_CHECKED(obj_id1, args[0]); |
| 11127 CONVERT_SMI_CHECKED(obj_id2, args[1]); | 11640 CONVERT_SMI_CHECKED(obj_id2, args[1]); |
| 11128 RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsJSObject()); | 11641 RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsJSObject()); |
| 11129 | 11642 |
| 11130 Handle<JSObject> instance_filter; | 11643 Handle<JSObject> instance_filter; |
| 11131 if (args[2]->IsJSObject()) { | 11644 if (args[2]->IsJSObject()) { |
| 11132 instance_filter = args.at<JSObject>(2); | 11645 instance_filter = args.at<JSObject>(2); |
| 11133 } | 11646 } |
| 11134 | 11647 |
| 11135 Object* result = | 11648 Object* result = |
| 11136 LiveObjectList::GetPath(obj_id1, obj_id2, instance_filter); | 11649 LiveObjectList::GetPath(obj_id1, obj_id2, instance_filter); |
| 11137 return result; | 11650 return result; |
| 11138 #else | 11651 #else |
| 11139 return Heap::undefined_value(); | 11652 return isolate->heap()->undefined_value(); |
| 11140 #endif | 11653 #endif |
| 11141 } | 11654 } |
| 11142 | 11655 |
| 11143 | 11656 |
| 11144 // Generates the response to a debugger request for a list of all | 11657 // Generates the response to a debugger request for a list of all |
| 11145 // previously captured live object lists. | 11658 // previously captured live object lists. |
| 11146 static MaybeObject* Runtime_InfoLOL(Arguments args) { | 11659 static MaybeObject* Runtime_InfoLOL(RUNTIME_CALLING_CONVENTION) { |
| 11660 RUNTIME_GET_ISOLATE; |
| 11147 #ifdef LIVE_OBJECT_LIST | 11661 #ifdef LIVE_OBJECT_LIST |
| 11148 CONVERT_SMI_CHECKED(start, args[0]); | 11662 CONVERT_SMI_CHECKED(start, args[0]); |
| 11149 CONVERT_SMI_CHECKED(count, args[1]); | 11663 CONVERT_SMI_CHECKED(count, args[1]); |
| 11150 return LiveObjectList::Info(start, count); | 11664 return LiveObjectList::Info(start, count); |
| 11151 #else | 11665 #else |
| 11152 return Heap::undefined_value(); | 11666 return isolate->heap()->undefined_value(); |
| 11153 #endif | 11667 #endif |
| 11154 } | 11668 } |
| 11155 | 11669 |
| 11156 | 11670 |
| 11157 // Gets a dump of the specified object as requested by the debugger. | 11671 // Gets a dump of the specified object as requested by the debugger. |
| 11158 // This is only used for obj ids shown in live object lists. | 11672 // This is only used for obj ids shown in live object lists. |
| 11159 static MaybeObject* Runtime_PrintLOLObj(Arguments args) { | 11673 static MaybeObject* Runtime_PrintLOLObj(RUNTIME_CALLING_CONVENTION) { |
| 11674 RUNTIME_GET_ISOLATE; |
| 11160 #ifdef LIVE_OBJECT_LIST | 11675 #ifdef LIVE_OBJECT_LIST |
| 11161 HandleScope scope; | 11676 HandleScope scope; |
| 11162 CONVERT_SMI_CHECKED(obj_id, args[0]); | 11677 CONVERT_SMI_CHECKED(obj_id, args[0]); |
| 11163 Object* result = LiveObjectList::PrintObj(obj_id); | 11678 Object* result = LiveObjectList::PrintObj(obj_id); |
| 11164 return result; | 11679 return result; |
| 11165 #else | 11680 #else |
| 11166 return Heap::undefined_value(); | 11681 return isolate->heap()->undefined_value(); |
| 11167 #endif | 11682 #endif |
| 11168 } | 11683 } |
| 11169 | 11684 |
| 11170 | 11685 |
| 11171 // Resets and releases all previously captured live object lists. | 11686 // Resets and releases all previously captured live object lists. |
| 11172 static MaybeObject* Runtime_ResetLOL(Arguments args) { | 11687 static MaybeObject* Runtime_ResetLOL(RUNTIME_CALLING_CONVENTION) { |
| 11688 RUNTIME_GET_ISOLATE; |
| 11173 #ifdef LIVE_OBJECT_LIST | 11689 #ifdef LIVE_OBJECT_LIST |
| 11174 LiveObjectList::Reset(); | 11690 LiveObjectList::Reset(); |
| 11175 return Heap::undefined_value(); | 11691 return isolate->heap()->undefined_value(); |
| 11176 #else | 11692 #else |
| 11177 return Heap::undefined_value(); | 11693 return isolate->heap()->undefined_value(); |
| 11178 #endif | 11694 #endif |
| 11179 } | 11695 } |
| 11180 | 11696 |
| 11181 | 11697 |
| 11182 // Generates the response to a debugger request for a summary of the types | 11698 // Generates the response to a debugger request for a summary of the types |
| 11183 // of objects in the difference between the captured live object lists | 11699 // of objects in the difference between the captured live object lists |
| 11184 // specified by id1 and id2. | 11700 // specified by id1 and id2. |
| 11185 // If id1 is 0 (i.e. not a valid lol), then the whole of lol id2 will be | 11701 // If id1 is 0 (i.e. not a valid lol), then the whole of lol id2 will be |
| 11186 // summarized. | 11702 // summarized. |
| 11187 static MaybeObject* Runtime_SummarizeLOL(Arguments args) { | 11703 static MaybeObject* Runtime_SummarizeLOL(RUNTIME_CALLING_CONVENTION) { |
| 11704 RUNTIME_GET_ISOLATE; |
| 11188 #ifdef LIVE_OBJECT_LIST | 11705 #ifdef LIVE_OBJECT_LIST |
| 11189 HandleScope scope; | 11706 HandleScope scope; |
| 11190 CONVERT_SMI_CHECKED(id1, args[0]); | 11707 CONVERT_SMI_CHECKED(id1, args[0]); |
| 11191 CONVERT_SMI_CHECKED(id2, args[1]); | 11708 CONVERT_SMI_CHECKED(id2, args[1]); |
| 11192 CONVERT_ARG_CHECKED(JSObject, filter_obj, 2); | 11709 CONVERT_ARG_CHECKED(JSObject, filter_obj, 2); |
| 11193 | 11710 |
| 11194 EnterDebugger enter_debugger; | 11711 EnterDebugger enter_debugger; |
| 11195 return LiveObjectList::Summarize(id1, id2, filter_obj); | 11712 return LiveObjectList::Summarize(id1, id2, filter_obj); |
| 11196 #else | 11713 #else |
| 11197 return Heap::undefined_value(); | 11714 return isolate->heap()->undefined_value(); |
| 11198 #endif | 11715 #endif |
| 11199 } | 11716 } |
| 11200 | 11717 |
| 11201 #endif // ENABLE_DEBUGGER_SUPPORT | 11718 #endif // ENABLE_DEBUGGER_SUPPORT |
| 11202 | 11719 |
| 11203 | 11720 |
| 11204 #ifdef ENABLE_LOGGING_AND_PROFILING | 11721 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 11205 static MaybeObject* Runtime_ProfilerResume(Arguments args) { | 11722 static MaybeObject* Runtime_ProfilerResume(RUNTIME_CALLING_CONVENTION) { |
| 11723 RUNTIME_GET_ISOLATE; |
| 11206 NoHandleAllocation ha; | 11724 NoHandleAllocation ha; |
| 11207 ASSERT(args.length() == 2); | 11725 ASSERT(args.length() == 2); |
| 11208 | 11726 |
| 11209 CONVERT_CHECKED(Smi, smi_modules, args[0]); | 11727 CONVERT_CHECKED(Smi, smi_modules, args[0]); |
| 11210 CONVERT_CHECKED(Smi, smi_tag, args[1]); | 11728 CONVERT_CHECKED(Smi, smi_tag, args[1]); |
| 11211 v8::V8::ResumeProfilerEx(smi_modules->value(), smi_tag->value()); | 11729 v8::V8::ResumeProfilerEx(smi_modules->value(), smi_tag->value()); |
| 11212 return Heap::undefined_value(); | 11730 return isolate->heap()->undefined_value(); |
| 11213 } | 11731 } |
| 11214 | 11732 |
| 11215 | 11733 |
| 11216 static MaybeObject* Runtime_ProfilerPause(Arguments args) { | 11734 static MaybeObject* Runtime_ProfilerPause(RUNTIME_CALLING_CONVENTION) { |
| 11735 RUNTIME_GET_ISOLATE; |
| 11217 NoHandleAllocation ha; | 11736 NoHandleAllocation ha; |
| 11218 ASSERT(args.length() == 2); | 11737 ASSERT(args.length() == 2); |
| 11219 | 11738 |
| 11220 CONVERT_CHECKED(Smi, smi_modules, args[0]); | 11739 CONVERT_CHECKED(Smi, smi_modules, args[0]); |
| 11221 CONVERT_CHECKED(Smi, smi_tag, args[1]); | 11740 CONVERT_CHECKED(Smi, smi_tag, args[1]); |
| 11222 v8::V8::PauseProfilerEx(smi_modules->value(), smi_tag->value()); | 11741 v8::V8::PauseProfilerEx(smi_modules->value(), smi_tag->value()); |
| 11223 return Heap::undefined_value(); | 11742 return isolate->heap()->undefined_value(); |
| 11224 } | 11743 } |
| 11225 | 11744 |
| 11226 #endif // ENABLE_LOGGING_AND_PROFILING | 11745 #endif // ENABLE_LOGGING_AND_PROFILING |
| 11227 | 11746 |
| 11228 // Finds the script object from the script data. NOTE: This operation uses | 11747 // Finds the script object from the script data. NOTE: This operation uses |
| 11229 // heap traversal to find the function generated for the source position | 11748 // heap traversal to find the function generated for the source position |
| 11230 // for the requested break point. For lazily compiled functions several heap | 11749 // for the requested break point. For lazily compiled functions several heap |
| 11231 // traversals might be required rendering this operation as a rather slow | 11750 // traversals might be required rendering this operation as a rather slow |
| 11232 // operation. However for setting break points which is normally done through | 11751 // operation. However for setting break points which is normally done through |
| 11233 // some kind of user interaction the performance is not crucial. | 11752 // some kind of user interaction the performance is not crucial. |
| 11234 static Handle<Object> Runtime_GetScriptFromScriptName( | 11753 static Handle<Object> Runtime_GetScriptFromScriptName( |
| 11235 Handle<String> script_name) { | 11754 Handle<String> script_name) { |
| 11236 // Scan the heap for Script objects to find the script with the requested | 11755 // Scan the heap for Script objects to find the script with the requested |
| 11237 // script data. | 11756 // script data. |
| 11238 Handle<Script> script; | 11757 Handle<Script> script; |
| 11239 HeapIterator iterator; | 11758 HeapIterator iterator; |
| 11240 HeapObject* obj = NULL; | 11759 HeapObject* obj = NULL; |
| 11241 while (script.is_null() && ((obj = iterator.next()) != NULL)) { | 11760 while (script.is_null() && ((obj = iterator.next()) != NULL)) { |
| 11242 // If a script is found check if it has the script data requested. | 11761 // If a script is found check if it has the script data requested. |
| 11243 if (obj->IsScript()) { | 11762 if (obj->IsScript()) { |
| 11244 if (Script::cast(obj)->name()->IsString()) { | 11763 if (Script::cast(obj)->name()->IsString()) { |
| 11245 if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) { | 11764 if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) { |
| 11246 script = Handle<Script>(Script::cast(obj)); | 11765 script = Handle<Script>(Script::cast(obj)); |
| 11247 } | 11766 } |
| 11248 } | 11767 } |
| 11249 } | 11768 } |
| 11250 } | 11769 } |
| 11251 | 11770 |
| 11252 // If no script with the requested script data is found return undefined. | 11771 // If no script with the requested script data is found return undefined. |
| 11253 if (script.is_null()) return Factory::undefined_value(); | 11772 if (script.is_null()) return FACTORY->undefined_value(); |
| 11254 | 11773 |
| 11255 // Return the script found. | 11774 // Return the script found. |
| 11256 return GetScriptWrapper(script); | 11775 return GetScriptWrapper(script); |
| 11257 } | 11776 } |
| 11258 | 11777 |
| 11259 | 11778 |
| 11260 // Get the script object from script data. NOTE: Regarding performance | 11779 // Get the script object from script data. NOTE: Regarding performance |
| 11261 // see the NOTE for GetScriptFromScriptData. | 11780 // see the NOTE for GetScriptFromScriptData. |
| 11262 // args[0]: script data for the script to find the source for | 11781 // args[0]: script data for the script to find the source for |
| 11263 static MaybeObject* Runtime_GetScript(Arguments args) { | 11782 static MaybeObject* Runtime_GetScript(RUNTIME_CALLING_CONVENTION) { |
| 11264 HandleScope scope; | 11783 RUNTIME_GET_ISOLATE; |
| 11784 HandleScope scope(isolate); |
| 11265 | 11785 |
| 11266 ASSERT(args.length() == 1); | 11786 ASSERT(args.length() == 1); |
| 11267 | 11787 |
| 11268 CONVERT_CHECKED(String, script_name, args[0]); | 11788 CONVERT_CHECKED(String, script_name, args[0]); |
| 11269 | 11789 |
| 11270 // Find the requested script. | 11790 // Find the requested script. |
| 11271 Handle<Object> result = | 11791 Handle<Object> result = |
| 11272 Runtime_GetScriptFromScriptName(Handle<String>(script_name)); | 11792 Runtime_GetScriptFromScriptName(Handle<String>(script_name)); |
| 11273 return *result; | 11793 return *result; |
| 11274 } | 11794 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 11298 // obvious builtin calls. Some builtin calls (such as Number.ADD | 11818 // obvious builtin calls. Some builtin calls (such as Number.ADD |
| 11299 // which is invoked using 'call') are very difficult to recognize | 11819 // which is invoked using 'call') are very difficult to recognize |
| 11300 // so we're leaving them in for now. | 11820 // so we're leaving them in for now. |
| 11301 return *seen_caller && !frame->receiver()->IsJSBuiltinsObject(); | 11821 return *seen_caller && !frame->receiver()->IsJSBuiltinsObject(); |
| 11302 } | 11822 } |
| 11303 | 11823 |
| 11304 | 11824 |
| 11305 // Collect the raw data for a stack trace. Returns an array of 4 | 11825 // Collect the raw data for a stack trace. Returns an array of 4 |
| 11306 // element segments each containing a receiver, function, code and | 11826 // element segments each containing a receiver, function, code and |
| 11307 // native code offset. | 11827 // native code offset. |
| 11308 static MaybeObject* Runtime_CollectStackTrace(Arguments args) { | 11828 static MaybeObject* Runtime_CollectStackTrace(RUNTIME_CALLING_CONVENTION) { |
| 11829 RUNTIME_GET_ISOLATE; |
| 11309 ASSERT_EQ(args.length(), 2); | 11830 ASSERT_EQ(args.length(), 2); |
| 11310 Handle<Object> caller = args.at<Object>(0); | 11831 Handle<Object> caller = args.at<Object>(0); |
| 11311 CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[1]); | 11832 CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[1]); |
| 11312 | 11833 |
| 11313 HandleScope scope; | 11834 HandleScope scope(isolate); |
| 11835 Factory* factory = isolate->factory(); |
| 11314 | 11836 |
| 11315 limit = Max(limit, 0); // Ensure that limit is not negative. | 11837 limit = Max(limit, 0); // Ensure that limit is not negative. |
| 11316 int initial_size = Min(limit, 10); | 11838 int initial_size = Min(limit, 10); |
| 11317 Handle<FixedArray> elements = | 11839 Handle<FixedArray> elements = |
| 11318 Factory::NewFixedArrayWithHoles(initial_size * 4); | 11840 factory->NewFixedArrayWithHoles(initial_size * 4); |
| 11319 | 11841 |
| 11320 StackFrameIterator iter; | 11842 StackFrameIterator iter; |
| 11321 // If the caller parameter is a function we skip frames until we're | 11843 // If the caller parameter is a function we skip frames until we're |
| 11322 // under it before starting to collect. | 11844 // under it before starting to collect. |
| 11323 bool seen_caller = !caller->IsJSFunction(); | 11845 bool seen_caller = !caller->IsJSFunction(); |
| 11324 int cursor = 0; | 11846 int cursor = 0; |
| 11325 int frames_seen = 0; | 11847 int frames_seen = 0; |
| 11326 while (!iter.done() && frames_seen < limit) { | 11848 while (!iter.done() && frames_seen < limit) { |
| 11327 StackFrame* raw_frame = iter.frame(); | 11849 StackFrame* raw_frame = iter.frame(); |
| 11328 if (ShowFrameInStackTrace(raw_frame, *caller, &seen_caller)) { | 11850 if (ShowFrameInStackTrace(raw_frame, *caller, &seen_caller)) { |
| 11329 frames_seen++; | 11851 frames_seen++; |
| 11330 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame); | 11852 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame); |
| 11331 List<FrameSummary> frames(3); // Max 2 levels of inlining. | 11853 List<FrameSummary> frames(3); // Max 2 levels of inlining. |
| 11332 frame->Summarize(&frames); | 11854 frame->Summarize(&frames); |
| 11333 for (int i = frames.length() - 1; i >= 0; i--) { | 11855 for (int i = frames.length() - 1; i >= 0; i--) { |
| 11334 if (cursor + 4 > elements->length()) { | 11856 if (cursor + 4 > elements->length()) { |
| 11335 int new_capacity = JSObject::NewElementsCapacity(elements->length()); | 11857 int new_capacity = JSObject::NewElementsCapacity(elements->length()); |
| 11336 Handle<FixedArray> new_elements = | 11858 Handle<FixedArray> new_elements = |
| 11337 Factory::NewFixedArrayWithHoles(new_capacity); | 11859 factory->NewFixedArrayWithHoles(new_capacity); |
| 11338 for (int i = 0; i < cursor; i++) { | 11860 for (int i = 0; i < cursor; i++) { |
| 11339 new_elements->set(i, elements->get(i)); | 11861 new_elements->set(i, elements->get(i)); |
| 11340 } | 11862 } |
| 11341 elements = new_elements; | 11863 elements = new_elements; |
| 11342 } | 11864 } |
| 11343 ASSERT(cursor + 4 <= elements->length()); | 11865 ASSERT(cursor + 4 <= elements->length()); |
| 11344 | 11866 |
| 11345 Handle<Object> recv = frames[i].receiver(); | 11867 Handle<Object> recv = frames[i].receiver(); |
| 11346 Handle<JSFunction> fun = frames[i].function(); | 11868 Handle<JSFunction> fun = frames[i].function(); |
| 11347 Handle<Code> code = frames[i].code(); | 11869 Handle<Code> code = frames[i].code(); |
| 11348 Handle<Smi> offset(Smi::FromInt(frames[i].offset())); | 11870 Handle<Smi> offset(Smi::FromInt(frames[i].offset())); |
| 11349 elements->set(cursor++, *recv); | 11871 elements->set(cursor++, *recv); |
| 11350 elements->set(cursor++, *fun); | 11872 elements->set(cursor++, *fun); |
| 11351 elements->set(cursor++, *code); | 11873 elements->set(cursor++, *code); |
| 11352 elements->set(cursor++, *offset); | 11874 elements->set(cursor++, *offset); |
| 11353 } | 11875 } |
| 11354 } | 11876 } |
| 11355 iter.Advance(); | 11877 iter.Advance(); |
| 11356 } | 11878 } |
| 11357 Handle<JSArray> result = Factory::NewJSArrayWithElements(elements); | 11879 Handle<JSArray> result = factory->NewJSArrayWithElements(elements); |
| 11358 result->set_length(Smi::FromInt(cursor)); | 11880 result->set_length(Smi::FromInt(cursor)); |
| 11359 return *result; | 11881 return *result; |
| 11360 } | 11882 } |
| 11361 | 11883 |
| 11362 | 11884 |
| 11363 // Returns V8 version as a string. | 11885 // Returns V8 version as a string. |
| 11364 static MaybeObject* Runtime_GetV8Version(Arguments args) { | 11886 static MaybeObject* Runtime_GetV8Version(RUNTIME_CALLING_CONVENTION) { |
| 11887 RUNTIME_GET_ISOLATE; |
| 11365 ASSERT_EQ(args.length(), 0); | 11888 ASSERT_EQ(args.length(), 0); |
| 11366 | 11889 |
| 11367 NoHandleAllocation ha; | 11890 NoHandleAllocation ha; |
| 11368 | 11891 |
| 11369 const char* version_string = v8::V8::GetVersion(); | 11892 const char* version_string = v8::V8::GetVersion(); |
| 11370 | 11893 |
| 11371 return Heap::AllocateStringFromAscii(CStrVector(version_string), NOT_TENURED); | 11894 return isolate->heap()->AllocateStringFromAscii(CStrVector(version_string), |
| 11895 NOT_TENURED); |
| 11372 } | 11896 } |
| 11373 | 11897 |
| 11374 | 11898 |
| 11375 static MaybeObject* Runtime_Abort(Arguments args) { | 11899 static MaybeObject* Runtime_Abort(RUNTIME_CALLING_CONVENTION) { |
| 11900 RUNTIME_GET_ISOLATE; |
| 11376 ASSERT(args.length() == 2); | 11901 ASSERT(args.length() == 2); |
| 11377 OS::PrintError("abort: %s\n", reinterpret_cast<char*>(args[0]) + | 11902 OS::PrintError("abort: %s\n", reinterpret_cast<char*>(args[0]) + |
| 11378 Smi::cast(args[1])->value()); | 11903 Smi::cast(args[1])->value()); |
| 11379 Top::PrintStack(); | 11904 isolate->PrintStack(); |
| 11380 OS::Abort(); | 11905 OS::Abort(); |
| 11381 UNREACHABLE(); | 11906 UNREACHABLE(); |
| 11382 return NULL; | 11907 return NULL; |
| 11383 } | 11908 } |
| 11384 | 11909 |
| 11385 | 11910 |
| 11386 static MaybeObject* Runtime_GetFromCache(Arguments args) { | 11911 static MaybeObject* Runtime_GetFromCache(RUNTIME_CALLING_CONVENTION) { |
| 11912 RUNTIME_GET_ISOLATE; |
| 11387 // This is only called from codegen, so checks might be more lax. | 11913 // This is only called from codegen, so checks might be more lax. |
| 11388 CONVERT_CHECKED(JSFunctionResultCache, cache, args[0]); | 11914 CONVERT_CHECKED(JSFunctionResultCache, cache, args[0]); |
| 11389 Object* key = args[1]; | 11915 Object* key = args[1]; |
| 11390 | 11916 |
| 11391 int finger_index = cache->finger_index(); | 11917 int finger_index = cache->finger_index(); |
| 11392 Object* o = cache->get(finger_index); | 11918 Object* o = cache->get(finger_index); |
| 11393 if (o == key) { | 11919 if (o == key) { |
| 11394 // The fastest case: hit the same place again. | 11920 // The fastest case: hit the same place again. |
| 11395 return cache->get(finger_index + 1); | 11921 return cache->get(finger_index + 1); |
| 11396 } | 11922 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 11410 | 11936 |
| 11411 for (int i = size - 2; i > finger_index; i -= 2) { | 11937 for (int i = size - 2; i > finger_index; i -= 2) { |
| 11412 o = cache->get(i); | 11938 o = cache->get(i); |
| 11413 if (o == key) { | 11939 if (o == key) { |
| 11414 cache->set_finger_index(i); | 11940 cache->set_finger_index(i); |
| 11415 return cache->get(i + 1); | 11941 return cache->get(i + 1); |
| 11416 } | 11942 } |
| 11417 } | 11943 } |
| 11418 | 11944 |
| 11419 // There is no value in the cache. Invoke the function and cache result. | 11945 // There is no value in the cache. Invoke the function and cache result. |
| 11420 HandleScope scope; | 11946 HandleScope scope(isolate); |
| 11421 | 11947 |
| 11422 Handle<JSFunctionResultCache> cache_handle(cache); | 11948 Handle<JSFunctionResultCache> cache_handle(cache); |
| 11423 Handle<Object> key_handle(key); | 11949 Handle<Object> key_handle(key); |
| 11424 Handle<Object> value; | 11950 Handle<Object> value; |
| 11425 { | 11951 { |
| 11426 Handle<JSFunction> factory(JSFunction::cast( | 11952 Handle<JSFunction> factory(JSFunction::cast( |
| 11427 cache_handle->get(JSFunctionResultCache::kFactoryIndex))); | 11953 cache_handle->get(JSFunctionResultCache::kFactoryIndex))); |
| 11428 // TODO(antonm): consider passing a receiver when constructing a cache. | 11954 // TODO(antonm): consider passing a receiver when constructing a cache. |
| 11429 Handle<Object> receiver(Top::global_context()->global()); | 11955 Handle<Object> receiver(isolate->global_context()->global()); |
| 11430 // This handle is nor shared, nor used later, so it's safe. | 11956 // This handle is nor shared, nor used later, so it's safe. |
| 11431 Object** argv[] = { key_handle.location() }; | 11957 Object** argv[] = { key_handle.location() }; |
| 11432 bool pending_exception = false; | 11958 bool pending_exception = false; |
| 11433 value = Execution::Call(factory, | 11959 value = Execution::Call(factory, |
| 11434 receiver, | 11960 receiver, |
| 11435 1, | 11961 1, |
| 11436 argv, | 11962 argv, |
| 11437 &pending_exception); | 11963 &pending_exception); |
| 11438 if (pending_exception) return Failure::Exception(); | 11964 if (pending_exception) return Failure::Exception(); |
| 11439 } | 11965 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 11468 cache_handle->set_finger_index(index); | 11994 cache_handle->set_finger_index(index); |
| 11469 | 11995 |
| 11470 #ifdef DEBUG | 11996 #ifdef DEBUG |
| 11471 cache_handle->JSFunctionResultCacheVerify(); | 11997 cache_handle->JSFunctionResultCacheVerify(); |
| 11472 #endif | 11998 #endif |
| 11473 | 11999 |
| 11474 return *value; | 12000 return *value; |
| 11475 } | 12001 } |
| 11476 | 12002 |
| 11477 | 12003 |
| 11478 static MaybeObject* Runtime_NewMessageObject(Arguments args) { | 12004 static MaybeObject* Runtime_NewMessageObject(RUNTIME_CALLING_CONVENTION) { |
| 11479 HandleScope scope; | 12005 RUNTIME_GET_ISOLATE; |
| 12006 HandleScope scope(isolate); |
| 11480 CONVERT_ARG_CHECKED(String, type, 0); | 12007 CONVERT_ARG_CHECKED(String, type, 0); |
| 11481 CONVERT_ARG_CHECKED(JSArray, arguments, 1); | 12008 CONVERT_ARG_CHECKED(JSArray, arguments, 1); |
| 11482 return *Factory::NewJSMessageObject(type, | 12009 return *isolate->factory()->NewJSMessageObject( |
| 11483 arguments, | 12010 type, |
| 11484 0, | 12011 arguments, |
| 11485 0, | 12012 0, |
| 11486 Factory::undefined_value(), | 12013 0, |
| 11487 Factory::undefined_value(), | 12014 isolate->factory()->undefined_value(), |
| 11488 Factory::undefined_value()); | 12015 isolate->factory()->undefined_value(), |
| 12016 isolate->factory()->undefined_value()); |
| 11489 } | 12017 } |
| 11490 | 12018 |
| 11491 | 12019 |
| 11492 static MaybeObject* Runtime_MessageGetType(Arguments args) { | 12020 static MaybeObject* Runtime_MessageGetType(RUNTIME_CALLING_CONVENTION) { |
| 12021 RUNTIME_GET_ISOLATE; |
| 11493 CONVERT_CHECKED(JSMessageObject, message, args[0]); | 12022 CONVERT_CHECKED(JSMessageObject, message, args[0]); |
| 11494 return message->type(); | 12023 return message->type(); |
| 11495 } | 12024 } |
| 11496 | 12025 |
| 11497 | 12026 |
| 11498 static MaybeObject* Runtime_MessageGetArguments(Arguments args) { | 12027 static MaybeObject* Runtime_MessageGetArguments(RUNTIME_CALLING_CONVENTION) { |
| 12028 RUNTIME_GET_ISOLATE; |
| 11499 CONVERT_CHECKED(JSMessageObject, message, args[0]); | 12029 CONVERT_CHECKED(JSMessageObject, message, args[0]); |
| 11500 return message->arguments(); | 12030 return message->arguments(); |
| 11501 } | 12031 } |
| 11502 | 12032 |
| 11503 | 12033 |
| 11504 static MaybeObject* Runtime_MessageGetStartPosition(Arguments args) { | 12034 static MaybeObject* Runtime_MessageGetStartPosition( |
| 12035 RUNTIME_CALLING_CONVENTION) { |
| 12036 RUNTIME_GET_ISOLATE; |
| 11505 CONVERT_CHECKED(JSMessageObject, message, args[0]); | 12037 CONVERT_CHECKED(JSMessageObject, message, args[0]); |
| 11506 return Smi::FromInt(message->start_position()); | 12038 return Smi::FromInt(message->start_position()); |
| 11507 } | 12039 } |
| 11508 | 12040 |
| 11509 | 12041 |
| 11510 static MaybeObject* Runtime_MessageGetScript(Arguments args) { | 12042 static MaybeObject* Runtime_MessageGetScript(RUNTIME_CALLING_CONVENTION) { |
| 12043 RUNTIME_GET_ISOLATE; |
| 11511 CONVERT_CHECKED(JSMessageObject, message, args[0]); | 12044 CONVERT_CHECKED(JSMessageObject, message, args[0]); |
| 11512 return message->script(); | 12045 return message->script(); |
| 11513 } | 12046 } |
| 11514 | 12047 |
| 11515 | 12048 |
| 11516 #ifdef DEBUG | 12049 #ifdef DEBUG |
| 11517 // ListNatives is ONLY used by the fuzz-natives.js in debug mode | 12050 // ListNatives is ONLY used by the fuzz-natives.js in debug mode |
| 11518 // Exclude the code in release mode. | 12051 // Exclude the code in release mode. |
| 11519 static MaybeObject* Runtime_ListNatives(Arguments args) { | 12052 static MaybeObject* Runtime_ListNatives(RUNTIME_CALLING_CONVENTION) { |
| 12053 RUNTIME_GET_ISOLATE; |
| 11520 ASSERT(args.length() == 0); | 12054 ASSERT(args.length() == 0); |
| 11521 HandleScope scope; | 12055 HandleScope scope; |
| 11522 #define COUNT_ENTRY(Name, argc, ressize) + 1 | 12056 #define COUNT_ENTRY(Name, argc, ressize) + 1 |
| 11523 int entry_count = 0 | 12057 int entry_count = 0 |
| 11524 RUNTIME_FUNCTION_LIST(COUNT_ENTRY) | 12058 RUNTIME_FUNCTION_LIST(COUNT_ENTRY) |
| 11525 INLINE_FUNCTION_LIST(COUNT_ENTRY) | 12059 INLINE_FUNCTION_LIST(COUNT_ENTRY) |
| 11526 INLINE_RUNTIME_FUNCTION_LIST(COUNT_ENTRY); | 12060 INLINE_RUNTIME_FUNCTION_LIST(COUNT_ENTRY); |
| 11527 #undef COUNT_ENTRY | 12061 #undef COUNT_ENTRY |
| 11528 Handle<FixedArray> elements = Factory::NewFixedArray(entry_count); | 12062 Factory* factory = isolate->factory(); |
| 12063 Handle<FixedArray> elements = factory->NewFixedArray(entry_count); |
| 11529 int index = 0; | 12064 int index = 0; |
| 11530 bool inline_runtime_functions = false; | 12065 bool inline_runtime_functions = false; |
| 11531 #define ADD_ENTRY(Name, argc, ressize) \ | 12066 #define ADD_ENTRY(Name, argc, ressize) \ |
| 11532 { \ | 12067 { \ |
| 11533 HandleScope inner; \ | 12068 HandleScope inner; \ |
| 11534 Handle<String> name; \ | 12069 Handle<String> name; \ |
| 11535 /* Inline runtime functions have an underscore in front of the name. */ \ | 12070 /* Inline runtime functions have an underscore in front of the name. */ \ |
| 11536 if (inline_runtime_functions) { \ | 12071 if (inline_runtime_functions) { \ |
| 11537 name = Factory::NewStringFromAscii( \ | 12072 name = factory->NewStringFromAscii( \ |
| 11538 Vector<const char>("_" #Name, StrLength("_" #Name))); \ | 12073 Vector<const char>("_" #Name, StrLength("_" #Name))); \ |
| 11539 } else { \ | 12074 } else { \ |
| 11540 name = Factory::NewStringFromAscii( \ | 12075 name = factory->NewStringFromAscii( \ |
| 11541 Vector<const char>(#Name, StrLength(#Name))); \ | 12076 Vector<const char>(#Name, StrLength(#Name))); \ |
| 11542 } \ | 12077 } \ |
| 11543 Handle<FixedArray> pair_elements = Factory::NewFixedArray(2); \ | 12078 Handle<FixedArray> pair_elements = factory->NewFixedArray(2); \ |
| 11544 pair_elements->set(0, *name); \ | 12079 pair_elements->set(0, *name); \ |
| 11545 pair_elements->set(1, Smi::FromInt(argc)); \ | 12080 pair_elements->set(1, Smi::FromInt(argc)); \ |
| 11546 Handle<JSArray> pair = Factory::NewJSArrayWithElements(pair_elements); \ | 12081 Handle<JSArray> pair = factory->NewJSArrayWithElements(pair_elements); \ |
| 11547 elements->set(index++, *pair); \ | 12082 elements->set(index++, *pair); \ |
| 11548 } | 12083 } |
| 11549 inline_runtime_functions = false; | 12084 inline_runtime_functions = false; |
| 11550 RUNTIME_FUNCTION_LIST(ADD_ENTRY) | 12085 RUNTIME_FUNCTION_LIST(ADD_ENTRY) |
| 11551 inline_runtime_functions = true; | 12086 inline_runtime_functions = true; |
| 11552 INLINE_FUNCTION_LIST(ADD_ENTRY) | 12087 INLINE_FUNCTION_LIST(ADD_ENTRY) |
| 11553 INLINE_RUNTIME_FUNCTION_LIST(ADD_ENTRY) | 12088 INLINE_RUNTIME_FUNCTION_LIST(ADD_ENTRY) |
| 11554 #undef ADD_ENTRY | 12089 #undef ADD_ENTRY |
| 11555 ASSERT_EQ(index, entry_count); | 12090 ASSERT_EQ(index, entry_count); |
| 11556 Handle<JSArray> result = Factory::NewJSArrayWithElements(elements); | 12091 Handle<JSArray> result = factory->NewJSArrayWithElements(elements); |
| 11557 return *result; | 12092 return *result; |
| 11558 } | 12093 } |
| 11559 #endif | 12094 #endif |
| 11560 | 12095 |
| 11561 | 12096 |
| 11562 static MaybeObject* Runtime_Log(Arguments args) { | 12097 static MaybeObject* Runtime_Log(RUNTIME_CALLING_CONVENTION) { |
| 12098 RUNTIME_GET_ISOLATE; |
| 11563 ASSERT(args.length() == 2); | 12099 ASSERT(args.length() == 2); |
| 11564 CONVERT_CHECKED(String, format, args[0]); | 12100 CONVERT_CHECKED(String, format, args[0]); |
| 11565 CONVERT_CHECKED(JSArray, elms, args[1]); | 12101 CONVERT_CHECKED(JSArray, elms, args[1]); |
| 11566 Vector<const char> chars = format->ToAsciiVector(); | 12102 Vector<const char> chars = format->ToAsciiVector(); |
| 11567 Logger::LogRuntime(chars, elms); | 12103 LOGGER->LogRuntime(chars, elms); |
| 11568 return Heap::undefined_value(); | 12104 return isolate->heap()->undefined_value(); |
| 11569 } | 12105 } |
| 11570 | 12106 |
| 11571 | 12107 |
| 11572 static MaybeObject* Runtime_IS_VAR(Arguments args) { | 12108 static MaybeObject* Runtime_IS_VAR(RUNTIME_CALLING_CONVENTION) { |
| 11573 UNREACHABLE(); // implemented as macro in the parser | 12109 UNREACHABLE(); // implemented as macro in the parser |
| 11574 return NULL; | 12110 return NULL; |
| 11575 } | 12111 } |
| 11576 | 12112 |
| 11577 | 12113 |
| 11578 // ---------------------------------------------------------------------------- | 12114 // ---------------------------------------------------------------------------- |
| 11579 // Implementation of Runtime | 12115 // Implementation of Runtime |
| 11580 | 12116 |
| 11581 #define F(name, number_of_args, result_size) \ | 12117 #define F(name, number_of_args, result_size) \ |
| 11582 { Runtime::k##name, Runtime::RUNTIME, #name, \ | 12118 { Runtime::k##name, Runtime::RUNTIME, #name, \ |
| 11583 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size }, | 12119 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size }, |
| 11584 | 12120 |
| 11585 | 12121 |
| 11586 #define I(name, number_of_args, result_size) \ | 12122 #define I(name, number_of_args, result_size) \ |
| 11587 { Runtime::kInline##name, Runtime::INLINE, \ | 12123 { Runtime::kInline##name, Runtime::INLINE, \ |
| 11588 "_" #name, NULL, number_of_args, result_size }, | 12124 "_" #name, NULL, number_of_args, result_size }, |
| 11589 | 12125 |
| 11590 Runtime::Function kIntrinsicFunctions[] = { | 12126 static const Runtime::Function kIntrinsicFunctions[] = { |
| 11591 RUNTIME_FUNCTION_LIST(F) | 12127 RUNTIME_FUNCTION_LIST(F) |
| 11592 INLINE_FUNCTION_LIST(I) | 12128 INLINE_FUNCTION_LIST(I) |
| 11593 INLINE_RUNTIME_FUNCTION_LIST(I) | 12129 INLINE_RUNTIME_FUNCTION_LIST(I) |
| 11594 }; | 12130 }; |
| 11595 | 12131 |
| 11596 | 12132 |
| 11597 MaybeObject* Runtime::InitializeIntrinsicFunctionNames(Object* dictionary) { | 12133 MaybeObject* Runtime::InitializeIntrinsicFunctionNames(Heap* heap, |
| 12134 Object* dictionary) { |
| 12135 ASSERT(Isolate::Current()->heap() == heap); |
| 11598 ASSERT(dictionary != NULL); | 12136 ASSERT(dictionary != NULL); |
| 11599 ASSERT(StringDictionary::cast(dictionary)->NumberOfElements() == 0); | 12137 ASSERT(StringDictionary::cast(dictionary)->NumberOfElements() == 0); |
| 11600 for (int i = 0; i < kNumFunctions; ++i) { | 12138 for (int i = 0; i < kNumFunctions; ++i) { |
| 11601 Object* name_symbol; | 12139 Object* name_symbol; |
| 11602 { MaybeObject* maybe_name_symbol = | 12140 { MaybeObject* maybe_name_symbol = |
| 11603 Heap::LookupAsciiSymbol(kIntrinsicFunctions[i].name); | 12141 heap->LookupAsciiSymbol(kIntrinsicFunctions[i].name); |
| 11604 if (!maybe_name_symbol->ToObject(&name_symbol)) return maybe_name_symbol; | 12142 if (!maybe_name_symbol->ToObject(&name_symbol)) return maybe_name_symbol; |
| 11605 } | 12143 } |
| 11606 StringDictionary* string_dictionary = StringDictionary::cast(dictionary); | 12144 StringDictionary* string_dictionary = StringDictionary::cast(dictionary); |
| 11607 { MaybeObject* maybe_dictionary = string_dictionary->Add( | 12145 { MaybeObject* maybe_dictionary = string_dictionary->Add( |
| 11608 String::cast(name_symbol), | 12146 String::cast(name_symbol), |
| 11609 Smi::FromInt(i), | 12147 Smi::FromInt(i), |
| 11610 PropertyDetails(NONE, NORMAL)); | 12148 PropertyDetails(NONE, NORMAL)); |
| 11611 if (!maybe_dictionary->ToObject(&dictionary)) { | 12149 if (!maybe_dictionary->ToObject(&dictionary)) { |
| 11612 // Non-recoverable failure. Calling code must restart heap | 12150 // Non-recoverable failure. Calling code must restart heap |
| 11613 // initialization. | 12151 // initialization. |
| 11614 return maybe_dictionary; | 12152 return maybe_dictionary; |
| 11615 } | 12153 } |
| 11616 } | 12154 } |
| 11617 } | 12155 } |
| 11618 return dictionary; | 12156 return dictionary; |
| 11619 } | 12157 } |
| 11620 | 12158 |
| 11621 | 12159 |
| 11622 Runtime::Function* Runtime::FunctionForSymbol(Handle<String> name) { | 12160 const Runtime::Function* Runtime::FunctionForSymbol(Handle<String> name) { |
| 11623 int entry = Heap::intrinsic_function_names()->FindEntry(*name); | 12161 Heap* heap = name->GetHeap(); |
| 12162 int entry = heap->intrinsic_function_names()->FindEntry(*name); |
| 11624 if (entry != kNotFound) { | 12163 if (entry != kNotFound) { |
| 11625 Object* smi_index = Heap::intrinsic_function_names()->ValueAt(entry); | 12164 Object* smi_index = heap->intrinsic_function_names()->ValueAt(entry); |
| 11626 int function_index = Smi::cast(smi_index)->value(); | 12165 int function_index = Smi::cast(smi_index)->value(); |
| 11627 return &(kIntrinsicFunctions[function_index]); | 12166 return &(kIntrinsicFunctions[function_index]); |
| 11628 } | 12167 } |
| 11629 return NULL; | 12168 return NULL; |
| 11630 } | 12169 } |
| 11631 | 12170 |
| 11632 | 12171 |
| 11633 Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 12172 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
| 11634 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 12173 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
| 11635 } | 12174 } |
| 11636 | 12175 |
| 11637 | 12176 |
| 11638 void Runtime::PerformGC(Object* result) { | 12177 void Runtime::PerformGC(Object* result) { |
| 11639 Failure* failure = Failure::cast(result); | 12178 Failure* failure = Failure::cast(result); |
| 11640 if (failure->IsRetryAfterGC()) { | 12179 if (failure->IsRetryAfterGC()) { |
| 11641 // Try to do a garbage collection; ignore it if it fails. The C | 12180 // Try to do a garbage collection; ignore it if it fails. The C |
| 11642 // entry stub will throw an out-of-memory exception in that case. | 12181 // entry stub will throw an out-of-memory exception in that case. |
| 11643 Heap::CollectGarbage(failure->allocation_space()); | 12182 HEAP->CollectGarbage(failure->allocation_space()); |
| 11644 } else { | 12183 } else { |
| 11645 // Handle last resort GC and make sure to allow future allocations | 12184 // Handle last resort GC and make sure to allow future allocations |
| 11646 // to grow the heap without causing GCs (if possible). | 12185 // to grow the heap without causing GCs (if possible). |
| 11647 Counters::gc_last_resort_from_js.Increment(); | 12186 COUNTERS->gc_last_resort_from_js()->Increment(); |
| 11648 Heap::CollectAllGarbage(false); | 12187 HEAP->CollectAllGarbage(false); |
| 11649 } | 12188 } |
| 11650 } | 12189 } |
| 11651 | 12190 |
| 11652 | 12191 |
| 11653 } } // namespace v8::internal | 12192 } } // namespace v8::internal |
| OLD | NEW |