Commit d8c3c5ef authored by yangguo@chromium.org's avatar yangguo@chromium.org

Introduce API to trigger exception on JS execution.

R=jochen@chromium.org, pmarch@chromium.org

Review URL: https://codereview.chromium.org/203223013

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20070 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 9be17fb3
......@@ -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&);
};
/**
......
......@@ -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_);
}
......
......@@ -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;
......
......@@ -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);
......
......@@ -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());
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment