Index: src/execution.cc |
diff --git a/src/execution.cc b/src/execution.cc |
index 2e164139c801e91a01c417a9e0b88dd0a60b8f50..b41c35d51e3245a5a2eefe2099d6f5341421af05 100644 |
--- a/src/execution.cc |
+++ b/src/execution.cc |
@@ -36,12 +36,12 @@ void StackGuard::reset_limits(const ExecutionAccess& lock) { |
} |
-static Handle<Object> Invoke(bool is_construct, |
- Handle<JSFunction> function, |
- Handle<Object> receiver, |
- int argc, |
- Handle<Object> args[], |
- bool* has_pending_exception) { |
+MUST_USE_RESULT static MaybeHandle<Object> Invoke( |
+ bool is_construct, |
+ Handle<JSFunction> function, |
+ Handle<Object> receiver, |
+ int argc, |
+ Handle<Object> args[]) { |
Isolate* isolate = function->GetIsolate(); |
// Entering JavaScript. |
@@ -49,9 +49,8 @@ static Handle<Object> Invoke(bool is_construct, |
CHECK(AllowJavascriptExecution::IsAllowed(isolate)); |
if (!ThrowOnJavascriptExecution::IsAllowed(isolate)) { |
isolate->ThrowIllegalOperation(); |
- *has_pending_exception = true; |
isolate->ReportPendingMessages(); |
- return Handle<Object>(); |
+ return MaybeHandle<Object>(); |
} |
// Placeholder for return value. |
@@ -100,9 +99,9 @@ static Handle<Object> Invoke(bool is_construct, |
#endif |
// Update the pending exception flag and return the value. |
- *has_pending_exception = value->IsException(); |
- ASSERT(*has_pending_exception == isolate->has_pending_exception()); |
- if (*has_pending_exception) { |
+ bool has_exception = value->IsException(); |
+ ASSERT(has_exception == isolate->has_pending_exception()); |
+ if (has_exception) { |
isolate->ReportPendingMessages(); |
#ifdef ENABLE_DEBUGGER_SUPPORT |
// Reset stepping state when script exits with uncaught exception. |
@@ -110,7 +109,7 @@ static Handle<Object> Invoke(bool is_construct, |
isolate->debug()->ClearStepping(); |
} |
#endif // ENABLE_DEBUGGER_SUPPORT |
- return Handle<Object>(); |
+ return MaybeHandle<Object>(); |
} else { |
isolate->clear_pending_message(); |
} |
@@ -119,18 +118,15 @@ static Handle<Object> Invoke(bool is_construct, |
} |
-Handle<Object> Execution::Call(Isolate* isolate, |
- Handle<Object> callable, |
- Handle<Object> receiver, |
- int argc, |
- Handle<Object> argv[], |
- bool* pending_exception, |
- bool convert_receiver) { |
- *pending_exception = false; |
- |
+MaybeHandle<Object> Execution::Call(Isolate* isolate, |
+ Handle<Object> callable, |
+ Handle<Object> receiver, |
+ int argc, |
+ Handle<Object> argv[], |
+ bool convert_receiver) { |
if (!callable->IsJSFunction()) { |
- callable = TryGetFunctionDelegate(isolate, callable, pending_exception); |
- if (*pending_exception) return callable; |
+ ASSIGN_RETURN_ON_EXCEPTION( |
+ isolate, callable, TryGetFunctionDelegate(isolate, callable), Object); |
} |
Handle<JSFunction> func = Handle<JSFunction>::cast(callable); |
@@ -147,29 +143,27 @@ Handle<Object> Execution::Call(Isolate* isolate, |
receiver = Handle<Object>(global, func->GetIsolate()); |
} |
} else { |
- receiver = ToObject(isolate, receiver, pending_exception); |
+ ASSIGN_RETURN_ON_EXCEPTION( |
+ isolate, receiver, ToObject(isolate, receiver), Object); |
} |
- if (*pending_exception) return callable; |
} |
- return Invoke(false, func, receiver, argc, argv, pending_exception); |
+ return Invoke(false, func, receiver, argc, argv); |
} |
-Handle<Object> Execution::New(Handle<JSFunction> func, |
- int argc, |
- Handle<Object> argv[], |
- bool* pending_exception) { |
- return Invoke(true, func, func->GetIsolate()->global_object(), argc, argv, |
- pending_exception); |
+MaybeHandle<Object> Execution::New(Handle<JSFunction> func, |
+ int argc, |
+ Handle<Object> argv[]) { |
+ return Invoke(true, func, func->GetIsolate()->global_object(), argc, argv); |
} |
-Handle<Object> Execution::TryCall(Handle<JSFunction> func, |
- Handle<Object> receiver, |
- int argc, |
- Handle<Object> args[], |
- bool* caught_exception) { |
+MaybeHandle<Object> Execution::TryCall(Handle<JSFunction> func, |
+ Handle<Object> receiver, |
+ int argc, |
+ Handle<Object> args[], |
+ Handle<Object>* exception_out) { |
// Enter a try-block while executing the JavaScript code. To avoid |
// duplicate error printing it must be non-verbose. Also, to avoid |
// creating message objects during stack overflow we shouldn't |
@@ -177,30 +171,30 @@ Handle<Object> Execution::TryCall(Handle<JSFunction> func, |
v8::TryCatch catcher; |
catcher.SetVerbose(false); |
catcher.SetCaptureMessage(false); |
- *caught_exception = false; |
// Get isolate now, because handle might be persistent |
// and get destroyed in the next call. |
Isolate* isolate = func->GetIsolate(); |
- Handle<Object> result = Invoke(false, func, receiver, argc, args, |
- caught_exception); |
+ MaybeHandle<Object> maybe_result = Invoke(false, func, receiver, argc, args); |
- if (*caught_exception) { |
+ if (maybe_result.is_null()) { |
ASSERT(catcher.HasCaught()); |
ASSERT(isolate->has_pending_exception()); |
ASSERT(isolate->external_caught_exception()); |
- if (isolate->pending_exception() == |
- isolate->heap()->termination_exception()) { |
- result = isolate->factory()->termination_exception(); |
- } else { |
- result = v8::Utils::OpenHandle(*catcher.Exception()); |
+ if (exception_out != NULL) { |
+ if (isolate->pending_exception() == |
+ isolate->heap()->termination_exception()) { |
+ *exception_out = isolate->factory()->termination_exception(); |
+ } else { |
+ *exception_out = v8::Utils::OpenHandle(*catcher.Exception()); |
+ } |
} |
isolate->OptionalRescheduleException(true); |
} |
ASSERT(!isolate->has_pending_exception()); |
ASSERT(!isolate->external_caught_exception()); |
- return result; |
+ return maybe_result; |
} |
@@ -231,9 +225,8 @@ Handle<Object> Execution::GetFunctionDelegate(Isolate* isolate, |
} |
-Handle<Object> Execution::TryGetFunctionDelegate(Isolate* isolate, |
- Handle<Object> object, |
- bool* has_pending_exception) { |
+MaybeHandle<Object> Execution::TryGetFunctionDelegate(Isolate* isolate, |
+ Handle<Object> object) { |
ASSERT(!object->IsJSFunction()); |
// If object is a function proxy, get its handler. Iterate if necessary. |
@@ -255,10 +248,8 @@ Handle<Object> Execution::TryGetFunctionDelegate(Isolate* isolate, |
// throw a non-callable exception. |
i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError( |
"called_non_callable", i::HandleVector<i::Object>(&object, 1)); |
- isolate->Throw(*error_obj); |
- *has_pending_exception = true; |
- return isolate->factory()->undefined_value(); |
+ return isolate->Throw<Object>(error_obj); |
} |
@@ -288,10 +279,8 @@ Handle<Object> Execution::GetConstructorDelegate(Isolate* isolate, |
} |
-Handle<Object> Execution::TryGetConstructorDelegate( |
- Isolate* isolate, |
- Handle<Object> object, |
- bool* has_pending_exception) { |
+MaybeHandle<Object> Execution::TryGetConstructorDelegate( |
+ Isolate* isolate, Handle<Object> object) { |
ASSERT(!object->IsJSFunction()); |
// If you return a function from here, it will be called when an |
@@ -316,38 +305,29 @@ Handle<Object> Execution::TryGetConstructorDelegate( |
// throw a non-callable exception. |
i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError( |
"called_non_callable", i::HandleVector<i::Object>(&object, 1)); |
- isolate->Throw(*error_obj); |
- *has_pending_exception = true; |
- |
- return isolate->factory()->undefined_value(); |
+ return isolate->Throw<Object>(error_obj); |
} |
void Execution::RunMicrotasks(Isolate* isolate) { |
ASSERT(isolate->microtask_pending()); |
- bool threw = false; |
Execution::Call( |
isolate, |
isolate->run_microtasks(), |
isolate->factory()->undefined_value(), |
0, |
- NULL, |
- &threw); |
- ASSERT(!threw); |
+ NULL).Assert(); |
} |
void Execution::EnqueueMicrotask(Isolate* isolate, Handle<Object> microtask) { |
- bool threw = false; |
Handle<Object> args[] = { microtask }; |
Execution::Call( |
isolate, |
isolate->enqueue_external_microtask(), |
isolate->factory()->undefined_value(), |
1, |
- args, |
- &threw); |
- ASSERT(!threw); |
+ args).Assert(); |
} |
@@ -665,78 +645,78 @@ void StackGuard::InitThread(const ExecutionAccess& lock) { |
// --- C a l l s t o n a t i v e s --- |
-#define RETURN_NATIVE_CALL(name, args, has_pending_exception) \ |
+#define RETURN_NATIVE_CALL(name, args) \ |
do { \ |
Handle<Object> argv[] = args; \ |
- ASSERT(has_pending_exception != NULL); \ |
return Call(isolate, \ |
isolate->name##_fun(), \ |
isolate->js_builtins_object(), \ |
- ARRAY_SIZE(argv), argv, \ |
- has_pending_exception); \ |
+ ARRAY_SIZE(argv), argv); \ |
} while (false) |
-Handle<Object> Execution::ToNumber( |
- Isolate* isolate, Handle<Object> obj, bool* exc) { |
- RETURN_NATIVE_CALL(to_number, { obj }, exc); |
+MaybeHandle<Object> Execution::ToNumber( |
+ Isolate* isolate, Handle<Object> obj) { |
+ RETURN_NATIVE_CALL(to_number, { obj }); |
} |
-Handle<Object> Execution::ToString( |
- Isolate* isolate, Handle<Object> obj, bool* exc) { |
- RETURN_NATIVE_CALL(to_string, { obj }, exc); |
+MaybeHandle<Object> Execution::ToString( |
+ Isolate* isolate, Handle<Object> obj) { |
+ RETURN_NATIVE_CALL(to_string, { obj }); |
} |
-Handle<Object> Execution::ToDetailString( |
- Isolate* isolate, Handle<Object> obj, bool* exc) { |
- RETURN_NATIVE_CALL(to_detail_string, { obj }, exc); |
+MaybeHandle<Object> Execution::ToDetailString( |
+ Isolate* isolate, Handle<Object> obj) { |
+ RETURN_NATIVE_CALL(to_detail_string, { obj }); |
} |
-Handle<Object> Execution::ToObject( |
- Isolate* isolate, Handle<Object> obj, bool* exc) { |
+MaybeHandle<Object> Execution::ToObject( |
+ Isolate* isolate, Handle<Object> obj) { |
if (obj->IsSpecObject()) return obj; |
- RETURN_NATIVE_CALL(to_object, { obj }, exc); |
+ RETURN_NATIVE_CALL(to_object, { obj }); |
} |
-Handle<Object> Execution::ToInteger( |
- Isolate* isolate, Handle<Object> obj, bool* exc) { |
- RETURN_NATIVE_CALL(to_integer, { obj }, exc); |
+MaybeHandle<Object> Execution::ToInteger( |
+ Isolate* isolate, Handle<Object> obj) { |
+ RETURN_NATIVE_CALL(to_integer, { obj }); |
} |
-Handle<Object> Execution::ToUint32( |
- Isolate* isolate, Handle<Object> obj, bool* exc) { |
- RETURN_NATIVE_CALL(to_uint32, { obj }, exc); |
+MaybeHandle<Object> Execution::ToUint32( |
+ Isolate* isolate, Handle<Object> obj) { |
+ RETURN_NATIVE_CALL(to_uint32, { obj }); |
} |
-Handle<Object> Execution::ToInt32( |
- Isolate* isolate, Handle<Object> obj, bool* exc) { |
- RETURN_NATIVE_CALL(to_int32, { obj }, exc); |
+MaybeHandle<Object> Execution::ToInt32( |
+ Isolate* isolate, Handle<Object> obj) { |
+ RETURN_NATIVE_CALL(to_int32, { obj }); |
} |
-Handle<Object> Execution::NewDate(Isolate* isolate, double time, bool* exc) { |
+MaybeHandle<Object> Execution::NewDate(Isolate* isolate, double time) { |
Handle<Object> time_obj = isolate->factory()->NewNumber(time); |
- RETURN_NATIVE_CALL(create_date, { time_obj }, exc); |
+ RETURN_NATIVE_CALL(create_date, { time_obj }); |
} |
#undef RETURN_NATIVE_CALL |
-Handle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern, |
- Handle<String> flags, |
- bool* exc) { |
+MaybeHandle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern, |
+ Handle<String> flags) { |
+ Isolate* isolate = pattern->GetIsolate(); |
Handle<JSFunction> function = Handle<JSFunction>( |
- pattern->GetIsolate()->native_context()->regexp_function()); |
- Handle<Object> re_obj = RegExpImpl::CreateRegExpLiteral( |
- function, pattern, flags, exc); |
- if (*exc) return Handle<JSRegExp>(); |
+ isolate->native_context()->regexp_function()); |
+ Handle<Object> re_obj; |
+ ASSIGN_RETURN_ON_EXCEPTION( |
+ isolate, re_obj, |
+ RegExpImpl::CreateRegExpLiteral(function, pattern, flags), |
+ JSRegExp); |
return Handle<JSRegExp>::cast(re_obj); |
} |
@@ -756,24 +736,22 @@ Handle<Object> Execution::CharAt(Handle<String> string, uint32_t index) { |
return factory->undefined_value(); |
} |
- bool caught_exception; |
Handle<Object> index_object = factory->NewNumberFromInt(int_index); |
Handle<Object> index_arg[] = { index_object }; |
- Handle<Object> result = TryCall(Handle<JSFunction>::cast(char_at), |
- string, |
- ARRAY_SIZE(index_arg), |
- index_arg, |
- &caught_exception); |
- if (caught_exception) { |
- return factory->undefined_value(); |
- } |
+ Handle<Object> result; |
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
+ isolate, result, |
+ TryCall(Handle<JSFunction>::cast(char_at), |
+ string, |
+ ARRAY_SIZE(index_arg), |
+ index_arg), |
+ factory->undefined_value()); |
return result; |
} |
-Handle<JSFunction> Execution::InstantiateFunction( |
- Handle<FunctionTemplateInfo> data, |
- bool* exc) { |
+MaybeHandle<JSFunction> Execution::InstantiateFunction( |
+ Handle<FunctionTemplateInfo> data) { |
Isolate* isolate = data->GetIsolate(); |
if (!data->do_not_cache()) { |
// Fast case: see if the function has already been instantiated |
@@ -785,62 +763,57 @@ Handle<JSFunction> Execution::InstantiateFunction( |
} |
// The function has not yet been instantiated in this context; do it. |
Handle<Object> args[] = { data }; |
- Handle<Object> result = Call(isolate, |
- isolate->instantiate_fun(), |
- isolate->js_builtins_object(), |
- ARRAY_SIZE(args), |
- args, |
- exc); |
- if (*exc) return Handle<JSFunction>::null(); |
+ Handle<Object> result; |
+ ASSIGN_RETURN_ON_EXCEPTION( |
+ isolate, result, |
+ Call(isolate, |
+ isolate->instantiate_fun(), |
+ isolate->js_builtins_object(), |
+ ARRAY_SIZE(args), |
+ args), |
+ JSFunction); |
return Handle<JSFunction>::cast(result); |
} |
-Handle<JSObject> Execution::InstantiateObject(Handle<ObjectTemplateInfo> data, |
- bool* exc) { |
+MaybeHandle<JSObject> Execution::InstantiateObject( |
+ Handle<ObjectTemplateInfo> data) { |
Isolate* isolate = data->GetIsolate(); |
+ Handle<Object> result; |
if (data->property_list()->IsUndefined() && |
!data->constructor()->IsUndefined()) { |
- // Initialization to make gcc happy. |
- Object* result = NULL; |
- { |
- HandleScope scope(isolate); |
- Handle<FunctionTemplateInfo> cons_template = |
- Handle<FunctionTemplateInfo>( |
- FunctionTemplateInfo::cast(data->constructor())); |
- Handle<JSFunction> cons = InstantiateFunction(cons_template, exc); |
- if (*exc) return Handle<JSObject>::null(); |
- Handle<Object> value = New(cons, 0, NULL, exc); |
- if (*exc) return Handle<JSObject>::null(); |
- result = *value; |
- } |
- ASSERT(!*exc); |
- return Handle<JSObject>(JSObject::cast(result)); |
+ Handle<FunctionTemplateInfo> cons_template = |
+ Handle<FunctionTemplateInfo>( |
+ FunctionTemplateInfo::cast(data->constructor())); |
+ Handle<JSFunction> cons; |
+ ASSIGN_RETURN_ON_EXCEPTION( |
+ isolate, cons, InstantiateFunction(cons_template), JSObject); |
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, result, New(cons, 0, NULL), JSObject); |
} else { |
Handle<Object> args[] = { data }; |
- Handle<Object> result = Call(isolate, |
- isolate->instantiate_fun(), |
- isolate->js_builtins_object(), |
- ARRAY_SIZE(args), |
- args, |
- exc); |
- if (*exc) return Handle<JSObject>::null(); |
- return Handle<JSObject>::cast(result); |
+ ASSIGN_RETURN_ON_EXCEPTION( |
+ isolate, result, |
+ Call(isolate, |
+ isolate->instantiate_fun(), |
+ isolate->js_builtins_object(), |
+ ARRAY_SIZE(args), |
+ args), |
+ JSObject); |
} |
+ return Handle<JSObject>::cast(result); |
} |
-void Execution::ConfigureInstance(Isolate* isolate, |
- Handle<Object> instance, |
- Handle<Object> instance_template, |
- bool* exc) { |
+MaybeHandle<Object> Execution::ConfigureInstance( |
+ Isolate* isolate, |
+ Handle<Object> instance, |
+ Handle<Object> instance_template) { |
Handle<Object> args[] = { instance, instance_template }; |
- Execution::Call(isolate, |
- isolate->configure_instance_fun(), |
- isolate->js_builtins_object(), |
- ARRAY_SIZE(args), |
- args, |
- exc); |
+ return Execution::Call(isolate, |
+ isolate->configure_instance_fun(), |
+ isolate->js_builtins_object(), |
+ ARRAY_SIZE(args), |
+ args); |
} |
@@ -850,14 +823,14 @@ Handle<String> Execution::GetStackTraceLine(Handle<Object> recv, |
Handle<Object> is_global) { |
Isolate* isolate = fun->GetIsolate(); |
Handle<Object> args[] = { recv, fun, pos, is_global }; |
- bool caught_exception; |
- Handle<Object> result = TryCall(isolate->get_stack_trace_line_fun(), |
- isolate->js_builtins_object(), |
- ARRAY_SIZE(args), |
- args, |
- &caught_exception); |
- if (caught_exception || !result->IsString()) { |
- return isolate->factory()->empty_string(); |
+ MaybeHandle<Object> maybe_result = |
+ TryCall(isolate->get_stack_trace_line_fun(), |
+ isolate->js_builtins_object(), |
+ ARRAY_SIZE(args), |
+ args); |
+ Handle<Object> result; |
+ if (!maybe_result.ToHandle(&result) || !result->IsString()) { |
+ return isolate->factory()->empty_string(); |
} |
return Handle<String>::cast(result); |