1 // -*- mode: c++; c-basic-offset: 4 -*-
3 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "JSObjectRef.h"
30 #include <wtf/Platform.h>
32 #include "JSValueRef.h"
33 #include "JSCallbackConstructor.h"
34 #include "JSCallbackFunction.h"
35 #include "JSCallbackObject.h"
36 #include "JSClassRef.h"
37 #include "JSGlobalObject.h"
39 #include "PropertyNameArray.h"
41 #include "function_object.h"
42 #include "identifier.h"
45 #include "object_object.h"
49 JSClassRef
JSClassCreate(const JSClassDefinition
* definition
)
52 JSClassRef jsClass
= (definition
->attributes
& kJSClassAttributeNoAutomaticPrototype
)
53 ? OpaqueJSClass::createNoAutomaticPrototype(definition
)
54 : OpaqueJSClass::create(definition
);
56 return JSClassRetain(jsClass
);
59 JSClassRef
JSClassRetain(JSClassRef jsClass
)
66 void JSClassRelease(JSClassRef jsClass
)
72 JSObjectRef
JSObjectMake(JSContextRef ctx
, JSClassRef jsClass
, void* data
)
75 ExecState
* exec
= toJS(ctx
);
78 return toRef(new JSObject(exec
->lexicalGlobalObject()->objectPrototype())); // slightly more efficient
80 JSValue
* jsPrototype
= jsClass
->prototype(ctx
);
82 jsPrototype
= exec
->lexicalGlobalObject()->objectPrototype();
84 return toRef(new JSCallbackObject
<JSObject
>(exec
, jsClass
, jsPrototype
, data
));
87 JSObjectRef
JSObjectMakeFunctionWithCallback(JSContextRef ctx
, JSStringRef name
, JSObjectCallAsFunctionCallback callAsFunction
)
90 ExecState
* exec
= toJS(ctx
);
91 Identifier nameID
= name
? Identifier(toJS(name
)) : Identifier("anonymous");
93 return toRef(new JSCallbackFunction(exec
, callAsFunction
, nameID
));
96 JSObjectRef
JSObjectMakeConstructor(JSContextRef ctx
, JSClassRef jsClass
, JSObjectCallAsConstructorCallback callAsConstructor
)
99 ExecState
* exec
= toJS(ctx
);
101 JSValue
* jsPrototype
= jsClass
102 ? jsClass
->prototype(ctx
)
103 : exec
->dynamicGlobalObject()->objectPrototype();
105 JSCallbackConstructor
* constructor
= new JSCallbackConstructor(exec
, jsClass
, callAsConstructor
);
106 constructor
->putDirect(exec
->propertyNames().prototype
, jsPrototype
, DontEnum
| DontDelete
| ReadOnly
);
107 return toRef(constructor
);
110 JSObjectRef
JSObjectMakeFunction(JSContextRef ctx
, JSStringRef name
, unsigned parameterCount
, const JSStringRef parameterNames
[], JSStringRef body
, JSStringRef sourceURL
, int startingLineNumber
, JSValueRef
* exception
)
114 ExecState
* exec
= toJS(ctx
);
115 UString::Rep
* bodyRep
= toJS(body
);
116 UString::Rep
* sourceURLRep
= sourceURL
? toJS(sourceURL
) : &UString::Rep::null
;
118 Identifier nameID
= name
? Identifier(toJS(name
)) : Identifier("anonymous");
121 for (unsigned i
= 0; i
< parameterCount
; i
++)
122 args
.append(jsString(UString(toJS(parameterNames
[i
]))));
123 args
.append(jsString(UString(bodyRep
)));
125 JSObject
* result
= exec
->dynamicGlobalObject()->functionConstructor()->construct(exec
, args
, nameID
, UString(sourceURLRep
), startingLineNumber
);
126 if (exec
->hadException()) {
128 *exception
= toRef(exec
->exception());
129 exec
->clearException();
132 return toRef(result
);
135 JSValueRef
JSObjectGetPrototype(JSContextRef
, JSObjectRef object
)
137 JSObject
* jsObject
= toJS(object
);
138 return toRef(jsObject
->prototype());
141 void JSObjectSetPrototype(JSContextRef
, JSObjectRef object
, JSValueRef value
)
143 JSObject
* jsObject
= toJS(object
);
144 JSValue
* jsValue
= toJS(value
);
146 jsObject
->setPrototype(jsValue
);
149 bool JSObjectHasProperty(JSContextRef ctx
, JSObjectRef object
, JSStringRef propertyName
)
152 ExecState
* exec
= toJS(ctx
);
153 JSObject
* jsObject
= toJS(object
);
154 UString::Rep
* nameRep
= toJS(propertyName
);
156 return jsObject
->hasProperty(exec
, Identifier(nameRep
));
159 JSValueRef
JSObjectGetProperty(JSContextRef ctx
, JSObjectRef object
, JSStringRef propertyName
, JSValueRef
* exception
)
162 ExecState
* exec
= toJS(ctx
);
163 JSObject
* jsObject
= toJS(object
);
164 UString::Rep
* nameRep
= toJS(propertyName
);
166 JSValue
* jsValue
= jsObject
->get(exec
, Identifier(nameRep
));
167 if (exec
->hadException()) {
169 *exception
= toRef(exec
->exception());
170 exec
->clearException();
172 return toRef(jsValue
);
175 void JSObjectSetProperty(JSContextRef ctx
, JSObjectRef object
, JSStringRef propertyName
, JSValueRef value
, JSPropertyAttributes attributes
, JSValueRef
* exception
)
178 ExecState
* exec
= toJS(ctx
);
179 JSObject
* jsObject
= toJS(object
);
180 UString::Rep
* nameRep
= toJS(propertyName
);
181 JSValue
* jsValue
= toJS(value
);
183 jsObject
->put(exec
, Identifier(nameRep
), jsValue
, attributes
);
184 if (exec
->hadException()) {
186 *exception
= toRef(exec
->exception());
187 exec
->clearException();
191 JSValueRef
JSObjectGetPropertyAtIndex(JSContextRef ctx
, JSObjectRef object
, unsigned propertyIndex
, JSValueRef
* exception
)
194 ExecState
* exec
= toJS(ctx
);
195 JSObject
* jsObject
= toJS(object
);
197 JSValue
* jsValue
= jsObject
->get(exec
, propertyIndex
);
198 if (exec
->hadException()) {
200 *exception
= toRef(exec
->exception());
201 exec
->clearException();
203 return toRef(jsValue
);
207 void JSObjectSetPropertyAtIndex(JSContextRef ctx
, JSObjectRef object
, unsigned propertyIndex
, JSValueRef value
, JSValueRef
* exception
)
210 ExecState
* exec
= toJS(ctx
);
211 JSObject
* jsObject
= toJS(object
);
212 JSValue
* jsValue
= toJS(value
);
214 jsObject
->put(exec
, propertyIndex
, jsValue
);
215 if (exec
->hadException()) {
217 *exception
= toRef(exec
->exception());
218 exec
->clearException();
222 bool JSObjectDeleteProperty(JSContextRef ctx
, JSObjectRef object
, JSStringRef propertyName
, JSValueRef
* exception
)
225 ExecState
* exec
= toJS(ctx
);
226 JSObject
* jsObject
= toJS(object
);
227 UString::Rep
* nameRep
= toJS(propertyName
);
229 bool result
= jsObject
->deleteProperty(exec
, Identifier(nameRep
));
230 if (exec
->hadException()) {
232 *exception
= toRef(exec
->exception());
233 exec
->clearException();
238 void* JSObjectGetPrivate(JSObjectRef object
)
240 JSObject
* jsObject
= toJS(object
);
242 if (jsObject
->inherits(&JSCallbackObject
<JSGlobalObject
>::info
))
243 return static_cast<JSCallbackObject
<JSGlobalObject
>*>(jsObject
)->getPrivate();
244 else if (jsObject
->inherits(&JSCallbackObject
<JSObject
>::info
))
245 return static_cast<JSCallbackObject
<JSObject
>*>(jsObject
)->getPrivate();
250 bool JSObjectSetPrivate(JSObjectRef object
, void* data
)
252 JSObject
* jsObject
= toJS(object
);
254 if (jsObject
->inherits(&JSCallbackObject
<JSGlobalObject
>::info
)) {
255 static_cast<JSCallbackObject
<JSGlobalObject
>*>(jsObject
)->setPrivate(data
);
257 } else if (jsObject
->inherits(&JSCallbackObject
<JSObject
>::info
)) {
258 static_cast<JSCallbackObject
<JSObject
>*>(jsObject
)->setPrivate(data
);
265 bool JSObjectIsFunction(JSContextRef
, JSObjectRef object
)
267 JSObject
* jsObject
= toJS(object
);
268 return jsObject
->implementsCall();
271 JSValueRef
JSObjectCallAsFunction(JSContextRef ctx
, JSObjectRef object
, JSObjectRef thisObject
, size_t argumentCount
, const JSValueRef arguments
[], JSValueRef
* exception
)
274 ExecState
* exec
= toJS(ctx
);
275 JSObject
* jsObject
= toJS(object
);
276 JSObject
* jsThisObject
= toJS(thisObject
);
279 jsThisObject
= exec
->dynamicGlobalObject();
282 for (size_t i
= 0; i
< argumentCount
; i
++)
283 argList
.append(toJS(arguments
[i
]));
285 JSValueRef result
= toRef(jsObject
->call(exec
, jsThisObject
, argList
)); // returns NULL if object->implementsCall() is false
286 if (exec
->hadException()) {
288 *exception
= toRef(exec
->exception());
289 exec
->clearException();
295 bool JSObjectIsConstructor(JSContextRef
, JSObjectRef object
)
297 JSObject
* jsObject
= toJS(object
);
298 return jsObject
->implementsConstruct();
301 JSObjectRef
JSObjectCallAsConstructor(JSContextRef ctx
, JSObjectRef object
, size_t argumentCount
, const JSValueRef arguments
[], JSValueRef
* exception
)
304 ExecState
* exec
= toJS(ctx
);
305 JSObject
* jsObject
= toJS(object
);
308 for (size_t i
= 0; i
< argumentCount
; i
++)
309 argList
.append(toJS(arguments
[i
]));
311 JSObjectRef result
= toRef(jsObject
->construct(exec
, argList
)); // returns NULL if object->implementsCall() is false
312 if (exec
->hadException()) {
314 *exception
= toRef(exec
->exception());
315 exec
->clearException();
321 struct OpaqueJSPropertyNameArray
323 OpaqueJSPropertyNameArray() : refCount(0)
328 PropertyNameArray array
;
331 JSPropertyNameArrayRef
JSObjectCopyPropertyNames(JSContextRef ctx
, JSObjectRef object
)
334 JSObject
* jsObject
= toJS(object
);
335 ExecState
* exec
= toJS(ctx
);
337 JSPropertyNameArrayRef propertyNames
= new OpaqueJSPropertyNameArray();
338 jsObject
->getPropertyNames(exec
, propertyNames
->array
);
340 return JSPropertyNameArrayRetain(propertyNames
);
343 JSPropertyNameArrayRef
JSPropertyNameArrayRetain(JSPropertyNameArrayRef array
)
350 void JSPropertyNameArrayRelease(JSPropertyNameArrayRef array
)
353 if (--array
->refCount
== 0)
357 size_t JSPropertyNameArrayGetCount(JSPropertyNameArrayRef array
)
359 return array
->array
.size();
362 JSStringRef
JSPropertyNameArrayGetNameAtIndex(JSPropertyNameArrayRef array
, size_t index
)
364 return toRef(array
->array
[static_cast<unsigned>(index
)].ustring().rep());
367 void JSPropertyNameAccumulatorAddName(JSPropertyNameAccumulatorRef array
, JSStringRef propertyName
)
370 PropertyNameArray
* propertyNames
= toJS(array
);
371 UString::Rep
* rep
= toJS(propertyName
);
373 propertyNames
->add(Identifier(rep
));