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 |