source: webkit/trunk/JavaScriptCore/API/JSObjectRef.cpp@ 15224

Last change on this file since 15224 was 15224, checked in by ggaren, 19 years ago

Reviewed by Maciej.


More API action.


  • Headerdoc finished

Semantic Changes:

  • Added a JSContextRef argument to many functions, because you need a JSContextRef for doing virtually anything. I expect to add this argument to even more functions in a future patch.


  • Removed the globalObjectPrototype argument to JSContextCreate because you can't create an object until you have a context, so it's impossible to pass a prototype object to JSContextCreate. That's OK because (1) there's no reason to give the global object a prototype and (2) if you really want to, you can just use a separate call to JSObjectSetPrototype.


  • Removed the JSClassRef argument to JSClassCreate because it was unnecessary, and you need to be able to make the global object's class before you've created a JSContext.


  • Added an optional exception parameter to JSFunctionMakeWithBody because anything less would be uncivilized.


  • Made the return value parameter to JSObjectGetProperty optional to match all other return value parameters in the API.


  • Made JSObjectSetPrivate/JSObjectGetPrivate work on JSCallbackFunctions and JSCallbackConstructors. You could use an abstract base class or strategic placement of m_privateData in the class structure to implement this, but the former seemed like overkill, and the latter seemed too dangerous.


  • Fixed a bug where JSPropertyEnumeratorGetNext would skip the first property.

Cosmetic Changes:

  • Reversed the logic of the JSChar #ifdef to avoid confusing headerdoc


  • Removed function names from @function declarations because headeroc can parse them automatically, and I wanted to rule out manual mismatch.
  • Changed Error::create to take a const UString& instead of a UString* because it was looking at me funny.


  • Renamed JSStringBufferCreateWithCFString to JSStringBufferCreateCF because the latter is more concise and it matches JSStringBufferCreateUTF8.


  • API/JSCallbackObject.cpp: (KJS::JSCallbackObject::getOwnPropertySlot): (KJS::JSCallbackObject::put): (KJS::JSCallbackObject::deleteProperty): (KJS::JSCallbackObject::getPropertyList): (KJS::JSCallbackObject::toBoolean): (KJS::JSCallbackObject::toNumber): (KJS::JSCallbackObject::toString):
  • API/JSClassRef.cpp: (JSClassCreate):
  • API/JSContextRef.cpp: (JSContextCreate): (JSContextSetException):
  • API/JSContextRef.h:
  • API/JSNode.c: (JSNodePrototype_class): (JSNode_class):
  • API/JSNodeList.c: (JSNodeListPrototype_class): (JSNodeList_class):
  • API/JSObjectRef.cpp: (JSObjectGetProperty): (JSObjectGetPrivate): (JSObjectSetPrivate): (JSObjectCallAsFunction): (JSObjectCallAsConstructor): (JSPropertyEnumeratorGetNext):
  • API/JSObjectRef.h:
  • API/JSStringBufferRef.cpp: (JSStringBufferCreateCF):
  • API/JSStringBufferRef.h:
  • API/JSValueRef.cpp: (JSValueIsInstanceOf):
  • API/JSValueRef.h:
  • API/minidom.c: (main):
  • API/minidom.js:
  • API/testapi.c: (MyObject_hasProperty): (MyObject_setProperty): (MyObject_deleteProperty): (MyObject_getPropertyList): (MyObject_convertToType): (MyObject_class): (main):
  • JavaScriptCore.exp:
