Home | History | Annotate | Download | only in js
      1 /*
      2  * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
      3  * Copyright (c) 2011 Google Inc. All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *
      9  * 1.  Redistributions of source code must retain the above copyright
     10  *     notice, this list of conditions and the following disclaimer.
     11  * 2.  Redistributions in binary form must reproduce the above copyright
     12  *     notice, this list of conditions and the following disclaimer in the
     13  *     documentation and/or other materials provided with the distribution.
     14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     15  *     its contributors may be used to endorse or promote products derived
     16  *     from this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 #include "config.h"
     31 #include "ScriptValue.h"
     32 
     33 #include "InspectorValues.h"
     34 #include "SerializedScriptValue.h"
     35 
     36 #include <JavaScriptCore/APICast.h>
     37 #include <JavaScriptCore/JSValueRef.h>
     38 
     39 #include <heap/Strong.h>
     40 #include <runtime/JSLock.h>
     41 #include <runtime/UString.h>
     42 
     43 using namespace JSC;
     44 
     45 namespace WebCore {
     46 
     47 bool ScriptValue::getString(ScriptState* scriptState, String& result) const
     48 {
     49     if (!m_value)
     50         return false;
     51     JSLock lock(SilenceAssertionsOnly);
     52     UString ustring;
     53     if (!m_value.get().getString(scriptState, ustring))
     54         return false;
     55     result = ustringToString(ustring);
     56     return true;
     57 }
     58 
     59 String ScriptValue::toString(ScriptState* scriptState) const
     60 {
     61     String result = ustringToString(m_value.get().toString(scriptState));
     62     // Handle the case where an exception is thrown as part of invoking toString on the object.
     63     if (scriptState->hadException())
     64         scriptState->clearException();
     65     return result;
     66 }
     67 
     68 bool ScriptValue::isEqual(ScriptState* scriptState, const ScriptValue& anotherValue) const
     69 {
     70     if (hasNoValue())
     71         return anotherValue.hasNoValue();
     72 
     73     return JSValueIsEqual(toRef(scriptState), toRef(scriptState, jsValue()), toRef(scriptState, anotherValue.jsValue()), 0);
     74 }
     75 
     76 bool ScriptValue::isNull() const
     77 {
     78     if (!m_value)
     79         return false;
     80     return m_value.get().isNull();
     81 }
     82 
     83 bool ScriptValue::isUndefined() const
     84 {
     85     if (!m_value)
     86         return false;
     87     return m_value.get().isUndefined();
     88 }
     89 
     90 bool ScriptValue::isObject() const
     91 {
     92     if (!m_value)
     93         return false;
     94     return m_value.get().isObject();
     95 }
     96 
     97 bool ScriptValue::isFunction() const
     98 {
     99     CallData callData;
    100     return getCallData(m_value.get(), callData) != CallTypeNone;
    101 }
    102 
    103 PassRefPtr<SerializedScriptValue> ScriptValue::serialize(ScriptState* scriptState, SerializationErrorMode throwExceptions)
    104 {
    105     return SerializedScriptValue::create(scriptState, jsValue(), throwExceptions);
    106 }
    107 
    108 ScriptValue ScriptValue::deserialize(ScriptState* scriptState, SerializedScriptValue* value, SerializationErrorMode throwExceptions)
    109 {
    110     return ScriptValue(scriptState->globalData(), value->deserialize(scriptState, scriptState->lexicalGlobalObject(), throwExceptions));
    111 }
    112 
    113 #if ENABLE(INSPECTOR)
    114 static PassRefPtr<InspectorValue> jsToInspectorValue(ScriptState* scriptState, JSValue value)
    115 {
    116     if (!value) {
    117         ASSERT_NOT_REACHED();
    118         return 0;
    119     }
    120     if (value.isNull() || value.isUndefined())
    121         return InspectorValue::null();
    122     if (value.isBoolean())
    123         return InspectorBasicValue::create(value.getBoolean());
    124     if (value.isNumber())
    125         return InspectorBasicValue::create(value.uncheckedGetNumber());
    126     if (value.isString()) {
    127         UString s = value.getString(scriptState);
    128         return InspectorString::create(String(s.characters(), s.length()));
    129     }
    130     if (value.isObject()) {
    131         if (isJSArray(&scriptState->globalData(), value)) {
    132             RefPtr<InspectorArray> inspectorArray = InspectorArray::create();
    133             JSArray* array = asArray(value);
    134             unsigned length = array->length();
    135             for (unsigned i = 0; i < length; i++) {
    136                 JSValue element = array->getIndex(i);
    137                 RefPtr<InspectorValue> elementValue = jsToInspectorValue(scriptState, element);
    138                 if (!elementValue) {
    139                     ASSERT_NOT_REACHED();
    140                     elementValue = InspectorValue::null();
    141                 }
    142                 inspectorArray->pushValue(elementValue);
    143             }
    144             return inspectorArray;
    145         }
    146         RefPtr<InspectorObject> inspectorObject = InspectorObject::create();
    147         JSObject* object = value.getObject();
    148         PropertyNameArray propertyNames(scriptState);
    149         object->getOwnPropertyNames(scriptState, propertyNames);
    150         for (size_t i = 0; i < propertyNames.size(); i++) {
    151             const Identifier& name =  propertyNames[i];
    152             JSValue propertyValue = object->get(scriptState, name);
    153             RefPtr<InspectorValue> inspectorValue = jsToInspectorValue(scriptState, propertyValue);
    154             if (!inspectorValue) {
    155                 ASSERT_NOT_REACHED();
    156                 inspectorValue = InspectorValue::null();
    157             }
    158             inspectorObject->setValue(String(name.characters(), name.length()), inspectorValue);
    159         }
    160         return inspectorObject;
    161     }
    162     ASSERT_NOT_REACHED();
    163     return 0;
    164 }
    165 
    166 PassRefPtr<InspectorValue> ScriptValue::toInspectorValue(ScriptState* scriptState) const
    167 {
    168     return jsToInspectorValue(scriptState, m_value.get());
    169 }
    170 #endif // ENABLE(INSPECTOR)
    171 
    172 } // namespace WebCore
    173