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 "ScriptFunctionCall.h"
     33 
     34 #include "ScriptScope.h"
     35 #include "ScriptState.h"
     36 #include "ScriptValue.h"
     37 
     38 #include "V8Binding.h"
     39 #include "V8Proxy.h"
     40 #include "V8Utilities.h"
     41 
     42 #include <v8.h>
     43 #include <wtf/OwnArrayPtr.h>
     44 
     45 namespace WebCore {
     46 
     47 void ScriptCallArgumentHandler::appendArgument(const ScriptObject& argument)
     48 {
     49     if (argument.scriptState() != m_scriptState) {
     50         ASSERT_NOT_REACHED();
     51         return;
     52     }
     53     m_arguments.append(argument);
     54 }
     55 
     56 void ScriptCallArgumentHandler::appendArgument(const ScriptValue& argument)
     57 {
     58     m_arguments.append(argument);
     59 }
     60 
     61 void ScriptCallArgumentHandler::appendArgument(const String& argument)
     62 {
     63     ScriptScope scope(m_scriptState);
     64     m_arguments.append(v8String(argument));
     65 }
     66 
     67 void ScriptCallArgumentHandler::appendArgument(const char* argument)
     68 {
     69     ScriptScope scope(m_scriptState);
     70     m_arguments.append(v8String(argument));
     71 }
     72 
     73 void ScriptCallArgumentHandler::appendArgument(long argument)
     74 {
     75     ScriptScope scope(m_scriptState);
     76     m_arguments.append(v8::Number::New(argument));
     77 }
     78 
     79 void ScriptCallArgumentHandler::appendArgument(long long argument)
     80 {
     81     ScriptScope scope(m_scriptState);
     82     m_arguments.append(v8::Number::New(argument));
     83 }
     84 
     85 void ScriptCallArgumentHandler::appendArgument(unsigned int argument)
     86 {
     87     ScriptScope scope(m_scriptState);
     88     m_arguments.append(v8::Number::New(argument));
     89 }
     90 
     91 void ScriptCallArgumentHandler::appendArgument(unsigned long argument)
     92 {
     93     ScriptScope scope(m_scriptState);
     94     m_arguments.append(v8::Number::New(argument));
     95 }
     96 
     97 void ScriptCallArgumentHandler::appendArgument(int argument)
     98 {
     99     ScriptScope scope(m_scriptState);
    100     m_arguments.append(v8::Number::New(argument));
    101 }
    102 
    103 void ScriptCallArgumentHandler::appendArgument(bool argument)
    104 {
    105     m_arguments.append(v8Boolean(argument));
    106 }
    107 
    108 ScriptFunctionCall::ScriptFunctionCall(const ScriptObject& thisObject, const String& name)
    109     : ScriptCallArgumentHandler(thisObject.scriptState())
    110     , m_thisObject(thisObject)
    111     , m_name(name)
    112 {
    113 }
    114 
    115 ScriptValue ScriptFunctionCall::call(bool& hadException, bool reportExceptions)
    116 {
    117     ScriptScope scope(m_scriptState, reportExceptions);
    118 
    119     v8::Local<v8::Object> thisObject = m_thisObject.v8Object();
    120     v8::Local<v8::Value> value = thisObject->Get(v8String(m_name));
    121     if (!scope.success()) {
    122         hadException = true;
    123         return ScriptValue();
    124     }
    125 
    126     ASSERT(value->IsFunction());
    127 
    128     v8::Local<v8::Function> function(v8::Function::Cast(*value));
    129     OwnArrayPtr<v8::Handle<v8::Value> > args = adoptArrayPtr(new v8::Handle<v8::Value>[m_arguments.size()]);
    130     for (size_t i = 0; i < m_arguments.size(); ++i)
    131         args[i] = m_arguments[i].v8Value();
    132 
    133     v8::Local<v8::Value> result = function->Call(thisObject, m_arguments.size(), args.get());
    134     if (!scope.success()) {
    135         hadException = true;
    136         return ScriptValue();
    137     }
    138 
    139     return ScriptValue(result);
    140 }
    141 
    142 ScriptValue ScriptFunctionCall::call()
    143 {
    144     bool hadException = false;
    145     return call(hadException);
    146 }
    147 
    148 ScriptObject ScriptFunctionCall::construct(bool& hadException, bool reportExceptions)
    149 {
    150     ScriptScope scope(m_scriptState, reportExceptions);
    151 
    152     v8::Local<v8::Object> thisObject = m_thisObject.v8Object();
    153     v8::Local<v8::Value> value = thisObject->Get(v8String(m_name));
    154     if (!scope.success()) {
    155         hadException = true;
    156         return ScriptObject();
    157     }
    158 
    159     ASSERT(value->IsFunction());
    160 
    161     v8::Local<v8::Function> constructor(v8::Function::Cast(*value));
    162     OwnArrayPtr<v8::Handle<v8::Value> > args = adoptArrayPtr(new v8::Handle<v8::Value>[m_arguments.size()]);
    163     for (size_t i = 0; i < m_arguments.size(); ++i)
    164         args[i] = m_arguments[i].v8Value();
    165 
    166     v8::Local<v8::Object> result = SafeAllocation::newInstance(constructor, m_arguments.size(), args.get());
    167     if (!scope.success()) {
    168         hadException = true;
    169         return ScriptObject();
    170     }
    171 
    172     return ScriptObject(m_scriptState, result);
    173 }
    174 
    175 ScriptCallback::ScriptCallback(ScriptState* state, ScriptValue function)
    176     : ScriptCallArgumentHandler(state)
    177     , m_function(function)
    178 {
    179 }
    180 
    181 ScriptValue ScriptCallback::call()
    182 {
    183     bool hadException = false;
    184     return call(hadException);
    185 }
    186 
    187 ScriptValue ScriptCallback::call(bool& hadException)
    188 {
    189     ASSERT(v8::Context::InContext());
    190     ASSERT(m_function.v8Value()->IsFunction());
    191 
    192     v8::TryCatch exceptionCatcher;
    193     v8::Handle<v8::Object> object = v8::Context::GetCurrent()->Global();
    194     v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(m_function.v8Value());
    195 
    196     OwnArrayPtr<v8::Handle<v8::Value> > args = adoptArrayPtr(new v8::Handle<v8::Value>[m_arguments.size()]);
    197     for (size_t i = 0; i < m_arguments.size(); ++i)
    198         args[i] = m_arguments[i].v8Value();
    199 
    200     v8::Handle<v8::Value> result = V8Proxy::callFunctionWithoutFrame(function, object, m_arguments.size(), args.get());
    201 
    202     if (exceptionCatcher.HasCaught()) {
    203         hadException = true;
    204         m_scriptState->setException(exceptionCatcher.Exception());
    205         return ScriptValue();
    206     }
    207 
    208     return ScriptValue(result);
    209 }
    210 
    211 } // namespace WebCore
    212