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