File size: 9.8 KB
Line 
1// -*- mode: c++; c-basic-offset: 4 -*-
2/*
3 * Copyright (C) 2006 Apple Computer, 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 * 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.
13 *
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.
25 */
26
27#include "APICast.h"
28#include "JSValueRef.h"
29#include "JSObjectRef.h"
30#include "JSCallbackConstructor.h"
31#include "JSCallbackFunction.h"
32#include "JSCallbackObject.h"
33
34#include "identifier.h"
35#include "function.h"
36#include "nodes.h"
37#include "internal.h"
38#include "object.h"
39#include "reference_list.h"
40
41using namespace KJS;
42
43JSObjectRef JSObjectMake(JSContextRef context, JSClassRef jsClass, JSObjectRef prototype)
44{
45 JSLock lock;
46
47 ExecState* exec = toJS(context);
48 JSObject* jsPrototype = toJS(prototype);
49
50 if (!prototype)
51 jsPrototype = exec->lexicalInterpreter()->builtinObjectPrototype();
52
53 if (!jsClass)
54 return toRef(new JSObject(jsPrototype)); // slightly more efficient
55 else
56 return toRef(new JSCallbackObject(jsClass, jsPrototype));
57}
58
59JSObjectRef JSFunctionMake(JSContextRef context, JSCallAsFunctionCallback callAsFunction)
60{
61 JSLock lock;
62 ExecState* exec = toJS(context);
63 return toRef(new JSCallbackFunction(exec, callAsFunction));
64}
65
66JSObjectRef JSConstructorMake(JSContextRef context, JSCallAsConstructorCallback callAsConstructor)
67{
68 JSLock lock;
69 ExecState* exec = toJS(context);
70 return toRef(new JSCallbackConstructor(exec, callAsConstructor));
71}
72
73JSObjectRef JSFunctionMakeWithBody(JSContextRef context, JSStringBufferRef body, JSStringBufferRef sourceURL, int startingLineNumber, JSValueRef* exception)
74{
75 JSLock lock;
76
77 ExecState* exec = toJS(context);
78 UString::Rep* bodyRep = toJS(body);
79 UString jsSourceURL = UString(toJS(sourceURL));
80
81 if (!bodyRep)
82 bodyRep = &UString::Rep::null;
83
84 int sid;
85 int errLine;
86 UString errMsg;
87 RefPtr<FunctionBodyNode> bodyNode = Parser::parse(jsSourceURL, startingLineNumber, bodyRep->data(), bodyRep->size(), &sid, &errLine, &errMsg);
88 if (!bodyNode) {
89 if (exception)
90 *exception = Error::create(exec, SyntaxError, errMsg, errLine, sid, jsSourceURL);
91 return NULL;
92 }
93
94 ScopeChain scopeChain;
95 scopeChain.push(exec->dynamicInterpreter()->globalObject());
96 return toRef(static_cast<JSObject*>(new DeclaredFunctionImp(exec, "anonymous", bodyNode.get(), scopeChain)));
97}
98
99JSStringBufferRef JSObjectGetDescription(JSObjectRef object)
100{
101 JSLock lock;
102 JSObject* jsObject = toJS(object);
103 return toRef(jsObject->className().rep());
104}
105
106JSValueRef JSObjectGetPrototype(JSObjectRef object)
107{
108 JSObject* jsObject = toJS(object);
109 return toRef(jsObject->prototype());
110}
111
112void JSObjectSetPrototype(JSObjectRef object, JSValueRef value)
113{
114 JSObject* jsObject = toJS(object);
115 JSValue* jsValue = toJS(value);
116
117 jsObject->setPrototype(jsValue);
118}
119
120bool JSObjectHasProperty(JSContextRef context, JSObjectRef object, JSStringBufferRef propertyName)
121{
122 JSLock lock;
123 ExecState* exec = toJS(context);
124 JSObject* jsObject = toJS(object);
125 UString::Rep* nameRep = toJS(propertyName);
126
127 return jsObject->hasProperty(exec, Identifier(nameRep));
128}
129
130bool JSObjectGetProperty(JSContextRef context, JSObjectRef object, JSStringBufferRef propertyName, JSValueRef* value)
131{
132 JSLock lock;
133 ExecState* exec = toJS(context);
134 JSObject* jsObject = toJS(object);
135 UString::Rep* nameRep = toJS(propertyName);
136
137 JSValue* jsValue = jsObject->get(exec, Identifier(nameRep));
138 if (value)
139 *value = toRef(jsValue);
140 return !jsValue->isUndefined();
141}
142
143bool JSObjectSetProperty(JSContextRef context, JSObjectRef object, JSStringBufferRef propertyName, JSValueRef value, JSPropertyAttributes attributes)
144{
145 JSLock lock;
146 ExecState* exec = toJS(context);
147 JSObject* jsObject = toJS(object);
148 UString::Rep* nameRep = toJS(propertyName);
149 JSValue* jsValue = toJS(value);
150
151 Identifier jsNameID = Identifier(nameRep);
152 if (jsObject->canPut(exec, jsNameID)) {
153 jsObject->put(exec, jsNameID, jsValue, attributes);
154 return true;
155 } else
156 return false;
157}
158
159bool JSObjectDeleteProperty(JSContextRef context, JSObjectRef object, JSStringBufferRef propertyName)
160{
161 JSLock lock;
162 ExecState* exec = toJS(context);
163 JSObject* jsObject = toJS(object);
164 UString::Rep* nameRep = toJS(propertyName);
165
166 return jsObject->deleteProperty(exec, Identifier(nameRep));
167}
168
169void* JSObjectGetPrivate(JSObjectRef object)
170{
171 JSObject* jsObject = toJS(object);
172
173 if (jsObject->inherits(&JSCallbackObject::info))
174 return static_cast<JSCallbackObject*>(jsObject)->getPrivate();
175
176 if (jsObject->inherits(&JSCallbackFunction::info))
177 return static_cast<JSCallbackFunction*>(jsObject)->getPrivate();
178
179 if (jsObject->inherits(&JSCallbackConstructor::info))
180 return static_cast<JSCallbackConstructor*>(jsObject)->getPrivate();
181
182 return 0;
183}
184
185bool JSObjectSetPrivate(JSObjectRef object, void* data)
186{
187 JSObject* jsObject = toJS(object);
188
189 if (jsObject->inherits(&JSCallbackObject::info)) {
190 static_cast<JSCallbackObject*>(jsObject)->setPrivate(data);
191 return true;
192 }
193
194 if (jsObject->inherits(&JSCallbackFunction::info)) {
195 static_cast<JSCallbackFunction*>(jsObject)->setPrivate(data);
196 return true;
197 }
198
199 if (jsObject->inherits(&JSCallbackConstructor::info)) {
200 static_cast<JSCallbackConstructor*>(jsObject)->setPrivate(data);
201 return true;
202 }
203
204 return false;
205}
206
207bool JSObjectIsFunction(JSObjectRef object)
208{
209 JSObject* jsObject = toJS(object);
210 return jsObject->implementsCall();
211}
212
213JSValueRef JSObjectCallAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argc, JSValueRef argv[], JSValueRef* exception)
214{
215 JSLock lock;
216 ExecState* exec = toJS(context);
217 JSObject* jsObject = toJS(object);
218 JSObject* jsThisObject = toJS(thisObject);
219
220 List argList;
221 for (size_t i = 0; i < argc; i++)
222 argList.append(toJS(argv[i]));
223
224 JSValueRef result = toRef(jsObject->call(exec, jsThisObject, argList)); // returns NULL if object->implementsCall() is false
225 if (exec->hadException()) {
226 if (exception)
227 *exception = exec->exception();
228 result = NULL;
229 exec->clearException();
230 }
231 return result;
232}
233
234bool JSObjectIsConstructor(JSObjectRef object)
235{
236 JSObject* jsObject = toJS(object);
237 return jsObject->implementsConstruct();
238}
239
240JSObjectRef JSObjectCallAsConstructor(JSContextRef context, JSObjectRef object, size_t argc, JSValueRef argv[], JSValueRef* exception)
241{
242 JSLock lock;
243 ExecState* exec = toJS(context);
244 JSObject* jsObject = toJS(object);
245
246 List argList;
247 for (size_t i = 0; i < argc; i++)
248 argList.append(toJS(argv[i]));
249
250 JSObjectRef result = toRef(jsObject->construct(exec, argList)); // returns NULL if object->implementsCall() is false
251 if (exec->hadException()) {
252 if (exception)
253 *exception = exec->exception();
254 result = NULL;
255 exec->clearException();
256 }
257 return result;
258}
259
260struct __JSPropertyEnumerator
261{
262 __JSPropertyEnumerator() : refCount(0), iterator(list.end())
263 {
264 }
265
266 unsigned refCount;
267 ReferenceList list;
268 ReferenceListIterator iterator;
269};
270
271JSPropertyEnumeratorRef JSObjectCreatePropertyEnumerator(JSContextRef context, JSObjectRef object)
272{
273 JSLock lock;
274 ExecState* exec = toJS(context);
275 JSObject* jsObject = toJS(object);
276
277 JSPropertyEnumeratorRef enumerator = new __JSPropertyEnumerator();
278 jsObject->getPropertyList(exec, enumerator->list);
279 enumerator->iterator = enumerator->list.begin();
280
281 return JSPropertyEnumeratorRetain(enumerator);
282}
283
284JSStringBufferRef JSPropertyEnumeratorGetNext(JSContextRef context, JSPropertyEnumeratorRef enumerator)
285{
286 ExecState* exec = toJS(context);
287 ReferenceListIterator& iterator = enumerator->iterator;
288 if (iterator != enumerator->list.end()) {
289 JSStringBufferRef result = toRef(iterator->getPropertyName(exec).ustring().rep());
290 iterator++;
291 return result;
292 }
293 return 0;
294}
295
296JSPropertyEnumeratorRef JSPropertyEnumeratorRetain(JSPropertyEnumeratorRef enumerator)
297{
298 ++enumerator->refCount;
299 return enumerator;
300}
301
302void JSPropertyEnumeratorRelease(JSPropertyEnumeratorRef enumerator)
303{
304 if (--enumerator->refCount == 0)
305 delete enumerator;
306}
307
308void JSPropertyListAdd(JSPropertyListRef propertyList, JSObjectRef thisObject, JSStringBufferRef propertyName)
309{
310 JSLock lock;
311 ReferenceList* jsPropertyList = toJS(propertyList);
312 JSObject* jsObject = toJS(thisObject);
313 UString::Rep* rep = toJS(propertyName);
314
315 jsPropertyList->append(Reference(jsObject, Identifier(rep)));
316}
Note: See TracBrowser for help on using the repository browser.