2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Kelvin W Sherlock (ksherlock@gmail.com)
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 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 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"
29 #include "JSObjectRefPrivate.h"
32 #include "ButterflyInlines.h"
33 #include "CodeBlock.h"
34 #include "CopiedSpaceInlines.h"
35 #include "DateConstructor.h"
36 #include "ErrorConstructor.h"
37 #include "Exception.h"
38 #include "FunctionConstructor.h"
39 #include "Identifier.h"
40 #include "InitializeThreading.h"
41 #include "JSAPIWrapperObject.h"
43 #include "JSCallbackConstructor.h"
44 #include "JSCallbackFunction.h"
45 #include "JSCallbackObject.h"
46 #include "JSClassRef.h"
47 #include "JSFunction.h"
48 #include "JSGlobalObject.h"
50 #include "JSRetainPtr.h"
52 #include "JSValueRef.h"
53 #include "ObjectConstructor.h"
54 #include "ObjectPrototype.h"
55 #include "JSCInlines.h"
56 #include "PropertyNameArray.h"
57 #include "RegExpConstructor.h"
59 #if ENABLE(REMOTE_INSPECTOR)
60 #include "JSGlobalObjectInspectorController.h"
65 enum class ExceptionStatus
{
70 static ExceptionStatus
handleExceptionIfNeeded(ExecState
* exec
, JSValueRef
* returnedExceptionRef
)
72 if (exec
->hadException()) {
73 Exception
* exception
= exec
->exception();
74 if (returnedExceptionRef
)
75 *returnedExceptionRef
= toRef(exec
, exception
->value());
76 exec
->clearException();
77 #if ENABLE(REMOTE_INSPECTOR)
78 exec
->vmEntryGlobalObject()->inspectorController().reportAPIException(exec
, exception
);
80 return ExceptionStatus::DidThrow
;
82 return ExceptionStatus::DidNotThrow
;
85 JSClassRef
JSClassCreate(const JSClassDefinition
* definition
)
87 initializeThreading();
88 RefPtr
<OpaqueJSClass
> jsClass
= (definition
->attributes
& kJSClassAttributeNoAutomaticPrototype
)
89 ? OpaqueJSClass::createNoAutomaticPrototype(definition
)
90 : OpaqueJSClass::create(definition
);
92 return jsClass
.release().leakRef();
95 JSClassRef
JSClassRetain(JSClassRef jsClass
)
101 void JSClassRelease(JSClassRef jsClass
)
106 JSObjectRef
JSObjectMake(JSContextRef ctx
, JSClassRef jsClass
, void* data
)
109 ASSERT_NOT_REACHED();
112 ExecState
* exec
= toJS(ctx
);
113 JSLockHolder
locker(exec
);
116 return toRef(constructEmptyObject(exec
));
118 JSCallbackObject
<JSDestructibleObject
>* object
= JSCallbackObject
<JSDestructibleObject
>::create(exec
, exec
->lexicalGlobalObject(), exec
->lexicalGlobalObject()->callbackObjectStructure(), jsClass
, data
);
119 if (JSObject
* prototype
= jsClass
->prototype(exec
))
120 object
->setPrototype(exec
->vm(), prototype
);
122 return toRef(object
);
125 JSObjectRef
JSObjectMakeFunctionWithCallback(JSContextRef ctx
, JSStringRef name
, JSObjectCallAsFunctionCallback callAsFunction
)
128 ASSERT_NOT_REACHED();
131 ExecState
* exec
= toJS(ctx
);
132 JSLockHolder
locker(exec
);
133 return toRef(JSCallbackFunction::create(exec
->vm(), exec
->lexicalGlobalObject(), callAsFunction
, name
? name
->string() : ASCIILiteral("anonymous")));
136 JSObjectRef
JSObjectMakeConstructor(JSContextRef ctx
, JSClassRef jsClass
, JSObjectCallAsConstructorCallback callAsConstructor
)
139 ASSERT_NOT_REACHED();
142 ExecState
* exec
= toJS(ctx
);
143 JSLockHolder
locker(exec
);
145 JSValue jsPrototype
= jsClass
? jsClass
->prototype(exec
) : 0;
147 jsPrototype
= exec
->lexicalGlobalObject()->objectPrototype();
149 JSCallbackConstructor
* constructor
= JSCallbackConstructor::create(exec
, exec
->lexicalGlobalObject(), exec
->lexicalGlobalObject()->callbackConstructorStructure(), jsClass
, callAsConstructor
);
150 constructor
->putDirect(exec
->vm(), exec
->propertyNames().prototype
, jsPrototype
, DontEnum
| DontDelete
| ReadOnly
);
151 return toRef(constructor
);
154 JSObjectRef
JSObjectMakeFunction(JSContextRef ctx
, JSStringRef name
, unsigned parameterCount
, const JSStringRef parameterNames
[], JSStringRef body
, JSStringRef sourceURL
, int startingLineNumber
, JSValueRef
* exception
)
157 ASSERT_NOT_REACHED();
160 ExecState
* exec
= toJS(ctx
);
161 JSLockHolder
locker(exec
);
163 startingLineNumber
= std::max(1, startingLineNumber
);
164 Identifier nameID
= name
? name
->identifier(&exec
->vm()) : Identifier::fromString(exec
, "anonymous");
166 MarkedArgumentBuffer args
;
167 for (unsigned i
= 0; i
< parameterCount
; i
++)
168 args
.append(jsString(exec
, parameterNames
[i
]->string()));
169 args
.append(jsString(exec
, body
->string()));
171 JSObject
* result
= constructFunction(exec
, exec
->lexicalGlobalObject(), args
, nameID
, sourceURL
? sourceURL
->string() : String(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber
), OrdinalNumber::first()));
172 if (handleExceptionIfNeeded(exec
, exception
) == ExceptionStatus::DidThrow
)
174 return toRef(result
);
177 JSObjectRef
JSObjectMakeArray(JSContextRef ctx
, size_t argumentCount
, const JSValueRef arguments
[], JSValueRef
* exception
)
180 ASSERT_NOT_REACHED();
183 ExecState
* exec
= toJS(ctx
);
184 JSLockHolder
locker(exec
);
188 MarkedArgumentBuffer argList
;
189 for (size_t i
= 0; i
< argumentCount
; ++i
)
190 argList
.append(toJS(exec
, arguments
[i
]));
192 result
= constructArray(exec
, static_cast<ArrayAllocationProfile
*>(0), argList
);
194 result
= constructEmptyArray(exec
, 0);
196 if (handleExceptionIfNeeded(exec
, exception
) == ExceptionStatus::DidThrow
)
199 return toRef(result
);
202 JSObjectRef
JSObjectMakeDate(JSContextRef ctx
, size_t argumentCount
, const JSValueRef arguments
[], JSValueRef
* exception
)
205 ASSERT_NOT_REACHED();
208 ExecState
* exec
= toJS(ctx
);
209 JSLockHolder
locker(exec
);
211 MarkedArgumentBuffer argList
;
212 for (size_t i
= 0; i
< argumentCount
; ++i
)
213 argList
.append(toJS(exec
, arguments
[i
]));
215 JSObject
* result
= constructDate(exec
, exec
->lexicalGlobalObject(), argList
);
216 if (handleExceptionIfNeeded(exec
, exception
) == ExceptionStatus::DidThrow
)
219 return toRef(result
);
222 JSObjectRef
JSObjectMakeError(JSContextRef ctx
, size_t argumentCount
, const JSValueRef arguments
[], JSValueRef
* exception
)
225 ASSERT_NOT_REACHED();
228 ExecState
* exec
= toJS(ctx
);
229 JSLockHolder
locker(exec
);
231 JSValue message
= argumentCount
? toJS(exec
, arguments
[0]) : jsUndefined();
232 Structure
* errorStructure
= exec
->lexicalGlobalObject()->errorStructure();
233 JSObject
* result
= ErrorInstance::create(exec
, errorStructure
, message
);
235 if (handleExceptionIfNeeded(exec
, exception
) == ExceptionStatus::DidThrow
)
238 return toRef(result
);
241 JSObjectRef
JSObjectMakeRegExp(JSContextRef ctx
, size_t argumentCount
, const JSValueRef arguments
[], JSValueRef
* exception
)
244 ASSERT_NOT_REACHED();
247 ExecState
* exec
= toJS(ctx
);
248 JSLockHolder
locker(exec
);
250 MarkedArgumentBuffer argList
;
251 for (size_t i
= 0; i
< argumentCount
; ++i
)
252 argList
.append(toJS(exec
, arguments
[i
]));
254 JSObject
* result
= constructRegExp(exec
, exec
->lexicalGlobalObject(), argList
);
255 if (handleExceptionIfNeeded(exec
, exception
) == ExceptionStatus::DidThrow
)
258 return toRef(result
);
261 JSValueRef
JSObjectGetPrototype(JSContextRef ctx
, JSObjectRef object
)
264 ASSERT_NOT_REACHED();
267 ExecState
* exec
= toJS(ctx
);
268 JSLockHolder
locker(exec
);
270 JSObject
* jsObject
= toJS(object
);
271 return toRef(exec
, jsObject
->prototype());
274 void JSObjectSetPrototype(JSContextRef ctx
, JSObjectRef object
, JSValueRef value
)
277 ASSERT_NOT_REACHED();
280 ExecState
* exec
= toJS(ctx
);
281 JSLockHolder
locker(exec
);
283 JSObject
* jsObject
= toJS(object
);
284 JSValue jsValue
= toJS(exec
, value
);
286 if (JSProxy
* proxy
= jsDynamicCast
<JSProxy
*>(jsObject
)) {
287 if (JSGlobalObject
* globalObject
= jsDynamicCast
<JSGlobalObject
*>(proxy
->target())) {
288 globalObject
->resetPrototype(exec
->vm(), jsValue
.isObject() ? jsValue
: jsNull());
291 // Someday we might use proxies for something other than JSGlobalObjects, but today is not that day.
292 RELEASE_ASSERT_NOT_REACHED();
294 jsObject
->setPrototypeWithCycleCheck(exec
, jsValue
.isObject() ? jsValue
: jsNull());
297 bool JSObjectHasProperty(JSContextRef ctx
, JSObjectRef object
, JSStringRef propertyName
)
300 ASSERT_NOT_REACHED();
303 ExecState
* exec
= toJS(ctx
);
304 JSLockHolder
locker(exec
);
306 JSObject
* jsObject
= toJS(object
);
308 return jsObject
->hasProperty(exec
, propertyName
->identifier(&exec
->vm()));
311 JSValueRef
JSObjectGetProperty(JSContextRef ctx
, JSObjectRef object
, JSStringRef propertyName
, JSValueRef
* exception
)
314 ASSERT_NOT_REACHED();
317 ExecState
* exec
= toJS(ctx
);
318 JSLockHolder
locker(exec
);
320 JSObject
* jsObject
= toJS(object
);
322 JSValue jsValue
= jsObject
->get(exec
, propertyName
->identifier(&exec
->vm()));
323 handleExceptionIfNeeded(exec
, exception
);
324 return toRef(exec
, jsValue
);
327 void JSObjectSetProperty(JSContextRef ctx
, JSObjectRef object
, JSStringRef propertyName
, JSValueRef value
, JSPropertyAttributes attributes
, JSValueRef
* exception
)
330 ASSERT_NOT_REACHED();
333 ExecState
* exec
= toJS(ctx
);
334 JSLockHolder
locker(exec
);
336 JSObject
* jsObject
= toJS(object
);
337 Identifier
name(propertyName
->identifier(&exec
->vm()));
338 JSValue jsValue
= toJS(exec
, value
);
340 if (attributes
&& !jsObject
->hasProperty(exec
, name
)) {
341 PropertyDescriptor
desc(jsValue
, attributes
);
342 jsObject
->methodTable()->defineOwnProperty(jsObject
, exec
, name
, desc
, false);
344 PutPropertySlot
slot(jsObject
);
345 jsObject
->methodTable()->put(jsObject
, exec
, name
, jsValue
, slot
);
348 handleExceptionIfNeeded(exec
, exception
);
351 JSValueRef
JSObjectGetPropertyAtIndex(JSContextRef ctx
, JSObjectRef object
, unsigned propertyIndex
, JSValueRef
* exception
)
354 ASSERT_NOT_REACHED();
357 ExecState
* exec
= toJS(ctx
);
358 JSLockHolder
locker(exec
);
360 JSObject
* jsObject
= toJS(object
);
362 JSValue jsValue
= jsObject
->get(exec
, propertyIndex
);
363 handleExceptionIfNeeded(exec
, exception
);
364 return toRef(exec
, jsValue
);
368 void JSObjectSetPropertyAtIndex(JSContextRef ctx
, JSObjectRef object
, unsigned propertyIndex
, JSValueRef value
, JSValueRef
* exception
)
371 ASSERT_NOT_REACHED();
374 ExecState
* exec
= toJS(ctx
);
375 JSLockHolder
locker(exec
);
377 JSObject
* jsObject
= toJS(object
);
378 JSValue jsValue
= toJS(exec
, value
);
380 jsObject
->methodTable()->putByIndex(jsObject
, exec
, propertyIndex
, jsValue
, false);
381 handleExceptionIfNeeded(exec
, exception
);
384 bool JSObjectDeleteProperty(JSContextRef ctx
, JSObjectRef object
, JSStringRef propertyName
, JSValueRef
* exception
)
387 ASSERT_NOT_REACHED();
390 ExecState
* exec
= toJS(ctx
);
391 JSLockHolder
locker(exec
);
393 JSObject
* jsObject
= toJS(object
);
395 bool result
= jsObject
->methodTable()->deleteProperty(jsObject
, exec
, propertyName
->identifier(&exec
->vm()));
396 handleExceptionIfNeeded(exec
, exception
);
400 void* JSObjectGetPrivate(JSObjectRef object
)
402 JSObject
* jsObject
= uncheckedToJS(object
);
404 // Get wrapped object if proxied
405 if (jsObject
->inherits(JSProxy::info()))
406 jsObject
= jsCast
<JSProxy
*>(jsObject
)->target();
408 if (jsObject
->inherits(JSCallbackObject
<JSGlobalObject
>::info()))
409 return jsCast
<JSCallbackObject
<JSGlobalObject
>*>(jsObject
)->getPrivate();
410 if (jsObject
->inherits(JSCallbackObject
<JSDestructibleObject
>::info()))
411 return jsCast
<JSCallbackObject
<JSDestructibleObject
>*>(jsObject
)->getPrivate();
412 #if JSC_OBJC_API_ENABLED
413 if (jsObject
->inherits(JSCallbackObject
<JSAPIWrapperObject
>::info()))
414 return jsCast
<JSCallbackObject
<JSAPIWrapperObject
>*>(jsObject
)->getPrivate();
420 bool JSObjectSetPrivate(JSObjectRef object
, void* data
)
422 JSObject
* jsObject
= uncheckedToJS(object
);
424 // Get wrapped object if proxied
425 if (jsObject
->inherits(JSProxy::info()))
426 jsObject
= jsCast
<JSProxy
*>(jsObject
)->target();
428 if (jsObject
->inherits(JSCallbackObject
<JSGlobalObject
>::info())) {
429 jsCast
<JSCallbackObject
<JSGlobalObject
>*>(jsObject
)->setPrivate(data
);
432 if (jsObject
->inherits(JSCallbackObject
<JSDestructibleObject
>::info())) {
433 jsCast
<JSCallbackObject
<JSDestructibleObject
>*>(jsObject
)->setPrivate(data
);
436 #if JSC_OBJC_API_ENABLED
437 if (jsObject
->inherits(JSCallbackObject
<JSAPIWrapperObject
>::info())) {
438 jsCast
<JSCallbackObject
<JSAPIWrapperObject
>*>(jsObject
)->setPrivate(data
);
446 JSValueRef
JSObjectGetPrivateProperty(JSContextRef ctx
, JSObjectRef object
, JSStringRef propertyName
)
448 ExecState
* exec
= toJS(ctx
);
449 JSLockHolder
locker(exec
);
450 JSObject
* jsObject
= toJS(object
);
452 Identifier
name(propertyName
->identifier(&exec
->vm()));
454 // Get wrapped object if proxied
455 if (jsObject
->inherits(JSProxy::info()))
456 jsObject
= jsCast
<JSProxy
*>(jsObject
)->target();
458 if (jsObject
->inherits(JSCallbackObject
<JSGlobalObject
>::info()))
459 result
= jsCast
<JSCallbackObject
<JSGlobalObject
>*>(jsObject
)->getPrivateProperty(name
);
460 else if (jsObject
->inherits(JSCallbackObject
<JSDestructibleObject
>::info()))
461 result
= jsCast
<JSCallbackObject
<JSDestructibleObject
>*>(jsObject
)->getPrivateProperty(name
);
462 #if JSC_OBJC_API_ENABLED
463 else if (jsObject
->inherits(JSCallbackObject
<JSAPIWrapperObject
>::info()))
464 result
= jsCast
<JSCallbackObject
<JSAPIWrapperObject
>*>(jsObject
)->getPrivateProperty(name
);
466 return toRef(exec
, result
);
469 bool JSObjectSetPrivateProperty(JSContextRef ctx
, JSObjectRef object
, JSStringRef propertyName
, JSValueRef value
)
471 ExecState
* exec
= toJS(ctx
);
472 JSLockHolder
locker(exec
);
473 JSObject
* jsObject
= toJS(object
);
474 JSValue jsValue
= value
? toJS(exec
, value
) : JSValue();
475 Identifier
name(propertyName
->identifier(&exec
->vm()));
477 // Get wrapped object if proxied
478 if (jsObject
->inherits(JSProxy::info()))
479 jsObject
= jsCast
<JSProxy
*>(jsObject
)->target();
481 if (jsObject
->inherits(JSCallbackObject
<JSGlobalObject
>::info())) {
482 jsCast
<JSCallbackObject
<JSGlobalObject
>*>(jsObject
)->setPrivateProperty(exec
->vm(), name
, jsValue
);
485 if (jsObject
->inherits(JSCallbackObject
<JSDestructibleObject
>::info())) {
486 jsCast
<JSCallbackObject
<JSDestructibleObject
>*>(jsObject
)->setPrivateProperty(exec
->vm(), name
, jsValue
);
489 #if JSC_OBJC_API_ENABLED
490 if (jsObject
->inherits(JSCallbackObject
<JSAPIWrapperObject
>::info())) {
491 jsCast
<JSCallbackObject
<JSAPIWrapperObject
>*>(jsObject
)->setPrivateProperty(exec
->vm(), name
, jsValue
);
498 bool JSObjectDeletePrivateProperty(JSContextRef ctx
, JSObjectRef object
, JSStringRef propertyName
)
500 ExecState
* exec
= toJS(ctx
);
501 JSLockHolder
locker(exec
);
502 JSObject
* jsObject
= toJS(object
);
503 Identifier
name(propertyName
->identifier(&exec
->vm()));
505 // Get wrapped object if proxied
506 if (jsObject
->inherits(JSProxy::info()))
507 jsObject
= jsCast
<JSProxy
*>(jsObject
)->target();
509 if (jsObject
->inherits(JSCallbackObject
<JSGlobalObject
>::info())) {
510 jsCast
<JSCallbackObject
<JSGlobalObject
>*>(jsObject
)->deletePrivateProperty(name
);
513 if (jsObject
->inherits(JSCallbackObject
<JSDestructibleObject
>::info())) {
514 jsCast
<JSCallbackObject
<JSDestructibleObject
>*>(jsObject
)->deletePrivateProperty(name
);
517 #if JSC_OBJC_API_ENABLED
518 if (jsObject
->inherits(JSCallbackObject
<JSAPIWrapperObject
>::info())) {
519 jsCast
<JSCallbackObject
<JSAPIWrapperObject
>*>(jsObject
)->deletePrivateProperty(name
);
526 bool JSObjectIsFunction(JSContextRef ctx
, JSObjectRef object
)
530 JSLockHolder
locker(toJS(ctx
));
532 JSCell
* cell
= toJS(object
);
533 return cell
->methodTable()->getCallData(cell
, callData
) != CallTypeNone
;
536 JSValueRef
JSObjectCallAsFunction(JSContextRef ctx
, JSObjectRef object
, JSObjectRef thisObject
, size_t argumentCount
, const JSValueRef arguments
[], JSValueRef
* exception
)
538 ExecState
* exec
= toJS(ctx
);
539 JSLockHolder
locker(exec
);
544 JSObject
* jsObject
= toJS(object
);
545 JSObject
* jsThisObject
= toJS(thisObject
);
548 jsThisObject
= exec
->globalThisValue();
550 MarkedArgumentBuffer argList
;
551 for (size_t i
= 0; i
< argumentCount
; i
++)
552 argList
.append(toJS(exec
, arguments
[i
]));
555 CallType callType
= jsObject
->methodTable()->getCallData(jsObject
, callData
);
556 if (callType
== CallTypeNone
)
559 JSValueRef result
= toRef(exec
, call(exec
, jsObject
, callType
, callData
, jsThisObject
, argList
));
560 if (handleExceptionIfNeeded(exec
, exception
) == ExceptionStatus::DidThrow
)
565 bool JSObjectIsConstructor(JSContextRef
, JSObjectRef object
)
569 JSObject
* jsObject
= toJS(object
);
570 ConstructData constructData
;
571 return jsObject
->methodTable()->getConstructData(jsObject
, constructData
) != ConstructTypeNone
;
574 JSObjectRef
JSObjectCallAsConstructor(JSContextRef ctx
, JSObjectRef object
, size_t argumentCount
, const JSValueRef arguments
[], JSValueRef
* exception
)
576 ExecState
* exec
= toJS(ctx
);
577 JSLockHolder
locker(exec
);
582 JSObject
* jsObject
= toJS(object
);
584 ConstructData constructData
;
585 ConstructType constructType
= jsObject
->methodTable()->getConstructData(jsObject
, constructData
);
586 if (constructType
== ConstructTypeNone
)
589 MarkedArgumentBuffer argList
;
590 for (size_t i
= 0; i
< argumentCount
; i
++)
591 argList
.append(toJS(exec
, arguments
[i
]));
592 JSObjectRef result
= toRef(construct(exec
, jsObject
, constructType
, constructData
, argList
));
593 if (handleExceptionIfNeeded(exec
, exception
) == ExceptionStatus::DidThrow
)
598 struct OpaqueJSPropertyNameArray
{
599 WTF_MAKE_FAST_ALLOCATED
;
601 OpaqueJSPropertyNameArray(VM
* vm
)
609 Vector
<JSRetainPtr
<JSStringRef
>> array
;
612 JSPropertyNameArrayRef
JSObjectCopyPropertyNames(JSContextRef ctx
, JSObjectRef object
)
615 ASSERT_NOT_REACHED();
618 ExecState
* exec
= toJS(ctx
);
619 JSLockHolder
locker(exec
);
621 VM
* vm
= &exec
->vm();
623 JSObject
* jsObject
= toJS(object
);
624 JSPropertyNameArrayRef propertyNames
= new OpaqueJSPropertyNameArray(vm
);
625 PropertyNameArray
array(vm
);
626 jsObject
->methodTable()->getPropertyNames(jsObject
, exec
, array
, EnumerationMode());
628 size_t size
= array
.size();
629 propertyNames
->array
.reserveInitialCapacity(size
);
630 for (size_t i
= 0; i
< size
; ++i
)
631 propertyNames
->array
.uncheckedAppend(JSRetainPtr
<JSStringRef
>(Adopt
, OpaqueJSString::create(array
[i
].string()).leakRef()));
633 return JSPropertyNameArrayRetain(propertyNames
);
636 JSPropertyNameArrayRef
JSPropertyNameArrayRetain(JSPropertyNameArrayRef array
)
642 void JSPropertyNameArrayRelease(JSPropertyNameArrayRef array
)
644 if (--array
->refCount
== 0) {
645 JSLockHolder
locker(array
->vm
);
650 size_t JSPropertyNameArrayGetCount(JSPropertyNameArrayRef array
)
652 return array
->array
.size();
655 JSStringRef
JSPropertyNameArrayGetNameAtIndex(JSPropertyNameArrayRef array
, size_t index
)
657 return array
->array
[static_cast<unsigned>(index
)].get();
660 void JSPropertyNameAccumulatorAddName(JSPropertyNameAccumulatorRef array
, JSStringRef propertyName
)
662 PropertyNameArray
* propertyNames
= toJS(array
);
663 JSLockHolder
locker(propertyNames
->vm());
664 propertyNames
->add(propertyName
->identifier(propertyNames
->vm()));