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