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
[] = {
53 L
"[object ArrayBuffer]",
62 if(is_undefined(vthis
) || is_null(vthis
)) {
63 if(ctx
->version
< SCRIPTLANGUAGEVERSION_ES5
)
64 str
= L
"[object Object]";
66 str
= is_null(vthis
) ? L
"[object Null]" : L
"[object Undefined]";
70 hres
= to_object(ctx
, vthis
, &disp
);
74 jsdisp
= to_jsdisp(disp
);
76 str
= L
"[object Object]";
77 }else if(names
[jsdisp
->builtin_info
->class]) {
78 str
= names
[jsdisp
->builtin_info
->class];
80 assert(jsdisp
->builtin_info
->class != JSCLASS_NONE
);
81 FIXME("jsdisp->builtin_info->class = %d\n", jsdisp
->builtin_info
->class);
84 IDispatch_Release(disp
);
91 ret
= jsstr_alloc(str
);
94 *r
= jsval_string(ret
);
100 static HRESULT
Object_toLocaleString(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
109 hres
= to_object(ctx
, vthis
, &disp
);
113 if(!(jsdisp
= to_jsdisp(disp
))) {
114 FIXME("Host object this\n");
119 hres
= jsdisp_call_name(jsdisp
, L
"toString", DISPATCH_METHOD
, 0, NULL
, r
);
121 IDispatch_Release(disp
);
125 static HRESULT
Object_valueOf(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
133 if(is_null_disp(vthis
)) {
134 if(r
) *r
= jsval_null_disp();
138 hres
= to_object(ctx
, vthis
, &disp
);
143 *r
= jsval_disp(disp
);
145 IDispatch_Release(disp
);
149 static HRESULT
Object_hasOwnProperty(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
162 hres
= to_object(ctx
, vthis
, &disp
);
168 *r
= jsval_bool(FALSE
);
172 hres
= to_string(ctx
, argv
[0], &name
);
176 if((jsdisp
= to_jsdisp(disp
))) {
177 property_desc_t prop_desc
;
178 const WCHAR
*name_str
;
180 name_str
= jsstr_flatten(name
);
183 hres
= E_OUTOFMEMORY
;
187 hres
= jsdisp_get_own_property(jsdisp
, name_str
, TRUE
, &prop_desc
);
189 if(FAILED(hres
) && hres
!= DISP_E_UNKNOWNNAME
)
192 if(r
) *r
= jsval_bool(hres
== S_OK
);
198 bstr
= SysAllocStringLen(NULL
, jsstr_length(name
));
200 jsstr_flush(name
, bstr
);
203 hres
= E_OUTOFMEMORY
;
207 hres
= IDispatch_QueryInterface(disp
, &IID_IDispatchEx
, (void**)&dispex
);
208 if(SUCCEEDED(hres
)) {
209 hres
= IDispatchEx_GetDispID(dispex
, bstr
, make_grfdex(ctx
, fdexNameCaseSensitive
), &id
);
210 IDispatchEx_Release(dispex
);
212 hres
= IDispatch_GetIDsOfNames(disp
, &IID_NULL
, &bstr
, 1, ctx
->lcid
, &id
);
216 *r
= jsval_bool(SUCCEEDED(hres
));
219 IDispatch_Release(disp
);
223 static HRESULT
Object_propertyIsEnumerable(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
226 property_desc_t prop_desc
;
235 hres
= to_object(ctx
, vthis
, &disp
);
240 FIXME("argc %d not supported\n", argc
);
245 if(!(jsdisp
= to_jsdisp(disp
))) {
246 FIXME("Host object this\n");
251 hres
= to_flat_string(ctx
, argv
[0], &name_str
, &name
);
255 hres
= jsdisp_get_own_property(jsdisp
, name
, TRUE
, &prop_desc
);
256 jsstr_release(name_str
);
257 if(FAILED(hres
) && hres
!= DISP_E_UNKNOWNNAME
)
261 *r
= jsval_bool(hres
== S_OK
&& (prop_desc
.flags
& PROPF_ENUMERABLE
) != 0);
264 IDispatch_Release(disp
);
268 static HRESULT
Object_isPrototypeOf(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
271 jsdisp_t
*jsthis
, *jsdisp
;
276 hres
= to_object(ctx
, vthis
, &disp
);
283 if(argc
&& (jsthis
= to_jsdisp(disp
)) && is_object_instance(argv
[0]) &&
284 (jsdisp
= to_jsdisp(get_object(argv
[0])))) {
285 while(jsdisp
->prototype
) {
286 if(jsdisp
->prototype
== jsthis
) {
290 jsdisp
= jsdisp
->prototype
;
294 *r
= jsval_bool(ret
);
296 IDispatch_Release(disp
);
300 static HRESULT
Object_defineGetter(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
302 property_desc_t desc
;
310 if(!is_object_instance(vthis
) || !(jsthis
= to_jsdisp(get_object(vthis
))))
313 if(argc
< 2 || !is_object_instance(argv
[1]))
314 return JS_E_FUNCTION_EXPECTED
;
316 desc
.getter
= to_jsdisp(get_object(argv
[1]));
318 FIXME("getter is not JS object\n");
321 /* FIXME: Check IsCallable */
323 hres
= to_flat_string(ctx
, argv
[0], &name_str
, &name
);
327 desc
.flags
= desc
.mask
= PROPF_CONFIGURABLE
| PROPF_ENUMERABLE
;
328 desc
.explicit_getter
= TRUE
;
329 desc
.explicit_setter
= FALSE
;
330 desc
.explicit_value
= FALSE
;
332 hres
= jsdisp_define_property(jsthis
, name
, &desc
);
334 jsstr_release(name_str
);
339 *r
= jsval_undefined();
343 static HRESULT
Object_defineSetter(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
345 property_desc_t desc
;
353 if(!is_object_instance(vthis
) || !(jsthis
= to_jsdisp(get_object(vthis
))))
356 if(argc
< 2 || !is_object_instance(argv
[1]))
357 return JS_E_FUNCTION_EXPECTED
;
359 desc
.setter
= to_jsdisp(get_object(argv
[1]));
361 FIXME("setter is not JS object\n");
364 /* FIXME: Check IsCallable */
366 hres
= to_flat_string(ctx
, argv
[0], &name_str
, &name
);
370 desc
.flags
= desc
.mask
= PROPF_CONFIGURABLE
| PROPF_ENUMERABLE
;
371 desc
.explicit_getter
= FALSE
;
372 desc
.explicit_setter
= TRUE
;
373 desc
.explicit_value
= FALSE
;
375 hres
= jsdisp_define_property(jsthis
, name
, &desc
);
377 jsstr_release(name_str
);
382 *r
= jsval_undefined();
386 HRESULT
Object_get_proto_(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
392 TRACE("%s\n", debugstr_jsval(vthis
));
394 hres
= to_object(ctx
, vthis
, &disp
);
401 if(!(jsthis
= to_jsdisp(disp
))) {
402 FIXME("Host object this\n");
407 *r
= jsthis
->prototype
408 ? jsval_obj(jsdisp_addref(jsthis
->prototype
))
411 IDispatch_Release(disp
);
415 HRESULT
Object_set_proto_(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
417 jsdisp_t
*jsthis
, *proto
;
420 TRACE("%s\n", debugstr_jsval(vthis
));
422 if(is_undefined(vthis
) || is_null(vthis
))
423 return JS_E_OBJECT_EXPECTED
;
426 *r
= jsval_undefined();
429 if(!is_object_instance(vthis
) || !(jsthis
= to_jsdisp(get_object(vthis
))))
432 if(is_null(argv
[0])) {
434 }else if(is_object_instance(argv
[0])) {
435 proto
= to_jsdisp(get_object(argv
[0]));
437 FIXME("Host object value\n");
443 hres
= jsdisp_change_prototype(jsthis
, proto
);
448 return r
? jsval_copy(argv
[0], r
) : S_OK
;
451 static void Object_destructor(jsdisp_t
*dispex
)
456 static const builtin_prop_t Object_props
[] = {
457 {L
"__defineGetter__", Object_defineGetter
, PROPF_METHOD
|PROPF_ES6
|2},
458 {L
"__defineSetter__", Object_defineSetter
, PROPF_METHOD
|PROPF_ES6
|2},
459 {L
"hasOwnProperty", Object_hasOwnProperty
, PROPF_METHOD
|1},
460 {L
"isPrototypeOf", Object_isPrototypeOf
, PROPF_METHOD
|1},
461 {L
"propertyIsEnumerable", Object_propertyIsEnumerable
, PROPF_METHOD
|1},
462 {L
"toLocaleString", Object_toLocaleString
, PROPF_METHOD
},
463 {L
"toString", Object_toString
, PROPF_METHOD
},
464 {L
"valueOf", Object_valueOf
, PROPF_METHOD
}
467 static const builtin_info_t Object_info
= {
470 ARRAY_SIZE(Object_props
),
476 static const builtin_info_t ObjectInst_info
= {
484 static void release_property_descriptor(property_desc_t
*desc
)
486 if(desc
->explicit_value
)
487 jsval_release(desc
->value
);
489 jsdisp_release(desc
->getter
);
491 jsdisp_release(desc
->setter
);
494 static HRESULT
to_property_descriptor(script_ctx_t
*ctx
, jsdisp_t
*attr_obj
, property_desc_t
*desc
)
501 memset(desc
, 0, sizeof(*desc
));
502 desc
->value
= jsval_undefined();
504 hres
= jsdisp_get_id(attr_obj
, L
"enumerable", 0, &id
);
505 if(SUCCEEDED(hres
)) {
506 desc
->mask
|= PROPF_ENUMERABLE
;
507 hres
= jsdisp_propget(attr_obj
, id
, &v
);
510 hres
= to_boolean(v
, &b
);
515 desc
->flags
|= PROPF_ENUMERABLE
;
516 }else if(hres
!= DISP_E_UNKNOWNNAME
) {
520 hres
= jsdisp_get_id(attr_obj
, L
"configurable", 0, &id
);
521 if(SUCCEEDED(hres
)) {
522 desc
->mask
|= PROPF_CONFIGURABLE
;
523 hres
= jsdisp_propget(attr_obj
, id
, &v
);
526 hres
= to_boolean(v
, &b
);
531 desc
->flags
|= PROPF_CONFIGURABLE
;
532 }else if(hres
!= DISP_E_UNKNOWNNAME
) {
536 hres
= jsdisp_get_id(attr_obj
, L
"value", 0, &id
);
537 if(SUCCEEDED(hres
)) {
538 hres
= jsdisp_propget(attr_obj
, id
, &desc
->value
);
541 desc
->explicit_value
= TRUE
;
542 }else if(hres
!= DISP_E_UNKNOWNNAME
) {
546 hres
= jsdisp_get_id(attr_obj
, L
"writable", 0, &id
);
547 if(SUCCEEDED(hres
)) {
548 desc
->mask
|= PROPF_WRITABLE
;
549 hres
= jsdisp_propget(attr_obj
, id
, &v
);
550 if(SUCCEEDED(hres
)) {
551 hres
= to_boolean(v
, &b
);
553 if(SUCCEEDED(hres
) && b
)
554 desc
->flags
|= PROPF_WRITABLE
;
556 }else if(hres
== DISP_E_UNKNOWNNAME
) {
560 release_property_descriptor(desc
);
564 hres
= jsdisp_get_id(attr_obj
, L
"get", 0, &id
);
565 if(SUCCEEDED(hres
)) {
566 desc
->explicit_getter
= TRUE
;
567 hres
= jsdisp_propget(attr_obj
, id
, &v
);
568 if(SUCCEEDED(hres
) && !is_undefined(v
)) {
569 if(!is_object_instance(v
)) {
570 FIXME("getter is not an object\n");
574 /* FIXME: Check IsCallable */
575 desc
->getter
= to_jsdisp(get_object(v
));
577 FIXME("getter is not JS object\n");
580 }else if(hres
== DISP_E_UNKNOWNNAME
) {
584 release_property_descriptor(desc
);
588 hres
= jsdisp_get_id(attr_obj
, L
"set", 0, &id
);
589 if(SUCCEEDED(hres
)) {
590 desc
->explicit_setter
= TRUE
;
591 hres
= jsdisp_propget(attr_obj
, id
, &v
);
592 if(SUCCEEDED(hres
) && !is_undefined(v
)) {
593 if(!is_object_instance(v
)) {
594 FIXME("setter is not an object\n");
598 /* FIXME: Check IsCallable */
599 desc
->setter
= to_jsdisp(get_object(v
));
601 FIXME("setter is not JS object\n");
604 }else if(hres
== DISP_E_UNKNOWNNAME
) {
608 release_property_descriptor(desc
);
612 if(desc
->explicit_getter
|| desc
->explicit_setter
) {
613 if(desc
->explicit_value
)
614 hres
= JS_E_PROP_DESC_MISMATCH
;
615 else if(desc
->mask
& PROPF_WRITABLE
)
616 hres
= JS_E_INVALID_WRITABLE_PROP_DESC
;
620 release_property_descriptor(desc
);
624 static HRESULT
jsdisp_define_properties(script_ctx_t
*ctx
, jsdisp_t
*obj
, jsval_t list_val
)
626 DISPID id
= DISPID_STARTENUM
;
627 property_desc_t prop_desc
;
628 IDispatch
*list_disp
;
629 jsdisp_t
*list_obj
, *desc_obj
;
634 hres
= to_object(ctx
, list_val
, &list_disp
);
638 if(!(list_obj
= to_jsdisp(list_disp
))) {
639 FIXME("non-JS list obj\n");
640 IDispatch_Release(list_disp
);
645 hres
= jsdisp_next_prop(list_obj
, id
, JSDISP_ENUM_OWN_ENUMERABLE
, &id
);
649 hres
= jsdisp_propget(list_obj
, id
, &desc_val
);
653 if(!is_object_instance(desc_val
) || !(desc_obj
= to_jsdisp(get_object(desc_val
)))) {
654 jsval_release(desc_val
);
658 hres
= to_property_descriptor(ctx
, desc_obj
, &prop_desc
);
659 jsdisp_release(desc_obj
);
663 hres
= IDispatchEx_GetMemberName(&list_obj
->IDispatchEx_iface
, id
, &name
);
665 hres
= jsdisp_define_property(obj
, name
, &prop_desc
);
666 release_property_descriptor(&prop_desc
);
671 jsdisp_release(list_obj
);
672 return FAILED(hres
) ? hres
: S_OK
;
675 static HRESULT
Object_defineProperty(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
,
676 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
678 property_desc_t prop_desc
;
679 jsdisp_t
*obj
, *attr_obj
;
686 if(argc
< 1 || !is_object_instance(argv
[0]))
687 return JS_E_OBJECT_EXPECTED
;
688 obj
= to_jsdisp(get_object(argv
[0]));
690 FIXME("not implemented non-JS object\n");
694 hres
= to_flat_string(ctx
, argc
>= 2 ? argv
[1] : jsval_undefined(), &name_str
, &name
);
698 if(argc
>= 3 && is_object_instance(argv
[2])) {
699 attr_obj
= to_jsdisp(get_object(argv
[2]));
701 hres
= to_property_descriptor(ctx
, attr_obj
, &prop_desc
);
703 FIXME("not implemented non-JS object\n");
707 hres
= JS_E_OBJECT_EXPECTED
;
712 jsstr_release(name_str
);
716 hres
= jsdisp_define_property(obj
, name
, &prop_desc
);
717 jsstr_release(name_str
);
718 release_property_descriptor(&prop_desc
);
719 if(SUCCEEDED(hres
) && r
)
720 *r
= jsval_obj(jsdisp_addref(obj
));
724 static HRESULT
Object_defineProperties(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
,
725 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
730 if(argc
< 1 || !is_object_instance(argv
[0]) || !(obj
= to_jsdisp(get_object(argv
[0])))) {
731 FIXME("not an object\n");
737 hres
= jsdisp_define_properties(ctx
, obj
, argc
>= 2 ? argv
[1] : jsval_undefined());
738 if(SUCCEEDED(hres
) && r
)
739 *r
= jsval_obj(jsdisp_addref(obj
));
743 static HRESULT
Object_getOwnPropertyDescriptor(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
,
744 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
746 property_desc_t prop_desc
;
747 jsdisp_t
*obj
, *desc_obj
;
754 if(argc
< 1 || !is_object_instance(argv
[0]))
755 return JS_E_OBJECT_EXPECTED
;
756 obj
= to_jsdisp(get_object(argv
[0]));
758 FIXME("not implemented non-JS object\n");
762 hres
= to_flat_string(ctx
, argc
>= 2 ? argv
[1] : jsval_undefined(), &name_str
, &name
);
766 hres
= jsdisp_get_own_property(obj
, name
, FALSE
, &prop_desc
);
767 jsstr_release(name_str
);
768 if(hres
== DISP_E_UNKNOWNNAME
) {
769 if(r
) *r
= jsval_undefined();
775 hres
= create_object(ctx
, NULL
, &desc_obj
);
779 if(prop_desc
.explicit_getter
|| prop_desc
.explicit_setter
) {
780 hres
= jsdisp_define_data_property(desc_obj
, L
"get", PROPF_ALL
,
781 prop_desc
.getter
? jsval_obj(prop_desc
.getter
) : jsval_undefined());
783 hres
= jsdisp_define_data_property(desc_obj
, L
"set", PROPF_ALL
,
784 prop_desc
.setter
? jsval_obj(prop_desc
.setter
) : jsval_undefined());
786 hres
= jsdisp_propput_name(desc_obj
, L
"value", prop_desc
.value
);
788 hres
= jsdisp_define_data_property(desc_obj
, L
"writable", PROPF_ALL
,
789 jsval_bool(!!(prop_desc
.flags
& PROPF_WRITABLE
)));
792 hres
= jsdisp_define_data_property(desc_obj
, L
"enumerable", PROPF_ALL
,
793 jsval_bool(!!(prop_desc
.flags
& PROPF_ENUMERABLE
)));
795 hres
= jsdisp_define_data_property(desc_obj
, L
"configurable", PROPF_ALL
,
796 jsval_bool(!!(prop_desc
.flags
& PROPF_CONFIGURABLE
)));
798 release_property_descriptor(&prop_desc
);
799 if(SUCCEEDED(hres
) && r
)
800 *r
= jsval_obj(desc_obj
);
802 jsdisp_release(desc_obj
);
806 static HRESULT
Object_create(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
,
807 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
809 jsdisp_t
*proto
= NULL
, *obj
;
812 if(!argc
|| (!is_object_instance(argv
[0]) && !is_null(argv
[0]))) {
813 FIXME("Invalid arg\n");
817 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
819 if(argc
&& is_object_instance(argv
[0])) {
820 if(get_object(argv
[0]))
821 proto
= to_jsdisp(get_object(argv
[0]));
823 FIXME("Non-JS prototype\n");
826 }else if(!is_null(argv
[0])) {
827 FIXME("Invalid arg %s\n", debugstr_jsval(argc
? argv
[0] : jsval_undefined()));
831 hres
= create_dispex(ctx
, &ObjectInst_info
, proto
, &obj
);
835 if(argc
>= 2 && !is_undefined(argv
[1]))
836 hres
= jsdisp_define_properties(ctx
, obj
, argv
[1]);
838 if(SUCCEEDED(hres
) && r
)
845 static HRESULT
Object_getPrototypeOf(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
,
846 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
850 if(!argc
|| !is_object_instance(argv
[0]))
851 return JS_E_OBJECT_EXPECTED
;
853 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
855 obj
= to_jsdisp(get_object(argv
[0]));
857 *r
= obj
&& obj
->prototype
858 ? jsval_obj(jsdisp_addref(obj
->prototype
))
863 static HRESULT
object_keys(script_ctx_t
*ctx
, jsval_t arg
, enum jsdisp_enum_type enum_type
, jsval_t
*r
)
865 DISPID id
= DISPID_STARTENUM
;
866 jsdisp_t
*obj
, *array
;
871 if(!is_object_instance(arg
))
872 return JS_E_OBJECT_EXPECTED
;
874 obj
= to_jsdisp(get_object(arg
));
876 FIXME("Non-JS object\n");
880 hres
= create_array(ctx
, 0, &array
);
885 hres
= jsdisp_next_prop(obj
, id
, enum_type
, &id
);
889 hres
= jsdisp_get_prop_name(obj
, id
, &key
);
893 hres
= jsdisp_propput_idx(array
, i
++, jsval_string(key
));
895 } while(hres
== S_OK
);
897 if(SUCCEEDED(hres
) && r
)
898 *r
= jsval_obj(array
);
900 jsdisp_release(array
);
904 static HRESULT
Object_keys(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
,
905 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
907 jsval_t arg
= argc
? argv
[0] : jsval_undefined();
909 TRACE("(%s)\n", debugstr_jsval(arg
));
911 return object_keys(ctx
, arg
, JSDISP_ENUM_OWN_ENUMERABLE
, r
);
914 static HRESULT
Object_getOwnPropertyNames(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
,
915 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
917 jsval_t arg
= argc
? argv
[0] : jsval_undefined();
919 TRACE("(%s)\n", debugstr_jsval(arg
));
921 return object_keys(ctx
, arg
, JSDISP_ENUM_OWN
, r
);
924 static HRESULT
Object_preventExtensions(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
928 if(!argc
|| !is_object_instance(argv
[0]))
929 return JS_E_OBJECT_EXPECTED
;
931 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
933 obj
= to_jsdisp(get_object(argv
[0]));
935 FIXME("Non-JS object\n");
939 obj
->extensible
= FALSE
;
940 if(r
) *r
= jsval_obj(jsdisp_addref(obj
));
944 static HRESULT
Object_freeze(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
,
945 jsval_t
*argv
, jsval_t
*r
)
949 if(!argc
|| !is_object_instance(argv
[0])) {
950 WARN("argument is not an object\n");
951 return JS_E_OBJECT_EXPECTED
;
954 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
956 obj
= to_jsdisp(get_object(argv
[0]));
958 FIXME("Non-JS object\n");
962 jsdisp_freeze(obj
, FALSE
);
963 if(r
) *r
= jsval_obj(jsdisp_addref(obj
));
967 static HRESULT
Object_seal(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
,
968 jsval_t
*argv
, jsval_t
*r
)
972 if(!argc
|| !is_object_instance(argv
[0])) {
973 WARN("argument is not an object\n");
974 return JS_E_OBJECT_EXPECTED
;
977 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
979 obj
= to_jsdisp(get_object(argv
[0]));
981 FIXME("Non-JS object\n");
985 jsdisp_freeze(obj
, TRUE
);
986 if(r
) *r
= jsval_obj(jsdisp_addref(obj
));
990 static HRESULT
Object_isExtensible(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
994 if(!argc
|| !is_object_instance(argv
[0])) {
995 WARN("argument is not an object\n");
996 return JS_E_OBJECT_EXPECTED
;
999 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
1001 obj
= to_jsdisp(get_object(argv
[0]));
1003 FIXME("Non-JS object\n");
1007 if(r
) *r
= jsval_bool(obj
->extensible
);
1011 static HRESULT
Object_isFrozen(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
,
1012 jsval_t
*argv
, jsval_t
*r
)
1016 if(!argc
|| !is_object_instance(argv
[0])) {
1017 WARN("argument is not an object\n");
1018 return JS_E_OBJECT_EXPECTED
;
1021 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
1023 obj
= to_jsdisp(get_object(argv
[0]));
1025 FIXME("Non-JS object\n");
1029 if(r
) *r
= jsval_bool(jsdisp_is_frozen(obj
, FALSE
));
1033 static HRESULT
Object_isSealed(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
,
1034 jsval_t
*argv
, jsval_t
*r
)
1038 if(!argc
|| !is_object_instance(argv
[0])) {
1039 WARN("argument is not an object\n");
1040 return JS_E_OBJECT_EXPECTED
;
1043 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
1045 obj
= to_jsdisp(get_object(argv
[0]));
1047 FIXME("Non-JS object\n");
1051 if(r
) *r
= jsval_bool(jsdisp_is_frozen(obj
, TRUE
));
1055 static const builtin_prop_t ObjectConstr_props
[] = {
1056 {L
"create", Object_create
, PROPF_ES5
|PROPF_METHOD
|2},
1057 {L
"defineProperties", Object_defineProperties
, PROPF_ES5
|PROPF_METHOD
|2},
1058 {L
"defineProperty", Object_defineProperty
, PROPF_ES5
|PROPF_METHOD
|2},
1059 {L
"freeze", Object_freeze
, PROPF_ES5
|PROPF_METHOD
|1},
1060 {L
"getOwnPropertyDescriptor", Object_getOwnPropertyDescriptor
, PROPF_ES5
|PROPF_METHOD
|2},
1061 {L
"getOwnPropertyNames", Object_getOwnPropertyNames
, PROPF_ES5
|PROPF_METHOD
|1},
1062 {L
"getPrototypeOf", Object_getPrototypeOf
, PROPF_ES5
|PROPF_METHOD
|1},
1063 {L
"isExtensible", Object_isExtensible
, PROPF_ES5
|PROPF_METHOD
|1},
1064 {L
"isFrozen", Object_isFrozen
, PROPF_ES5
|PROPF_METHOD
|1},
1065 {L
"isSealed", Object_isSealed
, PROPF_ES5
|PROPF_METHOD
|1},
1066 {L
"keys", Object_keys
, PROPF_ES5
|PROPF_METHOD
|1},
1067 {L
"preventExtensions", Object_preventExtensions
, PROPF_ES5
|PROPF_METHOD
|1},
1068 {L
"seal", Object_seal
, PROPF_ES5
|PROPF_METHOD
|1},
1071 static const builtin_info_t ObjectConstr_info
= {
1074 ARRAY_SIZE(ObjectConstr_props
),
1080 static HRESULT
ObjectConstr_value(script_ctx_t
*ctx
, jsval_t vthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
1088 case DISPATCH_METHOD
:
1089 case DISPATCH_CONSTRUCT
: {
1093 if(!is_undefined(argv
[0]) && !is_null(argv
[0])) {
1096 hres
= to_object(ctx
, argv
[0], &disp
);
1101 *r
= jsval_disp(disp
);
1103 IDispatch_Release(disp
);
1108 hres
= create_object(ctx
, NULL
, &obj
);
1113 *r
= jsval_obj(obj
);
1115 jsdisp_release(obj
);
1120 FIXME("unimplemented flags: %x\n", flags
);
1127 HRESULT
create_object_constr(script_ctx_t
*ctx
, jsdisp_t
*object_prototype
, jsdisp_t
**ret
)
1129 return create_builtin_constructor(ctx
, ObjectConstr_value
, L
"Object", &ObjectConstr_info
, PROPF_CONSTR
,
1130 object_prototype
, ret
);
1133 HRESULT
create_object_prototype(script_ctx_t
*ctx
, jsdisp_t
**ret
)
1135 return create_dispex(ctx
, &Object_info
, NULL
, ret
);
1138 HRESULT
create_object(script_ctx_t
*ctx
, jsdisp_t
*constr
, jsdisp_t
**ret
)
1143 object
= calloc(1, sizeof(jsdisp_t
));
1145 return E_OUTOFMEMORY
;
1147 hres
= init_dispex_from_constr(object
, ctx
, &ObjectInst_info
, constr
? constr
: ctx
->object_constr
);