ReactOS 0.4.17-dev-357-ga8f14ff
engine.c
Go to the documentation of this file.
1/*
2 * Copyright 2008,2011 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#ifdef __REACTOS__
20#include <wine/config.h>
21#include <wine/port.h>
22#endif
23
24#include <math.h>
25#include <assert.h>
26
27#include "jscript.h"
28#include "engine.h"
29
30#include "wine/debug.h"
31
33
35 unsigned stack_top;
37 unsigned catch_off;
38 unsigned finally_off;
39
41};
42
43typedef struct {
44 enum {
48 EXPRVAL_INVALID
50 union {
52 struct {
55 } idref;
56 unsigned off;
58 } u;
59} exprval_t;
60
61static const size_t stack_size = 0x40000;
62
64{
65 if(ctx->stack_top == stack_size)
67
68 ctx->stack[ctx->stack_top++] = v;
69 return S_OK;
70}
71
73{
74 jsstr_t *v;
75
76 v = jsstr_alloc(str);
77 if(!v)
78 return E_OUTOFMEMORY;
79
80 return stack_push(ctx, jsval_string(v));
81}
82
84{
85 assert(ctx->stack_top > ctx->call_ctx->stack_base);
86 return ctx->stack[ctx->stack_top-1];
87}
88
89static inline jsval_t *stack_top_ref(script_ctx_t *ctx, unsigned n)
90{
91 assert(ctx->stack_top > ctx->call_ctx->stack_base+n);
92 return ctx->stack+ctx->stack_top-1-n;
93}
94
95static inline jsval_t stack_topn(script_ctx_t *ctx, unsigned n)
96{
97 return *stack_top_ref(ctx, n);
98}
99
100static inline jsval_t *stack_args(script_ctx_t *ctx, unsigned n)
101{
102 if(!n)
103 return NULL;
104 assert(ctx->stack_top > ctx->call_ctx->stack_base+n-1);
105 return ctx->stack + ctx->stack_top-n;
106}
107
109{
110 assert(ctx->stack_top > ctx->call_ctx->stack_base);
111 return ctx->stack[--ctx->stack_top];
112}
113
114static void stack_popn(script_ctx_t *ctx, unsigned n)
115{
116 while(n--)
118}
119
121{
122 jsval_t v;
124
125 v = stack_pop(ctx);
126 hres = to_number(ctx, v, r);
128 return hres;
129}
130
132{
133 jsval_t v;
135
136 v = stack_pop(ctx);
137 if(is_object_instance(v)) {
138 *r = get_object(v);
139 return S_OK;
140 }
141
142 hres = to_object(ctx, v, r);
144 return hres;
145}
146
148{
149 return to_int32(ctx, stack_pop(ctx), r);
150}
151
153{
154 return to_uint32(ctx, stack_pop(ctx), r);
155}
156
157static inline unsigned local_off(call_frame_t *frame, int ref)
158{
159 return ref < 0
160 ? frame->arguments_off - ref-1
161 : frame->variables_off + ref;
162}
163
164static inline BSTR local_name(call_frame_t *frame, int ref)
165{
166 return ref < 0 ? frame->function->params[-ref-1] : frame->function->variables[ref].name;
167}
168
170{
171 struct vars_buffer *detached_vars = scope->detached_vars;
173
174 if(!detached_vars)
175 return NULL;
176 ref = lookup_local(detached_vars->func_code, name, scope->scope_index);
177 return ref && ref->ref < 0 ? &detached_vars->var[-ref->ref - 1] : NULL;
178}
179
181{
182 jsval_t *var_ref = get_detached_var_ref(scope, name);
183 return var_ref ? jsdisp_get_idx_id(&scope->dispex, var_ref - scope->detached_vars->var, id) : DISP_E_UNKNOWNNAME;
184}
185
186/* Steals input reference even on failure. */
188{
190
191 switch(val->type) {
192 case EXPRVAL_JSVAL:
194 if(SUCCEEDED(hres))
195 hres = stack_push(ctx, val->u.val);
196 return hres;
197 case EXPRVAL_IDREF:
198 hres = stack_push(ctx, jsval_disp(val->u.idref.disp));
199 if(SUCCEEDED(hres))
200 hres = stack_push(ctx, jsval_number(val->u.idref.id));
201 else
202 IDispatch_Release(val->u.idref.disp);
203 return hres;
204 case EXPRVAL_STACK_REF:
205 hres = stack_push(ctx, jsval_number(val->u.off));
206 if(SUCCEEDED(hres))
208 return hres;
209 case EXPRVAL_INVALID:
211 if(SUCCEEDED(hres))
212 hres = stack_push(ctx, jsval_number(val->u.hres));
213 return hres;
214 }
215
216 assert(0);
217 return E_FAIL;
218}
219
221{
222 jsval_t v = stack_topn(ctx, n+1);
223
224 switch(jsval_type(v)) {
225 case JSV_NUMBER: {
226 call_frame_t *frame = ctx->call_ctx;
227 scope_chain_t *scope;
228 unsigned off = get_number(v);
229
230 if(!frame->base_scope->frame && off >= frame->arguments_off) {
231 jsdisp_t *jsobj;
232 DISPID id;
233 BSTR name;
235
236 /* Got stack reference in deoptimized code. Need to convert it back to variable object reference. */
237
238 assert(off < frame->variables_off + frame->function->var_cnt);
239 if (off >= frame->variables_off)
240 {
241 name = frame->function->variables[off - frame->variables_off].name;
242 scope = frame->scope;
243 }
244 else
245 {
246 name = frame->function->params[off - frame->arguments_off];
247 scope = frame->base_scope;
248 }
249
250 while (1)
251 {
252 hres = get_detached_var_dispid(scope, name, &id);
254 {
255 if (FAILED(hres))
256 {
257 r->type = EXPRVAL_INVALID;
258 r->u.hres = hres;
259 return FALSE;
260 }
261 jsobj = &scope->dispex;
262 break;
263 }
264 if ((jsobj = to_jsdisp(scope->obj)) && SUCCEEDED(hres = jsdisp_get_id(jsobj, name, 0, &id)))
265 break;
266 if (scope == frame->base_scope)
267 {
268 r->type = EXPRVAL_INVALID;
269 r->u.hres = hres;
270 return FALSE;
271 }
272 scope = scope->next;
273 }
274
277 r->type = EXPRVAL_IDREF;
278 r->u.idref.disp = to_disp(jsobj);
279 r->u.idref.id = id;
280 return TRUE;
281 }
282
283 r->type = EXPRVAL_STACK_REF;
284 r->u.off = off;
285 return TRUE;
286 }
287 case JSV_OBJECT:
288 r->type = EXPRVAL_IDREF;
289 r->u.idref.disp = get_object(v);
291 r->u.idref.id = get_number(stack_topn(ctx, n));
292 return TRUE;
293 case JSV_UNDEFINED:
294 r->type = EXPRVAL_INVALID;
296 r->u.hres = get_number(stack_topn(ctx, n));
297 return FALSE;
298 case JSV_NULL:
299 r->type = EXPRVAL_JSVAL;
300 r->u.val = stack_topn(ctx, n);
301 return TRUE;
302 default:
303 assert(0);
304 return FALSE;
305 }
306}
307
309{
311 ctx->stack_top -= 2;
312 return ret;
313}
314
316{
317 switch(ref->type) {
318 case EXPRVAL_STACK_REF: {
319 jsval_t *r = ctx->stack + ref->u.off;
321 return jsval_copy(v, r);
322 }
323 case EXPRVAL_IDREF:
324 return disp_propput(ctx, ref->u.idref.disp, ref->u.idref.id, v);
325 case EXPRVAL_JSVAL:
326 WARN("ignoring an attempt to set value reference\n");
327 return S_OK;
328 default:
329 assert(0);
330 return E_FAIL;
331 }
332}
333
335{
336 switch(ref->type) {
337 case EXPRVAL_STACK_REF:
338 return jsval_copy(ctx->stack[ref->u.off], r);
339 case EXPRVAL_IDREF:
340 return disp_propget(ctx, ref->u.idref.disp, ref->u.idref.id, r);
341 case EXPRVAL_JSVAL:
342 return jsval_copy(ref->u.val, r);
343 default:
344 assert(0);
345 return E_FAIL;
346 }
347}
348
350{
351 jsdisp_t *jsdisp;
353 jsval_t v;
354
355 switch(ref->type) {
356 case EXPRVAL_STACK_REF: {
357 v = ctx->stack[ref->u.off];
358
359 if(!is_object_instance(v)) {
360 FIXME("invoke %s\n", debugstr_jsval(v));
361 return E_FAIL;
362 }
363
365 }
366 case EXPRVAL_IDREF:
367 /* ECMA-262 3rd Edition 11.2.3.7 / ECMA-262 5.1 Edition 11.2.3.6 *
368 * Don't treat scope object props as PropertyReferences. */
369 if((jsdisp = to_jsdisp(ref->u.idref.disp)) && jsdisp->builtin_info->class == JSCLASS_NONE) {
370 hres = disp_propget(ctx, ref->u.idref.disp, ref->u.idref.id, &v);
371 if(FAILED(hres))
372 return hres;
373 if(!is_object_instance(v)) {
374 FIXME("invoke %s\n", debugstr_jsval(v));
375 hres = E_FAIL;
376 }else {
378 }
380 return hres;
381 }
382 return disp_call(ctx, ref->u.idref.disp, ref->u.idref.id, flags, argc, argv, r);
383 case EXPRVAL_JSVAL: {
384 IDispatch *obj;
385
386 hres = to_object(ctx, ref->u.val, &obj);
387 if(SUCCEEDED(hres)) {
389 IDispatch_Release(obj);
390 }
391 return hres;
392 }
393 default:
394 assert(0);
395 return E_FAIL;
396 }
397}
398
399/* ECMA-262 3rd Edition 8.7.1 */
400/* Steals input reference. */
402{
404
405 if(ref->type == EXPRVAL_JSVAL) {
406 *r = ref->u.val;
407 return S_OK;
408 }
409
411
412 if(ref->type == EXPRVAL_IDREF)
413 IDispatch_Release(ref->u.idref.disp);
414 return hres;
415}
416
418{
419 switch(val->type) {
420 case EXPRVAL_JSVAL:
421 jsval_release(val->u.val);
422 return;
423 case EXPRVAL_IDREF:
424 if(val->u.idref.disp)
425 IDispatch_Release(val->u.idref.disp);
426 return;
427 case EXPRVAL_STACK_REF:
428 case EXPRVAL_INVALID:
429 return;
430 }
431}
432
434{
435 val->type = EXPRVAL_INVALID;
436 val->u.hres = hres;
437}
438
440{
441 ref->type = EXPRVAL_IDREF;
442#ifdef __REACTOS__
443 ref->u.idref.disp = obj;
444 IDispatch_AddRef(obj);
445#else
446 IDispatch_AddRef(ref->u.idref.disp = obj);
447#endif
448 ref->u.idref.id = id;
449}
450
451static inline jsval_t steal_ret(call_frame_t *frame)
452{
453 jsval_t r = frame->ret;
454 frame->ret = jsval_undefined();
455 return r;
456}
457
458static inline void clear_acc(script_ctx_t *ctx)
459{
460 jsval_release(ctx->acc);
461 ctx->acc = jsval_undefined();
462}
463
465{
466 return CONTAINING_RECORD(dispex, scope_chain_t, dispex);
467}
468
469static void scope_destructor(jsdisp_t *dispex)
470{
471 scope_chain_t *scope = scope_from_dispex(dispex);
472
473 if(scope->detached_vars) {
474 struct vars_buffer *vars = scope->detached_vars;
475 unsigned i, cnt = vars->argc;
476
478 for(i = 0; i < cnt; i++)
479 jsval_release(vars->var[i]);
480 free(vars);
481 }
482
483 if(scope->next)
484 scope_release(scope->next);
485
486 if(scope->obj)
487 IDispatch_Release(scope->obj);
488}
489
490static HRESULT scope_lookup_prop(jsdisp_t *jsdisp, const WCHAR *name, unsigned flags, struct property_info *desc)
491{
492 scope_chain_t *scope = scope_from_dispex(jsdisp);
493
494 return jsdisp_index_lookup(&scope->dispex, name, scope->detached_vars->argc, desc);
495}
496
497static HRESULT scope_prop_get(jsdisp_t *dispex, unsigned idx, jsval_t *r)
498{
499 scope_chain_t *scope = scope_from_dispex(dispex);
500
501 return jsval_copy(scope->detached_vars->var[idx], r);
502}
503
504static HRESULT scope_prop_put(jsdisp_t *dispex, unsigned idx, jsval_t val)
505{
506 scope_chain_t *scope = scope_from_dispex(dispex);
507 jsval_t copy, *ref;
509
510 hres = jsval_copy(val, &copy);
511 if(FAILED(hres))
512 return hres;
513
514 ref = &scope->detached_vars->var[idx];
516 *ref = copy;
517 return S_OK;
518}
519
521{
522 scope_chain_t *scope = scope_from_dispex(dispex);
523 jsdisp_t *jsobj;
525
526 if(scope->detached_vars) {
527 struct vars_buffer *vars = scope->detached_vars;
528 unsigned i, cnt = vars->argc;
529
530 for(i = 0; i < cnt; i++) {
531 hres = gc_process_linked_val(gc_ctx, op, dispex, &vars->var[i]);
532 if(FAILED(hres))
533 return hres;
534 }
535 }
536
537 if(scope->next) {
538 hres = gc_process_linked_obj(gc_ctx, op, dispex, &scope->next->dispex, (void**)&scope->next);
539 if(FAILED(hres))
540 return hres;
541 }
542
543 if(op == GC_TRAVERSE_UNLINK) {
544 IDispatch *obj = scope->obj;
545 if(obj) {
546 scope->obj = NULL;
547 IDispatch_Release(obj);
548 }
549 return S_OK;
550 }
551
552 return scope->obj && (jsobj = to_jsdisp(scope->obj)) ? gc_process_linked_obj(gc_ctx, op, dispex, jsobj, (void**)&scope->obj) : S_OK;
553}
554
557 .destructor = scope_destructor,
558 .lookup_prop = scope_lookup_prop,
559 .prop_get = scope_prop_get,
560 .prop_put = scope_prop_put,
561 .gc_traverse = scope_gc_traverse
562};
563
565{
566 scope_chain_t *new_scope;
568
569 new_scope = calloc(1, sizeof(scope_chain_t));
570 if(!new_scope)
571 return E_OUTOFMEMORY;
572
573 hres = init_dispex(&new_scope->dispex, ctx, &scope_info, NULL);
574 if(FAILED(hres)) {
575 free(new_scope);
576 return hres;
577 }
578
579 if (obj)
580 IDispatch_AddRef(obj);
581 new_scope->obj = obj;
582 new_scope->frame = NULL;
583 new_scope->next = scope ? scope_addref(scope) : NULL;
584 new_scope->scope_index = 0;
585
586 *ret = new_scope;
587 return S_OK;
588}
589
590static void scope_pop(scope_chain_t **scope)
591{
592 scope_chain_t *tmp;
593
594 tmp = *scope;
595 *scope = tmp->next;
596 scope_release(tmp);
597}
598
599static HRESULT disp_get_id(script_ctx_t *ctx, IDispatch *disp, const WCHAR *name, BSTR name_bstr, DWORD flags, DISPID *id)
600{
601 IDispatchEx *dispex;
602 jsdisp_t *jsdisp;
603 BSTR bstr;
605
606 jsdisp = to_jsdisp(disp);
607 if(jsdisp)
608 return jsdisp_get_id(jsdisp, name, flags, id);
609
610 if(name_bstr) {
611 bstr = name_bstr;
612 }else {
613 bstr = SysAllocString(name);
614 if(!bstr)
615 return E_OUTOFMEMORY;
616 }
617
618 *id = 0;
619 hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
620 if(SUCCEEDED(hres)) {
621 hres = IDispatchEx_GetDispID(dispex, bstr, make_grfdex(ctx, flags|fdexNameCaseSensitive), id);
622 IDispatchEx_Release(dispex);
623 }else {
624 TRACE("using IDispatch\n");
625 hres = IDispatch_GetIDsOfNames(disp, &IID_NULL, &bstr, 1, 0, id);
626 }
627
628 if(name_bstr != bstr)
629 SysFreeString(bstr);
630 return hres;
631}
632
633static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, BOOL *ret)
634{
636 IUnknown *unk1, *unk2;
638
639 if(disp1 == disp2) {
640 *ret = TRUE;
641 return S_OK;
642 }
643
644 if(!disp1 || !disp2) {
645 *ret = FALSE;
646 return S_OK;
647 }
648
649 unk1 = (IUnknown *)get_host_dispatch(disp1);
650 if(!unk1) {
651 hres = IDispatch_QueryInterface(disp1, &IID_IUnknown, (void**)&unk1);
652 if(FAILED(hres))
653 return hres;
654 }
655
656 unk2 = (IUnknown *)get_host_dispatch(disp2);
657 if(!unk2) {
658 hres = IDispatch_QueryInterface(disp2, &IID_IUnknown, (void**)&unk2);
659 if(FAILED(hres)) {
660 IUnknown_Release(unk1);
661 return hres;
662 }
663 }
664
665 if(unk1 == unk2) {
666 *ret = TRUE;
667 }else {
668 hres = IUnknown_QueryInterface(unk1, &IID_IObjectIdentity, (void**)&identity);
669 if(SUCCEEDED(hres)) {
670 hres = IObjectIdentity_IsEqualObject(identity, unk2);
671 IObjectIdentity_Release(identity);
672 *ret = hres == S_OK;
673 }else {
674 *ret = FALSE;
675 }
676 }
677
678 IUnknown_Release(unk1);
679 IUnknown_Release(unk2);
680 return S_OK;
681}
682
683/* ECMA-262 3rd Edition 11.9.6 */
685{
687
688 TRACE("\n");
689
690 if(type != jsval_type(rval)) {
691 *ret = FALSE;
692 return S_OK;
693 }
694
695 switch(type) {
696 case JSV_UNDEFINED:
697 case JSV_NULL:
698 *ret = TRUE;
699 break;
700 case JSV_OBJECT:
701 return disp_cmp(get_object(lval), get_object(rval), ret);
702 case JSV_STRING:
704 break;
705 case JSV_NUMBER:
706 *ret = get_number(lval) == get_number(rval);
707 break;
708 case JSV_BOOL:
709 *ret = !get_bool(lval) == !get_bool(rval);
710 break;
711 case JSV_VARIANT:
712 WARN("VARIANT type, returning false\n");
713 *ret = FALSE;
714 return S_OK;
715 }
716
717 return S_OK;
718}
719
721{
722 function_code_t *func = frame->function;
723 unsigned i, argc;
724
725 argc = (scope == frame->base_scope) ? max(frame->argc, func->param_cnt) : 0;
726 if(!argc)
727 return S_OK;
728
729 if(!(scope->detached_vars = malloc(FIELD_OFFSET(struct vars_buffer, var[argc]))))
730 return E_OUTOFMEMORY;
731 scope->detached_vars->argc = argc;
732 scope->detached_vars->func_code = func;
733 bytecode_addref(func->bytecode);
734
735 for(i = 0; i < argc; i++) {
736 scope->detached_vars->var[i] = ctx->stack[frame->arguments_off + i];
737 ctx->stack[frame->arguments_off + i] = jsval_undefined();
738 }
739
740 return S_OK;
741}
742
744{
745 function_code_t *func = frame->function;
746 unsigned int i, index;
747 jsdisp_t *jsobj;
749
750 if (!scope->frame)
751 return S_OK;
752
753 assert(scope->frame == frame);
754 scope->frame = NULL;
755
756 hres = alloc_detached_vars(ctx, frame, scope);
757 if (FAILED(hres))
758 return hres;
759
760 if (!scope->obj)
761 {
762 if (FAILED(hres = create_dispex(ctx, NULL, NULL, &jsobj)))
763 return hres;
764 scope->obj = to_disp(jsobj);
765 }
766 else
767 jsobj = as_jsdisp(scope->obj);
768
769 if (scope == frame->base_scope && func->name && func->local_ref == INVALID_LOCAL_REF &&
770 ctx->version >= SCRIPTLANGUAGEVERSION_ES5)
772
773 index = scope->scope_index;
774 for(i = 0; i < frame->function->local_scopes[index].locals_cnt; i++)
775 {
777 int ref = frame->function->local_scopes[index].locals[i].ref;
778
779 if (ref < 0)
780 continue;
781 if (FAILED(hres = jsdisp_propput_name(jsobj, name, ctx->stack[local_off(frame, ref)])))
782 return hres;
783 if (scope != frame->base_scope && frame->function->variables[ref].func_id != -1
784 && FAILED(hres = jsdisp_propput_name(frame->variable_obj, name, ctx->stack[local_off(frame, ref)])))
785 return hres;
786 }
787 return S_OK;
788}
789
791{
793
794 if (scope != frame->base_scope && FAILED(hres = detach_scope_chain(ctx, frame, scope->next)))
795 return hres;
796 return detach_scope(ctx, frame, scope);
797}
798
799/*
800 * Transfers local variables from stack to variable object.
801 * It's slow, so we want to avoid it as much as possible.
802 */
804{
806
807 if(!frame->base_scope || !frame->base_scope->frame)
808 return S_OK;
809
810 TRACE("detaching %p\n", frame);
811
812 assert(frame == frame->base_scope->frame);
813 assert(to_disp(frame->variable_obj) == frame->base_scope->obj);
814
815 if(!from_release && !frame->arguments_obj) {
817 if(FAILED(hres))
818 return hres;
819 }
820
821 TRACE("detaching scope chain %p, frame %p.\n", ctx->call_ctx->scope, frame);
822 return detach_scope_chain(ctx, frame, ctx->call_ctx->scope);
823}
824
826{
828 DISPID id;
830
831 LIST_FOR_EACH_ENTRY(item, &ctx->named_items, named_item_t, entry) {
832 if(item->flags & SCRIPTITEM_GLOBALMEMBERS) {
833 hres = disp_get_id(ctx, item->disp, identifier, identifier, 0, &id);
834 if(SUCCEEDED(hres)) {
835 if(ret)
836 exprval_set_disp_ref(ret, item->disp, id);
837 return TRUE;
838 }
839 }
840 }
841
842 return FALSE;
843}
844
846{
847 IDispatch *disp = NULL;
849
850 LIST_FOR_EACH_ENTRY(item, &ctx->named_items, named_item_t, entry) {
851 if(!(item->flags & SCRIPTITEM_GLOBALMEMBERS)) continue;
852 disp = item->disp;
853 break;
854 }
855 if(!disp) disp = to_disp(ctx->global);
856
857 return disp;
858}
859
860static int __cdecl local_ref_cmp(const void *key, const void *ref)
861{
862 return wcscmp((const WCHAR*)key, ((const local_ref_t*)ref)->name);
863}
864
865local_ref_t *lookup_local(const function_code_t *function, const WCHAR *identifier, unsigned int scope)
866{
867 return bsearch(identifier, function->local_scopes[scope].locals, function->local_scopes[scope].locals_cnt,
868 sizeof(*function->local_scopes[scope].locals), local_ref_cmp);
869}
870
871/* ECMA-262 3rd Edition 10.1.4 */
873{
874 scope_chain_t *scope;
876 DISPID id = 0;
878
879 TRACE("%s\n", debugstr_w(identifier));
880
881 if(ctx->call_ctx) {
882 for(scope = ctx->call_ctx->scope; scope; scope = scope->next) {
883 if(scope->frame) {
884 function_code_t *func = scope->frame->function;
885 local_ref_t *ref = lookup_local(func, identifier, scope->scope_index);
886
887 if(ref) {
888 ret->type = EXPRVAL_STACK_REF;
889 ret->u.off = local_off(scope->frame, ref->ref);
890 TRACE("returning ref %d for %d\n", ret->u.off, ref->ref);
891 return S_OK;
892 }
893
894 if(!wcscmp(identifier, L"arguments")) {
896 if(FAILED(hres))
897 return hres;
898 }
899
900 /* ECMA-262 5.1 Edition 13 */
901 if(func->name && ctx->version >= SCRIPTLANGUAGEVERSION_ES5 &&
902 func->local_ref == INVALID_LOCAL_REF && !wcscmp(identifier, func->name)) {
903 TRACE("returning a function from scope chain\n");
904 ret->type = EXPRVAL_JSVAL;
905 ret->u.val = jsval_obj(jsdisp_addref(scope->frame->function_instance));
906 return S_OK;
907 }
908 }else if((hres = get_detached_var_dispid(scope, identifier, &id)) != DISP_E_UNKNOWNNAME) {
909 if(SUCCEEDED(hres))
910 exprval_set_disp_ref(ret, to_disp(&scope->dispex), id);
911 return hres;
912 }
913
914 if (!scope->obj)
915 continue;
916
917 hres = disp_get_id(ctx, scope->obj, identifier, identifier, fdexNameImplicit, &id);
918 if(SUCCEEDED(hres)) {
919 exprval_set_disp_ref(ret, scope->obj, id);
920 return S_OK;
921 }
922 }
923
924 item = ctx->call_ctx->bytecode->named_item;
925 if(item) {
926 hres = jsdisp_get_id(item->script_obj, identifier, 0, &id);
927 if(SUCCEEDED(hres)) {
928 exprval_set_disp_ref(ret, to_disp(item->script_obj), id);
929 return S_OK;
930 }
931 if(!(item->flags & SCRIPTITEM_CODEONLY)) {
932 hres = disp_get_id(ctx, item->disp, identifier, identifier, 0, &id);
933 if(SUCCEEDED(hres)) {
934 exprval_set_disp_ref(ret, item->disp, id);
935 return S_OK;
936 }
937 }
938 }
939 }
940
941 hres = jsdisp_get_id(ctx->global, identifier, 0, &id);
942 if(SUCCEEDED(hres)) {
943 exprval_set_disp_ref(ret, to_disp(ctx->global), id);
944 return S_OK;
945 }
946
947 item = lookup_named_item(ctx, identifier, SCRIPTITEM_ISVISIBLE);
948 if(item) {
949 IDispatch_AddRef(item->disp);
950 ret->type = EXPRVAL_JSVAL;
951 ret->u.val = jsval_disp(item->disp);
952 return S_OK;
953 }
954
955 if(lookup_global_members(ctx, identifier, ret))
956 return S_OK;
957
959 return S_OK;
960}
961
962static inline BSTR get_op_bstr(script_ctx_t *ctx, int i)
963{
964 call_frame_t *frame = ctx->call_ctx;
965 return frame->bytecode->instrs[frame->ip].u.arg[i].bstr;
966}
967
968static inline unsigned get_op_uint(script_ctx_t *ctx, int i)
969{
970 call_frame_t *frame = ctx->call_ctx;
971 return frame->bytecode->instrs[frame->ip].u.arg[i].uint;
972}
973
974static inline unsigned get_op_int(script_ctx_t *ctx, int i)
975{
976 call_frame_t *frame = ctx->call_ctx;
977 return frame->bytecode->instrs[frame->ip].u.arg[i].lng;
978}
979
980static inline jsstr_t *get_op_str(script_ctx_t *ctx, int i)
981{
982 call_frame_t *frame = ctx->call_ctx;
983 return frame->bytecode->instrs[frame->ip].u.arg[i].str;
984}
985
986static inline double get_op_double(script_ctx_t *ctx)
987{
988 call_frame_t *frame = ctx->call_ctx;
989 return frame->bytecode->instrs[frame->ip].u.dbl;
990}
991
992static inline void jmp_next(script_ctx_t *ctx)
993{
994 ctx->call_ctx->ip++;
995}
996
997static inline void jmp_abs(script_ctx_t *ctx, unsigned dst)
998{
999 ctx->call_ctx->ip = dst;
1000}
1001
1002/* ECMA-262 3rd Edition 12.6.4 */
1004{
1005 const HRESULT arg = get_op_uint(ctx, 0);
1006 IDispatch *obj = NULL;
1007 IDispatchEx *dispex;
1008 exprval_t prop_ref;
1009 DISPID id;
1010 BSTR name = NULL;
1011 HRESULT hres;
1012
1013 TRACE("\n");
1014
1016 id = get_number(stack_top(ctx));
1017
1018 if(!stack_topn_exprval(ctx, 1, &prop_ref)) {
1019 FIXME("invalid ref: %08lx\n", prop_ref.u.hres);
1020 return E_FAIL;
1021 }
1022
1025
1026 if(obj) {
1027 hres = IDispatch_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex);
1028 if(SUCCEEDED(hres)) {
1029 hres = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, id, &id);
1030 if(hres == S_OK)
1031 hres = IDispatchEx_GetMemberName(dispex, id, &name);
1032 IDispatchEx_Release(dispex);
1033 if(FAILED(hres))
1034 return hres;
1035 }else {
1036 TRACE("No IDispatchEx\n");
1037 }
1038 }
1039
1040 if(name) {
1041 jsstr_t *str;
1042
1045 if(!str)
1046 return E_OUTOFMEMORY;
1047
1048 stack_pop(ctx);
1049 stack_push(ctx, jsval_number(id)); /* safe, just after pop() */
1050
1051 hres = exprval_propput(ctx, &prop_ref, jsval_string(str));
1053 if(FAILED(hres))
1054 return hres;
1055
1056 jmp_next(ctx);
1057 }else {
1058 stack_popn(ctx, 4);
1059 jmp_abs(ctx, arg);
1060 }
1061 return S_OK;
1062}
1063
1065{
1066 call_frame_t *frame = ctx->call_ctx;
1067 unsigned int i, off, index;
1068 scope_chain_t *scope;
1069 BOOL detached_vars;
1070 jsdisp_t *jsobj;
1071 HRESULT hres;
1072
1073 scope = frame->scope;
1074 index = scope->scope_index;
1075 detached_vars = !(frame->base_scope && frame->base_scope->frame);
1076
1077 if (!detached_vars)
1078 {
1079 assert(frame->base_scope->frame == frame);
1080 frame->scope->frame = ctx->call_ctx;
1081 }
1082 else if (!scope->obj)
1083 {
1084 if (FAILED(hres = create_dispex(ctx, NULL, NULL, &jsobj)))
1085 return hres;
1086 scope->obj = to_disp(jsobj);
1087 }
1088 else
1089 jsobj = as_jsdisp(scope->obj);
1090
1091 for(i = 0; i < frame->function->local_scopes[index].locals_cnt; i++)
1092 {
1094 int ref = frame->function->local_scopes[index].locals[i].ref;
1095 jsdisp_t *func_obj;
1096 jsval_t val;
1097
1098 if (frame->function->variables[ref].func_id != -1)
1099 {
1100 TRACE("function %s %d\n", debugstr_w(name), i);
1101
1103 + frame->function->variables[ref].func_id, ctx->call_ctx->scope, &func_obj)))
1104 return hres;
1105 val = jsval_obj(func_obj);
1106 if (detached_vars && FAILED(hres = jsdisp_propput_name(frame->variable_obj, name, jsval_obj(func_obj))))
1107 {
1108 jsdisp_release(func_obj);
1109 return hres;
1110 }
1111 }
1112 else
1113 {
1114 val = jsval_undefined();
1115 }
1116
1117 if (detached_vars)
1118 {
1119 hres = jsdisp_propput_name(jsobj, name, val);
1121 if (FAILED(hres))
1122 return hres;
1123 }
1124 else
1125 {
1126 off = local_off(frame, ref);
1127 jsval_release(ctx->stack[off]);
1128 ctx->stack[off] = val;
1129 }
1130 }
1131 return S_OK;
1132}
1133
1134/* ECMA-262 3rd Edition 12.10 */
1136{
1137 IDispatch *disp;
1138 jsval_t v;
1139 HRESULT hres;
1140
1141 TRACE("\n");
1142
1143 v = stack_pop(ctx);
1144 hres = to_object(ctx, v, &disp);
1146 if(FAILED(hres))
1147 return hres;
1148
1149 hres = scope_push(ctx, ctx->call_ctx->scope, disp, &ctx->call_ctx->scope);
1150 IDispatch_Release(disp);
1151 return hres;
1152}
1153
1154/* ECMA-262 10th Edition 13.3.1 */
1156{
1157 unsigned int scope_index = get_op_uint(ctx, 0);
1158 call_frame_t *frame = ctx->call_ctx;
1159 HRESULT hres;
1160
1161 TRACE("scope_index %u.\n", scope_index);
1162
1163 hres = scope_push(ctx, ctx->call_ctx->scope, NULL, &frame->scope);
1164
1165 if (FAILED(hres) || !scope_index)
1166 return hres;
1167
1168 frame->scope->scope_index = scope_index;
1169
1170 return scope_init_locals(ctx);
1171}
1172
1173/* ECMA-262 3rd Edition 12.10 */
1175{
1176 TRACE("\n");
1177
1178 if(ctx->call_ctx->scope->dispex.ref > 1) {
1180 if(FAILED(hres))
1181 ERR("Failed to detach variable object: %08lx\n", hres);
1182 }
1183
1184 scope_pop(&ctx->call_ctx->scope);
1185 return S_OK;
1186}
1187
1188/* ECMA-262 3rd Edition 12.13 */
1190{
1191 const unsigned arg = get_op_uint(ctx, 0);
1192 jsval_t v;
1193 BOOL b;
1194 HRESULT hres;
1195
1196 TRACE("\n");
1197
1198 v = stack_pop(ctx);
1201 if(FAILED(hres))
1202 return hres;
1203
1204 if(b) {
1205 stack_popn(ctx, 1);
1206 jmp_abs(ctx, arg);
1207 }else {
1208 jmp_next(ctx);
1209 }
1210 return S_OK;
1211}
1212
1214{
1215 jsexcept_t *ei = ctx->ei;
1216 jsdisp_t *obj;
1217
1218 reset_ei(ei);
1220 ei->valid_value = TRUE;
1221 ei->value = value;
1222
1224 UINT32 number;
1225 jsstr_t *str;
1226 jsval_t v;
1227 HRESULT hres;
1228
1229 /* FIXME: We should check if object is an error instance */
1230
1231 hres = jsdisp_propget_name(obj, L"number", &v);
1232 if(SUCCEEDED(hres)) {
1233 hres = to_uint32(ctx, v, &number);
1234 if(SUCCEEDED(hres))
1235 ei->error = FAILED(number) ? number : E_FAIL;
1237 }
1238
1239 hres = jsdisp_propget_name(obj, L"description", &v);
1240 if(SUCCEEDED(hres)) {
1241 hres = to_string(ctx, v, &str);
1242 if(SUCCEEDED(hres))
1243 ei->message = str;
1245 }
1246 }
1247}
1248
1249/* ECMA-262 3rd Edition 12.13 */
1251{
1252 TRACE("\n");
1253
1255 return DISP_E_EXCEPTION;
1256}
1257
1259{
1260 const HRESULT arg = get_op_uint(ctx, 0);
1261
1262 TRACE("%08lx\n", arg);
1263
1264 return arg;
1265}
1266
1268{
1269 const HRESULT hres = get_op_uint(ctx, 0);
1270 jsstr_t *str = get_op_str(ctx, 1);
1271 const WCHAR *ptr;
1272
1273 TRACE("%08lx %s\n", hres, debugstr_jsstr(str));
1274
1276 return ptr ? throw_error(ctx, hres, ptr) : E_OUTOFMEMORY;
1277}
1278
1279/* ECMA-262 3rd Edition 12.14 */
1281{
1282 const unsigned catch_off = get_op_uint(ctx, 0);
1283 const unsigned finally_off = get_op_uint(ctx, 1);
1284 call_frame_t *frame = ctx->call_ctx;
1286
1287 TRACE("\n");
1288
1289 except = malloc(sizeof(*except));
1290 if(!except)
1291 return E_OUTOFMEMORY;
1292
1293 except->stack_top = ctx->stack_top;
1294 except->scope = frame->scope;
1295 except->catch_off = catch_off;
1296 except->finally_off = finally_off;
1297 except->next = frame->except_frame;
1298 frame->except_frame = except;
1299 return S_OK;
1300}
1301
1302/* ECMA-262 3rd Edition 12.14 */
1304{
1305 const unsigned ret_off = get_op_uint(ctx, 0);
1306 call_frame_t *frame = ctx->call_ctx;
1308 unsigned finally_off;
1309
1310 TRACE("%u\n", ret_off);
1311
1312 except = frame->except_frame;
1313 assert(except != NULL);
1314
1315 finally_off = except->finally_off;
1316 frame->except_frame = except->next;
1317 free(except);
1318
1319 if(finally_off) {
1320 HRESULT hres;
1321
1322 hres = stack_push(ctx, jsval_number(ret_off));
1323 if(FAILED(hres))
1324 return hres;
1326 if(FAILED(hres))
1327 return hres;
1328 frame->ip = finally_off;
1329 }else {
1330 frame->ip = ret_off;
1331 }
1332
1333 return S_OK;
1334}
1335
1336/* ECMA-262 3rd Edition 12.14 */
1338{
1339 call_frame_t *frame = ctx->call_ctx;
1340 jsval_t v;
1341
1342 TRACE("\n");
1343
1344 v = stack_pop(ctx);
1345 assert(is_bool(v));
1346
1347 if(!get_bool(v)) {
1348 TRACE("passing exception\n");
1349
1351 return DISP_E_EXCEPTION;
1352 }
1353
1354 v = stack_pop(ctx);
1355 assert(is_number(v));
1356 frame->ip = get_number(v);
1357 return S_OK;
1358}
1359
1361{
1362 const BSTR ident = get_op_bstr(ctx, 0);
1363 jsdisp_t *scope_obj;
1364 jsval_t v;
1365 HRESULT hres;
1366
1367 hres = create_dispex(ctx, NULL, NULL, &scope_obj);
1368 if(FAILED(hres))
1369 return hres;
1370
1371 v = stack_pop(ctx);
1372 hres = jsdisp_propput_name(scope_obj, ident, v);
1374 if(SUCCEEDED(hres))
1375 hres = scope_push(ctx, ctx->call_ctx->scope, to_disp(scope_obj), &ctx->call_ctx->scope);
1376 jsdisp_release(scope_obj);
1377 return hres;
1378}
1379
1380/* ECMA-262 3rd Edition 13 */
1382{
1383 unsigned func_idx = get_op_uint(ctx, 0);
1384 call_frame_t *frame = ctx->call_ctx;
1385 jsdisp_t *dispex;
1386 HRESULT hres;
1387
1388 TRACE("%d\n", func_idx);
1389
1390 hres = create_source_function(ctx, frame->bytecode, frame->function->funcs+func_idx,
1391 frame->scope, &dispex);
1392 if(FAILED(hres))
1393 return hres;
1394
1395 return stack_push(ctx, jsval_obj(dispex));
1396}
1397
1398/* ECMA-262 3rd Edition 11.2.1 */
1400{
1401 jsstr_t *name_str;
1402 const WCHAR *name;
1403 jsval_t v, namev;
1404 IDispatch *obj;
1405 DISPID id;
1406 HRESULT hres;
1407
1408 TRACE("\n");
1409
1410 namev = stack_pop(ctx);
1411
1413 if(FAILED(hres)) {
1414 jsval_release(namev);
1415 return hres;
1416 }
1417
1418 hres = to_flat_string(ctx, namev, &name_str, &name);
1419 jsval_release(namev);
1420 if(FAILED(hres)) {
1421 IDispatch_Release(obj);
1422 return hres;
1423 }
1424
1425 hres = disp_get_id(ctx, obj, name, NULL, 0, &id);
1426 jsstr_release(name_str);
1427 if(SUCCEEDED(hres)) {
1428 hres = disp_propget(ctx, obj, id, &v);
1429 }else if(hres == DISP_E_UNKNOWNNAME) {
1430 v = jsval_undefined();
1431 hres = S_OK;
1432 }
1433 IDispatch_Release(obj);
1434 if(FAILED(hres))
1435 return hres;
1436
1437 return stack_push(ctx, v);
1438}
1439
1440/* ECMA-262 3rd Edition 11.2.1 */
1442{
1443 const BSTR arg = get_op_bstr(ctx, 0);
1444 IDispatch *obj;
1445 jsval_t v;
1446 DISPID id;
1447 HRESULT hres;
1448
1449 TRACE("\n");
1450
1452 if(FAILED(hres))
1453 return hres;
1454
1455 hres = disp_get_id(ctx, obj, arg, arg, 0, &id);
1456 if(SUCCEEDED(hres)) {
1457 hres = disp_propget(ctx, obj, id, &v);
1458 }else if(hres == DISP_E_UNKNOWNNAME) {
1459 v = jsval_undefined();
1460 hres = S_OK;
1461 }
1462 IDispatch_Release(obj);
1463 if(FAILED(hres))
1464 return hres;
1465
1466 return stack_push(ctx, v);
1467}
1468
1469/* ECMA-262 3rd Edition 11.2.1 */
1471{
1472 const unsigned arg = get_op_uint(ctx, 0);
1473 jsval_t objv, namev;
1474 const WCHAR *name;
1475 jsstr_t *name_str;
1476 IDispatch *obj;
1477 exprval_t ref;
1478 DISPID id;
1479 HRESULT hres;
1480
1481 TRACE("%x\n", arg);
1482
1483 namev = stack_pop(ctx);
1484 objv = stack_pop(ctx);
1485
1486 hres = to_object(ctx, objv, &obj);
1487 jsval_release(objv);
1488 if(SUCCEEDED(hres)) {
1489 hres = to_flat_string(ctx, namev, &name_str, &name);
1490 if(FAILED(hres))
1491 IDispatch_Release(obj);
1492 }
1493 jsval_release(namev);
1494 if(FAILED(hres))
1495 return hres;
1496
1497 hres = disp_get_id(ctx, obj, name, NULL, arg, &id);
1498 jsstr_release(name_str);
1499 if(SUCCEEDED(hres)) {
1500 ref.type = EXPRVAL_IDREF;
1501 ref.u.idref.disp = obj;
1502 ref.u.idref.id = id;
1503 }else {
1504 IDispatch_Release(obj);
1505 if(hres == DISP_E_UNKNOWNNAME && !(arg & fdexNameEnsure)) {
1507 hres = S_OK;
1508 }else {
1509 ERR("failed %08lx\n", hres);
1510 return hres;
1511 }
1512 }
1513
1514 return stack_push_exprval(ctx, &ref);
1515}
1516
1517/* ECMA-262 3rd Edition 11.2.1 */
1519{
1520 exprval_t ref;
1521 jsval_t v;
1522 HRESULT hres;
1523
1524 TRACE("\n");
1525
1526 if(!stack_topn_exprval(ctx, 0, &ref))
1527 return JS_E_ILLEGAL_ASSIGN;
1528
1529 hres = exprval_propget(ctx, &ref, &v);
1530 if(FAILED(hres))
1531 return hres;
1532
1533 return stack_push(ctx, v);
1534}
1535
1536/* ECMA-262 3rd Edition 11.2.2 */
1538{
1539 const unsigned argc = get_op_uint(ctx, 0);
1540 jsval_t constr;
1541
1542 TRACE("%d\n", argc);
1543
1544 constr = stack_topn(ctx, argc);
1545
1546 /* NOTE: Should use to_object here */
1547
1548 if(is_null(constr))
1550 if(!is_object_instance(constr))
1551 return JS_E_INVALID_ACTION;
1552
1553 clear_acc(ctx);
1554 return disp_call_value(ctx, get_object(constr), jsval_undefined(), DISPATCH_CONSTRUCT | DISPATCH_JSCRIPT_CALLEREXECSSOURCE,
1555 argc, stack_args(ctx, argc), &ctx->acc);
1556}
1557
1558/* ECMA-262 3rd Edition 11.2.3 */
1560{
1561 const unsigned argn = get_op_uint(ctx, 0);
1562 const int do_ret = get_op_int(ctx, 1);
1563 jsval_t obj;
1564
1565 TRACE("%d %d\n", argn, do_ret);
1566
1567 obj = stack_topn(ctx, argn);
1569 return JS_E_INVALID_PROPERTY;
1570
1571 clear_acc(ctx);
1573 argn, stack_args(ctx, argn), do_ret ? &ctx->acc : NULL);
1574}
1575
1576/* ECMA-262 3rd Edition 11.2.3 */
1578{
1579 const unsigned argn = get_op_uint(ctx, 0);
1580 const int do_ret = get_op_int(ctx, 1);
1581 exprval_t ref;
1582
1583 TRACE("%d %d\n", argn, do_ret);
1584
1585 if(!stack_topn_exprval(ctx, argn, &ref))
1586 return ref.u.hres;
1587
1588 clear_acc(ctx);
1590 argn, stack_args(ctx, argn), do_ret ? &ctx->acc : NULL);
1591}
1592
1593/* ECMA-262 5th Edition 15.1.2.1.1 */
1595{
1596 const unsigned argn = get_op_uint(ctx, 0);
1597 const int do_ret = get_op_int(ctx, 1);
1598 HRESULT hres = S_OK;
1599 exprval_t exprval;
1600 jsdisp_t *jsdisp;
1601 BSTR identifier;
1602 jsval_t v;
1603
1604 TRACE("%d %d\n", argn, do_ret);
1605
1606 identifier = SysAllocString(L"eval");
1607 hres = identifier_eval(ctx, identifier, &exprval);
1608 SysFreeString(identifier);
1609 if(FAILED(hres))
1610 return hres;
1611
1612 clear_acc(ctx);
1613 hres = exprval_propget(ctx, &exprval, &v);
1614 if(SUCCEEDED(hres)) {
1615 if(is_object_instance(v) && (jsdisp = to_jsdisp(get_object(v))) && jsdisp->ctx == ctx && is_builtin_eval_func(jsdisp))
1617 argn, stack_args(ctx, argn), do_ret ? &ctx->acc : NULL);
1618 else
1620 argn, stack_args(ctx, argn), do_ret ? &ctx->acc : NULL);
1622 }
1623 exprval_release(&exprval);
1624 return hres;
1625}
1626
1627/* ECMA-262 3rd Edition 11.1.1 */
1629{
1630 IDispatch *this_obj = ctx->call_ctx->this_obj;
1631
1632 TRACE("\n");
1633
1634 if(!this_obj) {
1635 named_item_t *item = ctx->call_ctx->bytecode->named_item;
1636
1637 if(item)
1638 this_obj = (item->flags & SCRIPTITEM_CODEONLY) ? to_disp(item->script_obj) : item->disp;
1639 else
1640 this_obj = lookup_global_host(ctx);
1641 }
1642
1643 IDispatch_AddRef(this_obj);
1644 return stack_push(ctx, jsval_disp(this_obj));
1645}
1646
1648{
1649 exprval_t exprval;
1650 HRESULT hres;
1651
1652 hres = identifier_eval(ctx, identifier, &exprval);
1653 if(FAILED(hres))
1654 return hres;
1655
1656 if(exprval.type == EXPRVAL_INVALID && (flags & fdexNameEnsure)) {
1657 jsdisp_t *script_obj = ctx->global;
1658 DISPID id;
1659
1660 if(ctx->call_ctx->bytecode->named_item)
1661 script_obj = ctx->call_ctx->bytecode->named_item->script_obj;
1662
1663 hres = jsdisp_get_id(script_obj, identifier, fdexNameEnsure, &id);
1664 if(FAILED(hres))
1665 return hres;
1666
1667 exprval_set_disp_ref(&exprval, to_disp(script_obj), id);
1668 }
1669
1670 if(exprval.type == EXPRVAL_INVALID ||
1671 (exprval.type == EXPRVAL_JSVAL && ctx->version < SCRIPTLANGUAGEVERSION_ES5)) {
1672 WARN("invalid ref\n");
1673 exprval_release(&exprval);
1675 }
1676
1677 return stack_push_exprval(ctx, &exprval);
1678}
1679
1681{
1682 exprval_t exprval;
1683 jsval_t v;
1684 HRESULT hres;
1685
1686 hres = identifier_eval(ctx, identifier, &exprval);
1687 if(FAILED(hres))
1688 return hres;
1689
1690 if(exprval.type == EXPRVAL_INVALID)
1691 return throw_error(ctx, exprval.u.hres, identifier);
1692
1693 hres = exprval_to_value(ctx, &exprval, &v);
1694 if(FAILED(hres))
1695 return hres;
1696
1697 return stack_push(ctx, v);
1698}
1699
1701{
1702 const int arg = get_op_int(ctx, 0);
1703 const unsigned flags = get_op_uint(ctx, 1);
1704 call_frame_t *frame = ctx->call_ctx;
1705 exprval_t ref;
1706
1707 TRACE("%s\n", debugstr_w(local_name(frame, arg)));
1708
1709 if(!frame->base_scope || !frame->base_scope->frame)
1710 return interp_identifier_ref(ctx, local_name(frame, arg), flags);
1711
1712 ref.type = EXPRVAL_STACK_REF;
1713 ref.u.off = local_off(frame, arg);
1714 return stack_push_exprval(ctx, &ref);
1715}
1716
1718{
1719 const int arg = get_op_int(ctx, 0);
1720 call_frame_t *frame = ctx->call_ctx;
1721 jsval_t copy;
1722 HRESULT hres;
1723
1724 if(!frame->base_scope || !frame->base_scope->frame) {
1725 TRACE("%s\n", debugstr_w(local_name(frame, arg)));
1726 return identifier_value(ctx, local_name(frame, arg));
1727 }
1728
1729 hres = jsval_copy(ctx->stack[local_off(frame, arg)], &copy);
1730 if(FAILED(hres))
1731 return hres;
1732
1733 TRACE("%s: %s\n", debugstr_w(local_name(frame, arg)), debugstr_jsval(copy));
1734 return stack_push(ctx, copy);
1735}
1736
1737/* ECMA-262 3rd Edition 10.1.4 */
1739{
1740 const BSTR arg = get_op_bstr(ctx, 0);
1741
1742 TRACE("%s\n", debugstr_w(arg));
1743
1744 return identifier_value(ctx, arg);
1745}
1746
1747/* ECMA-262 3rd Edition 10.1.4 */
1749{
1750 const BSTR arg = get_op_bstr(ctx, 0);
1751 const unsigned flags = get_op_uint(ctx, 1);
1752
1753 TRACE("%s %x\n", debugstr_w(arg), flags);
1754
1756}
1757
1758/* ECMA-262 3rd Edition 7.8.1 */
1760{
1761 TRACE("\n");
1762
1763 return stack_push(ctx, jsval_null());
1764}
1765
1766/* ECMA-262 3rd Edition 7.8.2 */
1768{
1769 const int arg = get_op_int(ctx, 0);
1770
1771 TRACE("%s\n", arg ? "true" : "false");
1772
1773 return stack_push(ctx, jsval_bool(arg));
1774}
1775
1776/* ECMA-262 3rd Edition 7.8.3 */
1778{
1779 const int arg = get_op_int(ctx, 0);
1780
1781 TRACE("%d\n", arg);
1782
1783 return stack_push(ctx, jsval_number(arg));
1784}
1785
1786/* ECMA-262 3rd Edition 7.8.3 */
1788{
1789 const double arg = get_op_double(ctx);
1790
1791 TRACE("%lf\n", arg);
1792
1793 return stack_push(ctx, jsval_number(arg));
1794}
1795
1796/* ECMA-262 3rd Edition 7.8.4 */
1798{
1799 jsstr_t *str = get_op_str(ctx, 0);
1800
1801 TRACE("%s\n", debugstr_jsstr(str));
1802
1804}
1805
1806/* ECMA-262 3rd Edition 7.8 */
1808{
1810 const unsigned flags = get_op_uint(ctx, 1);
1811 jsdisp_t *regexp;
1812 HRESULT hres;
1813
1814 TRACE("%s %x\n", debugstr_jsstr(source), flags);
1815
1816 hres = create_regexp(ctx, source, flags, &regexp);
1817 if(FAILED(hres))
1818 return hres;
1819
1820 return stack_push(ctx, jsval_obj(regexp));
1821}
1822
1823/* ECMA-262 3rd Edition 11.1.4 */
1825{
1826 const unsigned arg = get_op_uint(ctx, 0);
1827 jsdisp_t *array;
1828 HRESULT hres;
1829
1830 TRACE("%u\n", arg);
1831
1833 if(FAILED(hres))
1834 return hres;
1835
1836 return stack_push(ctx, jsval_obj(array));
1837}
1838
1840{
1841 const unsigned index = get_op_uint(ctx, 0);
1843 HRESULT hres;
1844
1845 value = stack_pop(ctx);
1846
1847 TRACE("[%u] = %s\n", index, debugstr_jsval(value));
1848
1849 array = stack_top(ctx);
1851
1854 return hres;
1855}
1856
1857/* ECMA-262 3rd Edition 11.1.5 */
1859{
1860 jsdisp_t *obj;
1861 HRESULT hres;
1862
1863 TRACE("\n");
1864
1866 if(FAILED(hres))
1867 return hres;
1868
1869 return stack_push(ctx, jsval_obj(obj));
1870}
1871
1872/* ECMA-262 3rd Edition 11.1.5 */
1874{
1875 jsstr_t *name_arg = get_op_str(ctx, 0);
1876 unsigned type = get_op_uint(ctx, 1);
1877 const WCHAR *name;
1878 jsdisp_t *obj;
1879 jsval_t val;
1880 HRESULT hres;
1881
1882 TRACE("%s\n", debugstr_jsstr(name_arg));
1883
1884 val = stack_pop(ctx);
1885
1886 /* FIXME: we should pass it as jsstr_t */
1887 name = jsstr_flatten(name_arg);
1888
1891
1894 }else {
1896 jsdisp_t *func;
1897
1900
1901 desc.mask = desc.flags;
1903 desc.explicit_getter = TRUE;
1904 desc.getter = func;
1905 }else {
1906 desc.explicit_setter = TRUE;
1907 desc.setter = func;
1908 }
1909
1911 }
1912
1914 return hres;
1915}
1916
1917/* ECMA-262 3rd Edition 11.11 */
1919{
1920 const unsigned arg = get_op_uint(ctx, 0);
1921 BOOL b;
1922 HRESULT hres;
1923
1924 TRACE("\n");
1925
1927 if(FAILED(hres))
1928 return hres;
1929
1930 if(b) {
1931 jmp_abs(ctx, arg);
1932 }else {
1933 stack_popn(ctx, 1);
1934 jmp_next(ctx);
1935 }
1936 return S_OK;
1937}
1938
1939/* ECMA-262 3rd Edition 11.11 */
1941{
1942 const unsigned arg = get_op_uint(ctx, 0);
1943 BOOL b;
1944 HRESULT hres;
1945
1946 TRACE("\n");
1947
1949 if(FAILED(hres))
1950 return hres;
1951
1952 if(b) {
1953 stack_popn(ctx, 1);
1954 jmp_next(ctx);
1955 }else {
1956 jmp_abs(ctx, arg);
1957 }
1958 return S_OK;
1959}
1960
1961/* ECMA-262 3rd Edition 11.10 */
1963{
1964 INT l, r;
1965 HRESULT hres;
1966
1967 TRACE("\n");
1968
1969 hres = stack_pop_int(ctx, &r);
1970 if(FAILED(hres))
1971 return hres;
1972
1973 hres = stack_pop_int(ctx, &l);
1974 if(FAILED(hres))
1975 return hres;
1976
1977 return stack_push(ctx, jsval_number(l|r));
1978}
1979
1980/* ECMA-262 3rd Edition 11.10 */
1982{
1983 INT l, r;
1984 HRESULT hres;
1985
1986 TRACE("\n");
1987
1988 hres = stack_pop_int(ctx, &r);
1989 if(FAILED(hres))
1990 return hres;
1991
1992 hres = stack_pop_int(ctx, &l);
1993 if(FAILED(hres))
1994 return hres;
1995
1996 return stack_push(ctx, jsval_number(l^r));
1997}
1998
1999/* ECMA-262 3rd Edition 11.10 */
2001{
2002 INT l, r;
2003 HRESULT hres;
2004
2005 TRACE("\n");
2006
2007 hres = stack_pop_int(ctx, &r);
2008 if(FAILED(hres))
2009 return hres;
2010
2011 hres = stack_pop_int(ctx, &l);
2012 if(FAILED(hres))
2013 return hres;
2014
2015 return stack_push(ctx, jsval_number(l&r));
2016}
2017
2018/* ECMA-262 3rd Edition 11.8.6 */
2020{
2021 jsdisp_t *obj, *iter, *tmp = NULL;
2022 jsval_t prot, v;
2023 BOOL ret = FALSE;
2024 HRESULT hres;
2025
2026 v = stack_pop(ctx);
2027 if(!is_object_instance(v)) {
2030 }
2031
2033 IDispatch_Release(get_object(v));
2034 if(!obj) {
2035 FIXME("non-jsdisp objects not supported\n");
2036 return E_FAIL;
2037 }
2038
2039 if(obj->is_constructor) {
2040 hres = jsdisp_propget_name(obj, L"prototype", &prot);
2041 }else {
2043 }
2045 if(FAILED(hres))
2046 return hres;
2047
2048 v = stack_pop(ctx);
2049
2050 if(is_null_disp(v))
2052 else if(is_object_instance(prot)) {
2054 tmp = to_jsdisp(get_object(v));
2055 for(iter = tmp; !ret && iter; iter = iter->prototype) {
2056 hres = disp_cmp(get_object(prot), to_disp(iter), &ret);
2057 if(FAILED(hres))
2058 break;
2059 }
2060 }else {
2061 FIXME("prototype is not an object\n");
2062 hres = E_FAIL;
2063 }
2064
2065 jsval_release(prot);
2067 if(FAILED(hres))
2068 return hres;
2069
2070 return stack_push(ctx, jsval_bool(ret));
2071}
2072
2073/* ECMA-262 3rd Edition 11.8.7 */
2075{
2076 const WCHAR *str;
2077 jsstr_t *jsstr;
2078 jsval_t obj, v;
2079 DISPID id = 0;
2080 BOOL ret;
2081 HRESULT hres;
2082
2083 TRACE("\n");
2084
2085 obj = stack_pop(ctx);
2086 if(!is_object_instance(obj)) {
2088 return JS_E_OBJECT_EXPECTED;
2089 }
2090
2091 v = stack_pop(ctx);
2092 hres = to_flat_string(ctx, v, &jsstr, &str);
2094 if(FAILED(hres)) {
2095 IDispatch_Release(get_object(obj));
2096 return hres;
2097 }
2098
2099 hres = disp_get_id(ctx, get_object(obj), str, NULL, 0, &id);
2100 IDispatch_Release(get_object(obj));
2101 jsstr_release(jsstr);
2102 if(SUCCEEDED(hres))
2103 ret = TRUE;
2104 else if(hres == DISP_E_UNKNOWNNAME)
2105 ret = FALSE;
2106 else
2107 return hres;
2108
2109 return stack_push(ctx, jsval_bool(ret));
2110}
2111
2112/* ECMA-262 3rd Edition 11.6.1 */
2114{
2115 jsval_t l, r, lval, rval, ret;
2116 HRESULT hres;
2117
2118 rval = stack_pop(ctx);
2119 lval = stack_pop(ctx);
2120
2121 TRACE("%s + %s\n", debugstr_jsval(lval), debugstr_jsval(rval));
2122
2123 hres = to_primitive(ctx, lval, &l, NO_HINT);
2124 if(SUCCEEDED(hres)) {
2126 if(FAILED(hres))
2128 }
2129 jsval_release(lval);
2131 if(FAILED(hres))
2132 return hres;
2133
2134 if(is_string(l) || is_string(r)) {
2135 jsstr_t *lstr, *rstr = NULL;
2136
2137 hres = to_string(ctx, l, &lstr);
2138 if(SUCCEEDED(hres))
2139 hres = to_string(ctx, r, &rstr);
2140
2141 if(SUCCEEDED(hres)) {
2142 jsstr_t *ret_str;
2143
2144 ret_str = jsstr_concat(lstr, rstr);
2145 if(ret_str)
2146 ret = jsval_string(ret_str);
2147 else
2149 }
2150
2151 jsstr_release(lstr);
2152 if(rstr)
2154 }else {
2155 double nl, nr;
2156
2157 hres = to_number(ctx, l, &nl);
2158 if(SUCCEEDED(hres)) {
2159 hres = to_number(ctx, r, &nr);
2160 if(SUCCEEDED(hres))
2161 ret = jsval_number(nl+nr);
2162 }
2163 }
2164
2167 if(FAILED(hres))
2168 return hres;
2169
2170 return stack_push(ctx, ret);
2171}
2172
2173/* ECMA-262 3rd Edition 11.6.2 */
2175{
2176 double l, r;
2177 HRESULT hres;
2178
2179 TRACE("\n");
2180
2182 if(FAILED(hres))
2183 return hres;
2184
2186 if(FAILED(hres))
2187 return hres;
2188
2189 return stack_push(ctx, jsval_number(l-r));
2190}
2191
2192/* ECMA-262 3rd Edition 11.5.1 */
2194{
2195 double l, r;
2196 HRESULT hres;
2197
2198 TRACE("\n");
2199
2201 if(FAILED(hres))
2202 return hres;
2203
2205 if(FAILED(hres))
2206 return hres;
2207
2208 return stack_push(ctx, jsval_number(l*r));
2209}
2210
2211/* ECMA-262 3rd Edition 11.5.2 */
2213{
2214 double l, r;
2215 HRESULT hres;
2216
2217 TRACE("\n");
2218
2220 if(FAILED(hres))
2221 return hres;
2222
2224 if(FAILED(hres))
2225 return hres;
2226
2227 return stack_push(ctx, jsval_number(l/r));
2228}
2229
2230/* ECMA-262 3rd Edition 11.5.3 */
2232{
2233 double l, r;
2234 HRESULT hres;
2235
2236 TRACE("\n");
2237
2239 if(FAILED(hres))
2240 return hres;
2241
2243 if(FAILED(hres))
2244 return hres;
2245
2246 return stack_push(ctx, jsval_number(fmod(l, r)));
2247}
2248
2249/* ECMA-262 3rd Edition 11.4.2 */
2251{
2252 jsval_t objv, namev;
2253 IDispatch *obj;
2254 jsstr_t *name;
2255 BOOL ret;
2256 HRESULT hres;
2257
2258 TRACE("\n");
2259
2260 namev = stack_pop(ctx);
2261 objv = stack_pop(ctx);
2262
2263 hres = to_object(ctx, objv, &obj);
2264 jsval_release(objv);
2265 if(FAILED(hres)) {
2266 jsval_release(namev);
2267 return hres;
2268 }
2269
2270 hres = to_string(ctx, namev, &name);
2271 jsval_release(namev);
2272 if(FAILED(hres)) {
2273 IDispatch_Release(obj);
2274 return hres;
2275 }
2276
2278 IDispatch_Release(obj);
2280 if(FAILED(hres))
2281 return hres;
2282
2283 return stack_push(ctx, jsval_bool(ret));
2284}
2285
2286/* ECMA-262 3rd Edition 11.4.2 */
2288{
2289 const BSTR arg = get_op_bstr(ctx, 0);
2290 exprval_t exprval;
2291 BOOL ret;
2292 HRESULT hres;
2293
2294 TRACE("%s\n", debugstr_w(arg));
2295
2296 hres = identifier_eval(ctx, arg, &exprval);
2297 if(FAILED(hres))
2298 return hres;
2299
2300 switch(exprval.type) {
2301 case EXPRVAL_STACK_REF:
2302 ret = FALSE;
2303 break;
2304 case EXPRVAL_IDREF:
2305 hres = disp_delete(exprval.u.idref.disp, exprval.u.idref.id, &ret);
2306 IDispatch_Release(exprval.u.idref.disp);
2307 if(FAILED(hres))
2308 return hres;
2309 break;
2310 case EXPRVAL_INVALID:
2311 ret = TRUE;
2312 break;
2313 default:
2314 FIXME("Unsupported exprval\n");
2315 exprval_release(&exprval);
2316 return E_NOTIMPL;
2317 }
2318
2319
2320 return stack_push(ctx, jsval_bool(ret));
2321}
2322
2323/* ECMA-262 3rd Edition 11.4.2 */
2325{
2326 TRACE("\n");
2327
2328 stack_popn(ctx, 1);
2329 return stack_push(ctx, jsval_undefined());
2330}
2331
2332/* ECMA-262 3rd Edition 11.4.3 */
2334{
2335 switch(jsval_type(v)) {
2336 case JSV_UNDEFINED:
2337 *ret = L"undefined";
2338 break;
2339 case JSV_NULL:
2340 *ret = L"object";
2341 break;
2342 case JSV_OBJECT: {
2343 jsdisp_t *dispex;
2344
2345 if((dispex = to_jsdisp(get_object(v)))) {
2346 *ret = is_class(dispex, JSCLASS_FUNCTION) ? L"function" : L"object";
2347 }else {
2348 *ret = L"object";
2349 }
2350 break;
2351 }
2352 case JSV_STRING:
2353 *ret = L"string";
2354 break;
2355 case JSV_NUMBER:
2356 *ret = L"number";
2357 break;
2358 case JSV_BOOL:
2359 *ret = L"boolean";
2360 break;
2361 case JSV_VARIANT:
2362 FIXME("unhandled variant %s\n", debugstr_variant(get_variant(v)));
2363 return E_NOTIMPL;
2364 }
2365
2366 return S_OK;
2367}
2368
2369/* ECMA-262 3rd Edition 11.4.3 */
2371{
2372 const WCHAR *ret;
2373 exprval_t ref;
2374 jsval_t v;
2375 HRESULT hres;
2376
2377 TRACE("\n");
2378
2379 if(!stack_pop_exprval(ctx, &ref))
2381
2382 hres = exprval_propget(ctx, &ref, &v);
2384 if(FAILED(hres))
2385 return stack_push_string(ctx, L"unknown");
2386
2387 hres = typeof_string(v, &ret);
2389 if(FAILED(hres))
2390 return hres;
2391
2392 return stack_push_string(ctx, ret);
2393}
2394
2395/* ECMA-262 3rd Edition 11.4.3 */
2397{
2398 const BSTR arg = get_op_bstr(ctx, 0);
2399 exprval_t exprval;
2400 const WCHAR *ret;
2401 jsval_t v;
2402 HRESULT hres;
2403
2404 TRACE("%s\n", debugstr_w(arg));
2405
2406 hres = identifier_eval(ctx, arg, &exprval);
2407 if(FAILED(hres))
2408 return hres;
2409
2410 if(exprval.type == EXPRVAL_INVALID)
2412
2413 hres = exprval_to_value(ctx, &exprval, &v);
2414 if(FAILED(hres))
2415 return hres;
2416
2417 hres = typeof_string(v, &ret);
2419 if(FAILED(hres))
2420 return hres;
2421
2422 return stack_push_string(ctx, ret);
2423}
2424
2425/* ECMA-262 3rd Edition 11.4.3 */
2427{
2428 const WCHAR *ret;
2429 jsval_t v;
2430 HRESULT hres;
2431
2432 TRACE("\n");
2433
2434 v = stack_pop(ctx);
2435 hres = typeof_string(v, &ret);
2437 if(FAILED(hres))
2438 return hres;
2439
2440 return stack_push_string(ctx, ret);
2441}
2442
2443/* ECMA-262 3rd Edition 11.4.7 */
2445{
2446 double n;
2447 HRESULT hres;
2448
2449 TRACE("\n");
2450
2452 if(FAILED(hres))
2453 return hres;
2454
2455 return stack_push(ctx, jsval_number(-n));
2456}
2457
2458/* ECMA-262 3rd Edition 11.4.6 */
2460{
2461 jsval_t v;
2462 double n;
2463 HRESULT hres;
2464
2465 TRACE("\n");
2466
2467 v = stack_pop(ctx);
2468 hres = to_number(ctx, v, &n);
2470 if(FAILED(hres))
2471 return hres;
2472
2473 return stack_push(ctx, jsval_number(n));
2474}
2475
2476/* ECMA-262 3rd Edition 11.3.1 */
2478{
2479 const int arg = get_op_int(ctx, 0);
2480 exprval_t ref;
2481 jsval_t v;
2482 HRESULT hres;
2483
2484 TRACE("%d\n", arg);
2485
2486 if(!stack_pop_exprval(ctx, &ref))
2487 return JS_E_OBJECT_EXPECTED;
2488
2489 hres = exprval_propget(ctx, &ref, &v);
2490 if(SUCCEEDED(hres)) {
2491 double n;
2492
2493 hres = to_number(ctx, v, &n);
2494 if(SUCCEEDED(hres))
2495 hres = exprval_propput(ctx, &ref, jsval_number(n+(double)arg));
2496 if(FAILED(hres))
2498 }
2500 if(FAILED(hres))
2501 return hres;
2502
2503 return stack_push(ctx, v);
2504}
2505
2506/* ECMA-262 3rd Edition 11.4.4, 11.4.5 */
2508{
2509 const int arg = get_op_int(ctx, 0);
2510 exprval_t ref;
2511 double ret;
2512 jsval_t v;
2513 HRESULT hres;
2514
2515 TRACE("%d\n", arg);
2516
2517 if(!stack_pop_exprval(ctx, &ref))
2518 return JS_E_OBJECT_EXPECTED;
2519
2520 hres = exprval_propget(ctx, &ref, &v);
2521 if(SUCCEEDED(hres)) {
2522 double n;
2523
2524 hres = to_number(ctx, v, &n);
2526 if(SUCCEEDED(hres)) {
2527 ret = n+(double)arg;
2529 }
2530 }
2532 if(FAILED(hres))
2533 return hres;
2534
2535 return stack_push(ctx, jsval_number(ret));
2536}
2537
2538/* ECMA-262 3rd Edition 11.9.3 */
2540{
2541 if(jsval_type(lval) == jsval_type(rval) || (is_number(lval) && is_number(rval)))
2542 return jsval_strict_equal(lval, rval, ret);
2543
2544 if((is_null(lval) && is_undefined(rval)) || (is_undefined(lval) && is_null(rval))) {
2545 *ret = TRUE;
2546 return S_OK;
2547 }
2548
2549 if(is_string(lval) && is_number(rval)) {
2550 double n;
2551 HRESULT hres;
2552
2553 hres = to_number(ctx, lval, &n);
2554 if(FAILED(hres))
2555 return hres;
2556
2557 /* FIXME: optimize */
2558 return equal_values(ctx, jsval_number(n), rval, ret);
2559 }
2560
2561 if(is_string(rval) && is_number(lval)) {
2562 double n;
2563 HRESULT hres;
2564
2565 hres = to_number(ctx, rval, &n);
2566 if(FAILED(hres))
2567 return hres;
2568
2569 /* FIXME: optimize */
2570 return equal_values(ctx, lval, jsval_number(n), ret);
2571 }
2572
2573 if(is_bool(rval))
2574 return equal_values(ctx, lval, jsval_number(get_bool(rval) ? 1 : 0), ret);
2575
2576 if(is_bool(lval))
2577 return equal_values(ctx, jsval_number(get_bool(lval) ? 1 : 0), rval, ret);
2578
2579
2580 if(is_object_instance(rval) && (is_string(lval) || is_number(lval))) {
2581 jsval_t prim;
2582 HRESULT hres;
2583
2585 if(FAILED(hres))
2586 return hres;
2587
2588 hres = equal_values(ctx, lval, prim, ret);
2590 return hres;
2591 }
2592
2593
2594 if(is_object_instance(lval) && (is_string(rval) || is_number(rval))) {
2595 jsval_t prim;
2596 HRESULT hres;
2597
2598 hres = to_primitive(ctx, lval, &prim, NO_HINT);
2599 if(FAILED(hres))
2600 return hres;
2601
2604 return hres;
2605 }
2606
2607
2608 *ret = FALSE;
2609 return S_OK;
2610}
2611
2612/* ECMA-262 3rd Edition 11.9.1 */
2614{
2615 jsval_t l, r;
2616 BOOL b;
2617 HRESULT hres;
2618
2619 r = stack_pop(ctx);
2620 l = stack_pop(ctx);
2621
2622 TRACE("%s == %s\n", debugstr_jsval(l), debugstr_jsval(r));
2623
2624 hres = equal_values(ctx, l, r, &b);
2627 if(FAILED(hres))
2628 return hres;
2629
2630 return stack_push(ctx, jsval_bool(b));
2631}
2632
2633/* ECMA-262 3rd Edition 11.9.2 */
2635{
2636 jsval_t l, r;
2637 BOOL b;
2638 HRESULT hres;
2639
2640 r = stack_pop(ctx);
2641 l = stack_pop(ctx);
2642
2643 TRACE("%s != %s\n", debugstr_jsval(l), debugstr_jsval(r));
2644
2645 hres = equal_values(ctx, l, r, &b);
2648 if(FAILED(hres))
2649 return hres;
2650
2651 return stack_push(ctx, jsval_bool(!b));
2652}
2653
2654/* ECMA-262 3rd Edition 11.9.4 */
2656{
2657 jsval_t l, r;
2658 BOOL b;
2659 HRESULT hres;
2660
2661 r = stack_pop(ctx);
2662 l = stack_pop(ctx);
2663
2664 TRACE("%s === %s\n", debugstr_jsval(l), debugstr_jsval(r));
2665
2666 hres = jsval_strict_equal(r, l, &b);
2669 if(FAILED(hres))
2670 return hres;
2671
2672 return stack_push(ctx, jsval_bool(b));
2673}
2674
2675/* ECMA-262 3rd Edition 11.9.5 */
2677{
2678 jsval_t l, r;
2679 BOOL b;
2680 HRESULT hres;
2681
2682 TRACE("\n");
2683
2684 r = stack_pop(ctx);
2685 l = stack_pop(ctx);
2686
2687 hres = jsval_strict_equal(r, l, &b);
2690 if(FAILED(hres))
2691 return hres;
2692
2693 return stack_push(ctx, jsval_bool(!b));
2694}
2695
2696/* ECMA-262 3rd Edition 11.8.5 */
2698{
2699 double ln, rn;
2700 jsval_t l, r;
2701 HRESULT hres;
2702
2703 hres = to_primitive(ctx, lval, &l, NO_HINT);
2704 if(FAILED(hres))
2705 return hres;
2706
2708 if(FAILED(hres)) {
2710 return hres;
2711 }
2712
2713 if(is_string(l) && is_string(r)) {
2714 *ret = (jsstr_cmp(get_string(l), get_string(r)) < 0) ^ greater;
2717 return S_OK;
2718 }
2719
2720 hres = to_number(ctx, l, &ln);
2722 if(SUCCEEDED(hres))
2723 hres = to_number(ctx, r, &rn);
2725 if(FAILED(hres))
2726 return hres;
2727
2728 *ret = !isnan(ln) && !isnan(rn) && ((ln < rn) ^ greater);
2729 return S_OK;
2730}
2731
2732/* ECMA-262 3rd Edition 11.8.1 */
2734{
2735 jsval_t l, r;
2736 BOOL b;
2737 HRESULT hres;
2738
2739 r = stack_pop(ctx);
2740 l = stack_pop(ctx);
2741
2742 TRACE("%s < %s\n", debugstr_jsval(l), debugstr_jsval(r));
2743
2744 hres = less_eval(ctx, l, r, FALSE, &b);
2747 if(FAILED(hres))
2748 return hres;
2749
2750 return stack_push(ctx, jsval_bool(b));
2751}
2752
2753/* ECMA-262 3rd Edition 11.8.1 */
2755{
2756 jsval_t l, r;
2757 BOOL b;
2758 HRESULT hres;
2759
2760 r = stack_pop(ctx);
2761 l = stack_pop(ctx);
2762
2763 TRACE("%s <= %s\n", debugstr_jsval(l), debugstr_jsval(r));
2764
2765 hres = less_eval(ctx, r, l, TRUE, &b);
2768 if(FAILED(hres))
2769 return hres;
2770
2771 return stack_push(ctx, jsval_bool(b));
2772}
2773
2774/* ECMA-262 3rd Edition 11.8.2 */
2776{
2777 jsval_t l, r;
2778 BOOL b;
2779 HRESULT hres;
2780
2781 r = stack_pop(ctx);
2782 l = stack_pop(ctx);
2783
2784 TRACE("%s > %s\n", debugstr_jsval(l), debugstr_jsval(r));
2785
2786 hres = less_eval(ctx, r, l, FALSE, &b);
2789 if(FAILED(hres))
2790 return hres;
2791
2792 return stack_push(ctx, jsval_bool(b));
2793}
2794
2795/* ECMA-262 3rd Edition 11.8.4 */
2797{
2798 jsval_t l, r;
2799 BOOL b;
2800 HRESULT hres;
2801
2802 r = stack_pop(ctx);
2803 l = stack_pop(ctx);
2804
2805 TRACE("%s >= %s\n", debugstr_jsval(l), debugstr_jsval(r));
2806
2807 hres = less_eval(ctx, l, r, TRUE, &b);
2810 if(FAILED(hres))
2811 return hres;
2812
2813 return stack_push(ctx, jsval_bool(b));
2814}
2815
2816/* ECMA-262 3rd Edition 11.4.8 */
2818{
2819 jsval_t v;
2820 INT i;
2821 HRESULT hres;
2822
2823 TRACE("\n");
2824
2825 v = stack_pop(ctx);
2826 hres = to_int32(ctx, v, &i);
2828 if(FAILED(hres))
2829 return hres;
2830
2831 return stack_push(ctx, jsval_number(~i));
2832}
2833
2834/* ECMA-262 3rd Edition 11.4.9 */
2836{
2837 jsval_t v;
2838 BOOL b;
2839 HRESULT hres;
2840
2841 TRACE("\n");
2842
2843 v = stack_pop(ctx);
2844 hres = to_boolean(v, &b);
2846 if(FAILED(hres))
2847 return hres;
2848
2849 return stack_push(ctx, jsval_bool(!b));
2850}
2851
2852/* ECMA-262 3rd Edition 11.7.1 */
2854{
2855 UINT32 r;
2856 INT l;
2857 HRESULT hres;
2858
2859 hres = stack_pop_uint(ctx, &r);
2860 if(FAILED(hres))
2861 return hres;
2862
2863 hres = stack_pop_int(ctx, &l);
2864 if(FAILED(hres))
2865 return hres;
2866
2867 return stack_push(ctx, jsval_number(l << (r&0x1f)));
2868}
2869
2870/* ECMA-262 3rd Edition 11.7.2 */
2872{
2873 UINT32 r;
2874 INT l;
2875 HRESULT hres;
2876
2877 hres = stack_pop_uint(ctx, &r);
2878 if(FAILED(hres))
2879 return hres;
2880
2881 hres = stack_pop_int(ctx, &l);
2882 if(FAILED(hres))
2883 return hres;
2884
2885 return stack_push(ctx, jsval_number(l >> (r&0x1f)));
2886}
2887
2888/* ECMA-262 3rd Edition 11.7.3 */
2890{
2891 UINT32 r, l;
2892 HRESULT hres;
2893
2894 hres = stack_pop_uint(ctx, &r);
2895 if(FAILED(hres))
2896 return hres;
2897
2898 hres = stack_pop_uint(ctx, &l);
2899 if(FAILED(hres))
2900 return hres;
2901
2902 return stack_push(ctx, jsval_number(l >> (r&0x1f)));
2903}
2904
2905/* ECMA-262 3rd Edition 9.8 */
2907{
2908 jsstr_t *str;
2909 jsval_t v;
2910 HRESULT hres;
2911
2912 v = stack_pop(ctx);
2913 TRACE("%s\n", debugstr_jsval(v));
2914 hres = to_string(ctx, v, &str);
2916 if(FAILED(hres)) {
2917 WARN("failed %08lx\n", hres);
2918 return hres;
2919 }
2920
2921 return stack_push(ctx, jsval_string(str));
2922}
2923
2924/* ECMA-262 3rd Edition 11.13.1 */
2926{
2927 exprval_t ref;
2928 jsval_t v;
2929 HRESULT hres;
2930
2931 TRACE("\n");
2932
2933 v = stack_pop(ctx);
2934
2935 if(!stack_pop_exprval(ctx, &ref)) {
2937 return JS_E_ILLEGAL_ASSIGN;
2938 }
2939
2942 if(FAILED(hres)) {
2944 return hres;
2945 }
2946
2947 return stack_push(ctx, v);
2948}
2949
2950/* ECMA-262 3rd Edition 11.13.1 */
2952{
2953 jsval_t objv, namev, value;
2954 const WCHAR *name;
2955 IDispatch *obj;
2956 HRESULT hres;
2957
2958 value = stack_pop(ctx);
2959 namev = stack_pop(ctx);
2960 assert(is_string(namev));
2961 objv = stack_pop(ctx);
2962
2963 TRACE("%s.%s = %s\n", debugstr_jsval(objv), debugstr_jsval(namev), debugstr_jsval(value));
2964
2965 hres = to_object(ctx, objv, &obj);
2966 jsval_release(objv);
2967 if(SUCCEEDED(hres) && !(name = jsstr_flatten(get_string(namev)))) {
2968 IDispatch_Release(obj);
2970 }
2971 if(SUCCEEDED(hres)) {
2973 IDispatch_Release(obj);
2974 jsstr_release(get_string(namev));
2975 }
2976 if(FAILED(hres)) {
2977 WARN("failed %08lx\n", hres);
2979 return hres;
2980 }
2981
2982 return stack_push(ctx, value);
2983}
2984
2985/* JScript extension */
2987{
2988 const unsigned argc = get_op_uint(ctx, 0);
2989 exprval_t ref;
2990 jsval_t v;
2991 HRESULT hres;
2992
2993 TRACE("%u\n", argc);
2994
2995 if(!stack_topn_exprval(ctx, argc+1, &ref))
2996 return JS_E_ILLEGAL_ASSIGN;
2997
2999 if(FAILED(hres))
3000 return hres;
3001
3002 v = stack_pop(ctx);
3003 stack_popn(ctx, argc+2);
3004 return stack_push(ctx, v);
3005}
3006
3008{
3009 TRACE("\n");
3010
3011 return stack_push(ctx, jsval_undefined());
3012}
3013
3015{
3016 const unsigned arg = get_op_uint(ctx, 0);
3017
3018 TRACE("%u\n", arg);
3019
3020 jmp_abs(ctx, arg);
3021 return S_OK;
3022}
3023
3025{
3026 const unsigned arg = get_op_uint(ctx, 0);
3027 BOOL b;
3028 jsval_t v;
3029 HRESULT hres;
3030
3031 TRACE("\n");
3032
3033 v = stack_pop(ctx);
3034 hres = to_boolean(v, &b);
3036 if(FAILED(hres))
3037 return hres;
3038
3039 if(b)
3040 jmp_next(ctx);
3041 else
3042 jmp_abs(ctx, arg);
3043 return S_OK;
3044}
3045
3047{
3048 const unsigned arg = get_op_uint(ctx, 0);
3049
3050 TRACE("%u\n", arg);
3051
3052 stack_popn(ctx, arg);
3053 return S_OK;
3054}
3055
3057{
3058 const unsigned clear_ret = get_op_uint(ctx, 0);
3059 call_frame_t *frame = ctx->call_ctx;
3060
3061 TRACE("\n");
3062
3063 if(clear_ret)
3064 jsval_release(steal_ret(frame));
3065
3066 if((frame->flags & EXEC_CONSTRUCTOR) && !is_object_instance(frame->ret)) {
3067 jsval_release(frame->ret);
3068 IDispatch_AddRef(frame->this_obj);
3069 frame->ret = jsval_disp(frame->this_obj);
3070 }
3071
3072 jmp_abs(ctx, -1);
3073 return S_OK;
3074}
3075
3077{
3078 call_frame_t *frame = ctx->call_ctx;
3079
3080 TRACE("\n");
3081
3082 jsval_release(frame->ret);
3083 frame->ret = stack_pop(ctx);
3084 return S_OK;
3085}
3086
3088{
3089 HRESULT hres;
3090
3091 TRACE("\n");
3092
3093 hres = stack_push(ctx, ctx->acc);
3094 if(SUCCEEDED(hres))
3095 ctx->acc = jsval_undefined();
3096 return hres;
3097}
3098
3100
3101static const op_func_t op_funcs[] = {
3102#define X(x,a,b,c) interp_##x,
3103OP_LIST
3104#undef X
3105};
3106
3107static const unsigned op_move[] = {
3108#define X(a,x,b,c) x,
3109OP_LIST
3110#undef X
3111};
3112
3114{
3115 call_frame_t *frame = ctx->call_ctx;
3116
3117 frame->stack_base -= frame->pop_locals + frame->pop_variables;
3118
3119 assert(frame->scope == frame->base_scope);
3120
3121 /* If current scope will be kept alive, we need to transfer local variables to its variable object. */
3122 if(frame->scope && frame->scope->dispex.ref > 1) {
3124 if(FAILED(hres))
3125 ERR("Failed to detach variable object: %08lx\n", hres);
3126 }
3127
3128 if(frame->arguments_obj)
3130 if(frame->scope)
3131 scope_release(frame->scope);
3132
3133 if(frame->pop_variables)
3134 stack_popn(ctx, frame->pop_variables);
3135 stack_popn(ctx, frame->pop_locals);
3136
3137 ctx->call_ctx = frame->prev_frame;
3138
3139 if(frame->function_instance)
3141 if(frame->variable_obj)
3143 if(frame->this_obj)
3144 IDispatch_Release(frame->this_obj);
3145 jsval_release(frame->ret);
3146 release_bytecode(frame->bytecode);
3147 free(frame);
3148}
3149
3151{
3152 unsigned depth = 0, i, line, char_pos;
3153 call_frame_t *frame;
3154
3155 for(frame = ctx->call_ctx; frame; frame = frame->prev_frame) {
3156 WARN("%u\t", depth);
3157 depth++;
3158
3159 if(frame->this_obj)
3160 WARN("%p->", frame->this_obj);
3161 WARN("%s(", frame->function->name ? debugstr_w(frame->function->name) : "[unnamed]");
3162 if(frame->base_scope && frame->base_scope->frame) {
3163 for(i=0; i < frame->argc; i++) {
3164 if(i < frame->function->param_cnt)
3165 WARN("%s%s=%s", i ? ", " : "", debugstr_w(frame->function->params[i]),
3166 debugstr_jsval(ctx->stack[local_off(frame, -i-1)]));
3167 else
3168 WARN("%s%s", i ? ", " : "", debugstr_jsval(ctx->stack[local_off(frame, -i-1)]));
3169 }
3170 }else {
3171 WARN("[detached frame]");
3172 }
3173 line = get_location_line(frame->bytecode, frame->bytecode->instrs[frame->ip].loc, &char_pos);
3174 WARN(") context %s line %u char %u\n", wine_dbgstr_longlong(frame->bytecode->source_context), line, char_pos);
3175
3176 if(!(frame->flags & EXEC_RETURN_TO_INTERP)) {
3177 WARN("%u\t[native code]\n", depth);
3178 depth++;
3179 }
3180 }
3181}
3182
3184{
3185 except_frame_t *except_frame;
3186 jsexcept_t *ei = ctx->ei;
3187 call_frame_t *frame;
3188 jsval_t except_val;
3189 unsigned catch_off;
3190 HRESULT hres;
3191
3192 if(WARN_ON(jscript)) {
3193 jsdisp_t *error_obj;
3194 jsval_t msg;
3195
3196 WARN("Exception %08lx %s", exception_hres, debugstr_jsval(ei->valid_value ? ei->value : jsval_undefined()));
3197 if(ei->valid_value && jsval_type(ei->value) == JSV_OBJECT) {
3198 error_obj = to_jsdisp(get_object(ei->value));
3199 if(error_obj) {
3200 hres = jsdisp_propget_name(error_obj, L"message", &msg);
3201 if(SUCCEEDED(hres)) {
3202 WARN(" (message %s)", debugstr_jsval(msg));
3204 }
3205 }
3206 }
3207 WARN(" in:\n");
3208
3210 }
3211
3212 frame = ctx->call_ctx;
3213 if(exception_hres != DISP_E_EXCEPTION)
3214 throw_error(ctx, exception_hres, NULL);
3215 set_error_location(ei, frame->bytecode, frame->bytecode->instrs[frame->ip].loc, IDS_RUNTIME_ERROR, NULL);
3216
3217 while(!frame->except_frame) {
3218 DWORD flags;
3219
3220 while(frame->scope != frame->base_scope)
3221 scope_pop(&frame->scope);
3222
3223 stack_popn(ctx, ctx->stack_top-frame->stack_base);
3224
3225 flags = frame->flags;
3228 return DISP_E_EXCEPTION;
3229 frame = ctx->call_ctx;
3230 }
3231
3232 except_frame = frame->except_frame;
3233 catch_off = except_frame->catch_off;
3234
3235 assert(except_frame->stack_top <= ctx->stack_top);
3236 stack_popn(ctx, ctx->stack_top - except_frame->stack_top);
3237
3238 while(except_frame->scope != frame->scope)
3239 scope_pop(&frame->scope);
3240
3241 frame->ip = catch_off ? catch_off : except_frame->finally_off;
3242 assert(!catch_off || frame->bytecode->instrs[frame->ip].op == OP_enter_catch);
3243
3244 if(ei->valid_value) {
3245 except_val = ctx->ei->value;
3246 ei->valid_value = FALSE;
3247 }else {
3248 jsdisp_t *err;
3249 if(!(err = create_builtin_error(ctx)))
3250 return E_OUTOFMEMORY;
3251 except_val = jsval_obj(err);
3252 }
3253
3254 /* keep current except_frame if we're entering catch block with finally block associated */
3255 if(catch_off && except_frame->finally_off) {
3256 except_frame->catch_off = 0;
3257 }else {
3258 frame->except_frame = except_frame->next;
3259 free(except_frame);
3260 }
3261
3262 hres = stack_push(ctx, except_val);
3263 if(FAILED(hres))
3264 return hres;
3265
3266 if(!catch_off)
3268 return hres;
3269}
3270
3272{
3273 call_frame_t *frame;
3274 jsop_t op;
3275 HRESULT hres = S_OK;
3276
3277 TRACE("\n");
3278
3279 while(1) {
3280 frame = ctx->call_ctx;
3281 op = frame->bytecode->instrs[frame->ip].op;
3282 hres = op_funcs[op](ctx);
3283 if(FAILED(hres)) {
3285 if(FAILED(hres))
3286 return hres;
3287 }else if(frame->ip == -1) {
3288 const DWORD return_to_interp = frame->flags & EXEC_RETURN_TO_INTERP;
3289
3290 assert(ctx->stack_top == frame->stack_base);
3291 assert(frame->scope == frame->base_scope);
3292
3293 if(return_to_interp) {
3294 jsval_release(ctx->acc);
3295 ctx->acc = steal_ret(frame);
3296 }else if(r) {
3297 *r = steal_ret(frame);
3298 }
3300 if(!return_to_interp)
3301 break;
3302 }else {
3303 frame->ip += op_move[op];
3304 }
3305 }
3306
3307 return S_OK;
3308}
3309
3311{
3313 exprval_t exprval;
3314 IDispatch *disp;
3315 jsval_t v;
3316 HRESULT hres;
3317
3318 hres = identifier_eval(ctx, func->event_target, &exprval);
3319 if(FAILED(hres))
3320 return hres;
3321
3322 hres = exprval_to_value(ctx, &exprval, &v);
3323 if(FAILED(hres))
3324 return hres;
3325
3326 if(!is_object_instance(v)) {
3327 FIXME("Can't bind to %s\n", debugstr_jsval(v));
3329 }
3330
3331 disp = get_object(v);
3332 hres = IDispatch_QueryInterface(disp, &IID_IBindEventHandler, (void**)&target);
3333 if(SUCCEEDED(hres)) {
3334 hres = IBindEventHandler_BindHandler(target, func->name, to_disp(func_obj));
3335 IBindEventHandler_Release(target);
3336 if(FAILED(hres))
3337 WARN("BindEvent failed: %08lx\n", hres);
3338 }else {
3339 FIXME("No IBindEventHandler, not yet supported binding\n");
3340 }
3341
3342 IDispatch_Release(disp);
3343 return hres;
3344}
3345
3346static HRESULT setup_scope(script_ctx_t *ctx, call_frame_t *frame, scope_chain_t *scope_chain, jsdisp_t *variable_object, unsigned argc, jsval_t *argv)
3347{
3348 const unsigned orig_stack = ctx->stack_top;
3349 scope_chain_t *scope;
3350 unsigned i;
3351 jsval_t v;
3352 HRESULT hres;
3353
3354 /* If arguments are already on the stack, we may use them. */
3355 if(argv + argc == ctx->stack + ctx->stack_top) {
3356 frame->arguments_off = argv - ctx->stack;
3357 i = argc;
3358 }else {
3359 frame->arguments_off = ctx->stack_top;
3360 for(i = 0; i < argc; i++) {
3361 hres = jsval_copy(argv[i], &v);
3362 if(SUCCEEDED(hres))
3363 hres = stack_push(ctx, v);
3364 if(FAILED(hres)) {
3365 stack_popn(ctx, i);
3366 return hres;
3367 }
3368 }
3369 }
3370
3371 /* If fewer than declared arguments were passed, fill remaining with undefined value. */
3372 for(; i < frame->function->param_cnt; i++) {
3374 if(FAILED(hres)) {
3375 stack_popn(ctx, ctx->stack_top - orig_stack);
3376 return hres;
3377 }
3378 }
3379
3380 frame->pop_locals = ctx->stack_top - orig_stack;
3381
3382 frame->variables_off = ctx->stack_top;
3383
3384 for(i = 0; i < frame->function->var_cnt; i++) {
3386 if(FAILED(hres)) {
3387 stack_popn(ctx, ctx->stack_top - orig_stack);
3388 return hres;
3389 }
3390 }
3391
3392 frame->pop_variables = i;
3393
3394 hres = scope_push(ctx, scope_chain, to_disp(variable_object), &scope);
3395 if(FAILED(hres)) {
3396 stack_popn(ctx, ctx->stack_top - orig_stack);
3397 return hres;
3398 }
3399
3400 for(i = 0; i < frame->function->func_cnt; i++) {
3401 if(frame->function->funcs[i].local_ref != INVALID_LOCAL_REF
3402 && !frame->function->funcs[i].scope_index)
3403 {
3404 jsdisp_t *func_obj;
3405 unsigned off;
3406
3407 hres = create_source_function(ctx, frame->bytecode, frame->function->funcs+i, scope, &func_obj);
3408 if(FAILED(hres)) {
3409 stack_popn(ctx, ctx->stack_top - orig_stack);
3410 scope_release(scope);
3411 return hres;
3412 }
3413
3414 off = local_off(frame, frame->function->funcs[i].local_ref);
3415 jsval_release(ctx->stack[off]);
3416 ctx->stack[off] = jsval_obj(func_obj);
3417 }
3418 }
3419
3420 scope->frame = frame;
3421 frame->base_scope = frame->scope = scope;
3422 return S_OK;
3423}
3424
3426 IDispatch *this_obj, jsdisp_t *function_instance, unsigned argc, jsval_t *argv, jsval_t *r)
3427{
3428 jsdisp_t *variable_obj;
3429 call_frame_t *frame;
3430 unsigned i;
3431 HRESULT hres;
3432
3433 if(!ctx->stack) {
3434 ctx->stack = malloc(stack_size * sizeof(*ctx->stack));
3435 if(!ctx->stack)
3436 return E_OUTOFMEMORY;
3437 }
3438
3439 if(bytecode->named_item) {
3440 if(!bytecode->named_item->script_obj) {
3442 if(FAILED(hres)) return hres;
3443 }
3444 }
3445
3446 if(!ctx->ei->enter_notified) {
3447 ctx->ei->enter_notified = TRUE;
3448 IActiveScriptSite_OnEnterScript(ctx->site);
3449 }
3450
3451 for(i = 0; i < function->func_cnt; i++) {
3452 jsdisp_t *func_obj;
3453
3454 if(!function->funcs[i].event_target)
3455 continue;
3456
3457 if (function->funcs[i].scope_index)
3458 {
3459 /* TODO: Add tests and handle in interp_push_scope(). */
3460 FIXME("Event target with scope index are not properly handled.\n");
3461 }
3462
3463 hres = create_source_function(ctx, bytecode, function->funcs+i, scope, &func_obj);
3464 if(FAILED(hres))
3465 return hres;
3466
3467 hres = bind_event_target(ctx, function->funcs+i, func_obj);
3468 jsdisp_release(func_obj);
3469 if(FAILED(hres))
3470 return hres;
3471 }
3472
3473 if((flags & EXEC_EVAL) && scope) {
3474 variable_obj = jsdisp_addref(ctx->call_ctx->variable_obj);
3475 }else if(!(flags & (EXEC_GLOBAL | EXEC_EVAL))) {
3476 hres = create_dispex(ctx, NULL, NULL, &variable_obj);
3477 if(FAILED(hres)) return hres;
3478 }else if(bytecode->named_item) {
3479 variable_obj = jsdisp_addref(bytecode->named_item->script_obj);
3480 }else {
3481 variable_obj = jsdisp_addref(ctx->global);
3482 }
3483
3484 if(flags & (EXEC_GLOBAL | EXEC_EVAL)) {
3485 named_item_t *item = bytecode->named_item;
3486 DISPID id;
3487
3488 for(i=0; i < function->var_cnt; i++) {
3489 TRACE("[%d] %s %d\n", i, debugstr_w(function->variables[i].name), function->variables[i].func_id);
3490 if(function->variables[i].func_id != -1) {
3491 jsdisp_t *func_obj;
3492
3493 if (function->funcs[function->variables[i].func_id].scope_index && flags & EXEC_EVAL)
3494 {
3495 /* TODO: Add tests and handle in interp_push_scope(). */
3496 FIXME("Functions with scope index inside eval() are not properly handled.\n");
3497 }
3498
3499 hres = create_source_function(ctx, bytecode, function->funcs+function->variables[i].func_id, scope, &func_obj);
3500 if(FAILED(hres))
3501 goto fail;
3502
3503 hres = jsdisp_propput_name(variable_obj, function->variables[i].name, jsval_obj(func_obj));
3504 jsdisp_release(func_obj);
3505 continue;
3506 }
3507
3508 if(item && !(item->flags & SCRIPTITEM_CODEONLY)
3509 && SUCCEEDED(disp_get_id(ctx, item->disp, function->variables[i].name, function->variables[i].name, 0, &id)))
3510 continue;
3511
3512 if(!item && (flags & EXEC_GLOBAL) && lookup_global_members(ctx, function->variables[i].name, NULL))
3513 continue;
3514
3515 hres = jsdisp_get_id(variable_obj, function->variables[i].name, fdexNameEnsure, &id);
3516 if(FAILED(hres))
3517 goto fail;
3518 }
3519 }
3520
3521 if(this_obj) {
3522 jsdisp_t *jsthis = to_jsdisp(this_obj);
3523
3524 if(jsthis && jsthis->builtin_info->class == JSCLASS_GLOBAL)
3525 this_obj = NULL;
3526 }
3527
3528 if(scope && (flags & EXEC_EVAL)) {
3529 hres = detach_variable_object(ctx, ctx->call_ctx, FALSE);
3530 if(FAILED(hres))
3531 goto fail;
3532 }
3533
3534 frame = calloc(1, sizeof(*frame));
3535 if(!frame) {
3537 goto fail;
3538 }
3539
3540 frame->function = function;
3541 frame->ret = jsval_undefined();
3542 frame->argc = argc;
3543 frame->bytecode = bytecode_addref(bytecode);
3544
3545 if(!(flags & (EXEC_GLOBAL|EXEC_EVAL))) {
3546 hres = setup_scope(ctx, frame, scope, variable_obj, argc, argv);
3547 if(FAILED(hres)) {
3548 release_bytecode(frame->bytecode);
3549 free(frame);
3550 goto fail;
3551 }
3552 }else if(scope) {
3553 frame->base_scope = frame->scope = scope_addref(scope);
3554 }
3555
3556 frame->ip = function->instr_off;
3557 frame->stack_base = ctx->stack_top;
3558 if(this_obj) {
3559 frame->this_obj = this_obj;
3560 IDispatch_AddRef(frame->this_obj);
3561 }
3562
3563 if(function_instance)
3564 frame->function_instance = jsdisp_addref(function_instance);
3565
3566 frame->flags = flags;
3567 frame->variable_obj = variable_obj;
3568
3569 frame->prev_frame = ctx->call_ctx;
3570 ctx->call_ctx = frame;
3571
3573 /*
3574 * We're called directly from interpreter, so we may just setup call frame and return.
3575 * Already running interpreter will take care of execution.
3576 */
3577 if(r)
3578 *r = jsval_undefined();
3579 return S_OK;
3580 }
3581
3582 return enter_bytecode(ctx, r);
3583
3584fail:
3585 jsdisp_release(variable_obj);
3586 return hres;
3587}
HRESULT create_array(script_ctx_t *ctx, DWORD length, jsdisp_t **ret)
Definition: array.c:1780
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
const GUID IID_IUnknown
#define except(x)
Definition: btrfs_drv.h:136
r l[0]
Definition: byte_order.h:168
float rval
Definition: cylfrac.c:48
static BOOL get_bool(D3DXPARAMETER_TYPE type, const void *data)
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT op
Definition: effect.c:236
unsigned int idx
Definition: utils.c:41
void(* interp_func)(GLcontext *, GLuint, GLuint, GLfloat, GLuint, GLuint)
Definition: types.h:253
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
OLECHAR * BSTR
Definition: compat.h:2293
jsdisp_t * create_builtin_error(script_ctx_t *ctx)
Definition: error.c:448
HRESULT throw_error(script_ctx_t *ctx, HRESULT error, const WCHAR *str)
Definition: error.c:398
BOOL is_builtin_eval_func(jsdisp_t *jsdisp)
Definition: function.c:1470
HRESULT create_named_item_script_obj(script_ctx_t *ctx, named_item_t *item)
Definition: jscript.c:124
named_item_t * lookup_named_item(script_ctx_t *ctx, const WCHAR *item_name, unsigned flags)
Definition: jscript.c:162
#define IDS_RUNTIME_ERROR
Definition: resource.h:90
MonoAssembly int argc
Definition: metahost.c:107
#define assert(_expr)
Definition: assert.h:32
#define __cdecl
Definition: corecrt.h:121
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
#define isnan(x)
Definition: math.h:360
_ACRTIMP double __cdecl fmod(double, double)
static const char * debugstr_variant(const VARIANT *var)
Definition: dom.c:505
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
static HRESULT interp_identid(script_ctx_t *ctx)
Definition: engine.c:1748
static HRESULT interp_push_except(script_ctx_t *ctx)
Definition: engine.c:1280
static void pop_call_frame(script_ctx_t *ctx)
Definition: engine.c:3113
static HRESULT interp_undefined(script_ctx_t *ctx)
Definition: engine.c:3007
static jsval_t stack_topn(script_ctx_t *ctx, unsigned n)
Definition: engine.c:95
static jsval_t * get_detached_var_ref(scope_chain_t *scope, const WCHAR *name)
Definition: engine.c:169
static HRESULT exprval_propget(script_ctx_t *ctx, exprval_t *ref, jsval_t *r)
Definition: engine.c:334
static HRESULT interp_assign(script_ctx_t *ctx)
Definition: engine.c:2925
static HRESULT interp_case(script_ctx_t *ctx)
Definition: engine.c:1189
static void print_backtrace(script_ctx_t *ctx)
Definition: engine.c:3150
static HRESULT stack_pop_int(script_ctx_t *ctx, INT *r)
Definition: engine.c:147
static HRESULT interp_setret(script_ctx_t *ctx)
Definition: engine.c:3076
static HRESULT stack_push(script_ctx_t *ctx, jsval_t v)
Definition: engine.c:63
static HRESULT interp_carray_set(script_ctx_t *ctx)
Definition: engine.c:1839
static HRESULT interp_local(script_ctx_t *ctx)
Definition: engine.c:1717
static HRESULT disp_get_id(script_ctx_t *ctx, IDispatch *disp, const WCHAR *name, BSTR name_bstr, DWORD flags, DISPID *id)
Definition: engine.c:599
static HRESULT interp_eq2(script_ctx_t *ctx)
Definition: engine.c:2655
static HRESULT interp_add(script_ctx_t *ctx)
Definition: engine.c:2113
static HRESULT exprval_call(script_ctx_t *ctx, exprval_t *ref, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: engine.c:349
static HRESULT unwind_exception(script_ctx_t *ctx, HRESULT exception_hres)
Definition: engine.c:3183
static unsigned get_op_int(script_ctx_t *ctx, int i)
Definition: engine.c:974
static HRESULT stack_pop_object(script_ctx_t *ctx, IDispatch **r)
Definition: engine.c:131
static HRESULT detach_variable_object(script_ctx_t *ctx, call_frame_t *frame, BOOL from_release)
Definition: engine.c:803
static HRESULT bind_event_target(script_ctx_t *ctx, function_code_t *func, jsdisp_t *func_obj)
Definition: engine.c:3310
static HRESULT interp_call_eval(script_ctx_t *ctx)
Definition: engine.c:1594
static HRESULT detach_scope(script_ctx_t *ctx, call_frame_t *frame, scope_chain_t *scope)
Definition: engine.c:743
static BOOL lookup_global_members(script_ctx_t *ctx, BSTR identifier, exprval_t *ret)
Definition: engine.c:825
static HRESULT setup_scope(script_ctx_t *ctx, call_frame_t *frame, scope_chain_t *scope_chain, jsdisp_t *variable_object, unsigned argc, jsval_t *argv)
Definition: engine.c:3346
static HRESULT interp_forin(script_ctx_t *ctx)
Definition: engine.c:1003
static HRESULT interp_lshift(script_ctx_t *ctx)
Definition: engine.c:2853
static HRESULT interp_array(script_ctx_t *ctx)
Definition: engine.c:1399
static HRESULT scope_prop_get(jsdisp_t *dispex, unsigned idx, jsval_t *r)
Definition: engine.c:497
static HRESULT detach_scope_chain(script_ctx_t *ctx, call_frame_t *frame, scope_chain_t *scope)
Definition: engine.c:790
static HRESULT interp_member(script_ctx_t *ctx)
Definition: engine.c:1441
static HRESULT interp_eq(script_ctx_t *ctx)
Definition: engine.c:2613
local_ref_t * lookup_local(const function_code_t *function, const WCHAR *identifier, unsigned int scope)
Definition: engine.c:865
static HRESULT interp_typeof(script_ctx_t *ctx)
Definition: engine.c:2426
static HRESULT interp_memberid(script_ctx_t *ctx)
Definition: engine.c:1470
static HRESULT scope_gc_traverse(struct gc_ctx *gc_ctx, enum gc_traverse_op op, jsdisp_t *dispex)
Definition: engine.c:520
static HRESULT interp_minus(script_ctx_t *ctx)
Definition: engine.c:2444
static HRESULT identifier_value(script_ctx_t *ctx, BSTR identifier)
Definition: engine.c:1680
static HRESULT interp_regexp(script_ctx_t *ctx)
Definition: engine.c:1807
static HRESULT interp_identifier_ref(script_ctx_t *ctx, BSTR identifier, unsigned flags)
Definition: engine.c:1647
static HRESULT identifier_eval(script_ctx_t *ctx, BSTR identifier, exprval_t *ret)
Definition: engine.c:872
static HRESULT interp_push_with_scope(script_ctx_t *ctx)
Definition: engine.c:1135
static HRESULT stack_pop_uint(script_ctx_t *ctx, UINT32 *r)
Definition: engine.c:152
static HRESULT interp_neq(script_ctx_t *ctx)
Definition: engine.c:2634
static jsval_t stack_pop(script_ctx_t *ctx)
Definition: engine.c:108
static const unsigned op_move[]
Definition: engine.c:3107
static HRESULT interp_end_finally(script_ctx_t *ctx)
Definition: engine.c:1337
static void exprval_set_disp_ref(exprval_t *ref, IDispatch *obj, DISPID id)
Definition: engine.c:439
static HRESULT interp_delete(script_ctx_t *ctx)
Definition: engine.c:2250
static HRESULT interp_new(script_ctx_t *ctx)
Definition: engine.c:1537
static HRESULT interp_gteq(script_ctx_t *ctx)
Definition: engine.c:2796
static HRESULT interp_push_block_scope(script_ctx_t *ctx)
Definition: engine.c:1155
static HRESULT interp_tonum(script_ctx_t *ctx)
Definition: engine.c:2459
static HRESULT stack_push_exprval(script_ctx_t *ctx, exprval_t *val)
Definition: engine.c:187
static HRESULT interp_in(script_ctx_t *ctx)
Definition: engine.c:2074
static HRESULT interp_set_member(script_ctx_t *ctx)
Definition: engine.c:2951
static HRESULT interp_typeofident(script_ctx_t *ctx)
Definition: engine.c:2396
static HRESULT interp_and(script_ctx_t *ctx)
Definition: engine.c:2000
static HRESULT interp_pop(script_ctx_t *ctx)
Definition: engine.c:3046
static jsval_t * stack_top_ref(script_ctx_t *ctx, unsigned n)
Definition: engine.c:89
static HRESULT interp_jmp(script_ctx_t *ctx)
Definition: engine.c:3014
static HRESULT interp_push_acc(script_ctx_t *ctx)
Definition: engine.c:3087
static HRESULT interp_mod(script_ctx_t *ctx)
Definition: engine.c:2231
static HRESULT interp_bool(script_ctx_t *ctx)
Definition: engine.c:1767
static HRESULT interp_rshift(script_ctx_t *ctx)
Definition: engine.c:2871
static HRESULT interp_lteq(script_ctx_t *ctx)
Definition: engine.c:2754
static HRESULT interp_call(script_ctx_t *ctx)
Definition: engine.c:1559
static void scope_destructor(jsdisp_t *dispex)
Definition: engine.c:469
static const op_func_t op_funcs[]
Definition: engine.c:3101
static HRESULT interp_refval(script_ctx_t *ctx)
Definition: engine.c:1518
static HRESULT interp_xor(script_ctx_t *ctx)
Definition: engine.c:1981
static HRESULT interp_call_member(script_ctx_t *ctx)
Definition: engine.c:1577
static HRESULT interp_pop_scope(script_ctx_t *ctx)
Definition: engine.c:1174
static jsval_t * stack_args(script_ctx_t *ctx, unsigned n)
Definition: engine.c:100
HRESULT(* op_func_t)(script_ctx_t *)
Definition: engine.c:3099
static HRESULT interp_jmp_z(script_ctx_t *ctx)
Definition: engine.c:3024
static HRESULT interp_pop_except(script_ctx_t *ctx)
Definition: engine.c:1303
static HRESULT interp_local_ref(script_ctx_t *ctx)
Definition: engine.c:1700
static HRESULT interp_bneg(script_ctx_t *ctx)
Definition: engine.c:2817
static HRESULT interp_this(script_ctx_t *ctx)
Definition: engine.c:1628
static BSTR get_op_bstr(script_ctx_t *ctx, int i)
Definition: engine.c:962
static HRESULT interp_throw(script_ctx_t *ctx)
Definition: engine.c:1250
static void exprval_set_exception(exprval_t *val, HRESULT hres)
Definition: engine.c:433
static HRESULT interp_postinc(script_ctx_t *ctx)
Definition: engine.c:2477
static HRESULT interp_void(script_ctx_t *ctx)
Definition: engine.c:2324
static void jmp_abs(script_ctx_t *ctx, unsigned dst)
Definition: engine.c:997
static const size_t stack_size
Definition: engine.c:61
static jsstr_t * get_op_str(script_ctx_t *ctx, int i)
Definition: engine.c:980
static HRESULT interp_gt(script_ctx_t *ctx)
Definition: engine.c:2775
static void scope_pop(scope_chain_t **scope)
Definition: engine.c:590
static void jmp_next(script_ctx_t *ctx)
Definition: engine.c:992
static HRESULT interp_ret(script_ctx_t *ctx)
Definition: engine.c:3056
static HRESULT exprval_propput(script_ctx_t *ctx, exprval_t *ref, jsval_t v)
Definition: engine.c:315
static HRESULT interp_throw_type(script_ctx_t *ctx)
Definition: engine.c:1267
static HRESULT scope_lookup_prop(jsdisp_t *jsdisp, const WCHAR *name, unsigned flags, struct property_info *desc)
Definition: engine.c:490
static HRESULT interp_neq2(script_ctx_t *ctx)
Definition: engine.c:2676
static void clear_acc(script_ctx_t *ctx)
Definition: engine.c:458
static HRESULT interp_cnd_nz(script_ctx_t *ctx)
Definition: engine.c:1918
static double get_op_double(script_ctx_t *ctx)
Definition: engine.c:986
static HRESULT interp_sub(script_ctx_t *ctx)
Definition: engine.c:2174
static HRESULT interp_new_obj(script_ctx_t *ctx)
Definition: engine.c:1858
static jsval_t steal_ret(call_frame_t *frame)
Definition: engine.c:451
static HRESULT interp_throw_ref(script_ctx_t *ctx)
Definition: engine.c:1258
static HRESULT interp_rshift2(script_ctx_t *ctx)
Definition: engine.c:2889
static HRESULT interp_or(script_ctx_t *ctx)
Definition: engine.c:1962
IDispatch * lookup_global_host(script_ctx_t *ctx)
Definition: engine.c:845
static HRESULT interp_instanceof(script_ctx_t *ctx)
Definition: engine.c:2019
static HRESULT interp_cnd_z(script_ctx_t *ctx)
Definition: engine.c:1940
static HRESULT interp_delete_ident(script_ctx_t *ctx)
Definition: engine.c:2287
static HRESULT interp_neg(script_ctx_t *ctx)
Definition: engine.c:2835
static const builtin_info_t scope_info
Definition: engine.c:555
static unsigned get_op_uint(script_ctx_t *ctx, int i)
Definition: engine.c:968
static HRESULT scope_init_locals(script_ctx_t *ctx)
Definition: engine.c:1064
static jsval_t stack_top(script_ctx_t *ctx)
Definition: engine.c:83
static HRESULT exprval_to_value(script_ctx_t *ctx, exprval_t *ref, jsval_t *r)
Definition: engine.c:401
static void exprval_release(exprval_t *val)
Definition: engine.c:417
static void set_error_value(script_ctx_t *ctx, jsval_t value)
Definition: engine.c:1213
static unsigned local_off(call_frame_t *frame, int ref)
Definition: engine.c:157
static HRESULT interp_carray(script_ctx_t *ctx)
Definition: engine.c:1824
static HRESULT interp_double(script_ctx_t *ctx)
Definition: engine.c:1787
static HRESULT equal_values(script_ctx_t *ctx, jsval_t lval, jsval_t rval, BOOL *ret)
Definition: engine.c:2539
static HRESULT interp_str(script_ctx_t *ctx)
Definition: engine.c:1797
static HRESULT enter_bytecode(script_ctx_t *ctx, jsval_t *r)
Definition: engine.c:3271
static HRESULT get_detached_var_dispid(scope_chain_t *scope, const WCHAR *name, DISPID *id)
Definition: engine.c:180
static BOOL stack_pop_exprval(script_ctx_t *ctx, exprval_t *r)
Definition: engine.c:308
static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, BOOL *ret)
Definition: engine.c:633
static void stack_popn(script_ctx_t *ctx, unsigned n)
Definition: engine.c:114
static HRESULT typeof_string(jsval_t v, const WCHAR **ret)
Definition: engine.c:2333
static HRESULT interp_ident(script_ctx_t *ctx)
Definition: engine.c:1738
static scope_chain_t * scope_from_dispex(jsdisp_t *dispex)
Definition: engine.c:464
static HRESULT interp_enter_catch(script_ctx_t *ctx)
Definition: engine.c:1360
static HRESULT interp_null(script_ctx_t *ctx)
Definition: engine.c:1759
static HRESULT interp_int(script_ctx_t *ctx)
Definition: engine.c:1777
static HRESULT stack_push_string(script_ctx_t *ctx, const WCHAR *str)
Definition: engine.c:72
static HRESULT less_eval(script_ctx_t *ctx, jsval_t lval, jsval_t rval, BOOL greater, BOOL *ret)
Definition: engine.c:2697
static BSTR local_name(call_frame_t *frame, int ref)
Definition: engine.c:164
HRESULT jsval_strict_equal(jsval_t lval, jsval_t rval, BOOL *ret)
Definition: engine.c:684
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, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: engine.c:3425
static HRESULT scope_push(script_ctx_t *ctx, scope_chain_t *scope, IDispatch *obj, scope_chain_t **ret)
Definition: engine.c:564
static HRESULT stack_pop_number(script_ctx_t *ctx, double *r)
Definition: engine.c:120
static HRESULT interp_preinc(script_ctx_t *ctx)
Definition: engine.c:2507
static HRESULT interp_obj_prop(script_ctx_t *ctx)
Definition: engine.c:1873
static int __cdecl local_ref_cmp(const void *key, const void *ref)
Definition: engine.c:860
static HRESULT interp_div(script_ctx_t *ctx)
Definition: engine.c:2212
static HRESULT interp_to_string(script_ctx_t *ctx)
Definition: engine.c:2906
static HRESULT alloc_detached_vars(script_ctx_t *ctx, call_frame_t *frame, scope_chain_t *scope)
Definition: engine.c:720
static BOOL stack_topn_exprval(script_ctx_t *ctx, unsigned n, exprval_t *r)
Definition: engine.c:220
static HRESULT interp_typeofid(script_ctx_t *ctx)
Definition: engine.c:2370
static HRESULT interp_lt(script_ctx_t *ctx)
Definition: engine.c:2733
static HRESULT interp_assign_call(script_ctx_t *ctx)
Definition: engine.c:2986
static HRESULT scope_prop_put(jsdisp_t *dispex, unsigned idx, jsval_t val)
Definition: engine.c:504
static HRESULT interp_mul(script_ctx_t *ctx)
Definition: engine.c:2193
void detach_arguments_object(call_frame_t *)
Definition: function.c:293
void set_error_location(jsexcept_t *, bytecode_t *, unsigned, unsigned, jsstr_t *)
Definition: error.c:426
#define OP_LIST
Definition: engine.h:21
static scope_chain_t * scope_addref(scope_chain_t *scope)
Definition: engine.h:242
#define EXEC_GLOBAL
Definition: engine.h:305
@ PROPERTY_DEFINITION_GETTER
Definition: engine.h:143
@ PROPERTY_DEFINITION_VALUE
Definition: engine.h:142
static void scope_release(scope_chain_t *scope)
Definition: engine.h:248
HRESULT setup_arguments_object(script_ctx_t *, call_frame_t *)
Definition: function.c:259
HRESULT create_source_function(script_ctx_t *, bytecode_t *, function_code_t *, scope_chain_t *, jsdisp_t **)
Definition: function.c:953
#define EXEC_RETURN_TO_INTERP
Definition: engine.h:307
void reset_ei(jsexcept_t *)
Definition: jscript.c:314
#define INVALID_LOCAL_REF
Definition: engine.h:152
#define EXEC_EVAL
Definition: engine.h:308
jsop_t
Definition: engine.h:105
#define EXEC_CONSTRUCTOR
Definition: engine.h:306
static bytecode_t * bytecode_addref(bytecode_t *code)
Definition: engine.h:221
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
const GLdouble * v
Definition: gl.h:2040
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLenum func
Definition: glext.h:6028
GLdouble n
Definition: glext.h:7729
GLuint index
Definition: glext.h:6031
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLuint GLfloat * val
Definition: glext.h:7180
GLuint id
Definition: glext.h:5910
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
static HRESULT to_string(VARIANT *src, BSTR *dst)
Definition: host.c:46
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
void release_bytecode(bytecode_t *code)
Definition: compile.c:2459
unsigned get_location_line(bytecode_t *code, unsigned loc, unsigned *char_pos)
Definition: compile.c:2445
HRESULT jsdisp_propput_name(jsdisp_t *obj, const WCHAR *name, jsval_t val)
Definition: dispex.c:2859
HRESULT disp_propget(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t *val)
Definition: dispex.c:2994
HRESULT jsdisp_get_id(jsdisp_t *jsdisp, const WCHAR *name, DWORD flags, DISPID *id)
Definition: dispex.c:2550
HRESULT disp_delete(IDispatch *disp, DISPID id, BOOL *ret)
Definition: dispex.c:3038
jsdisp_t * iface_to_jsdisp(IDispatch *iface)
Definition: dispex.c:2543
HRESULT gc_process_linked_val(struct gc_ctx *gc_ctx, enum gc_traverse_op op, jsdisp_t *obj, jsval_t *link)
Definition: dispex.c:1139
HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, unsigned argc, jsval_t *argv, jsval_t *ret)
Definition: dispex.c:2666
HRESULT disp_delete_name(script_ctx_t *ctx, IDispatch *disp, jsstr_t *name, BOOL *ret)
Definition: dispex.c:3112
ULONG jsdisp_release(jsdisp_t *obj)
Definition: dispex.c:1911
HRESULT gc_process_linked_obj(struct gc_ctx *gc_ctx, enum gc_traverse_op op, jsdisp_t *obj, jsdisp_t *link, void **unlink_ref)
Definition: dispex.c:1124
HRESULT jsdisp_index_lookup(jsdisp_t *obj, const WCHAR *name, unsigned length, struct property_info *desc)
Definition: dispex.c:481
jsdisp_t * as_jsdisp(IDispatch *disp)
Definition: dispex.c:2441
HRESULT disp_propput_name(script_ctx_t *ctx, IDispatch *disp, const WCHAR *name, jsval_t val)
Definition: dispex.c:2910
HRESULT create_dispex(script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype, jsdisp_t **dispex)
Definition: dispex.c:2493
IWineJSDispatchHost * get_host_dispatch(IDispatch *disp)
Definition: dispex.c:3584
HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype)
Definition: dispex.c:2454
HRESULT jsdisp_get_idx_id(jsdisp_t *jsdisp, DWORD idx, DISPID *id)
Definition: dispex.c:2573
HRESULT jsdisp_propget_name(jsdisp_t *obj, const WCHAR *name, jsval_t *val)
Definition: dispex.c:2946
HRESULT jsdisp_propput_idx(jsdisp_t *obj, DWORD idx, jsval_t val)
Definition: dispex.c:2864
jsdisp_t * jsdisp_addref(jsdisp_t *obj)
Definition: dispex.c:1902
jsdisp_t * to_jsdisp(IDispatch *disp)
Definition: dispex.c:2447
HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t val)
Definition: dispex.c:2872
HRESULT jsdisp_define_property(jsdisp_t *obj, const WCHAR *name, property_desc_t *desc)
Definition: dispex.c:3216
HRESULT builtin_eval(script_ctx_t *ctx, call_frame_t *frame, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: global.c:137
HRESULT to_flat_string(script_ctx_t *, jsval_t, jsstr_t **, const WCHAR **)
Definition: jsutils.c:846
#define DISPATCH_JSCRIPT_CALLEREXECSSOURCE
Definition: jscript.h:98
#define JS_E_ILLEGAL_ASSIGN
Definition: jscript.h:556
@ NO_HINT
Definition: jscript.h:309
#define JS_E_OBJECT_EXPECTED
Definition: jscript.h:555
HRESULT create_object(script_ctx_t *, jsdisp_t *, jsdisp_t **)
Definition: object.c:1131
HRESULT to_primitive(script_ctx_t *, jsval_t, jsval_t *, hint_t)
Definition: jsutils.c:423
HRESULT create_regexp(script_ctx_t *, jsstr_t *, DWORD, jsdisp_t **)
Definition: jsregexp.c:626
HRESULT to_uint32(script_ctx_t *, jsval_t, UINT32 *)
Definition: jsutils.c:754
#define SCRIPTLANGUAGEVERSION_ES5
Definition: jscript.h:53
#define JS_E_FUNCTION_EXPECTED
Definition: jscript.h:552
static HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
Definition: jscript.h:518
static IDispatch * to_disp(jsdisp_t *jsdisp)
Definition: jscript.h:222
const char * debugstr_jsval(const jsval_t)
Definition: jsutils.c:35
#define JS_E_UNDEFINED_VARIABLE
Definition: jscript.h:557
static DWORD make_grfdex(script_ctx_t *ctx, DWORD flags)
Definition: jscript.h:513
HRESULT to_object(script_ctx_t *, jsval_t, IDispatch **)
Definition: jsutils.c:864
HRESULT to_number(script_ctx_t *, jsval_t, double *)
Definition: jsutils.c:630
HRESULT to_int32(script_ctx_t *, jsval_t, INT *)
Definition: jsutils.c:735
@ JSCLASS_FUNCTION
Definition: jscript.h:109
@ JSCLASS_NONE
Definition: jscript.h:103
@ JSCLASS_GLOBAL
Definition: jscript.h:110
#define JS_E_STACK_OVERFLOW
Definition: jscript.h:529
#define JS_E_INVALID_PROPERTY
Definition: jscript.h:532
#define JS_E_EXCEPTION_THROWN
Definition: jscript.h:566
gc_traverse_op
Definition: jscript.h:161
@ GC_TRAVERSE_UNLINK
Definition: jscript.h:162
HRESULT to_boolean(jsval_t, BOOL *)
Definition: jsutils.c:489
#define JS_E_INVALID_ACTION
Definition: jscript.h:533
static BOOL is_class(jsdisp_t *jsdisp, jsclass_t class)
Definition: jscript.h:503
const unsigned int PROPF_ENUMERABLE
Definition: jsdisp.idl:36
const unsigned int PROPF_CONFIGURABLE
Definition: jsdisp.idl:38
jsstr_t * jsstr_alloc_len(const WCHAR *buf, unsigned len)
Definition: jsstr.c:86
int jsstr_cmp(jsstr_t *str1, jsstr_t *str2)
Definition: jsstr.c:192
jsstr_t * jsstr_undefined(void)
Definition: jsstr.c:296
jsstr_t * jsstr_concat(jsstr_t *str1, jsstr_t *str2)
Definition: jsstr.c:214
const char * debugstr_jsstr(jsstr_t *str)
Definition: jsstr.c:37
static jsstr_t * jsstr_addref(jsstr_t *str)
Definition: jsstr.h:113
static const WCHAR * jsstr_flatten(jsstr_t *str)
Definition: jsstr.h:136
static BOOL jsstr_eq(jsstr_t *left, jsstr_t *right)
Definition: jsstr.h:173
static void jsstr_release(jsstr_t *str)
Definition: jsstr.h:107
static jsstr_t * jsstr_alloc(const WCHAR *str)
Definition: jsstr.h:100
HRESULT jsval_copy(jsval_t v, jsval_t *r)
Definition: jsutils.c:225
void jsval_release(jsval_t val)
Definition: jsutils.c:186
static BOOL is_number(jsval_t v)
Definition: jsval.h:200
static VARIANT * get_variant(jsval_t v)
Definition: jsval.h:243
jsval_type_t
Definition: jsval.h:44
@ JSV_STRING
Definition: jsval.h:48
@ JSV_NUMBER
Definition: jsval.h:49
@ JSV_VARIANT
Definition: jsval.h:51
@ JSV_OBJECT
Definition: jsval.h:47
@ JSV_NULL
Definition: jsval.h:46
@ JSV_UNDEFINED
Definition: jsval.h:45
@ JSV_BOOL
Definition: jsval.h:50
static jsval_t jsval_null(void)
Definition: jsval.h:130
static jsval_t jsval_string(jsstr_t *str)
Definition: jsval.h:109
static jsval_t jsval_undefined(void)
Definition: jsval.h:146
static jsval_t jsval_obj(jsdisp_t *obj)
Definition: jsval.h:125
static jsval_t jsval_bool(BOOL b)
Definition: jsval.h:101
static jsval_type_t jsval_type(jsval_t v)
Definition: jsval.h:219
static BOOL is_null_disp(jsval_t v)
Definition: jsval.h:190
static jsstr_t * get_string(jsval_t v)
Definition: jsval.h:238
static BOOL is_undefined(jsval_t v)
Definition: jsval.h:180
static double get_number(jsval_t v)
Definition: jsval.h:233
static jsval_t jsval_disp(IDispatch *obj)
Definition: jsval.h:117
static IDispatch * get_object(jsval_t v)
Definition: jsval.h:228
static BOOL is_object_instance(jsval_t v)
Definition: jsval.h:175
static BOOL is_null(jsval_t v)
Definition: jsval.h:185
static jsval_t jsval_number(double n)
Definition: jsval.h:153
static BOOL is_bool(jsval_t v)
Definition: jsval.h:214
#define b
Definition: ke_i.h:79
#define debugstr_w
Definition: kernel32.h:32
LOCAL int prim(arg_t *ap)
Definition: match.c:440
#define WARN_ON(c)
Definition: module.h:257
static PVOID ptr
Definition: dispmode.c:27
ULONG nr
Definition: thread.c:7
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1204
const char * var
Definition: shader.c:5666
static unsigned int number
Definition: dsound.c:1479
HRESULT hres
Definition: protocol.c:465
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:91
static VARIANTARG static DISPID
Definition: ordinal.c:49
static DWORD unk1
Definition: cursoricon.c:1804
#define argv
Definition: mplay32.c:18
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:196
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
#define DISPATCH_PROPERTYPUT
Definition: oleauto.h:1008
#define DISPATCH_METHOD
Definition: oleauto.h:1006
static BOOL is_string(parse_buffer *buf)
Definition: parsing.c:600
short WCHAR
Definition: pedump.c:58
#define IID_NULL
Definition: guiddef.h:98
#define err(...)
#define calloc
Definition: rosglue.h:14
const WCHAR * str
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
LOCAL char * rstr(char *s1, char *s2)
Definition: tree.c:165
#define TRACE(s)
Definition: solgame.cpp:4
instr_t * instrs
Definition: engine.h:195
UINT64 source_context
Definition: engine.h:202
named_item_t * named_item
Definition: engine.h:199
IDispatch * this_obj
Definition: engine.h:287
except_frame_t * except_frame
Definition: engine.h:280
struct _call_frame_t * prev_frame
Definition: engine.h:302
unsigned variables_off
Definition: engine.h:296
unsigned ip
Definition: engine.h:279
unsigned argc
Definition: engine.h:293
unsigned pop_locals
Definition: engine.h:294
jsdisp_t * arguments_obj
Definition: engine.h:290
scope_chain_t * base_scope
Definition: engine.h:283
jsdisp_t * variable_obj
Definition: engine.h:289
function_code_t * function
Definition: engine.h:300
bytecode_t * bytecode
Definition: engine.h:299
unsigned arguments_off
Definition: engine.h:295
DWORD flags
Definition: engine.h:291
scope_chain_t * scope
Definition: engine.h:282
jsval_t ret
Definition: engine.h:285
unsigned pop_variables
Definition: engine.h:297
jsdisp_t * function_instance
Definition: engine.h:288
unsigned stack_base
Definition: engine.h:281
scope_chain_t * scope
Definition: engine.c:36
unsigned stack_top
Definition: engine.c:35
except_frame_t * next
Definition: engine.c:40
unsigned catch_off
Definition: engine.c:37
unsigned finally_off
Definition: engine.c:38
unsigned var_cnt
Definition: engine.h:171
struct _function_code_t::@436 * variables
struct _function_code_t * funcs
Definition: engine.h:169
unsigned func_cnt
Definition: engine.h:168
BSTR * params
Definition: engine.h:178
bytecode_t * bytecode
Definition: engine.h:185
unsigned param_cnt
Definition: engine.h:177
unsigned instr_off
Definition: engine.h:163
local_ref_scopes_t * local_scopes
Definition: engine.h:180
BOOL valid_value
Definition: engine.h:256
jsstr_t * message
Definition: engine.h:260
HRESULT error
Definition: engine.h:254
jsval_t value
Definition: engine.h:257
Definition: jsstr.h:36
Definition: jsval.h:54
IDispatch * obj
Definition: engine.h:235
unsigned int scope_index
Definition: engine.h:236
struct _call_frame_t * frame
Definition: engine.h:238
struct _scope_chain_t * next
Definition: engine.h:239
struct vars_buffer * detached_vars
Definition: engine.h:237
jsdisp_t dispex
Definition: engine.h:234
Definition: undname.c:54
jsclass_t class
Definition: jscript.h:183
struct define * next
Definition: compiler.c:65
HRESULT hres
Definition: engine.c:57
unsigned off
Definition: engine.c:56
union exprval_t::@433 u
enum exprval_t::@432 type
struct exprval_t::@433::@434 idref
jsval_t val
Definition: engine.c:51
@ EXPRVAL_JSVAL
Definition: engine.c:45
@ EXPRVAL_STACK_REF
Definition: engine.c:47
@ EXPRVAL_IDREF
Definition: engine.c:46
IDispatch * disp
Definition: engine.c:53
DISPID id
Definition: engine.c:54
Definition: dispex.c:889
instr_arg_t arg[2]
Definition: engine.h:136
jsop_t op
Definition: engine.h:133
double dbl
Definition: engine.h:137
union instr_t::@435 u
unsigned loc
Definition: engine.h:134
const builtin_info_t * builtin_info
Definition: jscript.h:218
jsdisp_t * prototype
Definition: jscript.h:216
LONG ref
Definition: jscript.h:204
script_ctx_t * ctx
Definition: jscript.h:214
Definition: copy.c:22
Definition: parser.c:49
local_ref_t * locals
Definition: engine.h:156
unsigned locals_cnt
Definition: engine.h:155
int ref
Definition: engine.h:149
BSTR name
Definition: engine.h:148
Definition: name.c:39
jsdisp_t * script_obj
Definition: jscript.h:150
Definition: send.c:48
Definition: tools.h:99
unsigned argc
Definition: engine.h:229
jsval_t var[]
Definition: engine.h:230
function_code_t * func_code
Definition: engine.h:228
#define max(a, b)
Definition: svc.c:63
#define bsearch
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
int32_t INT
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t UINT32
Definition: typedefs.h:59
unsigned uint
Definition: engine.h:118
LONG lng
Definition: engine.h:116
jsstr_t * str
Definition: engine.h:117
BSTR bstr
Definition: engine.h:115
Definition: pdh_main.c:96
_In_ size_t cnt
Definition: wcstombs.cpp:43
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3994
void * arg
Definition: msvc.h:10
#define HRESULT
Definition: msvc.h:7
#define DISP_E_EXCEPTION
Definition: winerror.h:3621
#define DISP_E_UNKNOWNNAME
Definition: winerror.h:3618