[json] check and handle interrupts.

R=jkummerow@chromium.org
BUG=chromium:595626

Review-Url: https://codereview.chromium.org/2037363002
Cr-Commit-Position: refs/heads/master@{#36785}
This commit is contained in:
yangguo 2016-06-07 04:43:41 -07:00 committed by Commit bot
parent f53d1009e2
commit 2963b5bd40
3 changed files with 43 additions and 4 deletions

View File

@ -249,10 +249,9 @@ Handle<Object> JsonParser<seq_one_byte>::ParseJsonValue() {
return Handle<Object>::null();
}
if (stack_check.InterruptRequested()) {
ExecutionAccess access(isolate_);
// Avoid blocking GC in long running parser (v8:3974).
isolate_->stack_guard()->HandleGCInterrupt();
if (stack_check.InterruptRequested() &&
isolate_->stack_guard()->HandleInterrupts()->IsException()) {
return Handle<Object>::null();
}
if (c0_ == '"') return ParseJsonString();

View File

@ -272,6 +272,11 @@ template <bool deferred_string_key>
JsonStringifier::Result JsonStringifier::Serialize_(Handle<Object> object,
bool comma,
Handle<Object> key) {
StackLimitCheck interrupt_check(isolate_);
if (interrupt_check.InterruptRequested() &&
isolate_->stack_guard()->HandleInterrupts()->IsException()) {
return EXCEPTION;
}
if (object->IsJSReceiver()) {
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate_, object, ApplyToJsonFunction(object, key), EXCEPTION);
@ -399,7 +404,12 @@ JsonStringifier::Result JsonStringifier::SerializeJSArray(
case FAST_SMI_ELEMENTS: {
Handle<FixedArray> elements(FixedArray::cast(object->elements()),
isolate_);
StackLimitCheck interrupt_check(isolate_);
while (i < length) {
if (interrupt_check.InterruptRequested() &&
isolate_->stack_guard()->HandleInterrupts()->IsException()) {
return EXCEPTION;
}
Separator(i == 0);
SerializeSmi(Smi::cast(elements->get(i)));
i++;
@ -411,7 +421,12 @@ JsonStringifier::Result JsonStringifier::SerializeJSArray(
if (length == 0) break;
Handle<FixedDoubleArray> elements(
FixedDoubleArray::cast(object->elements()), isolate_);
StackLimitCheck interrupt_check(isolate_);
while (i < length) {
if (interrupt_check.InterruptRequested() &&
isolate_->stack_guard()->HandleInterrupts()->IsException()) {
return EXCEPTION;
}
Separator(i == 0);
SerializeDouble(elements->get_scalar(i));
i++;

View File

@ -204,6 +204,31 @@ TEST(TerminateOnlyV8ThreadFromOtherThread) {
semaphore = NULL;
}
// Test that execution can be terminated from within JSON.stringify.
TEST(TerminateJsonStringify) {
semaphore = new v8::base::Semaphore(0);
TerminatorThread thread(CcTest::i_isolate());
thread.Start();
v8::HandleScope scope(CcTest::isolate());
v8::Local<v8::ObjectTemplate> global =
CreateGlobalTemplate(CcTest::isolate(), Signal, DoLoop);
v8::Local<v8::Context> context =
v8::Context::New(CcTest::isolate(), NULL, global);
v8::Context::Scope context_scope(context);
CHECK(!CcTest::isolate()->IsExecutionTerminating());
v8::MaybeLocal<v8::Value> result =
CompileRun(CcTest::isolate()->GetCurrentContext(),
"var x = [];"
"x[2**31]=1;"
"terminate();"
"JSON.stringify(x);"
"fail();");
CHECK(result.IsEmpty());
thread.Join();
delete semaphore;
semaphore = NULL;
}
int call_count = 0;