From 7be66cf5d7f98316697088089c5deba504a3d879 Mon Sep 17 00:00:00 2001 From: "yangguo@chromium.org" Date: Mon, 1 Sep 2014 09:11:44 +0000 Subject: [PATCH] Do not expose termination exceptions to the Exception API. R=verwaest@chromium.org BUG=403509 LOG=N Review URL: https://codereview.chromium.org/516913003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23544 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/accessors.cc | 39 ++++-- src/api.cc | 115 +++++---------- src/builtins.cc | 17 +-- src/debug.cc | 32 +++-- src/elements.cc | 13 +- src/execution.cc | 68 ++++----- src/execution.h | 12 +- src/factory.cc | 70 +++++----- src/factory.h | 54 ++++---- src/ic/ic.cc | 14 +- src/isolate.cc | 24 ++-- src/isolate.h | 17 ++- src/json-parser.h | 4 +- src/json-stringifier.h | 9 +- src/jsregexp.cc | 13 +- src/objects.cc | 159 +++++++++++---------- src/parser.cc | 10 +- src/runtime.cc | 246 +++++++++++++++++---------------- src/scopes.cc | 10 +- test/cctest/test-thread-termination.cc | 12 ++ 20 files changed, 466 insertions(+), 472 deletions(-) diff --git a/src/accessors.cc b/src/accessors.cc index 9a2431b..03ab9c4 100644 --- a/src/accessors.cc +++ b/src/accessors.cc @@ -262,9 +262,15 @@ void Accessors::ArrayLengthSetter( return; } - isolate->ScheduleThrow( - *isolate->factory()->NewRangeError("invalid_array_length", - HandleVector(NULL, 0))); + Handle exception; + maybe = isolate->factory()->NewRangeError("invalid_array_length", + HandleVector(NULL, 0)); + if (!maybe.ToHandle(&exception)) { + isolate->OptionalRescheduleException(false); + return; + } + + isolate->ScheduleThrow(*exception); } @@ -1350,9 +1356,16 @@ static void ModuleGetExport( Isolate* isolate = instance->GetIsolate(); if (value->IsTheHole()) { Handle name = v8::Utils::OpenHandle(*property); - isolate->ScheduleThrow( - *isolate->factory()->NewReferenceError("not_defined", - HandleVector(&name, 1))); + + Handle exception; + MaybeHandle maybe = isolate->factory()->NewReferenceError( + "not_defined", HandleVector(&name, 1)); + if (!maybe.ToHandle(&exception)) { + isolate->OptionalRescheduleException(false); + return; + } + + isolate->ScheduleThrow(*exception); return; } info.GetReturnValue().Set(v8::Utils::ToLocal(Handle(value, isolate))); @@ -1368,12 +1381,18 @@ static void ModuleSetExport( DCHECK(context->IsModuleContext()); int slot = info.Data()->Int32Value(); Object* old_value = context->get(slot); + Isolate* isolate = context->GetIsolate(); if (old_value->IsTheHole()) { Handle name = v8::Utils::OpenHandle(*property); - Isolate* isolate = instance->GetIsolate(); - isolate->ScheduleThrow( - *isolate->factory()->NewReferenceError("not_defined", - HandleVector(&name, 1))); + Handle exception; + MaybeHandle maybe = isolate->factory()->NewReferenceError( + "not_defined", HandleVector(&name, 1)); + if (!maybe.ToHandle(&exception)) { + isolate->OptionalRescheduleException(false); + return; + } + + isolate->ScheduleThrow(*exception); return; } context->set(slot, *v8::Utils::OpenHandle(*value)); diff --git a/src/api.cc b/src/api.cc index 667f9af..a45510d 100644 --- a/src/api.cc +++ b/src/api.cc @@ -6820,90 +6820,37 @@ String::Value::~Value() { } -Local Exception::RangeError(v8::Handle raw_message) { - i::Isolate* isolate = i::Isolate::Current(); - LOG_API(isolate, "RangeError"); - ON_BAILOUT(isolate, "v8::Exception::RangeError()", return Local()); - ENTER_V8(isolate); - i::Object* error; - { - i::HandleScope scope(isolate); - i::Handle message = Utils::OpenHandle(*raw_message); - i::Handle result = isolate->factory()->NewRangeError(message); - error = *result; - } - i::Handle result(error, isolate); - return Utils::ToLocal(result); -} - - -Local Exception::ReferenceError(v8::Handle raw_message) { - i::Isolate* isolate = i::Isolate::Current(); - LOG_API(isolate, "ReferenceError"); - ON_BAILOUT(isolate, "v8::Exception::ReferenceError()", return Local()); - ENTER_V8(isolate); - i::Object* error; - { - i::HandleScope scope(isolate); - i::Handle message = Utils::OpenHandle(*raw_message); - i::Handle result = - isolate->factory()->NewReferenceError(message); - error = *result; - } - i::Handle result(error, isolate); - return Utils::ToLocal(result); -} - - -Local Exception::SyntaxError(v8::Handle raw_message) { - i::Isolate* isolate = i::Isolate::Current(); - LOG_API(isolate, "SyntaxError"); - ON_BAILOUT(isolate, "v8::Exception::SyntaxError()", return Local()); - ENTER_V8(isolate); - i::Object* error; - { - i::HandleScope scope(isolate); - i::Handle message = Utils::OpenHandle(*raw_message); - i::Handle result = isolate->factory()->NewSyntaxError(message); - error = *result; - } - i::Handle result(error, isolate); - return Utils::ToLocal(result); -} - - -Local Exception::TypeError(v8::Handle raw_message) { - i::Isolate* isolate = i::Isolate::Current(); - LOG_API(isolate, "TypeError"); - ON_BAILOUT(isolate, "v8::Exception::TypeError()", return Local()); - ENTER_V8(isolate); - i::Object* error; - { - i::HandleScope scope(isolate); - i::Handle message = Utils::OpenHandle(*raw_message); - i::Handle result = isolate->factory()->NewTypeError(message); - error = *result; - } - i::Handle result(error, isolate); - return Utils::ToLocal(result); -} - - -Local Exception::Error(v8::Handle raw_message) { - i::Isolate* isolate = i::Isolate::Current(); - LOG_API(isolate, "Error"); - ON_BAILOUT(isolate, "v8::Exception::Error()", return Local()); - ENTER_V8(isolate); - i::Object* error; - { - i::HandleScope scope(isolate); - i::Handle message = Utils::OpenHandle(*raw_message); - i::Handle result = isolate->factory()->NewError(message); - error = *result; - } - i::Handle result(error, isolate); - return Utils::ToLocal(result); -} +#define DEFINE_ERROR(NAME) \ + Local Exception::NAME(v8::Handle raw_message) { \ + i::Isolate* isolate = i::Isolate::Current(); \ + LOG_API(isolate, #NAME); \ + ON_BAILOUT(isolate, "v8::Exception::" #NAME "()", return Local()); \ + ENTER_V8(isolate); \ + i::Object* error; \ + { \ + i::HandleScope scope(isolate); \ + i::Handle message = Utils::OpenHandle(*raw_message); \ + i::Handle result; \ + EXCEPTION_PREAMBLE(isolate); \ + i::MaybeHandle maybe_result = \ + isolate->factory()->New##NAME(message); \ + has_pending_exception = !maybe_result.ToHandle(&result); \ + /* TODO(yangguo): crbug/403509. Return empty handle instead. */ \ + EXCEPTION_BAILOUT_CHECK( \ + isolate, v8::Undefined(reinterpret_cast(isolate))); \ + error = *result; \ + } \ + i::Handle result(error, isolate); \ + return Utils::ToLocal(result); \ + } + +DEFINE_ERROR(RangeError) +DEFINE_ERROR(ReferenceError) +DEFINE_ERROR(SyntaxError) +DEFINE_ERROR(TypeError) +DEFINE_ERROR(Error) + +#undef DEFINE_ERROR // --- D e b u g S u p p o r t --- diff --git a/src/builtins.cc b/src/builtins.cc index 7c64f65..14b0c93 100644 --- a/src/builtins.cc +++ b/src/builtins.cc @@ -1010,15 +1010,17 @@ BUILTIN(ArrayConcat) { BUILTIN(StrictModePoisonPill) { HandleScope scope(isolate); - return isolate->Throw(*isolate->factory()->NewTypeError( - "strict_poison_pill", HandleVector(NULL, 0))); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, + NewTypeError("strict_poison_pill", HandleVector(NULL, 0))); } BUILTIN(GeneratorPoisonPill) { HandleScope scope(isolate); - return isolate->Throw(*isolate->factory()->NewTypeError( - "generator_poison_pill", HandleVector(NULL, 0))); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, + NewTypeError("generator_poison_pill", HandleVector(NULL, 0))); } @@ -1115,10 +1117,9 @@ MUST_USE_RESULT static Object* HandleApiCallHelper( if (raw_holder->IsNull()) { // This function cannot be called with the given receiver. Abort! - Handle obj = - isolate->factory()->NewTypeError( - "illegal_invocation", HandleVector(&function, 1)); - return isolate->Throw(*obj); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, + NewTypeError("illegal_invocation", HandleVector(&function, 1))); } Object* raw_call_data = fun_data->call_code(); diff --git a/src/debug.cc b/src/debug.cc index f4ab115..5bdf53f 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -757,13 +757,9 @@ bool Debug::CompileDebuggerScript(Isolate* isolate, int index) { Handle function = factory->NewFunctionFromSharedFunctionInfo(function_info, context); - Handle exception; - MaybeHandle result = - Execution::TryCall(function, - handle(context->global_proxy()), - 0, - NULL, - &exception); + MaybeHandle maybe_exception; + MaybeHandle result = Execution::TryCall( + function, handle(context->global_proxy()), 0, NULL, &maybe_exception); // Check for caught exceptions. if (result.is_null()) { @@ -774,7 +770,8 @@ bool Debug::CompileDebuggerScript(Isolate* isolate, int index) { isolate, "error_loading_debugger", &computed_location, Vector >::empty(), Handle()); DCHECK(!isolate->has_pending_exception()); - if (!exception.is_null()) { + Handle exception; + if (maybe_exception.ToHandle(&exception)) { isolate->set_pending_exception(*exception); MessageHandler::ReportMessage(isolate, NULL, message); isolate->clear_pending_exception(); @@ -2865,11 +2862,12 @@ void Debug::NotifyMessageHandler(v8::DebugEvent event, Handle request_text = isolate_->factory()->NewStringFromTwoByte( command_text).ToHandleChecked(); Handle request_args[] = { request_text }; - Handle exception; Handle answer_value; Handle answer; - MaybeHandle maybe_result = Execution::TryCall( - process_debug_request, cmd_processor, 1, request_args, &exception); + MaybeHandle maybe_exception; + MaybeHandle maybe_result = + Execution::TryCall(process_debug_request, cmd_processor, 1, + request_args, &maybe_exception); if (maybe_result.ToHandle(&answer_value)) { if (answer_value->IsUndefined()) { @@ -2887,10 +2885,15 @@ void Debug::NotifyMessageHandler(v8::DebugEvent event, Handle is_running_args[] = { answer }; maybe_result = Execution::Call( isolate_, is_running, cmd_processor, 1, is_running_args); - running = maybe_result.ToHandleChecked()->IsTrue(); + Handle result; + if (!maybe_result.ToHandle(&result)) break; + running = result->IsTrue(); } else { - answer = Handle::cast( - Execution::ToString(isolate_, exception).ToHandleChecked()); + Handle exception; + if (!maybe_exception.ToHandle(&exception)) break; + Handle result; + if (!Execution::ToString(isolate_, exception).ToHandle(&result)) break; + answer = Handle::cast(result); } // Return the result. @@ -2903,6 +2906,7 @@ void Debug::NotifyMessageHandler(v8::DebugEvent event, // running state (through a continue command) or auto continue is active // and there are no more commands queued. } while (!running || has_commands()); + command_queue_.Clear(); } diff --git a/src/elements.cc b/src/elements.cc index 121dd7d..6b4f5ec 100644 --- a/src/elements.cc +++ b/src/elements.cc @@ -141,9 +141,9 @@ static bool HasKey(Handle array, Handle key_handle) { MUST_USE_RESULT static MaybeHandle ThrowArrayLengthRangeError(Isolate* isolate) { - return isolate->Throw( - isolate->factory()->NewRangeError("invalid_array_length", - HandleVector(NULL, 0))); + THROW_NEW_ERROR(isolate, NewRangeError("invalid_array_length", + HandleVector(NULL, 0)), + Object); } @@ -1421,10 +1421,9 @@ class DictionaryElementsAccessor // Deleting a non-configurable property in strict mode. Handle name = isolate->factory()->NewNumberFromUint(key); Handle args[2] = { name, obj }; - Handle error = - isolate->factory()->NewTypeError("strict_delete_property", - HandleVector(args, 2)); - return isolate->Throw(error); + THROW_NEW_ERROR(isolate, NewTypeError("strict_delete_property", + HandleVector(args, 2)), + Object); } return isolate->factory()->false_value(); } diff --git a/src/execution.cc b/src/execution.cc index 12dd862..7aa4f33 100644 --- a/src/execution.cc +++ b/src/execution.cc @@ -150,40 +150,43 @@ MaybeHandle Execution::New(Handle func, MaybeHandle Execution::TryCall(Handle func, - Handle receiver, - int argc, + Handle receiver, int argc, Handle args[], - Handle* exception_out) { + MaybeHandle* exception_out) { + bool is_termination = false; + Isolate* isolate = func->GetIsolate(); + MaybeHandle maybe_result; + if (exception_out != NULL) *exception_out = MaybeHandle(); // 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 // capture messages. - v8::TryCatch catcher; - catcher.SetVerbose(false); - catcher.SetCaptureMessage(false); - - // Get isolate now, because handle might be persistent - // and get destroyed in the next call. - Isolate* isolate = func->GetIsolate(); - MaybeHandle maybe_result = Invoke(false, func, receiver, argc, args); - - if (maybe_result.is_null()) { - DCHECK(catcher.HasCaught()); - DCHECK(isolate->has_pending_exception()); - DCHECK(isolate->external_caught_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()); + { + v8::TryCatch catcher; + catcher.SetVerbose(false); + catcher.SetCaptureMessage(false); + + maybe_result = Invoke(false, func, receiver, argc, args); + + if (maybe_result.is_null()) { + DCHECK(catcher.HasCaught()); + DCHECK(isolate->has_pending_exception()); + DCHECK(isolate->external_caught_exception()); + if (exception_out != NULL) { + if (isolate->pending_exception() == + isolate->heap()->termination_exception()) { + is_termination = true; + } else { + *exception_out = v8::Utils::OpenHandle(*catcher.Exception()); + } } + isolate->OptionalRescheduleException(true); } - isolate->OptionalRescheduleException(true); - } - DCHECK(!isolate->has_pending_exception()); - DCHECK(!isolate->external_caught_exception()); + DCHECK(!isolate->has_pending_exception()); + DCHECK(!isolate->external_caught_exception()); + } + if (is_termination) isolate->TerminateExecution(); return maybe_result; } @@ -236,10 +239,9 @@ MaybeHandle Execution::TryGetFunctionDelegate(Isolate* isolate, // If the Object doesn't have an instance-call handler we should // throw a non-callable exception. - i::Handle error_obj = isolate->factory()->NewTypeError( - "called_non_callable", i::HandleVector(&object, 1)); - - return isolate->Throw(error_obj); + THROW_NEW_ERROR(isolate, NewTypeError("called_non_callable", + i::HandleVector(&object, 1)), + Object); } @@ -293,9 +295,9 @@ MaybeHandle Execution::TryGetConstructorDelegate( // If the Object doesn't have an instance-call handler we should // throw a non-callable exception. - i::Handle error_obj = isolate->factory()->NewTypeError( - "called_non_callable", i::HandleVector(&object, 1)); - return isolate->Throw(error_obj); + THROW_NEW_ERROR(isolate, NewTypeError("called_non_callable", + i::HandleVector(&object, 1)), + Object); } diff --git a/src/execution.h b/src/execution.h index 2a41bb8..9af446b 100644 --- a/src/execution.h +++ b/src/execution.h @@ -46,12 +46,12 @@ class Execution V8_FINAL : public AllStatic { // any thrown exceptions. The return value is either the result of // calling the function (if caught exception is false) or the exception // that occurred (if caught exception is true). - static MaybeHandle TryCall( - Handle func, - Handle receiver, - int argc, - Handle argv[], - Handle* exception_out = NULL); + // In the exception case, exception_out holds the caught exceptions, unless + // it is a termination exception. + static MaybeHandle TryCall(Handle func, + Handle receiver, int argc, + Handle argv[], + MaybeHandle* exception_out = NULL); // ECMA-262 9.3 MUST_USE_RESULT static MaybeHandle ToNumber( diff --git a/src/factory.cc b/src/factory.cc index 5a07708..13cba9d 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -366,7 +366,7 @@ MaybeHandle Factory::InternalizedStringMapForString( MaybeHandle Factory::NewRawOneByteString( int length, PretenureFlag pretenure) { if (length > String::kMaxLength || length < 0) { - return isolate()->Throw(NewInvalidStringLengthError()); + THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqOneByteString); } CALL_HEAP_FUNCTION( isolate(), @@ -378,7 +378,7 @@ MaybeHandle Factory::NewRawOneByteString( MaybeHandle Factory::NewRawTwoByteString( int length, PretenureFlag pretenure) { if (length > String::kMaxLength || length < 0) { - return isolate()->Throw(NewInvalidStringLengthError()); + THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqTwoByteString); } CALL_HEAP_FUNCTION( isolate(), @@ -483,7 +483,7 @@ MaybeHandle Factory::NewConsString(Handle left, // Make sure that an out of memory exception is thrown if the length // of the new cons string is too large. if (length > String::kMaxLength || length < 0) { - return isolate()->Throw(NewInvalidStringLengthError()); + THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String); } bool left_is_one_byte = left->IsOneByteRepresentation(); @@ -616,7 +616,7 @@ MaybeHandle Factory::NewExternalStringFromAscii( const ExternalAsciiString::Resource* resource) { size_t length = resource->length(); if (length > static_cast(String::kMaxLength)) { - return isolate()->Throw(NewInvalidStringLengthError()); + THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String); } Handle map = external_ascii_string_map(); @@ -634,7 +634,7 @@ MaybeHandle Factory::NewExternalStringFromTwoByte( const ExternalTwoByteString::Resource* resource) { size_t length = resource->length(); if (length > static_cast(String::kMaxLength)) { - return isolate()->Throw(NewInvalidStringLengthError()); + THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String); } // For small strings we check whether the resource contains only @@ -1050,59 +1050,58 @@ Handle Factory::NewHeapNumber(double value, } -Handle Factory::NewTypeError(const char* message, - Vector< Handle > args) { +MaybeHandle Factory::NewTypeError(const char* message, + Vector > args) { return NewError("MakeTypeError", message, args); } -Handle Factory::NewTypeError(Handle message) { +MaybeHandle Factory::NewTypeError(Handle message) { return NewError("$TypeError", message); } -Handle Factory::NewRangeError(const char* message, - Vector< Handle > args) { +MaybeHandle Factory::NewRangeError(const char* message, + Vector > args) { return NewError("MakeRangeError", message, args); } -Handle Factory::NewRangeError(Handle message) { +MaybeHandle Factory::NewRangeError(Handle message) { return NewError("$RangeError", message); } -Handle Factory::NewSyntaxError(const char* message, - Handle args) { +MaybeHandle Factory::NewSyntaxError(const char* message, + Handle args) { return NewError("MakeSyntaxError", message, args); } -Handle Factory::NewSyntaxError(Handle message) { +MaybeHandle Factory::NewSyntaxError(Handle message) { return NewError("$SyntaxError", message); } -Handle Factory::NewReferenceError(const char* message, - Vector< Handle > args) { +MaybeHandle Factory::NewReferenceError(const char* message, + Vector > args) { return NewError("MakeReferenceError", message, args); } -Handle Factory::NewReferenceError(const char* message, - Handle args) { +MaybeHandle Factory::NewReferenceError(const char* message, + Handle args) { return NewError("MakeReferenceError", message, args); } -Handle Factory::NewReferenceError(Handle message) { +MaybeHandle Factory::NewReferenceError(Handle message) { return NewError("$ReferenceError", message); } -Handle Factory::NewError(const char* maker, - const char* message, - Vector< Handle > args) { +MaybeHandle Factory::NewError(const char* maker, const char* message, + Vector > args) { // Instantiate a closeable HandleScope for EscapeFrom. v8::EscapableHandleScope scope(reinterpret_cast(isolate())); Handle array = NewFixedArray(args.length()); @@ -1110,19 +1109,21 @@ Handle Factory::NewError(const char* maker, array->set(i, *args[i]); } Handle object = NewJSArrayWithElements(array); - Handle result = NewError(maker, message, object); + Handle result; + ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, + NewError(maker, message, object), Object); return result.EscapeFrom(&scope); } -Handle Factory::NewEvalError(const char* message, - Vector< Handle > args) { +MaybeHandle Factory::NewEvalError(const char* message, + Vector > args) { return NewError("MakeEvalError", message, args); } -Handle Factory::NewError(const char* message, - Vector< Handle > args) { +MaybeHandle Factory::NewError(const char* message, + Vector > args) { return NewError("MakeError", message, args); } @@ -1163,9 +1164,8 @@ Handle Factory::EmergencyNewError(const char* message, } -Handle Factory::NewError(const char* maker, - const char* message, - Handle args) { +MaybeHandle Factory::NewError(const char* maker, const char* message, + Handle args) { Handle make_str = InternalizeUtf8String(maker); Handle fun_obj = Object::GetProperty( isolate()->js_builtins_object(), make_str).ToHandleChecked(); @@ -1181,7 +1181,7 @@ Handle Factory::NewError(const char* maker, // Invoke the JavaScript factory method. If an exception is thrown while // running the factory method, use the exception as the result. Handle result; - Handle exception; + MaybeHandle exception; if (!Execution::TryCall(fun, isolate()->js_builtins_object(), arraysize(argv), @@ -1193,13 +1193,13 @@ Handle Factory::NewError(const char* maker, } -Handle Factory::NewError(Handle message) { +MaybeHandle Factory::NewError(Handle message) { return NewError("$Error", message); } -Handle Factory::NewError(const char* constructor, - Handle message) { +MaybeHandle Factory::NewError(const char* constructor, + Handle message) { Handle constr = InternalizeUtf8String(constructor); Handle fun = Handle::cast(Object::GetProperty( isolate()->js_builtins_object(), constr).ToHandleChecked()); @@ -1208,7 +1208,7 @@ Handle Factory::NewError(const char* constructor, // Invoke the JavaScript factory method. If an exception is thrown while // running the factory method, use the exception as the result. Handle result; - Handle exception; + MaybeHandle exception; if (!Execution::TryCall(fun, isolate()->js_builtins_object(), arraysize(argv), diff --git a/src/factory.h b/src/factory.h index f9329ae..ab48f28 100644 --- a/src/factory.h +++ b/src/factory.h @@ -507,40 +507,40 @@ class Factory V8_FINAL { // Interface for creating error objects. - Handle NewError(const char* maker, const char* message, - Handle args); + MaybeHandle NewError(const char* maker, const char* message, + Handle args); Handle EmergencyNewError(const char* message, Handle args); - Handle NewError(const char* maker, const char* message, - Vector< Handle > args); - Handle NewError(const char* message, - Vector< Handle > args); - Handle NewError(Handle message); - Handle NewError(const char* constructor, - Handle message); - - Handle NewTypeError(const char* message, - Vector< Handle > args); - Handle NewTypeError(Handle message); - - Handle NewRangeError(const char* message, - Vector< Handle > args); - Handle NewRangeError(Handle message); - - Handle NewInvalidStringLengthError() { + MaybeHandle NewError(const char* maker, const char* message, + Vector > args); + MaybeHandle NewError(const char* message, + Vector > args); + MaybeHandle NewError(Handle message); + MaybeHandle NewError(const char* constructor, Handle message); + + MaybeHandle NewTypeError(const char* message, + Vector > args); + MaybeHandle NewTypeError(Handle message); + + MaybeHandle NewRangeError(const char* message, + Vector > args); + MaybeHandle NewRangeError(Handle message); + + MaybeHandle NewInvalidStringLengthError() { return NewRangeError("invalid_string_length", HandleVector(NULL, 0)); } - Handle NewSyntaxError(const char* message, Handle args); - Handle NewSyntaxError(Handle message); + MaybeHandle NewSyntaxError(const char* message, Handle args); + MaybeHandle NewSyntaxError(Handle message); - Handle NewReferenceError(const char* message, - Vector< Handle > args); - Handle NewReferenceError(const char* message, Handle args); - Handle NewReferenceError(Handle message); + MaybeHandle NewReferenceError(const char* message, + Vector > args); + MaybeHandle NewReferenceError(const char* message, + Handle args); + MaybeHandle NewReferenceError(Handle message); - Handle NewEvalError(const char* message, - Vector< Handle > args); + MaybeHandle NewEvalError(const char* message, + Vector > args); Handle NumberToString(Handle number, bool check_number_string_cache = true); diff --git a/src/ic/ic.cc b/src/ic/ic.cc index 784a5e5..59db5bf 100644 --- a/src/ic/ic.cc +++ b/src/ic/ic.cc @@ -333,17 +333,14 @@ MaybeHandle IC::TypeError(const char* type, Handle object, Handle key) { HandleScope scope(isolate()); Handle args[2] = {key, object}; - Handle error = - isolate()->factory()->NewTypeError(type, HandleVector(args, 2)); - return isolate()->Throw(error); + THROW_NEW_ERROR(isolate(), NewTypeError(type, HandleVector(args, 2)), Object); } MaybeHandle IC::ReferenceError(const char* type, Handle name) { HandleScope scope(isolate()); - Handle error = - isolate()->factory()->NewReferenceError(type, HandleVector(&name, 1)); - return isolate()->Throw(error); + THROW_NEW_ERROR(isolate(), NewReferenceError(type, HandleVector(&name, 1)), + Object); } @@ -3116,9 +3113,8 @@ static Object* ThrowReferenceError(Isolate* isolate, Name* name) { // Throw a reference error. Handle name_handle(name); - Handle error = isolate->factory()->NewReferenceError( - "not_defined", HandleVector(&name_handle, 1)); - return isolate->Throw(*error); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewReferenceError("not_defined", HandleVector(&name_handle, 1))); } diff --git a/src/isolate.cc b/src/isolate.cc index 028da3d..f049208 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -645,7 +645,10 @@ void Isolate::ReportFailedAccessCheck(Handle receiver, v8::AccessType type) { if (!thread_local_top()->failed_access_check_callback_) { Handle message = factory()->InternalizeUtf8String("no access"); - ScheduleThrow(*factory()->NewTypeError(message)); + Handle error; + ASSIGN_RETURN_ON_EXCEPTION_VALUE( + this, error, factory()->NewTypeError(message), /* void */); + ScheduleThrow(*error); return; } @@ -862,12 +865,6 @@ Object* Isolate::ThrowIllegalOperation() { } -Object* Isolate::ThrowInvalidStringLength() { - return Throw(*factory()->NewRangeError( - "invalid_string_length", HandleVector(NULL, 0))); -} - - void Isolate::ScheduleThrow(Object* exception) { // When scheduling a throw we first throw the exception to get the // error reporting if it is uncaught before rescheduling it. @@ -2361,14 +2358,13 @@ void Isolate::RunMicrotasks() { Handle::cast(microtask); SaveContext save(this); set_context(microtask_function->context()->native_context()); - Handle exception; - MaybeHandle result = Execution::TryCall( - microtask_function, factory()->undefined_value(), - 0, NULL, &exception); + MaybeHandle maybe_exception; + MaybeHandle result = + Execution::TryCall(microtask_function, factory()->undefined_value(), + 0, NULL, &maybe_exception); // If execution is terminating, just bail out. - if (result.is_null() && - !exception.is_null() && - *exception == heap()->termination_exception()) { + Handle exception; + if (result.is_null() && maybe_exception.is_null()) { // Clear out any remaining callbacks in the queue. heap()->set_microtask_queue(heap()->empty_fixed_array()); set_pending_microtask_count(0); diff --git a/src/isolate.h b/src/isolate.h index 0437f32..8755dcd 100644 --- a/src/isolate.h +++ b/src/isolate.h @@ -134,6 +134,22 @@ typedef ZoneList > ZoneObjectList; #define ASSIGN_RETURN_ON_EXCEPTION(isolate, dst, call, T) \ ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, MaybeHandle()) +#define THROW_NEW_ERROR(isolate, call, T) \ + do { \ + Handle __error__; \ + ASSIGN_RETURN_ON_EXCEPTION(isolate, __error__, isolate->factory()->call, \ + T); \ + return isolate->Throw(__error__); \ + } while (false) + +#define THROW_NEW_ERROR_RETURN_FAILURE(isolate, call) \ + do { \ + Handle __error__; \ + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, __error__, \ + isolate->factory()->call); \ + return isolate->Throw(*__error__); \ + } while (false) + #define RETURN_ON_EXCEPTION_VALUE(isolate, call, value) \ do { \ if ((call).is_null()) { \ @@ -762,7 +778,6 @@ class Isolate { // Return pending location if any or unfilled structure. MessageLocation GetMessageLocation(); Object* ThrowIllegalOperation(); - Object* ThrowInvalidStringLength(); // Promote a scheduled exception to pending. Asserts has_scheduled_exception. Object* PromoteScheduledException(); diff --git a/src/json-parser.h b/src/json-parser.h index c23e50d..82ab9c5 100644 --- a/src/json-parser.h +++ b/src/json-parser.h @@ -244,7 +244,9 @@ MaybeHandle JsonParser::ParseJson() { MessageLocation location(factory->NewScript(source_), position_, position_ + 1); - Handle error = factory->NewSyntaxError(message, array); + Handle error; + ASSIGN_RETURN_ON_EXCEPTION(isolate(), error, + factory->NewSyntaxError(message, array), Object); return isolate()->template Throw(error, &location); } return result; diff --git a/src/json-stringifier.h b/src/json-stringifier.h index 1b108ce..e6f5cfd 100644 --- a/src/json-stringifier.h +++ b/src/json-stringifier.h @@ -258,8 +258,7 @@ MaybeHandle BasicJsonStringifier::Stringify(Handle object) { ShrinkCurrentPart(); Accumulate(); if (overflowed_) { - return isolate_->Throw( - isolate_->factory()->NewInvalidStringLengthError()); + THROW_NEW_ERROR(isolate_, NewInvalidStringLengthError(), Object); } return accumulator(); } @@ -372,8 +371,10 @@ BasicJsonStringifier::Result BasicJsonStringifier::StackPush( for (int i = 0; i < length; i++) { if (elements->get(i) == *object) { AllowHeapAllocation allow_to_return_error; - isolate_->Throw(*factory_->NewTypeError( - "circular_structure", HandleVector(NULL, 0))); + Handle error; + MaybeHandle maybe_error = factory_->NewTypeError( + "circular_structure", HandleVector(NULL, 0)); + if (maybe_error.ToHandle(&error)) isolate_->Throw(*error); return EXCEPTION; } } diff --git a/src/jsregexp.cc b/src/jsregexp.cc index 3853197..7891cd8 100644 --- a/src/jsregexp.cc +++ b/src/jsregexp.cc @@ -88,8 +88,8 @@ static inline MaybeHandle ThrowRegExpException( elements->set(0, *pattern); elements->set(1, *error_text); Handle array = factory->NewJSArrayWithElements(elements); - Handle regexp_err = factory->NewSyntaxError(message, array); - return isolate->Throw(regexp_err); + Handle regexp_err; + THROW_NEW_ERROR(isolate, NewSyntaxError(message, array), Object); } @@ -372,8 +372,7 @@ bool RegExpImpl::EnsureCompiledIrregexp( } -static bool CreateRegExpErrorObjectAndThrow(Handle re, - bool is_ascii, +static void CreateRegExpErrorObjectAndThrow(Handle re, bool is_ascii, Handle error_message, Isolate* isolate) { Factory* factory = isolate->factory(); @@ -381,10 +380,10 @@ static bool CreateRegExpErrorObjectAndThrow(Handle re, elements->set(0, re->Pattern()); elements->set(1, *error_message); Handle array = factory->NewJSArrayWithElements(elements); - Handle regexp_err = + Handle error; + MaybeHandle maybe_error = factory->NewSyntaxError("malformed_regexp", array); - isolate->Throw(*regexp_err); - return false; + if (maybe_error.ToHandle(&error)) isolate->Throw(*error); } diff --git a/src/objects.cc b/src/objects.cc index ed349cc..b176522 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -424,11 +424,10 @@ MaybeHandle Object::GetPropertyWithAccessor(Handle receiver, Handle info = Handle::cast(structure); if (!info->IsCompatibleReceiver(*receiver)) { Handle args[2] = { name, receiver }; - Handle error = - isolate->factory()->NewTypeError("incompatible_method_receiver", - HandleVector(args, - arraysize(args))); - return isolate->Throw(error); + THROW_NEW_ERROR(isolate, + NewTypeError("incompatible_method_receiver", + HandleVector(args, arraysize(args))), + Object); } if (structure->IsDeclaredAccessorInfo()) { return GetDeclaredAccessorProperty( @@ -496,11 +495,10 @@ MaybeHandle Object::SetPropertyWithAccessor( ExecutableAccessorInfo* info = ExecutableAccessorInfo::cast(*structure); if (!info->IsCompatibleReceiver(*receiver)) { Handle args[2] = { name, receiver }; - Handle error = - isolate->factory()->NewTypeError("incompatible_method_receiver", - HandleVector(args, - arraysize(args))); - return isolate->Throw(error); + THROW_NEW_ERROR(isolate, + NewTypeError("incompatible_method_receiver", + HandleVector(args, arraysize(args))), + Object); } Object* call_obj = info->setter(); v8::AccessorNameSetterCallback call_fun = @@ -524,10 +522,9 @@ MaybeHandle Object::SetPropertyWithAccessor( } else { if (strict_mode == SLOPPY) return value; Handle args[2] = { name, holder }; - Handle error = - isolate->factory()->NewTypeError("no_setter_in_callback", - HandleVector(args, 2)); - return isolate->Throw(error); + THROW_NEW_ERROR( + isolate, NewTypeError("no_setter_in_callback", HandleVector(args, 2)), + Object); } } @@ -2909,9 +2906,9 @@ MaybeHandle Object::SetProperty(LookupIterator* it, // throw a reference error in strict mode. if (it->GetReceiver()->IsJSGlobalObject() && strict_mode == STRICT) { Handle args[1] = {it->name()}; - Handle error = it->isolate()->factory()->NewReferenceError( - "not_defined", HandleVector(args, 1)); - return it->isolate()->Throw(error); + THROW_NEW_ERROR(it->isolate(), + NewReferenceError("not_defined", HandleVector(args, 1)), + Object); } return AddDataProperty(it, value, NONE, strict_mode, store_mode); @@ -2924,9 +2921,10 @@ MaybeHandle Object::WriteToReadOnlyProperty(LookupIterator* it, if (strict_mode != STRICT) return value; Handle args[] = {it->name(), it->GetReceiver()}; - Handle error = it->factory()->NewTypeError( - "strict_read_only_property", HandleVector(args, arraysize(args))); - return it->isolate()->Throw(error); + THROW_NEW_ERROR(it->isolate(), + NewTypeError("strict_read_only_property", + HandleVector(args, arraysize(args))), + Object); } @@ -2989,9 +2987,10 @@ MaybeHandle Object::AddDataProperty(LookupIterator* it, if (strict_mode == SLOPPY) return value; Handle args[1] = {it->name()}; - Handle error = it->factory()->NewTypeError( - "object_not_extensible", HandleVector(args, arraysize(args))); - return it->isolate()->Throw(error); + THROW_NEW_ERROR(it->isolate(), + NewTypeError("object_not_extensible", + HandleVector(args, arraysize(args))), + Object); } it->ApplyTransitionToDataProperty(); @@ -3483,9 +3482,9 @@ MaybeHandle JSProxy::SetPropertyViaPrototypesWithHandler( isolate->factory()->InternalizeOneByteString( STATIC_ASCII_VECTOR("getPropertyDescriptor")); Handle args[] = { handler, trap, name }; - Handle error = isolate->factory()->NewTypeError( - "proxy_prop_not_configurable", HandleVector(args, arraysize(args))); - return isolate->Throw(error); + THROW_NEW_ERROR(isolate, NewTypeError("proxy_prop_not_configurable", + HandleVector(args, arraysize(args))), + Object); } DCHECK(configurable->IsTrue()); @@ -3507,9 +3506,9 @@ MaybeHandle JSProxy::SetPropertyViaPrototypesWithHandler( if (!*done) return isolate->factory()->the_hole_value(); if (strict_mode == SLOPPY) return value; Handle args[] = { name, receiver }; - Handle error = isolate->factory()->NewTypeError( - "strict_read_only_property", HandleVector(args, arraysize(args))); - return isolate->Throw(error); + THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", + HandleVector(args, arraysize(args))), + Object); } // We have an AccessorDescriptor. @@ -3524,9 +3523,9 @@ MaybeHandle JSProxy::SetPropertyViaPrototypesWithHandler( if (strict_mode == SLOPPY) return value; Handle args2[] = { name, proxy }; - Handle error = isolate->factory()->NewTypeError( - "no_setter_in_callback", HandleVector(args2, arraysize(args2))); - return isolate->Throw(error); + THROW_NEW_ERROR(isolate, NewTypeError("no_setter_in_callback", + HandleVector(args2, arraysize(args2))), + Object); } @@ -3554,9 +3553,9 @@ MaybeHandle JSProxy::DeletePropertyWithHandler( Handle trap_name = isolate->factory()->InternalizeOneByteString( STATIC_ASCII_VECTOR("delete")); Handle args[] = { handler, trap_name }; - Handle error = isolate->factory()->NewTypeError( - "handler_failed", HandleVector(args, arraysize(args))); - return isolate->Throw(error); + THROW_NEW_ERROR(isolate, NewTypeError("handler_failed", + HandleVector(args, arraysize(args))), + Object); } return isolate->factory()->ToBoolean(result_bool); } @@ -3630,9 +3629,10 @@ Maybe JSProxy::GetPropertyAttributesWithHandler( Handle trap = isolate->factory()->InternalizeOneByteString( STATIC_ASCII_VECTOR("getPropertyDescriptor")); Handle args[] = { handler, trap, name }; - Handle error = isolate->factory()->NewTypeError( + Handle error; + MaybeHandle maybe_error = isolate->factory()->NewTypeError( "proxy_prop_not_configurable", HandleVector(args, arraysize(args))); - isolate->Throw(*error); + if (maybe_error.ToHandle(&error)) isolate->Throw(*error); return maybe(NONE); } @@ -3692,9 +3692,10 @@ MaybeHandle JSProxy::CallTrap(Handle proxy, if (trap->IsUndefined()) { if (derived.is_null()) { Handle args[] = { handler, trap_name }; - Handle error = isolate->factory()->NewTypeError( - "handler_trap_missing", HandleVector(args, arraysize(args))); - return isolate->Throw(error); + THROW_NEW_ERROR(isolate, + NewTypeError("handler_trap_missing", + HandleVector(args, arraysize(args))), + Object); } trap = Handle(derived); } @@ -4846,11 +4847,9 @@ MaybeHandle JSObject::DeleteElement(Handle object, // Deleting a non-configurable property in strict mode. Handle name = factory->NewNumberFromUint(index); Handle args[2] = { name, object }; - Handle error = - factory->NewTypeError("strict_delete_property", - HandleVector(args, 2)); - isolate->Throw(*error); - return Handle(); + THROW_NEW_ERROR(isolate, NewTypeError("strict_delete_property", + HandleVector(args, 2)), + Object); } return factory->false_value(); } @@ -4952,10 +4951,10 @@ MaybeHandle JSObject::DeleteProperty(Handle object, // Fail if the property is not configurable. if (delete_mode == STRICT_DELETION) { Handle args[2] = {name, object}; - Handle error = it.isolate()->factory()->NewTypeError( - "strict_delete_property", HandleVector(args, arraysize(args))); - it.isolate()->Throw(*error); - return Handle(); + THROW_NEW_ERROR(it.isolate(), + NewTypeError("strict_delete_property", + HandleVector(args, arraysize(args))), + Object); } return it.isolate()->factory()->false_value(); } @@ -5180,11 +5179,10 @@ MaybeHandle JSObject::PreventExtensions(Handle object) { // It's not possible to seal objects with external array elements if (object->HasExternalArrayElements() || object->HasFixedTypedArrayElements()) { - Handle error = - isolate->factory()->NewTypeError( - "cant_prevent_ext_external_array_elements", - HandleVector(&object, 1)); - return isolate->Throw(error); + THROW_NEW_ERROR(isolate, + NewTypeError("cant_prevent_ext_external_array_elements", + HandleVector(&object, 1)), + Object); } // If there are fast elements we normalize. @@ -5263,11 +5261,10 @@ MaybeHandle JSObject::Freeze(Handle object) { // It's not possible to freeze objects with external array elements if (object->HasExternalArrayElements() || object->HasFixedTypedArrayElements()) { - Handle error = - isolate->factory()->NewTypeError( - "cant_prevent_ext_external_array_elements", - HandleVector(&object, 1)); - return isolate->Throw(error); + THROW_NEW_ERROR(isolate, + NewTypeError("cant_prevent_ext_external_array_elements", + HandleVector(&object, 1)), + Object); } Handle new_element_dictionary; @@ -11710,9 +11707,9 @@ MaybeHandle JSObject::SetPrototype(Handle object, // paragraph. if (!object->map()->is_extensible()) { Handle args[] = { object }; - Handle error = isolate->factory()->NewTypeError( - "non_extensible_proto", HandleVector(args, arraysize(args))); - return isolate->Throw(error); + THROW_NEW_ERROR(isolate, NewTypeError("non_extensible_proto", + HandleVector(args, arraysize(args))), + Object); } // Before we can set the prototype we need to be sure @@ -11724,9 +11721,9 @@ MaybeHandle JSObject::SetPrototype(Handle object, !iter.IsAtEnd(); iter.Advance()) { if (JSReceiver::cast(iter.GetCurrent()) == *object) { // Cycle detected. - Handle error = isolate->factory()->NewError( - "cyclic_proto", HandleVector(NULL, 0)); - return isolate->Throw(error); + THROW_NEW_ERROR(isolate, + NewError("cyclic_proto", HandleVector(NULL, 0)), + Object); } } @@ -11937,9 +11934,9 @@ MaybeHandle JSObject::SetElementWithCallback(Handle object, if (strict_mode == SLOPPY) return value; Handle key(isolate->factory()->NewNumberFromUint(index)); Handle args[2] = { key, holder }; - Handle error = isolate->factory()->NewTypeError( - "no_setter_in_callback", HandleVector(args, 2)); - return isolate->Throw(error); + THROW_NEW_ERROR( + isolate, NewTypeError("no_setter_in_callback", HandleVector(args, 2)), + Object); } } @@ -12148,10 +12145,9 @@ MaybeHandle JSObject::SetDictionaryElement( } else { Handle number = isolate->factory()->NewNumberFromUint(index); Handle args[2] = { number, object }; - Handle error = - isolate->factory()->NewTypeError("strict_read_only_property", - HandleVector(args, 2)); - return isolate->Throw(error); + THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", + HandleVector(args, 2)), + Object); } } // Elements of the arguments object in slow mode might be slow aliases. @@ -12186,10 +12182,9 @@ MaybeHandle JSObject::SetDictionaryElement( Handle number = isolate->factory()->NewNumberFromUint(index); Handle name = isolate->factory()->NumberToString(number); Handle args[1] = { name }; - Handle error = - isolate->factory()->NewTypeError("object_not_extensible", - HandleVector(args, 1)); - return isolate->Throw(error); + THROW_NEW_ERROR(isolate, NewTypeError("object_not_extensible", + HandleVector(args, 1)), + Object); } } @@ -12409,9 +12404,9 @@ MaybeHandle JSObject::SetElement(Handle object, set_mode == DEFINE_PROPERTY) { Handle number = isolate->factory()->NewNumberFromUint(index); Handle args[] = { object, number }; - Handle error = isolate->factory()->NewTypeError( - "redef_external_array_element", HandleVector(args, arraysize(args))); - return isolate->Throw(error); + THROW_NEW_ERROR(isolate, NewTypeError("redef_external_array_element", + HandleVector(args, arraysize(args))), + Object); } // Normalize the elements to enable attributes on the property. @@ -12863,9 +12858,9 @@ MaybeHandle JSArray::ReadOnlyLengthError(Handle array) { Isolate* isolate = array->GetIsolate(); Handle length = isolate->factory()->length_string(); Handle args[2] = { length, array }; - Handle error = isolate->factory()->NewTypeError( - "strict_read_only_property", HandleVector(args, arraysize(args))); - return isolate->Throw(error); + THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", + HandleVector(args, arraysize(args))), + Object); } diff --git a/src/parser.cc b/src/parser.cc index a3061dc..24510e3 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -3955,10 +3955,12 @@ void Parser::ThrowPendingError() { isolate()->debug()->OnCompileError(script_); Handle array = factory->NewJSArrayWithElements(elements); - Handle result = pending_error_is_reference_error_ - ? factory->NewReferenceError(pending_error_message_, array) - : factory->NewSyntaxError(pending_error_message_, array); - isolate()->Throw(*result, &location); + Handle error; + MaybeHandle maybe_error = + pending_error_is_reference_error_ + ? factory->NewReferenceError(pending_error_message_, array) + : factory->NewSyntaxError(pending_error_message_, array); + if (maybe_error.ToHandle(&error)) isolate()->Throw(*error, &location); } } diff --git a/src/runtime.cc b/src/runtime.cc index c69882f..40468c2 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -849,15 +849,15 @@ RUNTIME_FUNCTION(Runtime_ArrayBufferInitialize) { } size_t allocated_length = 0; if (!TryNumberToSize(isolate, *byteLength, &allocated_length)) { - return isolate->Throw( - *isolate->factory()->NewRangeError("invalid_array_buffer_length", - HandleVector(NULL, 0))); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewRangeError("invalid_array_buffer_length", + HandleVector(NULL, 0))); } if (!Runtime::SetupArrayBufferAllocatingData(isolate, holder, allocated_length)) { - return isolate->Throw( - *isolate->factory()->NewRangeError("invalid_array_buffer_length", - HandleVector(NULL, 0))); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewRangeError("invalid_array_buffer_length", + HandleVector(NULL, 0))); } return *holder; } @@ -987,9 +987,9 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) { size_t length = byte_length / element_size; if (length > static_cast(Smi::kMaxValue)) { - return isolate->Throw( - *isolate->factory()->NewRangeError("invalid_typed_array_length", - HandleVector(NULL, 0))); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewRangeError("invalid_typed_array_length", + HandleVector(NULL, 0))); } // All checks are done, now we can modify objects. @@ -1069,9 +1069,9 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) { if ((length > static_cast(Smi::kMaxValue)) || (length > (kMaxInt / element_size))) { - return isolate->Throw(*isolate->factory()-> - NewRangeError("invalid_typed_array_length", - HandleVector(NULL, 0))); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewRangeError("invalid_typed_array_length", + HandleVector(NULL, 0))); } size_t byte_length = length * element_size; @@ -1099,9 +1099,9 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) { if (!Runtime::SetupArrayBufferAllocatingData( isolate, buffer, byte_length, false)) { - return isolate->Throw(*isolate->factory()-> - NewRangeError("invalid_array_buffer_length", - HandleVector(NULL, 0))); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewRangeError("invalid_array_buffer_length", + HandleVector(NULL, 0))); } holder->set_buffer(*buffer); @@ -1183,9 +1183,11 @@ enum TypedArraySetResultCodes { RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) { HandleScope scope(isolate); DCHECK(args.length() == 3); - if (!args[0]->IsJSTypedArray()) - return isolate->Throw(*isolate->factory()->NewTypeError( - "not_typed_array", HandleVector(NULL, 0))); + if (!args[0]->IsJSTypedArray()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, + NewTypeError("not_typed_array", HandleVector(NULL, 0))); + } if (!args[1]->IsJSTypedArray()) return Smi::FromInt(TYPED_ARRAY_SET_NON_TYPED_ARRAY); @@ -1202,11 +1204,12 @@ RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) { size_t source_length = NumberToSize(isolate, source->length()); size_t target_byte_length = NumberToSize(isolate, target->byte_length()); size_t source_byte_length = NumberToSize(isolate, source->byte_length()); - if (offset > target_length || - offset + source_length > target_length || - offset + source_length < offset) // overflow - return isolate->Throw(*isolate->factory()->NewRangeError( - "typed_array_set_source_too_large", HandleVector(NULL, 0))); + if (offset > target_length || offset + source_length > target_length || + offset + source_length < offset) { // overflow + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewRangeError("typed_array_set_source_too_large", + HandleVector(NULL, 0))); + } size_t target_offset = NumberToSize(isolate, target->byte_offset()); size_t source_offset = NumberToSize(isolate, source->byte_offset()); @@ -1401,22 +1404,22 @@ static bool DataViewSetValue( } -#define DATA_VIEW_GETTER(TypeName, Type, Converter) \ - RUNTIME_FUNCTION(Runtime_DataViewGet##TypeName) { \ - HandleScope scope(isolate); \ - DCHECK(args.length() == 3); \ - CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \ - CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1); \ - CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2); \ - Type result; \ - if (DataViewGetValue( \ - isolate, holder, offset, is_little_endian, &result)) { \ - return *isolate->factory()->Converter(result); \ - } else { \ - return isolate->Throw(*isolate->factory()->NewRangeError( \ - "invalid_data_view_accessor_offset", \ - HandleVector(NULL, 0))); \ - } \ +#define DATA_VIEW_GETTER(TypeName, Type, Converter) \ + RUNTIME_FUNCTION(Runtime_DataViewGet##TypeName) { \ + HandleScope scope(isolate); \ + DCHECK(args.length() == 3); \ + CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \ + CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1); \ + CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2); \ + Type result; \ + if (DataViewGetValue(isolate, holder, offset, is_little_endian, \ + &result)) { \ + return *isolate->factory()->Converter(result); \ + } else { \ + THROW_NEW_ERROR_RETURN_FAILURE( \ + isolate, NewRangeError("invalid_data_view_accessor_offset", \ + HandleVector(NULL, 0))); \ + } \ } DATA_VIEW_GETTER(Uint8, uint8_t, NewNumberFromUint) @@ -1483,23 +1486,22 @@ double DataViewConvertValue(double value) { } -#define DATA_VIEW_SETTER(TypeName, Type) \ - RUNTIME_FUNCTION(Runtime_DataViewSet##TypeName) { \ - HandleScope scope(isolate); \ - DCHECK(args.length() == 4); \ - CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \ - CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1); \ - CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2); \ - CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3); \ - Type v = DataViewConvertValue(value->Number()); \ - if (DataViewSetValue( \ - isolate, holder, offset, is_little_endian, v)) { \ - return isolate->heap()->undefined_value(); \ - } else { \ - return isolate->Throw(*isolate->factory()->NewRangeError( \ - "invalid_data_view_accessor_offset", \ - HandleVector(NULL, 0))); \ - } \ +#define DATA_VIEW_SETTER(TypeName, Type) \ + RUNTIME_FUNCTION(Runtime_DataViewSet##TypeName) { \ + HandleScope scope(isolate); \ + DCHECK(args.length() == 4); \ + CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \ + CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1); \ + CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2); \ + CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3); \ + Type v = DataViewConvertValue(value->Number()); \ + if (DataViewSetValue(isolate, holder, offset, is_little_endian, v)) { \ + return isolate->heap()->undefined_value(); \ + } else { \ + THROW_NEW_ERROR_RETURN_FAILURE( \ + isolate, NewRangeError("invalid_data_view_accessor_offset", \ + HandleVector(NULL, 0))); \ + } \ } DATA_VIEW_SETTER(Uint8, uint8_t) @@ -2167,9 +2169,8 @@ RUNTIME_FUNCTION(Runtime_EnableAccessChecks) { static Object* ThrowRedeclarationError(Isolate* isolate, Handle name) { HandleScope scope(isolate); Handle args[1] = { name }; - Handle error = isolate->factory()->NewTypeError( - "var_redeclaration", HandleVector(args, 1)); - return isolate->Throw(*error); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError("var_redeclaration", HandleVector(args, 1))); } @@ -3075,8 +3076,7 @@ RUNTIME_FUNCTION(Runtime_ThrowGeneratorStateError) { const char* message = continuation == JSGeneratorObject::kGeneratorClosed ? "generator_finished" : "generator_running"; Vector< Handle > argv = HandleVector(NULL, 0); - Handle error = isolate->factory()->NewError(message, argv); - return isolate->Throw(*error); + THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewError(message, argv)); } @@ -4813,9 +4813,9 @@ MaybeHandle Runtime::GetObjectProperty(Isolate* isolate, Handle key) { if (object->IsUndefined() || object->IsNull()) { Handle args[2] = { key, object }; - return isolate->Throw( - isolate->factory()->NewTypeError("non_object_property_load", - HandleVector(args, 2))); + THROW_NEW_ERROR(isolate, NewTypeError("non_object_property_load", + HandleVector(args, 2)), + Object); } // Check if the given key is an array index. @@ -5088,10 +5088,9 @@ MaybeHandle Runtime::SetObjectProperty(Isolate* isolate, StrictMode strict_mode) { if (object->IsUndefined() || object->IsNull()) { Handle args[2] = { key, object }; - Handle error = - isolate->factory()->NewTypeError("non_object_property_store", - HandleVector(args, 2)); - return isolate->Throw(error); + THROW_NEW_ERROR(isolate, NewTypeError("non_object_property_store", + HandleVector(args, 2)), + Object); } if (object->IsJSProxy()) { @@ -5339,9 +5338,9 @@ RUNTIME_FUNCTION(Runtime_AddPropertyForTemplate) { } if (duplicate) { Handle args[1] = { key }; - Handle error = isolate->factory()->NewTypeError( - "duplicate_template_property", HandleVector(args, 1)); - return isolate->Throw(*error); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, + NewTypeError("duplicate_template_property", HandleVector(args, 1))); } #endif @@ -6051,8 +6050,9 @@ RUNTIME_FUNCTION(Runtime_GetArgumentsProperty) { if (String::Equals(isolate->factory()->callee_string(), key)) { JSFunction* function = frame->function(); if (function->shared()->strict_mode() == STRICT) { - return isolate->Throw(*isolate->factory()->NewTypeError( - "strict_arguments_callee", HandleVector(NULL, 0))); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError("strict_arguments_callee", + HandleVector(NULL, 0))); } return function; } @@ -6448,7 +6448,8 @@ MUST_USE_RESULT static Object* ConvertCaseHelper( current_length += char_length; if (current_length > String::kMaxLength) { AllowHeapAllocation allocate_error_and_return; - return isolate->ThrowInvalidStringLength(); + THROW_NEW_ERROR_RETURN_FAILURE(isolate, + NewInvalidStringLengthError()); } } // Try again with the real length. Return signed if we need @@ -7163,7 +7164,9 @@ RUNTIME_FUNCTION(Runtime_StringBuilderConcat) { HandleScope scope(isolate); DCHECK(args.length() == 3); CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); - if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength(); + if (!args[1]->IsSmi()) { + THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError()); + } CONVERT_SMI_ARG_CHECKED(array_length, 1); CONVERT_ARG_HANDLE_CHECKED(String, special, 2); @@ -7235,7 +7238,9 @@ RUNTIME_FUNCTION(Runtime_StringBuilderJoin) { HandleScope scope(isolate); DCHECK(args.length() == 3); CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); - if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength(); + if (!args[1]->IsSmi()) { + THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError()); + } CONVERT_SMI_ARG_CHECKED(array_length, 1); CONVERT_ARG_HANDLE_CHECKED(String, separator, 2); RUNTIME_ASSERT(array->HasFastObjectElements()); @@ -7259,7 +7264,7 @@ RUNTIME_FUNCTION(Runtime_StringBuilderJoin) { int max_nof_separators = (String::kMaxLength + separator_length - 1) / separator_length; if (max_nof_separators < (array_length - 1)) { - return isolate->ThrowInvalidStringLength(); + THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError()); } int length = (array_length - 1) * separator_length; for (int i = 0; i < array_length; i++) { @@ -7421,7 +7426,7 @@ RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) { // Throw an exception if the resulting string is too large. See // https://code.google.com/p/chromium/issues/detail?id=336820 // for details. - return isolate->ThrowInvalidStringLength(); + THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError()); } if (is_ascii) { @@ -8326,9 +8331,8 @@ static Object* Runtime_NewObjectHelper(Isolate* isolate, // If the constructor isn't a proper function we throw a type error. if (!constructor->IsJSFunction()) { Vector< Handle > arguments = HandleVector(&constructor, 1); - Handle type_error = - isolate->factory()->NewTypeError("not_constructor", arguments); - return isolate->Throw(*type_error); + THROW_NEW_ERROR_RETURN_FAILURE(isolate, + NewTypeError("not_constructor", arguments)); } Handle function = Handle::cast(constructor); @@ -8337,9 +8341,8 @@ static Object* Runtime_NewObjectHelper(Isolate* isolate, // case generated code bailouts here, since function has no initial_map. if (!function->should_have_prototype() && !function->shared()->bound()) { Vector< Handle > arguments = HandleVector(&constructor, 1); - Handle type_error = - isolate->factory()->NewTypeError("not_constructor", arguments); - return isolate->Throw(*type_error); + THROW_NEW_ERROR_RETURN_FAILURE(isolate, + NewTypeError("not_constructor", arguments)); } Debug* debug = isolate->debug(); @@ -9033,10 +9036,8 @@ RUNTIME_FUNCTION(Runtime_PushWithContext) { Object::ToObject(isolate, args.at(0)); if (!maybe_object.ToHandle(&extension_object)) { Handle handle = args.at(0); - Handle result = - isolate->factory()->NewTypeError("with_expression", - HandleVector(&handle, 1)); - return isolate->Throw(*result); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError("with_expression", HandleVector(&handle, 1))); } } @@ -9348,10 +9349,12 @@ static ObjectPair LoadLookupSlotHelper(Arguments args, Isolate* isolate, case MUTABLE_CHECK_INITIALIZED: case IMMUTABLE_CHECK_INITIALIZED_HARMONY: if (value->IsTheHole()) { - Handle reference_error = + Handle error; + MaybeHandle maybe_error = isolate->factory()->NewReferenceError("not_defined", HandleVector(&name, 1)); - return MakePair(isolate->Throw(*reference_error), NULL); + if (maybe_error.ToHandle(&error)) isolate->Throw(*error); + return MakePair(isolate->heap()->exception(), NULL); } // FALLTHROUGH case MUTABLE_IS_INITIALIZED: @@ -9403,10 +9406,11 @@ static ObjectPair LoadLookupSlotHelper(Arguments args, Isolate* isolate, if (throw_error) { // The property doesn't exist - throw exception. - Handle reference_error = - isolate->factory()->NewReferenceError("not_defined", - HandleVector(&name, 1)); - return MakePair(isolate->Throw(*reference_error), NULL); + Handle error; + MaybeHandle maybe_error = isolate->factory()->NewReferenceError( + "not_defined", HandleVector(&name, 1)); + if (maybe_error.ToHandle(&error)) isolate->Throw(*error); + return MakePair(isolate->heap()->exception(), NULL); } else { // The property doesn't exist - return undefined. return MakePair(isolate->heap()->undefined_value(), @@ -9452,10 +9456,9 @@ RUNTIME_FUNCTION(Runtime_StoreLookupSlot) { Handle::cast(holder)->set(index, *value); } else if (strict_mode == STRICT) { // Setting read only property in strict mode. - Handle error = - isolate->factory()->NewTypeError("strict_cannot_assign", - HandleVector(&name, 1)); - return isolate->Throw(*error); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, + NewTypeError("strict_cannot_assign", HandleVector(&name, 1))); } return *value; } @@ -9469,9 +9472,8 @@ RUNTIME_FUNCTION(Runtime_StoreLookupSlot) { object = Handle::cast(holder); } else if (strict_mode == STRICT) { // If absent in strict mode: throw. - Handle error = isolate->factory()->NewReferenceError( - "not_defined", HandleVector(&name, 1)); - return isolate->Throw(*error); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewReferenceError("not_defined", HandleVector(&name, 1))); } else { // If absent in sloppy mode: add the property to the global object. object = Handle(context->global_object()); @@ -9511,18 +9513,16 @@ RUNTIME_FUNCTION(Runtime_ThrowReferenceError) { HandleScope scope(isolate); DCHECK(args.length() == 1); CONVERT_ARG_HANDLE_CHECKED(Object, name, 0); - Handle reference_error = - isolate->factory()->NewReferenceError("not_defined", - HandleVector(&name, 1)); - return isolate->Throw(*reference_error); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewReferenceError("not_defined", HandleVector(&name, 1))); } RUNTIME_FUNCTION(Runtime_ThrowNotDateError) { HandleScope scope(isolate); DCHECK(args.length() == 0); - return isolate->Throw(*isolate->factory()->NewTypeError( - "not_date_object", HandleVector(NULL, 0))); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError("not_date_object", HandleVector(NULL, 0))); } @@ -9880,8 +9880,9 @@ RUNTIME_FUNCTION(Runtime_CompileString) { !CodeGenerationFromStringsAllowed(isolate, context)) { Handle error_message = context->ErrorMessageForCodeGenerationFromStrings(); - return isolate->Throw(*isolate->factory()->NewEvalError( - "code_gen_from_strings", HandleVector(&error_message, 1))); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewEvalError("code_gen_from_strings", + HandleVector(&error_message, 1))); } // Compile source string in the native context. @@ -9910,8 +9911,10 @@ static ObjectPair CompileGlobalEval(Isolate* isolate, !CodeGenerationFromStringsAllowed(isolate, native_context)) { Handle error_message = native_context->ErrorMessageForCodeGenerationFromStrings(); - isolate->Throw(*isolate->factory()->NewEvalError( - "code_gen_from_strings", HandleVector(&error_message, 1))); + Handle error; + MaybeHandle maybe_error = isolate->factory()->NewEvalError( + "code_gen_from_strings", HandleVector(&error_message, 1)); + if (maybe_error.ToHandle(&error)) isolate->Throw(*error); return MakePair(isolate->heap()->exception(), NULL); } @@ -10689,9 +10692,9 @@ RUNTIME_FUNCTION(Runtime_ArrayConcat) { } if (visitor.exceeds_array_limit()) { - return isolate->Throw( - *isolate->factory()->NewRangeError("invalid_array_length", - HandleVector(NULL, 0))); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, + NewRangeError("invalid_array_length", HandleVector(NULL, 0))); } return *visitor.ToArray(); } @@ -14036,9 +14039,8 @@ RUNTIME_FUNCTION(Runtime_GetImplFromInitializedIntlObject) { if (!input->IsJSObject()) { Vector< Handle > arguments = HandleVector(&input, 1); - Handle type_error = - isolate->factory()->NewTypeError("not_intl_object", arguments); - return isolate->Throw(*type_error); + THROW_NEW_ERROR_RETURN_FAILURE(isolate, + NewTypeError("not_intl_object", arguments)); } Handle obj = Handle::cast(input); @@ -14047,9 +14049,8 @@ RUNTIME_FUNCTION(Runtime_GetImplFromInitializedIntlObject) { Handle impl(obj->GetHiddenProperty(marker), isolate); if (impl->IsTheHole()) { Vector< Handle > arguments = HandleVector(&obj, 1); - Handle type_error = - isolate->factory()->NewTypeError("not_intl_object", arguments); - return isolate->Throw(*type_error); + THROW_NEW_ERROR_RETURN_FAILURE(isolate, + NewTypeError("not_intl_object", arguments)); } return *impl; } @@ -15371,8 +15372,9 @@ RUNTIME_FUNCTION(RuntimeReference_DateField) { CONVERT_SMI_ARG_CHECKED(index, 1); if (!obj->IsJSDate()) { HandleScope scope(isolate); - return isolate->Throw(*isolate->factory()->NewTypeError( - "not_date_object", HandleVector(NULL, 0))); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, + NewTypeError("not_date_object", HandleVector(NULL, 0))); } JSDate* date = JSDate::cast(obj); if (index == 0) return date->value(); diff --git a/src/scopes.cc b/src/scopes.cc index 5a91695..e1297b3 100644 --- a/src/scopes.cc +++ b/src/scopes.cc @@ -1080,9 +1080,10 @@ bool Scope::ResolveVariable(CompilationInfo* info, Isolate* isolate = info->isolate(); Factory* factory = isolate->factory(); Handle array = factory->NewJSArray(0); - Handle result = + Handle error; + MaybeHandle maybe_error = factory->NewSyntaxError("harmony_const_assign", array); - isolate->Throw(*result, &location); + if (maybe_error.ToHandle(&error)) isolate->Throw(*error, &location); return false; } @@ -1114,9 +1115,10 @@ bool Scope::ResolveVariable(CompilationInfo* info, Factory* factory = isolate->factory(); Handle array = factory->NewJSArray(1); JSObject::SetElement(array, 0, var->name(), NONE, STRICT).Assert(); - Handle result = + Handle error; + MaybeHandle maybe_error = factory->NewSyntaxError("module_type_error", array); - isolate->Throw(*result, &location); + if (maybe_error.ToHandle(&error)) isolate->Throw(*error, &location); return false; } } diff --git a/test/cctest/test-thread-termination.cc b/test/cctest/test-thread-termination.cc index a5ed7ab..21d3b95 100644 --- a/test/cctest/test-thread-termination.cc +++ b/test/cctest/test-thread-termination.cc @@ -459,3 +459,15 @@ TEST(PostponeTerminateException) { CHECK(try_catch.HasTerminated()); CHECK_EQ(2, callback_counter); } + + +TEST(ErrorObjectAfterTermination) { + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle context = v8::Context::New(CcTest::isolate()); + v8::Context::Scope context_scope(context); + v8::V8::TerminateExecution(isolate); + v8::Local error = v8::Exception::Error(v8_str("error")); + // TODO(yangguo): crbug/403509. Check for empty handle instead. + CHECK(error->IsUndefined()); +} -- 2.7.4