| 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 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 NormalizeProperties(js_object, 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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4668 dst[i] = c; | 4750 dst[i] = c; |
| 4669 } | 4751 } |
| 4670 return changed; | 4752 return changed; |
| 4671 } | 4753 } |
| 4672 }; | 4754 }; |
| 4673 | 4755 |
| 4674 } // namespace | 4756 } // namespace |
| 4675 | 4757 |
| 4676 | 4758 |
| 4677 template <typename ConvertTraits> | 4759 template <typename ConvertTraits> |
| 4678 static Object* ConvertCase( | 4760 MUST_USE_RESULT static MaybeObject* ConvertCase( |
| 4679 Arguments args, | 4761 Arguments args, |
| 4680 unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) { | 4762 unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) { |
| 4681 NoHandleAllocation ha; | 4763 NoHandleAllocation ha; |
| 4682 CONVERT_CHECKED(String, s, args[0]); | 4764 CONVERT_CHECKED(String, s, args[0]); |
| 4683 s = s->TryFlattenGetString(); | 4765 s = s->TryFlattenGetString(); |
| 4684 | 4766 |
| 4685 const int length = s->length(); | 4767 const int length = s->length(); |
| 4686 // Assume that the string is not empty; we need this assumption later | 4768 // Assume that the string is not empty; we need this assumption later |
| 4687 if (length == 0) return s; | 4769 if (length == 0) return s; |
| 4688 | 4770 |
| 4689 // Simpler handling of ascii strings. | 4771 // Simpler handling of ascii strings. |
| 4690 // | 4772 // |
| 4691 // NOTE: This assumes that the upper/lower case of an ascii | 4773 // NOTE: This assumes that the upper/lower case of an ascii |
| 4692 // character is also ascii. This is currently the case, but it | 4774 // character is also ascii. This is currently the case, but it |
| 4693 // might break in the future if we implement more context and locale | 4775 // might break in the future if we implement more context and locale |
| 4694 // dependent upper/lower conversions. | 4776 // dependent upper/lower conversions. |
| 4695 if (s->IsSeqAsciiString()) { | 4777 if (s->IsSeqAsciiString()) { |
| 4696 Object* o = Heap::AllocateRawAsciiString(length); | 4778 Object* o; |
| 4697 if (o->IsFailure()) return o; | 4779 { MaybeObject* maybe_o = Heap::AllocateRawAsciiString(length); |
| 4780 if (!maybe_o->ToObject(&o)) return maybe_o; |
| 4781 } |
| 4698 SeqAsciiString* result = SeqAsciiString::cast(o); | 4782 SeqAsciiString* result = SeqAsciiString::cast(o); |
| 4699 bool has_changed_character = ConvertTraits::ConvertAscii( | 4783 bool has_changed_character = ConvertTraits::ConvertAscii( |
| 4700 result->GetChars(), SeqAsciiString::cast(s)->GetChars(), length); | 4784 result->GetChars(), SeqAsciiString::cast(s)->GetChars(), length); |
| 4701 return has_changed_character ? result : s; | 4785 return has_changed_character ? result : s; |
| 4702 } | 4786 } |
| 4703 | 4787 |
| 4704 Object* answer = ConvertCaseHelper(s, length, length, mapping); | 4788 Object* answer; |
| 4789 { MaybeObject* maybe_answer = ConvertCaseHelper(s, length, length, mapping); |
| 4790 if (!maybe_answer->ToObject(&answer)) return maybe_answer; |
| 4791 } |
| 4705 if (answer->IsSmi()) { | 4792 if (answer->IsSmi()) { |
| 4706 // Retry with correct length. | 4793 // Retry with correct length. |
| 4707 answer = ConvertCaseHelper(s, Smi::cast(answer)->value(), length, mapping); | 4794 { MaybeObject* maybe_answer = |
| 4795 ConvertCaseHelper(s, Smi::cast(answer)->value(), length, mapping); |
| 4796 if (!maybe_answer->ToObject(&answer)) return maybe_answer; |
| 4797 } |
| 4708 } | 4798 } |
| 4709 return answer; // This may be a failure. | 4799 return answer; |
| 4710 } | 4800 } |
| 4711 | 4801 |
| 4712 | 4802 |
| 4713 static Object* Runtime_StringToLowerCase(Arguments args) { | 4803 static MaybeObject* Runtime_StringToLowerCase(Arguments args) { |
| 4714 return ConvertCase<ToLowerTraits>(args, &to_lower_mapping); | 4804 return ConvertCase<ToLowerTraits>(args, &to_lower_mapping); |
| 4715 } | 4805 } |
| 4716 | 4806 |
| 4717 | 4807 |
| 4718 static Object* Runtime_StringToUpperCase(Arguments args) { | 4808 static MaybeObject* Runtime_StringToUpperCase(Arguments args) { |
| 4719 return ConvertCase<ToUpperTraits>(args, &to_upper_mapping); | 4809 return ConvertCase<ToUpperTraits>(args, &to_upper_mapping); |
| 4720 } | 4810 } |
| 4721 | 4811 |
| 4722 | 4812 |
| 4723 static inline bool IsTrimWhiteSpace(unibrow::uchar c) { | 4813 static inline bool IsTrimWhiteSpace(unibrow::uchar c) { |
| 4724 return unibrow::WhiteSpace::Is(c) || c == 0x200b; | 4814 return unibrow::WhiteSpace::Is(c) || c == 0x200b; |
| 4725 } | 4815 } |
| 4726 | 4816 |
| 4727 | 4817 |
| 4728 static Object* Runtime_StringTrim(Arguments args) { | 4818 static MaybeObject* Runtime_StringTrim(Arguments args) { |
| 4729 NoHandleAllocation ha; | 4819 NoHandleAllocation ha; |
| 4730 ASSERT(args.length() == 3); | 4820 ASSERT(args.length() == 3); |
| 4731 | 4821 |
| 4732 CONVERT_CHECKED(String, s, args[0]); | 4822 CONVERT_CHECKED(String, s, args[0]); |
| 4733 CONVERT_BOOLEAN_CHECKED(trimLeft, args[1]); | 4823 CONVERT_BOOLEAN_CHECKED(trimLeft, args[1]); |
| 4734 CONVERT_BOOLEAN_CHECKED(trimRight, args[2]); | 4824 CONVERT_BOOLEAN_CHECKED(trimRight, args[2]); |
| 4735 | 4825 |
| 4736 s->TryFlatten(); | 4826 s->TryFlatten(); |
| 4737 int length = s->length(); | 4827 int length = s->length(); |
| 4738 | 4828 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 4767 while (limit > 0) { | 4857 while (limit > 0) { |
| 4768 index = search.Search(subject, index); | 4858 index = search.Search(subject, index); |
| 4769 if (index < 0) return; | 4859 if (index < 0) return; |
| 4770 indices->Add(index); | 4860 indices->Add(index); |
| 4771 index += pattern_length; | 4861 index += pattern_length; |
| 4772 limit--; | 4862 limit--; |
| 4773 } | 4863 } |
| 4774 } | 4864 } |
| 4775 | 4865 |
| 4776 | 4866 |
| 4777 static Object* Runtime_StringSplit(Arguments args) { | 4867 static MaybeObject* Runtime_StringSplit(Arguments args) { |
| 4778 ASSERT(args.length() == 3); | 4868 ASSERT(args.length() == 3); |
| 4779 HandleScope handle_scope; | 4869 HandleScope handle_scope; |
| 4780 CONVERT_ARG_CHECKED(String, subject, 0); | 4870 CONVERT_ARG_CHECKED(String, subject, 0); |
| 4781 CONVERT_ARG_CHECKED(String, pattern, 1); | 4871 CONVERT_ARG_CHECKED(String, pattern, 1); |
| 4782 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]); | 4872 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]); |
| 4783 | 4873 |
| 4784 int subject_length = subject->length(); | 4874 int subject_length = subject->length(); |
| 4785 int pattern_length = pattern->length(); | 4875 int pattern_length = pattern->length(); |
| 4786 RUNTIME_ASSERT(pattern_length > 0); | 4876 RUNTIME_ASSERT(pattern_length > 0); |
| 4787 | 4877 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4893 ASSERT(element == Smi::FromInt(0) || | 4983 ASSERT(element == Smi::FromInt(0) || |
| 4894 (element->IsString() && String::cast(element)->LooksValid())); | 4984 (element->IsString() && String::cast(element)->LooksValid())); |
| 4895 } | 4985 } |
| 4896 #endif | 4986 #endif |
| 4897 return i; | 4987 return i; |
| 4898 } | 4988 } |
| 4899 | 4989 |
| 4900 | 4990 |
| 4901 // Converts a String to JSArray. | 4991 // Converts a String to JSArray. |
| 4902 // For example, "foo" => ["f", "o", "o"]. | 4992 // For example, "foo" => ["f", "o", "o"]. |
| 4903 static Object* Runtime_StringToArray(Arguments args) { | 4993 static MaybeObject* Runtime_StringToArray(Arguments args) { |
| 4904 HandleScope scope; | 4994 HandleScope scope; |
| 4905 ASSERT(args.length() == 1); | 4995 ASSERT(args.length() == 1); |
| 4906 CONVERT_ARG_CHECKED(String, s, 0); | 4996 CONVERT_ARG_CHECKED(String, s, 0); |
| 4907 | 4997 |
| 4908 s->TryFlatten(); | 4998 s->TryFlatten(); |
| 4909 const int length = s->length(); | 4999 const int length = s->length(); |
| 4910 | 5000 |
| 4911 Handle<FixedArray> elements; | 5001 Handle<FixedArray> elements; |
| 4912 if (s->IsFlat() && s->IsAsciiRepresentation()) { | 5002 if (s->IsFlat() && s->IsAsciiRepresentation()) { |
| 4913 Object* obj = Heap::AllocateUninitializedFixedArray(length); | 5003 Object* obj; |
| 4914 if (obj->IsFailure()) return obj; | 5004 { MaybeObject* maybe_obj = Heap::AllocateUninitializedFixedArray(length); |
| 5005 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 5006 } |
| 4915 elements = Handle<FixedArray>(FixedArray::cast(obj)); | 5007 elements = Handle<FixedArray>(FixedArray::cast(obj)); |
| 4916 | 5008 |
| 4917 Vector<const char> chars = s->ToAsciiVector(); | 5009 Vector<const char> chars = s->ToAsciiVector(); |
| 4918 // Note, this will initialize all elements (not only the prefix) | 5010 // Note, this will initialize all elements (not only the prefix) |
| 4919 // to prevent GC from seeing partially initialized array. | 5011 // to prevent GC from seeing partially initialized array. |
| 4920 int num_copied_from_cache = CopyCachedAsciiCharsToArray(chars.start(), | 5012 int num_copied_from_cache = CopyCachedAsciiCharsToArray(chars.start(), |
| 4921 *elements, | 5013 *elements, |
| 4922 length); | 5014 length); |
| 4923 | 5015 |
| 4924 for (int i = num_copied_from_cache; i < length; ++i) { | 5016 for (int i = num_copied_from_cache; i < length; ++i) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4936 #ifdef DEBUG | 5028 #ifdef DEBUG |
| 4937 for (int i = 0; i < length; ++i) { | 5029 for (int i = 0; i < length; ++i) { |
| 4938 ASSERT(String::cast(elements->get(i))->length() == 1); | 5030 ASSERT(String::cast(elements->get(i))->length() == 1); |
| 4939 } | 5031 } |
| 4940 #endif | 5032 #endif |
| 4941 | 5033 |
| 4942 return *Factory::NewJSArrayWithElements(elements); | 5034 return *Factory::NewJSArrayWithElements(elements); |
| 4943 } | 5035 } |
| 4944 | 5036 |
| 4945 | 5037 |
| 4946 static Object* Runtime_NewStringWrapper(Arguments args) { | 5038 static MaybeObject* Runtime_NewStringWrapper(Arguments args) { |
| 4947 NoHandleAllocation ha; | 5039 NoHandleAllocation ha; |
| 4948 ASSERT(args.length() == 1); | 5040 ASSERT(args.length() == 1); |
| 4949 CONVERT_CHECKED(String, value, args[0]); | 5041 CONVERT_CHECKED(String, value, args[0]); |
| 4950 return value->ToObject(); | 5042 return value->ToObject(); |
| 4951 } | 5043 } |
| 4952 | 5044 |
| 4953 | 5045 |
| 4954 bool Runtime::IsUpperCaseChar(uint16_t ch) { | 5046 bool Runtime::IsUpperCaseChar(uint16_t ch) { |
| 4955 unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth]; | 5047 unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth]; |
| 4956 int char_length = to_upper_mapping.get(ch, 0, chars); | 5048 int char_length = to_upper_mapping.get(ch, 0, chars); |
| 4957 return char_length == 0; | 5049 return char_length == 0; |
| 4958 } | 5050 } |
| 4959 | 5051 |
| 4960 | 5052 |
| 4961 static Object* Runtime_NumberToString(Arguments args) { | 5053 static MaybeObject* Runtime_NumberToString(Arguments args) { |
| 4962 NoHandleAllocation ha; | 5054 NoHandleAllocation ha; |
| 4963 ASSERT(args.length() == 1); | 5055 ASSERT(args.length() == 1); |
| 4964 | 5056 |
| 4965 Object* number = args[0]; | 5057 Object* number = args[0]; |
| 4966 RUNTIME_ASSERT(number->IsNumber()); | 5058 RUNTIME_ASSERT(number->IsNumber()); |
| 4967 | 5059 |
| 4968 return Heap::NumberToString(number); | 5060 return Heap::NumberToString(number); |
| 4969 } | 5061 } |
| 4970 | 5062 |
| 4971 | 5063 |
| 4972 static Object* Runtime_NumberToStringSkipCache(Arguments args) { | 5064 static MaybeObject* Runtime_NumberToStringSkipCache(Arguments args) { |
| 4973 NoHandleAllocation ha; | 5065 NoHandleAllocation ha; |
| 4974 ASSERT(args.length() == 1); | 5066 ASSERT(args.length() == 1); |
| 4975 | 5067 |
| 4976 Object* number = args[0]; | 5068 Object* number = args[0]; |
| 4977 RUNTIME_ASSERT(number->IsNumber()); | 5069 RUNTIME_ASSERT(number->IsNumber()); |
| 4978 | 5070 |
| 4979 return Heap::NumberToString(number, false); | 5071 return Heap::NumberToString(number, false); |
| 4980 } | 5072 } |
| 4981 | 5073 |
| 4982 | 5074 |
| 4983 static Object* Runtime_NumberToInteger(Arguments args) { | 5075 static MaybeObject* Runtime_NumberToInteger(Arguments args) { |
| 4984 NoHandleAllocation ha; | 5076 NoHandleAllocation ha; |
| 4985 ASSERT(args.length() == 1); | 5077 ASSERT(args.length() == 1); |
| 4986 | 5078 |
| 4987 CONVERT_DOUBLE_CHECKED(number, args[0]); | 5079 CONVERT_DOUBLE_CHECKED(number, args[0]); |
| 4988 | 5080 |
| 4989 // We do not include 0 so that we don't have to treat +0 / -0 cases. | 5081 // We do not include 0 so that we don't have to treat +0 / -0 cases. |
| 4990 if (number > 0 && number <= Smi::kMaxValue) { | 5082 if (number > 0 && number <= Smi::kMaxValue) { |
| 4991 return Smi::FromInt(static_cast<int>(number)); | 5083 return Smi::FromInt(static_cast<int>(number)); |
| 4992 } | 5084 } |
| 4993 return Heap::NumberFromDouble(DoubleToInteger(number)); | 5085 return Heap::NumberFromDouble(DoubleToInteger(number)); |
| 4994 } | 5086 } |
| 4995 | 5087 |
| 4996 | 5088 |
| 4997 static Object* Runtime_NumberToIntegerMapMinusZero(Arguments args) { | 5089 static MaybeObject* Runtime_NumberToIntegerMapMinusZero(Arguments args) { |
| 4998 NoHandleAllocation ha; | 5090 NoHandleAllocation ha; |
| 4999 ASSERT(args.length() == 1); | 5091 ASSERT(args.length() == 1); |
| 5000 | 5092 |
| 5001 CONVERT_DOUBLE_CHECKED(number, args[0]); | 5093 CONVERT_DOUBLE_CHECKED(number, args[0]); |
| 5002 | 5094 |
| 5003 // We do not include 0 so that we don't have to treat +0 / -0 cases. | 5095 // We do not include 0 so that we don't have to treat +0 / -0 cases. |
| 5004 if (number > 0 && number <= Smi::kMaxValue) { | 5096 if (number > 0 && number <= Smi::kMaxValue) { |
| 5005 return Smi::FromInt(static_cast<int>(number)); | 5097 return Smi::FromInt(static_cast<int>(number)); |
| 5006 } | 5098 } |
| 5007 | 5099 |
| 5008 double double_value = DoubleToInteger(number); | 5100 double double_value = DoubleToInteger(number); |
| 5009 // Map both -0 and +0 to +0. | 5101 // Map both -0 and +0 to +0. |
| 5010 if (double_value == 0) double_value = 0; | 5102 if (double_value == 0) double_value = 0; |
| 5011 | 5103 |
| 5012 return Heap::NumberFromDouble(double_value); | 5104 return Heap::NumberFromDouble(double_value); |
| 5013 } | 5105 } |
| 5014 | 5106 |
| 5015 | 5107 |
| 5016 static Object* Runtime_NumberToJSUint32(Arguments args) { | 5108 static MaybeObject* Runtime_NumberToJSUint32(Arguments args) { |
| 5017 NoHandleAllocation ha; | 5109 NoHandleAllocation ha; |
| 5018 ASSERT(args.length() == 1); | 5110 ASSERT(args.length() == 1); |
| 5019 | 5111 |
| 5020 CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]); | 5112 CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]); |
| 5021 return Heap::NumberFromUint32(number); | 5113 return Heap::NumberFromUint32(number); |
| 5022 } | 5114 } |
| 5023 | 5115 |
| 5024 | 5116 |
| 5025 static Object* Runtime_NumberToJSInt32(Arguments args) { | 5117 static MaybeObject* Runtime_NumberToJSInt32(Arguments args) { |
| 5026 NoHandleAllocation ha; | 5118 NoHandleAllocation ha; |
| 5027 ASSERT(args.length() == 1); | 5119 ASSERT(args.length() == 1); |
| 5028 | 5120 |
| 5029 CONVERT_DOUBLE_CHECKED(number, args[0]); | 5121 CONVERT_DOUBLE_CHECKED(number, args[0]); |
| 5030 | 5122 |
| 5031 // We do not include 0 so that we don't have to treat +0 / -0 cases. | 5123 // We do not include 0 so that we don't have to treat +0 / -0 cases. |
| 5032 if (number > 0 && number <= Smi::kMaxValue) { | 5124 if (number > 0 && number <= Smi::kMaxValue) { |
| 5033 return Smi::FromInt(static_cast<int>(number)); | 5125 return Smi::FromInt(static_cast<int>(number)); |
| 5034 } | 5126 } |
| 5035 return Heap::NumberFromInt32(DoubleToInt32(number)); | 5127 return Heap::NumberFromInt32(DoubleToInt32(number)); |
| 5036 } | 5128 } |
| 5037 | 5129 |
| 5038 | 5130 |
| 5039 // Converts a Number to a Smi, if possible. Returns NaN if the number is not | 5131 // Converts a Number to a Smi, if possible. Returns NaN if the number is not |
| 5040 // a small integer. | 5132 // a small integer. |
| 5041 static Object* Runtime_NumberToSmi(Arguments args) { | 5133 static MaybeObject* Runtime_NumberToSmi(Arguments args) { |
| 5042 NoHandleAllocation ha; | 5134 NoHandleAllocation ha; |
| 5043 ASSERT(args.length() == 1); | 5135 ASSERT(args.length() == 1); |
| 5044 | 5136 |
| 5045 Object* obj = args[0]; | 5137 Object* obj = args[0]; |
| 5046 if (obj->IsSmi()) { | 5138 if (obj->IsSmi()) { |
| 5047 return obj; | 5139 return obj; |
| 5048 } | 5140 } |
| 5049 if (obj->IsHeapNumber()) { | 5141 if (obj->IsHeapNumber()) { |
| 5050 double value = HeapNumber::cast(obj)->value(); | 5142 double value = HeapNumber::cast(obj)->value(); |
| 5051 int int_value = FastD2I(value); | 5143 int int_value = FastD2I(value); |
| 5052 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) { | 5144 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) { |
| 5053 return Smi::FromInt(int_value); | 5145 return Smi::FromInt(int_value); |
| 5054 } | 5146 } |
| 5055 } | 5147 } |
| 5056 return Heap::nan_value(); | 5148 return Heap::nan_value(); |
| 5057 } | 5149 } |
| 5058 | 5150 |
| 5059 | 5151 |
| 5060 static Object* Runtime_NumberAdd(Arguments args) { | 5152 static MaybeObject* Runtime_NumberAdd(Arguments args) { |
| 5061 NoHandleAllocation ha; | 5153 NoHandleAllocation ha; |
| 5062 ASSERT(args.length() == 2); | 5154 ASSERT(args.length() == 2); |
| 5063 | 5155 |
| 5064 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5156 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5065 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5157 CONVERT_DOUBLE_CHECKED(y, args[1]); |
| 5066 return Heap::NumberFromDouble(x + y); | 5158 return Heap::NumberFromDouble(x + y); |
| 5067 } | 5159 } |
| 5068 | 5160 |
| 5069 | 5161 |
| 5070 static Object* Runtime_NumberSub(Arguments args) { | 5162 static MaybeObject* Runtime_NumberSub(Arguments args) { |
| 5071 NoHandleAllocation ha; | 5163 NoHandleAllocation ha; |
| 5072 ASSERT(args.length() == 2); | 5164 ASSERT(args.length() == 2); |
| 5073 | 5165 |
| 5074 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5166 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5075 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5167 CONVERT_DOUBLE_CHECKED(y, args[1]); |
| 5076 return Heap::NumberFromDouble(x - y); | 5168 return Heap::NumberFromDouble(x - y); |
| 5077 } | 5169 } |
| 5078 | 5170 |
| 5079 | 5171 |
| 5080 static Object* Runtime_NumberMul(Arguments args) { | 5172 static MaybeObject* Runtime_NumberMul(Arguments args) { |
| 5081 NoHandleAllocation ha; | 5173 NoHandleAllocation ha; |
| 5082 ASSERT(args.length() == 2); | 5174 ASSERT(args.length() == 2); |
| 5083 | 5175 |
| 5084 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5176 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5085 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5177 CONVERT_DOUBLE_CHECKED(y, args[1]); |
| 5086 return Heap::NumberFromDouble(x * y); | 5178 return Heap::NumberFromDouble(x * y); |
| 5087 } | 5179 } |
| 5088 | 5180 |
| 5089 | 5181 |
| 5090 static Object* Runtime_NumberUnaryMinus(Arguments args) { | 5182 static MaybeObject* Runtime_NumberUnaryMinus(Arguments args) { |
| 5091 NoHandleAllocation ha; | 5183 NoHandleAllocation ha; |
| 5092 ASSERT(args.length() == 1); | 5184 ASSERT(args.length() == 1); |
| 5093 | 5185 |
| 5094 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5186 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5095 return Heap::NumberFromDouble(-x); | 5187 return Heap::NumberFromDouble(-x); |
| 5096 } | 5188 } |
| 5097 | 5189 |
| 5098 | 5190 |
| 5099 static Object* Runtime_NumberAlloc(Arguments args) { | 5191 static MaybeObject* Runtime_NumberAlloc(Arguments args) { |
| 5100 NoHandleAllocation ha; | 5192 NoHandleAllocation ha; |
| 5101 ASSERT(args.length() == 0); | 5193 ASSERT(args.length() == 0); |
| 5102 | 5194 |
| 5103 return Heap::NumberFromDouble(9876543210.0); | 5195 return Heap::NumberFromDouble(9876543210.0); |
| 5104 } | 5196 } |
| 5105 | 5197 |
| 5106 | 5198 |
| 5107 static Object* Runtime_NumberDiv(Arguments args) { | 5199 static MaybeObject* Runtime_NumberDiv(Arguments args) { |
| 5108 NoHandleAllocation ha; | 5200 NoHandleAllocation ha; |
| 5109 ASSERT(args.length() == 2); | 5201 ASSERT(args.length() == 2); |
| 5110 | 5202 |
| 5111 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5203 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5112 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5204 CONVERT_DOUBLE_CHECKED(y, args[1]); |
| 5113 return Heap::NumberFromDouble(x / y); | 5205 return Heap::NumberFromDouble(x / y); |
| 5114 } | 5206 } |
| 5115 | 5207 |
| 5116 | 5208 |
| 5117 static Object* Runtime_NumberMod(Arguments args) { | 5209 static MaybeObject* Runtime_NumberMod(Arguments args) { |
| 5118 NoHandleAllocation ha; | 5210 NoHandleAllocation ha; |
| 5119 ASSERT(args.length() == 2); | 5211 ASSERT(args.length() == 2); |
| 5120 | 5212 |
| 5121 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5213 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5122 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5214 CONVERT_DOUBLE_CHECKED(y, args[1]); |
| 5123 | 5215 |
| 5124 x = modulo(x, y); | 5216 x = modulo(x, y); |
| 5125 // NumberFromDouble may return a Smi instead of a Number object | 5217 // NumberFromDouble may return a Smi instead of a Number object |
| 5126 return Heap::NumberFromDouble(x); | 5218 return Heap::NumberFromDouble(x); |
| 5127 } | 5219 } |
| 5128 | 5220 |
| 5129 | 5221 |
| 5130 static Object* Runtime_StringAdd(Arguments args) { | 5222 static MaybeObject* Runtime_StringAdd(Arguments args) { |
| 5131 NoHandleAllocation ha; | 5223 NoHandleAllocation ha; |
| 5132 ASSERT(args.length() == 2); | 5224 ASSERT(args.length() == 2); |
| 5133 CONVERT_CHECKED(String, str1, args[0]); | 5225 CONVERT_CHECKED(String, str1, args[0]); |
| 5134 CONVERT_CHECKED(String, str2, args[1]); | 5226 CONVERT_CHECKED(String, str2, args[1]); |
| 5135 Counters::string_add_runtime.Increment(); | 5227 Counters::string_add_runtime.Increment(); |
| 5136 return Heap::AllocateConsString(str1, str2); | 5228 return Heap::AllocateConsString(str1, str2); |
| 5137 } | 5229 } |
| 5138 | 5230 |
| 5139 | 5231 |
| 5140 template <typename sinkchar> | 5232 template <typename sinkchar> |
| (...skipping 28 matching lines...) Expand all Loading... |
| 5169 } else { | 5261 } else { |
| 5170 String* string = String::cast(element); | 5262 String* string = String::cast(element); |
| 5171 int element_length = string->length(); | 5263 int element_length = string->length(); |
| 5172 String::WriteToFlat(string, sink + position, 0, element_length); | 5264 String::WriteToFlat(string, sink + position, 0, element_length); |
| 5173 position += element_length; | 5265 position += element_length; |
| 5174 } | 5266 } |
| 5175 } | 5267 } |
| 5176 } | 5268 } |
| 5177 | 5269 |
| 5178 | 5270 |
| 5179 static Object* Runtime_StringBuilderConcat(Arguments args) { | 5271 static MaybeObject* Runtime_StringBuilderConcat(Arguments args) { |
| 5180 NoHandleAllocation ha; | 5272 NoHandleAllocation ha; |
| 5181 ASSERT(args.length() == 3); | 5273 ASSERT(args.length() == 3); |
| 5182 CONVERT_CHECKED(JSArray, array, args[0]); | 5274 CONVERT_CHECKED(JSArray, array, args[0]); |
| 5183 if (!args[1]->IsSmi()) { | 5275 if (!args[1]->IsSmi()) { |
| 5184 Top::context()->mark_out_of_memory(); | 5276 Top::context()->mark_out_of_memory(); |
| 5185 return Failure::OutOfMemoryException(); | 5277 return Failure::OutOfMemoryException(); |
| 5186 } | 5278 } |
| 5187 int array_length = Smi::cast(args[1])->value(); | 5279 int array_length = Smi::cast(args[1])->value(); |
| 5188 CONVERT_CHECKED(String, special, args[2]); | 5280 CONVERT_CHECKED(String, special, args[2]); |
| 5189 | 5281 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5257 Top::context()->mark_out_of_memory(); | 5349 Top::context()->mark_out_of_memory(); |
| 5258 return Failure::OutOfMemoryException(); | 5350 return Failure::OutOfMemoryException(); |
| 5259 } | 5351 } |
| 5260 position += increment; | 5352 position += increment; |
| 5261 } | 5353 } |
| 5262 | 5354 |
| 5263 int length = position; | 5355 int length = position; |
| 5264 Object* object; | 5356 Object* object; |
| 5265 | 5357 |
| 5266 if (ascii) { | 5358 if (ascii) { |
| 5267 object = Heap::AllocateRawAsciiString(length); | 5359 { MaybeObject* maybe_object = Heap::AllocateRawAsciiString(length); |
| 5268 if (object->IsFailure()) return object; | 5360 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 5361 } |
| 5269 SeqAsciiString* answer = SeqAsciiString::cast(object); | 5362 SeqAsciiString* answer = SeqAsciiString::cast(object); |
| 5270 StringBuilderConcatHelper(special, | 5363 StringBuilderConcatHelper(special, |
| 5271 answer->GetChars(), | 5364 answer->GetChars(), |
| 5272 fixed_array, | 5365 fixed_array, |
| 5273 array_length); | 5366 array_length); |
| 5274 return answer; | 5367 return answer; |
| 5275 } else { | 5368 } else { |
| 5276 object = Heap::AllocateRawTwoByteString(length); | 5369 { MaybeObject* maybe_object = Heap::AllocateRawTwoByteString(length); |
| 5277 if (object->IsFailure()) return object; | 5370 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 5371 } |
| 5278 SeqTwoByteString* answer = SeqTwoByteString::cast(object); | 5372 SeqTwoByteString* answer = SeqTwoByteString::cast(object); |
| 5279 StringBuilderConcatHelper(special, | 5373 StringBuilderConcatHelper(special, |
| 5280 answer->GetChars(), | 5374 answer->GetChars(), |
| 5281 fixed_array, | 5375 fixed_array, |
| 5282 array_length); | 5376 array_length); |
| 5283 return answer; | 5377 return answer; |
| 5284 } | 5378 } |
| 5285 } | 5379 } |
| 5286 | 5380 |
| 5287 | 5381 |
| 5288 static Object* Runtime_NumberOr(Arguments args) { | 5382 static MaybeObject* Runtime_NumberOr(Arguments args) { |
| 5289 NoHandleAllocation ha; | 5383 NoHandleAllocation ha; |
| 5290 ASSERT(args.length() == 2); | 5384 ASSERT(args.length() == 2); |
| 5291 | 5385 |
| 5292 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 5386 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
| 5293 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 5387 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
| 5294 return Heap::NumberFromInt32(x | y); | 5388 return Heap::NumberFromInt32(x | y); |
| 5295 } | 5389 } |
| 5296 | 5390 |
| 5297 | 5391 |
| 5298 static Object* Runtime_NumberAnd(Arguments args) { | 5392 static MaybeObject* Runtime_NumberAnd(Arguments args) { |
| 5299 NoHandleAllocation ha; | 5393 NoHandleAllocation ha; |
| 5300 ASSERT(args.length() == 2); | 5394 ASSERT(args.length() == 2); |
| 5301 | 5395 |
| 5302 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 5396 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
| 5303 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 5397 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
| 5304 return Heap::NumberFromInt32(x & y); | 5398 return Heap::NumberFromInt32(x & y); |
| 5305 } | 5399 } |
| 5306 | 5400 |
| 5307 | 5401 |
| 5308 static Object* Runtime_NumberXor(Arguments args) { | 5402 static MaybeObject* Runtime_NumberXor(Arguments args) { |
| 5309 NoHandleAllocation ha; | 5403 NoHandleAllocation ha; |
| 5310 ASSERT(args.length() == 2); | 5404 ASSERT(args.length() == 2); |
| 5311 | 5405 |
| 5312 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 5406 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
| 5313 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 5407 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
| 5314 return Heap::NumberFromInt32(x ^ y); | 5408 return Heap::NumberFromInt32(x ^ y); |
| 5315 } | 5409 } |
| 5316 | 5410 |
| 5317 | 5411 |
| 5318 static Object* Runtime_NumberNot(Arguments args) { | 5412 static MaybeObject* Runtime_NumberNot(Arguments args) { |
| 5319 NoHandleAllocation ha; | 5413 NoHandleAllocation ha; |
| 5320 ASSERT(args.length() == 1); | 5414 ASSERT(args.length() == 1); |
| 5321 | 5415 |
| 5322 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 5416 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
| 5323 return Heap::NumberFromInt32(~x); | 5417 return Heap::NumberFromInt32(~x); |
| 5324 } | 5418 } |
| 5325 | 5419 |
| 5326 | 5420 |
| 5327 static Object* Runtime_NumberShl(Arguments args) { | 5421 static MaybeObject* Runtime_NumberShl(Arguments args) { |
| 5328 NoHandleAllocation ha; | 5422 NoHandleAllocation ha; |
| 5329 ASSERT(args.length() == 2); | 5423 ASSERT(args.length() == 2); |
| 5330 | 5424 |
| 5331 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 5425 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
| 5332 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 5426 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
| 5333 return Heap::NumberFromInt32(x << (y & 0x1f)); | 5427 return Heap::NumberFromInt32(x << (y & 0x1f)); |
| 5334 } | 5428 } |
| 5335 | 5429 |
| 5336 | 5430 |
| 5337 static Object* Runtime_NumberShr(Arguments args) { | 5431 static MaybeObject* Runtime_NumberShr(Arguments args) { |
| 5338 NoHandleAllocation ha; | 5432 NoHandleAllocation ha; |
| 5339 ASSERT(args.length() == 2); | 5433 ASSERT(args.length() == 2); |
| 5340 | 5434 |
| 5341 CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]); | 5435 CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]); |
| 5342 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 5436 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
| 5343 return Heap::NumberFromUint32(x >> (y & 0x1f)); | 5437 return Heap::NumberFromUint32(x >> (y & 0x1f)); |
| 5344 } | 5438 } |
| 5345 | 5439 |
| 5346 | 5440 |
| 5347 static Object* Runtime_NumberSar(Arguments args) { | 5441 static MaybeObject* Runtime_NumberSar(Arguments args) { |
| 5348 NoHandleAllocation ha; | 5442 NoHandleAllocation ha; |
| 5349 ASSERT(args.length() == 2); | 5443 ASSERT(args.length() == 2); |
| 5350 | 5444 |
| 5351 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 5445 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
| 5352 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 5446 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
| 5353 return Heap::NumberFromInt32(ArithmeticShiftRight(x, y & 0x1f)); | 5447 return Heap::NumberFromInt32(ArithmeticShiftRight(x, y & 0x1f)); |
| 5354 } | 5448 } |
| 5355 | 5449 |
| 5356 | 5450 |
| 5357 static Object* Runtime_NumberEquals(Arguments args) { | 5451 static MaybeObject* Runtime_NumberEquals(Arguments args) { |
| 5358 NoHandleAllocation ha; | 5452 NoHandleAllocation ha; |
| 5359 ASSERT(args.length() == 2); | 5453 ASSERT(args.length() == 2); |
| 5360 | 5454 |
| 5361 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5455 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5362 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5456 CONVERT_DOUBLE_CHECKED(y, args[1]); |
| 5363 if (isnan(x)) return Smi::FromInt(NOT_EQUAL); | 5457 if (isnan(x)) return Smi::FromInt(NOT_EQUAL); |
| 5364 if (isnan(y)) return Smi::FromInt(NOT_EQUAL); | 5458 if (isnan(y)) return Smi::FromInt(NOT_EQUAL); |
| 5365 if (x == y) return Smi::FromInt(EQUAL); | 5459 if (x == y) return Smi::FromInt(EQUAL); |
| 5366 Object* result; | 5460 Object* result; |
| 5367 if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) { | 5461 if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) { |
| 5368 result = Smi::FromInt(EQUAL); | 5462 result = Smi::FromInt(EQUAL); |
| 5369 } else { | 5463 } else { |
| 5370 result = Smi::FromInt(NOT_EQUAL); | 5464 result = Smi::FromInt(NOT_EQUAL); |
| 5371 } | 5465 } |
| 5372 return result; | 5466 return result; |
| 5373 } | 5467 } |
| 5374 | 5468 |
| 5375 | 5469 |
| 5376 static Object* Runtime_StringEquals(Arguments args) { | 5470 static MaybeObject* Runtime_StringEquals(Arguments args) { |
| 5377 NoHandleAllocation ha; | 5471 NoHandleAllocation ha; |
| 5378 ASSERT(args.length() == 2); | 5472 ASSERT(args.length() == 2); |
| 5379 | 5473 |
| 5380 CONVERT_CHECKED(String, x, args[0]); | 5474 CONVERT_CHECKED(String, x, args[0]); |
| 5381 CONVERT_CHECKED(String, y, args[1]); | 5475 CONVERT_CHECKED(String, y, args[1]); |
| 5382 | 5476 |
| 5383 bool not_equal = !x->Equals(y); | 5477 bool not_equal = !x->Equals(y); |
| 5384 // This is slightly convoluted because the value that signifies | 5478 // This is slightly convoluted because the value that signifies |
| 5385 // equality is 0 and inequality is 1 so we have to negate the result | 5479 // equality is 0 and inequality is 1 so we have to negate the result |
| 5386 // from String::Equals. | 5480 // from String::Equals. |
| 5387 ASSERT(not_equal == 0 || not_equal == 1); | 5481 ASSERT(not_equal == 0 || not_equal == 1); |
| 5388 STATIC_CHECK(EQUAL == 0); | 5482 STATIC_CHECK(EQUAL == 0); |
| 5389 STATIC_CHECK(NOT_EQUAL == 1); | 5483 STATIC_CHECK(NOT_EQUAL == 1); |
| 5390 return Smi::FromInt(not_equal); | 5484 return Smi::FromInt(not_equal); |
| 5391 } | 5485 } |
| 5392 | 5486 |
| 5393 | 5487 |
| 5394 static Object* Runtime_NumberCompare(Arguments args) { | 5488 static MaybeObject* Runtime_NumberCompare(Arguments args) { |
| 5395 NoHandleAllocation ha; | 5489 NoHandleAllocation ha; |
| 5396 ASSERT(args.length() == 3); | 5490 ASSERT(args.length() == 3); |
| 5397 | 5491 |
| 5398 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5492 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5399 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5493 CONVERT_DOUBLE_CHECKED(y, args[1]); |
| 5400 if (isnan(x) || isnan(y)) return args[2]; | 5494 if (isnan(x) || isnan(y)) return args[2]; |
| 5401 if (x == y) return Smi::FromInt(EQUAL); | 5495 if (x == y) return Smi::FromInt(EQUAL); |
| 5402 if (isless(x, y)) return Smi::FromInt(LESS); | 5496 if (isless(x, y)) return Smi::FromInt(LESS); |
| 5403 return Smi::FromInt(GREATER); | 5497 return Smi::FromInt(GREATER); |
| 5404 } | 5498 } |
| 5405 | 5499 |
| 5406 | 5500 |
| 5407 // Compare two Smis as if they were converted to strings and then | 5501 // Compare two Smis as if they were converted to strings and then |
| 5408 // compared lexicographically. | 5502 // compared lexicographically. |
| 5409 static Object* Runtime_SmiLexicographicCompare(Arguments args) { | 5503 static MaybeObject* Runtime_SmiLexicographicCompare(Arguments args) { |
| 5410 NoHandleAllocation ha; | 5504 NoHandleAllocation ha; |
| 5411 ASSERT(args.length() == 2); | 5505 ASSERT(args.length() == 2); |
| 5412 | 5506 |
| 5413 // Arrays for the individual characters of the two Smis. Smis are | 5507 // Arrays for the individual characters of the two Smis. Smis are |
| 5414 // 31 bit integers and 10 decimal digits are therefore enough. | 5508 // 31 bit integers and 10 decimal digits are therefore enough. |
| 5415 static int x_elms[10]; | 5509 static int x_elms[10]; |
| 5416 static int y_elms[10]; | 5510 static int y_elms[10]; |
| 5417 | 5511 |
| 5418 // Extract the integer values from the Smis. | 5512 // Extract the integer values from the Smis. |
| 5419 CONVERT_CHECKED(Smi, x, args[0]); | 5513 CONVERT_CHECKED(Smi, x, args[0]); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5517 if (r == 0) { | 5611 if (r == 0) { |
| 5518 result = equal_prefix_result; | 5612 result = equal_prefix_result; |
| 5519 } else { | 5613 } else { |
| 5520 result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER); | 5614 result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER); |
| 5521 } | 5615 } |
| 5522 ASSERT(result == StringInputBufferCompare(x, y)); | 5616 ASSERT(result == StringInputBufferCompare(x, y)); |
| 5523 return result; | 5617 return result; |
| 5524 } | 5618 } |
| 5525 | 5619 |
| 5526 | 5620 |
| 5527 static Object* Runtime_StringCompare(Arguments args) { | 5621 static MaybeObject* Runtime_StringCompare(Arguments args) { |
| 5528 NoHandleAllocation ha; | 5622 NoHandleAllocation ha; |
| 5529 ASSERT(args.length() == 2); | 5623 ASSERT(args.length() == 2); |
| 5530 | 5624 |
| 5531 CONVERT_CHECKED(String, x, args[0]); | 5625 CONVERT_CHECKED(String, x, args[0]); |
| 5532 CONVERT_CHECKED(String, y, args[1]); | 5626 CONVERT_CHECKED(String, y, args[1]); |
| 5533 | 5627 |
| 5534 Counters::string_compare_runtime.Increment(); | 5628 Counters::string_compare_runtime.Increment(); |
| 5535 | 5629 |
| 5536 // A few fast case tests before we flatten. | 5630 // A few fast case tests before we flatten. |
| 5537 if (x == y) return Smi::FromInt(EQUAL); | 5631 if (x == y) return Smi::FromInt(EQUAL); |
| 5538 if (y->length() == 0) { | 5632 if (y->length() == 0) { |
| 5539 if (x->length() == 0) return Smi::FromInt(EQUAL); | 5633 if (x->length() == 0) return Smi::FromInt(EQUAL); |
| 5540 return Smi::FromInt(GREATER); | 5634 return Smi::FromInt(GREATER); |
| 5541 } else if (x->length() == 0) { | 5635 } else if (x->length() == 0) { |
| 5542 return Smi::FromInt(LESS); | 5636 return Smi::FromInt(LESS); |
| 5543 } | 5637 } |
| 5544 | 5638 |
| 5545 int d = x->Get(0) - y->Get(0); | 5639 int d = x->Get(0) - y->Get(0); |
| 5546 if (d < 0) return Smi::FromInt(LESS); | 5640 if (d < 0) return Smi::FromInt(LESS); |
| 5547 else if (d > 0) return Smi::FromInt(GREATER); | 5641 else if (d > 0) return Smi::FromInt(GREATER); |
| 5548 | 5642 |
| 5549 Object* obj = Heap::PrepareForCompare(x); | 5643 Object* obj; |
| 5550 if (obj->IsFailure()) return obj; | 5644 { MaybeObject* maybe_obj = Heap::PrepareForCompare(x); |
| 5551 obj = Heap::PrepareForCompare(y); | 5645 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 5552 if (obj->IsFailure()) return obj; | 5646 } |
| 5647 { MaybeObject* maybe_obj = Heap::PrepareForCompare(y); |
| 5648 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 5649 } |
| 5553 | 5650 |
| 5554 return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y) | 5651 return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y) |
| 5555 : StringInputBufferCompare(x, y); | 5652 : StringInputBufferCompare(x, y); |
| 5556 } | 5653 } |
| 5557 | 5654 |
| 5558 | 5655 |
| 5559 static Object* Runtime_Math_acos(Arguments args) { | 5656 static MaybeObject* Runtime_Math_acos(Arguments args) { |
| 5560 NoHandleAllocation ha; | 5657 NoHandleAllocation ha; |
| 5561 ASSERT(args.length() == 1); | 5658 ASSERT(args.length() == 1); |
| 5562 Counters::math_acos.Increment(); | 5659 Counters::math_acos.Increment(); |
| 5563 | 5660 |
| 5564 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5661 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5565 return TranscendentalCache::Get(TranscendentalCache::ACOS, x); | 5662 return TranscendentalCache::Get(TranscendentalCache::ACOS, x); |
| 5566 } | 5663 } |
| 5567 | 5664 |
| 5568 | 5665 |
| 5569 static Object* Runtime_Math_asin(Arguments args) { | 5666 static MaybeObject* Runtime_Math_asin(Arguments args) { |
| 5570 NoHandleAllocation ha; | 5667 NoHandleAllocation ha; |
| 5571 ASSERT(args.length() == 1); | 5668 ASSERT(args.length() == 1); |
| 5572 Counters::math_asin.Increment(); | 5669 Counters::math_asin.Increment(); |
| 5573 | 5670 |
| 5574 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5671 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5575 return TranscendentalCache::Get(TranscendentalCache::ASIN, x); | 5672 return TranscendentalCache::Get(TranscendentalCache::ASIN, x); |
| 5576 } | 5673 } |
| 5577 | 5674 |
| 5578 | 5675 |
| 5579 static Object* Runtime_Math_atan(Arguments args) { | 5676 static MaybeObject* Runtime_Math_atan(Arguments args) { |
| 5580 NoHandleAllocation ha; | 5677 NoHandleAllocation ha; |
| 5581 ASSERT(args.length() == 1); | 5678 ASSERT(args.length() == 1); |
| 5582 Counters::math_atan.Increment(); | 5679 Counters::math_atan.Increment(); |
| 5583 | 5680 |
| 5584 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5681 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5585 return TranscendentalCache::Get(TranscendentalCache::ATAN, x); | 5682 return TranscendentalCache::Get(TranscendentalCache::ATAN, x); |
| 5586 } | 5683 } |
| 5587 | 5684 |
| 5588 | 5685 |
| 5589 static Object* Runtime_Math_atan2(Arguments args) { | 5686 static MaybeObject* Runtime_Math_atan2(Arguments args) { |
| 5590 NoHandleAllocation ha; | 5687 NoHandleAllocation ha; |
| 5591 ASSERT(args.length() == 2); | 5688 ASSERT(args.length() == 2); |
| 5592 Counters::math_atan2.Increment(); | 5689 Counters::math_atan2.Increment(); |
| 5593 | 5690 |
| 5594 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5691 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5595 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5692 CONVERT_DOUBLE_CHECKED(y, args[1]); |
| 5596 double result; | 5693 double result; |
| 5597 if (isinf(x) && isinf(y)) { | 5694 if (isinf(x) && isinf(y)) { |
| 5598 // Make sure that the result in case of two infinite arguments | 5695 // 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 | 5696 // 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 | 5697 // by the first argument (x) and the sign of the second argument |
| 5601 // determines the multiplier: one or three. | 5698 // determines the multiplier: one or three. |
| 5602 static double kPiDividedBy4 = 0.78539816339744830962; | 5699 static double kPiDividedBy4 = 0.78539816339744830962; |
| 5603 int multiplier = (x < 0) ? -1 : 1; | 5700 int multiplier = (x < 0) ? -1 : 1; |
| 5604 if (y < 0) multiplier *= 3; | 5701 if (y < 0) multiplier *= 3; |
| 5605 result = multiplier * kPiDividedBy4; | 5702 result = multiplier * kPiDividedBy4; |
| 5606 } else { | 5703 } else { |
| 5607 result = atan2(x, y); | 5704 result = atan2(x, y); |
| 5608 } | 5705 } |
| 5609 return Heap::AllocateHeapNumber(result); | 5706 return Heap::AllocateHeapNumber(result); |
| 5610 } | 5707 } |
| 5611 | 5708 |
| 5612 | 5709 |
| 5613 static Object* Runtime_Math_ceil(Arguments args) { | 5710 static MaybeObject* Runtime_Math_ceil(Arguments args) { |
| 5614 NoHandleAllocation ha; | 5711 NoHandleAllocation ha; |
| 5615 ASSERT(args.length() == 1); | 5712 ASSERT(args.length() == 1); |
| 5616 Counters::math_ceil.Increment(); | 5713 Counters::math_ceil.Increment(); |
| 5617 | 5714 |
| 5618 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5715 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5619 return Heap::NumberFromDouble(ceiling(x)); | 5716 return Heap::NumberFromDouble(ceiling(x)); |
| 5620 } | 5717 } |
| 5621 | 5718 |
| 5622 | 5719 |
| 5623 static Object* Runtime_Math_cos(Arguments args) { | 5720 static MaybeObject* Runtime_Math_cos(Arguments args) { |
| 5624 NoHandleAllocation ha; | 5721 NoHandleAllocation ha; |
| 5625 ASSERT(args.length() == 1); | 5722 ASSERT(args.length() == 1); |
| 5626 Counters::math_cos.Increment(); | 5723 Counters::math_cos.Increment(); |
| 5627 | 5724 |
| 5628 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5725 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5629 return TranscendentalCache::Get(TranscendentalCache::COS, x); | 5726 return TranscendentalCache::Get(TranscendentalCache::COS, x); |
| 5630 } | 5727 } |
| 5631 | 5728 |
| 5632 | 5729 |
| 5633 static Object* Runtime_Math_exp(Arguments args) { | 5730 static MaybeObject* Runtime_Math_exp(Arguments args) { |
| 5634 NoHandleAllocation ha; | 5731 NoHandleAllocation ha; |
| 5635 ASSERT(args.length() == 1); | 5732 ASSERT(args.length() == 1); |
| 5636 Counters::math_exp.Increment(); | 5733 Counters::math_exp.Increment(); |
| 5637 | 5734 |
| 5638 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5735 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5639 return TranscendentalCache::Get(TranscendentalCache::EXP, x); | 5736 return TranscendentalCache::Get(TranscendentalCache::EXP, x); |
| 5640 } | 5737 } |
| 5641 | 5738 |
| 5642 | 5739 |
| 5643 static Object* Runtime_Math_floor(Arguments args) { | 5740 static MaybeObject* Runtime_Math_floor(Arguments args) { |
| 5644 NoHandleAllocation ha; | 5741 NoHandleAllocation ha; |
| 5645 ASSERT(args.length() == 1); | 5742 ASSERT(args.length() == 1); |
| 5646 Counters::math_floor.Increment(); | 5743 Counters::math_floor.Increment(); |
| 5647 | 5744 |
| 5648 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5745 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5649 return Heap::NumberFromDouble(floor(x)); | 5746 return Heap::NumberFromDouble(floor(x)); |
| 5650 } | 5747 } |
| 5651 | 5748 |
| 5652 | 5749 |
| 5653 static Object* Runtime_Math_log(Arguments args) { | 5750 static MaybeObject* Runtime_Math_log(Arguments args) { |
| 5654 NoHandleAllocation ha; | 5751 NoHandleAllocation ha; |
| 5655 ASSERT(args.length() == 1); | 5752 ASSERT(args.length() == 1); |
| 5656 Counters::math_log.Increment(); | 5753 Counters::math_log.Increment(); |
| 5657 | 5754 |
| 5658 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5755 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5659 return TranscendentalCache::Get(TranscendentalCache::LOG, x); | 5756 return TranscendentalCache::Get(TranscendentalCache::LOG, x); |
| 5660 } | 5757 } |
| 5661 | 5758 |
| 5662 | 5759 |
| 5663 // Helper function to compute x^y, where y is known to be an | 5760 // Helper function to compute x^y, where y is known to be an |
| (...skipping 20 matching lines...) Expand all Loading... |
| 5684 : result; | 5781 : result; |
| 5685 } else { | 5782 } else { |
| 5686 return p; | 5783 return p; |
| 5687 } | 5784 } |
| 5688 } | 5785 } |
| 5689 m *= m; | 5786 m *= m; |
| 5690 } | 5787 } |
| 5691 } | 5788 } |
| 5692 | 5789 |
| 5693 | 5790 |
| 5694 static Object* Runtime_Math_pow(Arguments args) { | 5791 static MaybeObject* Runtime_Math_pow(Arguments args) { |
| 5695 NoHandleAllocation ha; | 5792 NoHandleAllocation ha; |
| 5696 ASSERT(args.length() == 2); | 5793 ASSERT(args.length() == 2); |
| 5697 Counters::math_pow.Increment(); | 5794 Counters::math_pow.Increment(); |
| 5698 | 5795 |
| 5699 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5796 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5700 | 5797 |
| 5701 // If the second argument is a smi, it is much faster to call the | 5798 // If the second argument is a smi, it is much faster to call the |
| 5702 // custom powi() function than the generic pow(). | 5799 // custom powi() function than the generic pow(). |
| 5703 if (args[1]->IsSmi()) { | 5800 if (args[1]->IsSmi()) { |
| 5704 int y = Smi::cast(args[1])->value(); | 5801 int y = Smi::cast(args[1])->value(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 5724 return Smi::FromInt(1); | 5821 return Smi::FromInt(1); |
| 5725 } else if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) { | 5822 } else if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) { |
| 5726 return Heap::nan_value(); | 5823 return Heap::nan_value(); |
| 5727 } else { | 5824 } else { |
| 5728 return Heap::AllocateHeapNumber(pow(x, y)); | 5825 return Heap::AllocateHeapNumber(pow(x, y)); |
| 5729 } | 5826 } |
| 5730 } | 5827 } |
| 5731 | 5828 |
| 5732 // Fast version of Math.pow if we know that y is not an integer and | 5829 // 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. | 5830 // y is not -0.5 or 0.5. Used as slowcase from codegen. |
| 5734 static Object* Runtime_Math_pow_cfunction(Arguments args) { | 5831 static MaybeObject* Runtime_Math_pow_cfunction(Arguments args) { |
| 5735 NoHandleAllocation ha; | 5832 NoHandleAllocation ha; |
| 5736 ASSERT(args.length() == 2); | 5833 ASSERT(args.length() == 2); |
| 5737 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5834 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5738 CONVERT_DOUBLE_CHECKED(y, args[1]); | 5835 CONVERT_DOUBLE_CHECKED(y, args[1]); |
| 5739 if (y == 0) { | 5836 if (y == 0) { |
| 5740 return Smi::FromInt(1); | 5837 return Smi::FromInt(1); |
| 5741 } else if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) { | 5838 } else if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) { |
| 5742 return Heap::nan_value(); | 5839 return Heap::nan_value(); |
| 5743 } else { | 5840 } else { |
| 5744 return Heap::AllocateHeapNumber(pow(x, y)); | 5841 return Heap::AllocateHeapNumber(pow(x, y)); |
| 5745 } | 5842 } |
| 5746 } | 5843 } |
| 5747 | 5844 |
| 5748 | 5845 |
| 5749 static Object* Runtime_RoundNumber(Arguments args) { | 5846 static MaybeObject* Runtime_RoundNumber(Arguments args) { |
| 5750 NoHandleAllocation ha; | 5847 NoHandleAllocation ha; |
| 5751 ASSERT(args.length() == 1); | 5848 ASSERT(args.length() == 1); |
| 5752 Counters::math_round.Increment(); | 5849 Counters::math_round.Increment(); |
| 5753 | 5850 |
| 5754 if (!args[0]->IsHeapNumber()) { | 5851 if (!args[0]->IsHeapNumber()) { |
| 5755 // Must be smi. Return the argument unchanged for all the other types | 5852 // Must be smi. Return the argument unchanged for all the other types |
| 5756 // to make fuzz-natives test happy. | 5853 // to make fuzz-natives test happy. |
| 5757 return args[0]; | 5854 return args[0]; |
| 5758 } | 5855 } |
| 5759 | 5856 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 5775 return number; | 5872 return number; |
| 5776 } | 5873 } |
| 5777 | 5874 |
| 5778 if (sign && value >= -0.5) return Heap::minus_zero_value(); | 5875 if (sign && value >= -0.5) return Heap::minus_zero_value(); |
| 5779 | 5876 |
| 5780 // Do not call NumberFromDouble() to avoid extra checks. | 5877 // Do not call NumberFromDouble() to avoid extra checks. |
| 5781 return Heap::AllocateHeapNumber(floor(value + 0.5)); | 5878 return Heap::AllocateHeapNumber(floor(value + 0.5)); |
| 5782 } | 5879 } |
| 5783 | 5880 |
| 5784 | 5881 |
| 5785 static Object* Runtime_Math_sin(Arguments args) { | 5882 static MaybeObject* Runtime_Math_sin(Arguments args) { |
| 5786 NoHandleAllocation ha; | 5883 NoHandleAllocation ha; |
| 5787 ASSERT(args.length() == 1); | 5884 ASSERT(args.length() == 1); |
| 5788 Counters::math_sin.Increment(); | 5885 Counters::math_sin.Increment(); |
| 5789 | 5886 |
| 5790 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5887 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5791 return TranscendentalCache::Get(TranscendentalCache::SIN, x); | 5888 return TranscendentalCache::Get(TranscendentalCache::SIN, x); |
| 5792 } | 5889 } |
| 5793 | 5890 |
| 5794 | 5891 |
| 5795 static Object* Runtime_Math_sqrt(Arguments args) { | 5892 static MaybeObject* Runtime_Math_sqrt(Arguments args) { |
| 5796 NoHandleAllocation ha; | 5893 NoHandleAllocation ha; |
| 5797 ASSERT(args.length() == 1); | 5894 ASSERT(args.length() == 1); |
| 5798 Counters::math_sqrt.Increment(); | 5895 Counters::math_sqrt.Increment(); |
| 5799 | 5896 |
| 5800 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5897 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5801 return Heap::AllocateHeapNumber(sqrt(x)); | 5898 return Heap::AllocateHeapNumber(sqrt(x)); |
| 5802 } | 5899 } |
| 5803 | 5900 |
| 5804 | 5901 |
| 5805 static Object* Runtime_Math_tan(Arguments args) { | 5902 static MaybeObject* Runtime_Math_tan(Arguments args) { |
| 5806 NoHandleAllocation ha; | 5903 NoHandleAllocation ha; |
| 5807 ASSERT(args.length() == 1); | 5904 ASSERT(args.length() == 1); |
| 5808 Counters::math_tan.Increment(); | 5905 Counters::math_tan.Increment(); |
| 5809 | 5906 |
| 5810 CONVERT_DOUBLE_CHECKED(x, args[0]); | 5907 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 5811 return TranscendentalCache::Get(TranscendentalCache::TAN, x); | 5908 return TranscendentalCache::Get(TranscendentalCache::TAN, x); |
| 5812 } | 5909 } |
| 5813 | 5910 |
| 5814 | 5911 |
| 5815 static int MakeDay(int year, int month, int day) { | 5912 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; | 5947 base_day; |
| 5851 | 5948 |
| 5852 if (year % 4 || (year % 100 == 0 && year % 400 != 0)) { | 5949 if (year % 4 || (year % 100 == 0 && year % 400 != 0)) { |
| 5853 return day_from_year + day_from_month[month] + day - 1; | 5950 return day_from_year + day_from_month[month] + day - 1; |
| 5854 } | 5951 } |
| 5855 | 5952 |
| 5856 return day_from_year + day_from_month_leap[month] + day - 1; | 5953 return day_from_year + day_from_month_leap[month] + day - 1; |
| 5857 } | 5954 } |
| 5858 | 5955 |
| 5859 | 5956 |
| 5860 static Object* Runtime_DateMakeDay(Arguments args) { | 5957 static MaybeObject* Runtime_DateMakeDay(Arguments args) { |
| 5861 NoHandleAllocation ha; | 5958 NoHandleAllocation ha; |
| 5862 ASSERT(args.length() == 3); | 5959 ASSERT(args.length() == 3); |
| 5863 | 5960 |
| 5864 CONVERT_SMI_CHECKED(year, args[0]); | 5961 CONVERT_SMI_CHECKED(year, args[0]); |
| 5865 CONVERT_SMI_CHECKED(month, args[1]); | 5962 CONVERT_SMI_CHECKED(month, args[1]); |
| 5866 CONVERT_SMI_CHECKED(date, args[2]); | 5963 CONVERT_SMI_CHECKED(date, args[2]); |
| 5867 | 5964 |
| 5868 return Smi::FromInt(MakeDay(year, month, date)); | 5965 return Smi::FromInt(MakeDay(year, month, date)); |
| 5869 } | 5966 } |
| 5870 | 5967 |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6149 static inline void DateYMDFromTime(int date, | 6246 static inline void DateYMDFromTime(int date, |
| 6150 int& year, int& month, int& day) { | 6247 int& year, int& month, int& day) { |
| 6151 if (date >= 0 && date < 32 * kDaysIn4Years) { | 6248 if (date >= 0 && date < 32 * kDaysIn4Years) { |
| 6152 DateYMDFromTimeAfter1970(date, year, month, day); | 6249 DateYMDFromTimeAfter1970(date, year, month, day); |
| 6153 } else { | 6250 } else { |
| 6154 DateYMDFromTimeSlow(date, year, month, day); | 6251 DateYMDFromTimeSlow(date, year, month, day); |
| 6155 } | 6252 } |
| 6156 } | 6253 } |
| 6157 | 6254 |
| 6158 | 6255 |
| 6159 static Object* Runtime_DateYMDFromTime(Arguments args) { | 6256 static MaybeObject* Runtime_DateYMDFromTime(Arguments args) { |
| 6160 NoHandleAllocation ha; | 6257 NoHandleAllocation ha; |
| 6161 ASSERT(args.length() == 2); | 6258 ASSERT(args.length() == 2); |
| 6162 | 6259 |
| 6163 CONVERT_DOUBLE_CHECKED(t, args[0]); | 6260 CONVERT_DOUBLE_CHECKED(t, args[0]); |
| 6164 CONVERT_CHECKED(JSArray, res_array, args[1]); | 6261 CONVERT_CHECKED(JSArray, res_array, args[1]); |
| 6165 | 6262 |
| 6166 int year, month, day; | 6263 int year, month, day; |
| 6167 DateYMDFromTime(static_cast<int>(floor(t / 86400000)), year, month, day); | 6264 DateYMDFromTime(static_cast<int>(floor(t / 86400000)), year, month, day); |
| 6168 | 6265 |
| 6169 RUNTIME_ASSERT(res_array->elements()->map() == Heap::fixed_array_map()); | 6266 RUNTIME_ASSERT(res_array->elements()->map() == Heap::fixed_array_map()); |
| 6170 FixedArray* elms = FixedArray::cast(res_array->elements()); | 6267 FixedArray* elms = FixedArray::cast(res_array->elements()); |
| 6171 RUNTIME_ASSERT(elms->length() == 3); | 6268 RUNTIME_ASSERT(elms->length() == 3); |
| 6172 | 6269 |
| 6173 elms->set(0, Smi::FromInt(year)); | 6270 elms->set(0, Smi::FromInt(year)); |
| 6174 elms->set(1, Smi::FromInt(month)); | 6271 elms->set(1, Smi::FromInt(month)); |
| 6175 elms->set(2, Smi::FromInt(day)); | 6272 elms->set(2, Smi::FromInt(day)); |
| 6176 | 6273 |
| 6177 return Heap::undefined_value(); | 6274 return Heap::undefined_value(); |
| 6178 } | 6275 } |
| 6179 | 6276 |
| 6180 | 6277 |
| 6181 static Object* Runtime_NewArgumentsFast(Arguments args) { | 6278 static MaybeObject* Runtime_NewArgumentsFast(Arguments args) { |
| 6182 NoHandleAllocation ha; | 6279 NoHandleAllocation ha; |
| 6183 ASSERT(args.length() == 3); | 6280 ASSERT(args.length() == 3); |
| 6184 | 6281 |
| 6185 JSFunction* callee = JSFunction::cast(args[0]); | 6282 JSFunction* callee = JSFunction::cast(args[0]); |
| 6186 Object** parameters = reinterpret_cast<Object**>(args[1]); | 6283 Object** parameters = reinterpret_cast<Object**>(args[1]); |
| 6187 const int length = Smi::cast(args[2])->value(); | 6284 const int length = Smi::cast(args[2])->value(); |
| 6188 | 6285 |
| 6189 Object* result = Heap::AllocateArgumentsObject(callee, length); | 6286 Object* result; |
| 6190 if (result->IsFailure()) return result; | 6287 { MaybeObject* maybe_result = Heap::AllocateArgumentsObject(callee, length); |
| 6288 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 6289 } |
| 6191 // Allocate the elements if needed. | 6290 // Allocate the elements if needed. |
| 6192 if (length > 0) { | 6291 if (length > 0) { |
| 6193 // Allocate the fixed array. | 6292 // Allocate the fixed array. |
| 6194 Object* obj = Heap::AllocateRawFixedArray(length); | 6293 Object* obj; |
| 6195 if (obj->IsFailure()) return obj; | 6294 { MaybeObject* maybe_obj = Heap::AllocateRawFixedArray(length); |
| 6295 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6296 } |
| 6196 | 6297 |
| 6197 AssertNoAllocation no_gc; | 6298 AssertNoAllocation no_gc; |
| 6198 FixedArray* array = reinterpret_cast<FixedArray*>(obj); | 6299 FixedArray* array = reinterpret_cast<FixedArray*>(obj); |
| 6199 array->set_map(Heap::fixed_array_map()); | 6300 array->set_map(Heap::fixed_array_map()); |
| 6200 array->set_length(length); | 6301 array->set_length(length); |
| 6201 | 6302 |
| 6202 WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc); | 6303 WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc); |
| 6203 for (int i = 0; i < length; i++) { | 6304 for (int i = 0; i < length; i++) { |
| 6204 array->set(i, *--parameters, mode); | 6305 array->set(i, *--parameters, mode); |
| 6205 } | 6306 } |
| 6206 JSObject::cast(result)->set_elements(FixedArray::cast(obj)); | 6307 JSObject::cast(result)->set_elements(FixedArray::cast(obj)); |
| 6207 } | 6308 } |
| 6208 return result; | 6309 return result; |
| 6209 } | 6310 } |
| 6210 | 6311 |
| 6211 | 6312 |
| 6212 static Object* Runtime_NewClosure(Arguments args) { | 6313 static MaybeObject* Runtime_NewClosure(Arguments args) { |
| 6213 HandleScope scope; | 6314 HandleScope scope; |
| 6214 ASSERT(args.length() == 2); | 6315 ASSERT(args.length() == 2); |
| 6215 CONVERT_ARG_CHECKED(Context, context, 0); | 6316 CONVERT_ARG_CHECKED(Context, context, 0); |
| 6216 CONVERT_ARG_CHECKED(SharedFunctionInfo, shared, 1); | 6317 CONVERT_ARG_CHECKED(SharedFunctionInfo, shared, 1); |
| 6217 | 6318 |
| 6218 PretenureFlag pretenure = (context->global_context() == *context) | 6319 PretenureFlag pretenure = (context->global_context() == *context) |
| 6219 ? TENURED // Allocate global closures in old space. | 6320 ? TENURED // Allocate global closures in old space. |
| 6220 : NOT_TENURED; // Allocate local closures in new space. | 6321 : NOT_TENURED; // Allocate local closures in new space. |
| 6221 Handle<JSFunction> result = | 6322 Handle<JSFunction> result = |
| 6222 Factory::NewFunctionFromSharedFunctionInfo(shared, context, pretenure); | 6323 Factory::NewFunctionFromSharedFunctionInfo(shared, context, pretenure); |
| 6223 return *result; | 6324 return *result; |
| 6224 } | 6325 } |
| 6225 | 6326 |
| 6226 static Object* Runtime_NewObjectFromBound(Arguments args) { | 6327 static MaybeObject* Runtime_NewObjectFromBound(Arguments args) { |
| 6227 HandleScope scope; | 6328 HandleScope scope; |
| 6228 ASSERT(args.length() == 2); | 6329 ASSERT(args.length() == 2); |
| 6229 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 6330 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
| 6230 CONVERT_ARG_CHECKED(JSArray, params, 1); | 6331 CONVERT_ARG_CHECKED(JSArray, params, 1); |
| 6231 | 6332 |
| 6232 RUNTIME_ASSERT(params->HasFastElements()); | 6333 RUNTIME_ASSERT(params->HasFastElements()); |
| 6233 FixedArray* fixed = FixedArray::cast(params->elements()); | 6334 FixedArray* fixed = FixedArray::cast(params->elements()); |
| 6234 | 6335 |
| 6235 int fixed_length = Smi::cast(params->length())->value(); | 6336 int fixed_length = Smi::cast(params->length())->value(); |
| 6236 SmartPointer<Object**> param_data(NewArray<Object**>(fixed_length)); | 6337 SmartPointer<Object**> param_data(NewArray<Object**>(fixed_length)); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 6250 } | 6351 } |
| 6251 | 6352 |
| 6252 | 6353 |
| 6253 static void TrySettingInlineConstructStub(Handle<JSFunction> function) { | 6354 static void TrySettingInlineConstructStub(Handle<JSFunction> function) { |
| 6254 Handle<Object> prototype = Factory::null_value(); | 6355 Handle<Object> prototype = Factory::null_value(); |
| 6255 if (function->has_instance_prototype()) { | 6356 if (function->has_instance_prototype()) { |
| 6256 prototype = Handle<Object>(function->instance_prototype()); | 6357 prototype = Handle<Object>(function->instance_prototype()); |
| 6257 } | 6358 } |
| 6258 if (function->shared()->CanGenerateInlineConstructor(*prototype)) { | 6359 if (function->shared()->CanGenerateInlineConstructor(*prototype)) { |
| 6259 ConstructStubCompiler compiler; | 6360 ConstructStubCompiler compiler; |
| 6260 Object* code = compiler.CompileConstructStub(function->shared()); | 6361 MaybeObject* code = compiler.CompileConstructStub(function->shared()); |
| 6261 if (!code->IsFailure()) { | 6362 if (!code->IsFailure()) { |
| 6262 function->shared()->set_construct_stub(Code::cast(code)); | 6363 function->shared()->set_construct_stub( |
| 6364 Code::cast(code->ToObjectUnchecked())); |
| 6263 } | 6365 } |
| 6264 } | 6366 } |
| 6265 } | 6367 } |
| 6266 | 6368 |
| 6267 | 6369 |
| 6268 static Object* Runtime_NewObject(Arguments args) { | 6370 static MaybeObject* Runtime_NewObject(Arguments args) { |
| 6269 HandleScope scope; | 6371 HandleScope scope; |
| 6270 ASSERT(args.length() == 1); | 6372 ASSERT(args.length() == 1); |
| 6271 | 6373 |
| 6272 Handle<Object> constructor = args.at<Object>(0); | 6374 Handle<Object> constructor = args.at<Object>(0); |
| 6273 | 6375 |
| 6274 // If the constructor isn't a proper function we throw a type error. | 6376 // If the constructor isn't a proper function we throw a type error. |
| 6275 if (!constructor->IsJSFunction()) { | 6377 if (!constructor->IsJSFunction()) { |
| 6276 Vector< Handle<Object> > arguments = HandleVector(&constructor, 1); | 6378 Vector< Handle<Object> > arguments = HandleVector(&constructor, 1); |
| 6277 Handle<Object> type_error = | 6379 Handle<Object> type_error = |
| 6278 Factory::NewTypeError("not_constructor", arguments); | 6380 Factory::NewTypeError("not_constructor", arguments); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6334 TrySettingInlineConstructStub(function); | 6436 TrySettingInlineConstructStub(function); |
| 6335 } | 6437 } |
| 6336 | 6438 |
| 6337 Counters::constructed_objects.Increment(); | 6439 Counters::constructed_objects.Increment(); |
| 6338 Counters::constructed_objects_runtime.Increment(); | 6440 Counters::constructed_objects_runtime.Increment(); |
| 6339 | 6441 |
| 6340 return *result; | 6442 return *result; |
| 6341 } | 6443 } |
| 6342 | 6444 |
| 6343 | 6445 |
| 6344 static Object* Runtime_FinalizeInstanceSize(Arguments args) { | 6446 static MaybeObject* Runtime_FinalizeInstanceSize(Arguments args) { |
| 6345 HandleScope scope; | 6447 HandleScope scope; |
| 6346 ASSERT(args.length() == 1); | 6448 ASSERT(args.length() == 1); |
| 6347 | 6449 |
| 6348 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 6450 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
| 6349 function->shared()->CompleteInobjectSlackTracking(); | 6451 function->shared()->CompleteInobjectSlackTracking(); |
| 6350 TrySettingInlineConstructStub(function); | 6452 TrySettingInlineConstructStub(function); |
| 6351 | 6453 |
| 6352 return Heap::undefined_value(); | 6454 return Heap::undefined_value(); |
| 6353 } | 6455 } |
| 6354 | 6456 |
| 6355 | 6457 |
| 6356 static Object* Runtime_LazyCompile(Arguments args) { | 6458 static MaybeObject* Runtime_LazyCompile(Arguments args) { |
| 6357 HandleScope scope; | 6459 HandleScope scope; |
| 6358 ASSERT(args.length() == 1); | 6460 ASSERT(args.length() == 1); |
| 6359 | 6461 |
| 6360 Handle<JSFunction> function = args.at<JSFunction>(0); | 6462 Handle<JSFunction> function = args.at<JSFunction>(0); |
| 6361 #ifdef DEBUG | 6463 #ifdef DEBUG |
| 6362 if (FLAG_trace_lazy && !function->shared()->is_compiled()) { | 6464 if (FLAG_trace_lazy && !function->shared()->is_compiled()) { |
| 6363 PrintF("[lazy: "); | 6465 PrintF("[lazy: "); |
| 6364 function->shared()->name()->Print(); | 6466 function->shared()->name()->Print(); |
| 6365 PrintF("]\n"); | 6467 PrintF("]\n"); |
| 6366 } | 6468 } |
| 6367 #endif | 6469 #endif |
| 6368 | 6470 |
| 6369 // Compile the target function. Here we compile using CompileLazyInLoop in | 6471 // Compile the target function. Here we compile using CompileLazyInLoop in |
| 6370 // order to get the optimized version. This helps code like delta-blue | 6472 // order to get the optimized version. This helps code like delta-blue |
| 6371 // that calls performance-critical routines through constructors. A | 6473 // that calls performance-critical routines through constructors. A |
| 6372 // constructor call doesn't use a CallIC, it uses a LoadIC followed by a | 6474 // 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 | 6475 // direct call. Since the in-loop tracking takes place through CallICs |
| 6374 // this means that things called through constructors are never known to | 6476 // 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. | 6477 // be in loops. We compile them as if they are in loops here just in case. |
| 6376 ASSERT(!function->is_compiled()); | 6478 ASSERT(!function->is_compiled()); |
| 6377 if (!CompileLazyInLoop(function, KEEP_EXCEPTION)) { | 6479 if (!CompileLazyInLoop(function, KEEP_EXCEPTION)) { |
| 6378 return Failure::Exception(); | 6480 return Failure::Exception(); |
| 6379 } | 6481 } |
| 6380 | 6482 |
| 6381 return function->code(); | 6483 return function->code(); |
| 6382 } | 6484 } |
| 6383 | 6485 |
| 6384 | 6486 |
| 6385 static Object* Runtime_GetFunctionDelegate(Arguments args) { | 6487 static MaybeObject* Runtime_GetFunctionDelegate(Arguments args) { |
| 6386 HandleScope scope; | 6488 HandleScope scope; |
| 6387 ASSERT(args.length() == 1); | 6489 ASSERT(args.length() == 1); |
| 6388 RUNTIME_ASSERT(!args[0]->IsJSFunction()); | 6490 RUNTIME_ASSERT(!args[0]->IsJSFunction()); |
| 6389 return *Execution::GetFunctionDelegate(args.at<Object>(0)); | 6491 return *Execution::GetFunctionDelegate(args.at<Object>(0)); |
| 6390 } | 6492 } |
| 6391 | 6493 |
| 6392 | 6494 |
| 6393 static Object* Runtime_GetConstructorDelegate(Arguments args) { | 6495 static MaybeObject* Runtime_GetConstructorDelegate(Arguments args) { |
| 6394 HandleScope scope; | 6496 HandleScope scope; |
| 6395 ASSERT(args.length() == 1); | 6497 ASSERT(args.length() == 1); |
| 6396 RUNTIME_ASSERT(!args[0]->IsJSFunction()); | 6498 RUNTIME_ASSERT(!args[0]->IsJSFunction()); |
| 6397 return *Execution::GetConstructorDelegate(args.at<Object>(0)); | 6499 return *Execution::GetConstructorDelegate(args.at<Object>(0)); |
| 6398 } | 6500 } |
| 6399 | 6501 |
| 6400 | 6502 |
| 6401 static Object* Runtime_NewContext(Arguments args) { | 6503 static MaybeObject* Runtime_NewContext(Arguments args) { |
| 6402 NoHandleAllocation ha; | 6504 NoHandleAllocation ha; |
| 6403 ASSERT(args.length() == 1); | 6505 ASSERT(args.length() == 1); |
| 6404 | 6506 |
| 6405 CONVERT_CHECKED(JSFunction, function, args[0]); | 6507 CONVERT_CHECKED(JSFunction, function, args[0]); |
| 6406 int length = function->shared()->scope_info()->NumberOfContextSlots(); | 6508 int length = function->shared()->scope_info()->NumberOfContextSlots(); |
| 6407 Object* result = Heap::AllocateFunctionContext(length, function); | 6509 Object* result; |
| 6408 if (result->IsFailure()) return result; | 6510 { MaybeObject* maybe_result = Heap::AllocateFunctionContext(length, function); |
| 6511 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 6512 } |
| 6409 | 6513 |
| 6410 Top::set_context(Context::cast(result)); | 6514 Top::set_context(Context::cast(result)); |
| 6411 | 6515 |
| 6412 return result; // non-failure | 6516 return result; // non-failure |
| 6413 } | 6517 } |
| 6414 | 6518 |
| 6415 static Object* PushContextHelper(Object* object, bool is_catch_context) { | 6519 |
| 6520 MUST_USE_RESULT static MaybeObject* PushContextHelper(Object* object, |
| 6521 bool is_catch_context) { |
| 6416 // Convert the object to a proper JavaScript object. | 6522 // Convert the object to a proper JavaScript object. |
| 6417 Object* js_object = object; | 6523 Object* js_object = object; |
| 6418 if (!js_object->IsJSObject()) { | 6524 if (!js_object->IsJSObject()) { |
| 6419 js_object = js_object->ToObject(); | 6525 MaybeObject* maybe_js_object = js_object->ToObject(); |
| 6420 if (js_object->IsFailure()) { | 6526 if (!maybe_js_object->ToObject(&js_object)) { |
| 6421 if (!Failure::cast(js_object)->IsInternalError()) return js_object; | 6527 if (!Failure::cast(maybe_js_object)->IsInternalError()) { |
| 6528 return maybe_js_object; |
| 6529 } |
| 6422 HandleScope scope; | 6530 HandleScope scope; |
| 6423 Handle<Object> handle(object); | 6531 Handle<Object> handle(object); |
| 6424 Handle<Object> result = | 6532 Handle<Object> result = |
| 6425 Factory::NewTypeError("with_expression", HandleVector(&handle, 1)); | 6533 Factory::NewTypeError("with_expression", HandleVector(&handle, 1)); |
| 6426 return Top::Throw(*result); | 6534 return Top::Throw(*result); |
| 6427 } | 6535 } |
| 6428 } | 6536 } |
| 6429 | 6537 |
| 6430 Object* result = | 6538 Object* result; |
| 6431 Heap::AllocateWithContext(Top::context(), | 6539 { MaybeObject* maybe_result = |
| 6432 JSObject::cast(js_object), | 6540 Heap::AllocateWithContext(Top::context(), |
| 6433 is_catch_context); | 6541 JSObject::cast(js_object), |
| 6434 if (result->IsFailure()) return result; | 6542 is_catch_context); |
| 6543 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 6544 } |
| 6435 | 6545 |
| 6436 Context* context = Context::cast(result); | 6546 Context* context = Context::cast(result); |
| 6437 Top::set_context(context); | 6547 Top::set_context(context); |
| 6438 | 6548 |
| 6439 return result; | 6549 return result; |
| 6440 } | 6550 } |
| 6441 | 6551 |
| 6442 | 6552 |
| 6443 static Object* Runtime_PushContext(Arguments args) { | 6553 static MaybeObject* Runtime_PushContext(Arguments args) { |
| 6444 NoHandleAllocation ha; | 6554 NoHandleAllocation ha; |
| 6445 ASSERT(args.length() == 1); | 6555 ASSERT(args.length() == 1); |
| 6446 return PushContextHelper(args[0], false); | 6556 return PushContextHelper(args[0], false); |
| 6447 } | 6557 } |
| 6448 | 6558 |
| 6449 | 6559 |
| 6450 static Object* Runtime_PushCatchContext(Arguments args) { | 6560 static MaybeObject* Runtime_PushCatchContext(Arguments args) { |
| 6451 NoHandleAllocation ha; | 6561 NoHandleAllocation ha; |
| 6452 ASSERT(args.length() == 1); | 6562 ASSERT(args.length() == 1); |
| 6453 return PushContextHelper(args[0], true); | 6563 return PushContextHelper(args[0], true); |
| 6454 } | 6564 } |
| 6455 | 6565 |
| 6456 | 6566 |
| 6457 static Object* Runtime_LookupContext(Arguments args) { | 6567 static MaybeObject* Runtime_LookupContext(Arguments args) { |
| 6458 HandleScope scope; | 6568 HandleScope scope; |
| 6459 ASSERT(args.length() == 2); | 6569 ASSERT(args.length() == 2); |
| 6460 | 6570 |
| 6461 CONVERT_ARG_CHECKED(Context, context, 0); | 6571 CONVERT_ARG_CHECKED(Context, context, 0); |
| 6462 CONVERT_ARG_CHECKED(String, name, 1); | 6572 CONVERT_ARG_CHECKED(String, name, 1); |
| 6463 | 6573 |
| 6464 int index; | 6574 int index; |
| 6465 PropertyAttributes attributes; | 6575 PropertyAttributes attributes; |
| 6466 ContextLookupFlags flags = FOLLOW_CHAINS; | 6576 ContextLookupFlags flags = FOLLOW_CHAINS; |
| 6467 Handle<Object> holder = | 6577 Handle<Object> holder = |
| (...skipping 12 matching lines...) Expand all Loading... |
| 6480 // A mechanism to return a pair of Object pointers in registers (if possible). | 6590 // A mechanism to return a pair of Object pointers in registers (if possible). |
| 6481 // How this is achieved is calling convention-dependent. | 6591 // How this is achieved is calling convention-dependent. |
| 6482 // All currently supported x86 compiles uses calling conventions that are cdecl | 6592 // 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 | 6593 // variants where a 64-bit value is returned in two 32-bit registers |
| 6484 // (edx:eax on ia32, r1:r0 on ARM). | 6594 // (edx:eax on ia32, r1:r0 on ARM). |
| 6485 // In AMD-64 calling convention a struct of two pointers is returned in rdx:rax. | 6595 // 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, | 6596 // 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. | 6597 // allocated by the caller, and passed as a pointer in a hidden first parameter. |
| 6488 #ifdef V8_HOST_ARCH_64_BIT | 6598 #ifdef V8_HOST_ARCH_64_BIT |
| 6489 struct ObjectPair { | 6599 struct ObjectPair { |
| 6490 Object* x; | 6600 MaybeObject* x; |
| 6491 Object* y; | 6601 MaybeObject* y; |
| 6492 }; | 6602 }; |
| 6493 | 6603 |
| 6494 static inline ObjectPair MakePair(Object* x, Object* y) { | 6604 static inline ObjectPair MakePair(MaybeObject* x, MaybeObject* y) { |
| 6495 ObjectPair result = {x, y}; | 6605 ObjectPair result = {x, y}; |
| 6496 // Pointers x and y returned in rax and rdx, in AMD-x64-abi. | 6606 // Pointers x and y returned in rax and rdx, in AMD-x64-abi. |
| 6497 // In Win64 they are assigned to a hidden first argument. | 6607 // In Win64 they are assigned to a hidden first argument. |
| 6498 return result; | 6608 return result; |
| 6499 } | 6609 } |
| 6500 #else | 6610 #else |
| 6501 typedef uint64_t ObjectPair; | 6611 typedef uint64_t ObjectPair; |
| 6502 static inline ObjectPair MakePair(Object* x, Object* y) { | 6612 static inline ObjectPair MakePair(MaybeObject* x, MaybeObject* y) { |
| 6503 return reinterpret_cast<uint32_t>(x) | | 6613 return reinterpret_cast<uint32_t>(x) | |
| 6504 (reinterpret_cast<ObjectPair>(y) << 32); | 6614 (reinterpret_cast<ObjectPair>(y) << 32); |
| 6505 } | 6615 } |
| 6506 #endif | 6616 #endif |
| 6507 | 6617 |
| 6508 | 6618 |
| 6509 static inline Object* Unhole(Object* x, PropertyAttributes attributes) { | 6619 static inline MaybeObject* Unhole(MaybeObject* x, |
| 6620 PropertyAttributes attributes) { |
| 6510 ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0); | 6621 ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0); |
| 6511 USE(attributes); | 6622 USE(attributes); |
| 6512 return x->IsTheHole() ? Heap::undefined_value() : x; | 6623 return x->IsTheHole() ? Heap::undefined_value() : x; |
| 6513 } | 6624 } |
| 6514 | 6625 |
| 6515 | 6626 |
| 6516 static JSObject* ComputeReceiverForNonGlobal(JSObject* holder) { | 6627 static JSObject* ComputeReceiverForNonGlobal(JSObject* holder) { |
| 6517 ASSERT(!holder->IsGlobalObject()); | 6628 ASSERT(!holder->IsGlobalObject()); |
| 6518 Context* top = Top::context(); | 6629 Context* top = Top::context(); |
| 6519 // Get the context extension function. | 6630 // Get the context extension function. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 6549 context->Lookup(name, flags, &index, &attributes); | 6660 context->Lookup(name, flags, &index, &attributes); |
| 6550 | 6661 |
| 6551 // If the index is non-negative, the slot has been found in a local | 6662 // 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 | 6663 // variable or a parameter. Read it from the context object or the |
| 6553 // arguments object. | 6664 // arguments object. |
| 6554 if (index >= 0) { | 6665 if (index >= 0) { |
| 6555 // If the "property" we were looking for is a local variable or an | 6666 // 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 | 6667 // argument in a context, the receiver is the global object; see |
| 6557 // ECMA-262, 3rd., 10.1.6 and 10.2.3. | 6668 // ECMA-262, 3rd., 10.1.6 and 10.2.3. |
| 6558 JSObject* receiver = Top::context()->global()->global_receiver(); | 6669 JSObject* receiver = Top::context()->global()->global_receiver(); |
| 6559 Object* value = (holder->IsContext()) | 6670 MaybeObject* value = (holder->IsContext()) |
| 6560 ? Context::cast(*holder)->get(index) | 6671 ? Context::cast(*holder)->get(index) |
| 6561 : JSObject::cast(*holder)->GetElement(index); | 6672 : JSObject::cast(*holder)->GetElement(index); |
| 6562 return MakePair(Unhole(value, attributes), receiver); | 6673 return MakePair(Unhole(value, attributes), receiver); |
| 6563 } | 6674 } |
| 6564 | 6675 |
| 6565 // If the holder is found, we read the property from it. | 6676 // If the holder is found, we read the property from it. |
| 6566 if (!holder.is_null() && holder->IsJSObject()) { | 6677 if (!holder.is_null() && holder->IsJSObject()) { |
| 6567 ASSERT(Handle<JSObject>::cast(holder)->HasProperty(*name)); | 6678 ASSERT(Handle<JSObject>::cast(holder)->HasProperty(*name)); |
| 6568 JSObject* object = JSObject::cast(*holder); | 6679 JSObject* object = JSObject::cast(*holder); |
| 6569 JSObject* receiver; | 6680 JSObject* receiver; |
| 6570 if (object->IsGlobalObject()) { | 6681 if (object->IsGlobalObject()) { |
| 6571 receiver = GlobalObject::cast(object)->global_receiver(); | 6682 receiver = GlobalObject::cast(object)->global_receiver(); |
| 6572 } else if (context->is_exception_holder(*holder)) { | 6683 } else if (context->is_exception_holder(*holder)) { |
| 6573 receiver = Top::context()->global()->global_receiver(); | 6684 receiver = Top::context()->global()->global_receiver(); |
| 6574 } else { | 6685 } else { |
| 6575 receiver = ComputeReceiverForNonGlobal(object); | 6686 receiver = ComputeReceiverForNonGlobal(object); |
| 6576 } | 6687 } |
| 6577 // No need to unhole the value here. This is taken care of by the | 6688 // No need to unhole the value here. This is taken care of by the |
| 6578 // GetProperty function. | 6689 // GetProperty function. |
| 6579 Object* value = object->GetProperty(*name); | 6690 MaybeObject* value = object->GetProperty(*name); |
| 6580 return MakePair(value, receiver); | 6691 return MakePair(value, receiver); |
| 6581 } | 6692 } |
| 6582 | 6693 |
| 6583 if (throw_error) { | 6694 if (throw_error) { |
| 6584 // The property doesn't exist - throw exception. | 6695 // The property doesn't exist - throw exception. |
| 6585 Handle<Object> reference_error = | 6696 Handle<Object> reference_error = |
| 6586 Factory::NewReferenceError("not_defined", HandleVector(&name, 1)); | 6697 Factory::NewReferenceError("not_defined", HandleVector(&name, 1)); |
| 6587 return MakePair(Top::Throw(*reference_error), NULL); | 6698 return MakePair(Top::Throw(*reference_error), NULL); |
| 6588 } else { | 6699 } else { |
| 6589 // The property doesn't exist - return undefined | 6700 // The property doesn't exist - return undefined |
| 6590 return MakePair(Heap::undefined_value(), Heap::undefined_value()); | 6701 return MakePair(Heap::undefined_value(), Heap::undefined_value()); |
| 6591 } | 6702 } |
| 6592 } | 6703 } |
| 6593 | 6704 |
| 6594 | 6705 |
| 6595 static ObjectPair Runtime_LoadContextSlot(Arguments args) { | 6706 static ObjectPair Runtime_LoadContextSlot(Arguments args) { |
| 6596 return LoadContextSlotHelper(args, true); | 6707 return LoadContextSlotHelper(args, true); |
| 6597 } | 6708 } |
| 6598 | 6709 |
| 6599 | 6710 |
| 6600 static ObjectPair Runtime_LoadContextSlotNoReferenceError(Arguments args) { | 6711 static ObjectPair Runtime_LoadContextSlotNoReferenceError(Arguments args) { |
| 6601 return LoadContextSlotHelper(args, false); | 6712 return LoadContextSlotHelper(args, false); |
| 6602 } | 6713 } |
| 6603 | 6714 |
| 6604 | 6715 |
| 6605 static Object* Runtime_StoreContextSlot(Arguments args) { | 6716 static MaybeObject* Runtime_StoreContextSlot(Arguments args) { |
| 6606 HandleScope scope; | 6717 HandleScope scope; |
| 6607 ASSERT(args.length() == 3); | 6718 ASSERT(args.length() == 3); |
| 6608 | 6719 |
| 6609 Handle<Object> value(args[0]); | 6720 Handle<Object> value(args[0]); |
| 6610 CONVERT_ARG_CHECKED(Context, context, 1); | 6721 CONVERT_ARG_CHECKED(Context, context, 1); |
| 6611 CONVERT_ARG_CHECKED(String, name, 2); | 6722 CONVERT_ARG_CHECKED(String, name, 2); |
| 6612 | 6723 |
| 6613 int index; | 6724 int index; |
| 6614 PropertyAttributes attributes; | 6725 PropertyAttributes attributes; |
| 6615 ContextLookupFlags flags = FOLLOW_CHAINS; | 6726 ContextLookupFlags flags = FOLLOW_CHAINS; |
| 6616 Handle<Object> holder = | 6727 Handle<Object> holder = |
| 6617 context->Lookup(name, flags, &index, &attributes); | 6728 context->Lookup(name, flags, &index, &attributes); |
| 6618 | 6729 |
| 6619 if (index >= 0) { | 6730 if (index >= 0) { |
| 6620 if (holder->IsContext()) { | 6731 if (holder->IsContext()) { |
| 6621 // Ignore if read_only variable. | 6732 // Ignore if read_only variable. |
| 6622 if ((attributes & READ_ONLY) == 0) { | 6733 if ((attributes & READ_ONLY) == 0) { |
| 6623 Handle<Context>::cast(holder)->set(index, *value); | 6734 Handle<Context>::cast(holder)->set(index, *value); |
| 6624 } | 6735 } |
| 6625 } else { | 6736 } else { |
| 6626 ASSERT((attributes & READ_ONLY) == 0); | 6737 ASSERT((attributes & READ_ONLY) == 0); |
| 6627 Object* result = | 6738 Handle<JSObject>::cast(holder)->SetElement(index, *value)-> |
| 6628 Handle<JSObject>::cast(holder)->SetElement(index, *value); | 6739 ToObjectUnchecked(); |
| 6629 USE(result); | |
| 6630 ASSERT(!result->IsFailure()); | |
| 6631 } | 6740 } |
| 6632 return *value; | 6741 return *value; |
| 6633 } | 6742 } |
| 6634 | 6743 |
| 6635 // Slow case: The property is not in a FixedArray context. | 6744 // Slow case: The property is not in a FixedArray context. |
| 6636 // It is either in an JSObject extension context or it was not found. | 6745 // It is either in an JSObject extension context or it was not found. |
| 6637 Handle<JSObject> context_ext; | 6746 Handle<JSObject> context_ext; |
| 6638 | 6747 |
| 6639 if (!holder.is_null()) { | 6748 if (!holder.is_null()) { |
| 6640 // The property exists in the extension context. | 6749 // The property exists in the extension context. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 6656 // handle-based methods such as SetProperty. We therefore need | 6765 // handle-based methods such as SetProperty. We therefore need |
| 6657 // to convert null handles back to exceptions. | 6766 // to convert null handles back to exceptions. |
| 6658 ASSERT(Top::has_pending_exception()); | 6767 ASSERT(Top::has_pending_exception()); |
| 6659 return Failure::Exception(); | 6768 return Failure::Exception(); |
| 6660 } | 6769 } |
| 6661 } | 6770 } |
| 6662 return *value; | 6771 return *value; |
| 6663 } | 6772 } |
| 6664 | 6773 |
| 6665 | 6774 |
| 6666 static Object* Runtime_Throw(Arguments args) { | 6775 static MaybeObject* Runtime_Throw(Arguments args) { |
| 6667 HandleScope scope; | 6776 HandleScope scope; |
| 6668 ASSERT(args.length() == 1); | 6777 ASSERT(args.length() == 1); |
| 6669 | 6778 |
| 6670 return Top::Throw(args[0]); | 6779 return Top::Throw(args[0]); |
| 6671 } | 6780 } |
| 6672 | 6781 |
| 6673 | 6782 |
| 6674 static Object* Runtime_ReThrow(Arguments args) { | 6783 static MaybeObject* Runtime_ReThrow(Arguments args) { |
| 6675 HandleScope scope; | 6784 HandleScope scope; |
| 6676 ASSERT(args.length() == 1); | 6785 ASSERT(args.length() == 1); |
| 6677 | 6786 |
| 6678 return Top::ReThrow(args[0]); | 6787 return Top::ReThrow(args[0]); |
| 6679 } | 6788 } |
| 6680 | 6789 |
| 6681 | 6790 |
| 6682 static Object* Runtime_PromoteScheduledException(Arguments args) { | 6791 static MaybeObject* Runtime_PromoteScheduledException(Arguments args) { |
| 6683 ASSERT_EQ(0, args.length()); | 6792 ASSERT_EQ(0, args.length()); |
| 6684 return Top::PromoteScheduledException(); | 6793 return Top::PromoteScheduledException(); |
| 6685 } | 6794 } |
| 6686 | 6795 |
| 6687 | 6796 |
| 6688 static Object* Runtime_ThrowReferenceError(Arguments args) { | 6797 static MaybeObject* Runtime_ThrowReferenceError(Arguments args) { |
| 6689 HandleScope scope; | 6798 HandleScope scope; |
| 6690 ASSERT(args.length() == 1); | 6799 ASSERT(args.length() == 1); |
| 6691 | 6800 |
| 6692 Handle<Object> name(args[0]); | 6801 Handle<Object> name(args[0]); |
| 6693 Handle<Object> reference_error = | 6802 Handle<Object> reference_error = |
| 6694 Factory::NewReferenceError("not_defined", HandleVector(&name, 1)); | 6803 Factory::NewReferenceError("not_defined", HandleVector(&name, 1)); |
| 6695 return Top::Throw(*reference_error); | 6804 return Top::Throw(*reference_error); |
| 6696 } | 6805 } |
| 6697 | 6806 |
| 6698 | 6807 |
| 6699 static Object* Runtime_StackOverflow(Arguments args) { | 6808 static MaybeObject* Runtime_StackOverflow(Arguments args) { |
| 6700 NoHandleAllocation na; | 6809 NoHandleAllocation na; |
| 6701 return Top::StackOverflow(); | 6810 return Top::StackOverflow(); |
| 6702 } | 6811 } |
| 6703 | 6812 |
| 6704 | 6813 |
| 6705 static Object* Runtime_StackGuard(Arguments args) { | 6814 static MaybeObject* Runtime_StackGuard(Arguments args) { |
| 6706 ASSERT(args.length() == 0); | 6815 ASSERT(args.length() == 0); |
| 6707 | 6816 |
| 6708 // First check if this is a real stack overflow. | 6817 // First check if this is a real stack overflow. |
| 6709 if (StackGuard::IsStackOverflow()) { | 6818 if (StackGuard::IsStackOverflow()) { |
| 6710 return Runtime_StackOverflow(args); | 6819 return Runtime_StackOverflow(args); |
| 6711 } | 6820 } |
| 6712 | 6821 |
| 6713 return Execution::HandleStackGuardInterrupt(); | 6822 return Execution::HandleStackGuardInterrupt(); |
| 6714 } | 6823 } |
| 6715 | 6824 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6793 | 6902 |
| 6794 } else { | 6903 } else { |
| 6795 // function result | 6904 // function result |
| 6796 PrintF("} -> "); | 6905 PrintF("} -> "); |
| 6797 PrintObject(result); | 6906 PrintObject(result); |
| 6798 PrintF("\n"); | 6907 PrintF("\n"); |
| 6799 } | 6908 } |
| 6800 } | 6909 } |
| 6801 | 6910 |
| 6802 | 6911 |
| 6803 static Object* Runtime_TraceEnter(Arguments args) { | 6912 static MaybeObject* Runtime_TraceEnter(Arguments args) { |
| 6804 ASSERT(args.length() == 0); | 6913 ASSERT(args.length() == 0); |
| 6805 NoHandleAllocation ha; | 6914 NoHandleAllocation ha; |
| 6806 PrintTransition(NULL); | 6915 PrintTransition(NULL); |
| 6807 return Heap::undefined_value(); | 6916 return Heap::undefined_value(); |
| 6808 } | 6917 } |
| 6809 | 6918 |
| 6810 | 6919 |
| 6811 static Object* Runtime_TraceExit(Arguments args) { | 6920 static MaybeObject* Runtime_TraceExit(Arguments args) { |
| 6812 NoHandleAllocation ha; | 6921 NoHandleAllocation ha; |
| 6813 PrintTransition(args[0]); | 6922 PrintTransition(args[0]); |
| 6814 return args[0]; // return TOS | 6923 return args[0]; // return TOS |
| 6815 } | 6924 } |
| 6816 | 6925 |
| 6817 | 6926 |
| 6818 static Object* Runtime_DebugPrint(Arguments args) { | 6927 static MaybeObject* Runtime_DebugPrint(Arguments args) { |
| 6819 NoHandleAllocation ha; | 6928 NoHandleAllocation ha; |
| 6820 ASSERT(args.length() == 1); | 6929 ASSERT(args.length() == 1); |
| 6821 | 6930 |
| 6822 #ifdef DEBUG | 6931 #ifdef DEBUG |
| 6823 if (args[0]->IsString()) { | 6932 if (args[0]->IsString()) { |
| 6824 // If we have a string, assume it's a code "marker" | 6933 // If we have a string, assume it's a code "marker" |
| 6825 // and print some interesting cpu debugging info. | 6934 // and print some interesting cpu debugging info. |
| 6826 JavaScriptFrameIterator it; | 6935 JavaScriptFrameIterator it; |
| 6827 JavaScriptFrame* frame = it.frame(); | 6936 JavaScriptFrame* frame = it.frame(); |
| 6828 PrintF("fp = %p, sp = %p, caller_sp = %p: ", | 6937 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. | 6948 // ShortPrint is available in release mode. Print is not. |
| 6840 args[0]->ShortPrint(); | 6949 args[0]->ShortPrint(); |
| 6841 #endif | 6950 #endif |
| 6842 PrintF("\n"); | 6951 PrintF("\n"); |
| 6843 Flush(); | 6952 Flush(); |
| 6844 | 6953 |
| 6845 return args[0]; // return TOS | 6954 return args[0]; // return TOS |
| 6846 } | 6955 } |
| 6847 | 6956 |
| 6848 | 6957 |
| 6849 static Object* Runtime_DebugTrace(Arguments args) { | 6958 static MaybeObject* Runtime_DebugTrace(Arguments args) { |
| 6850 ASSERT(args.length() == 0); | 6959 ASSERT(args.length() == 0); |
| 6851 NoHandleAllocation ha; | 6960 NoHandleAllocation ha; |
| 6852 Top::PrintStack(); | 6961 Top::PrintStack(); |
| 6853 return Heap::undefined_value(); | 6962 return Heap::undefined_value(); |
| 6854 } | 6963 } |
| 6855 | 6964 |
| 6856 | 6965 |
| 6857 static Object* Runtime_DateCurrentTime(Arguments args) { | 6966 static MaybeObject* Runtime_DateCurrentTime(Arguments args) { |
| 6858 NoHandleAllocation ha; | 6967 NoHandleAllocation ha; |
| 6859 ASSERT(args.length() == 0); | 6968 ASSERT(args.length() == 0); |
| 6860 | 6969 |
| 6861 // According to ECMA-262, section 15.9.1, page 117, the precision of | 6970 // 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 | 6971 // the number in a Date object representing a particular instant in |
| 6863 // time is milliseconds. Therefore, we floor the result of getting | 6972 // time is milliseconds. Therefore, we floor the result of getting |
| 6864 // the OS time. | 6973 // the OS time. |
| 6865 double millis = floor(OS::TimeCurrentMillis()); | 6974 double millis = floor(OS::TimeCurrentMillis()); |
| 6866 return Heap::NumberFromDouble(millis); | 6975 return Heap::NumberFromDouble(millis); |
| 6867 } | 6976 } |
| 6868 | 6977 |
| 6869 | 6978 |
| 6870 static Object* Runtime_DateParseString(Arguments args) { | 6979 static MaybeObject* Runtime_DateParseString(Arguments args) { |
| 6871 HandleScope scope; | 6980 HandleScope scope; |
| 6872 ASSERT(args.length() == 2); | 6981 ASSERT(args.length() == 2); |
| 6873 | 6982 |
| 6874 CONVERT_ARG_CHECKED(String, str, 0); | 6983 CONVERT_ARG_CHECKED(String, str, 0); |
| 6875 FlattenString(str); | 6984 FlattenString(str); |
| 6876 | 6985 |
| 6877 CONVERT_ARG_CHECKED(JSArray, output, 1); | 6986 CONVERT_ARG_CHECKED(JSArray, output, 1); |
| 6878 RUNTIME_ASSERT(output->HasFastElements()); | 6987 RUNTIME_ASSERT(output->HasFastElements()); |
| 6879 | 6988 |
| 6880 AssertNoAllocation no_allocation; | 6989 AssertNoAllocation no_allocation; |
| 6881 | 6990 |
| 6882 FixedArray* output_array = FixedArray::cast(output->elements()); | 6991 FixedArray* output_array = FixedArray::cast(output->elements()); |
| 6883 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); | 6992 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); |
| 6884 bool result; | 6993 bool result; |
| 6885 if (str->IsAsciiRepresentation()) { | 6994 if (str->IsAsciiRepresentation()) { |
| 6886 result = DateParser::Parse(str->ToAsciiVector(), output_array); | 6995 result = DateParser::Parse(str->ToAsciiVector(), output_array); |
| 6887 } else { | 6996 } else { |
| 6888 ASSERT(str->IsTwoByteRepresentation()); | 6997 ASSERT(str->IsTwoByteRepresentation()); |
| 6889 result = DateParser::Parse(str->ToUC16Vector(), output_array); | 6998 result = DateParser::Parse(str->ToUC16Vector(), output_array); |
| 6890 } | 6999 } |
| 6891 | 7000 |
| 6892 if (result) { | 7001 if (result) { |
| 6893 return *output; | 7002 return *output; |
| 6894 } else { | 7003 } else { |
| 6895 return Heap::null_value(); | 7004 return Heap::null_value(); |
| 6896 } | 7005 } |
| 6897 } | 7006 } |
| 6898 | 7007 |
| 6899 | 7008 |
| 6900 static Object* Runtime_DateLocalTimezone(Arguments args) { | 7009 static MaybeObject* Runtime_DateLocalTimezone(Arguments args) { |
| 6901 NoHandleAllocation ha; | 7010 NoHandleAllocation ha; |
| 6902 ASSERT(args.length() == 1); | 7011 ASSERT(args.length() == 1); |
| 6903 | 7012 |
| 6904 CONVERT_DOUBLE_CHECKED(x, args[0]); | 7013 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 6905 const char* zone = OS::LocalTimezone(x); | 7014 const char* zone = OS::LocalTimezone(x); |
| 6906 return Heap::AllocateStringFromUtf8(CStrVector(zone)); | 7015 return Heap::AllocateStringFromUtf8(CStrVector(zone)); |
| 6907 } | 7016 } |
| 6908 | 7017 |
| 6909 | 7018 |
| 6910 static Object* Runtime_DateLocalTimeOffset(Arguments args) { | 7019 static MaybeObject* Runtime_DateLocalTimeOffset(Arguments args) { |
| 6911 NoHandleAllocation ha; | 7020 NoHandleAllocation ha; |
| 6912 ASSERT(args.length() == 0); | 7021 ASSERT(args.length() == 0); |
| 6913 | 7022 |
| 6914 return Heap::NumberFromDouble(OS::LocalTimeOffset()); | 7023 return Heap::NumberFromDouble(OS::LocalTimeOffset()); |
| 6915 } | 7024 } |
| 6916 | 7025 |
| 6917 | 7026 |
| 6918 static Object* Runtime_DateDaylightSavingsOffset(Arguments args) { | 7027 static MaybeObject* Runtime_DateDaylightSavingsOffset(Arguments args) { |
| 6919 NoHandleAllocation ha; | 7028 NoHandleAllocation ha; |
| 6920 ASSERT(args.length() == 1); | 7029 ASSERT(args.length() == 1); |
| 6921 | 7030 |
| 6922 CONVERT_DOUBLE_CHECKED(x, args[0]); | 7031 CONVERT_DOUBLE_CHECKED(x, args[0]); |
| 6923 return Heap::NumberFromDouble(OS::DaylightSavingsOffset(x)); | 7032 return Heap::NumberFromDouble(OS::DaylightSavingsOffset(x)); |
| 6924 } | 7033 } |
| 6925 | 7034 |
| 6926 | 7035 |
| 6927 static Object* Runtime_GlobalReceiver(Arguments args) { | 7036 static MaybeObject* Runtime_GlobalReceiver(Arguments args) { |
| 6928 ASSERT(args.length() == 1); | 7037 ASSERT(args.length() == 1); |
| 6929 Object* global = args[0]; | 7038 Object* global = args[0]; |
| 6930 if (!global->IsJSGlobalObject()) return Heap::null_value(); | 7039 if (!global->IsJSGlobalObject()) return Heap::null_value(); |
| 6931 return JSGlobalObject::cast(global)->global_receiver(); | 7040 return JSGlobalObject::cast(global)->global_receiver(); |
| 6932 } | 7041 } |
| 6933 | 7042 |
| 6934 | 7043 |
| 6935 static Object* Runtime_CompileString(Arguments args) { | 7044 static MaybeObject* Runtime_CompileString(Arguments args) { |
| 6936 HandleScope scope; | 7045 HandleScope scope; |
| 6937 ASSERT_EQ(2, args.length()); | 7046 ASSERT_EQ(2, args.length()); |
| 6938 CONVERT_ARG_CHECKED(String, source, 0); | 7047 CONVERT_ARG_CHECKED(String, source, 0); |
| 6939 CONVERT_ARG_CHECKED(Oddball, is_json, 1) | 7048 CONVERT_ARG_CHECKED(Oddball, is_json, 1) |
| 6940 | 7049 |
| 6941 // Compile source string in the global context. | 7050 // Compile source string in the global context. |
| 6942 Handle<Context> context(Top::context()->global_context()); | 7051 Handle<Context> context(Top::context()->global_context()); |
| 6943 Compiler::ValidationState validate = (is_json->IsTrue()) | 7052 Compiler::ValidationState validate = (is_json->IsTrue()) |
| 6944 ? Compiler::VALIDATE_JSON : Compiler::DONT_VALIDATE_JSON; | 7053 ? Compiler::VALIDATE_JSON : Compiler::DONT_VALIDATE_JSON; |
| 6945 Handle<SharedFunctionInfo> shared = Compiler::CompileEval(source, | 7054 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. | 7162 // Compare it to the builtin 'GlobalEval' function to make sure. |
| 7054 if (*callee != Top::global_context()->global_eval_fun() || | 7163 if (*callee != Top::global_context()->global_eval_fun() || |
| 7055 !args[1]->IsString()) { | 7164 !args[1]->IsString()) { |
| 7056 return MakePair(*callee, Top::context()->global()->global_receiver()); | 7165 return MakePair(*callee, Top::context()->global()->global_receiver()); |
| 7057 } | 7166 } |
| 7058 | 7167 |
| 7059 return CompileGlobalEval(args.at<String>(1), args.at<Object>(2)); | 7168 return CompileGlobalEval(args.at<String>(1), args.at<Object>(2)); |
| 7060 } | 7169 } |
| 7061 | 7170 |
| 7062 | 7171 |
| 7063 static Object* Runtime_SetNewFunctionAttributes(Arguments args) { | 7172 static MaybeObject* Runtime_SetNewFunctionAttributes(Arguments args) { |
| 7064 // This utility adjusts the property attributes for newly created Function | 7173 // This utility adjusts the property attributes for newly created Function |
| 7065 // object ("new Function(...)") by changing the map. | 7174 // object ("new Function(...)") by changing the map. |
| 7066 // All it does is changing the prototype property to enumerable | 7175 // All it does is changing the prototype property to enumerable |
| 7067 // as specified in ECMA262, 15.3.5.2. | 7176 // as specified in ECMA262, 15.3.5.2. |
| 7068 HandleScope scope; | 7177 HandleScope scope; |
| 7069 ASSERT(args.length() == 1); | 7178 ASSERT(args.length() == 1); |
| 7070 CONVERT_ARG_CHECKED(JSFunction, func, 0); | 7179 CONVERT_ARG_CHECKED(JSFunction, func, 0); |
| 7071 ASSERT(func->map()->instance_type() == | 7180 ASSERT(func->map()->instance_type() == |
| 7072 Top::function_instance_map()->instance_type()); | 7181 Top::function_instance_map()->instance_type()); |
| 7073 ASSERT(func->map()->instance_size() == | 7182 ASSERT(func->map()->instance_size() == |
| 7074 Top::function_instance_map()->instance_size()); | 7183 Top::function_instance_map()->instance_size()); |
| 7075 func->set_map(*Top::function_instance_map()); | 7184 func->set_map(*Top::function_instance_map()); |
| 7076 return *func; | 7185 return *func; |
| 7077 } | 7186 } |
| 7078 | 7187 |
| 7079 | 7188 |
| 7080 static Object* Runtime_AllocateInNewSpace(Arguments args) { | 7189 static MaybeObject* Runtime_AllocateInNewSpace(Arguments args) { |
| 7081 // Allocate a block of memory in NewSpace (filled with a filler). | 7190 // Allocate a block of memory in NewSpace (filled with a filler). |
| 7082 // Use as fallback for allocation in generated code when NewSpace | 7191 // Use as fallback for allocation in generated code when NewSpace |
| 7083 // is full. | 7192 // is full. |
| 7084 ASSERT(args.length() == 1); | 7193 ASSERT(args.length() == 1); |
| 7085 CONVERT_ARG_CHECKED(Smi, size_smi, 0); | 7194 CONVERT_ARG_CHECKED(Smi, size_smi, 0); |
| 7086 int size = size_smi->value(); | 7195 int size = size_smi->value(); |
| 7087 RUNTIME_ASSERT(IsAligned(size, kPointerSize)); | 7196 RUNTIME_ASSERT(IsAligned(size, kPointerSize)); |
| 7088 RUNTIME_ASSERT(size > 0); | 7197 RUNTIME_ASSERT(size > 0); |
| 7089 static const int kMinFreeNewSpaceAfterGC = | 7198 static const int kMinFreeNewSpaceAfterGC = |
| 7090 Heap::InitialSemiSpaceSize() * 3/4; | 7199 Heap::InitialSemiSpaceSize() * 3/4; |
| 7091 RUNTIME_ASSERT(size <= kMinFreeNewSpaceAfterGC); | 7200 RUNTIME_ASSERT(size <= kMinFreeNewSpaceAfterGC); |
| 7092 Object* allocation = Heap::new_space()->AllocateRaw(size); | 7201 Object* allocation; |
| 7093 if (!allocation->IsFailure()) { | 7202 { MaybeObject* maybe_allocation = Heap::new_space()->AllocateRaw(size); |
| 7094 Heap::CreateFillerObjectAt(HeapObject::cast(allocation)->address(), size); | 7203 if (maybe_allocation->ToObject(&allocation)) { |
| 7204 Heap::CreateFillerObjectAt(HeapObject::cast(allocation)->address(), size); |
| 7205 } |
| 7206 return maybe_allocation; |
| 7095 } | 7207 } |
| 7096 return allocation; | |
| 7097 } | 7208 } |
| 7098 | 7209 |
| 7099 | 7210 |
| 7100 // Push an array unto an array of arrays if it is not already in the | 7211 // 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 | 7212 // array. Returns true if the element was pushed on the stack and |
| 7102 // false otherwise. | 7213 // false otherwise. |
| 7103 static Object* Runtime_PushIfAbsent(Arguments args) { | 7214 static MaybeObject* Runtime_PushIfAbsent(Arguments args) { |
| 7104 ASSERT(args.length() == 2); | 7215 ASSERT(args.length() == 2); |
| 7105 CONVERT_CHECKED(JSArray, array, args[0]); | 7216 CONVERT_CHECKED(JSArray, array, args[0]); |
| 7106 CONVERT_CHECKED(JSArray, element, args[1]); | 7217 CONVERT_CHECKED(JSArray, element, args[1]); |
| 7107 RUNTIME_ASSERT(array->HasFastElements()); | 7218 RUNTIME_ASSERT(array->HasFastElements()); |
| 7108 int length = Smi::cast(array->length())->value(); | 7219 int length = Smi::cast(array->length())->value(); |
| 7109 FixedArray* elements = FixedArray::cast(array->elements()); | 7220 FixedArray* elements = FixedArray::cast(array->elements()); |
| 7110 for (int i = 0; i < length; i++) { | 7221 for (int i = 0; i < length; i++) { |
| 7111 if (elements->get(i) == element) return Heap::false_value(); | 7222 if (elements->get(i) == element) return Heap::false_value(); |
| 7112 } | 7223 } |
| 7113 Object* obj = array->SetFastElement(length, element); | 7224 Object* obj; |
| 7114 if (obj->IsFailure()) return obj; | 7225 { MaybeObject* maybe_obj = array->SetFastElement(length, element); |
| 7226 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 7227 } |
| 7115 return Heap::true_value(); | 7228 return Heap::true_value(); |
| 7116 } | 7229 } |
| 7117 | 7230 |
| 7118 | 7231 |
| 7119 /** | 7232 /** |
| 7120 * A simple visitor visits every element of Array's. | 7233 * A simple visitor visits every element of Array's. |
| 7121 * The backend storage can be a fixed array for fast elements case, | 7234 * The backend storage can be a fixed array for fast elements case, |
| 7122 * or a dictionary for sparse array. Since Dictionary is a subtype | 7235 * 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. | 7236 * of FixedArray, the class can be used by both fast and slow cases. |
| 7124 * The second parameter of the constructor, fast_elements, specifies | 7237 * 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. | 7511 * concatenated array length is 0. |
| 7399 * TODO(lrn) Change length behavior to ECMAScript 5 specification (length | 7512 * TODO(lrn) Change length behavior to ECMAScript 5 specification (length |
| 7400 * is one more than the last array index to get a value assigned). | 7513 * is one more than the last array index to get a value assigned). |
| 7401 */ | 7514 */ |
| 7402 static uint32_t IterateArguments(Handle<JSArray> arguments, | 7515 static uint32_t IterateArguments(Handle<JSArray> arguments, |
| 7403 ArrayConcatVisitor* visitor) { | 7516 ArrayConcatVisitor* visitor) { |
| 7404 uint32_t visited_elements = 0; | 7517 uint32_t visited_elements = 0; |
| 7405 uint32_t num_of_args = static_cast<uint32_t>(arguments->length()->Number()); | 7518 uint32_t num_of_args = static_cast<uint32_t>(arguments->length()->Number()); |
| 7406 | 7519 |
| 7407 for (uint32_t i = 0; i < num_of_args; i++) { | 7520 for (uint32_t i = 0; i < num_of_args; i++) { |
| 7408 Handle<Object> obj(arguments->GetElement(i)); | 7521 Object *element; |
| 7409 if (obj->IsJSArray()) { | 7522 MaybeObject* maybe_element = arguments->GetElement(i); |
| 7410 Handle<JSArray> array = Handle<JSArray>::cast(obj); | 7523 // 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()); | 7524 // interest of hardening the runtime calls. |
| 7412 uint32_t nof_elements = | 7525 if (maybe_element->ToObject(&element)) { |
| 7413 IterateArrayAndPrototypeElements(array, visitor); | 7526 Handle<Object> obj(element); |
| 7414 // Total elements of array and its prototype chain can be more than | 7527 if (obj->IsJSArray()) { |
| 7415 // the array length, but ArrayConcat can only concatenate at most | 7528 Handle<JSArray> array = Handle<JSArray>::cast(obj); |
| 7416 // the array length number of elements. We use the length as an estimate | 7529 uint32_t len = static_cast<uint32_t>(array->length()->Number()); |
| 7417 // for the actual number of elements added. | 7530 uint32_t nof_elements = |
| 7418 uint32_t added_elements = (nof_elements > len) ? len : nof_elements; | 7531 IterateArrayAndPrototypeElements(array, visitor); |
| 7419 if (JSArray::kMaxElementCount - visited_elements < added_elements) { | 7532 // Total elements of array and its prototype chain can be more than |
| 7420 visited_elements = JSArray::kMaxElementCount; | 7533 // the array length, but ArrayConcat can only concatenate at most |
| 7534 // the array length number of elements. We use the length as an estimate |
| 7535 // for the actual number of elements added. |
| 7536 uint32_t added_elements = (nof_elements > len) ? len : nof_elements; |
| 7537 if (JSArray::kMaxElementCount - visited_elements < added_elements) { |
| 7538 visited_elements = JSArray::kMaxElementCount; |
| 7539 } else { |
| 7540 visited_elements += added_elements; |
| 7541 } |
| 7542 if (visitor) visitor->increase_index_offset(len); |
| 7421 } else { | 7543 } else { |
| 7422 visited_elements += added_elements; | 7544 if (visitor) { |
| 7423 } | 7545 visitor->visit(0, obj); |
| 7424 if (visitor) visitor->increase_index_offset(len); | 7546 visitor->increase_index_offset(1); |
| 7425 } else { | 7547 } |
| 7426 if (visitor) { | 7548 if (visited_elements < JSArray::kMaxElementCount) { |
| 7427 visitor->visit(0, obj); | 7549 visited_elements++; |
| 7428 visitor->increase_index_offset(1); | 7550 } |
| 7429 } | |
| 7430 if (visited_elements < JSArray::kMaxElementCount) { | |
| 7431 visited_elements++; | |
| 7432 } | 7551 } |
| 7433 } | 7552 } |
| 7434 } | 7553 } |
| 7435 return visited_elements; | 7554 return visited_elements; |
| 7436 } | 7555 } |
| 7437 | 7556 |
| 7438 | 7557 |
| 7439 /** | 7558 /** |
| 7440 * Array::concat implementation. | 7559 * Array::concat implementation. |
| 7441 * See ECMAScript 262, 15.4.4.4. | 7560 * See ECMAScript 262, 15.4.4.4. |
| 7442 * TODO(lrn): Fix non-compliance for very large concatenations and update to | 7561 * TODO(lrn): Fix non-compliance for very large concatenations and update to |
| 7443 * following the ECMAScript 5 specification. | 7562 * following the ECMAScript 5 specification. |
| 7444 */ | 7563 */ |
| 7445 static Object* Runtime_ArrayConcat(Arguments args) { | 7564 static MaybeObject* Runtime_ArrayConcat(Arguments args) { |
| 7446 ASSERT(args.length() == 1); | 7565 ASSERT(args.length() == 1); |
| 7447 HandleScope handle_scope; | 7566 HandleScope handle_scope; |
| 7448 | 7567 |
| 7449 CONVERT_CHECKED(JSArray, arg_arrays, args[0]); | 7568 CONVERT_CHECKED(JSArray, arg_arrays, args[0]); |
| 7450 Handle<JSArray> arguments(arg_arrays); | 7569 Handle<JSArray> arguments(arg_arrays); |
| 7451 | 7570 |
| 7452 // Pass 1: estimate the number of elements of the result | 7571 // Pass 1: estimate the number of elements of the result |
| 7453 // (it could be more than real numbers if prototype has elements). | 7572 // (it could be more than real numbers if prototype has elements). |
| 7454 uint32_t result_length = 0; | 7573 uint32_t result_length = 0; |
| 7455 uint32_t num_of_args = static_cast<uint32_t>(arguments->length()->Number()); | 7574 uint32_t num_of_args = static_cast<uint32_t>(arguments->length()->Number()); |
| 7456 | 7575 |
| 7457 { AssertNoAllocation nogc; | 7576 { AssertNoAllocation nogc; |
| 7458 for (uint32_t i = 0; i < num_of_args; i++) { | 7577 for (uint32_t i = 0; i < num_of_args; i++) { |
| 7459 Object* obj = arguments->GetElement(i); | 7578 Object* obj; |
| 7460 uint32_t length_estimate; | 7579 MaybeObject* maybe_object = arguments->GetElement(i); |
| 7461 if (obj->IsJSArray()) { | 7580 // This if() is not expected to fail, but we have the check in the |
| 7462 length_estimate = | 7581 // interest of hardening the runtime calls. |
| 7463 static_cast<uint32_t>(JSArray::cast(obj)->length()->Number()); | 7582 if (maybe_object->ToObject(&obj)) { |
| 7464 } else { | 7583 uint32_t length_estimate; |
| 7465 length_estimate = 1; | 7584 if (obj->IsJSArray()) { |
| 7585 length_estimate = |
| 7586 static_cast<uint32_t>(JSArray::cast(obj)->length()->Number()); |
| 7587 } else { |
| 7588 length_estimate = 1; |
| 7589 } |
| 7590 if (JSObject::kMaxElementCount - result_length < length_estimate) { |
| 7591 result_length = JSObject::kMaxElementCount; |
| 7592 break; |
| 7593 } |
| 7594 result_length += length_estimate; |
| 7466 } | 7595 } |
| 7467 if (JSObject::kMaxElementCount - result_length < length_estimate) { | |
| 7468 result_length = JSObject::kMaxElementCount; | |
| 7469 break; | |
| 7470 } | |
| 7471 result_length += length_estimate; | |
| 7472 } | 7596 } |
| 7473 } | 7597 } |
| 7474 | 7598 |
| 7475 // Allocate an empty array, will set length and content later. | 7599 // Allocate an empty array, will set length and content later. |
| 7476 Handle<JSArray> result = Factory::NewJSArray(0); | 7600 Handle<JSArray> result = Factory::NewJSArray(0); |
| 7477 | 7601 |
| 7478 uint32_t estimate_nof_elements = IterateArguments(arguments, NULL); | 7602 uint32_t estimate_nof_elements = IterateArguments(arguments, NULL); |
| 7479 // If estimated number of elements is more than half of length, a | 7603 // 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 | 7604 // fixed array (fast case) is more time and space-efficient than a |
| 7481 // dictionary. | 7605 // dictionary. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 7509 result->set_length(*len); | 7633 result->set_length(*len); |
| 7510 // Please note the storage might have changed in the visitor. | 7634 // Please note the storage might have changed in the visitor. |
| 7511 result->set_elements(*visitor.storage()); | 7635 result->set_elements(*visitor.storage()); |
| 7512 | 7636 |
| 7513 return *result; | 7637 return *result; |
| 7514 } | 7638 } |
| 7515 | 7639 |
| 7516 | 7640 |
| 7517 // This will not allocate (flatten the string), but it may run | 7641 // This will not allocate (flatten the string), but it may run |
| 7518 // very slowly for very deeply nested ConsStrings. For debugging use only. | 7642 // very slowly for very deeply nested ConsStrings. For debugging use only. |
| 7519 static Object* Runtime_GlobalPrint(Arguments args) { | 7643 static MaybeObject* Runtime_GlobalPrint(Arguments args) { |
| 7520 NoHandleAllocation ha; | 7644 NoHandleAllocation ha; |
| 7521 ASSERT(args.length() == 1); | 7645 ASSERT(args.length() == 1); |
| 7522 | 7646 |
| 7523 CONVERT_CHECKED(String, string, args[0]); | 7647 CONVERT_CHECKED(String, string, args[0]); |
| 7524 StringInputBuffer buffer(string); | 7648 StringInputBuffer buffer(string); |
| 7525 while (buffer.has_more()) { | 7649 while (buffer.has_more()) { |
| 7526 uint16_t character = buffer.GetNext(); | 7650 uint16_t character = buffer.GetNext(); |
| 7527 PrintF("%c", character); | 7651 PrintF("%c", character); |
| 7528 } | 7652 } |
| 7529 return string; | 7653 return string; |
| 7530 } | 7654 } |
| 7531 | 7655 |
| 7532 // Moves all own elements of an object, that are below a limit, to positions | 7656 // 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, | 7657 // 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 | 7658 // and are followed by non-existing element. Does not change the length |
| 7535 // property. | 7659 // property. |
| 7536 // Returns the number of non-undefined elements collected. | 7660 // Returns the number of non-undefined elements collected. |
| 7537 static Object* Runtime_RemoveArrayHoles(Arguments args) { | 7661 static MaybeObject* Runtime_RemoveArrayHoles(Arguments args) { |
| 7538 ASSERT(args.length() == 2); | 7662 ASSERT(args.length() == 2); |
| 7539 CONVERT_CHECKED(JSObject, object, args[0]); | 7663 CONVERT_CHECKED(JSObject, object, args[0]); |
| 7540 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); | 7664 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); |
| 7541 return object->PrepareElementsForSort(limit); | 7665 return object->PrepareElementsForSort(limit); |
| 7542 } | 7666 } |
| 7543 | 7667 |
| 7544 | 7668 |
| 7545 // Move contents of argument 0 (an array) to argument 1 (an array) | 7669 // Move contents of argument 0 (an array) to argument 1 (an array) |
| 7546 static Object* Runtime_MoveArrayContents(Arguments args) { | 7670 static MaybeObject* Runtime_MoveArrayContents(Arguments args) { |
| 7547 ASSERT(args.length() == 2); | 7671 ASSERT(args.length() == 2); |
| 7548 CONVERT_CHECKED(JSArray, from, args[0]); | 7672 CONVERT_CHECKED(JSArray, from, args[0]); |
| 7549 CONVERT_CHECKED(JSArray, to, args[1]); | 7673 CONVERT_CHECKED(JSArray, to, args[1]); |
| 7550 HeapObject* new_elements = from->elements(); | 7674 HeapObject* new_elements = from->elements(); |
| 7551 Object* new_map; | 7675 MaybeObject* maybe_new_map; |
| 7552 if (new_elements->map() == Heap::fixed_array_map() || | 7676 if (new_elements->map() == Heap::fixed_array_map() || |
| 7553 new_elements->map() == Heap::fixed_cow_array_map()) { | 7677 new_elements->map() == Heap::fixed_cow_array_map()) { |
| 7554 new_map = to->map()->GetFastElementsMap(); | 7678 maybe_new_map = to->map()->GetFastElementsMap(); |
| 7555 } else { | 7679 } else { |
| 7556 new_map = to->map()->GetSlowElementsMap(); | 7680 maybe_new_map = to->map()->GetSlowElementsMap(); |
| 7557 } | 7681 } |
| 7558 if (new_map->IsFailure()) return new_map; | 7682 Object* new_map; |
| 7683 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
| 7559 to->set_map(Map::cast(new_map)); | 7684 to->set_map(Map::cast(new_map)); |
| 7560 to->set_elements(new_elements); | 7685 to->set_elements(new_elements); |
| 7561 to->set_length(from->length()); | 7686 to->set_length(from->length()); |
| 7562 Object* obj = from->ResetElements(); | 7687 Object* obj; |
| 7563 if (obj->IsFailure()) return obj; | 7688 { MaybeObject* maybe_obj = from->ResetElements(); |
| 7689 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 7690 } |
| 7564 from->set_length(Smi::FromInt(0)); | 7691 from->set_length(Smi::FromInt(0)); |
| 7565 return to; | 7692 return to; |
| 7566 } | 7693 } |
| 7567 | 7694 |
| 7568 | 7695 |
| 7569 // How many elements does this object/array have? | 7696 // How many elements does this object/array have? |
| 7570 static Object* Runtime_EstimateNumberOfElements(Arguments args) { | 7697 static MaybeObject* Runtime_EstimateNumberOfElements(Arguments args) { |
| 7571 ASSERT(args.length() == 1); | 7698 ASSERT(args.length() == 1); |
| 7572 CONVERT_CHECKED(JSObject, object, args[0]); | 7699 CONVERT_CHECKED(JSObject, object, args[0]); |
| 7573 HeapObject* elements = object->elements(); | 7700 HeapObject* elements = object->elements(); |
| 7574 if (elements->IsDictionary()) { | 7701 if (elements->IsDictionary()) { |
| 7575 return Smi::FromInt(NumberDictionary::cast(elements)->NumberOfElements()); | 7702 return Smi::FromInt(NumberDictionary::cast(elements)->NumberOfElements()); |
| 7576 } else if (object->IsJSArray()) { | 7703 } else if (object->IsJSArray()) { |
| 7577 return JSArray::cast(object)->length(); | 7704 return JSArray::cast(object)->length(); |
| 7578 } else { | 7705 } else { |
| 7579 return Smi::FromInt(FixedArray::cast(elements)->length()); | 7706 return Smi::FromInt(FixedArray::cast(elements)->length()); |
| 7580 } | 7707 } |
| 7581 } | 7708 } |
| 7582 | 7709 |
| 7583 | 7710 |
| 7584 static Object* Runtime_SwapElements(Arguments args) { | 7711 static MaybeObject* Runtime_SwapElements(Arguments args) { |
| 7585 HandleScope handle_scope; | 7712 HandleScope handle_scope; |
| 7586 | 7713 |
| 7587 ASSERT_EQ(3, args.length()); | 7714 ASSERT_EQ(3, args.length()); |
| 7588 | 7715 |
| 7589 CONVERT_ARG_CHECKED(JSObject, object, 0); | 7716 CONVERT_ARG_CHECKED(JSObject, object, 0); |
| 7590 Handle<Object> key1 = args.at<Object>(1); | 7717 Handle<Object> key1 = args.at<Object>(1); |
| 7591 Handle<Object> key2 = args.at<Object>(2); | 7718 Handle<Object> key2 = args.at<Object>(2); |
| 7592 | 7719 |
| 7593 uint32_t index1, index2; | 7720 uint32_t index1, index2; |
| 7594 if (!key1->ToArrayIndex(&index1) | 7721 if (!key1->ToArrayIndex(&index1) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 7605 | 7732 |
| 7606 return Heap::undefined_value(); | 7733 return Heap::undefined_value(); |
| 7607 } | 7734 } |
| 7608 | 7735 |
| 7609 | 7736 |
| 7610 // Returns an array that tells you where in the [0, length) interval an array | 7737 // 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 | 7738 // might have elements. Can either return keys (positive integers) or |
| 7612 // intervals (pair of a negative integer (-start-1) followed by a | 7739 // intervals (pair of a negative integer (-start-1) followed by a |
| 7613 // positive (length)) or undefined values. | 7740 // positive (length)) or undefined values. |
| 7614 // Intervals can span over some keys that are not in the object. | 7741 // Intervals can span over some keys that are not in the object. |
| 7615 static Object* Runtime_GetArrayKeys(Arguments args) { | 7742 static MaybeObject* Runtime_GetArrayKeys(Arguments args) { |
| 7616 ASSERT(args.length() == 2); | 7743 ASSERT(args.length() == 2); |
| 7617 HandleScope scope; | 7744 HandleScope scope; |
| 7618 CONVERT_ARG_CHECKED(JSObject, array, 0); | 7745 CONVERT_ARG_CHECKED(JSObject, array, 0); |
| 7619 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); | 7746 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); |
| 7620 if (array->elements()->IsDictionary()) { | 7747 if (array->elements()->IsDictionary()) { |
| 7621 // Create an array and get all the keys into it, then remove all the | 7748 // 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. | 7749 // keys that are not integers in the range 0 to length-1. |
| 7623 Handle<FixedArray> keys = GetKeysInFixedArrayFor(array, INCLUDE_PROTOS); | 7750 Handle<FixedArray> keys = GetKeysInFixedArrayFor(array, INCLUDE_PROTOS); |
| 7624 int keys_length = keys->length(); | 7751 int keys_length = keys->length(); |
| 7625 for (int i = 0; i < keys_length; i++) { | 7752 for (int i = 0; i < keys_length; i++) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 7645 return *Factory::NewJSArrayWithElements(single_interval); | 7772 return *Factory::NewJSArrayWithElements(single_interval); |
| 7646 } | 7773 } |
| 7647 } | 7774 } |
| 7648 | 7775 |
| 7649 | 7776 |
| 7650 // DefineAccessor takes an optional final argument which is the | 7777 // DefineAccessor takes an optional final argument which is the |
| 7651 // property attributes (eg, DONT_ENUM, DONT_DELETE). IMPORTANT: due | 7778 // property attributes (eg, DONT_ENUM, DONT_DELETE). IMPORTANT: due |
| 7652 // to the way accessors are implemented, it is set for both the getter | 7779 // 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 | 7780 // and setter on the first call to DefineAccessor and ignored on |
| 7654 // subsequent calls. | 7781 // subsequent calls. |
| 7655 static Object* Runtime_DefineAccessor(Arguments args) { | 7782 static MaybeObject* Runtime_DefineAccessor(Arguments args) { |
| 7656 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5); | 7783 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5); |
| 7657 // Compute attributes. | 7784 // Compute attributes. |
| 7658 PropertyAttributes attributes = NONE; | 7785 PropertyAttributes attributes = NONE; |
| 7659 if (args.length() == 5) { | 7786 if (args.length() == 5) { |
| 7660 CONVERT_CHECKED(Smi, attrs, args[4]); | 7787 CONVERT_CHECKED(Smi, attrs, args[4]); |
| 7661 int value = attrs->value(); | 7788 int value = attrs->value(); |
| 7662 // Only attribute bits should be set. | 7789 // Only attribute bits should be set. |
| 7663 ASSERT((value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 7790 ASSERT((value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
| 7664 attributes = static_cast<PropertyAttributes>(value); | 7791 attributes = static_cast<PropertyAttributes>(value); |
| 7665 } | 7792 } |
| 7666 | 7793 |
| 7667 CONVERT_CHECKED(JSObject, obj, args[0]); | 7794 CONVERT_CHECKED(JSObject, obj, args[0]); |
| 7668 CONVERT_CHECKED(String, name, args[1]); | 7795 CONVERT_CHECKED(String, name, args[1]); |
| 7669 CONVERT_CHECKED(Smi, flag, args[2]); | 7796 CONVERT_CHECKED(Smi, flag, args[2]); |
| 7670 CONVERT_CHECKED(JSFunction, fun, args[3]); | 7797 CONVERT_CHECKED(JSFunction, fun, args[3]); |
| 7671 return obj->DefineAccessor(name, flag->value() == 0, fun, attributes); | 7798 return obj->DefineAccessor(name, flag->value() == 0, fun, attributes); |
| 7672 } | 7799 } |
| 7673 | 7800 |
| 7674 | 7801 |
| 7675 static Object* Runtime_LookupAccessor(Arguments args) { | 7802 static MaybeObject* Runtime_LookupAccessor(Arguments args) { |
| 7676 ASSERT(args.length() == 3); | 7803 ASSERT(args.length() == 3); |
| 7677 CONVERT_CHECKED(JSObject, obj, args[0]); | 7804 CONVERT_CHECKED(JSObject, obj, args[0]); |
| 7678 CONVERT_CHECKED(String, name, args[1]); | 7805 CONVERT_CHECKED(String, name, args[1]); |
| 7679 CONVERT_CHECKED(Smi, flag, args[2]); | 7806 CONVERT_CHECKED(Smi, flag, args[2]); |
| 7680 return obj->LookupAccessor(name, flag->value() == 0); | 7807 return obj->LookupAccessor(name, flag->value() == 0); |
| 7681 } | 7808 } |
| 7682 | 7809 |
| 7683 | 7810 |
| 7684 #ifdef ENABLE_DEBUGGER_SUPPORT | 7811 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 7685 static Object* Runtime_DebugBreak(Arguments args) { | 7812 static MaybeObject* Runtime_DebugBreak(Arguments args) { |
| 7686 ASSERT(args.length() == 0); | 7813 ASSERT(args.length() == 0); |
| 7687 return Execution::DebugBreakHelper(); | 7814 return Execution::DebugBreakHelper(); |
| 7688 } | 7815 } |
| 7689 | 7816 |
| 7690 | 7817 |
| 7691 // Helper functions for wrapping and unwrapping stack frame ids. | 7818 // Helper functions for wrapping and unwrapping stack frame ids. |
| 7692 static Smi* WrapFrameId(StackFrame::Id id) { | 7819 static Smi* WrapFrameId(StackFrame::Id id) { |
| 7693 ASSERT(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4))); | 7820 ASSERT(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4))); |
| 7694 return Smi::FromInt(id >> 2); | 7821 return Smi::FromInt(id >> 2); |
| 7695 } | 7822 } |
| 7696 | 7823 |
| 7697 | 7824 |
| 7698 static StackFrame::Id UnwrapFrameId(Smi* wrapped) { | 7825 static StackFrame::Id UnwrapFrameId(Smi* wrapped) { |
| 7699 return static_cast<StackFrame::Id>(wrapped->value() << 2); | 7826 return static_cast<StackFrame::Id>(wrapped->value() << 2); |
| 7700 } | 7827 } |
| 7701 | 7828 |
| 7702 | 7829 |
| 7703 // Adds a JavaScript function as a debug event listener. | 7830 // Adds a JavaScript function as a debug event listener. |
| 7704 // args[0]: debug event listener function to set or null or undefined for | 7831 // args[0]: debug event listener function to set or null or undefined for |
| 7705 // clearing the event listener function | 7832 // clearing the event listener function |
| 7706 // args[1]: object supplied during callback | 7833 // args[1]: object supplied during callback |
| 7707 static Object* Runtime_SetDebugEventListener(Arguments args) { | 7834 static MaybeObject* Runtime_SetDebugEventListener(Arguments args) { |
| 7708 ASSERT(args.length() == 2); | 7835 ASSERT(args.length() == 2); |
| 7709 RUNTIME_ASSERT(args[0]->IsJSFunction() || | 7836 RUNTIME_ASSERT(args[0]->IsJSFunction() || |
| 7710 args[0]->IsUndefined() || | 7837 args[0]->IsUndefined() || |
| 7711 args[0]->IsNull()); | 7838 args[0]->IsNull()); |
| 7712 Handle<Object> callback = args.at<Object>(0); | 7839 Handle<Object> callback = args.at<Object>(0); |
| 7713 Handle<Object> data = args.at<Object>(1); | 7840 Handle<Object> data = args.at<Object>(1); |
| 7714 Debugger::SetEventListener(callback, data); | 7841 Debugger::SetEventListener(callback, data); |
| 7715 | 7842 |
| 7716 return Heap::undefined_value(); | 7843 return Heap::undefined_value(); |
| 7717 } | 7844 } |
| 7718 | 7845 |
| 7719 | 7846 |
| 7720 static Object* Runtime_Break(Arguments args) { | 7847 static MaybeObject* Runtime_Break(Arguments args) { |
| 7721 ASSERT(args.length() == 0); | 7848 ASSERT(args.length() == 0); |
| 7722 StackGuard::DebugBreak(); | 7849 StackGuard::DebugBreak(); |
| 7723 return Heap::undefined_value(); | 7850 return Heap::undefined_value(); |
| 7724 } | 7851 } |
| 7725 | 7852 |
| 7726 | 7853 |
| 7727 static Object* DebugLookupResultValue(Object* receiver, String* name, | 7854 static MaybeObject* DebugLookupResultValue(Object* receiver, String* name, |
| 7728 LookupResult* result, | 7855 LookupResult* result, |
| 7729 bool* caught_exception) { | 7856 bool* caught_exception) { |
| 7730 Object* value; | 7857 Object* value; |
| 7731 switch (result->type()) { | 7858 switch (result->type()) { |
| 7732 case NORMAL: | 7859 case NORMAL: |
| 7733 value = result->holder()->GetNormalizedProperty(result); | 7860 value = result->holder()->GetNormalizedProperty(result); |
| 7734 if (value->IsTheHole()) { | 7861 if (value->IsTheHole()) { |
| 7735 return Heap::undefined_value(); | 7862 return Heap::undefined_value(); |
| 7736 } | 7863 } |
| 7737 return value; | 7864 return value; |
| 7738 case FIELD: | 7865 case FIELD: |
| 7739 value = | 7866 value = |
| 7740 JSObject::cast( | 7867 JSObject::cast( |
| 7741 result->holder())->FastPropertyAt(result->GetFieldIndex()); | 7868 result->holder())->FastPropertyAt(result->GetFieldIndex()); |
| 7742 if (value->IsTheHole()) { | 7869 if (value->IsTheHole()) { |
| 7743 return Heap::undefined_value(); | 7870 return Heap::undefined_value(); |
| 7744 } | 7871 } |
| 7745 return value; | 7872 return value; |
| 7746 case CONSTANT_FUNCTION: | 7873 case CONSTANT_FUNCTION: |
| 7747 return result->GetConstantFunction(); | 7874 return result->GetConstantFunction(); |
| 7748 case CALLBACKS: { | 7875 case CALLBACKS: { |
| 7749 Object* structure = result->GetCallbackObject(); | 7876 Object* structure = result->GetCallbackObject(); |
| 7750 if (structure->IsProxy() || structure->IsAccessorInfo()) { | 7877 if (structure->IsProxy() || structure->IsAccessorInfo()) { |
| 7751 value = receiver->GetPropertyWithCallback( | 7878 MaybeObject* maybe_value = receiver->GetPropertyWithCallback( |
| 7752 receiver, structure, name, result->holder()); | 7879 receiver, structure, name, result->holder()); |
| 7753 if (value->IsException()) { | 7880 if (!maybe_value->ToObject(&value)) { |
| 7754 value = Top::pending_exception(); | 7881 ASSERT(maybe_value->IsException()); |
| 7882 maybe_value = Top::pending_exception(); |
| 7755 Top::clear_pending_exception(); | 7883 Top::clear_pending_exception(); |
| 7756 if (caught_exception != NULL) { | 7884 if (caught_exception != NULL) { |
| 7757 *caught_exception = true; | 7885 *caught_exception = true; |
| 7758 } | 7886 } |
| 7887 return maybe_value; |
| 7759 } | 7888 } |
| 7760 return value; | 7889 return value; |
| 7761 } else { | 7890 } else { |
| 7762 return Heap::undefined_value(); | 7891 return Heap::undefined_value(); |
| 7763 } | 7892 } |
| 7764 } | 7893 } |
| 7765 case INTERCEPTOR: | 7894 case INTERCEPTOR: |
| 7766 case MAP_TRANSITION: | 7895 case MAP_TRANSITION: |
| 7767 case CONSTANT_TRANSITION: | 7896 case CONSTANT_TRANSITION: |
| 7768 case NULL_DESCRIPTOR: | 7897 case NULL_DESCRIPTOR: |
| (...skipping 11 matching lines...) Expand all Loading... |
| 7780 // args[1]: name of the property | 7909 // args[1]: name of the property |
| 7781 // | 7910 // |
| 7782 // The array returned contains the following information: | 7911 // The array returned contains the following information: |
| 7783 // 0: Property value | 7912 // 0: Property value |
| 7784 // 1: Property details | 7913 // 1: Property details |
| 7785 // 2: Property value is exception | 7914 // 2: Property value is exception |
| 7786 // 3: Getter function if defined | 7915 // 3: Getter function if defined |
| 7787 // 4: Setter function if defined | 7916 // 4: Setter function if defined |
| 7788 // Items 2-4 are only filled if the property has either a getter or a setter | 7917 // Items 2-4 are only filled if the property has either a getter or a setter |
| 7789 // defined through __defineGetter__ and/or __defineSetter__. | 7918 // defined through __defineGetter__ and/or __defineSetter__. |
| 7790 static Object* Runtime_DebugGetPropertyDetails(Arguments args) { | 7919 static MaybeObject* Runtime_DebugGetPropertyDetails(Arguments args) { |
| 7791 HandleScope scope; | 7920 HandleScope scope; |
| 7792 | 7921 |
| 7793 ASSERT(args.length() == 2); | 7922 ASSERT(args.length() == 2); |
| 7794 | 7923 |
| 7795 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 7924 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 7796 CONVERT_ARG_CHECKED(String, name, 1); | 7925 CONVERT_ARG_CHECKED(String, name, 1); |
| 7797 | 7926 |
| 7798 // Make sure to set the current context to the context before the debugger was | 7927 // 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 | 7928 // entered (if the debugger is entered). The reason for switching context here |
| 7800 // is that for some property lookups (accessors and interceptors) callbacks | 7929 // is that for some property lookups (accessors and interceptors) callbacks |
| (...skipping 10 matching lines...) Expand all Loading... |
| 7811 if (obj->IsJSGlobalProxy()) { | 7940 if (obj->IsJSGlobalProxy()) { |
| 7812 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); | 7941 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); |
| 7813 } | 7942 } |
| 7814 | 7943 |
| 7815 | 7944 |
| 7816 // Check if the name is trivially convertible to an index and get the element | 7945 // Check if the name is trivially convertible to an index and get the element |
| 7817 // if so. | 7946 // if so. |
| 7818 uint32_t index; | 7947 uint32_t index; |
| 7819 if (name->AsArrayIndex(&index)) { | 7948 if (name->AsArrayIndex(&index)) { |
| 7820 Handle<FixedArray> details = Factory::NewFixedArray(2); | 7949 Handle<FixedArray> details = Factory::NewFixedArray(2); |
| 7821 Object* element_or_char = Runtime::GetElementOrCharAt(obj, index); | 7950 Object* element_or_char; |
| 7951 { MaybeObject* maybe_element_or_char = |
| 7952 Runtime::GetElementOrCharAt(obj, index); |
| 7953 if (!maybe_element_or_char->ToObject(&element_or_char)) { |
| 7954 return maybe_element_or_char; |
| 7955 } |
| 7956 } |
| 7822 details->set(0, element_or_char); | 7957 details->set(0, element_or_char); |
| 7823 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); | 7958 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); |
| 7824 return *Factory::NewJSArrayWithElements(details); | 7959 return *Factory::NewJSArrayWithElements(details); |
| 7825 } | 7960 } |
| 7826 | 7961 |
| 7827 // Find the number of objects making up this. | 7962 // Find the number of objects making up this. |
| 7828 int length = LocalPrototypeChainLength(*obj); | 7963 int length = LocalPrototypeChainLength(*obj); |
| 7829 | 7964 |
| 7830 // Try local lookup on each of the objects. | 7965 // Try local lookup on each of the objects. |
| 7831 Handle<JSObject> jsproto = obj; | 7966 Handle<JSObject> jsproto = obj; |
| 7832 for (int i = 0; i < length; i++) { | 7967 for (int i = 0; i < length; i++) { |
| 7833 LookupResult result; | 7968 LookupResult result; |
| 7834 jsproto->LocalLookup(*name, &result); | 7969 jsproto->LocalLookup(*name, &result); |
| 7835 if (result.IsProperty()) { | 7970 if (result.IsProperty()) { |
| 7836 // LookupResult is not GC safe as it holds raw object pointers. | 7971 // 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 | 7972 // GC can happen later in this code so put the required fields into |
| 7838 // local variables using handles when required for later use. | 7973 // local variables using handles when required for later use. |
| 7839 PropertyType result_type = result.type(); | 7974 PropertyType result_type = result.type(); |
| 7840 Handle<Object> result_callback_obj; | 7975 Handle<Object> result_callback_obj; |
| 7841 if (result_type == CALLBACKS) { | 7976 if (result_type == CALLBACKS) { |
| 7842 result_callback_obj = Handle<Object>(result.GetCallbackObject()); | 7977 result_callback_obj = Handle<Object>(result.GetCallbackObject()); |
| 7843 } | 7978 } |
| 7844 Smi* property_details = result.GetPropertyDetails().AsSmi(); | 7979 Smi* property_details = result.GetPropertyDetails().AsSmi(); |
| 7845 // DebugLookupResultValue can cause GC so details from LookupResult needs | 7980 // DebugLookupResultValue can cause GC so details from LookupResult needs |
| 7846 // to be copied to handles before this. | 7981 // to be copied to handles before this. |
| 7847 bool caught_exception = false; | 7982 bool caught_exception = false; |
| 7848 Object* raw_value = DebugLookupResultValue(*obj, *name, &result, | 7983 Object* raw_value; |
| 7849 &caught_exception); | 7984 { MaybeObject* maybe_raw_value = |
| 7850 if (raw_value->IsFailure()) return raw_value; | 7985 DebugLookupResultValue(*obj, *name, &result, &caught_exception); |
| 7986 if (!maybe_raw_value->ToObject(&raw_value)) return maybe_raw_value; |
| 7987 } |
| 7851 Handle<Object> value(raw_value); | 7988 Handle<Object> value(raw_value); |
| 7852 | 7989 |
| 7853 // If the callback object is a fixed array then it contains JavaScript | 7990 // If the callback object is a fixed array then it contains JavaScript |
| 7854 // getter and/or setter. | 7991 // getter and/or setter. |
| 7855 bool hasJavaScriptAccessors = result_type == CALLBACKS && | 7992 bool hasJavaScriptAccessors = result_type == CALLBACKS && |
| 7856 result_callback_obj->IsFixedArray(); | 7993 result_callback_obj->IsFixedArray(); |
| 7857 Handle<FixedArray> details = | 7994 Handle<FixedArray> details = |
| 7858 Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2); | 7995 Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2); |
| 7859 details->set(0, *value); | 7996 details->set(0, *value); |
| 7860 details->set(1, property_details); | 7997 details->set(1, property_details); |
| 7861 if (hasJavaScriptAccessors) { | 7998 if (hasJavaScriptAccessors) { |
| 7862 details->set(2, | 7999 details->set(2, |
| 7863 caught_exception ? Heap::true_value() | 8000 caught_exception ? Heap::true_value() |
| 7864 : Heap::false_value()); | 8001 : Heap::false_value()); |
| 7865 details->set(3, FixedArray::cast(*result_callback_obj)->get(0)); | 8002 details->set(3, FixedArray::cast(*result_callback_obj)->get(0)); |
| 7866 details->set(4, FixedArray::cast(*result_callback_obj)->get(1)); | 8003 details->set(4, FixedArray::cast(*result_callback_obj)->get(1)); |
| 7867 } | 8004 } |
| 7868 | 8005 |
| 7869 return *Factory::NewJSArrayWithElements(details); | 8006 return *Factory::NewJSArrayWithElements(details); |
| 7870 } | 8007 } |
| 7871 if (i < length - 1) { | 8008 if (i < length - 1) { |
| 7872 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | 8009 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); |
| 7873 } | 8010 } |
| 7874 } | 8011 } |
| 7875 | 8012 |
| 7876 return Heap::undefined_value(); | 8013 return Heap::undefined_value(); |
| 7877 } | 8014 } |
| 7878 | 8015 |
| 7879 | 8016 |
| 7880 static Object* Runtime_DebugGetProperty(Arguments args) { | 8017 static MaybeObject* Runtime_DebugGetProperty(Arguments args) { |
| 7881 HandleScope scope; | 8018 HandleScope scope; |
| 7882 | 8019 |
| 7883 ASSERT(args.length() == 2); | 8020 ASSERT(args.length() == 2); |
| 7884 | 8021 |
| 7885 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 8022 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 7886 CONVERT_ARG_CHECKED(String, name, 1); | 8023 CONVERT_ARG_CHECKED(String, name, 1); |
| 7887 | 8024 |
| 7888 LookupResult result; | 8025 LookupResult result; |
| 7889 obj->Lookup(*name, &result); | 8026 obj->Lookup(*name, &result); |
| 7890 if (result.IsProperty()) { | 8027 if (result.IsProperty()) { |
| 7891 return DebugLookupResultValue(*obj, *name, &result, NULL); | 8028 return DebugLookupResultValue(*obj, *name, &result, NULL); |
| 7892 } | 8029 } |
| 7893 return Heap::undefined_value(); | 8030 return Heap::undefined_value(); |
| 7894 } | 8031 } |
| 7895 | 8032 |
| 7896 | 8033 |
| 7897 // Return the property type calculated from the property details. | 8034 // Return the property type calculated from the property details. |
| 7898 // args[0]: smi with property details. | 8035 // args[0]: smi with property details. |
| 7899 static Object* Runtime_DebugPropertyTypeFromDetails(Arguments args) { | 8036 static MaybeObject* Runtime_DebugPropertyTypeFromDetails(Arguments args) { |
| 7900 ASSERT(args.length() == 1); | 8037 ASSERT(args.length() == 1); |
| 7901 CONVERT_CHECKED(Smi, details, args[0]); | 8038 CONVERT_CHECKED(Smi, details, args[0]); |
| 7902 PropertyType type = PropertyDetails(details).type(); | 8039 PropertyType type = PropertyDetails(details).type(); |
| 7903 return Smi::FromInt(static_cast<int>(type)); | 8040 return Smi::FromInt(static_cast<int>(type)); |
| 7904 } | 8041 } |
| 7905 | 8042 |
| 7906 | 8043 |
| 7907 // Return the property attribute calculated from the property details. | 8044 // Return the property attribute calculated from the property details. |
| 7908 // args[0]: smi with property details. | 8045 // args[0]: smi with property details. |
| 7909 static Object* Runtime_DebugPropertyAttributesFromDetails(Arguments args) { | 8046 static MaybeObject* Runtime_DebugPropertyAttributesFromDetails(Arguments args) { |
| 7910 ASSERT(args.length() == 1); | 8047 ASSERT(args.length() == 1); |
| 7911 CONVERT_CHECKED(Smi, details, args[0]); | 8048 CONVERT_CHECKED(Smi, details, args[0]); |
| 7912 PropertyAttributes attributes = PropertyDetails(details).attributes(); | 8049 PropertyAttributes attributes = PropertyDetails(details).attributes(); |
| 7913 return Smi::FromInt(static_cast<int>(attributes)); | 8050 return Smi::FromInt(static_cast<int>(attributes)); |
| 7914 } | 8051 } |
| 7915 | 8052 |
| 7916 | 8053 |
| 7917 // Return the property insertion index calculated from the property details. | 8054 // Return the property insertion index calculated from the property details. |
| 7918 // args[0]: smi with property details. | 8055 // args[0]: smi with property details. |
| 7919 static Object* Runtime_DebugPropertyIndexFromDetails(Arguments args) { | 8056 static MaybeObject* Runtime_DebugPropertyIndexFromDetails(Arguments args) { |
| 7920 ASSERT(args.length() == 1); | 8057 ASSERT(args.length() == 1); |
| 7921 CONVERT_CHECKED(Smi, details, args[0]); | 8058 CONVERT_CHECKED(Smi, details, args[0]); |
| 7922 int index = PropertyDetails(details).index(); | 8059 int index = PropertyDetails(details).index(); |
| 7923 return Smi::FromInt(index); | 8060 return Smi::FromInt(index); |
| 7924 } | 8061 } |
| 7925 | 8062 |
| 7926 | 8063 |
| 7927 // Return property value from named interceptor. | 8064 // Return property value from named interceptor. |
| 7928 // args[0]: object | 8065 // args[0]: object |
| 7929 // args[1]: property name | 8066 // args[1]: property name |
| 7930 static Object* Runtime_DebugNamedInterceptorPropertyValue(Arguments args) { | 8067 static MaybeObject* Runtime_DebugNamedInterceptorPropertyValue(Arguments args) { |
| 7931 HandleScope scope; | 8068 HandleScope scope; |
| 7932 ASSERT(args.length() == 2); | 8069 ASSERT(args.length() == 2); |
| 7933 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 8070 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 7934 RUNTIME_ASSERT(obj->HasNamedInterceptor()); | 8071 RUNTIME_ASSERT(obj->HasNamedInterceptor()); |
| 7935 CONVERT_ARG_CHECKED(String, name, 1); | 8072 CONVERT_ARG_CHECKED(String, name, 1); |
| 7936 | 8073 |
| 7937 PropertyAttributes attributes; | 8074 PropertyAttributes attributes; |
| 7938 return obj->GetPropertyWithInterceptor(*obj, *name, &attributes); | 8075 return obj->GetPropertyWithInterceptor(*obj, *name, &attributes); |
| 7939 } | 8076 } |
| 7940 | 8077 |
| 7941 | 8078 |
| 7942 // Return element value from indexed interceptor. | 8079 // Return element value from indexed interceptor. |
| 7943 // args[0]: object | 8080 // args[0]: object |
| 7944 // args[1]: index | 8081 // args[1]: index |
| 7945 static Object* Runtime_DebugIndexedInterceptorElementValue(Arguments args) { | 8082 static MaybeObject* Runtime_DebugIndexedInterceptorElementValue( |
| 8083 Arguments args) { |
| 7946 HandleScope scope; | 8084 HandleScope scope; |
| 7947 ASSERT(args.length() == 2); | 8085 ASSERT(args.length() == 2); |
| 7948 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 8086 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 7949 RUNTIME_ASSERT(obj->HasIndexedInterceptor()); | 8087 RUNTIME_ASSERT(obj->HasIndexedInterceptor()); |
| 7950 CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]); | 8088 CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]); |
| 7951 | 8089 |
| 7952 return obj->GetElementWithInterceptor(*obj, index); | 8090 return obj->GetElementWithInterceptor(*obj, index); |
| 7953 } | 8091 } |
| 7954 | 8092 |
| 7955 | 8093 |
| 7956 static Object* Runtime_CheckExecutionState(Arguments args) { | 8094 static MaybeObject* Runtime_CheckExecutionState(Arguments args) { |
| 7957 ASSERT(args.length() >= 1); | 8095 ASSERT(args.length() >= 1); |
| 7958 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); | 8096 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); |
| 7959 // Check that the break id is valid. | 8097 // Check that the break id is valid. |
| 7960 if (Debug::break_id() == 0 || break_id != Debug::break_id()) { | 8098 if (Debug::break_id() == 0 || break_id != Debug::break_id()) { |
| 7961 return Top::Throw(Heap::illegal_execution_state_symbol()); | 8099 return Top::Throw(Heap::illegal_execution_state_symbol()); |
| 7962 } | 8100 } |
| 7963 | 8101 |
| 7964 return Heap::true_value(); | 8102 return Heap::true_value(); |
| 7965 } | 8103 } |
| 7966 | 8104 |
| 7967 | 8105 |
| 7968 static Object* Runtime_GetFrameCount(Arguments args) { | 8106 static MaybeObject* Runtime_GetFrameCount(Arguments args) { |
| 7969 HandleScope scope; | 8107 HandleScope scope; |
| 7970 ASSERT(args.length() == 1); | 8108 ASSERT(args.length() == 1); |
| 7971 | 8109 |
| 7972 // Check arguments. | 8110 // Check arguments. |
| 7973 Object* result = Runtime_CheckExecutionState(args); | 8111 Object* result; |
| 7974 if (result->IsFailure()) return result; | 8112 { MaybeObject* maybe_result = Runtime_CheckExecutionState(args); |
| 8113 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 8114 } |
| 7975 | 8115 |
| 7976 // Count all frames which are relevant to debugging stack trace. | 8116 // Count all frames which are relevant to debugging stack trace. |
| 7977 int n = 0; | 8117 int n = 0; |
| 7978 StackFrame::Id id = Debug::break_frame_id(); | 8118 StackFrame::Id id = Debug::break_frame_id(); |
| 7979 if (id == StackFrame::NO_ID) { | 8119 if (id == StackFrame::NO_ID) { |
| 7980 // If there is no JavaScript stack frame count is 0. | 8120 // If there is no JavaScript stack frame count is 0. |
| 7981 return Smi::FromInt(0); | 8121 return Smi::FromInt(0); |
| 7982 } | 8122 } |
| 7983 for (JavaScriptFrameIterator it(id); !it.done(); it.Advance()) n++; | 8123 for (JavaScriptFrameIterator it(id); !it.done(); it.Advance()) n++; |
| 7984 return Smi::FromInt(n); | 8124 return Smi::FromInt(n); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 8006 // 2: Function | 8146 // 2: Function |
| 8007 // 3: Argument count | 8147 // 3: Argument count |
| 8008 // 4: Local count | 8148 // 4: Local count |
| 8009 // 5: Source position | 8149 // 5: Source position |
| 8010 // 6: Constructor call | 8150 // 6: Constructor call |
| 8011 // 7: Is at return | 8151 // 7: Is at return |
| 8012 // 8: Debugger frame | 8152 // 8: Debugger frame |
| 8013 // Arguments name, value | 8153 // Arguments name, value |
| 8014 // Locals name, value | 8154 // Locals name, value |
| 8015 // Return value if any | 8155 // Return value if any |
| 8016 static Object* Runtime_GetFrameDetails(Arguments args) { | 8156 static MaybeObject* Runtime_GetFrameDetails(Arguments args) { |
| 8017 HandleScope scope; | 8157 HandleScope scope; |
| 8018 ASSERT(args.length() == 2); | 8158 ASSERT(args.length() == 2); |
| 8019 | 8159 |
| 8020 // Check arguments. | 8160 // Check arguments. |
| 8021 Object* check = Runtime_CheckExecutionState(args); | 8161 Object* check; |
| 8022 if (check->IsFailure()) return check; | 8162 { MaybeObject* maybe_check = Runtime_CheckExecutionState(args); |
| 8163 if (!maybe_check->ToObject(&check)) return maybe_check; |
| 8164 } |
| 8023 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); | 8165 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); |
| 8024 | 8166 |
| 8025 // Find the relevant frame with the requested index. | 8167 // Find the relevant frame with the requested index. |
| 8026 StackFrame::Id id = Debug::break_frame_id(); | 8168 StackFrame::Id id = Debug::break_frame_id(); |
| 8027 if (id == StackFrame::NO_ID) { | 8169 if (id == StackFrame::NO_ID) { |
| 8028 // If there are no JavaScript stack frames return undefined. | 8170 // If there are no JavaScript stack frames return undefined. |
| 8029 return Heap::undefined_value(); | 8171 return Heap::undefined_value(); |
| 8030 } | 8172 } |
| 8031 int count = 0; | 8173 int count = 0; |
| 8032 JavaScriptFrameIterator it(id); | 8174 JavaScriptFrameIterator it(id); |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8313 // Check whether the arguments shadow object exists. | 8455 // Check whether the arguments shadow object exists. |
| 8314 int arguments_shadow_index = | 8456 int arguments_shadow_index = |
| 8315 shared->scope_info()->ContextSlotIndex(Heap::arguments_shadow_symbol(), | 8457 shared->scope_info()->ContextSlotIndex(Heap::arguments_shadow_symbol(), |
| 8316 NULL); | 8458 NULL); |
| 8317 if (arguments_shadow_index >= 0) { | 8459 if (arguments_shadow_index >= 0) { |
| 8318 // In this case all the arguments are available in the arguments shadow | 8460 // In this case all the arguments are available in the arguments shadow |
| 8319 // object. | 8461 // object. |
| 8320 Handle<JSObject> arguments_shadow( | 8462 Handle<JSObject> arguments_shadow( |
| 8321 JSObject::cast(context->get(arguments_shadow_index))); | 8463 JSObject::cast(context->get(arguments_shadow_index))); |
| 8322 for (int i = 0; i < scope_info.number_of_parameters(); ++i) { | 8464 for (int i = 0; i < scope_info.number_of_parameters(); ++i) { |
| 8465 // We don't expect exception-throwing getters on the arguments shadow. |
| 8466 Object* element = arguments_shadow->GetElement(i)->ToObjectUnchecked(); |
| 8323 SetProperty(closure_scope, | 8467 SetProperty(closure_scope, |
| 8324 scope_info.parameter_name(i), | 8468 scope_info.parameter_name(i), |
| 8325 Handle<Object>(arguments_shadow->GetElement(i)), NONE); | 8469 Handle<Object>(element), |
| 8470 NONE); |
| 8326 } | 8471 } |
| 8327 } | 8472 } |
| 8328 | 8473 |
| 8329 // Fill all context locals to the context extension. | 8474 // Fill all context locals to the context extension. |
| 8330 CopyContextLocalsToScopeObject(serialized_scope_info, scope_info, | 8475 CopyContextLocalsToScopeObject(serialized_scope_info, scope_info, |
| 8331 context, closure_scope); | 8476 context, closure_scope); |
| 8332 | 8477 |
| 8333 // Finally copy any properties from the function context extension. This will | 8478 // Finally copy any properties from the function context extension. This will |
| 8334 // be variables introduced by eval. | 8479 // be variables introduced by eval. |
| 8335 if (context->has_extension()) { | 8480 if (context->has_extension()) { |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8547 JavaScriptFrame* frame_; | 8692 JavaScriptFrame* frame_; |
| 8548 Handle<JSFunction> function_; | 8693 Handle<JSFunction> function_; |
| 8549 Handle<Context> context_; | 8694 Handle<Context> context_; |
| 8550 bool local_done_; | 8695 bool local_done_; |
| 8551 bool at_local_; | 8696 bool at_local_; |
| 8552 | 8697 |
| 8553 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); | 8698 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); |
| 8554 }; | 8699 }; |
| 8555 | 8700 |
| 8556 | 8701 |
| 8557 static Object* Runtime_GetScopeCount(Arguments args) { | 8702 static MaybeObject* Runtime_GetScopeCount(Arguments args) { |
| 8558 HandleScope scope; | 8703 HandleScope scope; |
| 8559 ASSERT(args.length() == 2); | 8704 ASSERT(args.length() == 2); |
| 8560 | 8705 |
| 8561 // Check arguments. | 8706 // Check arguments. |
| 8562 Object* check = Runtime_CheckExecutionState(args); | 8707 Object* check; |
| 8563 if (check->IsFailure()) return check; | 8708 { MaybeObject* maybe_check = Runtime_CheckExecutionState(args); |
| 8709 if (!maybe_check->ToObject(&check)) return maybe_check; |
| 8710 } |
| 8564 CONVERT_CHECKED(Smi, wrapped_id, args[1]); | 8711 CONVERT_CHECKED(Smi, wrapped_id, args[1]); |
| 8565 | 8712 |
| 8566 // Get the frame where the debugging is performed. | 8713 // Get the frame where the debugging is performed. |
| 8567 StackFrame::Id id = UnwrapFrameId(wrapped_id); | 8714 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
| 8568 JavaScriptFrameIterator it(id); | 8715 JavaScriptFrameIterator it(id); |
| 8569 JavaScriptFrame* frame = it.frame(); | 8716 JavaScriptFrame* frame = it.frame(); |
| 8570 | 8717 |
| 8571 // Count the visible scopes. | 8718 // Count the visible scopes. |
| 8572 int n = 0; | 8719 int n = 0; |
| 8573 for (ScopeIterator it(frame); !it.Done(); it.Next()) { | 8720 for (ScopeIterator it(frame); !it.Done(); it.Next()) { |
| 8574 n++; | 8721 n++; |
| 8575 } | 8722 } |
| 8576 | 8723 |
| 8577 return Smi::FromInt(n); | 8724 return Smi::FromInt(n); |
| 8578 } | 8725 } |
| 8579 | 8726 |
| 8580 | 8727 |
| 8581 static const int kScopeDetailsTypeIndex = 0; | 8728 static const int kScopeDetailsTypeIndex = 0; |
| 8582 static const int kScopeDetailsObjectIndex = 1; | 8729 static const int kScopeDetailsObjectIndex = 1; |
| 8583 static const int kScopeDetailsSize = 2; | 8730 static const int kScopeDetailsSize = 2; |
| 8584 | 8731 |
| 8585 // Return an array with scope details | 8732 // Return an array with scope details |
| 8586 // args[0]: number: break id | 8733 // args[0]: number: break id |
| 8587 // args[1]: number: frame index | 8734 // args[1]: number: frame index |
| 8588 // args[2]: number: scope index | 8735 // args[2]: number: scope index |
| 8589 // | 8736 // |
| 8590 // The array returned contains the following information: | 8737 // The array returned contains the following information: |
| 8591 // 0: Scope type | 8738 // 0: Scope type |
| 8592 // 1: Scope object | 8739 // 1: Scope object |
| 8593 static Object* Runtime_GetScopeDetails(Arguments args) { | 8740 static MaybeObject* Runtime_GetScopeDetails(Arguments args) { |
| 8594 HandleScope scope; | 8741 HandleScope scope; |
| 8595 ASSERT(args.length() == 3); | 8742 ASSERT(args.length() == 3); |
| 8596 | 8743 |
| 8597 // Check arguments. | 8744 // Check arguments. |
| 8598 Object* check = Runtime_CheckExecutionState(args); | 8745 Object* check; |
| 8599 if (check->IsFailure()) return check; | 8746 { MaybeObject* maybe_check = Runtime_CheckExecutionState(args); |
| 8747 if (!maybe_check->ToObject(&check)) return maybe_check; |
| 8748 } |
| 8600 CONVERT_CHECKED(Smi, wrapped_id, args[1]); | 8749 CONVERT_CHECKED(Smi, wrapped_id, args[1]); |
| 8601 CONVERT_NUMBER_CHECKED(int, index, Int32, args[2]); | 8750 CONVERT_NUMBER_CHECKED(int, index, Int32, args[2]); |
| 8602 | 8751 |
| 8603 // Get the frame where the debugging is performed. | 8752 // Get the frame where the debugging is performed. |
| 8604 StackFrame::Id id = UnwrapFrameId(wrapped_id); | 8753 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
| 8605 JavaScriptFrameIterator frame_it(id); | 8754 JavaScriptFrameIterator frame_it(id); |
| 8606 JavaScriptFrame* frame = frame_it.frame(); | 8755 JavaScriptFrame* frame = frame_it.frame(); |
| 8607 | 8756 |
| 8608 // Find the requested scope. | 8757 // Find the requested scope. |
| 8609 int n = 0; | 8758 int n = 0; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 8621 | 8770 |
| 8622 // Fill in scope details. | 8771 // Fill in scope details. |
| 8623 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type())); | 8772 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type())); |
| 8624 Handle<JSObject> scope_object = it.ScopeObject(); | 8773 Handle<JSObject> scope_object = it.ScopeObject(); |
| 8625 details->set(kScopeDetailsObjectIndex, *scope_object); | 8774 details->set(kScopeDetailsObjectIndex, *scope_object); |
| 8626 | 8775 |
| 8627 return *Factory::NewJSArrayWithElements(details); | 8776 return *Factory::NewJSArrayWithElements(details); |
| 8628 } | 8777 } |
| 8629 | 8778 |
| 8630 | 8779 |
| 8631 static Object* Runtime_DebugPrintScopes(Arguments args) { | 8780 static MaybeObject* Runtime_DebugPrintScopes(Arguments args) { |
| 8632 HandleScope scope; | 8781 HandleScope scope; |
| 8633 ASSERT(args.length() == 0); | 8782 ASSERT(args.length() == 0); |
| 8634 | 8783 |
| 8635 #ifdef DEBUG | 8784 #ifdef DEBUG |
| 8636 // Print the scopes for the top frame. | 8785 // Print the scopes for the top frame. |
| 8637 StackFrameLocator locator; | 8786 StackFrameLocator locator; |
| 8638 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); | 8787 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); |
| 8639 for (ScopeIterator it(frame); !it.Done(); it.Next()) { | 8788 for (ScopeIterator it(frame); !it.Done(); it.Next()) { |
| 8640 it.DebugPrint(); | 8789 it.DebugPrint(); |
| 8641 } | 8790 } |
| 8642 #endif | 8791 #endif |
| 8643 return Heap::undefined_value(); | 8792 return Heap::undefined_value(); |
| 8644 } | 8793 } |
| 8645 | 8794 |
| 8646 | 8795 |
| 8647 static Object* Runtime_GetCFrames(Arguments args) { | 8796 static MaybeObject* Runtime_GetCFrames(Arguments args) { |
| 8648 HandleScope scope; | 8797 // 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(); | 8798 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 } | 8799 } |
| 8692 | 8800 |
| 8693 | 8801 |
| 8694 static Object* Runtime_GetThreadCount(Arguments args) { | 8802 static MaybeObject* Runtime_GetThreadCount(Arguments args) { |
| 8695 HandleScope scope; | 8803 HandleScope scope; |
| 8696 ASSERT(args.length() == 1); | 8804 ASSERT(args.length() == 1); |
| 8697 | 8805 |
| 8698 // Check arguments. | 8806 // Check arguments. |
| 8699 Object* result = Runtime_CheckExecutionState(args); | 8807 Object* result; |
| 8700 if (result->IsFailure()) return result; | 8808 { MaybeObject* maybe_result = Runtime_CheckExecutionState(args); |
| 8809 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 8810 } |
| 8701 | 8811 |
| 8702 // Count all archived V8 threads. | 8812 // Count all archived V8 threads. |
| 8703 int n = 0; | 8813 int n = 0; |
| 8704 for (ThreadState* thread = ThreadState::FirstInUse(); | 8814 for (ThreadState* thread = ThreadState::FirstInUse(); |
| 8705 thread != NULL; | 8815 thread != NULL; |
| 8706 thread = thread->Next()) { | 8816 thread = thread->Next()) { |
| 8707 n++; | 8817 n++; |
| 8708 } | 8818 } |
| 8709 | 8819 |
| 8710 // Total number of threads is current thread and archived threads. | 8820 // Total number of threads is current thread and archived threads. |
| 8711 return Smi::FromInt(n + 1); | 8821 return Smi::FromInt(n + 1); |
| 8712 } | 8822 } |
| 8713 | 8823 |
| 8714 | 8824 |
| 8715 static const int kThreadDetailsCurrentThreadIndex = 0; | 8825 static const int kThreadDetailsCurrentThreadIndex = 0; |
| 8716 static const int kThreadDetailsThreadIdIndex = 1; | 8826 static const int kThreadDetailsThreadIdIndex = 1; |
| 8717 static const int kThreadDetailsSize = 2; | 8827 static const int kThreadDetailsSize = 2; |
| 8718 | 8828 |
| 8719 // Return an array with thread details | 8829 // Return an array with thread details |
| 8720 // args[0]: number: break id | 8830 // args[0]: number: break id |
| 8721 // args[1]: number: thread index | 8831 // args[1]: number: thread index |
| 8722 // | 8832 // |
| 8723 // The array returned contains the following information: | 8833 // The array returned contains the following information: |
| 8724 // 0: Is current thread? | 8834 // 0: Is current thread? |
| 8725 // 1: Thread id | 8835 // 1: Thread id |
| 8726 static Object* Runtime_GetThreadDetails(Arguments args) { | 8836 static MaybeObject* Runtime_GetThreadDetails(Arguments args) { |
| 8727 HandleScope scope; | 8837 HandleScope scope; |
| 8728 ASSERT(args.length() == 2); | 8838 ASSERT(args.length() == 2); |
| 8729 | 8839 |
| 8730 // Check arguments. | 8840 // Check arguments. |
| 8731 Object* check = Runtime_CheckExecutionState(args); | 8841 Object* check; |
| 8732 if (check->IsFailure()) return check; | 8842 { MaybeObject* maybe_check = Runtime_CheckExecutionState(args); |
| 8843 if (!maybe_check->ToObject(&check)) return maybe_check; |
| 8844 } |
| 8733 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); | 8845 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); |
| 8734 | 8846 |
| 8735 // Allocate array for result. | 8847 // Allocate array for result. |
| 8736 Handle<FixedArray> details = Factory::NewFixedArray(kThreadDetailsSize); | 8848 Handle<FixedArray> details = Factory::NewFixedArray(kThreadDetailsSize); |
| 8737 | 8849 |
| 8738 // Thread index 0 is current thread. | 8850 // Thread index 0 is current thread. |
| 8739 if (index == 0) { | 8851 if (index == 0) { |
| 8740 // Fill the details. | 8852 // Fill the details. |
| 8741 details->set(kThreadDetailsCurrentThreadIndex, Heap::true_value()); | 8853 details->set(kThreadDetailsCurrentThreadIndex, Heap::true_value()); |
| 8742 details->set(kThreadDetailsThreadIdIndex, | 8854 details->set(kThreadDetailsThreadIdIndex, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 8758 details->set(kThreadDetailsThreadIdIndex, Smi::FromInt(thread->id())); | 8870 details->set(kThreadDetailsThreadIdIndex, Smi::FromInt(thread->id())); |
| 8759 } | 8871 } |
| 8760 | 8872 |
| 8761 // Convert to JS array and return. | 8873 // Convert to JS array and return. |
| 8762 return *Factory::NewJSArrayWithElements(details); | 8874 return *Factory::NewJSArrayWithElements(details); |
| 8763 } | 8875 } |
| 8764 | 8876 |
| 8765 | 8877 |
| 8766 // Sets the disable break state | 8878 // Sets the disable break state |
| 8767 // args[0]: disable break state | 8879 // args[0]: disable break state |
| 8768 static Object* Runtime_SetDisableBreak(Arguments args) { | 8880 static MaybeObject* Runtime_SetDisableBreak(Arguments args) { |
| 8769 HandleScope scope; | 8881 HandleScope scope; |
| 8770 ASSERT(args.length() == 1); | 8882 ASSERT(args.length() == 1); |
| 8771 CONVERT_BOOLEAN_CHECKED(disable_break, args[0]); | 8883 CONVERT_BOOLEAN_CHECKED(disable_break, args[0]); |
| 8772 Debug::set_disable_break(disable_break); | 8884 Debug::set_disable_break(disable_break); |
| 8773 return Heap::undefined_value(); | 8885 return Heap::undefined_value(); |
| 8774 } | 8886 } |
| 8775 | 8887 |
| 8776 | 8888 |
| 8777 static Object* Runtime_GetBreakLocations(Arguments args) { | 8889 static MaybeObject* Runtime_GetBreakLocations(Arguments args) { |
| 8778 HandleScope scope; | 8890 HandleScope scope; |
| 8779 ASSERT(args.length() == 1); | 8891 ASSERT(args.length() == 1); |
| 8780 | 8892 |
| 8781 CONVERT_ARG_CHECKED(JSFunction, fun, 0); | 8893 CONVERT_ARG_CHECKED(JSFunction, fun, 0); |
| 8782 Handle<SharedFunctionInfo> shared(fun->shared()); | 8894 Handle<SharedFunctionInfo> shared(fun->shared()); |
| 8783 // Find the number of break points | 8895 // Find the number of break points |
| 8784 Handle<Object> break_locations = Debug::GetSourceBreakLocations(shared); | 8896 Handle<Object> break_locations = Debug::GetSourceBreakLocations(shared); |
| 8785 if (break_locations->IsUndefined()) return Heap::undefined_value(); | 8897 if (break_locations->IsUndefined()) return Heap::undefined_value(); |
| 8786 // Return array as JS array | 8898 // Return array as JS array |
| 8787 return *Factory::NewJSArrayWithElements( | 8899 return *Factory::NewJSArrayWithElements( |
| 8788 Handle<FixedArray>::cast(break_locations)); | 8900 Handle<FixedArray>::cast(break_locations)); |
| 8789 } | 8901 } |
| 8790 | 8902 |
| 8791 | 8903 |
| 8792 // Set a break point in a function | 8904 // Set a break point in a function |
| 8793 // args[0]: function | 8905 // args[0]: function |
| 8794 // args[1]: number: break source position (within the function source) | 8906 // args[1]: number: break source position (within the function source) |
| 8795 // args[2]: number: break point object | 8907 // args[2]: number: break point object |
| 8796 static Object* Runtime_SetFunctionBreakPoint(Arguments args) { | 8908 static MaybeObject* Runtime_SetFunctionBreakPoint(Arguments args) { |
| 8797 HandleScope scope; | 8909 HandleScope scope; |
| 8798 ASSERT(args.length() == 3); | 8910 ASSERT(args.length() == 3); |
| 8799 CONVERT_ARG_CHECKED(JSFunction, fun, 0); | 8911 CONVERT_ARG_CHECKED(JSFunction, fun, 0); |
| 8800 Handle<SharedFunctionInfo> shared(fun->shared()); | 8912 Handle<SharedFunctionInfo> shared(fun->shared()); |
| 8801 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); | 8913 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); |
| 8802 RUNTIME_ASSERT(source_position >= 0); | 8914 RUNTIME_ASSERT(source_position >= 0); |
| 8803 Handle<Object> break_point_object_arg = args.at<Object>(2); | 8915 Handle<Object> break_point_object_arg = args.at<Object>(2); |
| 8804 | 8916 |
| 8805 // Set break point. | 8917 // Set break point. |
| 8806 Debug::SetBreakPoint(shared, break_point_object_arg, &source_position); | 8918 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; | 8997 return *target; |
| 8886 } | 8998 } |
| 8887 | 8999 |
| 8888 | 9000 |
| 8889 // Changes the state of a break point in a script and returns source position | 9001 // 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 | 9002 // where break point was set. NOTE: Regarding performance see the NOTE for |
| 8891 // GetScriptFromScriptData. | 9003 // GetScriptFromScriptData. |
| 8892 // args[0]: script to set break point in | 9004 // args[0]: script to set break point in |
| 8893 // args[1]: number: break source position (within the script source) | 9005 // args[1]: number: break source position (within the script source) |
| 8894 // args[2]: number: break point object | 9006 // args[2]: number: break point object |
| 8895 static Object* Runtime_SetScriptBreakPoint(Arguments args) { | 9007 static MaybeObject* Runtime_SetScriptBreakPoint(Arguments args) { |
| 8896 HandleScope scope; | 9008 HandleScope scope; |
| 8897 ASSERT(args.length() == 3); | 9009 ASSERT(args.length() == 3); |
| 8898 CONVERT_ARG_CHECKED(JSValue, wrapper, 0); | 9010 CONVERT_ARG_CHECKED(JSValue, wrapper, 0); |
| 8899 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); | 9011 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); |
| 8900 RUNTIME_ASSERT(source_position >= 0); | 9012 RUNTIME_ASSERT(source_position >= 0); |
| 8901 Handle<Object> break_point_object_arg = args.at<Object>(2); | 9013 Handle<Object> break_point_object_arg = args.at<Object>(2); |
| 8902 | 9014 |
| 8903 // Get the script from the script wrapper. | 9015 // Get the script from the script wrapper. |
| 8904 RUNTIME_ASSERT(wrapper->value()->IsScript()); | 9016 RUNTIME_ASSERT(wrapper->value()->IsScript()); |
| 8905 Handle<Script> script(Script::cast(wrapper->value())); | 9017 Handle<Script> script(Script::cast(wrapper->value())); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 8919 Debug::SetBreakPoint(shared, break_point_object_arg, &position); | 9031 Debug::SetBreakPoint(shared, break_point_object_arg, &position); |
| 8920 position += shared->start_position(); | 9032 position += shared->start_position(); |
| 8921 return Smi::FromInt(position); | 9033 return Smi::FromInt(position); |
| 8922 } | 9034 } |
| 8923 return Heap::undefined_value(); | 9035 return Heap::undefined_value(); |
| 8924 } | 9036 } |
| 8925 | 9037 |
| 8926 | 9038 |
| 8927 // Clear a break point | 9039 // Clear a break point |
| 8928 // args[0]: number: break point object | 9040 // args[0]: number: break point object |
| 8929 static Object* Runtime_ClearBreakPoint(Arguments args) { | 9041 static MaybeObject* Runtime_ClearBreakPoint(Arguments args) { |
| 8930 HandleScope scope; | 9042 HandleScope scope; |
| 8931 ASSERT(args.length() == 1); | 9043 ASSERT(args.length() == 1); |
| 8932 Handle<Object> break_point_object_arg = args.at<Object>(0); | 9044 Handle<Object> break_point_object_arg = args.at<Object>(0); |
| 8933 | 9045 |
| 8934 // Clear break point. | 9046 // Clear break point. |
| 8935 Debug::ClearBreakPoint(break_point_object_arg); | 9047 Debug::ClearBreakPoint(break_point_object_arg); |
| 8936 | 9048 |
| 8937 return Heap::undefined_value(); | 9049 return Heap::undefined_value(); |
| 8938 } | 9050 } |
| 8939 | 9051 |
| 8940 | 9052 |
| 8941 // Change the state of break on exceptions. | 9053 // Change the state of break on exceptions. |
| 8942 // args[0]: Enum value indicating whether to affect caught/uncaught exceptions. | 9054 // args[0]: Enum value indicating whether to affect caught/uncaught exceptions. |
| 8943 // args[1]: Boolean indicating on/off. | 9055 // args[1]: Boolean indicating on/off. |
| 8944 static Object* Runtime_ChangeBreakOnException(Arguments args) { | 9056 static MaybeObject* Runtime_ChangeBreakOnException(Arguments args) { |
| 8945 HandleScope scope; | 9057 HandleScope scope; |
| 8946 ASSERT(args.length() == 2); | 9058 ASSERT(args.length() == 2); |
| 8947 RUNTIME_ASSERT(args[0]->IsNumber()); | 9059 RUNTIME_ASSERT(args[0]->IsNumber()); |
| 8948 CONVERT_BOOLEAN_CHECKED(enable, args[1]); | 9060 CONVERT_BOOLEAN_CHECKED(enable, args[1]); |
| 8949 | 9061 |
| 8950 // If the number doesn't match an enum value, the ChangeBreakOnException | 9062 // If the number doesn't match an enum value, the ChangeBreakOnException |
| 8951 // function will default to affecting caught exceptions. | 9063 // function will default to affecting caught exceptions. |
| 8952 ExceptionBreakType type = | 9064 ExceptionBreakType type = |
| 8953 static_cast<ExceptionBreakType>(NumberToUint32(args[0])); | 9065 static_cast<ExceptionBreakType>(NumberToUint32(args[0])); |
| 8954 // Update break point state. | 9066 // Update break point state. |
| 8955 Debug::ChangeBreakOnException(type, enable); | 9067 Debug::ChangeBreakOnException(type, enable); |
| 8956 return Heap::undefined_value(); | 9068 return Heap::undefined_value(); |
| 8957 } | 9069 } |
| 8958 | 9070 |
| 8959 | 9071 |
| 8960 // Returns the state of break on exceptions | 9072 // Returns the state of break on exceptions |
| 8961 // args[0]: boolean indicating uncaught exceptions | 9073 // args[0]: boolean indicating uncaught exceptions |
| 8962 static Object* Runtime_IsBreakOnException(Arguments args) { | 9074 static MaybeObject* Runtime_IsBreakOnException(Arguments args) { |
| 8963 HandleScope scope; | 9075 HandleScope scope; |
| 8964 ASSERT(args.length() == 1); | 9076 ASSERT(args.length() == 1); |
| 8965 RUNTIME_ASSERT(args[0]->IsNumber()); | 9077 RUNTIME_ASSERT(args[0]->IsNumber()); |
| 8966 | 9078 |
| 8967 ExceptionBreakType type = | 9079 ExceptionBreakType type = |
| 8968 static_cast<ExceptionBreakType>(NumberToUint32(args[0])); | 9080 static_cast<ExceptionBreakType>(NumberToUint32(args[0])); |
| 8969 bool result = Debug::IsBreakOnException(type); | 9081 bool result = Debug::IsBreakOnException(type); |
| 8970 return Smi::FromInt(result); | 9082 return Smi::FromInt(result); |
| 8971 } | 9083 } |
| 8972 | 9084 |
| 8973 | 9085 |
| 8974 // Prepare for stepping | 9086 // Prepare for stepping |
| 8975 // args[0]: break id for checking execution state | 9087 // args[0]: break id for checking execution state |
| 8976 // args[1]: step action from the enumeration StepAction | 9088 // 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 | 9089 // args[2]: number of times to perform the step, for step out it is the number |
| 8978 // of frames to step down. | 9090 // of frames to step down. |
| 8979 static Object* Runtime_PrepareStep(Arguments args) { | 9091 static MaybeObject* Runtime_PrepareStep(Arguments args) { |
| 8980 HandleScope scope; | 9092 HandleScope scope; |
| 8981 ASSERT(args.length() == 3); | 9093 ASSERT(args.length() == 3); |
| 8982 // Check arguments. | 9094 // Check arguments. |
| 8983 Object* check = Runtime_CheckExecutionState(args); | 9095 Object* check; |
| 8984 if (check->IsFailure()) return check; | 9096 { MaybeObject* maybe_check = Runtime_CheckExecutionState(args); |
| 9097 if (!maybe_check->ToObject(&check)) return maybe_check; |
| 9098 } |
| 8985 if (!args[1]->IsNumber() || !args[2]->IsNumber()) { | 9099 if (!args[1]->IsNumber() || !args[2]->IsNumber()) { |
| 8986 return Top::Throw(Heap::illegal_argument_symbol()); | 9100 return Top::Throw(Heap::illegal_argument_symbol()); |
| 8987 } | 9101 } |
| 8988 | 9102 |
| 8989 // Get the step action and check validity. | 9103 // Get the step action and check validity. |
| 8990 StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1])); | 9104 StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1])); |
| 8991 if (step_action != StepIn && | 9105 if (step_action != StepIn && |
| 8992 step_action != StepNext && | 9106 step_action != StepNext && |
| 8993 step_action != StepOut && | 9107 step_action != StepOut && |
| 8994 step_action != StepInMin && | 9108 step_action != StepInMin && |
| (...skipping 10 matching lines...) Expand all Loading... |
| 9005 // Clear all current stepping setup. | 9119 // Clear all current stepping setup. |
| 9006 Debug::ClearStepping(); | 9120 Debug::ClearStepping(); |
| 9007 | 9121 |
| 9008 // Prepare step. | 9122 // Prepare step. |
| 9009 Debug::PrepareStep(static_cast<StepAction>(step_action), step_count); | 9123 Debug::PrepareStep(static_cast<StepAction>(step_action), step_count); |
| 9010 return Heap::undefined_value(); | 9124 return Heap::undefined_value(); |
| 9011 } | 9125 } |
| 9012 | 9126 |
| 9013 | 9127 |
| 9014 // Clear all stepping set by PrepareStep. | 9128 // Clear all stepping set by PrepareStep. |
| 9015 static Object* Runtime_ClearStepping(Arguments args) { | 9129 static MaybeObject* Runtime_ClearStepping(Arguments args) { |
| 9016 HandleScope scope; | 9130 HandleScope scope; |
| 9017 ASSERT(args.length() == 0); | 9131 ASSERT(args.length() == 0); |
| 9018 Debug::ClearStepping(); | 9132 Debug::ClearStepping(); |
| 9019 return Heap::undefined_value(); | 9133 return Heap::undefined_value(); |
| 9020 } | 9134 } |
| 9021 | 9135 |
| 9022 | 9136 |
| 9023 // Creates a copy of the with context chain. The copy of the context chain is | 9137 // Creates a copy of the with context chain. The copy of the context chain is |
| 9024 // is linked to the function context supplied. | 9138 // is linked to the function context supplied. |
| 9025 static Handle<Context> CopyWithContextChain(Handle<Context> context_chain, | 9139 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 | 9196 // 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 | 9197 // 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 | 9198 // 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 | 9199 // 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) | 9200 // 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. | 9201 // 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 | 9202 // 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 | 9203 // 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 | 9204 // local variables as if the piece of JavaScript was evaluated at the point |
| 9091 // where the function on the stack frame is currently stopped. | 9205 // where the function on the stack frame is currently stopped. |
| 9092 static Object* Runtime_DebugEvaluate(Arguments args) { | 9206 static MaybeObject* Runtime_DebugEvaluate(Arguments args) { |
| 9093 HandleScope scope; | 9207 HandleScope scope; |
| 9094 | 9208 |
| 9095 // Check the execution state and decode arguments frame and source to be | 9209 // Check the execution state and decode arguments frame and source to be |
| 9096 // evaluated. | 9210 // evaluated. |
| 9097 ASSERT(args.length() == 4); | 9211 ASSERT(args.length() == 4); |
| 9098 Object* check_result = Runtime_CheckExecutionState(args); | 9212 Object* check_result; |
| 9099 if (check_result->IsFailure()) return check_result; | 9213 { MaybeObject* maybe_check_result = Runtime_CheckExecutionState(args); |
| 9214 if (!maybe_check_result->ToObject(&check_result)) { |
| 9215 return maybe_check_result; |
| 9216 } |
| 9217 } |
| 9100 CONVERT_CHECKED(Smi, wrapped_id, args[1]); | 9218 CONVERT_CHECKED(Smi, wrapped_id, args[1]); |
| 9101 CONVERT_ARG_CHECKED(String, source, 2); | 9219 CONVERT_ARG_CHECKED(String, source, 2); |
| 9102 CONVERT_BOOLEAN_CHECKED(disable_break, args[3]); | 9220 CONVERT_BOOLEAN_CHECKED(disable_break, args[3]); |
| 9103 | 9221 |
| 9104 // Handle the processing of break. | 9222 // Handle the processing of break. |
| 9105 DisableBreak disable_break_save(disable_break); | 9223 DisableBreak disable_break_save(disable_break); |
| 9106 | 9224 |
| 9107 // Get the frame where the debugging is performed. | 9225 // Get the frame where the debugging is performed. |
| 9108 StackFrame::Id id = UnwrapFrameId(wrapped_id); | 9226 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
| 9109 JavaScriptFrameIterator it(id); | 9227 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 | 9311 // Skip the global proxy as it has no properties and always delegates to the |
| 9194 // real global object. | 9312 // real global object. |
| 9195 if (result->IsJSGlobalProxy()) { | 9313 if (result->IsJSGlobalProxy()) { |
| 9196 result = Handle<JSObject>(JSObject::cast(result->GetPrototype())); | 9314 result = Handle<JSObject>(JSObject::cast(result->GetPrototype())); |
| 9197 } | 9315 } |
| 9198 | 9316 |
| 9199 return *result; | 9317 return *result; |
| 9200 } | 9318 } |
| 9201 | 9319 |
| 9202 | 9320 |
| 9203 static Object* Runtime_DebugEvaluateGlobal(Arguments args) { | 9321 static MaybeObject* Runtime_DebugEvaluateGlobal(Arguments args) { |
| 9204 HandleScope scope; | 9322 HandleScope scope; |
| 9205 | 9323 |
| 9206 // Check the execution state and decode arguments frame and source to be | 9324 // Check the execution state and decode arguments frame and source to be |
| 9207 // evaluated. | 9325 // evaluated. |
| 9208 ASSERT(args.length() == 3); | 9326 ASSERT(args.length() == 3); |
| 9209 Object* check_result = Runtime_CheckExecutionState(args); | 9327 Object* check_result; |
| 9210 if (check_result->IsFailure()) return check_result; | 9328 { MaybeObject* maybe_check_result = Runtime_CheckExecutionState(args); |
| 9329 if (!maybe_check_result->ToObject(&check_result)) { |
| 9330 return maybe_check_result; |
| 9331 } |
| 9332 } |
| 9211 CONVERT_ARG_CHECKED(String, source, 1); | 9333 CONVERT_ARG_CHECKED(String, source, 1); |
| 9212 CONVERT_BOOLEAN_CHECKED(disable_break, args[2]); | 9334 CONVERT_BOOLEAN_CHECKED(disable_break, args[2]); |
| 9213 | 9335 |
| 9214 // Handle the processing of break. | 9336 // Handle the processing of break. |
| 9215 DisableBreak disable_break_save(disable_break); | 9337 DisableBreak disable_break_save(disable_break); |
| 9216 | 9338 |
| 9217 // Enter the top context from before the debugger was invoked. | 9339 // Enter the top context from before the debugger was invoked. |
| 9218 SaveContext save; | 9340 SaveContext save; |
| 9219 SaveContext* top = &save; | 9341 SaveContext* top = &save; |
| 9220 while (top != NULL && *top->context() == *Debug::debug_context()) { | 9342 while (top != NULL && *top->context() == *Debug::debug_context()) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 9243 bool has_pending_exception; | 9365 bool has_pending_exception; |
| 9244 Handle<Object> receiver = Top::global(); | 9366 Handle<Object> receiver = Top::global(); |
| 9245 Handle<Object> result = | 9367 Handle<Object> result = |
| 9246 Execution::Call(compiled_function, receiver, 0, NULL, | 9368 Execution::Call(compiled_function, receiver, 0, NULL, |
| 9247 &has_pending_exception); | 9369 &has_pending_exception); |
| 9248 if (has_pending_exception) return Failure::Exception(); | 9370 if (has_pending_exception) return Failure::Exception(); |
| 9249 return *result; | 9371 return *result; |
| 9250 } | 9372 } |
| 9251 | 9373 |
| 9252 | 9374 |
| 9253 static Object* Runtime_DebugGetLoadedScripts(Arguments args) { | 9375 static MaybeObject* Runtime_DebugGetLoadedScripts(Arguments args) { |
| 9254 HandleScope scope; | 9376 HandleScope scope; |
| 9255 ASSERT(args.length() == 0); | 9377 ASSERT(args.length() == 0); |
| 9256 | 9378 |
| 9257 // Fill the script objects. | 9379 // Fill the script objects. |
| 9258 Handle<FixedArray> instances = Debug::GetLoadedScripts(); | 9380 Handle<FixedArray> instances = Debug::GetLoadedScripts(); |
| 9259 | 9381 |
| 9260 // Convert the script objects to proper JS objects. | 9382 // Convert the script objects to proper JS objects. |
| 9261 for (int i = 0; i < instances->length(); i++) { | 9383 for (int i = 0; i < instances->length(); i++) { |
| 9262 Handle<Script> script = Handle<Script>(Script::cast(instances->get(i))); | 9384 Handle<Script> script = Handle<Script>(Script::cast(instances->get(i))); |
| 9263 // Get the script wrapper in a local handle before calling GetScriptWrapper, | 9385 // 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 | 9465 |
| 9344 // Return the number of referencing objects found. | 9466 // Return the number of referencing objects found. |
| 9345 return count; | 9467 return count; |
| 9346 } | 9468 } |
| 9347 | 9469 |
| 9348 | 9470 |
| 9349 // Scan the heap for objects with direct references to an object | 9471 // Scan the heap for objects with direct references to an object |
| 9350 // args[0]: the object to find references to | 9472 // args[0]: the object to find references to |
| 9351 // args[1]: constructor function for instances to exclude (Mirror) | 9473 // args[1]: constructor function for instances to exclude (Mirror) |
| 9352 // args[2]: the the maximum number of objects to return | 9474 // args[2]: the the maximum number of objects to return |
| 9353 static Object* Runtime_DebugReferencedBy(Arguments args) { | 9475 static MaybeObject* Runtime_DebugReferencedBy(Arguments args) { |
| 9354 ASSERT(args.length() == 3); | 9476 ASSERT(args.length() == 3); |
| 9355 | 9477 |
| 9356 // First perform a full GC in order to avoid references from dead objects. | 9478 // First perform a full GC in order to avoid references from dead objects. |
| 9357 Heap::CollectAllGarbage(false); | 9479 Heap::CollectAllGarbage(false); |
| 9358 | 9480 |
| 9359 // Check parameters. | 9481 // Check parameters. |
| 9360 CONVERT_CHECKED(JSObject, target, args[0]); | 9482 CONVERT_CHECKED(JSObject, target, args[0]); |
| 9361 Object* instance_filter = args[1]; | 9483 Object* instance_filter = args[1]; |
| 9362 RUNTIME_ASSERT(instance_filter->IsUndefined() || | 9484 RUNTIME_ASSERT(instance_filter->IsUndefined() || |
| 9363 instance_filter->IsJSObject()); | 9485 instance_filter->IsJSObject()); |
| 9364 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]); | 9486 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]); |
| 9365 RUNTIME_ASSERT(max_references >= 0); | 9487 RUNTIME_ASSERT(max_references >= 0); |
| 9366 | 9488 |
| 9367 // Get the constructor function for context extension and arguments array. | 9489 // Get the constructor function for context extension and arguments array. |
| 9368 JSObject* arguments_boilerplate = | 9490 JSObject* arguments_boilerplate = |
| 9369 Top::context()->global_context()->arguments_boilerplate(); | 9491 Top::context()->global_context()->arguments_boilerplate(); |
| 9370 JSFunction* arguments_function = | 9492 JSFunction* arguments_function = |
| 9371 JSFunction::cast(arguments_boilerplate->map()->constructor()); | 9493 JSFunction::cast(arguments_boilerplate->map()->constructor()); |
| 9372 | 9494 |
| 9373 // Get the number of referencing objects. | 9495 // Get the number of referencing objects. |
| 9374 int count; | 9496 int count; |
| 9375 count = DebugReferencedBy(target, instance_filter, max_references, | 9497 count = DebugReferencedBy(target, instance_filter, max_references, |
| 9376 NULL, 0, arguments_function); | 9498 NULL, 0, arguments_function); |
| 9377 | 9499 |
| 9378 // Allocate an array to hold the result. | 9500 // Allocate an array to hold the result. |
| 9379 Object* object = Heap::AllocateFixedArray(count); | 9501 Object* object; |
| 9380 if (object->IsFailure()) return object; | 9502 { MaybeObject* maybe_object = Heap::AllocateFixedArray(count); |
| 9503 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 9504 } |
| 9381 FixedArray* instances = FixedArray::cast(object); | 9505 FixedArray* instances = FixedArray::cast(object); |
| 9382 | 9506 |
| 9383 // Fill the referencing objects. | 9507 // Fill the referencing objects. |
| 9384 count = DebugReferencedBy(target, instance_filter, max_references, | 9508 count = DebugReferencedBy(target, instance_filter, max_references, |
| 9385 instances, count, arguments_function); | 9509 instances, count, arguments_function); |
| 9386 | 9510 |
| 9387 // Return result as JS array. | 9511 // Return result as JS array. |
| 9388 Object* result = | 9512 Object* result; |
| 9389 Heap::AllocateJSObject( | 9513 { MaybeObject* maybe_result = Heap::AllocateJSObject( |
| 9390 Top::context()->global_context()->array_function()); | 9514 Top::context()->global_context()->array_function()); |
| 9391 if (!result->IsFailure()) JSArray::cast(result)->SetContent(instances); | 9515 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 9516 } |
| 9517 JSArray::cast(result)->SetContent(instances); |
| 9392 return result; | 9518 return result; |
| 9393 } | 9519 } |
| 9394 | 9520 |
| 9395 | 9521 |
| 9396 // Helper function used by Runtime_DebugConstructedBy below. | 9522 // Helper function used by Runtime_DebugConstructedBy below. |
| 9397 static int DebugConstructedBy(JSFunction* constructor, int max_references, | 9523 static int DebugConstructedBy(JSFunction* constructor, int max_references, |
| 9398 FixedArray* instances, int instances_size) { | 9524 FixedArray* instances, int instances_size) { |
| 9399 AssertNoAllocation no_alloc; | 9525 AssertNoAllocation no_alloc; |
| 9400 | 9526 |
| 9401 // Iterate the heap. | 9527 // Iterate the heap. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 9419 } | 9545 } |
| 9420 | 9546 |
| 9421 // Return the number of referencing objects found. | 9547 // Return the number of referencing objects found. |
| 9422 return count; | 9548 return count; |
| 9423 } | 9549 } |
| 9424 | 9550 |
| 9425 | 9551 |
| 9426 // Scan the heap for objects constructed by a specific function. | 9552 // Scan the heap for objects constructed by a specific function. |
| 9427 // args[0]: the constructor to find instances of | 9553 // args[0]: the constructor to find instances of |
| 9428 // args[1]: the the maximum number of objects to return | 9554 // args[1]: the the maximum number of objects to return |
| 9429 static Object* Runtime_DebugConstructedBy(Arguments args) { | 9555 static MaybeObject* Runtime_DebugConstructedBy(Arguments args) { |
| 9430 ASSERT(args.length() == 2); | 9556 ASSERT(args.length() == 2); |
| 9431 | 9557 |
| 9432 // First perform a full GC in order to avoid dead objects. | 9558 // First perform a full GC in order to avoid dead objects. |
| 9433 Heap::CollectAllGarbage(false); | 9559 Heap::CollectAllGarbage(false); |
| 9434 | 9560 |
| 9435 // Check parameters. | 9561 // Check parameters. |
| 9436 CONVERT_CHECKED(JSFunction, constructor, args[0]); | 9562 CONVERT_CHECKED(JSFunction, constructor, args[0]); |
| 9437 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]); | 9563 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]); |
| 9438 RUNTIME_ASSERT(max_references >= 0); | 9564 RUNTIME_ASSERT(max_references >= 0); |
| 9439 | 9565 |
| 9440 // Get the number of referencing objects. | 9566 // Get the number of referencing objects. |
| 9441 int count; | 9567 int count; |
| 9442 count = DebugConstructedBy(constructor, max_references, NULL, 0); | 9568 count = DebugConstructedBy(constructor, max_references, NULL, 0); |
| 9443 | 9569 |
| 9444 // Allocate an array to hold the result. | 9570 // Allocate an array to hold the result. |
| 9445 Object* object = Heap::AllocateFixedArray(count); | 9571 Object* object; |
| 9446 if (object->IsFailure()) return object; | 9572 { MaybeObject* maybe_object = Heap::AllocateFixedArray(count); |
| 9573 if (!maybe_object->ToObject(&object)) return maybe_object; |
| 9574 } |
| 9447 FixedArray* instances = FixedArray::cast(object); | 9575 FixedArray* instances = FixedArray::cast(object); |
| 9448 | 9576 |
| 9449 // Fill the referencing objects. | 9577 // Fill the referencing objects. |
| 9450 count = DebugConstructedBy(constructor, max_references, instances, count); | 9578 count = DebugConstructedBy(constructor, max_references, instances, count); |
| 9451 | 9579 |
| 9452 // Return result as JS array. | 9580 // Return result as JS array. |
| 9453 Object* result = | 9581 Object* result; |
| 9454 Heap::AllocateJSObject( | 9582 { MaybeObject* maybe_result = Heap::AllocateJSObject( |
| 9455 Top::context()->global_context()->array_function()); | 9583 Top::context()->global_context()->array_function()); |
| 9456 if (!result->IsFailure()) JSArray::cast(result)->SetContent(instances); | 9584 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 9585 } |
| 9586 JSArray::cast(result)->SetContent(instances); |
| 9457 return result; | 9587 return result; |
| 9458 } | 9588 } |
| 9459 | 9589 |
| 9460 | 9590 |
| 9461 // Find the effective prototype object as returned by __proto__. | 9591 // Find the effective prototype object as returned by __proto__. |
| 9462 // args[0]: the object to find the prototype for. | 9592 // args[0]: the object to find the prototype for. |
| 9463 static Object* Runtime_DebugGetPrototype(Arguments args) { | 9593 static MaybeObject* Runtime_DebugGetPrototype(Arguments args) { |
| 9464 ASSERT(args.length() == 1); | 9594 ASSERT(args.length() == 1); |
| 9465 | 9595 |
| 9466 CONVERT_CHECKED(JSObject, obj, args[0]); | 9596 CONVERT_CHECKED(JSObject, obj, args[0]); |
| 9467 | 9597 |
| 9468 // Use the __proto__ accessor. | 9598 // Use the __proto__ accessor. |
| 9469 return Accessors::ObjectPrototype.getter(obj, NULL); | 9599 return Accessors::ObjectPrototype.getter(obj, NULL); |
| 9470 } | 9600 } |
| 9471 | 9601 |
| 9472 | 9602 |
| 9473 static Object* Runtime_SystemBreak(Arguments args) { | 9603 static MaybeObject* Runtime_SystemBreak(Arguments args) { |
| 9474 ASSERT(args.length() == 0); | 9604 ASSERT(args.length() == 0); |
| 9475 CPU::DebugBreak(); | 9605 CPU::DebugBreak(); |
| 9476 return Heap::undefined_value(); | 9606 return Heap::undefined_value(); |
| 9477 } | 9607 } |
| 9478 | 9608 |
| 9479 | 9609 |
| 9480 static Object* Runtime_DebugDisassembleFunction(Arguments args) { | 9610 static MaybeObject* Runtime_DebugDisassembleFunction(Arguments args) { |
| 9481 #ifdef DEBUG | 9611 #ifdef DEBUG |
| 9482 HandleScope scope; | 9612 HandleScope scope; |
| 9483 ASSERT(args.length() == 1); | 9613 ASSERT(args.length() == 1); |
| 9484 // Get the function and make sure it is compiled. | 9614 // Get the function and make sure it is compiled. |
| 9485 CONVERT_ARG_CHECKED(JSFunction, func, 0); | 9615 CONVERT_ARG_CHECKED(JSFunction, func, 0); |
| 9486 Handle<SharedFunctionInfo> shared(func->shared()); | 9616 Handle<SharedFunctionInfo> shared(func->shared()); |
| 9487 if (!EnsureCompiled(shared, KEEP_EXCEPTION)) { | 9617 if (!EnsureCompiled(shared, KEEP_EXCEPTION)) { |
| 9488 return Failure::Exception(); | 9618 return Failure::Exception(); |
| 9489 } | 9619 } |
| 9490 func->code()->PrintLn(); | 9620 func->code()->PrintLn(); |
| 9491 #endif // DEBUG | 9621 #endif // DEBUG |
| 9492 return Heap::undefined_value(); | 9622 return Heap::undefined_value(); |
| 9493 } | 9623 } |
| 9494 | 9624 |
| 9495 | 9625 |
| 9496 static Object* Runtime_DebugDisassembleConstructor(Arguments args) { | 9626 static MaybeObject* Runtime_DebugDisassembleConstructor(Arguments args) { |
| 9497 #ifdef DEBUG | 9627 #ifdef DEBUG |
| 9498 HandleScope scope; | 9628 HandleScope scope; |
| 9499 ASSERT(args.length() == 1); | 9629 ASSERT(args.length() == 1); |
| 9500 // Get the function and make sure it is compiled. | 9630 // Get the function and make sure it is compiled. |
| 9501 CONVERT_ARG_CHECKED(JSFunction, func, 0); | 9631 CONVERT_ARG_CHECKED(JSFunction, func, 0); |
| 9502 Handle<SharedFunctionInfo> shared(func->shared()); | 9632 Handle<SharedFunctionInfo> shared(func->shared()); |
| 9503 if (!EnsureCompiled(shared, KEEP_EXCEPTION)) { | 9633 if (!EnsureCompiled(shared, KEEP_EXCEPTION)) { |
| 9504 return Failure::Exception(); | 9634 return Failure::Exception(); |
| 9505 } | 9635 } |
| 9506 shared->construct_stub()->PrintLn(); | 9636 shared->construct_stub()->PrintLn(); |
| 9507 #endif // DEBUG | 9637 #endif // DEBUG |
| 9508 return Heap::undefined_value(); | 9638 return Heap::undefined_value(); |
| 9509 } | 9639 } |
| 9510 | 9640 |
| 9511 | 9641 |
| 9512 static Object* Runtime_FunctionGetInferredName(Arguments args) { | 9642 static MaybeObject* Runtime_FunctionGetInferredName(Arguments args) { |
| 9513 NoHandleAllocation ha; | 9643 NoHandleAllocation ha; |
| 9514 ASSERT(args.length() == 1); | 9644 ASSERT(args.length() == 1); |
| 9515 | 9645 |
| 9516 CONVERT_CHECKED(JSFunction, f, args[0]); | 9646 CONVERT_CHECKED(JSFunction, f, args[0]); |
| 9517 return f->shared()->inferred_name(); | 9647 return f->shared()->inferred_name(); |
| 9518 } | 9648 } |
| 9519 | 9649 |
| 9520 | 9650 |
| 9521 static int FindSharedFunctionInfosForScript(Script* script, | 9651 static int FindSharedFunctionInfosForScript(Script* script, |
| 9522 FixedArray* buffer) { | 9652 FixedArray* buffer) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 9538 buffer->set(counter, shared); | 9668 buffer->set(counter, shared); |
| 9539 } | 9669 } |
| 9540 counter++; | 9670 counter++; |
| 9541 } | 9671 } |
| 9542 return counter; | 9672 return counter; |
| 9543 } | 9673 } |
| 9544 | 9674 |
| 9545 // For a script finds all SharedFunctionInfo's in the heap that points | 9675 // For a script finds all SharedFunctionInfo's in the heap that points |
| 9546 // to this script. Returns JSArray of SharedFunctionInfo wrapped | 9676 // to this script. Returns JSArray of SharedFunctionInfo wrapped |
| 9547 // in OpaqueReferences. | 9677 // in OpaqueReferences. |
| 9548 static Object* Runtime_LiveEditFindSharedFunctionInfosForScript( | 9678 static MaybeObject* Runtime_LiveEditFindSharedFunctionInfosForScript( |
| 9549 Arguments args) { | 9679 Arguments args) { |
| 9550 ASSERT(args.length() == 1); | 9680 ASSERT(args.length() == 1); |
| 9551 HandleScope scope; | 9681 HandleScope scope; |
| 9552 CONVERT_CHECKED(JSValue, script_value, args[0]); | 9682 CONVERT_CHECKED(JSValue, script_value, args[0]); |
| 9553 | 9683 |
| 9554 Handle<Script> script = Handle<Script>(Script::cast(script_value->value())); | 9684 Handle<Script> script = Handle<Script>(Script::cast(script_value->value())); |
| 9555 | 9685 |
| 9556 const int kBufferSize = 32; | 9686 const int kBufferSize = 32; |
| 9557 | 9687 |
| 9558 Handle<FixedArray> array; | 9688 Handle<FixedArray> array; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 9571 return *result; | 9701 return *result; |
| 9572 } | 9702 } |
| 9573 | 9703 |
| 9574 // For a script calculates compilation information about all its functions. | 9704 // For a script calculates compilation information about all its functions. |
| 9575 // The script source is explicitly specified by the second argument. | 9705 // 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 | 9706 // 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. | 9707 // all generated code keeps references to this particular instance of script. |
| 9578 // Returns a JSArray of compilation infos. The array is ordered so that | 9708 // 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 | 9709 // 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. | 9710 // with the function itself going first. The root function is a script function. |
| 9581 static Object* Runtime_LiveEditGatherCompileInfo(Arguments args) { | 9711 static MaybeObject* Runtime_LiveEditGatherCompileInfo(Arguments args) { |
| 9582 ASSERT(args.length() == 2); | 9712 ASSERT(args.length() == 2); |
| 9583 HandleScope scope; | 9713 HandleScope scope; |
| 9584 CONVERT_CHECKED(JSValue, script, args[0]); | 9714 CONVERT_CHECKED(JSValue, script, args[0]); |
| 9585 CONVERT_ARG_CHECKED(String, source, 1); | 9715 CONVERT_ARG_CHECKED(String, source, 1); |
| 9586 Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); | 9716 Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); |
| 9587 | 9717 |
| 9588 JSArray* result = LiveEdit::GatherCompileInfo(script_handle, source); | 9718 JSArray* result = LiveEdit::GatherCompileInfo(script_handle, source); |
| 9589 | 9719 |
| 9590 if (Top::has_pending_exception()) { | 9720 if (Top::has_pending_exception()) { |
| 9591 return Failure::Exception(); | 9721 return Failure::Exception(); |
| 9592 } | 9722 } |
| 9593 | 9723 |
| 9594 return result; | 9724 return result; |
| 9595 } | 9725 } |
| 9596 | 9726 |
| 9597 // Changes the source of the script to a new_source. | 9727 // 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 | 9728 // 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. | 9729 // the script with its original source and sends notification to debugger. |
| 9600 static Object* Runtime_LiveEditReplaceScript(Arguments args) { | 9730 static MaybeObject* Runtime_LiveEditReplaceScript(Arguments args) { |
| 9601 ASSERT(args.length() == 3); | 9731 ASSERT(args.length() == 3); |
| 9602 HandleScope scope; | 9732 HandleScope scope; |
| 9603 CONVERT_CHECKED(JSValue, original_script_value, args[0]); | 9733 CONVERT_CHECKED(JSValue, original_script_value, args[0]); |
| 9604 CONVERT_ARG_CHECKED(String, new_source, 1); | 9734 CONVERT_ARG_CHECKED(String, new_source, 1); |
| 9605 Handle<Object> old_script_name(args[2]); | 9735 Handle<Object> old_script_name(args[2]); |
| 9606 | 9736 |
| 9607 CONVERT_CHECKED(Script, original_script_pointer, | 9737 CONVERT_CHECKED(Script, original_script_pointer, |
| 9608 original_script_value->value()); | 9738 original_script_value->value()); |
| 9609 Handle<Script> original_script(original_script_pointer); | 9739 Handle<Script> original_script(original_script_pointer); |
| 9610 | 9740 |
| 9611 Object* old_script = LiveEdit::ChangeScriptSource(original_script, | 9741 Object* old_script = LiveEdit::ChangeScriptSource(original_script, |
| 9612 new_source, | 9742 new_source, |
| 9613 old_script_name); | 9743 old_script_name); |
| 9614 | 9744 |
| 9615 if (old_script->IsScript()) { | 9745 if (old_script->IsScript()) { |
| 9616 Handle<Script> script_handle(Script::cast(old_script)); | 9746 Handle<Script> script_handle(Script::cast(old_script)); |
| 9617 return *(GetScriptWrapper(script_handle)); | 9747 return *(GetScriptWrapper(script_handle)); |
| 9618 } else { | 9748 } else { |
| 9619 return Heap::null_value(); | 9749 return Heap::null_value(); |
| 9620 } | 9750 } |
| 9621 } | 9751 } |
| 9622 | 9752 |
| 9623 // Replaces code of SharedFunctionInfo with a new one. | 9753 // Replaces code of SharedFunctionInfo with a new one. |
| 9624 static Object* Runtime_LiveEditReplaceFunctionCode(Arguments args) { | 9754 static MaybeObject* Runtime_LiveEditReplaceFunctionCode(Arguments args) { |
| 9625 ASSERT(args.length() == 2); | 9755 ASSERT(args.length() == 2); |
| 9626 HandleScope scope; | 9756 HandleScope scope; |
| 9627 CONVERT_ARG_CHECKED(JSArray, new_compile_info, 0); | 9757 CONVERT_ARG_CHECKED(JSArray, new_compile_info, 0); |
| 9628 CONVERT_ARG_CHECKED(JSArray, shared_info, 1); | 9758 CONVERT_ARG_CHECKED(JSArray, shared_info, 1); |
| 9629 | 9759 |
| 9630 return LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info); | 9760 return LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info); |
| 9631 } | 9761 } |
| 9632 | 9762 |
| 9633 // Connects SharedFunctionInfo to another script. | 9763 // Connects SharedFunctionInfo to another script. |
| 9634 static Object* Runtime_LiveEditFunctionSetScript(Arguments args) { | 9764 static MaybeObject* Runtime_LiveEditFunctionSetScript(Arguments args) { |
| 9635 ASSERT(args.length() == 2); | 9765 ASSERT(args.length() == 2); |
| 9636 HandleScope scope; | 9766 HandleScope scope; |
| 9637 Handle<Object> function_object(args[0]); | 9767 Handle<Object> function_object(args[0]); |
| 9638 Handle<Object> script_object(args[1]); | 9768 Handle<Object> script_object(args[1]); |
| 9639 | 9769 |
| 9640 if (function_object->IsJSValue()) { | 9770 if (function_object->IsJSValue()) { |
| 9641 Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object); | 9771 Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object); |
| 9642 if (script_object->IsJSValue()) { | 9772 if (script_object->IsJSValue()) { |
| 9643 CONVERT_CHECKED(Script, script, JSValue::cast(*script_object)->value()); | 9773 CONVERT_CHECKED(Script, script, JSValue::cast(*script_object)->value()); |
| 9644 script_object = Handle<Object>(script); | 9774 script_object = Handle<Object>(script); |
| 9645 } | 9775 } |
| 9646 | 9776 |
| 9647 LiveEdit::SetFunctionScript(function_wrapper, script_object); | 9777 LiveEdit::SetFunctionScript(function_wrapper, script_object); |
| 9648 } else { | 9778 } else { |
| 9649 // Just ignore this. We may not have a SharedFunctionInfo for some functions | 9779 // Just ignore this. We may not have a SharedFunctionInfo for some functions |
| 9650 // and we check it in this function. | 9780 // and we check it in this function. |
| 9651 } | 9781 } |
| 9652 | 9782 |
| 9653 return Heap::undefined_value(); | 9783 return Heap::undefined_value(); |
| 9654 } | 9784 } |
| 9655 | 9785 |
| 9656 | 9786 |
| 9657 // In a code of a parent function replaces original function as embedded object | 9787 // In a code of a parent function replaces original function as embedded object |
| 9658 // with a substitution one. | 9788 // with a substitution one. |
| 9659 static Object* Runtime_LiveEditReplaceRefToNestedFunction(Arguments args) { | 9789 static MaybeObject* Runtime_LiveEditReplaceRefToNestedFunction(Arguments args) { |
| 9660 ASSERT(args.length() == 3); | 9790 ASSERT(args.length() == 3); |
| 9661 HandleScope scope; | 9791 HandleScope scope; |
| 9662 | 9792 |
| 9663 CONVERT_ARG_CHECKED(JSValue, parent_wrapper, 0); | 9793 CONVERT_ARG_CHECKED(JSValue, parent_wrapper, 0); |
| 9664 CONVERT_ARG_CHECKED(JSValue, orig_wrapper, 1); | 9794 CONVERT_ARG_CHECKED(JSValue, orig_wrapper, 1); |
| 9665 CONVERT_ARG_CHECKED(JSValue, subst_wrapper, 2); | 9795 CONVERT_ARG_CHECKED(JSValue, subst_wrapper, 2); |
| 9666 | 9796 |
| 9667 LiveEdit::ReplaceRefToNestedFunction(parent_wrapper, orig_wrapper, | 9797 LiveEdit::ReplaceRefToNestedFunction(parent_wrapper, orig_wrapper, |
| 9668 subst_wrapper); | 9798 subst_wrapper); |
| 9669 | 9799 |
| 9670 return Heap::undefined_value(); | 9800 return Heap::undefined_value(); |
| 9671 } | 9801 } |
| 9672 | 9802 |
| 9673 | 9803 |
| 9674 // Updates positions of a shared function info (first parameter) according | 9804 // Updates positions of a shared function info (first parameter) according |
| 9675 // to script source change. Text change is described in second parameter as | 9805 // to script source change. Text change is described in second parameter as |
| 9676 // array of groups of 3 numbers: | 9806 // array of groups of 3 numbers: |
| 9677 // (change_begin, change_end, change_end_new_position). | 9807 // (change_begin, change_end, change_end_new_position). |
| 9678 // Each group describes a change in text; groups are sorted by change_begin. | 9808 // Each group describes a change in text; groups are sorted by change_begin. |
| 9679 static Object* Runtime_LiveEditPatchFunctionPositions(Arguments args) { | 9809 static MaybeObject* Runtime_LiveEditPatchFunctionPositions(Arguments args) { |
| 9680 ASSERT(args.length() == 2); | 9810 ASSERT(args.length() == 2); |
| 9681 HandleScope scope; | 9811 HandleScope scope; |
| 9682 CONVERT_ARG_CHECKED(JSArray, shared_array, 0); | 9812 CONVERT_ARG_CHECKED(JSArray, shared_array, 0); |
| 9683 CONVERT_ARG_CHECKED(JSArray, position_change_array, 1); | 9813 CONVERT_ARG_CHECKED(JSArray, position_change_array, 1); |
| 9684 | 9814 |
| 9685 return LiveEdit::PatchFunctionPositions(shared_array, position_change_array); | 9815 return LiveEdit::PatchFunctionPositions(shared_array, position_change_array); |
| 9686 } | 9816 } |
| 9687 | 9817 |
| 9688 | 9818 |
| 9689 // For array of SharedFunctionInfo's (each wrapped in JSValue) | 9819 // For array of SharedFunctionInfo's (each wrapped in JSValue) |
| 9690 // checks that none of them have activations on stacks (of any thread). | 9820 // checks that none of them have activations on stacks (of any thread). |
| 9691 // Returns array of the same length with corresponding results of | 9821 // Returns array of the same length with corresponding results of |
| 9692 // LiveEdit::FunctionPatchabilityStatus type. | 9822 // LiveEdit::FunctionPatchabilityStatus type. |
| 9693 static Object* Runtime_LiveEditCheckAndDropActivations(Arguments args) { | 9823 static MaybeObject* Runtime_LiveEditCheckAndDropActivations(Arguments args) { |
| 9694 ASSERT(args.length() == 2); | 9824 ASSERT(args.length() == 2); |
| 9695 HandleScope scope; | 9825 HandleScope scope; |
| 9696 CONVERT_ARG_CHECKED(JSArray, shared_array, 0); | 9826 CONVERT_ARG_CHECKED(JSArray, shared_array, 0); |
| 9697 CONVERT_BOOLEAN_CHECKED(do_drop, args[1]); | 9827 CONVERT_BOOLEAN_CHECKED(do_drop, args[1]); |
| 9698 | 9828 |
| 9699 return *LiveEdit::CheckAndDropActivations(shared_array, do_drop); | 9829 return *LiveEdit::CheckAndDropActivations(shared_array, do_drop); |
| 9700 } | 9830 } |
| 9701 | 9831 |
| 9702 // Compares 2 strings line-by-line and returns diff in form of JSArray of | 9832 // 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. | 9833 // triplets (pos1, pos1_end, pos2_end) describing list of diff chunks. |
| 9704 static Object* Runtime_LiveEditCompareStringsLinewise(Arguments args) { | 9834 static MaybeObject* Runtime_LiveEditCompareStringsLinewise(Arguments args) { |
| 9705 ASSERT(args.length() == 2); | 9835 ASSERT(args.length() == 2); |
| 9706 HandleScope scope; | 9836 HandleScope scope; |
| 9707 CONVERT_ARG_CHECKED(String, s1, 0); | 9837 CONVERT_ARG_CHECKED(String, s1, 0); |
| 9708 CONVERT_ARG_CHECKED(String, s2, 1); | 9838 CONVERT_ARG_CHECKED(String, s2, 1); |
| 9709 | 9839 |
| 9710 return *LiveEdit::CompareStringsLinewise(s1, s2); | 9840 return *LiveEdit::CompareStringsLinewise(s1, s2); |
| 9711 } | 9841 } |
| 9712 | 9842 |
| 9713 | 9843 |
| 9714 | 9844 |
| 9715 // A testing entry. Returns statement position which is the closest to | 9845 // A testing entry. Returns statement position which is the closest to |
| 9716 // source_position. | 9846 // source_position. |
| 9717 static Object* Runtime_GetFunctionCodePositionFromSource(Arguments args) { | 9847 static MaybeObject* Runtime_GetFunctionCodePositionFromSource(Arguments args) { |
| 9718 ASSERT(args.length() == 2); | 9848 ASSERT(args.length() == 2); |
| 9719 HandleScope scope; | 9849 HandleScope scope; |
| 9720 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 9850 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
| 9721 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); | 9851 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); |
| 9722 | 9852 |
| 9723 Handle<Code> code(function->code()); | 9853 Handle<Code> code(function->code()); |
| 9724 | 9854 |
| 9725 RelocIterator it(*code, 1 << RelocInfo::STATEMENT_POSITION); | 9855 RelocIterator it(*code, 1 << RelocInfo::STATEMENT_POSITION); |
| 9726 int closest_pc = 0; | 9856 int closest_pc = 0; |
| 9727 int distance = kMaxInt; | 9857 int distance = kMaxInt; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 9739 it.next(); | 9869 it.next(); |
| 9740 } | 9870 } |
| 9741 | 9871 |
| 9742 return Smi::FromInt(closest_pc); | 9872 return Smi::FromInt(closest_pc); |
| 9743 } | 9873 } |
| 9744 | 9874 |
| 9745 | 9875 |
| 9746 // Calls specified function with or without entering the debugger. | 9876 // 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 | 9877 // 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. | 9878 // to have a stack with C++ frame in the middle. |
| 9749 static Object* Runtime_ExecuteInDebugContext(Arguments args) { | 9879 static MaybeObject* Runtime_ExecuteInDebugContext(Arguments args) { |
| 9750 ASSERT(args.length() == 2); | 9880 ASSERT(args.length() == 2); |
| 9751 HandleScope scope; | 9881 HandleScope scope; |
| 9752 CONVERT_ARG_CHECKED(JSFunction, function, 0); | 9882 CONVERT_ARG_CHECKED(JSFunction, function, 0); |
| 9753 CONVERT_BOOLEAN_CHECKED(without_debugger, args[1]); | 9883 CONVERT_BOOLEAN_CHECKED(without_debugger, args[1]); |
| 9754 | 9884 |
| 9755 Handle<Object> result; | 9885 Handle<Object> result; |
| 9756 bool pending_exception; | 9886 bool pending_exception; |
| 9757 { | 9887 { |
| 9758 if (without_debugger) { | 9888 if (without_debugger) { |
| 9759 result = Execution::Call(function, Top::global(), 0, NULL, | 9889 result = Execution::Call(function, Top::global(), 0, NULL, |
| 9760 &pending_exception); | 9890 &pending_exception); |
| 9761 } else { | 9891 } else { |
| 9762 EnterDebugger enter_debugger; | 9892 EnterDebugger enter_debugger; |
| 9763 result = Execution::Call(function, Top::global(), 0, NULL, | 9893 result = Execution::Call(function, Top::global(), 0, NULL, |
| 9764 &pending_exception); | 9894 &pending_exception); |
| 9765 } | 9895 } |
| 9766 } | 9896 } |
| 9767 if (!pending_exception) { | 9897 if (!pending_exception) { |
| 9768 return *result; | 9898 return *result; |
| 9769 } else { | 9899 } else { |
| 9770 return Failure::Exception(); | 9900 return Failure::Exception(); |
| 9771 } | 9901 } |
| 9772 } | 9902 } |
| 9773 | 9903 |
| 9774 | 9904 |
| 9775 #endif // ENABLE_DEBUGGER_SUPPORT | 9905 #endif // ENABLE_DEBUGGER_SUPPORT |
| 9776 | 9906 |
| 9777 #ifdef ENABLE_LOGGING_AND_PROFILING | 9907 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 9778 | 9908 |
| 9779 static Object* Runtime_ProfilerResume(Arguments args) { | 9909 static MaybeObject* Runtime_ProfilerResume(Arguments args) { |
| 9780 NoHandleAllocation ha; | 9910 NoHandleAllocation ha; |
| 9781 ASSERT(args.length() == 2); | 9911 ASSERT(args.length() == 2); |
| 9782 | 9912 |
| 9783 CONVERT_CHECKED(Smi, smi_modules, args[0]); | 9913 CONVERT_CHECKED(Smi, smi_modules, args[0]); |
| 9784 CONVERT_CHECKED(Smi, smi_tag, args[1]); | 9914 CONVERT_CHECKED(Smi, smi_tag, args[1]); |
| 9785 v8::V8::ResumeProfilerEx(smi_modules->value(), smi_tag->value()); | 9915 v8::V8::ResumeProfilerEx(smi_modules->value(), smi_tag->value()); |
| 9786 return Heap::undefined_value(); | 9916 return Heap::undefined_value(); |
| 9787 } | 9917 } |
| 9788 | 9918 |
| 9789 | 9919 |
| 9790 static Object* Runtime_ProfilerPause(Arguments args) { | 9920 static MaybeObject* Runtime_ProfilerPause(Arguments args) { |
| 9791 NoHandleAllocation ha; | 9921 NoHandleAllocation ha; |
| 9792 ASSERT(args.length() == 2); | 9922 ASSERT(args.length() == 2); |
| 9793 | 9923 |
| 9794 CONVERT_CHECKED(Smi, smi_modules, args[0]); | 9924 CONVERT_CHECKED(Smi, smi_modules, args[0]); |
| 9795 CONVERT_CHECKED(Smi, smi_tag, args[1]); | 9925 CONVERT_CHECKED(Smi, smi_tag, args[1]); |
| 9796 v8::V8::PauseProfilerEx(smi_modules->value(), smi_tag->value()); | 9926 v8::V8::PauseProfilerEx(smi_modules->value(), smi_tag->value()); |
| 9797 return Heap::undefined_value(); | 9927 return Heap::undefined_value(); |
| 9798 } | 9928 } |
| 9799 | 9929 |
| 9800 #endif // ENABLE_LOGGING_AND_PROFILING | 9930 #endif // ENABLE_LOGGING_AND_PROFILING |
| (...skipping 26 matching lines...) Expand all Loading... |
| 9827 if (script.is_null()) return Factory::undefined_value(); | 9957 if (script.is_null()) return Factory::undefined_value(); |
| 9828 | 9958 |
| 9829 // Return the script found. | 9959 // Return the script found. |
| 9830 return GetScriptWrapper(script); | 9960 return GetScriptWrapper(script); |
| 9831 } | 9961 } |
| 9832 | 9962 |
| 9833 | 9963 |
| 9834 // Get the script object from script data. NOTE: Regarding performance | 9964 // Get the script object from script data. NOTE: Regarding performance |
| 9835 // see the NOTE for GetScriptFromScriptData. | 9965 // see the NOTE for GetScriptFromScriptData. |
| 9836 // args[0]: script data for the script to find the source for | 9966 // args[0]: script data for the script to find the source for |
| 9837 static Object* Runtime_GetScript(Arguments args) { | 9967 static MaybeObject* Runtime_GetScript(Arguments args) { |
| 9838 HandleScope scope; | 9968 HandleScope scope; |
| 9839 | 9969 |
| 9840 ASSERT(args.length() == 1); | 9970 ASSERT(args.length() == 1); |
| 9841 | 9971 |
| 9842 CONVERT_CHECKED(String, script_name, args[0]); | 9972 CONVERT_CHECKED(String, script_name, args[0]); |
| 9843 | 9973 |
| 9844 // Find the requested script. | 9974 // Find the requested script. |
| 9845 Handle<Object> result = | 9975 Handle<Object> result = |
| 9846 Runtime_GetScriptFromScriptName(Handle<String>(script_name)); | 9976 Runtime_GetScriptFromScriptName(Handle<String>(script_name)); |
| 9847 return *result; | 9977 return *result; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 9872 // obvious builtin calls. Some builtin calls (such as Number.ADD | 10002 // obvious builtin calls. Some builtin calls (such as Number.ADD |
| 9873 // which is invoked using 'call') are very difficult to recognize | 10003 // which is invoked using 'call') are very difficult to recognize |
| 9874 // so we're leaving them in for now. | 10004 // so we're leaving them in for now. |
| 9875 return *seen_caller && !frame->receiver()->IsJSBuiltinsObject(); | 10005 return *seen_caller && !frame->receiver()->IsJSBuiltinsObject(); |
| 9876 } | 10006 } |
| 9877 | 10007 |
| 9878 | 10008 |
| 9879 // Collect the raw data for a stack trace. Returns an array of three | 10009 // Collect the raw data for a stack trace. Returns an array of three |
| 9880 // element segments each containing a receiver, function and native | 10010 // element segments each containing a receiver, function and native |
| 9881 // code offset. | 10011 // code offset. |
| 9882 static Object* Runtime_CollectStackTrace(Arguments args) { | 10012 static MaybeObject* Runtime_CollectStackTrace(Arguments args) { |
| 9883 ASSERT_EQ(args.length(), 2); | 10013 ASSERT_EQ(args.length(), 2); |
| 9884 Handle<Object> caller = args.at<Object>(0); | 10014 Handle<Object> caller = args.at<Object>(0); |
| 9885 CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[1]); | 10015 CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[1]); |
| 9886 | 10016 |
| 9887 HandleScope scope; | 10017 HandleScope scope; |
| 9888 | 10018 |
| 9889 limit = Max(limit, 0); // Ensure that limit is not negative. | 10019 limit = Max(limit, 0); // Ensure that limit is not negative. |
| 9890 int initial_size = Min(limit, 10); | 10020 int initial_size = Min(limit, 10); |
| 9891 Handle<JSArray> result = Factory::NewJSArray(initial_size * 3); | 10021 Handle<JSArray> result = Factory::NewJSArray(initial_size * 3); |
| 9892 | 10022 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 9922 } | 10052 } |
| 9923 iter.Advance(); | 10053 iter.Advance(); |
| 9924 } | 10054 } |
| 9925 | 10055 |
| 9926 result->set_length(Smi::FromInt(cursor)); | 10056 result->set_length(Smi::FromInt(cursor)); |
| 9927 return *result; | 10057 return *result; |
| 9928 } | 10058 } |
| 9929 | 10059 |
| 9930 | 10060 |
| 9931 // Returns V8 version as a string. | 10061 // Returns V8 version as a string. |
| 9932 static Object* Runtime_GetV8Version(Arguments args) { | 10062 static MaybeObject* Runtime_GetV8Version(Arguments args) { |
| 9933 ASSERT_EQ(args.length(), 0); | 10063 ASSERT_EQ(args.length(), 0); |
| 9934 | 10064 |
| 9935 NoHandleAllocation ha; | 10065 NoHandleAllocation ha; |
| 9936 | 10066 |
| 9937 const char* version_string = v8::V8::GetVersion(); | 10067 const char* version_string = v8::V8::GetVersion(); |
| 9938 | 10068 |
| 9939 return Heap::AllocateStringFromAscii(CStrVector(version_string), NOT_TENURED); | 10069 return Heap::AllocateStringFromAscii(CStrVector(version_string), NOT_TENURED); |
| 9940 } | 10070 } |
| 9941 | 10071 |
| 9942 | 10072 |
| 9943 static Object* Runtime_Abort(Arguments args) { | 10073 static MaybeObject* Runtime_Abort(Arguments args) { |
| 9944 ASSERT(args.length() == 2); | 10074 ASSERT(args.length() == 2); |
| 9945 OS::PrintError("abort: %s\n", reinterpret_cast<char*>(args[0]) + | 10075 OS::PrintError("abort: %s\n", reinterpret_cast<char*>(args[0]) + |
| 9946 Smi::cast(args[1])->value()); | 10076 Smi::cast(args[1])->value()); |
| 9947 Top::PrintStack(); | 10077 Top::PrintStack(); |
| 9948 OS::Abort(); | 10078 OS::Abort(); |
| 9949 UNREACHABLE(); | 10079 UNREACHABLE(); |
| 9950 return NULL; | 10080 return NULL; |
| 9951 } | 10081 } |
| 9952 | 10082 |
| 9953 | 10083 |
| 9954 static Object* CacheMiss(FixedArray* cache_obj, int index, Object* key_obj) { | 10084 MUST_USE_RESULT static MaybeObject* CacheMiss(FixedArray* cache_obj, |
| 10085 int index, |
| 10086 Object* key_obj) { |
| 9955 ASSERT(index % 2 == 0); // index of the key | 10087 ASSERT(index % 2 == 0); // index of the key |
| 9956 ASSERT(index >= JSFunctionResultCache::kEntriesIndex); | 10088 ASSERT(index >= JSFunctionResultCache::kEntriesIndex); |
| 9957 ASSERT(index < cache_obj->length()); | 10089 ASSERT(index < cache_obj->length()); |
| 9958 | 10090 |
| 9959 HandleScope scope; | 10091 HandleScope scope; |
| 9960 | 10092 |
| 9961 Handle<FixedArray> cache(cache_obj); | 10093 Handle<FixedArray> cache(cache_obj); |
| 9962 Handle<Object> key(key_obj); | 10094 Handle<Object> key(key_obj); |
| 9963 Handle<JSFunction> factory(JSFunction::cast( | 10095 Handle<JSFunction> factory(JSFunction::cast( |
| 9964 cache->get(JSFunctionResultCache::kFactoryIndex))); | 10096 cache->get(JSFunctionResultCache::kFactoryIndex))); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 9979 } | 10111 } |
| 9980 | 10112 |
| 9981 cache->set(index, *key); | 10113 cache->set(index, *key); |
| 9982 cache->set(index + 1, *value); | 10114 cache->set(index + 1, *value); |
| 9983 cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(index)); | 10115 cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(index)); |
| 9984 | 10116 |
| 9985 return *value; | 10117 return *value; |
| 9986 } | 10118 } |
| 9987 | 10119 |
| 9988 | 10120 |
| 9989 static Object* Runtime_GetFromCache(Arguments args) { | 10121 static MaybeObject* Runtime_GetFromCache(Arguments args) { |
| 9990 // This is only called from codegen, so checks might be more lax. | 10122 // This is only called from codegen, so checks might be more lax. |
| 9991 CONVERT_CHECKED(FixedArray, cache, args[0]); | 10123 CONVERT_CHECKED(FixedArray, cache, args[0]); |
| 9992 Object* key = args[1]; | 10124 Object* key = args[1]; |
| 9993 | 10125 |
| 9994 const int finger_index = | 10126 const int finger_index = |
| 9995 Smi::cast(cache->get(JSFunctionResultCache::kFingerIndex))->value(); | 10127 Smi::cast(cache->get(JSFunctionResultCache::kFingerIndex))->value(); |
| 9996 | 10128 |
| 9997 Object* o = cache->get(finger_index); | 10129 Object* o = cache->get(finger_index); |
| 9998 if (o == key) { | 10130 if (o == key) { |
| 9999 // The fastest case: hit the same place again. | 10131 // The fastest case: hit the same place again. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10032 if (target_index == cache->length()) { | 10164 if (target_index == cache->length()) { |
| 10033 target_index = JSFunctionResultCache::kEntriesIndex; | 10165 target_index = JSFunctionResultCache::kEntriesIndex; |
| 10034 } | 10166 } |
| 10035 return CacheMiss(cache, target_index, key); | 10167 return CacheMiss(cache, target_index, key); |
| 10036 } | 10168 } |
| 10037 } | 10169 } |
| 10038 | 10170 |
| 10039 #ifdef DEBUG | 10171 #ifdef DEBUG |
| 10040 // ListNatives is ONLY used by the fuzz-natives.js in debug mode | 10172 // ListNatives is ONLY used by the fuzz-natives.js in debug mode |
| 10041 // Exclude the code in release mode. | 10173 // Exclude the code in release mode. |
| 10042 static Object* Runtime_ListNatives(Arguments args) { | 10174 static MaybeObject* Runtime_ListNatives(Arguments args) { |
| 10043 ASSERT(args.length() == 0); | 10175 ASSERT(args.length() == 0); |
| 10044 HandleScope scope; | 10176 HandleScope scope; |
| 10045 Handle<JSArray> result = Factory::NewJSArray(0); | 10177 Handle<JSArray> result = Factory::NewJSArray(0); |
| 10046 int index = 0; | 10178 int index = 0; |
| 10047 bool inline_runtime_functions = false; | 10179 bool inline_runtime_functions = false; |
| 10048 #define ADD_ENTRY(Name, argc, ressize) \ | 10180 #define ADD_ENTRY(Name, argc, ressize) \ |
| 10049 { \ | 10181 { \ |
| 10050 HandleScope inner; \ | 10182 HandleScope inner; \ |
| 10051 Handle<String> name; \ | 10183 Handle<String> name; \ |
| 10052 /* Inline runtime functions have an underscore in front of the name. */ \ | 10184 /* Inline runtime functions have an underscore in front of the name. */ \ |
| (...skipping 13 matching lines...) Expand all Loading... |
| 10066 RUNTIME_FUNCTION_LIST(ADD_ENTRY) | 10198 RUNTIME_FUNCTION_LIST(ADD_ENTRY) |
| 10067 inline_runtime_functions = true; | 10199 inline_runtime_functions = true; |
| 10068 INLINE_FUNCTION_LIST(ADD_ENTRY) | 10200 INLINE_FUNCTION_LIST(ADD_ENTRY) |
| 10069 INLINE_RUNTIME_FUNCTION_LIST(ADD_ENTRY) | 10201 INLINE_RUNTIME_FUNCTION_LIST(ADD_ENTRY) |
| 10070 #undef ADD_ENTRY | 10202 #undef ADD_ENTRY |
| 10071 return *result; | 10203 return *result; |
| 10072 } | 10204 } |
| 10073 #endif | 10205 #endif |
| 10074 | 10206 |
| 10075 | 10207 |
| 10076 static Object* Runtime_Log(Arguments args) { | 10208 static MaybeObject* Runtime_Log(Arguments args) { |
| 10077 ASSERT(args.length() == 2); | 10209 ASSERT(args.length() == 2); |
| 10078 CONVERT_CHECKED(String, format, args[0]); | 10210 CONVERT_CHECKED(String, format, args[0]); |
| 10079 CONVERT_CHECKED(JSArray, elms, args[1]); | 10211 CONVERT_CHECKED(JSArray, elms, args[1]); |
| 10080 Vector<const char> chars = format->ToAsciiVector(); | 10212 Vector<const char> chars = format->ToAsciiVector(); |
| 10081 Logger::LogRuntime(chars, elms); | 10213 Logger::LogRuntime(chars, elms); |
| 10082 return Heap::undefined_value(); | 10214 return Heap::undefined_value(); |
| 10083 } | 10215 } |
| 10084 | 10216 |
| 10085 | 10217 |
| 10086 static Object* Runtime_IS_VAR(Arguments args) { | 10218 static MaybeObject* Runtime_IS_VAR(Arguments args) { |
| 10087 UNREACHABLE(); // implemented as macro in the parser | 10219 UNREACHABLE(); // implemented as macro in the parser |
| 10088 return NULL; | 10220 return NULL; |
| 10089 } | 10221 } |
| 10090 | 10222 |
| 10091 | 10223 |
| 10092 // ---------------------------------------------------------------------------- | 10224 // ---------------------------------------------------------------------------- |
| 10093 // Implementation of Runtime | 10225 // Implementation of Runtime |
| 10094 | 10226 |
| 10095 #define F(name, number_of_args, result_size) \ | 10227 #define F(name, number_of_args, result_size) \ |
| 10096 { Runtime::k##name, Runtime::RUNTIME, #name, \ | 10228 { Runtime::k##name, Runtime::RUNTIME, #name, \ |
| 10097 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size }, | 10229 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size }, |
| 10098 | 10230 |
| 10099 | 10231 |
| 10100 #define I(name, number_of_args, result_size) \ | 10232 #define I(name, number_of_args, result_size) \ |
| 10101 { Runtime::kInline##name, Runtime::INLINE, \ | 10233 { Runtime::kInline##name, Runtime::INLINE, \ |
| 10102 "_" #name, NULL, number_of_args, result_size }, | 10234 "_" #name, NULL, number_of_args, result_size }, |
| 10103 | 10235 |
| 10104 Runtime::Function kIntrinsicFunctions[] = { | 10236 Runtime::Function kIntrinsicFunctions[] = { |
| 10105 RUNTIME_FUNCTION_LIST(F) | 10237 RUNTIME_FUNCTION_LIST(F) |
| 10106 INLINE_FUNCTION_LIST(I) | 10238 INLINE_FUNCTION_LIST(I) |
| 10107 INLINE_RUNTIME_FUNCTION_LIST(I) | 10239 INLINE_RUNTIME_FUNCTION_LIST(I) |
| 10108 }; | 10240 }; |
| 10109 | 10241 |
| 10110 | 10242 |
| 10111 Object* Runtime::InitializeIntrinsicFunctionNames(Object* dictionary) { | 10243 MaybeObject* Runtime::InitializeIntrinsicFunctionNames(Object* dictionary) { |
| 10112 ASSERT(dictionary != NULL); | 10244 ASSERT(dictionary != NULL); |
| 10113 ASSERT(StringDictionary::cast(dictionary)->NumberOfElements() == 0); | 10245 ASSERT(StringDictionary::cast(dictionary)->NumberOfElements() == 0); |
| 10114 for (int i = 0; i < kNumFunctions; ++i) { | 10246 for (int i = 0; i < kNumFunctions; ++i) { |
| 10115 Object* name_symbol = Heap::LookupAsciiSymbol(kIntrinsicFunctions[i].name); | 10247 Object* name_symbol; |
| 10116 if (name_symbol->IsFailure()) return name_symbol; | 10248 { MaybeObject* maybe_name_symbol = |
| 10249 Heap::LookupAsciiSymbol(kIntrinsicFunctions[i].name); |
| 10250 if (!maybe_name_symbol->ToObject(&name_symbol)) return maybe_name_symbol; |
| 10251 } |
| 10117 StringDictionary* string_dictionary = StringDictionary::cast(dictionary); | 10252 StringDictionary* string_dictionary = StringDictionary::cast(dictionary); |
| 10118 dictionary = string_dictionary->Add(String::cast(name_symbol), | 10253 { MaybeObject* maybe_dictionary = string_dictionary->Add( |
| 10119 Smi::FromInt(i), | 10254 String::cast(name_symbol), |
| 10120 PropertyDetails(NONE, NORMAL)); | 10255 Smi::FromInt(i), |
| 10121 // Non-recoverable failure. Calling code must restart heap initialization. | 10256 PropertyDetails(NONE, NORMAL)); |
| 10122 if (dictionary->IsFailure()) return dictionary; | 10257 if (!maybe_dictionary->ToObject(&dictionary)) { |
| 10258 // Non-recoverable failure. Calling code must restart heap |
| 10259 // initialization. |
| 10260 return maybe_dictionary; |
| 10261 } |
| 10262 } |
| 10123 } | 10263 } |
| 10124 return dictionary; | 10264 return dictionary; |
| 10125 } | 10265 } |
| 10126 | 10266 |
| 10127 | 10267 |
| 10128 Runtime::Function* Runtime::FunctionForSymbol(Handle<String> name) { | 10268 Runtime::Function* Runtime::FunctionForSymbol(Handle<String> name) { |
| 10129 int entry = Heap::intrinsic_function_names()->FindEntry(*name); | 10269 int entry = Heap::intrinsic_function_names()->FindEntry(*name); |
| 10130 if (entry != kNotFound) { | 10270 if (entry != kNotFound) { |
| 10131 Object* smi_index = Heap::intrinsic_function_names()->ValueAt(entry); | 10271 Object* smi_index = Heap::intrinsic_function_names()->ValueAt(entry); |
| 10132 int function_index = Smi::cast(smi_index)->value(); | 10272 int function_index = Smi::cast(smi_index)->value(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 10150 } else { | 10290 } else { |
| 10151 // Handle last resort GC and make sure to allow future allocations | 10291 // Handle last resort GC and make sure to allow future allocations |
| 10152 // to grow the heap without causing GCs (if possible). | 10292 // to grow the heap without causing GCs (if possible). |
| 10153 Counters::gc_last_resort_from_js.Increment(); | 10293 Counters::gc_last_resort_from_js.Increment(); |
| 10154 Heap::CollectAllGarbage(false); | 10294 Heap::CollectAllGarbage(false); |
| 10155 } | 10295 } |
| 10156 } | 10296 } |
| 10157 | 10297 |
| 10158 | 10298 |
| 10159 } } // namespace v8::internal | 10299 } } // namespace v8::internal |
| OLD | NEW |