| Index: src/runtime.cc
|
| ===================================================================
|
| --- src/runtime.cc (revision 1168)
|
| +++ src/runtime.cc (working copy)
|
| @@ -154,22 +154,23 @@
|
| &is_result_from_cache);
|
|
|
| Handle<JSObject> boilerplate = Factory::NewJSObjectFromMap(map);
|
| - { // Add the constant propeties to the boilerplate.
|
| + { // Add the constant properties to the boilerplate.
|
| int length = constant_properties->length();
|
| OptimizedObjectForAddingMultipleProperties opt(boilerplate,
|
| !is_result_from_cache);
|
| for (int index = 0; index < length; index +=2) {
|
| Handle<Object> key(constant_properties->get(index+0));
|
| Handle<Object> value(constant_properties->get(index+1));
|
| + Handle<Object> result;
|
| uint32_t element_index = 0;
|
| if (key->IsSymbol()) {
|
| // If key is a symbol it is not an array element.
|
| Handle<String> name(String::cast(*key));
|
| ASSERT(!name->AsArrayIndex(&element_index));
|
| - SetProperty(boilerplate, name, value, NONE);
|
| + result = SetProperty(boilerplate, name, value, NONE);
|
| } else if (Array::IndexFromObject(*key, &element_index)) {
|
| // Array index (uint32).
|
| - SetElement(boilerplate, element_index, value);
|
| + result = SetElement(boilerplate, element_index, value);
|
| } else {
|
| // Non-uint32 number.
|
| ASSERT(key->IsNumber());
|
| @@ -178,8 +179,13 @@
|
| Vector<char> buffer(arr, ARRAY_SIZE(arr));
|
| const char* str = DoubleToCString(num, buffer);
|
| Handle<String> name = Factory::NewStringFromAscii(CStrVector(str));
|
| - SetProperty(boilerplate, name, value, NONE);
|
| + result = SetProperty(boilerplate, name, value, NONE);
|
| }
|
| + // If setting the property on the boilerplate throws an
|
| + // exception, the exception is converted to an empty handle in
|
| + // the handle based operations. In that case, we need to
|
| + // convert back to an exception.
|
| + if (result.is_null()) return Failure::Exception();
|
| }
|
| }
|
|
|
| @@ -215,6 +221,23 @@
|
| }
|
|
|
|
|
| +static Object* Runtime_CreateCatchExtensionObject(Arguments args) {
|
| + ASSERT(args.length() == 2);
|
| + CONVERT_CHECKED(String, key, args[0]);
|
| + Object* value = args[1];
|
| + // Create a catch context extension object.
|
| + JSFunction* constructor =
|
| + Top::context()->global_context()->context_extension_function();
|
| + Object* object = Heap::AllocateJSObject(constructor);
|
| + if (object->IsFailure()) return object;
|
| + // Assign the exception value to the catch variable and make sure
|
| + // that the catch variable is DontDelete.
|
| + value = JSObject::cast(object)->SetProperty(key, value, DONT_DELETE);
|
| + if (value->IsFailure()) return value;
|
| + return object;
|
| +}
|
| +
|
| +
|
| static Object* Runtime_ClassOf(Arguments args) {
|
| NoHandleAllocation ha;
|
| ASSERT(args.length() == 1);
|
| @@ -343,8 +366,16 @@
|
| static Object* Runtime_DisableAccessChecks(Arguments args) {
|
| ASSERT(args.length() == 1);
|
| CONVERT_CHECKED(HeapObject, object, args[0]);
|
| - bool needs_access_checks = object->map()->is_access_check_needed();
|
| - object->map()->set_is_access_check_needed(false);
|
| + Map* old_map = object->map();
|
| + bool needs_access_checks = old_map->is_access_check_needed();
|
| + if (needs_access_checks) {
|
| + // Copy map so it won't interfere constructor's initial map.
|
| + Object* new_map = old_map->CopyDropTransitions();
|
| + if (new_map->IsFailure()) return new_map;
|
| +
|
| + Map::cast(new_map)->set_is_access_check_needed(false);
|
| + object->set_map(Map::cast(new_map));
|
| + }
|
| return needs_access_checks ? Heap::true_value() : Heap::false_value();
|
| }
|
|
|
| @@ -352,7 +383,15 @@
|
| static Object* Runtime_EnableAccessChecks(Arguments args) {
|
| ASSERT(args.length() == 1);
|
| CONVERT_CHECKED(HeapObject, object, args[0]);
|
| - object->map()->set_is_access_check_needed(true);
|
| + Map* old_map = object->map();
|
| + if (!old_map->is_access_check_needed()) {
|
| + // Copy map so it won't interfere constructor's initial map.
|
| + Object* new_map = old_map->CopyDropTransitions();
|
| + if (new_map->IsFailure()) return new_map;
|
| +
|
| + Map::cast(new_map)->set_is_access_check_needed(true);
|
| + object->set_map(Map::cast(new_map));
|
| + }
|
| return Heap::undefined_value();
|
| }
|
|
|
| @@ -725,56 +764,94 @@
|
|
|
| int index;
|
| PropertyAttributes attributes;
|
| - ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
|
| + ContextLookupFlags flags = FOLLOW_CHAINS;
|
| Handle<Object> holder =
|
| context->Lookup(name, flags, &index, &attributes);
|
|
|
| - // The property should always be present. It is always declared
|
| - // before being initialized through DeclareContextSlot.
|
| - ASSERT(attributes != ABSENT && (attributes & READ_ONLY) != 0);
|
| -
|
| - // If the slot is in the context, we set it but only if it hasn't
|
| - // been set before.
|
| + // In most situations, the property introduced by the const
|
| + // declaration should be present in the context extension object.
|
| + // However, because declaration and initialization are separate, the
|
| + // property might have been deleted (if it was introduced by eval)
|
| + // before we reach the initialization point.
|
| + //
|
| + // Example:
|
| + //
|
| + // function f() { eval("delete x; const x;"); }
|
| + //
|
| + // In that case, the initialization behaves like a normal assignment
|
| + // to property 'x'.
|
| if (index >= 0) {
|
| - // The constant context slot should always be in the function
|
| - // context; not in any outer context nor in the arguments object.
|
| - ASSERT(holder.is_identical_to(context));
|
| - if (context->get(index)->IsTheHole()) {
|
| - context->set(index, *value);
|
| + // Property was found in a context.
|
| + if (holder->IsContext()) {
|
| + // The holder cannot be the function context. If it is, there
|
| + // should have been a const redeclaration error when declaring
|
| + // the const property.
|
| + ASSERT(!holder.is_identical_to(context));
|
| + if ((attributes & READ_ONLY) == 0) {
|
| + Handle<Context>::cast(holder)->set(index, *value);
|
| + }
|
| + } else {
|
| + // The holder is an arguments object.
|
| + ASSERT((attributes & READ_ONLY) == 0);
|
| + Handle<JSObject>::cast(holder)->SetElement(index, *value);
|
| }
|
| return *value;
|
| }
|
|
|
| - // Otherwise, the slot must be in a JS object extension.
|
| - Handle<JSObject> context_ext(JSObject::cast(*holder));
|
| + // The property could not be found, we introduce it in the global
|
| + // context.
|
| + if (attributes == ABSENT) {
|
| + Handle<JSObject> global = Handle<JSObject>(Top::context()->global());
|
| + SetProperty(global, name, value, NONE);
|
| + return *value;
|
| + }
|
|
|
| - // We must initialize the value only if it wasn't initialized
|
| - // before, e.g. for const declarations in a loop. The property has
|
| - // the hole value if it wasn't initialized yet. NOTE: We cannot use
|
| - // GetProperty() to get the current value as it 'unholes' the value.
|
| - LookupResult lookup;
|
| - context_ext->LocalLookupRealNamedProperty(*name, &lookup);
|
| - ASSERT(lookup.IsProperty()); // the property was declared
|
| - ASSERT(lookup.IsReadOnly()); // and it was declared as read-only
|
| + // The property was present in a context extension object.
|
| + Handle<JSObject> context_ext = Handle<JSObject>::cast(holder);
|
|
|
| - PropertyType type = lookup.type();
|
| - if (type == FIELD) {
|
| - FixedArray* properties = context_ext->properties();
|
| - int index = lookup.GetFieldIndex();
|
| - if (properties->get(index)->IsTheHole()) {
|
| - properties->set(index, *value);
|
| + if (*context_ext == context->extension()) {
|
| + // This is the property that was introduced by the const
|
| + // declaration. Set it if it hasn't been set before. NOTE: We
|
| + // cannot use GetProperty() to get the current value as it
|
| + // 'unholes' the value.
|
| + LookupResult lookup;
|
| + context_ext->LocalLookupRealNamedProperty(*name, &lookup);
|
| + ASSERT(lookup.IsProperty()); // the property was declared
|
| + ASSERT(lookup.IsReadOnly()); // and it was declared as read-only
|
| +
|
| + PropertyType type = lookup.type();
|
| + if (type == FIELD) {
|
| + FixedArray* properties = context_ext->properties();
|
| + int index = lookup.GetFieldIndex();
|
| + if (properties->get(index)->IsTheHole()) {
|
| + properties->set(index, *value);
|
| + }
|
| + } else if (type == NORMAL) {
|
| + Dictionary* dictionary = context_ext->property_dictionary();
|
| + int entry = lookup.GetDictionaryEntry();
|
| + if (dictionary->ValueAt(entry)->IsTheHole()) {
|
| + dictionary->ValueAtPut(entry, *value);
|
| + }
|
| + } else {
|
| + // We should not reach here. Any real, named property should be
|
| + // either a field or a dictionary slot.
|
| + UNREACHABLE();
|
| }
|
| - } else if (type == NORMAL) {
|
| - Dictionary* dictionary = context_ext->property_dictionary();
|
| - int entry = lookup.GetDictionaryEntry();
|
| - if (dictionary->ValueAt(entry)->IsTheHole()) {
|
| - dictionary->ValueAtPut(entry, *value);
|
| + } else {
|
| + // The property was found in a different context extension object.
|
| + // Set it if it is not a read-only property.
|
| + if ((attributes & READ_ONLY) == 0) {
|
| + Handle<Object> set = SetProperty(context_ext, name, value, attributes);
|
| + // Setting a property might throw an exception. Exceptions
|
| + // are converted to empty handles in handle operations. We
|
| + // need to convert back to exceptions here.
|
| + if (set.is_null()) {
|
| + ASSERT(Top::has_pending_exception());
|
| + return Failure::Exception();
|
| + }
|
| }
|
| - } else {
|
| - // We should not reach here. Any real, named property should be
|
| - // either a field or a dictionary slot.
|
| - UNREACHABLE();
|
| }
|
| +
|
| return *value;
|
| }
|
|
|
| @@ -989,7 +1066,7 @@
|
| // Flatten the string. If someone wants to get a char at an index
|
| // in a cons string, it is likely that more indices will be
|
| // accessed.
|
| - subject->TryFlatten(StringShape(subject));
|
| + subject->TryFlattenIfNotFlat(StringShape(subject));
|
| StringShape shape(subject);
|
| if (i >= static_cast<uint32_t>(subject->length(shape))) {
|
| return Heap::nan_value();
|
| @@ -1460,8 +1537,8 @@
|
| CONVERT_CHECKED(String, pat, args[1]);
|
| Object* index = args[2];
|
|
|
| - sub->TryFlatten(StringShape(sub));
|
| - pat->TryFlatten(StringShape(pat));
|
| + sub->TryFlattenIfNotFlat(StringShape(sub));
|
| + pat->TryFlattenIfNotFlat(StringShape(pat));
|
|
|
| StringShape sub_shape(sub);
|
| StringShape pat_shape(pat);
|
| @@ -1520,8 +1597,8 @@
|
| int d = str1->Get(shape1, 0) - str2->Get(shape2, 0);
|
| if (d != 0) return Smi::FromInt(d);
|
|
|
| - str1->TryFlatten(shape1); // Shapes are no longer valid now!
|
| - str2->TryFlatten(shape2);
|
| + str1->TryFlattenIfNotFlat(shape1); // Shapes are no longer valid now!
|
| + str2->TryFlattenIfNotFlat(shape2);
|
|
|
| static StringInputBuffer buf1;
|
| static StringInputBuffer buf2;
|
| @@ -1658,7 +1735,7 @@
|
| static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
|
| StringShape shape(*string);
|
| if (index < static_cast<uint32_t>(string->length(shape))) {
|
| - string->TryFlatten(shape); // Invalidates shape!
|
| + string->TryFlattenIfNotFlat(shape); // Invalidates shape!
|
| return LookupSingleCharacterStringFromCode(
|
| string->Get(StringShape(*string), index));
|
| }
|
| @@ -1719,7 +1796,7 @@
|
| name = Handle<String>::cast(converted);
|
| }
|
|
|
| - // Check if the name is trivially convertable to an index and get
|
| + // Check if the name is trivially convertible to an index and get
|
| // the element if so.
|
| if (name->AsArrayIndex(&index)) {
|
| return GetElementOrCharAt(object, index);
|
| @@ -1751,7 +1828,7 @@
|
| // itself.
|
| //
|
| // The global proxy objects has to be excluded since LocalLookup on
|
| - // the global proxy object can return a valid result eventhough the
|
| + // the global proxy object can return a valid result even though the
|
| // global proxy object never has properties. This is the case
|
| // because the global proxy object forwards everything to its hidden
|
| // prototype including local lookups.
|
| @@ -1851,7 +1928,7 @@
|
| result = SetElement(js_object, index, value);
|
| } else {
|
| Handle<String> key_string = Handle<String>::cast(key);
|
| - key_string->TryFlatten(StringShape(*key_string));
|
| + key_string->TryFlattenIfNotFlat(StringShape(*key_string));
|
| result = SetProperty(js_object, key_string, value, attr);
|
| }
|
| if (result.is_null()) return Failure::Exception();
|
| @@ -2123,7 +2200,7 @@
|
| NoHandleAllocation ha;
|
| ASSERT(args.length() == 1);
|
| CONVERT_CHECKED(String, subject, args[0]);
|
| - subject->TryFlatten(StringShape(subject));
|
| + subject->TryFlattenIfNotFlat(StringShape(subject));
|
| return Heap::NumberFromDouble(StringToDouble(subject, ALLOW_HEX));
|
| }
|
|
|
| @@ -2206,7 +2283,7 @@
|
| ASSERT(args.length() == 1);
|
| CONVERT_CHECKED(String, source, args[0]);
|
|
|
| - source->TryFlatten(StringShape(source));
|
| + source->TryFlattenIfNotFlat(StringShape(source));
|
|
|
| int escaped_length = 0;
|
| int length = source->length();
|
| @@ -2320,7 +2397,7 @@
|
| ASSERT(args.length() == 1);
|
| CONVERT_CHECKED(String, source, args[0]);
|
|
|
| - source->TryFlatten(StringShape(source));
|
| + source->TryFlattenIfNotFlat(StringShape(source));
|
| StringShape source_shape(source);
|
|
|
| bool ascii = true;
|
| @@ -2369,7 +2446,7 @@
|
| CONVERT_DOUBLE_CHECKED(n, args[1]);
|
| int radix = FastD2I(n);
|
|
|
| - s->TryFlatten(StringShape(s));
|
| + s->TryFlattenIfNotFlat(StringShape(s));
|
|
|
| StringShape shape(s);
|
|
|
| @@ -2442,7 +2519,7 @@
|
| NoHandleAllocation ha;
|
|
|
| CONVERT_CHECKED(String, s, args[0]);
|
| - s->TryFlatten(StringShape(s));
|
| + s->TryFlattenIfNotFlat(StringShape(s));
|
| StringShape shape(s);
|
|
|
| int raw_string_length = s->length(shape);
|
| @@ -2987,7 +3064,7 @@
|
| // same as the lexicographic order of the string representations.
|
| if (x_value == 0 || y_value == 0) return Smi::FromInt(x_value - y_value);
|
|
|
| - // If only one of the intergers is negative the negative number is
|
| + // If only one of the integers is negative the negative number is
|
| // smallest because the char code of '-' is less than the char code
|
| // of any digit. Otherwise, we make both values positive.
|
| if (x_value < 0 || y_value < 0) {
|
| @@ -3046,8 +3123,8 @@
|
| if (d < 0) return Smi::FromInt(LESS);
|
| else if (d > 0) return Smi::FromInt(GREATER);
|
|
|
| - x->TryFlatten(x_shape); // Shapes are no longer valid!
|
| - y->TryFlatten(y_shape);
|
| + x->TryFlattenIfNotFlat(x_shape); // Shapes are no longer valid!
|
| + y->TryFlattenIfNotFlat(y_shape);
|
|
|
| static StringInputBuffer bufx;
|
| static StringInputBuffer bufy;
|
| @@ -3325,7 +3402,7 @@
|
| if (constructor->IsJSFunction()) {
|
| JSFunction* function = JSFunction::cast(constructor);
|
|
|
| - // Handle steping into constructors if step into is active.
|
| + // Handle stepping into constructors if step into is active.
|
| if (Debug::StepInActive()) {
|
| HandleScope scope;
|
| Debug::HandleStepIn(Handle<JSFunction>(function), 0, true);
|
| @@ -3701,7 +3778,9 @@
|
| ASSERT(args.length() == 1);
|
|
|
| // First check if this is a real stack overflow.
|
| - if (StackGuard::IsStackOverflow()) return Runtime_StackOverflow(args);
|
| + if (StackGuard::IsStackOverflow()) {
|
| + return Runtime_StackOverflow(args);
|
| + }
|
|
|
| return Execution::HandleStackGuardInterrupt();
|
| }
|
| @@ -4503,32 +4582,64 @@
|
| }
|
|
|
|
|
| -static Object* DebugLookupResultValue(Object* obj, String* name,
|
| - LookupResult* result,
|
| +// Find the length of the prototype chain that is to to handled as one. If a
|
| +// prototype object is hidden it is to be viewed as part of the the object it
|
| +// is prototype for.
|
| +static int LocalPrototypeChainLength(JSObject* obj) {
|
| + int count = 1;
|
| + Object* proto = obj->GetPrototype();
|
| + while (proto->IsJSObject() &&
|
| + JSObject::cast(proto)->map()->is_hidden_prototype()) {
|
| + count++;
|
| + proto = JSObject::cast(proto)->GetPrototype();
|
| + }
|
| + return count;
|
| +}
|
| +
|
| +
|
| +static Object* DebugLookupResultValue(Object* receiver, LookupResult* result,
|
| bool* caught_exception) {
|
| + Object* value;
|
| switch (result->type()) {
|
| - case NORMAL:
|
| + case NORMAL: {
|
| + Dictionary* dict =
|
| + JSObject::cast(result->holder())->property_dictionary();
|
| + value = dict->ValueAt(result->GetDictionaryEntry());
|
| + if (value->IsTheHole()) {
|
| + return Heap::undefined_value();
|
| + }
|
| + return value;
|
| + }
|
| case FIELD:
|
| + value =
|
| + JSObject::cast(
|
| + result->holder())->FastPropertyAt(result->GetFieldIndex());
|
| + if (value->IsTheHole()) {
|
| + return Heap::undefined_value();
|
| + }
|
| + return value;
|
| case CONSTANT_FUNCTION:
|
| - return obj->GetProperty(name);
|
| + return result->GetConstantFunction();
|
| case CALLBACKS: {
|
| - // Get the property value. If there is an exception it must be thown from
|
| - // a JavaScript getter.
|
| - Object* value;
|
| - value = obj->GetProperty(name);
|
| - if (value->IsException()) {
|
| - if (caught_exception != NULL) {
|
| - *caught_exception = true;
|
| + Object* structure = result->GetCallbackObject();
|
| + if (structure->IsProxy()) {
|
| + AccessorDescriptor* callback =
|
| + reinterpret_cast<AccessorDescriptor*>(
|
| + Proxy::cast(structure)->proxy());
|
| + value = (callback->getter)(receiver, callback->data);
|
| + if (value->IsFailure()) {
|
| + value = Top::pending_exception();
|
| + Top::clear_pending_exception();
|
| + if (caught_exception != NULL) {
|
| + *caught_exception = true;
|
| + }
|
| }
|
| - value = Top::pending_exception();
|
| - Top::optional_reschedule_exception(true);
|
| + return value;
|
| + } else {
|
| + return Heap::undefined_value();
|
| }
|
| - ASSERT(!Top::has_pending_exception());
|
| - ASSERT(!Top::external_caught_exception());
|
| - return value;
|
| }
|
| case INTERCEPTOR:
|
| - return obj->GetProperty(name);
|
| case MAP_TRANSITION:
|
| case CONSTANT_TRANSITION:
|
| case NULL_DESCRIPTOR:
|
| @@ -4561,6 +4672,13 @@
|
| CONVERT_ARG_CHECKED(JSObject, obj, 0);
|
| CONVERT_ARG_CHECKED(String, name, 1);
|
|
|
| + // Skip the global proxy as it has no properties and always delegates to the
|
| + // real global object.
|
| + if (obj->IsJSGlobalProxy()) {
|
| + obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
|
| + }
|
| +
|
| +
|
| // Check if the name is trivially convertible to an index and get the element
|
| // if so.
|
| uint32_t index;
|
| @@ -4571,12 +4689,25 @@
|
| return *Factory::NewJSArrayWithElements(details);
|
| }
|
|
|
| - // Perform standard local lookup on the object.
|
| + // Find the number of objects making up this.
|
| + int length = LocalPrototypeChainLength(*obj);
|
| +
|
| + // Try local lookup on each of the objects.
|
| LookupResult result;
|
| - obj->LocalLookup(*name, &result);
|
| + Handle<JSObject> jsproto = obj;
|
| + for (int i = 0; i < length; i++) {
|
| + jsproto->LocalLookup(*name, &result);
|
| + if (result.IsProperty()) {
|
| + break;
|
| + }
|
| + if (i < length - 1) {
|
| + jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
|
| + }
|
| + }
|
| +
|
| if (result.IsProperty()) {
|
| bool caught_exception = false;
|
| - Handle<Object> value(DebugLookupResultValue(*obj, *name, &result,
|
| + Handle<Object> value(DebugLookupResultValue(*obj, &result,
|
| &caught_exception));
|
| // If the callback object is a fixed array then it contains JavaScript
|
| // getter and/or setter.
|
| @@ -4610,7 +4741,7 @@
|
| LookupResult result;
|
| obj->Lookup(*name, &result);
|
| if (result.IsProperty()) {
|
| - return DebugLookupResultValue(*obj, *name, &result, NULL);
|
| + return DebugLookupResultValue(*obj, &result, NULL);
|
| }
|
| return Heap::undefined_value();
|
| }
|
| @@ -4626,9 +4757,43 @@
|
| }
|
| CONVERT_ARG_CHECKED(JSObject, obj, 0);
|
|
|
| - int n = obj->NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE));
|
| - Handle<FixedArray> names = Factory::NewFixedArray(n);
|
| - obj->GetLocalPropertyNames(*names);
|
| + // Skip the global proxy as it has no properties and always delegates to the
|
| + // real global object.
|
| + if (obj->IsJSGlobalProxy()) {
|
| + obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
|
| + }
|
| +
|
| + // Find the number of objects making up this.
|
| + int length = LocalPrototypeChainLength(*obj);
|
| +
|
| + // Find the number of local properties for each of the objects.
|
| + int* local_property_count = NewArray<int>(length);
|
| + int total_property_count = 0;
|
| + Handle<JSObject> jsproto = obj;
|
| + for (int i = 0; i < length; i++) {
|
| + int n;
|
| + n = jsproto->NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE));
|
| + local_property_count[i] = n;
|
| + total_property_count += n;
|
| + if (i < length - 1) {
|
| + jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
|
| + }
|
| + }
|
| +
|
| + // Allocate an array with storage for all the property names.
|
| + Handle<FixedArray> names = Factory::NewFixedArray(total_property_count);
|
| +
|
| + // Get the property names.
|
| + jsproto = obj;
|
| + for (int i = 0; i < length; i++) {
|
| + jsproto->GetLocalPropertyNames(*names,
|
| + i == 0 ? 0 : local_property_count[i - 1]);
|
| + if (i < length - 1) {
|
| + jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
|
| + }
|
| + }
|
| +
|
| + DeleteArray(local_property_count);
|
| return *Factory::NewJSArrayWithElements(names);
|
| }
|
|
|
| @@ -5091,7 +5256,7 @@
|
| }
|
| if (start_position <= position &&
|
| position <= shared->end_position()) {
|
| - // If there is no candidate or this function is within the currrent
|
| + // If there is no candidate or this function is within the current
|
| // candidate this is the new candidate.
|
| if (target.is_null()) {
|
| target_start_position = start_position;
|
| @@ -5309,7 +5474,7 @@
|
|
|
|
|
| // Evaluate a piece of JavaScript in the context of a stack frame for
|
| -// debugging. This is acomplished by creating a new context which in its
|
| +// debugging. This is accomplished by creating a new context which in its
|
| // extension part has all the parameters and locals of the function on the
|
| // stack frame. A function which calls eval with the code to evaluate is then
|
| // compiled in this context and called in this context. As this context
|
| @@ -5420,7 +5585,7 @@
|
| // Wrap the evaluation statement in a new function compiled in the newly
|
| // created context. The function has one parameter which has to be called
|
| // 'arguments'. This it to have access to what would have been 'arguments' in
|
| - // the function beeing debugged.
|
| + // the function being debugged.
|
| // function(arguments,__source__) {return eval(__source__);}
|
| static const char* source_str =
|
| "function(arguments,__source__){return eval(__source__);}";
|
| @@ -5535,7 +5700,7 @@
|
| ASSERT(args.length() == 0);
|
|
|
| // Perform two GCs to get rid of all unreferenced scripts. The first GC gets
|
| - // rid of all the cached script wrappes and the second gets rid of the
|
| + // rid of all the cached script wrappers and the second gets rid of the
|
| // scripts which is no longer referenced.
|
| Heap::CollectAllGarbage();
|
| Heap::CollectAllGarbage();
|
| @@ -5756,12 +5921,15 @@
|
| }
|
|
|
|
|
| -static Object* Runtime_GetPrototype(Arguments args) {
|
| +// Find the effective prototype object as returned by __proto__.
|
| +// args[0]: the object to find the prototype for.
|
| +static Object* Runtime_DebugGetPrototype(Arguments args) {
|
| ASSERT(args.length() == 1);
|
|
|
| CONVERT_CHECKED(JSObject, obj, args[0]);
|
|
|
| - return obj->GetPrototype();
|
| + // Use the __proto__ accessor.
|
| + return Accessors::ObjectPrototype.getter(obj, NULL);
|
| }
|
|
|
|
|
|
|