Commit a6ff3f7f authored by adamk@chromium.org's avatar adamk@chromium.org

Handle exceptions thrown by Array.observe machinery

BUG=chromium:417709
LOG=N
R=yangguo@chromium.org

Review URL: https://codereview.chromium.org/651323003

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24646 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent e6a73c1e
...@@ -11120,10 +11120,9 @@ static bool GetOldValue(Isolate* isolate, ...@@ -11120,10 +11120,9 @@ static bool GetOldValue(Isolate* isolate,
return true; return true;
} }
static void EnqueueSpliceRecord(Handle<JSArray> object, MUST_USE_RESULT static MaybeHandle<Object> EnqueueSpliceRecord(
uint32_t index, Handle<JSArray> object, uint32_t index, Handle<JSArray> deleted,
Handle<JSArray> deleted, uint32_t add_count) {
uint32_t add_count) {
Isolate* isolate = object->GetIsolate(); Isolate* isolate = object->GetIsolate();
HandleScope scope(isolate); HandleScope scope(isolate);
Handle<Object> index_object = isolate->factory()->NewNumberFromUint(index); Handle<Object> index_object = isolate->factory()->NewNumberFromUint(index);
...@@ -11133,37 +11132,33 @@ static void EnqueueSpliceRecord(Handle<JSArray> object, ...@@ -11133,37 +11132,33 @@ static void EnqueueSpliceRecord(Handle<JSArray> object,
Handle<Object> args[] = Handle<Object> args[] =
{ object, index_object, deleted, add_count_object }; { object, index_object, deleted, add_count_object };
Execution::Call(isolate, return Execution::Call(
Handle<JSFunction>(isolate->observers_enqueue_splice()), isolate, Handle<JSFunction>(isolate->observers_enqueue_splice()),
isolate->factory()->undefined_value(), isolate->factory()->undefined_value(), arraysize(args), args);
arraysize(args),
args).Assert();
} }
static void BeginPerformSplice(Handle<JSArray> object) { MUST_USE_RESULT static MaybeHandle<Object> BeginPerformSplice(
Handle<JSArray> object) {
Isolate* isolate = object->GetIsolate(); Isolate* isolate = object->GetIsolate();
HandleScope scope(isolate); HandleScope scope(isolate);
Handle<Object> args[] = { object }; Handle<Object> args[] = { object };
Execution::Call(isolate, return Execution::Call(
Handle<JSFunction>(isolate->observers_begin_perform_splice()), isolate, Handle<JSFunction>(isolate->observers_begin_perform_splice()),
isolate->factory()->undefined_value(), isolate->factory()->undefined_value(), arraysize(args), args);
arraysize(args),
args).Assert();
} }
static void EndPerformSplice(Handle<JSArray> object) { MUST_USE_RESULT static MaybeHandle<Object> EndPerformSplice(
Handle<JSArray> object) {
Isolate* isolate = object->GetIsolate(); Isolate* isolate = object->GetIsolate();
HandleScope scope(isolate); HandleScope scope(isolate);
Handle<Object> args[] = { object }; Handle<Object> args[] = { object };
Execution::Call(isolate, return Execution::Call(
Handle<JSFunction>(isolate->observers_end_perform_splice()), isolate, Handle<JSFunction>(isolate->observers_end_perform_splice()),
isolate->factory()->undefined_value(), isolate->factory()->undefined_value(), arraysize(args), args);
arraysize(args),
args).Assert();
} }
...@@ -11227,7 +11222,7 @@ MaybeHandle<Object> JSArray::SetElementsLength( ...@@ -11227,7 +11222,7 @@ MaybeHandle<Object> JSArray::SetElementsLength(
CHECK(array->length()->ToArrayIndex(&new_length)); CHECK(array->length()->ToArrayIndex(&new_length));
if (old_length == new_length) return hresult; if (old_length == new_length) return hresult;
BeginPerformSplice(array); RETURN_ON_EXCEPTION(isolate, BeginPerformSplice(array), Object);
for (int i = 0; i < indices.length(); ++i) { for (int i = 0; i < indices.length(); ++i) {
// For deletions where the property was an accessor, old_values[i] // For deletions where the property was an accessor, old_values[i]
...@@ -11246,7 +11241,7 @@ MaybeHandle<Object> JSArray::SetElementsLength( ...@@ -11246,7 +11241,7 @@ MaybeHandle<Object> JSArray::SetElementsLength(
old_length_handle), old_length_handle),
Object); Object);
EndPerformSplice(array); RETURN_ON_EXCEPTION(isolate, EndPerformSplice(array), Object);
uint32_t index = Min(old_length, new_length); uint32_t index = Min(old_length, new_length);
uint32_t add_count = new_length > old_length ? new_length - old_length : 0; uint32_t add_count = new_length > old_length ? new_length - old_length : 0;
...@@ -11266,7 +11261,8 @@ MaybeHandle<Object> JSArray::SetElementsLength( ...@@ -11266,7 +11261,8 @@ MaybeHandle<Object> JSArray::SetElementsLength(
STRICT).Assert(); STRICT).Assert();
} }
EnqueueSpliceRecord(array, index, deleted, add_count); RETURN_ON_EXCEPTION(
isolate, EnqueueSpliceRecord(array, index, deleted, add_count), Object);
return hresult; return hresult;
} }
...@@ -12451,7 +12447,8 @@ MaybeHandle<Object> JSObject::SetElement(Handle<JSObject> object, ...@@ -12451,7 +12447,8 @@ MaybeHandle<Object> JSObject::SetElement(Handle<JSObject> object,
CHECK(old_length_handle->ToArrayIndex(&old_length)); CHECK(old_length_handle->ToArrayIndex(&old_length));
CHECK(new_length_handle->ToArrayIndex(&new_length)); CHECK(new_length_handle->ToArrayIndex(&new_length));
BeginPerformSplice(Handle<JSArray>::cast(object)); RETURN_ON_EXCEPTION(
isolate, BeginPerformSplice(Handle<JSArray>::cast(object)), Object);
RETURN_ON_EXCEPTION( RETURN_ON_EXCEPTION(
isolate, EnqueueChangeRecord(object, "add", name, old_value), Object); isolate, EnqueueChangeRecord(object, "add", name, old_value), Object);
RETURN_ON_EXCEPTION( RETURN_ON_EXCEPTION(
...@@ -12459,10 +12456,14 @@ MaybeHandle<Object> JSObject::SetElement(Handle<JSObject> object, ...@@ -12459,10 +12456,14 @@ MaybeHandle<Object> JSObject::SetElement(Handle<JSObject> object,
isolate->factory()->length_string(), isolate->factory()->length_string(),
old_length_handle), old_length_handle),
Object); Object);
EndPerformSplice(Handle<JSArray>::cast(object)); RETURN_ON_EXCEPTION(
isolate, EndPerformSplice(Handle<JSArray>::cast(object)), Object);
Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); Handle<JSArray> deleted = isolate->factory()->NewJSArray(0);
EnqueueSpliceRecord(Handle<JSArray>::cast(object), old_length, deleted, RETURN_ON_EXCEPTION(
new_length - old_length); isolate,
EnqueueSpliceRecord(Handle<JSArray>::cast(object), old_length,
deleted, new_length - old_length),
Object);
} else { } else {
RETURN_ON_EXCEPTION( RETURN_ON_EXCEPTION(
isolate, EnqueueChangeRecord(object, "add", name, old_value), Object); isolate, EnqueueChangeRecord(object, "add", name, old_value), Object);
......
// 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 = [];
Array.observe(a, function() {});
function f(a, x) {
a.length = x;
f(a, x + 1);
}
assertThrows(function() { f(a, 1); }, RangeError);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment