blob: 06c51ca7b21766e934033dbef41527f3954a2b28 [file] [log] [blame]
weinig@apple.com007f8302007-12-17 04:50:53 +00001/*
2 * Copyright (C) 2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2006 Jon Shier (jshier@iastate.edu)
weinig@apple.com6da3b702009-04-28 20:30:52 +00004 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reseved.
weinig@apple.com007f8302007-12-17 04:50:53 +00005 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
ap@webkit.orgc1ff8e52009-01-11 08:06:58 +00006 * Copyright (C) 2009 Google Inc. All rights reseved.
weinig@apple.com007f8302007-12-17 04:50:53 +00007 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 * USA
22 */
23
24#include "config.h"
25#include "ScheduledAction.h"
26
abarth@webkit.orga51b9992011-04-16 02:33:08 +000027#include "ContentSecurityPolicy.h"
weinig@apple.com007f8302007-12-17 04:50:53 +000028#include "DOMWindow.h"
29#include "Document.h"
30#include "Frame.h"
31#include "FrameLoader.h"
ap@webkit.orge9b6b592008-11-19 17:42:39 +000032#include "JSDOMBinding.h"
weinig@apple.com5f38e1a2008-03-04 03:08:30 +000033#include "JSDOMWindow.h"
yaar@chromium.org37eb4772010-05-20 21:56:45 +000034#include "JSMainThreadExecState.h"
akling@apple.com4d3b9892013-09-06 22:08:14 +000035#include "JSMainThreadExecStateInstrumentation.h"
commit-queue@webkit.orgf0eff202013-11-22 05:01:46 +000036#include "JSWorkerGlobalScope.h"
darin@apple.com92aaa2a2008-06-15 07:00:11 +000037#include "ScriptController.h"
ap@webkit.org3b2f2c32008-12-28 10:05:59 +000038#include "ScriptExecutionContext.h"
ap@webkit.orgc1ff8e52009-01-11 08:06:58 +000039#include "ScriptSourceCode.h"
weinig@apple.com771c7a22011-05-01 23:56:41 +000040#include "ScriptValue.h"
ch.dumez@sisa.samsung.com14792a62013-06-27 06:21:54 +000041#include "WorkerGlobalScope.h"
ap@webkit.orgc1ff8e52009-01-11 08:06:58 +000042#include "WorkerThread.h"
commit-queue@webkit.orgf0eff202013-11-22 05:01:46 +000043#include <runtime/JSLock.h>
weinig@apple.com007f8302007-12-17 04:50:53 +000044
cwzwarich@webkit.org3f782f62008-09-08 01:28:33 +000045using namespace JSC;
weinig@apple.com007f8302007-12-17 04:50:53 +000046
47namespace WebCore {
48
weinig@apple.com8f716032013-10-02 17:03:09 +000049PassOwnPtr<ScheduledAction> ScheduledAction::create(ExecState* exec, DOMWrapperWorld& isolatedWorld, ContentSecurityPolicy* policy)
weinig@apple.com6da3b702009-04-28 20:30:52 +000050{
ggaren@apple.comfea29f12010-05-29 06:33:05 +000051 JSValue v = exec->argument(0);
weinig@apple.com6da3b702009-04-28 20:30:52 +000052 CallData callData;
barraclough@apple.com99ff3432010-06-03 20:00:18 +000053 if (getCallData(v, callData) == CallTypeNone) {
mkwst@chromium.org109f7e72012-10-02 11:29:33 +000054 if (policy && !policy->allowEval(exec))
aroben@apple.com71e211b2011-05-03 13:54:58 +000055 return nullptr;
benjamin@webkit.orgcff06e42012-08-30 21:23:51 +000056 String string = v.toString(exec)->value(exec);
weinig@apple.combcd18832009-04-30 17:16:17 +000057 if (exec->hadException())
aroben@apple.com71e211b2011-05-03 13:54:58 +000058 return nullptr;
benjamin@webkit.orgcff06e42012-08-30 21:23:51 +000059 return adoptPtr(new ScheduledAction(string, isolatedWorld));
weinig@apple.combcd18832009-04-30 17:16:17 +000060 }
ggaren@apple.comfea29f12010-05-29 06:33:05 +000061
levin@chromium.org38484e02011-04-26 07:31:19 +000062 return adoptPtr(new ScheduledAction(exec, v, isolatedWorld));
weinig@apple.com6da3b702009-04-28 20:30:52 +000063}
64
weinig@apple.com8f716032013-10-02 17:03:09 +000065ScheduledAction::ScheduledAction(ExecState* exec, JSValue function, DOMWrapperWorld& isolatedWorld)
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000066 : m_function(exec->vm(), function)
weinig@apple.com8f716032013-10-02 17:03:09 +000067 , m_isolatedWorld(&isolatedWorld)
weinig@apple.com007f8302007-12-17 04:50:53 +000068{
ggaren@apple.comfea29f12010-05-29 06:33:05 +000069 // setTimeout(function, interval, arg0, arg1...).
70 // Start at 2 to skip function and interval.
71 for (size_t i = 2; i < exec->argumentCount(); ++i)
darin@apple.comd9b22132013-09-22 04:02:59 +000072 m_args.append(Strong<JSC::Unknown>(exec->vm(), exec->uncheckedArgument(i)));
weinig@apple.com007f8302007-12-17 04:50:53 +000073}
74
ap@webkit.org3b2f2c32008-12-28 10:05:59 +000075void ScheduledAction::execute(ScriptExecutionContext* context)
76{
ap@webkit.orgc1ff8e52009-01-11 08:06:58 +000077 if (context->isDocument())
inferno@chromium.org8da49f12013-03-13 20:29:08 +000078 execute(toDocument(context));
ap@webkit.orgc1ff8e52009-01-11 08:06:58 +000079 else {
akling@apple.com670fea12013-10-12 18:16:42 +000080 ASSERT_WITH_SECURITY_IMPLICATION(context->isWorkerGlobalScope());
ch.dumez@sisa.samsung.com14792a62013-06-27 06:21:54 +000081 execute(static_cast<WorkerGlobalScope*>(context));
ap@webkit.orgc1ff8e52009-01-11 08:06:58 +000082 }
ap@webkit.org3b2f2c32008-12-28 10:05:59 +000083}
84
yaar@chromium.org37eb4772010-05-20 21:56:45 +000085void ScheduledAction::executeFunctionInContext(JSGlobalObject* globalObject, JSValue thisValue, ScriptExecutionContext* context)
weinig@apple.com007f8302007-12-17 04:50:53 +000086{
ap@webkit.orgc1ff8e52009-01-11 08:06:58 +000087 ASSERT(m_function);
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000088 JSLockHolder lock(context->vm());
ap@webkit.orgc1ff8e52009-01-11 08:06:58 +000089
90 CallData callData;
barraclough@apple.com99ff3432010-06-03 20:00:18 +000091 CallType callType = getCallData(m_function.get(), callData);
ap@webkit.orgc1ff8e52009-01-11 08:06:58 +000092 if (callType == CallTypeNone)
weinig@apple.com007f8302007-12-17 04:50:53 +000093 return;
94
ap@webkit.orgc1ff8e52009-01-11 08:06:58 +000095 ExecState* exec = globalObject->globalExec();
96
oliver@apple.comf32186e2009-04-30 01:21:52 +000097 MarkedArgumentBuffer args;
ap@webkit.orgc1ff8e52009-01-11 08:06:58 +000098 size_t size = m_args.size();
99 for (size_t i = 0; i < size; ++i)
oliver@apple.com8d857052011-02-15 23:54:06 +0000100 args.append(m_args[i].get());
ap@webkit.orgc1ff8e52009-01-11 08:06:58 +0000101
timothy@apple.com7e721462012-05-11 23:40:47 +0000102 InspectorInstrumentationCookie cookie = JSMainThreadExecState::instrumentFunctionCall(context, callType, callData);
103
yaar@chromium.org37eb4772010-05-20 21:56:45 +0000104 if (context->isDocument())
oliver@apple.com8d857052011-02-15 23:54:06 +0000105 JSMainThreadExecState::call(exec, m_function.get(), callType, callData, thisValue, args);
yaar@chromium.org37eb4772010-05-20 21:56:45 +0000106 else
oliver@apple.com8d857052011-02-15 23:54:06 +0000107 JSC::call(exec, m_function.get(), callType, callData, thisValue, args);
timothy@apple.com7e721462012-05-11 23:40:47 +0000108
109 InspectorInstrumentation::didCallFunction(cookie);
ap@webkit.orgc1ff8e52009-01-11 08:06:58 +0000110
111 if (exec->hadException())
112 reportCurrentException(exec);
113}
114
ap@webkit.orgc1ff8e52009-01-11 08:06:58 +0000115void ScheduledAction::execute(Document* document)
116{
weinig@apple.com8f716032013-10-02 17:03:09 +0000117 JSDOMWindow* window = toJSDOMWindow(document->frame(), *m_isolatedWorld);
ap@webkit.orgc1ff8e52009-01-11 08:06:58 +0000118 if (!window)
119 return;
120
akling@apple.com51269d92013-10-10 12:01:51 +0000121 RefPtr<Frame> frame = window->impl().frame();
psolanki@apple.comc5b5dad2013-08-16 17:55:32 +0000122 if (!frame || !frame->script().canExecuteScripts(AboutToExecuteScript))
weinig@apple.com007f8302007-12-17 04:50:53 +0000123 return;
124
jamesr@google.com2b55f692012-01-26 22:24:10 +0000125 if (m_function)
yaar@chromium.org37eb4772010-05-20 21:56:45 +0000126 executeFunctionInContext(window, window->shell(), document);
jamesr@google.com2b55f692012-01-26 22:24:10 +0000127 else
weinig@apple.com8f716032013-10-02 17:03:09 +0000128 frame->script().executeScriptInWorld(*m_isolatedWorld, m_code);
weinig@apple.com007f8302007-12-17 04:50:53 +0000129}
130
ch.dumez@sisa.samsung.com14792a62013-06-27 06:21:54 +0000131void ScheduledAction::execute(WorkerGlobalScope* workerGlobalScope)
weinig@apple.com6da3b702009-04-28 20:30:52 +0000132{
133 // In a Worker, the execution should always happen on a worker thread.
ch.dumez@sisa.samsung.com14792a62013-06-27 06:21:54 +0000134 ASSERT(workerGlobalScope->thread()->threadID() == currentThread());
weinig@apple.com6da3b702009-04-28 20:30:52 +0000135
ch.dumez@sisa.samsung.com14792a62013-06-27 06:21:54 +0000136 WorkerScriptController* scriptController = workerGlobalScope->script();
weinig@apple.com6da3b702009-04-28 20:30:52 +0000137
138 if (m_function) {
ch.dumez@sisa.samsung.com14792a62013-06-27 06:21:54 +0000139 JSWorkerGlobalScope* contextWrapper = scriptController->workerGlobalScopeWrapper();
140 executeFunctionInContext(contextWrapper, contextWrapper, workerGlobalScope);
weinig@apple.com6da3b702009-04-28 20:30:52 +0000141 } else {
ch.dumez@sisa.samsung.com14792a62013-06-27 06:21:54 +0000142 ScriptSourceCode code(m_code, workerGlobalScope->url());
weinig@apple.com6da3b702009-04-28 20:30:52 +0000143 scriptController->evaluate(code);
144 }
145}
weinig@apple.com6da3b702009-04-28 20:30:52 +0000146
weinig@apple.com007f8302007-12-17 04:50:53 +0000147} // namespace WebCore