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 // For now, we don't put any artificial limitations on the depth // of recursion that stems from calling functions. This is in // contrast to the script evaluations. v8::Local<v8::Value> result; { V8ConsoleMessage::Scope scope; // 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(); result = function->Call(receiver, argc, args); } if (v8::V8::IsDead()) handleFatalErrorInV8(); #ifdef ANDROID_INSTRUMENT android::TimeCounter::record(android::TimeCounter::JavaScriptExecuteTimeCounter, __FUNCTION__); #endif return result; }
v8::Local<v8::Value> V8Proxy::instrumentedCallFunction(Frame* frame, v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[]) { V8GCController::checkMemoryUsage(); if (V8RecursionScope::recursionLevel() >= kMaxRecursionDepth) return handleMaxRecursionDepthExceeded(); ScriptExecutionContext* context = frame ? frame->document() : 0; InspectorInstrumentationCookie cookie; if (InspectorInstrumentation::hasFrontends() && context) { String resourceName; int lineNumber; resourceInfo(function, resourceName, lineNumber); cookie = InspectorInstrumentation::willCallFunction(context, resourceName, lineNumber); } v8::Local<v8::Value> result; { #if PLATFORM(CHROMIUM) TRACE_EVENT1("v8", "v8.callFunction", "callsite", resourceString(function).utf8()); #endif V8RecursionScope recursionScope(context); result = function->Call(receiver, argc, args); } InspectorInstrumentation::didCallFunction(cookie); if (v8::V8::IsDead()) handleFatalErrorInV8(); return result; }
static void reportFatalErrorInV8(const char* location, const char* message) { // V8 is shutdown, we cannot use V8 api. // The only thing we can do is to disable JavaScript. // FIXME: clean up V8Proxy and disable JavaScript. printf("V8 error: %s (%s)\n", message, location); handleFatalErrorInV8(); }
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::callFunctionWithoutFrame(v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[]) { V8GCController::checkMemoryUsage(); v8::Local<v8::Value> result = function->Call(receiver, argc, args); if (v8::V8::IsDead()) handleFatalErrorInV8(); return result; }
static void reportFatalErrorInV8(const char* location, const char* message) { // V8 is shutdown, we cannot use V8 api. // The only thing we can do is to disable JavaScript. // FIXME: clean up V8Proxy and disable JavaScript. int memoryUsageMB = -1; #if PLATFORM(CHROMIUM) memoryUsageMB = ChromiumBridge::actualMemoryUsageMB(); #endif printf("V8 error: %s (%s). Current memory usage: %d MB\n", message, location, memoryUsageMB); handleFatalErrorInV8(); }
v8::Local<v8::Value> V8Proxy::callFunction(v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[]) { /// M: add for systrace TRACE_METHOD() V8GCController::checkMemoryUsage(); v8::Local<v8::Value> result; { 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(); InspectorInstrumentationCookie cookie; if (InspectorInstrumentation::hasFrontends()) { v8::ScriptOrigin origin = function->GetScriptOrigin(); String resourceName("undefined"); int lineNumber = 1; if (!origin.ResourceName().IsEmpty()) { resourceName = toWebCoreString(origin.ResourceName()); lineNumber = function->GetScriptLineNumber() + 1; } cookie = InspectorInstrumentation::willCallFunction(m_frame, resourceName, lineNumber); } m_recursion++; result = function->Call(receiver, argc, args); m_recursion--; InspectorInstrumentation::didCallFunction(cookie); } // Release the storage mutex if applicable. didLeaveScriptContext(); if (v8::V8::IsDead()) handleFatalErrorInV8(); return result; }
v8::Local<v8::Value> V8Proxy::newInstance(v8::Handle<v8::Function> constructor, int argc, v8::Handle<v8::Value> args[]) { // No artificial limitations on the depth of recursion, see comment in // V8Proxy::callFunction. v8::Local<v8::Value> result; { // See comment in V8Proxy::callFunction. m_frame->keepAlive(); result = constructor->NewInstance(argc, args); } if (v8::V8::IsDead()) handleFatalErrorInV8(); return result; }
v8::Local<v8::Value> V8Proxy::newInstance(v8::Handle<v8::Function> constructor, int argc, v8::Handle<v8::Value> args[]) { #if PLATFORM(CHROMIUM) TRACE_EVENT0("v8", "v8.newInstance"); #endif // No artificial limitations on the depth of recursion, see comment in // V8Proxy::callFunction. v8::Local<v8::Value> result; { result = constructor->NewInstance(argc, args); } 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::runScript(v8::Handle<v8::Script> script) { if (script.IsEmpty()) return v8::Local<v8::Value>(); V8GCController::checkMemoryUsage(); if (V8RecursionScope::recursionLevel() >= kMaxRecursionDepth) return handleMaxRecursionDepthExceeded(); if (handleOutOfMemory()) ASSERT(script.IsEmpty()); // Keep Frame (and therefore ScriptController and V8Proxy) alive. RefPtr<Frame> protect(frame()); // Run the script and keep track of the current recursion depth. v8::Local<v8::Value> result; v8::TryCatch tryCatch; tryCatch.SetVerbose(true); { V8RecursionScope recursionScope(frame()->document()); result = script->Run(); } if (handleOutOfMemory()) ASSERT(result.IsEmpty()); // Handle V8 internal error situation (Out-of-memory). if (tryCatch.HasCaught()) { ASSERT(result.IsEmpty()); return v8::Local<v8::Value>(); } if (result.IsEmpty()) return v8::Local<v8::Value>(); if (v8::V8::IsDead()) handleFatalErrorInV8(); return result; }
v8::Local<v8::Value> V8Proxy::instrumentedCallFunction(Frame* frame, v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[]) { V8GCController::checkMemoryUsage(); if (V8RecursionScope::recursionLevel() >= kMaxRecursionDepth) return handleMaxRecursionDepthExceeded(); ScriptExecutionContext* context = frame ? frame->document() : 0; InspectorInstrumentationCookie cookie; if (InspectorInstrumentation::hasFrontends() && context) { String resourceName("undefined"); int lineNumber = 1; v8::ScriptOrigin origin = function->GetScriptOrigin(); if (!origin.ResourceName().IsEmpty()) { resourceName = toWebCoreString(origin.ResourceName()); lineNumber = function->GetScriptLineNumber() + 1; } cookie = InspectorInstrumentation::willCallFunction(context, resourceName, lineNumber); } v8::Local<v8::Value> result; { #if PLATFORM(CHROMIUM) TRACE_EVENT0("v8", "v8.callFunction"); #endif V8RecursionScope recursionScope(context); result = function->Call(receiver, argc, args); } InspectorInstrumentation::didCallFunction(cookie); 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[]) { 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. didLeaveScriptContext(); if (v8::V8::IsDead()) handleFatalErrorInV8(); return result; }