summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-02-16 13:27:44 +0000
committerSteve Block <steveblock@google.com>2011-02-16 15:22:50 +0000
commit103cc40e0c7630e0dada7fcec7f9de7c16ef8844 (patch)
tree0b379f3183f0523f6a3f61925e124b09b3be23c9 /src
parent81362e16c30e9e970af6b17592f627ad8cdee4d8 (diff)
downloadandroid_external_v8-103cc40e0c7630e0dada7fcec7f9de7c16ef8844.tar.gz
android_external_v8-103cc40e0c7630e0dada7fcec7f9de7c16ef8844.tar.bz2
android_external_v8-103cc40e0c7630e0dada7fcec7f9de7c16ef8844.zip
Merge V8 at Chromium 9.0.597.106
This is V8 branches/2.5 at r6641. Note that the bug fix that we'd cherry-picked to Android (http://code.google.com/p/v8/source/detail?r=6579) was pulled into the 2.5 branch in http://code.google.com/p/v8/source/detail?r=6601 so is subsumed by this revision. Change-Id: I63fd80c82c821d94e71db82e66cea0fbf33a1140
Diffstat (limited to 'src')
-rw-r--r--src/objects.cc7
-rw-r--r--src/runtime.cc160
-rw-r--r--src/v8natives.js57
-rw-r--r--src/version.cc2
4 files changed, 176 insertions, 50 deletions
diff --git a/src/objects.cc b/src/objects.cc
index f5d19e28..dcfd926f 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -6265,6 +6265,13 @@ JSObject::LocalElementType JSObject::HasLocalElement(uint32_t index) {
return UNDEFINED_ELEMENT;
}
+ if (IsJSGlobalProxy()) {
+ Object* proto = GetPrototype();
+ if (proto->IsNull()) return UNDEFINED_ELEMENT;
+ ASSERT(proto->IsJSGlobalObject());
+ return JSObject::cast(proto)->HasLocalElement(index);
+ }
+
// Check for lookup interceptor
if (HasIndexedInterceptor()) {
return HasElementWithInterceptor(this, index) ? INTERCEPTED_ELEMENT
diff --git a/src/runtime.cc b/src/runtime.cc
index 7214cb98..2324e62d 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -635,6 +635,90 @@ static void GetOwnPropertyImplementation(JSObject* obj,
}
+static bool CheckAccessException(LookupResult* result,
+ v8::AccessType access_type) {
+ if (result->type() == CALLBACKS) {
+ Object* callback = result->GetCallbackObject();
+ if (callback->IsAccessorInfo()) {
+ AccessorInfo* info = AccessorInfo::cast(callback);
+ bool can_access =
+ (access_type == v8::ACCESS_HAS &&
+ (info->all_can_read() || info->all_can_write())) ||
+ (access_type == v8::ACCESS_GET && info->all_can_read()) ||
+ (access_type == v8::ACCESS_SET && info->all_can_write());
+ return can_access;
+ }
+ }
+
+ return false;
+}
+
+
+static bool CheckAccess(JSObject* obj,
+ String* name,
+ LookupResult* result,
+ v8::AccessType access_type) {
+ ASSERT(result->IsProperty());
+
+ JSObject* holder = result->holder();
+ JSObject* current = obj;
+ while (true) {
+ if (current->IsAccessCheckNeeded() &&
+ !Top::MayNamedAccess(current, name, access_type)) {
+ // Access check callback denied the access, but some properties
+ // can have a special permissions which override callbacks descision
+ // (currently see v8::AccessControl).
+ break;
+ }
+
+ if (current == holder) {
+ return true;
+ }
+
+ current = JSObject::cast(current->GetPrototype());
+ }
+
+ // API callbacks can have per callback access exceptions.
+ switch (result->type()) {
+ case CALLBACKS: {
+ if (CheckAccessException(result, access_type)) {
+ return true;
+ }
+ break;
+ }
+ case INTERCEPTOR: {
+ // If the object has an interceptor, try real named properties.
+ // Overwrite the result to fetch the correct property later.
+ holder->LookupRealNamedProperty(name, result);
+ if (result->IsProperty()) {
+ if (CheckAccessException(result, access_type)) {
+ return true;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ Top::ReportFailedAccessCheck(current, access_type);
+ return false;
+}
+
+
+// TODO(1095): we should traverse hidden prototype hierachy as well.
+static bool CheckElementAccess(JSObject* obj,
+ uint32_t index,
+ v8::AccessType access_type) {
+ if (obj->IsAccessCheckNeeded() &&
+ !Top::MayIndexedAccess(obj, index, access_type)) {
+ return false;
+ }
+
+ return true;
+}
+
+
// Enumerator used as indices into the array returned from GetOwnProperty
enum PropertyDescriptorIndices {
IS_ACCESSOR_INDEX,
@@ -677,7 +761,7 @@ static MaybeObject* Runtime_GetOwnProperty(Arguments args) {
// subsequent cases.
Handle<JSValue> js_value = Handle<JSValue>::cast(obj);
Handle<String> str(String::cast(js_value->value()));
- Handle<String> substr = SubString(str, index, index+1, NOT_TENURED);
+ Handle<String> substr = SubString(str, index, index + 1, NOT_TENURED);
elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
elms->set(VALUE_INDEX, *substr);
@@ -690,8 +774,7 @@ static MaybeObject* Runtime_GetOwnProperty(Arguments args) {
case JSObject::INTERCEPTED_ELEMENT:
case JSObject::FAST_ELEMENT: {
elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
- Handle<Object> element = GetElement(Handle<Object>(obj), index);
- elms->set(VALUE_INDEX, *element);
+ elms->set(VALUE_INDEX, *GetElement(obj, index));
elms->set(WRITABLE_INDEX, Heap::true_value());
elms->set(ENUMERABLE_INDEX, Heap::true_value());
elms->set(CONFIGURABLE_INDEX, Heap::true_value());
@@ -699,7 +782,14 @@ static MaybeObject* Runtime_GetOwnProperty(Arguments args) {
}
case JSObject::DICTIONARY_ELEMENT: {
- NumberDictionary* dictionary = obj->element_dictionary();
+ Handle<JSObject> holder = obj;
+ if (obj->IsJSGlobalProxy()) {
+ Object* proto = obj->GetPrototype();
+ if (proto->IsNull()) return Heap::undefined_value();
+ ASSERT(proto->IsJSGlobalObject());
+ holder = Handle<JSObject>(JSObject::cast(proto));
+ }
+ NumberDictionary* dictionary = holder->element_dictionary();
int entry = dictionary->FindEntry(index);
ASSERT(entry != NumberDictionary::kNotFound);
PropertyDetails details = dictionary->DetailsAt(entry);
@@ -709,14 +799,18 @@ static MaybeObject* Runtime_GetOwnProperty(Arguments args) {
FixedArray* callbacks =
FixedArray::cast(dictionary->ValueAt(entry));
elms->set(IS_ACCESSOR_INDEX, Heap::true_value());
- elms->set(GETTER_INDEX, callbacks->get(0));
- elms->set(SETTER_INDEX, callbacks->get(1));
+ if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) {
+ elms->set(GETTER_INDEX, callbacks->get(0));
+ }
+ if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) {
+ elms->set(SETTER_INDEX, callbacks->get(1));
+ }
break;
}
case NORMAL:
// This is a data property.
elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
- elms->set(VALUE_INDEX, dictionary->ValueAt(entry));
+ elms->set(VALUE_INDEX, *GetElement(obj, index));
elms->set(WRITABLE_INDEX, Heap::ToBoolean(!details.IsReadOnly()));
break;
default:
@@ -736,35 +830,41 @@ static MaybeObject* Runtime_GetOwnProperty(Arguments args) {
if (!result.IsProperty()) {
return Heap::undefined_value();
}
- if (result.type() == CALLBACKS) {
- Object* structure = result.GetCallbackObject();
- if (structure->IsProxy() || structure->IsAccessorInfo()) {
- // Property that is internally implemented as a callback or
- // an API defined callback.
- Object* value;
- { MaybeObject* maybe_value = obj->GetPropertyWithCallback(
- *obj, structure, *name, result.holder());
- if (!maybe_value->ToObject(&value)) return maybe_value;
- }
- elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
- elms->set(VALUE_INDEX, value);
- elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly()));
- } else if (structure->IsFixedArray()) {
- // __defineGetter__/__defineSetter__ callback.
- elms->set(IS_ACCESSOR_INDEX, Heap::true_value());
- elms->set(GETTER_INDEX, FixedArray::cast(structure)->get(0));
- elms->set(SETTER_INDEX, FixedArray::cast(structure)->get(1));
- } else {
- return Heap::undefined_value();
+
+ if (!CheckAccess(*obj, *name, &result, v8::ACCESS_HAS)) {
+ return Heap::false_value();
+ }
+
+ elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!result.IsDontEnum()));
+ elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!result.IsDontDelete()));
+
+ bool is_js_accessor = (result.type() == CALLBACKS) &&
+ (result.GetCallbackObject()->IsFixedArray());
+
+ if (is_js_accessor) {
+ // __defineGetter__/__defineSetter__ callback.
+ elms->set(IS_ACCESSOR_INDEX, Heap::true_value());
+
+ FixedArray* structure = FixedArray::cast(result.GetCallbackObject());
+ if (CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) {
+ elms->set(GETTER_INDEX, structure->get(0));
+ }
+ if (CheckAccess(*obj, *name, &result, v8::ACCESS_SET)) {
+ elms->set(SETTER_INDEX, structure->get(1));
}
} else {
elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
- elms->set(VALUE_INDEX, result.GetLazyValue());
elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly()));
+
+ PropertyAttributes attrs;
+ Object* value;
+ // GetProperty will check access and report any violations.
+ { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs);
+ if (!maybe_value->ToObject(&value)) return maybe_value;
+ }
+ elms->set(VALUE_INDEX, value);
}
- elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!result.IsDontEnum()));
- elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!result.IsDontDelete()));
return *desc;
}
diff --git a/src/v8natives.js b/src/v8natives.js
index 50a2774d..09b296d4 100644
--- a/src/v8natives.js
+++ b/src/v8natives.js
@@ -491,28 +491,29 @@ PropertyDescriptor.prototype.hasSetter = function() {
}
+// Converts an array returned from Runtime_GetOwnProperty to an actual
+// property descriptor. For a description of the array layout please
+// see the runtime.cc file.
+function ConvertDescriptorArrayToDescriptor(desc_array) {
+ if (desc_array == false) {
+ throw 'Internal error: invalid desc_array';
+ }
-// ES5 section 8.12.1.
-function GetOwnProperty(obj, p) {
- var desc = new PropertyDescriptor();
-
- // GetOwnProperty returns an array indexed by the constants
- // defined in macros.py.
- // If p is not a property on obj undefined is returned.
- var props = %GetOwnProperty(ToObject(obj), ToString(p));
-
- if (IS_UNDEFINED(props)) return void 0;
+ if (IS_UNDEFINED(desc_array)) {
+ return void 0;
+ }
- // This is an accessor
- if (props[IS_ACCESSOR_INDEX]) {
- desc.setGet(props[GETTER_INDEX]);
- desc.setSet(props[SETTER_INDEX]);
+ var desc = new PropertyDescriptor();
+ // This is an accessor.
+ if (desc_array[IS_ACCESSOR_INDEX]) {
+ desc.setGet(desc_array[GETTER_INDEX]);
+ desc.setSet(desc_array[SETTER_INDEX]);
} else {
- desc.setValue(props[VALUE_INDEX]);
- desc.setWritable(props[WRITABLE_INDEX]);
+ desc.setValue(desc_array[VALUE_INDEX]);
+ desc.setWritable(desc_array[WRITABLE_INDEX]);
}
- desc.setEnumerable(props[ENUMERABLE_INDEX]);
- desc.setConfigurable(props[CONFIGURABLE_INDEX]);
+ desc.setEnumerable(desc_array[ENUMERABLE_INDEX]);
+ desc.setConfigurable(desc_array[CONFIGURABLE_INDEX]);
return desc;
}
@@ -535,9 +536,27 @@ function HasProperty(obj, p) {
}
+// ES5 section 8.12.1.
+function GetOwnProperty(obj, p) {
+ // GetOwnProperty returns an array indexed by the constants
+ // defined in macros.py.
+ // If p is not a property on obj undefined is returned.
+ var props = %GetOwnProperty(ToObject(obj), ToString(p));
+
+ // A false value here means that access checks failed.
+ if (props == false) return void 0;
+
+ return ConvertDescriptorArrayToDescriptor(props);
+}
+
+
// ES5 8.12.9.
function DefineOwnProperty(obj, p, desc, should_throw) {
- var current = GetOwnProperty(obj, p);
+ var current_or_access = %GetOwnProperty(ToObject(obj), ToString(p));
+ // A false value here means that access checks failed.
+ if (current_or_access == false) return void 0;
+
+ var current = ConvertDescriptorArrayToDescriptor(current_or_access);
var extensible = %IsExtensible(ToObject(obj));
// Error handling according to spec.
diff --git a/src/version.cc b/src/version.cc
index 24e95847..041facd3 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 2
#define MINOR_VERSION 5
#define BUILD_NUMBER 9
-#define PATCH_LEVEL 11
+#define PATCH_LEVEL 15
#define CANDIDATE_VERSION false
// Define SONAME to have the SCons build the put a specific SONAME into the