Home | History | Annotate | Download | only in js
      1 /*
      2  *  Copyright (C) 2000 Harri Porten (porten (at) kde.org)
      3  *  Copyright (C) 2006 Jon Shier (jshier (at) iastate.edu)
      4  *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reseved.
      5  *  Copyright (C) 2006 Alexey Proskuryakov (ap (at) webkit.org)
      6  *  Copyright (C) 2009 Google Inc. All rights reseved.
      7  *
      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 
     27 #include "CString.h"
     28 #include "DOMWindow.h"
     29 #include "Document.h"
     30 #include "Frame.h"
     31 #include "FrameLoader.h"
     32 #include "JSDOMBinding.h"
     33 #include "JSDOMWindow.h"
     34 #include "ScriptController.h"
     35 #include "ScriptExecutionContext.h"
     36 #include "ScriptSourceCode.h"
     37 #include "ScriptValue.h"
     38 #include <runtime/JSLock.h>
     39 
     40 #if ENABLE(WORKERS)
     41 #include "JSWorkerContext.h"
     42 #include "WorkerContext.h"
     43 #include "WorkerThread.h"
     44 #endif
     45 
     46 using namespace JSC;
     47 
     48 namespace WebCore {
     49 
     50 ScheduledAction* ScheduledAction::create(ExecState* exec, const ArgList& args, DOMWrapperWorld* isolatedWorld)
     51 {
     52     JSValue v = args.at(0);
     53     CallData callData;
     54     if (v.getCallData(callData) == CallTypeNone) {
     55         UString string = v.toString(exec);
     56         if (exec->hadException())
     57             return 0;
     58         return new ScheduledAction(string, isolatedWorld);
     59     }
     60     ArgList argsTail;
     61     args.getSlice(2, argsTail);
     62     return new ScheduledAction(v, argsTail, isolatedWorld);
     63 }
     64 
     65 ScheduledAction::ScheduledAction(JSValue function, const ArgList& args, DOMWrapperWorld* isolatedWorld)
     66     : m_function(function)
     67     , m_isolatedWorld(isolatedWorld)
     68 {
     69     ArgList::const_iterator end = args.end();
     70     for (ArgList::const_iterator it = args.begin(); it != end; ++it)
     71         m_args.append(*it);
     72 }
     73 
     74 void ScheduledAction::execute(ScriptExecutionContext* context)
     75 {
     76     if (context->isDocument())
     77         execute(static_cast<Document*>(context));
     78 #if ENABLE(WORKERS)
     79     else {
     80         ASSERT(context->isWorkerContext());
     81         execute(static_cast<WorkerContext*>(context));
     82     }
     83 #else
     84     ASSERT(context->isDocument());
     85 #endif
     86 }
     87 
     88 void ScheduledAction::executeFunctionInContext(JSGlobalObject* globalObject, JSValue thisValue)
     89 {
     90     ASSERT(m_function);
     91     JSLock lock(SilenceAssertionsOnly);
     92 
     93     CallData callData;
     94     CallType callType = m_function.get().getCallData(callData);
     95     if (callType == CallTypeNone)
     96         return;
     97 
     98     ExecState* exec = globalObject->globalExec();
     99 
    100     MarkedArgumentBuffer args;
    101     size_t size = m_args.size();
    102     for (size_t i = 0; i < size; ++i)
    103         args.append(m_args[i]);
    104 
    105     globalObject->globalData()->timeoutChecker.start();
    106     JSC::call(exec, m_function, callType, callData, thisValue, args);
    107     globalObject->globalData()->timeoutChecker.stop();
    108 
    109     if (exec->hadException())
    110         reportCurrentException(exec);
    111 }
    112 
    113 void ScheduledAction::execute(Document* document)
    114 {
    115     JSDOMWindow* window = toJSDOMWindow(document->frame(), m_isolatedWorld.get());
    116     if (!window)
    117         return;
    118 
    119     RefPtr<Frame> frame = window->impl()->frame();
    120     if (!frame || !frame->script()->canExecuteScripts())
    121         return;
    122 
    123     frame->script()->setProcessingTimerCallback(true);
    124 
    125     if (m_function) {
    126         executeFunctionInContext(window, window->shell());
    127         Document::updateStyleForAllDocuments();
    128     } else
    129         frame->script()->executeScriptInWorld(m_isolatedWorld.get(), m_code);
    130 
    131     frame->script()->setProcessingTimerCallback(false);
    132 }
    133 
    134 #if ENABLE(WORKERS)
    135 void ScheduledAction::execute(WorkerContext* workerContext)
    136 {
    137     // In a Worker, the execution should always happen on a worker thread.
    138     ASSERT(workerContext->thread()->threadID() == currentThread());
    139 
    140     WorkerScriptController* scriptController = workerContext->script();
    141 
    142     if (m_function) {
    143         JSWorkerContext* contextWrapper = scriptController->workerContextWrapper();
    144         executeFunctionInContext(contextWrapper, contextWrapper);
    145     } else {
    146         ScriptSourceCode code(m_code, workerContext->url());
    147         scriptController->evaluate(code);
    148     }
    149 }
    150 #endif // ENABLE(WORKERS)
    151 
    152 } // namespace WebCore
    153