ReactOS  0.4.13-dev-455-g28ed234
function.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18 
19 #include <assert.h>
20 
21 #include "jscript.h"
22 #include "engine.h"
23 
24 #include "wine/debug.h"
25 
27 
28 typedef struct {
31  const WCHAR *name;
38 
39 typedef struct {
41  FunctionInstance *function;
44  unsigned argc;
46 
48 {
49  return CONTAINING_RECORD(jsdisp, FunctionInstance, dispex);
50 }
51 
53 {
54  return function_from_jsdisp(vdisp->u.jsdisp);
55 }
56 
57 static inline FunctionInstance *function_this(vdisp_t *jsthis)
58 {
59  return is_vclass(jsthis, JSCLASS_FUNCTION) ? function_from_vdisp(jsthis) : NULL;
60 }
61 
63 {
64  return CONTAINING_RECORD(jsdisp, ArgumentsInstance, jsdisp);
65 }
66 
67 static const WCHAR prototypeW[] = {'p','r','o','t','o','t', 'y', 'p','e',0};
68 
69 static const WCHAR lengthW[] = {'l','e','n','g','t','h',0};
70 static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
71 static const WCHAR applyW[] = {'a','p','p','l','y',0};
72 static const WCHAR callW[] = {'c','a','l','l',0};
73 static const WCHAR argumentsW[] = {'a','r','g','u','m','e','n','t','s',0};
74 
76  jsval_t *r)
77 {
78  FIXME("\n");
79  return E_NOTIMPL;
80 }
81 
82 static void Arguments_destructor(jsdisp_t *jsdisp)
83 {
84  ArgumentsInstance *arguments = arguments_from_jsdisp(jsdisp);
85 
86  TRACE("(%p)\n", arguments);
87 
88  if(arguments->buf) {
89  unsigned i;
90  for(i = 0; i < arguments->argc; i++)
91  jsval_release(arguments->buf[i]);
92  heap_free(arguments->buf);
93  }
94 
95  jsdisp_release(&arguments->function->dispex);
96  heap_free(arguments);
97 }
98 
99 static unsigned Arguments_idx_length(jsdisp_t *jsdisp)
100 {
101  ArgumentsInstance *arguments = arguments_from_jsdisp(jsdisp);
102  return arguments->argc;
103 }
104 
105 static jsval_t *get_argument_ref(ArgumentsInstance *arguments, unsigned idx)
106 {
107  if(arguments->buf)
108  return arguments->buf + idx;
109  if(arguments->frame->base_scope->frame || idx >= arguments->frame->function->param_cnt)
110  return arguments->jsdisp.ctx->stack + arguments->frame->arguments_off + idx;
111  return NULL;
112 }
113 
114 static HRESULT Arguments_idx_get(jsdisp_t *jsdisp, unsigned idx, jsval_t *r)
115 {
116  ArgumentsInstance *arguments = arguments_from_jsdisp(jsdisp);
117  jsval_t *ref;
118 
119  TRACE("%p[%u]\n", arguments, idx);
120 
121  if((ref = get_argument_ref(arguments, idx)))
122  return jsval_copy(*ref, r);
123 
124  /* FIXME: Accessing by name won't work for duplicated argument names */
125  return jsdisp_propget_name(arguments->frame->base_scope->jsobj, arguments->function->func_code->params[idx], r);
126 }
127 
128 static HRESULT Arguments_idx_put(jsdisp_t *jsdisp, unsigned idx, jsval_t val)
129 {
130  ArgumentsInstance *arguments = arguments_from_jsdisp(jsdisp);
131  jsval_t *ref;
132  HRESULT hres;
133 
134  TRACE("%p[%u] = %s\n", arguments, idx, debugstr_jsval(val));
135 
136  if((ref = get_argument_ref(arguments, idx))) {
137  jsval_t copy;
138  hres = jsval_copy(val, &copy);
139  if(FAILED(hres))
140  return hres;
141 
142  jsval_release(*ref);
143  *ref = copy;
144  return S_OK;
145  }
146 
147  /* FIXME: Accessing by name won't work for duplicated argument names */
148  return jsdisp_propput_name(arguments->frame->base_scope->jsobj, arguments->function->func_code->params[idx], val);
149 }
150 
153  {NULL, Arguments_value, 0},
154  0, NULL,
156  NULL,
160 };
161 
163 {
165  HRESULT hres;
166 
167  static const WCHAR caleeW[] = {'c','a','l','l','e','e',0};
168 
169  args = heap_alloc_zero(sizeof(*args));
170  if(!args)
171  return E_OUTOFMEMORY;
172 
174  if(FAILED(hres)) {
175  heap_free(args);
176  return hres;
177  }
178 
180  args->argc = frame->argc;
181  args->frame = frame;
182 
184  jsval_number(args->argc));
185  if(SUCCEEDED(hres))
187  jsval_obj(&args->function->dispex));
188  if(SUCCEEDED(hres))
190  if(FAILED(hres)) {
191  jsdisp_release(&args->jsdisp);
192  return hres;
193  }
194 
195  frame->arguments_obj = &args->jsdisp;
196  return S_OK;
197 }
198 
200 {
201  ArgumentsInstance *arguments = arguments_from_jsdisp(args_disp);
202  call_frame_t *frame = arguments->frame;
203  const BOOL on_stack = frame->base_scope->frame == frame;
204  HRESULT hres;
205 
206  /* Reset arguments value to cut the reference cycle. Note that since all activation contexts have
207  * their own arguments property, it's impossible to use prototype's one during name lookup */
209  arguments->frame = NULL;
210 
211  /* Don't bother coppying arguments if call frame holds the last reference. */
212  if(arguments->jsdisp.ref > 1) {
213  arguments->buf = heap_alloc(arguments->argc * sizeof(*arguments->buf));
214  if(arguments->buf) {
215  int i;
216 
217  for(i = 0; i < arguments->argc ; i++) {
218  if(on_stack || i >= frame->function->param_cnt)
219  hres = jsval_copy(arguments->jsdisp.ctx->stack[frame->arguments_off + i], arguments->buf+i);
220  else
221  hres = jsdisp_propget_name(frame->base_scope->jsobj, frame->function->params[i], arguments->buf+i);
222  if(FAILED(hres))
223  arguments->buf[i] = jsval_undefined();
224  }
225  }else {
226  ERR("out of memory\n");
227  arguments->argc = 0;
228  }
229  }
230 
232 }
233 
234 static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_obj, unsigned argc, jsval_t *argv,
235  BOOL is_constructor, BOOL caller_execs_source, jsval_t *r)
236 {
237  jsdisp_t *var_disp;
238  DWORD exec_flags = 0;
239  HRESULT hres;
240 
242  WARN("Script engine state does not allow running code.\n");
243  return E_UNEXPECTED;
244  }
245 
246  if(!function->func_code) {
247  FIXME("no source\n");
248  return E_FAIL;
249  }
250 
251  hres = create_dispex(ctx, NULL, NULL, &var_disp);
252  if(FAILED(hres))
253  return hres;
254 
255  if(caller_execs_source)
256  exec_flags |= EXEC_RETURN_TO_INTERP;
257  if(is_constructor)
258  exec_flags |= EXEC_CONSTRUCTOR;
259  hres = exec_source(ctx, exec_flags, function->code, function->func_code, function->scope_chain, this_obj,
260  &function->dispex, var_disp, argc, argv, r);
261 
262  jsdisp_release(var_disp);
263  return hres;
264 }
265 
267  unsigned argc, jsval_t *argv, jsval_t *r)
268 {
269  vdisp_t vthis;
270  HRESULT hres;
271 
272  if(this_disp)
273  set_disp(&vthis, this_disp);
274  else if(ctx->host_global)
275  set_disp(&vthis, ctx->host_global);
276  else
277  set_jsdisp(&vthis, ctx->global);
278 
279  hres = function->value_proc(ctx, &vthis, flags, argc, argv, r);
280 
281  vdisp_release(&vthis);
282  return hres;
283 }
284 
285 static HRESULT call_function(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_obj,
286  unsigned argc, jsval_t *argv, BOOL caller_execs_source, jsval_t *r)
287 {
288  if(function->value_proc)
289  return invoke_value_proc(ctx, function, this_obj, DISPATCH_METHOD, argc, argv, r);
290 
291  return invoke_source(ctx, function, this_obj, argc, argv, FALSE, caller_execs_source, r);
292 }
293 
295 {
296  jsstr_t *str;
297 
298  static const WCHAR native_prefixW[] = {'\n','f','u','n','c','t','i','o','n',' '};
299  static const WCHAR native_suffixW[] =
300  {'(',')',' ','{','\n',' ',' ',' ',' ','[','n','a','t','i','v','e',' ','c','o','d','e',']','\n','}','\n'};
301 
302  if(function->value_proc) {
303  DWORD name_len;
304  WCHAR *ptr;
305 
306  name_len = strlenW(function->name);
307  str = jsstr_alloc_buf(ARRAY_SIZE(native_prefixW) + ARRAY_SIZE(native_suffixW) + name_len, &ptr);
308  if(!str)
309  return E_OUTOFMEMORY;
310 
311  memcpy(ptr, native_prefixW, sizeof(native_prefixW));
312  memcpy(ptr += ARRAY_SIZE(native_prefixW), function->name, name_len*sizeof(WCHAR));
313  memcpy(ptr + name_len, native_suffixW, sizeof(native_suffixW));
314  }else {
315  str = jsstr_alloc_len(function->func_code->source, function->func_code->source_len);
316  if(!str)
317  return E_OUTOFMEMORY;
318  }
319 
320  *ret = str;
321  return S_OK;
322 }
323 
325 {
326  const BOOL caller_execs_source = (flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE) != 0;
327  FunctionInstance *function;
328 
329  TRACE("func %p this %p\n", func_this, jsthis);
330 
331  assert(is_class(func_this, JSCLASS_FUNCTION));
332  function = function_from_jsdisp(func_this);
333 
335  if(function->value_proc)
336  return invoke_value_proc(function->dispex.ctx, function, jsthis, flags, argc, argv, r);
337 
338  if(flags == DISPATCH_CONSTRUCT) {
339  jsdisp_t *this_obj;
340  HRESULT hres;
341 
342  hres = create_object(function->dispex.ctx, &function->dispex, &this_obj);
343  if(FAILED(hres))
344  return hres;
345 
346  hres = invoke_source(function->dispex.ctx, function, to_disp(this_obj), argc, argv, TRUE, caller_execs_source, r);
347  jsdisp_release(this_obj);
348  return hres;
349  }
350 
352  return invoke_source(function->dispex.ctx, function, jsthis, argc, argv, FALSE, caller_execs_source, r);
353 }
354 
356 {
357  TRACE("%p\n", jsthis);
358 
360  return S_OK;
361 }
362 
364  jsval_t *r)
365 {
366  FunctionInstance *function;
367  jsstr_t *str;
368  HRESULT hres;
369 
370  TRACE("\n");
371 
372  if(!(function = function_this(jsthis)))
374 
375  hres = function_to_string(function, &str);
376  if(FAILED(hres))
377  return hres;
378 
379  if(r)
380  *r = jsval_string(str);
381  else
383  return S_OK;
384 }
385 
386 static HRESULT array_to_args(script_ctx_t *ctx, jsdisp_t *arg_array, unsigned *argc, jsval_t **ret)
387 {
388  jsval_t *argv, val;
389  DWORD length, i;
390  HRESULT hres;
391 
392  hres = jsdisp_propget_name(arg_array, lengthW, &val);
393  if(FAILED(hres))
394  return hres;
395 
396  hres = to_uint32(ctx, val, &length);
398  if(FAILED(hres))
399  return hres;
400 
401  argv = heap_alloc(length * sizeof(*argv));
402  if(!argv)
403  return E_OUTOFMEMORY;
404 
405  for(i=0; i<length; i++) {
406  hres = jsdisp_get_idx(arg_array, i, argv+i);
407  if(hres == DISP_E_UNKNOWNNAME) {
408  argv[i] = jsval_undefined();
409  }else if(FAILED(hres)) {
410  while(i--)
411  jsval_release(argv[i]);
412  heap_free(argv);
413  return hres;
414  }
415  }
416 
417  *argc = length;
418  *ret = argv;
419  return S_OK;
420 }
421 
423 {
424  FunctionInstance *function;
425  jsval_t *args = NULL;
426  unsigned i, cnt = 0;
427  IDispatch *this_obj = NULL;
428  HRESULT hres = S_OK;
429 
430  TRACE("\n");
431 
432  if(!(function = function_this(jsthis)) && (jsthis->flags & VDISP_JSDISP))
434 
435  if(argc) {
436  if(!is_undefined(argv[0]) && !is_null(argv[0])) {
437  hres = to_object(ctx, argv[0], &this_obj);
438  if(FAILED(hres))
439  return hres;
440  }
441  }
442 
443  if(argc >= 2) {
444  jsdisp_t *arg_array = NULL;
445 
446  if(is_object_instance(argv[1])) {
447  arg_array = iface_to_jsdisp(get_object(argv[1]));
448  if(arg_array &&
449  (!is_class(arg_array, JSCLASS_ARRAY) && !is_class(arg_array, JSCLASS_ARGUMENTS) )) {
450  jsdisp_release(arg_array);
451  arg_array = NULL;
452  }
453  }
454 
455  if(arg_array) {
456  hres = array_to_args(ctx, arg_array, &cnt, &args);
457  jsdisp_release(arg_array);
458  }else {
459  FIXME("throw TypeError\n");
460  hres = E_FAIL;
461  }
462  }
463 
464  if(SUCCEEDED(hres)) {
465  if(function) {
466  hres = call_function(ctx, function, this_obj, cnt, args, (flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE) != 0, r);
467  }else {
468  jsval_t res;
469  hres = disp_call_value(ctx, jsthis->u.disp, this_obj, DISPATCH_METHOD, cnt, args, &res);
470  if(SUCCEEDED(hres)) {
471  if(r)
472  *r = res;
473  else
475  }
476  }
477  }
478 
479  if(this_obj)
480  IDispatch_Release(this_obj);
481  for(i=0; i < cnt; i++)
482  jsval_release(args[i]);
483  heap_free(args);
484  return hres;
485 }
486 
487 static HRESULT Function_call(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
488  jsval_t *r)
489 {
490  FunctionInstance *function;
491  IDispatch *this_obj = NULL;
492  unsigned cnt = 0;
493  HRESULT hres;
494 
495  TRACE("\n");
496 
497  if(!(function = function_this(jsthis)))
499 
500  if(argc) {
501  if(!is_undefined(argv[0]) && !is_null(argv[0])) {
502  hres = to_object(ctx, argv[0], &this_obj);
503  if(FAILED(hres))
504  return hres;
505  }
506 
507  cnt = argc-1;
508  }
509 
510  hres = call_function(ctx, function, this_obj, cnt, argv+1, (flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE) != 0, r);
511 
512  if(this_obj)
513  IDispatch_Release(this_obj);
514  return hres;
515 }
516 
518  jsval_t *r)
519 {
520  FunctionInstance *function;
521 
522  TRACE("\n");
523 
524  if(!is_vclass(jsthis, JSCLASS_FUNCTION)) {
525  ERR("dispex is not a function\n");
526  return E_FAIL;
527  }
528 
529  function = function_from_jsdisp(jsthis->u.jsdisp);
530 
531  assert(function->value_proc != NULL);
532  return invoke_value_proc(ctx, function, NULL, flags, argc, argv, r);
533 }
534 
536 {
537  jsstr_t *str;
538  HRESULT hres;
539 
540  TRACE("\n");
541 
543  if(FAILED(hres))
544  return hres;
545 
546  *r = jsval_string(str);
547  return S_OK;
548 }
549 
551 {
552  FunctionInstance *function = function_from_jsdisp(jsthis);
553  call_frame_t *frame;
554  HRESULT hres;
555 
556  TRACE("\n");
557 
558  for(frame = ctx->call_ctx; frame; frame = frame->prev_frame) {
559  if(frame->function_instance == &function->dispex) {
560  if(!frame->arguments_obj) {
561  hres = setup_arguments_object(ctx, frame);
562  if(FAILED(hres))
563  return hres;
564  }
566  return S_OK;
567  }
568  }
569 
570  *r = jsval_null();
571  return S_OK;
572 }
573 
574 static void Function_destructor(jsdisp_t *dispex)
575 {
577 
578  if(This->code)
579  release_bytecode(This->code);
580  if(This->scope_chain)
581  scope_release(This->scope_chain);
582  heap_free(This);
583 }
584 
585 static const builtin_prop_t Function_props[] = {
591 };
592 
599  NULL
600 };
601 
605 };
606 
613  NULL
614 };
615 
616 static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_info, DWORD flags,
617  BOOL funcprot, jsdisp_t *prototype, FunctionInstance **ret)
618 {
619  FunctionInstance *function;
620  HRESULT hres;
621 
622  function = heap_alloc_zero(sizeof(FunctionInstance));
623  if(!function)
624  return E_OUTOFMEMORY;
625 
626  if(funcprot)
627  hres = init_dispex(&function->dispex, ctx, builtin_info, prototype);
628  else if(builtin_info)
629  hres = init_dispex_from_constr(&function->dispex, ctx, builtin_info, ctx->function_constr);
630  else
631  hres = init_dispex_from_constr(&function->dispex, ctx, &FunctionInst_info, ctx->function_constr);
632  if(FAILED(hres)) {
633  heap_free(function);
634  return hres;
635  }
636 
637  function->flags = flags;
638  function->length = flags & PROPF_ARGMASK;
639 
640  *ret = function;
641  return S_OK;
642 }
643 
645  const builtin_info_t *builtin_info, DWORD flags, jsdisp_t *prototype, jsdisp_t **ret)
646 {
647  FunctionInstance *function;
648  HRESULT hres;
649 
650  hres = create_function(ctx, builtin_info, flags, FALSE, NULL, &function);
651  if(FAILED(hres))
652  return hres;
653 
654  if(builtin_info)
655  hres = jsdisp_define_data_property(&function->dispex, lengthW, 0,
656  jsval_number(function->length));
657  if(SUCCEEDED(hres))
658  hres = jsdisp_define_data_property(&function->dispex, prototypeW, 0, jsval_obj(prototype));
659  if(FAILED(hres)) {
660  jsdisp_release(&function->dispex);
661  return hres;
662  }
663 
664  function->value_proc = value_proc;
665  function->name = name;
666 
667  *ret = &function->dispex;
668  return S_OK;
669 }
670 
672 {
673  static const WCHAR constructorW[] = {'c','o','n','s','t','r','u','c','t','o','r',0};
674 
676  jsval_obj(constr));
677 }
678 
680  const builtin_info_t *builtin_info, DWORD flags, jsdisp_t *prototype, jsdisp_t **ret)
681 {
682  jsdisp_t *constr;
683  HRESULT hres;
684 
685  hres = create_builtin_function(ctx, value_proc, name, builtin_info, flags, prototype, &constr);
686  if(FAILED(hres))
687  return hres;
688 
689  hres = set_constructor_prop(ctx, constr, prototype);
690  if(FAILED(hres)) {
691  jsdisp_release(constr);
692  return hres;
693  }
694 
695  *ret = constr;
696  return S_OK;
697 }
698 
700  scope_chain_t *scope_chain, jsdisp_t **ret)
701 {
702  FunctionInstance *function;
703  jsdisp_t *prototype;
704  HRESULT hres;
705 
706  hres = create_object(ctx, NULL, &prototype);
707  if(FAILED(hres))
708  return hres;
709 
710  hres = create_function(ctx, NULL, PROPF_CONSTR, FALSE, NULL, &function);
711  if(SUCCEEDED(hres)) {
713  jsval_obj(prototype));
714  if(SUCCEEDED(hres))
715  hres = set_constructor_prop(ctx, &function->dispex, prototype);
716  if(FAILED(hres))
717  jsdisp_release(&function->dispex);
718  }
719  jsdisp_release(prototype);
720  if(FAILED(hres))
721  return hres;
722 
723  if(scope_chain) {
724  scope_addref(scope_chain);
725  function->scope_chain = scope_chain;
726  }
727 
729  function->code = code;
730  function->func_code = func_code;
731  function->length = function->func_code->param_cnt;
732 
733  *ret = &function->dispex;
734  return S_OK;
735 }
736 
738 {
739  WCHAR *str = NULL, *ptr;
740  unsigned len = 0, i = 0;
741  bytecode_t *code;
742  jsdisp_t *function;
743  jsstr_t **params = NULL;
744  int j = 0;
745  HRESULT hres = S_OK;
746 
747  static const WCHAR function_anonymousW[] = {'f','u','n','c','t','i','o','n',' ','a','n','o','n','y','m','o','u','s','('};
748  static const WCHAR function_beginW[] = {')',' ','{','\n'};
749  static const WCHAR function_endW[] = {'\n','}',0};
750 
751  if(argc) {
752  params = heap_alloc(argc*sizeof(*params));
753  if(!params)
754  return E_OUTOFMEMORY;
755 
756  if(argc > 2)
757  len = (argc-2)*2; /* separating commas */
758  for(i=0; i < argc; i++) {
759  hres = to_string(ctx, argv[i], params+i);
760  if(FAILED(hres))
761  break;
762  len += jsstr_length(params[i]);
763  }
764  }
765 
766  if(SUCCEEDED(hres)) {
767  len += ARRAY_SIZE(function_anonymousW) + ARRAY_SIZE(function_beginW) + ARRAY_SIZE(function_endW);
768  str = heap_alloc(len*sizeof(WCHAR));
769  if(str) {
770  memcpy(str, function_anonymousW, sizeof(function_anonymousW));
771  ptr = str + ARRAY_SIZE(function_anonymousW);
772  if(argc > 1) {
773  while(1) {
774  ptr += jsstr_flush(params[j], ptr);
775  if(++j == argc-1)
776  break;
777  *ptr++ = ',';
778  *ptr++ = ' ';
779  }
780  }
781  memcpy(ptr, function_beginW, sizeof(function_beginW));
782  ptr += ARRAY_SIZE(function_beginW);
783  if(argc)
784  ptr += jsstr_flush(params[argc-1], ptr);
785  memcpy(ptr, function_endW, sizeof(function_endW));
786 
787  TRACE("%s\n", debugstr_w(str));
788  }else {
790  }
791  }
792 
793  while(i)
794  jsstr_release(params[--i]);
795  heap_free(params);
796  if(FAILED(hres))
797  return hres;
798 
799  hres = compile_script(ctx, str, NULL, NULL, FALSE, FALSE, &code);
800  heap_free(str);
801  if(FAILED(hres))
802  return hres;
803 
804  if(code->global_code.func_cnt != 1 || code->global_code.var_cnt != 1) {
805  ERR("Invalid parser result!\n");
807  return E_UNEXPECTED;
808  }
809 
810  hres = create_source_function(ctx, code, code->global_code.funcs, NULL, &function);
812  if(FAILED(hres))
813  return hres;
814 
815  *ret = to_disp(function);
816  return S_OK;
817 }
818 
820  jsval_t *r)
821 {
822  HRESULT hres;
823 
824  TRACE("\n");
825 
826  switch(flags) {
827  case DISPATCH_METHOD:
828  case DISPATCH_CONSTRUCT: {
829  IDispatch *ret;
830 
831  hres = construct_function(ctx, argc, argv, &ret);
832  if(FAILED(hres))
833  return hres;
834 
835  *r = jsval_disp(ret);
836  break;
837  }
838  default:
839  FIXME("unimplemented flags %x\n", flags);
840  return E_NOTIMPL;
841  }
842 
843  return S_OK;
844 }
845 
847  jsval_t *r)
848 {
849  FIXME("\n");
850  return E_NOTIMPL;
851 }
852 
854 {
855  FunctionInstance *prot, *constr;
856  HRESULT hres;
857 
858  static const WCHAR FunctionW[] = {'F','u','n','c','t','i','o','n',0};
859 
860  hres = create_function(ctx, &Function_info, PROPF_CONSTR, TRUE, object_prototype, &prot);
861  if(FAILED(hres))
862  return hres;
863 
865  prot->name = prototypeW;
866 
867  hres = create_function(ctx, &FunctionInst_info, PROPF_CONSTR|1, TRUE, &prot->dispex, &constr);
868  if(SUCCEEDED(hres)) {
870  constr->name = FunctionW;
872  if(SUCCEEDED(hres))
873  hres = set_constructor_prop(ctx, &constr->dispex, &prot->dispex);
874  if(FAILED(hres))
875  jsdisp_release(&constr->dispex);
876  }
877  jsdisp_release(&prot->dispex);
878  if(FAILED(hres))
879  return hres;
880 
881  ctx->function_constr = &constr->dispex;
882  return S_OK;
883 }
HRESULT to_uint32(script_ctx_t *, jsval_t, UINT32 *) DECLSPEC_HIDDEN
Definition: jsutils.c:678
jsstr_t * jsstr_alloc_len(const WCHAR *buf, unsigned len)
Definition: jsstr.c:86
#define PROPF_WRITABLE
Definition: jscript.h:98
Definition: jsval.h:54
jsdisp_t * arguments_obj
Definition: engine.h:233
unsigned arguments_off
Definition: engine.h:238
static void Arguments_destructor(jsdisp_t *jsdisp)
Definition: function.c:82
#define DISP_E_UNKNOWNNAME
Definition: winerror.h:2515
char * name
Definition: wpp.c:36
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
#define TRUE
Definition: types.h:120
static HRESULT invoke_value_proc(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_disp, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: function.c:266
bytecode_t * code
Definition: function.c:34
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
static void set_disp(vdisp_t *vdisp, IDispatch *disp)
Definition: jscript.h:170
static void vdisp_release(vdisp_t *vdisp)
Definition: jscript.h:148
HRESULT setup_arguments_object(script_ctx_t *ctx, call_frame_t *frame)
Definition: function.c:162
#define JS_E_FUNCTION_EXPECTED
Definition: jscript.h:553
Definition: jsstr.h:39
jsdisp_t * jsobj
Definition: engine.h:204
static const WCHAR lengthW[]
Definition: function.c:69
static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *argv, IDispatch **ret)
Definition: function.c:737
static jsval_t jsval_null(void)
Definition: jsval.h:130
static IDispatch * get_object(jsval_t v)
Definition: jsval.h:219
static HRESULT Function_get_arguments(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
Definition: function.c:550
static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_obj, unsigned argc, jsval_t *argv, BOOL is_constructor, BOOL caller_execs_source, jsval_t *r)
Definition: function.c:234
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#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
static HRESULT Function_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: function.c:363
#define PROPF_CONSTR
Definition: jscript.h:95
static void Function_destructor(jsdisp_t *dispex)
Definition: function.c:574
HRESULT create_builtin_constructor(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:679
const WCHAR * name
Definition: function.c:31
scope_chain_t * scope_chain
Definition: function.c:33
DWORD flags
Definition: jscript.h:142
static const WCHAR callW[]
Definition: function.c:72
static BOOL is_undefined(jsval_t v)
Definition: jsval.h:171
static unsigned jsstr_flush(jsstr_t *str, WCHAR *buf)
Definition: jsstr.h:148
static const builtin_prop_t Function_props[]
Definition: function.c:585
#define assert(x)
Definition: debug.h:53
struct _call_frame_t * call_ctx
Definition: jscript.h:410
HRESULT Function_get_value(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
Definition: function.c:535
union vdisp_t::@418 u
static HRESULT Function_call(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: function.c:487
static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_info, DWORD flags, BOOL funcprot, jsdisp_t *prototype, FunctionInstance **ret)
Definition: function.c:616
static unsigned jsstr_length(jsstr_t *str)
Definition: jsstr.h:58
jsdisp_t * function_instance
Definition: engine.h:231
static void jsstr_release(jsstr_t *str)
Definition: jsstr.h:110
function_code_t * function
Definition: engine.h:243
static const WCHAR prototypeW[]
Definition: function.c:67
HRESULT create_source_function(script_ctx_t *ctx, bytecode_t *code, function_code_t *func_code, scope_chain_t *scope_chain, jsdisp_t **ret)
Definition: function.c:699
builtin_invoke_t value_proc
Definition: function.c:30
#define argv
Definition: mplay32.c:18
#define EXEC_RETURN_TO_INTERP
Definition: engine.h:250
#define E_FAIL
Definition: ddrawi.h:102
LONG ref
Definition: jscript.h:229
Definition: match.c:390
#define EXEC_CONSTRUCTOR
Definition: engine.h:249
Definition: send.c:47
IDispatch * host_global
Definition: jscript.h:424
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
#define DISPATCH_METHOD
Definition: oleauto.h:1006
static HRESULT FunctionConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: function.c:819
static const builtin_info_t Arguments_info
Definition: function.c:151
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 scope_chain_t * scope_addref(scope_chain_t *scope)
Definition: engine.h:212
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define DISPATCH_JSCRIPT_INTERNAL_MASK
Definition: jscript.h:113
GLenum const GLfloat * params
Definition: glext.h:5645
static HRESULT Arguments_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: function.c:75
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 const builtin_info_t Function_info
Definition: function.c:593
#define debugstr_w
Definition: kernel32.h:32
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:110
static PVOID ptr
Definition: dispmode.c:27
static HRESULT to_string(VARIANT *src, BSTR *dst)
Definition: host.c:48
unsigned int idx
Definition: utils.c:41
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
jsdisp_t * jsdisp
Definition: jscript.h:140
static BOOL is_object_instance(jsval_t v)
Definition: jsval.h:166
HRESULT compile_script(script_ctx_t *ctx, const WCHAR *code, const WCHAR *args, const WCHAR *delimiter, BOOL from_eval, BOOL use_decode, bytecode_t **ret)
Definition: compile.c:2458
#define PROPF_ARGMASK
Definition: jscript.h:93
static jsval_t jsval_string(jsstr_t *str)
Definition: jsval.h:109
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
static const WCHAR applyW[]
Definition: function.c:71
GLuint GLfloat * val
Definition: glext.h:7180
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
static void set_jsdisp(vdisp_t *vdisp, jsdisp_t *jsdisp)
Definition: jscript.h:163
HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, function_code_t *function, scope_chain_t *scope, IDispatch *this_obj, jsdisp_t *function_instance, jsdisp_t *variable_obj, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: engine.c:2952
#define TRACE(s)
Definition: solgame.cpp:4
static jsval_t jsval_disp(IDispatch *obj)
Definition: jsval.h:117
HRESULT hres
Definition: protocol.c:465
IDispatch * disp
Definition: jscript.h:138
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
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static FunctionInstance * function_this(vdisp_t *jsthis)
Definition: function.c:57
call_frame_t * frame
Definition: function.c:43
static BOOL is_vclass(vdisp_t *vdisp, jsclass_t class)
Definition: jscript.h:502
struct _call_frame_t * frame
Definition: engine.h:206
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
static BOOL is_null(jsval_t v)
Definition: jsval.h:176
static jsdisp_t * jsdisp_addref(jsdisp_t *jsdisp)
Definition: jscript.h:258
SCRIPTSTATE state
Definition: jscript.h:407
static HRESULT array_to_args(script_ctx_t *ctx, jsdisp_t *arg_array, unsigned *argc, jsval_t **ret)
Definition: function.c:386
jsdisp_t dispex
Definition: function.c:29
GLbitfield flags
Definition: glext.h:7161
jsdisp_t * object_constr
Definition: jscript.h:450
static HRESULT set_constructor_prop(script_ctx_t *ctx, jsdisp_t *constr, jsdisp_t *prot)
Definition: function.c:671
HRESULT Function_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: function.c:517
unsigned param_cnt
Definition: engine.h:163
int ret
static HRESULT Arguments_idx_put(jsdisp_t *jsdisp, unsigned idx, jsval_t val)
Definition: function.c:128
static HRESULT call_function(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_obj, unsigned argc, jsval_t *argv, BOOL caller_execs_source, jsval_t *r)
Definition: function.c:285
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
int code
Definition: i386-dis.c:3591
jsval_t * stack
Definition: jscript.h:426
#define DEFAULT_FUNCTION_VALUE
Definition: jscript.h:310
static IDispatch * to_disp(jsdisp_t *jsdisp)
Definition: jscript.h:241
function_code_t * func_code
Definition: function.c:35
struct _call_frame_t * prev_frame
Definition: engine.h:245
static FunctionInstance * function_from_jsdisp(jsdisp_t *jsdisp)
Definition: function.c:47
unsigned argc
Definition: function.c:44
#define ERR(fmt,...)
Definition: debug.h:109
scope_chain_t * base_scope
Definition: engine.h:226
jsdisp_t * iface_to_jsdisp(IDispatch *iface)
Definition: dispex.c:1081
HRESULT init_function_constr(script_ctx_t *ctx, jsdisp_t *object_prototype)
Definition: function.c:853
static jsval_t jsval_undefined(void)
Definition: jsval.h:137
static const builtin_prop_t FunctionInst_props[]
Definition: function.c:602
#define S_OK
Definition: intsafe.h:59
jsdisp_t * function_constr
Definition: jscript.h:437
static const WCHAR argumentsW[]
Definition: function.c:73
#define PROPF_METHOD
Definition: jscript.h:94
static HRESULT Arguments_idx_get(jsdisp_t *jsdisp, unsigned idx, jsval_t *r)
Definition: function.c:114
#define ARRAY_SIZE(a)
Definition: main.h:24
static HRESULT Function_get_length(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
Definition: function.c:355
static const WCHAR FunctionW[]
Definition: global.c:44
#define DISPATCH_JSCRIPT_CALLEREXECSSOURCE
Definition: jscript.h:112
static jsval_t * get_argument_ref(ArgumentsInstance *arguments, unsigned idx)
Definition: function.c:105
jsval_t * buf
Definition: function.c:42
HRESULT jsdisp_get_idx(jsdisp_t *obj, DWORD idx, jsval_t *r)
Definition: dispex.c:1446
#define E_NOTIMPL
Definition: ddrawi.h:99
HRESULT create_dispex(script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype, jsdisp_t **dispex)
Definition: dispex.c:978
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
static void jsdisp_release(jsdisp_t *jsdisp)
Definition: jscript.h:264
HRESULT Function_invoke(jsdisp_t *func_this, IDispatch *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: function.c:324
jsdisp_t * global
Definition: jscript.h:436
static ArgumentsInstance * arguments_from_jsdisp(jsdisp_t *jsdisp)
Definition: function.c:62
HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype)
Definition: dispex.c:940
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
#define E_UNEXPECTED
Definition: winerror.h:2456
jsstr_t * jsstr_alloc_buf(unsigned len, WCHAR **buf)
Definition: jsstr.c:69
void release_bytecode(bytecode_t *code)
Definition: compile.c:2223
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 jsdisp
Definition: function.c:40
HRESULT to_object(script_ctx_t *, jsval_t, IDispatch **) DECLSPEC_HIDDEN
Definition: jsutils.c:808
GLuint res
Definition: glext.h:9613
HRESULT jsdisp_propput_name(jsdisp_t *obj, const WCHAR *name, jsval_t val)
Definition: dispex.c:1365
static FunctionInstance * function_from_vdisp(vdisp_t *vdisp)
Definition: function.c:52
HRESULT create_object(script_ctx_t *, jsdisp_t *, jsdisp_t **) DECLSPEC_HIDDEN
Definition: object.c:597
HRESULT throw_type_error(script_ctx_t *ctx, HRESULT error, const WCHAR *str)
Definition: error.c:438
void detach_arguments_object(jsdisp_t *args_disp)
Definition: function.c:199
#define VDISP_JSDISP
Definition: jscript.h:146
WINE_DEFAULT_DEBUG_CHANNEL(jscript)
BSTR * params
Definition: engine.h:164
unsigned argc
Definition: engine.h:236
void scope_release(scope_chain_t *scope)
Definition: engine.c:435
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 const WCHAR toStringW[]
Definition: function.c:70
#define args
Definition: format.c:66
FunctionInstance * function
Definition: function.c:41
#define PROPF_CONFIGURABLE
Definition: jscript.h:99
static unsigned Arguments_idx_length(jsdisp_t *jsdisp)
Definition: function.c:99
#define SUCCEEDED(hr)
Definition: intsafe.h:57
HRESULT(* builtin_invoke_t)(script_ctx_t *, vdisp_t *, WORD, unsigned, jsval_t *, jsval_t *)
Definition: jscript.h:200
static jsval_t jsval_number(double n)
Definition: jsval.h:144
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
static bytecode_t * bytecode_addref(bytecode_t *code)
Definition: engine.h:196
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
static HRESULT function_to_string(FunctionInstance *function, jsstr_t **ret)
Definition: function.c:294
static HRESULT Function_apply(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: function.c:422
static const builtin_info_t FunctionInst_info
Definition: function.c:607
static HRESULT FunctionProt_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: function.c:846
GLuint const GLchar * name
Definition: glext.h:6031