]> git.saurik.com Git - apple/javascriptcore.git/blame - API/JSObjectRef.cpp
JavaScriptCore-1097.3.3.tar.gz
[apple/javascriptcore.git] / API / JSObjectRef.cpp
CommitLineData
b37bf2e1 1/*
9dae56ea
A
2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Kelvin W Sherlock (ksherlock@gmail.com)
b37bf2e1
A
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 "config.h"
28#include "JSObjectRef.h"
4e4e5a6f 29#include "JSObjectRefPrivate.h"
b37bf2e1 30
b37bf2e1 31#include "APICast.h"
f9bf01c6 32#include "CodeBlock.h"
9dae56ea
A
33#include "DateConstructor.h"
34#include "ErrorConstructor.h"
35#include "FunctionConstructor.h"
36#include "Identifier.h"
37#include "InitializeThreading.h"
38#include "JSArray.h"
b37bf2e1
A
39#include "JSCallbackConstructor.h"
40#include "JSCallbackFunction.h"
41#include "JSCallbackObject.h"
42#include "JSClassRef.h"
9dae56ea 43#include "JSFunction.h"
b37bf2e1 44#include "JSGlobalObject.h"
9dae56ea
A
45#include "JSObject.h"
46#include "JSRetainPtr.h"
47#include "JSString.h"
48#include "JSValueRef.h"
49#include "ObjectPrototype.h"
b37bf2e1 50#include "PropertyNameArray.h"
9dae56ea 51#include "RegExpConstructor.h"
b37bf2e1 52
9dae56ea 53using namespace JSC;
b37bf2e1
A
54
55JSClassRef JSClassCreate(const JSClassDefinition* definition)
56{
9dae56ea
A
57 initializeThreading();
58 RefPtr<OpaqueJSClass> jsClass = (definition->attributes & kJSClassAttributeNoAutomaticPrototype)
b37bf2e1
A
59 ? OpaqueJSClass::createNoAutomaticPrototype(definition)
60 : OpaqueJSClass::create(definition);
61
14957cd0 62 return jsClass.release().leakRef();
b37bf2e1
A
63}
64
65JSClassRef JSClassRetain(JSClassRef jsClass)
66{
b37bf2e1
A
67 jsClass->ref();
68 return jsClass;
69}
70
71void JSClassRelease(JSClassRef jsClass)
72{
b37bf2e1
A
73 jsClass->deref();
74}
75
76JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data)
77{
b37bf2e1 78 ExecState* exec = toJS(ctx);
f9bf01c6 79 APIEntryShim entryShim(exec);
b37bf2e1
A
80
81 if (!jsClass)
14957cd0 82 return toRef(constructEmptyObject(exec));
b37bf2e1 83
6fe7ccc8 84 JSCallbackObject<JSNonFinalObject>* object = JSCallbackObject<JSNonFinalObject>::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackObjectStructure(), jsClass, data);
9dae56ea 85 if (JSObject* prototype = jsClass->prototype(exec))
14957cd0 86 object->setPrototype(exec->globalData(), prototype);
b37bf2e1 87
9dae56ea 88 return toRef(object);
b37bf2e1
A
89}
90
91JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name, JSObjectCallAsFunctionCallback callAsFunction)
92{
b37bf2e1 93 ExecState* exec = toJS(ctx);
f9bf01c6 94 APIEntryShim entryShim(exec);
9dae56ea
A
95
96 Identifier nameID = name ? name->identifier(&exec->globalData()) : Identifier(exec, "anonymous");
b37bf2e1 97
6fe7ccc8 98 return toRef(JSCallbackFunction::create(exec, exec->lexicalGlobalObject(), callAsFunction, nameID));
b37bf2e1
A
99}
100
101JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObjectCallAsConstructorCallback callAsConstructor)
102{
b37bf2e1 103 ExecState* exec = toJS(ctx);
f9bf01c6 104 APIEntryShim entryShim(exec);
9dae56ea 105
ba379fdc
A
106 JSValue jsPrototype = jsClass ? jsClass->prototype(exec) : 0;
107 if (!jsPrototype)
108 jsPrototype = exec->lexicalGlobalObject()->objectPrototype();
109
6fe7ccc8 110 JSCallbackConstructor* constructor = JSCallbackConstructor::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackConstructorStructure(), jsClass, callAsConstructor);
14957cd0 111 constructor->putDirect(exec->globalData(), exec->propertyNames().prototype, jsPrototype, DontEnum | DontDelete | ReadOnly);
b37bf2e1
A
112 return toRef(constructor);
113}
114
115JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned parameterCount, const JSStringRef parameterNames[], JSStringRef body, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
116{
b37bf2e1 117 ExecState* exec = toJS(ctx);
f9bf01c6 118 APIEntryShim entryShim(exec);
9dae56ea
A
119
120 Identifier nameID = name ? name->identifier(&exec->globalData()) : Identifier(exec, "anonymous");
b37bf2e1 121
ba379fdc 122 MarkedArgumentBuffer args;
b37bf2e1 123 for (unsigned i = 0; i < parameterCount; i++)
9dae56ea
A
124 args.append(jsString(exec, parameterNames[i]->ustring()));
125 args.append(jsString(exec, body->ustring()));
126
6fe7ccc8 127 JSObject* result = constructFunction(exec, exec->lexicalGlobalObject(), args, nameID, sourceURL->ustring(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));
9dae56ea
A
128 if (exec->hadException()) {
129 if (exception)
ba379fdc 130 *exception = toRef(exec, exec->exception());
9dae56ea
A
131 exec->clearException();
132 result = 0;
133 }
134 return toRef(result);
135}
136
137JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
138{
139 ExecState* exec = toJS(ctx);
f9bf01c6 140 APIEntryShim entryShim(exec);
9dae56ea
A
141
142 JSObject* result;
143 if (argumentCount) {
ba379fdc 144 MarkedArgumentBuffer argList;
9dae56ea 145 for (size_t i = 0; i < argumentCount; ++i)
ba379fdc 146 argList.append(toJS(exec, arguments[i]));
9dae56ea
A
147
148 result = constructArray(exec, argList);
149 } else
150 result = constructEmptyArray(exec);
b37bf2e1 151
b37bf2e1
A
152 if (exec->hadException()) {
153 if (exception)
ba379fdc 154 *exception = toRef(exec, exec->exception());
b37bf2e1
A
155 exec->clearException();
156 result = 0;
157 }
9dae56ea
A
158
159 return toRef(result);
160}
161
162JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
163{
164 ExecState* exec = toJS(ctx);
f9bf01c6 165 APIEntryShim entryShim(exec);
9dae56ea 166
ba379fdc 167 MarkedArgumentBuffer argList;
9dae56ea 168 for (size_t i = 0; i < argumentCount; ++i)
ba379fdc 169 argList.append(toJS(exec, arguments[i]));
9dae56ea 170
14957cd0 171 JSObject* result = constructDate(exec, exec->lexicalGlobalObject(), argList);
9dae56ea
A
172 if (exec->hadException()) {
173 if (exception)
ba379fdc 174 *exception = toRef(exec, exec->exception());
9dae56ea
A
175 exec->clearException();
176 result = 0;
177 }
178
179 return toRef(result);
180}
181
182JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
183{
184 ExecState* exec = toJS(ctx);
f9bf01c6 185 APIEntryShim entryShim(exec);
9dae56ea 186
14957cd0
A
187 JSValue message = argumentCount ? toJS(exec, arguments[0]) : jsUndefined();
188 Structure* errorStructure = exec->lexicalGlobalObject()->errorStructure();
189 JSObject* result = ErrorInstance::create(exec, errorStructure, message);
9dae56ea 190
9dae56ea
A
191 if (exec->hadException()) {
192 if (exception)
ba379fdc 193 *exception = toRef(exec, exec->exception());
9dae56ea
A
194 exec->clearException();
195 result = 0;
196 }
197
198 return toRef(result);
199}
200
201JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
202{
203 ExecState* exec = toJS(ctx);
f9bf01c6 204 APIEntryShim entryShim(exec);
9dae56ea 205
ba379fdc 206 MarkedArgumentBuffer argList;
9dae56ea 207 for (size_t i = 0; i < argumentCount; ++i)
ba379fdc 208 argList.append(toJS(exec, arguments[i]));
9dae56ea 209
14957cd0 210 JSObject* result = constructRegExp(exec, exec->lexicalGlobalObject(), argList);
9dae56ea
A
211 if (exec->hadException()) {
212 if (exception)
ba379fdc 213 *exception = toRef(exec, exec->exception());
9dae56ea
A
214 exec->clearException();
215 result = 0;
216 }
217
b37bf2e1
A
218 return toRef(result);
219}
220
ba379fdc 221JSValueRef JSObjectGetPrototype(JSContextRef ctx, JSObjectRef object)
b37bf2e1 222{
ba379fdc 223 ExecState* exec = toJS(ctx);
f9bf01c6 224 APIEntryShim entryShim(exec);
ba379fdc 225
b37bf2e1 226 JSObject* jsObject = toJS(object);
ba379fdc 227 return toRef(exec, jsObject->prototype());
b37bf2e1
A
228}
229
ba379fdc 230void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value)
b37bf2e1 231{
ba379fdc 232 ExecState* exec = toJS(ctx);
f9bf01c6 233 APIEntryShim entryShim(exec);
ba379fdc 234
b37bf2e1 235 JSObject* jsObject = toJS(object);
ba379fdc 236 JSValue jsValue = toJS(exec, value);
b37bf2e1 237
14957cd0 238 jsObject->setPrototypeWithCycleCheck(exec->globalData(), jsValue.isObject() ? jsValue : jsNull());
b37bf2e1
A
239}
240
241bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
242{
b37bf2e1 243 ExecState* exec = toJS(ctx);
f9bf01c6 244 APIEntryShim entryShim(exec);
9dae56ea 245
b37bf2e1 246 JSObject* jsObject = toJS(object);
b37bf2e1 247
9dae56ea 248 return jsObject->hasProperty(exec, propertyName->identifier(&exec->globalData()));
b37bf2e1
A
249}
250
251JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
252{
b37bf2e1 253 ExecState* exec = toJS(ctx);
f9bf01c6 254 APIEntryShim entryShim(exec);
9dae56ea 255
b37bf2e1 256 JSObject* jsObject = toJS(object);
b37bf2e1 257
ba379fdc 258 JSValue jsValue = jsObject->get(exec, propertyName->identifier(&exec->globalData()));
b37bf2e1
A
259 if (exec->hadException()) {
260 if (exception)
ba379fdc 261 *exception = toRef(exec, exec->exception());
b37bf2e1
A
262 exec->clearException();
263 }
ba379fdc 264 return toRef(exec, jsValue);
b37bf2e1
A
265}
266
267void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception)
268{
b37bf2e1 269 ExecState* exec = toJS(ctx);
f9bf01c6 270 APIEntryShim entryShim(exec);
9dae56ea 271
b37bf2e1 272 JSObject* jsObject = toJS(object);
9dae56ea 273 Identifier name(propertyName->identifier(&exec->globalData()));
ba379fdc 274 JSValue jsValue = toJS(exec, value);
9dae56ea
A
275
276 if (attributes && !jsObject->hasProperty(exec, name))
6fe7ccc8 277 jsObject->methodTable()->putDirectVirtual(jsObject, exec, name, jsValue, attributes);
9dae56ea
A
278 else {
279 PutPropertySlot slot;
6fe7ccc8 280 jsObject->methodTable()->put(jsObject, exec, name, jsValue, slot);
9dae56ea
A
281 }
282
b37bf2e1
A
283 if (exec->hadException()) {
284 if (exception)
ba379fdc 285 *exception = toRef(exec, exec->exception());
b37bf2e1
A
286 exec->clearException();
287 }
288}
289
290JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef* exception)
291{
b37bf2e1 292 ExecState* exec = toJS(ctx);
f9bf01c6 293 APIEntryShim entryShim(exec);
9dae56ea 294
b37bf2e1
A
295 JSObject* jsObject = toJS(object);
296
ba379fdc 297 JSValue jsValue = jsObject->get(exec, propertyIndex);
b37bf2e1
A
298 if (exec->hadException()) {
299 if (exception)
ba379fdc 300 *exception = toRef(exec, exec->exception());
b37bf2e1
A
301 exec->clearException();
302 }
ba379fdc 303 return toRef(exec, jsValue);
b37bf2e1
A
304}
305
306
307void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef value, JSValueRef* exception)
308{
b37bf2e1 309 ExecState* exec = toJS(ctx);
f9bf01c6 310 APIEntryShim entryShim(exec);
9dae56ea 311
b37bf2e1 312 JSObject* jsObject = toJS(object);
ba379fdc 313 JSValue jsValue = toJS(exec, value);
b37bf2e1 314
6fe7ccc8 315 jsObject->methodTable()->putByIndex(jsObject, exec, propertyIndex, jsValue, false);
b37bf2e1
A
316 if (exec->hadException()) {
317 if (exception)
ba379fdc 318 *exception = toRef(exec, exec->exception());
b37bf2e1
A
319 exec->clearException();
320 }
321}
322
323bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
324{
b37bf2e1 325 ExecState* exec = toJS(ctx);
f9bf01c6 326 APIEntryShim entryShim(exec);
9dae56ea 327
b37bf2e1 328 JSObject* jsObject = toJS(object);
b37bf2e1 329
6fe7ccc8 330 bool result = jsObject->methodTable()->deleteProperty(jsObject, exec, propertyName->identifier(&exec->globalData()));
b37bf2e1
A
331 if (exec->hadException()) {
332 if (exception)
ba379fdc 333 *exception = toRef(exec, exec->exception());
b37bf2e1
A
334 exec->clearException();
335 }
336 return result;
337}
338
339void* JSObjectGetPrivate(JSObjectRef object)
340{
341 JSObject* jsObject = toJS(object);
342
14957cd0 343 if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info))
6fe7ccc8
A
344 return jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->getPrivate();
345 if (jsObject->inherits(&JSCallbackObject<JSNonFinalObject>::s_info))
346 return jsCast<JSCallbackObject<JSNonFinalObject>*>(jsObject)->getPrivate();
b37bf2e1
A
347
348 return 0;
349}
350
351bool JSObjectSetPrivate(JSObjectRef object, void* data)
352{
353 JSObject* jsObject = toJS(object);
354
14957cd0 355 if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info)) {
6fe7ccc8 356 jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->setPrivate(data);
b37bf2e1 357 return true;
14957cd0 358 }
6fe7ccc8
A
359 if (jsObject->inherits(&JSCallbackObject<JSNonFinalObject>::s_info)) {
360 jsCast<JSCallbackObject<JSNonFinalObject>*>(jsObject)->setPrivate(data);
b37bf2e1
A
361 return true;
362 }
363
364 return false;
365}
366
4e4e5a6f
A
367JSValueRef JSObjectGetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
368{
369 ExecState* exec = toJS(ctx);
370 APIEntryShim entryShim(exec);
371 JSObject* jsObject = toJS(object);
372 JSValue result;
373 Identifier name(propertyName->identifier(&exec->globalData()));
14957cd0 374 if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info))
6fe7ccc8
A
375 result = jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->getPrivateProperty(name);
376 else if (jsObject->inherits(&JSCallbackObject<JSNonFinalObject>::s_info))
377 result = jsCast<JSCallbackObject<JSNonFinalObject>*>(jsObject)->getPrivateProperty(name);
4e4e5a6f
A
378 return toRef(exec, result);
379}
380
381bool JSObjectSetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value)
382{
383 ExecState* exec = toJS(ctx);
384 APIEntryShim entryShim(exec);
385 JSObject* jsObject = toJS(object);
14957cd0 386 JSValue jsValue = value ? toJS(exec, value) : JSValue();
4e4e5a6f 387 Identifier name(propertyName->identifier(&exec->globalData()));
14957cd0 388 if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info)) {
6fe7ccc8 389 jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->setPrivateProperty(exec->globalData(), name, jsValue);
4e4e5a6f
A
390 return true;
391 }
6fe7ccc8
A
392 if (jsObject->inherits(&JSCallbackObject<JSNonFinalObject>::s_info)) {
393 jsCast<JSCallbackObject<JSNonFinalObject>*>(jsObject)->setPrivateProperty(exec->globalData(), name, jsValue);
4e4e5a6f
A
394 return true;
395 }
396 return false;
397}
398
399bool JSObjectDeletePrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
400{
401 ExecState* exec = toJS(ctx);
402 APIEntryShim entryShim(exec);
403 JSObject* jsObject = toJS(object);
404 Identifier name(propertyName->identifier(&exec->globalData()));
14957cd0 405 if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info)) {
6fe7ccc8 406 jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->deletePrivateProperty(name);
4e4e5a6f
A
407 return true;
408 }
6fe7ccc8
A
409 if (jsObject->inherits(&JSCallbackObject<JSNonFinalObject>::s_info)) {
410 jsCast<JSCallbackObject<JSNonFinalObject>*>(jsObject)->deletePrivateProperty(name);
4e4e5a6f
A
411 return true;
412 }
413 return false;
414}
415
b37bf2e1
A
416bool JSObjectIsFunction(JSContextRef, JSObjectRef object)
417{
9dae56ea 418 CallData callData;
6fe7ccc8
A
419 JSCell* cell = toJS(object);
420 return cell->methodTable()->getCallData(cell, callData) != CallTypeNone;
b37bf2e1
A
421}
422
423JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
424{
b37bf2e1 425 ExecState* exec = toJS(ctx);
f9bf01c6 426 APIEntryShim entryShim(exec);
9dae56ea 427
b37bf2e1
A
428 JSObject* jsObject = toJS(object);
429 JSObject* jsThisObject = toJS(thisObject);
430
431 if (!jsThisObject)
9dae56ea
A
432 jsThisObject = exec->globalThisValue();
433
ba379fdc 434 MarkedArgumentBuffer argList;
b37bf2e1 435 for (size_t i = 0; i < argumentCount; i++)
ba379fdc 436 argList.append(toJS(exec, arguments[i]));
b37bf2e1 437
9dae56ea 438 CallData callData;
6fe7ccc8 439 CallType callType = jsObject->methodTable()->getCallData(jsObject, callData);
9dae56ea
A
440 if (callType == CallTypeNone)
441 return 0;
442
ba379fdc 443 JSValueRef result = toRef(exec, call(exec, jsObject, callType, callData, jsThisObject, argList));
b37bf2e1
A
444 if (exec->hadException()) {
445 if (exception)
ba379fdc 446 *exception = toRef(exec, exec->exception());
b37bf2e1
A
447 exec->clearException();
448 result = 0;
449 }
450 return result;
451}
452
453bool JSObjectIsConstructor(JSContextRef, JSObjectRef object)
454{
455 JSObject* jsObject = toJS(object);
9dae56ea 456 ConstructData constructData;
6fe7ccc8 457 return jsObject->methodTable()->getConstructData(jsObject, constructData) != ConstructTypeNone;
b37bf2e1
A
458}
459
460JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
461{
b37bf2e1 462 ExecState* exec = toJS(ctx);
f9bf01c6 463 APIEntryShim entryShim(exec);
9dae56ea 464
b37bf2e1 465 JSObject* jsObject = toJS(object);
9dae56ea
A
466
467 ConstructData constructData;
6fe7ccc8 468 ConstructType constructType = jsObject->methodTable()->getConstructData(jsObject, constructData);
9dae56ea
A
469 if (constructType == ConstructTypeNone)
470 return 0;
471
ba379fdc 472 MarkedArgumentBuffer argList;
b37bf2e1 473 for (size_t i = 0; i < argumentCount; i++)
ba379fdc 474 argList.append(toJS(exec, arguments[i]));
9dae56ea 475 JSObjectRef result = toRef(construct(exec, jsObject, constructType, constructData, argList));
b37bf2e1
A
476 if (exec->hadException()) {
477 if (exception)
ba379fdc 478 *exception = toRef(exec, exec->exception());
b37bf2e1
A
479 exec->clearException();
480 result = 0;
481 }
482 return result;
483}
484
14957cd0
A
485struct OpaqueJSPropertyNameArray {
486 WTF_MAKE_FAST_ALLOCATED;
487public:
9dae56ea
A
488 OpaqueJSPropertyNameArray(JSGlobalData* globalData)
489 : refCount(0)
490 , globalData(globalData)
b37bf2e1
A
491 {
492 }
493
494 unsigned refCount;
9dae56ea
A
495 JSGlobalData* globalData;
496 Vector<JSRetainPtr<JSStringRef> > array;
b37bf2e1
A
497};
498
499JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef object)
500{
b37bf2e1
A
501 JSObject* jsObject = toJS(object);
502 ExecState* exec = toJS(ctx);
f9bf01c6 503 APIEntryShim entryShim(exec);
9dae56ea
A
504
505 JSGlobalData* globalData = &exec->globalData();
506
507 JSPropertyNameArrayRef propertyNames = new OpaqueJSPropertyNameArray(globalData);
508 PropertyNameArray array(globalData);
6fe7ccc8 509 jsObject->methodTable()->getPropertyNames(jsObject, exec, array, ExcludeDontEnumProperties);
9dae56ea
A
510
511 size_t size = array.size();
512 propertyNames->array.reserveInitialCapacity(size);
513 for (size_t i = 0; i < size; ++i)
14957cd0 514 propertyNames->array.append(JSRetainPtr<JSStringRef>(Adopt, OpaqueJSString::create(array[i].ustring()).leakRef()));
b37bf2e1
A
515
516 return JSPropertyNameArrayRetain(propertyNames);
517}
518
519JSPropertyNameArrayRef JSPropertyNameArrayRetain(JSPropertyNameArrayRef array)
520{
b37bf2e1
A
521 ++array->refCount;
522 return array;
523}
524
525void JSPropertyNameArrayRelease(JSPropertyNameArrayRef array)
526{
9dae56ea 527 if (--array->refCount == 0) {
f9bf01c6 528 APIEntryShim entryShim(array->globalData, false);
b37bf2e1 529 delete array;
9dae56ea 530 }
b37bf2e1
A
531}
532
533size_t JSPropertyNameArrayGetCount(JSPropertyNameArrayRef array)
534{
535 return array->array.size();
536}
537
538JSStringRef JSPropertyNameArrayGetNameAtIndex(JSPropertyNameArrayRef array, size_t index)
539{
9dae56ea 540 return array->array[static_cast<unsigned>(index)].get();
b37bf2e1
A
541}
542
543void JSPropertyNameAccumulatorAddName(JSPropertyNameAccumulatorRef array, JSStringRef propertyName)
544{
b37bf2e1 545 PropertyNameArray* propertyNames = toJS(array);
f9bf01c6 546 APIEntryShim entryShim(propertyNames->globalData());
9dae56ea 547 propertyNames->add(propertyName->identifier(propertyNames->globalData()));
b37bf2e1 548}