From: yangguo@chromium.org Date: Mon, 23 Jun 2014 11:47:20 +0000 (+0000) Subject: Run JS micro tasks in the appropriate context. X-Git-Tag: upstream/4.7.83~8605 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9e3ba659d96ed7abcd1530ecd338fbcb250dc0b2;p=platform%2Fupstream%2Fv8.git Run JS micro tasks in the appropriate context. R=jochen@chromium.org BUG=385349 LOG=Y Review URL: https://codereview.chromium.org/332923003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21933 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/isolate.cc b/src/isolate.cc index d4368da..8905213 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -2292,12 +2292,10 @@ void Isolate::EnqueueMicrotask(Handle microtask) { void Isolate::RunMicrotasks() { - // TODO(adamk): This ASSERT triggers in mjsunit tests which - // call the %RunMicrotasks runtime function. But it should - // never happen outside of tests, so it would be nice to - // uncomment it. - // - // ASSERT(handle_scope_implementer()->CallDepthIsZero()); + // In some mjsunit tests %RunMicrotasks is called explicitly, violating + // this assertion. Therefore we also check for --allow-natives-syntax. + ASSERT(FLAG_allow_natives_syntax || + handle_scope_implementer()->CallDepthIsZero()); // Increase call depth to prevent recursive callbacks. v8::Isolate::SuppressMicrotaskExecutionScope suppress( @@ -2317,6 +2315,8 @@ void Isolate::RunMicrotasks() { if (microtask->IsJSFunction()) { Handle microtask_function = Handle::cast(microtask); + SaveContext save(this); + set_context(microtask_function->context()->native_context()); Handle exception; MaybeHandle result = Execution::TryCall( microtask_function, factory()->undefined_value(), diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index a7cb454..4837cff 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -20828,6 +20828,37 @@ TEST(RunMicrotasksWithoutEnteringContext) { } +static void DebugEventInObserver(const v8::Debug::EventDetails& event_details) { + v8::DebugEvent event = event_details.GetEvent(); + if (event != v8::Break) return; + Handle exec_state = event_details.GetExecutionState(); + Handle break_id = exec_state->Get(v8_str("break_id")); + CompileRun("function f(id) { new FrameDetails(id, 0); }"); + Handle fun = Handle::Cast( + CcTest::global()->Get(v8_str("f"))->ToObject()); + fun->Call(CcTest::global(), 1, &break_id); +} + + +TEST(Regress385349) { + i::FLAG_allow_natives_syntax = true; + v8::Isolate* isolate = CcTest::isolate(); + HandleScope handle_scope(isolate); + isolate->SetAutorunMicrotasks(false); + Handle context = Context::New(isolate); + v8::Debug::SetDebugEventListener(DebugEventInObserver); + { + Context::Scope context_scope(context); + CompileRun("var obj = {};" + "Object.observe(obj, function(changes) { debugger; });" + "obj.a = 0;"); + } + isolate->RunMicrotasks(); + isolate->SetAutorunMicrotasks(true); + v8::Debug::SetDebugEventListener(NULL); +} + + static int probes_counter = 0; static int misses_counter = 0; static int updates_counter = 0;