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
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
33 /* Keep in sync with jsclass_t enum */
34 static const WCHAR
*names
[] = {
57 jsdisp
= get_jsdisp(jsthis
);
59 str
= L
"[object Object]";
60 }else if(names
[jsdisp
->builtin_info
->class]) {
61 str
= names
[jsdisp
->builtin_info
->class];
63 assert(jsdisp
->builtin_info
->class != JSCLASS_NONE
);
64 FIXME("jsdisp->builtin_info->class = %d\n", jsdisp
->builtin_info
->class);
70 ret
= jsstr_alloc(str
);
73 *r
= jsval_string(ret
);
79 static HRESULT
Object_toLocaleString(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
84 if(!is_jsdisp(jsthis
)) {
85 FIXME("Host object this\n");
89 return jsdisp_call_name(jsthis
->u
.jsdisp
, L
"toString", DISPATCH_METHOD
, 0, NULL
, r
);
92 static HRESULT
Object_valueOf(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
98 IDispatch_AddRef(jsthis
->u
.disp
);
99 *r
= jsval_disp(jsthis
->u
.disp
);
104 static HRESULT
Object_hasOwnProperty(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
116 *r
= jsval_bool(FALSE
);
120 hres
= to_string(ctx
, argv
[0], &name
);
124 if(is_jsdisp(jsthis
)) {
125 property_desc_t prop_desc
;
126 const WCHAR
*name_str
;
128 name_str
= jsstr_flatten(name
);
131 return E_OUTOFMEMORY
;
134 hres
= jsdisp_get_own_property(jsthis
->u
.jsdisp
, name_str
, TRUE
, &prop_desc
);
136 if(FAILED(hres
) && hres
!= DISP_E_UNKNOWNNAME
)
139 if(r
) *r
= jsval_bool(hres
== S_OK
);
144 bstr
= SysAllocStringLen(NULL
, jsstr_length(name
));
146 jsstr_flush(name
, bstr
);
149 return E_OUTOFMEMORY
;
151 if(is_dispex(jsthis
))
152 hres
= IDispatchEx_GetDispID(jsthis
->u
.dispex
, bstr
, make_grfdex(ctx
, fdexNameCaseSensitive
), &id
);
154 hres
= IDispatch_GetIDsOfNames(jsthis
->u
.disp
, &IID_NULL
, &bstr
, 1, ctx
->lcid
, &id
);
158 *r
= jsval_bool(SUCCEEDED(hres
));
162 static HRESULT
Object_propertyIsEnumerable(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
165 property_desc_t prop_desc
;
173 FIXME("argc %d not supported\n", argc
);
177 if(!is_jsdisp(jsthis
)) {
178 FIXME("Host object this\n");
182 hres
= to_flat_string(ctx
, argv
[0], &name_str
, &name
);
186 hres
= jsdisp_get_own_property(jsthis
->u
.jsdisp
, name
, TRUE
, &prop_desc
);
187 jsstr_release(name_str
);
188 if(FAILED(hres
) && hres
!= DISP_E_UNKNOWNNAME
)
192 *r
= jsval_bool(hres
== S_OK
&& (prop_desc
.flags
& PROPF_ENUMERABLE
) != 0);
196 static HRESULT
Object_isPrototypeOf(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
203 static HRESULT
Object_get_value(script_ctx_t
*ctx
, jsdisp_t
*jsthis
, jsval_t
*r
)
209 ret
= jsstr_alloc(L
"[object Object]");
211 return E_OUTOFMEMORY
;
213 *r
= jsval_string(ret
);
217 static void Object_destructor(jsdisp_t
*dispex
)
222 static const builtin_prop_t Object_props
[] = {
223 {L
"hasOwnProperty", Object_hasOwnProperty
, PROPF_METHOD
|1},
224 {L
"isPrototypeOf", Object_isPrototypeOf
, PROPF_METHOD
|1},
225 {L
"propertyIsEnumerable", Object_propertyIsEnumerable
, PROPF_METHOD
|1},
226 {L
"toLocaleString", Object_toLocaleString
, PROPF_METHOD
},
227 {L
"toString", Object_toString
, PROPF_METHOD
},
228 {L
"valueOf", Object_valueOf
, PROPF_METHOD
}
231 static const builtin_info_t Object_info
= {
233 {NULL
, NULL
,0, Object_get_value
},
234 ARRAY_SIZE(Object_props
),
240 static const builtin_info_t ObjectInst_info
= {
242 {NULL
, NULL
,0, Object_get_value
},
248 static void release_property_descriptor(property_desc_t
*desc
)
250 if(desc
->explicit_value
)
251 jsval_release(desc
->value
);
253 jsdisp_release(desc
->getter
);
255 jsdisp_release(desc
->setter
);
258 static HRESULT
to_property_descriptor(script_ctx_t
*ctx
, jsdisp_t
*attr_obj
, property_desc_t
*desc
)
265 memset(desc
, 0, sizeof(*desc
));
266 desc
->value
= jsval_undefined();
268 hres
= jsdisp_get_id(attr_obj
, L
"enumerable", 0, &id
);
269 if(SUCCEEDED(hres
)) {
270 desc
->mask
|= PROPF_ENUMERABLE
;
271 hres
= jsdisp_propget(attr_obj
, id
, &v
);
274 hres
= to_boolean(v
, &b
);
279 desc
->flags
|= PROPF_ENUMERABLE
;
280 }else if(hres
!= DISP_E_UNKNOWNNAME
) {
284 hres
= jsdisp_get_id(attr_obj
, L
"configurable", 0, &id
);
285 if(SUCCEEDED(hres
)) {
286 desc
->mask
|= PROPF_CONFIGURABLE
;
287 hres
= jsdisp_propget(attr_obj
, id
, &v
);
290 hres
= to_boolean(v
, &b
);
295 desc
->flags
|= PROPF_CONFIGURABLE
;
296 }else if(hres
!= DISP_E_UNKNOWNNAME
) {
300 hres
= jsdisp_get_id(attr_obj
, L
"value", 0, &id
);
301 if(SUCCEEDED(hres
)) {
302 hres
= jsdisp_propget(attr_obj
, id
, &desc
->value
);
305 desc
->explicit_value
= TRUE
;
306 }else if(hres
!= DISP_E_UNKNOWNNAME
) {
310 hres
= jsdisp_get_id(attr_obj
, L
"writable", 0, &id
);
311 if(SUCCEEDED(hres
)) {
312 desc
->mask
|= PROPF_WRITABLE
;
313 hres
= jsdisp_propget(attr_obj
, id
, &v
);
314 if(SUCCEEDED(hres
)) {
315 hres
= to_boolean(v
, &b
);
317 if(SUCCEEDED(hres
) && b
)
318 desc
->flags
|= PROPF_WRITABLE
;
320 }else if(hres
== DISP_E_UNKNOWNNAME
) {
324 release_property_descriptor(desc
);
328 hres
= jsdisp_get_id(attr_obj
, L
"get", 0, &id
);
329 if(SUCCEEDED(hres
)) {
330 desc
->explicit_getter
= TRUE
;
331 hres
= jsdisp_propget(attr_obj
, id
, &v
);
332 if(SUCCEEDED(hres
) && !is_undefined(v
)) {
333 if(!is_object_instance(v
)) {
334 FIXME("getter is not an object\n");
338 /* FIXME: Check IsCallable */
339 desc
->getter
= to_jsdisp(get_object(v
));
341 FIXME("getter is not JS object\n");
344 }else if(hres
== DISP_E_UNKNOWNNAME
) {
348 release_property_descriptor(desc
);
352 hres
= jsdisp_get_id(attr_obj
, L
"set", 0, &id
);
353 if(SUCCEEDED(hres
)) {
354 desc
->explicit_setter
= TRUE
;
355 hres
= jsdisp_propget(attr_obj
, id
, &v
);
356 if(SUCCEEDED(hres
) && !is_undefined(v
)) {
357 if(!is_object_instance(v
)) {
358 FIXME("setter is not an object\n");
362 /* FIXME: Check IsCallable */
363 desc
->setter
= to_jsdisp(get_object(v
));
365 FIXME("setter is not JS object\n");
368 }else if(hres
== DISP_E_UNKNOWNNAME
) {
372 release_property_descriptor(desc
);
376 if(desc
->explicit_getter
|| desc
->explicit_setter
) {
377 if(desc
->explicit_value
)
378 hres
= JS_E_PROP_DESC_MISMATCH
;
379 else if(desc
->mask
& PROPF_WRITABLE
)
380 hres
= JS_E_INVALID_WRITABLE_PROP_DESC
;
384 release_property_descriptor(desc
);
388 static HRESULT
jsdisp_define_properties(script_ctx_t
*ctx
, jsdisp_t
*obj
, jsval_t list_val
)
390 DISPID id
= DISPID_STARTENUM
;
391 property_desc_t prop_desc
;
392 IDispatch
*list_disp
;
393 jsdisp_t
*list_obj
, *desc_obj
;
398 hres
= to_object(ctx
, list_val
, &list_disp
);
402 if(!(list_obj
= to_jsdisp(list_disp
))) {
403 FIXME("non-JS list obj\n");
404 IDispatch_Release(list_disp
);
409 hres
= jsdisp_next_prop(list_obj
, id
, JSDISP_ENUM_OWN_ENUMERABLE
, &id
);
413 hres
= jsdisp_propget(list_obj
, id
, &desc_val
);
417 if(!is_object_instance(desc_val
) || !get_object(desc_val
) || !(desc_obj
= to_jsdisp(get_object(desc_val
)))) {
418 jsval_release(desc_val
);
422 hres
= to_property_descriptor(ctx
, desc_obj
, &prop_desc
);
423 jsdisp_release(desc_obj
);
427 hres
= IDispatchEx_GetMemberName(&list_obj
->IDispatchEx_iface
, id
, &name
);
429 hres
= jsdisp_define_property(obj
, name
, &prop_desc
);
430 release_property_descriptor(&prop_desc
);
435 jsdisp_release(list_obj
);
436 return FAILED(hres
) ? hres
: S_OK
;
439 static HRESULT
Object_defineProperty(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
,
440 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
442 property_desc_t prop_desc
;
443 jsdisp_t
*obj
, *attr_obj
;
450 if(argc
< 1 || !is_object_instance(argv
[0]))
451 return JS_E_OBJECT_EXPECTED
;
452 obj
= to_jsdisp(get_object(argv
[0]));
454 FIXME("not implemented non-JS object\n");
458 hres
= to_flat_string(ctx
, argc
>= 2 ? argv
[1] : jsval_undefined(), &name_str
, &name
);
462 if(argc
>= 3 && is_object_instance(argv
[2])) {
463 attr_obj
= to_jsdisp(get_object(argv
[2]));
465 hres
= to_property_descriptor(ctx
, attr_obj
, &prop_desc
);
467 FIXME("not implemented non-JS object\n");
471 hres
= JS_E_OBJECT_EXPECTED
;
476 jsstr_release(name_str
);
480 hres
= jsdisp_define_property(obj
, name
, &prop_desc
);
481 jsstr_release(name_str
);
482 release_property_descriptor(&prop_desc
);
483 if(SUCCEEDED(hres
) && r
)
484 *r
= jsval_obj(jsdisp_addref(obj
));
488 static HRESULT
Object_defineProperties(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
,
489 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
494 if(argc
< 1 || !is_object_instance(argv
[0]) || !get_object(argv
[0]) || !(obj
= to_jsdisp(get_object(argv
[0])))) {
495 FIXME("not an object\n");
501 hres
= jsdisp_define_properties(ctx
, obj
, argc
>= 2 ? argv
[1] : jsval_undefined());
502 if(SUCCEEDED(hres
) && r
)
503 *r
= jsval_obj(jsdisp_addref(obj
));
507 static HRESULT
Object_getOwnPropertyDescriptor(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
,
508 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
510 property_desc_t prop_desc
;
511 jsdisp_t
*obj
, *desc_obj
;
518 if(argc
< 1 || !is_object_instance(argv
[0]))
519 return JS_E_OBJECT_EXPECTED
;
520 obj
= to_jsdisp(get_object(argv
[0]));
522 FIXME("not implemented non-JS object\n");
526 hres
= to_flat_string(ctx
, argc
>= 2 ? argv
[1] : jsval_undefined(), &name_str
, &name
);
530 hres
= jsdisp_get_own_property(obj
, name
, FALSE
, &prop_desc
);
531 jsstr_release(name_str
);
532 if(hres
== DISP_E_UNKNOWNNAME
) {
533 if(r
) *r
= jsval_undefined();
539 hres
= create_object(ctx
, NULL
, &desc_obj
);
543 if(prop_desc
.explicit_getter
|| prop_desc
.explicit_setter
) {
544 hres
= jsdisp_define_data_property(desc_obj
, L
"get", PROPF_ALL
,
545 prop_desc
.getter
? jsval_obj(prop_desc
.getter
) : jsval_undefined());
547 hres
= jsdisp_define_data_property(desc_obj
, L
"set", PROPF_ALL
,
548 prop_desc
.setter
? jsval_obj(prop_desc
.setter
) : jsval_undefined());
550 hres
= jsdisp_propput_name(desc_obj
, L
"value", prop_desc
.value
);
552 hres
= jsdisp_define_data_property(desc_obj
, L
"writable", PROPF_ALL
,
553 jsval_bool(!!(prop_desc
.flags
& PROPF_WRITABLE
)));
556 hres
= jsdisp_define_data_property(desc_obj
, L
"enumerable", PROPF_ALL
,
557 jsval_bool(!!(prop_desc
.flags
& PROPF_ENUMERABLE
)));
559 hres
= jsdisp_define_data_property(desc_obj
, L
"configurable", PROPF_ALL
,
560 jsval_bool(!!(prop_desc
.flags
& PROPF_CONFIGURABLE
)));
562 release_property_descriptor(&prop_desc
);
563 if(SUCCEEDED(hres
) && r
)
564 *r
= jsval_obj(desc_obj
);
566 jsdisp_release(desc_obj
);
570 static HRESULT
Object_create(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
,
571 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
573 jsdisp_t
*proto
= NULL
, *obj
;
576 if(!argc
|| (!is_object_instance(argv
[0]) && !is_null(argv
[0]))) {
577 FIXME("Invalid arg\n");
581 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
583 if(argc
&& is_object_instance(argv
[0])) {
584 if(get_object(argv
[0]))
585 proto
= to_jsdisp(get_object(argv
[0]));
587 FIXME("Non-JS prototype\n");
590 }else if(!is_null(argv
[0])) {
591 FIXME("Invalid arg %s\n", debugstr_jsval(argc
? argv
[0] : jsval_undefined()));
595 hres
= create_dispex(ctx
, &ObjectInst_info
, proto
, &obj
);
599 if(argc
>= 2 && !is_undefined(argv
[1]))
600 hres
= jsdisp_define_properties(ctx
, obj
, argv
[1]);
602 if(SUCCEEDED(hres
) && r
)
609 static HRESULT
Object_getPrototypeOf(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
,
610 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
614 if(!argc
|| !is_object_instance(argv
[0])) {
615 FIXME("invalid arguments\n");
619 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
621 obj
= to_jsdisp(get_object(argv
[0]));
623 FIXME("Non-JS object\n");
629 ? jsval_obj(jsdisp_addref(obj
->prototype
))
634 static HRESULT
object_keys(script_ctx_t
*ctx
, jsval_t arg
, enum jsdisp_enum_type enum_type
, jsval_t
*r
)
636 DISPID id
= DISPID_STARTENUM
;
637 jsdisp_t
*obj
, *array
;
642 if(!is_object_instance(arg
) || !get_object(arg
)) {
643 FIXME("invalid arguments %s\n", debugstr_jsval(arg
));
647 obj
= to_jsdisp(get_object(arg
));
649 FIXME("Non-JS object\n");
653 hres
= create_array(ctx
, 0, &array
);
658 hres
= jsdisp_next_prop(obj
, id
, enum_type
, &id
);
662 hres
= jsdisp_get_prop_name(obj
, id
, &key
);
666 hres
= jsdisp_propput_idx(array
, i
++, jsval_string(key
));
668 } while(hres
== S_OK
);
670 if(SUCCEEDED(hres
) && r
)
671 *r
= jsval_obj(array
);
673 jsdisp_release(array
);
677 static HRESULT
Object_keys(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
,
678 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
680 jsval_t arg
= argc
? argv
[0] : jsval_undefined();
682 TRACE("(%s)\n", debugstr_jsval(arg
));
684 return object_keys(ctx
, arg
, JSDISP_ENUM_OWN_ENUMERABLE
, r
);
687 static HRESULT
Object_getOwnPropertyNames(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
,
688 unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
690 jsval_t arg
= argc
? argv
[0] : jsval_undefined();
692 TRACE("(%s)\n", debugstr_jsval(arg
));
694 return object_keys(ctx
, arg
, JSDISP_ENUM_OWN
, r
);
697 static HRESULT
Object_preventExtensions(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
701 if(!argc
|| !is_object_instance(argv
[0]) || !get_object(argv
[0])) {
702 FIXME("invalid arguments\n");
706 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
708 obj
= to_jsdisp(get_object(argv
[0]));
710 FIXME("Non-JS object\n");
714 obj
->extensible
= FALSE
;
715 if(r
) *r
= jsval_obj(jsdisp_addref(obj
));
719 static HRESULT
Object_freeze(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
,
720 jsval_t
*argv
, jsval_t
*r
)
724 if(!argc
|| !is_object_instance(argv
[0]) || !get_object(argv
[0])) {
725 WARN("argument is not an object\n");
726 return JS_E_OBJECT_EXPECTED
;
729 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
731 obj
= to_jsdisp(get_object(argv
[0]));
733 FIXME("Non-JS object\n");
737 jsdisp_freeze(obj
, FALSE
);
738 if(r
) *r
= jsval_obj(jsdisp_addref(obj
));
742 static HRESULT
Object_seal(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
,
743 jsval_t
*argv
, jsval_t
*r
)
747 if(!argc
|| !is_object_instance(argv
[0]) || !get_object(argv
[0])) {
748 WARN("argument is not an object\n");
749 return JS_E_OBJECT_EXPECTED
;
752 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
754 obj
= to_jsdisp(get_object(argv
[0]));
756 FIXME("Non-JS object\n");
760 jsdisp_freeze(obj
, TRUE
);
761 if(r
) *r
= jsval_obj(jsdisp_addref(obj
));
765 static HRESULT
Object_isExtensible(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
, jsval_t
*r
)
769 if(!argc
|| !is_object_instance(argv
[0]) || !get_object(argv
[0])) {
770 WARN("argument is not an object\n");
771 return JS_E_OBJECT_EXPECTED
;
774 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
776 obj
= to_jsdisp(get_object(argv
[0]));
778 FIXME("Non-JS object\n");
782 if(r
) *r
= jsval_bool(obj
->extensible
);
786 static HRESULT
Object_isFrozen(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
,
787 jsval_t
*argv
, jsval_t
*r
)
791 if(!argc
|| !is_object_instance(argv
[0]) || !get_object(argv
[0])) {
792 WARN("argument is not an object\n");
793 return JS_E_OBJECT_EXPECTED
;
796 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
798 obj
= to_jsdisp(get_object(argv
[0]));
800 FIXME("Non-JS object\n");
804 if(r
) *r
= jsval_bool(jsdisp_is_frozen(obj
, FALSE
));
808 static HRESULT
Object_isSealed(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
,
809 jsval_t
*argv
, jsval_t
*r
)
813 if(!argc
|| !is_object_instance(argv
[0]) || !get_object(argv
[0])) {
814 WARN("argument is not an object\n");
815 return JS_E_OBJECT_EXPECTED
;
818 TRACE("(%s)\n", debugstr_jsval(argv
[0]));
820 obj
= to_jsdisp(get_object(argv
[0]));
822 FIXME("Non-JS object\n");
826 if(r
) *r
= jsval_bool(jsdisp_is_frozen(obj
, TRUE
));
830 static const builtin_prop_t ObjectConstr_props
[] = {
831 {L
"create", Object_create
, PROPF_ES5
|PROPF_METHOD
|2},
832 {L
"defineProperties", Object_defineProperties
, PROPF_ES5
|PROPF_METHOD
|2},
833 {L
"defineProperty", Object_defineProperty
, PROPF_ES5
|PROPF_METHOD
|2},
834 {L
"freeze", Object_freeze
, PROPF_ES5
|PROPF_METHOD
|1},
835 {L
"getOwnPropertyDescriptor", Object_getOwnPropertyDescriptor
, PROPF_ES5
|PROPF_METHOD
|2},
836 {L
"getOwnPropertyNames", Object_getOwnPropertyNames
, PROPF_ES5
|PROPF_METHOD
|1},
837 {L
"getPrototypeOf", Object_getPrototypeOf
, PROPF_ES5
|PROPF_METHOD
|1},
838 {L
"isExtensible", Object_isExtensible
, PROPF_ES5
|PROPF_METHOD
|1},
839 {L
"isFrozen", Object_isFrozen
, PROPF_ES5
|PROPF_METHOD
|1},
840 {L
"isSealed", Object_isSealed
, PROPF_ES5
|PROPF_METHOD
|1},
841 {L
"keys", Object_keys
, PROPF_ES5
|PROPF_METHOD
|1},
842 {L
"preventExtensions", Object_preventExtensions
, PROPF_ES5
|PROPF_METHOD
|1},
843 {L
"seal", Object_seal
, PROPF_ES5
|PROPF_METHOD
|1},
846 static const builtin_info_t ObjectConstr_info
= {
848 DEFAULT_FUNCTION_VALUE
,
849 ARRAY_SIZE(ObjectConstr_props
),
855 static HRESULT
ObjectConstr_value(script_ctx_t
*ctx
, vdisp_t
*jsthis
, WORD flags
, unsigned argc
, jsval_t
*argv
,
863 case DISPATCH_METHOD
:
864 case DISPATCH_CONSTRUCT
: {
868 if(!is_undefined(argv
[0]) && !is_null(argv
[0]) && (!is_object_instance(argv
[0]) || get_object(argv
[0]))) {
871 hres
= to_object(ctx
, argv
[0], &disp
);
876 *r
= jsval_disp(disp
);
878 IDispatch_Release(disp
);
883 hres
= create_object(ctx
, NULL
, &obj
);
895 FIXME("unimplemented flags: %x\n", flags
);
902 HRESULT
create_object_constr(script_ctx_t
*ctx
, jsdisp_t
*object_prototype
, jsdisp_t
**ret
)
904 return create_builtin_constructor(ctx
, ObjectConstr_value
, L
"Object", &ObjectConstr_info
, PROPF_CONSTR
,
905 object_prototype
, ret
);
908 HRESULT
create_object_prototype(script_ctx_t
*ctx
, jsdisp_t
**ret
)
910 return create_dispex(ctx
, &Object_info
, NULL
, ret
);
913 HRESULT
create_object(script_ctx_t
*ctx
, jsdisp_t
*constr
, jsdisp_t
**ret
)
918 object
= heap_alloc_zero(sizeof(jsdisp_t
));
920 return E_OUTOFMEMORY
;
922 hres
= init_dispex_from_constr(object
, ctx
, &ObjectInst_info
, constr
? constr
: ctx
->object_constr
);