OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 // a variable of the specified type with the given name. If the | 92 // a variable of the specified type with the given name. If the |
93 // object is not a Number call IllegalOperation and return. | 93 // object is not a Number call IllegalOperation and return. |
94 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj) \ | 94 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj) \ |
95 RUNTIME_ASSERT(obj->IsNumber()); \ | 95 RUNTIME_ASSERT(obj->IsNumber()); \ |
96 type name = NumberTo##Type(obj); | 96 type name = NumberTo##Type(obj); |
97 | 97 |
98 // Non-reentrant string buffer for efficient general use in this file. | 98 // Non-reentrant string buffer for efficient general use in this file. |
99 static StaticResource<StringInputBuffer> runtime_string_input_buffer; | 99 static StaticResource<StringInputBuffer> runtime_string_input_buffer; |
100 | 100 |
101 | 101 |
102 MUST_USE_RESULT static Object* DeepCopyBoilerplate(JSObject* boilerplate) { | 102 MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(JSObject* boilerplate) { |
103 StackLimitCheck check; | 103 StackLimitCheck check; |
104 if (check.HasOverflowed()) return Top::StackOverflow(); | 104 if (check.HasOverflowed()) return Top::StackOverflow(); |
105 | 105 |
106 Object* result = Heap::CopyJSObject(boilerplate); | 106 Object* result; |
107 if (result->IsFailure()) return result; | 107 { MaybeObject* maybe_result = Heap::CopyJSObject(boilerplate); |
| 108 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 109 } |
108 JSObject* copy = JSObject::cast(result); | 110 JSObject* copy = JSObject::cast(result); |
109 | 111 |
110 // Deep copy local properties. | 112 // Deep copy local properties. |
111 if (copy->HasFastProperties()) { | 113 if (copy->HasFastProperties()) { |
112 FixedArray* properties = copy->properties(); | 114 FixedArray* properties = copy->properties(); |
113 for (int i = 0; i < properties->length(); i++) { | 115 for (int i = 0; i < properties->length(); i++) { |
114 Object* value = properties->get(i); | 116 Object* value = properties->get(i); |
115 if (value->IsJSObject()) { | 117 if (value->IsJSObject()) { |
116 JSObject* js_object = JSObject::cast(value); | 118 JSObject* js_object = JSObject::cast(value); |
117 result = DeepCopyBoilerplate(js_object); | 119 { MaybeObject* maybe_result = DeepCopyBoilerplate(js_object); |
118 if (result->IsFailure()) return result; | 120 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 121 } |
119 properties->set(i, result); | 122 properties->set(i, result); |
120 } | 123 } |
121 } | 124 } |
122 int nof = copy->map()->inobject_properties(); | 125 int nof = copy->map()->inobject_properties(); |
123 for (int i = 0; i < nof; i++) { | 126 for (int i = 0; i < nof; i++) { |
124 Object* value = copy->InObjectPropertyAt(i); | 127 Object* value = copy->InObjectPropertyAt(i); |
125 if (value->IsJSObject()) { | 128 if (value->IsJSObject()) { |
126 JSObject* js_object = JSObject::cast(value); | 129 JSObject* js_object = JSObject::cast(value); |
127 result = DeepCopyBoilerplate(js_object); | 130 { MaybeObject* maybe_result = DeepCopyBoilerplate(js_object); |
128 if (result->IsFailure()) return result; | 131 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 132 } |
129 copy->InObjectPropertyAtPut(i, result); | 133 copy->InObjectPropertyAtPut(i, result); |
130 } | 134 } |
131 } | 135 } |
132 } else { | 136 } else { |
133 result = Heap::AllocateFixedArray(copy->NumberOfLocalProperties(NONE)); | 137 { MaybeObject* maybe_result = |
134 if (result->IsFailure()) return result; | 138 Heap::AllocateFixedArray(copy->NumberOfLocalProperties(NONE)); |
| 139 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 140 } |
135 FixedArray* names = FixedArray::cast(result); | 141 FixedArray* names = FixedArray::cast(result); |
136 copy->GetLocalPropertyNames(names, 0); | 142 copy->GetLocalPropertyNames(names, 0); |
137 for (int i = 0; i < names->length(); i++) { | 143 for (int i = 0; i < names->length(); i++) { |
138 ASSERT(names->get(i)->IsString()); | 144 ASSERT(names->get(i)->IsString()); |
139 String* key_string = String::cast(names->get(i)); | 145 String* key_string = String::cast(names->get(i)); |
140 PropertyAttributes attributes = | 146 PropertyAttributes attributes = |
141 copy->GetLocalPropertyAttribute(key_string); | 147 copy->GetLocalPropertyAttribute(key_string); |
142 // Only deep copy fields from the object literal expression. | 148 // Only deep copy fields from the object literal expression. |
143 // In particular, don't try to copy the length attribute of | 149 // In particular, don't try to copy the length attribute of |
144 // an array. | 150 // an array. |
145 if (attributes != NONE) continue; | 151 if (attributes != NONE) continue; |
146 Object* value = copy->GetProperty(key_string, &attributes); | 152 Object* value = |
147 ASSERT(!value->IsFailure()); | 153 copy->GetProperty(key_string, &attributes)->ToObjectUnchecked(); |
148 if (value->IsJSObject()) { | 154 if (value->IsJSObject()) { |
149 JSObject* js_object = JSObject::cast(value); | 155 JSObject* js_object = JSObject::cast(value); |
150 result = DeepCopyBoilerplate(js_object); | 156 { MaybeObject* maybe_result = DeepCopyBoilerplate(js_object); |
151 if (result->IsFailure()) return result; | 157 if (!maybe_result->ToObject(&result)) return maybe_result; |
152 result = copy->SetProperty(key_string, result, NONE); | 158 } |
153 if (result->IsFailure()) return result; | 159 { MaybeObject* maybe_result = |
| 160 copy->SetProperty(key_string, result, NONE); |
| 161 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 162 } |
154 } | 163 } |
155 } | 164 } |
156 } | 165 } |
157 | 166 |
158 // Deep copy local elements. | 167 // Deep copy local elements. |
159 // Pixel elements cannot be created using an object literal. | 168 // Pixel elements cannot be created using an object literal. |
160 ASSERT(!copy->HasPixelElements() && !copy->HasExternalArrayElements()); | 169 ASSERT(!copy->HasPixelElements() && !copy->HasExternalArrayElements()); |
161 switch (copy->GetElementsKind()) { | 170 switch (copy->GetElementsKind()) { |
162 case JSObject::FAST_ELEMENTS: { | 171 case JSObject::FAST_ELEMENTS: { |
163 FixedArray* elements = FixedArray::cast(copy->elements()); | 172 FixedArray* elements = FixedArray::cast(copy->elements()); |
164 if (elements->map() == Heap::fixed_cow_array_map()) { | 173 if (elements->map() == Heap::fixed_cow_array_map()) { |
165 Counters::cow_arrays_created_runtime.Increment(); | 174 Counters::cow_arrays_created_runtime.Increment(); |
166 #ifdef DEBUG | 175 #ifdef DEBUG |
167 for (int i = 0; i < elements->length(); i++) { | 176 for (int i = 0; i < elements->length(); i++) { |
168 ASSERT(!elements->get(i)->IsJSObject()); | 177 ASSERT(!elements->get(i)->IsJSObject()); |
169 } | 178 } |
170 #endif | 179 #endif |
171 } else { | 180 } else { |
172 for (int i = 0; i < elements->length(); i++) { | 181 for (int i = 0; i < elements->length(); i++) { |
173 Object* value = elements->get(i); | 182 Object* value = elements->get(i); |
174 if (value->IsJSObject()) { | 183 if (value->IsJSObject()) { |
175 JSObject* js_object = JSObject::cast(value); | 184 JSObject* js_object = JSObject::cast(value); |
176 result = DeepCopyBoilerplate(js_object); | 185 { MaybeObject* maybe_result = DeepCopyBoilerplate(js_object); |
177 if (result->IsFailure()) return result; | 186 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 187 } |
178 elements->set(i, result); | 188 elements->set(i, result); |
179 } | 189 } |
180 } | 190 } |
181 } | 191 } |
182 break; | 192 break; |
183 } | 193 } |
184 case JSObject::DICTIONARY_ELEMENTS: { | 194 case JSObject::DICTIONARY_ELEMENTS: { |
185 NumberDictionary* element_dictionary = copy->element_dictionary(); | 195 NumberDictionary* element_dictionary = copy->element_dictionary(); |
186 int capacity = element_dictionary->Capacity(); | 196 int capacity = element_dictionary->Capacity(); |
187 for (int i = 0; i < capacity; i++) { | 197 for (int i = 0; i < capacity; i++) { |
188 Object* k = element_dictionary->KeyAt(i); | 198 Object* k = element_dictionary->KeyAt(i); |
189 if (element_dictionary->IsKey(k)) { | 199 if (element_dictionary->IsKey(k)) { |
190 Object* value = element_dictionary->ValueAt(i); | 200 Object* value = element_dictionary->ValueAt(i); |
191 if (value->IsJSObject()) { | 201 if (value->IsJSObject()) { |
192 JSObject* js_object = JSObject::cast(value); | 202 JSObject* js_object = JSObject::cast(value); |
193 result = DeepCopyBoilerplate(js_object); | 203 { MaybeObject* maybe_result = DeepCopyBoilerplate(js_object); |
194 if (result->IsFailure()) return result; | 204 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 205 } |
195 element_dictionary->ValueAtPut(i, result); | 206 element_dictionary->ValueAtPut(i, result); |
196 } | 207 } |
197 } | 208 } |
198 } | 209 } |
199 break; | 210 break; |
200 } | 211 } |
201 default: | 212 default: |
202 UNREACHABLE(); | 213 UNREACHABLE(); |
203 break; | 214 break; |
204 } | 215 } |
205 return copy; | 216 return copy; |
206 } | 217 } |
207 | 218 |
208 | 219 |
209 static Object* Runtime_CloneLiteralBoilerplate(Arguments args) { | 220 static MaybeObject* Runtime_CloneLiteralBoilerplate(Arguments args) { |
210 CONVERT_CHECKED(JSObject, boilerplate, args[0]); | 221 CONVERT_CHECKED(JSObject, boilerplate, args[0]); |
211 return DeepCopyBoilerplate(boilerplate); | 222 return DeepCopyBoilerplate(boilerplate); |
212 } | 223 } |
213 | 224 |
214 | 225 |
215 static Object* Runtime_CloneShallowLiteralBoilerplate(Arguments args) { | 226 static MaybeObject* Runtime_CloneShallowLiteralBoilerplate(Arguments args) { |
216 CONVERT_CHECKED(JSObject, boilerplate, args[0]); | 227 CONVERT_CHECKED(JSObject, boilerplate, args[0]); |
217 return Heap::CopyJSObject(boilerplate); | 228 return Heap::CopyJSObject(boilerplate); |
218 } | 229 } |
219 | 230 |
220 | 231 |
221 static Handle<Map> ComputeObjectLiteralMap( | 232 static Handle<Map> ComputeObjectLiteralMap( |
222 Handle<Context> context, | 233 Handle<Context> context, |
223 Handle<FixedArray> constant_properties, | 234 Handle<FixedArray> constant_properties, |
224 bool* is_result_from_cache) { | 235 bool* is_result_from_cache) { |
225 int properties_length = constant_properties->length(); | 236 int properties_length = constant_properties->length(); |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 return CreateObjectLiteralBoilerplate(literals, elements, false); | 407 return CreateObjectLiteralBoilerplate(literals, elements, false); |
397 case CompileTimeValue::ARRAY_LITERAL: | 408 case CompileTimeValue::ARRAY_LITERAL: |
398 return CreateArrayLiteralBoilerplate(literals, elements); | 409 return CreateArrayLiteralBoilerplate(literals, elements); |
399 default: | 410 default: |
400 UNREACHABLE(); | 411 UNREACHABLE(); |
401 return Handle<Object>::null(); | 412 return Handle<Object>::null(); |
402 } | 413 } |
403 } | 414 } |
404 | 415 |
405 | 416 |
406 static Object* Runtime_CreateArrayLiteralBoilerplate(Arguments args) { | 417 static MaybeObject* Runtime_CreateArrayLiteralBoilerplate(Arguments args) { |
407 // Takes a FixedArray of elements containing the literal elements of | 418 // Takes a FixedArray of elements containing the literal elements of |
408 // the array literal and produces JSArray with those elements. | 419 // the array literal and produces JSArray with those elements. |
409 // Additionally takes the literals array of the surrounding function | 420 // Additionally takes the literals array of the surrounding function |
410 // which contains the context from which to get the Array function | 421 // which contains the context from which to get the Array function |
411 // to use for creating the array literal. | 422 // to use for creating the array literal. |
412 HandleScope scope; | 423 HandleScope scope; |
413 ASSERT(args.length() == 3); | 424 ASSERT(args.length() == 3); |
414 CONVERT_ARG_CHECKED(FixedArray, literals, 0); | 425 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
415 CONVERT_SMI_CHECKED(literals_index, args[1]); | 426 CONVERT_SMI_CHECKED(literals_index, args[1]); |
416 CONVERT_ARG_CHECKED(FixedArray, elements, 2); | 427 CONVERT_ARG_CHECKED(FixedArray, elements, 2); |
417 | 428 |
418 Handle<Object> object = CreateArrayLiteralBoilerplate(literals, elements); | 429 Handle<Object> object = CreateArrayLiteralBoilerplate(literals, elements); |
419 if (object.is_null()) return Failure::Exception(); | 430 if (object.is_null()) return Failure::Exception(); |
420 | 431 |
421 // Update the functions literal and return the boilerplate. | 432 // Update the functions literal and return the boilerplate. |
422 literals->set(literals_index, *object); | 433 literals->set(literals_index, *object); |
423 return *object; | 434 return *object; |
424 } | 435 } |
425 | 436 |
426 | 437 |
427 static Object* Runtime_CreateObjectLiteral(Arguments args) { | 438 static MaybeObject* Runtime_CreateObjectLiteral(Arguments args) { |
428 HandleScope scope; | 439 HandleScope scope; |
429 ASSERT(args.length() == 4); | 440 ASSERT(args.length() == 4); |
430 CONVERT_ARG_CHECKED(FixedArray, literals, 0); | 441 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
431 CONVERT_SMI_CHECKED(literals_index, args[1]); | 442 CONVERT_SMI_CHECKED(literals_index, args[1]); |
432 CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2); | 443 CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2); |
433 CONVERT_SMI_CHECKED(fast_elements, args[3]); | 444 CONVERT_SMI_CHECKED(fast_elements, args[3]); |
434 bool should_have_fast_elements = fast_elements == 1; | 445 bool should_have_fast_elements = fast_elements == 1; |
435 | 446 |
436 // Check if boilerplate exists. If not, create it first. | 447 // Check if boilerplate exists. If not, create it first. |
437 Handle<Object> boilerplate(literals->get(literals_index)); | 448 Handle<Object> boilerplate(literals->get(literals_index)); |
438 if (*boilerplate == Heap::undefined_value()) { | 449 if (*boilerplate == Heap::undefined_value()) { |
439 boilerplate = CreateObjectLiteralBoilerplate(literals, | 450 boilerplate = CreateObjectLiteralBoilerplate(literals, |
440 constant_properties, | 451 constant_properties, |
441 should_have_fast_elements); | 452 should_have_fast_elements); |
442 if (boilerplate.is_null()) return Failure::Exception(); | 453 if (boilerplate.is_null()) return Failure::Exception(); |
443 // Update the functions literal and return the boilerplate. | 454 // Update the functions literal and return the boilerplate. |
444 literals->set(literals_index, *boilerplate); | 455 literals->set(literals_index, *boilerplate); |
445 } | 456 } |
446 return DeepCopyBoilerplate(JSObject::cast(*boilerplate)); | 457 return DeepCopyBoilerplate(JSObject::cast(*boilerplate)); |
447 } | 458 } |
448 | 459 |
449 | 460 |
450 static Object* Runtime_CreateObjectLiteralShallow(Arguments args) { | 461 static MaybeObject* Runtime_CreateObjectLiteralShallow(Arguments args) { |
451 HandleScope scope; | 462 HandleScope scope; |
452 ASSERT(args.length() == 4); | 463 ASSERT(args.length() == 4); |
453 CONVERT_ARG_CHECKED(FixedArray, literals, 0); | 464 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
454 CONVERT_SMI_CHECKED(literals_index, args[1]); | 465 CONVERT_SMI_CHECKED(literals_index, args[1]); |
455 CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2); | 466 CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2); |
456 CONVERT_SMI_CHECKED(fast_elements, args[3]); | 467 CONVERT_SMI_CHECKED(fast_elements, args[3]); |
457 bool should_have_fast_elements = fast_elements == 1; | 468 bool should_have_fast_elements = fast_elements == 1; |
458 | 469 |
459 // Check if boilerplate exists. If not, create it first. | 470 // Check if boilerplate exists. If not, create it first. |
460 Handle<Object> boilerplate(literals->get(literals_index)); | 471 Handle<Object> boilerplate(literals->get(literals_index)); |
461 if (*boilerplate == Heap::undefined_value()) { | 472 if (*boilerplate == Heap::undefined_value()) { |
462 boilerplate = CreateObjectLiteralBoilerplate(literals, | 473 boilerplate = CreateObjectLiteralBoilerplate(literals, |
463 constant_properties, | 474 constant_properties, |
464 should_have_fast_elements); | 475 should_have_fast_elements); |
465 if (boilerplate.is_null()) return Failure::Exception(); | 476 if (boilerplate.is_null()) return Failure::Exception(); |
466 // Update the functions literal and return the boilerplate. | 477 // Update the functions literal and return the boilerplate. |
467 literals->set(literals_index, *boilerplate); | 478 literals->set(literals_index, *boilerplate); |
468 } | 479 } |
469 return Heap::CopyJSObject(JSObject::cast(*boilerplate)); | 480 return Heap::CopyJSObject(JSObject::cast(*boilerplate)); |
470 } | 481 } |
471 | 482 |
472 | 483 |
473 static Object* Runtime_CreateArrayLiteral(Arguments args) { | 484 static MaybeObject* Runtime_CreateArrayLiteral(Arguments args) { |
474 HandleScope scope; | 485 HandleScope scope; |
475 ASSERT(args.length() == 3); | 486 ASSERT(args.length() == 3); |
476 CONVERT_ARG_CHECKED(FixedArray, literals, 0); | 487 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
477 CONVERT_SMI_CHECKED(literals_index, args[1]); | 488 CONVERT_SMI_CHECKED(literals_index, args[1]); |
478 CONVERT_ARG_CHECKED(FixedArray, elements, 2); | 489 CONVERT_ARG_CHECKED(FixedArray, elements, 2); |
479 | 490 |
480 // Check if boilerplate exists. If not, create it first. | 491 // Check if boilerplate exists. If not, create it first. |
481 Handle<Object> boilerplate(literals->get(literals_index)); | 492 Handle<Object> boilerplate(literals->get(literals_index)); |
482 if (*boilerplate == Heap::undefined_value()) { | 493 if (*boilerplate == Heap::undefined_value()) { |
483 boilerplate = CreateArrayLiteralBoilerplate(literals, elements); | 494 boilerplate = CreateArrayLiteralBoilerplate(literals, elements); |
484 if (boilerplate.is_null()) return Failure::Exception(); | 495 if (boilerplate.is_null()) return Failure::Exception(); |
485 // Update the functions literal and return the boilerplate. | 496 // Update the functions literal and return the boilerplate. |
486 literals->set(literals_index, *boilerplate); | 497 literals->set(literals_index, *boilerplate); |
487 } | 498 } |
488 return DeepCopyBoilerplate(JSObject::cast(*boilerplate)); | 499 return DeepCopyBoilerplate(JSObject::cast(*boilerplate)); |
489 } | 500 } |
490 | 501 |
491 | 502 |
492 static Object* Runtime_CreateArrayLiteralShallow(Arguments args) { | 503 static MaybeObject* Runtime_CreateArrayLiteralShallow(Arguments args) { |
493 HandleScope scope; | 504 HandleScope scope; |
494 ASSERT(args.length() == 3); | 505 ASSERT(args.length() == 3); |
495 CONVERT_ARG_CHECKED(FixedArray, literals, 0); | 506 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
496 CONVERT_SMI_CHECKED(literals_index, args[1]); | 507 CONVERT_SMI_CHECKED(literals_index, args[1]); |
497 CONVERT_ARG_CHECKED(FixedArray, elements, 2); | 508 CONVERT_ARG_CHECKED(FixedArray, elements, 2); |
498 | 509 |
499 // Check if boilerplate exists. If not, create it first. | 510 // Check if boilerplate exists. If not, create it first. |
500 Handle<Object> boilerplate(literals->get(literals_index)); | 511 Handle<Object> boilerplate(literals->get(literals_index)); |
501 if (*boilerplate == Heap::undefined_value()) { | 512 if (*boilerplate == Heap::undefined_value()) { |
502 boilerplate = CreateArrayLiteralBoilerplate(literals, elements); | 513 boilerplate = CreateArrayLiteralBoilerplate(literals, elements); |
503 if (boilerplate.is_null()) return Failure::Exception(); | 514 if (boilerplate.is_null()) return Failure::Exception(); |
504 // Update the functions literal and return the boilerplate. | 515 // Update the functions literal and return the boilerplate. |
505 literals->set(literals_index, *boilerplate); | 516 literals->set(literals_index, *boilerplate); |
506 } | 517 } |
507 if (JSObject::cast(*boilerplate)->elements()->map() == | 518 if (JSObject::cast(*boilerplate)->elements()->map() == |
508 Heap::fixed_cow_array_map()) { | 519 Heap::fixed_cow_array_map()) { |
509 Counters::cow_arrays_created_runtime.Increment(); | 520 Counters::cow_arrays_created_runtime.Increment(); |
510 } | 521 } |
511 return Heap::CopyJSObject(JSObject::cast(*boilerplate)); | 522 return Heap::CopyJSObject(JSObject::cast(*boilerplate)); |
512 } | 523 } |
513 | 524 |
514 | 525 |
515 static Object* Runtime_CreateCatchExtensionObject(Arguments args) { | 526 static MaybeObject* Runtime_CreateCatchExtensionObject(Arguments args) { |
516 ASSERT(args.length() == 2); | 527 ASSERT(args.length() == 2); |
517 CONVERT_CHECKED(String, key, args[0]); | 528 CONVERT_CHECKED(String, key, args[0]); |
518 Object* value = args[1]; | 529 Object* value = args[1]; |
519 // Create a catch context extension object. | 530 // Create a catch context extension object. |
520 JSFunction* constructor = | 531 JSFunction* constructor = |
521 Top::context()->global_context()->context_extension_function(); | 532 Top::context()->global_context()->context_extension_function(); |
522 Object* object = Heap::AllocateJSObject(constructor); | 533 Object* object; |
523 if (object->IsFailure()) return object; | 534 { MaybeObject* maybe_object = Heap::AllocateJSObject(constructor); |
| 535 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 536 } |
524 // Assign the exception value to the catch variable and make sure | 537 // Assign the exception value to the catch variable and make sure |
525 // that the catch variable is DontDelete. | 538 // that the catch variable is DontDelete. |
526 value = JSObject::cast(object)->SetProperty(key, value, DONT_DELETE); | 539 { MaybeObject* maybe_value = |
527 if (value->IsFailure()) return value; | 540 JSObject::cast(object)->SetProperty(key, value, DONT_DELETE); |
| 541 if (!maybe_value->ToObject(&value)) return maybe_value; |
| 542 } |
528 return object; | 543 return object; |
529 } | 544 } |
530 | 545 |
531 | 546 |
532 static Object* Runtime_ClassOf(Arguments args) { | 547 static MaybeObject* Runtime_ClassOf(Arguments args) { |
533 NoHandleAllocation ha; | 548 NoHandleAllocation ha; |
534 ASSERT(args.length() == 1); | 549 ASSERT(args.length() == 1); |
535 Object* obj = args[0]; | 550 Object* obj = args[0]; |
536 if (!obj->IsJSObject()) return Heap::null_value(); | 551 if (!obj->IsJSObject()) return Heap::null_value(); |
537 return JSObject::cast(obj)->class_name(); | 552 return JSObject::cast(obj)->class_name(); |
538 } | 553 } |
539 | 554 |
540 | 555 |
541 static Object* Runtime_IsInPrototypeChain(Arguments args) { | 556 static MaybeObject* Runtime_IsInPrototypeChain(Arguments args) { |
542 NoHandleAllocation ha; | 557 NoHandleAllocation ha; |
543 ASSERT(args.length() == 2); | 558 ASSERT(args.length() == 2); |
544 // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8). | 559 // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8). |
545 Object* O = args[0]; | 560 Object* O = args[0]; |
546 Object* V = args[1]; | 561 Object* V = args[1]; |
547 while (true) { | 562 while (true) { |
548 Object* prototype = V->GetPrototype(); | 563 Object* prototype = V->GetPrototype(); |
549 if (prototype->IsNull()) return Heap::false_value(); | 564 if (prototype->IsNull()) return Heap::false_value(); |
550 if (O == prototype) return Heap::true_value(); | 565 if (O == prototype) return Heap::true_value(); |
551 V = prototype; | 566 V = prototype; |
552 } | 567 } |
553 } | 568 } |
554 | 569 |
555 | 570 |
556 // Inserts an object as the hidden prototype of another object. | 571 // Inserts an object as the hidden prototype of another object. |
557 static Object* Runtime_SetHiddenPrototype(Arguments args) { | 572 static MaybeObject* Runtime_SetHiddenPrototype(Arguments args) { |
558 NoHandleAllocation ha; | 573 NoHandleAllocation ha; |
559 ASSERT(args.length() == 2); | 574 ASSERT(args.length() == 2); |
560 CONVERT_CHECKED(JSObject, jsobject, args[0]); | 575 CONVERT_CHECKED(JSObject, jsobject, args[0]); |
561 CONVERT_CHECKED(JSObject, proto, args[1]); | 576 CONVERT_CHECKED(JSObject, proto, args[1]); |
562 | 577 |
563 // Sanity checks. The old prototype (that we are replacing) could | 578 // Sanity checks. The old prototype (that we are replacing) could |
564 // theoretically be null, but if it is not null then check that we | 579 // theoretically be null, but if it is not null then check that we |
565 // didn't already install a hidden prototype here. | 580 // didn't already install a hidden prototype here. |
566 RUNTIME_ASSERT(!jsobject->GetPrototype()->IsHeapObject() || | 581 RUNTIME_ASSERT(!jsobject->GetPrototype()->IsHeapObject() || |
567 !HeapObject::cast(jsobject->GetPrototype())->map()->is_hidden_prototype()); | 582 !HeapObject::cast(jsobject->GetPrototype())->map()->is_hidden_prototype()); |
568 RUNTIME_ASSERT(!proto->map()->is_hidden_prototype()); | 583 RUNTIME_ASSERT(!proto->map()->is_hidden_prototype()); |
569 | 584 |
570 // Allocate up front before we start altering state in case we get a GC. | 585 // Allocate up front before we start altering state in case we get a GC. |
571 Object* map_or_failure = proto->map()->CopyDropTransitions(); | 586 Object* map_or_failure; |
572 if (map_or_failure->IsFailure()) return map_or_failure; | 587 { MaybeObject* maybe_map_or_failure = proto->map()->CopyDropTransitions(); |
| 588 if (!maybe_map_or_failure->ToObject(&map_or_failure)) { |
| 589 return maybe_map_or_failure; |
| 590 } |
| 591 } |
573 Map* new_proto_map = Map::cast(map_or_failure); | 592 Map* new_proto_map = Map::cast(map_or_failure); |
574 | 593 |
575 map_or_failure = jsobject->map()->CopyDropTransitions(); | 594 { MaybeObject* maybe_map_or_failure = jsobject->map()->CopyDropTransitions(); |
576 if (map_or_failure->IsFailure()) return map_or_failure; | 595 if (!maybe_map_or_failure->ToObject(&map_or_failure)) { |
| 596 return maybe_map_or_failure; |
| 597 } |
| 598 } |
577 Map* new_map = Map::cast(map_or_failure); | 599 Map* new_map = Map::cast(map_or_failure); |
578 | 600 |
579 // Set proto's prototype to be the old prototype of the object. | 601 // Set proto's prototype to be the old prototype of the object. |
580 new_proto_map->set_prototype(jsobject->GetPrototype()); | 602 new_proto_map->set_prototype(jsobject->GetPrototype()); |
581 proto->set_map(new_proto_map); | 603 proto->set_map(new_proto_map); |
582 new_proto_map->set_is_hidden_prototype(); | 604 new_proto_map->set_is_hidden_prototype(); |
583 | 605 |
584 // Set the object's prototype to proto. | 606 // Set the object's prototype to proto. |
585 new_map->set_prototype(proto); | 607 new_map->set_prototype(proto); |
586 jsobject->set_map(new_map); | 608 jsobject->set_map(new_map); |
587 | 609 |
588 return Heap::undefined_value(); | 610 return Heap::undefined_value(); |
589 } | 611 } |
590 | 612 |
591 | 613 |
592 static Object* Runtime_IsConstructCall(Arguments args) { | 614 static MaybeObject* Runtime_IsConstructCall(Arguments args) { |
593 NoHandleAllocation ha; | 615 NoHandleAllocation ha; |
594 ASSERT(args.length() == 0); | 616 ASSERT(args.length() == 0); |
595 JavaScriptFrameIterator it; | 617 JavaScriptFrameIterator it; |
596 return Heap::ToBoolean(it.frame()->IsConstructor()); | 618 return Heap::ToBoolean(it.frame()->IsConstructor()); |
597 } | 619 } |
598 | 620 |
599 | 621 |
600 // Recursively traverses hidden prototypes if property is not found | 622 // Recursively traverses hidden prototypes if property is not found |
601 static void GetOwnPropertyImplementation(JSObject* obj, | 623 static void GetOwnPropertyImplementation(JSObject* obj, |
602 String* name, | 624 String* name, |
(...skipping 22 matching lines...) Expand all Loading... |
625 DESCRIPTOR_SIZE | 647 DESCRIPTOR_SIZE |
626 }; | 648 }; |
627 | 649 |
628 // Returns an array with the property description: | 650 // Returns an array with the property description: |
629 // if args[1] is not a property on args[0] | 651 // if args[1] is not a property on args[0] |
630 // returns undefined | 652 // returns undefined |
631 // if args[1] is a data property on args[0] | 653 // if args[1] is a data property on args[0] |
632 // [false, value, Writeable, Enumerable, Configurable] | 654 // [false, value, Writeable, Enumerable, Configurable] |
633 // if args[1] is an accessor on args[0] | 655 // if args[1] is an accessor on args[0] |
634 // [true, GetFunction, SetFunction, Enumerable, Configurable] | 656 // [true, GetFunction, SetFunction, Enumerable, Configurable] |
635 static Object* Runtime_GetOwnProperty(Arguments args) { | 657 static MaybeObject* Runtime_GetOwnProperty(Arguments args) { |
636 ASSERT(args.length() == 2); | 658 ASSERT(args.length() == 2); |
637 HandleScope scope; | 659 HandleScope scope; |
638 Handle<FixedArray> elms = Factory::NewFixedArray(DESCRIPTOR_SIZE); | 660 Handle<FixedArray> elms = Factory::NewFixedArray(DESCRIPTOR_SIZE); |
639 Handle<JSArray> desc = Factory::NewJSArrayWithElements(elms); | 661 Handle<JSArray> desc = Factory::NewJSArrayWithElements(elms); |
640 LookupResult result; | 662 LookupResult result; |
641 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 663 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
642 CONVERT_ARG_CHECKED(String, name, 1); | 664 CONVERT_ARG_CHECKED(String, name, 1); |
643 | 665 |
644 // This could be an element. | 666 // This could be an element. |
645 uint32_t index; | 667 uint32_t index; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
712 GetOwnPropertyImplementation(*obj, *name, &result); | 734 GetOwnPropertyImplementation(*obj, *name, &result); |
713 | 735 |
714 if (!result.IsProperty()) { | 736 if (!result.IsProperty()) { |
715 return Heap::undefined_value(); | 737 return Heap::undefined_value(); |
716 } | 738 } |
717 if (result.type() == CALLBACKS) { | 739 if (result.type() == CALLBACKS) { |
718 Object* structure = result.GetCallbackObject(); | 740 Object* structure = result.GetCallbackObject(); |
719 if (structure->IsProxy() || structure->IsAccessorInfo()) { | 741 if (structure->IsProxy() || structure->IsAccessorInfo()) { |
720 // Property that is internally implemented as a callback or | 742 // Property that is internally implemented as a callback or |
721 // an API defined callback. | 743 // an API defined callback. |
722 Object* value = obj->GetPropertyWithCallback( | 744 Object* value; |
723 *obj, structure, *name, result.holder()); | 745 { MaybeObject* maybe_value = obj->GetPropertyWithCallback( |
724 if (value->IsFailure()) return value; | 746 *obj, structure, *name, result.holder()); |
| 747 if (!maybe_value->ToObject(&value)) return maybe_value; |
| 748 } |
725 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); | 749 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); |
726 elms->set(VALUE_INDEX, value); | 750 elms->set(VALUE_INDEX, value); |
727 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly())); | 751 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly())); |
728 } else if (structure->IsFixedArray()) { | 752 } else if (structure->IsFixedArray()) { |
729 // __defineGetter__/__defineSetter__ callback. | 753 // __defineGetter__/__defineSetter__ callback. |
730 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); | 754 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); |
731 elms->set(GETTER_INDEX, FixedArray::cast(structure)->get(0)); | 755 elms->set(GETTER_INDEX, FixedArray::cast(structure)->get(0)); |
732 elms->set(SETTER_INDEX, FixedArray::cast(structure)->get(1)); | 756 elms->set(SETTER_INDEX, FixedArray::cast(structure)->get(1)); |
733 } else { | 757 } else { |
734 return Heap::undefined_value(); | 758 return Heap::undefined_value(); |
735 } | 759 } |
736 } else { | 760 } else { |
737 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); | 761 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); |
738 elms->set(VALUE_INDEX, result.GetLazyValue()); | 762 elms->set(VALUE_INDEX, result.GetLazyValue()); |
739 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly())); | 763 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly())); |
740 } | 764 } |
741 | 765 |
742 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!result.IsDontEnum())); | 766 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!result.IsDontEnum())); |
743 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!result.IsDontDelete())); | 767 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!result.IsDontDelete())); |
744 return *desc; | 768 return *desc; |
745 } | 769 } |
746 | 770 |
747 | 771 |
748 static Object* Runtime_PreventExtensions(Arguments args) { | 772 static MaybeObject* Runtime_PreventExtensions(Arguments args) { |
749 ASSERT(args.length() == 1); | 773 ASSERT(args.length() == 1); |
750 CONVERT_CHECKED(JSObject, obj, args[0]); | 774 CONVERT_CHECKED(JSObject, obj, args[0]); |
751 return obj->PreventExtensions(); | 775 return obj->PreventExtensions(); |
752 } | 776 } |
753 | 777 |
754 static Object* Runtime_IsExtensible(Arguments args) { | 778 static MaybeObject* Runtime_IsExtensible(Arguments args) { |
755 ASSERT(args.length() == 1); | 779 ASSERT(args.length() == 1); |
756 CONVERT_CHECKED(JSObject, obj, args[0]); | 780 CONVERT_CHECKED(JSObject, obj, args[0]); |
757 return obj->map()->is_extensible() ? Heap::true_value() | 781 return obj->map()->is_extensible() ? Heap::true_value() |
758 : Heap::false_value(); | 782 : Heap::false_value(); |
759 } | 783 } |
760 | 784 |
761 | 785 |
762 static Object* Runtime_RegExpCompile(Arguments args) { | 786 static MaybeObject* Runtime_RegExpCompile(Arguments args) { |
763 HandleScope scope; | 787 HandleScope scope; |
764 ASSERT(args.length() == 3); | 788 ASSERT(args.length() == 3); |
765 CONVERT_ARG_CHECKED(JSRegExp, re, 0); | 789 CONVERT_ARG_CHECKED(JSRegExp, re, 0); |
766 CONVERT_ARG_CHECKED(String, pattern, 1); | 790 CONVERT_ARG_CHECKED(String, pattern, 1); |
767 CONVERT_ARG_CHECKED(String, flags, 2); | 791 CONVERT_ARG_CHECKED(String, flags, 2); |
768 Handle<Object> result = RegExpImpl::Compile(re, pattern, flags); | 792 Handle<Object> result = RegExpImpl::Compile(re, pattern, flags); |
769 if (result.is_null()) return Failure::Exception(); | 793 if (result.is_null()) return Failure::Exception(); |
770 return *result; | 794 return *result; |
771 } | 795 } |
772 | 796 |
773 | 797 |
774 static Object* Runtime_CreateApiFunction(Arguments args) { | 798 static MaybeObject* Runtime_CreateApiFunction(Arguments args) { |
775 HandleScope scope; | 799 HandleScope scope; |
776 ASSERT(args.length() == 1); | 800 ASSERT(args.length() == 1); |
777 CONVERT_ARG_CHECKED(FunctionTemplateInfo, data, 0); | 801 CONVERT_ARG_CHECKED(FunctionTemplateInfo, data, 0); |
778 return *Factory::CreateApiFunction(data); | 802 return *Factory::CreateApiFunction(data); |
779 } | 803 } |
780 | 804 |
781 | 805 |
782 static Object* Runtime_IsTemplate(Arguments args) { | 806 static MaybeObject* Runtime_IsTemplate(Arguments args) { |
783 ASSERT(args.length() == 1); | 807 ASSERT(args.length() == 1); |
784 Object* arg = args[0]; | 808 Object* arg = args[0]; |
785 bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo(); | 809 bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo(); |
786 return Heap::ToBoolean(result); | 810 return Heap::ToBoolean(result); |
787 } | 811 } |
788 | 812 |
789 | 813 |
790 static Object* Runtime_GetTemplateField(Arguments args) { | 814 static MaybeObject* Runtime_GetTemplateField(Arguments args) { |
791 ASSERT(args.length() == 2); | 815 ASSERT(args.length() == 2); |
792 CONVERT_CHECKED(HeapObject, templ, args[0]); | 816 CONVERT_CHECKED(HeapObject, templ, args[0]); |
793 CONVERT_CHECKED(Smi, field, args[1]); | 817 CONVERT_CHECKED(Smi, field, args[1]); |
794 int index = field->value(); | 818 int index = field->value(); |
795 int offset = index * kPointerSize + HeapObject::kHeaderSize; | 819 int offset = index * kPointerSize + HeapObject::kHeaderSize; |
796 InstanceType type = templ->map()->instance_type(); | 820 InstanceType type = templ->map()->instance_type(); |
797 RUNTIME_ASSERT(type == FUNCTION_TEMPLATE_INFO_TYPE || | 821 RUNTIME_ASSERT(type == FUNCTION_TEMPLATE_INFO_TYPE || |
798 type == OBJECT_TEMPLATE_INFO_TYPE); | 822 type == OBJECT_TEMPLATE_INFO_TYPE); |
799 RUNTIME_ASSERT(offset > 0); | 823 RUNTIME_ASSERT(offset > 0); |
800 if (type == FUNCTION_TEMPLATE_INFO_TYPE) { | 824 if (type == FUNCTION_TEMPLATE_INFO_TYPE) { |
801 RUNTIME_ASSERT(offset < FunctionTemplateInfo::kSize); | 825 RUNTIME_ASSERT(offset < FunctionTemplateInfo::kSize); |
802 } else { | 826 } else { |
803 RUNTIME_ASSERT(offset < ObjectTemplateInfo::kSize); | 827 RUNTIME_ASSERT(offset < ObjectTemplateInfo::kSize); |
804 } | 828 } |
805 return *HeapObject::RawField(templ, offset); | 829 return *HeapObject::RawField(templ, offset); |
806 } | 830 } |
807 | 831 |
808 | 832 |
809 static Object* Runtime_DisableAccessChecks(Arguments args) { | 833 static MaybeObject* Runtime_DisableAccessChecks(Arguments args) { |
810 ASSERT(args.length() == 1); | 834 ASSERT(args.length() == 1); |
811 CONVERT_CHECKED(HeapObject, object, args[0]); | 835 CONVERT_CHECKED(HeapObject, object, args[0]); |
812 Map* old_map = object->map(); | 836 Map* old_map = object->map(); |
813 bool needs_access_checks = old_map->is_access_check_needed(); | 837 bool needs_access_checks = old_map->is_access_check_needed(); |
814 if (needs_access_checks) { | 838 if (needs_access_checks) { |
815 // Copy map so it won't interfere constructor's initial map. | 839 // Copy map so it won't interfere constructor's initial map. |
816 Object* new_map = old_map->CopyDropTransitions(); | 840 Object* new_map; |
817 if (new_map->IsFailure()) return new_map; | 841 { MaybeObject* maybe_new_map = old_map->CopyDropTransitions(); |
| 842 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
| 843 } |
818 | 844 |
819 Map::cast(new_map)->set_is_access_check_needed(false); | 845 Map::cast(new_map)->set_is_access_check_needed(false); |
820 object->set_map(Map::cast(new_map)); | 846 object->set_map(Map::cast(new_map)); |
821 } | 847 } |
822 return needs_access_checks ? Heap::true_value() : Heap::false_value(); | 848 return needs_access_checks ? Heap::true_value() : Heap::false_value(); |
823 } | 849 } |
824 | 850 |
825 | 851 |
826 static Object* Runtime_EnableAccessChecks(Arguments args) { | 852 static MaybeObject* Runtime_EnableAccessChecks(Arguments args) { |
827 ASSERT(args.length() == 1); | 853 ASSERT(args.length() == 1); |
828 CONVERT_CHECKED(HeapObject, object, args[0]); | 854 CONVERT_CHECKED(HeapObject, object, args[0]); |
829 Map* old_map = object->map(); | 855 Map* old_map = object->map(); |
830 if (!old_map->is_access_check_needed()) { | 856 if (!old_map->is_access_check_needed()) { |
831 // Copy map so it won't interfere constructor's initial map. | 857 // Copy map so it won't interfere constructor's initial map. |
832 Object* new_map = old_map->CopyDropTransitions(); | 858 Object* new_map; |
833 if (new_map->IsFailure()) return new_map; | 859 { MaybeObject* maybe_new_map = old_map->CopyDropTransitions(); |
| 860 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
| 861 } |
834 | 862 |
835 Map::cast(new_map)->set_is_access_check_needed(true); | 863 Map::cast(new_map)->set_is_access_check_needed(true); |
836 object->set_map(Map::cast(new_map)); | 864 object->set_map(Map::cast(new_map)); |
837 } | 865 } |
838 return Heap::undefined_value(); | 866 return Heap::undefined_value(); |
839 } | 867 } |
840 | 868 |
841 | 869 |
842 static Object* ThrowRedeclarationError(const char* type, Handle<String> name) { | 870 static Failure* ThrowRedeclarationError(const char* type, Handle<String> name) { |
843 HandleScope scope; | 871 HandleScope scope; |
844 Handle<Object> type_handle = Factory::NewStringFromAscii(CStrVector(type)); | 872 Handle<Object> type_handle = Factory::NewStringFromAscii(CStrVector(type)); |
845 Handle<Object> args[2] = { type_handle, name }; | 873 Handle<Object> args[2] = { type_handle, name }; |
846 Handle<Object> error = | 874 Handle<Object> error = |
847 Factory::NewTypeError("redeclaration", HandleVector(args, 2)); | 875 Factory::NewTypeError("redeclaration", HandleVector(args, 2)); |
848 return Top::Throw(*error); | 876 return Top::Throw(*error); |
849 } | 877 } |
850 | 878 |
851 | 879 |
852 static Object* Runtime_DeclareGlobals(Arguments args) { | 880 static MaybeObject* Runtime_DeclareGlobals(Arguments args) { |
853 HandleScope scope; | 881 HandleScope scope; |
854 Handle<GlobalObject> global = Handle<GlobalObject>(Top::context()->global()); | 882 Handle<GlobalObject> global = Handle<GlobalObject>(Top::context()->global()); |
855 | 883 |
856 Handle<Context> context = args.at<Context>(0); | 884 Handle<Context> context = args.at<Context>(0); |
857 CONVERT_ARG_CHECKED(FixedArray, pairs, 1); | 885 CONVERT_ARG_CHECKED(FixedArray, pairs, 1); |
858 bool is_eval = Smi::cast(args[2])->value() == 1; | 886 bool is_eval = Smi::cast(args[2])->value() == 1; |
859 | 887 |
860 // Compute the property attributes. According to ECMA-262, section | 888 // Compute the property attributes. According to ECMA-262, section |
861 // 13, page 71, the property must be read-only and | 889 // 13, page 71, the property must be read-only and |
862 // non-deletable. However, neither SpiderMonkey nor KJS creates the | 890 // non-deletable. However, neither SpiderMonkey nor KJS creates the |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
954 // SetProperty). Also, we must use the handle-based version to | 982 // SetProperty). Also, we must use the handle-based version to |
955 // avoid GC issues. | 983 // avoid GC issues. |
956 IgnoreAttributesAndSetLocalProperty(global, name, value, attributes); | 984 IgnoreAttributesAndSetLocalProperty(global, name, value, attributes); |
957 } | 985 } |
958 } | 986 } |
959 | 987 |
960 return Heap::undefined_value(); | 988 return Heap::undefined_value(); |
961 } | 989 } |
962 | 990 |
963 | 991 |
964 static Object* Runtime_DeclareContextSlot(Arguments args) { | 992 static MaybeObject* Runtime_DeclareContextSlot(Arguments args) { |
965 HandleScope scope; | 993 HandleScope scope; |
966 ASSERT(args.length() == 4); | 994 ASSERT(args.length() == 4); |
967 | 995 |
968 CONVERT_ARG_CHECKED(Context, context, 0); | 996 CONVERT_ARG_CHECKED(Context, context, 0); |
969 Handle<String> name(String::cast(args[1])); | 997 Handle<String> name(String::cast(args[1])); |
970 PropertyAttributes mode = | 998 PropertyAttributes mode = |
971 static_cast<PropertyAttributes>(Smi::cast(args[2])->value()); | 999 static_cast<PropertyAttributes>(Smi::cast(args[2])->value()); |
972 RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE); | 1000 RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE); |
973 Handle<Object> initial_value(args[3]); | 1001 Handle<Object> initial_value(args[3]); |
974 | 1002 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1039 Handle<Object> value(Heap::undefined_value()); | 1067 Handle<Object> value(Heap::undefined_value()); |
1040 if (*initial_value != NULL) value = initial_value; | 1068 if (*initial_value != NULL) value = initial_value; |
1041 SetProperty(context_ext, name, value, mode); | 1069 SetProperty(context_ext, name, value, mode); |
1042 ASSERT(context_ext->GetLocalPropertyAttribute(*name) == mode); | 1070 ASSERT(context_ext->GetLocalPropertyAttribute(*name) == mode); |
1043 } | 1071 } |
1044 | 1072 |
1045 return Heap::undefined_value(); | 1073 return Heap::undefined_value(); |
1046 } | 1074 } |
1047 | 1075 |
1048 | 1076 |
1049 static Object* Runtime_InitializeVarGlobal(Arguments args) { | 1077 static MaybeObject* Runtime_InitializeVarGlobal(Arguments args) { |
1050 NoHandleAllocation nha; | 1078 NoHandleAllocation nha; |
1051 | 1079 |
1052 // Determine if we need to assign to the variable if it already | 1080 // Determine if we need to assign to the variable if it already |
1053 // exists (based on the number of arguments). | 1081 // exists (based on the number of arguments). |
1054 RUNTIME_ASSERT(args.length() == 1 || args.length() == 2); | 1082 RUNTIME_ASSERT(args.length() == 1 || args.length() == 2); |
1055 bool assign = args.length() == 2; | 1083 bool assign = args.length() == 2; |
1056 | 1084 |
1057 CONVERT_ARG_CHECKED(String, name, 0); | 1085 CONVERT_ARG_CHECKED(String, name, 0); |
1058 GlobalObject* global = Top::context()->global(); | 1086 GlobalObject* global = Top::context()->global(); |
1059 | 1087 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1132 global = Top::context()->global(); | 1160 global = Top::context()->global(); |
1133 if (assign) { | 1161 if (assign) { |
1134 return global->IgnoreAttributesAndSetLocalProperty(*name, | 1162 return global->IgnoreAttributesAndSetLocalProperty(*name, |
1135 args[1], | 1163 args[1], |
1136 attributes); | 1164 attributes); |
1137 } | 1165 } |
1138 return Heap::undefined_value(); | 1166 return Heap::undefined_value(); |
1139 } | 1167 } |
1140 | 1168 |
1141 | 1169 |
1142 static Object* Runtime_InitializeConstGlobal(Arguments args) { | 1170 static MaybeObject* Runtime_InitializeConstGlobal(Arguments args) { |
1143 // All constants are declared with an initial value. The name | 1171 // All constants are declared with an initial value. The name |
1144 // of the constant is the first argument and the initial value | 1172 // of the constant is the first argument and the initial value |
1145 // is the second. | 1173 // is the second. |
1146 RUNTIME_ASSERT(args.length() == 2); | 1174 RUNTIME_ASSERT(args.length() == 2); |
1147 CONVERT_ARG_CHECKED(String, name, 0); | 1175 CONVERT_ARG_CHECKED(String, name, 0); |
1148 Handle<Object> value = args.at<Object>(1); | 1176 Handle<Object> value = args.at<Object>(1); |
1149 | 1177 |
1150 // Get the current global object from top. | 1178 // Get the current global object from top. |
1151 GlobalObject* global = Top::context()->global(); | 1179 GlobalObject* global = Top::context()->global(); |
1152 | 1180 |
(...skipping 27 matching lines...) Expand all Loading... |
1180 | 1208 |
1181 // Throw re-declaration error if the intercepted property is present | 1209 // Throw re-declaration error if the intercepted property is present |
1182 // but not read-only. | 1210 // but not read-only. |
1183 if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) { | 1211 if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) { |
1184 return ThrowRedeclarationError("var", name); | 1212 return ThrowRedeclarationError("var", name); |
1185 } | 1213 } |
1186 | 1214 |
1187 // Restore global object from context (in case of GC) and continue | 1215 // Restore global object from context (in case of GC) and continue |
1188 // with setting the value because the property is either absent or | 1216 // with setting the value because the property is either absent or |
1189 // read-only. We also have to do redo the lookup. | 1217 // read-only. We also have to do redo the lookup. |
1190 global = Top::context()->global(); | 1218 HandleScope handle_scope; |
| 1219 Handle<GlobalObject>global(Top::context()->global()); |
1191 | 1220 |
1192 // BUG 1213579: Handle the case where we have to set a read-only | 1221 // BUG 1213579: Handle the case where we have to set a read-only |
1193 // property through an interceptor and only do it if it's | 1222 // property through an interceptor and only do it if it's |
1194 // uninitialized, e.g. the hole. Nirk... | 1223 // uninitialized, e.g. the hole. Nirk... |
1195 global->SetProperty(*name, *value, attributes); | 1224 SetProperty(global, name, value, attributes); |
1196 return *value; | 1225 return *value; |
1197 } | 1226 } |
1198 | 1227 |
1199 // Set the value, but only we're assigning the initial value to a | 1228 // Set the value, but only we're assigning the initial value to a |
1200 // constant. For now, we determine this by checking if the | 1229 // constant. For now, we determine this by checking if the |
1201 // current value is the hole. | 1230 // current value is the hole. |
1202 PropertyType type = lookup.type(); | 1231 PropertyType type = lookup.type(); |
1203 if (type == FIELD) { | 1232 if (type == FIELD) { |
1204 FixedArray* properties = global->properties(); | 1233 FixedArray* properties = global->properties(); |
1205 int index = lookup.GetFieldIndex(); | 1234 int index = lookup.GetFieldIndex(); |
1206 if (properties->get(index)->IsTheHole()) { | 1235 if (properties->get(index)->IsTheHole()) { |
1207 properties->set(index, *value); | 1236 properties->set(index, *value); |
1208 } | 1237 } |
1209 } else if (type == NORMAL) { | 1238 } else if (type == NORMAL) { |
1210 if (global->GetNormalizedProperty(&lookup)->IsTheHole()) { | 1239 if (global->GetNormalizedProperty(&lookup)->IsTheHole()) { |
1211 global->SetNormalizedProperty(&lookup, *value); | 1240 global->SetNormalizedProperty(&lookup, *value); |
1212 } | 1241 } |
1213 } else { | 1242 } else { |
1214 // Ignore re-initialization of constants that have already been | 1243 // Ignore re-initialization of constants that have already been |
1215 // assigned a function value. | 1244 // assigned a function value. |
1216 ASSERT(lookup.IsReadOnly() && type == CONSTANT_FUNCTION); | 1245 ASSERT(lookup.IsReadOnly() && type == CONSTANT_FUNCTION); |
1217 } | 1246 } |
1218 | 1247 |
1219 // Use the set value as the result of the operation. | 1248 // Use the set value as the result of the operation. |
1220 return *value; | 1249 return *value; |
1221 } | 1250 } |
1222 | 1251 |
1223 | 1252 |
1224 static Object* Runtime_InitializeConstContextSlot(Arguments args) { | 1253 static MaybeObject* Runtime_InitializeConstContextSlot(Arguments args) { |
1225 HandleScope scope; | 1254 HandleScope scope; |
1226 ASSERT(args.length() == 3); | 1255 ASSERT(args.length() == 3); |
1227 | 1256 |
1228 Handle<Object> value(args[0]); | 1257 Handle<Object> value(args[0]); |
1229 ASSERT(!value->IsTheHole()); | 1258 ASSERT(!value->IsTheHole()); |
1230 CONVERT_ARG_CHECKED(Context, context, 1); | 1259 CONVERT_ARG_CHECKED(Context, context, 1); |
1231 Handle<String> name(String::cast(args[2])); | 1260 Handle<String> name(String::cast(args[2])); |
1232 | 1261 |
1233 // Initializations are always done in the function context. | 1262 // Initializations are always done in the function context. |
1234 context = Handle<Context>(context->fcontext()); | 1263 context = Handle<Context>(context->fcontext()); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1319 ASSERT(Top::has_pending_exception()); | 1348 ASSERT(Top::has_pending_exception()); |
1320 return Failure::Exception(); | 1349 return Failure::Exception(); |
1321 } | 1350 } |
1322 } | 1351 } |
1323 } | 1352 } |
1324 | 1353 |
1325 return *value; | 1354 return *value; |
1326 } | 1355 } |
1327 | 1356 |
1328 | 1357 |
1329 static Object* Runtime_OptimizeObjectForAddingMultipleProperties( | 1358 static MaybeObject* Runtime_OptimizeObjectForAddingMultipleProperties( |
1330 Arguments args) { | 1359 Arguments args) { |
1331 HandleScope scope; | 1360 HandleScope scope; |
1332 ASSERT(args.length() == 2); | 1361 ASSERT(args.length() == 2); |
1333 CONVERT_ARG_CHECKED(JSObject, object, 0); | 1362 CONVERT_ARG_CHECKED(JSObject, object, 0); |
1334 CONVERT_SMI_CHECKED(properties, args[1]); | 1363 CONVERT_SMI_CHECKED(properties, args[1]); |
1335 if (object->HasFastProperties()) { | 1364 if (object->HasFastProperties()) { |
1336 NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); | 1365 NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); |
1337 } | 1366 } |
1338 return *object; | 1367 return *object; |
1339 } | 1368 } |
1340 | 1369 |
1341 | 1370 |
1342 static Object* Runtime_RegExpExec(Arguments args) { | 1371 static MaybeObject* Runtime_RegExpExec(Arguments args) { |
1343 HandleScope scope; | 1372 HandleScope scope; |
1344 ASSERT(args.length() == 4); | 1373 ASSERT(args.length() == 4); |
1345 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); | 1374 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); |
1346 CONVERT_ARG_CHECKED(String, subject, 1); | 1375 CONVERT_ARG_CHECKED(String, subject, 1); |
1347 // Due to the way the JS calls are constructed this must be less than the | 1376 // Due to the way the JS calls are constructed this must be less than the |
1348 // length of a string, i.e. it is always a Smi. We check anyway for security. | 1377 // length of a string, i.e. it is always a Smi. We check anyway for security. |
1349 CONVERT_SMI_CHECKED(index, args[2]); | 1378 CONVERT_SMI_CHECKED(index, args[2]); |
1350 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3); | 1379 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3); |
1351 RUNTIME_ASSERT(last_match_info->HasFastElements()); | 1380 RUNTIME_ASSERT(last_match_info->HasFastElements()); |
1352 RUNTIME_ASSERT(index >= 0); | 1381 RUNTIME_ASSERT(index >= 0); |
1353 RUNTIME_ASSERT(index <= subject->length()); | 1382 RUNTIME_ASSERT(index <= subject->length()); |
1354 Counters::regexp_entry_runtime.Increment(); | 1383 Counters::regexp_entry_runtime.Increment(); |
1355 Handle<Object> result = RegExpImpl::Exec(regexp, | 1384 Handle<Object> result = RegExpImpl::Exec(regexp, |
1356 subject, | 1385 subject, |
1357 index, | 1386 index, |
1358 last_match_info); | 1387 last_match_info); |
1359 if (result.is_null()) return Failure::Exception(); | 1388 if (result.is_null()) return Failure::Exception(); |
1360 return *result; | 1389 return *result; |
1361 } | 1390 } |
1362 | 1391 |
1363 | 1392 |
1364 static Object* Runtime_RegExpConstructResult(Arguments args) { | 1393 static MaybeObject* Runtime_RegExpConstructResult(Arguments args) { |
1365 ASSERT(args.length() == 3); | 1394 ASSERT(args.length() == 3); |
1366 CONVERT_SMI_CHECKED(elements_count, args[0]); | 1395 CONVERT_SMI_CHECKED(elements_count, args[0]); |
1367 if (elements_count > JSArray::kMaxFastElementsLength) { | 1396 if (elements_count > JSArray::kMaxFastElementsLength) { |
1368 return Top::ThrowIllegalOperation(); | 1397 return Top::ThrowIllegalOperation(); |
1369 } | 1398 } |
1370 Object* new_object = Heap::AllocateFixedArrayWithHoles(elements_count); | 1399 Object* new_object; |
1371 if (new_object->IsFailure()) return new_object; | 1400 { MaybeObject* maybe_new_object = |
| 1401 Heap::AllocateFixedArrayWithHoles(elements_count); |
| 1402 if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object; |
| 1403 } |
1372 FixedArray* elements = FixedArray::cast(new_object); | 1404 FixedArray* elements = FixedArray::cast(new_object); |
1373 new_object = Heap::AllocateRaw(JSRegExpResult::kSize, | 1405 { MaybeObject* maybe_new_object = Heap::AllocateRaw(JSRegExpResult::kSize, |
1374 NEW_SPACE, | 1406 NEW_SPACE, |
1375 OLD_POINTER_SPACE); | 1407 OLD_POINTER_SPACE); |
1376 if (new_object->IsFailure()) return new_object; | 1408 if (!maybe_new_object->ToObject(&new_object)) return maybe_new_object; |
| 1409 } |
1377 { | 1410 { |
1378 AssertNoAllocation no_gc; | 1411 AssertNoAllocation no_gc; |
1379 HandleScope scope; | 1412 HandleScope scope; |
1380 reinterpret_cast<HeapObject*>(new_object)-> | 1413 reinterpret_cast<HeapObject*>(new_object)-> |
1381 set_map(Top::global_context()->regexp_result_map()); | 1414 set_map(Top::global_context()->regexp_result_map()); |
1382 } | 1415 } |
1383 JSArray* array = JSArray::cast(new_object); | 1416 JSArray* array = JSArray::cast(new_object); |
1384 array->set_properties(Heap::empty_fixed_array()); | 1417 array->set_properties(Heap::empty_fixed_array()); |
1385 array->set_elements(elements); | 1418 array->set_elements(elements); |
1386 array->set_length(Smi::FromInt(elements_count)); | 1419 array->set_length(Smi::FromInt(elements_count)); |
1387 // Write in-object properties after the length of the array. | 1420 // Write in-object properties after the length of the array. |
1388 array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, args[1]); | 1421 array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, args[1]); |
1389 array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, args[2]); | 1422 array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, args[2]); |
1390 return array; | 1423 return array; |
1391 } | 1424 } |
1392 | 1425 |
1393 | 1426 |
1394 static Object* Runtime_RegExpCloneResult(Arguments args) { | 1427 static MaybeObject* Runtime_RegExpCloneResult(Arguments args) { |
1395 ASSERT(args.length() == 1); | 1428 ASSERT(args.length() == 1); |
1396 Map* regexp_result_map; | 1429 Map* regexp_result_map; |
1397 { | 1430 { |
1398 AssertNoAllocation no_gc; | 1431 AssertNoAllocation no_gc; |
1399 HandleScope handles; | 1432 HandleScope handles; |
1400 regexp_result_map = Top::global_context()->regexp_result_map(); | 1433 regexp_result_map = Top::global_context()->regexp_result_map(); |
1401 } | 1434 } |
1402 if (!args[0]->IsJSArray()) return args[0]; | 1435 if (!args[0]->IsJSArray()) return args[0]; |
1403 | 1436 |
1404 JSArray* result = JSArray::cast(args[0]); | 1437 JSArray* result = JSArray::cast(args[0]); |
1405 // Arguments to RegExpCloneResult should always be fresh RegExp exec call | 1438 // Arguments to RegExpCloneResult should always be fresh RegExp exec call |
1406 // results (either a fresh JSRegExpResult or null). | 1439 // results (either a fresh JSRegExpResult or null). |
1407 // If the argument is not a JSRegExpResult, or isn't unmodified, just return | 1440 // If the argument is not a JSRegExpResult, or isn't unmodified, just return |
1408 // the argument uncloned. | 1441 // the argument uncloned. |
1409 if (result->map() != regexp_result_map) return result; | 1442 if (result->map() != regexp_result_map) return result; |
1410 | 1443 |
1411 // Having the original JSRegExpResult map guarantees that we have | 1444 // Having the original JSRegExpResult map guarantees that we have |
1412 // fast elements and no properties except the two in-object properties. | 1445 // fast elements and no properties except the two in-object properties. |
1413 ASSERT(result->HasFastElements()); | 1446 ASSERT(result->HasFastElements()); |
1414 ASSERT(result->properties() == Heap::empty_fixed_array()); | 1447 ASSERT(result->properties() == Heap::empty_fixed_array()); |
1415 ASSERT_EQ(2, regexp_result_map->inobject_properties()); | 1448 ASSERT_EQ(2, regexp_result_map->inobject_properties()); |
1416 | 1449 |
1417 Object* new_array_alloc = Heap::AllocateRaw(JSRegExpResult::kSize, | 1450 Object* new_array_alloc; |
1418 NEW_SPACE, | 1451 { MaybeObject* maybe_new_array_alloc = |
1419 OLD_POINTER_SPACE); | 1452 Heap::AllocateRaw(JSRegExpResult::kSize, NEW_SPACE, OLD_POINTER_SPACE); |
1420 if (new_array_alloc->IsFailure()) return new_array_alloc; | 1453 if (!maybe_new_array_alloc->ToObject(&new_array_alloc)) { |
| 1454 return maybe_new_array_alloc; |
| 1455 } |
| 1456 } |
1421 | 1457 |
1422 // Set HeapObject map to JSRegExpResult map. | 1458 // Set HeapObject map to JSRegExpResult map. |
1423 reinterpret_cast<HeapObject*>(new_array_alloc)->set_map(regexp_result_map); | 1459 reinterpret_cast<HeapObject*>(new_array_alloc)->set_map(regexp_result_map); |
1424 | 1460 |
1425 JSArray* new_array = JSArray::cast(new_array_alloc); | 1461 JSArray* new_array = JSArray::cast(new_array_alloc); |
1426 | 1462 |
1427 // Copy JSObject properties. | 1463 // Copy JSObject properties. |
1428 new_array->set_properties(result->properties()); // Empty FixedArray. | 1464 new_array->set_properties(result->properties()); // Empty FixedArray. |
1429 | 1465 |
1430 // Copy JSObject elements as copy-on-write. | 1466 // Copy JSObject elements as copy-on-write. |
(...skipping 10 matching lines...) Expand all Loading... |
1441 new_array->FastPropertyAtPut(JSRegExpResult::kIndexIndex, | 1477 new_array->FastPropertyAtPut(JSRegExpResult::kIndexIndex, |
1442 result->FastPropertyAt( | 1478 result->FastPropertyAt( |
1443 JSRegExpResult::kIndexIndex)); | 1479 JSRegExpResult::kIndexIndex)); |
1444 new_array->FastPropertyAtPut(JSRegExpResult::kInputIndex, | 1480 new_array->FastPropertyAtPut(JSRegExpResult::kInputIndex, |
1445 result->FastPropertyAt( | 1481 result->FastPropertyAt( |
1446 JSRegExpResult::kInputIndex)); | 1482 JSRegExpResult::kInputIndex)); |
1447 return new_array; | 1483 return new_array; |
1448 } | 1484 } |
1449 | 1485 |
1450 | 1486 |
1451 static Object* Runtime_RegExpInitializeObject(Arguments args) { | 1487 static MaybeObject* Runtime_RegExpInitializeObject(Arguments args) { |
1452 AssertNoAllocation no_alloc; | 1488 AssertNoAllocation no_alloc; |
1453 ASSERT(args.length() == 5); | 1489 ASSERT(args.length() == 5); |
1454 CONVERT_CHECKED(JSRegExp, regexp, args[0]); | 1490 CONVERT_CHECKED(JSRegExp, regexp, args[0]); |
1455 CONVERT_CHECKED(String, source, args[1]); | 1491 CONVERT_CHECKED(String, source, args[1]); |
1456 | 1492 |
1457 Object* global = args[2]; | 1493 Object* global = args[2]; |
1458 if (!global->IsTrue()) global = Heap::false_value(); | 1494 if (!global->IsTrue()) global = Heap::false_value(); |
1459 | 1495 |
1460 Object* ignoreCase = args[3]; | 1496 Object* ignoreCase = args[3]; |
1461 if (!ignoreCase->IsTrue()) ignoreCase = Heap::false_value(); | 1497 if (!ignoreCase->IsTrue()) ignoreCase = Heap::false_value(); |
(...skipping 11 matching lines...) Expand all Loading... |
1473 // Both true and false should be in oldspace at all times. | 1509 // Both true and false should be in oldspace at all times. |
1474 regexp->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex, global); | 1510 regexp->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex, global); |
1475 regexp->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, ignoreCase); | 1511 regexp->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, ignoreCase); |
1476 regexp->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex, multiline); | 1512 regexp->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex, multiline); |
1477 regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, | 1513 regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, |
1478 Smi::FromInt(0), | 1514 Smi::FromInt(0), |
1479 SKIP_WRITE_BARRIER); | 1515 SKIP_WRITE_BARRIER); |
1480 return regexp; | 1516 return regexp; |
1481 } | 1517 } |
1482 | 1518 |
1483 // Map has changed, so use generic, but slower, method. | 1519 // Map has changed, so use generic, but slower, method. Since these |
| 1520 // properties were all added as DONT_DELETE they must be present and |
| 1521 // normal so no failures can be expected. |
1484 PropertyAttributes final = | 1522 PropertyAttributes final = |
1485 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); | 1523 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); |
1486 PropertyAttributes writable = | 1524 PropertyAttributes writable = |
1487 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); | 1525 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); |
1488 regexp->IgnoreAttributesAndSetLocalProperty(Heap::source_symbol(), | 1526 MaybeObject* result; |
1489 source, | 1527 result = regexp->IgnoreAttributesAndSetLocalProperty(Heap::source_symbol(), |
1490 final); | 1528 source, |
1491 regexp->IgnoreAttributesAndSetLocalProperty(Heap::global_symbol(), | 1529 final); |
1492 global, | 1530 ASSERT(!result->IsFailure()); |
1493 final); | 1531 result = regexp->IgnoreAttributesAndSetLocalProperty(Heap::global_symbol(), |
1494 regexp->IgnoreAttributesAndSetLocalProperty(Heap::ignore_case_symbol(), | 1532 global, |
1495 ignoreCase, | 1533 final); |
1496 final); | 1534 ASSERT(!result->IsFailure()); |
1497 regexp->IgnoreAttributesAndSetLocalProperty(Heap::multiline_symbol(), | 1535 result = |
1498 multiline, | 1536 regexp->IgnoreAttributesAndSetLocalProperty(Heap::ignore_case_symbol(), |
1499 final); | 1537 ignoreCase, |
1500 regexp->IgnoreAttributesAndSetLocalProperty(Heap::last_index_symbol(), | 1538 final); |
1501 Smi::FromInt(0), | 1539 ASSERT(!result->IsFailure()); |
1502 writable); | 1540 result = regexp->IgnoreAttributesAndSetLocalProperty(Heap::multiline_symbol(), |
| 1541 multiline, |
| 1542 final); |
| 1543 ASSERT(!result->IsFailure()); |
| 1544 result = |
| 1545 regexp->IgnoreAttributesAndSetLocalProperty(Heap::last_index_symbol(), |
| 1546 Smi::FromInt(0), |
| 1547 writable); |
| 1548 ASSERT(!result->IsFailure()); |
| 1549 USE(result); |
1503 return regexp; | 1550 return regexp; |
1504 } | 1551 } |
1505 | 1552 |
1506 | 1553 |
1507 static Object* Runtime_FinishArrayPrototypeSetup(Arguments args) { | 1554 static MaybeObject* Runtime_FinishArrayPrototypeSetup(Arguments args) { |
1508 HandleScope scope; | 1555 HandleScope scope; |
1509 ASSERT(args.length() == 1); | 1556 ASSERT(args.length() == 1); |
1510 CONVERT_ARG_CHECKED(JSArray, prototype, 0); | 1557 CONVERT_ARG_CHECKED(JSArray, prototype, 0); |
1511 // This is necessary to enable fast checks for absence of elements | 1558 // This is necessary to enable fast checks for absence of elements |
1512 // on Array.prototype and below. | 1559 // on Array.prototype and below. |
1513 prototype->set_elements(Heap::empty_fixed_array()); | 1560 prototype->set_elements(Heap::empty_fixed_array()); |
1514 return Smi::FromInt(0); | 1561 return Smi::FromInt(0); |
1515 } | 1562 } |
1516 | 1563 |
1517 | 1564 |
1518 static Handle<JSFunction> InstallBuiltin(Handle<JSObject> holder, | 1565 static Handle<JSFunction> InstallBuiltin(Handle<JSObject> holder, |
1519 const char* name, | 1566 const char* name, |
1520 Builtins::Name builtin_name) { | 1567 Builtins::Name builtin_name) { |
1521 Handle<String> key = Factory::LookupAsciiSymbol(name); | 1568 Handle<String> key = Factory::LookupAsciiSymbol(name); |
1522 Handle<Code> code(Builtins::builtin(builtin_name)); | 1569 Handle<Code> code(Builtins::builtin(builtin_name)); |
1523 Handle<JSFunction> optimized = Factory::NewFunction(key, | 1570 Handle<JSFunction> optimized = Factory::NewFunction(key, |
1524 JS_OBJECT_TYPE, | 1571 JS_OBJECT_TYPE, |
1525 JSObject::kHeaderSize, | 1572 JSObject::kHeaderSize, |
1526 code, | 1573 code, |
1527 false); | 1574 false); |
1528 optimized->shared()->DontAdaptArguments(); | 1575 optimized->shared()->DontAdaptArguments(); |
1529 SetProperty(holder, key, optimized, NONE); | 1576 SetProperty(holder, key, optimized, NONE); |
1530 return optimized; | 1577 return optimized; |
1531 } | 1578 } |
1532 | 1579 |
1533 | 1580 |
1534 static Object* Runtime_SpecialArrayFunctions(Arguments args) { | 1581 static MaybeObject* Runtime_SpecialArrayFunctions(Arguments args) { |
1535 HandleScope scope; | 1582 HandleScope scope; |
1536 ASSERT(args.length() == 1); | 1583 ASSERT(args.length() == 1); |
1537 CONVERT_ARG_CHECKED(JSObject, holder, 0); | 1584 CONVERT_ARG_CHECKED(JSObject, holder, 0); |
1538 | 1585 |
1539 InstallBuiltin(holder, "pop", Builtins::ArrayPop); | 1586 InstallBuiltin(holder, "pop", Builtins::ArrayPop); |
1540 InstallBuiltin(holder, "push", Builtins::ArrayPush); | 1587 InstallBuiltin(holder, "push", Builtins::ArrayPush); |
1541 InstallBuiltin(holder, "shift", Builtins::ArrayShift); | 1588 InstallBuiltin(holder, "shift", Builtins::ArrayShift); |
1542 InstallBuiltin(holder, "unshift", Builtins::ArrayUnshift); | 1589 InstallBuiltin(holder, "unshift", Builtins::ArrayUnshift); |
1543 InstallBuiltin(holder, "slice", Builtins::ArraySlice); | 1590 InstallBuiltin(holder, "slice", Builtins::ArraySlice); |
1544 InstallBuiltin(holder, "splice", Builtins::ArraySplice); | 1591 InstallBuiltin(holder, "splice", Builtins::ArraySplice); |
1545 InstallBuiltin(holder, "concat", Builtins::ArrayConcat); | 1592 InstallBuiltin(holder, "concat", Builtins::ArrayConcat); |
1546 | 1593 |
1547 return *holder; | 1594 return *holder; |
1548 } | 1595 } |
1549 | 1596 |
1550 | 1597 |
1551 static Object* Runtime_GetGlobalReceiver(Arguments args) { | 1598 static MaybeObject* Runtime_GetGlobalReceiver(Arguments args) { |
1552 // Returns a real global receiver, not one of builtins object. | 1599 // Returns a real global receiver, not one of builtins object. |
1553 Context* global_context = Top::context()->global()->global_context(); | 1600 Context* global_context = Top::context()->global()->global_context(); |
1554 return global_context->global()->global_receiver(); | 1601 return global_context->global()->global_receiver(); |
1555 } | 1602 } |
1556 | 1603 |
1557 | 1604 |
1558 static Object* Runtime_MaterializeRegExpLiteral(Arguments args) { | 1605 static MaybeObject* Runtime_MaterializeRegExpLiteral(Arguments args) { |
1559 HandleScope scope; | 1606 HandleScope scope; |
1560 ASSERT(args.length() == 4); | 1607 ASSERT(args.length() == 4); |
1561 CONVERT_ARG_CHECKED(FixedArray, literals, 0); | 1608 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
1562 int index = Smi::cast(args[1])->value(); | 1609 int index = Smi::cast(args[1])->value(); |
1563 Handle<String> pattern = args.at<String>(2); | 1610 Handle<String> pattern = args.at<String>(2); |
1564 Handle<String> flags = args.at<String>(3); | 1611 Handle<String> flags = args.at<String>(3); |
1565 | 1612 |
1566 // Get the RegExp function from the context in the literals array. | 1613 // Get the RegExp function from the context in the literals array. |
1567 // This is the RegExp function from the context in which the | 1614 // This is the RegExp function from the context in which the |
1568 // function was created. We do not use the RegExp function from the | 1615 // function was created. We do not use the RegExp function from the |
1569 // current global context because this might be the RegExp function | 1616 // current global context because this might be the RegExp function |
1570 // from another context which we should not have access to. | 1617 // from another context which we should not have access to. |
1571 Handle<JSFunction> constructor = | 1618 Handle<JSFunction> constructor = |
1572 Handle<JSFunction>( | 1619 Handle<JSFunction>( |
1573 JSFunction::GlobalContextFromLiterals(*literals)->regexp_function()); | 1620 JSFunction::GlobalContextFromLiterals(*literals)->regexp_function()); |
1574 // Compute the regular expression literal. | 1621 // Compute the regular expression literal. |
1575 bool has_pending_exception; | 1622 bool has_pending_exception; |
1576 Handle<Object> regexp = | 1623 Handle<Object> regexp = |
1577 RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags, | 1624 RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags, |
1578 &has_pending_exception); | 1625 &has_pending_exception); |
1579 if (has_pending_exception) { | 1626 if (has_pending_exception) { |
1580 ASSERT(Top::has_pending_exception()); | 1627 ASSERT(Top::has_pending_exception()); |
1581 return Failure::Exception(); | 1628 return Failure::Exception(); |
1582 } | 1629 } |
1583 literals->set(index, *regexp); | 1630 literals->set(index, *regexp); |
1584 return *regexp; | 1631 return *regexp; |
1585 } | 1632 } |
1586 | 1633 |
1587 | 1634 |
1588 static Object* Runtime_FunctionGetName(Arguments args) { | 1635 static MaybeObject* Runtime_FunctionGetName(Arguments args) { |
1589 NoHandleAllocation ha; | 1636 NoHandleAllocation ha; |
1590 ASSERT(args.length() == 1); | 1637 ASSERT(args.length() == 1); |
1591 | 1638 |
1592 CONVERT_CHECKED(JSFunction, f, args[0]); | 1639 CONVERT_CHECKED(JSFunction, f, args[0]); |
1593 return f->shared()->name(); | 1640 return f->shared()->name(); |
1594 } | 1641 } |
1595 | 1642 |
1596 | 1643 |
1597 static Object* Runtime_FunctionSetName(Arguments args) { | 1644 static MaybeObject* Runtime_FunctionSetName(Arguments args) { |
1598 NoHandleAllocation ha; | 1645 NoHandleAllocation ha; |
1599 ASSERT(args.length() == 2); | 1646 ASSERT(args.length() == 2); |
1600 | 1647 |
1601 CONVERT_CHECKED(JSFunction, f, args[0]); | 1648 CONVERT_CHECKED(JSFunction, f, args[0]); |
1602 CONVERT_CHECKED(String, name, args[1]); | 1649 CONVERT_CHECKED(String, name, args[1]); |
1603 f->shared()->set_name(name); | 1650 f->shared()->set_name(name); |
1604 return Heap::undefined_value(); | 1651 return Heap::undefined_value(); |
1605 } | 1652 } |
1606 | 1653 |
1607 | 1654 |
1608 static Object* Runtime_FunctionRemovePrototype(Arguments args) { | 1655 static MaybeObject* Runtime_FunctionRemovePrototype(Arguments args) { |
1609 NoHandleAllocation ha; | 1656 NoHandleAllocation ha; |
1610 ASSERT(args.length() == 1); | 1657 ASSERT(args.length() == 1); |
1611 | 1658 |
1612 CONVERT_CHECKED(JSFunction, f, args[0]); | 1659 CONVERT_CHECKED(JSFunction, f, args[0]); |
1613 Object* obj = f->RemovePrototype(); | 1660 Object* obj; |
1614 if (obj->IsFailure()) return obj; | 1661 { MaybeObject* maybe_obj = f->RemovePrototype(); |
| 1662 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1663 } |
1615 | 1664 |
1616 return Heap::undefined_value(); | 1665 return Heap::undefined_value(); |
1617 } | 1666 } |
1618 | 1667 |
1619 | 1668 |
1620 static Object* Runtime_FunctionGetScript(Arguments args) { | 1669 static MaybeObject* Runtime_FunctionGetScript(Arguments args) { |
1621 HandleScope scope; | 1670 HandleScope scope; |
1622 ASSERT(args.length() == 1); | 1671 ASSERT(args.length() == 1); |
1623 | 1672 |
1624 CONVERT_CHECKED(JSFunction, fun, args[0]); | 1673 CONVERT_CHECKED(JSFunction, fun, args[0]); |
1625 Handle<Object> script = Handle<Object>(fun->shared()->script()); | 1674 Handle<Object> script = Handle<Object>(fun->shared()->script()); |
1626 if (!script->IsScript()) return Heap::undefined_value(); | 1675 if (!script->IsScript()) return Heap::undefined_value(); |
1627 | 1676 |
1628 return *GetScriptWrapper(Handle<Script>::cast(script)); | 1677 return *GetScriptWrapper(Handle<Script>::cast(script)); |
1629 } | 1678 } |
1630 | 1679 |
1631 | 1680 |
1632 static Object* Runtime_FunctionGetSourceCode(Arguments args) { | 1681 static MaybeObject* Runtime_FunctionGetSourceCode(Arguments args) { |
1633 NoHandleAllocation ha; | 1682 NoHandleAllocation ha; |
1634 ASSERT(args.length() == 1); | 1683 ASSERT(args.length() == 1); |
1635 | 1684 |
1636 CONVERT_CHECKED(JSFunction, f, args[0]); | 1685 CONVERT_CHECKED(JSFunction, f, args[0]); |
1637 return f->shared()->GetSourceCode(); | 1686 return f->shared()->GetSourceCode(); |
1638 } | 1687 } |
1639 | 1688 |
1640 | 1689 |
1641 static Object* Runtime_FunctionGetScriptSourcePosition(Arguments args) { | 1690 static MaybeObject* Runtime_FunctionGetScriptSourcePosition(Arguments args) { |
1642 NoHandleAllocation ha; | 1691 NoHandleAllocation ha; |
1643 ASSERT(args.length() == 1); | 1692 ASSERT(args.length() == 1); |
1644 | 1693 |
1645 CONVERT_CHECKED(JSFunction, fun, args[0]); | 1694 CONVERT_CHECKED(JSFunction, fun, args[0]); |
1646 int pos = fun->shared()->start_position(); | 1695 int pos = fun->shared()->start_position(); |
1647 return Smi::FromInt(pos); | 1696 return Smi::FromInt(pos); |
1648 } | 1697 } |
1649 | 1698 |
1650 | 1699 |
1651 static Object* Runtime_FunctionGetPositionForOffset(Arguments args) { | 1700 static MaybeObject* Runtime_FunctionGetPositionForOffset(Arguments args) { |
1652 ASSERT(args.length() == 2); | 1701 ASSERT(args.length() == 2); |
1653 | 1702 |
1654 CONVERT_CHECKED(JSFunction, fun, args[0]); | 1703 CONVERT_CHECKED(JSFunction, fun, args[0]); |
1655 CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]); | 1704 CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]); |
1656 | 1705 |
1657 Code* code = fun->code(); | 1706 Code* code = fun->code(); |
1658 RUNTIME_ASSERT(0 <= offset && offset < code->Size()); | 1707 RUNTIME_ASSERT(0 <= offset && offset < code->Size()); |
1659 | 1708 |
1660 Address pc = code->address() + offset; | 1709 Address pc = code->address() + offset; |
1661 return Smi::FromInt(fun->code()->SourcePosition(pc)); | 1710 return Smi::FromInt(fun->code()->SourcePosition(pc)); |
1662 } | 1711 } |
1663 | 1712 |
1664 | 1713 |
1665 | 1714 |
1666 static Object* Runtime_FunctionSetInstanceClassName(Arguments args) { | 1715 static MaybeObject* Runtime_FunctionSetInstanceClassName(Arguments args) { |
1667 NoHandleAllocation ha; | 1716 NoHandleAllocation ha; |
1668 ASSERT(args.length() == 2); | 1717 ASSERT(args.length() == 2); |
1669 | 1718 |
1670 CONVERT_CHECKED(JSFunction, fun, args[0]); | 1719 CONVERT_CHECKED(JSFunction, fun, args[0]); |
1671 CONVERT_CHECKED(String, name, args[1]); | 1720 CONVERT_CHECKED(String, name, args[1]); |
1672 fun->SetInstanceClassName(name); | 1721 fun->SetInstanceClassName(name); |
1673 return Heap::undefined_value(); | 1722 return Heap::undefined_value(); |
1674 } | 1723 } |
1675 | 1724 |
1676 | 1725 |
1677 static Object* Runtime_FunctionSetLength(Arguments args) { | 1726 static MaybeObject* Runtime_FunctionSetLength(Arguments args) { |
1678 NoHandleAllocation ha; | 1727 NoHandleAllocation ha; |
1679 ASSERT(args.length() == 2); | 1728 ASSERT(args.length() == 2); |
1680 | 1729 |
1681 CONVERT_CHECKED(JSFunction, fun, args[0]); | 1730 CONVERT_CHECKED(JSFunction, fun, args[0]); |
1682 CONVERT_CHECKED(Smi, length, args[1]); | 1731 CONVERT_CHECKED(Smi, length, args[1]); |
1683 fun->shared()->set_length(length->value()); | 1732 fun->shared()->set_length(length->value()); |
1684 return length; | 1733 return length; |
1685 } | 1734 } |
1686 | 1735 |
1687 | 1736 |
1688 static Object* Runtime_FunctionSetPrototype(Arguments args) { | 1737 static MaybeObject* Runtime_FunctionSetPrototype(Arguments args) { |
1689 NoHandleAllocation ha; | 1738 NoHandleAllocation ha; |
1690 ASSERT(args.length() == 2); | 1739 ASSERT(args.length() == 2); |
1691 | 1740 |
1692 CONVERT_CHECKED(JSFunction, fun, args[0]); | 1741 CONVERT_CHECKED(JSFunction, fun, args[0]); |
1693 ASSERT(fun->should_have_prototype()); | 1742 ASSERT(fun->should_have_prototype()); |
1694 Object* obj = Accessors::FunctionSetPrototype(fun, args[1], NULL); | 1743 Object* obj; |
1695 if (obj->IsFailure()) return obj; | 1744 { MaybeObject* maybe_obj = |
| 1745 Accessors::FunctionSetPrototype(fun, args[1], NULL); |
| 1746 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1747 } |
1696 return args[0]; // return TOS | 1748 return args[0]; // return TOS |
1697 } | 1749 } |
1698 | 1750 |
1699 | 1751 |
1700 static Object* Runtime_FunctionIsAPIFunction(Arguments args) { | 1752 static MaybeObject* Runtime_FunctionIsAPIFunction(Arguments args) { |
1701 NoHandleAllocation ha; | 1753 NoHandleAllocation ha; |
1702 ASSERT(args.length() == 1); | 1754 ASSERT(args.length() == 1); |
1703 | 1755 |
1704 CONVERT_CHECKED(JSFunction, f, args[0]); | 1756 CONVERT_CHECKED(JSFunction, f, args[0]); |
1705 return f->shared()->IsApiFunction() ? Heap::true_value() | 1757 return f->shared()->IsApiFunction() ? Heap::true_value() |
1706 : Heap::false_value(); | 1758 : Heap::false_value(); |
1707 } | 1759 } |
1708 | 1760 |
1709 static Object* Runtime_FunctionIsBuiltin(Arguments args) { | 1761 static MaybeObject* Runtime_FunctionIsBuiltin(Arguments args) { |
1710 NoHandleAllocation ha; | 1762 NoHandleAllocation ha; |
1711 ASSERT(args.length() == 1); | 1763 ASSERT(args.length() == 1); |
1712 | 1764 |
1713 CONVERT_CHECKED(JSFunction, f, args[0]); | 1765 CONVERT_CHECKED(JSFunction, f, args[0]); |
1714 return f->IsBuiltin() ? Heap::true_value() : Heap::false_value(); | 1766 return f->IsBuiltin() ? Heap::true_value() : Heap::false_value(); |
1715 } | 1767 } |
1716 | 1768 |
1717 | 1769 |
1718 static Object* Runtime_SetCode(Arguments args) { | 1770 static MaybeObject* Runtime_SetCode(Arguments args) { |
1719 HandleScope scope; | 1771 HandleScope scope; |
1720 ASSERT(args.length() == 2); | 1772 ASSERT(args.length() == 2); |
1721 | 1773 |
1722 CONVERT_ARG_CHECKED(JSFunction, target, 0); | 1774 CONVERT_ARG_CHECKED(JSFunction, target, 0); |
1723 Handle<Object> code = args.at<Object>(1); | 1775 Handle<Object> code = args.at<Object>(1); |
1724 | 1776 |
1725 Handle<Context> context(target->context()); | 1777 Handle<Context> context(target->context()); |
1726 | 1778 |
1727 if (!code->IsNull()) { | 1779 if (!code->IsNull()) { |
1728 RUNTIME_ASSERT(code->IsJSFunction()); | 1780 RUNTIME_ASSERT(code->IsJSFunction()); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1765 // It's okay to skip the write barrier here because the literals | 1817 // It's okay to skip the write barrier here because the literals |
1766 // are guaranteed to be in old space. | 1818 // are guaranteed to be in old space. |
1767 target->set_literals(*literals, SKIP_WRITE_BARRIER); | 1819 target->set_literals(*literals, SKIP_WRITE_BARRIER); |
1768 } | 1820 } |
1769 | 1821 |
1770 target->set_context(*context); | 1822 target->set_context(*context); |
1771 return *target; | 1823 return *target; |
1772 } | 1824 } |
1773 | 1825 |
1774 | 1826 |
1775 static Object* Runtime_SetExpectedNumberOfProperties(Arguments args) { | 1827 static MaybeObject* Runtime_SetExpectedNumberOfProperties(Arguments args) { |
1776 HandleScope scope; | 1828 HandleScope scope; |
1777 ASSERT(args.length() == 2); | 1829 ASSERT(args.length() == 2); |
1778 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 1830 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
1779 CONVERT_SMI_CHECKED(num, args[1]); | 1831 CONVERT_SMI_CHECKED(num, args[1]); |
1780 RUNTIME_ASSERT(num >= 0); | 1832 RUNTIME_ASSERT(num >= 0); |
1781 SetExpectedNofProperties(function, num); | 1833 SetExpectedNofProperties(function, num); |
1782 return Heap::undefined_value(); | 1834 return Heap::undefined_value(); |
1783 } | 1835 } |
1784 | 1836 |
1785 | 1837 |
1786 static Object* CharFromCode(Object* char_code) { | 1838 MUST_USE_RESULT static MaybeObject* CharFromCode(Object* char_code) { |
1787 uint32_t code; | 1839 uint32_t code; |
1788 if (char_code->ToArrayIndex(&code)) { | 1840 if (char_code->ToArrayIndex(&code)) { |
1789 if (code <= 0xffff) { | 1841 if (code <= 0xffff) { |
1790 return Heap::LookupSingleCharacterStringFromCode(code); | 1842 return Heap::LookupSingleCharacterStringFromCode(code); |
1791 } | 1843 } |
1792 } | 1844 } |
1793 return Heap::empty_string(); | 1845 return Heap::empty_string(); |
1794 } | 1846 } |
1795 | 1847 |
1796 | 1848 |
1797 static Object* Runtime_StringCharCodeAt(Arguments args) { | 1849 static MaybeObject* Runtime_StringCharCodeAt(Arguments args) { |
1798 NoHandleAllocation ha; | 1850 NoHandleAllocation ha; |
1799 ASSERT(args.length() == 2); | 1851 ASSERT(args.length() == 2); |
1800 | 1852 |
1801 CONVERT_CHECKED(String, subject, args[0]); | 1853 CONVERT_CHECKED(String, subject, args[0]); |
1802 Object* index = args[1]; | 1854 Object* index = args[1]; |
1803 RUNTIME_ASSERT(index->IsNumber()); | 1855 RUNTIME_ASSERT(index->IsNumber()); |
1804 | 1856 |
1805 uint32_t i = 0; | 1857 uint32_t i = 0; |
1806 if (index->IsSmi()) { | 1858 if (index->IsSmi()) { |
1807 int value = Smi::cast(index)->value(); | 1859 int value = Smi::cast(index)->value(); |
1808 if (value < 0) return Heap::nan_value(); | 1860 if (value < 0) return Heap::nan_value(); |
1809 i = value; | 1861 i = value; |
1810 } else { | 1862 } else { |
1811 ASSERT(index->IsHeapNumber()); | 1863 ASSERT(index->IsHeapNumber()); |
1812 double value = HeapNumber::cast(index)->value(); | 1864 double value = HeapNumber::cast(index)->value(); |
1813 i = static_cast<uint32_t>(DoubleToInteger(value)); | 1865 i = static_cast<uint32_t>(DoubleToInteger(value)); |
1814 } | 1866 } |
1815 | 1867 |
1816 // Flatten the string. If someone wants to get a char at an index | 1868 // Flatten the string. If someone wants to get a char at an index |
1817 // in a cons string, it is likely that more indices will be | 1869 // in a cons string, it is likely that more indices will be |
1818 // accessed. | 1870 // accessed. |
1819 Object* flat = subject->TryFlatten(); | 1871 Object* flat; |
1820 if (flat->IsFailure()) return flat; | 1872 { MaybeObject* maybe_flat = subject->TryFlatten(); |
| 1873 if (!maybe_flat->ToObject(&flat)) return maybe_flat; |
| 1874 } |
1821 subject = String::cast(flat); | 1875 subject = String::cast(flat); |
1822 | 1876 |
1823 if (i >= static_cast<uint32_t>(subject->length())) { | 1877 if (i >= static_cast<uint32_t>(subject->length())) { |
1824 return Heap::nan_value(); | 1878 return Heap::nan_value(); |
1825 } | 1879 } |
1826 | 1880 |
1827 return Smi::FromInt(subject->Get(i)); | 1881 return Smi::FromInt(subject->Get(i)); |
1828 } | 1882 } |
1829 | 1883 |
1830 | 1884 |
1831 static Object* Runtime_CharFromCode(Arguments args) { | 1885 static MaybeObject* Runtime_CharFromCode(Arguments args) { |
1832 NoHandleAllocation ha; | 1886 NoHandleAllocation ha; |
1833 ASSERT(args.length() == 1); | 1887 ASSERT(args.length() == 1); |
1834 return CharFromCode(args[0]); | 1888 return CharFromCode(args[0]); |
1835 } | 1889 } |
1836 | 1890 |
1837 | 1891 |
1838 class FixedArrayBuilder { | 1892 class FixedArrayBuilder { |
1839 public: | 1893 public: |
1840 explicit FixedArrayBuilder(int initial_capacity) | 1894 explicit FixedArrayBuilder(int initial_capacity) |
1841 : array_(Factory::NewFixedArrayWithHoles(initial_capacity)), | 1895 : array_(Factory::NewFixedArrayWithHoles(initial_capacity)), |
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2310 builder->AddString(replacement_substrings_[part.data]); | 2364 builder->AddString(replacement_substrings_[part.data]); |
2311 break; | 2365 break; |
2312 default: | 2366 default: |
2313 UNREACHABLE(); | 2367 UNREACHABLE(); |
2314 } | 2368 } |
2315 } | 2369 } |
2316 } | 2370 } |
2317 | 2371 |
2318 | 2372 |
2319 | 2373 |
2320 static Object* StringReplaceRegExpWithString(String* subject, | 2374 MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithString( |
2321 JSRegExp* regexp, | 2375 String* subject, |
2322 String* replacement, | 2376 JSRegExp* regexp, |
2323 JSArray* last_match_info) { | 2377 String* replacement, |
| 2378 JSArray* last_match_info) { |
2324 ASSERT(subject->IsFlat()); | 2379 ASSERT(subject->IsFlat()); |
2325 ASSERT(replacement->IsFlat()); | 2380 ASSERT(replacement->IsFlat()); |
2326 | 2381 |
2327 HandleScope handles; | 2382 HandleScope handles; |
2328 | 2383 |
2329 int length = subject->length(); | 2384 int length = subject->length(); |
2330 Handle<String> subject_handle(subject); | 2385 Handle<String> subject_handle(subject); |
2331 Handle<JSRegExp> regexp_handle(regexp); | 2386 Handle<JSRegExp> regexp_handle(regexp); |
2332 Handle<String> replacement_handle(replacement); | 2387 Handle<String> replacement_handle(replacement); |
2333 Handle<JSArray> last_match_info_handle(last_match_info); | 2388 Handle<JSArray> last_match_info_handle(last_match_info); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2418 | 2473 |
2419 if (prev < length) { | 2474 if (prev < length) { |
2420 builder.AddSubjectSlice(prev, length); | 2475 builder.AddSubjectSlice(prev, length); |
2421 } | 2476 } |
2422 | 2477 |
2423 return *(builder.ToString()); | 2478 return *(builder.ToString()); |
2424 } | 2479 } |
2425 | 2480 |
2426 | 2481 |
2427 template <typename ResultSeqString> | 2482 template <typename ResultSeqString> |
2428 static Object* StringReplaceRegExpWithEmptyString(String* subject, | 2483 MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString( |
2429 JSRegExp* regexp, | 2484 String* subject, |
2430 JSArray* last_match_info) { | 2485 JSRegExp* regexp, |
| 2486 JSArray* last_match_info) { |
2431 ASSERT(subject->IsFlat()); | 2487 ASSERT(subject->IsFlat()); |
2432 | 2488 |
2433 HandleScope handles; | 2489 HandleScope handles; |
2434 | 2490 |
2435 Handle<String> subject_handle(subject); | 2491 Handle<String> subject_handle(subject); |
2436 Handle<JSRegExp> regexp_handle(regexp); | 2492 Handle<JSRegExp> regexp_handle(regexp); |
2437 Handle<JSArray> last_match_info_handle(last_match_info); | 2493 Handle<JSArray> last_match_info_handle(last_match_info); |
2438 Handle<Object> match = RegExpImpl::Exec(regexp_handle, | 2494 Handle<Object> match = RegExpImpl::Exec(regexp_handle, |
2439 subject_handle, | 2495 subject_handle, |
2440 0, | 2496 0, |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2545 answer->set_length(position); | 2601 answer->set_length(position); |
2546 if (delta == 0) return *answer; | 2602 if (delta == 0) return *answer; |
2547 | 2603 |
2548 Address end_of_string = answer->address() + string_size; | 2604 Address end_of_string = answer->address() + string_size; |
2549 Heap::CreateFillerObjectAt(end_of_string, delta); | 2605 Heap::CreateFillerObjectAt(end_of_string, delta); |
2550 | 2606 |
2551 return *answer; | 2607 return *answer; |
2552 } | 2608 } |
2553 | 2609 |
2554 | 2610 |
2555 static Object* Runtime_StringReplaceRegExpWithString(Arguments args) { | 2611 static MaybeObject* Runtime_StringReplaceRegExpWithString(Arguments args) { |
2556 ASSERT(args.length() == 4); | 2612 ASSERT(args.length() == 4); |
2557 | 2613 |
2558 CONVERT_CHECKED(String, subject, args[0]); | 2614 CONVERT_CHECKED(String, subject, args[0]); |
2559 if (!subject->IsFlat()) { | 2615 if (!subject->IsFlat()) { |
2560 Object* flat_subject = subject->TryFlatten(); | 2616 Object* flat_subject; |
2561 if (flat_subject->IsFailure()) { | 2617 { MaybeObject* maybe_flat_subject = subject->TryFlatten(); |
2562 return flat_subject; | 2618 if (!maybe_flat_subject->ToObject(&flat_subject)) { |
| 2619 return maybe_flat_subject; |
| 2620 } |
2563 } | 2621 } |
2564 subject = String::cast(flat_subject); | 2622 subject = String::cast(flat_subject); |
2565 } | 2623 } |
2566 | 2624 |
2567 CONVERT_CHECKED(String, replacement, args[2]); | 2625 CONVERT_CHECKED(String, replacement, args[2]); |
2568 if (!replacement->IsFlat()) { | 2626 if (!replacement->IsFlat()) { |
2569 Object* flat_replacement = replacement->TryFlatten(); | 2627 Object* flat_replacement; |
2570 if (flat_replacement->IsFailure()) { | 2628 { MaybeObject* maybe_flat_replacement = replacement->TryFlatten(); |
2571 return flat_replacement; | 2629 if (!maybe_flat_replacement->ToObject(&flat_replacement)) { |
| 2630 return maybe_flat_replacement; |
| 2631 } |
2572 } | 2632 } |
2573 replacement = String::cast(flat_replacement); | 2633 replacement = String::cast(flat_replacement); |
2574 } | 2634 } |
2575 | 2635 |
2576 CONVERT_CHECKED(JSRegExp, regexp, args[1]); | 2636 CONVERT_CHECKED(JSRegExp, regexp, args[1]); |
2577 CONVERT_CHECKED(JSArray, last_match_info, args[3]); | 2637 CONVERT_CHECKED(JSArray, last_match_info, args[3]); |
2578 | 2638 |
2579 ASSERT(last_match_info->HasFastElements()); | 2639 ASSERT(last_match_info->HasFastElements()); |
2580 | 2640 |
2581 if (replacement->length() == 0) { | 2641 if (replacement->length() == 0) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2629 return SearchString(seq_sub->ToUC16Vector(), pat_vector, start_index); | 2689 return SearchString(seq_sub->ToUC16Vector(), pat_vector, start_index); |
2630 } | 2690 } |
2631 Vector<const uc16> pat_vector = seq_pat->ToUC16Vector(); | 2691 Vector<const uc16> pat_vector = seq_pat->ToUC16Vector(); |
2632 if (seq_sub->IsAsciiRepresentation()) { | 2692 if (seq_sub->IsAsciiRepresentation()) { |
2633 return SearchString(seq_sub->ToAsciiVector(), pat_vector, start_index); | 2693 return SearchString(seq_sub->ToAsciiVector(), pat_vector, start_index); |
2634 } | 2694 } |
2635 return SearchString(seq_sub->ToUC16Vector(), pat_vector, start_index); | 2695 return SearchString(seq_sub->ToUC16Vector(), pat_vector, start_index); |
2636 } | 2696 } |
2637 | 2697 |
2638 | 2698 |
2639 static Object* Runtime_StringIndexOf(Arguments args) { | 2699 static MaybeObject* Runtime_StringIndexOf(Arguments args) { |
2640 HandleScope scope; // create a new handle scope | 2700 HandleScope scope; // create a new handle scope |
2641 ASSERT(args.length() == 3); | 2701 ASSERT(args.length() == 3); |
2642 | 2702 |
2643 CONVERT_ARG_CHECKED(String, sub, 0); | 2703 CONVERT_ARG_CHECKED(String, sub, 0); |
2644 CONVERT_ARG_CHECKED(String, pat, 1); | 2704 CONVERT_ARG_CHECKED(String, pat, 1); |
2645 | 2705 |
2646 Object* index = args[2]; | 2706 Object* index = args[2]; |
2647 uint32_t start_index; | 2707 uint32_t start_index; |
2648 if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1); | 2708 if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1); |
2649 | 2709 |
(...skipping 30 matching lines...) Expand all Loading... |
2680 } | 2740 } |
2681 j++; | 2741 j++; |
2682 } | 2742 } |
2683 if (j == pattern_length) { | 2743 if (j == pattern_length) { |
2684 return i; | 2744 return i; |
2685 } | 2745 } |
2686 } | 2746 } |
2687 return -1; | 2747 return -1; |
2688 } | 2748 } |
2689 | 2749 |
2690 static Object* Runtime_StringLastIndexOf(Arguments args) { | 2750 static MaybeObject* Runtime_StringLastIndexOf(Arguments args) { |
2691 HandleScope scope; // create a new handle scope | 2751 HandleScope scope; // create a new handle scope |
2692 ASSERT(args.length() == 3); | 2752 ASSERT(args.length() == 3); |
2693 | 2753 |
2694 CONVERT_ARG_CHECKED(String, sub, 0); | 2754 CONVERT_ARG_CHECKED(String, sub, 0); |
2695 CONVERT_ARG_CHECKED(String, pat, 1); | 2755 CONVERT_ARG_CHECKED(String, pat, 1); |
2696 | 2756 |
2697 Object* index = args[2]; | 2757 Object* index = args[2]; |
2698 uint32_t start_index; | 2758 uint32_t start_index; |
2699 if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1); | 2759 if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1); |
2700 | 2760 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2737 position = StringMatchBackwards(sub->ToUC16Vector(), | 2797 position = StringMatchBackwards(sub->ToUC16Vector(), |
2738 pat_vector, | 2798 pat_vector, |
2739 start_index); | 2799 start_index); |
2740 } | 2800 } |
2741 } | 2801 } |
2742 | 2802 |
2743 return Smi::FromInt(position); | 2803 return Smi::FromInt(position); |
2744 } | 2804 } |
2745 | 2805 |
2746 | 2806 |
2747 static Object* Runtime_StringLocaleCompare(Arguments args) { | 2807 static MaybeObject* Runtime_StringLocaleCompare(Arguments args) { |
2748 NoHandleAllocation ha; | 2808 NoHandleAllocation ha; |
2749 ASSERT(args.length() == 2); | 2809 ASSERT(args.length() == 2); |
2750 | 2810 |
2751 CONVERT_CHECKED(String, str1, args[0]); | 2811 CONVERT_CHECKED(String, str1, args[0]); |
2752 CONVERT_CHECKED(String, str2, args[1]); | 2812 CONVERT_CHECKED(String, str2, args[1]); |
2753 | 2813 |
2754 if (str1 == str2) return Smi::FromInt(0); // Equal. | 2814 if (str1 == str2) return Smi::FromInt(0); // Equal. |
2755 int str1_length = str1->length(); | 2815 int str1_length = str1->length(); |
2756 int str2_length = str2->length(); | 2816 int str2_length = str2->length(); |
2757 | 2817 |
(...skipping 25 matching lines...) Expand all Loading... |
2783 for (int i = 0; i < end; i++) { | 2843 for (int i = 0; i < end; i++) { |
2784 uint16_t char1 = buf1.GetNext(); | 2844 uint16_t char1 = buf1.GetNext(); |
2785 uint16_t char2 = buf2.GetNext(); | 2845 uint16_t char2 = buf2.GetNext(); |
2786 if (char1 != char2) return Smi::FromInt(char1 - char2); | 2846 if (char1 != char2) return Smi::FromInt(char1 - char2); |
2787 } | 2847 } |
2788 | 2848 |
2789 return Smi::FromInt(str1_length - str2_length); | 2849 return Smi::FromInt(str1_length - str2_length); |
2790 } | 2850 } |
2791 | 2851 |
2792 | 2852 |
2793 static Object* Runtime_SubString(Arguments args) { | 2853 static MaybeObject* Runtime_SubString(Arguments args) { |
2794 NoHandleAllocation ha; | 2854 NoHandleAllocation ha; |
2795 ASSERT(args.length() == 3); | 2855 ASSERT(args.length() == 3); |
2796 | 2856 |
2797 CONVERT_CHECKED(String, value, args[0]); | 2857 CONVERT_CHECKED(String, value, args[0]); |
2798 Object* from = args[1]; | 2858 Object* from = args[1]; |
2799 Object* to = args[2]; | 2859 Object* to = args[2]; |
2800 int start, end; | 2860 int start, end; |
2801 // We have a fast integer-only case here to avoid a conversion to double in | 2861 // We have a fast integer-only case here to avoid a conversion to double in |
2802 // the common case where from and to are Smis. | 2862 // the common case where from and to are Smis. |
2803 if (from->IsSmi() && to->IsSmi()) { | 2863 if (from->IsSmi() && to->IsSmi()) { |
2804 start = Smi::cast(from)->value(); | 2864 start = Smi::cast(from)->value(); |
2805 end = Smi::cast(to)->value(); | 2865 end = Smi::cast(to)->value(); |
2806 } else { | 2866 } else { |
2807 CONVERT_DOUBLE_CHECKED(from_number, from); | 2867 CONVERT_DOUBLE_CHECKED(from_number, from); |
2808 CONVERT_DOUBLE_CHECKED(to_number, to); | 2868 CONVERT_DOUBLE_CHECKED(to_number, to); |
2809 start = FastD2I(from_number); | 2869 start = FastD2I(from_number); |
2810 end = FastD2I(to_number); | 2870 end = FastD2I(to_number); |
2811 } | 2871 } |
2812 RUNTIME_ASSERT(end >= start); | 2872 RUNTIME_ASSERT(end >= start); |
2813 RUNTIME_ASSERT(start >= 0); | 2873 RUNTIME_ASSERT(start >= 0); |
2814 RUNTIME_ASSERT(end <= value->length()); | 2874 RUNTIME_ASSERT(end <= value->length()); |
2815 Counters::sub_string_runtime.Increment(); | 2875 Counters::sub_string_runtime.Increment(); |
2816 return value->SubString(start, end); | 2876 return value->SubString(start, end); |
2817 } | 2877 } |
2818 | 2878 |
2819 | 2879 |
2820 static Object* Runtime_StringMatch(Arguments args) { | 2880 static MaybeObject* Runtime_StringMatch(Arguments args) { |
2821 ASSERT_EQ(3, args.length()); | 2881 ASSERT_EQ(3, args.length()); |
2822 | 2882 |
2823 CONVERT_ARG_CHECKED(String, subject, 0); | 2883 CONVERT_ARG_CHECKED(String, subject, 0); |
2824 CONVERT_ARG_CHECKED(JSRegExp, regexp, 1); | 2884 CONVERT_ARG_CHECKED(JSRegExp, regexp, 1); |
2825 CONVERT_ARG_CHECKED(JSArray, regexp_info, 2); | 2885 CONVERT_ARG_CHECKED(JSArray, regexp_info, 2); |
2826 HandleScope handles; | 2886 HandleScope handles; |
2827 | 2887 |
2828 Handle<Object> match = RegExpImpl::Exec(regexp, subject, 0, regexp_info); | 2888 Handle<Object> match = RegExpImpl::Exec(regexp, subject, 0, regexp_info); |
2829 | 2889 |
2830 if (match.is_null()) { | 2890 if (match.is_null()) { |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3165 RegExpImpl::SetCapture(elements, i, prev_register_vector[i]); | 3225 RegExpImpl::SetCapture(elements, i, prev_register_vector[i]); |
3166 } | 3226 } |
3167 return RegExpImpl::RE_SUCCESS; | 3227 return RegExpImpl::RE_SUCCESS; |
3168 } | 3228 } |
3169 } | 3229 } |
3170 // No matches at all, return failure or exception result directly. | 3230 // No matches at all, return failure or exception result directly. |
3171 return result; | 3231 return result; |
3172 } | 3232 } |
3173 | 3233 |
3174 | 3234 |
3175 static Object* Runtime_RegExpExecMultiple(Arguments args) { | 3235 static MaybeObject* Runtime_RegExpExecMultiple(Arguments args) { |
3176 ASSERT(args.length() == 4); | 3236 ASSERT(args.length() == 4); |
3177 HandleScope handles; | 3237 HandleScope handles; |
3178 | 3238 |
3179 CONVERT_ARG_CHECKED(String, subject, 1); | 3239 CONVERT_ARG_CHECKED(String, subject, 1); |
3180 if (!subject->IsFlat()) { FlattenString(subject); } | 3240 if (!subject->IsFlat()) { FlattenString(subject); } |
3181 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); | 3241 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); |
3182 CONVERT_ARG_CHECKED(JSArray, last_match_info, 2); | 3242 CONVERT_ARG_CHECKED(JSArray, last_match_info, 2); |
3183 CONVERT_ARG_CHECKED(JSArray, result_array, 3); | 3243 CONVERT_ARG_CHECKED(JSArray, result_array, 3); |
3184 | 3244 |
3185 ASSERT(last_match_info->HasFastElements()); | 3245 ASSERT(last_match_info->HasFastElements()); |
(...skipping 28 matching lines...) Expand all Loading... |
3214 } else { | 3274 } else { |
3215 result = SearchRegExpMultiple(subject, regexp, last_match_info, &builder); | 3275 result = SearchRegExpMultiple(subject, regexp, last_match_info, &builder); |
3216 } | 3276 } |
3217 if (result == RegExpImpl::RE_SUCCESS) return *builder.ToJSArray(result_array); | 3277 if (result == RegExpImpl::RE_SUCCESS) return *builder.ToJSArray(result_array); |
3218 if (result == RegExpImpl::RE_FAILURE) return Heap::null_value(); | 3278 if (result == RegExpImpl::RE_FAILURE) return Heap::null_value(); |
3219 ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION); | 3279 ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION); |
3220 return Failure::Exception(); | 3280 return Failure::Exception(); |
3221 } | 3281 } |
3222 | 3282 |
3223 | 3283 |
3224 static Object* Runtime_NumberToRadixString(Arguments args) { | 3284 static MaybeObject* Runtime_NumberToRadixString(Arguments args) { |
3225 NoHandleAllocation ha; | 3285 NoHandleAllocation ha; |
3226 ASSERT(args.length() == 2); | 3286 ASSERT(args.length() == 2); |
3227 | 3287 |
3228 // Fast case where the result is a one character string. | 3288 // Fast case where the result is a one character string. |
3229 if (args[0]->IsSmi() && args[1]->IsSmi()) { | 3289 if (args[0]->IsSmi() && args[1]->IsSmi()) { |
3230 int value = Smi::cast(args[0])->value(); | 3290 int value = Smi::cast(args[0])->value(); |
3231 int radix = Smi::cast(args[1])->value(); | 3291 int radix = Smi::cast(args[1])->value(); |
3232 if (value >= 0 && value < radix) { | 3292 if (value >= 0 && value < radix) { |
3233 RUNTIME_ASSERT(radix <= 36); | 3293 RUNTIME_ASSERT(radix <= 36); |
3234 // Character array used for conversion. | 3294 // Character array used for conversion. |
(...skipping 10 matching lines...) Expand all Loading... |
3245 if (isinf(value)) { | 3305 if (isinf(value)) { |
3246 if (value < 0) { | 3306 if (value < 0) { |
3247 return Heap::AllocateStringFromAscii(CStrVector("-Infinity")); | 3307 return Heap::AllocateStringFromAscii(CStrVector("-Infinity")); |
3248 } | 3308 } |
3249 return Heap::AllocateStringFromAscii(CStrVector("Infinity")); | 3309 return Heap::AllocateStringFromAscii(CStrVector("Infinity")); |
3250 } | 3310 } |
3251 CONVERT_DOUBLE_CHECKED(radix_number, args[1]); | 3311 CONVERT_DOUBLE_CHECKED(radix_number, args[1]); |
3252 int radix = FastD2I(radix_number); | 3312 int radix = FastD2I(radix_number); |
3253 RUNTIME_ASSERT(2 <= radix && radix <= 36); | 3313 RUNTIME_ASSERT(2 <= radix && radix <= 36); |
3254 char* str = DoubleToRadixCString(value, radix); | 3314 char* str = DoubleToRadixCString(value, radix); |
3255 Object* result = Heap::AllocateStringFromAscii(CStrVector(str)); | 3315 MaybeObject* result = Heap::AllocateStringFromAscii(CStrVector(str)); |
3256 DeleteArray(str); | 3316 DeleteArray(str); |
3257 return result; | 3317 return result; |
3258 } | 3318 } |
3259 | 3319 |
3260 | 3320 |
3261 static Object* Runtime_NumberToFixed(Arguments args) { | 3321 static MaybeObject* Runtime_NumberToFixed(Arguments args) { |
3262 NoHandleAllocation ha; | 3322 NoHandleAllocation ha; |
3263 ASSERT(args.length() == 2); | 3323 ASSERT(args.length() == 2); |
3264 | 3324 |
3265 CONVERT_DOUBLE_CHECKED(value, args[0]); | 3325 CONVERT_DOUBLE_CHECKED(value, args[0]); |
3266 if (isnan(value)) { | 3326 if (isnan(value)) { |
3267 return Heap::AllocateStringFromAscii(CStrVector("NaN")); | 3327 return Heap::AllocateStringFromAscii(CStrVector("NaN")); |
3268 } | 3328 } |
3269 if (isinf(value)) { | 3329 if (isinf(value)) { |
3270 if (value < 0) { | 3330 if (value < 0) { |
3271 return Heap::AllocateStringFromAscii(CStrVector("-Infinity")); | 3331 return Heap::AllocateStringFromAscii(CStrVector("-Infinity")); |
3272 } | 3332 } |
3273 return Heap::AllocateStringFromAscii(CStrVector("Infinity")); | 3333 return Heap::AllocateStringFromAscii(CStrVector("Infinity")); |
3274 } | 3334 } |
3275 CONVERT_DOUBLE_CHECKED(f_number, args[1]); | 3335 CONVERT_DOUBLE_CHECKED(f_number, args[1]); |
3276 int f = FastD2I(f_number); | 3336 int f = FastD2I(f_number); |
3277 RUNTIME_ASSERT(f >= 0); | 3337 RUNTIME_ASSERT(f >= 0); |
3278 char* str = DoubleToFixedCString(value, f); | 3338 char* str = DoubleToFixedCString(value, f); |
3279 Object* res = Heap::AllocateStringFromAscii(CStrVector(str)); | 3339 MaybeObject* result = Heap::AllocateStringFromAscii(CStrVector(str)); |
3280 DeleteArray(str); | 3340 DeleteArray(str); |
3281 return res; | 3341 return result; |
3282 } | 3342 } |
3283 | 3343 |
3284 | 3344 |
3285 static Object* Runtime_NumberToExponential(Arguments args) { | 3345 static MaybeObject* Runtime_NumberToExponential(Arguments args) { |
3286 NoHandleAllocation ha; | 3346 NoHandleAllocation ha; |
3287 ASSERT(args.length() == 2); | 3347 ASSERT(args.length() == 2); |
3288 | 3348 |
3289 CONVERT_DOUBLE_CHECKED(value, args[0]); | 3349 CONVERT_DOUBLE_CHECKED(value, args[0]); |
3290 if (isnan(value)) { | 3350 if (isnan(value)) { |
3291 return Heap::AllocateStringFromAscii(CStrVector("NaN")); | 3351 return Heap::AllocateStringFromAscii(CStrVector("NaN")); |
3292 } | 3352 } |
3293 if (isinf(value)) { | 3353 if (isinf(value)) { |
3294 if (value < 0) { | 3354 if (value < 0) { |
3295 return Heap::AllocateStringFromAscii(CStrVector("-Infinity")); | 3355 return Heap::AllocateStringFromAscii(CStrVector("-Infinity")); |
3296 } | 3356 } |
3297 return Heap::AllocateStringFromAscii(CStrVector("Infinity")); | 3357 return Heap::AllocateStringFromAscii(CStrVector("Infinity")); |
3298 } | 3358 } |
3299 CONVERT_DOUBLE_CHECKED(f_number, args[1]); | 3359 CONVERT_DOUBLE_CHECKED(f_number, args[1]); |
3300 int f = FastD2I(f_number); | 3360 int f = FastD2I(f_number); |
3301 RUNTIME_ASSERT(f >= -1 && f <= 20); | 3361 RUNTIME_ASSERT(f >= -1 && f <= 20); |
3302 char* str = DoubleToExponentialCString(value, f); | 3362 char* str = DoubleToExponentialCString(value, f); |
3303 Object* res = Heap::AllocateStringFromAscii(CStrVector(str)); | 3363 MaybeObject* result = Heap::AllocateStringFromAscii(CStrVector(str)); |
3304 DeleteArray(str); | 3364 DeleteArray(str); |
3305 return res; | 3365 return result; |
3306 } | 3366 } |
3307 | 3367 |
3308 | 3368 |
3309 static Object* Runtime_NumberToPrecision(Arguments args) { | 3369 static MaybeObject* Runtime_NumberToPrecision(Arguments args) { |
3310 NoHandleAllocation ha; | 3370 NoHandleAllocation ha; |
3311 ASSERT(args.length() == 2); | 3371 ASSERT(args.length() == 2); |
3312 | 3372 |
3313 CONVERT_DOUBLE_CHECKED(value, args[0]); | 3373 CONVERT_DOUBLE_CHECKED(value, args[0]); |
3314 if (isnan(value)) { | 3374 if (isnan(value)) { |
3315 return Heap::AllocateStringFromAscii(CStrVector("NaN")); | 3375 return Heap::AllocateStringFromAscii(CStrVector("NaN")); |
3316 } | 3376 } |
3317 if (isinf(value)) { | 3377 if (isinf(value)) { |
3318 if (value < 0) { | 3378 if (value < 0) { |
3319 return Heap::AllocateStringFromAscii(CStrVector("-Infinity")); | 3379 return Heap::AllocateStringFromAscii(CStrVector("-Infinity")); |
3320 } | 3380 } |
3321 return Heap::AllocateStringFromAscii(CStrVector("Infinity")); | 3381 return Heap::AllocateStringFromAscii(CStrVector("Infinity")); |
3322 } | 3382 } |
3323 CONVERT_DOUBLE_CHECKED(f_number, args[1]); | 3383 CONVERT_DOUBLE_CHECKED(f_number, args[1]); |
3324 int f = FastD2I(f_number); | 3384 int f = FastD2I(f_number); |
3325 RUNTIME_ASSERT(f >= 1 && f <= 21); | 3385 RUNTIME_ASSERT(f >= 1 && f <= 21); |
3326 char* str = DoubleToPrecisionCString(value, f); | 3386 char* str = DoubleToPrecisionCString(value, f); |
3327 Object* res = Heap::AllocateStringFromAscii(CStrVector(str)); | 3387 MaybeObject* result = Heap::AllocateStringFromAscii(CStrVector(str)); |
3328 DeleteArray(str); | 3388 DeleteArray(str); |
3329 return res; | 3389 return result; |
3330 } | 3390 } |
3331 | 3391 |
3332 | 3392 |
3333 // Returns a single character string where first character equals | 3393 // Returns a single character string where first character equals |
3334 // string->Get(index). | 3394 // string->Get(index). |
3335 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) { | 3395 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) { |
3336 if (index < static_cast<uint32_t>(string->length())) { | 3396 if (index < static_cast<uint32_t>(string->length())) { |
3337 string->TryFlatten(); | 3397 string->TryFlatten(); |
3338 return LookupSingleCharacterStringFromCode( | 3398 return LookupSingleCharacterStringFromCode( |
3339 string->Get(index)); | 3399 string->Get(index)); |
3340 } | 3400 } |
3341 return Execution::CharAt(string, index); | 3401 return Execution::CharAt(string, index); |
3342 } | 3402 } |
3343 | 3403 |
3344 | 3404 |
3345 Object* Runtime::GetElementOrCharAt(Handle<Object> object, uint32_t index) { | 3405 MaybeObject* Runtime::GetElementOrCharAt(Handle<Object> object, |
| 3406 uint32_t index) { |
3346 // Handle [] indexing on Strings | 3407 // Handle [] indexing on Strings |
3347 if (object->IsString()) { | 3408 if (object->IsString()) { |
3348 Handle<Object> result = GetCharAt(Handle<String>::cast(object), index); | 3409 Handle<Object> result = GetCharAt(Handle<String>::cast(object), index); |
3349 if (!result->IsUndefined()) return *result; | 3410 if (!result->IsUndefined()) return *result; |
3350 } | 3411 } |
3351 | 3412 |
3352 // Handle [] indexing on String objects | 3413 // Handle [] indexing on String objects |
3353 if (object->IsStringObjectWithCharacterAt(index)) { | 3414 if (object->IsStringObjectWithCharacterAt(index)) { |
3354 Handle<JSValue> js_value = Handle<JSValue>::cast(object); | 3415 Handle<JSValue> js_value = Handle<JSValue>::cast(object); |
3355 Handle<Object> result = | 3416 Handle<Object> result = |
3356 GetCharAt(Handle<String>(String::cast(js_value->value())), index); | 3417 GetCharAt(Handle<String>(String::cast(js_value->value())), index); |
3357 if (!result->IsUndefined()) return *result; | 3418 if (!result->IsUndefined()) return *result; |
3358 } | 3419 } |
3359 | 3420 |
3360 if (object->IsString() || object->IsNumber() || object->IsBoolean()) { | 3421 if (object->IsString() || object->IsNumber() || object->IsBoolean()) { |
3361 Handle<Object> prototype = GetPrototype(object); | 3422 Handle<Object> prototype = GetPrototype(object); |
3362 return prototype->GetElement(index); | 3423 return prototype->GetElement(index); |
3363 } | 3424 } |
3364 | 3425 |
3365 return GetElement(object, index); | 3426 return GetElement(object, index); |
3366 } | 3427 } |
3367 | 3428 |
3368 | 3429 |
3369 Object* Runtime::GetElement(Handle<Object> object, uint32_t index) { | 3430 MaybeObject* Runtime::GetElement(Handle<Object> object, uint32_t index) { |
3370 return object->GetElement(index); | 3431 return object->GetElement(index); |
3371 } | 3432 } |
3372 | 3433 |
3373 | 3434 |
3374 Object* Runtime::GetObjectProperty(Handle<Object> object, Handle<Object> key) { | 3435 MaybeObject* Runtime::GetObjectProperty(Handle<Object> object, |
| 3436 Handle<Object> key) { |
3375 HandleScope scope; | 3437 HandleScope scope; |
3376 | 3438 |
3377 if (object->IsUndefined() || object->IsNull()) { | 3439 if (object->IsUndefined() || object->IsNull()) { |
3378 Handle<Object> args[2] = { key, object }; | 3440 Handle<Object> args[2] = { key, object }; |
3379 Handle<Object> error = | 3441 Handle<Object> error = |
3380 Factory::NewTypeError("non_object_property_load", | 3442 Factory::NewTypeError("non_object_property_load", |
3381 HandleVector(args, 2)); | 3443 HandleVector(args, 2)); |
3382 return Top::Throw(*error); | 3444 return Top::Throw(*error); |
3383 } | 3445 } |
3384 | 3446 |
(...skipping 19 matching lines...) Expand all Loading... |
3404 // the element if so. | 3466 // the element if so. |
3405 if (name->AsArrayIndex(&index)) { | 3467 if (name->AsArrayIndex(&index)) { |
3406 return GetElementOrCharAt(object, index); | 3468 return GetElementOrCharAt(object, index); |
3407 } else { | 3469 } else { |
3408 PropertyAttributes attr; | 3470 PropertyAttributes attr; |
3409 return object->GetProperty(*name, &attr); | 3471 return object->GetProperty(*name, &attr); |
3410 } | 3472 } |
3411 } | 3473 } |
3412 | 3474 |
3413 | 3475 |
3414 static Object* Runtime_GetProperty(Arguments args) { | 3476 static MaybeObject* Runtime_GetProperty(Arguments args) { |
3415 NoHandleAllocation ha; | 3477 NoHandleAllocation ha; |
3416 ASSERT(args.length() == 2); | 3478 ASSERT(args.length() == 2); |
3417 | 3479 |
3418 Handle<Object> object = args.at<Object>(0); | 3480 Handle<Object> object = args.at<Object>(0); |
3419 Handle<Object> key = args.at<Object>(1); | 3481 Handle<Object> key = args.at<Object>(1); |
3420 | 3482 |
3421 return Runtime::GetObjectProperty(object, key); | 3483 return Runtime::GetObjectProperty(object, key); |
3422 } | 3484 } |
3423 | 3485 |
3424 | 3486 |
3425 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric. | 3487 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric. |
3426 static Object* Runtime_KeyedGetProperty(Arguments args) { | 3488 static MaybeObject* Runtime_KeyedGetProperty(Arguments args) { |
3427 NoHandleAllocation ha; | 3489 NoHandleAllocation ha; |
3428 ASSERT(args.length() == 2); | 3490 ASSERT(args.length() == 2); |
3429 | 3491 |
3430 // Fast cases for getting named properties of the receiver JSObject | 3492 // Fast cases for getting named properties of the receiver JSObject |
3431 // itself. | 3493 // itself. |
3432 // | 3494 // |
3433 // The global proxy objects has to be excluded since LocalLookup on | 3495 // The global proxy objects has to be excluded since LocalLookup on |
3434 // the global proxy object can return a valid result even though the | 3496 // the global proxy object can return a valid result even though the |
3435 // global proxy object never has properties. This is the case | 3497 // global proxy object never has properties. This is the case |
3436 // because the global proxy object forwards everything to its hidden | 3498 // because the global proxy object forwards everything to its hidden |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3481 Handle<Object> result = GetCharAt(str, index); | 3543 Handle<Object> result = GetCharAt(str, index); |
3482 return *result; | 3544 return *result; |
3483 } | 3545 } |
3484 | 3546 |
3485 // Fall back to GetObjectProperty. | 3547 // Fall back to GetObjectProperty. |
3486 return Runtime::GetObjectProperty(args.at<Object>(0), | 3548 return Runtime::GetObjectProperty(args.at<Object>(0), |
3487 args.at<Object>(1)); | 3549 args.at<Object>(1)); |
3488 } | 3550 } |
3489 | 3551 |
3490 | 3552 |
3491 static Object* Runtime_DefineOrRedefineAccessorProperty(Arguments args) { | 3553 static MaybeObject* Runtime_DefineOrRedefineAccessorProperty(Arguments args) { |
3492 ASSERT(args.length() == 5); | 3554 ASSERT(args.length() == 5); |
3493 HandleScope scope; | 3555 HandleScope scope; |
3494 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 3556 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
3495 CONVERT_CHECKED(String, name, args[1]); | 3557 CONVERT_CHECKED(String, name, args[1]); |
3496 CONVERT_CHECKED(Smi, flag_setter, args[2]); | 3558 CONVERT_CHECKED(Smi, flag_setter, args[2]); |
3497 CONVERT_CHECKED(JSFunction, fun, args[3]); | 3559 CONVERT_CHECKED(JSFunction, fun, args[3]); |
3498 CONVERT_CHECKED(Smi, flag_attr, args[4]); | 3560 CONVERT_CHECKED(Smi, flag_attr, args[4]); |
3499 int unchecked = flag_attr->value(); | 3561 int unchecked = flag_attr->value(); |
3500 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 3562 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
3501 RUNTIME_ASSERT(!obj->IsNull()); | 3563 RUNTIME_ASSERT(!obj->IsNull()); |
3502 LookupResult result; | 3564 LookupResult result; |
3503 obj->LocalLookupRealNamedProperty(name, &result); | 3565 obj->LocalLookupRealNamedProperty(name, &result); |
3504 | 3566 |
3505 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); | 3567 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
3506 // If an existing property is either FIELD, NORMAL or CONSTANT_FUNCTION | 3568 // If an existing property is either FIELD, NORMAL or CONSTANT_FUNCTION |
3507 // delete it to avoid running into trouble in DefineAccessor, which | 3569 // delete it to avoid running into trouble in DefineAccessor, which |
3508 // handles this incorrectly if the property is readonly (does nothing) | 3570 // handles this incorrectly if the property is readonly (does nothing) |
3509 if (result.IsProperty() && | 3571 if (result.IsProperty() && |
3510 (result.type() == FIELD || result.type() == NORMAL | 3572 (result.type() == FIELD || result.type() == NORMAL |
3511 || result.type() == CONSTANT_FUNCTION)) { | 3573 || result.type() == CONSTANT_FUNCTION)) { |
3512 Object* ok = obj->DeleteProperty(name, JSObject::NORMAL_DELETION); | 3574 Object* ok; |
3513 if (ok->IsFailure()) return ok; | 3575 { MaybeObject* maybe_ok = |
| 3576 obj->DeleteProperty(name, JSObject::NORMAL_DELETION); |
| 3577 if (!maybe_ok->ToObject(&ok)) return maybe_ok; |
| 3578 } |
3514 } | 3579 } |
3515 return obj->DefineAccessor(name, flag_setter->value() == 0, fun, attr); | 3580 return obj->DefineAccessor(name, flag_setter->value() == 0, fun, attr); |
3516 } | 3581 } |
3517 | 3582 |
3518 static Object* Runtime_DefineOrRedefineDataProperty(Arguments args) { | 3583 static MaybeObject* Runtime_DefineOrRedefineDataProperty(Arguments args) { |
3519 ASSERT(args.length() == 4); | 3584 ASSERT(args.length() == 4); |
3520 HandleScope scope; | 3585 HandleScope scope; |
3521 CONVERT_ARG_CHECKED(JSObject, js_object, 0); | 3586 CONVERT_ARG_CHECKED(JSObject, js_object, 0); |
3522 CONVERT_ARG_CHECKED(String, name, 1); | 3587 CONVERT_ARG_CHECKED(String, name, 1); |
3523 Handle<Object> obj_value = args.at<Object>(2); | 3588 Handle<Object> obj_value = args.at<Object>(2); |
3524 | 3589 |
3525 CONVERT_CHECKED(Smi, flag, args[3]); | 3590 CONVERT_CHECKED(Smi, flag, args[3]); |
3526 int unchecked = flag->value(); | 3591 int unchecked = flag->value(); |
3527 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 3592 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
3528 | 3593 |
3529 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); | 3594 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
3530 | 3595 |
3531 // Check if this is an element. | 3596 // Check if this is an element. |
3532 uint32_t index; | 3597 uint32_t index; |
3533 bool is_element = name->AsArrayIndex(&index); | 3598 bool is_element = name->AsArrayIndex(&index); |
3534 | 3599 |
3535 // Special case for elements if any of the flags are true. | 3600 // Special case for elements if any of the flags are true. |
3536 // If elements are in fast case we always implicitly assume that: | 3601 // If elements are in fast case we always implicitly assume that: |
3537 // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false. | 3602 // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false. |
3538 if (((unchecked & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) && | 3603 if (((unchecked & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) && |
3539 is_element) { | 3604 is_element) { |
3540 // Normalize the elements to enable attributes on the property. | 3605 // Normalize the elements to enable attributes on the property. |
3541 js_object->NormalizeElements(); | 3606 NormalizeElements(js_object); |
3542 NumberDictionary* dictionary = js_object->element_dictionary(); | 3607 Handle<NumberDictionary> dictionary(js_object->element_dictionary()); |
3543 // Make sure that we never go back to fast case. | 3608 // Make sure that we never go back to fast case. |
3544 dictionary->set_requires_slow_elements(); | 3609 dictionary->set_requires_slow_elements(); |
3545 PropertyDetails details = PropertyDetails(attr, NORMAL); | 3610 PropertyDetails details = PropertyDetails(attr, NORMAL); |
3546 dictionary->Set(index, *obj_value, details); | 3611 NumberDictionarySet(dictionary, index, obj_value, details); |
3547 } | 3612 } |
3548 | 3613 |
3549 LookupResult result; | 3614 LookupResult result; |
3550 js_object->LocalLookupRealNamedProperty(*name, &result); | 3615 js_object->LocalLookupRealNamedProperty(*name, &result); |
3551 | 3616 |
3552 // Take special care when attributes are different and there is already | 3617 // Take special care when attributes are different and there is already |
3553 // a property. For simplicity we normalize the property which enables us | 3618 // a property. For simplicity we normalize the property which enables us |
3554 // to not worry about changing the instance_descriptor and creating a new | 3619 // to not worry about changing the instance_descriptor and creating a new |
3555 // map. The current version of SetObjectProperty does not handle attributes | 3620 // map. The current version of SetObjectProperty does not handle attributes |
3556 // correctly in the case where a property is a field and is reset with | 3621 // correctly in the case where a property is a field and is reset with |
3557 // new attributes. | 3622 // new attributes. |
3558 if (result.IsProperty() && attr != result.GetAttributes()) { | 3623 if (result.IsProperty() && attr != result.GetAttributes()) { |
3559 // New attributes - normalize to avoid writing to instance descriptor | 3624 // New attributes - normalize to avoid writing to instance descriptor |
3560 js_object->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 3625 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); |
3561 // Use IgnoreAttributes version since a readonly property may be | 3626 // Use IgnoreAttributes version since a readonly property may be |
3562 // overridden and SetProperty does not allow this. | 3627 // overridden and SetProperty does not allow this. |
3563 return js_object->IgnoreAttributesAndSetLocalProperty(*name, | 3628 return js_object->IgnoreAttributesAndSetLocalProperty(*name, |
3564 *obj_value, | 3629 *obj_value, |
3565 attr); | 3630 attr); |
3566 } | 3631 } |
3567 | 3632 |
3568 return Runtime::SetObjectProperty(js_object, name, obj_value, attr); | 3633 return Runtime::SetObjectProperty(js_object, name, obj_value, attr); |
3569 } | 3634 } |
3570 | 3635 |
3571 | 3636 |
3572 Object* Runtime::SetObjectProperty(Handle<Object> object, | 3637 MaybeObject* Runtime::SetObjectProperty(Handle<Object> object, |
3573 Handle<Object> key, | 3638 Handle<Object> key, |
3574 Handle<Object> value, | 3639 Handle<Object> value, |
3575 PropertyAttributes attr) { | 3640 PropertyAttributes attr) { |
3576 HandleScope scope; | 3641 HandleScope scope; |
3577 | 3642 |
3578 if (object->IsUndefined() || object->IsNull()) { | 3643 if (object->IsUndefined() || object->IsNull()) { |
3579 Handle<Object> args[2] = { key, object }; | 3644 Handle<Object> args[2] = { key, object }; |
3580 Handle<Object> error = | 3645 Handle<Object> error = |
3581 Factory::NewTypeError("non_object_property_store", | 3646 Factory::NewTypeError("non_object_property_store", |
3582 HandleVector(args, 2)); | 3647 HandleVector(args, 2)); |
3583 return Top::Throw(*error); | 3648 return Top::Throw(*error); |
3584 } | 3649 } |
3585 | 3650 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3627 Handle<String> name = Handle<String>::cast(converted); | 3692 Handle<String> name = Handle<String>::cast(converted); |
3628 | 3693 |
3629 if (name->AsArrayIndex(&index)) { | 3694 if (name->AsArrayIndex(&index)) { |
3630 return js_object->SetElement(index, *value); | 3695 return js_object->SetElement(index, *value); |
3631 } else { | 3696 } else { |
3632 return js_object->SetProperty(*name, *value, attr); | 3697 return js_object->SetProperty(*name, *value, attr); |
3633 } | 3698 } |
3634 } | 3699 } |
3635 | 3700 |
3636 | 3701 |
3637 Object* Runtime::ForceSetObjectProperty(Handle<JSObject> js_object, | 3702 MaybeObject* Runtime::ForceSetObjectProperty(Handle<JSObject> js_object, |
3638 Handle<Object> key, | 3703 Handle<Object> key, |
3639 Handle<Object> value, | 3704 Handle<Object> value, |
3640 PropertyAttributes attr) { | 3705 PropertyAttributes attr) { |
3641 HandleScope scope; | 3706 HandleScope scope; |
3642 | 3707 |
3643 // Check if the given key is an array index. | 3708 // Check if the given key is an array index. |
3644 uint32_t index; | 3709 uint32_t index; |
3645 if (key->ToArrayIndex(&index)) { | 3710 if (key->ToArrayIndex(&index)) { |
3646 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters | 3711 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters |
3647 // of a string using [] notation. We need to support this too in | 3712 // of a string using [] notation. We need to support this too in |
3648 // JavaScript. | 3713 // JavaScript. |
3649 // In the case of a String object we just need to redirect the assignment to | 3714 // In the case of a String object we just need to redirect the assignment to |
3650 // the underlying string if the index is in range. Since the underlying | 3715 // the underlying string if the index is in range. Since the underlying |
(...skipping 25 matching lines...) Expand all Loading... |
3676 Handle<String> name = Handle<String>::cast(converted); | 3741 Handle<String> name = Handle<String>::cast(converted); |
3677 | 3742 |
3678 if (name->AsArrayIndex(&index)) { | 3743 if (name->AsArrayIndex(&index)) { |
3679 return js_object->SetElement(index, *value); | 3744 return js_object->SetElement(index, *value); |
3680 } else { | 3745 } else { |
3681 return js_object->IgnoreAttributesAndSetLocalProperty(*name, *value, attr); | 3746 return js_object->IgnoreAttributesAndSetLocalProperty(*name, *value, attr); |
3682 } | 3747 } |
3683 } | 3748 } |
3684 | 3749 |
3685 | 3750 |
3686 Object* Runtime::ForceDeleteObjectProperty(Handle<JSObject> js_object, | 3751 MaybeObject* Runtime::ForceDeleteObjectProperty(Handle<JSObject> js_object, |
3687 Handle<Object> key) { | 3752 Handle<Object> key) { |
3688 HandleScope scope; | 3753 HandleScope scope; |
3689 | 3754 |
3690 // Check if the given key is an array index. | 3755 // Check if the given key is an array index. |
3691 uint32_t index; | 3756 uint32_t index; |
3692 if (key->ToArrayIndex(&index)) { | 3757 if (key->ToArrayIndex(&index)) { |
3693 // In Firefox/SpiderMonkey, Safari and Opera you can access the | 3758 // In Firefox/SpiderMonkey, Safari and Opera you can access the |
3694 // characters of a string using [] notation. In the case of a | 3759 // characters of a string using [] notation. In the case of a |
3695 // String object we just need to redirect the deletion to the | 3760 // String object we just need to redirect the deletion to the |
3696 // underlying string if the index is in range. Since the | 3761 // underlying string if the index is in range. Since the |
3697 // underlying string does nothing with the deletion, we can ignore | 3762 // underlying string does nothing with the deletion, we can ignore |
(...skipping 14 matching lines...) Expand all Loading... |
3712 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); | 3777 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); |
3713 if (has_pending_exception) return Failure::Exception(); | 3778 if (has_pending_exception) return Failure::Exception(); |
3714 key_string = Handle<String>::cast(converted); | 3779 key_string = Handle<String>::cast(converted); |
3715 } | 3780 } |
3716 | 3781 |
3717 key_string->TryFlatten(); | 3782 key_string->TryFlatten(); |
3718 return js_object->DeleteProperty(*key_string, JSObject::FORCE_DELETION); | 3783 return js_object->DeleteProperty(*key_string, JSObject::FORCE_DELETION); |
3719 } | 3784 } |
3720 | 3785 |
3721 | 3786 |
3722 static Object* Runtime_SetProperty(Arguments args) { | 3787 static MaybeObject* Runtime_SetProperty(Arguments args) { |
3723 NoHandleAllocation ha; | 3788 NoHandleAllocation ha; |
3724 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); | 3789 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); |
3725 | 3790 |
3726 Handle<Object> object = args.at<Object>(0); | 3791 Handle<Object> object = args.at<Object>(0); |
3727 Handle<Object> key = args.at<Object>(1); | 3792 Handle<Object> key = args.at<Object>(1); |
3728 Handle<Object> value = args.at<Object>(2); | 3793 Handle<Object> value = args.at<Object>(2); |
3729 | 3794 |
3730 // Compute attributes. | 3795 // Compute attributes. |
3731 PropertyAttributes attributes = NONE; | 3796 PropertyAttributes attributes = NONE; |
3732 if (args.length() == 4) { | 3797 if (args.length() == 4) { |
3733 CONVERT_CHECKED(Smi, value_obj, args[3]); | 3798 CONVERT_CHECKED(Smi, value_obj, args[3]); |
3734 int unchecked_value = value_obj->value(); | 3799 int unchecked_value = value_obj->value(); |
3735 // Only attribute bits should be set. | 3800 // Only attribute bits should be set. |
3736 RUNTIME_ASSERT( | 3801 RUNTIME_ASSERT( |
3737 (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 3802 (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
3738 attributes = static_cast<PropertyAttributes>(unchecked_value); | 3803 attributes = static_cast<PropertyAttributes>(unchecked_value); |
3739 } | 3804 } |
3740 return Runtime::SetObjectProperty(object, key, value, attributes); | 3805 return Runtime::SetObjectProperty(object, key, value, attributes); |
3741 } | 3806 } |
3742 | 3807 |
3743 | 3808 |
3744 // Set a local property, even if it is READ_ONLY. If the property does not | 3809 // Set a local property, even if it is READ_ONLY. If the property does not |
3745 // exist, it will be added with attributes NONE. | 3810 // exist, it will be added with attributes NONE. |
3746 static Object* Runtime_IgnoreAttributesAndSetProperty(Arguments args) { | 3811 static MaybeObject* Runtime_IgnoreAttributesAndSetProperty(Arguments args) { |
3747 NoHandleAllocation ha; | 3812 NoHandleAllocation ha; |
3748 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); | 3813 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); |
3749 CONVERT_CHECKED(JSObject, object, args[0]); | 3814 CONVERT_CHECKED(JSObject, object, args[0]); |
3750 CONVERT_CHECKED(String, name, args[1]); | 3815 CONVERT_CHECKED(String, name, args[1]); |
3751 // Compute attributes. | 3816 // Compute attributes. |
3752 PropertyAttributes attributes = NONE; | 3817 PropertyAttributes attributes = NONE; |
3753 if (args.length() == 4) { | 3818 if (args.length() == 4) { |
3754 CONVERT_CHECKED(Smi, value_obj, args[3]); | 3819 CONVERT_CHECKED(Smi, value_obj, args[3]); |
3755 int unchecked_value = value_obj->value(); | 3820 int unchecked_value = value_obj->value(); |
3756 // Only attribute bits should be set. | 3821 // Only attribute bits should be set. |
3757 RUNTIME_ASSERT( | 3822 RUNTIME_ASSERT( |
3758 (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 3823 (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
3759 attributes = static_cast<PropertyAttributes>(unchecked_value); | 3824 attributes = static_cast<PropertyAttributes>(unchecked_value); |
3760 } | 3825 } |
3761 | 3826 |
3762 return object-> | 3827 return object-> |
3763 IgnoreAttributesAndSetLocalProperty(name, args[2], attributes); | 3828 IgnoreAttributesAndSetLocalProperty(name, args[2], attributes); |
3764 } | 3829 } |
3765 | 3830 |
3766 | 3831 |
3767 static Object* Runtime_DeleteProperty(Arguments args) { | 3832 static MaybeObject* Runtime_DeleteProperty(Arguments args) { |
3768 NoHandleAllocation ha; | 3833 NoHandleAllocation ha; |
3769 ASSERT(args.length() == 2); | 3834 ASSERT(args.length() == 2); |
3770 | 3835 |
3771 CONVERT_CHECKED(JSObject, object, args[0]); | 3836 CONVERT_CHECKED(JSObject, object, args[0]); |
3772 CONVERT_CHECKED(String, key, args[1]); | 3837 CONVERT_CHECKED(String, key, args[1]); |
3773 return object->DeleteProperty(key, JSObject::NORMAL_DELETION); | 3838 return object->DeleteProperty(key, JSObject::NORMAL_DELETION); |
3774 } | 3839 } |
3775 | 3840 |
3776 | 3841 |
3777 static Object* HasLocalPropertyImplementation(Handle<JSObject> object, | 3842 static Object* HasLocalPropertyImplementation(Handle<JSObject> object, |
3778 Handle<String> key) { | 3843 Handle<String> key) { |
3779 if (object->HasLocalProperty(*key)) return Heap::true_value(); | 3844 if (object->HasLocalProperty(*key)) return Heap::true_value(); |
3780 // Handle hidden prototypes. If there's a hidden prototype above this thing | 3845 // Handle hidden prototypes. If there's a hidden prototype above this thing |
3781 // then we have to check it for properties, because they are supposed to | 3846 // then we have to check it for properties, because they are supposed to |
3782 // look like they are on this object. | 3847 // look like they are on this object. |
3783 Handle<Object> proto(object->GetPrototype()); | 3848 Handle<Object> proto(object->GetPrototype()); |
3784 if (proto->IsJSObject() && | 3849 if (proto->IsJSObject() && |
3785 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) { | 3850 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) { |
3786 return HasLocalPropertyImplementation(Handle<JSObject>::cast(proto), key); | 3851 return HasLocalPropertyImplementation(Handle<JSObject>::cast(proto), key); |
3787 } | 3852 } |
3788 return Heap::false_value(); | 3853 return Heap::false_value(); |
3789 } | 3854 } |
3790 | 3855 |
3791 | 3856 |
3792 static Object* Runtime_HasLocalProperty(Arguments args) { | 3857 static MaybeObject* Runtime_HasLocalProperty(Arguments args) { |
3793 NoHandleAllocation ha; | 3858 NoHandleAllocation ha; |
3794 ASSERT(args.length() == 2); | 3859 ASSERT(args.length() == 2); |
3795 CONVERT_CHECKED(String, key, args[1]); | 3860 CONVERT_CHECKED(String, key, args[1]); |
3796 | 3861 |
3797 Object* obj = args[0]; | 3862 Object* obj = args[0]; |
3798 // Only JS objects can have properties. | 3863 // Only JS objects can have properties. |
3799 if (obj->IsJSObject()) { | 3864 if (obj->IsJSObject()) { |
3800 JSObject* object = JSObject::cast(obj); | 3865 JSObject* object = JSObject::cast(obj); |
3801 // Fast case - no interceptors. | 3866 // Fast case - no interceptors. |
3802 if (object->HasRealNamedProperty(key)) return Heap::true_value(); | 3867 if (object->HasRealNamedProperty(key)) return Heap::true_value(); |
3803 // Slow case. Either it's not there or we have an interceptor. We should | 3868 // Slow case. Either it's not there or we have an interceptor. We should |
3804 // have handles for this kind of deal. | 3869 // have handles for this kind of deal. |
3805 HandleScope scope; | 3870 HandleScope scope; |
3806 return HasLocalPropertyImplementation(Handle<JSObject>(object), | 3871 return HasLocalPropertyImplementation(Handle<JSObject>(object), |
3807 Handle<String>(key)); | 3872 Handle<String>(key)); |
3808 } else if (obj->IsString()) { | 3873 } else if (obj->IsString()) { |
3809 // Well, there is one exception: Handle [] on strings. | 3874 // Well, there is one exception: Handle [] on strings. |
3810 uint32_t index; | 3875 uint32_t index; |
3811 if (key->AsArrayIndex(&index)) { | 3876 if (key->AsArrayIndex(&index)) { |
3812 String* string = String::cast(obj); | 3877 String* string = String::cast(obj); |
3813 if (index < static_cast<uint32_t>(string->length())) | 3878 if (index < static_cast<uint32_t>(string->length())) |
3814 return Heap::true_value(); | 3879 return Heap::true_value(); |
3815 } | 3880 } |
3816 } | 3881 } |
3817 return Heap::false_value(); | 3882 return Heap::false_value(); |
3818 } | 3883 } |
3819 | 3884 |
3820 | 3885 |
3821 static Object* Runtime_HasProperty(Arguments args) { | 3886 static MaybeObject* Runtime_HasProperty(Arguments args) { |
3822 NoHandleAllocation na; | 3887 NoHandleAllocation na; |
3823 ASSERT(args.length() == 2); | 3888 ASSERT(args.length() == 2); |
3824 | 3889 |
3825 // Only JS objects can have properties. | 3890 // Only JS objects can have properties. |
3826 if (args[0]->IsJSObject()) { | 3891 if (args[0]->IsJSObject()) { |
3827 JSObject* object = JSObject::cast(args[0]); | 3892 JSObject* object = JSObject::cast(args[0]); |
3828 CONVERT_CHECKED(String, key, args[1]); | 3893 CONVERT_CHECKED(String, key, args[1]); |
3829 if (object->HasProperty(key)) return Heap::true_value(); | 3894 if (object->HasProperty(key)) return Heap::true_value(); |
3830 } | 3895 } |
3831 return Heap::false_value(); | 3896 return Heap::false_value(); |
3832 } | 3897 } |
3833 | 3898 |
3834 | 3899 |
3835 static Object* Runtime_HasElement(Arguments args) { | 3900 static MaybeObject* Runtime_HasElement(Arguments args) { |
3836 NoHandleAllocation na; | 3901 NoHandleAllocation na; |
3837 ASSERT(args.length() == 2); | 3902 ASSERT(args.length() == 2); |
3838 | 3903 |
3839 // Only JS objects can have elements. | 3904 // Only JS objects can have elements. |
3840 if (args[0]->IsJSObject()) { | 3905 if (args[0]->IsJSObject()) { |
3841 JSObject* object = JSObject::cast(args[0]); | 3906 JSObject* object = JSObject::cast(args[0]); |
3842 CONVERT_CHECKED(Smi, index_obj, args[1]); | 3907 CONVERT_CHECKED(Smi, index_obj, args[1]); |
3843 uint32_t index = index_obj->value(); | 3908 uint32_t index = index_obj->value(); |
3844 if (object->HasElement(index)) return Heap::true_value(); | 3909 if (object->HasElement(index)) return Heap::true_value(); |
3845 } | 3910 } |
3846 return Heap::false_value(); | 3911 return Heap::false_value(); |
3847 } | 3912 } |
3848 | 3913 |
3849 | 3914 |
3850 static Object* Runtime_IsPropertyEnumerable(Arguments args) { | 3915 static MaybeObject* Runtime_IsPropertyEnumerable(Arguments args) { |
3851 NoHandleAllocation ha; | 3916 NoHandleAllocation ha; |
3852 ASSERT(args.length() == 2); | 3917 ASSERT(args.length() == 2); |
3853 | 3918 |
3854 CONVERT_CHECKED(JSObject, object, args[0]); | 3919 CONVERT_CHECKED(JSObject, object, args[0]); |
3855 CONVERT_CHECKED(String, key, args[1]); | 3920 CONVERT_CHECKED(String, key, args[1]); |
3856 | 3921 |
3857 uint32_t index; | 3922 uint32_t index; |
3858 if (key->AsArrayIndex(&index)) { | 3923 if (key->AsArrayIndex(&index)) { |
3859 return Heap::ToBoolean(object->HasElement(index)); | 3924 return Heap::ToBoolean(object->HasElement(index)); |
3860 } | 3925 } |
3861 | 3926 |
3862 PropertyAttributes att = object->GetLocalPropertyAttribute(key); | 3927 PropertyAttributes att = object->GetLocalPropertyAttribute(key); |
3863 return Heap::ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); | 3928 return Heap::ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); |
3864 } | 3929 } |
3865 | 3930 |
3866 | 3931 |
3867 static Object* Runtime_GetPropertyNames(Arguments args) { | 3932 static MaybeObject* Runtime_GetPropertyNames(Arguments args) { |
3868 HandleScope scope; | 3933 HandleScope scope; |
3869 ASSERT(args.length() == 1); | 3934 ASSERT(args.length() == 1); |
3870 CONVERT_ARG_CHECKED(JSObject, object, 0); | 3935 CONVERT_ARG_CHECKED(JSObject, object, 0); |
3871 return *GetKeysFor(object); | 3936 return *GetKeysFor(object); |
3872 } | 3937 } |
3873 | 3938 |
3874 | 3939 |
3875 // Returns either a FixedArray as Runtime_GetPropertyNames, | 3940 // Returns either a FixedArray as Runtime_GetPropertyNames, |
3876 // or, if the given object has an enum cache that contains | 3941 // or, if the given object has an enum cache that contains |
3877 // all enumerable properties of the object and its prototypes | 3942 // all enumerable properties of the object and its prototypes |
3878 // have none, the map of the object. This is used to speed up | 3943 // have none, the map of the object. This is used to speed up |
3879 // the check for deletions during a for-in. | 3944 // the check for deletions during a for-in. |
3880 static Object* Runtime_GetPropertyNamesFast(Arguments args) { | 3945 static MaybeObject* Runtime_GetPropertyNamesFast(Arguments args) { |
3881 ASSERT(args.length() == 1); | 3946 ASSERT(args.length() == 1); |
3882 | 3947 |
3883 CONVERT_CHECKED(JSObject, raw_object, args[0]); | 3948 CONVERT_CHECKED(JSObject, raw_object, args[0]); |
3884 | 3949 |
3885 if (raw_object->IsSimpleEnum()) return raw_object->map(); | 3950 if (raw_object->IsSimpleEnum()) return raw_object->map(); |
3886 | 3951 |
3887 HandleScope scope; | 3952 HandleScope scope; |
3888 Handle<JSObject> object(raw_object); | 3953 Handle<JSObject> object(raw_object); |
3889 Handle<FixedArray> content = GetKeysInFixedArrayFor(object, | 3954 Handle<FixedArray> content = GetKeysInFixedArrayFor(object, |
3890 INCLUDE_PROTOS); | 3955 INCLUDE_PROTOS); |
(...skipping 15 matching lines...) Expand all Loading... |
3906 JSObject::cast(proto)->map()->is_hidden_prototype()) { | 3971 JSObject::cast(proto)->map()->is_hidden_prototype()) { |
3907 count++; | 3972 count++; |
3908 proto = JSObject::cast(proto)->GetPrototype(); | 3973 proto = JSObject::cast(proto)->GetPrototype(); |
3909 } | 3974 } |
3910 return count; | 3975 return count; |
3911 } | 3976 } |
3912 | 3977 |
3913 | 3978 |
3914 // Return the names of the local named properties. | 3979 // Return the names of the local named properties. |
3915 // args[0]: object | 3980 // args[0]: object |
3916 static Object* Runtime_GetLocalPropertyNames(Arguments args) { | 3981 static MaybeObject* Runtime_GetLocalPropertyNames(Arguments args) { |
3917 HandleScope scope; | 3982 HandleScope scope; |
3918 ASSERT(args.length() == 1); | 3983 ASSERT(args.length() == 1); |
3919 if (!args[0]->IsJSObject()) { | 3984 if (!args[0]->IsJSObject()) { |
3920 return Heap::undefined_value(); | 3985 return Heap::undefined_value(); |
3921 } | 3986 } |
3922 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 3987 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
3923 | 3988 |
3924 // Skip the global proxy as it has no properties and always delegates to the | 3989 // Skip the global proxy as it has no properties and always delegates to the |
3925 // real global object. | 3990 // real global object. |
3926 if (obj->IsJSGlobalProxy()) { | 3991 if (obj->IsJSGlobalProxy()) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3989 names->set(dest_pos++, name); | 4054 names->set(dest_pos++, name); |
3990 } | 4055 } |
3991 } | 4056 } |
3992 | 4057 |
3993 return *Factory::NewJSArrayWithElements(names); | 4058 return *Factory::NewJSArrayWithElements(names); |
3994 } | 4059 } |
3995 | 4060 |
3996 | 4061 |
3997 // Return the names of the local indexed properties. | 4062 // Return the names of the local indexed properties. |
3998 // args[0]: object | 4063 // args[0]: object |
3999 static Object* Runtime_GetLocalElementNames(Arguments args) { | 4064 static MaybeObject* Runtime_GetLocalElementNames(Arguments args) { |
4000 HandleScope scope; | 4065 HandleScope scope; |
4001 ASSERT(args.length() == 1); | 4066 ASSERT(args.length() == 1); |
4002 if (!args[0]->IsJSObject()) { | 4067 if (!args[0]->IsJSObject()) { |
4003 return Heap::undefined_value(); | 4068 return Heap::undefined_value(); |
4004 } | 4069 } |
4005 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 4070 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
4006 | 4071 |
4007 int n = obj->NumberOfLocalElements(static_cast<PropertyAttributes>(NONE)); | 4072 int n = obj->NumberOfLocalElements(static_cast<PropertyAttributes>(NONE)); |
4008 Handle<FixedArray> names = Factory::NewFixedArray(n); | 4073 Handle<FixedArray> names = Factory::NewFixedArray(n); |
4009 obj->GetLocalElementKeys(*names, static_cast<PropertyAttributes>(NONE)); | 4074 obj->GetLocalElementKeys(*names, static_cast<PropertyAttributes>(NONE)); |
4010 return *Factory::NewJSArrayWithElements(names); | 4075 return *Factory::NewJSArrayWithElements(names); |
4011 } | 4076 } |
4012 | 4077 |
4013 | 4078 |
4014 // Return information on whether an object has a named or indexed interceptor. | 4079 // Return information on whether an object has a named or indexed interceptor. |
4015 // args[0]: object | 4080 // args[0]: object |
4016 static Object* Runtime_GetInterceptorInfo(Arguments args) { | 4081 static MaybeObject* Runtime_GetInterceptorInfo(Arguments args) { |
4017 HandleScope scope; | 4082 HandleScope scope; |
4018 ASSERT(args.length() == 1); | 4083 ASSERT(args.length() == 1); |
4019 if (!args[0]->IsJSObject()) { | 4084 if (!args[0]->IsJSObject()) { |
4020 return Smi::FromInt(0); | 4085 return Smi::FromInt(0); |
4021 } | 4086 } |
4022 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 4087 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
4023 | 4088 |
4024 int result = 0; | 4089 int result = 0; |
4025 if (obj->HasNamedInterceptor()) result |= 2; | 4090 if (obj->HasNamedInterceptor()) result |= 2; |
4026 if (obj->HasIndexedInterceptor()) result |= 1; | 4091 if (obj->HasIndexedInterceptor()) result |= 1; |
4027 | 4092 |
4028 return Smi::FromInt(result); | 4093 return Smi::FromInt(result); |
4029 } | 4094 } |
4030 | 4095 |
4031 | 4096 |
4032 // Return property names from named interceptor. | 4097 // Return property names from named interceptor. |
4033 // args[0]: object | 4098 // args[0]: object |
4034 static Object* Runtime_GetNamedInterceptorPropertyNames(Arguments args) { | 4099 static MaybeObject* Runtime_GetNamedInterceptorPropertyNames(Arguments args) { |
4035 HandleScope scope; | 4100 HandleScope scope; |
4036 ASSERT(args.length() == 1); | 4101 ASSERT(args.length() == 1); |
4037 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 4102 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
4038 | 4103 |
4039 if (obj->HasNamedInterceptor()) { | 4104 if (obj->HasNamedInterceptor()) { |
4040 v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj); | 4105 v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj); |
4041 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); | 4106 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); |
4042 } | 4107 } |
4043 return Heap::undefined_value(); | 4108 return Heap::undefined_value(); |
4044 } | 4109 } |
4045 | 4110 |
4046 | 4111 |
4047 // Return element names from indexed interceptor. | 4112 // Return element names from indexed interceptor. |
4048 // args[0]: object | 4113 // args[0]: object |
4049 static Object* Runtime_GetIndexedInterceptorElementNames(Arguments args) { | 4114 static MaybeObject* Runtime_GetIndexedInterceptorElementNames(Arguments args) { |
4050 HandleScope scope; | 4115 HandleScope scope; |
4051 ASSERT(args.length() == 1); | 4116 ASSERT(args.length() == 1); |
4052 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 4117 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
4053 | 4118 |
4054 if (obj->HasIndexedInterceptor()) { | 4119 if (obj->HasIndexedInterceptor()) { |
4055 v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj); | 4120 v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj); |
4056 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); | 4121 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); |
4057 } | 4122 } |
4058 return Heap::undefined_value(); | 4123 return Heap::undefined_value(); |
4059 } | 4124 } |
4060 | 4125 |
4061 | 4126 |
4062 static Object* Runtime_LocalKeys(Arguments args) { | 4127 static MaybeObject* Runtime_LocalKeys(Arguments args) { |
4063 ASSERT_EQ(args.length(), 1); | 4128 ASSERT_EQ(args.length(), 1); |
4064 CONVERT_CHECKED(JSObject, raw_object, args[0]); | 4129 CONVERT_CHECKED(JSObject, raw_object, args[0]); |
4065 HandleScope scope; | 4130 HandleScope scope; |
4066 Handle<JSObject> object(raw_object); | 4131 Handle<JSObject> object(raw_object); |
4067 Handle<FixedArray> contents = GetKeysInFixedArrayFor(object, | 4132 Handle<FixedArray> contents = GetKeysInFixedArrayFor(object, |
4068 LOCAL_ONLY); | 4133 LOCAL_ONLY); |
4069 // Some fast paths through GetKeysInFixedArrayFor reuse a cached | 4134 // Some fast paths through GetKeysInFixedArrayFor reuse a cached |
4070 // property array and since the result is mutable we have to create | 4135 // property array and since the result is mutable we have to create |
4071 // a fresh clone on each invocation. | 4136 // a fresh clone on each invocation. |
4072 int length = contents->length(); | 4137 int length = contents->length(); |
4073 Handle<FixedArray> copy = Factory::NewFixedArray(length); | 4138 Handle<FixedArray> copy = Factory::NewFixedArray(length); |
4074 for (int i = 0; i < length; i++) { | 4139 for (int i = 0; i < length; i++) { |
4075 Object* entry = contents->get(i); | 4140 Object* entry = contents->get(i); |
4076 if (entry->IsString()) { | 4141 if (entry->IsString()) { |
4077 copy->set(i, entry); | 4142 copy->set(i, entry); |
4078 } else { | 4143 } else { |
4079 ASSERT(entry->IsNumber()); | 4144 ASSERT(entry->IsNumber()); |
4080 HandleScope scope; | 4145 HandleScope scope; |
4081 Handle<Object> entry_handle(entry); | 4146 Handle<Object> entry_handle(entry); |
4082 Handle<Object> entry_str = Factory::NumberToString(entry_handle); | 4147 Handle<Object> entry_str = Factory::NumberToString(entry_handle); |
4083 copy->set(i, *entry_str); | 4148 copy->set(i, *entry_str); |
4084 } | 4149 } |
4085 } | 4150 } |
4086 return *Factory::NewJSArrayWithElements(copy); | 4151 return *Factory::NewJSArrayWithElements(copy); |
4087 } | 4152 } |
4088 | 4153 |
4089 | 4154 |
4090 static Object* Runtime_GetArgumentsProperty(Arguments args) { | 4155 static MaybeObject* Runtime_GetArgumentsProperty(Arguments args) { |
4091 NoHandleAllocation ha; | 4156 NoHandleAllocation ha; |
4092 ASSERT(args.length() == 1); | 4157 ASSERT(args.length() == 1); |
4093 | 4158 |
4094 // Compute the frame holding the arguments. | 4159 // Compute the frame holding the arguments. |
4095 JavaScriptFrameIterator it; | 4160 JavaScriptFrameIterator it; |
4096 it.AdvanceToArgumentsFrame(); | 4161 it.AdvanceToArgumentsFrame(); |
4097 JavaScriptFrame* frame = it.frame(); | 4162 JavaScriptFrame* frame = it.frame(); |
4098 | 4163 |
4099 // Get the actual number of provided arguments. | 4164 // Get the actual number of provided arguments. |
4100 const uint32_t n = frame->GetProvidedParametersCount(); | 4165 const uint32_t n = frame->GetProvidedParametersCount(); |
(...skipping 24 matching lines...) Expand all Loading... |
4125 | 4190 |
4126 // Handle special arguments properties. | 4191 // Handle special arguments properties. |
4127 if (key->Equals(Heap::length_symbol())) return Smi::FromInt(n); | 4192 if (key->Equals(Heap::length_symbol())) return Smi::FromInt(n); |
4128 if (key->Equals(Heap::callee_symbol())) return frame->function(); | 4193 if (key->Equals(Heap::callee_symbol())) return frame->function(); |
4129 | 4194 |
4130 // Lookup in the initial Object.prototype object. | 4195 // Lookup in the initial Object.prototype object. |
4131 return Top::initial_object_prototype()->GetProperty(*key); | 4196 return Top::initial_object_prototype()->GetProperty(*key); |
4132 } | 4197 } |
4133 | 4198 |
4134 | 4199 |
4135 static Object* Runtime_ToFastProperties(Arguments args) { | 4200 static MaybeObject* Runtime_ToFastProperties(Arguments args) { |
4136 HandleScope scope; | 4201 HandleScope scope; |
4137 | 4202 |
4138 ASSERT(args.length() == 1); | 4203 ASSERT(args.length() == 1); |
4139 Handle<Object> object = args.at<Object>(0); | 4204 Handle<Object> object = args.at<Object>(0); |
4140 if (object->IsJSObject()) { | 4205 if (object->IsJSObject()) { |
4141 Handle<JSObject> js_object = Handle<JSObject>::cast(object); | 4206 Handle<JSObject> js_object = Handle<JSObject>::cast(object); |
4142 if (!js_object->HasFastProperties() && !js_object->IsGlobalObject()) { | 4207 if (!js_object->HasFastProperties() && !js_object->IsGlobalObject()) { |
4143 js_object->TransformToFastProperties(0); | 4208 MaybeObject* ok = js_object->TransformToFastProperties(0); |
| 4209 if (ok->IsRetryAfterGC()) return ok; |
4144 } | 4210 } |
4145 } | 4211 } |
4146 return *object; | 4212 return *object; |
4147 } | 4213 } |
4148 | 4214 |
4149 | 4215 |
4150 static Object* Runtime_ToSlowProperties(Arguments args) { | 4216 static MaybeObject* Runtime_ToSlowProperties(Arguments args) { |
4151 HandleScope scope; | 4217 HandleScope scope; |
4152 | 4218 |
4153 ASSERT(args.length() == 1); | 4219 ASSERT(args.length() == 1); |
4154 Handle<Object> object = args.at<Object>(0); | 4220 Handle<Object> object = args.at<Object>(0); |
4155 if (object->IsJSObject()) { | 4221 if (object->IsJSObject()) { |
4156 Handle<JSObject> js_object = Handle<JSObject>::cast(object); | 4222 Handle<JSObject> js_object = Handle<JSObject>::cast(object); |
4157 js_object->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 4223 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); |
4158 } | 4224 } |
4159 return *object; | 4225 return *object; |
4160 } | 4226 } |
4161 | 4227 |
4162 | 4228 |
4163 static Object* Runtime_ToBool(Arguments args) { | 4229 static MaybeObject* Runtime_ToBool(Arguments args) { |
4164 NoHandleAllocation ha; | 4230 NoHandleAllocation ha; |
4165 ASSERT(args.length() == 1); | 4231 ASSERT(args.length() == 1); |
4166 | 4232 |
4167 return args[0]->ToBoolean(); | 4233 return args[0]->ToBoolean(); |
4168 } | 4234 } |
4169 | 4235 |
4170 | 4236 |
4171 // Returns the type string of a value; see ECMA-262, 11.4.3 (p 47). | 4237 // Returns the type string of a value; see ECMA-262, 11.4.3 (p 47). |
4172 // Possible optimizations: put the type string into the oddballs. | 4238 // Possible optimizations: put the type string into the oddballs. |
4173 static Object* Runtime_Typeof(Arguments args) { | 4239 static MaybeObject* Runtime_Typeof(Arguments args) { |
4174 NoHandleAllocation ha; | 4240 NoHandleAllocation ha; |
4175 | 4241 |
4176 Object* obj = args[0]; | 4242 Object* obj = args[0]; |
4177 if (obj->IsNumber()) return Heap::number_symbol(); | 4243 if (obj->IsNumber()) return Heap::number_symbol(); |
4178 HeapObject* heap_obj = HeapObject::cast(obj); | 4244 HeapObject* heap_obj = HeapObject::cast(obj); |
4179 | 4245 |
4180 // typeof an undetectable object is 'undefined' | 4246 // typeof an undetectable object is 'undefined' |
4181 if (heap_obj->map()->is_undetectable()) return Heap::undefined_symbol(); | 4247 if (heap_obj->map()->is_undetectable()) return Heap::undefined_symbol(); |
4182 | 4248 |
4183 InstanceType instance_type = heap_obj->map()->instance_type(); | 4249 InstanceType instance_type = heap_obj->map()->instance_type(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4220 int d = s[from] - '0'; | 4286 int d = s[from] - '0'; |
4221 | 4287 |
4222 for (int i = from + 1; i < to; i++) { | 4288 for (int i = from + 1; i < to; i++) { |
4223 d = 10 * d + (s[i] - '0'); | 4289 d = 10 * d + (s[i] - '0'); |
4224 } | 4290 } |
4225 | 4291 |
4226 return d; | 4292 return d; |
4227 } | 4293 } |
4228 | 4294 |
4229 | 4295 |
4230 static Object* Runtime_StringToNumber(Arguments args) { | 4296 static MaybeObject* Runtime_StringToNumber(Arguments args) { |
4231 NoHandleAllocation ha; | 4297 NoHandleAllocation ha; |
4232 ASSERT(args.length() == 1); | 4298 ASSERT(args.length() == 1); |
4233 CONVERT_CHECKED(String, subject, args[0]); | 4299 CONVERT_CHECKED(String, subject, args[0]); |
4234 subject->TryFlatten(); | 4300 subject->TryFlatten(); |
4235 | 4301 |
4236 // Fast case: short integer or some sorts of junk values. | 4302 // Fast case: short integer or some sorts of junk values. |
4237 int len = subject->length(); | 4303 int len = subject->length(); |
4238 if (subject->IsSeqAsciiString()) { | 4304 if (subject->IsSeqAsciiString()) { |
4239 if (len == 0) return Smi::FromInt(0); | 4305 if (len == 0) return Smi::FromInt(0); |
4240 | 4306 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4274 } | 4340 } |
4275 return Smi::FromInt(d); | 4341 return Smi::FromInt(d); |
4276 } | 4342 } |
4277 } | 4343 } |
4278 | 4344 |
4279 // Slower case. | 4345 // Slower case. |
4280 return Heap::NumberFromDouble(StringToDouble(subject, ALLOW_HEX)); | 4346 return Heap::NumberFromDouble(StringToDouble(subject, ALLOW_HEX)); |
4281 } | 4347 } |
4282 | 4348 |
4283 | 4349 |
4284 static Object* Runtime_StringFromCharCodeArray(Arguments args) { | 4350 static MaybeObject* Runtime_StringFromCharCodeArray(Arguments args) { |
4285 NoHandleAllocation ha; | 4351 NoHandleAllocation ha; |
4286 ASSERT(args.length() == 1); | 4352 ASSERT(args.length() == 1); |
4287 | 4353 |
4288 CONVERT_CHECKED(JSArray, codes, args[0]); | 4354 CONVERT_CHECKED(JSArray, codes, args[0]); |
4289 int length = Smi::cast(codes->length())->value(); | 4355 int length = Smi::cast(codes->length())->value(); |
4290 | 4356 |
4291 // Check if the string can be ASCII. | 4357 // Check if the string can be ASCII. |
4292 int i; | 4358 int i; |
4293 for (i = 0; i < length; i++) { | 4359 for (i = 0; i < length; i++) { |
4294 Object* element = codes->GetElement(i); | 4360 Object* element; |
| 4361 { MaybeObject* maybe_element = codes->GetElement(i); |
| 4362 // We probably can't get an exception here, but just in order to enforce |
| 4363 // the checking of inputs in the runtime calls we check here. |
| 4364 if (!maybe_element->ToObject(&element)) return maybe_element; |
| 4365 } |
4295 CONVERT_NUMBER_CHECKED(int, chr, Int32, element); | 4366 CONVERT_NUMBER_CHECKED(int, chr, Int32, element); |
4296 if ((chr & 0xffff) > String::kMaxAsciiCharCode) | 4367 if ((chr & 0xffff) > String::kMaxAsciiCharCode) |
4297 break; | 4368 break; |
4298 } | 4369 } |
4299 | 4370 |
4300 Object* object = NULL; | 4371 MaybeObject* maybe_object = NULL; |
4301 if (i == length) { // The string is ASCII. | 4372 if (i == length) { // The string is ASCII. |
4302 object = Heap::AllocateRawAsciiString(length); | 4373 maybe_object = Heap::AllocateRawAsciiString(length); |
4303 } else { // The string is not ASCII. | 4374 } else { // The string is not ASCII. |
4304 object = Heap::AllocateRawTwoByteString(length); | 4375 maybe_object = Heap::AllocateRawTwoByteString(length); |
4305 } | 4376 } |
4306 | 4377 |
4307 if (object->IsFailure()) return object; | 4378 Object* object = NULL; |
| 4379 if (!maybe_object->ToObject(&object)) return maybe_object; |
4308 String* result = String::cast(object); | 4380 String* result = String::cast(object); |
4309 for (int i = 0; i < length; i++) { | 4381 for (int i = 0; i < length; i++) { |
4310 Object* element = codes->GetElement(i); | 4382 Object* element; |
| 4383 { MaybeObject* maybe_element = codes->GetElement(i); |
| 4384 if (!maybe_element->ToObject(&element)) return maybe_element; |
| 4385 } |
4311 CONVERT_NUMBER_CHECKED(int, chr, Int32, element); | 4386 CONVERT_NUMBER_CHECKED(int, chr, Int32, element); |
4312 result->Set(i, chr & 0xffff); | 4387 result->Set(i, chr & 0xffff); |
4313 } | 4388 } |
4314 return result; | 4389 return result; |
4315 } | 4390 } |
4316 | 4391 |
4317 | 4392 |
4318 // kNotEscaped is generated by the following: | 4393 // kNotEscaped is generated by the following: |
4319 // | 4394 // |
4320 // #!/bin/perl | 4395 // #!/bin/perl |
(...skipping 24 matching lines...) Expand all Loading... |
4345 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 4420 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
4346 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 4421 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
4347 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 4422 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
4348 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 4423 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
4349 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 4424 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
4350 }; | 4425 }; |
4351 return kNotEscaped[character] != 0; | 4426 return kNotEscaped[character] != 0; |
4352 } | 4427 } |
4353 | 4428 |
4354 | 4429 |
4355 static Object* Runtime_URIEscape(Arguments args) { | 4430 static MaybeObject* Runtime_URIEscape(Arguments args) { |
4356 const char hex_chars[] = "0123456789ABCDEF"; | 4431 const char hex_chars[] = "0123456789ABCDEF"; |
4357 NoHandleAllocation ha; | 4432 NoHandleAllocation ha; |
4358 ASSERT(args.length() == 1); | 4433 ASSERT(args.length() == 1); |
4359 CONVERT_CHECKED(String, source, args[0]); | 4434 CONVERT_CHECKED(String, source, args[0]); |
4360 | 4435 |
4361 source->TryFlatten(); | 4436 source->TryFlatten(); |
4362 | 4437 |
4363 int escaped_length = 0; | 4438 int escaped_length = 0; |
4364 int length = source->length(); | 4439 int length = source->length(); |
4365 { | 4440 { |
(...skipping 13 matching lines...) Expand all Loading... |
4379 if (escaped_length > String::kMaxLength) { | 4454 if (escaped_length > String::kMaxLength) { |
4380 Top::context()->mark_out_of_memory(); | 4455 Top::context()->mark_out_of_memory(); |
4381 return Failure::OutOfMemoryException(); | 4456 return Failure::OutOfMemoryException(); |
4382 } | 4457 } |
4383 } | 4458 } |
4384 } | 4459 } |
4385 // No length change implies no change. Return original string if no change. | 4460 // No length change implies no change. Return original string if no change. |
4386 if (escaped_length == length) { | 4461 if (escaped_length == length) { |
4387 return source; | 4462 return source; |
4388 } | 4463 } |
4389 Object* o = Heap::AllocateRawAsciiString(escaped_length); | 4464 Object* o; |
4390 if (o->IsFailure()) return o; | 4465 { MaybeObject* maybe_o = Heap::AllocateRawAsciiString(escaped_length); |
| 4466 if (!maybe_o->ToObject(&o)) return maybe_o; |
| 4467 } |
4391 String* destination = String::cast(o); | 4468 String* destination = String::cast(o); |
4392 int dest_position = 0; | 4469 int dest_position = 0; |
4393 | 4470 |
4394 Access<StringInputBuffer> buffer(&runtime_string_input_buffer); | 4471 Access<StringInputBuffer> buffer(&runtime_string_input_buffer); |
4395 buffer->Rewind(); | 4472 buffer->Rewind(); |
4396 while (buffer->has_more()) { | 4473 while (buffer->has_more()) { |
4397 uint16_t chr = buffer->GetNext(); | 4474 uint16_t chr = buffer->GetNext(); |
4398 if (chr >= 256) { | 4475 if (chr >= 256) { |
4399 destination->Set(dest_position, '%'); | 4476 destination->Set(dest_position, '%'); |
4400 destination->Set(dest_position+1, 'u'); | 4477 destination->Set(dest_position+1, 'u'); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4459 source->Get(i + 2))) != -1) { | 4536 source->Get(i + 2))) != -1) { |
4460 *step = 3; | 4537 *step = 3; |
4461 return lo; | 4538 return lo; |
4462 } else { | 4539 } else { |
4463 *step = 1; | 4540 *step = 1; |
4464 return character; | 4541 return character; |
4465 } | 4542 } |
4466 } | 4543 } |
4467 | 4544 |
4468 | 4545 |
4469 static Object* Runtime_URIUnescape(Arguments args) { | 4546 static MaybeObject* Runtime_URIUnescape(Arguments args) { |
4470 NoHandleAllocation ha; | 4547 NoHandleAllocation ha; |
4471 ASSERT(args.length() == 1); | 4548 ASSERT(args.length() == 1); |
4472 CONVERT_CHECKED(String, source, args[0]); | 4549 CONVERT_CHECKED(String, source, args[0]); |
4473 | 4550 |
4474 source->TryFlatten(); | 4551 source->TryFlatten(); |
4475 | 4552 |
4476 bool ascii = true; | 4553 bool ascii = true; |
4477 int length = source->length(); | 4554 int length = source->length(); |
4478 | 4555 |
4479 int unescaped_length = 0; | 4556 int unescaped_length = 0; |
4480 for (int i = 0; i < length; unescaped_length++) { | 4557 for (int i = 0; i < length; unescaped_length++) { |
4481 int step; | 4558 int step; |
4482 if (Unescape(source, i, length, &step) > String::kMaxAsciiCharCode) { | 4559 if (Unescape(source, i, length, &step) > String::kMaxAsciiCharCode) { |
4483 ascii = false; | 4560 ascii = false; |
4484 } | 4561 } |
4485 i += step; | 4562 i += step; |
4486 } | 4563 } |
4487 | 4564 |
4488 // No length change implies no change. Return original string if no change. | 4565 // No length change implies no change. Return original string if no change. |
4489 if (unescaped_length == length) | 4566 if (unescaped_length == length) |
4490 return source; | 4567 return source; |
4491 | 4568 |
4492 Object* o = ascii ? | 4569 Object* o; |
4493 Heap::AllocateRawAsciiString(unescaped_length) : | 4570 { MaybeObject* maybe_o = ascii ? |
4494 Heap::AllocateRawTwoByteString(unescaped_length); | 4571 Heap::AllocateRawAsciiString(unescaped_length) : |
4495 if (o->IsFailure()) return o; | 4572 Heap::AllocateRawTwoByteString(unescaped_length); |
| 4573 if (!maybe_o->ToObject(&o)) return maybe_o; |
| 4574 } |
4496 String* destination = String::cast(o); | 4575 String* destination = String::cast(o); |
4497 | 4576 |
4498 int dest_position = 0; | 4577 int dest_position = 0; |
4499 for (int i = 0; i < length; dest_position++) { | 4578 for (int i = 0; i < length; dest_position++) { |
4500 int step; | 4579 int step; |
4501 destination->Set(dest_position, Unescape(source, i, length, &step)); | 4580 destination->Set(dest_position, Unescape(source, i, length, &step)); |
4502 i += step; | 4581 i += step; |
4503 } | 4582 } |
4504 return destination; | 4583 return destination; |
4505 } | 4584 } |
4506 | 4585 |
4507 | 4586 |
4508 static Object* Runtime_StringParseInt(Arguments args) { | 4587 static MaybeObject* Runtime_StringParseInt(Arguments args) { |
4509 NoHandleAllocation ha; | 4588 NoHandleAllocation ha; |
4510 | 4589 |
4511 CONVERT_CHECKED(String, s, args[0]); | 4590 CONVERT_CHECKED(String, s, args[0]); |
4512 CONVERT_SMI_CHECKED(radix, args[1]); | 4591 CONVERT_SMI_CHECKED(radix, args[1]); |
4513 | 4592 |
4514 s->TryFlatten(); | 4593 s->TryFlatten(); |
4515 | 4594 |
4516 RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36)); | 4595 RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36)); |
4517 double value = StringToInt(s, radix); | 4596 double value = StringToInt(s, radix); |
4518 return Heap::NumberFromDouble(value); | 4597 return Heap::NumberFromDouble(value); |
4519 } | 4598 } |
4520 | 4599 |
4521 | 4600 |
4522 static Object* Runtime_StringParseFloat(Arguments args) { | 4601 static MaybeObject* Runtime_StringParseFloat(Arguments args) { |
4523 NoHandleAllocation ha; | 4602 NoHandleAllocation ha; |
4524 CONVERT_CHECKED(String, str, args[0]); | 4603 CONVERT_CHECKED(String, str, args[0]); |
4525 | 4604 |
4526 // ECMA-262 section 15.1.2.3, empty string is NaN | 4605 // ECMA-262 section 15.1.2.3, empty string is NaN |
4527 double value = StringToDouble(str, ALLOW_TRAILING_JUNK, OS::nan_value()); | 4606 double value = StringToDouble(str, ALLOW_TRAILING_JUNK, OS::nan_value()); |
4528 | 4607 |
4529 // Create a number object from the value. | 4608 // Create a number object from the value. |
4530 return Heap::NumberFromDouble(value); | 4609 return Heap::NumberFromDouble(value); |
4531 } | 4610 } |
4532 | 4611 |
4533 | 4612 |
4534 static unibrow::Mapping<unibrow::ToUppercase, 128> to_upper_mapping; | 4613 static unibrow::Mapping<unibrow::ToUppercase, 128> to_upper_mapping; |
4535 static unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping; | 4614 static unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping; |
4536 | 4615 |
4537 | 4616 |
4538 template <class Converter> | 4617 template <class Converter> |
4539 static Object* ConvertCaseHelper(String* s, | 4618 MUST_USE_RESULT static MaybeObject* ConvertCaseHelper( |
4540 int length, | 4619 String* s, |
4541 int input_string_length, | 4620 int length, |
4542 unibrow::Mapping<Converter, 128>* mapping) { | 4621 int input_string_length, |
| 4622 unibrow::Mapping<Converter, 128>* mapping) { |
4543 // We try this twice, once with the assumption that the result is no longer | 4623 // We try this twice, once with the assumption that the result is no longer |
4544 // than the input and, if that assumption breaks, again with the exact | 4624 // than the input and, if that assumption breaks, again with the exact |
4545 // length. This may not be pretty, but it is nicer than what was here before | 4625 // length. This may not be pretty, but it is nicer than what was here before |
4546 // and I hereby claim my vaffel-is. | 4626 // and I hereby claim my vaffel-is. |
4547 // | 4627 // |
4548 // Allocate the resulting string. | 4628 // Allocate the resulting string. |
4549 // | 4629 // |
4550 // NOTE: This assumes that the upper/lower case of an ascii | 4630 // NOTE: This assumes that the upper/lower case of an ascii |
4551 // character is also ascii. This is currently the case, but it | 4631 // character is also ascii. This is currently the case, but it |
4552 // might break in the future if we implement more context and locale | 4632 // might break in the future if we implement more context and locale |
4553 // dependent upper/lower conversions. | 4633 // dependent upper/lower conversions. |
4554 Object* o = s->IsAsciiRepresentation() | 4634 Object* o; |
4555 ? Heap::AllocateRawAsciiString(length) | 4635 { MaybeObject* maybe_o = s->IsAsciiRepresentation() |
4556 : Heap::AllocateRawTwoByteString(length); | 4636 ? Heap::AllocateRawAsciiString(length) |
4557 if (o->IsFailure()) return o; | 4637 : Heap::AllocateRawTwoByteString(length); |
| 4638 if (!maybe_o->ToObject(&o)) return maybe_o; |
| 4639 } |
4558 String* result = String::cast(o); | 4640 String* result = String::cast(o); |
4559 bool has_changed_character = false; | 4641 bool has_changed_character = false; |
4560 | 4642 |
4561 // Convert all characters to upper case, assuming that they will fit | 4643 // Convert all characters to upper case, assuming that they will fit |
4562 // in the buffer | 4644 // in the buffer |
4563 Access<StringInputBuffer> buffer(&runtime_string_input_buffer); | 4645 Access<StringInputBuffer> buffer(&runtime_string_input_buffer); |
4564 buffer->Reset(s); | 4646 buffer->Reset(s); |
4565 unibrow::uchar chars[Converter::kMaxWidth]; | 4647 unibrow::uchar chars[Converter::kMaxWidth]; |
4566 // We can assume that the string is not empty | 4648 // We can assume that the string is not empty |
4567 uc32 current = buffer->GetNext(); | 4649 uc32 current = buffer->GetNext(); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4629 // we simple return the result and let the converted string | 4711 // we simple return the result and let the converted string |
4630 // become garbage; there is no reason to keep two identical strings | 4712 // become garbage; there is no reason to keep two identical strings |
4631 // alive. | 4713 // alive. |
4632 return s; | 4714 return s; |
4633 } | 4715 } |
4634 } | 4716 } |
4635 | 4717 |
4636 | 4718 |
4637 namespace { | 4719 namespace { |
4638 | 4720 |
| 4721 static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF; |
| 4722 |
| 4723 |
| 4724 // Given a word and two range boundaries returns a word with high bit |
| 4725 // set in every byte iff the corresponding input byte was strictly in |
| 4726 // the range (m, n). All the other bits in the result are cleared. |
| 4727 // This function is only useful when it can be inlined and the |
| 4728 // boundaries are statically known. |
| 4729 // Requires: all bytes in the input word and the boundaries must be |
| 4730 // ascii (less than 0x7F). |
| 4731 static inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) { |
| 4732 // Every byte in an ascii string is less than or equal to 0x7F. |
| 4733 ASSERT((w & (kOneInEveryByte * 0x7F)) == w); |
| 4734 // Use strict inequalities since in edge cases the function could be |
| 4735 // further simplified. |
| 4736 ASSERT(0 < m && m < n && n < 0x7F); |
| 4737 // Has high bit set in every w byte less than n. |
| 4738 uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w; |
| 4739 // Has high bit set in every w byte greater than m. |
| 4740 uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m); |
| 4741 return (tmp1 & tmp2 & (kOneInEveryByte * 0x80)); |
| 4742 } |
| 4743 |
| 4744 |
| 4745 enum AsciiCaseConversion { |
| 4746 ASCII_TO_LOWER, |
| 4747 ASCII_TO_UPPER |
| 4748 }; |
| 4749 |
| 4750 |
| 4751 template <AsciiCaseConversion dir> |
| 4752 struct FastAsciiConverter { |
| 4753 static bool Convert(char* dst, char* src, int length) { |
| 4754 #ifdef DEBUG |
| 4755 char* saved_dst = dst; |
| 4756 char* saved_src = src; |
| 4757 #endif |
| 4758 // We rely on the distance between upper and lower case letters |
| 4759 // being a known power of 2. |
| 4760 ASSERT('a' - 'A' == (1 << 5)); |
| 4761 // Boundaries for the range of input characters than require conversion. |
| 4762 const char lo = (dir == ASCII_TO_LOWER) ? 'A' - 1 : 'a' - 1; |
| 4763 const char hi = (dir == ASCII_TO_LOWER) ? 'Z' + 1 : 'z' + 1; |
| 4764 bool changed = false; |
| 4765 char* const limit = src + length; |
| 4766 #ifdef V8_HOST_CAN_READ_UNALIGNED |
| 4767 // Process the prefix of the input that requires no conversion one |
| 4768 // (machine) word at a time. |
| 4769 while (src <= limit - sizeof(uintptr_t)) { |
| 4770 uintptr_t w = *reinterpret_cast<uintptr_t*>(src); |
| 4771 if (AsciiRangeMask(w, lo, hi) != 0) { |
| 4772 changed = true; |
| 4773 break; |
| 4774 } |
| 4775 *reinterpret_cast<uintptr_t*>(dst) = w; |
| 4776 src += sizeof(uintptr_t); |
| 4777 dst += sizeof(uintptr_t); |
| 4778 } |
| 4779 // Process the remainder of the input performing conversion when |
| 4780 // required one word at a time. |
| 4781 while (src <= limit - sizeof(uintptr_t)) { |
| 4782 uintptr_t w = *reinterpret_cast<uintptr_t*>(src); |
| 4783 uintptr_t m = AsciiRangeMask(w, lo, hi); |
| 4784 // The mask has high (7th) bit set in every byte that needs |
| 4785 // conversion and we know that the distance between cases is |
| 4786 // 1 << 5. |
| 4787 *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2); |
| 4788 src += sizeof(uintptr_t); |
| 4789 dst += sizeof(uintptr_t); |
| 4790 } |
| 4791 #endif |
| 4792 // Process the last few bytes of the input (or the whole input if |
| 4793 // unaligned access is not supported). |
| 4794 while (src < limit) { |
| 4795 char c = *src; |
| 4796 if (lo < c && c < hi) { |
| 4797 c ^= (1 << 5); |
| 4798 changed = true; |
| 4799 } |
| 4800 *dst = c; |
| 4801 ++src; |
| 4802 ++dst; |
| 4803 } |
| 4804 #ifdef DEBUG |
| 4805 CheckConvert(saved_dst, saved_src, length, changed); |
| 4806 #endif |
| 4807 return changed; |
| 4808 } |
| 4809 |
| 4810 #ifdef DEBUG |
| 4811 static void CheckConvert(char* dst, char* src, int length, bool changed) { |
| 4812 bool expected_changed = false; |
| 4813 for (int i = 0; i < length; i++) { |
| 4814 if (dst[i] == src[i]) continue; |
| 4815 expected_changed = true; |
| 4816 if (dir == ASCII_TO_LOWER) { |
| 4817 ASSERT('A' <= src[i] && src[i] <= 'Z'); |
| 4818 ASSERT(dst[i] == src[i] + ('a' - 'A')); |
| 4819 } else { |
| 4820 ASSERT(dir == ASCII_TO_UPPER); |
| 4821 ASSERT('a' <= src[i] && src[i] <= 'z'); |
| 4822 ASSERT(dst[i] == src[i] - ('a' - 'A')); |
| 4823 } |
| 4824 } |
| 4825 ASSERT(expected_changed == changed); |
| 4826 } |
| 4827 #endif |
| 4828 }; |
| 4829 |
| 4830 |
4639 struct ToLowerTraits { | 4831 struct ToLowerTraits { |
4640 typedef unibrow::ToLowercase UnibrowConverter; | 4832 typedef unibrow::ToLowercase UnibrowConverter; |
4641 | 4833 |
4642 static bool ConvertAscii(char* dst, char* src, int length) { | 4834 typedef FastAsciiConverter<ASCII_TO_LOWER> AsciiConverter; |
4643 bool changed = false; | |
4644 for (int i = 0; i < length; ++i) { | |
4645 char c = src[i]; | |
4646 if ('A' <= c && c <= 'Z') { | |
4647 c += ('a' - 'A'); | |
4648 changed = true; | |
4649 } | |
4650 dst[i] = c; | |
4651 } | |
4652 return changed; | |
4653 } | |
4654 }; | 4835 }; |
4655 | 4836 |
4656 | 4837 |
4657 struct ToUpperTraits { | 4838 struct ToUpperTraits { |
4658 typedef unibrow::ToUppercase UnibrowConverter; | 4839 typedef unibrow::ToUppercase UnibrowConverter; |
4659 | 4840 |
4660 static bool ConvertAscii(char* dst, char* src, int length) { | 4841 typedef FastAsciiConverter<ASCII_TO_UPPER> AsciiConverter; |
4661 bool changed = false; | |
4662 for (int i = 0; i < length; ++i) { | |
4663 char c = src[i]; | |
4664 if ('a' <= c && c <= 'z') { | |
4665 c -= ('a' - 'A'); | |
4666 changed = true; | |
4667 } | |
4668 dst[i] = c; | |
4669 } | |
4670 return changed; | |
4671 } | |
4672 }; | 4842 }; |
4673 | 4843 |
4674 } // namespace | 4844 } // namespace |
4675 | 4845 |
4676 | 4846 |
4677 template <typename ConvertTraits> | 4847 template <typename ConvertTraits> |
4678 static Object* ConvertCase( | 4848 MUST_USE_RESULT static MaybeObject* ConvertCase( |
4679 Arguments args, | 4849 Arguments args, |
4680 unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) { | 4850 unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) { |
4681 NoHandleAllocation ha; | 4851 NoHandleAllocation ha; |
4682 CONVERT_CHECKED(String, s, args[0]); | 4852 CONVERT_CHECKED(String, s, args[0]); |
4683 s = s->TryFlattenGetString(); | 4853 s = s->TryFlattenGetString(); |
4684 | 4854 |
4685 const int length = s->length(); | 4855 const int length = s->length(); |
4686 // Assume that the string is not empty; we need this assumption later | 4856 // Assume that the string is not empty; we need this assumption later |
4687 if (length == 0) return s; | 4857 if (length == 0) return s; |
4688 | 4858 |
4689 // Simpler handling of ascii strings. | 4859 // Simpler handling of ascii strings. |
4690 // | 4860 // |
4691 // NOTE: This assumes that the upper/lower case of an ascii | 4861 // NOTE: This assumes that the upper/lower case of an ascii |
4692 // character is also ascii. This is currently the case, but it | 4862 // character is also ascii. This is currently the case, but it |
4693 // might break in the future if we implement more context and locale | 4863 // might break in the future if we implement more context and locale |
4694 // dependent upper/lower conversions. | 4864 // dependent upper/lower conversions. |
4695 if (s->IsSeqAsciiString()) { | 4865 if (s->IsSeqAsciiString()) { |
4696 Object* o = Heap::AllocateRawAsciiString(length); | 4866 Object* o; |
4697 if (o->IsFailure()) return o; | 4867 { MaybeObject* maybe_o = Heap::AllocateRawAsciiString(length); |
| 4868 if (!maybe_o->ToObject(&o)) return maybe_o; |
| 4869 } |
4698 SeqAsciiString* result = SeqAsciiString::cast(o); | 4870 SeqAsciiString* result = SeqAsciiString::cast(o); |
4699 bool has_changed_character = ConvertTraits::ConvertAscii( | 4871 bool has_changed_character = ConvertTraits::AsciiConverter::Convert( |
4700 result->GetChars(), SeqAsciiString::cast(s)->GetChars(), length); | 4872 result->GetChars(), SeqAsciiString::cast(s)->GetChars(), length); |
4701 return has_changed_character ? result : s; | 4873 return has_changed_character ? result : s; |
4702 } | 4874 } |
4703 | 4875 |
4704 Object* answer = ConvertCaseHelper(s, length, length, mapping); | 4876 Object* answer; |
| 4877 { MaybeObject* maybe_answer = ConvertCaseHelper(s, length, length, mapping); |
| 4878 if (!maybe_answer->ToObject(&answer)) return maybe_answer; |
| 4879 } |
4705 if (answer->IsSmi()) { | 4880 if (answer->IsSmi()) { |
4706 // Retry with correct length. | 4881 // Retry with correct length. |
4707 answer = ConvertCaseHelper(s, Smi::cast(answer)->value(), length, mapping); | 4882 { MaybeObject* maybe_answer = |
| 4883 ConvertCaseHelper(s, Smi::cast(answer)->value(), length, mapping); |
| 4884 if (!maybe_answer->ToObject(&answer)) return maybe_answer; |
| 4885 } |
4708 } | 4886 } |
4709 return answer; // This may be a failure. | 4887 return answer; |
4710 } | 4888 } |
4711 | 4889 |
4712 | 4890 |
4713 static Object* Runtime_StringToLowerCase(Arguments args) { | 4891 static MaybeObject* Runtime_StringToLowerCase(Arguments args) { |
4714 return ConvertCase<ToLowerTraits>(args, &to_lower_mapping); | 4892 return ConvertCase<ToLowerTraits>(args, &to_lower_mapping); |
4715 } | 4893 } |
4716 | 4894 |
4717 | 4895 |
4718 static Object* Runtime_StringToUpperCase(Arguments args) { | 4896 static MaybeObject* Runtime_StringToUpperCase(Arguments args) { |
4719 return ConvertCase<ToUpperTraits>(args, &to_upper_mapping); | 4897 return ConvertCase<ToUpperTraits>(args, &to_upper_mapping); |
4720 } | 4898 } |
4721 | 4899 |
4722 | 4900 |
4723 static inline bool IsTrimWhiteSpace(unibrow::uchar c) { | 4901 static inline bool IsTrimWhiteSpace(unibrow::uchar c) { |
4724 return unibrow::WhiteSpace::Is(c) || c == 0x200b; | 4902 return unibrow::WhiteSpace::Is(c) || c == 0x200b; |
4725 } | 4903 } |
4726 | 4904 |
4727 | 4905 |
4728 static Object* Runtime_StringTrim(Arguments args) { | 4906 static MaybeObject* Runtime_StringTrim(Arguments args) { |
4729 NoHandleAllocation ha; | 4907 NoHandleAllocation ha; |
4730 ASSERT(args.length() == 3); | 4908 ASSERT(args.length() == 3); |
4731 | 4909 |
4732 CONVERT_CHECKED(String, s, args[0]); | 4910 CONVERT_CHECKED(String, s, args[0]); |
4733 CONVERT_BOOLEAN_CHECKED(trimLeft, args[1]); | 4911 CONVERT_BOOLEAN_CHECKED(trimLeft, args[1]); |
4734 CONVERT_BOOLEAN_CHECKED(trimRight, args[2]); | 4912 CONVERT_BOOLEAN_CHECKED(trimRight, args[2]); |
4735 | 4913 |
4736 s->TryFlatten(); | 4914 s->TryFlatten(); |
4737 int length = s->length(); | 4915 int length = s->length(); |
4738 | 4916 |
(...skipping 28 matching lines...) Expand all Loading... |
4767 while (limit > 0) { | 4945 while (limit > 0) { |
4768 index = search.Search(subject, index); | 4946 index = search.Search(subject, index); |
4769 if (index < 0) return; | 4947 if (index < 0) return; |
4770 indices->Add(index); | 4948 indices->Add(index); |
4771 index += pattern_length; | 4949 index += pattern_length; |
4772 limit--; | 4950 limit--; |
4773 } | 4951 } |
4774 } | 4952 } |
4775 | 4953 |
4776 | 4954 |
4777 static Object* Runtime_StringSplit(Arguments args) { | 4955 static MaybeObject* Runtime_StringSplit(Arguments args) { |
4778 ASSERT(args.length() == 3); | 4956 ASSERT(args.length() == 3); |
4779 HandleScope handle_scope; | 4957 HandleScope handle_scope; |
4780 CONVERT_ARG_CHECKED(String, subject, 0); | 4958 CONVERT_ARG_CHECKED(String, subject, 0); |
4781 CONVERT_ARG_CHECKED(String, pattern, 1); | 4959 CONVERT_ARG_CHECKED(String, pattern, 1); |
4782 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]); | 4960 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]); |
4783 | 4961 |
4784 int subject_length = subject->length(); | 4962 int subject_length = subject->length(); |
4785 int pattern_length = pattern->length(); | 4963 int pattern_length = pattern->length(); |
4786 RUNTIME_ASSERT(pattern_length > 0); | 4964 RUNTIME_ASSERT(pattern_length > 0); |
4787 | 4965 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4893 ASSERT(element == Smi::FromInt(0) || | 5071 ASSERT(element == Smi::FromInt(0) || |
4894 (element->IsString() && String::cast(element)->LooksValid())); | 5072 (element->IsString() && String::cast(element)->LooksValid())); |
4895 } | 5073 } |
4896 #endif | 5074 #endif |
4897 return i; | 5075 return i; |
4898 } | 5076 } |
4899 | 5077 |
4900 | 5078 |
4901 // Converts a String to JSArray. | 5079 // Converts a String to JSArray. |
4902 // For example, "foo" => ["f", "o", "o"]. | 5080 // For example, "foo" => ["f", "o", "o"]. |
4903 static Object* Runtime_StringToArray(Arguments args) { | 5081 static MaybeObject* Runtime_StringToArray(Arguments args) { |
4904 HandleScope scope; | 5082 HandleScope scope; |
4905 ASSERT(args.length() == 1); | 5083 ASSERT(args.length() == 1); |
4906 CONVERT_ARG_CHECKED(String, s, 0); | 5084 CONVERT_ARG_CHECKED(String, s, 0); |
4907 | 5085 |
4908 s->TryFlatten(); | 5086 s->TryFlatten(); |
4909 const int length = s->length(); | 5087 const int length = s->length(); |
4910 | 5088 |
4911 Handle<FixedArray> elements; | 5089 Handle<FixedArray> elements; |
4912 if (s->IsFlat() && s->IsAsciiRepresentation()) { | 5090 if (s->IsFlat() && s->IsAsciiRepresentation()) { |
4913 Object* obj = Heap::AllocateUninitializedFixedArray(length); | 5091 Object* obj; |
4914 if (obj->IsFailure()) return obj; | 5092 { MaybeObject* maybe_obj = Heap::AllocateUninitializedFixedArray(length); |
| 5093 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 5094 } |
4915 elements = Handle<FixedArray>(FixedArray::cast(obj)); | 5095 elements = Handle<FixedArray>(FixedArray::cast(obj)); |
4916 | 5096 |
4917 Vector<const char> chars = s->ToAsciiVector(); | 5097 Vector<const char> chars = s->ToAsciiVector(); |
4918 // Note, this will initialize all elements (not only the prefix) | 5098 // Note, this will initialize all elements (not only the prefix) |
4919 // to prevent GC from seeing partially initialized array. | 5099 // to prevent GC from seeing partially initialized array. |
4920 int num_copied_from_cache = CopyCachedAsciiCharsToArray(chars.start(), | 5100 int num_copied_from_cache = CopyCachedAsciiCharsToArray(chars.start(), |
4921 *elements, | 5101 *elements, |
4922 length); | 5102 length); |
4923 | 5103 |
4924 for (int i = num_copied_from_cache; i < length; ++i) { | 5104 for (int i = num_copied_from_cache; i < length; ++i) { |
(...skipping 11 matching lines...) Expand all Loading... |
4936 #ifdef DEBUG | 5116 #ifdef DEBUG |
4937 for (int i = 0; i < length; ++i) { | 5117 for (int i = 0; i < length; ++i) { |
4938 ASSERT(String::cast(elements->get(i))->length() == 1); | 5118 ASSERT(String::cast(elements->get(i))->length() == 1); |
4939 } | 5119 } |
4940 #endif | 5120 #endif |
4941 | 5121 |
4942 return *Factory::NewJSArrayWithElements(elements); | 5122 return *Factory::NewJSArrayWithElements(elements); |
4943 } | 5123 } |
4944 | 5124 |
4945 | 5125 |
4946 static Object* Runtime_NewStringWrapper(Arguments args) { | 5126 static MaybeObject* Runtime_NewStringWrapper(Arguments args) { |
4947 NoHandleAllocation ha; | 5127 NoHandleAllocation ha; |
4948 ASSERT(args.length() == 1); | 5128 ASSERT(args.length() == 1); |
4949 CONVERT_CHECKED(String, value, args[0]); | 5129 CONVERT_CHECKED(String, value, args[0]); |
4950 return value->ToObject(); | 5130 return value->ToObject(); |
4951 } | 5131 } |
4952 | 5132 |
4953 | 5133 |
4954 bool Runtime::IsUpperCaseChar(uint16_t ch) { | 5134 bool Runtime::IsUpperCaseChar(uint16_t ch) { |
4955 unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth]; | 5135 unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth]; |
4956 int char_length = to_upper_mapping.get(ch, 0, chars); | 5136 int char_length = to_upper_mapping.get(ch, 0, chars); |
4957 return char_length == 0; | 5137 return char_length == 0; |
4958 } | 5138 } |
4959 | 5139 |
4960 | 5140 |
4961 static Object* Runtime_NumberToString(Arguments args) { | 5141 static MaybeObject* Runtime_NumberToString(Arguments args) { |
4962 NoHandleAllocation ha; | 5142 NoHandleAllocation ha; |
4963 ASSERT(args.length() == 1); | 5143 ASSERT(args.length() == 1); |
4964 | 5144 |
4965 Object* number = args[0]; | 5145 Object* number = args[0]; |
4966 RUNTIME_ASSERT(number->IsNumber()); | 5146 RUNTIME_ASSERT(number->IsNumber()); |
4967 | 5147 |
4968 return Heap::NumberToString(number); | 5148 return Heap::NumberToString(number); |
4969 } | 5149 } |
4970 | 5150 |
4971 | 5151 |
4972 static Object* Runtime_NumberToStringSkipCache(Arguments args) { | 5152 static MaybeObject* Runtime_NumberToStringSkipCache(Arguments args) { |
4973 NoHandleAllocation ha; | 5153 NoHandleAllocation ha; |
4974 ASSERT(args.length() == 1); | 5154 ASSERT(args.length() == 1); |
4975 | 5155 |
4976 Object* number = args[0]; | 5156 Object* number = args[0]; |
4977 RUNTIME_ASSERT(number->IsNumber()); | 5157 RUNTIME_ASSERT(number->IsNumber()); |
4978 | 5158 |
4979 return Heap::NumberToString(number, false); | 5159 return Heap::NumberToString(number, false); |
4980 } | 5160 } |
4981 | 5161 |
4982 | 5162 |
4983 static Object* Runtime_NumberToInteger(Arguments args) { | 5163 static MaybeObject* Runtime_NumberToInteger(Arguments args) { |
4984 NoHandleAllocation ha; | 5164 NoHandleAllocation ha; |
4985 ASSERT(args.length() == 1); | 5165 ASSERT(args.length() == 1); |
4986 | 5166 |
4987 CONVERT_DOUBLE_CHECKED(number, args[0]); | 5167 CONVERT_DOUBLE_CHECKED(number, args[0]); |
4988 | 5168 |
4989 // We do not include 0 so that we don't have to treat +0 / -0 cases. | 5169 // We do not include 0 so that we don't have to treat +0 / -0 cases. |
4990 if (number > 0 && number <= Smi::kMaxValue) { | 5170 if (number > 0 && number <= Smi::kMaxValue) { |
4991 return Smi::FromInt(static_cast<int>(number)); | 5171 return Smi::FromInt(static_cast<int>(number)); |
4992 } | 5172 } |
4993 return Heap::NumberFromDouble(DoubleToInteger(number)); | 5173 return Heap::NumberFromDouble(DoubleToInteger(number)); |
4994 } | 5174 } |
4995 | 5175 |
4996 | 5176 |
4997 static Object* Runtime_NumberToIntegerMapMinusZero(Arguments args) { | 5177 static MaybeObject* Runtime_NumberToIntegerMapMinusZero(Arguments args) { |
4998 NoHandleAllocation ha; | 5178 NoHandleAllocation ha; |
4999 ASSERT(args.length() == 1); | 5179 ASSERT(args.length() == 1); |
5000 | 5180 |
5001 CONVERT_DOUBLE_CHECKED(number, args[0]); | 5181 CONVERT_DOUBLE_CHECKED(number, args[0]); |
5002 | 5182 |
5003 // We do not include 0 so that we don't have to treat +0 / -0 cases. | 5183 // We do not include 0 so that we don't have to treat +0 / -0 cases. |
5004 if (number > 0 && number <= Smi::kMaxValue) { | 5184 if (number > 0 && number <= Smi::kMaxValue) { |
5005 return Smi::FromInt(static_cast<int>(number)); | 5185 return Smi::FromInt(static_cast<int>(number)); |
5006 } | 5186 } |
5007 | 5187 |
5008 double double_value = DoubleToInteger(number); | 5188 double double_value = DoubleToInteger(number); |
5009 // Map both -0 and +0 to +0. | 5189 // Map both -0 and +0 to +0. |
5010 if (double_value == 0) double_value = 0; | 5190 if (double_value == 0) double_value = 0; |
5011 | 5191 |
5012 return Heap::NumberFromDouble(double_value); | 5192 return Heap::NumberFromDouble(double_value); |
5013 } | 5193 } |
5014 | 5194 |
5015 | 5195 |
5016 static Object* Runtime_NumberToJSUint32(Arguments args) { | 5196 static MaybeObject* Runtime_NumberToJSUint32(Arguments args) { |
5017 NoHandleAllocation ha; | 5197 NoHandleAllocation ha; |
5018 ASSERT(args.length() == 1); | 5198 ASSERT(args.length() == 1); |
5019 | 5199 |
5020 CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]); | 5200 CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]); |
5021 return Heap::NumberFromUint32(number); | 5201 return Heap::NumberFromUint32(number); |
5022 } | 5202 } |
5023 | 5203 |
5024 | 5204 |
5025 static Object* Runtime_NumberToJSInt32(Arguments args) { | 5205 static MaybeObject* Runtime_NumberToJSInt32(Arguments args) { |
5026 NoHandleAllocation ha; | 5206 NoHandleAllocation ha; |
5027 ASSERT(args.length() == 1); | 5207 ASSERT(args.length() == 1); |
5028 | 5208 |
5029 CONVERT_DOUBLE_CHECKED(number, args[0]); | 5209 CONVERT_DOUBLE_CHECKED(number, args[0]); |
5030 | 5210 |
5031 // We do not include 0 so that we don't have to treat +0 / -0 cases. | 5211 // We do not include 0 so that we don't have to treat +0 / -0 cases. |
5032 if (number > 0 && number <= Smi::kMaxValue) { | 5212 if (number > 0 && number <= Smi::kMaxValue) { |
5033 return Smi::FromInt(static_cast<int>(number)); | 5213 return Smi::FromInt(static_cast<int>(number)); |
5034 } | 5214 } |
5035 return Heap::NumberFromInt32(DoubleToInt32(number)); | 5215 return Heap::NumberFromInt32(DoubleToInt32(number)); |
5036 } | 5216 } |
5037 | 5217 |
5038 | 5218 |
5039 // Converts a Number to a Smi, if possible. Returns NaN if the number is not | 5219 // Converts a Number to a Smi, if possible. Returns NaN if the number is not |
5040 // a small integer. | 5220 // a small integer. |
5041 static Object* Runtime_NumberToSmi(Arguments args) { | 5221 static MaybeObject* Runtime_NumberToSmi(Arguments args) { |
5042 NoHandleAllocation ha; | 5222 NoHandleAllocation ha; |
5043 ASSERT(args.length() == 1); | 5223 ASSERT(args.length() == 1); |
5044 | 5224 |
5045 Object* obj = args[0]; | 5225 Object* obj = args[0]; |
5046 if (obj->IsSmi()) { | 5226 if (obj->IsSmi()) { |
5047 return obj; | 5227 return obj; |
5048 } | 5228 } |
5049 if (obj->IsHeapNumber()) { | 5229 if (obj->IsHeapNumber()) { |
5050 double value = HeapNumber::cast(obj)->value(); | 5230 double value = HeapNumber::cast(obj)->value(); |
5051 int int_value = FastD2I(value); | 5231 int int_value = FastD2I(value); |
5052 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) { | 5232 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) { |
5053 return Smi::FromInt(int_value); | 5233 return Smi::FromInt(int_value); |
5054 } | 5234 } |
5055 } | 5235 } |
5056 return Heap::nan_value(); | 5236 return Heap::nan_value(); |
5057 } | 5237 } |
5058 | 5238 |
5059 | 5239 |
5060 static Object* Runtime_NumberAdd(Arguments args) { | 5240 static MaybeObject* Runtime_NumberAdd(Arguments args) { |
5061 NoHandleAllocation ha; | 5241 NoHandleAllocation ha; |
5062 ASSERT(args.length() == 2); | 5242 ASSERT(args.length() == 2); |
5063 | 5243 |
5064 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5244 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5065 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5245 CONVERT_DOUBLE_CHECKED(y, args[1]); |
5066 return Heap::NumberFromDouble(x + y); | 5246 return Heap::NumberFromDouble(x + y); |
5067 } | 5247 } |
5068 | 5248 |
5069 | 5249 |
5070 static Object* Runtime_NumberSub(Arguments args) { | 5250 static MaybeObject* Runtime_NumberSub(Arguments args) { |
5071 NoHandleAllocation ha; | 5251 NoHandleAllocation ha; |
5072 ASSERT(args.length() == 2); | 5252 ASSERT(args.length() == 2); |
5073 | 5253 |
5074 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5254 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5075 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5255 CONVERT_DOUBLE_CHECKED(y, args[1]); |
5076 return Heap::NumberFromDouble(x - y); | 5256 return Heap::NumberFromDouble(x - y); |
5077 } | 5257 } |
5078 | 5258 |
5079 | 5259 |
5080 static Object* Runtime_NumberMul(Arguments args) { | 5260 static MaybeObject* Runtime_NumberMul(Arguments args) { |
5081 NoHandleAllocation ha; | 5261 NoHandleAllocation ha; |
5082 ASSERT(args.length() == 2); | 5262 ASSERT(args.length() == 2); |
5083 | 5263 |
5084 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5264 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5085 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5265 CONVERT_DOUBLE_CHECKED(y, args[1]); |
5086 return Heap::NumberFromDouble(x * y); | 5266 return Heap::NumberFromDouble(x * y); |
5087 } | 5267 } |
5088 | 5268 |
5089 | 5269 |
5090 static Object* Runtime_NumberUnaryMinus(Arguments args) { | 5270 static MaybeObject* Runtime_NumberUnaryMinus(Arguments args) { |
5091 NoHandleAllocation ha; | 5271 NoHandleAllocation ha; |
5092 ASSERT(args.length() == 1); | 5272 ASSERT(args.length() == 1); |
5093 | 5273 |
5094 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5274 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5095 return Heap::NumberFromDouble(-x); | 5275 return Heap::NumberFromDouble(-x); |
5096 } | 5276 } |
5097 | 5277 |
5098 | 5278 |
5099 static Object* Runtime_NumberAlloc(Arguments args) { | 5279 static MaybeObject* Runtime_NumberAlloc(Arguments args) { |
5100 NoHandleAllocation ha; | 5280 NoHandleAllocation ha; |
5101 ASSERT(args.length() == 0); | 5281 ASSERT(args.length() == 0); |
5102 | 5282 |
5103 return Heap::NumberFromDouble(9876543210.0); | 5283 return Heap::NumberFromDouble(9876543210.0); |
5104 } | 5284 } |
5105 | 5285 |
5106 | 5286 |
5107 static Object* Runtime_NumberDiv(Arguments args) { | 5287 static MaybeObject* Runtime_NumberDiv(Arguments args) { |
5108 NoHandleAllocation ha; | 5288 NoHandleAllocation ha; |
5109 ASSERT(args.length() == 2); | 5289 ASSERT(args.length() == 2); |
5110 | 5290 |
5111 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5291 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5112 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5292 CONVERT_DOUBLE_CHECKED(y, args[1]); |
5113 return Heap::NumberFromDouble(x / y); | 5293 return Heap::NumberFromDouble(x / y); |
5114 } | 5294 } |
5115 | 5295 |
5116 | 5296 |
5117 static Object* Runtime_NumberMod(Arguments args) { | 5297 static MaybeObject* Runtime_NumberMod(Arguments args) { |
5118 NoHandleAllocation ha; | 5298 NoHandleAllocation ha; |
5119 ASSERT(args.length() == 2); | 5299 ASSERT(args.length() == 2); |
5120 | 5300 |
5121 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5301 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5122 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5302 CONVERT_DOUBLE_CHECKED(y, args[1]); |
5123 | 5303 |
5124 x = modulo(x, y); | 5304 x = modulo(x, y); |
5125 // NumberFromDouble may return a Smi instead of a Number object | 5305 // NumberFromDouble may return a Smi instead of a Number object |
5126 return Heap::NumberFromDouble(x); | 5306 return Heap::NumberFromDouble(x); |
5127 } | 5307 } |
5128 | 5308 |
5129 | 5309 |
5130 static Object* Runtime_StringAdd(Arguments args) { | 5310 static MaybeObject* Runtime_StringAdd(Arguments args) { |
5131 NoHandleAllocation ha; | 5311 NoHandleAllocation ha; |
5132 ASSERT(args.length() == 2); | 5312 ASSERT(args.length() == 2); |
5133 CONVERT_CHECKED(String, str1, args[0]); | 5313 CONVERT_CHECKED(String, str1, args[0]); |
5134 CONVERT_CHECKED(String, str2, args[1]); | 5314 CONVERT_CHECKED(String, str2, args[1]); |
5135 Counters::string_add_runtime.Increment(); | 5315 Counters::string_add_runtime.Increment(); |
5136 return Heap::AllocateConsString(str1, str2); | 5316 return Heap::AllocateConsString(str1, str2); |
5137 } | 5317 } |
5138 | 5318 |
5139 | 5319 |
5140 template <typename sinkchar> | 5320 template <typename sinkchar> |
(...skipping 28 matching lines...) Expand all Loading... |
5169 } else { | 5349 } else { |
5170 String* string = String::cast(element); | 5350 String* string = String::cast(element); |
5171 int element_length = string->length(); | 5351 int element_length = string->length(); |
5172 String::WriteToFlat(string, sink + position, 0, element_length); | 5352 String::WriteToFlat(string, sink + position, 0, element_length); |
5173 position += element_length; | 5353 position += element_length; |
5174 } | 5354 } |
5175 } | 5355 } |
5176 } | 5356 } |
5177 | 5357 |
5178 | 5358 |
5179 static Object* Runtime_StringBuilderConcat(Arguments args) { | 5359 static MaybeObject* Runtime_StringBuilderConcat(Arguments args) { |
5180 NoHandleAllocation ha; | 5360 NoHandleAllocation ha; |
5181 ASSERT(args.length() == 3); | 5361 ASSERT(args.length() == 3); |
5182 CONVERT_CHECKED(JSArray, array, args[0]); | 5362 CONVERT_CHECKED(JSArray, array, args[0]); |
5183 if (!args[1]->IsSmi()) { | 5363 if (!args[1]->IsSmi()) { |
5184 Top::context()->mark_out_of_memory(); | 5364 Top::context()->mark_out_of_memory(); |
5185 return Failure::OutOfMemoryException(); | 5365 return Failure::OutOfMemoryException(); |
5186 } | 5366 } |
5187 int array_length = Smi::cast(args[1])->value(); | 5367 int array_length = Smi::cast(args[1])->value(); |
5188 CONVERT_CHECKED(String, special, args[2]); | 5368 CONVERT_CHECKED(String, special, args[2]); |
5189 | 5369 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5257 Top::context()->mark_out_of_memory(); | 5437 Top::context()->mark_out_of_memory(); |
5258 return Failure::OutOfMemoryException(); | 5438 return Failure::OutOfMemoryException(); |
5259 } | 5439 } |
5260 position += increment; | 5440 position += increment; |
5261 } | 5441 } |
5262 | 5442 |
5263 int length = position; | 5443 int length = position; |
5264 Object* object; | 5444 Object* object; |
5265 | 5445 |
5266 if (ascii) { | 5446 if (ascii) { |
5267 object = Heap::AllocateRawAsciiString(length); | 5447 { MaybeObject* maybe_object = Heap::AllocateRawAsciiString(length); |
5268 if (object->IsFailure()) return object; | 5448 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 5449 } |
5269 SeqAsciiString* answer = SeqAsciiString::cast(object); | 5450 SeqAsciiString* answer = SeqAsciiString::cast(object); |
5270 StringBuilderConcatHelper(special, | 5451 StringBuilderConcatHelper(special, |
5271 answer->GetChars(), | 5452 answer->GetChars(), |
5272 fixed_array, | 5453 fixed_array, |
5273 array_length); | 5454 array_length); |
5274 return answer; | 5455 return answer; |
5275 } else { | 5456 } else { |
5276 object = Heap::AllocateRawTwoByteString(length); | 5457 { MaybeObject* maybe_object = Heap::AllocateRawTwoByteString(length); |
5277 if (object->IsFailure()) return object; | 5458 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 5459 } |
5278 SeqTwoByteString* answer = SeqTwoByteString::cast(object); | 5460 SeqTwoByteString* answer = SeqTwoByteString::cast(object); |
5279 StringBuilderConcatHelper(special, | 5461 StringBuilderConcatHelper(special, |
5280 answer->GetChars(), | 5462 answer->GetChars(), |
5281 fixed_array, | 5463 fixed_array, |
5282 array_length); | 5464 array_length); |
5283 return answer; | 5465 return answer; |
5284 } | 5466 } |
5285 } | 5467 } |
5286 | 5468 |
5287 | 5469 |
5288 static Object* Runtime_NumberOr(Arguments args) { | 5470 static MaybeObject* Runtime_NumberOr(Arguments args) { |
5289 NoHandleAllocation ha; | 5471 NoHandleAllocation ha; |
5290 ASSERT(args.length() == 2); | 5472 ASSERT(args.length() == 2); |
5291 | 5473 |
5292 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 5474 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
5293 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 5475 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
5294 return Heap::NumberFromInt32(x | y); | 5476 return Heap::NumberFromInt32(x | y); |
5295 } | 5477 } |
5296 | 5478 |
5297 | 5479 |
5298 static Object* Runtime_NumberAnd(Arguments args) { | 5480 static MaybeObject* Runtime_NumberAnd(Arguments args) { |
5299 NoHandleAllocation ha; | 5481 NoHandleAllocation ha; |
5300 ASSERT(args.length() == 2); | 5482 ASSERT(args.length() == 2); |
5301 | 5483 |
5302 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 5484 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
5303 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 5485 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
5304 return Heap::NumberFromInt32(x & y); | 5486 return Heap::NumberFromInt32(x & y); |
5305 } | 5487 } |
5306 | 5488 |
5307 | 5489 |
5308 static Object* Runtime_NumberXor(Arguments args) { | 5490 static MaybeObject* Runtime_NumberXor(Arguments args) { |
5309 NoHandleAllocation ha; | 5491 NoHandleAllocation ha; |
5310 ASSERT(args.length() == 2); | 5492 ASSERT(args.length() == 2); |
5311 | 5493 |
5312 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 5494 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
5313 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 5495 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
5314 return Heap::NumberFromInt32(x ^ y); | 5496 return Heap::NumberFromInt32(x ^ y); |
5315 } | 5497 } |
5316 | 5498 |
5317 | 5499 |
5318 static Object* Runtime_NumberNot(Arguments args) { | 5500 static MaybeObject* Runtime_NumberNot(Arguments args) { |
5319 NoHandleAllocation ha; | 5501 NoHandleAllocation ha; |
5320 ASSERT(args.length() == 1); | 5502 ASSERT(args.length() == 1); |
5321 | 5503 |
5322 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 5504 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
5323 return Heap::NumberFromInt32(~x); | 5505 return Heap::NumberFromInt32(~x); |
5324 } | 5506 } |
5325 | 5507 |
5326 | 5508 |
5327 static Object* Runtime_NumberShl(Arguments args) { | 5509 static MaybeObject* Runtime_NumberShl(Arguments args) { |
5328 NoHandleAllocation ha; | 5510 NoHandleAllocation ha; |
5329 ASSERT(args.length() == 2); | 5511 ASSERT(args.length() == 2); |
5330 | 5512 |
5331 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 5513 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
5332 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 5514 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
5333 return Heap::NumberFromInt32(x << (y & 0x1f)); | 5515 return Heap::NumberFromInt32(x << (y & 0x1f)); |
5334 } | 5516 } |
5335 | 5517 |
5336 | 5518 |
5337 static Object* Runtime_NumberShr(Arguments args) { | 5519 static MaybeObject* Runtime_NumberShr(Arguments args) { |
5338 NoHandleAllocation ha; | 5520 NoHandleAllocation ha; |
5339 ASSERT(args.length() == 2); | 5521 ASSERT(args.length() == 2); |
5340 | 5522 |
5341 CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]); | 5523 CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]); |
5342 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 5524 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
5343 return Heap::NumberFromUint32(x >> (y & 0x1f)); | 5525 return Heap::NumberFromUint32(x >> (y & 0x1f)); |
5344 } | 5526 } |
5345 | 5527 |
5346 | 5528 |
5347 static Object* Runtime_NumberSar(Arguments args) { | 5529 static MaybeObject* Runtime_NumberSar(Arguments args) { |
5348 NoHandleAllocation ha; | 5530 NoHandleAllocation ha; |
5349 ASSERT(args.length() == 2); | 5531 ASSERT(args.length() == 2); |
5350 | 5532 |
5351 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 5533 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
5352 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 5534 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
5353 return Heap::NumberFromInt32(ArithmeticShiftRight(x, y & 0x1f)); | 5535 return Heap::NumberFromInt32(ArithmeticShiftRight(x, y & 0x1f)); |
5354 } | 5536 } |
5355 | 5537 |
5356 | 5538 |
5357 static Object* Runtime_NumberEquals(Arguments args) { | 5539 static MaybeObject* Runtime_NumberEquals(Arguments args) { |
5358 NoHandleAllocation ha; | 5540 NoHandleAllocation ha; |
5359 ASSERT(args.length() == 2); | 5541 ASSERT(args.length() == 2); |
5360 | 5542 |
5361 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5543 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5362 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5544 CONVERT_DOUBLE_CHECKED(y, args[1]); |
5363 if (isnan(x)) return Smi::FromInt(NOT_EQUAL); | 5545 if (isnan(x)) return Smi::FromInt(NOT_EQUAL); |
5364 if (isnan(y)) return Smi::FromInt(NOT_EQUAL); | 5546 if (isnan(y)) return Smi::FromInt(NOT_EQUAL); |
5365 if (x == y) return Smi::FromInt(EQUAL); | 5547 if (x == y) return Smi::FromInt(EQUAL); |
5366 Object* result; | 5548 Object* result; |
5367 if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) { | 5549 if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) { |
5368 result = Smi::FromInt(EQUAL); | 5550 result = Smi::FromInt(EQUAL); |
5369 } else { | 5551 } else { |
5370 result = Smi::FromInt(NOT_EQUAL); | 5552 result = Smi::FromInt(NOT_EQUAL); |
5371 } | 5553 } |
5372 return result; | 5554 return result; |
5373 } | 5555 } |
5374 | 5556 |
5375 | 5557 |
5376 static Object* Runtime_StringEquals(Arguments args) { | 5558 static MaybeObject* Runtime_StringEquals(Arguments args) { |
5377 NoHandleAllocation ha; | 5559 NoHandleAllocation ha; |
5378 ASSERT(args.length() == 2); | 5560 ASSERT(args.length() == 2); |
5379 | 5561 |
5380 CONVERT_CHECKED(String, x, args[0]); | 5562 CONVERT_CHECKED(String, x, args[0]); |
5381 CONVERT_CHECKED(String, y, args[1]); | 5563 CONVERT_CHECKED(String, y, args[1]); |
5382 | 5564 |
5383 bool not_equal = !x->Equals(y); | 5565 bool not_equal = !x->Equals(y); |
5384 // This is slightly convoluted because the value that signifies | 5566 // This is slightly convoluted because the value that signifies |
5385 // equality is 0 and inequality is 1 so we have to negate the result | 5567 // equality is 0 and inequality is 1 so we have to negate the result |
5386 // from String::Equals. | 5568 // from String::Equals. |
5387 ASSERT(not_equal == 0 || not_equal == 1); | 5569 ASSERT(not_equal == 0 || not_equal == 1); |
5388 STATIC_CHECK(EQUAL == 0); | 5570 STATIC_CHECK(EQUAL == 0); |
5389 STATIC_CHECK(NOT_EQUAL == 1); | 5571 STATIC_CHECK(NOT_EQUAL == 1); |
5390 return Smi::FromInt(not_equal); | 5572 return Smi::FromInt(not_equal); |
5391 } | 5573 } |
5392 | 5574 |
5393 | 5575 |
5394 static Object* Runtime_NumberCompare(Arguments args) { | 5576 static MaybeObject* Runtime_NumberCompare(Arguments args) { |
5395 NoHandleAllocation ha; | 5577 NoHandleAllocation ha; |
5396 ASSERT(args.length() == 3); | 5578 ASSERT(args.length() == 3); |
5397 | 5579 |
5398 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5580 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5399 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5581 CONVERT_DOUBLE_CHECKED(y, args[1]); |
5400 if (isnan(x) || isnan(y)) return args[2]; | 5582 if (isnan(x) || isnan(y)) return args[2]; |
5401 if (x == y) return Smi::FromInt(EQUAL); | 5583 if (x == y) return Smi::FromInt(EQUAL); |
5402 if (isless(x, y)) return Smi::FromInt(LESS); | 5584 if (isless(x, y)) return Smi::FromInt(LESS); |
5403 return Smi::FromInt(GREATER); | 5585 return Smi::FromInt(GREATER); |
5404 } | 5586 } |
5405 | 5587 |
5406 | 5588 |
5407 // Compare two Smis as if they were converted to strings and then | 5589 // Compare two Smis as if they were converted to strings and then |
5408 // compared lexicographically. | 5590 // compared lexicographically. |
5409 static Object* Runtime_SmiLexicographicCompare(Arguments args) { | 5591 static MaybeObject* Runtime_SmiLexicographicCompare(Arguments args) { |
5410 NoHandleAllocation ha; | 5592 NoHandleAllocation ha; |
5411 ASSERT(args.length() == 2); | 5593 ASSERT(args.length() == 2); |
5412 | 5594 |
5413 // Arrays for the individual characters of the two Smis. Smis are | 5595 // Arrays for the individual characters of the two Smis. Smis are |
5414 // 31 bit integers and 10 decimal digits are therefore enough. | 5596 // 31 bit integers and 10 decimal digits are therefore enough. |
5415 static int x_elms[10]; | 5597 static int x_elms[10]; |
5416 static int y_elms[10]; | 5598 static int y_elms[10]; |
5417 | 5599 |
5418 // Extract the integer values from the Smis. | 5600 // Extract the integer values from the Smis. |
5419 CONVERT_CHECKED(Smi, x, args[0]); | 5601 CONVERT_CHECKED(Smi, x, args[0]); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5517 if (r == 0) { | 5699 if (r == 0) { |
5518 result = equal_prefix_result; | 5700 result = equal_prefix_result; |
5519 } else { | 5701 } else { |
5520 result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER); | 5702 result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER); |
5521 } | 5703 } |
5522 ASSERT(result == StringInputBufferCompare(x, y)); | 5704 ASSERT(result == StringInputBufferCompare(x, y)); |
5523 return result; | 5705 return result; |
5524 } | 5706 } |
5525 | 5707 |
5526 | 5708 |
5527 static Object* Runtime_StringCompare(Arguments args) { | 5709 static MaybeObject* Runtime_StringCompare(Arguments args) { |
5528 NoHandleAllocation ha; | 5710 NoHandleAllocation ha; |
5529 ASSERT(args.length() == 2); | 5711 ASSERT(args.length() == 2); |
5530 | 5712 |
5531 CONVERT_CHECKED(String, x, args[0]); | 5713 CONVERT_CHECKED(String, x, args[0]); |
5532 CONVERT_CHECKED(String, y, args[1]); | 5714 CONVERT_CHECKED(String, y, args[1]); |
5533 | 5715 |
5534 Counters::string_compare_runtime.Increment(); | 5716 Counters::string_compare_runtime.Increment(); |
5535 | 5717 |
5536 // A few fast case tests before we flatten. | 5718 // A few fast case tests before we flatten. |
5537 if (x == y) return Smi::FromInt(EQUAL); | 5719 if (x == y) return Smi::FromInt(EQUAL); |
5538 if (y->length() == 0) { | 5720 if (y->length() == 0) { |
5539 if (x->length() == 0) return Smi::FromInt(EQUAL); | 5721 if (x->length() == 0) return Smi::FromInt(EQUAL); |
5540 return Smi::FromInt(GREATER); | 5722 return Smi::FromInt(GREATER); |
5541 } else if (x->length() == 0) { | 5723 } else if (x->length() == 0) { |
5542 return Smi::FromInt(LESS); | 5724 return Smi::FromInt(LESS); |
5543 } | 5725 } |
5544 | 5726 |
5545 int d = x->Get(0) - y->Get(0); | 5727 int d = x->Get(0) - y->Get(0); |
5546 if (d < 0) return Smi::FromInt(LESS); | 5728 if (d < 0) return Smi::FromInt(LESS); |
5547 else if (d > 0) return Smi::FromInt(GREATER); | 5729 else if (d > 0) return Smi::FromInt(GREATER); |
5548 | 5730 |
5549 Object* obj = Heap::PrepareForCompare(x); | 5731 Object* obj; |
5550 if (obj->IsFailure()) return obj; | 5732 { MaybeObject* maybe_obj = Heap::PrepareForCompare(x); |
5551 obj = Heap::PrepareForCompare(y); | 5733 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
5552 if (obj->IsFailure()) return obj; | 5734 } |
| 5735 { MaybeObject* maybe_obj = Heap::PrepareForCompare(y); |
| 5736 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 5737 } |
5553 | 5738 |
5554 return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y) | 5739 return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y) |
5555 : StringInputBufferCompare(x, y); | 5740 : StringInputBufferCompare(x, y); |
5556 } | 5741 } |
5557 | 5742 |
5558 | 5743 |
5559 static Object* Runtime_Math_acos(Arguments args) { | 5744 static MaybeObject* Runtime_Math_acos(Arguments args) { |
5560 NoHandleAllocation ha; | 5745 NoHandleAllocation ha; |
5561 ASSERT(args.length() == 1); | 5746 ASSERT(args.length() == 1); |
5562 Counters::math_acos.Increment(); | 5747 Counters::math_acos.Increment(); |
5563 | 5748 |
5564 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5749 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5565 return TranscendentalCache::Get(TranscendentalCache::ACOS, x); | 5750 return TranscendentalCache::Get(TranscendentalCache::ACOS, x); |
5566 } | 5751 } |
5567 | 5752 |
5568 | 5753 |
5569 static Object* Runtime_Math_asin(Arguments args) { | 5754 static MaybeObject* Runtime_Math_asin(Arguments args) { |
5570 NoHandleAllocation ha; | 5755 NoHandleAllocation ha; |
5571 ASSERT(args.length() == 1); | 5756 ASSERT(args.length() == 1); |
5572 Counters::math_asin.Increment(); | 5757 Counters::math_asin.Increment(); |
5573 | 5758 |
5574 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5759 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5575 return TranscendentalCache::Get(TranscendentalCache::ASIN, x); | 5760 return TranscendentalCache::Get(TranscendentalCache::ASIN, x); |
5576 } | 5761 } |
5577 | 5762 |
5578 | 5763 |
5579 static Object* Runtime_Math_atan(Arguments args) { | 5764 static MaybeObject* Runtime_Math_atan(Arguments args) { |
5580 NoHandleAllocation ha; | 5765 NoHandleAllocation ha; |
5581 ASSERT(args.length() == 1); | 5766 ASSERT(args.length() == 1); |
5582 Counters::math_atan.Increment(); | 5767 Counters::math_atan.Increment(); |
5583 | 5768 |
5584 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5769 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5585 return TranscendentalCache::Get(TranscendentalCache::ATAN, x); | 5770 return TranscendentalCache::Get(TranscendentalCache::ATAN, x); |
5586 } | 5771 } |
5587 | 5772 |
5588 | 5773 |
5589 static Object* Runtime_Math_atan2(Arguments args) { | 5774 static MaybeObject* Runtime_Math_atan2(Arguments args) { |
5590 NoHandleAllocation ha; | 5775 NoHandleAllocation ha; |
5591 ASSERT(args.length() == 2); | 5776 ASSERT(args.length() == 2); |
5592 Counters::math_atan2.Increment(); | 5777 Counters::math_atan2.Increment(); |
5593 | 5778 |
5594 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5779 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5595 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5780 CONVERT_DOUBLE_CHECKED(y, args[1]); |
5596 double result; | 5781 double result; |
5597 if (isinf(x) && isinf(y)) { | 5782 if (isinf(x) && isinf(y)) { |
5598 // Make sure that the result in case of two infinite arguments | 5783 // Make sure that the result in case of two infinite arguments |
5599 // is a multiple of Pi / 4. The sign of the result is determined | 5784 // is a multiple of Pi / 4. The sign of the result is determined |
5600 // by the first argument (x) and the sign of the second argument | 5785 // by the first argument (x) and the sign of the second argument |
5601 // determines the multiplier: one or three. | 5786 // determines the multiplier: one or three. |
5602 static double kPiDividedBy4 = 0.78539816339744830962; | 5787 static double kPiDividedBy4 = 0.78539816339744830962; |
5603 int multiplier = (x < 0) ? -1 : 1; | 5788 int multiplier = (x < 0) ? -1 : 1; |
5604 if (y < 0) multiplier *= 3; | 5789 if (y < 0) multiplier *= 3; |
5605 result = multiplier * kPiDividedBy4; | 5790 result = multiplier * kPiDividedBy4; |
5606 } else { | 5791 } else { |
5607 result = atan2(x, y); | 5792 result = atan2(x, y); |
5608 } | 5793 } |
5609 return Heap::AllocateHeapNumber(result); | 5794 return Heap::AllocateHeapNumber(result); |
5610 } | 5795 } |
5611 | 5796 |
5612 | 5797 |
5613 static Object* Runtime_Math_ceil(Arguments args) { | 5798 static MaybeObject* Runtime_Math_ceil(Arguments args) { |
5614 NoHandleAllocation ha; | 5799 NoHandleAllocation ha; |
5615 ASSERT(args.length() == 1); | 5800 ASSERT(args.length() == 1); |
5616 Counters::math_ceil.Increment(); | 5801 Counters::math_ceil.Increment(); |
5617 | 5802 |
5618 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5803 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5619 return Heap::NumberFromDouble(ceiling(x)); | 5804 return Heap::NumberFromDouble(ceiling(x)); |
5620 } | 5805 } |
5621 | 5806 |
5622 | 5807 |
5623 static Object* Runtime_Math_cos(Arguments args) { | 5808 static MaybeObject* Runtime_Math_cos(Arguments args) { |
5624 NoHandleAllocation ha; | 5809 NoHandleAllocation ha; |
5625 ASSERT(args.length() == 1); | 5810 ASSERT(args.length() == 1); |
5626 Counters::math_cos.Increment(); | 5811 Counters::math_cos.Increment(); |
5627 | 5812 |
5628 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5813 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5629 return TranscendentalCache::Get(TranscendentalCache::COS, x); | 5814 return TranscendentalCache::Get(TranscendentalCache::COS, x); |
5630 } | 5815 } |
5631 | 5816 |
5632 | 5817 |
5633 static Object* Runtime_Math_exp(Arguments args) { | 5818 static MaybeObject* Runtime_Math_exp(Arguments args) { |
5634 NoHandleAllocation ha; | 5819 NoHandleAllocation ha; |
5635 ASSERT(args.length() == 1); | 5820 ASSERT(args.length() == 1); |
5636 Counters::math_exp.Increment(); | 5821 Counters::math_exp.Increment(); |
5637 | 5822 |
5638 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5823 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5639 return TranscendentalCache::Get(TranscendentalCache::EXP, x); | 5824 return TranscendentalCache::Get(TranscendentalCache::EXP, x); |
5640 } | 5825 } |
5641 | 5826 |
5642 | 5827 |
5643 static Object* Runtime_Math_floor(Arguments args) { | 5828 static MaybeObject* Runtime_Math_floor(Arguments args) { |
5644 NoHandleAllocation ha; | 5829 NoHandleAllocation ha; |
5645 ASSERT(args.length() == 1); | 5830 ASSERT(args.length() == 1); |
5646 Counters::math_floor.Increment(); | 5831 Counters::math_floor.Increment(); |
5647 | 5832 |
5648 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5833 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5649 return Heap::NumberFromDouble(floor(x)); | 5834 return Heap::NumberFromDouble(floor(x)); |
5650 } | 5835 } |
5651 | 5836 |
5652 | 5837 |
5653 static Object* Runtime_Math_log(Arguments args) { | 5838 static MaybeObject* Runtime_Math_log(Arguments args) { |
5654 NoHandleAllocation ha; | 5839 NoHandleAllocation ha; |
5655 ASSERT(args.length() == 1); | 5840 ASSERT(args.length() == 1); |
5656 Counters::math_log.Increment(); | 5841 Counters::math_log.Increment(); |
5657 | 5842 |
5658 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5843 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5659 return TranscendentalCache::Get(TranscendentalCache::LOG, x); | 5844 return TranscendentalCache::Get(TranscendentalCache::LOG, x); |
5660 } | 5845 } |
5661 | 5846 |
5662 | 5847 |
5663 // Helper function to compute x^y, where y is known to be an | 5848 // Helper function to compute x^y, where y is known to be an |
(...skipping 20 matching lines...) Expand all Loading... |
5684 : result; | 5869 : result; |
5685 } else { | 5870 } else { |
5686 return p; | 5871 return p; |
5687 } | 5872 } |
5688 } | 5873 } |
5689 m *= m; | 5874 m *= m; |
5690 } | 5875 } |
5691 } | 5876 } |
5692 | 5877 |
5693 | 5878 |
5694 static Object* Runtime_Math_pow(Arguments args) { | 5879 static MaybeObject* Runtime_Math_pow(Arguments args) { |
5695 NoHandleAllocation ha; | 5880 NoHandleAllocation ha; |
5696 ASSERT(args.length() == 2); | 5881 ASSERT(args.length() == 2); |
5697 Counters::math_pow.Increment(); | 5882 Counters::math_pow.Increment(); |
5698 | 5883 |
5699 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5884 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5700 | 5885 |
5701 // If the second argument is a smi, it is much faster to call the | 5886 // If the second argument is a smi, it is much faster to call the |
5702 // custom powi() function than the generic pow(). | 5887 // custom powi() function than the generic pow(). |
5703 if (args[1]->IsSmi()) { | 5888 if (args[1]->IsSmi()) { |
5704 int y = Smi::cast(args[1])->value(); | 5889 int y = Smi::cast(args[1])->value(); |
(...skipping 19 matching lines...) Expand all Loading... |
5724 return Smi::FromInt(1); | 5909 return Smi::FromInt(1); |
5725 } else if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) { | 5910 } else if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) { |
5726 return Heap::nan_value(); | 5911 return Heap::nan_value(); |
5727 } else { | 5912 } else { |
5728 return Heap::AllocateHeapNumber(pow(x, y)); | 5913 return Heap::AllocateHeapNumber(pow(x, y)); |
5729 } | 5914 } |
5730 } | 5915 } |
5731 | 5916 |
5732 // Fast version of Math.pow if we know that y is not an integer and | 5917 // Fast version of Math.pow if we know that y is not an integer and |
5733 // y is not -0.5 or 0.5. Used as slowcase from codegen. | 5918 // y is not -0.5 or 0.5. Used as slowcase from codegen. |
5734 static Object* Runtime_Math_pow_cfunction(Arguments args) { | 5919 static MaybeObject* Runtime_Math_pow_cfunction(Arguments args) { |
5735 NoHandleAllocation ha; | 5920 NoHandleAllocation ha; |
5736 ASSERT(args.length() == 2); | 5921 ASSERT(args.length() == 2); |
5737 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5922 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5738 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5923 CONVERT_DOUBLE_CHECKED(y, args[1]); |
5739 if (y == 0) { | 5924 if (y == 0) { |
5740 return Smi::FromInt(1); | 5925 return Smi::FromInt(1); |
5741 } else if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) { | 5926 } else if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) { |
5742 return Heap::nan_value(); | 5927 return Heap::nan_value(); |
5743 } else { | 5928 } else { |
5744 return Heap::AllocateHeapNumber(pow(x, y)); | 5929 return Heap::AllocateHeapNumber(pow(x, y)); |
5745 } | 5930 } |
5746 } | 5931 } |
5747 | 5932 |
5748 | 5933 |
5749 static Object* Runtime_RoundNumber(Arguments args) { | 5934 static MaybeObject* Runtime_RoundNumber(Arguments args) { |
5750 NoHandleAllocation ha; | 5935 NoHandleAllocation ha; |
5751 ASSERT(args.length() == 1); | 5936 ASSERT(args.length() == 1); |
5752 Counters::math_round.Increment(); | 5937 Counters::math_round.Increment(); |
5753 | 5938 |
5754 if (!args[0]->IsHeapNumber()) { | 5939 if (!args[0]->IsHeapNumber()) { |
5755 // Must be smi. Return the argument unchanged for all the other types | 5940 // Must be smi. Return the argument unchanged for all the other types |
5756 // to make fuzz-natives test happy. | 5941 // to make fuzz-natives test happy. |
5757 return args[0]; | 5942 return args[0]; |
5758 } | 5943 } |
5759 | 5944 |
(...skipping 15 matching lines...) Expand all Loading... |
5775 return number; | 5960 return number; |
5776 } | 5961 } |
5777 | 5962 |
5778 if (sign && value >= -0.5) return Heap::minus_zero_value(); | 5963 if (sign && value >= -0.5) return Heap::minus_zero_value(); |
5779 | 5964 |
5780 // Do not call NumberFromDouble() to avoid extra checks. | 5965 // Do not call NumberFromDouble() to avoid extra checks. |
5781 return Heap::AllocateHeapNumber(floor(value + 0.5)); | 5966 return Heap::AllocateHeapNumber(floor(value + 0.5)); |
5782 } | 5967 } |
5783 | 5968 |
5784 | 5969 |
5785 static Object* Runtime_Math_sin(Arguments args) { | 5970 static MaybeObject* Runtime_Math_sin(Arguments args) { |
5786 NoHandleAllocation ha; | 5971 NoHandleAllocation ha; |
5787 ASSERT(args.length() == 1); | 5972 ASSERT(args.length() == 1); |
5788 Counters::math_sin.Increment(); | 5973 Counters::math_sin.Increment(); |
5789 | 5974 |
5790 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5975 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5791 return TranscendentalCache::Get(TranscendentalCache::SIN, x); | 5976 return TranscendentalCache::Get(TranscendentalCache::SIN, x); |
5792 } | 5977 } |
5793 | 5978 |
5794 | 5979 |
5795 static Object* Runtime_Math_sqrt(Arguments args) { | 5980 static MaybeObject* Runtime_Math_sqrt(Arguments args) { |
5796 NoHandleAllocation ha; | 5981 NoHandleAllocation ha; |
5797 ASSERT(args.length() == 1); | 5982 ASSERT(args.length() == 1); |
5798 Counters::math_sqrt.Increment(); | 5983 Counters::math_sqrt.Increment(); |
5799 | 5984 |
5800 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5985 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5801 return Heap::AllocateHeapNumber(sqrt(x)); | 5986 return Heap::AllocateHeapNumber(sqrt(x)); |
5802 } | 5987 } |
5803 | 5988 |
5804 | 5989 |
5805 static Object* Runtime_Math_tan(Arguments args) { | 5990 static MaybeObject* Runtime_Math_tan(Arguments args) { |
5806 NoHandleAllocation ha; | 5991 NoHandleAllocation ha; |
5807 ASSERT(args.length() == 1); | 5992 ASSERT(args.length() == 1); |
5808 Counters::math_tan.Increment(); | 5993 Counters::math_tan.Increment(); |
5809 | 5994 |
5810 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5995 CONVERT_DOUBLE_CHECKED(x, args[0]); |
5811 return TranscendentalCache::Get(TranscendentalCache::TAN, x); | 5996 return TranscendentalCache::Get(TranscendentalCache::TAN, x); |
5812 } | 5997 } |
5813 | 5998 |
5814 | 5999 |
5815 static int MakeDay(int year, int month, int day) { | 6000 static int MakeDay(int year, int month, int day) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5850 base_day; | 6035 base_day; |
5851 | 6036 |
5852 if (year % 4 || (year % 100 == 0 && year % 400 != 0)) { | 6037 if (year % 4 || (year % 100 == 0 && year % 400 != 0)) { |
5853 return day_from_year + day_from_month[month] + day - 1; | 6038 return day_from_year + day_from_month[month] + day - 1; |
5854 } | 6039 } |
5855 | 6040 |
5856 return day_from_year + day_from_month_leap[month] + day - 1; | 6041 return day_from_year + day_from_month_leap[month] + day - 1; |
5857 } | 6042 } |
5858 | 6043 |
5859 | 6044 |
5860 static Object* Runtime_DateMakeDay(Arguments args) { | 6045 static MaybeObject* Runtime_DateMakeDay(Arguments args) { |
5861 NoHandleAllocation ha; | 6046 NoHandleAllocation ha; |
5862 ASSERT(args.length() == 3); | 6047 ASSERT(args.length() == 3); |
5863 | 6048 |
5864 CONVERT_SMI_CHECKED(year, args[0]); | 6049 CONVERT_SMI_CHECKED(year, args[0]); |
5865 CONVERT_SMI_CHECKED(month, args[1]); | 6050 CONVERT_SMI_CHECKED(month, args[1]); |
5866 CONVERT_SMI_CHECKED(date, args[2]); | 6051 CONVERT_SMI_CHECKED(date, args[2]); |
5867 | 6052 |
5868 return Smi::FromInt(MakeDay(year, month, date)); | 6053 return Smi::FromInt(MakeDay(year, month, date)); |
5869 } | 6054 } |
5870 | 6055 |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6149 static inline void DateYMDFromTime(int date, | 6334 static inline void DateYMDFromTime(int date, |
6150 int& year, int& month, int& day) { | 6335 int& year, int& month, int& day) { |
6151 if (date >= 0 && date < 32 * kDaysIn4Years) { | 6336 if (date >= 0 && date < 32 * kDaysIn4Years) { |
6152 DateYMDFromTimeAfter1970(date, year, month, day); | 6337 DateYMDFromTimeAfter1970(date, year, month, day); |
6153 } else { | 6338 } else { |
6154 DateYMDFromTimeSlow(date, year, month, day); | 6339 DateYMDFromTimeSlow(date, year, month, day); |
6155 } | 6340 } |
6156 } | 6341 } |
6157 | 6342 |
6158 | 6343 |
6159 static Object* Runtime_DateYMDFromTime(Arguments args) { | 6344 static MaybeObject* Runtime_DateYMDFromTime(Arguments args) { |
6160 NoHandleAllocation ha; | 6345 NoHandleAllocation ha; |
6161 ASSERT(args.length() == 2); | 6346 ASSERT(args.length() == 2); |
6162 | 6347 |
6163 CONVERT_DOUBLE_CHECKED(t, args[0]); | 6348 CONVERT_DOUBLE_CHECKED(t, args[0]); |
6164 CONVERT_CHECKED(JSArray, res_array, args[1]); | 6349 CONVERT_CHECKED(JSArray, res_array, args[1]); |
6165 | 6350 |
6166 int year, month, day; | 6351 int year, month, day; |
6167 DateYMDFromTime(static_cast<int>(floor(t / 86400000)), year, month, day); | 6352 DateYMDFromTime(static_cast<int>(floor(t / 86400000)), year, month, day); |
6168 | 6353 |
6169 RUNTIME_ASSERT(res_array->elements()->map() == Heap::fixed_array_map()); | 6354 RUNTIME_ASSERT(res_array->elements()->map() == Heap::fixed_array_map()); |
6170 FixedArray* elms = FixedArray::cast(res_array->elements()); | 6355 FixedArray* elms = FixedArray::cast(res_array->elements()); |
6171 RUNTIME_ASSERT(elms->length() == 3); | 6356 RUNTIME_ASSERT(elms->length() == 3); |
6172 | 6357 |
6173 elms->set(0, Smi::FromInt(year)); | 6358 elms->set(0, Smi::FromInt(year)); |
6174 elms->set(1, Smi::FromInt(month)); | 6359 elms->set(1, Smi::FromInt(month)); |
6175 elms->set(2, Smi::FromInt(day)); | 6360 elms->set(2, Smi::FromInt(day)); |
6176 | 6361 |
6177 return Heap::undefined_value(); | 6362 return Heap::undefined_value(); |
6178 } | 6363 } |
6179 | 6364 |
6180 | 6365 |
6181 static Object* Runtime_NewArgumentsFast(Arguments args) { | 6366 static MaybeObject* Runtime_NewArgumentsFast(Arguments args) { |
6182 NoHandleAllocation ha; | 6367 NoHandleAllocation ha; |
6183 ASSERT(args.length() == 3); | 6368 ASSERT(args.length() == 3); |
6184 | 6369 |
6185 JSFunction* callee = JSFunction::cast(args[0]); | 6370 JSFunction* callee = JSFunction::cast(args[0]); |
6186 Object** parameters = reinterpret_cast<Object**>(args[1]); | 6371 Object** parameters = reinterpret_cast<Object**>(args[1]); |
6187 const int length = Smi::cast(args[2])->value(); | 6372 const int length = Smi::cast(args[2])->value(); |
6188 | 6373 |
6189 Object* result = Heap::AllocateArgumentsObject(callee, length); | 6374 Object* result; |
6190 if (result->IsFailure()) return result; | 6375 { MaybeObject* maybe_result = Heap::AllocateArgumentsObject(callee, length); |
| 6376 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 6377 } |
6191 // Allocate the elements if needed. | 6378 // Allocate the elements if needed. |
6192 if (length > 0) { | 6379 if (length > 0) { |
6193 // Allocate the fixed array. | 6380 // Allocate the fixed array. |
6194 Object* obj = Heap::AllocateRawFixedArray(length); | 6381 Object* obj; |
6195 if (obj->IsFailure()) return obj; | 6382 { MaybeObject* maybe_obj = Heap::AllocateRawFixedArray(length); |
| 6383 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6384 } |
6196 | 6385 |
6197 AssertNoAllocation no_gc; | 6386 AssertNoAllocation no_gc; |
6198 FixedArray* array = reinterpret_cast<FixedArray*>(obj); | 6387 FixedArray* array = reinterpret_cast<FixedArray*>(obj); |
6199 array->set_map(Heap::fixed_array_map()); | 6388 array->set_map(Heap::fixed_array_map()); |
6200 array->set_length(length); | 6389 array->set_length(length); |
6201 | 6390 |
6202 WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc); | 6391 WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc); |
6203 for (int i = 0; i < length; i++) { | 6392 for (int i = 0; i < length; i++) { |
6204 array->set(i, *--parameters, mode); | 6393 array->set(i, *--parameters, mode); |
6205 } | 6394 } |
6206 JSObject::cast(result)->set_elements(FixedArray::cast(obj)); | 6395 JSObject::cast(result)->set_elements(FixedArray::cast(obj)); |
6207 } | 6396 } |
6208 return result; | 6397 return result; |
6209 } | 6398 } |
6210 | 6399 |
6211 | 6400 |
6212 static Object* Runtime_NewClosure(Arguments args) { | 6401 static MaybeObject* Runtime_NewClosure(Arguments args) { |
6213 HandleScope scope; | 6402 HandleScope scope; |
6214 ASSERT(args.length() == 2); | 6403 ASSERT(args.length() == 2); |
6215 CONVERT_ARG_CHECKED(Context, context, 0); | 6404 CONVERT_ARG_CHECKED(Context, context, 0); |
6216 CONVERT_ARG_CHECKED(SharedFunctionInfo, shared, 1); | 6405 CONVERT_ARG_CHECKED(SharedFunctionInfo, shared, 1); |
6217 | 6406 |
6218 PretenureFlag pretenure = (context->global_context() == *context) | 6407 PretenureFlag pretenure = (context->global_context() == *context) |
6219 ? TENURED // Allocate global closures in old space. | 6408 ? TENURED // Allocate global closures in old space. |
6220 : NOT_TENURED; // Allocate local closures in new space. | 6409 : NOT_TENURED; // Allocate local closures in new space. |
6221 Handle<JSFunction> result = | 6410 Handle<JSFunction> result = |
6222 Factory::NewFunctionFromSharedFunctionInfo(shared, context, pretenure); | 6411 Factory::NewFunctionFromSharedFunctionInfo(shared, context, pretenure); |
6223 return *result; | 6412 return *result; |
6224 } | 6413 } |
6225 | 6414 |
6226 static Object* Runtime_NewObjectFromBound(Arguments args) { | 6415 static MaybeObject* Runtime_NewObjectFromBound(Arguments args) { |
6227 HandleScope scope; | 6416 HandleScope scope; |
6228 ASSERT(args.length() == 2); | 6417 ASSERT(args.length() == 2); |
6229 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 6418 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
6230 CONVERT_ARG_CHECKED(JSArray, params, 1); | 6419 CONVERT_ARG_CHECKED(JSArray, params, 1); |
6231 | 6420 |
6232 RUNTIME_ASSERT(params->HasFastElements()); | 6421 RUNTIME_ASSERT(params->HasFastElements()); |
6233 FixedArray* fixed = FixedArray::cast(params->elements()); | 6422 FixedArray* fixed = FixedArray::cast(params->elements()); |
6234 | 6423 |
6235 int fixed_length = Smi::cast(params->length())->value(); | 6424 int fixed_length = Smi::cast(params->length())->value(); |
6236 SmartPointer<Object**> param_data(NewArray<Object**>(fixed_length)); | 6425 SmartPointer<Object**> param_data(NewArray<Object**>(fixed_length)); |
(...skipping 13 matching lines...) Expand all Loading... |
6250 } | 6439 } |
6251 | 6440 |
6252 | 6441 |
6253 static void TrySettingInlineConstructStub(Handle<JSFunction> function) { | 6442 static void TrySettingInlineConstructStub(Handle<JSFunction> function) { |
6254 Handle<Object> prototype = Factory::null_value(); | 6443 Handle<Object> prototype = Factory::null_value(); |
6255 if (function->has_instance_prototype()) { | 6444 if (function->has_instance_prototype()) { |
6256 prototype = Handle<Object>(function->instance_prototype()); | 6445 prototype = Handle<Object>(function->instance_prototype()); |
6257 } | 6446 } |
6258 if (function->shared()->CanGenerateInlineConstructor(*prototype)) { | 6447 if (function->shared()->CanGenerateInlineConstructor(*prototype)) { |
6259 ConstructStubCompiler compiler; | 6448 ConstructStubCompiler compiler; |
6260 Object* code = compiler.CompileConstructStub(function->shared()); | 6449 MaybeObject* code = compiler.CompileConstructStub(function->shared()); |
6261 if (!code->IsFailure()) { | 6450 if (!code->IsFailure()) { |
6262 function->shared()->set_construct_stub(Code::cast(code)); | 6451 function->shared()->set_construct_stub( |
| 6452 Code::cast(code->ToObjectUnchecked())); |
6263 } | 6453 } |
6264 } | 6454 } |
6265 } | 6455 } |
6266 | 6456 |
6267 | 6457 |
6268 static Object* Runtime_NewObject(Arguments args) { | 6458 static MaybeObject* Runtime_NewObject(Arguments args) { |
6269 HandleScope scope; | 6459 HandleScope scope; |
6270 ASSERT(args.length() == 1); | 6460 ASSERT(args.length() == 1); |
6271 | 6461 |
6272 Handle<Object> constructor = args.at<Object>(0); | 6462 Handle<Object> constructor = args.at<Object>(0); |
6273 | 6463 |
6274 // If the constructor isn't a proper function we throw a type error. | 6464 // If the constructor isn't a proper function we throw a type error. |
6275 if (!constructor->IsJSFunction()) { | 6465 if (!constructor->IsJSFunction()) { |
6276 Vector< Handle<Object> > arguments = HandleVector(&constructor, 1); | 6466 Vector< Handle<Object> > arguments = HandleVector(&constructor, 1); |
6277 Handle<Object> type_error = | 6467 Handle<Object> type_error = |
6278 Factory::NewTypeError("not_constructor", arguments); | 6468 Factory::NewTypeError("not_constructor", arguments); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6334 TrySettingInlineConstructStub(function); | 6524 TrySettingInlineConstructStub(function); |
6335 } | 6525 } |
6336 | 6526 |
6337 Counters::constructed_objects.Increment(); | 6527 Counters::constructed_objects.Increment(); |
6338 Counters::constructed_objects_runtime.Increment(); | 6528 Counters::constructed_objects_runtime.Increment(); |
6339 | 6529 |
6340 return *result; | 6530 return *result; |
6341 } | 6531 } |
6342 | 6532 |
6343 | 6533 |
6344 static Object* Runtime_FinalizeInstanceSize(Arguments args) { | 6534 static MaybeObject* Runtime_FinalizeInstanceSize(Arguments args) { |
6345 HandleScope scope; | 6535 HandleScope scope; |
6346 ASSERT(args.length() == 1); | 6536 ASSERT(args.length() == 1); |
6347 | 6537 |
6348 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 6538 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
6349 function->shared()->CompleteInobjectSlackTracking(); | 6539 function->shared()->CompleteInobjectSlackTracking(); |
6350 TrySettingInlineConstructStub(function); | 6540 TrySettingInlineConstructStub(function); |
6351 | 6541 |
6352 return Heap::undefined_value(); | 6542 return Heap::undefined_value(); |
6353 } | 6543 } |
6354 | 6544 |
6355 | 6545 |
6356 static Object* Runtime_LazyCompile(Arguments args) { | 6546 static MaybeObject* Runtime_LazyCompile(Arguments args) { |
6357 HandleScope scope; | 6547 HandleScope scope; |
6358 ASSERT(args.length() == 1); | 6548 ASSERT(args.length() == 1); |
6359 | 6549 |
6360 Handle<JSFunction> function = args.at<JSFunction>(0); | 6550 Handle<JSFunction> function = args.at<JSFunction>(0); |
6361 #ifdef DEBUG | 6551 #ifdef DEBUG |
6362 if (FLAG_trace_lazy && !function->shared()->is_compiled()) { | 6552 if (FLAG_trace_lazy && !function->shared()->is_compiled()) { |
6363 PrintF("[lazy: "); | 6553 PrintF("[lazy: "); |
6364 function->shared()->name()->Print(); | 6554 function->shared()->name()->Print(); |
6365 PrintF("]\n"); | 6555 PrintF("]\n"); |
6366 } | 6556 } |
6367 #endif | 6557 #endif |
6368 | 6558 |
6369 // Compile the target function. Here we compile using CompileLazyInLoop in | 6559 // Compile the target function. Here we compile using CompileLazyInLoop in |
6370 // order to get the optimized version. This helps code like delta-blue | 6560 // order to get the optimized version. This helps code like delta-blue |
6371 // that calls performance-critical routines through constructors. A | 6561 // that calls performance-critical routines through constructors. A |
6372 // constructor call doesn't use a CallIC, it uses a LoadIC followed by a | 6562 // constructor call doesn't use a CallIC, it uses a LoadIC followed by a |
6373 // direct call. Since the in-loop tracking takes place through CallICs | 6563 // direct call. Since the in-loop tracking takes place through CallICs |
6374 // this means that things called through constructors are never known to | 6564 // this means that things called through constructors are never known to |
6375 // be in loops. We compile them as if they are in loops here just in case. | 6565 // be in loops. We compile them as if they are in loops here just in case. |
6376 ASSERT(!function->is_compiled()); | 6566 ASSERT(!function->is_compiled()); |
6377 if (!CompileLazyInLoop(function, KEEP_EXCEPTION)) { | 6567 if (!CompileLazyInLoop(function, KEEP_EXCEPTION)) { |
6378 return Failure::Exception(); | 6568 return Failure::Exception(); |
6379 } | 6569 } |
6380 | 6570 |
6381 return function->code(); | 6571 return function->code(); |
6382 } | 6572 } |
6383 | 6573 |
6384 | 6574 |
6385 static Object* Runtime_GetFunctionDelegate(Arguments args) { | 6575 static MaybeObject* Runtime_GetFunctionDelegate(Arguments args) { |
6386 HandleScope scope; | 6576 HandleScope scope; |
6387 ASSERT(args.length() == 1); | 6577 ASSERT(args.length() == 1); |
6388 RUNTIME_ASSERT(!args[0]->IsJSFunction()); | 6578 RUNTIME_ASSERT(!args[0]->IsJSFunction()); |
6389 return *Execution::GetFunctionDelegate(args.at<Object>(0)); | 6579 return *Execution::GetFunctionDelegate(args.at<Object>(0)); |
6390 } | 6580 } |
6391 | 6581 |
6392 | 6582 |
6393 static Object* Runtime_GetConstructorDelegate(Arguments args) { | 6583 static MaybeObject* Runtime_GetConstructorDelegate(Arguments args) { |
6394 HandleScope scope; | 6584 HandleScope scope; |
6395 ASSERT(args.length() == 1); | 6585 ASSERT(args.length() == 1); |
6396 RUNTIME_ASSERT(!args[0]->IsJSFunction()); | 6586 RUNTIME_ASSERT(!args[0]->IsJSFunction()); |
6397 return *Execution::GetConstructorDelegate(args.at<Object>(0)); | 6587 return *Execution::GetConstructorDelegate(args.at<Object>(0)); |
6398 } | 6588 } |
6399 | 6589 |
6400 | 6590 |
6401 static Object* Runtime_NewContext(Arguments args) { | 6591 static MaybeObject* Runtime_NewContext(Arguments args) { |
6402 NoHandleAllocation ha; | 6592 NoHandleAllocation ha; |
6403 ASSERT(args.length() == 1); | 6593 ASSERT(args.length() == 1); |
6404 | 6594 |
6405 CONVERT_CHECKED(JSFunction, function, args[0]); | 6595 CONVERT_CHECKED(JSFunction, function, args[0]); |
6406 int length = function->shared()->scope_info()->NumberOfContextSlots(); | 6596 int length = function->shared()->scope_info()->NumberOfContextSlots(); |
6407 Object* result = Heap::AllocateFunctionContext(length, function); | 6597 Object* result; |
6408 if (result->IsFailure()) return result; | 6598 { MaybeObject* maybe_result = Heap::AllocateFunctionContext(length, function); |
| 6599 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 6600 } |
6409 | 6601 |
6410 Top::set_context(Context::cast(result)); | 6602 Top::set_context(Context::cast(result)); |
6411 | 6603 |
6412 return result; // non-failure | 6604 return result; // non-failure |
6413 } | 6605 } |
6414 | 6606 |
6415 static Object* PushContextHelper(Object* object, bool is_catch_context) { | 6607 |
| 6608 MUST_USE_RESULT static MaybeObject* PushContextHelper(Object* object, |
| 6609 bool is_catch_context) { |
6416 // Convert the object to a proper JavaScript object. | 6610 // Convert the object to a proper JavaScript object. |
6417 Object* js_object = object; | 6611 Object* js_object = object; |
6418 if (!js_object->IsJSObject()) { | 6612 if (!js_object->IsJSObject()) { |
6419 js_object = js_object->ToObject(); | 6613 MaybeObject* maybe_js_object = js_object->ToObject(); |
6420 if (js_object->IsFailure()) { | 6614 if (!maybe_js_object->ToObject(&js_object)) { |
6421 if (!Failure::cast(js_object)->IsInternalError()) return js_object; | 6615 if (!Failure::cast(maybe_js_object)->IsInternalError()) { |
| 6616 return maybe_js_object; |
| 6617 } |
6422 HandleScope scope; | 6618 HandleScope scope; |
6423 Handle<Object> handle(object); | 6619 Handle<Object> handle(object); |
6424 Handle<Object> result = | 6620 Handle<Object> result = |
6425 Factory::NewTypeError("with_expression", HandleVector(&handle, 1)); | 6621 Factory::NewTypeError("with_expression", HandleVector(&handle, 1)); |
6426 return Top::Throw(*result); | 6622 return Top::Throw(*result); |
6427 } | 6623 } |
6428 } | 6624 } |
6429 | 6625 |
6430 Object* result = | 6626 Object* result; |
6431 Heap::AllocateWithContext(Top::context(), | 6627 { MaybeObject* maybe_result = |
6432 JSObject::cast(js_object), | 6628 Heap::AllocateWithContext(Top::context(), |
6433 is_catch_context); | 6629 JSObject::cast(js_object), |
6434 if (result->IsFailure()) return result; | 6630 is_catch_context); |
| 6631 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 6632 } |
6435 | 6633 |
6436 Context* context = Context::cast(result); | 6634 Context* context = Context::cast(result); |
6437 Top::set_context(context); | 6635 Top::set_context(context); |
6438 | 6636 |
6439 return result; | 6637 return result; |
6440 } | 6638 } |
6441 | 6639 |
6442 | 6640 |
6443 static Object* Runtime_PushContext(Arguments args) { | 6641 static MaybeObject* Runtime_PushContext(Arguments args) { |
6444 NoHandleAllocation ha; | 6642 NoHandleAllocation ha; |
6445 ASSERT(args.length() == 1); | 6643 ASSERT(args.length() == 1); |
6446 return PushContextHelper(args[0], false); | 6644 return PushContextHelper(args[0], false); |
6447 } | 6645 } |
6448 | 6646 |
6449 | 6647 |
6450 static Object* Runtime_PushCatchContext(Arguments args) { | 6648 static MaybeObject* Runtime_PushCatchContext(Arguments args) { |
6451 NoHandleAllocation ha; | 6649 NoHandleAllocation ha; |
6452 ASSERT(args.length() == 1); | 6650 ASSERT(args.length() == 1); |
6453 return PushContextHelper(args[0], true); | 6651 return PushContextHelper(args[0], true); |
6454 } | 6652 } |
6455 | 6653 |
6456 | 6654 |
6457 static Object* Runtime_LookupContext(Arguments args) { | 6655 static MaybeObject* Runtime_LookupContext(Arguments args) { |
6458 HandleScope scope; | 6656 HandleScope scope; |
6459 ASSERT(args.length() == 2); | 6657 ASSERT(args.length() == 2); |
6460 | 6658 |
6461 CONVERT_ARG_CHECKED(Context, context, 0); | 6659 CONVERT_ARG_CHECKED(Context, context, 0); |
6462 CONVERT_ARG_CHECKED(String, name, 1); | 6660 CONVERT_ARG_CHECKED(String, name, 1); |
6463 | 6661 |
6464 int index; | 6662 int index; |
6465 PropertyAttributes attributes; | 6663 PropertyAttributes attributes; |
6466 ContextLookupFlags flags = FOLLOW_CHAINS; | 6664 ContextLookupFlags flags = FOLLOW_CHAINS; |
6467 Handle<Object> holder = | 6665 Handle<Object> holder = |
(...skipping 12 matching lines...) Expand all Loading... |
6480 // A mechanism to return a pair of Object pointers in registers (if possible). | 6678 // A mechanism to return a pair of Object pointers in registers (if possible). |
6481 // How this is achieved is calling convention-dependent. | 6679 // How this is achieved is calling convention-dependent. |
6482 // All currently supported x86 compiles uses calling conventions that are cdecl | 6680 // All currently supported x86 compiles uses calling conventions that are cdecl |
6483 // variants where a 64-bit value is returned in two 32-bit registers | 6681 // variants where a 64-bit value is returned in two 32-bit registers |
6484 // (edx:eax on ia32, r1:r0 on ARM). | 6682 // (edx:eax on ia32, r1:r0 on ARM). |
6485 // In AMD-64 calling convention a struct of two pointers is returned in rdx:rax. | 6683 // In AMD-64 calling convention a struct of two pointers is returned in rdx:rax. |
6486 // In Win64 calling convention, a struct of two pointers is returned in memory, | 6684 // In Win64 calling convention, a struct of two pointers is returned in memory, |
6487 // allocated by the caller, and passed as a pointer in a hidden first parameter. | 6685 // allocated by the caller, and passed as a pointer in a hidden first parameter. |
6488 #ifdef V8_HOST_ARCH_64_BIT | 6686 #ifdef V8_HOST_ARCH_64_BIT |
6489 struct ObjectPair { | 6687 struct ObjectPair { |
6490 Object* x; | 6688 MaybeObject* x; |
6491 Object* y; | 6689 MaybeObject* y; |
6492 }; | 6690 }; |
6493 | 6691 |
6494 static inline ObjectPair MakePair(Object* x, Object* y) { | 6692 static inline ObjectPair MakePair(MaybeObject* x, MaybeObject* y) { |
6495 ObjectPair result = {x, y}; | 6693 ObjectPair result = {x, y}; |
6496 // Pointers x and y returned in rax and rdx, in AMD-x64-abi. | 6694 // Pointers x and y returned in rax and rdx, in AMD-x64-abi. |
6497 // In Win64 they are assigned to a hidden first argument. | 6695 // In Win64 they are assigned to a hidden first argument. |
6498 return result; | 6696 return result; |
6499 } | 6697 } |
6500 #else | 6698 #else |
6501 typedef uint64_t ObjectPair; | 6699 typedef uint64_t ObjectPair; |
6502 static inline ObjectPair MakePair(Object* x, Object* y) { | 6700 static inline ObjectPair MakePair(MaybeObject* x, MaybeObject* y) { |
6503 return reinterpret_cast<uint32_t>(x) | | 6701 return reinterpret_cast<uint32_t>(x) | |
6504 (reinterpret_cast<ObjectPair>(y) << 32); | 6702 (reinterpret_cast<ObjectPair>(y) << 32); |
6505 } | 6703 } |
6506 #endif | 6704 #endif |
6507 | 6705 |
6508 | 6706 |
6509 static inline Object* Unhole(Object* x, PropertyAttributes attributes) { | 6707 static inline MaybeObject* Unhole(MaybeObject* x, |
| 6708 PropertyAttributes attributes) { |
6510 ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0); | 6709 ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0); |
6511 USE(attributes); | 6710 USE(attributes); |
6512 return x->IsTheHole() ? Heap::undefined_value() : x; | 6711 return x->IsTheHole() ? Heap::undefined_value() : x; |
6513 } | 6712 } |
6514 | 6713 |
6515 | 6714 |
6516 static JSObject* ComputeReceiverForNonGlobal(JSObject* holder) { | 6715 static JSObject* ComputeReceiverForNonGlobal(JSObject* holder) { |
6517 ASSERT(!holder->IsGlobalObject()); | 6716 ASSERT(!holder->IsGlobalObject()); |
6518 Context* top = Top::context(); | 6717 Context* top = Top::context(); |
6519 // Get the context extension function. | 6718 // Get the context extension function. |
(...skipping 29 matching lines...) Expand all Loading... |
6549 context->Lookup(name, flags, &index, &attributes); | 6748 context->Lookup(name, flags, &index, &attributes); |
6550 | 6749 |
6551 // If the index is non-negative, the slot has been found in a local | 6750 // If the index is non-negative, the slot has been found in a local |
6552 // variable or a parameter. Read it from the context object or the | 6751 // variable or a parameter. Read it from the context object or the |
6553 // arguments object. | 6752 // arguments object. |
6554 if (index >= 0) { | 6753 if (index >= 0) { |
6555 // If the "property" we were looking for is a local variable or an | 6754 // If the "property" we were looking for is a local variable or an |
6556 // argument in a context, the receiver is the global object; see | 6755 // argument in a context, the receiver is the global object; see |
6557 // ECMA-262, 3rd., 10.1.6 and 10.2.3. | 6756 // ECMA-262, 3rd., 10.1.6 and 10.2.3. |
6558 JSObject* receiver = Top::context()->global()->global_receiver(); | 6757 JSObject* receiver = Top::context()->global()->global_receiver(); |
6559 Object* value = (holder->IsContext()) | 6758 MaybeObject* value = (holder->IsContext()) |
6560 ? Context::cast(*holder)->get(index) | 6759 ? Context::cast(*holder)->get(index) |
6561 : JSObject::cast(*holder)->GetElement(index); | 6760 : JSObject::cast(*holder)->GetElement(index); |
6562 return MakePair(Unhole(value, attributes), receiver); | 6761 return MakePair(Unhole(value, attributes), receiver); |
6563 } | 6762 } |
6564 | 6763 |
6565 // If the holder is found, we read the property from it. | 6764 // If the holder is found, we read the property from it. |
6566 if (!holder.is_null() && holder->IsJSObject()) { | 6765 if (!holder.is_null() && holder->IsJSObject()) { |
6567 ASSERT(Handle<JSObject>::cast(holder)->HasProperty(*name)); | 6766 ASSERT(Handle<JSObject>::cast(holder)->HasProperty(*name)); |
6568 JSObject* object = JSObject::cast(*holder); | 6767 JSObject* object = JSObject::cast(*holder); |
6569 JSObject* receiver; | 6768 JSObject* receiver; |
6570 if (object->IsGlobalObject()) { | 6769 if (object->IsGlobalObject()) { |
6571 receiver = GlobalObject::cast(object)->global_receiver(); | 6770 receiver = GlobalObject::cast(object)->global_receiver(); |
6572 } else if (context->is_exception_holder(*holder)) { | 6771 } else if (context->is_exception_holder(*holder)) { |
6573 receiver = Top::context()->global()->global_receiver(); | 6772 receiver = Top::context()->global()->global_receiver(); |
6574 } else { | 6773 } else { |
6575 receiver = ComputeReceiverForNonGlobal(object); | 6774 receiver = ComputeReceiverForNonGlobal(object); |
6576 } | 6775 } |
6577 // No need to unhole the value here. This is taken care of by the | 6776 // No need to unhole the value here. This is taken care of by the |
6578 // GetProperty function. | 6777 // GetProperty function. |
6579 Object* value = object->GetProperty(*name); | 6778 MaybeObject* value = object->GetProperty(*name); |
6580 return MakePair(value, receiver); | 6779 return MakePair(value, receiver); |
6581 } | 6780 } |
6582 | 6781 |
6583 if (throw_error) { | 6782 if (throw_error) { |
6584 // The property doesn't exist - throw exception. | 6783 // The property doesn't exist - throw exception. |
6585 Handle<Object> reference_error = | 6784 Handle<Object> reference_error = |
6586 Factory::NewReferenceError("not_defined", HandleVector(&name, 1)); | 6785 Factory::NewReferenceError("not_defined", HandleVector(&name, 1)); |
6587 return MakePair(Top::Throw(*reference_error), NULL); | 6786 return MakePair(Top::Throw(*reference_error), NULL); |
6588 } else { | 6787 } else { |
6589 // The property doesn't exist - return undefined | 6788 // The property doesn't exist - return undefined |
6590 return MakePair(Heap::undefined_value(), Heap::undefined_value()); | 6789 return MakePair(Heap::undefined_value(), Heap::undefined_value()); |
6591 } | 6790 } |
6592 } | 6791 } |
6593 | 6792 |
6594 | 6793 |
6595 static ObjectPair Runtime_LoadContextSlot(Arguments args) { | 6794 static ObjectPair Runtime_LoadContextSlot(Arguments args) { |
6596 return LoadContextSlotHelper(args, true); | 6795 return LoadContextSlotHelper(args, true); |
6597 } | 6796 } |
6598 | 6797 |
6599 | 6798 |
6600 static ObjectPair Runtime_LoadContextSlotNoReferenceError(Arguments args) { | 6799 static ObjectPair Runtime_LoadContextSlotNoReferenceError(Arguments args) { |
6601 return LoadContextSlotHelper(args, false); | 6800 return LoadContextSlotHelper(args, false); |
6602 } | 6801 } |
6603 | 6802 |
6604 | 6803 |
6605 static Object* Runtime_StoreContextSlot(Arguments args) { | 6804 static MaybeObject* Runtime_StoreContextSlot(Arguments args) { |
6606 HandleScope scope; | 6805 HandleScope scope; |
6607 ASSERT(args.length() == 3); | 6806 ASSERT(args.length() == 3); |
6608 | 6807 |
6609 Handle<Object> value(args[0]); | 6808 Handle<Object> value(args[0]); |
6610 CONVERT_ARG_CHECKED(Context, context, 1); | 6809 CONVERT_ARG_CHECKED(Context, context, 1); |
6611 CONVERT_ARG_CHECKED(String, name, 2); | 6810 CONVERT_ARG_CHECKED(String, name, 2); |
6612 | 6811 |
6613 int index; | 6812 int index; |
6614 PropertyAttributes attributes; | 6813 PropertyAttributes attributes; |
6615 ContextLookupFlags flags = FOLLOW_CHAINS; | 6814 ContextLookupFlags flags = FOLLOW_CHAINS; |
6616 Handle<Object> holder = | 6815 Handle<Object> holder = |
6617 context->Lookup(name, flags, &index, &attributes); | 6816 context->Lookup(name, flags, &index, &attributes); |
6618 | 6817 |
6619 if (index >= 0) { | 6818 if (index >= 0) { |
6620 if (holder->IsContext()) { | 6819 if (holder->IsContext()) { |
6621 // Ignore if read_only variable. | 6820 // Ignore if read_only variable. |
6622 if ((attributes & READ_ONLY) == 0) { | 6821 if ((attributes & READ_ONLY) == 0) { |
6623 Handle<Context>::cast(holder)->set(index, *value); | 6822 Handle<Context>::cast(holder)->set(index, *value); |
6624 } | 6823 } |
6625 } else { | 6824 } else { |
6626 ASSERT((attributes & READ_ONLY) == 0); | 6825 ASSERT((attributes & READ_ONLY) == 0); |
6627 Object* result = | 6826 Handle<JSObject>::cast(holder)->SetElement(index, *value)-> |
6628 Handle<JSObject>::cast(holder)->SetElement(index, *value); | 6827 ToObjectUnchecked(); |
6629 USE(result); | |
6630 ASSERT(!result->IsFailure()); | |
6631 } | 6828 } |
6632 return *value; | 6829 return *value; |
6633 } | 6830 } |
6634 | 6831 |
6635 // Slow case: The property is not in a FixedArray context. | 6832 // Slow case: The property is not in a FixedArray context. |
6636 // It is either in an JSObject extension context or it was not found. | 6833 // It is either in an JSObject extension context or it was not found. |
6637 Handle<JSObject> context_ext; | 6834 Handle<JSObject> context_ext; |
6638 | 6835 |
6639 if (!holder.is_null()) { | 6836 if (!holder.is_null()) { |
6640 // The property exists in the extension context. | 6837 // The property exists in the extension context. |
(...skipping 15 matching lines...) Expand all Loading... |
6656 // handle-based methods such as SetProperty. We therefore need | 6853 // handle-based methods such as SetProperty. We therefore need |
6657 // to convert null handles back to exceptions. | 6854 // to convert null handles back to exceptions. |
6658 ASSERT(Top::has_pending_exception()); | 6855 ASSERT(Top::has_pending_exception()); |
6659 return Failure::Exception(); | 6856 return Failure::Exception(); |
6660 } | 6857 } |
6661 } | 6858 } |
6662 return *value; | 6859 return *value; |
6663 } | 6860 } |
6664 | 6861 |
6665 | 6862 |
6666 static Object* Runtime_Throw(Arguments args) { | 6863 static MaybeObject* Runtime_Throw(Arguments args) { |
6667 HandleScope scope; | 6864 HandleScope scope; |
6668 ASSERT(args.length() == 1); | 6865 ASSERT(args.length() == 1); |
6669 | 6866 |
6670 return Top::Throw(args[0]); | 6867 return Top::Throw(args[0]); |
6671 } | 6868 } |
6672 | 6869 |
6673 | 6870 |
6674 static Object* Runtime_ReThrow(Arguments args) { | 6871 static MaybeObject* Runtime_ReThrow(Arguments args) { |
6675 HandleScope scope; | 6872 HandleScope scope; |
6676 ASSERT(args.length() == 1); | 6873 ASSERT(args.length() == 1); |
6677 | 6874 |
6678 return Top::ReThrow(args[0]); | 6875 return Top::ReThrow(args[0]); |
6679 } | 6876 } |
6680 | 6877 |
6681 | 6878 |
6682 static Object* Runtime_PromoteScheduledException(Arguments args) { | 6879 static MaybeObject* Runtime_PromoteScheduledException(Arguments args) { |
6683 ASSERT_EQ(0, args.length()); | 6880 ASSERT_EQ(0, args.length()); |
6684 return Top::PromoteScheduledException(); | 6881 return Top::PromoteScheduledException(); |
6685 } | 6882 } |
6686 | 6883 |
6687 | 6884 |
6688 static Object* Runtime_ThrowReferenceError(Arguments args) { | 6885 static MaybeObject* Runtime_ThrowReferenceError(Arguments args) { |
6689 HandleScope scope; | 6886 HandleScope scope; |
6690 ASSERT(args.length() == 1); | 6887 ASSERT(args.length() == 1); |
6691 | 6888 |
6692 Handle<Object> name(args[0]); | 6889 Handle<Object> name(args[0]); |
6693 Handle<Object> reference_error = | 6890 Handle<Object> reference_error = |
6694 Factory::NewReferenceError("not_defined", HandleVector(&name, 1)); | 6891 Factory::NewReferenceError("not_defined", HandleVector(&name, 1)); |
6695 return Top::Throw(*reference_error); | 6892 return Top::Throw(*reference_error); |
6696 } | 6893 } |
6697 | 6894 |
6698 | 6895 |
6699 static Object* Runtime_StackOverflow(Arguments args) { | 6896 static MaybeObject* Runtime_StackOverflow(Arguments args) { |
6700 NoHandleAllocation na; | 6897 NoHandleAllocation na; |
6701 return Top::StackOverflow(); | 6898 return Top::StackOverflow(); |
6702 } | 6899 } |
6703 | 6900 |
6704 | 6901 |
6705 static Object* Runtime_StackGuard(Arguments args) { | 6902 static MaybeObject* Runtime_StackGuard(Arguments args) { |
6706 ASSERT(args.length() == 0); | 6903 ASSERT(args.length() == 0); |
6707 | 6904 |
6708 // First check if this is a real stack overflow. | 6905 // First check if this is a real stack overflow. |
6709 if (StackGuard::IsStackOverflow()) { | 6906 if (StackGuard::IsStackOverflow()) { |
6710 return Runtime_StackOverflow(args); | 6907 return Runtime_StackOverflow(args); |
6711 } | 6908 } |
6712 | 6909 |
6713 return Execution::HandleStackGuardInterrupt(); | 6910 return Execution::HandleStackGuardInterrupt(); |
6714 } | 6911 } |
6715 | 6912 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6793 | 6990 |
6794 } else { | 6991 } else { |
6795 // function result | 6992 // function result |
6796 PrintF("} -> "); | 6993 PrintF("} -> "); |
6797 PrintObject(result); | 6994 PrintObject(result); |
6798 PrintF("\n"); | 6995 PrintF("\n"); |
6799 } | 6996 } |
6800 } | 6997 } |
6801 | 6998 |
6802 | 6999 |
6803 static Object* Runtime_TraceEnter(Arguments args) { | 7000 static MaybeObject* Runtime_TraceEnter(Arguments args) { |
6804 ASSERT(args.length() == 0); | 7001 ASSERT(args.length() == 0); |
6805 NoHandleAllocation ha; | 7002 NoHandleAllocation ha; |
6806 PrintTransition(NULL); | 7003 PrintTransition(NULL); |
6807 return Heap::undefined_value(); | 7004 return Heap::undefined_value(); |
6808 } | 7005 } |
6809 | 7006 |
6810 | 7007 |
6811 static Object* Runtime_TraceExit(Arguments args) { | 7008 static MaybeObject* Runtime_TraceExit(Arguments args) { |
6812 NoHandleAllocation ha; | 7009 NoHandleAllocation ha; |
6813 PrintTransition(args[0]); | 7010 PrintTransition(args[0]); |
6814 return args[0]; // return TOS | 7011 return args[0]; // return TOS |
6815 } | 7012 } |
6816 | 7013 |
6817 | 7014 |
6818 static Object* Runtime_DebugPrint(Arguments args) { | 7015 static MaybeObject* Runtime_DebugPrint(Arguments args) { |
6819 NoHandleAllocation ha; | 7016 NoHandleAllocation ha; |
6820 ASSERT(args.length() == 1); | 7017 ASSERT(args.length() == 1); |
6821 | 7018 |
6822 #ifdef DEBUG | 7019 #ifdef DEBUG |
6823 if (args[0]->IsString()) { | 7020 if (args[0]->IsString()) { |
6824 // If we have a string, assume it's a code "marker" | 7021 // If we have a string, assume it's a code "marker" |
6825 // and print some interesting cpu debugging info. | 7022 // and print some interesting cpu debugging info. |
6826 JavaScriptFrameIterator it; | 7023 JavaScriptFrameIterator it; |
6827 JavaScriptFrame* frame = it.frame(); | 7024 JavaScriptFrame* frame = it.frame(); |
6828 PrintF("fp = %p, sp = %p, caller_sp = %p: ", | 7025 PrintF("fp = %p, sp = %p, caller_sp = %p: ", |
(...skipping 10 matching lines...) Expand all Loading... |
6839 // ShortPrint is available in release mode. Print is not. | 7036 // ShortPrint is available in release mode. Print is not. |
6840 args[0]->ShortPrint(); | 7037 args[0]->ShortPrint(); |
6841 #endif | 7038 #endif |
6842 PrintF("\n"); | 7039 PrintF("\n"); |
6843 Flush(); | 7040 Flush(); |
6844 | 7041 |
6845 return args[0]; // return TOS | 7042 return args[0]; // return TOS |
6846 } | 7043 } |
6847 | 7044 |
6848 | 7045 |
6849 static Object* Runtime_DebugTrace(Arguments args) { | 7046 static MaybeObject* Runtime_DebugTrace(Arguments args) { |
6850 ASSERT(args.length() == 0); | 7047 ASSERT(args.length() == 0); |
6851 NoHandleAllocation ha; | 7048 NoHandleAllocation ha; |
6852 Top::PrintStack(); | 7049 Top::PrintStack(); |
6853 return Heap::undefined_value(); | 7050 return Heap::undefined_value(); |
6854 } | 7051 } |
6855 | 7052 |
6856 | 7053 |
6857 static Object* Runtime_DateCurrentTime(Arguments args) { | 7054 static MaybeObject* Runtime_DateCurrentTime(Arguments args) { |
6858 NoHandleAllocation ha; | 7055 NoHandleAllocation ha; |
6859 ASSERT(args.length() == 0); | 7056 ASSERT(args.length() == 0); |
6860 | 7057 |
6861 // According to ECMA-262, section 15.9.1, page 117, the precision of | 7058 // According to ECMA-262, section 15.9.1, page 117, the precision of |
6862 // the number in a Date object representing a particular instant in | 7059 // the number in a Date object representing a particular instant in |
6863 // time is milliseconds. Therefore, we floor the result of getting | 7060 // time is milliseconds. Therefore, we floor the result of getting |
6864 // the OS time. | 7061 // the OS time. |
6865 double millis = floor(OS::TimeCurrentMillis()); | 7062 double millis = floor(OS::TimeCurrentMillis()); |
6866 return Heap::NumberFromDouble(millis); | 7063 return Heap::NumberFromDouble(millis); |
6867 } | 7064 } |
6868 | 7065 |
6869 | 7066 |
6870 static Object* Runtime_DateParseString(Arguments args) { | 7067 static MaybeObject* Runtime_DateParseString(Arguments args) { |
6871 HandleScope scope; | 7068 HandleScope scope; |
6872 ASSERT(args.length() == 2); | 7069 ASSERT(args.length() == 2); |
6873 | 7070 |
6874 CONVERT_ARG_CHECKED(String, str, 0); | 7071 CONVERT_ARG_CHECKED(String, str, 0); |
6875 FlattenString(str); | 7072 FlattenString(str); |
6876 | 7073 |
6877 CONVERT_ARG_CHECKED(JSArray, output, 1); | 7074 CONVERT_ARG_CHECKED(JSArray, output, 1); |
6878 RUNTIME_ASSERT(output->HasFastElements()); | 7075 RUNTIME_ASSERT(output->HasFastElements()); |
6879 | 7076 |
6880 AssertNoAllocation no_allocation; | 7077 AssertNoAllocation no_allocation; |
6881 | 7078 |
6882 FixedArray* output_array = FixedArray::cast(output->elements()); | 7079 FixedArray* output_array = FixedArray::cast(output->elements()); |
6883 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); | 7080 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); |
6884 bool result; | 7081 bool result; |
6885 if (str->IsAsciiRepresentation()) { | 7082 if (str->IsAsciiRepresentation()) { |
6886 result = DateParser::Parse(str->ToAsciiVector(), output_array); | 7083 result = DateParser::Parse(str->ToAsciiVector(), output_array); |
6887 } else { | 7084 } else { |
6888 ASSERT(str->IsTwoByteRepresentation()); | 7085 ASSERT(str->IsTwoByteRepresentation()); |
6889 result = DateParser::Parse(str->ToUC16Vector(), output_array); | 7086 result = DateParser::Parse(str->ToUC16Vector(), output_array); |
6890 } | 7087 } |
6891 | 7088 |
6892 if (result) { | 7089 if (result) { |
6893 return *output; | 7090 return *output; |
6894 } else { | 7091 } else { |
6895 return Heap::null_value(); | 7092 return Heap::null_value(); |
6896 } | 7093 } |
6897 } | 7094 } |
6898 | 7095 |
6899 | 7096 |
6900 static Object* Runtime_DateLocalTimezone(Arguments args) { | 7097 static MaybeObject* Runtime_DateLocalTimezone(Arguments args) { |
6901 NoHandleAllocation ha; | 7098 NoHandleAllocation ha; |
6902 ASSERT(args.length() == 1); | 7099 ASSERT(args.length() == 1); |
6903 | 7100 |
6904 CONVERT_DOUBLE_CHECKED(x, args[0]); | 7101 CONVERT_DOUBLE_CHECKED(x, args[0]); |
6905 const char* zone = OS::LocalTimezone(x); | 7102 const char* zone = OS::LocalTimezone(x); |
6906 return Heap::AllocateStringFromUtf8(CStrVector(zone)); | 7103 return Heap::AllocateStringFromUtf8(CStrVector(zone)); |
6907 } | 7104 } |
6908 | 7105 |
6909 | 7106 |
6910 static Object* Runtime_DateLocalTimeOffset(Arguments args) { | 7107 static MaybeObject* Runtime_DateLocalTimeOffset(Arguments args) { |
6911 NoHandleAllocation ha; | 7108 NoHandleAllocation ha; |
6912 ASSERT(args.length() == 0); | 7109 ASSERT(args.length() == 0); |
6913 | 7110 |
6914 return Heap::NumberFromDouble(OS::LocalTimeOffset()); | 7111 return Heap::NumberFromDouble(OS::LocalTimeOffset()); |
6915 } | 7112 } |
6916 | 7113 |
6917 | 7114 |
6918 static Object* Runtime_DateDaylightSavingsOffset(Arguments args) { | 7115 static MaybeObject* Runtime_DateDaylightSavingsOffset(Arguments args) { |
6919 NoHandleAllocation ha; | 7116 NoHandleAllocation ha; |
6920 ASSERT(args.length() == 1); | 7117 ASSERT(args.length() == 1); |
6921 | 7118 |
6922 CONVERT_DOUBLE_CHECKED(x, args[0]); | 7119 CONVERT_DOUBLE_CHECKED(x, args[0]); |
6923 return Heap::NumberFromDouble(OS::DaylightSavingsOffset(x)); | 7120 return Heap::NumberFromDouble(OS::DaylightSavingsOffset(x)); |
6924 } | 7121 } |
6925 | 7122 |
6926 | 7123 |
6927 static Object* Runtime_GlobalReceiver(Arguments args) { | 7124 static MaybeObject* Runtime_GlobalReceiver(Arguments args) { |
6928 ASSERT(args.length() == 1); | 7125 ASSERT(args.length() == 1); |
6929 Object* global = args[0]; | 7126 Object* global = args[0]; |
6930 if (!global->IsJSGlobalObject()) return Heap::null_value(); | 7127 if (!global->IsJSGlobalObject()) return Heap::null_value(); |
6931 return JSGlobalObject::cast(global)->global_receiver(); | 7128 return JSGlobalObject::cast(global)->global_receiver(); |
6932 } | 7129 } |
6933 | 7130 |
6934 | 7131 |
6935 static Object* Runtime_CompileString(Arguments args) { | 7132 static MaybeObject* Runtime_CompileString(Arguments args) { |
6936 HandleScope scope; | 7133 HandleScope scope; |
6937 ASSERT_EQ(2, args.length()); | 7134 ASSERT_EQ(2, args.length()); |
6938 CONVERT_ARG_CHECKED(String, source, 0); | 7135 CONVERT_ARG_CHECKED(String, source, 0); |
6939 CONVERT_ARG_CHECKED(Oddball, is_json, 1) | 7136 CONVERT_ARG_CHECKED(Oddball, is_json, 1) |
6940 | 7137 |
6941 // Compile source string in the global context. | 7138 // Compile source string in the global context. |
6942 Handle<Context> context(Top::context()->global_context()); | 7139 Handle<Context> context(Top::context()->global_context()); |
6943 Compiler::ValidationState validate = (is_json->IsTrue()) | 7140 Compiler::ValidationState validate = (is_json->IsTrue()) |
6944 ? Compiler::VALIDATE_JSON : Compiler::DONT_VALIDATE_JSON; | 7141 ? Compiler::VALIDATE_JSON : Compiler::DONT_VALIDATE_JSON; |
6945 Handle<SharedFunctionInfo> shared = Compiler::CompileEval(source, | 7142 Handle<SharedFunctionInfo> shared = Compiler::CompileEval(source, |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7053 // Compare it to the builtin 'GlobalEval' function to make sure. | 7250 // Compare it to the builtin 'GlobalEval' function to make sure. |
7054 if (*callee != Top::global_context()->global_eval_fun() || | 7251 if (*callee != Top::global_context()->global_eval_fun() || |
7055 !args[1]->IsString()) { | 7252 !args[1]->IsString()) { |
7056 return MakePair(*callee, Top::context()->global()->global_receiver()); | 7253 return MakePair(*callee, Top::context()->global()->global_receiver()); |
7057 } | 7254 } |
7058 | 7255 |
7059 return CompileGlobalEval(args.at<String>(1), args.at<Object>(2)); | 7256 return CompileGlobalEval(args.at<String>(1), args.at<Object>(2)); |
7060 } | 7257 } |
7061 | 7258 |
7062 | 7259 |
7063 static Object* Runtime_SetNewFunctionAttributes(Arguments args) { | 7260 static MaybeObject* Runtime_SetNewFunctionAttributes(Arguments args) { |
7064 // This utility adjusts the property attributes for newly created Function | 7261 // This utility adjusts the property attributes for newly created Function |
7065 // object ("new Function(...)") by changing the map. | 7262 // object ("new Function(...)") by changing the map. |
7066 // All it does is changing the prototype property to enumerable | 7263 // All it does is changing the prototype property to enumerable |
7067 // as specified in ECMA262, 15.3.5.2. | 7264 // as specified in ECMA262, 15.3.5.2. |
7068 HandleScope scope; | 7265 HandleScope scope; |
7069 ASSERT(args.length() == 1); | 7266 ASSERT(args.length() == 1); |
7070 CONVERT_ARG_CHECKED(JSFunction, func, 0); | 7267 CONVERT_ARG_CHECKED(JSFunction, func, 0); |
7071 ASSERT(func->map()->instance_type() == | 7268 ASSERT(func->map()->instance_type() == |
7072 Top::function_instance_map()->instance_type()); | 7269 Top::function_instance_map()->instance_type()); |
7073 ASSERT(func->map()->instance_size() == | 7270 ASSERT(func->map()->instance_size() == |
7074 Top::function_instance_map()->instance_size()); | 7271 Top::function_instance_map()->instance_size()); |
7075 func->set_map(*Top::function_instance_map()); | 7272 func->set_map(*Top::function_instance_map()); |
7076 return *func; | 7273 return *func; |
7077 } | 7274 } |
7078 | 7275 |
7079 | 7276 |
7080 static Object* Runtime_AllocateInNewSpace(Arguments args) { | 7277 static MaybeObject* Runtime_AllocateInNewSpace(Arguments args) { |
7081 // Allocate a block of memory in NewSpace (filled with a filler). | 7278 // Allocate a block of memory in NewSpace (filled with a filler). |
7082 // Use as fallback for allocation in generated code when NewSpace | 7279 // Use as fallback for allocation in generated code when NewSpace |
7083 // is full. | 7280 // is full. |
7084 ASSERT(args.length() == 1); | 7281 ASSERT(args.length() == 1); |
7085 CONVERT_ARG_CHECKED(Smi, size_smi, 0); | 7282 CONVERT_ARG_CHECKED(Smi, size_smi, 0); |
7086 int size = size_smi->value(); | 7283 int size = size_smi->value(); |
7087 RUNTIME_ASSERT(IsAligned(size, kPointerSize)); | 7284 RUNTIME_ASSERT(IsAligned(size, kPointerSize)); |
7088 RUNTIME_ASSERT(size > 0); | 7285 RUNTIME_ASSERT(size > 0); |
7089 static const int kMinFreeNewSpaceAfterGC = | 7286 static const int kMinFreeNewSpaceAfterGC = |
7090 Heap::InitialSemiSpaceSize() * 3/4; | 7287 Heap::InitialSemiSpaceSize() * 3/4; |
7091 RUNTIME_ASSERT(size <= kMinFreeNewSpaceAfterGC); | 7288 RUNTIME_ASSERT(size <= kMinFreeNewSpaceAfterGC); |
7092 Object* allocation = Heap::new_space()->AllocateRaw(size); | 7289 Object* allocation; |
7093 if (!allocation->IsFailure()) { | 7290 { MaybeObject* maybe_allocation = Heap::new_space()->AllocateRaw(size); |
7094 Heap::CreateFillerObjectAt(HeapObject::cast(allocation)->address(), size); | 7291 if (maybe_allocation->ToObject(&allocation)) { |
| 7292 Heap::CreateFillerObjectAt(HeapObject::cast(allocation)->address(), size); |
| 7293 } |
| 7294 return maybe_allocation; |
7095 } | 7295 } |
7096 return allocation; | |
7097 } | 7296 } |
7098 | 7297 |
7099 | 7298 |
7100 // Push an array unto an array of arrays if it is not already in the | 7299 // Push an array unto an array of arrays if it is not already in the |
7101 // array. Returns true if the element was pushed on the stack and | 7300 // array. Returns true if the element was pushed on the stack and |
7102 // false otherwise. | 7301 // false otherwise. |
7103 static Object* Runtime_PushIfAbsent(Arguments args) { | 7302 static MaybeObject* Runtime_PushIfAbsent(Arguments args) { |
7104 ASSERT(args.length() == 2); | 7303 ASSERT(args.length() == 2); |
7105 CONVERT_CHECKED(JSArray, array, args[0]); | 7304 CONVERT_CHECKED(JSArray, array, args[0]); |
7106 CONVERT_CHECKED(JSArray, element, args[1]); | 7305 CONVERT_CHECKED(JSArray, element, args[1]); |
7107 RUNTIME_ASSERT(array->HasFastElements()); | 7306 RUNTIME_ASSERT(array->HasFastElements()); |
7108 int length = Smi::cast(array->length())->value(); | 7307 int length = Smi::cast(array->length())->value(); |
7109 FixedArray* elements = FixedArray::cast(array->elements()); | 7308 FixedArray* elements = FixedArray::cast(array->elements()); |
7110 for (int i = 0; i < length; i++) { | 7309 for (int i = 0; i < length; i++) { |
7111 if (elements->get(i) == element) return Heap::false_value(); | 7310 if (elements->get(i) == element) return Heap::false_value(); |
7112 } | 7311 } |
7113 Object* obj = array->SetFastElement(length, element); | 7312 Object* obj; |
7114 if (obj->IsFailure()) return obj; | 7313 { MaybeObject* maybe_obj = array->SetFastElement(length, element); |
| 7314 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 7315 } |
7115 return Heap::true_value(); | 7316 return Heap::true_value(); |
7116 } | 7317 } |
7117 | 7318 |
7118 | 7319 |
7119 /** | 7320 /** |
7120 * A simple visitor visits every element of Array's. | 7321 * A simple visitor visits every element of Array's. |
7121 * The backend storage can be a fixed array for fast elements case, | 7322 * The backend storage can be a fixed array for fast elements case, |
7122 * or a dictionary for sparse array. Since Dictionary is a subtype | 7323 * or a dictionary for sparse array. Since Dictionary is a subtype |
7123 * of FixedArray, the class can be used by both fast and slow cases. | 7324 * of FixedArray, the class can be used by both fast and slow cases. |
7124 * The second parameter of the constructor, fast_elements, specifies | 7325 * The second parameter of the constructor, fast_elements, specifies |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7398 * concatenated array length is 0. | 7599 * concatenated array length is 0. |
7399 * TODO(lrn) Change length behavior to ECMAScript 5 specification (length | 7600 * TODO(lrn) Change length behavior to ECMAScript 5 specification (length |
7400 * is one more than the last array index to get a value assigned). | 7601 * is one more than the last array index to get a value assigned). |
7401 */ | 7602 */ |
7402 static uint32_t IterateArguments(Handle<JSArray> arguments, | 7603 static uint32_t IterateArguments(Handle<JSArray> arguments, |
7403 ArrayConcatVisitor* visitor) { | 7604 ArrayConcatVisitor* visitor) { |
7404 uint32_t visited_elements = 0; | 7605 uint32_t visited_elements = 0; |
7405 uint32_t num_of_args = static_cast<uint32_t>(arguments->length()->Number()); | 7606 uint32_t num_of_args = static_cast<uint32_t>(arguments->length()->Number()); |
7406 | 7607 |
7407 for (uint32_t i = 0; i < num_of_args; i++) { | 7608 for (uint32_t i = 0; i < num_of_args; i++) { |
7408 Handle<Object> obj(arguments->GetElement(i)); | 7609 Object *element; |
7409 if (obj->IsJSArray()) { | 7610 MaybeObject* maybe_element = arguments->GetElement(i); |
7410 Handle<JSArray> array = Handle<JSArray>::cast(obj); | 7611 // This if() is not expected to fail, but we have the check in the |
7411 uint32_t len = static_cast<uint32_t>(array->length()->Number()); | 7612 // interest of hardening the runtime calls. |
7412 uint32_t nof_elements = | 7613 if (maybe_element->ToObject(&element)) { |
7413 IterateArrayAndPrototypeElements(array, visitor); | 7614 Handle<Object> obj(element); |
7414 // Total elements of array and its prototype chain can be more than | 7615 if (obj->IsJSArray()) { |
7415 // the array length, but ArrayConcat can only concatenate at most | 7616 Handle<JSArray> array = Handle<JSArray>::cast(obj); |
7416 // the array length number of elements. We use the length as an estimate | 7617 uint32_t len = static_cast<uint32_t>(array->length()->Number()); |
7417 // for the actual number of elements added. | 7618 uint32_t nof_elements = |
7418 uint32_t added_elements = (nof_elements > len) ? len : nof_elements; | 7619 IterateArrayAndPrototypeElements(array, visitor); |
7419 if (JSArray::kMaxElementCount - visited_elements < added_elements) { | 7620 // Total elements of array and its prototype chain can be more than |
7420 visited_elements = JSArray::kMaxElementCount; | 7621 // the array length, but ArrayConcat can only concatenate at most |
| 7622 // the array length number of elements. We use the length as an estimate |
| 7623 // for the actual number of elements added. |
| 7624 uint32_t added_elements = (nof_elements > len) ? len : nof_elements; |
| 7625 if (JSArray::kMaxElementCount - visited_elements < added_elements) { |
| 7626 visited_elements = JSArray::kMaxElementCount; |
| 7627 } else { |
| 7628 visited_elements += added_elements; |
| 7629 } |
| 7630 if (visitor) visitor->increase_index_offset(len); |
7421 } else { | 7631 } else { |
7422 visited_elements += added_elements; | 7632 if (visitor) { |
7423 } | 7633 visitor->visit(0, obj); |
7424 if (visitor) visitor->increase_index_offset(len); | 7634 visitor->increase_index_offset(1); |
7425 } else { | 7635 } |
7426 if (visitor) { | 7636 if (visited_elements < JSArray::kMaxElementCount) { |
7427 visitor->visit(0, obj); | 7637 visited_elements++; |
7428 visitor->increase_index_offset(1); | 7638 } |
7429 } | |
7430 if (visited_elements < JSArray::kMaxElementCount) { | |
7431 visited_elements++; | |
7432 } | 7639 } |
7433 } | 7640 } |
7434 } | 7641 } |
7435 return visited_elements; | 7642 return visited_elements; |
7436 } | 7643 } |
7437 | 7644 |
7438 | 7645 |
7439 /** | 7646 /** |
7440 * Array::concat implementation. | 7647 * Array::concat implementation. |
7441 * See ECMAScript 262, 15.4.4.4. | 7648 * See ECMAScript 262, 15.4.4.4. |
7442 * TODO(lrn): Fix non-compliance for very large concatenations and update to | 7649 * TODO(lrn): Fix non-compliance for very large concatenations and update to |
7443 * following the ECMAScript 5 specification. | 7650 * following the ECMAScript 5 specification. |
7444 */ | 7651 */ |
7445 static Object* Runtime_ArrayConcat(Arguments args) { | 7652 static MaybeObject* Runtime_ArrayConcat(Arguments args) { |
7446 ASSERT(args.length() == 1); | 7653 ASSERT(args.length() == 1); |
7447 HandleScope handle_scope; | 7654 HandleScope handle_scope; |
7448 | 7655 |
7449 CONVERT_CHECKED(JSArray, arg_arrays, args[0]); | 7656 CONVERT_CHECKED(JSArray, arg_arrays, args[0]); |
7450 Handle<JSArray> arguments(arg_arrays); | 7657 Handle<JSArray> arguments(arg_arrays); |
7451 | 7658 |
7452 // Pass 1: estimate the number of elements of the result | 7659 // Pass 1: estimate the number of elements of the result |
7453 // (it could be more than real numbers if prototype has elements). | 7660 // (it could be more than real numbers if prototype has elements). |
7454 uint32_t result_length = 0; | 7661 uint32_t result_length = 0; |
7455 uint32_t num_of_args = static_cast<uint32_t>(arguments->length()->Number()); | 7662 uint32_t num_of_args = static_cast<uint32_t>(arguments->length()->Number()); |
7456 | 7663 |
7457 { AssertNoAllocation nogc; | 7664 { AssertNoAllocation nogc; |
7458 for (uint32_t i = 0; i < num_of_args; i++) { | 7665 for (uint32_t i = 0; i < num_of_args; i++) { |
7459 Object* obj = arguments->GetElement(i); | 7666 Object* obj; |
7460 uint32_t length_estimate; | 7667 MaybeObject* maybe_object = arguments->GetElement(i); |
7461 if (obj->IsJSArray()) { | 7668 // This if() is not expected to fail, but we have the check in the |
7462 length_estimate = | 7669 // interest of hardening the runtime calls. |
7463 static_cast<uint32_t>(JSArray::cast(obj)->length()->Number()); | 7670 if (maybe_object->ToObject(&obj)) { |
7464 } else { | 7671 uint32_t length_estimate; |
7465 length_estimate = 1; | 7672 if (obj->IsJSArray()) { |
| 7673 length_estimate = |
| 7674 static_cast<uint32_t>(JSArray::cast(obj)->length()->Number()); |
| 7675 } else { |
| 7676 length_estimate = 1; |
| 7677 } |
| 7678 if (JSObject::kMaxElementCount - result_length < length_estimate) { |
| 7679 result_length = JSObject::kMaxElementCount; |
| 7680 break; |
| 7681 } |
| 7682 result_length += length_estimate; |
7466 } | 7683 } |
7467 if (JSObject::kMaxElementCount - result_length < length_estimate) { | |
7468 result_length = JSObject::kMaxElementCount; | |
7469 break; | |
7470 } | |
7471 result_length += length_estimate; | |
7472 } | 7684 } |
7473 } | 7685 } |
7474 | 7686 |
7475 // Allocate an empty array, will set length and content later. | 7687 // Allocate an empty array, will set length and content later. |
7476 Handle<JSArray> result = Factory::NewJSArray(0); | 7688 Handle<JSArray> result = Factory::NewJSArray(0); |
7477 | 7689 |
7478 uint32_t estimate_nof_elements = IterateArguments(arguments, NULL); | 7690 uint32_t estimate_nof_elements = IterateArguments(arguments, NULL); |
7479 // If estimated number of elements is more than half of length, a | 7691 // If estimated number of elements is more than half of length, a |
7480 // fixed array (fast case) is more time and space-efficient than a | 7692 // fixed array (fast case) is more time and space-efficient than a |
7481 // dictionary. | 7693 // dictionary. |
(...skipping 27 matching lines...) Expand all Loading... |
7509 result->set_length(*len); | 7721 result->set_length(*len); |
7510 // Please note the storage might have changed in the visitor. | 7722 // Please note the storage might have changed in the visitor. |
7511 result->set_elements(*visitor.storage()); | 7723 result->set_elements(*visitor.storage()); |
7512 | 7724 |
7513 return *result; | 7725 return *result; |
7514 } | 7726 } |
7515 | 7727 |
7516 | 7728 |
7517 // This will not allocate (flatten the string), but it may run | 7729 // This will not allocate (flatten the string), but it may run |
7518 // very slowly for very deeply nested ConsStrings. For debugging use only. | 7730 // very slowly for very deeply nested ConsStrings. For debugging use only. |
7519 static Object* Runtime_GlobalPrint(Arguments args) { | 7731 static MaybeObject* Runtime_GlobalPrint(Arguments args) { |
7520 NoHandleAllocation ha; | 7732 NoHandleAllocation ha; |
7521 ASSERT(args.length() == 1); | 7733 ASSERT(args.length() == 1); |
7522 | 7734 |
7523 CONVERT_CHECKED(String, string, args[0]); | 7735 CONVERT_CHECKED(String, string, args[0]); |
7524 StringInputBuffer buffer(string); | 7736 StringInputBuffer buffer(string); |
7525 while (buffer.has_more()) { | 7737 while (buffer.has_more()) { |
7526 uint16_t character = buffer.GetNext(); | 7738 uint16_t character = buffer.GetNext(); |
7527 PrintF("%c", character); | 7739 PrintF("%c", character); |
7528 } | 7740 } |
7529 return string; | 7741 return string; |
7530 } | 7742 } |
7531 | 7743 |
7532 // Moves all own elements of an object, that are below a limit, to positions | 7744 // Moves all own elements of an object, that are below a limit, to positions |
7533 // starting at zero. All undefined values are placed after non-undefined values, | 7745 // starting at zero. All undefined values are placed after non-undefined values, |
7534 // and are followed by non-existing element. Does not change the length | 7746 // and are followed by non-existing element. Does not change the length |
7535 // property. | 7747 // property. |
7536 // Returns the number of non-undefined elements collected. | 7748 // Returns the number of non-undefined elements collected. |
7537 static Object* Runtime_RemoveArrayHoles(Arguments args) { | 7749 static MaybeObject* Runtime_RemoveArrayHoles(Arguments args) { |
7538 ASSERT(args.length() == 2); | 7750 ASSERT(args.length() == 2); |
7539 CONVERT_CHECKED(JSObject, object, args[0]); | 7751 CONVERT_CHECKED(JSObject, object, args[0]); |
7540 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); | 7752 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); |
7541 return object->PrepareElementsForSort(limit); | 7753 return object->PrepareElementsForSort(limit); |
7542 } | 7754 } |
7543 | 7755 |
7544 | 7756 |
7545 // Move contents of argument 0 (an array) to argument 1 (an array) | 7757 // Move contents of argument 0 (an array) to argument 1 (an array) |
7546 static Object* Runtime_MoveArrayContents(Arguments args) { | 7758 static MaybeObject* Runtime_MoveArrayContents(Arguments args) { |
7547 ASSERT(args.length() == 2); | 7759 ASSERT(args.length() == 2); |
7548 CONVERT_CHECKED(JSArray, from, args[0]); | 7760 CONVERT_CHECKED(JSArray, from, args[0]); |
7549 CONVERT_CHECKED(JSArray, to, args[1]); | 7761 CONVERT_CHECKED(JSArray, to, args[1]); |
7550 HeapObject* new_elements = from->elements(); | 7762 HeapObject* new_elements = from->elements(); |
7551 Object* new_map; | 7763 MaybeObject* maybe_new_map; |
7552 if (new_elements->map() == Heap::fixed_array_map() || | 7764 if (new_elements->map() == Heap::fixed_array_map() || |
7553 new_elements->map() == Heap::fixed_cow_array_map()) { | 7765 new_elements->map() == Heap::fixed_cow_array_map()) { |
7554 new_map = to->map()->GetFastElementsMap(); | 7766 maybe_new_map = to->map()->GetFastElementsMap(); |
7555 } else { | 7767 } else { |
7556 new_map = to->map()->GetSlowElementsMap(); | 7768 maybe_new_map = to->map()->GetSlowElementsMap(); |
7557 } | 7769 } |
7558 if (new_map->IsFailure()) return new_map; | 7770 Object* new_map; |
| 7771 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
7559 to->set_map(Map::cast(new_map)); | 7772 to->set_map(Map::cast(new_map)); |
7560 to->set_elements(new_elements); | 7773 to->set_elements(new_elements); |
7561 to->set_length(from->length()); | 7774 to->set_length(from->length()); |
7562 Object* obj = from->ResetElements(); | 7775 Object* obj; |
7563 if (obj->IsFailure()) return obj; | 7776 { MaybeObject* maybe_obj = from->ResetElements(); |
| 7777 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 7778 } |
7564 from->set_length(Smi::FromInt(0)); | 7779 from->set_length(Smi::FromInt(0)); |
7565 return to; | 7780 return to; |
7566 } | 7781 } |
7567 | 7782 |
7568 | 7783 |
7569 // How many elements does this object/array have? | 7784 // How many elements does this object/array have? |
7570 static Object* Runtime_EstimateNumberOfElements(Arguments args) { | 7785 static MaybeObject* Runtime_EstimateNumberOfElements(Arguments args) { |
7571 ASSERT(args.length() == 1); | 7786 ASSERT(args.length() == 1); |
7572 CONVERT_CHECKED(JSObject, object, args[0]); | 7787 CONVERT_CHECKED(JSObject, object, args[0]); |
7573 HeapObject* elements = object->elements(); | 7788 HeapObject* elements = object->elements(); |
7574 if (elements->IsDictionary()) { | 7789 if (elements->IsDictionary()) { |
7575 return Smi::FromInt(NumberDictionary::cast(elements)->NumberOfElements()); | 7790 return Smi::FromInt(NumberDictionary::cast(elements)->NumberOfElements()); |
7576 } else if (object->IsJSArray()) { | 7791 } else if (object->IsJSArray()) { |
7577 return JSArray::cast(object)->length(); | 7792 return JSArray::cast(object)->length(); |
7578 } else { | 7793 } else { |
7579 return Smi::FromInt(FixedArray::cast(elements)->length()); | 7794 return Smi::FromInt(FixedArray::cast(elements)->length()); |
7580 } | 7795 } |
7581 } | 7796 } |
7582 | 7797 |
7583 | 7798 |
7584 static Object* Runtime_SwapElements(Arguments args) { | 7799 static MaybeObject* Runtime_SwapElements(Arguments args) { |
7585 HandleScope handle_scope; | 7800 HandleScope handle_scope; |
7586 | 7801 |
7587 ASSERT_EQ(3, args.length()); | 7802 ASSERT_EQ(3, args.length()); |
7588 | 7803 |
7589 CONVERT_ARG_CHECKED(JSObject, object, 0); | 7804 CONVERT_ARG_CHECKED(JSObject, object, 0); |
7590 Handle<Object> key1 = args.at<Object>(1); | 7805 Handle<Object> key1 = args.at<Object>(1); |
7591 Handle<Object> key2 = args.at<Object>(2); | 7806 Handle<Object> key2 = args.at<Object>(2); |
7592 | 7807 |
7593 uint32_t index1, index2; | 7808 uint32_t index1, index2; |
7594 if (!key1->ToArrayIndex(&index1) | 7809 if (!key1->ToArrayIndex(&index1) |
(...skipping 10 matching lines...) Expand all Loading... |
7605 | 7820 |
7606 return Heap::undefined_value(); | 7821 return Heap::undefined_value(); |
7607 } | 7822 } |
7608 | 7823 |
7609 | 7824 |
7610 // Returns an array that tells you where in the [0, length) interval an array | 7825 // Returns an array that tells you where in the [0, length) interval an array |
7611 // might have elements. Can either return keys (positive integers) or | 7826 // might have elements. Can either return keys (positive integers) or |
7612 // intervals (pair of a negative integer (-start-1) followed by a | 7827 // intervals (pair of a negative integer (-start-1) followed by a |
7613 // positive (length)) or undefined values. | 7828 // positive (length)) or undefined values. |
7614 // Intervals can span over some keys that are not in the object. | 7829 // Intervals can span over some keys that are not in the object. |
7615 static Object* Runtime_GetArrayKeys(Arguments args) { | 7830 static MaybeObject* Runtime_GetArrayKeys(Arguments args) { |
7616 ASSERT(args.length() == 2); | 7831 ASSERT(args.length() == 2); |
7617 HandleScope scope; | 7832 HandleScope scope; |
7618 CONVERT_ARG_CHECKED(JSObject, array, 0); | 7833 CONVERT_ARG_CHECKED(JSObject, array, 0); |
7619 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); | 7834 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); |
7620 if (array->elements()->IsDictionary()) { | 7835 if (array->elements()->IsDictionary()) { |
7621 // Create an array and get all the keys into it, then remove all the | 7836 // Create an array and get all the keys into it, then remove all the |
7622 // keys that are not integers in the range 0 to length-1. | 7837 // keys that are not integers in the range 0 to length-1. |
7623 Handle<FixedArray> keys = GetKeysInFixedArrayFor(array, INCLUDE_PROTOS); | 7838 Handle<FixedArray> keys = GetKeysInFixedArrayFor(array, INCLUDE_PROTOS); |
7624 int keys_length = keys->length(); | 7839 int keys_length = keys->length(); |
7625 for (int i = 0; i < keys_length; i++) { | 7840 for (int i = 0; i < keys_length; i++) { |
(...skipping 19 matching lines...) Expand all Loading... |
7645 return *Factory::NewJSArrayWithElements(single_interval); | 7860 return *Factory::NewJSArrayWithElements(single_interval); |
7646 } | 7861 } |
7647 } | 7862 } |
7648 | 7863 |
7649 | 7864 |
7650 // DefineAccessor takes an optional final argument which is the | 7865 // DefineAccessor takes an optional final argument which is the |
7651 // property attributes (eg, DONT_ENUM, DONT_DELETE). IMPORTANT: due | 7866 // property attributes (eg, DONT_ENUM, DONT_DELETE). IMPORTANT: due |
7652 // to the way accessors are implemented, it is set for both the getter | 7867 // to the way accessors are implemented, it is set for both the getter |
7653 // and setter on the first call to DefineAccessor and ignored on | 7868 // and setter on the first call to DefineAccessor and ignored on |
7654 // subsequent calls. | 7869 // subsequent calls. |
7655 static Object* Runtime_DefineAccessor(Arguments args) { | 7870 static MaybeObject* Runtime_DefineAccessor(Arguments args) { |
7656 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5); | 7871 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5); |
7657 // Compute attributes. | 7872 // Compute attributes. |
7658 PropertyAttributes attributes = NONE; | 7873 PropertyAttributes attributes = NONE; |
7659 if (args.length() == 5) { | 7874 if (args.length() == 5) { |
7660 CONVERT_CHECKED(Smi, attrs, args[4]); | 7875 CONVERT_CHECKED(Smi, attrs, args[4]); |
7661 int value = attrs->value(); | 7876 int value = attrs->value(); |
7662 // Only attribute bits should be set. | 7877 // Only attribute bits should be set. |
7663 ASSERT((value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 7878 ASSERT((value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
7664 attributes = static_cast<PropertyAttributes>(value); | 7879 attributes = static_cast<PropertyAttributes>(value); |
7665 } | 7880 } |
7666 | 7881 |
7667 CONVERT_CHECKED(JSObject, obj, args[0]); | 7882 CONVERT_CHECKED(JSObject, obj, args[0]); |
7668 CONVERT_CHECKED(String, name, args[1]); | 7883 CONVERT_CHECKED(String, name, args[1]); |
7669 CONVERT_CHECKED(Smi, flag, args[2]); | 7884 CONVERT_CHECKED(Smi, flag, args[2]); |
7670 CONVERT_CHECKED(JSFunction, fun, args[3]); | 7885 CONVERT_CHECKED(JSFunction, fun, args[3]); |
7671 return obj->DefineAccessor(name, flag->value() == 0, fun, attributes); | 7886 return obj->DefineAccessor(name, flag->value() == 0, fun, attributes); |
7672 } | 7887 } |
7673 | 7888 |
7674 | 7889 |
7675 static Object* Runtime_LookupAccessor(Arguments args) { | 7890 static MaybeObject* Runtime_LookupAccessor(Arguments args) { |
7676 ASSERT(args.length() == 3); | 7891 ASSERT(args.length() == 3); |
7677 CONVERT_CHECKED(JSObject, obj, args[0]); | 7892 CONVERT_CHECKED(JSObject, obj, args[0]); |
7678 CONVERT_CHECKED(String, name, args[1]); | 7893 CONVERT_CHECKED(String, name, args[1]); |
7679 CONVERT_CHECKED(Smi, flag, args[2]); | 7894 CONVERT_CHECKED(Smi, flag, args[2]); |
7680 return obj->LookupAccessor(name, flag->value() == 0); | 7895 return obj->LookupAccessor(name, flag->value() == 0); |
7681 } | 7896 } |
7682 | 7897 |
7683 | 7898 |
7684 #ifdef ENABLE_DEBUGGER_SUPPORT | 7899 #ifdef ENABLE_DEBUGGER_SUPPORT |
7685 static Object* Runtime_DebugBreak(Arguments args) { | 7900 static MaybeObject* Runtime_DebugBreak(Arguments args) { |
7686 ASSERT(args.length() == 0); | 7901 ASSERT(args.length() == 0); |
7687 return Execution::DebugBreakHelper(); | 7902 return Execution::DebugBreakHelper(); |
7688 } | 7903 } |
7689 | 7904 |
7690 | 7905 |
7691 // Helper functions for wrapping and unwrapping stack frame ids. | 7906 // Helper functions for wrapping and unwrapping stack frame ids. |
7692 static Smi* WrapFrameId(StackFrame::Id id) { | 7907 static Smi* WrapFrameId(StackFrame::Id id) { |
7693 ASSERT(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4))); | 7908 ASSERT(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4))); |
7694 return Smi::FromInt(id >> 2); | 7909 return Smi::FromInt(id >> 2); |
7695 } | 7910 } |
7696 | 7911 |
7697 | 7912 |
7698 static StackFrame::Id UnwrapFrameId(Smi* wrapped) { | 7913 static StackFrame::Id UnwrapFrameId(Smi* wrapped) { |
7699 return static_cast<StackFrame::Id>(wrapped->value() << 2); | 7914 return static_cast<StackFrame::Id>(wrapped->value() << 2); |
7700 } | 7915 } |
7701 | 7916 |
7702 | 7917 |
7703 // Adds a JavaScript function as a debug event listener. | 7918 // Adds a JavaScript function as a debug event listener. |
7704 // args[0]: debug event listener function to set or null or undefined for | 7919 // args[0]: debug event listener function to set or null or undefined for |
7705 // clearing the event listener function | 7920 // clearing the event listener function |
7706 // args[1]: object supplied during callback | 7921 // args[1]: object supplied during callback |
7707 static Object* Runtime_SetDebugEventListener(Arguments args) { | 7922 static MaybeObject* Runtime_SetDebugEventListener(Arguments args) { |
7708 ASSERT(args.length() == 2); | 7923 ASSERT(args.length() == 2); |
7709 RUNTIME_ASSERT(args[0]->IsJSFunction() || | 7924 RUNTIME_ASSERT(args[0]->IsJSFunction() || |
7710 args[0]->IsUndefined() || | 7925 args[0]->IsUndefined() || |
7711 args[0]->IsNull()); | 7926 args[0]->IsNull()); |
7712 Handle<Object> callback = args.at<Object>(0); | 7927 Handle<Object> callback = args.at<Object>(0); |
7713 Handle<Object> data = args.at<Object>(1); | 7928 Handle<Object> data = args.at<Object>(1); |
7714 Debugger::SetEventListener(callback, data); | 7929 Debugger::SetEventListener(callback, data); |
7715 | 7930 |
7716 return Heap::undefined_value(); | 7931 return Heap::undefined_value(); |
7717 } | 7932 } |
7718 | 7933 |
7719 | 7934 |
7720 static Object* Runtime_Break(Arguments args) { | 7935 static MaybeObject* Runtime_Break(Arguments args) { |
7721 ASSERT(args.length() == 0); | 7936 ASSERT(args.length() == 0); |
7722 StackGuard::DebugBreak(); | 7937 StackGuard::DebugBreak(); |
7723 return Heap::undefined_value(); | 7938 return Heap::undefined_value(); |
7724 } | 7939 } |
7725 | 7940 |
7726 | 7941 |
7727 static Object* DebugLookupResultValue(Object* receiver, String* name, | 7942 static MaybeObject* DebugLookupResultValue(Object* receiver, String* name, |
7728 LookupResult* result, | 7943 LookupResult* result, |
7729 bool* caught_exception) { | 7944 bool* caught_exception) { |
7730 Object* value; | 7945 Object* value; |
7731 switch (result->type()) { | 7946 switch (result->type()) { |
7732 case NORMAL: | 7947 case NORMAL: |
7733 value = result->holder()->GetNormalizedProperty(result); | 7948 value = result->holder()->GetNormalizedProperty(result); |
7734 if (value->IsTheHole()) { | 7949 if (value->IsTheHole()) { |
7735 return Heap::undefined_value(); | 7950 return Heap::undefined_value(); |
7736 } | 7951 } |
7737 return value; | 7952 return value; |
7738 case FIELD: | 7953 case FIELD: |
7739 value = | 7954 value = |
7740 JSObject::cast( | 7955 JSObject::cast( |
7741 result->holder())->FastPropertyAt(result->GetFieldIndex()); | 7956 result->holder())->FastPropertyAt(result->GetFieldIndex()); |
7742 if (value->IsTheHole()) { | 7957 if (value->IsTheHole()) { |
7743 return Heap::undefined_value(); | 7958 return Heap::undefined_value(); |
7744 } | 7959 } |
7745 return value; | 7960 return value; |
7746 case CONSTANT_FUNCTION: | 7961 case CONSTANT_FUNCTION: |
7747 return result->GetConstantFunction(); | 7962 return result->GetConstantFunction(); |
7748 case CALLBACKS: { | 7963 case CALLBACKS: { |
7749 Object* structure = result->GetCallbackObject(); | 7964 Object* structure = result->GetCallbackObject(); |
7750 if (structure->IsProxy() || structure->IsAccessorInfo()) { | 7965 if (structure->IsProxy() || structure->IsAccessorInfo()) { |
7751 value = receiver->GetPropertyWithCallback( | 7966 MaybeObject* maybe_value = receiver->GetPropertyWithCallback( |
7752 receiver, structure, name, result->holder()); | 7967 receiver, structure, name, result->holder()); |
7753 if (value->IsException()) { | 7968 if (!maybe_value->ToObject(&value)) { |
7754 value = Top::pending_exception(); | 7969 ASSERT(maybe_value->IsException()); |
| 7970 maybe_value = Top::pending_exception(); |
7755 Top::clear_pending_exception(); | 7971 Top::clear_pending_exception(); |
7756 if (caught_exception != NULL) { | 7972 if (caught_exception != NULL) { |
7757 *caught_exception = true; | 7973 *caught_exception = true; |
7758 } | 7974 } |
| 7975 return maybe_value; |
7759 } | 7976 } |
7760 return value; | 7977 return value; |
7761 } else { | 7978 } else { |
7762 return Heap::undefined_value(); | 7979 return Heap::undefined_value(); |
7763 } | 7980 } |
7764 } | 7981 } |
7765 case INTERCEPTOR: | 7982 case INTERCEPTOR: |
7766 case MAP_TRANSITION: | 7983 case MAP_TRANSITION: |
7767 case CONSTANT_TRANSITION: | 7984 case CONSTANT_TRANSITION: |
7768 case NULL_DESCRIPTOR: | 7985 case NULL_DESCRIPTOR: |
(...skipping 11 matching lines...) Expand all Loading... |
7780 // args[1]: name of the property | 7997 // args[1]: name of the property |
7781 // | 7998 // |
7782 // The array returned contains the following information: | 7999 // The array returned contains the following information: |
7783 // 0: Property value | 8000 // 0: Property value |
7784 // 1: Property details | 8001 // 1: Property details |
7785 // 2: Property value is exception | 8002 // 2: Property value is exception |
7786 // 3: Getter function if defined | 8003 // 3: Getter function if defined |
7787 // 4: Setter function if defined | 8004 // 4: Setter function if defined |
7788 // Items 2-4 are only filled if the property has either a getter or a setter | 8005 // Items 2-4 are only filled if the property has either a getter or a setter |
7789 // defined through __defineGetter__ and/or __defineSetter__. | 8006 // defined through __defineGetter__ and/or __defineSetter__. |
7790 static Object* Runtime_DebugGetPropertyDetails(Arguments args) { | 8007 static MaybeObject* Runtime_DebugGetPropertyDetails(Arguments args) { |
7791 HandleScope scope; | 8008 HandleScope scope; |
7792 | 8009 |
7793 ASSERT(args.length() == 2); | 8010 ASSERT(args.length() == 2); |
7794 | 8011 |
7795 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 8012 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
7796 CONVERT_ARG_CHECKED(String, name, 1); | 8013 CONVERT_ARG_CHECKED(String, name, 1); |
7797 | 8014 |
7798 // Make sure to set the current context to the context before the debugger was | 8015 // Make sure to set the current context to the context before the debugger was |
7799 // entered (if the debugger is entered). The reason for switching context here | 8016 // entered (if the debugger is entered). The reason for switching context here |
7800 // is that for some property lookups (accessors and interceptors) callbacks | 8017 // is that for some property lookups (accessors and interceptors) callbacks |
(...skipping 10 matching lines...) Expand all Loading... |
7811 if (obj->IsJSGlobalProxy()) { | 8028 if (obj->IsJSGlobalProxy()) { |
7812 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); | 8029 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); |
7813 } | 8030 } |
7814 | 8031 |
7815 | 8032 |
7816 // Check if the name is trivially convertible to an index and get the element | 8033 // Check if the name is trivially convertible to an index and get the element |
7817 // if so. | 8034 // if so. |
7818 uint32_t index; | 8035 uint32_t index; |
7819 if (name->AsArrayIndex(&index)) { | 8036 if (name->AsArrayIndex(&index)) { |
7820 Handle<FixedArray> details = Factory::NewFixedArray(2); | 8037 Handle<FixedArray> details = Factory::NewFixedArray(2); |
7821 Object* element_or_char = Runtime::GetElementOrCharAt(obj, index); | 8038 Object* element_or_char; |
| 8039 { MaybeObject* maybe_element_or_char = |
| 8040 Runtime::GetElementOrCharAt(obj, index); |
| 8041 if (!maybe_element_or_char->ToObject(&element_or_char)) { |
| 8042 return maybe_element_or_char; |
| 8043 } |
| 8044 } |
7822 details->set(0, element_or_char); | 8045 details->set(0, element_or_char); |
7823 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); | 8046 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); |
7824 return *Factory::NewJSArrayWithElements(details); | 8047 return *Factory::NewJSArrayWithElements(details); |
7825 } | 8048 } |
7826 | 8049 |
7827 // Find the number of objects making up this. | 8050 // Find the number of objects making up this. |
7828 int length = LocalPrototypeChainLength(*obj); | 8051 int length = LocalPrototypeChainLength(*obj); |
7829 | 8052 |
7830 // Try local lookup on each of the objects. | 8053 // Try local lookup on each of the objects. |
7831 Handle<JSObject> jsproto = obj; | 8054 Handle<JSObject> jsproto = obj; |
7832 for (int i = 0; i < length; i++) { | 8055 for (int i = 0; i < length; i++) { |
7833 LookupResult result; | 8056 LookupResult result; |
7834 jsproto->LocalLookup(*name, &result); | 8057 jsproto->LocalLookup(*name, &result); |
7835 if (result.IsProperty()) { | 8058 if (result.IsProperty()) { |
7836 // LookupResult is not GC safe as it holds raw object pointers. | 8059 // LookupResult is not GC safe as it holds raw object pointers. |
7837 // GC can happen later in this code so put the required fields into | 8060 // GC can happen later in this code so put the required fields into |
7838 // local variables using handles when required for later use. | 8061 // local variables using handles when required for later use. |
7839 PropertyType result_type = result.type(); | 8062 PropertyType result_type = result.type(); |
7840 Handle<Object> result_callback_obj; | 8063 Handle<Object> result_callback_obj; |
7841 if (result_type == CALLBACKS) { | 8064 if (result_type == CALLBACKS) { |
7842 result_callback_obj = Handle<Object>(result.GetCallbackObject()); | 8065 result_callback_obj = Handle<Object>(result.GetCallbackObject()); |
7843 } | 8066 } |
7844 Smi* property_details = result.GetPropertyDetails().AsSmi(); | 8067 Smi* property_details = result.GetPropertyDetails().AsSmi(); |
7845 // DebugLookupResultValue can cause GC so details from LookupResult needs | 8068 // DebugLookupResultValue can cause GC so details from LookupResult needs |
7846 // to be copied to handles before this. | 8069 // to be copied to handles before this. |
7847 bool caught_exception = false; | 8070 bool caught_exception = false; |
7848 Object* raw_value = DebugLookupResultValue(*obj, *name, &result, | 8071 Object* raw_value; |
7849 &caught_exception); | 8072 { MaybeObject* maybe_raw_value = |
7850 if (raw_value->IsFailure()) return raw_value; | 8073 DebugLookupResultValue(*obj, *name, &result, &caught_exception); |
| 8074 if (!maybe_raw_value->ToObject(&raw_value)) return maybe_raw_value; |
| 8075 } |
7851 Handle<Object> value(raw_value); | 8076 Handle<Object> value(raw_value); |
7852 | 8077 |
7853 // If the callback object is a fixed array then it contains JavaScript | 8078 // If the callback object is a fixed array then it contains JavaScript |
7854 // getter and/or setter. | 8079 // getter and/or setter. |
7855 bool hasJavaScriptAccessors = result_type == CALLBACKS && | 8080 bool hasJavaScriptAccessors = result_type == CALLBACKS && |
7856 result_callback_obj->IsFixedArray(); | 8081 result_callback_obj->IsFixedArray(); |
7857 Handle<FixedArray> details = | 8082 Handle<FixedArray> details = |
7858 Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2); | 8083 Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2); |
7859 details->set(0, *value); | 8084 details->set(0, *value); |
7860 details->set(1, property_details); | 8085 details->set(1, property_details); |
7861 if (hasJavaScriptAccessors) { | 8086 if (hasJavaScriptAccessors) { |
7862 details->set(2, | 8087 details->set(2, |
7863 caught_exception ? Heap::true_value() | 8088 caught_exception ? Heap::true_value() |
7864 : Heap::false_value()); | 8089 : Heap::false_value()); |
7865 details->set(3, FixedArray::cast(*result_callback_obj)->get(0)); | 8090 details->set(3, FixedArray::cast(*result_callback_obj)->get(0)); |
7866 details->set(4, FixedArray::cast(*result_callback_obj)->get(1)); | 8091 details->set(4, FixedArray::cast(*result_callback_obj)->get(1)); |
7867 } | 8092 } |
7868 | 8093 |
7869 return *Factory::NewJSArrayWithElements(details); | 8094 return *Factory::NewJSArrayWithElements(details); |
7870 } | 8095 } |
7871 if (i < length - 1) { | 8096 if (i < length - 1) { |
7872 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | 8097 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); |
7873 } | 8098 } |
7874 } | 8099 } |
7875 | 8100 |
7876 return Heap::undefined_value(); | 8101 return Heap::undefined_value(); |
7877 } | 8102 } |
7878 | 8103 |
7879 | 8104 |
7880 static Object* Runtime_DebugGetProperty(Arguments args) { | 8105 static MaybeObject* Runtime_DebugGetProperty(Arguments args) { |
7881 HandleScope scope; | 8106 HandleScope scope; |
7882 | 8107 |
7883 ASSERT(args.length() == 2); | 8108 ASSERT(args.length() == 2); |
7884 | 8109 |
7885 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 8110 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
7886 CONVERT_ARG_CHECKED(String, name, 1); | 8111 CONVERT_ARG_CHECKED(String, name, 1); |
7887 | 8112 |
7888 LookupResult result; | 8113 LookupResult result; |
7889 obj->Lookup(*name, &result); | 8114 obj->Lookup(*name, &result); |
7890 if (result.IsProperty()) { | 8115 if (result.IsProperty()) { |
7891 return DebugLookupResultValue(*obj, *name, &result, NULL); | 8116 return DebugLookupResultValue(*obj, *name, &result, NULL); |
7892 } | 8117 } |
7893 return Heap::undefined_value(); | 8118 return Heap::undefined_value(); |
7894 } | 8119 } |
7895 | 8120 |
7896 | 8121 |
7897 // Return the property type calculated from the property details. | 8122 // Return the property type calculated from the property details. |
7898 // args[0]: smi with property details. | 8123 // args[0]: smi with property details. |
7899 static Object* Runtime_DebugPropertyTypeFromDetails(Arguments args) { | 8124 static MaybeObject* Runtime_DebugPropertyTypeFromDetails(Arguments args) { |
7900 ASSERT(args.length() == 1); | 8125 ASSERT(args.length() == 1); |
7901 CONVERT_CHECKED(Smi, details, args[0]); | 8126 CONVERT_CHECKED(Smi, details, args[0]); |
7902 PropertyType type = PropertyDetails(details).type(); | 8127 PropertyType type = PropertyDetails(details).type(); |
7903 return Smi::FromInt(static_cast<int>(type)); | 8128 return Smi::FromInt(static_cast<int>(type)); |
7904 } | 8129 } |
7905 | 8130 |
7906 | 8131 |
7907 // Return the property attribute calculated from the property details. | 8132 // Return the property attribute calculated from the property details. |
7908 // args[0]: smi with property details. | 8133 // args[0]: smi with property details. |
7909 static Object* Runtime_DebugPropertyAttributesFromDetails(Arguments args) { | 8134 static MaybeObject* Runtime_DebugPropertyAttributesFromDetails(Arguments args) { |
7910 ASSERT(args.length() == 1); | 8135 ASSERT(args.length() == 1); |
7911 CONVERT_CHECKED(Smi, details, args[0]); | 8136 CONVERT_CHECKED(Smi, details, args[0]); |
7912 PropertyAttributes attributes = PropertyDetails(details).attributes(); | 8137 PropertyAttributes attributes = PropertyDetails(details).attributes(); |
7913 return Smi::FromInt(static_cast<int>(attributes)); | 8138 return Smi::FromInt(static_cast<int>(attributes)); |
7914 } | 8139 } |
7915 | 8140 |
7916 | 8141 |
7917 // Return the property insertion index calculated from the property details. | 8142 // Return the property insertion index calculated from the property details. |
7918 // args[0]: smi with property details. | 8143 // args[0]: smi with property details. |
7919 static Object* Runtime_DebugPropertyIndexFromDetails(Arguments args) { | 8144 static MaybeObject* Runtime_DebugPropertyIndexFromDetails(Arguments args) { |
7920 ASSERT(args.length() == 1); | 8145 ASSERT(args.length() == 1); |
7921 CONVERT_CHECKED(Smi, details, args[0]); | 8146 CONVERT_CHECKED(Smi, details, args[0]); |
7922 int index = PropertyDetails(details).index(); | 8147 int index = PropertyDetails(details).index(); |
7923 return Smi::FromInt(index); | 8148 return Smi::FromInt(index); |
7924 } | 8149 } |
7925 | 8150 |
7926 | 8151 |
7927 // Return property value from named interceptor. | 8152 // Return property value from named interceptor. |
7928 // args[0]: object | 8153 // args[0]: object |
7929 // args[1]: property name | 8154 // args[1]: property name |
7930 static Object* Runtime_DebugNamedInterceptorPropertyValue(Arguments args) { | 8155 static MaybeObject* Runtime_DebugNamedInterceptorPropertyValue(Arguments args) { |
7931 HandleScope scope; | 8156 HandleScope scope; |
7932 ASSERT(args.length() == 2); | 8157 ASSERT(args.length() == 2); |
7933 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 8158 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
7934 RUNTIME_ASSERT(obj->HasNamedInterceptor()); | 8159 RUNTIME_ASSERT(obj->HasNamedInterceptor()); |
7935 CONVERT_ARG_CHECKED(String, name, 1); | 8160 CONVERT_ARG_CHECKED(String, name, 1); |
7936 | 8161 |
7937 PropertyAttributes attributes; | 8162 PropertyAttributes attributes; |
7938 return obj->GetPropertyWithInterceptor(*obj, *name, &attributes); | 8163 return obj->GetPropertyWithInterceptor(*obj, *name, &attributes); |
7939 } | 8164 } |
7940 | 8165 |
7941 | 8166 |
7942 // Return element value from indexed interceptor. | 8167 // Return element value from indexed interceptor. |
7943 // args[0]: object | 8168 // args[0]: object |
7944 // args[1]: index | 8169 // args[1]: index |
7945 static Object* Runtime_DebugIndexedInterceptorElementValue(Arguments args) { | 8170 static MaybeObject* Runtime_DebugIndexedInterceptorElementValue( |
| 8171 Arguments args) { |
7946 HandleScope scope; | 8172 HandleScope scope; |
7947 ASSERT(args.length() == 2); | 8173 ASSERT(args.length() == 2); |
7948 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 8174 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
7949 RUNTIME_ASSERT(obj->HasIndexedInterceptor()); | 8175 RUNTIME_ASSERT(obj->HasIndexedInterceptor()); |
7950 CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]); | 8176 CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]); |
7951 | 8177 |
7952 return obj->GetElementWithInterceptor(*obj, index); | 8178 return obj->GetElementWithInterceptor(*obj, index); |
7953 } | 8179 } |
7954 | 8180 |
7955 | 8181 |
7956 static Object* Runtime_CheckExecutionState(Arguments args) { | 8182 static MaybeObject* Runtime_CheckExecutionState(Arguments args) { |
7957 ASSERT(args.length() >= 1); | 8183 ASSERT(args.length() >= 1); |
7958 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); | 8184 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); |
7959 // Check that the break id is valid. | 8185 // Check that the break id is valid. |
7960 if (Debug::break_id() == 0 || break_id != Debug::break_id()) { | 8186 if (Debug::break_id() == 0 || break_id != Debug::break_id()) { |
7961 return Top::Throw(Heap::illegal_execution_state_symbol()); | 8187 return Top::Throw(Heap::illegal_execution_state_symbol()); |
7962 } | 8188 } |
7963 | 8189 |
7964 return Heap::true_value(); | 8190 return Heap::true_value(); |
7965 } | 8191 } |
7966 | 8192 |
7967 | 8193 |
7968 static Object* Runtime_GetFrameCount(Arguments args) { | 8194 static MaybeObject* Runtime_GetFrameCount(Arguments args) { |
7969 HandleScope scope; | 8195 HandleScope scope; |
7970 ASSERT(args.length() == 1); | 8196 ASSERT(args.length() == 1); |
7971 | 8197 |
7972 // Check arguments. | 8198 // Check arguments. |
7973 Object* result = Runtime_CheckExecutionState(args); | 8199 Object* result; |
7974 if (result->IsFailure()) return result; | 8200 { MaybeObject* maybe_result = Runtime_CheckExecutionState(args); |
| 8201 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 8202 } |
7975 | 8203 |
7976 // Count all frames which are relevant to debugging stack trace. | 8204 // Count all frames which are relevant to debugging stack trace. |
7977 int n = 0; | 8205 int n = 0; |
7978 StackFrame::Id id = Debug::break_frame_id(); | 8206 StackFrame::Id id = Debug::break_frame_id(); |
7979 if (id == StackFrame::NO_ID) { | 8207 if (id == StackFrame::NO_ID) { |
7980 // If there is no JavaScript stack frame count is 0. | 8208 // If there is no JavaScript stack frame count is 0. |
7981 return Smi::FromInt(0); | 8209 return Smi::FromInt(0); |
7982 } | 8210 } |
7983 for (JavaScriptFrameIterator it(id); !it.done(); it.Advance()) n++; | 8211 for (JavaScriptFrameIterator it(id); !it.done(); it.Advance()) n++; |
7984 return Smi::FromInt(n); | 8212 return Smi::FromInt(n); |
(...skipping 21 matching lines...) Expand all Loading... |
8006 // 2: Function | 8234 // 2: Function |
8007 // 3: Argument count | 8235 // 3: Argument count |
8008 // 4: Local count | 8236 // 4: Local count |
8009 // 5: Source position | 8237 // 5: Source position |
8010 // 6: Constructor call | 8238 // 6: Constructor call |
8011 // 7: Is at return | 8239 // 7: Is at return |
8012 // 8: Debugger frame | 8240 // 8: Debugger frame |
8013 // Arguments name, value | 8241 // Arguments name, value |
8014 // Locals name, value | 8242 // Locals name, value |
8015 // Return value if any | 8243 // Return value if any |
8016 static Object* Runtime_GetFrameDetails(Arguments args) { | 8244 static MaybeObject* Runtime_GetFrameDetails(Arguments args) { |
8017 HandleScope scope; | 8245 HandleScope scope; |
8018 ASSERT(args.length() == 2); | 8246 ASSERT(args.length() == 2); |
8019 | 8247 |
8020 // Check arguments. | 8248 // Check arguments. |
8021 Object* check = Runtime_CheckExecutionState(args); | 8249 Object* check; |
8022 if (check->IsFailure()) return check; | 8250 { MaybeObject* maybe_check = Runtime_CheckExecutionState(args); |
| 8251 if (!maybe_check->ToObject(&check)) return maybe_check; |
| 8252 } |
8023 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); | 8253 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); |
8024 | 8254 |
8025 // Find the relevant frame with the requested index. | 8255 // Find the relevant frame with the requested index. |
8026 StackFrame::Id id = Debug::break_frame_id(); | 8256 StackFrame::Id id = Debug::break_frame_id(); |
8027 if (id == StackFrame::NO_ID) { | 8257 if (id == StackFrame::NO_ID) { |
8028 // If there are no JavaScript stack frames return undefined. | 8258 // If there are no JavaScript stack frames return undefined. |
8029 return Heap::undefined_value(); | 8259 return Heap::undefined_value(); |
8030 } | 8260 } |
8031 int count = 0; | 8261 int count = 0; |
8032 JavaScriptFrameIterator it(id); | 8262 JavaScriptFrameIterator it(id); |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8313 // Check whether the arguments shadow object exists. | 8543 // Check whether the arguments shadow object exists. |
8314 int arguments_shadow_index = | 8544 int arguments_shadow_index = |
8315 shared->scope_info()->ContextSlotIndex(Heap::arguments_shadow_symbol(), | 8545 shared->scope_info()->ContextSlotIndex(Heap::arguments_shadow_symbol(), |
8316 NULL); | 8546 NULL); |
8317 if (arguments_shadow_index >= 0) { | 8547 if (arguments_shadow_index >= 0) { |
8318 // In this case all the arguments are available in the arguments shadow | 8548 // In this case all the arguments are available in the arguments shadow |
8319 // object. | 8549 // object. |
8320 Handle<JSObject> arguments_shadow( | 8550 Handle<JSObject> arguments_shadow( |
8321 JSObject::cast(context->get(arguments_shadow_index))); | 8551 JSObject::cast(context->get(arguments_shadow_index))); |
8322 for (int i = 0; i < scope_info.number_of_parameters(); ++i) { | 8552 for (int i = 0; i < scope_info.number_of_parameters(); ++i) { |
| 8553 // We don't expect exception-throwing getters on the arguments shadow. |
| 8554 Object* element = arguments_shadow->GetElement(i)->ToObjectUnchecked(); |
8323 SetProperty(closure_scope, | 8555 SetProperty(closure_scope, |
8324 scope_info.parameter_name(i), | 8556 scope_info.parameter_name(i), |
8325 Handle<Object>(arguments_shadow->GetElement(i)), NONE); | 8557 Handle<Object>(element), |
| 8558 NONE); |
8326 } | 8559 } |
8327 } | 8560 } |
8328 | 8561 |
8329 // Fill all context locals to the context extension. | 8562 // Fill all context locals to the context extension. |
8330 CopyContextLocalsToScopeObject(serialized_scope_info, scope_info, | 8563 CopyContextLocalsToScopeObject(serialized_scope_info, scope_info, |
8331 context, closure_scope); | 8564 context, closure_scope); |
8332 | 8565 |
8333 // Finally copy any properties from the function context extension. This will | 8566 // Finally copy any properties from the function context extension. This will |
8334 // be variables introduced by eval. | 8567 // be variables introduced by eval. |
8335 if (context->has_extension()) { | 8568 if (context->has_extension()) { |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8547 JavaScriptFrame* frame_; | 8780 JavaScriptFrame* frame_; |
8548 Handle<JSFunction> function_; | 8781 Handle<JSFunction> function_; |
8549 Handle<Context> context_; | 8782 Handle<Context> context_; |
8550 bool local_done_; | 8783 bool local_done_; |
8551 bool at_local_; | 8784 bool at_local_; |
8552 | 8785 |
8553 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); | 8786 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); |
8554 }; | 8787 }; |
8555 | 8788 |
8556 | 8789 |
8557 static Object* Runtime_GetScopeCount(Arguments args) { | 8790 static MaybeObject* Runtime_GetScopeCount(Arguments args) { |
8558 HandleScope scope; | 8791 HandleScope scope; |
8559 ASSERT(args.length() == 2); | 8792 ASSERT(args.length() == 2); |
8560 | 8793 |
8561 // Check arguments. | 8794 // Check arguments. |
8562 Object* check = Runtime_CheckExecutionState(args); | 8795 Object* check; |
8563 if (check->IsFailure()) return check; | 8796 { MaybeObject* maybe_check = Runtime_CheckExecutionState(args); |
| 8797 if (!maybe_check->ToObject(&check)) return maybe_check; |
| 8798 } |
8564 CONVERT_CHECKED(Smi, wrapped_id, args[1]); | 8799 CONVERT_CHECKED(Smi, wrapped_id, args[1]); |
8565 | 8800 |
8566 // Get the frame where the debugging is performed. | 8801 // Get the frame where the debugging is performed. |
8567 StackFrame::Id id = UnwrapFrameId(wrapped_id); | 8802 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
8568 JavaScriptFrameIterator it(id); | 8803 JavaScriptFrameIterator it(id); |
8569 JavaScriptFrame* frame = it.frame(); | 8804 JavaScriptFrame* frame = it.frame(); |
8570 | 8805 |
8571 // Count the visible scopes. | 8806 // Count the visible scopes. |
8572 int n = 0; | 8807 int n = 0; |
8573 for (ScopeIterator it(frame); !it.Done(); it.Next()) { | 8808 for (ScopeIterator it(frame); !it.Done(); it.Next()) { |
8574 n++; | 8809 n++; |
8575 } | 8810 } |
8576 | 8811 |
8577 return Smi::FromInt(n); | 8812 return Smi::FromInt(n); |
8578 } | 8813 } |
8579 | 8814 |
8580 | 8815 |
8581 static const int kScopeDetailsTypeIndex = 0; | 8816 static const int kScopeDetailsTypeIndex = 0; |
8582 static const int kScopeDetailsObjectIndex = 1; | 8817 static const int kScopeDetailsObjectIndex = 1; |
8583 static const int kScopeDetailsSize = 2; | 8818 static const int kScopeDetailsSize = 2; |
8584 | 8819 |
8585 // Return an array with scope details | 8820 // Return an array with scope details |
8586 // args[0]: number: break id | 8821 // args[0]: number: break id |
8587 // args[1]: number: frame index | 8822 // args[1]: number: frame index |
8588 // args[2]: number: scope index | 8823 // args[2]: number: scope index |
8589 // | 8824 // |
8590 // The array returned contains the following information: | 8825 // The array returned contains the following information: |
8591 // 0: Scope type | 8826 // 0: Scope type |
8592 // 1: Scope object | 8827 // 1: Scope object |
8593 static Object* Runtime_GetScopeDetails(Arguments args) { | 8828 static MaybeObject* Runtime_GetScopeDetails(Arguments args) { |
8594 HandleScope scope; | 8829 HandleScope scope; |
8595 ASSERT(args.length() == 3); | 8830 ASSERT(args.length() == 3); |
8596 | 8831 |
8597 // Check arguments. | 8832 // Check arguments. |
8598 Object* check = Runtime_CheckExecutionState(args); | 8833 Object* check; |
8599 if (check->IsFailure()) return check; | 8834 { MaybeObject* maybe_check = Runtime_CheckExecutionState(args); |
| 8835 if (!maybe_check->ToObject(&check)) return maybe_check; |
| 8836 } |
8600 CONVERT_CHECKED(Smi, wrapped_id, args[1]); | 8837 CONVERT_CHECKED(Smi, wrapped_id, args[1]); |
8601 CONVERT_NUMBER_CHECKED(int, index, Int32, args[2]); | 8838 CONVERT_NUMBER_CHECKED(int, index, Int32, args[2]); |
8602 | 8839 |
8603 // Get the frame where the debugging is performed. | 8840 // Get the frame where the debugging is performed. |
8604 StackFrame::Id id = UnwrapFrameId(wrapped_id); | 8841 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
8605 JavaScriptFrameIterator frame_it(id); | 8842 JavaScriptFrameIterator frame_it(id); |
8606 JavaScriptFrame* frame = frame_it.frame(); | 8843 JavaScriptFrame* frame = frame_it.frame(); |
8607 | 8844 |
8608 // Find the requested scope. | 8845 // Find the requested scope. |
8609 int n = 0; | 8846 int n = 0; |
(...skipping 11 matching lines...) Expand all Loading... |
8621 | 8858 |
8622 // Fill in scope details. | 8859 // Fill in scope details. |
8623 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type())); | 8860 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type())); |
8624 Handle<JSObject> scope_object = it.ScopeObject(); | 8861 Handle<JSObject> scope_object = it.ScopeObject(); |
8625 details->set(kScopeDetailsObjectIndex, *scope_object); | 8862 details->set(kScopeDetailsObjectIndex, *scope_object); |
8626 | 8863 |
8627 return *Factory::NewJSArrayWithElements(details); | 8864 return *Factory::NewJSArrayWithElements(details); |
8628 } | 8865 } |
8629 | 8866 |
8630 | 8867 |
8631 static Object* Runtime_DebugPrintScopes(Arguments args) { | 8868 static MaybeObject* Runtime_DebugPrintScopes(Arguments args) { |
8632 HandleScope scope; | 8869 HandleScope scope; |
8633 ASSERT(args.length() == 0); | 8870 ASSERT(args.length() == 0); |
8634 | 8871 |
8635 #ifdef DEBUG | 8872 #ifdef DEBUG |
8636 // Print the scopes for the top frame. | 8873 // Print the scopes for the top frame. |
8637 StackFrameLocator locator; | 8874 StackFrameLocator locator; |
8638 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); | 8875 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); |
8639 for (ScopeIterator it(frame); !it.Done(); it.Next()) { | 8876 for (ScopeIterator it(frame); !it.Done(); it.Next()) { |
8640 it.DebugPrint(); | 8877 it.DebugPrint(); |
8641 } | 8878 } |
8642 #endif | 8879 #endif |
8643 return Heap::undefined_value(); | 8880 return Heap::undefined_value(); |
8644 } | 8881 } |
8645 | 8882 |
8646 | 8883 |
8647 static Object* Runtime_GetCFrames(Arguments args) { | 8884 static MaybeObject* Runtime_GetCFrames(Arguments args) { |
8648 HandleScope scope; | 8885 // See bug 906. |
8649 ASSERT(args.length() == 1); | |
8650 Object* result = Runtime_CheckExecutionState(args); | |
8651 if (result->IsFailure()) return result; | |
8652 | |
8653 #if V8_HOST_ARCH_64_BIT | |
8654 UNIMPLEMENTED(); | |
8655 return Heap::undefined_value(); | 8886 return Heap::undefined_value(); |
8656 #else | |
8657 | |
8658 static const int kMaxCFramesSize = 200; | |
8659 ScopedVector<OS::StackFrame> frames(kMaxCFramesSize); | |
8660 int frames_count = OS::StackWalk(frames); | |
8661 if (frames_count == OS::kStackWalkError) { | |
8662 return Heap::undefined_value(); | |
8663 } | |
8664 | |
8665 Handle<String> address_str = Factory::LookupAsciiSymbol("address"); | |
8666 Handle<String> text_str = Factory::LookupAsciiSymbol("text"); | |
8667 Handle<FixedArray> frames_array = Factory::NewFixedArray(frames_count); | |
8668 for (int i = 0; i < frames_count; i++) { | |
8669 Handle<JSObject> frame_value = Factory::NewJSObject(Top::object_function()); | |
8670 Handle<Object> frame_address = | |
8671 Factory::NewNumberFromInt(reinterpret_cast<int>(frames[i].address)); | |
8672 | |
8673 frame_value->SetProperty(*address_str, *frame_address, NONE); | |
8674 | |
8675 // Get the stack walk text for this frame. | |
8676 Handle<String> frame_text; | |
8677 int frame_text_length = StrLength(frames[i].text); | |
8678 if (frame_text_length > 0) { | |
8679 Vector<const char> str(frames[i].text, frame_text_length); | |
8680 frame_text = Factory::NewStringFromAscii(str); | |
8681 } | |
8682 | |
8683 if (!frame_text.is_null()) { | |
8684 frame_value->SetProperty(*text_str, *frame_text, NONE); | |
8685 } | |
8686 | |
8687 frames_array->set(i, *frame_value); | |
8688 } | |
8689 return *Factory::NewJSArrayWithElements(frames_array); | |
8690 #endif // V8_HOST_ARCH_64_BIT | |
8691 } | 8887 } |
8692 | 8888 |
8693 | 8889 |
8694 static Object* Runtime_GetThreadCount(Arguments args) { | 8890 static MaybeObject* Runtime_GetThreadCount(Arguments args) { |
8695 HandleScope scope; | 8891 HandleScope scope; |
8696 ASSERT(args.length() == 1); | 8892 ASSERT(args.length() == 1); |
8697 | 8893 |
8698 // Check arguments. | 8894 // Check arguments. |
8699 Object* result = Runtime_CheckExecutionState(args); | 8895 Object* result; |
8700 if (result->IsFailure()) return result; | 8896 { MaybeObject* maybe_result = Runtime_CheckExecutionState(args); |
| 8897 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 8898 } |
8701 | 8899 |
8702 // Count all archived V8 threads. | 8900 // Count all archived V8 threads. |
8703 int n = 0; | 8901 int n = 0; |
8704 for (ThreadState* thread = ThreadState::FirstInUse(); | 8902 for (ThreadState* thread = ThreadState::FirstInUse(); |
8705 thread != NULL; | 8903 thread != NULL; |
8706 thread = thread->Next()) { | 8904 thread = thread->Next()) { |
8707 n++; | 8905 n++; |
8708 } | 8906 } |
8709 | 8907 |
8710 // Total number of threads is current thread and archived threads. | 8908 // Total number of threads is current thread and archived threads. |
8711 return Smi::FromInt(n + 1); | 8909 return Smi::FromInt(n + 1); |
8712 } | 8910 } |
8713 | 8911 |
8714 | 8912 |
8715 static const int kThreadDetailsCurrentThreadIndex = 0; | 8913 static const int kThreadDetailsCurrentThreadIndex = 0; |
8716 static const int kThreadDetailsThreadIdIndex = 1; | 8914 static const int kThreadDetailsThreadIdIndex = 1; |
8717 static const int kThreadDetailsSize = 2; | 8915 static const int kThreadDetailsSize = 2; |
8718 | 8916 |
8719 // Return an array with thread details | 8917 // Return an array with thread details |
8720 // args[0]: number: break id | 8918 // args[0]: number: break id |
8721 // args[1]: number: thread index | 8919 // args[1]: number: thread index |
8722 // | 8920 // |
8723 // The array returned contains the following information: | 8921 // The array returned contains the following information: |
8724 // 0: Is current thread? | 8922 // 0: Is current thread? |
8725 // 1: Thread id | 8923 // 1: Thread id |
8726 static Object* Runtime_GetThreadDetails(Arguments args) { | 8924 static MaybeObject* Runtime_GetThreadDetails(Arguments args) { |
8727 HandleScope scope; | 8925 HandleScope scope; |
8728 ASSERT(args.length() == 2); | 8926 ASSERT(args.length() == 2); |
8729 | 8927 |
8730 // Check arguments. | 8928 // Check arguments. |
8731 Object* check = Runtime_CheckExecutionState(args); | 8929 Object* check; |
8732 if (check->IsFailure()) return check; | 8930 { MaybeObject* maybe_check = Runtime_CheckExecutionState(args); |
| 8931 if (!maybe_check->ToObject(&check)) return maybe_check; |
| 8932 } |
8733 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); | 8933 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); |
8734 | 8934 |
8735 // Allocate array for result. | 8935 // Allocate array for result. |
8736 Handle<FixedArray> details = Factory::NewFixedArray(kThreadDetailsSize); | 8936 Handle<FixedArray> details = Factory::NewFixedArray(kThreadDetailsSize); |
8737 | 8937 |
8738 // Thread index 0 is current thread. | 8938 // Thread index 0 is current thread. |
8739 if (index == 0) { | 8939 if (index == 0) { |
8740 // Fill the details. | 8940 // Fill the details. |
8741 details->set(kThreadDetailsCurrentThreadIndex, Heap::true_value()); | 8941 details->set(kThreadDetailsCurrentThreadIndex, Heap::true_value()); |
8742 details->set(kThreadDetailsThreadIdIndex, | 8942 details->set(kThreadDetailsThreadIdIndex, |
(...skipping 15 matching lines...) Expand all Loading... |
8758 details->set(kThreadDetailsThreadIdIndex, Smi::FromInt(thread->id())); | 8958 details->set(kThreadDetailsThreadIdIndex, Smi::FromInt(thread->id())); |
8759 } | 8959 } |
8760 | 8960 |
8761 // Convert to JS array and return. | 8961 // Convert to JS array and return. |
8762 return *Factory::NewJSArrayWithElements(details); | 8962 return *Factory::NewJSArrayWithElements(details); |
8763 } | 8963 } |
8764 | 8964 |
8765 | 8965 |
8766 // Sets the disable break state | 8966 // Sets the disable break state |
8767 // args[0]: disable break state | 8967 // args[0]: disable break state |
8768 static Object* Runtime_SetDisableBreak(Arguments args) { | 8968 static MaybeObject* Runtime_SetDisableBreak(Arguments args) { |
8769 HandleScope scope; | 8969 HandleScope scope; |
8770 ASSERT(args.length() == 1); | 8970 ASSERT(args.length() == 1); |
8771 CONVERT_BOOLEAN_CHECKED(disable_break, args[0]); | 8971 CONVERT_BOOLEAN_CHECKED(disable_break, args[0]); |
8772 Debug::set_disable_break(disable_break); | 8972 Debug::set_disable_break(disable_break); |
8773 return Heap::undefined_value(); | 8973 return Heap::undefined_value(); |
8774 } | 8974 } |
8775 | 8975 |
8776 | 8976 |
8777 static Object* Runtime_GetBreakLocations(Arguments args) { | 8977 static MaybeObject* Runtime_GetBreakLocations(Arguments args) { |
8778 HandleScope scope; | 8978 HandleScope scope; |
8779 ASSERT(args.length() == 1); | 8979 ASSERT(args.length() == 1); |
8780 | 8980 |
8781 CONVERT_ARG_CHECKED(JSFunction, fun, 0); | 8981 CONVERT_ARG_CHECKED(JSFunction, fun, 0); |
8782 Handle<SharedFunctionInfo> shared(fun->shared()); | 8982 Handle<SharedFunctionInfo> shared(fun->shared()); |
8783 // Find the number of break points | 8983 // Find the number of break points |
8784 Handle<Object> break_locations = Debug::GetSourceBreakLocations(shared); | 8984 Handle<Object> break_locations = Debug::GetSourceBreakLocations(shared); |
8785 if (break_locations->IsUndefined()) return Heap::undefined_value(); | 8985 if (break_locations->IsUndefined()) return Heap::undefined_value(); |
8786 // Return array as JS array | 8986 // Return array as JS array |
8787 return *Factory::NewJSArrayWithElements( | 8987 return *Factory::NewJSArrayWithElements( |
8788 Handle<FixedArray>::cast(break_locations)); | 8988 Handle<FixedArray>::cast(break_locations)); |
8789 } | 8989 } |
8790 | 8990 |
8791 | 8991 |
8792 // Set a break point in a function | 8992 // Set a break point in a function |
8793 // args[0]: function | 8993 // args[0]: function |
8794 // args[1]: number: break source position (within the function source) | 8994 // args[1]: number: break source position (within the function source) |
8795 // args[2]: number: break point object | 8995 // args[2]: number: break point object |
8796 static Object* Runtime_SetFunctionBreakPoint(Arguments args) { | 8996 static MaybeObject* Runtime_SetFunctionBreakPoint(Arguments args) { |
8797 HandleScope scope; | 8997 HandleScope scope; |
8798 ASSERT(args.length() == 3); | 8998 ASSERT(args.length() == 3); |
8799 CONVERT_ARG_CHECKED(JSFunction, fun, 0); | 8999 CONVERT_ARG_CHECKED(JSFunction, fun, 0); |
8800 Handle<SharedFunctionInfo> shared(fun->shared()); | 9000 Handle<SharedFunctionInfo> shared(fun->shared()); |
8801 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); | 9001 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); |
8802 RUNTIME_ASSERT(source_position >= 0); | 9002 RUNTIME_ASSERT(source_position >= 0); |
8803 Handle<Object> break_point_object_arg = args.at<Object>(2); | 9003 Handle<Object> break_point_object_arg = args.at<Object>(2); |
8804 | 9004 |
8805 // Set break point. | 9005 // Set break point. |
8806 Debug::SetBreakPoint(shared, break_point_object_arg, &source_position); | 9006 Debug::SetBreakPoint(shared, break_point_object_arg, &source_position); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8885 return *target; | 9085 return *target; |
8886 } | 9086 } |
8887 | 9087 |
8888 | 9088 |
8889 // Changes the state of a break point in a script and returns source position | 9089 // Changes the state of a break point in a script and returns source position |
8890 // where break point was set. NOTE: Regarding performance see the NOTE for | 9090 // where break point was set. NOTE: Regarding performance see the NOTE for |
8891 // GetScriptFromScriptData. | 9091 // GetScriptFromScriptData. |
8892 // args[0]: script to set break point in | 9092 // args[0]: script to set break point in |
8893 // args[1]: number: break source position (within the script source) | 9093 // args[1]: number: break source position (within the script source) |
8894 // args[2]: number: break point object | 9094 // args[2]: number: break point object |
8895 static Object* Runtime_SetScriptBreakPoint(Arguments args) { | 9095 static MaybeObject* Runtime_SetScriptBreakPoint(Arguments args) { |
8896 HandleScope scope; | 9096 HandleScope scope; |
8897 ASSERT(args.length() == 3); | 9097 ASSERT(args.length() == 3); |
8898 CONVERT_ARG_CHECKED(JSValue, wrapper, 0); | 9098 CONVERT_ARG_CHECKED(JSValue, wrapper, 0); |
8899 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); | 9099 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); |
8900 RUNTIME_ASSERT(source_position >= 0); | 9100 RUNTIME_ASSERT(source_position >= 0); |
8901 Handle<Object> break_point_object_arg = args.at<Object>(2); | 9101 Handle<Object> break_point_object_arg = args.at<Object>(2); |
8902 | 9102 |
8903 // Get the script from the script wrapper. | 9103 // Get the script from the script wrapper. |
8904 RUNTIME_ASSERT(wrapper->value()->IsScript()); | 9104 RUNTIME_ASSERT(wrapper->value()->IsScript()); |
8905 Handle<Script> script(Script::cast(wrapper->value())); | 9105 Handle<Script> script(Script::cast(wrapper->value())); |
(...skipping 13 matching lines...) Expand all Loading... |
8919 Debug::SetBreakPoint(shared, break_point_object_arg, &position); | 9119 Debug::SetBreakPoint(shared, break_point_object_arg, &position); |
8920 position += shared->start_position(); | 9120 position += shared->start_position(); |
8921 return Smi::FromInt(position); | 9121 return Smi::FromInt(position); |
8922 } | 9122 } |
8923 return Heap::undefined_value(); | 9123 return Heap::undefined_value(); |
8924 } | 9124 } |
8925 | 9125 |
8926 | 9126 |
8927 // Clear a break point | 9127 // Clear a break point |
8928 // args[0]: number: break point object | 9128 // args[0]: number: break point object |
8929 static Object* Runtime_ClearBreakPoint(Arguments args) { | 9129 static MaybeObject* Runtime_ClearBreakPoint(Arguments args) { |
8930 HandleScope scope; | 9130 HandleScope scope; |
8931 ASSERT(args.length() == 1); | 9131 ASSERT(args.length() == 1); |
8932 Handle<Object> break_point_object_arg = args.at<Object>(0); | 9132 Handle<Object> break_point_object_arg = args.at<Object>(0); |
8933 | 9133 |
8934 // Clear break point. | 9134 // Clear break point. |
8935 Debug::ClearBreakPoint(break_point_object_arg); | 9135 Debug::ClearBreakPoint(break_point_object_arg); |
8936 | 9136 |
8937 return Heap::undefined_value(); | 9137 return Heap::undefined_value(); |
8938 } | 9138 } |
8939 | 9139 |
8940 | 9140 |
8941 // Change the state of break on exceptions. | 9141 // Change the state of break on exceptions. |
8942 // args[0]: Enum value indicating whether to affect caught/uncaught exceptions. | 9142 // args[0]: Enum value indicating whether to affect caught/uncaught exceptions. |
8943 // args[1]: Boolean indicating on/off. | 9143 // args[1]: Boolean indicating on/off. |
8944 static Object* Runtime_ChangeBreakOnException(Arguments args) { | 9144 static MaybeObject* Runtime_ChangeBreakOnException(Arguments args) { |
8945 HandleScope scope; | 9145 HandleScope scope; |
8946 ASSERT(args.length() == 2); | 9146 ASSERT(args.length() == 2); |
8947 RUNTIME_ASSERT(args[0]->IsNumber()); | 9147 RUNTIME_ASSERT(args[0]->IsNumber()); |
8948 CONVERT_BOOLEAN_CHECKED(enable, args[1]); | 9148 CONVERT_BOOLEAN_CHECKED(enable, args[1]); |
8949 | 9149 |
8950 // If the number doesn't match an enum value, the ChangeBreakOnException | 9150 // If the number doesn't match an enum value, the ChangeBreakOnException |
8951 // function will default to affecting caught exceptions. | 9151 // function will default to affecting caught exceptions. |
8952 ExceptionBreakType type = | 9152 ExceptionBreakType type = |
8953 static_cast<ExceptionBreakType>(NumberToUint32(args[0])); | 9153 static_cast<ExceptionBreakType>(NumberToUint32(args[0])); |
8954 // Update break point state. | 9154 // Update break point state. |
8955 Debug::ChangeBreakOnException(type, enable); | 9155 Debug::ChangeBreakOnException(type, enable); |
8956 return Heap::undefined_value(); | 9156 return Heap::undefined_value(); |
8957 } | 9157 } |
8958 | 9158 |
8959 | 9159 |
8960 // Returns the state of break on exceptions | 9160 // Returns the state of break on exceptions |
8961 // args[0]: boolean indicating uncaught exceptions | 9161 // args[0]: boolean indicating uncaught exceptions |
8962 static Object* Runtime_IsBreakOnException(Arguments args) { | 9162 static MaybeObject* Runtime_IsBreakOnException(Arguments args) { |
8963 HandleScope scope; | 9163 HandleScope scope; |
8964 ASSERT(args.length() == 1); | 9164 ASSERT(args.length() == 1); |
8965 RUNTIME_ASSERT(args[0]->IsNumber()); | 9165 RUNTIME_ASSERT(args[0]->IsNumber()); |
8966 | 9166 |
8967 ExceptionBreakType type = | 9167 ExceptionBreakType type = |
8968 static_cast<ExceptionBreakType>(NumberToUint32(args[0])); | 9168 static_cast<ExceptionBreakType>(NumberToUint32(args[0])); |
8969 bool result = Debug::IsBreakOnException(type); | 9169 bool result = Debug::IsBreakOnException(type); |
8970 return Smi::FromInt(result); | 9170 return Smi::FromInt(result); |
8971 } | 9171 } |
8972 | 9172 |
8973 | 9173 |
8974 // Prepare for stepping | 9174 // Prepare for stepping |
8975 // args[0]: break id for checking execution state | 9175 // args[0]: break id for checking execution state |
8976 // args[1]: step action from the enumeration StepAction | 9176 // args[1]: step action from the enumeration StepAction |
8977 // args[2]: number of times to perform the step, for step out it is the number | 9177 // args[2]: number of times to perform the step, for step out it is the number |
8978 // of frames to step down. | 9178 // of frames to step down. |
8979 static Object* Runtime_PrepareStep(Arguments args) { | 9179 static MaybeObject* Runtime_PrepareStep(Arguments args) { |
8980 HandleScope scope; | 9180 HandleScope scope; |
8981 ASSERT(args.length() == 3); | 9181 ASSERT(args.length() == 3); |
8982 // Check arguments. | 9182 // Check arguments. |
8983 Object* check = Runtime_CheckExecutionState(args); | 9183 Object* check; |
8984 if (check->IsFailure()) return check; | 9184 { MaybeObject* maybe_check = Runtime_CheckExecutionState(args); |
| 9185 if (!maybe_check->ToObject(&check)) return maybe_check; |
| 9186 } |
8985 if (!args[1]->IsNumber() || !args[2]->IsNumber()) { | 9187 if (!args[1]->IsNumber() || !args[2]->IsNumber()) { |
8986 return Top::Throw(Heap::illegal_argument_symbol()); | 9188 return Top::Throw(Heap::illegal_argument_symbol()); |
8987 } | 9189 } |
8988 | 9190 |
8989 // Get the step action and check validity. | 9191 // Get the step action and check validity. |
8990 StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1])); | 9192 StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1])); |
8991 if (step_action != StepIn && | 9193 if (step_action != StepIn && |
8992 step_action != StepNext && | 9194 step_action != StepNext && |
8993 step_action != StepOut && | 9195 step_action != StepOut && |
8994 step_action != StepInMin && | 9196 step_action != StepInMin && |
(...skipping 10 matching lines...) Expand all Loading... |
9005 // Clear all current stepping setup. | 9207 // Clear all current stepping setup. |
9006 Debug::ClearStepping(); | 9208 Debug::ClearStepping(); |
9007 | 9209 |
9008 // Prepare step. | 9210 // Prepare step. |
9009 Debug::PrepareStep(static_cast<StepAction>(step_action), step_count); | 9211 Debug::PrepareStep(static_cast<StepAction>(step_action), step_count); |
9010 return Heap::undefined_value(); | 9212 return Heap::undefined_value(); |
9011 } | 9213 } |
9012 | 9214 |
9013 | 9215 |
9014 // Clear all stepping set by PrepareStep. | 9216 // Clear all stepping set by PrepareStep. |
9015 static Object* Runtime_ClearStepping(Arguments args) { | 9217 static MaybeObject* Runtime_ClearStepping(Arguments args) { |
9016 HandleScope scope; | 9218 HandleScope scope; |
9017 ASSERT(args.length() == 0); | 9219 ASSERT(args.length() == 0); |
9018 Debug::ClearStepping(); | 9220 Debug::ClearStepping(); |
9019 return Heap::undefined_value(); | 9221 return Heap::undefined_value(); |
9020 } | 9222 } |
9021 | 9223 |
9022 | 9224 |
9023 // Creates a copy of the with context chain. The copy of the context chain is | 9225 // Creates a copy of the with context chain. The copy of the context chain is |
9024 // is linked to the function context supplied. | 9226 // is linked to the function context supplied. |
9025 static Handle<Context> CopyWithContextChain(Handle<Context> context_chain, | 9227 static Handle<Context> CopyWithContextChain(Handle<Context> context_chain, |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9082 // debugging. This is accomplished by creating a new context which in its | 9284 // debugging. This is accomplished by creating a new context which in its |
9083 // extension part has all the parameters and locals of the function on the | 9285 // extension part has all the parameters and locals of the function on the |
9084 // stack frame. A function which calls eval with the code to evaluate is then | 9286 // stack frame. A function which calls eval with the code to evaluate is then |
9085 // compiled in this context and called in this context. As this context | 9287 // compiled in this context and called in this context. As this context |
9086 // replaces the context of the function on the stack frame a new (empty) | 9288 // replaces the context of the function on the stack frame a new (empty) |
9087 // function is created as well to be used as the closure for the context. | 9289 // function is created as well to be used as the closure for the context. |
9088 // This function and the context acts as replacements for the function on the | 9290 // This function and the context acts as replacements for the function on the |
9089 // stack frame presenting the same view of the values of parameters and | 9291 // stack frame presenting the same view of the values of parameters and |
9090 // local variables as if the piece of JavaScript was evaluated at the point | 9292 // local variables as if the piece of JavaScript was evaluated at the point |
9091 // where the function on the stack frame is currently stopped. | 9293 // where the function on the stack frame is currently stopped. |
9092 static Object* Runtime_DebugEvaluate(Arguments args) { | 9294 static MaybeObject* Runtime_DebugEvaluate(Arguments args) { |
9093 HandleScope scope; | 9295 HandleScope scope; |
9094 | 9296 |
9095 // Check the execution state and decode arguments frame and source to be | 9297 // Check the execution state and decode arguments frame and source to be |
9096 // evaluated. | 9298 // evaluated. |
9097 ASSERT(args.length() == 4); | 9299 ASSERT(args.length() == 4); |
9098 Object* check_result = Runtime_CheckExecutionState(args); | 9300 Object* check_result; |
9099 if (check_result->IsFailure()) return check_result; | 9301 { MaybeObject* maybe_check_result = Runtime_CheckExecutionState(args); |
| 9302 if (!maybe_check_result->ToObject(&check_result)) { |
| 9303 return maybe_check_result; |
| 9304 } |
| 9305 } |
9100 CONVERT_CHECKED(Smi, wrapped_id, args[1]); | 9306 CONVERT_CHECKED(Smi, wrapped_id, args[1]); |
9101 CONVERT_ARG_CHECKED(String, source, 2); | 9307 CONVERT_ARG_CHECKED(String, source, 2); |
9102 CONVERT_BOOLEAN_CHECKED(disable_break, args[3]); | 9308 CONVERT_BOOLEAN_CHECKED(disable_break, args[3]); |
9103 | 9309 |
9104 // Handle the processing of break. | 9310 // Handle the processing of break. |
9105 DisableBreak disable_break_save(disable_break); | 9311 DisableBreak disable_break_save(disable_break); |
9106 | 9312 |
9107 // Get the frame where the debugging is performed. | 9313 // Get the frame where the debugging is performed. |
9108 StackFrame::Id id = UnwrapFrameId(wrapped_id); | 9314 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
9109 JavaScriptFrameIterator it(id); | 9315 JavaScriptFrameIterator it(id); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9193 // Skip the global proxy as it has no properties and always delegates to the | 9399 // Skip the global proxy as it has no properties and always delegates to the |
9194 // real global object. | 9400 // real global object. |
9195 if (result->IsJSGlobalProxy()) { | 9401 if (result->IsJSGlobalProxy()) { |
9196 result = Handle<JSObject>(JSObject::cast(result->GetPrototype())); | 9402 result = Handle<JSObject>(JSObject::cast(result->GetPrototype())); |
9197 } | 9403 } |
9198 | 9404 |
9199 return *result; | 9405 return *result; |
9200 } | 9406 } |
9201 | 9407 |
9202 | 9408 |
9203 static Object* Runtime_DebugEvaluateGlobal(Arguments args) { | 9409 static MaybeObject* Runtime_DebugEvaluateGlobal(Arguments args) { |
9204 HandleScope scope; | 9410 HandleScope scope; |
9205 | 9411 |
9206 // Check the execution state and decode arguments frame and source to be | 9412 // Check the execution state and decode arguments frame and source to be |
9207 // evaluated. | 9413 // evaluated. |
9208 ASSERT(args.length() == 3); | 9414 ASSERT(args.length() == 3); |
9209 Object* check_result = Runtime_CheckExecutionState(args); | 9415 Object* check_result; |
9210 if (check_result->IsFailure()) return check_result; | 9416 { MaybeObject* maybe_check_result = Runtime_CheckExecutionState(args); |
| 9417 if (!maybe_check_result->ToObject(&check_result)) { |
| 9418 return maybe_check_result; |
| 9419 } |
| 9420 } |
9211 CONVERT_ARG_CHECKED(String, source, 1); | 9421 CONVERT_ARG_CHECKED(String, source, 1); |
9212 CONVERT_BOOLEAN_CHECKED(disable_break, args[2]); | 9422 CONVERT_BOOLEAN_CHECKED(disable_break, args[2]); |
9213 | 9423 |
9214 // Handle the processing of break. | 9424 // Handle the processing of break. |
9215 DisableBreak disable_break_save(disable_break); | 9425 DisableBreak disable_break_save(disable_break); |
9216 | 9426 |
9217 // Enter the top context from before the debugger was invoked. | 9427 // Enter the top context from before the debugger was invoked. |
9218 SaveContext save; | 9428 SaveContext save; |
9219 SaveContext* top = &save; | 9429 SaveContext* top = &save; |
9220 while (top != NULL && *top->context() == *Debug::debug_context()) { | 9430 while (top != NULL && *top->context() == *Debug::debug_context()) { |
(...skipping 22 matching lines...) Expand all Loading... |
9243 bool has_pending_exception; | 9453 bool has_pending_exception; |
9244 Handle<Object> receiver = Top::global(); | 9454 Handle<Object> receiver = Top::global(); |
9245 Handle<Object> result = | 9455 Handle<Object> result = |
9246 Execution::Call(compiled_function, receiver, 0, NULL, | 9456 Execution::Call(compiled_function, receiver, 0, NULL, |
9247 &has_pending_exception); | 9457 &has_pending_exception); |
9248 if (has_pending_exception) return Failure::Exception(); | 9458 if (has_pending_exception) return Failure::Exception(); |
9249 return *result; | 9459 return *result; |
9250 } | 9460 } |
9251 | 9461 |
9252 | 9462 |
9253 static Object* Runtime_DebugGetLoadedScripts(Arguments args) { | 9463 static MaybeObject* Runtime_DebugGetLoadedScripts(Arguments args) { |
9254 HandleScope scope; | 9464 HandleScope scope; |
9255 ASSERT(args.length() == 0); | 9465 ASSERT(args.length() == 0); |
9256 | 9466 |
9257 // Fill the script objects. | 9467 // Fill the script objects. |
9258 Handle<FixedArray> instances = Debug::GetLoadedScripts(); | 9468 Handle<FixedArray> instances = Debug::GetLoadedScripts(); |
9259 | 9469 |
9260 // Convert the script objects to proper JS objects. | 9470 // Convert the script objects to proper JS objects. |
9261 for (int i = 0; i < instances->length(); i++) { | 9471 for (int i = 0; i < instances->length(); i++) { |
9262 Handle<Script> script = Handle<Script>(Script::cast(instances->get(i))); | 9472 Handle<Script> script = Handle<Script>(Script::cast(instances->get(i))); |
9263 // Get the script wrapper in a local handle before calling GetScriptWrapper, | 9473 // Get the script wrapper in a local handle before calling GetScriptWrapper, |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9343 | 9553 |
9344 // Return the number of referencing objects found. | 9554 // Return the number of referencing objects found. |
9345 return count; | 9555 return count; |
9346 } | 9556 } |
9347 | 9557 |
9348 | 9558 |
9349 // Scan the heap for objects with direct references to an object | 9559 // Scan the heap for objects with direct references to an object |
9350 // args[0]: the object to find references to | 9560 // args[0]: the object to find references to |
9351 // args[1]: constructor function for instances to exclude (Mirror) | 9561 // args[1]: constructor function for instances to exclude (Mirror) |
9352 // args[2]: the the maximum number of objects to return | 9562 // args[2]: the the maximum number of objects to return |
9353 static Object* Runtime_DebugReferencedBy(Arguments args) { | 9563 static MaybeObject* Runtime_DebugReferencedBy(Arguments args) { |
9354 ASSERT(args.length() == 3); | 9564 ASSERT(args.length() == 3); |
9355 | 9565 |
9356 // First perform a full GC in order to avoid references from dead objects. | 9566 // First perform a full GC in order to avoid references from dead objects. |
9357 Heap::CollectAllGarbage(false); | 9567 Heap::CollectAllGarbage(false); |
9358 | 9568 |
9359 // Check parameters. | 9569 // Check parameters. |
9360 CONVERT_CHECKED(JSObject, target, args[0]); | 9570 CONVERT_CHECKED(JSObject, target, args[0]); |
9361 Object* instance_filter = args[1]; | 9571 Object* instance_filter = args[1]; |
9362 RUNTIME_ASSERT(instance_filter->IsUndefined() || | 9572 RUNTIME_ASSERT(instance_filter->IsUndefined() || |
9363 instance_filter->IsJSObject()); | 9573 instance_filter->IsJSObject()); |
9364 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]); | 9574 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]); |
9365 RUNTIME_ASSERT(max_references >= 0); | 9575 RUNTIME_ASSERT(max_references >= 0); |
9366 | 9576 |
9367 // Get the constructor function for context extension and arguments array. | 9577 // Get the constructor function for context extension and arguments array. |
9368 JSObject* arguments_boilerplate = | 9578 JSObject* arguments_boilerplate = |
9369 Top::context()->global_context()->arguments_boilerplate(); | 9579 Top::context()->global_context()->arguments_boilerplate(); |
9370 JSFunction* arguments_function = | 9580 JSFunction* arguments_function = |
9371 JSFunction::cast(arguments_boilerplate->map()->constructor()); | 9581 JSFunction::cast(arguments_boilerplate->map()->constructor()); |
9372 | 9582 |
9373 // Get the number of referencing objects. | 9583 // Get the number of referencing objects. |
9374 int count; | 9584 int count; |
9375 count = DebugReferencedBy(target, instance_filter, max_references, | 9585 count = DebugReferencedBy(target, instance_filter, max_references, |
9376 NULL, 0, arguments_function); | 9586 NULL, 0, arguments_function); |
9377 | 9587 |
9378 // Allocate an array to hold the result. | 9588 // Allocate an array to hold the result. |
9379 Object* object = Heap::AllocateFixedArray(count); | 9589 Object* object; |
9380 if (object->IsFailure()) return object; | 9590 { MaybeObject* maybe_object = Heap::AllocateFixedArray(count); |
| 9591 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 9592 } |
9381 FixedArray* instances = FixedArray::cast(object); | 9593 FixedArray* instances = FixedArray::cast(object); |
9382 | 9594 |
9383 // Fill the referencing objects. | 9595 // Fill the referencing objects. |
9384 count = DebugReferencedBy(target, instance_filter, max_references, | 9596 count = DebugReferencedBy(target, instance_filter, max_references, |
9385 instances, count, arguments_function); | 9597 instances, count, arguments_function); |
9386 | 9598 |
9387 // Return result as JS array. | 9599 // Return result as JS array. |
9388 Object* result = | 9600 Object* result; |
9389 Heap::AllocateJSObject( | 9601 { MaybeObject* maybe_result = Heap::AllocateJSObject( |
9390 Top::context()->global_context()->array_function()); | 9602 Top::context()->global_context()->array_function()); |
9391 if (!result->IsFailure()) JSArray::cast(result)->SetContent(instances); | 9603 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 9604 } |
| 9605 JSArray::cast(result)->SetContent(instances); |
9392 return result; | 9606 return result; |
9393 } | 9607 } |
9394 | 9608 |
9395 | 9609 |
9396 // Helper function used by Runtime_DebugConstructedBy below. | 9610 // Helper function used by Runtime_DebugConstructedBy below. |
9397 static int DebugConstructedBy(JSFunction* constructor, int max_references, | 9611 static int DebugConstructedBy(JSFunction* constructor, int max_references, |
9398 FixedArray* instances, int instances_size) { | 9612 FixedArray* instances, int instances_size) { |
9399 AssertNoAllocation no_alloc; | 9613 AssertNoAllocation no_alloc; |
9400 | 9614 |
9401 // Iterate the heap. | 9615 // Iterate the heap. |
(...skipping 17 matching lines...) Expand all Loading... |
9419 } | 9633 } |
9420 | 9634 |
9421 // Return the number of referencing objects found. | 9635 // Return the number of referencing objects found. |
9422 return count; | 9636 return count; |
9423 } | 9637 } |
9424 | 9638 |
9425 | 9639 |
9426 // Scan the heap for objects constructed by a specific function. | 9640 // Scan the heap for objects constructed by a specific function. |
9427 // args[0]: the constructor to find instances of | 9641 // args[0]: the constructor to find instances of |
9428 // args[1]: the the maximum number of objects to return | 9642 // args[1]: the the maximum number of objects to return |
9429 static Object* Runtime_DebugConstructedBy(Arguments args) { | 9643 static MaybeObject* Runtime_DebugConstructedBy(Arguments args) { |
9430 ASSERT(args.length() == 2); | 9644 ASSERT(args.length() == 2); |
9431 | 9645 |
9432 // First perform a full GC in order to avoid dead objects. | 9646 // First perform a full GC in order to avoid dead objects. |
9433 Heap::CollectAllGarbage(false); | 9647 Heap::CollectAllGarbage(false); |
9434 | 9648 |
9435 // Check parameters. | 9649 // Check parameters. |
9436 CONVERT_CHECKED(JSFunction, constructor, args[0]); | 9650 CONVERT_CHECKED(JSFunction, constructor, args[0]); |
9437 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]); | 9651 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]); |
9438 RUNTIME_ASSERT(max_references >= 0); | 9652 RUNTIME_ASSERT(max_references >= 0); |
9439 | 9653 |
9440 // Get the number of referencing objects. | 9654 // Get the number of referencing objects. |
9441 int count; | 9655 int count; |
9442 count = DebugConstructedBy(constructor, max_references, NULL, 0); | 9656 count = DebugConstructedBy(constructor, max_references, NULL, 0); |
9443 | 9657 |
9444 // Allocate an array to hold the result. | 9658 // Allocate an array to hold the result. |
9445 Object* object = Heap::AllocateFixedArray(count); | 9659 Object* object; |
9446 if (object->IsFailure()) return object; | 9660 { MaybeObject* maybe_object = Heap::AllocateFixedArray(count); |
| 9661 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 9662 } |
9447 FixedArray* instances = FixedArray::cast(object); | 9663 FixedArray* instances = FixedArray::cast(object); |
9448 | 9664 |
9449 // Fill the referencing objects. | 9665 // Fill the referencing objects. |
9450 count = DebugConstructedBy(constructor, max_references, instances, count); | 9666 count = DebugConstructedBy(constructor, max_references, instances, count); |
9451 | 9667 |
9452 // Return result as JS array. | 9668 // Return result as JS array. |
9453 Object* result = | 9669 Object* result; |
9454 Heap::AllocateJSObject( | 9670 { MaybeObject* maybe_result = Heap::AllocateJSObject( |
9455 Top::context()->global_context()->array_function()); | 9671 Top::context()->global_context()->array_function()); |
9456 if (!result->IsFailure()) JSArray::cast(result)->SetContent(instances); | 9672 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 9673 } |
| 9674 JSArray::cast(result)->SetContent(instances); |
9457 return result; | 9675 return result; |
9458 } | 9676 } |
9459 | 9677 |
9460 | 9678 |
9461 // Find the effective prototype object as returned by __proto__. | 9679 // Find the effective prototype object as returned by __proto__. |
9462 // args[0]: the object to find the prototype for. | 9680 // args[0]: the object to find the prototype for. |
9463 static Object* Runtime_DebugGetPrototype(Arguments args) { | 9681 static MaybeObject* Runtime_DebugGetPrototype(Arguments args) { |
9464 ASSERT(args.length() == 1); | 9682 ASSERT(args.length() == 1); |
9465 | 9683 |
9466 CONVERT_CHECKED(JSObject, obj, args[0]); | 9684 CONVERT_CHECKED(JSObject, obj, args[0]); |
9467 | 9685 |
9468 // Use the __proto__ accessor. | 9686 // Use the __proto__ accessor. |
9469 return Accessors::ObjectPrototype.getter(obj, NULL); | 9687 return Accessors::ObjectPrototype.getter(obj, NULL); |
9470 } | 9688 } |
9471 | 9689 |
9472 | 9690 |
9473 static Object* Runtime_SystemBreak(Arguments args) { | 9691 static MaybeObject* Runtime_SystemBreak(Arguments args) { |
9474 ASSERT(args.length() == 0); | 9692 ASSERT(args.length() == 0); |
9475 CPU::DebugBreak(); | 9693 CPU::DebugBreak(); |
9476 return Heap::undefined_value(); | 9694 return Heap::undefined_value(); |
9477 } | 9695 } |
9478 | 9696 |
9479 | 9697 |
9480 static Object* Runtime_DebugDisassembleFunction(Arguments args) { | 9698 static MaybeObject* Runtime_DebugDisassembleFunction(Arguments args) { |
9481 #ifdef DEBUG | 9699 #ifdef DEBUG |
9482 HandleScope scope; | 9700 HandleScope scope; |
9483 ASSERT(args.length() == 1); | 9701 ASSERT(args.length() == 1); |
9484 // Get the function and make sure it is compiled. | 9702 // Get the function and make sure it is compiled. |
9485 CONVERT_ARG_CHECKED(JSFunction, func, 0); | 9703 CONVERT_ARG_CHECKED(JSFunction, func, 0); |
9486 Handle<SharedFunctionInfo> shared(func->shared()); | 9704 Handle<SharedFunctionInfo> shared(func->shared()); |
9487 if (!EnsureCompiled(shared, KEEP_EXCEPTION)) { | 9705 if (!EnsureCompiled(shared, KEEP_EXCEPTION)) { |
9488 return Failure::Exception(); | 9706 return Failure::Exception(); |
9489 } | 9707 } |
9490 func->code()->PrintLn(); | 9708 func->code()->PrintLn(); |
9491 #endif // DEBUG | 9709 #endif // DEBUG |
9492 return Heap::undefined_value(); | 9710 return Heap::undefined_value(); |
9493 } | 9711 } |
9494 | 9712 |
9495 | 9713 |
9496 static Object* Runtime_DebugDisassembleConstructor(Arguments args) { | 9714 static MaybeObject* Runtime_DebugDisassembleConstructor(Arguments args) { |
9497 #ifdef DEBUG | 9715 #ifdef DEBUG |
9498 HandleScope scope; | 9716 HandleScope scope; |
9499 ASSERT(args.length() == 1); | 9717 ASSERT(args.length() == 1); |
9500 // Get the function and make sure it is compiled. | 9718 // Get the function and make sure it is compiled. |
9501 CONVERT_ARG_CHECKED(JSFunction, func, 0); | 9719 CONVERT_ARG_CHECKED(JSFunction, func, 0); |
9502 Handle<SharedFunctionInfo> shared(func->shared()); | 9720 Handle<SharedFunctionInfo> shared(func->shared()); |
9503 if (!EnsureCompiled(shared, KEEP_EXCEPTION)) { | 9721 if (!EnsureCompiled(shared, KEEP_EXCEPTION)) { |
9504 return Failure::Exception(); | 9722 return Failure::Exception(); |
9505 } | 9723 } |
9506 shared->construct_stub()->PrintLn(); | 9724 shared->construct_stub()->PrintLn(); |
9507 #endif // DEBUG | 9725 #endif // DEBUG |
9508 return Heap::undefined_value(); | 9726 return Heap::undefined_value(); |
9509 } | 9727 } |
9510 | 9728 |
9511 | 9729 |
9512 static Object* Runtime_FunctionGetInferredName(Arguments args) { | 9730 static MaybeObject* Runtime_FunctionGetInferredName(Arguments args) { |
9513 NoHandleAllocation ha; | 9731 NoHandleAllocation ha; |
9514 ASSERT(args.length() == 1); | 9732 ASSERT(args.length() == 1); |
9515 | 9733 |
9516 CONVERT_CHECKED(JSFunction, f, args[0]); | 9734 CONVERT_CHECKED(JSFunction, f, args[0]); |
9517 return f->shared()->inferred_name(); | 9735 return f->shared()->inferred_name(); |
9518 } | 9736 } |
9519 | 9737 |
9520 | 9738 |
9521 static int FindSharedFunctionInfosForScript(Script* script, | 9739 static int FindSharedFunctionInfosForScript(Script* script, |
9522 FixedArray* buffer) { | 9740 FixedArray* buffer) { |
(...skipping 15 matching lines...) Expand all Loading... |
9538 buffer->set(counter, shared); | 9756 buffer->set(counter, shared); |
9539 } | 9757 } |
9540 counter++; | 9758 counter++; |
9541 } | 9759 } |
9542 return counter; | 9760 return counter; |
9543 } | 9761 } |
9544 | 9762 |
9545 // For a script finds all SharedFunctionInfo's in the heap that points | 9763 // For a script finds all SharedFunctionInfo's in the heap that points |
9546 // to this script. Returns JSArray of SharedFunctionInfo wrapped | 9764 // to this script. Returns JSArray of SharedFunctionInfo wrapped |
9547 // in OpaqueReferences. | 9765 // in OpaqueReferences. |
9548 static Object* Runtime_LiveEditFindSharedFunctionInfosForScript( | 9766 static MaybeObject* Runtime_LiveEditFindSharedFunctionInfosForScript( |
9549 Arguments args) { | 9767 Arguments args) { |
9550 ASSERT(args.length() == 1); | 9768 ASSERT(args.length() == 1); |
9551 HandleScope scope; | 9769 HandleScope scope; |
9552 CONVERT_CHECKED(JSValue, script_value, args[0]); | 9770 CONVERT_CHECKED(JSValue, script_value, args[0]); |
9553 | 9771 |
9554 Handle<Script> script = Handle<Script>(Script::cast(script_value->value())); | 9772 Handle<Script> script = Handle<Script>(Script::cast(script_value->value())); |
9555 | 9773 |
9556 const int kBufferSize = 32; | 9774 const int kBufferSize = 32; |
9557 | 9775 |
9558 Handle<FixedArray> array; | 9776 Handle<FixedArray> array; |
(...skipping 12 matching lines...) Expand all Loading... |
9571 return *result; | 9789 return *result; |
9572 } | 9790 } |
9573 | 9791 |
9574 // For a script calculates compilation information about all its functions. | 9792 // For a script calculates compilation information about all its functions. |
9575 // The script source is explicitly specified by the second argument. | 9793 // The script source is explicitly specified by the second argument. |
9576 // The source of the actual script is not used, however it is important that | 9794 // The source of the actual script is not used, however it is important that |
9577 // all generated code keeps references to this particular instance of script. | 9795 // all generated code keeps references to this particular instance of script. |
9578 // Returns a JSArray of compilation infos. The array is ordered so that | 9796 // Returns a JSArray of compilation infos. The array is ordered so that |
9579 // each function with all its descendant is always stored in a continues range | 9797 // each function with all its descendant is always stored in a continues range |
9580 // with the function itself going first. The root function is a script function. | 9798 // with the function itself going first. The root function is a script function. |
9581 static Object* Runtime_LiveEditGatherCompileInfo(Arguments args) { | 9799 static MaybeObject* Runtime_LiveEditGatherCompileInfo(Arguments args) { |
9582 ASSERT(args.length() == 2); | 9800 ASSERT(args.length() == 2); |
9583 HandleScope scope; | 9801 HandleScope scope; |
9584 CONVERT_CHECKED(JSValue, script, args[0]); | 9802 CONVERT_CHECKED(JSValue, script, args[0]); |
9585 CONVERT_ARG_CHECKED(String, source, 1); | 9803 CONVERT_ARG_CHECKED(String, source, 1); |
9586 Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); | 9804 Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); |
9587 | 9805 |
9588 JSArray* result = LiveEdit::GatherCompileInfo(script_handle, source); | 9806 JSArray* result = LiveEdit::GatherCompileInfo(script_handle, source); |
9589 | 9807 |
9590 if (Top::has_pending_exception()) { | 9808 if (Top::has_pending_exception()) { |
9591 return Failure::Exception(); | 9809 return Failure::Exception(); |
9592 } | 9810 } |
9593 | 9811 |
9594 return result; | 9812 return result; |
9595 } | 9813 } |
9596 | 9814 |
9597 // Changes the source of the script to a new_source. | 9815 // Changes the source of the script to a new_source. |
9598 // If old_script_name is provided (i.e. is a String), also creates a copy of | 9816 // If old_script_name is provided (i.e. is a String), also creates a copy of |
9599 // the script with its original source and sends notification to debugger. | 9817 // the script with its original source and sends notification to debugger. |
9600 static Object* Runtime_LiveEditReplaceScript(Arguments args) { | 9818 static MaybeObject* Runtime_LiveEditReplaceScript(Arguments args) { |
9601 ASSERT(args.length() == 3); | 9819 ASSERT(args.length() == 3); |
9602 HandleScope scope; | 9820 HandleScope scope; |
9603 CONVERT_CHECKED(JSValue, original_script_value, args[0]); | 9821 CONVERT_CHECKED(JSValue, original_script_value, args[0]); |
9604 CONVERT_ARG_CHECKED(String, new_source, 1); | 9822 CONVERT_ARG_CHECKED(String, new_source, 1); |
9605 Handle<Object> old_script_name(args[2]); | 9823 Handle<Object> old_script_name(args[2]); |
9606 | 9824 |
9607 CONVERT_CHECKED(Script, original_script_pointer, | 9825 CONVERT_CHECKED(Script, original_script_pointer, |
9608 original_script_value->value()); | 9826 original_script_value->value()); |
9609 Handle<Script> original_script(original_script_pointer); | 9827 Handle<Script> original_script(original_script_pointer); |
9610 | 9828 |
9611 Object* old_script = LiveEdit::ChangeScriptSource(original_script, | 9829 Object* old_script = LiveEdit::ChangeScriptSource(original_script, |
9612 new_source, | 9830 new_source, |
9613 old_script_name); | 9831 old_script_name); |
9614 | 9832 |
9615 if (old_script->IsScript()) { | 9833 if (old_script->IsScript()) { |
9616 Handle<Script> script_handle(Script::cast(old_script)); | 9834 Handle<Script> script_handle(Script::cast(old_script)); |
9617 return *(GetScriptWrapper(script_handle)); | 9835 return *(GetScriptWrapper(script_handle)); |
9618 } else { | 9836 } else { |
9619 return Heap::null_value(); | 9837 return Heap::null_value(); |
9620 } | 9838 } |
9621 } | 9839 } |
9622 | 9840 |
9623 // Replaces code of SharedFunctionInfo with a new one. | 9841 // Replaces code of SharedFunctionInfo with a new one. |
9624 static Object* Runtime_LiveEditReplaceFunctionCode(Arguments args) { | 9842 static MaybeObject* Runtime_LiveEditReplaceFunctionCode(Arguments args) { |
9625 ASSERT(args.length() == 2); | 9843 ASSERT(args.length() == 2); |
9626 HandleScope scope; | 9844 HandleScope scope; |
9627 CONVERT_ARG_CHECKED(JSArray, new_compile_info, 0); | 9845 CONVERT_ARG_CHECKED(JSArray, new_compile_info, 0); |
9628 CONVERT_ARG_CHECKED(JSArray, shared_info, 1); | 9846 CONVERT_ARG_CHECKED(JSArray, shared_info, 1); |
9629 | 9847 |
9630 return LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info); | 9848 return LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info); |
9631 } | 9849 } |
9632 | 9850 |
9633 // Connects SharedFunctionInfo to another script. | 9851 // Connects SharedFunctionInfo to another script. |
9634 static Object* Runtime_LiveEditFunctionSetScript(Arguments args) { | 9852 static MaybeObject* Runtime_LiveEditFunctionSetScript(Arguments args) { |
9635 ASSERT(args.length() == 2); | 9853 ASSERT(args.length() == 2); |
9636 HandleScope scope; | 9854 HandleScope scope; |
9637 Handle<Object> function_object(args[0]); | 9855 Handle<Object> function_object(args[0]); |
9638 Handle<Object> script_object(args[1]); | 9856 Handle<Object> script_object(args[1]); |
9639 | 9857 |
9640 if (function_object->IsJSValue()) { | 9858 if (function_object->IsJSValue()) { |
9641 Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object); | 9859 Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object); |
9642 if (script_object->IsJSValue()) { | 9860 if (script_object->IsJSValue()) { |
9643 CONVERT_CHECKED(Script, script, JSValue::cast(*script_object)->value()); | 9861 CONVERT_CHECKED(Script, script, JSValue::cast(*script_object)->value()); |
9644 script_object = Handle<Object>(script); | 9862 script_object = Handle<Object>(script); |
9645 } | 9863 } |
9646 | 9864 |
9647 LiveEdit::SetFunctionScript(function_wrapper, script_object); | 9865 LiveEdit::SetFunctionScript(function_wrapper, script_object); |
9648 } else { | 9866 } else { |
9649 // Just ignore this. We may not have a SharedFunctionInfo for some functions | 9867 // Just ignore this. We may not have a SharedFunctionInfo for some functions |
9650 // and we check it in this function. | 9868 // and we check it in this function. |
9651 } | 9869 } |
9652 | 9870 |
9653 return Heap::undefined_value(); | 9871 return Heap::undefined_value(); |
9654 } | 9872 } |
9655 | 9873 |
9656 | 9874 |
9657 // In a code of a parent function replaces original function as embedded object | 9875 // In a code of a parent function replaces original function as embedded object |
9658 // with a substitution one. | 9876 // with a substitution one. |
9659 static Object* Runtime_LiveEditReplaceRefToNestedFunction(Arguments args) { | 9877 static MaybeObject* Runtime_LiveEditReplaceRefToNestedFunction(Arguments args) { |
9660 ASSERT(args.length() == 3); | 9878 ASSERT(args.length() == 3); |
9661 HandleScope scope; | 9879 HandleScope scope; |
9662 | 9880 |
9663 CONVERT_ARG_CHECKED(JSValue, parent_wrapper, 0); | 9881 CONVERT_ARG_CHECKED(JSValue, parent_wrapper, 0); |
9664 CONVERT_ARG_CHECKED(JSValue, orig_wrapper, 1); | 9882 CONVERT_ARG_CHECKED(JSValue, orig_wrapper, 1); |
9665 CONVERT_ARG_CHECKED(JSValue, subst_wrapper, 2); | 9883 CONVERT_ARG_CHECKED(JSValue, subst_wrapper, 2); |
9666 | 9884 |
9667 LiveEdit::ReplaceRefToNestedFunction(parent_wrapper, orig_wrapper, | 9885 LiveEdit::ReplaceRefToNestedFunction(parent_wrapper, orig_wrapper, |
9668 subst_wrapper); | 9886 subst_wrapper); |
9669 | 9887 |
9670 return Heap::undefined_value(); | 9888 return Heap::undefined_value(); |
9671 } | 9889 } |
9672 | 9890 |
9673 | 9891 |
9674 // Updates positions of a shared function info (first parameter) according | 9892 // Updates positions of a shared function info (first parameter) according |
9675 // to script source change. Text change is described in second parameter as | 9893 // to script source change. Text change is described in second parameter as |
9676 // array of groups of 3 numbers: | 9894 // array of groups of 3 numbers: |
9677 // (change_begin, change_end, change_end_new_position). | 9895 // (change_begin, change_end, change_end_new_position). |
9678 // Each group describes a change in text; groups are sorted by change_begin. | 9896 // Each group describes a change in text; groups are sorted by change_begin. |
9679 static Object* Runtime_LiveEditPatchFunctionPositions(Arguments args) { | 9897 static MaybeObject* Runtime_LiveEditPatchFunctionPositions(Arguments args) { |
9680 ASSERT(args.length() == 2); | 9898 ASSERT(args.length() == 2); |
9681 HandleScope scope; | 9899 HandleScope scope; |
9682 CONVERT_ARG_CHECKED(JSArray, shared_array, 0); | 9900 CONVERT_ARG_CHECKED(JSArray, shared_array, 0); |
9683 CONVERT_ARG_CHECKED(JSArray, position_change_array, 1); | 9901 CONVERT_ARG_CHECKED(JSArray, position_change_array, 1); |
9684 | 9902 |
9685 return LiveEdit::PatchFunctionPositions(shared_array, position_change_array); | 9903 return LiveEdit::PatchFunctionPositions(shared_array, position_change_array); |
9686 } | 9904 } |
9687 | 9905 |
9688 | 9906 |
9689 // For array of SharedFunctionInfo's (each wrapped in JSValue) | 9907 // For array of SharedFunctionInfo's (each wrapped in JSValue) |
9690 // checks that none of them have activations on stacks (of any thread). | 9908 // checks that none of them have activations on stacks (of any thread). |
9691 // Returns array of the same length with corresponding results of | 9909 // Returns array of the same length with corresponding results of |
9692 // LiveEdit::FunctionPatchabilityStatus type. | 9910 // LiveEdit::FunctionPatchabilityStatus type. |
9693 static Object* Runtime_LiveEditCheckAndDropActivations(Arguments args) { | 9911 static MaybeObject* Runtime_LiveEditCheckAndDropActivations(Arguments args) { |
9694 ASSERT(args.length() == 2); | 9912 ASSERT(args.length() == 2); |
9695 HandleScope scope; | 9913 HandleScope scope; |
9696 CONVERT_ARG_CHECKED(JSArray, shared_array, 0); | 9914 CONVERT_ARG_CHECKED(JSArray, shared_array, 0); |
9697 CONVERT_BOOLEAN_CHECKED(do_drop, args[1]); | 9915 CONVERT_BOOLEAN_CHECKED(do_drop, args[1]); |
9698 | 9916 |
9699 return *LiveEdit::CheckAndDropActivations(shared_array, do_drop); | 9917 return *LiveEdit::CheckAndDropActivations(shared_array, do_drop); |
9700 } | 9918 } |
9701 | 9919 |
9702 // Compares 2 strings line-by-line and returns diff in form of JSArray of | 9920 // Compares 2 strings line-by-line and returns diff in form of JSArray of |
9703 // triplets (pos1, pos1_end, pos2_end) describing list of diff chunks. | 9921 // triplets (pos1, pos1_end, pos2_end) describing list of diff chunks. |
9704 static Object* Runtime_LiveEditCompareStringsLinewise(Arguments args) { | 9922 static MaybeObject* Runtime_LiveEditCompareStringsLinewise(Arguments args) { |
9705 ASSERT(args.length() == 2); | 9923 ASSERT(args.length() == 2); |
9706 HandleScope scope; | 9924 HandleScope scope; |
9707 CONVERT_ARG_CHECKED(String, s1, 0); | 9925 CONVERT_ARG_CHECKED(String, s1, 0); |
9708 CONVERT_ARG_CHECKED(String, s2, 1); | 9926 CONVERT_ARG_CHECKED(String, s2, 1); |
9709 | 9927 |
9710 return *LiveEdit::CompareStringsLinewise(s1, s2); | 9928 return *LiveEdit::CompareStringsLinewise(s1, s2); |
9711 } | 9929 } |
9712 | 9930 |
9713 | 9931 |
9714 | 9932 |
9715 // A testing entry. Returns statement position which is the closest to | 9933 // A testing entry. Returns statement position which is the closest to |
9716 // source_position. | 9934 // source_position. |
9717 static Object* Runtime_GetFunctionCodePositionFromSource(Arguments args) { | 9935 static MaybeObject* Runtime_GetFunctionCodePositionFromSource(Arguments args) { |
9718 ASSERT(args.length() == 2); | 9936 ASSERT(args.length() == 2); |
9719 HandleScope scope; | 9937 HandleScope scope; |
9720 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 9938 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
9721 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); | 9939 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); |
9722 | 9940 |
9723 Handle<Code> code(function->code()); | 9941 Handle<Code> code(function->code()); |
9724 | 9942 |
9725 RelocIterator it(*code, 1 << RelocInfo::STATEMENT_POSITION); | 9943 RelocIterator it(*code, 1 << RelocInfo::STATEMENT_POSITION); |
9726 int closest_pc = 0; | 9944 int closest_pc = 0; |
9727 int distance = kMaxInt; | 9945 int distance = kMaxInt; |
(...skipping 11 matching lines...) Expand all Loading... |
9739 it.next(); | 9957 it.next(); |
9740 } | 9958 } |
9741 | 9959 |
9742 return Smi::FromInt(closest_pc); | 9960 return Smi::FromInt(closest_pc); |
9743 } | 9961 } |
9744 | 9962 |
9745 | 9963 |
9746 // Calls specified function with or without entering the debugger. | 9964 // Calls specified function with or without entering the debugger. |
9747 // This is used in unit tests to run code as if debugger is entered or simply | 9965 // This is used in unit tests to run code as if debugger is entered or simply |
9748 // to have a stack with C++ frame in the middle. | 9966 // to have a stack with C++ frame in the middle. |
9749 static Object* Runtime_ExecuteInDebugContext(Arguments args) { | 9967 static MaybeObject* Runtime_ExecuteInDebugContext(Arguments args) { |
9750 ASSERT(args.length() == 2); | 9968 ASSERT(args.length() == 2); |
9751 HandleScope scope; | 9969 HandleScope scope; |
9752 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 9970 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
9753 CONVERT_BOOLEAN_CHECKED(without_debugger, args[1]); | 9971 CONVERT_BOOLEAN_CHECKED(without_debugger, args[1]); |
9754 | 9972 |
9755 Handle<Object> result; | 9973 Handle<Object> result; |
9756 bool pending_exception; | 9974 bool pending_exception; |
9757 { | 9975 { |
9758 if (without_debugger) { | 9976 if (without_debugger) { |
9759 result = Execution::Call(function, Top::global(), 0, NULL, | 9977 result = Execution::Call(function, Top::global(), 0, NULL, |
9760 &pending_exception); | 9978 &pending_exception); |
9761 } else { | 9979 } else { |
9762 EnterDebugger enter_debugger; | 9980 EnterDebugger enter_debugger; |
9763 result = Execution::Call(function, Top::global(), 0, NULL, | 9981 result = Execution::Call(function, Top::global(), 0, NULL, |
9764 &pending_exception); | 9982 &pending_exception); |
9765 } | 9983 } |
9766 } | 9984 } |
9767 if (!pending_exception) { | 9985 if (!pending_exception) { |
9768 return *result; | 9986 return *result; |
9769 } else { | 9987 } else { |
9770 return Failure::Exception(); | 9988 return Failure::Exception(); |
9771 } | 9989 } |
9772 } | 9990 } |
9773 | 9991 |
9774 | 9992 |
9775 #endif // ENABLE_DEBUGGER_SUPPORT | 9993 #endif // ENABLE_DEBUGGER_SUPPORT |
9776 | 9994 |
9777 #ifdef ENABLE_LOGGING_AND_PROFILING | 9995 #ifdef ENABLE_LOGGING_AND_PROFILING |
9778 | 9996 |
9779 static Object* Runtime_ProfilerResume(Arguments args) { | 9997 static MaybeObject* Runtime_ProfilerResume(Arguments args) { |
9780 NoHandleAllocation ha; | 9998 NoHandleAllocation ha; |
9781 ASSERT(args.length() == 2); | 9999 ASSERT(args.length() == 2); |
9782 | 10000 |
9783 CONVERT_CHECKED(Smi, smi_modules, args[0]); | 10001 CONVERT_CHECKED(Smi, smi_modules, args[0]); |
9784 CONVERT_CHECKED(Smi, smi_tag, args[1]); | 10002 CONVERT_CHECKED(Smi, smi_tag, args[1]); |
9785 v8::V8::ResumeProfilerEx(smi_modules->value(), smi_tag->value()); | 10003 v8::V8::ResumeProfilerEx(smi_modules->value(), smi_tag->value()); |
9786 return Heap::undefined_value(); | 10004 return Heap::undefined_value(); |
9787 } | 10005 } |
9788 | 10006 |
9789 | 10007 |
9790 static Object* Runtime_ProfilerPause(Arguments args) { | 10008 static MaybeObject* Runtime_ProfilerPause(Arguments args) { |
9791 NoHandleAllocation ha; | 10009 NoHandleAllocation ha; |
9792 ASSERT(args.length() == 2); | 10010 ASSERT(args.length() == 2); |
9793 | 10011 |
9794 CONVERT_CHECKED(Smi, smi_modules, args[0]); | 10012 CONVERT_CHECKED(Smi, smi_modules, args[0]); |
9795 CONVERT_CHECKED(Smi, smi_tag, args[1]); | 10013 CONVERT_CHECKED(Smi, smi_tag, args[1]); |
9796 v8::V8::PauseProfilerEx(smi_modules->value(), smi_tag->value()); | 10014 v8::V8::PauseProfilerEx(smi_modules->value(), smi_tag->value()); |
9797 return Heap::undefined_value(); | 10015 return Heap::undefined_value(); |
9798 } | 10016 } |
9799 | 10017 |
9800 #endif // ENABLE_LOGGING_AND_PROFILING | 10018 #endif // ENABLE_LOGGING_AND_PROFILING |
(...skipping 26 matching lines...) Expand all Loading... |
9827 if (script.is_null()) return Factory::undefined_value(); | 10045 if (script.is_null()) return Factory::undefined_value(); |
9828 | 10046 |
9829 // Return the script found. | 10047 // Return the script found. |
9830 return GetScriptWrapper(script); | 10048 return GetScriptWrapper(script); |
9831 } | 10049 } |
9832 | 10050 |
9833 | 10051 |
9834 // Get the script object from script data. NOTE: Regarding performance | 10052 // Get the script object from script data. NOTE: Regarding performance |
9835 // see the NOTE for GetScriptFromScriptData. | 10053 // see the NOTE for GetScriptFromScriptData. |
9836 // args[0]: script data for the script to find the source for | 10054 // args[0]: script data for the script to find the source for |
9837 static Object* Runtime_GetScript(Arguments args) { | 10055 static MaybeObject* Runtime_GetScript(Arguments args) { |
9838 HandleScope scope; | 10056 HandleScope scope; |
9839 | 10057 |
9840 ASSERT(args.length() == 1); | 10058 ASSERT(args.length() == 1); |
9841 | 10059 |
9842 CONVERT_CHECKED(String, script_name, args[0]); | 10060 CONVERT_CHECKED(String, script_name, args[0]); |
9843 | 10061 |
9844 // Find the requested script. | 10062 // Find the requested script. |
9845 Handle<Object> result = | 10063 Handle<Object> result = |
9846 Runtime_GetScriptFromScriptName(Handle<String>(script_name)); | 10064 Runtime_GetScriptFromScriptName(Handle<String>(script_name)); |
9847 return *result; | 10065 return *result; |
(...skipping 24 matching lines...) Expand all Loading... |
9872 // obvious builtin calls. Some builtin calls (such as Number.ADD | 10090 // obvious builtin calls. Some builtin calls (such as Number.ADD |
9873 // which is invoked using 'call') are very difficult to recognize | 10091 // which is invoked using 'call') are very difficult to recognize |
9874 // so we're leaving them in for now. | 10092 // so we're leaving them in for now. |
9875 return *seen_caller && !frame->receiver()->IsJSBuiltinsObject(); | 10093 return *seen_caller && !frame->receiver()->IsJSBuiltinsObject(); |
9876 } | 10094 } |
9877 | 10095 |
9878 | 10096 |
9879 // Collect the raw data for a stack trace. Returns an array of three | 10097 // Collect the raw data for a stack trace. Returns an array of three |
9880 // element segments each containing a receiver, function and native | 10098 // element segments each containing a receiver, function and native |
9881 // code offset. | 10099 // code offset. |
9882 static Object* Runtime_CollectStackTrace(Arguments args) { | 10100 static MaybeObject* Runtime_CollectStackTrace(Arguments args) { |
9883 ASSERT_EQ(args.length(), 2); | 10101 ASSERT_EQ(args.length(), 2); |
9884 Handle<Object> caller = args.at<Object>(0); | 10102 Handle<Object> caller = args.at<Object>(0); |
9885 CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[1]); | 10103 CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[1]); |
9886 | 10104 |
9887 HandleScope scope; | 10105 HandleScope scope; |
9888 | 10106 |
9889 limit = Max(limit, 0); // Ensure that limit is not negative. | 10107 limit = Max(limit, 0); // Ensure that limit is not negative. |
9890 int initial_size = Min(limit, 10); | 10108 int initial_size = Min(limit, 10); |
9891 Handle<JSArray> result = Factory::NewJSArray(initial_size * 3); | 10109 Handle<JSArray> result = Factory::NewJSArray(initial_size * 3); |
9892 | 10110 |
(...skipping 29 matching lines...) Expand all Loading... |
9922 } | 10140 } |
9923 iter.Advance(); | 10141 iter.Advance(); |
9924 } | 10142 } |
9925 | 10143 |
9926 result->set_length(Smi::FromInt(cursor)); | 10144 result->set_length(Smi::FromInt(cursor)); |
9927 return *result; | 10145 return *result; |
9928 } | 10146 } |
9929 | 10147 |
9930 | 10148 |
9931 // Returns V8 version as a string. | 10149 // Returns V8 version as a string. |
9932 static Object* Runtime_GetV8Version(Arguments args) { | 10150 static MaybeObject* Runtime_GetV8Version(Arguments args) { |
9933 ASSERT_EQ(args.length(), 0); | 10151 ASSERT_EQ(args.length(), 0); |
9934 | 10152 |
9935 NoHandleAllocation ha; | 10153 NoHandleAllocation ha; |
9936 | 10154 |
9937 const char* version_string = v8::V8::GetVersion(); | 10155 const char* version_string = v8::V8::GetVersion(); |
9938 | 10156 |
9939 return Heap::AllocateStringFromAscii(CStrVector(version_string), NOT_TENURED); | 10157 return Heap::AllocateStringFromAscii(CStrVector(version_string), NOT_TENURED); |
9940 } | 10158 } |
9941 | 10159 |
9942 | 10160 |
9943 static Object* Runtime_Abort(Arguments args) { | 10161 static MaybeObject* Runtime_Abort(Arguments args) { |
9944 ASSERT(args.length() == 2); | 10162 ASSERT(args.length() == 2); |
9945 OS::PrintError("abort: %s\n", reinterpret_cast<char*>(args[0]) + | 10163 OS::PrintError("abort: %s\n", reinterpret_cast<char*>(args[0]) + |
9946 Smi::cast(args[1])->value()); | 10164 Smi::cast(args[1])->value()); |
9947 Top::PrintStack(); | 10165 Top::PrintStack(); |
9948 OS::Abort(); | 10166 OS::Abort(); |
9949 UNREACHABLE(); | 10167 UNREACHABLE(); |
9950 return NULL; | 10168 return NULL; |
9951 } | 10169 } |
9952 | 10170 |
9953 | 10171 |
9954 static Object* Runtime_DeleteHandleScopeExtensions(Arguments args) { | 10172 MUST_USE_RESULT static MaybeObject* CacheMiss(FixedArray* cache_obj, |
9955 ASSERT(args.length() == 0); | 10173 int index, |
9956 HandleScope::DeleteExtensions(); | 10174 Object* key_obj) { |
9957 return Heap::undefined_value(); | |
9958 } | |
9959 | |
9960 | |
9961 static Object* CacheMiss(FixedArray* cache_obj, int index, Object* key_obj) { | |
9962 ASSERT(index % 2 == 0); // index of the key | 10175 ASSERT(index % 2 == 0); // index of the key |
9963 ASSERT(index >= JSFunctionResultCache::kEntriesIndex); | 10176 ASSERT(index >= JSFunctionResultCache::kEntriesIndex); |
9964 ASSERT(index < cache_obj->length()); | 10177 ASSERT(index < cache_obj->length()); |
9965 | 10178 |
9966 HandleScope scope; | 10179 HandleScope scope; |
9967 | 10180 |
9968 Handle<FixedArray> cache(cache_obj); | 10181 Handle<FixedArray> cache(cache_obj); |
9969 Handle<Object> key(key_obj); | 10182 Handle<Object> key(key_obj); |
9970 Handle<JSFunction> factory(JSFunction::cast( | 10183 Handle<JSFunction> factory(JSFunction::cast( |
9971 cache->get(JSFunctionResultCache::kFactoryIndex))); | 10184 cache->get(JSFunctionResultCache::kFactoryIndex))); |
(...skipping 14 matching lines...) Expand all Loading... |
9986 } | 10199 } |
9987 | 10200 |
9988 cache->set(index, *key); | 10201 cache->set(index, *key); |
9989 cache->set(index + 1, *value); | 10202 cache->set(index + 1, *value); |
9990 cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(index)); | 10203 cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(index)); |
9991 | 10204 |
9992 return *value; | 10205 return *value; |
9993 } | 10206 } |
9994 | 10207 |
9995 | 10208 |
9996 static Object* Runtime_GetFromCache(Arguments args) { | 10209 static MaybeObject* Runtime_GetFromCache(Arguments args) { |
9997 // This is only called from codegen, so checks might be more lax. | 10210 // This is only called from codegen, so checks might be more lax. |
9998 CONVERT_CHECKED(FixedArray, cache, args[0]); | 10211 CONVERT_CHECKED(FixedArray, cache, args[0]); |
9999 Object* key = args[1]; | 10212 Object* key = args[1]; |
10000 | 10213 |
10001 const int finger_index = | 10214 const int finger_index = |
10002 Smi::cast(cache->get(JSFunctionResultCache::kFingerIndex))->value(); | 10215 Smi::cast(cache->get(JSFunctionResultCache::kFingerIndex))->value(); |
10003 | 10216 |
10004 Object* o = cache->get(finger_index); | 10217 Object* o = cache->get(finger_index); |
10005 if (o == key) { | 10218 if (o == key) { |
10006 // The fastest case: hit the same place again. | 10219 // The fastest case: hit the same place again. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10039 if (target_index == cache->length()) { | 10252 if (target_index == cache->length()) { |
10040 target_index = JSFunctionResultCache::kEntriesIndex; | 10253 target_index = JSFunctionResultCache::kEntriesIndex; |
10041 } | 10254 } |
10042 return CacheMiss(cache, target_index, key); | 10255 return CacheMiss(cache, target_index, key); |
10043 } | 10256 } |
10044 } | 10257 } |
10045 | 10258 |
10046 #ifdef DEBUG | 10259 #ifdef DEBUG |
10047 // ListNatives is ONLY used by the fuzz-natives.js in debug mode | 10260 // ListNatives is ONLY used by the fuzz-natives.js in debug mode |
10048 // Exclude the code in release mode. | 10261 // Exclude the code in release mode. |
10049 static Object* Runtime_ListNatives(Arguments args) { | 10262 static MaybeObject* Runtime_ListNatives(Arguments args) { |
10050 ASSERT(args.length() == 0); | 10263 ASSERT(args.length() == 0); |
10051 HandleScope scope; | 10264 HandleScope scope; |
10052 Handle<JSArray> result = Factory::NewJSArray(0); | 10265 Handle<JSArray> result = Factory::NewJSArray(0); |
10053 int index = 0; | 10266 int index = 0; |
10054 bool inline_runtime_functions = false; | 10267 bool inline_runtime_functions = false; |
10055 #define ADD_ENTRY(Name, argc, ressize) \ | 10268 #define ADD_ENTRY(Name, argc, ressize) \ |
10056 { \ | 10269 { \ |
10057 HandleScope inner; \ | 10270 HandleScope inner; \ |
10058 Handle<String> name; \ | 10271 Handle<String> name; \ |
10059 /* Inline runtime functions have an underscore in front of the name. */ \ | 10272 /* Inline runtime functions have an underscore in front of the name. */ \ |
(...skipping 13 matching lines...) Expand all Loading... |
10073 RUNTIME_FUNCTION_LIST(ADD_ENTRY) | 10286 RUNTIME_FUNCTION_LIST(ADD_ENTRY) |
10074 inline_runtime_functions = true; | 10287 inline_runtime_functions = true; |
10075 INLINE_FUNCTION_LIST(ADD_ENTRY) | 10288 INLINE_FUNCTION_LIST(ADD_ENTRY) |
10076 INLINE_RUNTIME_FUNCTION_LIST(ADD_ENTRY) | 10289 INLINE_RUNTIME_FUNCTION_LIST(ADD_ENTRY) |
10077 #undef ADD_ENTRY | 10290 #undef ADD_ENTRY |
10078 return *result; | 10291 return *result; |
10079 } | 10292 } |
10080 #endif | 10293 #endif |
10081 | 10294 |
10082 | 10295 |
10083 static Object* Runtime_Log(Arguments args) { | 10296 static MaybeObject* Runtime_Log(Arguments args) { |
10084 ASSERT(args.length() == 2); | 10297 ASSERT(args.length() == 2); |
10085 CONVERT_CHECKED(String, format, args[0]); | 10298 CONVERT_CHECKED(String, format, args[0]); |
10086 CONVERT_CHECKED(JSArray, elms, args[1]); | 10299 CONVERT_CHECKED(JSArray, elms, args[1]); |
10087 Vector<const char> chars = format->ToAsciiVector(); | 10300 Vector<const char> chars = format->ToAsciiVector(); |
10088 Logger::LogRuntime(chars, elms); | 10301 Logger::LogRuntime(chars, elms); |
10089 return Heap::undefined_value(); | 10302 return Heap::undefined_value(); |
10090 } | 10303 } |
10091 | 10304 |
10092 | 10305 |
10093 static Object* Runtime_IS_VAR(Arguments args) { | 10306 static MaybeObject* Runtime_IS_VAR(Arguments args) { |
10094 UNREACHABLE(); // implemented as macro in the parser | 10307 UNREACHABLE(); // implemented as macro in the parser |
10095 return NULL; | 10308 return NULL; |
10096 } | 10309 } |
10097 | 10310 |
10098 | 10311 |
10099 // ---------------------------------------------------------------------------- | 10312 // ---------------------------------------------------------------------------- |
10100 // Implementation of Runtime | 10313 // Implementation of Runtime |
10101 | 10314 |
10102 #define F(name, number_of_args, result_size) \ | 10315 #define F(name, number_of_args, result_size) \ |
10103 { Runtime::k##name, Runtime::RUNTIME, #name, \ | 10316 { Runtime::k##name, Runtime::RUNTIME, #name, \ |
10104 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size }, | 10317 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size }, |
10105 | 10318 |
10106 | 10319 |
10107 #define I(name, number_of_args, result_size) \ | 10320 #define I(name, number_of_args, result_size) \ |
10108 { Runtime::kInline##name, Runtime::INLINE, \ | 10321 { Runtime::kInline##name, Runtime::INLINE, \ |
10109 "_" #name, NULL, number_of_args, result_size }, | 10322 "_" #name, NULL, number_of_args, result_size }, |
10110 | 10323 |
10111 Runtime::Function kIntrinsicFunctions[] = { | 10324 Runtime::Function kIntrinsicFunctions[] = { |
10112 RUNTIME_FUNCTION_LIST(F) | 10325 RUNTIME_FUNCTION_LIST(F) |
10113 INLINE_FUNCTION_LIST(I) | 10326 INLINE_FUNCTION_LIST(I) |
10114 INLINE_RUNTIME_FUNCTION_LIST(I) | 10327 INLINE_RUNTIME_FUNCTION_LIST(I) |
10115 }; | 10328 }; |
10116 | 10329 |
10117 | 10330 |
10118 Object* Runtime::InitializeIntrinsicFunctionNames(Object* dictionary) { | 10331 MaybeObject* Runtime::InitializeIntrinsicFunctionNames(Object* dictionary) { |
10119 ASSERT(dictionary != NULL); | 10332 ASSERT(dictionary != NULL); |
10120 ASSERT(StringDictionary::cast(dictionary)->NumberOfElements() == 0); | 10333 ASSERT(StringDictionary::cast(dictionary)->NumberOfElements() == 0); |
10121 for (int i = 0; i < kNumFunctions; ++i) { | 10334 for (int i = 0; i < kNumFunctions; ++i) { |
10122 Object* name_symbol = Heap::LookupAsciiSymbol(kIntrinsicFunctions[i].name); | 10335 Object* name_symbol; |
10123 if (name_symbol->IsFailure()) return name_symbol; | 10336 { MaybeObject* maybe_name_symbol = |
| 10337 Heap::LookupAsciiSymbol(kIntrinsicFunctions[i].name); |
| 10338 if (!maybe_name_symbol->ToObject(&name_symbol)) return maybe_name_symbol; |
| 10339 } |
10124 StringDictionary* string_dictionary = StringDictionary::cast(dictionary); | 10340 StringDictionary* string_dictionary = StringDictionary::cast(dictionary); |
10125 dictionary = string_dictionary->Add(String::cast(name_symbol), | 10341 { MaybeObject* maybe_dictionary = string_dictionary->Add( |
10126 Smi::FromInt(i), | 10342 String::cast(name_symbol), |
10127 PropertyDetails(NONE, NORMAL)); | 10343 Smi::FromInt(i), |
10128 // Non-recoverable failure. Calling code must restart heap initialization. | 10344 PropertyDetails(NONE, NORMAL)); |
10129 if (dictionary->IsFailure()) return dictionary; | 10345 if (!maybe_dictionary->ToObject(&dictionary)) { |
| 10346 // Non-recoverable failure. Calling code must restart heap |
| 10347 // initialization. |
| 10348 return maybe_dictionary; |
| 10349 } |
| 10350 } |
10130 } | 10351 } |
10131 return dictionary; | 10352 return dictionary; |
10132 } | 10353 } |
10133 | 10354 |
10134 | 10355 |
10135 Runtime::Function* Runtime::FunctionForSymbol(Handle<String> name) { | 10356 Runtime::Function* Runtime::FunctionForSymbol(Handle<String> name) { |
10136 int entry = Heap::intrinsic_function_names()->FindEntry(*name); | 10357 int entry = Heap::intrinsic_function_names()->FindEntry(*name); |
10137 if (entry != kNotFound) { | 10358 if (entry != kNotFound) { |
10138 Object* smi_index = Heap::intrinsic_function_names()->ValueAt(entry); | 10359 Object* smi_index = Heap::intrinsic_function_names()->ValueAt(entry); |
10139 int function_index = Smi::cast(smi_index)->value(); | 10360 int function_index = Smi::cast(smi_index)->value(); |
(...skipping 17 matching lines...) Expand all Loading... |
10157 } else { | 10378 } else { |
10158 // Handle last resort GC and make sure to allow future allocations | 10379 // Handle last resort GC and make sure to allow future allocations |
10159 // to grow the heap without causing GCs (if possible). | 10380 // to grow the heap without causing GCs (if possible). |
10160 Counters::gc_last_resort_from_js.Increment(); | 10381 Counters::gc_last_resort_from_js.Increment(); |
10161 Heap::CollectAllGarbage(false); | 10382 Heap::CollectAllGarbage(false); |
10162 } | 10383 } |
10163 } | 10384 } |
10164 | 10385 |
10165 | 10386 |
10166 } } // namespace v8::internal | 10387 } } // namespace v8::internal |
OLD | NEW |