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