Home | History | Annotate | Download | only in v8
      1 /*
      2  * Copyright (C) 2009 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "bindings/v8/ScriptFunctionCall.h"
     33 
     34 #include "bindings/v8/ScriptController.h"
     35 #include "bindings/v8/ScriptScope.h"
     36 #include "bindings/v8/ScriptState.h"
     37 #include "bindings/v8/ScriptValue.h"
     38 #include "bindings/v8/V8Binding.h"
     39 #include "bindings/v8/V8ObjectConstructor.h"
     40 #include "bindings/v8/V8ScriptRunner.h"
     41 #include "bindings/v8/V8Utilities.h"
     42 
     43 #include <v8.h>
     44 #include "wtf/OwnArrayPtr.h"
     45 
     46 namespace WebCore {
     47 
     48 void ScriptCallArgumentHandler::appendArgument(const ScriptObject& argument)
     49 {
     50     if (argument.scriptState() != m_scriptState) {
     51         ASSERT_NOT_REACHED();
     52         return;
     53     }
     54     m_arguments.append(argument);
     55 }
     56 
     57 void ScriptCallArgumentHandler::appendArgument(const ScriptValue& argument)
     58 {
     59     m_arguments.append(argument);
     60 }
     61 
     62 void ScriptCallArgumentHandler::appendArgument(const String& argument)
     63 {
     64     ScriptScope scope(m_scriptState);
     65     m_arguments.append(v8String(argument, m_scriptState->isolate()));
     66 }
     67 
     68 void ScriptCallArgumentHandler::appendArgument(const char* argument)
     69 {
     70     ScriptScope scope(m_scriptState);
     71     m_arguments.append(v8String(argument, m_scriptState->isolate()));
     72 }
     73 
     74 void ScriptCallArgumentHandler::appendArgument(long argument)
     75 {
     76     ScriptScope scope(m_scriptState);
     77     m_arguments.append(v8::Number::New(argument));
     78 }
     79 
     80 void ScriptCallArgumentHandler::appendArgument(long long argument)
     81 {
     82     ScriptScope scope(m_scriptState);
     83     m_arguments.append(v8::Number::New(argument));
     84 }
     85 
     86 void ScriptCallArgumentHandler::appendArgument(unsigned int argument)
     87 {
     88     ScriptScope scope(m_scriptState);
     89     m_arguments.append(v8::Number::New(argument));
     90 }
     91 
     92 void ScriptCallArgumentHandler::appendArgument(unsigned long argument)
     93 {
     94     ScriptScope scope(m_scriptState);
     95     m_arguments.append(v8::Number::New(argument));
     96 }
     97 
     98 void ScriptCallArgumentHandler::appendArgument(int argument)
     99 {
    100     ScriptScope scope(m_scriptState);
    101     m_arguments.append(v8::Number::New(argument));
    102 }
    103 
    104 void ScriptCallArgumentHandler::appendArgument(bool argument)
    105 {
    106     m_arguments.append(v8Boolean(argument));
    107 }
    108 
    109 ScriptFunctionCall::ScriptFunctionCall(const ScriptObject& thisObject, const String& name)
    110     : ScriptCallArgumentHandler(thisObject.scriptState())
    111     , m_thisObject(thisObject)
    112     , m_name(name)
    113 {
    114 }
    115 
    116 ScriptValue ScriptFunctionCall::call(bool& hadException, bool reportExceptions)
    117 {
    118     ScriptScope scope(m_scriptState, reportExceptions);
    119 
    120     v8::Handle<v8::Object> thisObject = m_thisObject.v8Object();
    121     v8::Local<v8::Value> value = thisObject->Get(v8String(m_name, m_scriptState->isolate()));
    122     if (!scope.success()) {
    123         hadException = true;
    124         return ScriptValue();
    125     }
    126 
    127     ASSERT(value->IsFunction());
    128 
    129     v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(value);
    130     OwnArrayPtr<v8::Handle<v8::Value> > args = adoptArrayPtr(new v8::Handle<v8::Value>[m_arguments.size()]);
    131     for (size_t i = 0; i < m_arguments.size(); ++i) {
    132         args[i] = m_arguments[i].v8Value();
    133         ASSERT(!args[i].IsEmpty());
    134     }
    135 
    136     v8::Local<v8::Value> result = V8ScriptRunner::callFunction(function, getScriptExecutionContext(), thisObject, m_arguments.size(), args.get());
    137     if (!scope.success()) {
    138         hadException = true;
    139         return ScriptValue();
    140     }
    141 
    142     return ScriptValue(result);
    143 }
    144 
    145 ScriptValue ScriptFunctionCall::call()
    146 {
    147     bool hadException = false;
    148     return call(hadException);
    149 }
    150 
    151 ScriptObject ScriptFunctionCall::construct(bool& hadException, bool reportExceptions)
    152 {
    153     ScriptScope scope(m_scriptState, reportExceptions);
    154 
    155     v8::Handle<v8::Object> thisObject = m_thisObject.v8Object();
    156     v8::Local<v8::Value> value = thisObject->Get(v8String(m_name, m_scriptState->isolate()));
    157     if (!scope.success()) {
    158         hadException = true;
    159         return ScriptObject();
    160     }
    161 
    162     ASSERT(value->IsFunction());
    163 
    164     v8::Local<v8::Function> constructor = v8::Local<v8::Function>::Cast(value);
    165     OwnArrayPtr<v8::Handle<v8::Value> > args = adoptArrayPtr(new v8::Handle<v8::Value>[m_arguments.size()]);
    166     for (size_t i = 0; i < m_arguments.size(); ++i)
    167         args[i] = m_arguments[i].v8Value();
    168 
    169     v8::Local<v8::Object> result = V8ObjectConstructor::newInstance(constructor, m_arguments.size(), args.get());
    170     if (!scope.success()) {
    171         hadException = true;
    172         return ScriptObject();
    173     }
    174 
    175     return ScriptObject(m_scriptState, result);
    176 }
    177 
    178 ScriptCallback::ScriptCallback(ScriptState* state, const ScriptValue& function)
    179     : ScriptCallArgumentHandler(state)
    180     , m_function(function)
    181 {
    182 }
    183 
    184 ScriptValue ScriptCallback::call()
    185 {
    186     ASSERT(v8::Context::InContext());
    187     ASSERT(m_function.v8Value()->IsFunction());
    188 
    189     v8::TryCatch exceptionCatcher;
    190     exceptionCatcher.SetVerbose(true);
    191     v8::Handle<v8::Object> object = v8::Context::GetCurrent()->Global();
    192     v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(m_function.v8Value());
    193 
    194     OwnArrayPtr<v8::Handle<v8::Value> > args = adoptArrayPtr(new v8::Handle<v8::Value>[m_arguments.size()]);
    195     for (size_t i = 0; i < m_arguments.size(); ++i)
    196         args[i] = m_arguments[i].v8Value();
    197 
    198     v8::Handle<v8::Value> result = ScriptController::callFunctionWithInstrumentation(0, function, object, m_arguments.size(), args.get());
    199     return ScriptValue(result);
    200 }
    201 
    202 } // namespace WebCore
    203