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