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