ReactOS 0.4.17-dev-357-ga8f14ff
dispex.c
Go to the documentation of this file.
1/*
2 * Copyright 2008 Jacek Caban for CodeWeavers
3 *
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.
8 *
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.
13 *
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
17 */
18
19#include <assert.h>
20
21#include "jscript.h"
22#include "engine.h"
23
24#include "wine/debug.h"
25
27
28static const GUID GUID_JScriptTypeInfo = {0xc59c6b12,0xf6c1,0x11cf,{0x88,0x35,0x00,0xa0,0xc9,0x11,0xe8,0xb2}};
29
30#define FDEX_VERSION_MASK 0xf0000000
31#define GOLDEN_RATIO 0x9E3779B9U
32
33typedef enum {
41
44 unsigned hash;
47
48 union {
52 unsigned id;
53 struct {
57 } u;
58
61};
62
63static void fix_protref_prop(jsdisp_t *jsdisp, dispex_prop_t *prop)
64{
65 DWORD ref;
66
67 if(prop->type != PROP_PROTREF)
68 return;
69 ref = prop->u.ref;
70
71 while((jsdisp = jsdisp->prototype)) {
72 if(ref >= jsdisp->prop_cnt || jsdisp->props[ref].type == PROP_DELETED)
73 break;
74 if(jsdisp->props[ref].type != PROP_PROTREF)
75 return;
76 ref = jsdisp->props[ref].u.ref;
77 }
78 prop->type = PROP_DELETED;
79}
80
82{
83 /* don't overlap with DISPID_VALUE */
84 return prop - This->props + 1;
85}
86
88{
89 DWORD idx = id - 1;
90
91 if(idx >= This->prop_cnt)
92 return NULL;
93 fix_protref_prop(This, &This->props[idx]);
94
95 return This->props[idx].type == PROP_DELETED ? NULL : &This->props[idx];
96}
97
99{
100 BOOL ret = FALSE;
101
102 if (is_object_instance(prop->u.val))
103 {
104 jsdisp_t *jsdisp = to_jsdisp(get_object(prop->u.val));
105
106 if (jsdisp) ret = is_class(jsdisp, JSCLASS_FUNCTION);
107 }
108 return ret;
109}
110
112{
113 if(prop->type == PROP_PROTREF) {
115
116 if(prop->u.ref < This->prototype->prop_cnt)
117 parent = &This->prototype->props[prop->u.ref];
118
119 if(!parent || parent->type == PROP_DELETED) {
120 prop->type = PROP_DELETED;
121 return 0;
122 }
123
124 return get_flags(This->prototype, parent);
125 }
126
127 return prop->flags;
128}
129
130static const builtin_prop_t *find_builtin_prop(jsdisp_t *This, const WCHAR *name, BOOL case_insens)
131{
132 int min = 0, max = This->builtin_info->props_cnt-1, i, r;
133 unsigned version;
134
135 if(case_insens) {
136 for(i = min; i <= max; i++)
137 if(!wcsicmp(name, This->builtin_info->props[i].name))
138 goto found;
139 return NULL;
140 }
141
142 while(min <= max) {
143 i = (min+max)/2;
144
145 r = wcscmp(name, This->builtin_info->props[i].name);
146 if(!r)
147 goto found;
148
149 if(r < 0)
150 max = i-1;
151 else
152 min = i+1;
153 }
154
155 return NULL;
156
157found:
158 /* Skip prop if it's available only in higher compatibility mode. */
159 version = (This->builtin_info->props[i].flags & PROPF_VERSION_MASK) >> PROPF_VERSION_SHIFT;
160 if(version && version > This->ctx->version)
161 return NULL;
162
163 /* Skip prop if it's available only in HTML mode and we're not running in HTML mode. */
164 if((This->builtin_info->props[i].flags & PROPF_HTML) && !This->ctx->html_mode)
165 return NULL;
166
167 return This->builtin_info->props + i;
168}
169
170static inline unsigned string_hash(const WCHAR *name)
171{
172 unsigned h = 0;
173 for(; *name; name++)
174 h = (h>>(sizeof(unsigned)*8-4)) ^ (h<<4) ^ towlower(*name);
175 return h;
176}
177
178static inline unsigned get_props_idx(jsdisp_t *This, unsigned hash)
179{
180 return (hash*GOLDEN_RATIO) & (This->buf_size-1);
181}
182
184{
186 int i, bucket;
187
188 if(This->buf_size != This->prop_cnt)
189 return S_FALSE;
190
191 props = realloc(This->props, sizeof(dispex_prop_t) * This->buf_size * 2);
192 if(!props)
193 return E_OUTOFMEMORY;
194 This->buf_size *= 2;
195 This->props = props;
196
197 for(i=0; i<This->buf_size; i++) {
198 This->props[i].bucket_head = ~0;
199 This->props[i].bucket_next = ~0;
200 }
201
202 for(i=0; i<This->prop_cnt; i++) {
203 props = This->props+i;
204
205 bucket = get_props_idx(This, props->hash);
206 props->bucket_next = This->props[bucket].bucket_head;
207 This->props[bucket].bucket_head = i;
208 }
209
210 return S_OK;
211}
212
214{
215 dispex_prop_t *prop;
216 unsigned bucket;
217
219 return NULL;
220
221 prop = &This->props[This->prop_cnt];
222 prop->name = wcsdup(name);
223 if(!prop->name)
224 return NULL;
225 prop->type = type;
226 prop->flags = flags;
227 prop->hash = string_hash(name);
228
229 bucket = get_props_idx(This, prop->hash);
230 prop->bucket_next = This->props[bucket].bucket_head;
231 This->props[bucket].bucket_head = This->prop_cnt++;
232 return prop;
233}
234
236{
238
240 if(!ret)
241 return NULL;
242
243 ret->u.ref = ref;
244 return ret;
245}
246
247static dispex_prop_t *lookup_dispex_prop(jsdisp_t *obj, unsigned hash, const WCHAR *name, BOOL case_insens)
248{
249 unsigned bucket, pos, prev = ~0;
250
251 bucket = get_props_idx(obj, hash);
252 pos = obj->props[bucket].bucket_head;
253 while(pos != ~0) {
254 if(case_insens ? !wcsicmp(name, obj->props[pos].name) : !wcscmp(name, obj->props[pos].name)) {
255 if(prev != ~0) {
256 obj->props[prev].bucket_next = obj->props[pos].bucket_next;
257 obj->props[pos].bucket_next = obj->props[bucket].bucket_head;
258 obj->props[bucket].bucket_head = pos;
259 }
260
261 return &obj->props[pos];
262 }
263
264 prev = pos;
265 pos = obj->props[pos].bucket_next;
266 }
267
268 return NULL;
269}
270
272{
274
275 if(desc->name)
276 name = desc->name;
277
278 if(!desc->iid) {
279 if(!prop && !(prop = alloc_prop(obj, name, PROP_DELETED, 0)))
280 return E_OUTOFMEMORY;
281 prop->type = PROP_EXTERN;
282 prop->u.id = desc->id;
283 }else if(prop) {
284 /* If a property for a host non-volatile already exists, it must have been deleted. */
285 *ret = prop;
286 return S_OK;
287 }else if(desc->flags & PROPF_METHOD) {
288 jsdisp_t *func;
289
291 if(FAILED(hres))
292 return hres;
293
294 if(!(prop = alloc_prop(obj, name, PROP_JSVAL, 0)))
295 return E_OUTOFMEMORY;
296 prop->u.val = jsval_obj(func);
297 }else {
298 jsdisp_t *getter, *setter = NULL;
299
301 if(FAILED(hres))
302 return hres;
303
304 if(desc->flags & PROPF_WRITABLE) {
306 if(FAILED(hres)) {
307 jsdisp_release(getter);
308 return hres;
309 }
310 }
311
312 if(!(prop = alloc_prop(obj, name, PROP_ACCESSOR, 0)))
313 return E_OUTOFMEMORY;
314 prop->u.accessor.getter = getter;
315 prop->u.accessor.setter = setter;
316 }
317
318 prop->flags = desc->flags & PROPF_ALL;
319 *ret = prop;
320 return S_OK;
321}
322
324{
325 if(This->builtin_info->lookup_prop) {
326 struct property_info desc;
328
329 hres = This->builtin_info->lookup_prop(This, name,
330 case_insens ? fdexNameCaseInsensitive : fdexNameCaseSensitive, &desc);
331 if(hres != DISP_E_UNKNOWNNAME) {
332 if(FAILED(hres))
333 return hres;
334
335 if(prop && desc.name && wcscmp(prop->name, desc.name)) {
336 prop = lookup_dispex_prop(This, string_hash(desc.name), desc.name, case_insens);
337 if(prop && prop->type != PROP_EXTERN && prop->type != PROP_DELETED && prop->type != PROP_PROTREF) {
338 *ret = prop;
339 return S_OK;
340 }
341 }
342
343 return update_external_prop(This, name, prop, &desc, ret);
344 }else if(prop && prop->type == PROP_EXTERN) {
345 prop->type = PROP_DELETED;
346 }
347 }
348
349 *ret = prop;
350 return S_OK;
351}
352
353static HRESULT find_prop_name(jsdisp_t *This, unsigned hash, const WCHAR *name, BOOL case_insens,
355{
356 const builtin_prop_t *builtin;
358
359 if(!prop)
360 prop = lookup_dispex_prop(This, hash, name, case_insens);
361 if(prop && prop->type != PROP_DELETED && prop->type != PROP_EXTERN) {
362 *ret = prop;
363 return S_OK;
364 }
365
366 if(!prop && (builtin = find_builtin_prop(This, name, case_insens))) {
367 unsigned flags = builtin->flags;
368 if(flags & PROPF_METHOD) {
369 jsdisp_t *obj;
370
371 hres = create_builtin_function(This->ctx, builtin->invoke, builtin->name, NULL, flags, NULL, &obj);
372 if(FAILED(hres))
373 return hres;
374
376 if(!prop) {
378 return E_OUTOFMEMORY;
379 }
380
381 prop->type = PROP_JSVAL;
382 prop->u.val = jsval_obj(obj);
383 *ret = prop;
384 return S_OK;
385 }else if(builtin->setter)
388 prop = alloc_prop(This, builtin->name, PROP_BUILTIN, flags);
389 if(!prop)
390 return E_OUTOFMEMORY;
391
392 prop->u.p = builtin;
393 *ret = prop;
394 return S_OK;
395 }
396
397 return find_external_prop(This, name, case_insens, prop, ret);
398}
399
400static HRESULT find_prop_name_prot(jsdisp_t *This, unsigned hash, const WCHAR *name, BOOL case_insens,
401 dispex_prop_t *own_prop, dispex_prop_t **ret)
402{
403 dispex_prop_t *prot_prop = NULL;
405
406 hres = find_prop_name(This, hash, name, case_insens, own_prop, &own_prop);
407 if(FAILED(hres))
408 return hres;
409 if(own_prop) {
410 if(own_prop->type == PROP_PROTREF) {
411 prot_prop = &This->prototype->props[own_prop->u.ref];
412 }else if(own_prop->type != PROP_DELETED) {
413 *ret = own_prop;
414 return S_OK;
415 }
416 }
417
418 if(This->prototype) {
419 hres = find_prop_name_prot(This->prototype, hash, name, case_insens, prot_prop, &prot_prop);
420 if(FAILED(hres))
421 return hres;
422 if(prot_prop && prot_prop->type != PROP_DELETED) {
423 if(own_prop && case_insens && wcscmp(prot_prop->name, own_prop->name)) {
424 hres = find_prop_name(This, prot_prop->hash, prot_prop->name, FALSE, NULL, &own_prop);
425 if(FAILED(hres))
426 return hres;
427 if(own_prop && own_prop->type != PROP_DELETED) {
428 *ret = own_prop;
429 return S_OK;
430 }
431 }
432 if(own_prop) {
433 own_prop->type = PROP_PROTREF;
434 own_prop->u.ref = prot_prop - This->prototype->props;
435 }else {
436 own_prop = alloc_protref(This, prot_prop->name, prot_prop - This->prototype->props);
437 if(!own_prop)
438 return E_OUTOFMEMORY;
439 }
440 }else if(own_prop) {
441 own_prop->type = PROP_DELETED;
442 }
443 }
444
445 *ret = own_prop;
446 return S_OK;
447}
448
450{
451 dispex_prop_t *prop;
453
454 hres = find_prop_name_prot(This, string_hash(name), name, case_insens, NULL, &prop);
455 if(SUCCEEDED(hres) && (!prop || prop->type == PROP_DELETED)) {
456 TRACE("creating prop %s flags %lx\n", debugstr_w(name), create_flags);
457
458 if(!prop) {
459 prop = alloc_prop(This, name, PROP_DELETED, 0);
460 if(!prop)
461 return E_OUTOFMEMORY;
462 }
463
464 if(This->builtin_info->lookup_prop) {
465 struct property_info desc;
466 hres = This->builtin_info->lookup_prop(This, name, fdexNameEnsure, &desc);
467 if(hres == S_OK)
468 return update_external_prop(This, name, prop, &desc, ret);
469 }
470
471 hres = S_OK;
472 prop->type = PROP_JSVAL;
473 prop->flags = create_flags;
474 prop->u.val = jsval_undefined();
475 }
476
477 *ret = prop;
478 return hres;
479}
480
482{
483 const WCHAR *ptr;
484 unsigned idx = 0;
485
486 for(ptr = name; is_digit(*ptr); ptr++) {
487 idx = idx * 10 + (*ptr - '0');
488 if (idx >= length)
489 return DISP_E_UNKNOWNNAME;
490 }
491 if(*ptr)
492 return DISP_E_UNKNOWNNAME;
493
494 desc->id = idx;
495 desc->flags = PROPF_ENUMERABLE;
496 if(obj->builtin_info->prop_put)
497 desc->flags |= PROPF_WRITABLE;
498 desc->name = NULL;
499 desc->index = idx;
500 desc->iid = 0;
501 return S_OK;
502}
503
505{
506 if(id + 1 == length)
507 return S_FALSE;
508
509 desc->id = id + 1;
510 desc->flags = PROPF_ENUMERABLE;
511 if(obj->builtin_info->prop_put)
512 desc->flags |= PROPF_WRITABLE;
513 desc->name = NULL;
514 desc->index = desc->id;
515 desc->iid = 0;
516 return S_OK;
517}
518
519static IDispatch *get_this(DISPPARAMS *dp)
520{
521 DWORD i;
522
523 for(i=0; i < dp->cNamedArgs; i++) {
524 if(dp->rgdispidNamedArgs[i] == DISPID_THIS) {
525 if(V_VT(dp->rgvarg+i) == VT_DISPATCH)
526 return V_DISPATCH(dp->rgvarg+i);
527
528 WARN("This is not VT_DISPATCH\n");
529 return NULL;
530 }
531 }
532
533 TRACE("no this passed\n");
534 return NULL;
535}
536
537static HRESULT convert_params(script_ctx_t *ctx, const DISPPARAMS *dp, jsval_t *buf, unsigned *argc, jsval_t **ret)
538{
539 jsval_t *argv;
540 unsigned cnt;
541 unsigned i;
543
544 cnt = dp->cArgs - dp->cNamedArgs;
545
546 if(cnt > 6) {
547 argv = malloc(cnt * sizeof(*argv));
548 if(!argv)
549 return E_OUTOFMEMORY;
550 }else {
551 argv = buf;
552 }
553
554 for(i = 0; i < cnt; i++) {
555 hres = variant_to_jsval(ctx, dp->rgvarg+dp->cArgs-i-1, argv+i);
556 if(FAILED(hres)) {
557 while(i--)
559 if(argv != buf)
560 free(argv);
561 return hres;
562 }
563 }
564
565 *argc = cnt;
566 *ret = argv;
567 return S_OK;
568}
569
571{
572 jsdisp_t *prop_obj = This;
574
575 while(prop->type == PROP_PROTREF) {
576 prop_obj = prop_obj->prototype;
577 prop = prop_obj->props + prop->u.ref;
578 }
579
580 switch(prop->type) {
581 case PROP_BUILTIN:
582 hres = prop->u.p->getter(This->ctx, prop_obj, r);
583 break;
584 case PROP_JSVAL:
585 hres = jsval_copy(prop->u.val, r);
586 break;
587 case PROP_ACCESSOR:
588 if(prop->u.accessor.getter) {
589 hres = jsdisp_call_value(prop->u.accessor.getter, jsval_disp(jsthis),
590 DISPATCH_METHOD, 0, NULL, r);
591 }else {
592 *r = jsval_undefined();
593 hres = S_OK;
594 }
595 break;
596 case PROP_EXTERN:
597 hres = prop_obj->builtin_info->prop_get(prop_obj, prop->u.id, r);
598 break;
599 default:
600 ERR("type %d\n", prop->type);
601 return E_FAIL;
602 }
603
604 if(FAILED(hres)) {
605 TRACE("fail %08lx\n", hres);
606 return hres;
607 }
608
609 TRACE("%p.%s ret %s\n", This, debugstr_w(prop->name), debugstr_jsval(*r));
610 return hres;
611}
612
614{
616
617 if(prop->type == PROP_PROTREF) {
618 dispex_prop_t *prop_iter = prop;
619 jsdisp_t *prototype_iter = This;
620
621 do {
622 prototype_iter = prototype_iter->prototype;
623 prop_iter = prototype_iter->props + prop_iter->u.ref;
624 } while(prop_iter->type == PROP_PROTREF);
625
626 if(prop_iter->type == PROP_ACCESSOR)
627 prop = prop_iter;
628 }
629
630 switch(prop->type) {
631 case PROP_BUILTIN:
632 if(!prop->u.p->setter) {
633 TRACE("getter with no setter\n");
634 return S_OK;
635 }
636 return prop->u.p->setter(This->ctx, This, val);
637 case PROP_PROTREF:
638 case PROP_DELETED:
639 if(!This->extensible)
640 return S_OK;
641 prop->type = PROP_JSVAL;
643 prop->u.val = jsval_undefined();
644 break;
645 case PROP_JSVAL:
646 if(!(prop->flags & PROPF_WRITABLE))
647 return S_OK;
648
649 jsval_release(prop->u.val);
650 break;
651 case PROP_ACCESSOR:
652 if(!prop->u.accessor.setter) {
653 TRACE("no setter\n");
654 return S_OK;
655 }
656 return jsdisp_call_value(prop->u.accessor.setter, jsval_obj(This), DISPATCH_METHOD, 1, &val, NULL);
657 case PROP_EXTERN:
658 if(!This->builtin_info->prop_put) {
659 TRACE("no prop_put\n");
660 return S_OK;
661 }
662 hres = This->builtin_info->prop_put(This, prop->u.id, val);
663 if(hres != S_FALSE)
664 return hres;
665 prop->type = PROP_JSVAL;
667 prop->u.val = jsval_undefined();
668 break;
669 default:
670 ERR("type %d\n", prop->type);
671 return E_FAIL;
672 }
673
674 TRACE("%p.%s = %s\n", This, debugstr_w(prop->name), debugstr_jsval(val));
675
676 hres = jsval_copy(val, &prop->u.val);
677 if(FAILED(hres))
678 return hres;
679
680 if(This->builtin_info->on_put)
681 This->builtin_info->on_put(This, prop->name);
682
683 return S_OK;
684}
685
687 unsigned argc, jsval_t *argv, jsval_t *r, IServiceProvider *caller)
688{
690
691 switch(prop->type) {
692 case PROP_BUILTIN:
694 case PROP_PROTREF:
695 return invoke_prop_func(This->prototype, jsthis ? jsthis : to_disp(This),
696 This->prototype->props+prop->u.ref, flags, argc, argv, r, caller);
697 case PROP_JSVAL: {
698 if(!is_object_instance(prop->u.val)) {
699 FIXME("value %s is not a function\n", debugstr_jsval(prop->u.val));
701 }
702
703 TRACE("call %s %p\n", debugstr_w(prop->name), get_object(prop->u.val));
704
705 return disp_call_value_with_caller(This->ctx, get_object(prop->u.val),
706 jsval_disp(jsthis ? jsthis : to_disp(This)),
707 flags, argc, argv, r, caller);
708 }
709 case PROP_ACCESSOR:
710 case PROP_EXTERN: {
711 jsval_t val;
712
713 hres = prop_get(This, jsthis ? jsthis : to_disp(This), prop, &val);
714 if(FAILED(hres))
715 return hres;
716
718 jsdisp_t *jsfunc = to_jsdisp(get_object(val));
719 if(!jsfunc || is_class(jsfunc, JSCLASS_FUNCTION))
721 jsval_disp(jsthis ? jsthis : to_disp(This)),
722 flags, argc, argv, r, caller);
723 else
725 }else {
726 WARN("value %s is not a function\n", debugstr_jsval(val));
728 }
729
731 return hres;
732 }
733 case PROP_DELETED:
734 assert(0);
735 break;
736 }
737
738 return E_FAIL;
739}
740
742{
743 TRACE("%p %s\n", jsthis, debugstr_jsval(value));
744 return S_OK;
745}
746
748{
749 dispex_prop_t *prop;
751
752 if(obj->builtin_info->next_prop) {
753 struct property_info desc;
754 unsigned id = ~0;
755 WCHAR buf[12];
756
757 for(;;) {
758 hres = obj->builtin_info->next_prop(obj, id, &desc);
759 if(FAILED(hres))
760 return hres;
761 if(hres == S_FALSE)
762 break;
763
764 if(!desc.name) {
765 swprintf(buf, ARRAYSIZE(buf), L"%u", desc.index);
766 desc.name = buf;
767 }
768
769 prop = lookup_dispex_prop(obj, string_hash(desc.name), desc.name, FALSE);
770 if(!prop) {
771 hres = update_external_prop(obj, desc.name, NULL, &desc, &prop);
772 if(FAILED(hres))
773 return hres;
774 }
775 id = desc.id;
776 }
777 }
778
779 return S_OK;
780}
781
783{
784 dispex_prop_t *iter, *prop;
786
788 if(FAILED(hres))
789 return hres;
790
791 if(!This->prototype)
792 return S_OK;
793
794 hres = fill_protrefs(This->prototype);
795 if(FAILED(hres))
796 return hres;
797
798 for(iter = This->prototype->props; iter < This->prototype->props+This->prototype->prop_cnt; iter++) {
799 hres = find_prop_name(This, iter->hash, iter->name, FALSE, NULL, &prop);
800 if(FAILED(hres))
801 return hres;
802 if(!prop || prop->type==PROP_DELETED) {
803 if(prop) {
804 prop->type = PROP_PROTREF;
805 prop->flags = 0;
806 prop->u.ref = iter - This->prototype->props;
807 }else {
808 prop = alloc_protref(This, iter->name, iter - This->prototype->props);
809 if(!prop)
810 return E_OUTOFMEMORY;
811 }
812 }
813 }
814
815 return S_OK;
816}
817
818static void unlink_jsdisp(jsdisp_t *jsdisp)
819{
820 dispex_prop_t *prop = jsdisp->props, *end;
821
822 for(end = prop + jsdisp->prop_cnt; prop < end; prop++) {
823 switch(prop->type) {
824 case PROP_DELETED:
825 continue;
826 case PROP_JSVAL:
827 jsval_release(prop->u.val);
828 break;
829 case PROP_ACCESSOR:
830 if(prop->u.accessor.getter)
831 jsdisp_release(prop->u.accessor.getter);
832 if(prop->u.accessor.setter)
833 jsdisp_release(prop->u.accessor.setter);
834 break;
835 default:
836 break;
837 }
838 prop->type = PROP_DELETED;
839 }
840
841 if(jsdisp->prototype) {
842 jsdisp_release(jsdisp->prototype);
843 jsdisp->prototype = NULL;
844 }
845
846 if(jsdisp->builtin_info->gc_traverse)
848}
849
850
851
852/*
853 * To deal with circular refcounts, a basic Garbage Collector is used with a variant of the
854 * mark-and-sweep algorithm that doesn't require knowing or traversing any specific "roots".
855 * This works based on the assumption that circular references can only happen when objects
856 * end up pointing to each other, and each other alone, without any external refs.
857 *
858 * An "external ref" is a ref to the object that's not from any other object. Example of such
859 * refs can be local variables, the script ctx (which keeps a ref to the global object), etc.
860 *
861 * At a high level, there are 3 logical passes done on the entire list of objects:
862 *
863 * 1. Speculatively decrease refcounts of each linked-to-object from each object. This ensures
864 * that the only remaining refcount on each object is the number of "external refs" to it.
865 * At the same time, mark all of the objects so that they can be potentially collected.
866 *
867 * 2. For each object with a non-zero "external refcount", clear the mark from step 1, and
868 * recursively traverse all linked objects from it, clearing their marks as well (regardless
869 * of their refcount), stopping a given path when the object is unmarked (and then going back
870 * up the GC stack). This basically unmarks all of the objects with "external refcounts"
871 * and those accessible from them, and only the leaked dangling objects will still be marked.
872 *
873 * 3. For each object that is marked, unlink all of the objects linked from it, because they
874 * are dangling in a circular refcount and not accessible. This should release them.
875 *
876 * During unlinking (GC_TRAVERSE_UNLINK), it is important that we unlink *all* linked objects
877 * from the object, to be certain that releasing the object later will not delete any other
878 * objects. Otherwise calculating the "next" object in the list becomes impossible.
879 *
880 * This collection process has to be done periodically, but can be pretty expensive so there
881 * has to be a balance between reclaiming dangling objects and performance.
882 *
883 */
887};
888
889struct gc_ctx {
892 unsigned idx;
893};
894
896{
897 if(!gc_ctx->idx) {
898 if(gc_ctx->next)
900 else {
901 struct gc_stack_chunk *prev, *tmp = malloc(sizeof(*tmp));
902 if(!tmp)
903 return E_OUTOFMEMORY;
904 prev = gc_ctx->chunk;
905 gc_ctx->chunk = tmp;
906 gc_ctx->chunk->prev = prev;
907 }
908 gc_ctx->idx = ARRAY_SIZE(gc_ctx->chunk->objects);
909 gc_ctx->next = NULL;
910 }
911 gc_ctx->chunk->objects[--gc_ctx->idx] = obj;
912 return S_OK;
913}
914
916{
917 jsdisp_t *obj = gc_ctx->chunk->objects[gc_ctx->idx];
918
919 if(++gc_ctx->idx == ARRAY_SIZE(gc_ctx->chunk->objects)) {
920 free(gc_ctx->next);
922 gc_ctx->chunk = gc_ctx->chunk->prev;
923 gc_ctx->idx = 0;
924 }
925 return obj;
926}
927
929{
930 /* Save original refcounts in a linked list of chunks */
931 struct chunk
932 {
933 struct chunk *next;
934 LONG ref[1020];
935 } *head, *chunk;
936 struct thread_data *thread_data = ctx->thread_data;
937 jsdisp_t *obj, *obj2, *link, *link2;
938 dispex_prop_t *prop, *props_end;
939 struct gc_ctx gc_ctx = { 0 };
940 unsigned chunk_idx = 0;
941 HRESULT hres = S_OK;
942 struct list *iter;
943
944 /* Prevent recursive calls from side-effects during unlinking (e.g. CollectGarbage from host object's Release) */
946 return S_OK;
947
948 if(!(head = malloc(sizeof(*head))))
949 return E_OUTOFMEMORY;
950 head->next = NULL;
951 chunk = head;
952
953 /* 1. Save actual refcounts and decrease them speculatively as-if we unlinked the objects */
955 if(chunk_idx == ARRAY_SIZE(chunk->ref)) {
956 if(!(chunk->next = malloc(sizeof(*chunk)))) {
957 do {
958 chunk = head->next;
959 free(head);
960 head = chunk;
961 } while(head);
962 return E_OUTOFMEMORY;
963 }
964 chunk = chunk->next; chunk_idx = 0;
965 chunk->next = NULL;
966 }
967 chunk->ref[chunk_idx++] = obj->ref;
968 }
970 /* Skip objects with external reference counter */
971 if(obj->builtin_info->addref) {
972 obj->gc_marked = FALSE;
973 continue;
974 }
975 for(prop = obj->props, props_end = prop + obj->prop_cnt; prop < props_end; prop++) {
976 switch(prop->type) {
977 case PROP_JSVAL:
978 if(is_object_instance(prop->u.val) && (link = to_jsdisp(get_object(prop->u.val))))
979 link->ref--;
980 break;
981 case PROP_ACCESSOR:
982 if(prop->u.accessor.getter)
983 prop->u.accessor.getter->ref--;
984 if(prop->u.accessor.setter)
985 prop->u.accessor.setter->ref--;
986 break;
987 default:
988 break;
989 }
990 }
991
992 if(obj->prototype)
993 obj->prototype->ref--;
994 if(obj->builtin_info->gc_traverse)
995 obj->builtin_info->gc_traverse(&gc_ctx, GC_TRAVERSE_SPECULATIVELY, obj);
996 obj->gc_marked = TRUE;
997 }
998
999 /* 2. Clear mark on objects with non-zero "external refcount" and all objects accessible from them */
1001 if(!obj->ref || !obj->gc_marked)
1002 continue;
1003
1005 if(FAILED(hres))
1006 break;
1007
1008 obj2 = obj;
1009 do
1010 {
1011 obj2->gc_marked = FALSE;
1012
1013 for(prop = obj2->props, props_end = prop + obj2->prop_cnt; prop < props_end; prop++) {
1014 switch(prop->type) {
1015 case PROP_JSVAL:
1016 if(!is_object_instance(prop->u.val))
1017 continue;
1018 link = to_jsdisp(get_object(prop->u.val));
1019 link2 = NULL;
1020 break;
1021 case PROP_ACCESSOR:
1022 link = prop->u.accessor.getter;
1023 link2 = prop->u.accessor.setter;
1024 break;
1025 default:
1026 continue;
1027 }
1028 if(link && link->gc_marked) {
1030 if(FAILED(hres))
1031 break;
1032 }
1033 if(link2 && link2->gc_marked) {
1034 hres = gc_stack_push(&gc_ctx, link2);
1035 if(FAILED(hres))
1036 break;
1037 }
1038 }
1039
1040 if(FAILED(hres))
1041 break;
1042
1043 if(obj2->prototype && obj2->prototype->gc_marked) {
1045 if(FAILED(hres))
1046 break;
1047 }
1048
1049 if(obj2->builtin_info->gc_traverse) {
1051 if(FAILED(hres))
1052 break;
1053 }
1054
1055 /* For weak refs, traverse paths accessible from it via the WeakMaps, if the WeakMaps are alive at this point.
1056 We need both the key and the WeakMap for the entry to actually be accessible (and thus traversed). */
1057 if(obj2->has_weak_refs) {
1058 struct list *list = &RB_ENTRY_VALUE(rb_get(&thread_data->weak_refs, obj2), struct weak_refs_entry, entry)->list;
1059 struct weakmap_entry *entry;
1060
1062 if(!entry->weakmap->gc_marked && is_object_instance(entry->value) && (link = to_jsdisp(get_object(entry->value)))) {
1064 if(FAILED(hres))
1065 break;
1066 }
1067 }
1068
1069 if(FAILED(hres))
1070 break;
1071 }
1072
1073 do obj2 = gc_stack_pop(&gc_ctx); while(obj2 && !obj2->gc_marked);
1074 } while(obj2);
1075
1076 if(FAILED(hres)) {
1077 do obj2 = gc_stack_pop(&gc_ctx); while(obj2);
1078 break;
1079 }
1080 }
1081 free(gc_ctx.next);
1082
1083 /* Restore */
1084 chunk = head; chunk_idx = 0;
1086 obj->ref = chunk->ref[chunk_idx++];
1087 if(chunk_idx == ARRAY_SIZE(chunk->ref)) {
1088 struct chunk *next = chunk->next;
1089 free(chunk);
1090 chunk = next; chunk_idx = 0;
1091 }
1092 }
1093 free(chunk);
1094
1095 if(FAILED(hres))
1096 return hres;
1097
1098 /* 3. Remove all the links from the marked objects, since they are dangling */
1100
1101 iter = list_head(&thread_data->objects);
1102 while(iter) {
1103 obj = LIST_ENTRY(iter, jsdisp_t, entry);
1104 if(!obj->gc_marked) {
1105 iter = list_next(&thread_data->objects, iter);
1106 continue;
1107 }
1108
1109 /* Grab it since it gets removed when unlinked */
1112
1113 /* Releasing unlinked object should not delete any other object,
1114 so we can safely obtain the next pointer now */
1115 iter = list_next(&thread_data->objects, iter);
1117 }
1118
1121 return S_OK;
1122}
1123
1125{
1126 if(op == GC_TRAVERSE_UNLINK) {
1127 *unlink_ref = NULL;
1129 return S_OK;
1130 }
1131
1133 link->ref--;
1134 else if(link->gc_marked)
1135 return gc_stack_push(gc_ctx, link);
1136 return S_OK;
1137}
1138
1140{
1141 jsdisp_t *jsdisp;
1142
1143 if(op == GC_TRAVERSE_UNLINK) {
1144 jsval_t val = *link;
1145 *link = jsval_undefined();
1147 return S_OK;
1148 }
1149
1150 if(!is_object_instance(*link) || !(jsdisp = to_jsdisp(get_object(*link))))
1151 return S_OK;
1153 jsdisp->ref--;
1154 else if(jsdisp->gc_marked)
1155 return gc_stack_push(gc_ctx, jsdisp);
1156 return S_OK;
1157}
1158
1159
1160
1164};
1165
1166typedef struct {
1170
1175
1178
1180{
1181 UINT a = 0, b = typeinfo->num_funcs;
1182
1183 while (a < b)
1184 {
1185 UINT i = (a + b - 1) / 2;
1186 MEMBERID func_memid = prop_to_id(typeinfo->jsdisp, typeinfo->funcs[i].prop);
1187
1188 if (memid == func_memid)
1189 return &typeinfo->funcs[i];
1190 else if (memid < func_memid)
1191 b = i;
1192 else
1193 a = i + 1;
1194 }
1195 return NULL;
1196}
1197
1199{
1200 UINT a = 0, b = typeinfo->num_vars;
1201
1202 while (a < b)
1203 {
1204 UINT i = (a + b - 1) / 2;
1205 MEMBERID var_memid = prop_to_id(typeinfo->jsdisp, typeinfo->vars[i]);
1206
1207 if (memid == var_memid)
1208 return typeinfo->vars[i];
1209 else if (memid < var_memid)
1210 b = i;
1211 else
1212 a = i + 1;
1213 }
1214 return NULL;
1215}
1216
1218{
1219 return CONTAINING_RECORD(iface, ScriptTypeInfo, ITypeInfo_iface);
1220}
1221
1223{
1224 return CONTAINING_RECORD(iface, ScriptTypeInfo, ITypeComp_iface);
1225}
1226
1228{
1230
1231 if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_ITypeInfo, riid))
1232 *ppv = &This->ITypeInfo_iface;
1233 else if (IsEqualGUID(&IID_ITypeComp, riid))
1234 *ppv = &This->ITypeComp_iface;
1235 else
1236 {
1237 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1238 *ppv = NULL;
1239 return E_NOINTERFACE;
1240 }
1241
1242 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1243 IUnknown_AddRef((IUnknown*)*ppv);
1244 return S_OK;
1245}
1246
1248{
1251
1252 TRACE("(%p) ref=%ld\n", This, ref);
1253
1254 return ref;
1255}
1256
1258{
1261 UINT i;
1262
1263 TRACE("(%p) ref=%ld\n", This, ref);
1264
1265 if (!ref)
1266 {
1267 for (i = This->num_funcs; i--;)
1268 release_bytecode(This->funcs[i].code->bytecode);
1269 jsdisp_release(This->jsdisp);
1270 free(This->funcs);
1271 free(This->vars);
1272 free(This);
1273 }
1274 return ref;
1275}
1276
1277static HRESULT WINAPI ScriptTypeInfo_GetTypeAttr(ITypeInfo *iface, TYPEATTR **ppTypeAttr)
1278{
1280 TYPEATTR *attr;
1281
1282 TRACE("(%p)->(%p)\n", This, ppTypeAttr);
1283
1284 if (!ppTypeAttr) return E_INVALIDARG;
1285
1286 attr = calloc(1, sizeof(*attr));
1287 if (!attr) return E_OUTOFMEMORY;
1288
1289 attr->guid = GUID_JScriptTypeInfo;
1290 attr->lcid = LOCALE_USER_DEFAULT;
1291 attr->memidConstructor = MEMBERID_NIL;
1292 attr->memidDestructor = MEMBERID_NIL;
1293 attr->cbSizeInstance = 4;
1294 attr->typekind = TKIND_DISPATCH;
1295 attr->cFuncs = This->num_funcs;
1296 attr->cVars = This->num_vars;
1297 attr->cImplTypes = 1;
1298 attr->cbSizeVft = sizeof(IDispatchVtbl);
1299 attr->cbAlignment = 4;
1300 attr->wTypeFlags = TYPEFLAG_FDISPATCHABLE;
1301 attr->wMajorVerNum = JSCRIPT_MAJOR_VERSION;
1302 attr->wMinorVerNum = JSCRIPT_MINOR_VERSION;
1303
1304 *ppTypeAttr = attr;
1305 return S_OK;
1306}
1307
1309{
1311
1312 TRACE("(%p)->(%p)\n", This, ppTComp);
1313
1314 if (!ppTComp) return E_INVALIDARG;
1315
1316 *ppTComp = &This->ITypeComp_iface;
1317 ITypeInfo_AddRef(iface);
1318 return S_OK;
1319}
1320
1321static HRESULT WINAPI ScriptTypeInfo_GetFuncDesc(ITypeInfo *iface, UINT index, FUNCDESC **ppFuncDesc)
1322{
1324 struct typeinfo_func *func;
1325 FUNCDESC *desc;
1326 unsigned i;
1327
1328 TRACE("(%p)->(%u %p)\n", This, index, ppFuncDesc);
1329
1330 if (!ppFuncDesc) return E_INVALIDARG;
1331 if (index >= This->num_funcs) return TYPE_E_ELEMENTNOTFOUND;
1332 func = &This->funcs[index];
1333
1334 /* Store the parameter array after the FUNCDESC structure */
1335 desc = calloc(1, sizeof(*desc) + sizeof(ELEMDESC) * func->code->param_cnt);
1336 if (!desc) return E_OUTOFMEMORY;
1337
1338 desc->memid = prop_to_id(This->jsdisp, func->prop);
1339 desc->funckind = FUNC_DISPATCH;
1340 desc->invkind = INVOKE_FUNC;
1341 desc->callconv = CC_STDCALL;
1342 desc->cParams = func->code->param_cnt;
1343 desc->elemdescFunc.tdesc.vt = VT_VARIANT;
1344
1345 if (func->code->param_cnt) desc->lprgelemdescParam = (ELEMDESC*)(desc + 1);
1346 for (i = 0; i < func->code->param_cnt; i++)
1347 desc->lprgelemdescParam[i].tdesc.vt = VT_VARIANT;
1348
1349 *ppFuncDesc = desc;
1350 return S_OK;
1351}
1352
1353static HRESULT WINAPI ScriptTypeInfo_GetVarDesc(ITypeInfo *iface, UINT index, VARDESC **ppVarDesc)
1354{
1356 VARDESC *desc;
1357
1358 TRACE("(%p)->(%u %p)\n", This, index, ppVarDesc);
1359
1360 if (!ppVarDesc) return E_INVALIDARG;
1361 if (index >= This->num_vars) return TYPE_E_ELEMENTNOTFOUND;
1362
1363 desc = calloc(1, sizeof(*desc));
1364 if (!desc) return E_OUTOFMEMORY;
1365
1366 desc->memid = prop_to_id(This->jsdisp, This->vars[index]);
1367 desc->varkind = VAR_DISPATCH;
1368 desc->elemdescVar.tdesc.vt = VT_VARIANT;
1369
1370 *ppVarDesc = desc;
1371 return S_OK;
1372}
1373
1374static HRESULT WINAPI ScriptTypeInfo_GetNames(ITypeInfo *iface, MEMBERID memid, BSTR *rgBstrNames,
1375 UINT cMaxNames, UINT *pcNames)
1376{
1378 struct typeinfo_func *func;
1379 ITypeInfo *disp_typeinfo;
1381 HRESULT hr;
1382 UINT i = 0;
1383
1384 TRACE("(%p)->(%ld %p %u %p)\n", This, memid, rgBstrNames, cMaxNames, pcNames);
1385
1386 if (!rgBstrNames || !pcNames) return E_INVALIDARG;
1387 if (memid <= 0) return TYPE_E_ELEMENTNOTFOUND;
1388
1390 if (!func)
1391 {
1393 if (!var)
1394 {
1395 hr = get_dispatch_typeinfo(&disp_typeinfo);
1396 if (FAILED(hr)) return hr;
1397
1398 return ITypeInfo_GetNames(disp_typeinfo, memid, rgBstrNames, cMaxNames, pcNames);
1399 }
1400 }
1401
1402 *pcNames = 0;
1403 if (!cMaxNames) return S_OK;
1404
1405 rgBstrNames[0] = SysAllocString(func ? func->prop->name : var->name);
1406 if (!rgBstrNames[0]) return E_OUTOFMEMORY;
1407 i++;
1408
1409 if (func)
1410 {
1411 unsigned num = min(cMaxNames, func->code->param_cnt + 1);
1412
1413 for (; i < num; i++)
1414 {
1415 if (!(rgBstrNames[i] = SysAllocString(func->code->params[i - 1])))
1416 {
1417 do SysFreeString(rgBstrNames[--i]); while (i);
1418 return E_OUTOFMEMORY;
1419 }
1420 }
1421 }
1422
1423 *pcNames = i;
1424 return S_OK;
1425}
1426
1428{
1430
1431 TRACE("(%p)->(%u %p)\n", This, index, pRefType);
1432
1433 /* We only inherit from IDispatch */
1434 if (!pRefType) return E_INVALIDARG;
1435 if (index != 0) return TYPE_E_ELEMENTNOTFOUND;
1436
1437 *pRefType = 1;
1438 return S_OK;
1439}
1440
1442{
1444
1445 TRACE("(%p)->(%u %p)\n", This, index, pImplTypeFlags);
1446
1447 if (!pImplTypeFlags) return E_INVALIDARG;
1448 if (index != 0) return TYPE_E_ELEMENTNOTFOUND;
1449
1450 *pImplTypeFlags = 0;
1451 return S_OK;
1452}
1453
1454static HRESULT WINAPI ScriptTypeInfo_GetIDsOfNames(ITypeInfo *iface, LPOLESTR *rgszNames, UINT cNames,
1455 MEMBERID *pMemId)
1456{
1458 ITypeInfo *disp_typeinfo;
1459 const WCHAR *name;
1460 HRESULT hr = S_OK;
1461 int i, j, arg;
1462
1463 TRACE("(%p)->(%p %u %p)\n", This, rgszNames, cNames, pMemId);
1464
1465 if (!rgszNames || !cNames || !pMemId) return E_INVALIDARG;
1466
1467 for (i = 0; i < cNames; i++) pMemId[i] = MEMBERID_NIL;
1468 name = rgszNames[0];
1469
1470 for (i = 0; i < This->num_funcs; i++)
1471 {
1472 struct typeinfo_func *func = &This->funcs[i];
1473
1474 if (wcsicmp(name, func->prop->name)) continue;
1475 pMemId[0] = prop_to_id(This->jsdisp, func->prop);
1476
1477 for (j = 1; j < cNames; j++)
1478 {
1479 name = rgszNames[j];
1480 for (arg = func->code->param_cnt; --arg >= 0;)
1481 if (!wcsicmp(name, func->code->params[arg]))
1482 break;
1483 if (arg >= 0)
1484 pMemId[j] = arg;
1485 else
1487 }
1488 return hr;
1489 }
1490
1491 for (i = 0; i < This->num_vars; i++)
1492 {
1493 dispex_prop_t *var = This->vars[i];
1494
1495 if (wcsicmp(name, var->name)) continue;
1496 pMemId[0] = prop_to_id(This->jsdisp, var);
1497 return S_OK;
1498 }
1499
1500 /* Look into the inherited IDispatch */
1501 hr = get_dispatch_typeinfo(&disp_typeinfo);
1502 if (FAILED(hr)) return hr;
1503
1504 return ITypeInfo_GetIDsOfNames(disp_typeinfo, rgszNames, cNames, pMemId);
1505}
1506
1508 DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1509{
1511 ITypeInfo *disp_typeinfo;
1512 IDispatch *disp;
1513 HRESULT hr;
1514
1515 TRACE("(%p)->(%p %ld %d %p %p %p %p)\n", This, pvInstance, memid, wFlags,
1516 pDispParams, pVarResult, pExcepInfo, puArgErr);
1517
1518 if (!pvInstance) return E_INVALIDARG;
1519 if (memid <= 0) return TYPE_E_ELEMENTNOTFOUND;
1520
1522 {
1523 hr = get_dispatch_typeinfo(&disp_typeinfo);
1524 if (FAILED(hr)) return hr;
1525
1526 return ITypeInfo_Invoke(disp_typeinfo, pvInstance, memid, wFlags, pDispParams,
1527 pVarResult, pExcepInfo, puArgErr);
1528 }
1529
1530 hr = IUnknown_QueryInterface((IUnknown*)pvInstance, &IID_IDispatch, (void**)&disp);
1531 if (FAILED(hr)) return hr;
1532
1533 hr = IDispatch_Invoke(disp, memid, &IID_NULL, LOCALE_USER_DEFAULT, wFlags,
1534 pDispParams, pVarResult, pExcepInfo, puArgErr);
1535 IDispatch_Release(disp);
1536
1537 return hr;
1538}
1539
1541 BSTR *pBstrDocString, DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
1542{
1544 struct typeinfo_func *func;
1545 ITypeInfo *disp_typeinfo;
1547 HRESULT hr;
1548
1549 TRACE("(%p)->(%ld %p %p %p %p)\n", This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
1550
1551 if (pBstrDocString) *pBstrDocString = NULL;
1552 if (pdwHelpContext) *pdwHelpContext = 0;
1553 if (pBstrHelpFile) *pBstrHelpFile = NULL;
1554
1555 if (memid == MEMBERID_NIL)
1556 {
1557 if (pBstrName && !(*pBstrName = SysAllocString(L"JScriptTypeInfo")))
1558 return E_OUTOFMEMORY;
1559 if (pBstrDocString &&
1560 !(*pBstrDocString = SysAllocString(L"JScript Type Info")))
1561 {
1562 if (pBstrName) SysFreeString(*pBstrName);
1563 return E_OUTOFMEMORY;
1564 }
1565 return S_OK;
1566 }
1567 if (memid <= 0) return TYPE_E_ELEMENTNOTFOUND;
1568
1570 if (!func)
1571 {
1573 if (!var)
1574 {
1575 hr = get_dispatch_typeinfo(&disp_typeinfo);
1576 if (FAILED(hr)) return hr;
1577
1578 return ITypeInfo_GetDocumentation(disp_typeinfo, memid, pBstrName, pBstrDocString,
1579 pdwHelpContext, pBstrHelpFile);
1580 }
1581 }
1582
1583 if (pBstrName)
1584 {
1585 *pBstrName = SysAllocString(func ? func->prop->name : var->name);
1586
1587 if (!*pBstrName)
1588 return E_OUTOFMEMORY;
1589 }
1590 return S_OK;
1591}
1592
1593static HRESULT WINAPI ScriptTypeInfo_GetDllEntry(ITypeInfo *iface, MEMBERID memid, INVOKEKIND invKind,
1594 BSTR *pBstrDllName, BSTR *pBstrName, WORD *pwOrdinal)
1595{
1597 ITypeInfo *disp_typeinfo;
1598 HRESULT hr;
1599
1600 TRACE("(%p)->(%ld %d %p %p %p)\n", This, memid, invKind, pBstrDllName, pBstrName, pwOrdinal);
1601
1602 if (pBstrDllName) *pBstrDllName = NULL;
1603 if (pBstrName) *pBstrName = NULL;
1604 if (pwOrdinal) *pwOrdinal = 0;
1605
1607 {
1608 hr = get_dispatch_typeinfo(&disp_typeinfo);
1609 if (FAILED(hr)) return hr;
1610
1611 return ITypeInfo_GetDllEntry(disp_typeinfo, memid, invKind, pBstrDllName, pBstrName, pwOrdinal);
1612 }
1613 return TYPE_E_BADMODULEKIND;
1614}
1615
1616static HRESULT WINAPI ScriptTypeInfo_GetRefTypeInfo(ITypeInfo *iface, HREFTYPE hRefType, ITypeInfo **ppTInfo)
1617{
1619 HRESULT hr;
1620
1621 TRACE("(%p)->(%lx %p)\n", This, hRefType, ppTInfo);
1622
1623 if (!ppTInfo || (INT)hRefType < 0) return E_INVALIDARG;
1624
1625 if (hRefType & ~3) return E_FAIL;
1626 if (hRefType & 1)
1627 {
1628 hr = get_dispatch_typeinfo(ppTInfo);
1629 if (FAILED(hr)) return hr;
1630 }
1631 else
1632 *ppTInfo = iface;
1633
1634 ITypeInfo_AddRef(*ppTInfo);
1635 return S_OK;
1636}
1637
1638static HRESULT WINAPI ScriptTypeInfo_AddressOfMember(ITypeInfo *iface, MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
1639{
1641 ITypeInfo *disp_typeinfo;
1642 HRESULT hr;
1643
1644 TRACE("(%p)->(%ld %d %p)\n", This, memid, invKind, ppv);
1645
1646 if (!ppv) return E_INVALIDARG;
1647 *ppv = NULL;
1648
1650 {
1651 hr = get_dispatch_typeinfo(&disp_typeinfo);
1652 if (FAILED(hr)) return hr;
1653
1654 return ITypeInfo_AddressOfMember(disp_typeinfo, memid, invKind, ppv);
1655 }
1656 return TYPE_E_BADMODULEKIND;
1657}
1658
1660{
1662
1663 TRACE("(%p)->(%p %s %p)\n", This, pUnkOuter, debugstr_guid(riid), ppvObj);
1664
1665 if (!ppvObj) return E_INVALIDARG;
1666
1667 *ppvObj = NULL;
1668 return TYPE_E_BADMODULEKIND;
1669}
1670
1671static HRESULT WINAPI ScriptTypeInfo_GetMops(ITypeInfo *iface, MEMBERID memid, BSTR *pBstrMops)
1672{
1674 ITypeInfo *disp_typeinfo;
1675 HRESULT hr;
1676
1677 TRACE("(%p)->(%ld %p)\n", This, memid, pBstrMops);
1678
1679 if (!pBstrMops) return E_INVALIDARG;
1680
1682 {
1683 hr = get_dispatch_typeinfo(&disp_typeinfo);
1684 if (FAILED(hr)) return hr;
1685
1686 return ITypeInfo_GetMops(disp_typeinfo, memid, pBstrMops);
1687 }
1688
1689 *pBstrMops = NULL;
1690 return S_OK;
1691}
1692
1694{
1696
1697 FIXME("(%p)->(%p %p)\n", This, ppTLib, pIndex);
1698
1699 return E_NOTIMPL;
1700}
1701
1702static void WINAPI ScriptTypeInfo_ReleaseTypeAttr(ITypeInfo *iface, TYPEATTR *pTypeAttr)
1703{
1705
1706 TRACE("(%p)->(%p)\n", This, pTypeAttr);
1707
1708 free(pTypeAttr);
1709}
1710
1711static void WINAPI ScriptTypeInfo_ReleaseFuncDesc(ITypeInfo *iface, FUNCDESC *pFuncDesc)
1712{
1714
1715 TRACE("(%p)->(%p)\n", This, pFuncDesc);
1716
1717 free(pFuncDesc);
1718}
1719
1720static void WINAPI ScriptTypeInfo_ReleaseVarDesc(ITypeInfo *iface, VARDESC *pVarDesc)
1721{
1723
1724 TRACE("(%p)->(%p)\n", This, pVarDesc);
1725
1726 free(pVarDesc);
1727}
1728
1729static const ITypeInfoVtbl ScriptTypeInfoVtbl = {
1752};
1753
1755{
1757 return ITypeInfo_QueryInterface(&This->ITypeInfo_iface, riid, ppv);
1758}
1759
1761{
1763 return ITypeInfo_AddRef(&This->ITypeInfo_iface);
1764}
1765
1767{
1769 return ITypeInfo_Release(&This->ITypeInfo_iface);
1770}
1771
1773 ITypeInfo **ppTInfo, DESCKIND *pDescKind, BINDPTR *pBindPtr)
1774{
1776 UINT flags = wFlags ? wFlags : ~0;
1777 ITypeInfo *disp_typeinfo;
1778 ITypeComp *disp_typecomp;
1779 HRESULT hr;
1780 UINT i;
1781
1782 TRACE("(%p)->(%s %08lx %d %p %p %p)\n", This, debugstr_w(szName), lHashVal,
1783 wFlags, ppTInfo, pDescKind, pBindPtr);
1784
1785 if (!szName || !ppTInfo || !pDescKind || !pBindPtr)
1786 return E_INVALIDARG;
1787
1788 for (i = 0; i < This->num_funcs; i++)
1789 {
1790 if (wcsicmp(szName, This->funcs[i].prop->name)) continue;
1791 if (!(flags & INVOKE_FUNC)) return TYPE_E_TYPEMISMATCH;
1792
1793 hr = ITypeInfo_GetFuncDesc(&This->ITypeInfo_iface, i, &pBindPtr->lpfuncdesc);
1794 if (FAILED(hr)) return hr;
1795
1796 *pDescKind = DESCKIND_FUNCDESC;
1797 *ppTInfo = &This->ITypeInfo_iface;
1798 ITypeInfo_AddRef(*ppTInfo);
1799 return S_OK;
1800 }
1801
1802 for (i = 0; i < This->num_vars; i++)
1803 {
1804 if (wcsicmp(szName, This->vars[i]->name)) continue;
1805 if (!(flags & INVOKE_PROPERTYGET)) return TYPE_E_TYPEMISMATCH;
1806
1807 hr = ITypeInfo_GetVarDesc(&This->ITypeInfo_iface, i, &pBindPtr->lpvardesc);
1808 if (FAILED(hr)) return hr;
1809
1810 *pDescKind = DESCKIND_VARDESC;
1811 *ppTInfo = &This->ITypeInfo_iface;
1812 ITypeInfo_AddRef(*ppTInfo);
1813 return S_OK;
1814 }
1815
1816 /* Look into the inherited IDispatch */
1817 hr = get_dispatch_typeinfo(&disp_typeinfo);
1818 if (FAILED(hr)) return hr;
1819
1820 hr = ITypeInfo_GetTypeComp(disp_typeinfo, &disp_typecomp);
1821 if (FAILED(hr)) return hr;
1822
1823 hr = ITypeComp_Bind(disp_typecomp, szName, lHashVal, wFlags, ppTInfo, pDescKind, pBindPtr);
1824 ITypeComp_Release(disp_typecomp);
1825 return hr;
1826}
1827
1829 ITypeInfo **ppTInfo, ITypeComp **ppTComp)
1830{
1832 ITypeInfo *disp_typeinfo;
1833 ITypeComp *disp_typecomp;
1834 HRESULT hr;
1835
1836 TRACE("(%p)->(%s %08lx %p %p)\n", This, debugstr_w(szName), lHashVal, ppTInfo, ppTComp);
1837
1838 if (!szName || !ppTInfo || !ppTComp)
1839 return E_INVALIDARG;
1840
1841 /* Look into the inherited IDispatch */
1842 hr = get_dispatch_typeinfo(&disp_typeinfo);
1843 if (FAILED(hr)) return hr;
1844
1845 hr = ITypeInfo_GetTypeComp(disp_typeinfo, &disp_typecomp);
1846 if (FAILED(hr)) return hr;
1847
1848 hr = ITypeComp_BindType(disp_typecomp, szName, lHashVal, ppTInfo, ppTComp);
1849 ITypeComp_Release(disp_typecomp);
1850 return hr;
1851}
1852
1853static const ITypeCompVtbl ScriptTypeCompVtbl = {
1859};
1860
1862{
1864
1865 list_remove(&obj->entry);
1866
1867 TRACE("(%p)\n", obj);
1868
1869 if(obj->has_weak_refs) {
1870 struct list *list = &RB_ENTRY_VALUE(rb_get(&obj->ctx->thread_data->weak_refs, obj), struct weak_refs_entry, entry)->list;
1871 do {
1873 } while(obj->has_weak_refs);
1874 }
1875
1876 for(prop = obj->props; prop < obj->props+obj->prop_cnt; prop++) {
1877 switch(prop->type) {
1878 case PROP_JSVAL:
1879 jsval_release(prop->u.val);
1880 break;
1881 case PROP_ACCESSOR:
1882 if(prop->u.accessor.getter)
1883 jsdisp_release(prop->u.accessor.getter);
1884 if(prop->u.accessor.setter)
1885 jsdisp_release(prop->u.accessor.setter);
1886 break;
1887 default:
1888 break;
1889 };
1890 free(prop->name);
1891 }
1892 free(obj->props);
1893 script_release(obj->ctx);
1894 if(obj->prototype)
1895 jsdisp_release(obj->prototype);
1896
1897 if(obj->builtin_info->destructor)
1898 obj->builtin_info->destructor(obj);
1899 free(obj);
1900}
1901
1903{
1904 if(obj->builtin_info->addref)
1905 obj->builtin_info->addref(obj);
1906 else
1907 ++obj->ref;
1908 return obj;
1909}
1910
1912{
1913 ULONG ref;
1914
1915 if(obj->builtin_info->release)
1916 return obj->builtin_info->release(obj);
1917
1918 ref = --obj->ref;
1919 if(!ref)
1921 return ref;
1922}
1923
1925{
1926 return CONTAINING_RECORD(iface, jsdisp_t, IWineJSDispatch_iface);
1927}
1928
1930{
1932
1934 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
1935 *ppv = &This->IWineJSDispatch_iface;
1936 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
1937 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
1938 *ppv = &This->IWineJSDispatch_iface;
1939 }else if(IsEqualGUID(&IID_IDispatchEx, riid)) {
1940 TRACE("(%p)->(IID_IDispatchEx %p)\n", This, ppv);
1941 *ppv = &This->IWineJSDispatch_iface;
1942 }else if(IsEqualGUID(&IID_IWineJSDispatch, riid)) {
1943 TRACE("(%p)->(IID_IWineJSDispatch %p)\n", This, ppv);
1944 *ppv = &This->IWineJSDispatch_iface;
1945 }else {
1946 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1947 *ppv = NULL;
1948 return E_NOINTERFACE;
1949 }
1950
1952 return S_OK;
1953}
1954
1956{
1958 if(This->builtin_info->addref)
1959 return This->builtin_info->addref(This);
1961 return This->ref;
1962}
1963
1965{
1967 return jsdisp_release(This);
1968}
1969
1971{
1973
1974 TRACE("(%p)->(%p)\n", This, pctinfo);
1975
1976 *pctinfo = 1;
1977 return S_OK;
1978}
1979
1981 ITypeInfo **ppTInfo)
1982{
1984 dispex_prop_t *prop, *cur, *end, **typevar;
1985 UINT num_funcs = 0, num_vars = 0;
1986 struct typeinfo_func *typefunc;
1987 function_code_t *func_code;
1989 unsigned pos;
1990
1991 TRACE("(%p)->(%u %lu %p)\n", This, iTInfo, lcid, ppTInfo);
1992
1993 if (iTInfo != 0) return DISP_E_BADINDEX;
1994
1995 for (prop = This->props, end = prop + This->prop_cnt; prop != end; prop++)
1996 {
1997 if (prop->type != PROP_JSVAL || !(prop->flags & PROPF_ENUMERABLE))
1998 continue;
1999
2000 /* If two identifiers differ only by case, the TypeInfo fails */
2001 pos = This->props[get_props_idx(This, prop->hash)].bucket_head;
2002 while (pos != ~0)
2003 {
2004 cur = This->props + pos;
2005
2006 if (prop->hash == cur->hash && prop != cur &&
2007 cur->type == PROP_JSVAL && (cur->flags & PROPF_ENUMERABLE) &&
2008 !wcsicmp(prop->name, cur->name))
2009 {
2010 return TYPE_E_AMBIGUOUSNAME;
2011 }
2012 pos = cur->bucket_next;
2013 }
2014
2016 {
2018 num_funcs++;
2019 }
2020 else num_vars++;
2021 }
2022
2023 if (!(typeinfo = malloc(sizeof(*typeinfo))))
2024 return E_OUTOFMEMORY;
2025
2026 typeinfo->ITypeInfo_iface.lpVtbl = &ScriptTypeInfoVtbl;
2027 typeinfo->ITypeComp_iface.lpVtbl = &ScriptTypeCompVtbl;
2028 typeinfo->ref = 1;
2029 typeinfo->num_vars = num_vars;
2030 typeinfo->num_funcs = num_funcs;
2031 typeinfo->jsdisp = This;
2032
2033 typeinfo->funcs = malloc(sizeof(*typeinfo->funcs) * num_funcs);
2034 if (!typeinfo->funcs)
2035 {
2036 free(typeinfo);
2037 return E_OUTOFMEMORY;
2038 }
2039
2040 typeinfo->vars = malloc(sizeof(*typeinfo->vars) * num_vars);
2041 if (!typeinfo->vars)
2042 {
2043 free(typeinfo->funcs);
2044 free(typeinfo);
2045 return E_OUTOFMEMORY;
2046 }
2047
2048 typefunc = typeinfo->funcs;
2049 typevar = typeinfo->vars;
2050 for (prop = This->props; prop != end; prop++)
2051 {
2052 if (prop->type != PROP_JSVAL || !(prop->flags & PROPF_ENUMERABLE))
2053 continue;
2054
2056 {
2058 if (!func_code) continue;
2059
2060 typefunc->prop = prop;
2061 typefunc->code = func_code;
2062 typefunc++;
2063
2064 /* The function may be deleted, so keep a ref */
2065 bytecode_addref(func_code->bytecode);
2066 }
2067 else
2068 *typevar++ = prop;
2069 }
2070
2071 /* Keep a ref to the props and their names */
2073
2074 *ppTInfo = &typeinfo->ITypeInfo_iface;
2075 return S_OK;
2076}
2077
2079 LPOLESTR *rgszNames, UINT cNames, LCID lcid,
2080 DISPID *rgDispId)
2081{
2083 UINT i;
2084 HRESULT hres;
2085
2086 TRACE("(%p)->(%s %p %u %lu %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
2087 lcid, rgDispId);
2088
2089 if(cNames == 0)
2090 return S_OK;
2091
2092 hres = jsdisp_get_id(This, rgszNames[0], 0, rgDispId);
2093 if(FAILED(hres))
2094 return hres;
2095
2096 /* DISPIDs for parameters don't seem to be supported */
2097 if(cNames > 1) {
2098 for(i = 1; i < cNames; i++)
2099 rgDispId[i] = DISPID_UNKNOWN;
2101 }
2102
2103 return hres;
2104}
2105
2107 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
2108 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
2109{
2111
2112 TRACE("(%p)->(%ld %s %ld %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
2113 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2114
2115 return IDispatchEx_InvokeEx(to_dispex(This), dispIdMember, lcid, wFlags,
2116 pDispParams, pVarResult, pExcepInfo, NULL);
2117}
2118
2120{
2122
2123 TRACE("(%p)->(%s %lx %p)\n", This, debugstr_w(bstrName), grfdex, pid);
2124
2125 if(grfdex & ~(fdexNameCaseSensitive|fdexNameCaseInsensitive|fdexNameEnsure|fdexNameImplicit|FDEX_VERSION_MASK)) {
2126 FIXME("Unsupported grfdex %lx\n", grfdex);
2127 return E_NOTIMPL;
2128 }
2129
2130 return jsdisp_get_id(This, bstrName, grfdex, pid);
2131}
2132
2134 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
2135{
2137 IServiceProvider *prev_caller;
2139 jsexcept_t ei;
2140 HRESULT hres;
2141
2142 TRACE("(%p)->(%lx %lx %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
2143
2144 if(pvarRes)
2145 V_VT(pvarRes) = VT_EMPTY;
2146
2147 prop = get_prop(This, id);
2148 if(!prop && id != DISPID_VALUE) {
2149 TRACE("invalid id\n");
2150 return DISP_E_MEMBERNOTFOUND;
2151 }
2152
2153 enter_script(This->ctx, &ei);
2154
2155 prev_caller = This->ctx->jscaller->caller;
2156 This->ctx->jscaller->caller = pspCaller;
2157 if(pspCaller)
2158 IServiceProvider_AddRef(pspCaller);
2159
2160 switch(wFlags) {
2163 /* fall through */
2164 case DISPATCH_METHOD:
2165 case DISPATCH_CONSTRUCT: {
2166 jsval_t *argv, buf[6], r;
2167 IDispatch *passed_this;
2168 unsigned argc;
2169
2170 hres = convert_params(This->ctx, pdp, buf, &argc, &argv);
2171 if(FAILED(hres))
2172 break;
2173
2174 passed_this = get_this(pdp);
2175 if(prop)
2176 hres = invoke_prop_func(This, passed_this, prop, wFlags, argc, argv, pvarRes ? &r : NULL, pspCaller);
2177 else
2178 hres = jsdisp_call_value(This, passed_this ? jsval_disp(passed_this) : jsval_undefined(), wFlags, argc, argv, pvarRes ? &r : NULL);
2179
2180 while(argc--)
2182 if(argv != buf)
2183 free(argv);
2184 if(SUCCEEDED(hres) && pvarRes) {
2185 hres = jsval_to_variant(r, pvarRes);
2187 }
2188 break;
2189 }
2190 case DISPATCH_PROPERTYGET: {
2191 jsval_t r;
2192
2193 if(prop)
2195 else {
2197 if(hres == JS_E_TO_PRIMITIVE)
2199 }
2200
2201 if(SUCCEEDED(hres)) {
2202 hres = jsval_to_variant(r, pvarRes);
2204 }
2205 break;
2206 }
2209 case DISPATCH_PROPERTYPUT: {
2210 jsval_t val;
2211 DWORD i;
2212
2213 if(!prop) {
2215 break;
2216 }
2217
2218 for(i=0; i < pdp->cNamedArgs; i++) {
2219 if(pdp->rgdispidNamedArgs[i] == DISPID_PROPERTYPUT)
2220 break;
2221 }
2222
2223 if(i == pdp->cNamedArgs) {
2224 TRACE("no value to set\n");
2226 break;
2227 }
2228
2229 hres = variant_to_jsval(This->ctx, pdp->rgvarg+i, &val);
2230 if(FAILED(hres))
2231 break;
2232
2233 hres = prop_put(This, prop, val);
2235 break;
2236 }
2237 default:
2238 FIXME("Unimplemented flags %x\n", wFlags);
2240 break;
2241 }
2242
2243 This->ctx->jscaller->caller = prev_caller;
2244 if(pspCaller)
2245 IServiceProvider_Release(pspCaller);
2246 return leave_script(This->ctx, hres);
2247}
2248
2250{
2251 if(prop->type == PROP_PROTREF || prop->type == PROP_DELETED) {
2252 *ret = TRUE;
2253 return S_OK;
2254 }
2255
2256 if(!(prop->flags & PROPF_CONFIGURABLE)) {
2257 *ret = FALSE;
2258 return S_OK;
2259 }
2260
2261 *ret = TRUE;
2262
2263 switch(prop->type) {
2264 case PROP_JSVAL:
2266 break;
2267 case PROP_ACCESSOR:
2268 if(prop->u.accessor.getter)
2269 jsdisp_release(prop->u.accessor.getter);
2270 if(prop->u.accessor.setter)
2271 jsdisp_release(prop->u.accessor.setter);
2272 break;
2273 case PROP_EXTERN:
2274 if(obj->builtin_info->prop_delete) {
2275 HRESULT hres;
2276 hres = obj->builtin_info->prop_delete(obj, prop->u.id);
2277 if(FAILED(hres))
2278 return hres;
2279 }
2280 break;
2281 default:
2282 break;
2283 }
2285 return S_OK;
2286}
2287
2289{
2292 BOOL b;
2293 HRESULT hres;
2294
2295 TRACE("(%p)->(%s %lx)\n", This, debugstr_w(bstrName), grfdex);
2296
2297 if(grfdex & ~(fdexNameCaseSensitive|fdexNameCaseInsensitive|fdexNameEnsure|fdexNameImplicit|FDEX_VERSION_MASK))
2298 FIXME("Unsupported grfdex %lx\n", grfdex);
2299
2300 hres = find_prop_name(This, string_hash(bstrName), bstrName, grfdex & fdexNameCaseInsensitive, NULL, &prop);
2301 if(FAILED(hres))
2302 return hres;
2303 if(!prop) {
2304 TRACE("not found\n");
2305 return S_OK;
2306 }
2307
2308 return delete_prop(This, prop, &b);
2309}
2310
2312{
2315 BOOL b;
2316
2317 TRACE("(%p)->(%lx)\n", This, id);
2318
2319 prop = get_prop(This, id);
2320 if(!prop) {
2321 WARN("invalid id\n");
2322 return DISP_E_MEMBERNOTFOUND;
2323 }
2324
2325 return delete_prop(This, prop, &b);
2326}
2327
2329{
2332
2333 TRACE("(%p)->(%lx %lx %p)\n", This, id, grfdexFetch, pgrfdex);
2334
2335 prop = get_prop(This, id);
2336 if(!prop)
2337 return DISP_E_MEMBERNOTFOUND;
2338 *pgrfdex = 0;
2339
2340 if(grfdexFetch) {
2341 FIXME("unimplemented flags %08lx\n", grfdexFetch);
2342 return E_NOTIMPL;
2343 }
2344
2345 return S_OK;
2346}
2347
2349{
2352
2353 TRACE("(%p)->(%lx %p)\n", This, id, pbstrName);
2354
2355 prop = get_prop(This, id);
2356 if(!prop)
2357 return DISP_E_MEMBERNOTFOUND;
2358
2359 *pbstrName = SysAllocString(prop->name);
2360 if(!*pbstrName)
2361 return E_OUTOFMEMORY;
2362
2363 return S_OK;
2364}
2365
2367{
2370
2371 TRACE("(%p)->(%lx %lx %p)\n", This, grfdex, id, pid);
2372
2373 if(id != DISPID_VALUE)
2375 if(hres == S_FALSE)
2376 *pid = DISPID_STARTENUM;
2377 return hres;
2378}
2379
2381{
2383 FIXME("(%p)->(%p)\n", This, ppunk);
2384 return E_NOTIMPL;
2385}
2386
2388{
2391}
2392
2394{
2397
2398 if(!prop || prop->type == PROP_DELETED || prop->type == PROP_PROTREF)
2399 return DISP_E_MEMBERNOTFOUND;
2400
2402 return S_OK;
2403}
2404
2406{
2408 IDispatch *disp;
2409
2410 if(!This->ctx->site)
2411 return E_UNEXPECTED;
2412
2413 if(!(disp = lookup_global_host(This->ctx)))
2414 return E_NOINTERFACE;
2415
2416 *ret = get_host_dispatch(disp);
2417 return S_OK;
2418}
2419
2420static IWineJSDispatchVtbl DispatchExVtbl = {
2439};
2440
2442{
2443 assert(disp->lpVtbl == (IDispatchVtbl*)&DispatchExVtbl);
2445}
2446
2448{
2449 if(disp->lpVtbl != (IDispatchVtbl*)&DispatchExVtbl)
2450 return NULL;
2452}
2453
2454HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype)
2455{
2456 unsigned i;
2457
2458 /* FIXME: Use better heuristics to decide when to run the GC */
2459 if(GetTickCount() - ctx->thread_data->gc_last_tick > 30000)
2460 gc_run(ctx);
2461
2462 TRACE("%p (%p)\n", dispex, prototype);
2463
2464 dispex->IWineJSDispatch_iface.lpVtbl = &DispatchExVtbl;
2465 dispex->ref = 1;
2466 dispex->builtin_info = builtin_info;
2467 dispex->extensible = TRUE;
2468 dispex->is_constructor = builtin_info->class == JSCLASS_FUNCTION;
2469 dispex->prop_cnt = 0;
2470
2471 dispex->props = calloc(1, sizeof(dispex_prop_t)*(dispex->buf_size=4));
2472 if(!dispex->props)
2473 return E_OUTOFMEMORY;
2474
2475 for(i = 0; i < dispex->buf_size; i++) {
2476 dispex->props[i].bucket_head = ~0;
2477 dispex->props[i].bucket_next = ~0;
2478 }
2479
2480 dispex->prototype = prototype;
2481 if(prototype)
2482 jsdisp_addref(prototype);
2483
2485 dispex->ctx = ctx;
2486
2487 list_add_tail(&ctx->thread_data->objects, &dispex->entry);
2488 return S_OK;
2489}
2490
2492
2493HRESULT create_dispex(script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype, jsdisp_t **dispex)
2494{
2495 jsdisp_t *ret;
2496 HRESULT hres;
2497
2498 ret = calloc(1, sizeof(jsdisp_t));
2499 if(!ret)
2500 return E_OUTOFMEMORY;
2501
2502 hres = init_dispex(ret, ctx, builtin_info ? builtin_info : &dispex_info, prototype);
2503 if(FAILED(hres)) {
2504 free(ret);
2505 return hres;
2506 }
2507
2508 *dispex = ret;
2509 return S_OK;
2510}
2511
2513{
2514 jsdisp_t *prot = NULL;
2516 HRESULT hres;
2517
2518 hres = find_prop_name_prot(constr, string_hash(L"prototype"), L"prototype", FALSE, NULL, &prop);
2519 if(SUCCEEDED(hres) && prop && prop->type!=PROP_DELETED) {
2520 jsval_t val;
2521
2522 hres = prop_get(constr, to_disp(constr), prop, &val);
2523 if(FAILED(hres)) {
2524 ERR("Could not get prototype\n");
2525 return hres;
2526 }
2527
2530 else
2531 prot = jsdisp_addref(ctx->object_prototype);
2532
2534 }
2535
2536 hres = init_dispex(dispex, ctx, builtin_info, prot);
2537
2538 if(prot)
2539 jsdisp_release(prot);
2540 return hres;
2541}
2542
2544{
2545 return iface->lpVtbl == (const IDispatchVtbl*)&DispatchExVtbl
2547 : NULL;
2548}
2549
2551{
2553 HRESULT hres;
2554
2555 if(jsdisp->extensible && (flags & fdexNameEnsure))
2557 flags & fdexNameCaseInsensitive, &prop);
2558 else
2559 hres = find_prop_name_prot(jsdisp, string_hash(name), name, flags & fdexNameCaseInsensitive, NULL, &prop);
2560 if(FAILED(hres))
2561 return hres;
2562
2563 if(prop && prop->type!=PROP_DELETED) {
2564 *id = prop_to_id(jsdisp, prop);
2565 return S_OK;
2566 }
2567
2568 TRACE("not found %s\n", debugstr_w(name));
2569 *id = DISPID_UNKNOWN;
2570 return DISP_E_UNKNOWNNAME;
2571}
2572
2574{
2575 WCHAR name[11];
2576
2577 swprintf(name, ARRAY_SIZE(name), L"%u", idx);
2578 return jsdisp_get_id(jsdisp, name, 0, id);
2579}
2580
2582{
2583 HRESULT hres;
2584
2585 assert(!(flags & ~(DISPATCH_METHOD|DISPATCH_CONSTRUCT|DISPATCH_JSCRIPT_INTERNAL_MASK)));
2586
2587 if(is_class(jsfunc, JSCLASS_FUNCTION)) {
2588 hres = Function_invoke(jsfunc, vthis, flags, argc, argv, r);
2589 }else {
2590 if(!jsfunc->builtin_info->call) {
2591 WARN("Not a function\n");
2593 }
2594
2595 if(jsfunc->ctx->state == SCRIPTSTATE_UNINITIALIZED || jsfunc->ctx->state == SCRIPTSTATE_CLOSED)
2596 return E_UNEXPECTED;
2597
2598 flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK;
2599 hres = jsfunc->builtin_info->call(jsfunc->ctx, vthis, flags, argc, argv, r);
2600 }
2601 return hres;
2602}
2603
2605{
2607
2608 prop = get_prop(disp, id);
2609 if(!prop)
2610 return DISP_E_MEMBERNOTFOUND;
2611
2612 return invoke_prop_func(disp, to_disp(disp), prop, flags, argc, argv, r, &disp->ctx->jscaller->IServiceProvider_iface);
2613}
2614
2616{
2618 HRESULT hres;
2619
2621 if(FAILED(hres))
2622 return hres;
2623
2624 if(!prop || prop->type == PROP_DELETED)
2625 return JS_E_INVALID_PROPERTY;
2626
2627 return invoke_prop_func(disp, to_disp(disp), prop, flags, argc, argv, r, &disp->ctx->jscaller->IServiceProvider_iface);
2628}
2629
2631 IServiceProvider *caller)
2632{
2633 IDispatchEx *dispex;
2634 EXCEPINFO ei;
2635 HRESULT hres;
2636
2637 memset(&ei, 0, sizeof(ei));
2638 hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
2639 if(SUCCEEDED(hres)) {
2640 hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, flags, params, r, &ei, caller);
2641 IDispatchEx_Release(dispex);
2642 }else {
2643 UINT err = 0;
2644
2645 if(flags == DISPATCH_CONSTRUCT) {
2646 WARN("IDispatch cannot be constructor\n");
2647 return DISP_E_MEMBERNOTFOUND;
2648 }
2649
2650 if(params->cNamedArgs == 1 && params->rgdispidNamedArgs[0] == DISPID_THIS) {
2651 params->cNamedArgs = 0;
2652 params->rgdispidNamedArgs = NULL;
2653 params->cArgs--;
2654 params->rgvarg++;
2655 }
2656
2657 TRACE("using IDispatch\n");
2658 hres = IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, flags, params, r, &ei, &err);
2659 }
2660
2661 if(hres == DISP_E_EXCEPTION)
2663 return hres;
2664}
2665
2667{
2668 VARIANT buf[6], retv;
2669 jsdisp_t *jsdisp;
2670 DISPPARAMS dp;
2671 unsigned i;
2672 HRESULT hres;
2673
2674 jsdisp = iface_to_jsdisp(disp);
2675 if(jsdisp && jsdisp->ctx == ctx) {
2677 FIXME("disp_call(propput) on builtin object\n");
2678 jsdisp_release(jsdisp);
2679 return E_FAIL;
2680 }
2681
2682 if(ctx != jsdisp->ctx)
2683 flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK;
2684 hres = jsdisp_call(jsdisp, id, flags, argc, argv, ret);
2685 jsdisp_release(jsdisp);
2686 return hres;
2687 }
2688 if(jsdisp)
2689 jsdisp_release(jsdisp);
2690
2691 flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK;
2692 if(ret && argc)
2694
2695 dp.cArgs = argc;
2696
2698 static DISPID propput_dispid = DISPID_PROPERTYPUT;
2699
2700 dp.cNamedArgs = 1;
2701 dp.rgdispidNamedArgs = &propput_dispid;
2702 }else {
2703 dp.cNamedArgs = 0;
2704 dp.rgdispidNamedArgs = NULL;
2705 }
2706
2707 if(dp.cArgs > ARRAY_SIZE(buf)) {
2708 dp.rgvarg = malloc(argc * sizeof(VARIANT));
2709 if(!dp.rgvarg)
2710 return E_OUTOFMEMORY;
2711 }else {
2712 dp.rgvarg = buf;
2713 }
2714
2715 for(i=0; i<argc; i++) {
2716 hres = jsval_to_variant(argv[i], dp.rgvarg+argc-i-1);
2717 if(FAILED(hres)) {
2718 while(i--)
2719 VariantClear(dp.rgvarg+argc-i-1);
2720 if(dp.rgvarg != buf)
2721 free(dp.rgvarg);
2722 return hres;
2723 }
2724 }
2725
2726 V_VT(&retv) = VT_EMPTY;
2727 hres = disp_invoke(ctx, disp, id, flags, &dp, ret ? &retv : NULL, &ctx->jscaller->IServiceProvider_iface);
2728
2729 for(i=0; i<argc; i++)
2730 VariantClear(dp.rgvarg+argc-i-1);
2731 if(dp.rgvarg != buf)
2732 free(dp.rgvarg);
2733
2734 if(SUCCEEDED(hres) && ret)
2735 hres = variant_to_jsval(ctx, &retv, ret);
2736 VariantClear(&retv);
2737 return hres;
2738}
2739
2741{
2742 IDispatchEx *dispex;
2743 jsdisp_t *jsdisp;
2744 HRESULT hres;
2745 DISPID id;
2746 BSTR bstr;
2747
2748 if((jsdisp = to_jsdisp(disp)) && jsdisp->ctx == ctx)
2749 return jsdisp_call_name(jsdisp, name, flags, argc, argv, ret);
2750
2751 if(!(bstr = SysAllocString(name)))
2752 return E_OUTOFMEMORY;
2753 hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
2754 if(SUCCEEDED(hres) && dispex) {
2755 hres = IDispatchEx_GetDispID(dispex, bstr, make_grfdex(ctx, fdexNameCaseSensitive), &id);
2756 IDispatchEx_Release(dispex);
2757 }else {
2758 hres = IDispatch_GetIDsOfNames(disp, &IID_NULL, &bstr, 1, 0, &id);
2759 }
2760 SysFreeString(bstr);
2761 if(FAILED(hres))
2762 return hres;
2763
2764 return disp_call(ctx, disp, id, flags, argc, argv, ret);
2765}
2766
2769{
2770 VARIANT buf[6], retv, *args = buf;
2771 IDispatch *jsthis;
2772 jsdisp_t *jsdisp;
2773 DISPPARAMS dp;
2774 unsigned i;
2775 HRESULT hres = S_OK;
2776
2777 static DISPID this_id = DISPID_THIS;
2778
2779 assert(!(flags & ~(DISPATCH_METHOD|DISPATCH_CONSTRUCT|DISPATCH_JSCRIPT_INTERNAL_MASK)));
2780
2781 jsdisp = iface_to_jsdisp(disp);
2782 if(jsdisp && jsdisp->ctx == ctx) {
2783 hres = jsdisp_call_value(jsdisp, vthis, flags, argc, argv, r);
2784 jsdisp_release(jsdisp);
2785 return hres;
2786 }
2787 if(jsdisp)
2788 jsdisp_release(jsdisp);
2789
2790 if(is_object_instance(vthis) && (ctx->version < SCRIPTLANGUAGEVERSION_ES5 ||
2791 ((jsdisp = to_jsdisp(get_object(vthis))) && is_class(jsdisp, JSCLASS_OBJECT))))
2792 jsthis = get_object(vthis);
2793 else
2794 jsthis = NULL;
2795
2796 flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK;
2797 if(r && argc && flags == DISPATCH_METHOD)
2799
2800 if(jsthis) {
2801 dp.cArgs = argc + 1;
2802 dp.cNamedArgs = 1;
2803 dp.rgdispidNamedArgs = &this_id;
2804 }else {
2805 dp.cArgs = argc;
2806 dp.cNamedArgs = 0;
2807 dp.rgdispidNamedArgs = NULL;
2808 }
2809
2810 if(dp.cArgs > ARRAY_SIZE(buf) && !(args = malloc(dp.cArgs * sizeof(VARIANT))))
2811 return E_OUTOFMEMORY;
2812 dp.rgvarg = args;
2813
2814 if(jsthis) {
2815 V_VT(dp.rgvarg) = VT_DISPATCH;
2816 V_DISPATCH(dp.rgvarg) = jsthis;
2817 }
2818
2819 for(i=0; SUCCEEDED(hres) && i < argc; i++)
2820 hres = jsval_to_variant(argv[i], dp.rgvarg+dp.cArgs-i-1);
2821
2822 if(SUCCEEDED(hres)) {
2823 V_VT(&retv) = VT_EMPTY;
2824 hres = disp_invoke(ctx, disp, DISPID_VALUE, flags, &dp, r ? &retv : NULL, caller);
2825 }
2826
2827 for(i = 0; i < argc; i++)
2828 VariantClear(dp.rgvarg + dp.cArgs - i - 1);
2829 if(args != buf)
2830 free(args);
2831
2832 if(FAILED(hres))
2833 return hres;
2834 if(!r)
2835 return S_OK;
2836
2837 hres = variant_to_jsval(ctx, &retv, r);
2838 VariantClear(&retv);
2839 return hres;
2840}
2841
2843{
2845 HRESULT hres;
2846
2847 if(obj->extensible)
2849 else
2851 if(FAILED(hres))
2852 return hres;
2853 if(!prop || (prop->type == PROP_DELETED && !obj->extensible))
2854 return throw ? JS_E_INVALID_ACTION : S_OK;
2855
2856 return prop_put(obj, prop, val);
2857}
2858
2860{
2862}
2863
2865{
2866 WCHAR buf[12];
2867
2868 swprintf(buf, ARRAY_SIZE(buf), L"%d", idx);
2870}
2871
2873{
2874 jsdisp_t *jsdisp;
2875 HRESULT hres;
2876
2877 jsdisp = iface_to_jsdisp(disp);
2878 if(jsdisp && jsdisp->ctx == ctx) {
2880
2881 prop = get_prop(jsdisp, id);
2882 if(prop)
2883 hres = prop_put(jsdisp, prop, val);
2884 else
2886
2887 jsdisp_release(jsdisp);
2888 }else {
2889 DISPID dispid = DISPID_PROPERTYPUT;
2891 VARIANT var;
2892 DISPPARAMS dp = {&var, &dispid, 1, 1};
2893
2894 if(jsdisp)
2895 jsdisp_release(jsdisp);
2897 if(FAILED(hres))
2898 return hres;
2899
2900 if(V_VT(&var) == VT_DISPATCH)
2902
2903 hres = disp_invoke(ctx, disp, id, flags, &dp, NULL, &ctx->jscaller->IServiceProvider_iface);
2904 VariantClear(&var);
2905 }
2906
2907 return hres;
2908}
2909
2911{
2912 jsdisp_t *jsdisp;
2913 HRESULT hres;
2914
2915 jsdisp = iface_to_jsdisp(disp);
2916 if(!jsdisp || jsdisp->ctx != ctx) {
2917 IDispatchEx *dispex;
2918 BSTR str;
2919 DISPID id;
2920
2921 if(jsdisp)
2922 jsdisp_release(jsdisp);
2923 if(!(str = SysAllocString(name)))
2924 return E_OUTOFMEMORY;
2925
2926 hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
2927 if(SUCCEEDED(hres)) {
2928 hres = IDispatchEx_GetDispID(dispex, str, make_grfdex(ctx, fdexNameEnsure|fdexNameCaseSensitive), &id);
2929 IDispatchEx_Release(dispex);
2930 }else {
2931 TRACE("using IDispatch\n");
2932 hres = IDispatch_GetIDsOfNames(disp, &IID_NULL, &str, 1, 0, &id);
2933 }
2935 if(FAILED(hres))
2936 return hres;
2937
2938 return disp_propput(ctx, disp, id, val);
2939 }
2940
2941 hres = jsdisp_propput_name(jsdisp, name, val);
2942 jsdisp_release(jsdisp);
2943 return hres;
2944}
2945
2947{
2949 HRESULT hres;
2950
2952 if(FAILED(hres))
2953 return hres;
2954
2955 if(!prop || prop->type==PROP_DELETED) {
2956 *val = jsval_undefined();
2957 return S_OK;
2958 }
2959
2960 return prop_get(obj, to_disp(obj), prop, val);
2961}
2962
2964{
2965 WCHAR name[12];
2967 HRESULT hres;
2968
2969 swprintf(name, ARRAY_SIZE(name), L"%d", idx);
2970
2972 if(FAILED(hres))
2973 return hres;
2974
2975 if(!prop || prop->type==PROP_DELETED) {
2976 *r = jsval_undefined();
2977 return DISP_E_UNKNOWNNAME;
2978 }
2979
2980 return prop_get(obj, to_disp(obj), prop, r);
2981}
2982
2984{
2986
2987 prop = get_prop(jsdisp, id);
2988 if(!prop)
2989 return DISP_E_MEMBERNOTFOUND;
2990
2991 return prop_get(jsdisp, to_disp(jsdisp), prop, val);
2992}
2993
2995{
2996 DISPPARAMS dp = {NULL,NULL,0,0};
2997 jsdisp_t *jsdisp;
2998 VARIANT var;
2999 HRESULT hres;
3000
3001 jsdisp = iface_to_jsdisp(disp);
3002 if(jsdisp && jsdisp->ctx == ctx) {
3003 hres = jsdisp_propget(jsdisp, id, val);
3004 jsdisp_release(jsdisp);
3005 return hres;
3006 }
3007 if(jsdisp)
3008 jsdisp_release(jsdisp);
3009
3010 V_VT(&var) = VT_EMPTY;
3011 hres = disp_invoke(ctx, disp, id, INVOKE_PROPERTYGET, &dp, &var, &ctx->jscaller->IServiceProvider_iface);
3012 if(SUCCEEDED(hres)) {
3014 VariantClear(&var);
3015 }
3016 return hres;
3017}
3018
3020{
3021 WCHAR buf[12];
3023 BOOL b;
3024 HRESULT hres;
3025
3026 swprintf(buf, ARRAY_SIZE(buf), L"%d", idx);
3027
3029 if(FAILED(hres) || !prop)
3030 return hres;
3031
3032 hres = delete_prop(obj, prop, &b);
3033 if(FAILED(hres))
3034 return hres;
3035 return b ? S_OK : JS_E_INVALID_ACTION;
3036}
3037
3039{
3040 IDispatchEx *dispex;
3041 jsdisp_t *jsdisp;
3042 HRESULT hres;
3043
3044 jsdisp = iface_to_jsdisp(disp);
3045 if(jsdisp) {
3047
3048 prop = get_prop(jsdisp, id);
3049 if(prop)
3050 hres = delete_prop(jsdisp, prop, ret);
3051 else
3053
3054 jsdisp_release(jsdisp);
3055 return hres;
3056 }
3057
3058 hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
3059 if(FAILED(hres)) {
3060 *ret = FALSE;
3061 return S_OK;
3062 }
3063
3064 hres = IDispatchEx_DeleteMemberByDispID(dispex, id);
3065 IDispatchEx_Release(dispex);
3066 if(FAILED(hres))
3067 return hres;
3068
3069 *ret = hres == S_OK;
3070 return S_OK;
3071}
3072
3074{
3075 dispex_prop_t *iter;
3076 DWORD idx = id;
3077 HRESULT hres;
3078
3079 if(id == DISPID_STARTENUM || idx >= obj->prop_cnt) {
3080 hres = (enum_type == JSDISP_ENUM_ALL) ? fill_protrefs(obj) : fill_props(obj);
3081 if(FAILED(hres))
3082 return hres;
3083 if(id == DISPID_STARTENUM)
3084 idx = 0;
3085 if(idx >= obj->prop_cnt)
3086 return S_FALSE;
3087 }
3088
3089 for(iter = &obj->props[idx]; iter < obj->props + obj->prop_cnt; iter++) {
3090 if(iter->type == PROP_EXTERN) {
3092 hres = find_external_prop(obj, iter->name, FALSE, iter, &prop);
3093 if(FAILED(hres) || prop != iter)
3094 iter->type = PROP_DELETED;
3095 }
3096 if(iter->type == PROP_DELETED)
3097 continue;
3098 if(enum_type != JSDISP_ENUM_ALL && iter->type == PROP_PROTREF)
3099 continue;
3100 if(enum_type != JSDISP_ENUM_OWN && !(get_flags(obj, iter) & PROPF_ENUMERABLE))
3101 continue;
3102 *ret = prop_to_id(obj, iter);
3103 return S_OK;
3104 }
3105
3106 if(obj->ctx->html_mode)
3107 return jsdisp_next_prop(obj, prop_to_id(obj, iter - 1), enum_type, ret);
3108
3109 return S_FALSE;
3110}
3111
3113{
3114 IDispatchEx *dispex;
3115 jsdisp_t *jsdisp;
3116 BSTR bstr;
3117 HRESULT hres;
3118
3119 jsdisp = iface_to_jsdisp(disp);
3120 if(jsdisp) {
3122 const WCHAR *ptr;
3123
3125 if(!ptr) {
3126 jsdisp_release(jsdisp);
3127 return E_OUTOFMEMORY;
3128 }
3129
3131 if(prop) {
3132 hres = delete_prop(jsdisp, prop, ret);
3133 }else {
3134 *ret = TRUE;
3135 hres = S_OK;
3136 }
3137
3138 jsdisp_release(jsdisp);
3139 return hres;
3140 }
3141
3143 if(!bstr)
3144 return E_OUTOFMEMORY;
3145 jsstr_flush(name, bstr);
3146
3147 hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
3148 if(SUCCEEDED(hres)) {
3149 hres = IDispatchEx_DeleteMemberByName(dispex, bstr, make_grfdex(ctx, fdexNameCaseSensitive));
3150 if(SUCCEEDED(hres))
3151 *ret = hres == S_OK;
3152 IDispatchEx_Release(dispex);
3153 }else {
3154 DISPID id;
3155
3156 hres = IDispatch_GetIDsOfNames(disp, &IID_NULL, &bstr, 1, 0, &id);
3157 if(SUCCEEDED(hres)) {
3158 /* Property exists and we can't delete it from pure IDispatch interface, so return false. */
3159 *ret = FALSE;
3160 }else if(hres == DISP_E_UNKNOWNNAME) {
3161 /* Property doesn't exist, so nothing to delete */
3162 *ret = TRUE;
3163 hres = S_OK;
3164 }
3165 }
3166
3167 SysFreeString(bstr);
3168 return hres;
3169}
3170
3173{
3175 HRESULT hres;
3176
3178 if(FAILED(hres))
3179 return hres;
3180
3181 if(!prop)
3182 return DISP_E_UNKNOWNNAME;
3183
3184 memset(desc, 0, sizeof(*desc));
3185
3186 switch(prop->type) {
3187 case PROP_BUILTIN:
3188 case PROP_JSVAL:
3189 case PROP_EXTERN:
3190 desc->mask |= PROPF_WRITABLE;
3191 desc->explicit_value = TRUE;
3192 if(!flags_only) {
3193 hres = prop_get(obj, to_disp(obj), prop, &desc->value);
3194 if(FAILED(hres))
3195 return hres;
3196 }
3197 break;
3198 case PROP_ACCESSOR:
3199 desc->explicit_getter = desc->explicit_setter = TRUE;
3200 if(!flags_only) {
3201 desc->getter = prop->u.accessor.getter
3202 ? jsdisp_addref(prop->u.accessor.getter) : NULL;
3203 desc->setter = prop->u.accessor.setter
3204 ? jsdisp_addref(prop->u.accessor.setter) : NULL;
3205 }
3206 break;
3207 default:
3208 return DISP_E_UNKNOWNNAME;
3209 }
3210
3213 return S_OK;
3214}
3215
3217{
3219 HRESULT hres;
3220
3222 if(FAILED(hres))
3223 return hres;
3224
3225 if((!prop || prop->type == PROP_DELETED || prop->type == PROP_PROTREF) && !obj->extensible)
3227
3228 if(!prop && !(prop = alloc_prop(obj, name, PROP_DELETED, 0)))
3229 return E_OUTOFMEMORY;
3230
3231 if(prop->type == PROP_DELETED || prop->type == PROP_PROTREF) {
3232 prop->flags = desc->flags;
3233 if(desc->explicit_getter || desc->explicit_setter) {
3235 prop->u.accessor.getter = desc->getter ? jsdisp_addref(desc->getter) : NULL;
3236 prop->u.accessor.setter = desc->setter ? jsdisp_addref(desc->setter) : NULL;
3237 TRACE("%s = accessor { get: %p set: %p }\n", debugstr_w(name),
3238 prop->u.accessor.getter, prop->u.accessor.setter);
3239 }else {
3240 prop->type = PROP_JSVAL;
3241 if(desc->explicit_value) {
3242 hres = jsval_copy(desc->value, &prop->u.val);
3243 if(FAILED(hres))
3244 return hres;
3245 }else {
3247 }
3248 TRACE("%s = %s\n", debugstr_w(name), debugstr_jsval(prop->u.val));
3249 }
3250 return S_OK;
3251 }
3252
3253 TRACE("existing prop %s prop flags %lx desc flags %x desc mask %x\n", debugstr_w(name),
3254 prop->flags, desc->flags, desc->mask);
3255
3256 if(!(prop->flags & PROPF_CONFIGURABLE)) {
3257 if(((desc->mask & PROPF_CONFIGURABLE) && (desc->flags & PROPF_CONFIGURABLE))
3258 || ((desc->mask & PROPF_ENUMERABLE)
3259 && ((desc->flags & PROPF_ENUMERABLE) != (prop->flags & PROPF_ENUMERABLE))))
3261 }
3262
3263 if(desc->explicit_value || (desc->mask & PROPF_WRITABLE)) {
3264 if(prop->type == PROP_ACCESSOR) {
3265 if(!(prop->flags & PROPF_CONFIGURABLE))
3267 if(prop->u.accessor.getter)
3268 jsdisp_release(prop->u.accessor.getter);
3269 if(prop->u.accessor.setter)
3270 jsdisp_release(prop->u.accessor.setter);
3271
3272 prop->type = PROP_JSVAL;
3273 hres = jsval_copy(desc->value, &prop->u.val);
3274 if(FAILED(hres)) {
3276 return hres;
3277 }
3278 }else {
3280 if((desc->mask & PROPF_WRITABLE) && (desc->flags & PROPF_WRITABLE))
3282 if(desc->explicit_value) {
3283 if(prop->type == PROP_JSVAL) {
3284 BOOL eq;
3285 hres = jsval_strict_equal(desc->value, prop->u.val, &eq);
3286 if(FAILED(hres))
3287 return hres;
3288 if(!eq)
3290 }else {
3291 FIXME("redefinition of property type %d\n", prop->type);
3292 }
3293 }
3294 }
3295 if(desc->explicit_value) {
3296 if(prop->type == PROP_JSVAL)
3298 else {
3299 if(prop->type == PROP_EXTERN && obj->builtin_info->prop_delete) {
3300 hres = obj->builtin_info->prop_delete(obj, prop->u.id);
3301 if(FAILED(hres))
3302 return hres;
3303 }
3304 prop->type = PROP_JSVAL;
3305 }
3306 hres = jsval_copy(desc->value, &prop->u.val);
3307 if(FAILED(hres)) {
3309 return hres;
3310 }
3311 }
3312 }
3313 }else if(desc->explicit_getter || desc->explicit_setter) {
3314 if(prop->type != PROP_ACCESSOR) {
3315 if(!(prop->flags & PROPF_CONFIGURABLE))
3317 if(prop->type == PROP_JSVAL)
3320 prop->u.accessor.getter = prop->u.accessor.setter = NULL;
3321 }else if(!(prop->flags & PROPF_CONFIGURABLE)) {
3322 if((desc->explicit_getter && desc->getter != prop->u.accessor.getter)
3323 || (desc->explicit_setter && desc->setter != prop->u.accessor.setter))
3325 }
3326
3327 if(desc->explicit_getter) {
3328 if(prop->u.accessor.getter) {
3329 jsdisp_release(prop->u.accessor.getter);
3330 prop->u.accessor.getter = NULL;
3331 }
3332 if(desc->getter)
3333 prop->u.accessor.getter = jsdisp_addref(desc->getter);
3334 }
3335 if(desc->explicit_setter) {
3336 if(prop->u.accessor.setter) {
3337 jsdisp_release(prop->u.accessor.setter);
3338 prop->u.accessor.setter = NULL;
3339 }
3340 if(desc->setter)
3341 prop->u.accessor.setter = jsdisp_addref(desc->setter);
3342 }
3343 }
3344
3345 prop->flags = (prop->flags & ~desc->mask) | (desc->flags & desc->mask);
3346 return S_OK;
3347}
3348
3350{
3351 property_desc_t prop_desc = { flags, flags, TRUE };
3352 prop_desc.value = value;
3353 return jsdisp_define_property(obj, name, &prop_desc);
3354}
3355
3357{
3358 jsdisp_t *iter;
3359 DWORD i;
3360
3361 if(obj->prototype == proto)
3362 return S_OK;
3363 if(!obj->extensible)
3365
3366 for(iter = proto; iter; iter = iter->prototype)
3367 if(iter == obj)
3369
3370 if(obj->prototype) {
3371 for(i = 0; i < obj->prop_cnt; i++)
3372 if(obj->props[i].type == PROP_PROTREF)
3373 obj->props[i].type = PROP_DELETED;
3374 jsdisp_release(obj->prototype);
3375 }
3376
3377 obj->prototype = proto;
3378 if(proto)
3380 return S_OK;
3381}
3382
3384{
3385 if(prop->type == PROP_EXTERN && obj->builtin_info->prop_config) {
3386 HRESULT hres = obj->builtin_info->prop_config(obj, prop->u.id, flags);
3387 if(hres != S_OK)
3388 return;
3389 }
3390 prop->flags = (prop->flags & ~PROPF_PUBLIC_MASK) | flags;
3391}
3392
3394{
3395 unsigned int i;
3396
3397 fill_props(obj);
3398 for(i = 0; i < obj->prop_cnt; i++) {
3399 unsigned int mask = PROPF_CONFIGURABLE;
3400 if(!seal && obj->props[i].type == PROP_JSVAL)
3402 set_prop_flags(obj, &obj->props[i], obj->props[i].flags & PROPF_PUBLIC_MASK & ~mask);
3403 }
3404
3405 obj->extensible = FALSE;
3406}
3407
3409{
3410 unsigned int i;
3411
3412 if(obj->extensible)
3413 return FALSE;
3414 fill_props(obj);
3415
3416 for(i = 0; i < obj->prop_cnt; i++) {
3417 if(obj->props[i].type == PROP_JSVAL || obj->props[i].type == PROP_EXTERN) {
3418 if(!sealed && (obj->props[i].flags & PROPF_WRITABLE))
3419 return FALSE;
3420 }else if(obj->props[i].type != PROP_ACCESSOR)
3421 continue;
3422 if(obj->props[i].flags & PROPF_CONFIGURABLE)
3423 return FALSE;
3424 }
3425
3426 return TRUE;
3427}
3428
3430{
3432
3433 if(!prop)
3434 return DISP_E_MEMBERNOTFOUND;
3435
3436 *r = jsstr_alloc(prop->name);
3437 return *r ? S_OK : E_OUTOFMEMORY;
3438}
3439
3440typedef struct {
3443} HostObject;
3444
3446{
3447 return CONTAINING_RECORD(jsdisp, HostObject, jsdisp);
3448}
3449
3451{
3453 return IWineJSDispatchHost_AddRef(This->host_iface);
3454}
3455
3457{
3459 return IWineJSDispatchHost_Release(This->host_iface);
3460}
3461
3462static HRESULT HostObject_lookup_prop(jsdisp_t *jsdisp, const WCHAR *name, unsigned flags, struct property_info *desc)
3463{
3465
3466 return IWineJSDispatchHost_LookupProperty(This->host_iface, name, flags, desc);
3467}
3468
3470{
3472 EXCEPINFO ei = { 0 };
3473 VARIANT v;
3474 HRESULT hres;
3475
3476 V_VT(&v) = VT_EMPTY;
3477 hres = IWineJSDispatchHost_GetProperty(This->host_iface, idx, jsdisp->ctx->lcid, &v, &ei,
3479 if(hres == DISP_E_EXCEPTION)
3480 handle_dispatch_exception(jsdisp->ctx, &ei);
3481 if(FAILED(hres))
3482 return hres;
3483
3484 hres = variant_to_jsval(jsdisp->ctx, &v, r);
3485 VariantClear(&v);
3486 return hres;
3487}
3488
3490{
3492 EXCEPINFO ei = { 0 };
3493 VARIANT var;
3494 HRESULT hres;
3495
3497 if(FAILED(hres))
3498 return hres;
3499
3500 hres = IWineJSDispatchHost_SetProperty(This->host_iface, idx, jsdisp->ctx->lcid, &var, &ei,
3502 if(hres == DISP_E_EXCEPTION)
3503 handle_dispatch_exception(jsdisp->ctx, &ei);
3504 VariantClear(&var);
3505 return hres;
3506}
3507
3508static HRESULT HostObject_next_prop(jsdisp_t *jsdisp, unsigned id, struct property_info *desc)
3509{
3511
3512 return IWineJSDispatchHost_NextProperty(This->host_iface, id, desc);
3513}
3514
3515static HRESULT HostObject_prop_delete(jsdisp_t *jsdisp, unsigned id)
3516{
3518
3519 return IWineJSDispatchHost_DeleteProperty(This->host_iface, id);
3520}
3521
3522static HRESULT HostObject_prop_config(jsdisp_t *jsdisp, unsigned id, unsigned flags)
3523{
3525
3526 return IWineJSDispatchHost_ConfigureProperty(This->host_iface, id, flags);
3527}
3528
3530{
3532 BSTR str;
3533 HRESULT hres;
3534
3535 hres = IWineJSDispatchHost_ToString(This->host_iface, &str);
3536 if(FAILED(hres))
3537 return hres;
3538
3539 *ret = jsstr_alloc(str);
3541 return *ret ? S_OK : E_OUTOFMEMORY;
3542}
3543
3546 .addref = HostObject_addref,
3547 .release = HostObject_release,
3548 .lookup_prop = HostObject_lookup_prop,
3549 .prop_get = HostObject_prop_get,
3550 .prop_put = HostObject_prop_put,
3551 .next_prop = HostObject_next_prop,
3552 .prop_delete = HostObject_prop_delete,
3553 .prop_config = HostObject_prop_config,
3554 .to_string = HostObject_to_string,
3555};
3556
3559{
3561 jsdisp_t *prototype;
3562 HRESULT hres;
3563
3564 if(!(host_obj = calloc(1, sizeof(*host_obj))))
3565 return E_OUTOFMEMORY;
3566
3567 if(prototype_iface)
3568 prototype = impl_from_IWineJSDispatch(prototype_iface);
3569 else
3570 prototype = ctx->object_prototype;
3571 hres = init_dispex(&host_obj->jsdisp, ctx, &HostObject_info, prototype);
3572 if(FAILED(hres)) {
3573 free(host_obj);
3574 return hres;
3575 }
3576
3577 host_obj->host_iface = host_iface;
3579 host_obj->jsdisp.is_constructor = TRUE;
3580 *ret = &host_obj->jsdisp.IWineJSDispatch_iface;
3581 return S_OK;
3582}
3583
3585{
3588 jsdisp_t *jsdisp;
3589
3590 if(!(jsdisp = to_jsdisp(disp)))
3591 return NULL;
3592 if(jsdisp->builtin_info != &HostObject_info)
3593 return NULL;
3594
3596 IWineJSDispatchHost_GetOuterDispatch(host_obj->host_iface, &ret);
3597 return ret;
3598}
@ SCRIPTSTATE_UNINITIALIZED
Definition: activscp.idl:57
@ SCRIPTSTATE_CLOSED
Definition: activscp.idl:61
struct outqueuenode * head
Definition: adnsresfilter.c:66
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define is_digit(c)
Definition: astoll.c:39
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
#define ARRAY_SIZE(A)
Definition: main.h:20
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
const GUID IID_IUnknown
Definition: list.h:37
struct list * next
Definition: list.h:38
const WCHAR * link
Definition: db.cpp:998
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT op
Definition: effect.c:236
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
unsigned int idx
Definition: utils.c:41
OLECHAR * BSTR
Definition: compat.h:2293
@ VT_VARIANT
Definition: compat.h:2307
@ VT_EMPTY
Definition: compat.h:2295
@ VT_DISPATCH
Definition: compat.h:2304
#define wcsicmp
Definition: compat.h:15
static const WCHAR version[]
Definition: asmname.c:66
void handle_dispatch_exception(script_ctx_t *ctx, EXCEPINFO *ei)
Definition: error.c:409
HRESULT throw_error(script_ctx_t *ctx, HRESULT error, const WCHAR *str)
Definition: error.c:398
function_code_t * Function_get_code(jsdisp_t *jsthis)
Definition: function.c:655
HRESULT Function_invoke(jsdisp_t *func_this, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: function.c:327
HRESULT create_host_function(script_ctx_t *ctx, const struct property_info *desc, DWORD flags, jsdisp_t **ret)
Definition: function.c:1072
HRESULT create_builtin_function(script_ctx_t *ctx, builtin_invoke_t value_proc, const WCHAR *name, const builtin_info_t *builtin_info, DWORD flags, jsdisp_t *prototype, jsdisp_t **ret)
Definition: function.c:773
void script_release(script_ctx_t *ctx)
Definition: jscript.c:75
#define JSCRIPT_MAJOR_VERSION
Definition: resource.h:21
#define JSCRIPT_MINOR_VERSION
Definition: resource.h:22
LCID lcid
Definition: locale.c:5660
ULONG WINAPI DECLSPEC_HOTPATCH GetTickCount(void)
Definition: sync.c:182
MonoAssembly int argc
Definition: metahost.c:107
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
static wchar_t * wcsdup(const wchar_t *str)
Definition: string.h:94
#define swprintf
Definition: precomp.h:40
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
r parent
Definition: btrfs.c:3010
IDispatch * lookup_global_host(script_ctx_t *ctx)
Definition: engine.c:845
HRESULT jsval_strict_equal(jsval_t lval, jsval_t rval, BOOL *ret)
Definition: engine.c:684
HRESULT leave_script(script_ctx_t *, HRESULT)
Definition: jscript.c:348
void enter_script(script_ctx_t *, jsexcept_t *)
Definition: jscript.c:340
static bytecode_t * bytecode_addref(bytecode_t *code)
Definition: engine.h:221
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxCollectionEntry * cur
const GLdouble * v
Definition: gl.h:2040
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLenum func
Definition: glext.h:6028
GLuint index
Definition: glext.h:6031
GLenum GLint GLuint mask
Definition: glext.h:6028
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum const GLfloat * params
Definition: glext.h:5645
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint GLfloat * val
Definition: glext.h:7180
GLuint GLuint num
Definition: glext.h:9618
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLuint id
Definition: glext.h:5910
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
IHost host_obj
Definition: host.c:474
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
static DISPID propput_dispid
Definition: interp.c:27
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
void release_bytecode(bytecode_t *code)
Definition: compile.c:2459
HRESULT jsdisp_call(jsdisp_t *disp, DISPID id, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: dispex.c:2604
static HRESULT find_prop_name(jsdisp_t *This, unsigned hash, const WCHAR *name, BOOL case_insens, dispex_prop_t *prop, dispex_prop_t **ret)
Definition: dispex.c:353
HRESULT jsdisp_get_own_property(jsdisp_t *obj, const WCHAR *name, BOOL flags_only, property_desc_t *desc)
Definition: dispex.c:3171
HRESULT jsdisp_define_data_property(jsdisp_t *obj, const WCHAR *name, unsigned flags, jsval_t value)
Definition: dispex.c:3349
#define FDEX_VERSION_MASK
Definition: dispex.c:30
static dispex_prop_t * alloc_protref(jsdisp_t *This, const WCHAR *name, DWORD ref)
Definition: dispex.c:235
static dispex_prop_t * alloc_prop(jsdisp_t *This, const WCHAR *name, prop_type_t type, DWORD flags)
Definition: dispex.c:213
HRESULT jsdisp_propput_name(jsdisp_t *obj, const WCHAR *name, jsval_t val)
Definition: dispex.c:2859
static HRESULT HostObject_prop_get(jsdisp_t *jsdisp, unsigned idx, jsval_t *r)
Definition: dispex.c:3469
HRESULT disp_propget(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t *val)
Definition: dispex.c:2994
static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IWineJSDispatch *iface, DISPID id)
Definition: dispex.c:2311
static HRESULT WINAPI ScriptTypeInfo_GetContainingTypeLib(ITypeInfo *iface, ITypeLib **ppTLib, UINT *pIndex)
Definition: dispex.c:1693
static struct typeinfo_func * get_func_from_memid(const ScriptTypeInfo *typeinfo, MEMBERID memid)
Definition: dispex.c:1179
static void WINAPI ScriptTypeInfo_ReleaseVarDesc(ITypeInfo *iface, VARDESC *pVarDesc)
Definition: dispex.c:1720
HRESULT init_host_object(script_ctx_t *ctx, IWineJSDispatchHost *host_iface, IWineJSDispatch *prototype_iface, UINT32 flags, IWineJSDispatch **ret)
Definition: dispex.c:3557
static HRESULT find_prop_name_prot(jsdisp_t *This, unsigned hash, const WCHAR *name, BOOL case_insens, dispex_prop_t *own_prop, dispex_prop_t **ret)
Definition: dispex.c:400
HRESULT jsdisp_propput(jsdisp_t *obj, const WCHAR *name, DWORD flags, BOOL throw, jsval_t val)
Definition: dispex.c:2842
static const ITypeCompVtbl ScriptTypeCompVtbl
Definition: dispex.c:1853
static unsigned string_hash(const WCHAR *name)
Definition: dispex.c:170
static HRESULT WINAPI ScriptTypeInfo_GetImplTypeFlags(ITypeInfo *iface, UINT index, INT *pImplTypeFlags)
Definition: dispex.c:1441
static HRESULT HostObject_to_string(jsdisp_t *jsdisp, jsstr_t **ret)
Definition: dispex.c:3529
static IDispatch * get_this(DISPPARAMS *dp)
Definition: dispex.c:519
HRESULT jsdisp_get_id(jsdisp_t *jsdisp, const WCHAR *name, DWORD flags, DISPID *id)
Definition: dispex.c:2550
static HRESULT WINAPI DispatchEx_QueryInterface(IWineJSDispatch *iface, REFIID riid, void **ppv)
Definition: dispex.c:1929
static HRESULT WINAPI ScriptTypeInfo_GetDocumentation(ITypeInfo *iface, MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString, DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
Definition: dispex.c:1540
static HRESULT WINAPI ScriptTypeInfo_QueryInterface(ITypeInfo *iface, REFIID riid, void **ppv)
Definition: dispex.c:1227
static HRESULT WINAPI WineJSDispatch_GetPropertyFlags(IWineJSDispatch *iface, DISPID id, UINT32 *ret)
Definition: dispex.c:2393
HRESULT init_dispex_from_constr(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *constr)
Definition: dispex.c:2512
static void fix_protref_prop(jsdisp_t *jsdisp, dispex_prop_t *prop)
Definition: dispex.c:63
static const builtin_info_t HostObject_info
Definition: dispex.c:3544
static HRESULT WINAPI WineJSDispatch_GetScriptGlobal(IWineJSDispatch *iface, IWineJSDispatchHost **ret)
Definition: dispex.c:2405
static HRESULT HostObject_next_prop(jsdisp_t *jsdisp, unsigned id, struct property_info *desc)
Definition: dispex.c:3508
static dispex_prop_t * lookup_dispex_prop(jsdisp_t *obj, unsigned hash, const WCHAR *name, BOOL case_insens)
Definition: dispex.c:247
HRESULT disp_delete(IDispatch *disp, DISPID id, BOOL *ret)
Definition: dispex.c:3038
jsdisp_t * iface_to_jsdisp(IDispatch *iface)
Definition: dispex.c:2543
static HRESULT ensure_prop_name(jsdisp_t *This, const WCHAR *name, DWORD create_flags, BOOL case_insens, dispex_prop_t **ret)
Definition: dispex.c:449
HRESULT gc_process_linked_val(struct gc_ctx *gc_ctx, enum gc_traverse_op op, jsdisp_t *obj, jsval_t *link)
Definition: dispex.c:1139
HRESULT jsdisp_get_prop_name(jsdisp_t *obj, DISPID id, jsstr_t **r)
Definition: dispex.c:3429
static HRESULT WINAPI ScriptTypeInfo_GetVarDesc(ITypeInfo *iface, UINT index, VARDESC **ppVarDesc)
Definition: dispex.c:1353
static HRESULT WINAPI ScriptTypeComp_QueryInterface(ITypeComp *iface, REFIID riid, void **ppv)
Definition: dispex.c:1754
static BOOL is_function_prop(dispex_prop_t *prop)
Definition: dispex.c:98
HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, unsigned argc, jsval_t *argv, jsval_t *ret)
Definition: dispex.c:2666
static ScriptTypeInfo * ScriptTypeInfo_from_ITypeComp(ITypeComp *iface)
Definition: dispex.c:1222
HRESULT disp_call_name(script_ctx_t *ctx, IDispatch *disp, const WCHAR *name, WORD flags, unsigned argc, jsval_t *argv, jsval_t *ret)
Definition: dispex.c:2740
HRESULT disp_delete_name(script_ctx_t *ctx, IDispatch *disp, jsstr_t *name, BOOL *ret)
Definition: dispex.c:3112
static ULONG WINAPI ScriptTypeInfo_Release(ITypeInfo *iface)
Definition: dispex.c:1257
static HRESULT WINAPI DispatchEx_GetTypeInfo(IWineJSDispatch *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
Definition: dispex.c:1980
static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IWineJSDispatch *iface, UINT *pctinfo)
Definition: dispex.c:1970
static HRESULT WINAPI ScriptTypeInfo_Invoke(ITypeInfo *iface, PVOID pvInstance, MEMBERID memid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: dispex.c:1507
ULONG jsdisp_release(jsdisp_t *obj)
Definition: dispex.c:1911
static void unlink_jsdisp(jsdisp_t *jsdisp)
Definition: dispex.c:818
static void set_prop_flags(jsdisp_t *obj, dispex_prop_t *prop, UINT32 flags)
Definition: dispex.c:3383
HRESULT gc_process_linked_obj(struct gc_ctx *gc_ctx, enum gc_traverse_op op, jsdisp_t *obj, jsdisp_t *link, void **unlink_ref)
Definition: dispex.c:1124
static HRESULT gc_stack_push(struct gc_ctx *gc_ctx, jsdisp_t *obj)
Definition: dispex.c:895
static HRESULT WINAPI ScriptTypeInfo_GetFuncDesc(ITypeInfo *iface, UINT index, FUNCDESC **ppFuncDesc)
Definition: dispex.c:1321
static HRESULT WINAPI DispatchEx_GetMemberName(IWineJSDispatch *iface, DISPID id, BSTR *pbstrName)
Definition: dispex.c:2348
static HRESULT fill_props(jsdisp_t *obj)
Definition: dispex.c:747
static HRESULT find_external_prop(jsdisp_t *This, const WCHAR *name, BOOL case_insens, dispex_prop_t *prop, dispex_prop_t **ret)
Definition: dispex.c:323
static HRESULT WINAPI ScriptTypeInfo_GetNames(ITypeInfo *iface, MEMBERID memid, BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames)
Definition: dispex.c:1374
HRESULT jsdisp_index_lookup(jsdisp_t *obj, const WCHAR *name, unsigned length, struct property_info *desc)
Definition: dispex.c:481
static DISPID prop_to_id(jsdisp_t *This, dispex_prop_t *prop)
Definition: dispex.c:81
HRESULT jsdisp_delete_idx(jsdisp_t *obj, DWORD idx)
Definition: dispex.c:3019
jsdisp_t * as_jsdisp(IDispatch *disp)
Definition: dispex.c:2441
static HRESULT WINAPI ScriptTypeInfo_GetTypeComp(ITypeInfo *iface, ITypeComp **ppTComp)
Definition: dispex.c:1308
HRESULT jsdisp_call_value(jsdisp_t *jsfunc, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: dispex.c:2581
static HRESULT WINAPI ScriptTypeInfo_AddressOfMember(ITypeInfo *iface, MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
Definition: dispex.c:1638
HRESULT jsdisp_get_idx(jsdisp_t *obj, DWORD idx, jsval_t *r)
Definition: dispex.c:2963
static HRESULT prop_put(jsdisp_t *This, dispex_prop_t *prop, jsval_t val)
Definition: dispex.c:613
static unsigned get_props_idx(jsdisp_t *This, unsigned hash)
Definition: dispex.c:178
static const GUID GUID_JScriptTypeInfo
Definition: dispex.c:28
HRESULT disp_propput_name(script_ctx_t *ctx, IDispatch *disp, const WCHAR *name, jsval_t val)
Definition: dispex.c:2910
static const builtin_info_t dispex_info
Definition: dispex.c:2491
static HRESULT WINAPI DispatchEx_GetDispID(IWineJSDispatch *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
Definition: dispex.c:2119
static IWineJSDispatchVtbl DispatchExVtbl
Definition: dispex.c:2420
static jsdisp_t * impl_from_IWineJSDispatch(IWineJSDispatch *iface)
Definition: dispex.c:1924
static HRESULT WINAPI ScriptTypeComp_BindType(ITypeComp *iface, LPOLESTR szName, ULONG lHashVal, ITypeInfo **ppTInfo, ITypeComp **ppTComp)
Definition: dispex.c:1828
static HRESULT prop_get(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t *prop, jsval_t *r)
Definition: dispex.c:570
static HRESULT WINAPI DispatchEx_DeleteMemberByName(IWineJSDispatch *iface, BSTR bstrName, DWORD grfdex)
Definition: dispex.c:2288
static HRESULT HostObject_prop_put(jsdisp_t *jsdisp, unsigned idx, jsval_t v)
Definition: dispex.c:3489
HRESULT create_dispex(script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype, jsdisp_t **dispex)
Definition: dispex.c:2493
static ULONG HostObject_release(jsdisp_t *jsdisp)
Definition: dispex.c:3456
static ULONG WINAPI ScriptTypeComp_Release(ITypeComp *iface)
Definition: dispex.c:1766
static HRESULT WINAPI DispatchEx_InvokeEx(IWineJSDispatch *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
Definition: dispex.c:2133
static void WINAPI WineJSDispatch_Free(IWineJSDispatch *iface)
Definition: dispex.c:2387
static HRESULT WINAPI ScriptTypeInfo_GetRefTypeInfo(ITypeInfo *iface, HREFTYPE hRefType, ITypeInfo **ppTInfo)
Definition: dispex.c:1616
static ULONG WINAPI ScriptTypeInfo_AddRef(ITypeInfo *iface)
Definition: dispex.c:1247
static ScriptTypeInfo * ScriptTypeInfo_from_ITypeInfo(ITypeInfo *iface)
Definition: dispex.c:1217
static HRESULT HostObject_prop_config(jsdisp_t *jsdisp, unsigned id, unsigned flags)
Definition: dispex.c:3522
static void WINAPI ScriptTypeInfo_ReleaseTypeAttr(ITypeInfo *iface, TYPEATTR *pTypeAttr)
Definition: dispex.c:1702
void jsdisp_freeze(jsdisp_t *obj, BOOL seal)
Definition: dispex.c:3393
IWineJSDispatchHost * get_host_dispatch(IDispatch *disp)
Definition: dispex.c:3584
HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype)
Definition: dispex.c:2454
static const ITypeInfoVtbl ScriptTypeInfoVtbl
Definition: dispex.c:1729
static HRESULT WINAPI DispatchEx_GetNextDispID(IWineJSDispatch *iface, DWORD grfdex, DISPID id, DISPID *pid)
Definition: dispex.c:2366
#define GOLDEN_RATIO
Definition: dispex.c:31
static const builtin_prop_t * find_builtin_prop(jsdisp_t *This, const WCHAR *name, BOOL case_insens)
Definition: dispex.c:130
static HRESULT WINAPI ScriptTypeInfo_GetTypeAttr(ITypeInfo *iface, TYPEATTR **ppTypeAttr)
Definition: dispex.c:1277
static HRESULT WINAPI ScriptTypeInfo_GetDllEntry(ITypeInfo *iface, MEMBERID memid, INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName, WORD *pwOrdinal)
Definition: dispex.c:1593
HRESULT jsdisp_get_idx_id(jsdisp_t *jsdisp, DWORD idx, DISPID *id)
Definition: dispex.c:2573
prop_type_t
Definition: dispex.c:33
@ PROP_DELETED
Definition: dispex.c:38
@ PROP_PROTREF
Definition: dispex.c:36
@ PROP_ACCESSOR
Definition: dispex.c:37
@ PROP_JSVAL
Definition: dispex.c:34
@ PROP_BUILTIN
Definition: dispex.c:35
@ PROP_EXTERN
Definition: dispex.c:39
HRESULT jsdisp_propget_name(jsdisp_t *obj, const WCHAR *name, jsval_t *val)
Definition: dispex.c:2946
static jsdisp_t * gc_stack_pop(struct gc_ctx *gc_ctx)
Definition: dispex.c:915
static ULONG WINAPI DispatchEx_AddRef(IWineJSDispatch *iface)
Definition: dispex.c:1955
static HRESULT WINAPI ScriptTypeComp_Bind(ITypeComp *iface, LPOLESTR szName, ULONG lHashVal, WORD wFlags, ITypeInfo **ppTInfo, DESCKIND *pDescKind, BINDPTR *pBindPtr)
Definition: dispex.c:1772
static dispex_prop_t * get_prop(jsdisp_t *This, DISPID id)
Definition: dispex.c:87
HRESULT jsdisp_propput_idx(jsdisp_t *obj, DWORD idx, jsval_t val)
Definition: dispex.c:2864
jsdisp_t * jsdisp_addref(jsdisp_t *obj)
Definition: dispex.c:1902
static HRESULT WINAPI DispatchEx_Invoke(IWineJSDispatch *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: dispex.c:2106
static HRESULT resize_props(jsdisp_t *This)
Definition: dispex.c:183
HRESULT disp_call_value_with_caller(script_ctx_t *ctx, IDispatch *disp, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r, IServiceProvider *caller)
Definition: dispex.c:2767
HRESULT jsdisp_call_name(jsdisp_t *disp, const WCHAR *name, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: dispex.c:2615
HRESULT builtin_set_const(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t value)
Definition: dispex.c:741
static HRESULT WINAPI ScriptTypeInfo_CreateInstance(ITypeInfo *iface, IUnknown *pUnkOuter, REFIID riid, PVOID *ppvObj)
Definition: dispex.c:1659
static HRESULT WINAPI ScriptTypeInfo_GetIDsOfNames(ITypeInfo *iface, LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId)
Definition: dispex.c:1454
static HRESULT fill_protrefs(jsdisp_t *This)
Definition: dispex.c:782
static HRESULT WINAPI ScriptTypeInfo_GetRefTypeOfImplType(ITypeInfo *iface, UINT index, HREFTYPE *pRefType)
Definition: dispex.c:1427
static HRESULT disp_invoke(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, DISPPARAMS *params, VARIANT *r, IServiceProvider *caller)
Definition: dispex.c:2630
static ULONG WINAPI ScriptTypeComp_AddRef(ITypeComp *iface)
Definition: dispex.c:1760
static ULONG WINAPI DispatchEx_Release(IWineJSDispatch *iface)
Definition: dispex.c:1964
static void jsdisp_free(jsdisp_t *obj)
Definition: dispex.c:1861
static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IWineJSDispatch *iface, IUnknown **ppunk)
Definition: dispex.c:2380
jsdisp_t * to_jsdisp(IDispatch *disp)
Definition: dispex.c:2447
static HRESULT delete_prop(jsdisp_t *obj, dispex_prop_t *prop, BOOL *ret)
Definition: dispex.c:2249
HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t val)
Definition: dispex.c:2872
static ULONG HostObject_addref(jsdisp_t *jsdisp)
Definition: dispex.c:3450
HRESULT jsdisp_define_property(jsdisp_t *obj, const WCHAR *name, property_desc_t *desc)
Definition: dispex.c:3216
static HRESULT HostObject_prop_delete(jsdisp_t *jsdisp, unsigned id)
Definition: dispex.c:3515
static HRESULT WINAPI ScriptTypeInfo_GetMops(ITypeInfo *iface, MEMBERID memid, BSTR *pBstrMops)
Definition: dispex.c:1671
static HRESULT WINAPI DispatchEx_GetMemberProperties(IWineJSDispatch *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
Definition: dispex.c:2328
HRESULT jsdisp_change_prototype(jsdisp_t *obj, jsdisp_t *proto)
Definition: dispex.c:3356
static HRESULT convert_params(script_ctx_t *ctx, const DISPPARAMS *dp, jsval_t *buf, unsigned *argc, jsval_t **ret)
Definition: dispex.c:537
static void WINAPI ScriptTypeInfo_ReleaseFuncDesc(ITypeInfo *iface, FUNCDESC *pFuncDesc)
Definition: dispex.c:1711
HRESULT jsdisp_propget(jsdisp_t *jsdisp, DISPID id, jsval_t *val)
Definition: dispex.c:2983
static HRESULT invoke_prop_func(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t *prop, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r, IServiceProvider *caller)
Definition: dispex.c:686
HRESULT jsdisp_next_prop(jsdisp_t *obj, DISPID id, enum jsdisp_enum_type enum_type, DISPID *ret)
Definition: dispex.c:3073
static dispex_prop_t * get_var_from_memid(const ScriptTypeInfo *typeinfo, MEMBERID memid)
Definition: dispex.c:1198
BOOL jsdisp_is_frozen(jsdisp_t *obj, BOOL sealed)
Definition: dispex.c:3408
HRESULT jsdisp_next_index(jsdisp_t *obj, unsigned length, unsigned id, struct property_info *desc)
Definition: dispex.c:504
HRESULT gc_run(script_ctx_t *ctx)
Definition: dispex.c:928
static HostObject * HostObject_from_jsdisp(jsdisp_t *jsdisp)
Definition: dispex.c:3445
static HRESULT WINAPI DispatchEx_GetIDsOfNames(IWineJSDispatch *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
Definition: dispex.c:2078
static HRESULT HostObject_lookup_prop(jsdisp_t *jsdisp, const WCHAR *name, unsigned flags, struct property_info *desc)
Definition: dispex.c:3462
static HRESULT update_external_prop(jsdisp_t *obj, const WCHAR *name, dispex_prop_t *prop, const struct property_info *desc, dispex_prop_t **ret)
Definition: dispex.c:271
@ NO_HINT
Definition: jscript.h:309
#define JS_E_CANNOT_CREATE_FOR_NONEXTENSIBLE
Definition: jscript.h:574
HRESULT to_primitive(script_ctx_t *, jsval_t, jsval_t *, hint_t)
Definition: jsutils.c:423
#define PROPF_VERSION_MASK
Definition: jscript.h:87
void remove_weakmap_entry(struct weakmap_entry *)
Definition: set.c:642
#define JS_E_CYCLIC_PROTO_VALUE
Definition: jscript.h:573
static void script_addref(script_ctx_t *ctx)
Definition: jscript.h:457
#define SCRIPTLANGUAGEVERSION_ES5
Definition: jscript.h:53
#define JS_E_FUNCTION_EXPECTED
Definition: jscript.h:552
#define PROPF_ALL
Definition: jscript.h:84
jsdisp_enum_type
Definition: jscript.h:239
@ JSDISP_ENUM_ALL
Definition: jscript.h:240
@ JSDISP_ENUM_OWN
Definition: jscript.h:241
#define JS_E_NONWRITABLE_MODIFIED
Definition: jscript.h:577
static IDispatch * to_disp(jsdisp_t *jsdisp)
Definition: jscript.h:222
const char * debugstr_jsval(const jsval_t)
Definition: jsutils.c:35
static DWORD make_grfdex(script_ctx_t *ctx, DWORD flags)
Definition: jscript.h:513
static IDispatchEx * to_dispex(jsdisp_t *jsdisp)
Definition: jscript.h:227
@ JSCLASS_FUNCTION
Definition: jscript.h:109
@ JSCLASS_HOST
Definition: jscript.h:124
@ JSCLASS_OBJECT
Definition: jscript.h:113
@ JSCLASS_NONE
Definition: jscript.h:103
#define JS_E_NONCONFIGURABLE_REDEFINED
Definition: jscript.h:576
#define JS_E_INVALID_PROPERTY
Definition: jscript.h:532
gc_traverse_op
Definition: jscript.h:161
@ GC_TRAVERSE
Definition: jscript.h:164
@ GC_TRAVERSE_SPECULATIVELY
Definition: jscript.h:163
@ GC_TRAVERSE_UNLINK
Definition: jscript.h:162
#define JS_E_TO_PRIMITIVE
Definition: jscript.h:526
#define JS_E_INVALID_ACTION
Definition: jscript.h:533
#define PROPF_VERSION_SHIFT
Definition: jscript.h:88
#define PROPF_HTML
Definition: jscript.h:89
HRESULT get_dispatch_typeinfo(ITypeInfo **)
Definition: jscript_main.c:78
static BOOL is_class(jsdisp_t *jsdisp, jsclass_t class)
Definition: jscript.h:503
#define DISPATCH_JSCRIPT_INTERNAL_MASK
Definition: jscript.h:99
#define JS_E_OBJECT_NONEXTENSIBLE
Definition: jscript.h:575
const unsigned int PROPF_WRITABLE
Definition: jsdisp.idl:37
const unsigned int PROPF_ENUMERABLE
Definition: jsdisp.idl:36
const unsigned int PROPF_CONFIGURABLE
Definition: jsdisp.idl:38
const unsigned int PROPF_PUBLIC_MASK
Definition: jsdisp.idl:40
const unsigned int PROPF_METHOD
Definition: jsdisp.idl:33
const unsigned int HOSTOBJ_CONSTRUCTOR
Definition: jsdisp.idl:42
static const WCHAR * jsstr_flatten(jsstr_t *str)
Definition: jsstr.h:136
static unsigned jsstr_length(jsstr_t *str)
Definition: jsstr.h:55
static unsigned jsstr_flush(jsstr_t *str, WCHAR *buf)
Definition: jsstr.h:145
static jsstr_t * jsstr_alloc(const WCHAR *str)
Definition: jsstr.h:100
HRESULT jsval_copy(jsval_t v, jsval_t *r)
Definition: jsutils.c:225
HRESULT variant_to_jsval(script_ctx_t *ctx, VARIANT *var, jsval_t *r)
Definition: jsutils.c:251
void jsval_release(jsval_t val)
Definition: jsutils.c:186
HRESULT jsval_to_variant(jsval_t val, VARIANT *retv)
Definition: jsutils.c:367
static jsval_t jsval_undefined(void)
Definition: jsval.h:146
static jsval_t jsval_obj(jsdisp_t *obj)
Definition: jsval.h:125
static jsval_t jsval_disp(IDispatch *obj)
Definition: jsval.h:117
static IDispatch * get_object(jsval_t v)
Definition: jsval.h:228
static BOOL is_object_instance(jsval_t v)
Definition: jsval.h:175
#define b
Definition: ke_i.h:79
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
static PVOID ptr
Definition: dispmode.c:27
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1204
const char * var
Definition: shader.c:5666
HRESULT hres
Definition: protocol.c:465
#define eq(received, expected, label, type)
Definition: locale.c:179
static VARIANTARG static DISPID
Definition: ordinal.c:49
DWORD get_flags
Definition: misc.c:1720
DWORD create_flags
Definition: sec_mgr.c:1589
#define min(a, b)
Definition: monoChain.cc:55
#define argv
Definition: mplay32.c:18
_Out_ PULONG _Out_ PULONG pIndex
Definition: ndis.h:4565
unsigned int UINT
Definition: ndis.h:50
#define LOCALE_USER_DEFAULT
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:339
#define DISPATCH_PROPERTYPUT
Definition: oleauto.h:1008
#define DISPATCH_METHOD
Definition: oleauto.h:1006
#define MEMBERID_NIL
Definition: oleauto.h:1003
#define V_VT(A)
Definition: oleauto.h:211
#define V_DISPATCH(A)
Definition: oleauto.h:239
#define DISPATCH_PROPERTYGET
Definition: oleauto.h:1007
#define DISPATCH_PROPERTYPUTREF
Definition: oleauto.h:1009
#define DISPID_THIS
Definition: olectl.h:395
const GUID IID_IDispatch
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
static const WCHAR szName[]
Definition: powrprof.c:45
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define IID_NULL
Definition: guiddef.h:98
static unsigned __int64 next
Definition: rand_nt.c:6
#define err(...)
#define calloc
Definition: rosglue.h:14
const WCHAR * str
DWORD LCID
Definition: nls.h:13
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
__WINE_SERVER_LIST_INLINE struct list * list_next(const struct list *list, const struct list *elem)
Definition: list.h:115
#define RB_ENTRY_VALUE(element, type, field)
Definition: rbtree.h:26
static struct rb_entry * rb_get(const struct rb_tree *tree, const void *key)
Definition: rbtree.h:192
#define memset(x, y, z)
Definition: compat.h:39
#define towlower(c)
Definition: wctype.h:97
#define args
Definition: format.c:66
#define TRACE(s)
Definition: solgame.cpp:4
@ CC_STDCALL
Definition: spec2def.c:94
jsdisp_t jsdisp
Definition: dispex.c:3441
IWineJSDispatchHost * host_iface
Definition: dispex.c:3442
IServiceProvider IServiceProvider_iface
Definition: jscript.h:352
ITypeComp ITypeComp_iface
Definition: dispex.c:1168
ITypeInfo ITypeInfo_iface
Definition: dispex.c:1167
struct typeinfo_func * funcs
Definition: dispex.c:1173
dispex_prop_t ** vars
Definition: dispex.c:1174
UINT num_funcs
Definition: dispex.c:1171
jsdisp_t * jsdisp
Definition: dispex.c:1176
UINT num_vars
Definition: dispex.c:1172
jsdisp_t * setter
Definition: dispex.c:55
WCHAR * name
Definition: dispex.c:43
prop_type_t type
Definition: dispex.c:45
unsigned hash
Definition: dispex.c:44
DWORD ref
Definition: dispex.c:51
int bucket_head
Definition: dispex.c:59
union _dispex_prop_t::@430 u
DWORD flags
Definition: dispex.c:46
jsdisp_t * getter
Definition: dispex.c:54
const builtin_prop_t * p
Definition: dispex.c:50
jsval_t val
Definition: dispex.c:49
unsigned id
Definition: dispex.c:52
struct _dispex_prop_t::@430::@431 accessor
int bucket_next
Definition: dispex.c:60
bytecode_t * bytecode
Definition: engine.h:185
Definition: jsstr.h:36
Definition: jsval.h:54
jsval_t value
Definition: jscript.h:366
SCRIPTSTATE state
Definition: jscript.h:386
JSCaller * jscaller
Definition: jscript.h:399
Definition: match.c:390
Definition: cookie.c:202
HRESULT(* prop_get)(jsdisp_t *, unsigned, jsval_t *)
Definition: jscript.h:193
HRESULT(* gc_traverse)(struct gc_ctx *, enum gc_traverse_op, jsdisp_t *)
Definition: jscript.h:198
jsclass_t class
Definition: jscript.h:183
builtin_invoke_t call
Definition: jscript.h:184
builtin_getter_t getter
Definition: jscript.h:178
const WCHAR * name
Definition: jscript.h:175
builtin_setter_t setter
Definition: jscript.h:179
DWORD flags
Definition: jscript.h:177
builtin_invoke_t invoke
Definition: jscript.h:176
Definition: dispex.c:889
unsigned idx
Definition: dispex.c:892
struct gc_stack_chunk * next
Definition: dispex.c:891
struct gc_stack_chunk * chunk
Definition: dispex.c:890
jsdisp_t * objects[1020]
Definition: dispex.c:885
struct gc_stack_chunk * prev
Definition: dispex.c:886
Definition: _hash_fun.h:40
const builtin_info_t * builtin_info
Definition: jscript.h:218
BOOLEAN is_constructor
Definition: jscript.h:209
DWORD buf_size
Definition: jscript.h:211
jsdisp_t * prototype
Definition: jscript.h:216
DWORD prop_cnt
Definition: jscript.h:212
LONG ref
Definition: jscript.h:204
struct list entry
Definition: jscript.h:219
BOOLEAN gc_marked
Definition: jscript.h:208
IWineJSDispatch IWineJSDispatch_iface
Definition: jscript.h:202
BOOLEAN has_weak_refs
Definition: jscript.h:206
BOOLEAN extensible
Definition: jscript.h:207
dispex_prop_t * props
Definition: jscript.h:213
script_ctx_t * ctx
Definition: jscript.h:214
Definition: list.h:15
Definition: name.c:39
WCHAR * name
Definition: name.c:42
Definition: send.c:48
struct list objects
Definition: jscript.h:142
DWORD gc_last_tick
Definition: jscript.h:140
BOOL gc_is_unlinking
Definition: jscript.h:139
struct rb_tree weak_refs
Definition: jscript.h:143
MEMBERID memid
Definition: vbdisp.c:568
function_code_t * code
Definition: dispex.c:1163
dispex_prop_t * prop
Definition: dispex.c:1162
Definition: jscript.h:378
Definition: jscript.h:446
#define max(a, b)
Definition: svc.c:63
#define LIST_ENTRY(type)
Definition: queue.h:175
int32_t INT
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t UINT32
Definition: typedefs.h:59
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:96
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
static const WCHAR props[]
Definition: wbemdisp.c:288
_In_ size_t cnt
Definition: wcstombs.cpp:43
@ TKIND_DISPATCH
Definition: widltypes.h:238
WINBASEAPI _In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon_undoc.h:337
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837
void * arg
Definition: msvc.h:10
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
#define TYPE_E_BADMODULEKIND
Definition: winerror.h:3647
#define TYPE_E_ELEMENTNOTFOUND
Definition: winerror.h:3642
#define E_NOINTERFACE
Definition: winerror.h:3479
#define TYPE_E_AMBIGUOUSNAME
Definition: winerror.h:3643
#define TYPE_E_TYPEMISMATCH
Definition: winerror.h:3651
#define DISP_E_MEMBERNOTFOUND
Definition: winerror.h:3615
#define E_UNEXPECTED
Definition: winerror.h:3528
#define DISP_E_EXCEPTION
Definition: winerror.h:3621
#define DISP_E_BADINDEX
Definition: winerror.h:3623
#define DISP_E_PARAMNOTOPTIONAL
Definition: winerror.h:3627
#define DISP_E_UNKNOWNNAME
Definition: winerror.h:3618