~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/JavaScriptCore/API/JSObjectRef.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

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