| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 static Object* Runtime_CloneObjectLiteralBoilerplate(Arguments args) { | 95 static Object* Runtime_CloneObjectLiteralBoilerplate(Arguments args) { |
| 96 CONVERT_CHECKED(JSObject, boilerplate, args[0]); | 96 CONVERT_CHECKED(JSObject, boilerplate, args[0]); |
| 97 return Heap::CopyJSObject(boilerplate); | 97 return Heap::CopyJSObject(boilerplate); |
| 98 } | 98 } |
| 99 | 99 |
| 100 | 100 |
| 101 static Handle<Map> ComputeObjectLiteralMap( | 101 static Handle<Map> ComputeObjectLiteralMap( |
| 102 Handle<Context> context, | 102 Handle<Context> context, |
| 103 Handle<FixedArray> constant_properties, | 103 Handle<FixedArray> constant_properties, |
| 104 bool* is_result_from_cache) { | 104 bool* is_result_from_cache) { |
| 105 int number_of_properties = constant_properties->length() / 2; |
| 105 if (FLAG_canonicalize_object_literal_maps) { | 106 if (FLAG_canonicalize_object_literal_maps) { |
| 106 // First find prefix of consecutive symbol keys. | 107 // First find prefix of consecutive symbol keys. |
| 107 int number_of_properties = constant_properties->length()/2; | |
| 108 int number_of_symbol_keys = 0; | 108 int number_of_symbol_keys = 0; |
| 109 while ((number_of_symbol_keys < number_of_properties) && | 109 while ((number_of_symbol_keys < number_of_properties) && |
| 110 (constant_properties->get(number_of_symbol_keys*2)->IsSymbol())) { | 110 (constant_properties->get(number_of_symbol_keys*2)->IsSymbol())) { |
| 111 number_of_symbol_keys++; | 111 number_of_symbol_keys++; |
| 112 } | 112 } |
| 113 // Based on the number of prefix symbols key we decide whether | 113 // Based on the number of prefix symbols key we decide whether |
| 114 // to use the map cache in the global context. | 114 // to use the map cache in the global context. |
| 115 const int kMaxKeys = 10; | 115 const int kMaxKeys = 10; |
| 116 if ((number_of_symbol_keys == number_of_properties) && | 116 if ((number_of_symbol_keys == number_of_properties) && |
| 117 (number_of_symbol_keys < kMaxKeys)) { | 117 (number_of_symbol_keys < kMaxKeys)) { |
| 118 // Create the fixed array with the key. | 118 // Create the fixed array with the key. |
| 119 Handle<FixedArray> keys = Factory::NewFixedArray(number_of_symbol_keys); | 119 Handle<FixedArray> keys = Factory::NewFixedArray(number_of_symbol_keys); |
| 120 for (int i = 0; i < number_of_symbol_keys; i++) { | 120 for (int i = 0; i < number_of_symbol_keys; i++) { |
| 121 keys->set(i, constant_properties->get(i*2)); | 121 keys->set(i, constant_properties->get(i*2)); |
| 122 } | 122 } |
| 123 *is_result_from_cache = true; | 123 *is_result_from_cache = true; |
| 124 return Factory::ObjectLiteralMapFromCache(context, keys); | 124 return Factory::ObjectLiteralMapFromCache(context, keys); |
| 125 } | 125 } |
| 126 } | 126 } |
| 127 *is_result_from_cache = false; | 127 *is_result_from_cache = false; |
| 128 return Handle<Map>(context->object_function()->initial_map()); | 128 return Factory::CopyMap( |
| 129 Handle<Map>(context->object_function()->initial_map()), |
| 130 number_of_properties); |
| 129 } | 131 } |
| 130 | 132 |
| 131 | 133 |
| 132 static Object* Runtime_CreateObjectLiteralBoilerplate(Arguments args) { | 134 static Object* Runtime_CreateObjectLiteralBoilerplate(Arguments args) { |
| 133 HandleScope scope; | 135 HandleScope scope; |
| 134 ASSERT(args.length() == 3); | 136 ASSERT(args.length() == 3); |
| 135 // Copy the arguments. | 137 // Copy the arguments. |
| 136 Handle<FixedArray> literals = args.at<FixedArray>(0); | 138 Handle<FixedArray> literals = args.at<FixedArray>(0); |
| 137 int literals_index = Smi::cast(args[1])->value(); | 139 int literals_index = Smi::cast(args[1])->value(); |
| 138 Handle<FixedArray> constant_properties = args.at<FixedArray>(2); | 140 Handle<FixedArray> constant_properties = args.at<FixedArray>(2); |
| (...skipping 4355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4494 } | 4496 } |
| 4495 | 4497 |
| 4496 | 4498 |
| 4497 static Object* Runtime_Break(Arguments args) { | 4499 static Object* Runtime_Break(Arguments args) { |
| 4498 ASSERT(args.length() == 0); | 4500 ASSERT(args.length() == 0); |
| 4499 StackGuard::DebugBreak(); | 4501 StackGuard::DebugBreak(); |
| 4500 return Heap::undefined_value(); | 4502 return Heap::undefined_value(); |
| 4501 } | 4503 } |
| 4502 | 4504 |
| 4503 | 4505 |
| 4504 static Object* DebugLookupResultValue(LookupResult* result) { | 4506 static Object* DebugLookupResultValue(Object* obj, String* name, |
| 4505 Object* value; | 4507 LookupResult* result, |
| 4508 bool* caught_exception) { |
| 4506 switch (result->type()) { | 4509 switch (result->type()) { |
| 4507 case NORMAL: { | 4510 case NORMAL: |
| 4508 Dictionary* dict = | 4511 case FIELD: |
| 4509 JSObject::cast(result->holder())->property_dictionary(); | 4512 case CONSTANT_FUNCTION: |
| 4510 value = dict->ValueAt(result->GetDictionaryEntry()); | 4513 return obj->GetProperty(name); |
| 4511 if (value->IsTheHole()) { | 4514 case CALLBACKS: { |
| 4512 return Heap::undefined_value(); | 4515 // Get the property value. If there is an exception it must be thown from |
| 4516 // a JavaScript getter. |
| 4517 Object* value; |
| 4518 value = obj->GetProperty(name); |
| 4519 if (value->IsException()) { |
| 4520 if (caught_exception != NULL) { |
| 4521 *caught_exception = true; |
| 4522 } |
| 4523 value = Top::pending_exception(); |
| 4524 Top::optional_reschedule_exception(true); |
| 4513 } | 4525 } |
| 4526 ASSERT(!Top::has_pending_exception()); |
| 4527 ASSERT(!Top::external_caught_exception()); |
| 4514 return value; | 4528 return value; |
| 4515 } | 4529 } |
| 4516 case FIELD: | |
| 4517 value = | |
| 4518 JSObject::cast( | |
| 4519 result->holder())->FastPropertyAt(result->GetFieldIndex()); | |
| 4520 if (value->IsTheHole()) { | |
| 4521 return Heap::undefined_value(); | |
| 4522 } | |
| 4523 return value; | |
| 4524 case CONSTANT_FUNCTION: | |
| 4525 return result->GetConstantFunction(); | |
| 4526 case CALLBACKS: | |
| 4527 case INTERCEPTOR: | 4530 case INTERCEPTOR: |
| 4531 return obj->GetProperty(name); |
| 4528 case MAP_TRANSITION: | 4532 case MAP_TRANSITION: |
| 4529 case CONSTANT_TRANSITION: | 4533 case CONSTANT_TRANSITION: |
| 4530 case NULL_DESCRIPTOR: | 4534 case NULL_DESCRIPTOR: |
| 4531 return Heap::undefined_value(); | 4535 return Heap::undefined_value(); |
| 4532 default: | 4536 default: |
| 4533 UNREACHABLE(); | 4537 UNREACHABLE(); |
| 4534 } | 4538 } |
| 4535 UNREACHABLE(); | 4539 UNREACHABLE(); |
| 4536 return Heap::undefined_value(); | 4540 return Heap::undefined_value(); |
| 4537 } | 4541 } |
| 4538 | 4542 |
| 4539 | 4543 |
| 4544 // Get debugger related details for an object property. |
| 4545 // args[0]: object holding property |
| 4546 // args[1]: name of the property |
| 4547 // |
| 4548 // The array returned contains the following information: |
| 4549 // 0: Property value |
| 4550 // 1: Property details |
| 4551 // 2: Property value is exception |
| 4552 // 3: Getter function if defined |
| 4553 // 4: Setter function if defined |
| 4554 // Items 2-4 are only filled if the property has either a getter or a setter |
| 4555 // defined through __defineGetter__ and/or __defineSetter__. |
| 4540 static Object* Runtime_DebugGetPropertyDetails(Arguments args) { | 4556 static Object* Runtime_DebugGetPropertyDetails(Arguments args) { |
| 4541 HandleScope scope; | 4557 HandleScope scope; |
| 4542 | 4558 |
| 4543 ASSERT(args.length() == 2); | 4559 ASSERT(args.length() == 2); |
| 4544 | 4560 |
| 4545 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 4561 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 4546 CONVERT_ARG_CHECKED(String, name, 1); | 4562 CONVERT_ARG_CHECKED(String, name, 1); |
| 4547 | 4563 |
| 4548 // Check if the name is trivially convertible to an index and get the element | 4564 // Check if the name is trivially convertible to an index and get the element |
| 4549 // if so. | 4565 // if so. |
| 4550 uint32_t index; | 4566 uint32_t index; |
| 4551 if (name->AsArrayIndex(&index)) { | 4567 if (name->AsArrayIndex(&index)) { |
| 4552 Handle<FixedArray> details = Factory::NewFixedArray(2); | 4568 Handle<FixedArray> details = Factory::NewFixedArray(2); |
| 4553 details->set(0, Runtime::GetElementOrCharAt(obj, index)); | 4569 details->set(0, Runtime::GetElementOrCharAt(obj, index)); |
| 4554 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); | 4570 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); |
| 4555 return *Factory::NewJSArrayWithElements(details); | 4571 return *Factory::NewJSArrayWithElements(details); |
| 4556 } | 4572 } |
| 4557 | 4573 |
| 4558 // Perform standard local lookup on the object. | 4574 // Perform standard local lookup on the object. |
| 4559 LookupResult result; | 4575 LookupResult result; |
| 4560 obj->Lookup(*name, &result); | 4576 obj->LocalLookup(*name, &result); |
| 4561 if (result.IsProperty()) { | 4577 if (result.IsProperty()) { |
| 4562 Handle<Object> value(DebugLookupResultValue(&result)); | 4578 bool caught_exception = false; |
| 4563 Handle<FixedArray> details = Factory::NewFixedArray(2); | 4579 Handle<Object> value(DebugLookupResultValue(*obj, *name, &result, |
| 4580 &caught_exception)); |
| 4581 // If the callback object is a fixed array then it contains JavaScript |
| 4582 // getter and/or setter. |
| 4583 bool hasJavaScriptAccessors = result.type() == CALLBACKS && |
| 4584 result.GetCallbackObject()->IsFixedArray(); |
| 4585 Handle<FixedArray> details = |
| 4586 Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2); |
| 4564 details->set(0, *value); | 4587 details->set(0, *value); |
| 4565 details->set(1, result.GetPropertyDetails().AsSmi()); | 4588 details->set(1, result.GetPropertyDetails().AsSmi()); |
| 4589 if (hasJavaScriptAccessors) { |
| 4590 details->set(2, |
| 4591 caught_exception ? Heap::true_value() : Heap::false_value()); |
| 4592 details->set(3, FixedArray::cast(result.GetCallbackObject())->get(0)); |
| 4593 details->set(4, FixedArray::cast(result.GetCallbackObject())->get(1)); |
| 4594 } |
| 4595 |
| 4566 return *Factory::NewJSArrayWithElements(details); | 4596 return *Factory::NewJSArrayWithElements(details); |
| 4567 } | 4597 } |
| 4568 return Heap::undefined_value(); | 4598 return Heap::undefined_value(); |
| 4569 } | 4599 } |
| 4570 | 4600 |
| 4571 | 4601 |
| 4572 static Object* Runtime_DebugGetProperty(Arguments args) { | 4602 static Object* Runtime_DebugGetProperty(Arguments args) { |
| 4573 HandleScope scope; | 4603 HandleScope scope; |
| 4574 | 4604 |
| 4575 ASSERT(args.length() == 2); | 4605 ASSERT(args.length() == 2); |
| 4576 | 4606 |
| 4577 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 4607 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 4578 CONVERT_ARG_CHECKED(String, name, 1); | 4608 CONVERT_ARG_CHECKED(String, name, 1); |
| 4579 | 4609 |
| 4580 LookupResult result; | 4610 LookupResult result; |
| 4581 obj->Lookup(*name, &result); | 4611 obj->Lookup(*name, &result); |
| 4582 if (result.IsProperty()) { | 4612 if (result.IsProperty()) { |
| 4583 return DebugLookupResultValue(&result); | 4613 return DebugLookupResultValue(*obj, *name, &result, NULL); |
| 4584 } | 4614 } |
| 4585 return Heap::undefined_value(); | 4615 return Heap::undefined_value(); |
| 4586 } | 4616 } |
| 4587 | 4617 |
| 4588 | 4618 |
| 4589 // Return the names of the local named properties. | 4619 // Return the names of the local named properties. |
| 4590 // args[0]: object | 4620 // args[0]: object |
| 4591 static Object* Runtime_DebugLocalPropertyNames(Arguments args) { | 4621 static Object* Runtime_DebugLocalPropertyNames(Arguments args) { |
| 4592 HandleScope scope; | 4622 HandleScope scope; |
| 4593 ASSERT(args.length() == 1); | 4623 ASSERT(args.length() == 1); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4667 return Smi::FromInt(result); | 4697 return Smi::FromInt(result); |
| 4668 } | 4698 } |
| 4669 | 4699 |
| 4670 | 4700 |
| 4671 // Return property names from named interceptor. | 4701 // Return property names from named interceptor. |
| 4672 // args[0]: object | 4702 // args[0]: object |
| 4673 static Object* Runtime_DebugNamedInterceptorPropertyNames(Arguments args) { | 4703 static Object* Runtime_DebugNamedInterceptorPropertyNames(Arguments args) { |
| 4674 HandleScope scope; | 4704 HandleScope scope; |
| 4675 ASSERT(args.length() == 1); | 4705 ASSERT(args.length() == 1); |
| 4676 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 4706 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 4677 RUNTIME_ASSERT(obj->HasNamedInterceptor()); | |
| 4678 | 4707 |
| 4679 v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj); | 4708 if (obj->HasNamedInterceptor()) { |
| 4680 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); | 4709 v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj); |
| 4710 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); |
| 4711 } |
| 4681 return Heap::undefined_value(); | 4712 return Heap::undefined_value(); |
| 4682 } | 4713 } |
| 4683 | 4714 |
| 4684 | 4715 |
| 4685 // Return element names from indexed interceptor. | 4716 // Return element names from indexed interceptor. |
| 4686 // args[0]: object | 4717 // args[0]: object |
| 4687 static Object* Runtime_DebugIndexedInterceptorElementNames(Arguments args) { | 4718 static Object* Runtime_DebugIndexedInterceptorElementNames(Arguments args) { |
| 4688 HandleScope scope; | 4719 HandleScope scope; |
| 4689 ASSERT(args.length() == 1); | 4720 ASSERT(args.length() == 1); |
| 4690 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 4721 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 4691 RUNTIME_ASSERT(obj->HasIndexedInterceptor()); | |
| 4692 | 4722 |
| 4693 v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj); | 4723 if (obj->HasIndexedInterceptor()) { |
| 4694 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); | 4724 v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj); |
| 4725 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); |
| 4726 } |
| 4695 return Heap::undefined_value(); | 4727 return Heap::undefined_value(); |
| 4696 } | 4728 } |
| 4697 | 4729 |
| 4698 | 4730 |
| 4699 // Return property value from named interceptor. | 4731 // Return property value from named interceptor. |
| 4700 // args[0]: object | 4732 // args[0]: object |
| 4701 // args[1]: property name | 4733 // args[1]: property name |
| 4702 static Object* Runtime_DebugNamedInterceptorPropertyValue(Arguments args) { | 4734 static Object* Runtime_DebugNamedInterceptorPropertyValue(Arguments args) { |
| 4703 HandleScope scope; | 4735 HandleScope scope; |
| 4704 ASSERT(args.length() == 2); | 4736 ASSERT(args.length() == 2); |
| (...skipping 1191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5896 } else { | 5928 } else { |
| 5897 // Handle last resort GC and make sure to allow future allocations | 5929 // Handle last resort GC and make sure to allow future allocations |
| 5898 // to grow the heap without causing GCs (if possible). | 5930 // to grow the heap without causing GCs (if possible). |
| 5899 Counters::gc_last_resort_from_js.Increment(); | 5931 Counters::gc_last_resort_from_js.Increment(); |
| 5900 Heap::CollectAllGarbage(); | 5932 Heap::CollectAllGarbage(); |
| 5901 } | 5933 } |
| 5902 } | 5934 } |
| 5903 | 5935 |
| 5904 | 5936 |
| 5905 } } // namespace v8::internal | 5937 } } // namespace v8::internal |
| OLD | NEW |