ScheduledAction.cpp 4.65 KB
Newer Older
weinig@apple.com's avatar
weinig@apple.com committed
1 2 3
/*
 *  Copyright (C) 2000 Harri Porten (porten@kde.org)
 *  Copyright (C) 2006 Jon Shier (jshier@iastate.edu)
4
 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reseved.
weinig@apple.com's avatar
weinig@apple.com committed
5
 *  Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
6
 *  Copyright (C) 2009 Google Inc. All rights reseved.
weinig@apple.com's avatar
weinig@apple.com committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
 *  USA
 */

#include "config.h"
#include "ScheduledAction.h"

#include "CString.h"
#include "DOMWindow.h"
#include "Document.h"
#include "Frame.h"
#include "FrameLoader.h"
ap@webkit.org's avatar
ap@webkit.org committed
32
#include "JSDOMBinding.h"
weinig@apple.com's avatar
weinig@apple.com committed
33
#include "JSDOMWindow.h"
darin@apple.com's avatar
darin@apple.com committed
34
#include "ScriptController.h"
35
#include "ScriptExecutionContext.h"
36
#include "ScriptSourceCode.h"
37
#include "ScriptValue.h"
38 39 40 41
#include <runtime/JSLock.h>

#if ENABLE(WORKERS)
#include "JSWorkerContext.h"
42 43
#include "WorkerContext.h"
#include "WorkerThread.h"
44
#endif
weinig@apple.com's avatar
weinig@apple.com committed
45

46
using namespace JSC;
weinig@apple.com's avatar
weinig@apple.com committed
47 48 49

namespace WebCore {

50
ScheduledAction* ScheduledAction::create(ExecState* exec, const ArgList& args, DOMWrapperWorld* isolatedWorld)
51
{
ggaren@apple.com's avatar
ggaren@apple.com committed
52
    JSValue v = args.at(0);
53
    CallData callData;
54 55 56 57
    if (v.getCallData(callData) == CallTypeNone) {
        UString string = v.toString(exec);
        if (exec->hadException())
            return 0;
58
        return new ScheduledAction(string, isolatedWorld);
59
    }
60 61
    ArgList argsTail;
    args.getSlice(2, argsTail);
62
    return new ScheduledAction(v, argsTail, isolatedWorld);
63 64
}

65
ScheduledAction::ScheduledAction(JSValue function, const ArgList& args, DOMWrapperWorld* isolatedWorld)
darin@apple.com's avatar
darin@apple.com committed
66
    : m_function(function)
67
    , m_isolatedWorld(isolatedWorld)
weinig@apple.com's avatar
weinig@apple.com committed
68
{
darin@apple.com's avatar
darin@apple.com committed
69
    ArgList::const_iterator end = args.end();
70
    for (ArgList::const_iterator it = args.begin(); it != end; ++it)
71
        m_args.append(*it);
weinig@apple.com's avatar
weinig@apple.com committed
72 73
}

74 75
void ScheduledAction::execute(ScriptExecutionContext* context)
{
76 77 78 79 80 81 82 83
    if (context->isDocument())
        execute(static_cast<Document*>(context));
#if ENABLE(WORKERS)
    else {
        ASSERT(context->isWorkerContext());
        execute(static_cast<WorkerContext*>(context));
    }
#else
84
    ASSERT(context->isDocument());
85
#endif
86 87
}

ggaren@apple.com's avatar
ggaren@apple.com committed
88
void ScheduledAction::executeFunctionInContext(JSGlobalObject* globalObject, JSValue thisValue)
weinig@apple.com's avatar
weinig@apple.com committed
89
{
90
    ASSERT(m_function);
ap@webkit.org's avatar
ap@webkit.org committed
91
    JSLock lock(SilenceAssertionsOnly);
weinig@apple.com's avatar
weinig@apple.com committed
92

93
    CallData callData;
weinig@apple.com's avatar
weinig@apple.com committed
94
    CallType callType = m_function.get().getCallData(callData);
95
    if (callType == CallTypeNone)
weinig@apple.com's avatar
weinig@apple.com committed
96 97
        return;

98
    ExecState* exec = globalObject->globalExec();
weinig@apple.com's avatar
weinig@apple.com committed
99

100
    MarkedArgumentBuffer args;
101 102 103 104
    size_t size = m_args.size();
    for (size_t i = 0; i < size; ++i)
        args.append(m_args[i]);

ggaren@apple.com's avatar
ggaren@apple.com committed
105
    globalObject->globalData()->timeoutChecker.start();
106
    callInWorld(exec, m_function, callType, callData, thisValue, args, m_isolatedWorld.get());
ggaren@apple.com's avatar
ggaren@apple.com committed
107
    globalObject->globalData()->timeoutChecker.stop();
108 109 110 111 112 113 114

    if (exec->hadException())
        reportCurrentException(exec);
}

void ScheduledAction::execute(Document* document)
{
115
    JSDOMWindow* window = toJSDOMWindow(document->frame(), m_isolatedWorld.get());
116 117 118 119 120 121 122 123 124
    if (!window)
        return;

    RefPtr<Frame> frame = window->impl()->frame();
    if (!frame || !frame->script()->isEnabled())
        return;

    frame->script()->setProcessingTimerCallback(true);

125
    if (m_function) {
126
        executeFunctionInContext(window, window->shell());
127 128
        Document::updateStyleForAllDocuments();
    } else
129
        frame->script()->executeScriptInWorld(m_isolatedWorld.get(), m_code);
weinig@apple.com's avatar
weinig@apple.com committed
130

darin@apple.com's avatar
darin@apple.com committed
131
    frame->script()->setProcessingTimerCallback(false);
weinig@apple.com's avatar
weinig@apple.com committed
132 133
}

134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
#if ENABLE(WORKERS)
void ScheduledAction::execute(WorkerContext* workerContext)
{
    // In a Worker, the execution should always happen on a worker thread.
    ASSERT(workerContext->thread()->threadID() == currentThread());

    WorkerScriptController* scriptController = workerContext->script();

    if (m_function) {
        JSWorkerContext* contextWrapper = scriptController->workerContextWrapper();
        executeFunctionInContext(contextWrapper, contextWrapper);
    } else {
        ScriptSourceCode code(m_code, workerContext->url());
        scriptController->evaluate(code);
    }
}
#endif // ENABLE(WORKERS)

weinig@apple.com's avatar
weinig@apple.com committed
152
} // namespace WebCore