v8::Local<v8::Value> V8Proxy::runScriptInternal(v8::Handle<v8::Script> script, bool isInlineCode) #endif { if (script.IsEmpty()) return notHandledByInterceptor(); V8GCController::checkMemoryUsage(); // Compute the source string and prevent against infinite recursion. if (m_recursion >= kMaxRecursionDepth) { v8::Local<v8::String> code = v8ExternalString("throw RangeError('Recursion too deep')"); // FIXME: Ideally, we should be able to re-use the origin of the // script passed to us as the argument instead of using an empty string // and 0 baseLine. script = compileScript(code, "", 0); } if (handleOutOfMemory()) ASSERT(script.IsEmpty()); if (script.IsEmpty()) return notHandledByInterceptor(); // Save the previous value of the inlineCode flag and update the flag for // the duration of the script invocation. bool previousInlineCode = inlineCode(); setInlineCode(isInlineCode); // Run the script and keep track of the current recursion depth. v8::Local<v8::Value> result; { V8ConsoleMessage::Scope scope; // See comment in V8Proxy::callFunction. m_frame->keepAlive(); m_recursion++; result = script->Run(); m_recursion--; } // Release the storage mutex if applicable. releaseStorageMutex(); if (handleOutOfMemory()) ASSERT(result.IsEmpty()); // Handle V8 internal error situation (Out-of-memory). if (result.IsEmpty()) return notHandledByInterceptor(); // Restore inlineCode flag. setInlineCode(previousInlineCode); if (v8::V8::IsDead()) handleFatalErrorInV8(); return result; }
v8::Local<v8::Value> V8Proxy::callFunction(v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[]) { #ifdef ANDROID_INSTRUMENT android::TimeCounter::start(android::TimeCounter::JavaScriptExecuteTimeCounter); #endif V8GCController::checkMemoryUsage(); v8::Local<v8::Value> result; { V8ConsoleMessage::Scope scope; if (m_recursion >= kMaxRecursionDepth) { v8::Local<v8::String> code = v8::String::New("throw new RangeError('Maximum call stack size exceeded.')"); if (code.IsEmpty()) return result; v8::Local<v8::Script> script = v8::Script::Compile(code); if (script.IsEmpty()) return result; script->Run(); return result; } // Evaluating the JavaScript could cause the frame to be deallocated, // so we start the keep alive timer here. // Frame::keepAlive method adds the ref count of the frame and sets a // timer to decrease the ref count. It assumes that the current JavaScript // execution finishs before firing the timer. m_frame->keepAlive(); m_recursion++; result = function->Call(receiver, argc, args); m_recursion--; } // Release the storage mutex if applicable. releaseStorageMutex(); if (v8::V8::IsDead()) handleFatalErrorInV8(); #ifdef ANDROID_INSTRUMENT android::TimeCounter::record(android::TimeCounter::JavaScriptExecuteTimeCounter, __FUNCTION__); #endif return result; }
v8::Local<v8::Value> V8Proxy::callFunction(v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[]) { V8GCController::checkMemoryUsage(); v8::Local<v8::Value> result; { V8ConsoleMessage::Scope scope; if (m_recursion >= kMaxRecursionDepth) { v8::Local<v8::String> code = v8::String::New("throw new RangeError('Maximum call stack size exceeded.')"); if (code.IsEmpty()) return result; v8::Local<v8::Script> script = v8::Script::Compile(code); if (script.IsEmpty()) return result; script->Run(); return result; } // Evaluating the JavaScript could cause the frame to be deallocated, // so we start the keep alive timer here. // Frame::keepAlive method adds the ref count of the frame and sets a // timer to decrease the ref count. It assumes that the current JavaScript // execution finishs before firing the timer. m_frame->keepAlive(); #if ENABLE(INSPECTOR) Page* inspectedPage = InspectorTimelineAgent::instanceCount() ? m_frame->page(): 0; if (inspectedPage) { if (InspectorTimelineAgent* timelineAgent = inspectedPage->inspectorTimelineAgent()) { v8::ScriptOrigin origin = function->GetScriptOrigin(); String resourceName("undefined"); int lineNumber = 1; if (!origin.ResourceName().IsEmpty()) { resourceName = toWebCoreString(origin.ResourceName()); lineNumber = function->GetScriptLineNumber() + 1; } timelineAgent->willCallFunction(resourceName, lineNumber); } else inspectedPage = 0; } #endif // !ENABLE(INSPECTOR) m_recursion++; result = function->Call(receiver, argc, args); m_recursion--; #if ENABLE(INSPECTOR) if (inspectedPage) if (InspectorTimelineAgent* timelineAgent = inspectedPage->inspectorTimelineAgent()) timelineAgent->didCallFunction(); #endif // !ENABLE(INSPECTOR) } // Release the storage mutex if applicable. releaseStorageMutex(); if (v8::V8::IsDead()) handleFatalErrorInV8(); return result; }