Index: src/accessors.cc |
diff --git a/src/accessors.cc b/src/accessors.cc |
index 702343778ae756a2a92f5ce19363f9d13581f242..d9d239498350dc5942df64e8f8739edaa0df7f4a 100644 |
--- a/src/accessors.cc |
+++ b/src/accessors.cc |
@@ -136,6 +136,25 @@ bool Accessors::IsJSObjectFieldAccessor<HeapType>(Handle<HeapType> type, |
int* object_offset); |
+bool SetPropertyOnInstanceIfInherited( |
+ Isolate* isolate, const v8::PropertyCallbackInfo<void>& info, |
+ v8::Local<v8::String> name, Handle<Object> value) { |
+ Handle<Object> holder = Utils::OpenHandle(*info.Holder()); |
+ Handle<Object> receiver = Utils::OpenHandle(*info.This()); |
+ if (*holder == *receiver) return false; |
+ if (receiver->IsJSObject()) { |
+ Handle<JSObject> object = Handle<JSObject>::cast(receiver); |
+ // This behaves sloppy since we lost the actual strict-mode. |
+ // TODO(verwaest): Fix by making ExecutableAccessorInfo behave like data |
+ // properties. |
+ if (!object->map()->is_extensible()) return true; |
+ JSObject::SetOwnPropertyIgnoreAttributes(object, Utils::OpenHandle(*name), |
+ value, NONE); |
+ } |
+ return true; |
+} |
+ |
+ |
// |
// Accessors::ArrayLength |
// |
@@ -176,17 +195,7 @@ void Accessors::ArrayLengthSetter( |
HandleScope scope(isolate); |
Handle<JSObject> object = Utils::OpenHandle(*info.This()); |
Handle<Object> value = Utils::OpenHandle(*val); |
- // This means one of the object's prototypes is a JSArray and the |
- // object does not have a 'length' property. Calling SetProperty |
- // causes an infinite loop. |
- if (!object->IsJSArray()) { |
- // This behaves sloppy since we lost the actual strict-mode. |
- // TODO(verwaest): Fix by making ExecutableAccessorInfo behave like data |
- // properties. |
- if (!object->map()->is_extensible()) return; |
- MaybeHandle<Object> maybe_result = JSObject::SetOwnPropertyIgnoreAttributes( |
- object, isolate->factory()->length_string(), value, NONE); |
- maybe_result.Check(); |
+ if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) { |
return; |
} |
@@ -838,25 +847,10 @@ static Handle<Object> GetFunctionPrototype(Isolate* isolate, |
static Handle<Object> SetFunctionPrototype(Isolate* isolate, |
- Handle<JSObject> receiver, |
+ Handle<JSFunction> function, |
Handle<Object> value) { |
- Handle<JSFunction> function; |
- { |
- DisallowHeapAllocation no_allocation; |
- JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, *receiver); |
- if (function_raw == NULL) return isolate->factory()->undefined_value(); |
- function = Handle<JSFunction>(function_raw, isolate); |
- } |
- |
- if (!function->should_have_prototype()) { |
- // Since we hit this accessor, object will have no prototype property. |
- MaybeHandle<Object> maybe_result = JSObject::SetOwnPropertyIgnoreAttributes( |
- receiver, isolate->factory()->prototype_string(), value, NONE); |
- return maybe_result.ToHandleChecked(); |
- } |
- |
Handle<Object> old_value; |
- bool is_observed = *function == *receiver && function->map()->is_observed(); |
+ bool is_observed = function->map()->is_observed(); |
if (is_observed) { |
if (function->has_prototype()) |
old_value = handle(function->prototype(), isolate); |
@@ -907,10 +901,12 @@ void Accessors::FunctionPrototypeSetter( |
const v8::PropertyCallbackInfo<void>& info) { |
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); |
HandleScope scope(isolate); |
- Handle<JSObject> object = |
- Handle<JSObject>::cast(Utils::OpenHandle(*info.This())); |
Handle<Object> value = Utils::OpenHandle(*val); |
- |
+ if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) { |
+ return; |
+ } |
+ Handle<JSFunction> object = |
+ Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder())); |
SetFunctionPrototype(isolate, object, value); |
} |
@@ -960,7 +956,8 @@ void Accessors::FunctionLengthSetter( |
v8::Local<v8::String> name, |
v8::Local<v8::Value> val, |
const v8::PropertyCallbackInfo<void>& info) { |
- // Do nothing. |
+ // Function length is non writable, non configurable. |
+ UNREACHABLE(); |
} |
@@ -995,7 +992,8 @@ void Accessors::FunctionNameSetter( |
v8::Local<v8::String> name, |
v8::Local<v8::Value> val, |
const v8::PropertyCallbackInfo<void>& info) { |
- // Do nothing. |
+ // Function name is non writable, non configurable. |
+ UNREACHABLE(); |
} |
@@ -1131,7 +1129,8 @@ void Accessors::FunctionArgumentsSetter( |
v8::Local<v8::String> name, |
v8::Local<v8::Value> val, |
const v8::PropertyCallbackInfo<void>& info) { |
- // Do nothing. |
+ // Function arguments is non writable, non configurable. |
+ UNREACHABLE(); |
} |
@@ -1281,7 +1280,8 @@ void Accessors::FunctionCallerSetter( |
v8::Local<v8::String> name, |
v8::Local<v8::Value> val, |
const v8::PropertyCallbackInfo<void>& info) { |
- // Do nothing. |
+ // Function caller is non writable, non configurable. |
+ UNREACHABLE(); |
} |