OSDN Git Service

Merge commit 'remotes/korg/cupcake'
[android-x86/external-webkit.git] / JavaScriptCore / API / JSValueRef.cpp
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 "JSCallbackObject.h"
32
33 #include <runtime/JSGlobalObject.h>
34 #include <runtime/JSString.h>
35 #include <kjs/operations.h>
36 #include <kjs/protect.h>
37 #include <kjs/ustring.h>
38 #include <runtime/JSValue.h>
39
40 #include <wtf/Assertions.h>
41
42 #include <algorithm> // for std::min
43
44 JSType JSValueGetType(JSContextRef, JSValueRef value)
45 {
46     JSC::JSValue* jsValue = toJS(value);
47     if (jsValue->isUndefined())
48         return kJSTypeUndefined;
49     if (jsValue->isNull())
50         return kJSTypeNull;
51     if (jsValue->isBoolean())
52         return kJSTypeBoolean;
53     if (jsValue->isNumber())
54         return kJSTypeNumber;
55     if (jsValue->isString())
56         return kJSTypeString;
57     ASSERT(jsValue->isObject());
58     return kJSTypeObject;
59 }
60
61 using namespace JSC; // placed here to avoid conflict between JSC::JSType and JSType, above.
62
63 bool JSValueIsUndefined(JSContextRef, JSValueRef value)
64 {
65     JSValue* jsValue = toJS(value);
66     return jsValue->isUndefined();
67 }
68
69 bool JSValueIsNull(JSContextRef, JSValueRef value)
70 {
71     JSValue* jsValue = toJS(value);
72     return jsValue->isNull();
73 }
74
75 bool JSValueIsBoolean(JSContextRef, JSValueRef value)
76 {
77     JSValue* jsValue = toJS(value);
78     return jsValue->isBoolean();
79 }
80
81 bool JSValueIsNumber(JSContextRef, JSValueRef value)
82 {
83     JSValue* jsValue = toJS(value);
84     return jsValue->isNumber();
85 }
86
87 bool JSValueIsString(JSContextRef, JSValueRef value)
88 {
89     JSValue* jsValue = toJS(value);
90     return jsValue->isString();
91 }
92
93 bool JSValueIsObject(JSContextRef, JSValueRef value)
94 {
95     JSValue* jsValue = toJS(value);
96     return jsValue->isObject();
97 }
98
99 bool JSValueIsObjectOfClass(JSContextRef, JSValueRef value, JSClassRef jsClass)
100 {
101     JSValue* jsValue = toJS(value);
102     
103     if (JSObject* o = jsValue->getObject()) {
104         if (o->inherits(&JSCallbackObject<JSGlobalObject>::info))
105             return static_cast<JSCallbackObject<JSGlobalObject>*>(o)->inherits(jsClass);
106         else if (o->inherits(&JSCallbackObject<JSObject>::info))
107             return static_cast<JSCallbackObject<JSObject>*>(o)->inherits(jsClass);
108     }
109     return false;
110 }
111
112 bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* exception)
113 {
114     ExecState* exec = toJS(ctx);
115     exec->globalData().heap.registerThread();
116     JSLock lock(exec);
117
118     JSValue* jsA = toJS(a);
119     JSValue* jsB = toJS(b);
120
121     bool result = equal(exec, jsA, jsB); // false if an exception is thrown
122     if (exec->hadException()) {
123         if (exception)
124             *exception = toRef(exec->exception());
125         exec->clearException();
126     }
127     return result;
128 }
129
130 bool JSValueIsStrictEqual(JSContextRef, JSValueRef a, JSValueRef b)
131 {
132     JSValue* jsA = toJS(a);
133     JSValue* jsB = toJS(b);
134     
135     bool result = strictEqual(jsA, jsB);
136     return result;
137 }
138
139 bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObjectRef constructor, JSValueRef* exception)
140 {
141     ExecState* exec = toJS(ctx);
142     exec->globalData().heap.registerThread();
143     JSLock lock(exec);
144
145     JSValue* jsValue = toJS(value);
146     JSObject* jsConstructor = toJS(constructor);
147     if (!jsConstructor->structureID()->typeInfo().implementsHasInstance())
148         return false;
149     bool result = jsConstructor->hasInstance(exec, jsValue, jsConstructor->get(exec, exec->propertyNames().prototype)); // false if an exception is thrown
150     if (exec->hadException()) {
151         if (exception)
152             *exception = toRef(exec->exception());
153         exec->clearException();
154     }
155     return result;
156 }
157
158 JSValueRef JSValueMakeUndefined(JSContextRef)
159 {
160     return toRef(jsUndefined());
161 }
162
163 JSValueRef JSValueMakeNull(JSContextRef)
164 {
165     return toRef(jsNull());
166 }
167
168 JSValueRef JSValueMakeBoolean(JSContextRef, bool value)
169 {
170     return toRef(jsBoolean(value));
171 }
172
173 JSValueRef JSValueMakeNumber(JSContextRef ctx, double value)
174 {
175     ExecState* exec = toJS(ctx);
176     exec->globalData().heap.registerThread();
177     JSLock lock(exec);
178
179     return toRef(jsNumber(exec, value));
180 }
181
182 JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
183 {
184     ExecState* exec = toJS(ctx);
185     exec->globalData().heap.registerThread();
186     JSLock lock(exec);
187
188     return toRef(jsString(exec, string->ustring()));
189 }
190
191 bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
192 {
193     ExecState* exec = toJS(ctx);
194     JSValue* jsValue = toJS(value);
195     return jsValue->toBoolean(exec);
196 }
197
198 double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
199 {
200     ExecState* exec = toJS(ctx);
201     exec->globalData().heap.registerThread();
202     JSLock lock(exec);
203
204     JSValue* jsValue = toJS(value);
205
206     double number = jsValue->toNumber(exec);
207     if (exec->hadException()) {
208         if (exception)
209             *exception = toRef(exec->exception());
210         exec->clearException();
211         number = NaN;
212     }
213     return number;
214 }
215
216 JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
217 {
218     ExecState* exec = toJS(ctx);
219     exec->globalData().heap.registerThread();
220     JSLock lock(exec);
221
222     JSValue* jsValue = toJS(value);
223     
224     RefPtr<OpaqueJSString> stringRef(OpaqueJSString::create(jsValue->toString(exec)));
225     if (exec->hadException()) {
226         if (exception)
227             *exception = toRef(exec->exception());
228         exec->clearException();
229         stringRef.clear();
230     }
231     return stringRef.release().releaseRef();
232 }
233
234 JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
235 {
236     ExecState* exec = toJS(ctx);
237     exec->globalData().heap.registerThread();
238     JSLock lock(exec);
239
240     JSValue* jsValue = toJS(value);
241     
242     JSObjectRef objectRef = toRef(jsValue->toObject(exec));
243     if (exec->hadException()) {
244         if (exception)
245             *exception = toRef(exec->exception());
246         exec->clearException();
247         objectRef = 0;
248     }
249     return objectRef;
250 }    
251
252 void JSValueProtect(JSContextRef ctx, JSValueRef value)
253 {
254     ExecState* exec = toJS(ctx);
255     exec->globalData().heap.registerThread();
256     JSLock lock(exec);
257
258     JSValue* jsValue = toJS(value);
259     gcProtect(jsValue);
260 }
261
262 void JSValueUnprotect(JSContextRef ctx, JSValueRef value)
263 {
264     ExecState* exec = toJS(ctx);
265     exec->globalData().heap.registerThread();
266     JSLock lock(exec);
267
268     JSValue* jsValue = toJS(value);
269     gcUnprotect(jsValue);
270 }