Reviewers: jochen, pmarch,

Description:
Introduce API to trigger exception on JS execution.

Please review this at https://codereview.chromium.org/203223013/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+66, -10 lines):
  M include/v8.h
  M src/api.cc
  M src/assert-scope.h
  M src/execution.cc
  M test/cctest/test-api.cc


Index: include/v8.h
diff --git a/include/v8.h b/include/v8.h
index 942ef4d95f86c88115e3a67673a8bf853442cc30..4ff5830115c2b8737a679b368fa97497808b7c2f 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -4090,10 +4090,14 @@ class V8_EXPORT Isolate {
    */
   class DisallowJavascriptExecutionScope {
    public:
-    explicit DisallowJavascriptExecutionScope(Isolate* isolate);
+    enum OnFailure { CRASH_ON_FAILURE, THROW_ON_FAILURE };
+
+    explicit DisallowJavascriptExecutionScope(Isolate* isolate,
+                                              OnFailure on_failure);
     ~DisallowJavascriptExecutionScope();

    private:
+    bool on_failure_;
     void* internal_;

     // Prevent copying of Scope objects.
@@ -4112,7 +4116,13 @@ class V8_EXPORT Isolate {
     ~AllowJavascriptExecutionScope();

    private:
-    void* internal_;
+    void* internal_throws_;
+    void* internal_assert_;
+
+    // Prevent copying of Scope objects.
+    AllowJavascriptExecutionScope(const AllowJavascriptExecutionScope&);
+    AllowJavascriptExecutionScope& operator=(
+        const AllowJavascriptExecutionScope&);
   };

   /**
Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index 381ca004b1f7c1dff24962723b479e97e6cc6672..3eab31c0028322f373df9e052673f97c6fac5ddc 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -6515,28 +6515,43 @@ void Isolate::Exit() {


Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope(
-    Isolate* isolate) {
+  Isolate* isolate,
+  Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)
+    : on_failure_(on_failure) {
   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
-  internal_ = reinterpret_cast<void*>(
-      new i::DisallowJavascriptExecution(i_isolate));
+  if (on_failure_ == CRASH_ON_FAILURE) {
+    internal_ = reinterpret_cast<void*>(
+        new i::DisallowJavascriptExecution(i_isolate));
+  } else {
+    ASSERT_EQ(THROW_ON_FAILURE, on_failure);
+    internal_ = reinterpret_cast<void*>(
+        new i::ThrowOnJavascriptExecution(i_isolate));
+  }
 }


Isolate::DisallowJavascriptExecutionScope::~DisallowJavascriptExecutionScope() {
-  delete reinterpret_cast<i::DisallowJavascriptExecution*>(internal_);
+  if (on_failure_ == CRASH_ON_FAILURE) {
+    delete reinterpret_cast<i::DisallowJavascriptExecution*>(internal_);
+  } else {
+    delete reinterpret_cast<i::ThrowOnJavascriptExecution*>(internal_);
+  }
 }


 Isolate::AllowJavascriptExecutionScope::AllowJavascriptExecutionScope(
     Isolate* isolate) {
   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
-  internal_ = reinterpret_cast<void*>(
+  internal_assert_ = reinterpret_cast<void*>(
       new i::AllowJavascriptExecution(i_isolate));
+  internal_throws_ = reinterpret_cast<void*>(
+      new i::NoThrowOnJavascriptExecution(i_isolate));
 }


 Isolate::AllowJavascriptExecutionScope::~AllowJavascriptExecutionScope() {
-  delete reinterpret_cast<i::AllowJavascriptExecution*>(internal_);
+  delete reinterpret_cast<i::AllowJavascriptExecution*>(internal_assert_);
+ delete reinterpret_cast<i::NoThrowOnJavascriptExecution*>(internal_throws_);
 }


Index: src/assert-scope.h
diff --git a/src/assert-scope.h b/src/assert-scope.h
index 4357056404ebf62a93d7beea8ca9baa7b77d98a6..428e6d007ef8d5a9a5d03ba9484b402a16674bec 100644
--- a/src/assert-scope.h
+++ b/src/assert-scope.h
@@ -49,6 +49,7 @@ enum PerThreadAssertType {

 enum PerIsolateAssertType {
   JAVASCRIPT_EXECUTION_ASSERT,
+  JAVASCRIPT_EXECUTION_THROWS,
   ALLOCATION_FAILURE_ASSERT
 };

@@ -251,6 +252,14 @@ typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, false>
 typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, true>
     AllowJavascriptExecution;

+// Scope in which javascript execution leads to exception being thrown.
+typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, false>
+    ThrowOnJavascriptExecution;
+
+// Scope to introduce an exception to ThrowOnJavascriptExecution.
+typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, true>
+    NoThrowOnJavascriptExecution;
+
 // Scope to document where we do not expect an allocation failure.
 typedef PerIsolateAssertScopeDebugOnly<ALLOCATION_FAILURE_ASSERT, false>
     DisallowAllocationFailure;
Index: src/execution.cc
diff --git a/src/execution.cc b/src/execution.cc
index bef01a2a91ca47331eb7ff7236795cf12cd658b0..924814cff46cb4257e185eac1c78734eb1b1c884 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -78,6 +78,12 @@ static Handle<Object> Invoke(bool is_construct,
   // Entering JavaScript.
   VMState<JS> state(isolate);
   CHECK(AllowJavascriptExecution::IsAllowed(isolate));
+  if (!ThrowOnJavascriptExecution::IsAllowed(isolate)) {
+    isolate->ThrowIllegalOperation();
+    *has_pending_exception = true;
+    isolate->ReportPendingMessages();
+    return Handle<Object>();
+  }

   // Placeholder for return value.
   MaybeObject* value = reinterpret_cast<Object*>(kZapValue);
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 74afab2c1b069e63d6ff40781f452f89f9c920b1..d8214e15b0a5197fe8282c9511606db55abba291 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -22399,7 +22399,8 @@ TEST(DisallowJavascriptExecutionScope) {
   LocalContext context;
   v8::Isolate* isolate = context->GetIsolate();
   v8::HandleScope scope(isolate);
-  v8::Isolate::DisallowJavascriptExecutionScope no_js(isolate);
+  v8::Isolate::DisallowJavascriptExecutionScope no_js(
+ isolate, v8::Isolate::DisallowJavascriptExecutionScope::CRASH_ON_FAILURE);
   CompileRun("2+2");
 }

@@ -22408,8 +22409,23 @@ TEST(AllowJavascriptExecutionScope) {
   LocalContext context;
   v8::Isolate* isolate = context->GetIsolate();
   v8::HandleScope scope(isolate);
-  v8::Isolate::DisallowJavascriptExecutionScope no_js(isolate);
+  v8::Isolate::DisallowJavascriptExecutionScope no_js(
+ isolate, v8::Isolate::DisallowJavascriptExecutionScope::CRASH_ON_FAILURE);
+  v8::Isolate::DisallowJavascriptExecutionScope throw_js(
+ isolate, v8::Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE);
   { v8::Isolate::AllowJavascriptExecutionScope yes_js(isolate);
     CompileRun("1+1");
   }
 }
+
+
+TEST(ThrowOnJavascriptExecution) {
+  LocalContext context;
+  v8::Isolate* isolate = context->GetIsolate();
+  v8::HandleScope scope(isolate);
+  v8::TryCatch try_catch;
+  v8::Isolate::DisallowJavascriptExecutionScope throw_js(
+ isolate, v8::Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE);
+  CompileRun("1+1");
+  CHECK(try_catch.HasCaught());
+}


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to