ReactOS  0.4.14-dev-608-gd495a4f
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 
23 #include "wine/debug.h"
24 
26 
27 #define FDEX_VERSION_MASK 0xf0000000
28 #define GOLDEN_RATIO 0x9E3779B9U
29 
30 typedef enum {
37 } prop_type_t;
38 
41  unsigned hash;
44 
45  union {
47  const builtin_prop_t *p;
49  unsigned idx;
50  struct {
53  } accessor;
54  } u;
55 
58 };
59 
61 {
62  return prop - This->props;
63 }
64 
66 {
67  if(id < 0 || id >= This->prop_cnt || This->props[id].type == PROP_DELETED)
68  return NULL;
69 
70  return This->props+id;
71 }
72 
74 {
75  if(prop->type == PROP_PROTREF) {
76  dispex_prop_t *parent = get_prop(This->prototype, prop->u.ref);
77  if(!parent) {
78  prop->type = PROP_DELETED;
79  return 0;
80  }
81 
82  return get_flags(This->prototype, parent);
83  }
84 
85  return prop->flags;
86 }
87 
89 {
90  int min = 0, max, i, r;
91 
92  max = This->builtin_info->props_cnt-1;
93  while(min <= max) {
94  i = (min+max)/2;
95 
96  r = wcscmp(name, This->builtin_info->props[i].name);
97  if(!r) {
98  /* Skip prop if it's available only in higher compatibility mode. */
99  unsigned version = (This->builtin_info->props[i].flags & PROPF_VERSION_MASK)
101  if(version && version > This->ctx->version)
102  return NULL;
103 
104  /* Skip prop if it's available only in HTML mode and we're not running in HTML mode. */
105  if((This->builtin_info->props[i].flags & PROPF_HTML) && !This->ctx->html_mode)
106  return NULL;
107 
108  return This->builtin_info->props + i;
109  }
110 
111  if(r < 0)
112  max = i-1;
113  else
114  min = i+1;
115  }
116 
117  return NULL;
118 }
119 
120 static inline unsigned string_hash(const WCHAR *name)
121 {
122  unsigned h = 0;
123  for(; *name; name++)
124  h = (h>>(sizeof(unsigned)*8-4)) ^ (h<<4) ^ towlower(*name);
125  return h;
126 }
127 
128 static inline unsigned get_props_idx(jsdisp_t *This, unsigned hash)
129 {
130  return (hash*GOLDEN_RATIO) & (This->buf_size-1);
131 }
132 
134 {
136  int i, bucket;
137 
138  if(This->buf_size != This->prop_cnt)
139  return S_FALSE;
140 
141  props = heap_realloc(This->props, sizeof(dispex_prop_t)*This->buf_size*2);
142  if(!props)
143  return E_OUTOFMEMORY;
144  This->buf_size *= 2;
145  This->props = props;
146 
147  for(i=0; i<This->buf_size; i++) {
148  This->props[i].bucket_head = 0;
149  This->props[i].bucket_next = 0;
150  }
151 
152  for(i=1; i<This->prop_cnt; i++) {
153  props = This->props+i;
154 
155  bucket = get_props_idx(This, props->hash);
156  props->bucket_next = This->props[bucket].bucket_head;
157  This->props[bucket].bucket_head = i;
158  }
159 
160  return S_OK;
161 }
162 
164 {
165  dispex_prop_t *prop;
166  unsigned bucket;
167 
168  if(FAILED(resize_props(This)))
169  return NULL;
170 
171  prop = &This->props[This->prop_cnt];
172  prop->name = heap_strdupW(name);
173  if(!prop->name)
174  return NULL;
175  prop->type = type;
176  prop->flags = flags;
177  prop->hash = string_hash(name);
178 
179  bucket = get_props_idx(This, prop->hash);
180  prop->bucket_next = This->props[bucket].bucket_head;
181  This->props[bucket].bucket_head = This->prop_cnt++;
182  return prop;
183 }
184 
186 {
188 
190  if(!ret)
191  return NULL;
192 
193  ret->u.ref = ref;
194  return ret;
195 }
196 
198 {
199  const builtin_prop_t *builtin;
200  unsigned bucket, pos, prev = 0;
201  dispex_prop_t *prop;
202 
203  bucket = get_props_idx(This, hash);
204  pos = This->props[bucket].bucket_head;
205  while(pos != 0) {
206  if(!wcscmp(name, This->props[pos].name)) {
207  if(prev != 0) {
208  This->props[prev].bucket_next = This->props[pos].bucket_next;
209  This->props[pos].bucket_next = This->props[bucket].bucket_head;
210  This->props[bucket].bucket_head = pos;
211  }
212 
213  *ret = &This->props[pos];
214  return S_OK;
215  }
216 
217  prev = pos;
218  pos = This->props[pos].bucket_next;
219  }
220 
221  builtin = find_builtin_prop(This, name);
222  if(builtin) {
223  unsigned flags = builtin->flags;
224  if(flags & PROPF_METHOD)
226  else if(builtin->setter)
230  if(!prop)
231  return E_OUTOFMEMORY;
232 
233  prop->u.p = builtin;
234  *ret = prop;
235  return S_OK;
236  }
237 
238  if(This->builtin_info->idx_length) {
239  const WCHAR *ptr;
240  unsigned idx = 0;
241 
242  for(ptr = name; iswdigit(*ptr) && idx < 0x10000; ptr++)
243  idx = idx*10 + (*ptr-'0');
244  if(!*ptr && idx < This->builtin_info->idx_length(This)) {
245  prop = alloc_prop(This, name, PROP_IDX, This->builtin_info->idx_put ? PROPF_WRITABLE : 0);
246  if(!prop)
247  return E_OUTOFMEMORY;
248 
249  prop->u.idx = idx;
250  *ret = prop;
251  return S_OK;
252  }
253  }
254 
255  *ret = NULL;
256  return S_OK;
257 }
258 
260 {
261  dispex_prop_t *prop, *del=NULL;
262  HRESULT hres;
263 
264  hres = find_prop_name(This, hash, name, &prop);
265  if(FAILED(hres))
266  return hres;
267  if(prop && prop->type==PROP_DELETED) {
268  del = prop;
269  } else if(prop) {
270  *ret = prop;
271  return S_OK;
272  }
273 
274  if(This->prototype) {
275  hres = find_prop_name_prot(This->prototype, hash, name, &prop);
276  if(FAILED(hres))
277  return hres;
278  if(prop) {
279  if(del) {
280  del->type = PROP_PROTREF;
281  del->u.ref = prop - This->prototype->props;
282  prop = del;
283  }else {
284  prop = alloc_protref(This, prop->name, prop - This->prototype->props);
285  if(!prop)
286  return E_OUTOFMEMORY;
287  }
288 
289  *ret = prop;
290  return S_OK;
291  }
292  }
293 
294  *ret = del;
295  return S_OK;
296 }
297 
299 {
300  dispex_prop_t *prop;
301  HRESULT hres;
302 
304  if(SUCCEEDED(hres) && (!prop || prop->type == PROP_DELETED)) {
305  TRACE("creating prop %s flags %x\n", debugstr_w(name), create_flags);
306 
307  if(prop) {
308  prop->type = PROP_JSVAL;
309  prop->flags = create_flags;
310  prop->u.val = jsval_undefined();
311  }else {
313  if(!prop)
314  return E_OUTOFMEMORY;
315  }
316 
317  prop->u.val = jsval_undefined();
318  }
319 
320  *ret = prop;
321  return hres;
322 }
323 
325 {
326  DWORD i;
327 
328  for(i=0; i < dp->cNamedArgs; i++) {
329  if(dp->rgdispidNamedArgs[i] == DISPID_THIS) {
330  if(V_VT(dp->rgvarg+i) == VT_DISPATCH)
331  return V_DISPATCH(dp->rgvarg+i);
332 
333  WARN("This is not VT_DISPATCH\n");
334  return NULL;
335  }
336  }
337 
338  TRACE("no this passed\n");
339  return NULL;
340 }
341 
342 static HRESULT convert_params(const DISPPARAMS *dp, jsval_t *buf, unsigned *argc, jsval_t **ret)
343 {
344  jsval_t *argv;
345  unsigned cnt;
346  unsigned i;
347  HRESULT hres;
348 
349  cnt = dp->cArgs - dp->cNamedArgs;
350 
351  if(cnt > 6) {
352  argv = heap_alloc(cnt * sizeof(*argv));
353  if(!argv)
354  return E_OUTOFMEMORY;
355  }else {
356  argv = buf;
357  }
358 
359  for(i = 0; i < cnt; i++) {
360  hres = variant_to_jsval(dp->rgvarg+dp->cArgs-i-1, argv+i);
361  if(FAILED(hres)) {
362  while(i--)
363  jsval_release(argv[i]);
364  if(argv != buf)
365  heap_free(argv);
366  return hres;
367  }
368  }
369 
370  *argc = cnt;
371  *ret = argv;
372  return S_OK;
373 }
374 
376  unsigned argc, jsval_t *argv, jsval_t *r, IServiceProvider *caller)
377 {
378  HRESULT hres;
379 
380  switch(prop->type) {
381  case PROP_BUILTIN: {
382  if(flags == DISPATCH_CONSTRUCT && (prop->flags & PROPF_METHOD)) {
383  WARN("%s is not a constructor\n", debugstr_w(prop->name));
384  return E_INVALIDARG;
385  }
386 
387  if(prop->name || This->builtin_info->class != JSCLASS_FUNCTION) {
388  vdisp_t vthis;
389 
390  if(This->builtin_info->class != JSCLASS_FUNCTION && prop->u.p->invoke != JSGlobal_eval)
392  if(jsthis)
393  set_disp(&vthis, jsthis);
394  else
395  set_jsdisp(&vthis, This);
396  hres = prop->u.p->invoke(This->ctx, &vthis, flags, argc, argv, r);
397  vdisp_release(&vthis);
398  }else {
399  /* Function object calls are special case */
400  hres = Function_invoke(This, jsthis, flags, argc, argv, r);
401  }
402  return hres;
403  }
404  case PROP_PROTREF:
405  return invoke_prop_func(This->prototype, jsthis, This->prototype->props+prop->u.ref,
406  flags, argc, argv, r, caller);
407  case PROP_JSVAL: {
408  if(!is_object_instance(prop->u.val)) {
409  FIXME("invoke %s\n", debugstr_jsval(prop->u.val));
410  return E_FAIL;
411  }
412 
413  TRACE("call %s %p\n", debugstr_w(prop->name), get_object(prop->u.val));
414 
415  return disp_call_value(This->ctx, get_object(prop->u.val), jsthis, flags, argc, argv, r);
416  }
417  case PROP_ACCESSOR:
418  FIXME("accessor\n");
419  return E_NOTIMPL;
420  case PROP_IDX:
421  FIXME("Invoking PROP_IDX not yet supported\n");
422  return E_NOTIMPL;
423  case PROP_DELETED:
424  assert(0);
425  }
426 
427  assert(0);
428  return E_FAIL;
429 }
430 
432 {
433  jsdisp_t *prop_obj = This;
434  HRESULT hres;
435 
436  while(prop->type == PROP_PROTREF) {
437  prop_obj = prop_obj->prototype;
438  prop = prop_obj->props + prop->u.ref;
439  }
440 
441  switch(prop->type) {
442  case PROP_BUILTIN:
443  if(prop->u.p->getter) {
444  hres = prop->u.p->getter(This->ctx, This, r);
445  }else {
446  jsdisp_t *obj;
447 
448  assert(prop->u.p->invoke != NULL);
449  hres = create_builtin_function(This->ctx, prop->u.p->invoke, prop->u.p->name, NULL,
450  prop->u.p->flags, NULL, &obj);
451  if(FAILED(hres))
452  break;
453 
454  prop->type = PROP_JSVAL;
455  prop->u.val = jsval_obj(obj);
456 
458  *r = jsval_obj(obj);
459  }
460  break;
461  case PROP_JSVAL:
462  hres = jsval_copy(prop->u.val, r);
463  break;
464  case PROP_ACCESSOR:
465  if(prop->u.accessor.getter) {
466  hres = jsdisp_call_value(prop->u.accessor.getter, to_disp(This),
467  DISPATCH_METHOD, 0, NULL, r);
468  }else {
469  *r = jsval_undefined();
470  hres = S_OK;
471  }
472  break;
473  case PROP_IDX:
474  hres = prop_obj->builtin_info->idx_get(prop_obj, prop->u.idx, r);
475  break;
476  default:
477  ERR("type %d\n", prop->type);
478  return E_FAIL;
479  }
480 
481  if(FAILED(hres)) {
482  TRACE("fail %08x\n", hres);
483  return hres;
484  }
485 
486  TRACE("%s ret %s\n", debugstr_w(prop->name), debugstr_jsval(*r));
487  return hres;
488 }
489 
491 {
492  HRESULT hres;
493 
494  if(prop->type == PROP_PROTREF) {
495  dispex_prop_t *prop_iter = prop;
496  jsdisp_t *prototype_iter = This;
497 
498  do {
499  prototype_iter = prototype_iter->prototype;
500  prop_iter = prototype_iter->props + prop_iter->u.ref;
501  } while(prop_iter->type == PROP_PROTREF);
502 
503  if(prop_iter->type == PROP_ACCESSOR)
504  prop = prop_iter;
505  }
506 
507  switch(prop->type) {
508  case PROP_BUILTIN:
509  if(!prop->u.p->setter) {
510  TRACE("getter with no setter\n");
511  return S_OK;
512  }
513  return prop->u.p->setter(This->ctx, This, val);
514  case PROP_PROTREF:
515  case PROP_DELETED:
516  prop->type = PROP_JSVAL;
518  prop->u.val = jsval_undefined();
519  break;
520  case PROP_JSVAL:
521  if(!(prop->flags & PROPF_WRITABLE))
522  return S_OK;
523 
524  jsval_release(prop->u.val);
525  break;
526  case PROP_ACCESSOR:
527  if(!prop->u.accessor.setter) {
528  TRACE("no setter\n");
529  return S_OK;
530  }
531  return jsdisp_call_value(prop->u.accessor.setter, to_disp(This), DISPATCH_METHOD, 1, &val, NULL);
532  case PROP_IDX:
533  if(!This->builtin_info->idx_put) {
534  TRACE("no put_idx\n");
535  return S_OK;
536  }
537  return This->builtin_info->idx_put(This, prop->u.idx, val);
538  default:
539  ERR("type %d\n", prop->type);
540  return E_FAIL;
541  }
542 
543  TRACE("%s = %s\n", debugstr_w(prop->name), debugstr_jsval(val));
544 
545  hres = jsval_copy(val, &prop->u.val);
546  if(FAILED(hres))
547  return hres;
548 
549  if(This->builtin_info->on_put)
550  This->builtin_info->on_put(This, prop->name);
551 
552  return S_OK;
553 }
554 
556 {
557  TRACE("%p %s\n", jsthis, debugstr_jsval(value));
558  return S_OK;
559 }
560 
562 {
563  dispex_prop_t *iter, *prop;
564  HRESULT hres;
565 
566  if(!This->prototype)
567  return S_OK;
568 
569  fill_protrefs(This->prototype);
570 
571  for(iter = This->prototype->props; iter < This->prototype->props+This->prototype->prop_cnt; iter++) {
572  if(!iter->name)
573  continue;
574  hres = find_prop_name(This, iter->hash, iter->name, &prop);
575  if(FAILED(hres))
576  return hres;
577  if(!prop || prop->type==PROP_DELETED) {
578  if(prop) {
579  prop->type = PROP_PROTREF;
580  prop->flags = 0;
581  prop->u.ref = iter - This->prototype->props;
582  }else {
583  prop = alloc_protref(This, iter->name, iter - This->prototype->props);
584  if(!prop)
585  return E_OUTOFMEMORY;
586  }
587  }
588  }
589 
590  return S_OK;
591 }
592 
593 static inline jsdisp_t *impl_from_IDispatchEx(IDispatchEx *iface)
594 {
595  return CONTAINING_RECORD(iface, jsdisp_t, IDispatchEx_iface);
596 }
597 
598 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
599 {
601 
602  if(IsEqualGUID(&IID_IUnknown, riid)) {
603  TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
604  *ppv = &This->IDispatchEx_iface;
605  }else if(IsEqualGUID(&IID_IDispatch, riid)) {
606  TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
607  *ppv = &This->IDispatchEx_iface;
608  }else if(IsEqualGUID(&IID_IDispatchEx, riid)) {
609  TRACE("(%p)->(IID_IDispatchEx %p)\n", This, ppv);
610  *ppv = &This->IDispatchEx_iface;
611  }else {
612  WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
613  *ppv = NULL;
614  return E_NOINTERFACE;
615  }
616 
618  return S_OK;
619 }
620 
621 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
622 {
625  return This->ref;
626 }
627 
628 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
629 {
631  ULONG ref = --This->ref;
632  TRACE("(%p) ref=%d\n", This, ref);
633  if(!ref)
634  jsdisp_free(This);
635  return ref;
636 }
637 
638 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
639 {
641 
642  TRACE("(%p)->(%p)\n", This, pctinfo);
643 
644  *pctinfo = 1;
645  return S_OK;
646 }
647 
648 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, LCID lcid,
649  ITypeInfo **ppTInfo)
650 {
652  FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
653  return E_NOTIMPL;
654 }
655 
656 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
657  LPOLESTR *rgszNames, UINT cNames, LCID lcid,
658  DISPID *rgDispId)
659 {
661  UINT i;
662  HRESULT hres;
663 
664  TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
665  lcid, rgDispId);
666 
667  for(i=0; i < cNames; i++) {
668  hres = IDispatchEx_GetDispID(&This->IDispatchEx_iface, rgszNames[i], 0, rgDispId+i);
669  if(FAILED(hres))
670  return hres;
671  }
672 
673  return S_OK;
674 }
675 
676 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
677  REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
678  VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
679 {
681 
682  TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
683  lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
684 
685  return IDispatchEx_InvokeEx(&This->IDispatchEx_iface, dispIdMember, lcid, wFlags,
686  pDispParams, pVarResult, pExcepInfo, NULL);
687 }
688 
689 static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
690 {
692 
693  TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
694 
695  if(grfdex & ~(fdexNameCaseSensitive|fdexNameEnsure|fdexNameImplicit|FDEX_VERSION_MASK)) {
696  FIXME("Unsupported grfdex %x\n", grfdex);
697  return E_NOTIMPL;
698  }
699 
700  return jsdisp_get_id(This, bstrName, grfdex, pid);
701 }
702 
703 static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
704  VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
705 {
707  dispex_prop_t *prop;
708  HRESULT hres;
709 
710  TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
711 
712  if(pvarRes)
713  V_VT(pvarRes) = VT_EMPTY;
714 
715  prop = get_prop(This, id);
716  if(!prop || prop->type == PROP_DELETED) {
717  TRACE("invalid id\n");
718  return DISP_E_MEMBERNOTFOUND;
719  }
720 
721  clear_ei(This->ctx);
722 
723  switch(wFlags) {
726  /* fall through */
727  case DISPATCH_METHOD:
728  case DISPATCH_CONSTRUCT: {
729  jsval_t *argv, buf[6], r;
730  unsigned argc;
731 
732  hres = convert_params(pdp, buf, &argc, &argv);
733  if(FAILED(hres))
734  return hres;
735 
736  hres = invoke_prop_func(This, get_this(pdp), prop, wFlags, argc, argv, pvarRes ? &r : NULL, pspCaller);
737  if(argv != buf)
738  heap_free(argv);
739  if(SUCCEEDED(hres) && pvarRes) {
740  hres = jsval_to_variant(r, pvarRes);
741  jsval_release(r);
742  }
743  break;
744  }
745  case DISPATCH_PROPERTYGET: {
746  jsval_t r;
747 
748  hres = prop_get(This, prop, &r);
749  if(SUCCEEDED(hres)) {
750  hres = jsval_to_variant(r, pvarRes);
751  jsval_release(r);
752  }
753  break;
754  }
755  case DISPATCH_PROPERTYPUT: {
756  jsval_t val;
757  DWORD i;
758 
759  for(i=0; i < pdp->cNamedArgs; i++) {
760  if(pdp->rgdispidNamedArgs[i] == DISPID_PROPERTYPUT)
761  break;
762  }
763 
764  if(i == pdp->cNamedArgs) {
765  TRACE("no value to set\n");
767  }
768 
769  hres = variant_to_jsval(pdp->rgvarg+i, &val);
770  if(FAILED(hres))
771  return hres;
772 
773  hres = prop_put(This, prop, val);
775  break;
776  }
777  default:
778  FIXME("Unimplemented flags %x\n", wFlags);
779  return E_INVALIDARG;
780  }
781 
782  if(pei)
783  *pei = This->ctx->ei.ei;
784  return hres;
785 }
786 
788 {
789  if(!(prop->flags & PROPF_CONFIGURABLE)) {
790  *ret = FALSE;
791  return S_OK;
792  }
793 
794  *ret = TRUE; /* FIXME: not exactly right */
795 
796  if(prop->type == PROP_JSVAL) {
797  jsval_release(prop->u.val);
798  prop->type = PROP_DELETED;
799  }
800  if(prop->type == PROP_ACCESSOR)
801  FIXME("not supported on accessor property\n");
802  return S_OK;
803 }
804 
805 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
806 {
808  dispex_prop_t *prop;
809  BOOL b;
810  HRESULT hres;
811 
812  TRACE("(%p)->(%s %x)\n", This, debugstr_w(bstrName), grfdex);
813 
814  if(grfdex & ~(fdexNameCaseSensitive|fdexNameEnsure|fdexNameImplicit|FDEX_VERSION_MASK))
815  FIXME("Unsupported grfdex %x\n", grfdex);
816 
817  hres = find_prop_name(This, string_hash(bstrName), bstrName, &prop);
818  if(FAILED(hres))
819  return hres;
820  if(!prop) {
821  TRACE("not found\n");
822  return S_OK;
823  }
824 
825  return delete_prop(prop, &b);
826 }
827 
828 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
829 {
831  dispex_prop_t *prop;
832  BOOL b;
833 
834  TRACE("(%p)->(%x)\n", This, id);
835 
836  prop = get_prop(This, id);
837  if(!prop) {
838  WARN("invalid id\n");
839  return DISP_E_MEMBERNOTFOUND;
840  }
841 
842  return delete_prop(prop, &b);
843 }
844 
845 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
846 {
848  FIXME("(%p)->(%x %x %p)\n", This, id, grfdexFetch, pgrfdex);
849  return E_NOTIMPL;
850 }
851 
852 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
853 {
855  dispex_prop_t *prop;
856 
857  TRACE("(%p)->(%x %p)\n", This, id, pbstrName);
858 
859  prop = get_prop(This, id);
860  if(!prop || !prop->name || prop->type == PROP_DELETED)
861  return DISP_E_MEMBERNOTFOUND;
862 
863  *pbstrName = SysAllocString(prop->name);
864  if(!*pbstrName)
865  return E_OUTOFMEMORY;
866 
867  return S_OK;
868 }
869 
870 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
871 {
873  HRESULT hres;
874 
875  TRACE("(%p)->(%x %x %p)\n", This, grfdex, id, pid);
876 
878  if(hres == S_FALSE)
879  *pid = DISPID_STARTENUM;
880  return hres;
881 }
882 
883 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
884 {
886  FIXME("(%p)->(%p)\n", This, ppunk);
887  return E_NOTIMPL;
888 }
889 
890 static IDispatchExVtbl DispatchExVtbl = {
906 };
907 
909 {
910  assert(disp->lpVtbl == (IDispatchVtbl*)&DispatchExVtbl);
911  return impl_from_IDispatchEx((IDispatchEx*)disp);
912 }
913 
915 {
916  return disp->lpVtbl == (IDispatchVtbl*)&DispatchExVtbl ? impl_from_IDispatchEx((IDispatchEx*)disp) : NULL;
917 }
918 
919 HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype)
920 {
921  TRACE("%p (%p)\n", dispex, prototype);
922 
923  dispex->IDispatchEx_iface.lpVtbl = &DispatchExVtbl;
924  dispex->ref = 1;
925  dispex->builtin_info = builtin_info;
926 
927  dispex->props = heap_alloc_zero(sizeof(dispex_prop_t)*(dispex->buf_size=4));
928  if(!dispex->props)
929  return E_OUTOFMEMORY;
930 
931  dispex->prototype = prototype;
932  if(prototype)
933  jsdisp_addref(prototype);
934 
935  dispex->prop_cnt = 1;
936  if(builtin_info->value_prop.invoke || builtin_info->value_prop.getter) {
937  dispex->props[0].type = PROP_BUILTIN;
938  dispex->props[0].u.p = &builtin_info->value_prop;
939  }else {
940  dispex->props[0].type = PROP_DELETED;
941  }
942 
943  script_addref(ctx);
944  dispex->ctx = ctx;
945 
946  return S_OK;
947 }
948 
949 static const builtin_info_t dispex_info = {
950  JSCLASS_NONE,
951  {NULL, NULL, 0},
952  0, NULL,
953  NULL,
954  NULL
955 };
956 
957 HRESULT create_dispex(script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype, jsdisp_t **dispex)
958 {
959  jsdisp_t *ret;
960  HRESULT hres;
961 
962  ret = heap_alloc_zero(sizeof(jsdisp_t));
963  if(!ret)
964  return E_OUTOFMEMORY;
965 
966  hres = init_dispex(ret, ctx, builtin_info ? builtin_info : &dispex_info, prototype);
967  if(FAILED(hres)) {
968  heap_free(ret);
969  return hres;
970  }
971 
972  *dispex = ret;
973  return S_OK;
974 }
975 
977 {
978  dispex_prop_t *prop;
979 
980  TRACE("(%p)\n", obj);
981 
982  for(prop = obj->props; prop < obj->props+obj->prop_cnt; prop++) {
983  switch(prop->type) {
984  case PROP_JSVAL:
985  jsval_release(prop->u.val);
986  break;
987  case PROP_ACCESSOR:
988  if(prop->u.accessor.getter)
989  jsdisp_release(prop->u.accessor.getter);
990  if(prop->u.accessor.setter)
991  jsdisp_release(prop->u.accessor.setter);
992  break;
993  default:
994  break;
995  };
996  heap_free(prop->name);
997  }
998  heap_free(obj->props);
999  script_release(obj->ctx);
1000  if(obj->prototype)
1001  jsdisp_release(obj->prototype);
1002 
1003  if(obj->builtin_info->destructor)
1004  obj->builtin_info->destructor(obj);
1005  else
1006  heap_free(obj);
1007 }
1008 
1009 #ifdef TRACE_REFCNT
1010 
1012 {
1013  ULONG ref = ++jsdisp->ref;
1014  TRACE("(%p) ref=%d\n", jsdisp, ref);
1015  return jsdisp;
1016 }
1017 
1018 void jsdisp_release(jsdisp_t *jsdisp)
1019 {
1020  ULONG ref = --jsdisp->ref;
1021 
1022  TRACE("(%p) ref=%d\n", jsdisp, ref);
1023 
1024  if(!ref)
1025  jsdisp_free(jsdisp);
1026 }
1027 
1028 #endif
1029 
1030 HRESULT init_dispex_from_constr(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *constr)
1031 {
1032  jsdisp_t *prot = NULL;
1033  dispex_prop_t *prop;
1034  HRESULT hres;
1035 
1036  static const WCHAR prototypeW[] = {'p','r','o','t','o','t','y','p','e',0};
1037 
1039  if(SUCCEEDED(hres) && prop && prop->type!=PROP_DELETED) {
1040  jsval_t val;
1041 
1042  hres = prop_get(constr, prop, &val);
1043  if(FAILED(hres)) {
1044  ERR("Could not get prototype\n");
1045  return hres;
1046  }
1047 
1048  if(is_object_instance(val))
1049  prot = iface_to_jsdisp(get_object(val));
1050  jsval_release(val);
1051  }
1052 
1053  hres = init_dispex(dispex, ctx, builtin_info, prot);
1054 
1055  if(prot)
1056  jsdisp_release(prot);
1057  return hres;
1058 }
1059 
1061 {
1062  return iface->lpVtbl == (const IDispatchVtbl*)&DispatchExVtbl
1063  ? jsdisp_addref( impl_from_IDispatchEx((IDispatchEx*)iface))
1064  : NULL;
1065 }
1066 
1068 {
1069  dispex_prop_t *prop;
1070  HRESULT hres;
1071 
1072  if(flags & fdexNameEnsure)
1074  &prop);
1075  else
1076  hres = find_prop_name_prot(jsdisp, string_hash(name), name, &prop);
1077  if(FAILED(hres))
1078  return hres;
1079 
1080  if(prop && prop->type!=PROP_DELETED) {
1081  *id = prop_to_id(jsdisp, prop);
1082  return S_OK;
1083  }
1084 
1085  TRACE("not found %s\n", debugstr_w(name));
1086  return DISP_E_UNKNOWNNAME;
1087 }
1088 
1090 {
1091  HRESULT hres;
1092 
1093  assert(!(flags & ~(DISPATCH_METHOD|DISPATCH_CONSTRUCT|DISPATCH_JSCRIPT_INTERNAL_MASK)));
1094 
1095  if(is_class(jsfunc, JSCLASS_FUNCTION)) {
1096  hres = Function_invoke(jsfunc, jsthis, flags, argc, argv, r);
1097  }else {
1098  vdisp_t vdisp;
1099 
1100  if(!jsfunc->builtin_info->value_prop.invoke) {
1101  WARN("Not a function\n");
1102  return throw_type_error(jsfunc->ctx, JS_E_FUNCTION_EXPECTED, NULL);
1103  }
1104 
1105  set_disp(&vdisp, jsthis);
1107  hres = jsfunc->builtin_info->value_prop.invoke(jsfunc->ctx, &vdisp, flags, argc, argv, r);
1108  vdisp_release(&vdisp);
1109  }
1110  return hres;
1111 }
1112 
1114 {
1115  dispex_prop_t *prop;
1116 
1117  prop = get_prop(disp, id);
1118  if(!prop)
1119  return DISP_E_MEMBERNOTFOUND;
1120 
1121  return invoke_prop_func(disp, to_disp(disp), prop, flags, argc, argv, r, NULL);
1122 }
1123 
1125 {
1126  dispex_prop_t *prop;
1127  HRESULT hres;
1128 
1130  if(FAILED(hres))
1131  return hres;
1132 
1133  return invoke_prop_func(disp, to_disp(disp), prop, flags, argc, argv, r, NULL);
1134 }
1135 
1137 {
1138  IDispatchEx *dispex;
1139  jsdisp_t *jsdisp;
1140  VARIANT buf[6], retv;
1141  DISPPARAMS dp;
1142  unsigned i;
1143  HRESULT hres;
1144 
1145  jsdisp = iface_to_jsdisp(disp);
1146  if(jsdisp) {
1147  if(flags & DISPATCH_PROPERTYPUT) {
1148  FIXME("disp_call(propput) on builtin object\n");
1149  return E_FAIL;
1150  }
1151 
1152  if(ctx != jsdisp->ctx)
1154  hres = jsdisp_call(jsdisp, id, flags, argc, argv, ret);
1155  jsdisp_release(jsdisp);
1156  return hres;
1157  }
1158 
1160  if(ret && argc)
1162 
1163  dp.cArgs = argc;
1164 
1165  if(flags & DISPATCH_PROPERTYPUT) {
1166  static DISPID propput_dispid = DISPID_PROPERTYPUT;
1167 
1168  dp.cNamedArgs = 1;
1169  dp.rgdispidNamedArgs = &propput_dispid;
1170  }else {
1171  dp.cNamedArgs = 0;
1172  dp.rgdispidNamedArgs = NULL;
1173  }
1174 
1175  if(argc > 6) {
1176  dp.rgvarg = heap_alloc(argc*sizeof(VARIANT));
1177  if(!dp.rgvarg)
1178  return E_OUTOFMEMORY;
1179  }else {
1180  dp.rgvarg = buf;
1181  }
1182 
1183  for(i=0; i<argc; i++) {
1184  hres = jsval_to_variant(argv[i], dp.rgvarg+argc-i-1);
1185  if(FAILED(hres)) {
1186  while(i--)
1187  VariantClear(dp.rgvarg+argc-i-1);
1188  if(dp.rgvarg != buf)
1189  heap_free(dp.rgvarg);
1190  return hres;
1191  }
1192  }
1193 
1194  V_VT(&retv) = VT_EMPTY;
1195  clear_ei(ctx);
1196  hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
1197  if(SUCCEEDED(hres)) {
1198  hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, flags, &dp, ret ? &retv : NULL, &ctx->ei.ei,
1200  IDispatchEx_Release(dispex);
1201  }else {
1202  UINT err = 0;
1203 
1204  if(flags == DISPATCH_CONSTRUCT) {
1205  WARN("IDispatch cannot be constructor\n");
1206  return DISP_E_MEMBERNOTFOUND;
1207  }
1208 
1209  TRACE("using IDispatch\n");
1210  hres = IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, flags, &dp, ret ? &retv : NULL, &ctx->ei.ei, &err);
1211  }
1212 
1213  for(i=0; i<argc; i++)
1214  VariantClear(dp.rgvarg+argc-i-1);
1215  if(dp.rgvarg != buf)
1216  heap_free(dp.rgvarg);
1217  if(FAILED(hres))
1218  return hres;
1219 
1220  if(ret) {
1221  hres = variant_to_jsval(&retv, ret);
1222  VariantClear(&retv);
1223  }
1224 
1225  return hres;
1226 }
1227 
1229  jsval_t *r)
1230 {
1231  jsdisp_t *jsdisp;
1232  IDispatchEx *dispex;
1233  VARIANT buf[6], retv;
1234  DISPPARAMS dp;
1235  unsigned i;
1236  HRESULT hres;
1237 
1238  assert(!(flags & ~(DISPATCH_METHOD|DISPATCH_CONSTRUCT|DISPATCH_JSCRIPT_INTERNAL_MASK)));
1239 
1240  jsdisp = iface_to_jsdisp(disp);
1241  if(jsdisp) {
1242  if(ctx != jsdisp->ctx)
1244  hres = jsdisp_call_value(jsdisp, jsthis, flags, argc, argv, r);
1245  jsdisp_release(jsdisp);
1246  return hres;
1247  }
1248 
1250  if(r && argc && flags == DISPATCH_METHOD)
1252 
1253  hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
1254  if(FAILED(hres)) {
1255  TRACE("using IDispatch\n");
1256  dispex = NULL;
1257  jsthis = NULL;
1258  }
1259 
1260  if(jsthis) {
1261  static DISPID this_id = DISPID_THIS;
1262 
1263  dp.cArgs = argc+1;
1264  dp.cNamedArgs = 1;
1265  dp.rgdispidNamedArgs = &this_id;
1266  }else {
1267  dp.cArgs = argc;
1268  dp.cNamedArgs = 0;
1269  dp.rgdispidNamedArgs = NULL;
1270  }
1271 
1272  if(dp.cArgs > ARRAY_SIZE(buf)) {
1273  dp.rgvarg = heap_alloc(dp.cArgs*sizeof(VARIANT));
1274  if(!dp.rgvarg) {
1275  if(dispex)
1276  IDispatchEx_Release(dispex);
1277  return E_OUTOFMEMORY;
1278  }
1279  }else {
1280  dp.rgvarg = buf;
1281  }
1282 
1283  for(i=0; i<argc; i++) {
1284  hres = jsval_to_variant(argv[i], dp.rgvarg+dp.cArgs-i-1);
1285  if(FAILED(hres)) {
1286  while(i--)
1287  VariantClear(dp.rgvarg+dp.cArgs-i-1);
1288  if(dp.rgvarg != buf)
1289  heap_free(dp.rgvarg);
1290  if(dispex)
1291  IDispatchEx_Release(dispex);
1292  return hres;
1293  }
1294  }
1295  if(jsthis) {
1296  V_VT(dp.rgvarg) = VT_DISPATCH;
1297  V_DISPATCH(dp.rgvarg) = jsthis;
1298  }
1299 
1300  V_VT(&retv) = VT_EMPTY;
1301  clear_ei(ctx);
1302  if(dispex) {
1303  hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, ctx->lcid, flags, &dp, r ? &retv : NULL, &ctx->ei.ei,
1305  IDispatchEx_Release(dispex);
1306  }else {
1307  UINT err = 0;
1308 
1309  if(flags == DISPATCH_CONSTRUCT) {
1310  WARN("IDispatch cannot be constructor\n");
1311  return DISP_E_MEMBERNOTFOUND;
1312  }
1313 
1314  hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, ctx->lcid, flags, &dp, r ? &retv : NULL, &ctx->ei.ei, &err);
1315  }
1316 
1317  for(i=0; i<argc; i++)
1318  VariantClear(dp.rgvarg+dp.cArgs-i-1);
1319  if(dp.rgvarg != buf)
1320  heap_free(dp.rgvarg);
1321  if(FAILED(hres))
1322  return hres;
1323 
1324  if(!r)
1325  return S_OK;
1326 
1327  hres = variant_to_jsval(&retv, r);
1328  VariantClear(&retv);
1329  return hres;
1330 }
1331 
1333 {
1334  dispex_prop_t *prop;
1335  HRESULT hres;
1336 
1337  hres = ensure_prop_name(obj, name, flags, &prop);
1338  if(FAILED(hres))
1339  return hres;
1340 
1341  return prop_put(obj, prop, val);
1342 }
1343 
1345 {
1347 }
1348 
1350 {
1351  WCHAR buf[12];
1352 
1353  static const WCHAR formatW[] = {'%','d',0};
1354 
1355  swprintf(buf, formatW, idx);
1356  return jsdisp_propput_name(obj, buf, val);
1357 }
1358 
1360 {
1361  jsdisp_t *jsdisp;
1362  HRESULT hres;
1363 
1364  jsdisp = iface_to_jsdisp(disp);
1365  if(jsdisp) {
1366  dispex_prop_t *prop;
1367 
1368  prop = get_prop(jsdisp, id);
1369  if(prop)
1370  hres = prop_put(jsdisp, prop, val);
1371  else
1373 
1374  jsdisp_release(jsdisp);
1375  }else {
1376  DISPID dispid = DISPID_PROPERTYPUT;
1378  VARIANT var;
1379  DISPPARAMS dp = {&var, &dispid, 1, 1};
1380  IDispatchEx *dispex;
1381 
1382  hres = jsval_to_variant(val, &var);
1383  if(FAILED(hres))
1384  return hres;
1385 
1386  if(V_VT(&var) == VT_DISPATCH)
1388 
1389  clear_ei(ctx);
1390  hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
1391  if(SUCCEEDED(hres)) {
1392  hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, flags, &dp, NULL, &ctx->ei.ei,
1394  IDispatchEx_Release(dispex);
1395  }else {
1396  ULONG err = 0;
1397 
1398  TRACE("using IDispatch\n");
1399  hres = IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, flags, &dp, NULL, &ctx->ei.ei, &err);
1400  }
1401 
1402  VariantClear(&var);
1403  }
1404 
1405  return hres;
1406 }
1407 
1409 {
1410  dispex_prop_t *prop;
1411  HRESULT hres;
1412 
1414  if(FAILED(hres))
1415  return hres;
1416 
1417  if(!prop || prop->type==PROP_DELETED) {
1418  *val = jsval_undefined();
1419  return S_OK;
1420  }
1421 
1422  return prop_get(obj, prop, val);
1423 }
1424 
1426 {
1427  WCHAR name[12];
1428  dispex_prop_t *prop;
1429  HRESULT hres;
1430 
1431  static const WCHAR formatW[] = {'%','d',0};
1432 
1433  swprintf(name, formatW, idx);
1434 
1436  if(FAILED(hres))
1437  return hres;
1438 
1439  if(!prop || prop->type==PROP_DELETED) {
1440  *r = jsval_undefined();
1441  return DISP_E_UNKNOWNNAME;
1442  }
1443 
1444  return prop_get(obj, prop, r);
1445 }
1446 
1448 {
1449  dispex_prop_t *prop;
1450 
1451  prop = get_prop(jsdisp, id);
1452  if(!prop)
1453  return DISP_E_MEMBERNOTFOUND;
1454 
1455  return prop_get(jsdisp, prop, val);
1456 }
1457 
1459 {
1460  DISPPARAMS dp = {NULL,NULL,0,0};
1461  IDispatchEx *dispex;
1462  jsdisp_t *jsdisp;
1463  VARIANT var;
1464  HRESULT hres;
1465 
1466  jsdisp = iface_to_jsdisp(disp);
1467  if(jsdisp) {
1468  hres = jsdisp_propget(jsdisp, id, val);
1469  jsdisp_release(jsdisp);
1470  return hres;
1471  }
1472 
1473  V_VT(&var) = VT_EMPTY;
1474  clear_ei(ctx);
1475  hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
1476  if(SUCCEEDED(hres)) {
1477  hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, INVOKE_PROPERTYGET, &dp, &var, &ctx->ei.ei,
1479  IDispatchEx_Release(dispex);
1480  }else {
1481  ULONG err = 0;
1482 
1483  TRACE("using IDispatch\n");
1484  hres = IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, INVOKE_PROPERTYGET, &dp, &var, &ctx->ei.ei, &err);
1485  }
1486  if(FAILED(hres))
1487  return hres;
1488 
1489  hres = variant_to_jsval(&var, val);
1490  VariantClear(&var);
1491  return hres;
1492 }
1493 
1495 {
1496  static const WCHAR formatW[] = {'%','d',0};
1497  WCHAR buf[12];
1498  dispex_prop_t *prop;
1499  BOOL b;
1500  HRESULT hres;
1501 
1502  swprintf(buf, formatW, idx);
1503 
1504  hres = find_prop_name(obj, string_hash(buf), buf, &prop);
1505  if(FAILED(hres) || !prop)
1506  return hres;
1507 
1508  return delete_prop(prop, &b);
1509 }
1510 
1512 {
1513  IDispatchEx *dispex;
1514  jsdisp_t *jsdisp;
1515  HRESULT hres;
1516 
1517  jsdisp = iface_to_jsdisp(disp);
1518  if(jsdisp) {
1519  dispex_prop_t *prop;
1520 
1521  prop = get_prop(jsdisp, id);
1522  if(prop)
1523  hres = delete_prop(prop, ret);
1524  else
1526 
1527  jsdisp_release(jsdisp);
1528  return hres;
1529  }
1530 
1531  hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
1532  if(FAILED(hres)) {
1533  *ret = FALSE;
1534  return S_OK;
1535  }
1536 
1537  hres = IDispatchEx_DeleteMemberByDispID(dispex, id);
1538  IDispatchEx_Release(dispex);
1539  if(FAILED(hres))
1540  return hres;
1541 
1542  *ret = hres == S_OK;
1543  return S_OK;
1544 }
1545 
1547 {
1548  dispex_prop_t *iter;
1549  HRESULT hres;
1550 
1551  if(id == DISPID_STARTENUM && !own_only) {
1552  hres = fill_protrefs(obj);
1553  if(FAILED(hres))
1554  return hres;
1555  }
1556 
1557  if(id + 1 < 0 || id+1 >= obj->prop_cnt)
1558  return S_FALSE;
1559 
1560  for(iter = &obj->props[id + 1]; iter < obj->props + obj->prop_cnt; iter++) {
1561  if(!iter->name || iter->type == PROP_DELETED)
1562  continue;
1563  if(own_only && iter->type == PROP_PROTREF)
1564  continue;
1565  if(!(get_flags(obj, iter) & PROPF_ENUMERABLE))
1566  continue;
1567  *ret = prop_to_id(obj, iter);
1568  return S_OK;
1569  }
1570 
1571  return S_FALSE;
1572 }
1573 
1575 {
1576  IDispatchEx *dispex;
1577  jsdisp_t *jsdisp;
1578  BSTR bstr;
1579  HRESULT hres;
1580 
1581  jsdisp = iface_to_jsdisp(disp);
1582  if(jsdisp) {
1583  dispex_prop_t *prop;
1584  const WCHAR *ptr;
1585 
1586  ptr = jsstr_flatten(name);
1587  if(!ptr) {
1588  jsdisp_release(jsdisp);
1589  return E_OUTOFMEMORY;
1590  }
1591 
1592  hres = find_prop_name(jsdisp, string_hash(ptr), ptr, &prop);
1593  if(prop) {
1594  hres = delete_prop(prop, ret);
1595  }else {
1596  *ret = TRUE;
1597  hres = S_OK;
1598  }
1599 
1600  jsdisp_release(jsdisp);
1601  return hres;
1602  }
1603 
1605  if(!bstr)
1606  return E_OUTOFMEMORY;
1607  jsstr_flush(name, bstr);
1608 
1609  hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
1610  if(SUCCEEDED(hres)) {
1611  hres = IDispatchEx_DeleteMemberByName(dispex, bstr, make_grfdex(ctx, fdexNameCaseSensitive));
1612  if(SUCCEEDED(hres))
1613  *ret = hres == S_OK;
1614  IDispatchEx_Release(dispex);
1615  }else {
1616  DISPID id;
1617 
1618  hres = IDispatch_GetIDsOfNames(disp, &IID_NULL, &bstr, 1, 0, &id);
1619  if(SUCCEEDED(hres)) {
1620  /* Property exists and we can't delete it from pure IDispatch interface, so return false. */
1621  *ret = FALSE;
1622  }else if(hres == DISP_E_UNKNOWNNAME) {
1623  /* Property doesn't exist, so nothing to delete */
1624  *ret = TRUE;
1625  hres = S_OK;
1626  }
1627  }
1628 
1629  SysFreeString(bstr);
1630  return hres;
1631 }
1632 
1635 {
1636  dispex_prop_t *prop;
1637  HRESULT hres;
1638 
1639  hres = find_prop_name(obj, string_hash(name), name, &prop);
1640  if(FAILED(hres))
1641  return hres;
1642 
1643  if(!prop)
1644  return DISP_E_UNKNOWNNAME;
1645 
1646  memset(desc, 0, sizeof(*desc));
1647 
1648  switch(prop->type) {
1649  case PROP_BUILTIN:
1650  case PROP_JSVAL:
1651  desc->mask |= PROPF_WRITABLE;
1652  desc->explicit_value = TRUE;
1653  if(!flags_only) {
1654  hres = prop_get(obj, prop, &desc->value);
1655  if(FAILED(hres))
1656  return hres;
1657  }
1658  break;
1659  case PROP_ACCESSOR:
1660  desc->explicit_getter = desc->explicit_setter = TRUE;
1661  if(!flags_only) {
1662  desc->getter = prop->u.accessor.getter
1663  ? jsdisp_addref(prop->u.accessor.getter) : NULL;
1664  desc->setter = prop->u.accessor.setter
1665  ? jsdisp_addref(prop->u.accessor.setter) : NULL;
1666  }
1667  break;
1668  default:
1669  return DISP_E_UNKNOWNNAME;
1670  }
1671 
1674  return S_OK;
1675 }
1676 
1678 {
1679  dispex_prop_t *prop;
1680  HRESULT hres;
1681 
1682  hres = find_prop_name(obj, string_hash(name), name, &prop);
1683  if(FAILED(hres))
1684  return hres;
1685 
1686  if(!prop && !(prop = alloc_prop(obj, name, PROP_DELETED, 0)))
1687  return E_OUTOFMEMORY;
1688 
1689  if(prop->type == PROP_DELETED || prop->type == PROP_PROTREF) {
1690  prop->flags = desc->flags;
1691  if(desc->explicit_getter || desc->explicit_setter) {
1692  prop->type = PROP_ACCESSOR;
1693  prop->u.accessor.getter = desc->getter ? jsdisp_addref(desc->getter) : NULL;
1694  prop->u.accessor.setter = desc->setter ? jsdisp_addref(desc->setter) : NULL;
1695  TRACE("%s = accessor { get: %p set: %p }\n", debugstr_w(name),
1696  prop->u.accessor.getter, prop->u.accessor.setter);
1697  }else {
1698  prop->type = PROP_JSVAL;
1699  if(desc->explicit_value) {
1700  hres = jsval_copy(desc->value, &prop->u.val);
1701  if(FAILED(hres))
1702  return hres;
1703  }else {
1704  prop->u.val = jsval_undefined();
1705  }
1706  TRACE("%s = %s\n", debugstr_w(name), debugstr_jsval(prop->u.val));
1707  }
1708  return S_OK;
1709  }
1710 
1711  TRACE("existing prop %s prop flags %x desc flags %x desc mask %x\n", debugstr_w(name),
1712  prop->flags, desc->flags, desc->mask);
1713 
1714  if(!(prop->flags & PROPF_CONFIGURABLE)) {
1715  if(((desc->mask & PROPF_CONFIGURABLE) && (desc->flags & PROPF_CONFIGURABLE))
1716  || ((desc->mask & PROPF_ENUMERABLE)
1717  && ((desc->flags & PROPF_ENUMERABLE) != (prop->flags & PROPF_ENUMERABLE))))
1719  }
1720 
1721  if(desc->explicit_value || (desc->mask & PROPF_WRITABLE)) {
1722  if(prop->type == PROP_ACCESSOR) {
1723  if(!(prop->flags & PROPF_CONFIGURABLE))
1725  if(prop->u.accessor.getter)
1726  jsdisp_release(prop->u.accessor.getter);
1727  if(prop->u.accessor.setter)
1728  jsdisp_release(prop->u.accessor.setter);
1729 
1730  prop->type = PROP_JSVAL;
1731  hres = jsval_copy(desc->value, &prop->u.val);
1732  if(FAILED(hres)) {
1733  prop->u.val = jsval_undefined();
1734  return hres;
1735  }
1736  }else {
1737  if(!(prop->flags & PROPF_CONFIGURABLE) && !(prop->flags & PROPF_WRITABLE)) {
1738  if((desc->mask & PROPF_WRITABLE) && (desc->flags & PROPF_WRITABLE))
1740  if(desc->explicit_value) {
1741  if(prop->type == PROP_JSVAL) {
1742  BOOL eq;
1743  hres = jsval_strict_equal(desc->value, prop->u.val, &eq);
1744  if(FAILED(hres))
1745  return hres;
1746  if(!eq)
1748  }else {
1749  FIXME("redefinition of property type %d\n", prop->type);
1750  }
1751  }
1752  }
1753  if(desc->explicit_value) {
1754  if(prop->type == PROP_JSVAL)
1755  jsval_release(prop->u.val);
1756  else
1757  prop->type = PROP_JSVAL;
1758  hres = jsval_copy(desc->value, &prop->u.val);
1759  if(FAILED(hres)) {
1760  prop->u.val = jsval_undefined();
1761  return hres;
1762  }
1763  }
1764  }
1765  }else if(desc->explicit_getter || desc->explicit_setter) {
1766  if(prop->type != PROP_ACCESSOR) {
1767  if(!(prop->flags & PROPF_CONFIGURABLE))
1769  if(prop->type == PROP_JSVAL)
1770  jsval_release(prop->u.val);
1771  prop->type = PROP_ACCESSOR;
1772  prop->u.accessor.getter = prop->u.accessor.setter = NULL;
1773  }else if(!(prop->flags & PROPF_CONFIGURABLE)) {
1774  if((desc->explicit_getter && desc->getter != prop->u.accessor.getter)
1775  || (desc->explicit_setter && desc->setter != prop->u.accessor.setter))
1777  }
1778 
1779  if(desc->explicit_getter) {
1780  if(prop->u.accessor.getter) {
1781  jsdisp_release(prop->u.accessor.getter);
1782  prop->u.accessor.getter = NULL;
1783  }
1784  if(desc->getter)
1785  prop->u.accessor.getter = jsdisp_addref(desc->getter);
1786  }
1787  if(desc->explicit_setter) {
1788  if(prop->u.accessor.setter) {
1789  jsdisp_release(prop->u.accessor.setter);
1790  prop->u.accessor.setter = NULL;
1791  }
1792  if(desc->setter)
1793  prop->u.accessor.setter = jsdisp_addref(desc->setter);
1794  }
1795  }
1796 
1797  prop->flags = (prop->flags & ~desc->mask) | (desc->flags & desc->mask);
1798  return S_OK;
1799 }
1800 
1802 {
1803  property_desc_t prop_desc = { flags, flags, TRUE };
1804  prop_desc.value = value;
1805  return jsdisp_define_property(obj, name, &prop_desc);
1806 }
#define PROPF_WRITABLE
Definition: jscript.h:101
#define FDEX_VERSION_MASK
Definition: dispex.c:27
Definition: jsval.h:54
#define DISP_E_UNKNOWNNAME
Definition: winerror.h:2515
static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
Definition: dispex.c:845
static const WCHAR * jsstr_flatten(jsstr_t *str)
Definition: jsstr.h:139
static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
Definition: dispex.c:656
disp
Definition: i386-dis.c:3181
static int argc
Definition: ServiceArgs.c:12
void jsval_release(jsval_t val)
Definition: jsutils.c:191
script_ctx_t * ctx
Definition: jscript.h:238
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3835
prop_type_t type
Definition: dispex.c:42
#define max(a, b)
Definition: svc.c:63
DWORD ref
Definition: dispex.c:48
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
static IDispatchExVtbl DispatchExVtbl
Definition: dispex.c:890
static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
Definition: dispex.c:648
static DISPID propput_dispid
Definition: interp.c:27
#define E_NOINTERFACE
Definition: winerror.h:2364
const WCHAR * name
Definition: jscript.h:211
#define DISPATCH_PROPERTYGET
Definition: oleauto.h:1007
HRESULT jsdisp_propget(jsdisp_t *jsdisp, DISPID id, jsval_t *val)
Definition: dispex.c:1447
static void set_disp(vdisp_t *vdisp, IDispatch *disp)
Definition: jscript.h:174
static void vdisp_release(vdisp_t *vdisp)
Definition: jscript.h:152
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:339
#define JS_E_FUNCTION_EXPECTED
Definition: jscript.h:552
Definition: jsstr.h:39
static const builtin_info_t dispex_info
Definition: dispex.c:949
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
HRESULT jsdisp_call_name(jsdisp_t *disp, const WCHAR *name, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: dispex.c:1124
static HRESULT convert_params(const DISPPARAMS *dp, jsval_t *buf, unsigned *argc, jsval_t **ret)
Definition: dispex.c:342
static IDispatch * get_object(jsval_t v)
Definition: jsval.h:219
HRESULT jsdisp_get_own_property(jsdisp_t *obj, const WCHAR *name, BOOL flags_only, property_desc_t *desc)
Definition: dispex.c:1633
REFIID riid
Definition: precomp.h:44
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
static HRESULT resize_props(jsdisp_t *This)
Definition: dispex.c:133
DWORD flags
Definition: dispex.c:43
WINE_DEFAULT_DEBUG_CHANNEL(jscript)
#define iswdigit(_c)
Definition: ctype.h:667
builtin_getter_t getter
Definition: jscript.h:214
static const builtin_prop_t * find_builtin_prop(jsdisp_t *This, const WCHAR *name)
Definition: dispex.c:88
struct _dispex_prop_t::@418::@419 accessor
#define WARN(fmt,...)
Definition: debug.h:111
HRESULT jsdisp_define_data_property(jsdisp_t *obj, const WCHAR *name, unsigned flags, jsval_t value)
Definition: dispex.c:1801
const builtin_info_t * builtin_info
Definition: jscript.h:242
static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
Definition: dispex.c:621
#define DISP_E_MEMBERNOTFOUND
Definition: winerror.h:2512
static dispex_prop_t * alloc_prop(jsdisp_t *This, const WCHAR *name, prop_type_t type, DWORD flags)
Definition: dispex.c:163
REFIID LPVOID * ppv
Definition: atlbase.h:39
HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: global.c:183
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
static unsigned jsstr_flush(jsstr_t *str, WCHAR *buf)
Definition: jsstr.h:148
#define assert(x)
Definition: debug.h:53
static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
Definition: dispex.c:870
#define PROPF_VERSION_SHIFT
Definition: jscript.h:106
static IDispatch * get_this(DISPPARAMS *dp)
Definition: dispex.c:324
DWORD LCID
Definition: nls.h:13
static unsigned jsstr_length(jsstr_t *str)
Definition: jsstr.h:58
OLECHAR * BSTR
Definition: compat.h:1942
static dispex_prop_t * alloc_protref(jsdisp_t *This, const WCHAR *name, DWORD ref)
Definition: dispex.c:185
static const WCHAR prototypeW[]
Definition: function.c:94
static HRESULT fill_protrefs(jsdisp_t *This)
Definition: dispex.c:561
#define argv
Definition: mplay32.c:18
void clear_ei(script_ctx_t *ctx)
Definition: engine.c:430
static LPOLESTR
Definition: stg_prop.c:27
#define PROPF_ENUMERABLE
Definition: jscript.h:100
#define E_FAIL
Definition: ddrawi.h:102
LONG ref
Definition: jscript.h:233
#define eq(received, expected, label, type)
Definition: locale.c:144
Definition: send.c:47
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:70
jsdisp_t * to_jsdisp(IDispatch *disp)
Definition: dispex.c:914
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
#define DISPATCH_METHOD
Definition: oleauto.h:1006
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
HRESULT jsdisp_call(jsdisp_t *disp, DISPID id, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: dispex.c:1113
GLsizei GLsizei GLuint * obj
Definition: glext.h:6042
builtin_invoke_t invoke
Definition: jscript.h:212
#define V_DISPATCH(A)
Definition: oleauto.h:239
static HRESULT find_prop_name(jsdisp_t *This, unsigned hash, const WCHAR *name, dispex_prop_t **ret)
Definition: dispex.c:197
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
static unsigned string_hash(const WCHAR *name)
Definition: dispex.c:120
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define DISPATCH_JSCRIPT_INTERNAL_MASK
Definition: jscript.h:116
DWORD flags
Definition: jscript.h:213
IDispatchEx IDispatchEx_iface
Definition: jscript.h:231
unsigned int BOOL
Definition: ntddk_ex.h:94
HRESULT jsval_copy(jsval_t v, jsval_t *r)
Definition: jsutils.c:231
static BOOL is_class(jsdisp_t *jsdisp, jsclass_t class)
Definition: jscript.h:504
static const WCHAR desc[]
Definition: protectdata.c:36
static WCHAR * heap_strdupW(const WCHAR *str)
Definition: propsheet.c:178
static DWORD get_flags(jsdisp_t *This, dispex_prop_t *prop)
Definition: dispex.c:73
static HRESULT find_prop_name_prot(jsdisp_t *This, unsigned hash, const WCHAR *name, dispex_prop_t **ret)
Definition: dispex.c:259
HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, unsigned argc, jsval_t *argv, jsval_t *ret)
Definition: dispex.c:1136
#define debugstr_w
Definition: kernel32.h:32
jsval_t val
Definition: dispex.c:46
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:110
static PVOID ptr
Definition: dispmode.c:27
unsigned int idx
Definition: utils.c:41
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
HRESULT disp_propget(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t *val)
Definition: dispex.c:1458
HRESULT jsdisp_next_prop(jsdisp_t *obj, DISPID id, BOOL own_only, DISPID *ret)
Definition: dispex.c:1546
#define PROPF_VERSION_MASK
Definition: jscript.h:105
union _dispex_prop_t::@418 u
smooth NULL
Definition: ftsmooth.c:416
static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
Definition: dispex.c:628
static const WCHAR version[]
Definition: asmname.c:66
HRESULT jsval_to_variant(jsval_t val, VARIANT *retv)
Definition: jsutils.c:347
void script_release(script_ctx_t *ctx)
Definition: jscript.c:67
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
#define JS_E_NONWRITABLE_MODIFIED
Definition: jscript.h:571
IServiceProvider IServiceProvider_iface
Definition: jscript.h:379
static BOOL is_object_instance(jsval_t v)
Definition: jsval.h:166
HRESULT variant_to_jsval(VARIANT *var, jsval_t *r)
Definition: jsutils.c:258
jsdisp_t * setter
Definition: dispex.c:52
#define debugstr_guid
Definition: kernel32.h:35
#define DISPATCH_PROPERTYPUT
Definition: oleauto.h:1008
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define b
Definition: ke_i.h:79
static DWORD make_grfdex(script_ctx_t *ctx, DWORD flags)
Definition: jscript.h:519
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:375
GLuint GLfloat * val
Definition: glext.h:7180
JSCaller * jscaller
Definition: jscript.h:424
HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t val)
Definition: dispex.c:1359
int bucket_next
Definition: dispex.c:57
static void set_jsdisp(vdisp_t *vdisp, jsdisp_t *jsdisp)
Definition: jscript.h:167
HRESULT jsval_strict_equal(jsval_t lval, jsval_t rval, BOOL *ret)
Definition: engine.c:531
static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
Definition: dispex.c:598
HRESULT jsdisp_call_value(jsdisp_t *jsfunc, IDispatch *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: dispex.c:1089
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
HRESULT jsdisp_define_property(jsdisp_t *obj, const WCHAR *name, property_desc_t *desc)
Definition: dispex.c:1677
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT hres
Definition: protocol.c:465
static unsigned get_props_idx(jsdisp_t *This, unsigned hash)
Definition: dispex.c:128
r parent
Definition: btrfs.c:2869
HRESULT jsdisp_propget_name(jsdisp_t *obj, const WCHAR *name, jsval_t *val)
Definition: dispex.c:1408
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
const GUID IID_IUnknown
builtin_prop_t value_prop
Definition: jscript.h:220
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define WINAPI
Definition: msvc.h:6
HRESULT jsdisp_delete_idx(jsdisp_t *obj, DWORD idx)
Definition: dispex.c:1494
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
static jsdisp_t * jsdisp_addref(jsdisp_t *jsdisp)
Definition: jscript.h:262
static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
Definition: dispex.c:883
static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
Definition: dispex.c:828
GLbitfield flags
Definition: glext.h:7161
DWORD prop_cnt
Definition: jscript.h:236
const GUID IID_IDispatch
int ret
static HRESULT ensure_prop_name(jsdisp_t *This, const WCHAR *name, DWORD create_flags, dispex_prop_t **ret)
Definition: dispex.c:298
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
#define IID_NULL
Definition: guiddef.h:98
#define DISP_E_PARAMNOTOPTIONAL
Definition: winerror.h:2524
#define V_VT(A)
Definition: oleauto.h:211
static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
Definition: dispex.c:852
int bucket_head
Definition: dispex.c:56
HRESULT jsdisp_get_id(jsdisp_t *jsdisp, const WCHAR *name, DWORD flags, DISPID *id)
Definition: dispex.c:1067
#define err(...)
HRESULT disp_delete(IDispatch *disp, DISPID id, BOOL *ret)
Definition: dispex.c:1511
void jsdisp_free(jsdisp_t *obj)
Definition: dispex.c:976
GLsizei const GLfloat * value
Definition: glext.h:6069
#define DISPATCH_PROPERTYPUTREF
Definition: oleauto.h:1009
static IDispatch * to_disp(jsdisp_t *jsdisp)
Definition: jscript.h:245
dispex_prop_t * props
Definition: jscript.h:237
unsigned idx
Definition: dispex.c:49
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:519
#define ERR(fmt,...)
Definition: debug.h:109
jsdisp_t * iface_to_jsdisp(IDispatch *iface)
Definition: dispex.c:1060
HRESULT jsdisp_propput_idx(jsdisp_t *obj, DWORD idx, jsval_t val)
Definition: dispex.c:1349
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
static VOID del(LPHIST_ENTRY item)
Definition: history.c:199
struct stdole::EXCEPINFO EXCEPINFO
static jsval_t jsval_undefined(void)
Definition: jsval.h:137
#define S_OK
Definition: intsafe.h:59
static VARIANTARG static DISPID
Definition: ordinal.c:49
jsdisp_t * getter
Definition: dispex.c:51
#define DISPID_THIS
Definition: olectl.h:395
static HRESULT prop_put(jsdisp_t *This, dispex_prop_t *prop, jsval_t val)
Definition: dispex.c:490
#define PROPF_METHOD
Definition: jscript.h:97
#define ARRAY_SIZE(a)
Definition: main.h:24
HRESULT builtin_set_const(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t value)
Definition: dispex.c:555
HRESULT jsdisp_get_idx(jsdisp_t *obj, DWORD idx, jsval_t *r)
Definition: dispex.c:1425
#define E_NOTIMPL
Definition: ddrawi.h:99
static dispex_prop_t * get_prop(jsdisp_t *This, DISPID id)
Definition: dispex.c:65
HRESULT create_dispex(script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype, jsdisp_t **dispex)
Definition: dispex.c:957
#define min(a, b)
Definition: monoChain.cc:55
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
static void jsdisp_release(jsdisp_t *jsdisp)
Definition: jscript.h:268
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
HRESULT Function_invoke(jsdisp_t *func_this, IDispatch *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: function.c:264
static void script_addref(script_ctx_t *ctx)
Definition: jscript.h:465
HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype)
Definition: dispex.c:919
unsigned hash
Definition: dispex.c:41
static jsval_t jsval_obj(jsdisp_t *obj)
Definition: jsval.h:125
HRESULT jsdisp_propput(jsdisp_t *obj, const WCHAR *name, DWORD flags, jsval_t val)
Definition: dispex.c:1332
DWORD buf_size
Definition: jscript.h:235
WCHAR * name
Definition: dispex.c:40
static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
Definition: dispex.c:689
HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: dispex.c:1228
Definition: name.c:38
jsdisp_t * as_jsdisp(IDispatch *disp)
Definition: dispex.c:908
static HRESULT delete_prop(dispex_prop_t *prop, BOOL *ret)
Definition: dispex.c:787
static const WCHAR props[]
Definition: wbemdisp.c:288
struct stdole::DISPPARAMS DISPPARAMS
#define JS_E_NONCONFIGURABLE_REDEFINED
Definition: jscript.h:570
HRESULT(* idx_get)(jsdisp_t *, unsigned, jsval_t *)
Definition: jscript.h:226
HRESULT jsdisp_propput_name(jsdisp_t *obj, const WCHAR *name, jsval_t val)
Definition: dispex.c:1344
DWORD create_flags
Definition: sec_mgr.c:1595
unsigned int ULONG
Definition: retypes.h:1
GLenum GLuint id
Definition: glext.h:5579
#define towlower(c)
Definition: wctype.h:97
static jsdisp_t * impl_from_IDispatchEx(IDispatchEx *iface)
Definition: dispex.c:593
HRESULT throw_type_error(script_ctx_t *ctx, HRESULT error, const WCHAR *str)
Definition: error.c:440
jsdisp_t * prototype
Definition: jscript.h:240
static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: dispex.c:676
builtin_setter_t setter
Definition: jscript.h:215
static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
Definition: dispex.c:805
jsval_t value
Definition: jscript.h:392
EXCEPINFO ei
Definition: jscript.h:400
static HRESULT prop_get(jsdisp_t *This, dispex_prop_t *prop, jsval_t *r)
Definition: dispex.c:431
HRESULT init_dispex_from_constr(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *constr)
Definition: dispex.c:1030
static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
Definition: dispex.c:638
Definition: _hash_fun.h:40
#define memset(x, y, z)
Definition: compat.h:39
#define PROPF_CONFIGURABLE
Definition: jscript.h:102
static DISPID prop_to_id(jsdisp_t *This, dispex_prop_t *prop)
Definition: dispex.c:60
jsexcept_t ei
Definition: jscript.h:425
const builtin_prop_t * p
Definition: dispex.c:47
prop_type_t
Definition: dispex.c:30
#define SUCCEEDED(hr)
Definition: intsafe.h:57
HRESULT disp_delete_name(script_ctx_t *ctx, IDispatch *disp, jsstr_t *name, BOOL *ret)
Definition: dispex.c:1574
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:651
const char * debugstr_jsval(const jsval_t) DECLSPEC_HIDDEN
Definition: jsutils.c:35
#define GOLDEN_RATIO
Definition: dispex.c:28
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
#define PROPF_HTML
Definition: jscript.h:107
static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
Definition: dispex.c:703
GLuint const GLchar * name
Definition: glext.h:6031