Do not expose termination exceptions to the Exception API.
authoryangguo@chromium.org <yangguo@chromium.org>
Mon, 1 Sep 2014 09:11:44 +0000 (09:11 +0000)
committeryangguo@chromium.org <yangguo@chromium.org>
Mon, 1 Sep 2014 09:11:44 +0000 (09:11 +0000)
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

20 files changed:
src/accessors.cc
src/api.cc
src/builtins.cc
src/debug.cc
src/elements.cc
src/execution.cc
src/execution.h
src/factory.cc
src/factory.h
src/ic/ic.cc
src/isolate.cc
src/isolate.h
src/json-parser.h
src/json-stringifier.h
src/jsregexp.cc
src/objects.cc
src/parser.cc
src/runtime.cc
src/scopes.cc
test/cctest/test-thread-termination.cc

index 9a2431b..03ab9c4 100644 (file)
@@ -262,9 +262,15 @@ void Accessors::ArrayLengthSetter(
     return;
   }
 
-  isolate->ScheduleThrow(
-      *isolate->factory()->NewRangeError("invalid_array_length",
-                                         HandleVector<Object>(NULL, 0)));
+  Handle<Object> exception;
+  maybe = isolate->factory()->NewRangeError("invalid_array_length",
+                                            HandleVector<Object>(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<String> name = v8::Utils::OpenHandle(*property);
-    isolate->ScheduleThrow(
-        *isolate->factory()->NewReferenceError("not_defined",
-                                               HandleVector(&name, 1)));
+
+    Handle<Object> exception;
+    MaybeHandle<Object> 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<Object>(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<String> name = v8::Utils::OpenHandle(*property);
-    Isolate* isolate = instance->GetIsolate();
-    isolate->ScheduleThrow(
-        *isolate->factory()->NewReferenceError("not_defined",
-                                               HandleVector(&name, 1)));
+    Handle<Object> exception;
+    MaybeHandle<Object> 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));
index 667f9af..a45510d 100644 (file)
@@ -6820,90 +6820,37 @@ String::Value::~Value() {
 }
 
 
-Local<Value> Exception::RangeError(v8::Handle<v8::String> raw_message) {
-  i::Isolate* isolate = i::Isolate::Current();
-  LOG_API(isolate, "RangeError");
-  ON_BAILOUT(isolate, "v8::Exception::RangeError()", return Local<Value>());
-  ENTER_V8(isolate);
-  i::Object* error;
-  {
-    i::HandleScope scope(isolate);
-    i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
-    i::Handle<i::Object> result = isolate->factory()->NewRangeError(message);
-    error = *result;
-  }
-  i::Handle<i::Object> result(error, isolate);
-  return Utils::ToLocal(result);
-}
-
-
-Local<Value> Exception::ReferenceError(v8::Handle<v8::String> raw_message) {
-  i::Isolate* isolate = i::Isolate::Current();
-  LOG_API(isolate, "ReferenceError");
-  ON_BAILOUT(isolate, "v8::Exception::ReferenceError()", return Local<Value>());
-  ENTER_V8(isolate);
-  i::Object* error;
-  {
-    i::HandleScope scope(isolate);
-    i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
-    i::Handle<i::Object> result =
-        isolate->factory()->NewReferenceError(message);
-    error = *result;
-  }
-  i::Handle<i::Object> result(error, isolate);
-  return Utils::ToLocal(result);
-}
-
-
-Local<Value> Exception::SyntaxError(v8::Handle<v8::String> raw_message) {
-  i::Isolate* isolate = i::Isolate::Current();
-  LOG_API(isolate, "SyntaxError");
-  ON_BAILOUT(isolate, "v8::Exception::SyntaxError()", return Local<Value>());
-  ENTER_V8(isolate);
-  i::Object* error;
-  {
-    i::HandleScope scope(isolate);
-    i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
-    i::Handle<i::Object> result = isolate->factory()->NewSyntaxError(message);
-    error = *result;
-  }
-  i::Handle<i::Object> result(error, isolate);
-  return Utils::ToLocal(result);
-}
-
-
-Local<Value> Exception::TypeError(v8::Handle<v8::String> raw_message) {
-  i::Isolate* isolate = i::Isolate::Current();
-  LOG_API(isolate, "TypeError");
-  ON_BAILOUT(isolate, "v8::Exception::TypeError()", return Local<Value>());
-  ENTER_V8(isolate);
-  i::Object* error;
-  {
-    i::HandleScope scope(isolate);
-    i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
-    i::Handle<i::Object> result = isolate->factory()->NewTypeError(message);
-    error = *result;
-  }
-  i::Handle<i::Object> result(error, isolate);
-  return Utils::ToLocal(result);
-}
-
-
-Local<Value> Exception::Error(v8::Handle<v8::String> raw_message) {
-  i::Isolate* isolate = i::Isolate::Current();
-  LOG_API(isolate, "Error");
-  ON_BAILOUT(isolate, "v8::Exception::Error()", return Local<Value>());
-  ENTER_V8(isolate);
-  i::Object* error;
-  {
-    i::HandleScope scope(isolate);
-    i::Handle<i::String> message = Utils::OpenHandle(*raw_message);
-    i::Handle<i::Object> result = isolate->factory()->NewError(message);
-    error = *result;
-  }
-  i::Handle<i::Object> result(error, isolate);
-  return Utils::ToLocal(result);
-}
+#define DEFINE_ERROR(NAME)                                                    \
+  Local<Value> Exception::NAME(v8::Handle<v8::String> raw_message) {          \
+    i::Isolate* isolate = i::Isolate::Current();                              \
+    LOG_API(isolate, #NAME);                                                  \
+    ON_BAILOUT(isolate, "v8::Exception::" #NAME "()", return Local<Value>()); \
+    ENTER_V8(isolate);                                                        \
+    i::Object* error;                                                         \
+    {                                                                         \
+      i::HandleScope scope(isolate);                                          \
+      i::Handle<i::String> message = Utils::OpenHandle(*raw_message);         \
+      i::Handle<i::Object> result;                                            \
+      EXCEPTION_PREAMBLE(isolate);                                            \
+      i::MaybeHandle<i::Object> 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<v8::Isolate*>(isolate)));   \
+      error = *result;                                                        \
+    }                                                                         \
+    i::Handle<i::Object> 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 ---
index 7c64f65..14b0c93 100644 (file)
@@ -1010,15 +1010,17 @@ BUILTIN(ArrayConcat) {
 
 BUILTIN(StrictModePoisonPill) {
   HandleScope scope(isolate);
-  return isolate->Throw(*isolate->factory()->NewTypeError(
-      "strict_poison_pill", HandleVector<Object>(NULL, 0)));
+  THROW_NEW_ERROR_RETURN_FAILURE(
+      isolate,
+      NewTypeError("strict_poison_pill", HandleVector<Object>(NULL, 0)));
 }
 
 
 BUILTIN(GeneratorPoisonPill) {
   HandleScope scope(isolate);
-  return isolate->Throw(*isolate->factory()->NewTypeError(
-      "generator_poison_pill", HandleVector<Object>(NULL, 0)));
+  THROW_NEW_ERROR_RETURN_FAILURE(
+      isolate,
+      NewTypeError("generator_poison_pill", HandleVector<Object>(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<Object> 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();
index f4ab115..5bdf53f 100644 (file)
@@ -757,13 +757,9 @@ bool Debug::CompileDebuggerScript(Isolate* isolate, int index) {
   Handle<JSFunction> function =
       factory->NewFunctionFromSharedFunctionInfo(function_info, context);
 
-  Handle<Object> exception;
-  MaybeHandle<Object> result =
-      Execution::TryCall(function,
-                         handle(context->global_proxy()),
-                         0,
-                         NULL,
-                         &exception);
+  MaybeHandle<Object> maybe_exception;
+  MaybeHandle<Object> 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<Handle<Object> >::empty(), Handle<JSArray>());
     DCHECK(!isolate->has_pending_exception());
-    if (!exception.is_null()) {
+    Handle<Object> 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<String> request_text = isolate_->factory()->NewStringFromTwoByte(
         command_text).ToHandleChecked();
     Handle<Object> request_args[] = { request_text };
-    Handle<Object> exception;
     Handle<Object> answer_value;
     Handle<String> answer;
-    MaybeHandle<Object> maybe_result = Execution::TryCall(
-        process_debug_request, cmd_processor, 1, request_args, &exception);
+    MaybeHandle<Object> maybe_exception;
+    MaybeHandle<Object> 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<Object> is_running_args[] = { answer };
       maybe_result = Execution::Call(
           isolate_, is_running, cmd_processor, 1, is_running_args);
-      running = maybe_result.ToHandleChecked()->IsTrue();
+      Handle<Object> result;
+      if (!maybe_result.ToHandle(&result)) break;
+      running = result->IsTrue();
     } else {
-      answer = Handle<String>::cast(
-          Execution::ToString(isolate_, exception).ToHandleChecked());
+      Handle<Object> exception;
+      if (!maybe_exception.ToHandle(&exception)) break;
+      Handle<Object> result;
+      if (!Execution::ToString(isolate_, exception).ToHandle(&result)) break;
+      answer = Handle<String>::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();
 }
 
 
index 121dd7d..6b4f5ec 100644 (file)
@@ -141,9 +141,9 @@ static bool HasKey(Handle<FixedArray> array, Handle<Object> key_handle) {
 
 MUST_USE_RESULT
 static MaybeHandle<Object> ThrowArrayLengthRangeError(Isolate* isolate) {
-  return isolate->Throw<Object>(
-      isolate->factory()->NewRangeError("invalid_array_length",
-                                        HandleVector<Object>(NULL, 0)));
+  THROW_NEW_ERROR(isolate, NewRangeError("invalid_array_length",
+                                         HandleVector<Object>(NULL, 0)),
+                  Object);
 }
 
 
@@ -1421,10 +1421,9 @@ class DictionaryElementsAccessor
           // Deleting a non-configurable property in strict mode.
           Handle<Object> name = isolate->factory()->NewNumberFromUint(key);
           Handle<Object> args[2] = { name, obj };
-          Handle<Object> error =
-              isolate->factory()->NewTypeError("strict_delete_property",
-                                               HandleVector(args, 2));
-          return isolate->Throw<Object>(error);
+          THROW_NEW_ERROR(isolate, NewTypeError("strict_delete_property",
+                                                HandleVector(args, 2)),
+                          Object);
         }
         return isolate->factory()->false_value();
       }
index 12dd862..7aa4f33 100644 (file)
@@ -150,40 +150,43 @@ MaybeHandle<Object> Execution::New(Handle<JSFunction> func,
 
 
 MaybeHandle<Object> Execution::TryCall(Handle<JSFunction> func,
-                                       Handle<Object> receiver,
-                                       int argc,
+                                       Handle<Object> receiver, int argc,
                                        Handle<Object> args[],
-                                       Handle<Object>* exception_out) {
+                                       MaybeHandle<Object>* exception_out) {
+  bool is_termination = false;
+  Isolate* isolate = func->GetIsolate();
+  MaybeHandle<Object> maybe_result;
+  if (exception_out != NULL) *exception_out = MaybeHandle<Object>();
   // 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<Object> 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<Object> Execution::TryGetFunctionDelegate(Isolate* isolate,
 
   // If the Object doesn't have an instance-call handler we should
   // throw a non-callable exception.
-  i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
-      "called_non_callable", i::HandleVector<i::Object>(&object, 1));
-
-  return isolate->Throw<Object>(error_obj);
+  THROW_NEW_ERROR(isolate, NewTypeError("called_non_callable",
+                                        i::HandleVector<i::Object>(&object, 1)),
+                  Object);
 }
 
 
@@ -293,9 +295,9 @@ MaybeHandle<Object> Execution::TryGetConstructorDelegate(
 
   // If the Object doesn't have an instance-call handler we should
   // throw a non-callable exception.
-  i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
-      "called_non_callable", i::HandleVector<i::Object>(&object, 1));
-  return isolate->Throw<Object>(error_obj);
+  THROW_NEW_ERROR(isolate, NewTypeError("called_non_callable",
+                                        i::HandleVector<i::Object>(&object, 1)),
+                  Object);
 }
 
 
index 2a41bb8..9af446b 100644 (file)
@@ -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<Object> TryCall(
-      Handle<JSFunction> func,
-      Handle<Object> receiver,
-      int argc,
-      Handle<Object> argv[],
-      Handle<Object>* exception_out = NULL);
+  // In the exception case, exception_out holds the caught exceptions, unless
+  // it is a termination exception.
+  static MaybeHandle<Object> TryCall(Handle<JSFunction> func,
+                                     Handle<Object> receiver, int argc,
+                                     Handle<Object> argv[],
+                                     MaybeHandle<Object>* exception_out = NULL);
 
   // ECMA-262 9.3
   MUST_USE_RESULT static MaybeHandle<Object> ToNumber(
index 5a07708..13cba9d 100644 (file)
@@ -366,7 +366,7 @@ MaybeHandle<Map> Factory::InternalizedStringMapForString(
 MaybeHandle<SeqOneByteString> Factory::NewRawOneByteString(
     int length, PretenureFlag pretenure) {
   if (length > String::kMaxLength || length < 0) {
-    return isolate()->Throw<SeqOneByteString>(NewInvalidStringLengthError());
+    THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqOneByteString);
   }
   CALL_HEAP_FUNCTION(
       isolate(),
@@ -378,7 +378,7 @@ MaybeHandle<SeqOneByteString> Factory::NewRawOneByteString(
 MaybeHandle<SeqTwoByteString> Factory::NewRawTwoByteString(
     int length, PretenureFlag pretenure) {
   if (length > String::kMaxLength || length < 0) {
-    return isolate()->Throw<SeqTwoByteString>(NewInvalidStringLengthError());
+    THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqTwoByteString);
   }
   CALL_HEAP_FUNCTION(
       isolate(),
@@ -483,7 +483,7 @@ MaybeHandle<String> Factory::NewConsString(Handle<String> 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<String>(NewInvalidStringLengthError());
+    THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String);
   }
 
   bool left_is_one_byte = left->IsOneByteRepresentation();
@@ -616,7 +616,7 @@ MaybeHandle<String> Factory::NewExternalStringFromAscii(
     const ExternalAsciiString::Resource* resource) {
   size_t length = resource->length();
   if (length > static_cast<size_t>(String::kMaxLength)) {
-    return isolate()->Throw<String>(NewInvalidStringLengthError());
+    THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String);
   }
 
   Handle<Map> map = external_ascii_string_map();
@@ -634,7 +634,7 @@ MaybeHandle<String> Factory::NewExternalStringFromTwoByte(
     const ExternalTwoByteString::Resource* resource) {
   size_t length = resource->length();
   if (length > static_cast<size_t>(String::kMaxLength)) {
-    return isolate()->Throw<String>(NewInvalidStringLengthError());
+    THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String);
   }
 
   // For small strings we check whether the resource contains only
@@ -1050,59 +1050,58 @@ Handle<HeapNumber> Factory::NewHeapNumber(double value,
 }
 
 
-Handle<Object> Factory::NewTypeError(const char* message,
-                                     Vector< Handle<Object> > args) {
+MaybeHandle<Object> Factory::NewTypeError(const char* message,
+                                          Vector<Handle<Object> > args) {
   return NewError("MakeTypeError", message, args);
 }
 
 
-Handle<Object> Factory::NewTypeError(Handle<String> message) {
+MaybeHandle<Object> Factory::NewTypeError(Handle<String> message) {
   return NewError("$TypeError", message);
 }
 
 
-Handle<Object> Factory::NewRangeError(const char* message,
-                                      Vector< Handle<Object> > args) {
+MaybeHandle<Object> Factory::NewRangeError(const char* message,
+                                           Vector<Handle<Object> > args) {
   return NewError("MakeRangeError", message, args);
 }
 
 
-Handle<Object> Factory::NewRangeError(Handle<String> message) {
+MaybeHandle<Object> Factory::NewRangeError(Handle<String> message) {
   return NewError("$RangeError", message);
 }
 
 
-Handle<Object> Factory::NewSyntaxError(const char* message,
-                                       Handle<JSArray> args) {
+MaybeHandle<Object> Factory::NewSyntaxError(const char* message,
+                                            Handle<JSArray> args) {
   return NewError("MakeSyntaxError", message, args);
 }
 
 
-Handle<Object> Factory::NewSyntaxError(Handle<String> message) {
+MaybeHandle<Object> Factory::NewSyntaxError(Handle<String> message) {
   return NewError("$SyntaxError", message);
 }
 
 
-Handle<Object> Factory::NewReferenceError(const char* message,
-                                          Vector< Handle<Object> > args) {
+MaybeHandle<Object> Factory::NewReferenceError(const char* message,
+                                               Vector<Handle<Object> > args) {
   return NewError("MakeReferenceError", message, args);
 }
 
 
-Handle<Object> Factory::NewReferenceError(const char* message,
-                                          Handle<JSArray> args) {
+MaybeHandle<Object> Factory::NewReferenceError(const char* message,
+                                               Handle<JSArray> args) {
   return NewError("MakeReferenceError", message, args);
 }
 
 
-Handle<Object> Factory::NewReferenceError(Handle<String> message) {
+MaybeHandle<Object> Factory::NewReferenceError(Handle<String> message) {
   return NewError("$ReferenceError", message);
 }
 
 
-Handle<Object> Factory::NewError(const char* maker,
-                                 const char* message,
-                                 Vector< Handle<Object> > args) {
+MaybeHandle<Object> Factory::NewError(const char* maker, const char* message,
+                                      Vector<Handle<Object> > args) {
   // Instantiate a closeable HandleScope for EscapeFrom.
   v8::EscapableHandleScope scope(reinterpret_cast<v8::Isolate*>(isolate()));
   Handle<FixedArray> array = NewFixedArray(args.length());
@@ -1110,19 +1109,21 @@ Handle<Object> Factory::NewError(const char* maker,
     array->set(i, *args[i]);
   }
   Handle<JSArray> object = NewJSArrayWithElements(array);
-  Handle<Object> result = NewError(maker, message, object);
+  Handle<Object> result;
+  ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
+                             NewError(maker, message, object), Object);
   return result.EscapeFrom(&scope);
 }
 
 
-Handle<Object> Factory::NewEvalError(const char* message,
-                                     Vector< Handle<Object> > args) {
+MaybeHandle<Object> Factory::NewEvalError(const char* message,
+                                          Vector<Handle<Object> > args) {
   return NewError("MakeEvalError", message, args);
 }
 
 
-Handle<Object> Factory::NewError(const char* message,
-                                 Vector< Handle<Object> > args) {
+MaybeHandle<Object> Factory::NewError(const char* message,
+                                      Vector<Handle<Object> > args) {
   return NewError("MakeError", message, args);
 }
 
@@ -1163,9 +1164,8 @@ Handle<String> Factory::EmergencyNewError(const char* message,
 }
 
 
-Handle<Object> Factory::NewError(const char* maker,
-                                 const char* message,
-                                 Handle<JSArray> args) {
+MaybeHandle<Object> Factory::NewError(const char* maker, const char* message,
+                                      Handle<JSArray> args) {
   Handle<String> make_str = InternalizeUtf8String(maker);
   Handle<Object> fun_obj = Object::GetProperty(
       isolate()->js_builtins_object(), make_str).ToHandleChecked();
@@ -1181,7 +1181,7 @@ Handle<Object> 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<Object> result;
-  Handle<Object> exception;
+  MaybeHandle<Object> exception;
   if (!Execution::TryCall(fun,
                           isolate()->js_builtins_object(),
                           arraysize(argv),
@@ -1193,13 +1193,13 @@ Handle<Object> Factory::NewError(const char* maker,
 }
 
 
-Handle<Object> Factory::NewError(Handle<String> message) {
+MaybeHandle<Object> Factory::NewError(Handle<String> message) {
   return NewError("$Error", message);
 }
 
 
-Handle<Object> Factory::NewError(const char* constructor,
-                                 Handle<String> message) {
+MaybeHandle<Object> Factory::NewError(const char* constructor,
+                                      Handle<String> message) {
   Handle<String> constr = InternalizeUtf8String(constructor);
   Handle<JSFunction> fun = Handle<JSFunction>::cast(Object::GetProperty(
       isolate()->js_builtins_object(), constr).ToHandleChecked());
@@ -1208,7 +1208,7 @@ Handle<Object> 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<Object> result;
-  Handle<Object> exception;
+  MaybeHandle<Object> exception;
   if (!Execution::TryCall(fun,
                           isolate()->js_builtins_object(),
                           arraysize(argv),
index f9329ae..ab48f28 100644 (file)
@@ -507,40 +507,40 @@ class Factory V8_FINAL {
 
   // Interface for creating error objects.
 
-  Handle<Object> NewError(const char* maker, const char* message,
-                          Handle<JSArray> args);
+  MaybeHandle<Object> NewError(const char* maker, const char* message,
+                               Handle<JSArray> args);
   Handle<String> EmergencyNewError(const char* message, Handle<JSArray> args);
-  Handle<Object> NewError(const char* maker, const char* message,
-                          Vector< Handle<Object> > args);
-  Handle<Object> NewError(const char* message,
-                          Vector< Handle<Object> > args);
-  Handle<Object> NewError(Handle<String> message);
-  Handle<Object> NewError(const char* constructor,
-                          Handle<String> message);
-
-  Handle<Object> NewTypeError(const char* message,
-                              Vector< Handle<Object> > args);
-  Handle<Object> NewTypeError(Handle<String> message);
-
-  Handle<Object> NewRangeError(const char* message,
-                               Vector< Handle<Object> > args);
-  Handle<Object> NewRangeError(Handle<String> message);
-
-  Handle<Object> NewInvalidStringLengthError() {
+  MaybeHandle<Object> NewError(const char* maker, const char* message,
+                               Vector<Handle<Object> > args);
+  MaybeHandle<Object> NewError(const char* message,
+                               Vector<Handle<Object> > args);
+  MaybeHandle<Object> NewError(Handle<String> message);
+  MaybeHandle<Object> NewError(const char* constructor, Handle<String> message);
+
+  MaybeHandle<Object> NewTypeError(const char* message,
+                                   Vector<Handle<Object> > args);
+  MaybeHandle<Object> NewTypeError(Handle<String> message);
+
+  MaybeHandle<Object> NewRangeError(const char* message,
+                                    Vector<Handle<Object> > args);
+  MaybeHandle<Object> NewRangeError(Handle<String> message);
+
+  MaybeHandle<Object> NewInvalidStringLengthError() {
     return NewRangeError("invalid_string_length",
                          HandleVector<Object>(NULL, 0));
   }
 
-  Handle<Object> NewSyntaxError(const char* message, Handle<JSArray> args);
-  Handle<Object> NewSyntaxError(Handle<String> message);
+  MaybeHandle<Object> NewSyntaxError(const char* message, Handle<JSArray> args);
+  MaybeHandle<Object> NewSyntaxError(Handle<String> message);
 
-  Handle<Object> NewReferenceError(const char* message,
-                                   Vector< Handle<Object> > args);
-  Handle<Object> NewReferenceError(const char* message, Handle<JSArray> args);
-  Handle<Object> NewReferenceError(Handle<String> message);
+  MaybeHandle<Object> NewReferenceError(const char* message,
+                                        Vector<Handle<Object> > args);
+  MaybeHandle<Object> NewReferenceError(const char* message,
+                                        Handle<JSArray> args);
+  MaybeHandle<Object> NewReferenceError(Handle<String> message);
 
-  Handle<Object> NewEvalError(const char* message,
-                              Vector< Handle<Object> > args);
+  MaybeHandle<Object> NewEvalError(const char* message,
+                                   Vector<Handle<Object> > args);
 
   Handle<String> NumberToString(Handle<Object> number,
                                 bool check_number_string_cache = true);
index 784a5e5..59db5bf 100644 (file)
@@ -333,17 +333,14 @@ MaybeHandle<Object> IC::TypeError(const char* type, Handle<Object> object,
                                   Handle<Object> key) {
   HandleScope scope(isolate());
   Handle<Object> args[2] = {key, object};
-  Handle<Object> error =
-      isolate()->factory()->NewTypeError(type, HandleVector(args, 2));
-  return isolate()->Throw<Object>(error);
+  THROW_NEW_ERROR(isolate(), NewTypeError(type, HandleVector(args, 2)), Object);
 }
 
 
 MaybeHandle<Object> IC::ReferenceError(const char* type, Handle<Name> name) {
   HandleScope scope(isolate());
-  Handle<Object> error =
-      isolate()->factory()->NewReferenceError(type, HandleVector(&name, 1));
-  return isolate()->Throw<Object>(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> name_handle(name);
-  Handle<Object> 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)));
 }
 
 
index 028da3d..f049208 100644 (file)
@@ -645,7 +645,10 @@ void Isolate::ReportFailedAccessCheck(Handle<JSObject> receiver,
                                       v8::AccessType type) {
   if (!thread_local_top()->failed_access_check_callback_) {
     Handle<String> message = factory()->InternalizeUtf8String("no access");
-    ScheduleThrow(*factory()->NewTypeError(message));
+    Handle<Object> 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<Object>(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<JSFunction>::cast(microtask);
         SaveContext save(this);
         set_context(microtask_function->context()->native_context());
-        Handle<Object> exception;
-        MaybeHandle<Object> result = Execution::TryCall(
-            microtask_function, factory()->undefined_value(),
-            0, NULL, &exception);
+        MaybeHandle<Object> maybe_exception;
+        MaybeHandle<Object> 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<Object> 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);
index 0437f32..8755dcd 100644 (file)
@@ -134,6 +134,22 @@ typedef ZoneList<Handle<Object> > ZoneObjectList;
 #define ASSIGN_RETURN_ON_EXCEPTION(isolate, dst, call, T)  \
   ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, MaybeHandle<T>())
 
+#define THROW_NEW_ERROR(isolate, call, T)                                    \
+  do {                                                                       \
+    Handle<Object> __error__;                                                \
+    ASSIGN_RETURN_ON_EXCEPTION(isolate, __error__, isolate->factory()->call, \
+                               T);                                           \
+    return isolate->Throw<T>(__error__);                                     \
+  } while (false)
+
+#define THROW_NEW_ERROR_RETURN_FAILURE(isolate, call)             \
+  do {                                                            \
+    Handle<Object> __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();
index c23e50d..82ab9c5 100644 (file)
@@ -244,7 +244,9 @@ MaybeHandle<Object> JsonParser<seq_ascii>::ParseJson() {
     MessageLocation location(factory->NewScript(source_),
                              position_,
                              position_ + 1);
-    Handle<Object> error = factory->NewSyntaxError(message, array);
+    Handle<Object> error;
+    ASSIGN_RETURN_ON_EXCEPTION(isolate(), error,
+                               factory->NewSyntaxError(message, array), Object);
     return isolate()->template Throw<Object>(error, &location);
   }
   return result;
index 1b108ce..e6f5cfd 100644 (file)
@@ -258,8 +258,7 @@ MaybeHandle<Object> BasicJsonStringifier::Stringify(Handle<Object> object) {
     ShrinkCurrentPart();
     Accumulate();
     if (overflowed_) {
-      return isolate_->Throw<Object>(
-          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<Object>(NULL, 0)));
+        Handle<Object> error;
+        MaybeHandle<Object> maybe_error = factory_->NewTypeError(
+            "circular_structure", HandleVector<Object>(NULL, 0));
+        if (maybe_error.ToHandle(&error)) isolate_->Throw(*error);
         return EXCEPTION;
       }
     }
index 3853197..7891cd8 100644 (file)
@@ -88,8 +88,8 @@ static inline MaybeHandle<Object> ThrowRegExpException(
   elements->set(0, *pattern);
   elements->set(1, *error_text);
   Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
-  Handle<Object> regexp_err = factory->NewSyntaxError(message, array);
-  return isolate->Throw<Object>(regexp_err);
+  Handle<Object> regexp_err;
+  THROW_NEW_ERROR(isolate, NewSyntaxError(message, array), Object);
 }
 
 
@@ -372,8 +372,7 @@ bool RegExpImpl::EnsureCompiledIrregexp(
 }
 
 
-static bool CreateRegExpErrorObjectAndThrow(Handle<JSRegExp> re,
-                                            bool is_ascii,
+static void CreateRegExpErrorObjectAndThrow(Handle<JSRegExp> re, bool is_ascii,
                                             Handle<String> error_message,
                                             Isolate* isolate) {
   Factory* factory = isolate->factory();
@@ -381,10 +380,10 @@ static bool CreateRegExpErrorObjectAndThrow(Handle<JSRegExp> re,
   elements->set(0, re->Pattern());
   elements->set(1, *error_message);
   Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
-  Handle<Object> regexp_err =
+  Handle<Object> error;
+  MaybeHandle<Object> maybe_error =
       factory->NewSyntaxError("malformed_regexp", array);
-  isolate->Throw(*regexp_err);
-  return false;
+  if (maybe_error.ToHandle(&error)) isolate->Throw(*error);
 }
 
 
index ed349cc..b176522 100644 (file)
@@ -424,11 +424,10 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(Handle<Object> receiver,
     Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure);
     if (!info->IsCompatibleReceiver(*receiver)) {
       Handle<Object> args[2] = { name, receiver };
-      Handle<Object> error =
-          isolate->factory()->NewTypeError("incompatible_method_receiver",
-                                           HandleVector(args,
-                                                        arraysize(args)));
-      return isolate->Throw<Object>(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> Object::SetPropertyWithAccessor(
     ExecutableAccessorInfo* info = ExecutableAccessorInfo::cast(*structure);
     if (!info->IsCompatibleReceiver(*receiver)) {
       Handle<Object> args[2] = { name, receiver };
-      Handle<Object> error =
-          isolate->factory()->NewTypeError("incompatible_method_receiver",
-                                           HandleVector(args,
-                                                        arraysize(args)));
-      return isolate->Throw<Object>(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> Object::SetPropertyWithAccessor(
     } else {
       if (strict_mode == SLOPPY) return value;
       Handle<Object> args[2] = { name, holder };
-      Handle<Object> error =
-          isolate->factory()->NewTypeError("no_setter_in_callback",
-                                           HandleVector(args, 2));
-      return isolate->Throw<Object>(error);
+      THROW_NEW_ERROR(
+          isolate, NewTypeError("no_setter_in_callback", HandleVector(args, 2)),
+          Object);
     }
   }
 
@@ -2909,9 +2906,9 @@ MaybeHandle<Object> Object::SetProperty(LookupIterator* it,
   // throw a reference error in strict mode.
   if (it->GetReceiver()->IsJSGlobalObject() && strict_mode == STRICT) {
     Handle<Object> args[1] = {it->name()};
-    Handle<Object> error = it->isolate()->factory()->NewReferenceError(
-        "not_defined", HandleVector(args, 1));
-    return it->isolate()->Throw<Object>(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> Object::WriteToReadOnlyProperty(LookupIterator* it,
   if (strict_mode != STRICT) return value;
 
   Handle<Object> args[] = {it->name(), it->GetReceiver()};
-  Handle<Object> error = it->factory()->NewTypeError(
-      "strict_read_only_property", HandleVector(args, arraysize(args)));
-  return it->isolate()->Throw<Object>(error);
+  THROW_NEW_ERROR(it->isolate(),
+                  NewTypeError("strict_read_only_property",
+                               HandleVector(args, arraysize(args))),
+                  Object);
 }
 
 
@@ -2989,9 +2987,10 @@ MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it,
     if (strict_mode == SLOPPY) return value;
 
     Handle<Object> args[1] = {it->name()};
-    Handle<Object> error = it->factory()->NewTypeError(
-        "object_not_extensible", HandleVector(args, arraysize(args)));
-    return it->isolate()->Throw<Object>(error);
+    THROW_NEW_ERROR(it->isolate(),
+                    NewTypeError("object_not_extensible",
+                                 HandleVector(args, arraysize(args))),
+                    Object);
   }
   it->ApplyTransitionToDataProperty();
 
@@ -3483,9 +3482,9 @@ MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
         isolate->factory()->InternalizeOneByteString(
             STATIC_ASCII_VECTOR("getPropertyDescriptor"));
     Handle<Object> args[] = { handler, trap, name };
-    Handle<Object> error = isolate->factory()->NewTypeError(
-        "proxy_prop_not_configurable", HandleVector(args, arraysize(args)));
-    return isolate->Throw<Object>(error);
+    THROW_NEW_ERROR(isolate, NewTypeError("proxy_prop_not_configurable",
+                                          HandleVector(args, arraysize(args))),
+                    Object);
   }
   DCHECK(configurable->IsTrue());
 
@@ -3507,9 +3506,9 @@ MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
     if (!*done) return isolate->factory()->the_hole_value();
     if (strict_mode == SLOPPY) return value;
     Handle<Object> args[] = { name, receiver };
-    Handle<Object> error = isolate->factory()->NewTypeError(
-        "strict_read_only_property", HandleVector(args, arraysize(args)));
-    return isolate->Throw<Object>(error);
+    THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property",
+                                          HandleVector(args, arraysize(args))),
+                    Object);
   }
 
   // We have an AccessorDescriptor.
@@ -3524,9 +3523,9 @@ MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
 
   if (strict_mode == SLOPPY) return value;
   Handle<Object> args2[] = { name, proxy };
-  Handle<Object> error = isolate->factory()->NewTypeError(
-      "no_setter_in_callback", HandleVector(args2, arraysize(args2)));
-  return isolate->Throw<Object>(error);
+  THROW_NEW_ERROR(isolate, NewTypeError("no_setter_in_callback",
+                                        HandleVector(args2, arraysize(args2))),
+                  Object);
 }
 
 
@@ -3554,9 +3553,9 @@ MaybeHandle<Object> JSProxy::DeletePropertyWithHandler(
     Handle<String> trap_name = isolate->factory()->InternalizeOneByteString(
         STATIC_ASCII_VECTOR("delete"));
     Handle<Object> args[] = { handler, trap_name };
-    Handle<Object> error = isolate->factory()->NewTypeError(
-        "handler_failed", HandleVector(args, arraysize(args)));
-    return isolate->Throw<Object>(error);
+    THROW_NEW_ERROR(isolate, NewTypeError("handler_failed",
+                                          HandleVector(args, arraysize(args))),
+                    Object);
   }
   return isolate->factory()->ToBoolean(result_bool);
 }
@@ -3630,9 +3629,10 @@ Maybe<PropertyAttributes> JSProxy::GetPropertyAttributesWithHandler(
     Handle<String> trap = isolate->factory()->InternalizeOneByteString(
         STATIC_ASCII_VECTOR("getPropertyDescriptor"));
     Handle<Object> args[] = { handler, trap, name };
-    Handle<Object> error = isolate->factory()->NewTypeError(
+    Handle<Object> error;
+    MaybeHandle<Object> 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<Object> JSProxy::CallTrap(Handle<JSProxy> proxy,
   if (trap->IsUndefined()) {
     if (derived.is_null()) {
       Handle<Object> args[] = { handler, trap_name };
-      Handle<Object> error = isolate->factory()->NewTypeError(
-        "handler_trap_missing", HandleVector(args, arraysize(args)));
-      return isolate->Throw<Object>(error);
+      THROW_NEW_ERROR(isolate,
+                      NewTypeError("handler_trap_missing",
+                                   HandleVector(args, arraysize(args))),
+                      Object);
     }
     trap = Handle<Object>(derived);
   }
@@ -4846,11 +4847,9 @@ MaybeHandle<Object> JSObject::DeleteElement(Handle<JSObject> object,
       // Deleting a non-configurable property in strict mode.
       Handle<Object> name = factory->NewNumberFromUint(index);
       Handle<Object> args[2] = { name, object };
-      Handle<Object> error =
-          factory->NewTypeError("strict_delete_property",
-                                HandleVector(args, 2));
-      isolate->Throw(*error);
-      return Handle<Object>();
+      THROW_NEW_ERROR(isolate, NewTypeError("strict_delete_property",
+                                            HandleVector(args, 2)),
+                      Object);
     }
     return factory->false_value();
   }
@@ -4952,10 +4951,10 @@ MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object,
           // Fail if the property is not configurable.
           if (delete_mode == STRICT_DELETION) {
             Handle<Object> args[2] = {name, object};
-            Handle<Object> error = it.isolate()->factory()->NewTypeError(
-                "strict_delete_property", HandleVector(args, arraysize(args)));
-            it.isolate()->Throw(*error);
-            return Handle<Object>();
+            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<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
   // It's not possible to seal objects with external array elements
   if (object->HasExternalArrayElements() ||
       object->HasFixedTypedArrayElements()) {
-    Handle<Object> error  =
-        isolate->factory()->NewTypeError(
-            "cant_prevent_ext_external_array_elements",
-            HandleVector(&object, 1));
-    return isolate->Throw<Object>(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<Object> JSObject::Freeze(Handle<JSObject> object) {
   // It's not possible to freeze objects with external array elements
   if (object->HasExternalArrayElements() ||
       object->HasFixedTypedArrayElements()) {
-    Handle<Object> error  =
-        isolate->factory()->NewTypeError(
-            "cant_prevent_ext_external_array_elements",
-            HandleVector(&object, 1));
-    return isolate->Throw<Object>(error);
+    THROW_NEW_ERROR(isolate,
+                    NewTypeError("cant_prevent_ext_external_array_elements",
+                                 HandleVector(&object, 1)),
+                    Object);
   }
 
   Handle<SeededNumberDictionary> new_element_dictionary;
@@ -11710,9 +11707,9 @@ MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object,
   // paragraph.
   if (!object->map()->is_extensible()) {
     Handle<Object> args[] = { object };
-    Handle<Object> error = isolate->factory()->NewTypeError(
-        "non_extensible_proto", HandleVector(args, arraysize(args)));
-    return isolate->Throw<Object>(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<Object> JSObject::SetPrototype(Handle<JSObject> object,
        !iter.IsAtEnd(); iter.Advance()) {
     if (JSReceiver::cast(iter.GetCurrent()) == *object) {
       // Cycle detected.
-      Handle<Object> error = isolate->factory()->NewError(
-          "cyclic_proto", HandleVector<Object>(NULL, 0));
-      return isolate->Throw<Object>(error);
+      THROW_NEW_ERROR(isolate,
+                      NewError("cyclic_proto", HandleVector<Object>(NULL, 0)),
+                      Object);
     }
   }
 
@@ -11937,9 +11934,9 @@ MaybeHandle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object,
       if (strict_mode == SLOPPY) return value;
       Handle<Object> key(isolate->factory()->NewNumberFromUint(index));
       Handle<Object> args[2] = { key, holder };
-      Handle<Object> error = isolate->factory()->NewTypeError(
-          "no_setter_in_callback", HandleVector(args, 2));
-      return isolate->Throw<Object>(error);
+      THROW_NEW_ERROR(
+          isolate, NewTypeError("no_setter_in_callback", HandleVector(args, 2)),
+          Object);
     }
   }
 
@@ -12148,10 +12145,9 @@ MaybeHandle<Object> JSObject::SetDictionaryElement(
         } else {
           Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
           Handle<Object> args[2] = { number, object };
-          Handle<Object> error =
-              isolate->factory()->NewTypeError("strict_read_only_property",
-                                               HandleVector(args, 2));
-          return isolate->Throw<Object>(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<Object> JSObject::SetDictionaryElement(
         Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
         Handle<String> name = isolate->factory()->NumberToString(number);
         Handle<Object> args[1] = { name };
-        Handle<Object> error =
-            isolate->factory()->NewTypeError("object_not_extensible",
-                                             HandleVector(args, 1));
-        return isolate->Throw<Object>(error);
+        THROW_NEW_ERROR(isolate, NewTypeError("object_not_extensible",
+                                              HandleVector(args, 1)),
+                        Object);
       }
     }
 
@@ -12409,9 +12404,9 @@ MaybeHandle<Object> JSObject::SetElement(Handle<JSObject> object,
       set_mode == DEFINE_PROPERTY) {
     Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
     Handle<Object> args[] = { object, number };
-    Handle<Object> error = isolate->factory()->NewTypeError(
-        "redef_external_array_element", HandleVector(args, arraysize(args)));
-    return isolate->Throw<Object>(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<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) {
   Isolate* isolate = array->GetIsolate();
   Handle<Name> length = isolate->factory()->length_string();
   Handle<Object> args[2] = { length, array };
-  Handle<Object> error = isolate->factory()->NewTypeError(
-      "strict_read_only_property", HandleVector(args, arraysize(args)));
-  return isolate->Throw<Object>(error);
+  THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property",
+                                        HandleVector(args, arraysize(args))),
+                  Object);
 }
 
 
index a3061dc..24510e3 100644 (file)
@@ -3955,10 +3955,12 @@ void Parser::ThrowPendingError() {
     isolate()->debug()->OnCompileError(script_);
 
     Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
-    Handle<Object> result = pending_error_is_reference_error_
-        ? factory->NewReferenceError(pending_error_message_, array)
-        : factory->NewSyntaxError(pending_error_message_, array);
-    isolate()->Throw(*result, &location);
+    Handle<Object> error;
+    MaybeHandle<Object> 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);
   }
 }
 
index c69882f..40468c2 100644 (file)
@@ -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<Object>(NULL, 0)));
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewRangeError("invalid_array_buffer_length",
+                               HandleVector<Object>(NULL, 0)));
   }
   if (!Runtime::SetupArrayBufferAllocatingData(isolate,
                                                holder, allocated_length)) {
-    return isolate->Throw(
-        *isolate->factory()->NewRangeError("invalid_array_buffer_length",
-                                           HandleVector<Object>(NULL, 0)));
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewRangeError("invalid_array_buffer_length",
+                               HandleVector<Object>(NULL, 0)));
   }
   return *holder;
 }
@@ -987,9 +987,9 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
   size_t length = byte_length / element_size;
 
   if (length > static_cast<unsigned>(Smi::kMaxValue)) {
-    return isolate->Throw(
-        *isolate->factory()->NewRangeError("invalid_typed_array_length",
-                                           HandleVector<Object>(NULL, 0)));
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewRangeError("invalid_typed_array_length",
+                               HandleVector<Object>(NULL, 0)));
   }
 
   // All checks are done, now we can modify objects.
@@ -1069,9 +1069,9 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) {
 
   if ((length > static_cast<unsigned>(Smi::kMaxValue)) ||
       (length > (kMaxInt / element_size))) {
-    return isolate->Throw(*isolate->factory()->
-          NewRangeError("invalid_typed_array_length",
-            HandleVector<Object>(NULL, 0)));
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewRangeError("invalid_typed_array_length",
+                               HandleVector<Object>(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<Object>(NULL, 0)));
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewRangeError("invalid_array_buffer_length",
+                               HandleVector<Object>(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<Object>(NULL, 0)));
+  if (!args[0]->IsJSTypedArray()) {
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate,
+        NewTypeError("not_typed_array", HandleVector<Object>(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<Object>(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<Object>(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<Object>(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<Object>(NULL, 0)));     \
+    }                                                                 \
   }
 
 DATA_VIEW_GETTER(Uint8, uint8_t, NewNumberFromUint)
@@ -1483,23 +1486,22 @@ double DataViewConvertValue<double>(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<Type>(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<Object>(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<Type>(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<Object>(NULL, 0)));         \
+    }                                                                     \
   }
 
 DATA_VIEW_SETTER(Uint8, uint8_t)
@@ -2167,9 +2169,8 @@ RUNTIME_FUNCTION(Runtime_EnableAccessChecks) {
 static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) {
   HandleScope scope(isolate);
   Handle<Object> args[1] = { name };
-  Handle<Object> 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<Object> > argv = HandleVector<Object>(NULL, 0);
-  Handle<Object> error = isolate->factory()->NewError(message, argv);
-  return isolate->Throw(*error);
+  THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewError(message, argv));
 }
 
 
@@ -4813,9 +4813,9 @@ MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
                                                Handle<Object> key) {
   if (object->IsUndefined() || object->IsNull()) {
     Handle<Object> args[2] = { key, object };
-    return isolate->Throw<Object>(
-        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<Object> Runtime::SetObjectProperty(Isolate* isolate,
                                                StrictMode strict_mode) {
   if (object->IsUndefined() || object->IsNull()) {
     Handle<Object> args[2] = { key, object };
-    Handle<Object> error =
-        isolate->factory()->NewTypeError("non_object_property_store",
-                                         HandleVector(args, 2));
-    return isolate->Throw<Object>(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<Object> args[1] = { key };
-    Handle<Object> 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<Object>(NULL, 0)));
+      THROW_NEW_ERROR_RETURN_FAILURE(
+          isolate, NewTypeError("strict_arguments_callee",
+                                HandleVector<Object>(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<Object> > arguments = HandleVector(&constructor, 1);
-    Handle<Object> type_error =
-        isolate->factory()->NewTypeError("not_constructor", arguments);
-    return isolate->Throw(*type_error);
+    THROW_NEW_ERROR_RETURN_FAILURE(isolate,
+                                   NewTypeError("not_constructor", arguments));
   }
 
   Handle<JSFunction> function = Handle<JSFunction>::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<Object> > arguments = HandleVector(&constructor, 1);
-    Handle<Object> 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<Object>(0));
     if (!maybe_object.ToHandle(&extension_object)) {
       Handle<Object> handle = args.at<Object>(0);
-      Handle<Object> 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<Object> reference_error =
+          Handle<Object> error;
+          MaybeHandle<Object> 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<Object> reference_error =
-        isolate->factory()->NewReferenceError("not_defined",
-                                              HandleVector(&name, 1));
-    return MakePair(isolate->Throw(*reference_error), NULL);
+    Handle<Object> error;
+    MaybeHandle<Object> 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<Context>::cast(holder)->set(index, *value);
     } else if (strict_mode == STRICT) {
       // Setting read only property in strict mode.
-      Handle<Object> 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<JSReceiver>::cast(holder);
   } else if (strict_mode == STRICT) {
     // If absent in strict mode: throw.
-    Handle<Object> 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<JSReceiver>(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<Object> 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<Object>(NULL, 0)));
+  THROW_NEW_ERROR_RETURN_FAILURE(
+      isolate, NewTypeError("not_date_object", HandleVector<Object>(NULL, 0)));
 }
 
 
@@ -9880,8 +9880,9 @@ RUNTIME_FUNCTION(Runtime_CompileString) {
       !CodeGenerationFromStringsAllowed(isolate, context)) {
     Handle<Object> error_message =
         context->ErrorMessageForCodeGenerationFromStrings();
-    return isolate->Throw(*isolate->factory()->NewEvalError(
-        "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewEvalError("code_gen_from_strings",
+                              HandleVector<Object>(&error_message, 1)));
   }
 
   // Compile source string in the native context.
@@ -9910,8 +9911,10 @@ static ObjectPair CompileGlobalEval(Isolate* isolate,
       !CodeGenerationFromStringsAllowed(isolate, native_context)) {
     Handle<Object> error_message =
         native_context->ErrorMessageForCodeGenerationFromStrings();
-    isolate->Throw(*isolate->factory()->NewEvalError(
-        "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
+    Handle<Object> error;
+    MaybeHandle<Object> maybe_error = isolate->factory()->NewEvalError(
+        "code_gen_from_strings", HandleVector<Object>(&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<Object>(NULL, 0)));
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate,
+        NewRangeError("invalid_array_length", HandleVector<Object>(NULL, 0)));
   }
   return *visitor.ToArray();
 }
@@ -14036,9 +14039,8 @@ RUNTIME_FUNCTION(Runtime_GetImplFromInitializedIntlObject) {
 
   if (!input->IsJSObject()) {
     Vector< Handle<Object> > arguments = HandleVector(&input, 1);
-    Handle<Object> 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<JSObject> obj = Handle<JSObject>::cast(input);
@@ -14047,9 +14049,8 @@ RUNTIME_FUNCTION(Runtime_GetImplFromInitializedIntlObject) {
   Handle<Object> impl(obj->GetHiddenProperty(marker), isolate);
   if (impl->IsTheHole()) {
     Vector< Handle<Object> > arguments = HandleVector(&obj, 1);
-    Handle<Object> 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<Object>(NULL, 0)));
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate,
+        NewTypeError("not_date_object", HandleVector<Object>(NULL, 0)));
   }
   JSDate* date = JSDate::cast(obj);
   if (index == 0) return date->value();
index 5a91695..e1297b3 100644 (file)
@@ -1080,9 +1080,10 @@ bool Scope::ResolveVariable(CompilationInfo* info,
     Isolate* isolate = info->isolate();
     Factory* factory = isolate->factory();
     Handle<JSArray> array = factory->NewJSArray(0);
-    Handle<Object> result =
+    Handle<Object> error;
+    MaybeHandle<Object> 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<JSArray> array = factory->NewJSArray(1);
       JSObject::SetElement(array, 0, var->name(), NONE, STRICT).Assert();
-      Handle<Object> result =
+      Handle<Object> error;
+      MaybeHandle<Object> maybe_error =
           factory->NewSyntaxError("module_type_error", array);
-      isolate->Throw(*result, &location);
+      if (maybe_error.ToHandle(&error)) isolate->Throw(*error, &location);
       return false;
     }
   }
index a5ed7ab..21d3b95 100644 (file)
@@ -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<v8::Context> context = v8::Context::New(CcTest::isolate());
+  v8::Context::Scope context_scope(context);
+  v8::V8::TerminateExecution(isolate);
+  v8::Local<v8::Value> error = v8::Exception::Error(v8_str("error"));
+  // TODO(yangguo): crbug/403509. Check for empty handle instead.
+  CHECK(error->IsUndefined());
+}