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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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();
}
Beispiel #4
0
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;
}
Beispiel #5
0
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();
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
0
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;
}
Beispiel #11
0
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;
}
Beispiel #12
0
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;
}
Beispiel #13
0
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;
}