2 * Copyright 2008 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/debug.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(jscript
);
27 static HRESULT
Object_toString(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
35 /* Keep in sync with jsclass_t enum */
36 static const WCHAR
*names
[] = {
60 if(is_undefined(vthis
) || is_null(vthis
)) {
61 if(ctx
->version
< SCRIPTLANGUAGEVERSION_ES5
)
62 str
= L
"[object Object]";
64 str
= is_null(vthis
) ? L
"[object Null]" : L
"[object Undefined]";
68 hres
= to_object(ctx
, vthis
, &disp
);
72 jsdisp
= to_jsdisp(disp
);
74 str
= L
"[object Object]";
75 }else if(names
[jsdisp
->builtin_info
->class]) {
76 str
= names
[jsdisp
->builtin_info
->class];
78 assert(jsdisp
->builtin_info
->class != JSCLASS_NONE
);
79 FIXME("jsdisp->builtin_info->class = %d\n", jsdisp
->builtin_info
->class);
82 IDispatch_Release(disp
);
89 ret
= jsstr_alloc(str
);
92 *r
= jsval_string(ret
);
98 static HRESULT
Object_toLocaleString(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
107 hres
= to_object(ctx
, vthis
, &disp
);
111 if(!(jsdisp
= to_jsdisp(disp
))) {
112 FIXME("Host object this\n");
117 hres
= jsdisp_call_name(jsdisp
, L
"toString", DISPATCH_METHOD
, 0, NULL
, r
);
119 IDispatch_Release(disp
);
123 static HRESULT
Object_valueOf(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
131 if(is_null_disp(vthis
)) {
132 if(r
) *r
= jsval_null_disp();
136 hres
= to_object(ctx
, vthis
, &disp
);
141 *r
= jsval_disp(disp
);
143 IDispatch_Release(disp
);
147 static HRESULT
Object_hasOwnProperty(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
160 hres
= to_object(ctx
, vthis
, &disp
);
166 *r
= jsval_bool(FALSE
);
170 hres
= to_string(ctx
, argv
[0], &name
);
174 if((jsdisp
= to_jsdisp(disp
))) {
175 property_desc_t prop_desc
;
176 const WCHAR
*name_str
;
178 name_str
= jsstr_flatten(name
);
181 hres
= E_OUTOFMEMORY
;
185 hres
= jsdisp_get_own_property(jsdisp
, name_str
, TRUE
, &prop_desc
);
187 if(FAILED(hres
) && hres
!= DISP_E_UNKNOWNNAME
)
190 if(r
) *r
= jsval_bool(hres
== S_OK
);
196 bstr
= SysAllocStringLen(NULL
, jsstr_length(name
));
198 jsstr_flush(name
, bstr
);
201 hres
= E_OUTOFMEMORY
;
205 hres
= IDispatch_QueryInterface(disp
, &IID_IDispatchEx
, (void**)&dispex
);
206 if(SUCCEEDED(hres
)) {
207 hres
= IDispatchEx_GetDispID(dispex
, bstr
, make_grfdex(ctx
, fdexNameCaseSensitive
), &id
);
208 IDispatchEx_Release(dispex
);
210 hres
= IDispatch_GetIDsOfNames(disp
, &IID_NULL
, &bstr
, 1, ctx
->lcid
, &id
);
214 *r
= jsval_bool(SUCCEEDED(hres
));
217 IDispatch_Release(disp
);
221 static HRESULT
Object_propertyIsEnumerable(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
224 property_desc_t prop_desc
;
233 hres
= to_object(ctx
, vthis
, &disp
);
238 FIXME("argc %d not supported\n", argc
);
243 if(!(jsdisp
= to_jsdisp(disp
))) {
244 FIXME("Host object this\n");
249 hres
= to_flat_string(ctx
, argv
[0], &name_str
, &name
);
253 hres
= jsdisp_get_own_property(jsdisp
, name
, TRUE
, &prop_desc
);
254 jsstr_release(name_str
);
255 if(FAILED(hres
) && hres
!= DISP_E_UNKNOWNNAME
)
259 *r
= jsval_bool(hres
== S_OK
&& (prop_desc
.flags
& PROPF_ENUMERABLE
) != 0);
262 IDispatch_Release(disp
);
266 static HRESULT
Object_isPrototypeOf(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
269 jsdisp_t
*jsthis
, *jsdisp
;
274 hres
= to_object(ctx
, vthis
, &disp
);
281 if(argc
&& (jsthis
= to_jsdisp(disp
)) && is_object_instance(argv
[0]) &&
282 (jsdisp
= to_jsdisp(get_object(argv
[0])))) {
283 while(jsdisp
->prototype
) {
284 if(jsdisp
->prototype
== jsthis
) {
288 jsdisp
= jsdisp
->prototype
;
292 *r
= jsval_bool(ret
);
294 IDispatch_Release(disp
);
298 static HRESULT
Object_defineGetter(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
300 property_desc_t desc
;
308 if(!is_object_instance(vthis
) || !(jsthis
= to_jsdisp(get_object(vthis
))))
311 if(argc
< 2 || !is_object_instance(argv
[1]))
312 return JS_E_FUNCTION_EXPECTED
;
314 desc
.getter
= to_jsdisp(get_object(argv
[1]));
316 FIXME("getter is not JS object\n");
319 /* FIXME: Check IsCallable */
321 hres
= to_flat_string(ctx
, argv
[0], &name_str
, &name
);
325 desc
.flags
= desc
.mask
= PROPF_CONFIGURABLE
| PROPF_ENUMERABLE
;
326 desc
.explicit_getter
= TRUE
;
327 desc
.explicit_setter
= FALSE
;
328 desc
.explicit_value
= FALSE
;
330 hres
= jsdisp_define_property(jsthis
, name
, &desc
);
332 jsstr_release(name_str
);
337 *r
= jsval_undefined();
341 static HRESULT
Object_defineSetter(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
343 property_desc_t desc
;
351 if(!is_object_instance(vthis
) || !(jsthis
= to_jsdisp(get_object(vthis
))))
354 if(argc
< 2 || !is_object_instance(argv
[1]))
355 return JS_E_FUNCTION_EXPECTED
;
357 desc
.setter
= to_jsdisp(get_object(argv
[1]));
359 FIXME("setter is not JS object\n");
362 /* FIXME: Check IsCallable */
364 hres
= to_flat_string(ctx
, argv
[0], &name_str
, &name
);
368 desc
.flags
= desc
.mask
= PROPF_CONFIGURABLE
| PROPF_ENUMERABLE
;
369 desc
.explicit_getter
= FALSE
;
370 desc
.explicit_setter
= TRUE
;
371 desc
.explicit_value
= FALSE
;
373 hres
= jsdisp_define_property(jsthis
, name
, &desc
);
375 jsstr_release(name_str
);
380 *r
= jsval_undefined();
384 HRESULT
Object_get_proto_(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
390 TRACE("%s\n", debugstr_jsval(vthis
));
392 hres
= to_object(ctx
, vthis
, &disp
);
399 if(!(jsthis
= to_jsdisp(disp
))) {
400 FIXME("Host object this\n");
405 *r
= jsthis
->prototype
406 ? jsval_obj(jsdisp_addref(jsthis
->prototype
))
409 IDispatch_Release(disp
);
413 HRESULT
Object_set_proto_(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
415 jsdisp_t
*jsthis
, *proto
;
418 TRACE("%s\n", debugstr_jsval(vthis
));
420 if(is_undefined(vthis
) || is_null(vthis
))
421 return JS_E_OBJECT_EXPECTED
;
424 *r
= jsval_undefined();
427 if(!is_object_instance(vthis
) || !(jsthis
= to_jsdisp(get_object(vthis
))))
430 if(is_null(argv
[0])) {
432 }else if(is_object_instance(argv
[0])) {
433 proto
= to_jsdisp(get_object(argv
[0]));
435 FIXME("Host object value\n");
441 hres
= jsdisp_change_prototype(jsthis
, proto
);
446 return r
? jsval_copy(argv
[0], r
) : S_OK
;
449 static void Object_destructor(jsdisp_t
*dispex
)
454 static const builtin_prop_t Object_props
[] = {
455 {L
"__defineGetter__", Object_defineGetter
, PROPF_METHOD
|PROPF_ES6
|2},
456 {L
"__defineSetter__", Object_defineSetter
, PROPF_METHOD
|PROPF_ES6
|2},
457 {L
"hasOwnProperty", Object_hasOwnProperty
, PROPF_METHOD
|1},
458 {L
"isPrototypeOf", Object_isPrototypeOf
, PROPF_METHOD
|1},
459 {L
"propertyIsEnumerable", Object_propertyIsEnumerable
, PROPF_METHOD
|1},
460 {L
"toLocaleString", Object_toLocaleString
, PROPF_METHOD
},
461 {L
"toString", Object_toString
, PROPF_METHOD
},
462 {L
"valueOf", Object_valueOf
, PROPF_METHOD
}
465 static const builtin_info_t Object_info
= {
468 ARRAY_SIZE(Object_props
),
474 static const builtin_info_t ObjectInst_info
= {
482 static void release_property_descriptor(property_desc_t
*desc
)
484 if(desc
->explicit_value
)
485 jsval_release(desc
->value
);
487 jsdisp_release(desc
->getter
);
489 jsdisp_release(desc
->setter
);
492 static HRESULT
to_property_descriptor(script_ctx_t
*ctx
, jsdisp_t
*attr_obj
, property_desc_t
*desc
)
499 memset(desc
, 0, sizeof(*desc
));
500 desc
->value
= jsval_undefined();
502 hres
= jsdisp_get_id(attr_obj
, L
"enumerable", 0, &id
);
503 if(SUCCEEDED(hres
)) {
504 desc
->mask
|= PROPF_ENUMERABLE
;
505 hres
= jsdisp_propget(attr_obj
, id
, &v
);
508 hres
= to_boolean(v
, &b
);
513 desc
->flags
|= PROPF_ENUMERABLE
;
514 }else if(hres
!= DISP_E_UNKNOWNNAME
) {
518 hres
= jsdisp_get_id(attr_obj
, L
"configurable", 0, &id
);
519 if(SUCCEEDED(hres
)) {
520 desc
->mask
|= PROPF_CONFIGURABLE
;
521 hres
= jsdisp_propget(attr_obj
, id
, &v
);
524 hres
= to_boolean(v
, &b
);
529 desc
->flags
|= PROPF_CONFIGURABLE
;
530 }else if(hres
!= DISP_E_UNKNOWNNAME
) {
534 hres
= jsdisp_get_id(attr_obj
, L
"value", 0, &id
);
535 if(SUCCEEDED(hres
)) {
536 hres
= jsdisp_propget(attr_obj
, id
, &desc
->value
);
539 desc
->explicit_value
= TRUE
;
540 }else if(hres
!= DISP_E_UNKNOWNNAME
) {
544 hres
= jsdisp_get_id(attr_obj
, L
"writable", 0, &id
);
545 if(SUCCEEDED(hres
)) {
546 desc
->mask
|= PROPF_WRITABLE
;
547 hres
= jsdisp_propget(attr_obj
, id
, &v
);
548 if(SUCCEEDED(hres
)) {
549 hres
= to_boolean(v
, &b
);
551 if(SUCCEEDED(hres
) && b
)
552 desc
->flags
|= PROPF_WRITABLE
;
554 }else if(hres
== DISP_E_UNKNOWNNAME
) {
558 release_property_descriptor(desc
);
562 hres
= jsdisp_get_id(attr_obj
, L
"get", 0, &id
);
563 if(SUCCEEDED(hres
)) {
564 desc
->explicit_getter
= TRUE
;
565 hres
= jsdisp_propget(attr_obj
, id
, &v
);
566 if(SUCCEEDED(hres
) && !is_undefined(v
)) {
567 if(!is_object_instance(v
)) {
568 FIXME("getter is not an object\n");
572 /* FIXME: Check IsCallable */
573 desc
->getter
= to_jsdisp(get_object(v
));
575 FIXME("getter is not JS object\n");
578 }else if(hres
== DISP_E_UNKNOWNNAME
) {
582 release_property_descriptor(desc
);
586 hres
= jsdisp_get_id(attr_obj
, L
"set", 0, &id
);
587 if(SUCCEEDED(hres
)) {
588 desc
->explicit_setter
= TRUE
;
589 hres
= jsdisp_propget(attr_obj
, id
, &v
);
590 if(SUCCEEDED(hres
) && !is_undefined(v
)) {
591 if(!is_object_instance(v
)) {
592 FIXME("setter is not an object\n");
596 /* FIXME: Check IsCallable */
597 desc
->setter
= to_jsdisp(get_object(v
));
599 FIXME("setter is not JS object\n");
602 }else if(hres
== DISP_E_UNKNOWNNAME
) {
606 release_property_descriptor(desc
);
610 if(desc
->explicit_getter
|| desc
->explicit_setter
) {
611 if(desc
->explicit_value
)
612 hres
= JS_E_PROP_DESC_MISMATCH
;
613 else if(desc
->mask
& PROPF_WRITABLE
)
614 hres
= JS_E_INVALID_WRITABLE_PROP_DESC
;
618 release_property_descriptor(desc
);
622 static HRESULT
jsdisp_define_properties(script_ctx_t
*ctx
, jsdisp_t
*obj
, jsval_t list_val
)
624 DISPID id
= DISPID_STARTENUM
;
625 property_desc_t prop_desc
;
626 IDispatch
*list_disp
;
627 jsdisp_t
*list_obj
, *desc_obj
;
632 hres
= to_object(ctx
, list_val
, &list_disp
);
636 if(!(list_obj
= to_jsdisp(list_disp
))) {
637 FIXME("non-JS list obj\n");
638 IDispatch_Release(list_disp
);
643 hres
= jsdisp_next_prop(list_obj
, id
, JSDISP_ENUM_OWN_ENUMERABLE
, &id
);
647 hres
= jsdisp_propget(list_obj
, id
, &desc_val
);
651 if(!is_object_instance(desc_val
) || !(desc_obj
= to_jsdisp(get_object(desc_val
)))) {
652 jsval_release(desc_val
);
656 hres
= to_property_descriptor(ctx
, desc_obj
, &prop_desc
);
657 jsdisp_release(desc_obj
);
661 hres
= IDispatchEx_GetMemberName(&list_obj
->IDispatchEx_iface
, id
, &name
);
663 hres
= jsdisp_define_property(obj
, name
, &prop_desc
);
664 release_property_descriptor(&prop_desc
);
669 jsdisp_release(list_obj
);
670 return FAILED(hres
) ? hres
: S_OK
;
673 static HRESULT
Object_defineProperty(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
,
674 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
676 property_desc_t prop_desc
;
677 jsdisp_t
*obj
, *attr_obj
;
684 if(argc
< 1 || !is_object_instance(argv
[0]))
685 return JS_E_OBJECT_EXPECTED
;
686 obj
= to_jsdisp(get_object(argv
[0]));
688 FIXME("not implemented non-JS object\n");
692 hres
= to_flat_string(ctx
, argc
>= 2 ? argv
[1] : jsval_undefined(), &name_str
, &name
);
696 if(argc
>= 3 && is_object_instance(argv
[2])) {
697 attr_obj
= to_jsdisp(get_object(argv
[2]));
699 hres
= to_property_descriptor(ctx
, attr_obj
, &prop_desc
);
701 FIXME("not implemented non-JS object\n");
705 hres
= JS_E_OBJECT_EXPECTED
;
710 jsstr_release(name_str
);
714 hres
= jsdisp_define_property(obj
, name
, &prop_desc
);
715 jsstr_release(name_str
);
716 release_property_descriptor(&prop_desc
);
717 if(SUCCEEDED(hres
) && r
)
718 *r
= jsval_obj(jsdisp_addref(obj
));
722 static HRESULT
Object_defineProperties(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
,
723 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
728 if(argc
< 1 || !is_object_instance(argv
[0]) || !(obj
= to_jsdisp(get_object(argv
[0])))) {
729 FIXME("not an object\n");
735 hres
= jsdisp_define_properties(ctx
, obj
, argc
>= 2 ? argv
[1] : jsval_undefined());
736 if(SUCCEEDED(hres
) && r
)
737 *r
= jsval_obj(jsdisp_addref(obj
));
741 static HRESULT
Object_getOwnPropertyDescriptor(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
,
742 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
744 property_desc_t prop_desc
;
745 jsdisp_t
*obj
, *desc_obj
;
752 if(argc
< 1 || !is_object_instance(argv
[0]))
753 return JS_E_OBJECT_EXPECTED
;
754 obj
= to_jsdisp(get_object(argv
[0]));
756 FIXME("not implemented non-JS object\n");
760 hres
= to_flat_string(ctx
, argc
>= 2 ? argv
[1] : jsval_undefined(), &name_str
, &name
);
764 hres
= jsdisp_get_own_property(obj
, name
, FALSE
, &prop_desc
);
765 jsstr_release(name_str
);
766 if(hres
== DISP_E_UNKNOWNNAME
) {
767 if(r
) *r
= jsval_undefined();
773 hres
= create_object(ctx
, NULL
, &desc_obj
);
777 if(prop_desc
.explicit_getter
|| prop_desc
.explicit_setter
) {
778 hres
= jsdisp_define_data_property(desc_obj
, L
"get", PROPF_ALL
,
779 prop_desc
.getter
? jsval_obj(prop_desc
.getter
) : jsval_undefined());
781 hres
= jsdisp_define_data_property(desc_obj
, L
"set", PROPF_ALL
,
782 prop_desc
.setter
? jsval_obj(prop_desc
.setter
) : jsval_undefined());
784 hres
= jsdisp_propput_name(desc_obj
, L
"value", prop_desc
.value
);
786 hres
= jsdisp_define_data_property(desc_obj
, L
"writable", PROPF_ALL
,
787 jsval_bool(!!(prop_desc
.flags
& PROPF_WRITABLE
)));
790 hres
= jsdisp_define_data_property(desc_obj
, L
"enumerable", PROPF_ALL
,
791 jsval_bool(!!(prop_desc
.flags
& PROPF_ENUMERABLE
)));
793 hres
= jsdisp_define_data_property(desc_obj
, L
"configurable", PROPF_ALL
,
794 jsval_bool(!!(prop_desc
.flags
& PROPF_CONFIGURABLE
)));
796 release_property_descriptor(&prop_desc
);
797 if(SUCCEEDED(hres
) && r
)
798 *r
= jsval_obj(desc_obj
);
800 jsdisp_release(desc_obj
);
804 static HRESULT
Object_create(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
,
805 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
807 jsdisp_t
*proto
= NULL
, *obj
;
810 if(!argc
|| (!is_object_instance(argv
[0]) && !is_null(argv
[0]))) {
811 FIXME("Invalid arg\n");
815 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
817 if(argc
&& is_object_instance(argv
[0])) {
818 if(get_object(argv
[0]))
819 proto
= to_jsdisp(get_object(argv
[0]));
821 FIXME("Non-JS prototype\n");
824 }else if(!is_null(argv
[0])) {
825 FIXME("Invalid arg %s\n", debugstr_jsval(argc
? argv
[0] : jsval_undefined()));
829 hres
= create_dispex(ctx
, &ObjectInst_info
, proto
, &obj
);
833 if(argc
>= 2 && !is_undefined(argv
[1]))
834 hres
= jsdisp_define_properties(ctx
, obj
, argv
[1]);
836 if(SUCCEEDED(hres
) && r
)
843 static HRESULT
Object_getPrototypeOf(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
,
844 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
848 if(!argc
|| !is_object_instance(argv
[0]))
849 return JS_E_OBJECT_EXPECTED
;
851 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
853 obj
= to_jsdisp(get_object(argv
[0]));
855 *r
= obj
&& obj
->prototype
856 ? jsval_obj(jsdisp_addref(obj
->prototype
))
861 static HRESULT
object_keys(script_ctx_t
*ctx
, jsval_t arg
, enum jsdisp_enum_type enum_type
, jsval_t
*r
)
863 DISPID id
= DISPID_STARTENUM
;
864 jsdisp_t
*obj
, *array
;
869 if(!is_object_instance(arg
))
870 return JS_E_OBJECT_EXPECTED
;
872 obj
= to_jsdisp(get_object(arg
));
874 FIXME("Non-JS object\n");
878 hres
= create_array(ctx
, 0, &array
);
883 hres
= jsdisp_next_prop(obj
, id
, enum_type
, &id
);
887 hres
= jsdisp_get_prop_name(obj
, id
, &key
);
891 hres
= jsdisp_propput_idx(array
, i
++, jsval_string(key
));
893 } while(hres
== S_OK
);
895 if(SUCCEEDED(hres
) && r
)
896 *r
= jsval_obj(array
);
898 jsdisp_release(array
);
902 static HRESULT
Object_keys(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
,
903 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
905 jsval_t arg
= argc
? argv
[0] : jsval_undefined();
907 TRACE("(%s)\n", debugstr_jsval(arg
));
909 return object_keys(ctx
, arg
, JSDISP_ENUM_OWN_ENUMERABLE
, r
);
912 static HRESULT
Object_getOwnPropertyNames(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
,
913 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
915 jsval_t arg
= argc
? argv
[0] : jsval_undefined();
917 TRACE("(%s)\n", debugstr_jsval(arg
));
919 return object_keys(ctx
, arg
, JSDISP_ENUM_OWN
, r
);
922 static HRESULT
Object_preventExtensions(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
926 if(!argc
|| !is_object_instance(argv
[0]))
927 return JS_E_OBJECT_EXPECTED
;
929 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
931 obj
= to_jsdisp(get_object(argv
[0]));
933 FIXME("Non-JS object\n");
937 obj
->extensible
= FALSE
;
938 if(r
) *r
= jsval_obj(jsdisp_addref(obj
));
942 static HRESULT
Object_freeze(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
,
943 jsval_t
*argv
, jsval_t
*r
)
947 if(!argc
|| !is_object_instance(argv
[0])) {
948 WARN("argument is not an object\n");
949 return JS_E_OBJECT_EXPECTED
;
952 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
954 obj
= to_jsdisp(get_object(argv
[0]));
956 FIXME("Non-JS object\n");
960 jsdisp_freeze(obj
, FALSE
);
961 if(r
) *r
= jsval_obj(jsdisp_addref(obj
));
965 static HRESULT
Object_seal(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
,
966 jsval_t
*argv
, jsval_t
*r
)
970 if(!argc
|| !is_object_instance(argv
[0])) {
971 WARN("argument is not an object\n");
972 return JS_E_OBJECT_EXPECTED
;
975 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
977 obj
= to_jsdisp(get_object(argv
[0]));
979 FIXME("Non-JS object\n");
983 jsdisp_freeze(obj
, TRUE
);
984 if(r
) *r
= jsval_obj(jsdisp_addref(obj
));
988 static HRESULT
Object_isExtensible(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
992 if(!argc
|| !is_object_instance(argv
[0])) {
993 WARN("argument is not an object\n");
994 return JS_E_OBJECT_EXPECTED
;
997 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
999 obj
= to_jsdisp(get_object(argv
[0]));
1001 FIXME("Non-JS object\n");
1005 if(r
) *r
= jsval_bool(obj
->extensible
);
1009 static HRESULT
Object_isFrozen(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
,
1010 jsval_t
*argv
, jsval_t
*r
)
1014 if(!argc
|| !is_object_instance(argv
[0])) {
1015 WARN("argument is not an object\n");
1016 return JS_E_OBJECT_EXPECTED
;
1019 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
1021 obj
= to_jsdisp(get_object(argv
[0]));
1023 FIXME("Non-JS object\n");
1027 if(r
) *r
= jsval_bool(jsdisp_is_frozen(obj
, FALSE
));
1031 static HRESULT
Object_isSealed(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
,
1032 jsval_t
*argv
, jsval_t
*r
)
1036 if(!argc
|| !is_object_instance(argv
[0])) {
1037 WARN("argument is not an object\n");
1038 return JS_E_OBJECT_EXPECTED
;
1041 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
1043 obj
= to_jsdisp(get_object(argv
[0]));
1045 FIXME("Non-JS object\n");
1049 if(r
) *r
= jsval_bool(jsdisp_is_frozen(obj
, TRUE
));
1053 static const builtin_prop_t ObjectConstr_props
[] = {
1054 {L
"create", Object_create
, PROPF_ES5
|PROPF_METHOD
|2},
1055 {L
"defineProperties", Object_defineProperties
, PROPF_ES5
|PROPF_METHOD
|2},
1056 {L
"defineProperty", Object_defineProperty
, PROPF_ES5
|PROPF_METHOD
|2},
1057 {L
"freeze", Object_freeze
, PROPF_ES5
|PROPF_METHOD
|1},
1058 {L
"getOwnPropertyDescriptor", Object_getOwnPropertyDescriptor
, PROPF_ES5
|PROPF_METHOD
|2},
1059 {L
"getOwnPropertyNames", Object_getOwnPropertyNames
, PROPF_ES5
|PROPF_METHOD
|1},
1060 {L
"getPrototypeOf", Object_getPrototypeOf
, PROPF_ES5
|PROPF_METHOD
|1},
1061 {L
"isExtensible", Object_isExtensible
, PROPF_ES5
|PROPF_METHOD
|1},
1062 {L
"isFrozen", Object_isFrozen
, PROPF_ES5
|PROPF_METHOD
|1},
1063 {L
"isSealed", Object_isSealed
, PROPF_ES5
|PROPF_METHOD
|1},
1064 {L
"keys", Object_keys
, PROPF_ES5
|PROPF_METHOD
|1},
1065 {L
"preventExtensions", Object_preventExtensions
, PROPF_ES5
|PROPF_METHOD
|1},
1066 {L
"seal", Object_seal
, PROPF_ES5
|PROPF_METHOD
|1},
1069 static const builtin_info_t ObjectConstr_info
= {
1072 ARRAY_SIZE(ObjectConstr_props
),
1078 static HRESULT
ObjectConstr_value(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
1086 case DISPATCH_METHOD
:
1087 case DISPATCH_CONSTRUCT
: {
1091 if(!is_undefined(argv
[0]) && !is_null(argv
[0])) {
1094 hres
= to_object(ctx
, argv
[0], &disp
);
1099 *r
= jsval_disp(disp
);
1101 IDispatch_Release(disp
);
1106 hres
= create_object(ctx
, NULL
, &obj
);
1111 *r
= jsval_obj(obj
);
1113 jsdisp_release(obj
);
1118 FIXME("unimplemented flags: %x\n", flags
);
1125 HRESULT
create_object_constr(script_ctx_t
*ctx
, jsdisp_t
*object_prototype
, jsdisp_t
**ret
)
1127 return create_builtin_constructor(ctx
, ObjectConstr_value
, L
"Object", &ObjectConstr_info
, PROPF_CONSTR
,
1128 object_prototype
, ret
);
1131 HRESULT
create_object_prototype(script_ctx_t
*ctx
, jsdisp_t
**ret
)
1133 return create_dispex(ctx
, &Object_info
, NULL
, ret
);
1136 HRESULT
create_object(script_ctx_t
*ctx
, jsdisp_t
*constr
, jsdisp_t
**ret
)
1141 object
= calloc(1, sizeof(jsdisp_t
));
1143 return E_OUTOFMEMORY
;
1145 hres
= init_dispex_from_constr(object
, ctx
, &ObjectInst_info
, constr
? constr
: ctx
->object_constr
);