Revision: 24608
Author: [email protected]
Date: Tue Oct 14 14:46:11 2014 UTC
Log: Catch exceptions thrown when enqueuing change records.
[email protected]
BUG=chromium:417709
LOG=N
Review URL: https://codereview.chromium.org/653593002
https://code.google.com/p/v8/source/detail?r=24608
Added:
/branches/bleeding_edge/test/mjsunit/regress/regress-417709a.js
Modified:
/branches/bleeding_edge/src/accessors.cc
/branches/bleeding_edge/src/accessors.h
/branches/bleeding_edge/src/bootstrapper.cc
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/runtime/runtime-function.cc
/branches/bleeding_edge/src/runtime/runtime-object.cc
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/regress/regress-417709a.js Tue Oct
14 14:46:11 2014 UTC
@@ -0,0 +1,16 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --stack-size=100
+
+var a = [];
+
+Object.observe(a, function() {});
+
+function f(a, x) {
+ a.length = x;
+ f(a, x + 1);
+}
+
+assertThrows(function() { f(a, 1); }, RangeError);
=======================================
--- /branches/bleeding_edge/src/accessors.cc Thu Oct 2 10:52:12 2014 UTC
+++ /branches/bleeding_edge/src/accessors.cc Tue Oct 14 14:46:11 2014 UTC
@@ -172,7 +172,10 @@
LookupIterator it(object, Utils::OpenHandle(*name));
CHECK_EQ(LookupIterator::ACCESSOR, it.state());
DCHECK(it.HolderIsReceiverOrHiddenPrototype());
- Object::SetDataProperty(&it, value);
+
+ if (Object::SetDataProperty(&it, value).is_null()) {
+ isolate->OptionalRescheduleException(false);
+ }
}
@@ -247,7 +250,7 @@
if (uint32_v->Number() == number_v->Number()) {
maybe = JSArray::SetElementsLength(array_handle, uint32_v);
- maybe.Check();
+ if (maybe.is_null()) isolate->OptionalRescheduleException(false);
return;
}
@@ -881,9 +884,8 @@
}
-static Handle<Object> SetFunctionPrototype(Isolate* isolate,
- Handle<JSFunction> function,
- Handle<Object> value) {
+MUST_USE_RESULT static MaybeHandle<Object> SetFunctionPrototype(
+ Isolate* isolate, Handle<JSFunction> function, Handle<Object> value) {
Handle<Object> old_value;
bool is_observed = function->map()->is_observed();
if (is_observed) {
@@ -897,16 +899,17 @@
DCHECK(function->prototype() == *value);
if (is_observed && !old_value->SameValue(*value)) {
- JSObject::EnqueueChangeRecord(
+ MaybeHandle<Object> result = JSObject::EnqueueChangeRecord(
function, "update", isolate->factory()->prototype_string(),
old_value);
+ if (result.is_null()) return MaybeHandle<Object>();
}
return function;
}
-Handle<Object> Accessors::FunctionSetPrototype(Handle<JSFunction> function,
- Handle<Object> prototype) {
+MaybeHandle<Object> Accessors::FunctionSetPrototype(Handle<JSFunction>
function,
+ Handle<Object>
prototype) {
DCHECK(function->should_have_prototype());
Isolate* isolate = function->GetIsolate();
return SetFunctionPrototype(isolate, function, prototype);
@@ -937,7 +940,9 @@
}
Handle<JSFunction> object =
Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
- SetFunctionPrototype(isolate, object, value);
+ if (SetFunctionPrototype(isolate, object, value).is_null()) {
+ isolate->OptionalRescheduleException(false);
+ }
}
=======================================
--- /branches/bleeding_edge/src/accessors.h Thu Oct 2 10:52:12 2014 UTC
+++ /branches/bleeding_edge/src/accessors.h Tue Oct 14 14:46:11 2014 UTC
@@ -66,8 +66,8 @@
};
// Accessor functions called directly from the runtime system.
- static Handle<Object> FunctionSetPrototype(Handle<JSFunction> object,
- Handle<Object> value);
+ MUST_USE_RESULT static MaybeHandle<Object> FunctionSetPrototype(
+ Handle<JSFunction> object, Handle<Object> value);
static Handle<Object> FunctionGetArguments(Handle<JSFunction> object);
// Accessor infos.
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Wed Oct 8 14:42:31 2014 UTC
+++ /branches/bleeding_edge/src/bootstrapper.cc Tue Oct 14 14:46:11 2014 UTC
@@ -509,7 +509,7 @@
// prototype, otherwise the missing initial_array_prototype will cause
// assertions during startup.
native_context()->set_initial_array_prototype(*prototype);
- Accessors::FunctionSetPrototype(object_fun, prototype);
+ Accessors::FunctionSetPrototype(object_fun, prototype).Assert();
}
// Allocate the empty function as the prototype for function ECMAScript
@@ -1673,7 +1673,7 @@
isolate()->initial_object_prototype(), Builtins::kIllegal);
Handle<JSObject> prototype =
factory()->NewJSObject(isolate()->object_function(), TENURED);
- Accessors::FunctionSetPrototype(script_fun, prototype);
+ Accessors::FunctionSetPrototype(script_fun, prototype).Assert();
native_context()->set_script_function(*script_fun);
Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
@@ -1815,7 +1815,7 @@
isolate()->initial_object_prototype(), Builtins::kIllegal);
Handle<JSObject> prototype =
factory()->NewJSObject(isolate()->object_function(), TENURED);
- Accessors::FunctionSetPrototype(opaque_reference_fun, prototype);
+ Accessors::FunctionSetPrototype(opaque_reference_fun,
prototype).Assert();
native_context()->set_opaque_reference_function(*opaque_reference_fun);
}
=======================================
--- /branches/bleeding_edge/src/objects.cc Tue Oct 14 14:43:45 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc Tue Oct 14 14:46:11 2014 UTC
@@ -1811,10 +1811,10 @@
}
-void JSObject::EnqueueChangeRecord(Handle<JSObject> object,
- const char* type_str,
- Handle<Name> name,
- Handle<Object> old_value) {
+MaybeHandle<Object> JSObject::EnqueueChangeRecord(Handle<JSObject> object,
+ const char* type_str,
+ Handle<Name> name,
+ Handle<Object>
old_value) {
DCHECK(!object->IsJSGlobalProxy());
DCHECK(!object->IsJSGlobalObject());
Isolate* isolate = object->GetIsolate();
@@ -1823,10 +1823,9 @@
Handle<Object> args[] = { type, object, name, old_value };
int argc = name.is_null() ? 2 : old_value->IsTheHole() ? 3 : 4;
- Execution::Call(isolate,
- Handle<JSFunction>(isolate->observers_notify_change()),
- isolate->factory()->undefined_value(),
- argc, args).Assert();
+ return Execution::Call(isolate,
+
Handle<JSFunction>(isolate->observers_notify_change()),
+ isolate->factory()->undefined_value(), argc,
args);
}
@@ -2933,8 +2932,8 @@
}
-Handle<Object> Object::SetDataProperty(LookupIterator* it,
- Handle<Object> value) {
+MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it,
+ Handle<Object> value) {
// Proxies are handled on the WithHandler path. Other non-JSObjects
cannot
// have own properties.
Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
@@ -2960,8 +2959,10 @@
// Send the change record if there are observers.
if (is_observed && !value->SameValue(*maybe_old.ToHandleChecked())) {
- JSObject::EnqueueChangeRecord(receiver, "update", it->name(),
- maybe_old.ToHandleChecked());
+ RETURN_ON_EXCEPTION(it->isolate(), JSObject::EnqueueChangeRecord(
+ receiver, "update", it->name(),
+ maybe_old.ToHandleChecked()),
+ Object);
}
return value;
@@ -3012,8 +3013,10 @@
// Send the change record if there are observers.
if (receiver->map()->is_observed() &&
!it->name().is_identical_to(it->factory()->hidden_string())) {
- JSObject::EnqueueChangeRecord(receiver, "add", it->name(),
- it->factory()->the_hole_value());
+ RETURN_ON_EXCEPTION(it->isolate(), JSObject::EnqueueChangeRecord(
+ receiver, "add", it->name(),
+
it->factory()->the_hole_value()),
+ Object);
}
return value;
@@ -3862,7 +3865,10 @@
!Name::Equals(it.isolate()->factory()->prototype_string(),
name) ||
!Handle<JSFunction>::cast(object)->should_have_prototype())
{
- EnqueueChangeRecord(object, "update", name, old_value);
+ RETURN_ON_EXCEPTION(
+ it.isolate(),
+ EnqueueChangeRecord(object, "update", name, old_value),
+ Object);
}
}
return value;
@@ -3881,7 +3887,10 @@
if (old_value->SameValue(*value)) {
old_value = it.isolate()->factory()->the_hole_value();
}
- EnqueueChangeRecord(object, "reconfigure", name, old_value);
+ RETURN_ON_EXCEPTION(
+ it.isolate(),
+ EnqueueChangeRecord(object, "reconfigure", name,
old_value),
+ Object);
}
return value;
}
@@ -3894,7 +3903,10 @@
if (old_value->SameValue(*value)) {
old_value = it.isolate()->factory()->the_hole_value();
}
- EnqueueChangeRecord(object, "reconfigure", name, old_value);
+ RETURN_ON_EXCEPTION(
+ it.isolate(),
+ EnqueueChangeRecord(object, "reconfigure", name, old_value),
+ Object);
}
return value;
@@ -3918,7 +3930,10 @@
if (old_value->SameValue(*value)) {
old_value = it.isolate()->factory()->the_hole_value();
}
- EnqueueChangeRecord(object, "reconfigure", name, old_value);
+ RETURN_ON_EXCEPTION(
+ it.isolate(),
+ EnqueueChangeRecord(object, "reconfigure", name, old_value),
+ Object);
}
return value;
@@ -4891,7 +4906,9 @@
if (!maybe.has_value) return MaybeHandle<Object>();
if (!maybe.value) {
Handle<String> name = factory->Uint32ToString(index);
- EnqueueChangeRecord(object, "delete", name, old_value);
+ RETURN_ON_EXCEPTION(
+ isolate, EnqueueChangeRecord(object, "delete", name, old_value),
+ Object);
}
}
@@ -4977,7 +4994,9 @@
ReoptimizeIfPrototype(holder);
if (is_observed) {
- EnqueueChangeRecord(object, "delete", name, old_value);
+ RETURN_ON_EXCEPTION(
+ it.isolate(),
+ EnqueueChangeRecord(object, "delete", name, old_value),
Object);
}
return result;
@@ -5194,8 +5213,11 @@
DCHECK(!object->map()->is_extensible());
if (object->map()->is_observed()) {
- EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(),
- isolate->factory()->the_hole_value());
+ RETURN_ON_EXCEPTION(
+ isolate,
+ EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(),
+ isolate->factory()->the_hole_value()),
+ Object);
}
return object;
}
@@ -6168,7 +6190,8 @@
if (is_observed) {
const char* type = preexists ? "reconfigure" : "add";
- EnqueueChangeRecord(object, type, name, old_value);
+ RETURN_ON_EXCEPTION(
+ isolate, EnqueueChangeRecord(object, type, name, old_value),
Object);
}
return isolate->factory()->undefined_value();
@@ -11237,13 +11260,18 @@
// For deletions where the property was an accessor, old_values[i]
// will be the hole, which instructs EnqueueChangeRecord to elide
// the "oldValue" property.
- JSObject::EnqueueChangeRecord(
- array, "delete", isolate->factory()->Uint32ToString(indices[i]),
- old_values[i]);
+ RETURN_ON_EXCEPTION(
+ isolate,
+ JSObject::EnqueueChangeRecord(
+ array, "delete",
isolate->factory()->Uint32ToString(indices[i]),
+ old_values[i]),
+ Object);
}
- JSObject::EnqueueChangeRecord(
- array, "update", isolate->factory()->length_string(),
- old_length_handle);
+ RETURN_ON_EXCEPTION(isolate,
+ JSObject::EnqueueChangeRecord(
+ array, "update",
isolate->factory()->length_string(),
+ old_length_handle),
+ Object);
EndPerformSplice(array);
@@ -12451,27 +12479,38 @@
CHECK(new_length_handle->ToArrayIndex(&new_length));
BeginPerformSplice(Handle<JSArray>::cast(object));
- EnqueueChangeRecord(object, "add", name, old_value);
- EnqueueChangeRecord(object, "update",
isolate->factory()->length_string(),
- old_length_handle);
+ RETURN_ON_EXCEPTION(
+ isolate, EnqueueChangeRecord(object, "add", name, old_value),
Object);
+ RETURN_ON_EXCEPTION(
+ isolate, EnqueueChangeRecord(object, "update",
+ isolate->factory()->length_string(),
+ old_length_handle),
+ Object);
EndPerformSplice(Handle<JSArray>::cast(object));
Handle<JSArray> deleted = isolate->factory()->NewJSArray(0);
EnqueueSpliceRecord(Handle<JSArray>::cast(object), old_length,
deleted,
new_length - old_length);
} else {
- EnqueueChangeRecord(object, "add", name, old_value);
+ RETURN_ON_EXCEPTION(
+ isolate, EnqueueChangeRecord(object, "add", name, old_value),
Object);
}
} else if (old_value->IsTheHole()) {
- EnqueueChangeRecord(object, "reconfigure", name, old_value);
+ RETURN_ON_EXCEPTION(
+ isolate, EnqueueChangeRecord(object, "reconfigure", name,
old_value),
+ Object);
} else {
Handle<Object> new_value =
Object::GetElement(isolate, object, index).ToHandleChecked();
bool value_changed = !old_value->SameValue(*new_value);
if (old_attributes != new_attributes) {
if (!value_changed) old_value = isolate->factory()->the_hole_value();
- EnqueueChangeRecord(object, "reconfigure", name, old_value);
+ RETURN_ON_EXCEPTION(
+ isolate, EnqueueChangeRecord(object, "reconfigure", name,
old_value),
+ Object);
} else if (value_changed) {
- EnqueueChangeRecord(object, "update", name, old_value);
+ RETURN_ON_EXCEPTION(
+ isolate, EnqueueChangeRecord(object, "update", name, old_value),
+ Object);
}
}
=======================================
--- /branches/bleeding_edge/src/objects.h Tue Oct 14 14:43:45 2014 UTC
+++ /branches/bleeding_edge/src/objects.h Tue Oct 14 14:46:11 2014 UTC
@@ -1130,8 +1130,8 @@
StorePropertyMode data_store_mode = NORMAL_PROPERTY);
MUST_USE_RESULT static MaybeHandle<Object> WriteToReadOnlyProperty(
LookupIterator* it, Handle<Object> value, StrictMode strict_mode);
- static Handle<Object> SetDataProperty(LookupIterator* it,
- Handle<Object> value);
+ MUST_USE_RESULT static MaybeHandle<Object> SetDataProperty(
+ LookupIterator* it, Handle<Object> value);
MUST_USE_RESULT static MaybeHandle<Object> AddDataProperty(
LookupIterator* it, Handle<Object> value, PropertyAttributes
attributes,
StrictMode strict_mode, StoreFromKeyed store_mode);
@@ -2215,10 +2215,9 @@
Context* GetCreationContext();
// Enqueue change record for Object.observe. May cause GC.
- static void EnqueueChangeRecord(Handle<JSObject> object,
- const char* type,
- Handle<Name> name,
- Handle<Object> old_value);
+ MUST_USE_RESULT static MaybeHandle<Object> EnqueueChangeRecord(
+ Handle<JSObject> object, const char* type, Handle<Name> name,
+ Handle<Object> old_value);
private:
friend class DictionaryElementsAccessor;
=======================================
--- /branches/bleeding_edge/src/runtime/runtime-function.cc Tue Sep 30
10:46:04 2014 UTC
+++ /branches/bleeding_edge/src/runtime/runtime-function.cc Tue Oct 14
14:46:11 2014 UTC
@@ -201,7 +201,8 @@
CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
RUNTIME_ASSERT(fun->should_have_prototype());
- Accessors::FunctionSetPrototype(fun, value);
+ RETURN_FAILURE_ON_EXCEPTION(isolate,
+ Accessors::FunctionSetPrototype(fun, value));
return args[0]; // return TOS
}
=======================================
--- /branches/bleeding_edge/src/runtime/runtime-object.cc Fri Oct 10
14:59:53 2014 UTC
+++ /branches/bleeding_edge/src/runtime/runtime-object.cc Tue Oct 14
14:46:11 2014 UTC
@@ -362,8 +362,10 @@
Handle<Object> new_value =
Object::GetPrototypeSkipHiddenPrototypes(isolate, obj);
if (!new_value->SameValue(*old_value)) {
- JSObject::EnqueueChangeRecord(
- obj, "setPrototype", isolate->factory()->proto_string(),
old_value);
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate, JSObject::EnqueueChangeRecord(
+ obj, "setPrototype",
isolate->factory()->proto_string(),
+ old_value));
}
return *result;
}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.