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