Home | History | Annotate | Download | only in API
      1 /*
      2  * Copyright (C) 2006, 2007 Apple 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
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "JSValueRef.h"
     28 
     29 #include <wtf/Platform.h>
     30 #include "APICast.h"
     31 #include "APIShims.h"
     32 #include "JSCallbackObject.h"
     33 
     34 #include <runtime/JSGlobalObject.h>
     35 #include <runtime/JSString.h>
     36 #include <runtime/Operations.h>
     37 #include <runtime/Protect.h>
     38 #include <runtime/UString.h>
     39 #include <runtime/JSValue.h>
     40 
     41 #include <wtf/Assertions.h>
     42 
     43 #include <algorithm> // for std::min
     44 
     45 using namespace JSC;
     46 
     47 ::JSType JSValueGetType(JSContextRef ctx, JSValueRef value)
     48 {
     49     ExecState* exec = toJS(ctx);
     50     APIEntryShim entryShim(exec);
     51 
     52     JSValue jsValue = toJS(exec, value);
     53 
     54     if (jsValue.isUndefined())
     55         return kJSTypeUndefined;
     56     if (jsValue.isNull())
     57         return kJSTypeNull;
     58     if (jsValue.isBoolean())
     59         return kJSTypeBoolean;
     60     if (jsValue.isNumber())
     61         return kJSTypeNumber;
     62     if (jsValue.isString())
     63         return kJSTypeString;
     64     ASSERT(jsValue.isObject());
     65     return kJSTypeObject;
     66 }
     67 
     68 bool JSValueIsUndefined(JSContextRef ctx, JSValueRef value)
     69 {
     70     ExecState* exec = toJS(ctx);
     71     APIEntryShim entryShim(exec);
     72 
     73     JSValue jsValue = toJS(exec, value);
     74     return jsValue.isUndefined();
     75 }
     76 
     77 bool JSValueIsNull(JSContextRef ctx, JSValueRef value)
     78 {
     79     ExecState* exec = toJS(ctx);
     80     APIEntryShim entryShim(exec);
     81 
     82     JSValue jsValue = toJS(exec, value);
     83     return jsValue.isNull();
     84 }
     85 
     86 bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value)
     87 {
     88     ExecState* exec = toJS(ctx);
     89     APIEntryShim entryShim(exec);
     90 
     91     JSValue jsValue = toJS(exec, value);
     92     return jsValue.isBoolean();
     93 }
     94 
     95 bool JSValueIsNumber(JSContextRef ctx, JSValueRef value)
     96 {
     97     ExecState* exec = toJS(ctx);
     98     APIEntryShim entryShim(exec);
     99 
    100     JSValue jsValue = toJS(exec, value);
    101     return jsValue.isNumber();
    102 }
    103 
    104 bool JSValueIsString(JSContextRef ctx, JSValueRef value)
    105 {
    106     ExecState* exec = toJS(ctx);
    107     APIEntryShim entryShim(exec);
    108 
    109     JSValue jsValue = toJS(exec, value);
    110     return jsValue.isString();
    111 }
    112 
    113 bool JSValueIsObject(JSContextRef ctx, JSValueRef value)
    114 {
    115     ExecState* exec = toJS(ctx);
    116     APIEntryShim entryShim(exec);
    117 
    118     JSValue jsValue = toJS(exec, value);
    119     return jsValue.isObject();
    120 }
    121 
    122 bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass)
    123 {
    124     ExecState* exec = toJS(ctx);
    125     APIEntryShim entryShim(exec);
    126 
    127     JSValue jsValue = toJS(exec, value);
    128 
    129     if (JSObject* o = jsValue.getObject()) {
    130         if (o->inherits(&JSCallbackObject<JSGlobalObject>::info))
    131             return static_cast<JSCallbackObject<JSGlobalObject>*>(o)->inherits(jsClass);
    132         else if (o->inherits(&JSCallbackObject<JSObject>::info))
    133             return static_cast<JSCallbackObject<JSObject>*>(o)->inherits(jsClass);
    134     }
    135     return false;
    136 }
    137 
    138 bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* exception)
    139 {
    140     ExecState* exec = toJS(ctx);
    141     APIEntryShim entryShim(exec);
    142 
    143     JSValue jsA = toJS(exec, a);
    144     JSValue jsB = toJS(exec, b);
    145 
    146     bool result = JSValue::equal(exec, jsA, jsB); // false if an exception is thrown
    147     if (exec->hadException()) {
    148         if (exception)
    149             *exception = toRef(exec, exec->exception());
    150         exec->clearException();
    151     }
    152     return result;
    153 }
    154 
    155 bool JSValueIsStrictEqual(JSContextRef ctx, JSValueRef a, JSValueRef b)
    156 {
    157     ExecState* exec = toJS(ctx);
    158     APIEntryShim entryShim(exec);
    159 
    160     JSValue jsA = toJS(exec, a);
    161     JSValue jsB = toJS(exec, b);
    162 
    163     return JSValue::strictEqual(exec, jsA, jsB);
    164 }
    165 
    166 bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObjectRef constructor, JSValueRef* exception)
    167 {
    168     ExecState* exec = toJS(ctx);
    169     APIEntryShim entryShim(exec);
    170 
    171     JSValue jsValue = toJS(exec, value);
    172 
    173     JSObject* jsConstructor = toJS(constructor);
    174     if (!jsConstructor->structure()->typeInfo().implementsHasInstance())
    175         return false;
    176     bool result = jsConstructor->hasInstance(exec, jsValue, jsConstructor->get(exec, exec->propertyNames().prototype)); // false if an exception is thrown
    177     if (exec->hadException()) {
    178         if (exception)
    179             *exception = toRef(exec, exec->exception());
    180         exec->clearException();
    181     }
    182     return result;
    183 }
    184 
    185 JSValueRef JSValueMakeUndefined(JSContextRef ctx)
    186 {
    187     ExecState* exec = toJS(ctx);
    188     APIEntryShim entryShim(exec);
    189 
    190     return toRef(exec, jsUndefined());
    191 }
    192 
    193 JSValueRef JSValueMakeNull(JSContextRef ctx)
    194 {
    195     ExecState* exec = toJS(ctx);
    196     APIEntryShim entryShim(exec);
    197 
    198     return toRef(exec, jsNull());
    199 }
    200 
    201 JSValueRef JSValueMakeBoolean(JSContextRef ctx, bool value)
    202 {
    203     ExecState* exec = toJS(ctx);
    204     APIEntryShim entryShim(exec);
    205 
    206     return toRef(exec, jsBoolean(value));
    207 }
    208 
    209 JSValueRef JSValueMakeNumber(JSContextRef ctx, double value)
    210 {
    211     ExecState* exec = toJS(ctx);
    212     APIEntryShim entryShim(exec);
    213 
    214     return toRef(exec, jsNumber(exec, value));
    215 }
    216 
    217 JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
    218 {
    219     ExecState* exec = toJS(ctx);
    220     APIEntryShim entryShim(exec);
    221 
    222     return toRef(exec, jsString(exec, string->ustring()));
    223 }
    224 
    225 bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
    226 {
    227     ExecState* exec = toJS(ctx);
    228     APIEntryShim entryShim(exec);
    229 
    230     JSValue jsValue = toJS(exec, value);
    231     return jsValue.toBoolean(exec);
    232 }
    233 
    234 double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
    235 {
    236     ExecState* exec = toJS(ctx);
    237     APIEntryShim entryShim(exec);
    238 
    239     JSValue jsValue = toJS(exec, value);
    240 
    241     double number = jsValue.toNumber(exec);
    242     if (exec->hadException()) {
    243         if (exception)
    244             *exception = toRef(exec, exec->exception());
    245         exec->clearException();
    246         number = NaN;
    247     }
    248     return number;
    249 }
    250 
    251 JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
    252 {
    253     ExecState* exec = toJS(ctx);
    254     APIEntryShim entryShim(exec);
    255 
    256     JSValue jsValue = toJS(exec, value);
    257 
    258     RefPtr<OpaqueJSString> stringRef(OpaqueJSString::create(jsValue.toString(exec)));
    259     if (exec->hadException()) {
    260         if (exception)
    261             *exception = toRef(exec, exec->exception());
    262         exec->clearException();
    263         stringRef.clear();
    264     }
    265     return stringRef.release().releaseRef();
    266 }
    267 
    268 JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
    269 {
    270     ExecState* exec = toJS(ctx);
    271     APIEntryShim entryShim(exec);
    272 
    273     JSValue jsValue = toJS(exec, value);
    274 
    275     JSObjectRef objectRef = toRef(jsValue.toObject(exec));
    276     if (exec->hadException()) {
    277         if (exception)
    278             *exception = toRef(exec, exec->exception());
    279         exec->clearException();
    280         objectRef = 0;
    281     }
    282     return objectRef;
    283 }
    284 
    285 void JSValueProtect(JSContextRef ctx, JSValueRef value)
    286 {
    287     ExecState* exec = toJS(ctx);
    288     APIEntryShim entryShim(exec);
    289 
    290     JSValue jsValue = toJSForGC(exec, value);
    291     gcProtect(jsValue);
    292 }
    293 
    294 void JSValueUnprotect(JSContextRef ctx, JSValueRef value)
    295 {
    296     ExecState* exec = toJS(ctx);
    297     APIEntryShim entryShim(exec);
    298 
    299     JSValue jsValue = toJSForGC(exec, value);
    300     gcUnprotect(jsValue);
    301 }
    302