18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 2000 Harri Porten (porten@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 2006 Jon Shier (jshier@iastate.edu)
45f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reseved.
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
6635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *  Copyright (C) 2009 Google Inc. All rights reseved.
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is free software; you can redistribute it and/or
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  modify it under the terms of the GNU Lesser General Public
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  License as published by the Free Software Foundation; either
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  version 2 of the License, or (at your option) any later version.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is distributed in the hope that it will be useful,
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  but WITHOUT ANY WARRANTY; without even the implied warranty of
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Lesser General Public License for more details.
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  You should have received a copy of the GNU Lesser General Public
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  License along with this library; if not, write to the Free Software
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  USA
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ScheduledAction.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "ContentSecurityPolicy.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DOMWindow.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameLoader.h"
32635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "JSDOMBinding.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSDOMWindow.h"
34e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include "JSMainThreadExecState.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ScriptController.h"
36635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "ScriptExecutionContext.h"
37635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "ScriptSourceCode.h"
385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include <runtime/JSLock.h>
395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if ENABLE(WORKERS)
415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "JSWorkerContext.h"
42635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "WorkerContext.h"
43635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "WorkerThread.h"
445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace JSC;
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochPassOwnPtr<ScheduledAction> ScheduledAction::create(ExecState* exec, DOMWrapperWorld* isolatedWorld, ContentSecurityPolicy* policy)
515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
525af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSValue v = exec->argument(0);
535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    CallData callData;
54545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (getCallData(v, callData) == CallTypeNone) {
552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (policy && !policy->allowEval())
562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return 0;
575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        UString string = v.toString(exec);
585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (exec->hadException())
595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            return 0;
60dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return new ScheduledAction(ustringToString(string), isolatedWorld);
615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
625af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
635af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return new ScheduledAction(exec, v, isolatedWorld);
645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
665af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeScheduledAction::ScheduledAction(ExecState* exec, JSValue function, DOMWrapperWorld* isolatedWorld)
6781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    : m_function(exec->globalData(), function)
68cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    , m_isolatedWorld(isolatedWorld)
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
705af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // setTimeout(function, interval, arg0, arg1...).
715af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // Start at 2 to skip function and interval.
725af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    for (size_t i = 2; i < exec->argumentCount(); ++i)
732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        m_args.append(Strong<JSC::Unknown>(exec->globalData(), exec->argument(i)));
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
76635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ScheduledAction::execute(ScriptExecutionContext* context)
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
78635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (context->isDocument())
79635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        execute(static_cast<Document*>(context));
80635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(WORKERS)
81635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    else {
82635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        ASSERT(context->isWorkerContext());
83635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        execute(static_cast<WorkerContext*>(context));
84635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
85635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#else
86635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ASSERT(context->isDocument());
87635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif
88635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
89635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
90e78cbe89e6f337f2f1fe40315be88f742b547151Steve Blockvoid ScheduledAction::executeFunctionInContext(JSGlobalObject* globalObject, JSValue thisValue, ScriptExecutionContext* context)
91635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
92635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ASSERT(m_function);
930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    JSLock lock(SilenceAssertionsOnly);
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
95635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    CallData callData;
96545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    CallType callType = getCallData(m_function.get(), callData);
97635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (callType == CallTypeNone)
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
100635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ExecState* exec = globalObject->globalExec();
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    MarkedArgumentBuffer args;
103635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    size_t size = m_args.size();
104635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (size_t i = 0; i < size; ++i)
10581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        args.append(m_args[i].get());
106635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
107e14391e94c850b8bd03680c23b38978db68687a8John Reck    globalObject->globalData().timeoutChecker.start();
108e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (context->isDocument())
10981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        JSMainThreadExecState::call(exec, m_function.get(), callType, callData, thisValue, args);
110e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    else
11181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        JSC::call(exec, m_function.get(), callType, callData, thisValue, args);
112e14391e94c850b8bd03680c23b38978db68687a8John Reck    globalObject->globalData().timeoutChecker.stop();
113635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
114635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (exec->hadException())
115635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        reportCurrentException(exec);
116635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
117635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
118635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ScheduledAction::execute(Document* document)
119635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
120cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    JSDOMWindow* window = toJSDOMWindow(document->frame(), m_isolatedWorld.get());
121635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!window)
122635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
123635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
124635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RefPtr<Frame> frame = window->impl()->frame();
125dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!frame || !frame->script()->canExecuteScripts(AboutToExecuteScript))
126635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
127635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
128635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    frame->script()->setProcessingTimerCallback(true);
129635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (m_function) {
131e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        executeFunctionInContext(window, window->shell(), document);
1325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        Document::updateStyleForAllDocuments();
1335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    } else
134643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        frame->script()->executeScriptInWorld(m_isolatedWorld.get(), m_code);
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    frame->script()->setProcessingTimerCallback(false);
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if ENABLE(WORKERS)
1405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid ScheduledAction::execute(WorkerContext* workerContext)
1415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
1425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // In a Worker, the execution should always happen on a worker thread.
1435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(workerContext->thread()->threadID() == currentThread());
1445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    WorkerScriptController* scriptController = workerContext->script();
1465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (m_function) {
1485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        JSWorkerContext* contextWrapper = scriptController->workerContextWrapper();
149e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        executeFunctionInContext(contextWrapper, contextWrapper, workerContext);
1505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    } else {
1515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ScriptSourceCode code(m_code, workerContext->url());
1525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        scriptController->evaluate(code);
1535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
1545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
1555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif // ENABLE(WORKERS)
1565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
158