Index: src/objects.cc |
=================================================================== |
--- src/objects.cc (revision 539) |
+++ src/objects.cc (working copy) |
@@ -288,6 +288,7 @@ |
String* name, |
Object* value, |
PropertyAttributes attributes) { |
+ ASSERT(!IsJSGlobalProxy()); |
HandleScope scope; |
Handle<JSObject> this_handle(this); |
Handle<String> name_handle(name); |
@@ -636,7 +637,7 @@ |
break; |
} |
// All other JSObjects are rather similar to each other (JSObject, |
- // JSGlobalObject, JSUndetectableObject, JSValue). |
+ // JSGlobalProxy, JSGlobalObject, JSUndetectableObject, JSValue). |
default: { |
Object* constructor = map()->constructor(); |
bool printed = false; |
@@ -644,7 +645,7 @@ |
!Heap::Contains(HeapObject::cast(constructor))) { |
accumulator->Add("!!!INVALID CONSTRUCTOR!!!"); |
} else { |
- bool global_object = IsJSGlobalObject(); |
+ bool global_object = IsJSGlobalProxy(); |
if (constructor->IsJSFunction()) { |
if (!Heap::Contains(JSFunction::cast(constructor)->shared())) { |
accumulator->Add("!!!INVALID SHARED ON CONSTRUCTOR!!!"); |
@@ -656,7 +657,7 @@ |
if (str->length() > 0) { |
bool vowel = AnWord(str); |
accumulator->Add("<%sa%s ", |
- global_object ? "JS Global Object: " : "", |
+ global_object ? "Global Object: " : "", |
vowel ? "n" : ""); |
accumulator->Put(str); |
accumulator->Put('>'); |
@@ -820,9 +821,8 @@ |
case JS_ARRAY_TYPE: |
case JS_REGEXP_TYPE: |
case JS_FUNCTION_TYPE: |
+ case JS_GLOBAL_PROXY_TYPE: |
case JS_GLOBAL_OBJECT_TYPE: |
- reinterpret_cast<JSObject*>(this)->JSObjectIterateBody(object_size, v); |
- break; |
case JS_BUILTINS_OBJECT_TYPE: |
reinterpret_cast<JSObject*>(this)->JSObjectIterateBody(object_size, v); |
break; |
@@ -1085,6 +1085,7 @@ |
Object* JSObject::AddProperty(String* name, |
Object* value, |
PropertyAttributes attributes) { |
+ ASSERT(!IsJSGlobalProxy()); |
if (HasFastProperties()) { |
// Ensure the descriptor array does not get too big. |
if (map()->instance_descriptors()->number_of_descriptors() < |
@@ -1368,6 +1369,13 @@ |
void JSObject::LocalLookupRealNamedProperty(String* name, |
LookupResult* result) { |
+ if (IsJSGlobalProxy()) { |
+ Object* proto = GetPrototype(); |
+ if (proto->IsNull()) return result->NotFound(); |
+ ASSERT(proto->IsJSGlobalObject()); |
+ return JSObject::cast(proto)->LocalLookupRealNamedProperty(name, result); |
+ } |
+ |
if (HasFastProperties()) { |
LookupInDescriptor(name, result); |
if (result->IsValid()) { |
@@ -1486,6 +1494,14 @@ |
&& !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { |
return SetPropertyWithFailedAccessCheck(result, name, value); |
} |
+ |
+ if (IsJSGlobalProxy()) { |
+ Object* proto = GetPrototype(); |
+ if (proto->IsNull()) return value; |
+ ASSERT(proto->IsJSGlobalObject()); |
+ return JSObject::cast(proto)->SetProperty(result, name, value, attributes); |
+ } |
+ |
if (result->IsNotFound() || !result->IsProperty()) { |
// We could not find a local property so let's check whether there is an |
// accessor that wants to handle the property. |
@@ -1978,6 +1994,20 @@ |
Object* JSObject::DeleteElement(uint32_t index) { |
+ // Check access rights if needed. |
+ if (IsAccessCheckNeeded() && |
+ !Top::MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { |
+ Top::ReportFailedAccessCheck(this, v8::ACCESS_DELETE); |
+ return Heap::false_value(); |
+ } |
+ |
+ if (IsJSGlobalProxy()) { |
+ Object* proto = GetPrototype(); |
+ if (proto->IsNull()) return Heap::false_value(); |
+ ASSERT(proto->IsJSGlobalObject()); |
+ return JSGlobalObject::cast(proto)->DeleteElement(index); |
+ } |
+ |
if (HasIndexedInterceptor()) { |
return DeleteElementWithInterceptor(index); |
} |
@@ -2000,6 +2030,9 @@ |
Object* JSObject::DeleteProperty(String* name) { |
+ // ECMA-262, 3rd, 8.6.2.5 |
+ ASSERT(name->IsString()); |
+ |
// Check access rights if needed. |
if (IsAccessCheckNeeded() && |
!Top::MayNamedAccess(this, name, v8::ACCESS_DELETE)) { |
@@ -2007,8 +2040,12 @@ |
return Heap::false_value(); |
} |
- // ECMA-262, 3rd, 8.6.2.5 |
- ASSERT(name->IsString()); |
+ if (IsJSGlobalProxy()) { |
+ Object* proto = GetPrototype(); |
+ if (proto->IsNull()) return Heap::false_value(); |
+ ASSERT(proto->IsJSGlobalObject()); |
+ return JSGlobalObject::cast(proto)->DeleteProperty(name); |
+ } |
uint32_t index = 0; |
if (name->AsArrayIndex(&index)) { |
@@ -2191,9 +2228,16 @@ |
void JSObject::LocalLookup(String* name, LookupResult* result) { |
ASSERT(name->IsString()); |
+ if (IsJSGlobalProxy()) { |
+ Object* proto = GetPrototype(); |
+ if (proto->IsNull()) return result->NotFound(); |
+ ASSERT(proto->IsJSGlobalObject()); |
+ return JSObject::cast(proto)->LocalLookup(name, result); |
+ } |
+ |
// Do not use inline caching if the object is a non-global object |
// that requires access checks. |
- if (!IsJSGlobalObject() && IsAccessCheckNeeded()) { |
+ if (!IsJSGlobalProxy() && IsAccessCheckNeeded()) { |
result->DisallowCaching(); |
} |
@@ -2280,6 +2324,21 @@ |
Object* JSObject::DefineAccessor(String* name, bool is_getter, JSFunction* fun, |
PropertyAttributes attributes) { |
+ // Check access rights if needed. |
+ if (IsAccessCheckNeeded() && |
+ !Top::MayNamedAccess(this, name, v8::ACCESS_HAS)) { |
+ Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
+ return Heap::undefined_value(); |
+ } |
+ |
+ if (IsJSGlobalProxy()) { |
+ Object* proto = GetPrototype(); |
+ if (proto->IsNull()) return this; |
+ ASSERT(proto->IsJSGlobalObject()); |
+ return JSObject::cast(proto)->DefineAccessor(name, is_getter, |
+ fun, attributes); |
+ } |
+ |
Object* array = DefineGetterSetter(name, attributes); |
if (array->IsFailure() || array->IsUndefined()) return array; |
FixedArray::cast(array)->set(is_getter ? 0 : 1, fun); |
@@ -4743,6 +4802,13 @@ |
return value; |
} |
+ if (IsJSGlobalProxy()) { |
+ Object* proto = GetPrototype(); |
+ if (proto->IsNull()) return value; |
+ ASSERT(proto->IsJSGlobalObject()); |
+ return JSObject::cast(proto)->SetElement(index, value); |
+ } |
+ |
// Check for lookup interceptor |
if (HasIndexedInterceptor()) { |
return SetElementWithInterceptor(index, value); |