| 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);
|
|
|