*/
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.
~AllowJavascriptExecutionScope();
private:
- void* internal_;
+ void* internal_throws_;
+ void* internal_assert_;
+
+ // Prevent copying of Scope objects.
+ AllowJavascriptExecutionScope(const AllowJavascriptExecutionScope&);
+ AllowJavascriptExecutionScope& operator=(
+ const AllowJavascriptExecutionScope&);
};
/**
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_);
}
enum PerIsolateAssertType {
JAVASCRIPT_EXECUTION_ASSERT,
+ JAVASCRIPT_EXECUTION_THROWS,
ALLOCATION_FAILURE_ASSERT
};
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;
// 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);
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");
}
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());
+}