ReactOS 0.4.17-dev-357-ga8f14ff
engine.c File Reference
#include <math.h>
#include <assert.h>
#include "jscript.h"
#include "engine.h"
#include "wine/debug.h"
Include dependency graph for engine.c:

Go to the source code of this file.

Classes

struct  _except_frame_t
 
struct  exprval_t
 

Macros

#define X(x, a, b, c)   interp_##x,
 
#define X(a, x, b, c)   x,
 

Typedefs

typedef HRESULT(* op_func_t) (script_ctx_t *)
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (jscript)
 
static HRESULT stack_push (script_ctx_t *ctx, jsval_t v)
 
static HRESULT stack_push_string (script_ctx_t *ctx, const WCHAR *str)
 
static jsval_t stack_top (script_ctx_t *ctx)
 
static jsval_tstack_top_ref (script_ctx_t *ctx, unsigned n)
 
static jsval_t stack_topn (script_ctx_t *ctx, unsigned n)
 
static jsval_tstack_args (script_ctx_t *ctx, unsigned n)
 
static jsval_t stack_pop (script_ctx_t *ctx)
 
static void stack_popn (script_ctx_t *ctx, unsigned n)
 
static HRESULT stack_pop_number (script_ctx_t *ctx, double *r)
 
static HRESULT stack_pop_object (script_ctx_t *ctx, IDispatch **r)
 
static HRESULT stack_pop_int (script_ctx_t *ctx, INT *r)
 
static HRESULT stack_pop_uint (script_ctx_t *ctx, UINT32 *r)
 
static unsigned local_off (call_frame_t *frame, int ref)
 
static BSTR local_name (call_frame_t *frame, int ref)
 
static jsval_tget_detached_var_ref (scope_chain_t *scope, const WCHAR *name)
 
static HRESULT get_detached_var_dispid (scope_chain_t *scope, const WCHAR *name, DISPID *id)
 
static HRESULT stack_push_exprval (script_ctx_t *ctx, exprval_t *val)
 
static BOOL stack_topn_exprval (script_ctx_t *ctx, unsigned n, exprval_t *r)
 
static BOOL stack_pop_exprval (script_ctx_t *ctx, exprval_t *r)
 
static HRESULT exprval_propput (script_ctx_t *ctx, exprval_t *ref, jsval_t v)
 
static HRESULT exprval_propget (script_ctx_t *ctx, exprval_t *ref, jsval_t *r)
 
static HRESULT exprval_call (script_ctx_t *ctx, exprval_t *ref, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 
static HRESULT exprval_to_value (script_ctx_t *ctx, exprval_t *ref, jsval_t *r)
 
static void exprval_release (exprval_t *val)
 
static void exprval_set_exception (exprval_t *val, HRESULT hres)
 
static void exprval_set_disp_ref (exprval_t *ref, IDispatch *obj, DISPID id)
 
static jsval_t steal_ret (call_frame_t *frame)
 
static void clear_acc (script_ctx_t *ctx)
 
static scope_chain_tscope_from_dispex (jsdisp_t *dispex)
 
static void scope_destructor (jsdisp_t *dispex)
 
static HRESULT scope_lookup_prop (jsdisp_t *jsdisp, const WCHAR *name, unsigned flags, struct property_info *desc)
 
static HRESULT scope_prop_get (jsdisp_t *dispex, unsigned idx, jsval_t *r)
 
static HRESULT scope_prop_put (jsdisp_t *dispex, unsigned idx, jsval_t val)
 
static HRESULT scope_gc_traverse (struct gc_ctx *gc_ctx, enum gc_traverse_op op, jsdisp_t *dispex)
 
static HRESULT scope_push (script_ctx_t *ctx, scope_chain_t *scope, IDispatch *obj, scope_chain_t **ret)
 
static void scope_pop (scope_chain_t **scope)
 
static HRESULT disp_get_id (script_ctx_t *ctx, IDispatch *disp, const WCHAR *name, BSTR name_bstr, DWORD flags, DISPID *id)
 
static HRESULT disp_cmp (IDispatch *disp1, IDispatch *disp2, BOOL *ret)
 
HRESULT jsval_strict_equal (jsval_t lval, jsval_t rval, BOOL *ret)
 
static HRESULT alloc_detached_vars (script_ctx_t *ctx, call_frame_t *frame, scope_chain_t *scope)
 
static HRESULT detach_scope (script_ctx_t *ctx, call_frame_t *frame, scope_chain_t *scope)
 
static HRESULT detach_scope_chain (script_ctx_t *ctx, call_frame_t *frame, scope_chain_t *scope)
 
static HRESULT detach_variable_object (script_ctx_t *ctx, call_frame_t *frame, BOOL from_release)
 
static BOOL lookup_global_members (script_ctx_t *ctx, BSTR identifier, exprval_t *ret)
 
IDispatchlookup_global_host (script_ctx_t *ctx)
 
static int __cdecl local_ref_cmp (const void *key, const void *ref)
 
local_ref_tlookup_local (const function_code_t *function, const WCHAR *identifier, unsigned int scope)
 
static HRESULT identifier_eval (script_ctx_t *ctx, BSTR identifier, exprval_t *ret)
 
static BSTR get_op_bstr (script_ctx_t *ctx, int i)
 
static unsigned get_op_uint (script_ctx_t *ctx, int i)
 
static unsigned get_op_int (script_ctx_t *ctx, int i)
 
static jsstr_tget_op_str (script_ctx_t *ctx, int i)
 
static double get_op_double (script_ctx_t *ctx)
 
static void jmp_next (script_ctx_t *ctx)
 
static void jmp_abs (script_ctx_t *ctx, unsigned dst)
 
static HRESULT interp_forin (script_ctx_t *ctx)
 
static HRESULT scope_init_locals (script_ctx_t *ctx)
 
static HRESULT interp_push_with_scope (script_ctx_t *ctx)
 
static HRESULT interp_push_block_scope (script_ctx_t *ctx)
 
static HRESULT interp_pop_scope (script_ctx_t *ctx)
 
static HRESULT interp_case (script_ctx_t *ctx)
 
static void set_error_value (script_ctx_t *ctx, jsval_t value)
 
static HRESULT interp_throw (script_ctx_t *ctx)
 
static HRESULT interp_throw_ref (script_ctx_t *ctx)
 
static HRESULT interp_throw_type (script_ctx_t *ctx)
 
static HRESULT interp_push_except (script_ctx_t *ctx)
 
static HRESULT interp_pop_except (script_ctx_t *ctx)
 
static HRESULT interp_end_finally (script_ctx_t *ctx)
 
static HRESULT interp_enter_catch (script_ctx_t *ctx)
 
static HRESULT interp_func (script_ctx_t *ctx)
 
static HRESULT interp_array (script_ctx_t *ctx)
 
static HRESULT interp_member (script_ctx_t *ctx)
 
static HRESULT interp_memberid (script_ctx_t *ctx)
 
static HRESULT interp_refval (script_ctx_t *ctx)
 
static HRESULT interp_new (script_ctx_t *ctx)
 
static HRESULT interp_call (script_ctx_t *ctx)
 
static HRESULT interp_call_member (script_ctx_t *ctx)
 
static HRESULT interp_call_eval (script_ctx_t *ctx)
 
static HRESULT interp_this (script_ctx_t *ctx)
 
static HRESULT interp_identifier_ref (script_ctx_t *ctx, BSTR identifier, unsigned flags)
 
static HRESULT identifier_value (script_ctx_t *ctx, BSTR identifier)
 
static HRESULT interp_local_ref (script_ctx_t *ctx)
 
static HRESULT interp_local (script_ctx_t *ctx)
 
static HRESULT interp_ident (script_ctx_t *ctx)
 
static HRESULT interp_identid (script_ctx_t *ctx)
 
static HRESULT interp_null (script_ctx_t *ctx)
 
static HRESULT interp_bool (script_ctx_t *ctx)
 
static HRESULT interp_int (script_ctx_t *ctx)
 
static HRESULT interp_double (script_ctx_t *ctx)
 
static HRESULT interp_str (script_ctx_t *ctx)
 
static HRESULT interp_regexp (script_ctx_t *ctx)
 
static HRESULT interp_carray (script_ctx_t *ctx)
 
static HRESULT interp_carray_set (script_ctx_t *ctx)
 
static HRESULT interp_new_obj (script_ctx_t *ctx)
 
static HRESULT interp_obj_prop (script_ctx_t *ctx)
 
static HRESULT interp_cnd_nz (script_ctx_t *ctx)
 
static HRESULT interp_cnd_z (script_ctx_t *ctx)
 
static HRESULT interp_or (script_ctx_t *ctx)
 
static HRESULT interp_xor (script_ctx_t *ctx)
 
static HRESULT interp_and (script_ctx_t *ctx)
 
static HRESULT interp_instanceof (script_ctx_t *ctx)
 
static HRESULT interp_in (script_ctx_t *ctx)
 
static HRESULT interp_add (script_ctx_t *ctx)
 
static HRESULT interp_sub (script_ctx_t *ctx)
 
static HRESULT interp_mul (script_ctx_t *ctx)
 
static HRESULT interp_div (script_ctx_t *ctx)
 
static HRESULT interp_mod (script_ctx_t *ctx)
 
static HRESULT interp_delete (script_ctx_t *ctx)
 
static HRESULT interp_delete_ident (script_ctx_t *ctx)
 
static HRESULT interp_void (script_ctx_t *ctx)
 
static HRESULT typeof_string (jsval_t v, const WCHAR **ret)
 
static HRESULT interp_typeofid (script_ctx_t *ctx)
 
static HRESULT interp_typeofident (script_ctx_t *ctx)
 
static HRESULT interp_typeof (script_ctx_t *ctx)
 
static HRESULT interp_minus (script_ctx_t *ctx)
 
static HRESULT interp_tonum (script_ctx_t *ctx)
 
static HRESULT interp_postinc (script_ctx_t *ctx)
 
static HRESULT interp_preinc (script_ctx_t *ctx)
 
static HRESULT equal_values (script_ctx_t *ctx, jsval_t lval, jsval_t rval, BOOL *ret)
 
static HRESULT interp_eq (script_ctx_t *ctx)
 
static HRESULT interp_neq (script_ctx_t *ctx)
 
static HRESULT interp_eq2 (script_ctx_t *ctx)
 
static HRESULT interp_neq2 (script_ctx_t *ctx)
 
static HRESULT less_eval (script_ctx_t *ctx, jsval_t lval, jsval_t rval, BOOL greater, BOOL *ret)
 
static HRESULT interp_lt (script_ctx_t *ctx)
 
static HRESULT interp_lteq (script_ctx_t *ctx)
 
static HRESULT interp_gt (script_ctx_t *ctx)
 
static HRESULT interp_gteq (script_ctx_t *ctx)
 
static HRESULT interp_bneg (script_ctx_t *ctx)
 
static HRESULT interp_neg (script_ctx_t *ctx)
 
static HRESULT interp_lshift (script_ctx_t *ctx)
 
static HRESULT interp_rshift (script_ctx_t *ctx)
 
static HRESULT interp_rshift2 (script_ctx_t *ctx)
 
static HRESULT interp_to_string (script_ctx_t *ctx)
 
static HRESULT interp_assign (script_ctx_t *ctx)
 
static HRESULT interp_set_member (script_ctx_t *ctx)
 
static HRESULT interp_assign_call (script_ctx_t *ctx)
 
static HRESULT interp_undefined (script_ctx_t *ctx)
 
static HRESULT interp_jmp (script_ctx_t *ctx)
 
static HRESULT interp_jmp_z (script_ctx_t *ctx)
 
static HRESULT interp_pop (script_ctx_t *ctx)
 
static HRESULT interp_ret (script_ctx_t *ctx)
 
static HRESULT interp_setret (script_ctx_t *ctx)
 
static HRESULT interp_push_acc (script_ctx_t *ctx)
 
static void pop_call_frame (script_ctx_t *ctx)
 
static void print_backtrace (script_ctx_t *ctx)
 
static HRESULT unwind_exception (script_ctx_t *ctx, HRESULT exception_hres)
 
static HRESULT enter_bytecode (script_ctx_t *ctx, jsval_t *r)
 
static HRESULT bind_event_target (script_ctx_t *ctx, function_code_t *func, jsdisp_t *func_obj)
 
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)
 
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)
 

Variables

static const size_t stack_size = 0x40000
 
static const builtin_info_t scope_info
 
static const op_func_t op_funcs []
 
static const unsigned op_move []
 

Macro Definition Documentation

◆ X [1/2]

#define X (   a,
  x,
  b,
  c 
)    x,

◆ X [2/2]

#define X (   x,
  a,
  b,
  c 
)    interp_##x,

Typedef Documentation

◆ op_func_t

typedef HRESULT(* op_func_t) (script_ctx_t *)

Definition at line 3099 of file engine.c.

Function Documentation

◆ alloc_detached_vars()

static HRESULT alloc_detached_vars ( script_ctx_t ctx,
call_frame_t frame,
scope_chain_t scope 
)
static

Definition at line 720 of file engine.c.

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}
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define malloc
Definition: debug_ros.c:4
MonoAssembly int argc
Definition: metahost.c:107
static bytecode_t * bytecode_addref(bytecode_t *code)
Definition: engine.h:221
GLenum func
Definition: glext.h:6028
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
#define S_OK
Definition: intsafe.h:52
static jsval_t jsval_undefined(void)
Definition: jsval.h:146
const char * var
Definition: shader.c:5666
unsigned argc
Definition: engine.h:293
scope_chain_t * base_scope
Definition: engine.h:283
function_code_t * function
Definition: engine.h:300
unsigned arguments_off
Definition: engine.h:295
struct vars_buffer * detached_vars
Definition: engine.h:237
#define max(a, b)
Definition: svc.c:63
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255

Referenced by detach_scope().

◆ bind_event_target()

static HRESULT bind_event_target ( script_ctx_t ctx,
function_code_t func,
jsdisp_t func_obj 
)
static

Definition at line 3310 of file engine.c.

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}
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
static HRESULT identifier_eval(script_ctx_t *ctx, BSTR identifier, exprval_t *ret)
Definition: engine.c:872
static HRESULT exprval_to_value(script_ctx_t *ctx, exprval_t *ref, jsval_t *r)
Definition: engine.c:401
const GLdouble * v
Definition: gl.h:2040
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
static IDispatch * to_disp(jsdisp_t *jsdisp)
Definition: jscript.h:222
const char * debugstr_jsval(const jsval_t)
Definition: jsutils.c:35
void jsval_release(jsval_t val)
Definition: jsutils.c:186
static IDispatch * get_object(jsval_t v)
Definition: jsval.h:228
static BOOL is_object_instance(jsval_t v)
Definition: jsval.h:175
HRESULT hres
Definition: protocol.c:465
Definition: jsval.h:54
Definition: tools.h:99

Referenced by exec_source().

◆ clear_acc()

static void clear_acc ( script_ctx_t ctx)
inlinestatic

Definition at line 458 of file engine.c.

459{
460 jsval_release(ctx->acc);
461 ctx->acc = jsval_undefined();
462}

Referenced by interp_call(), interp_call_eval(), interp_call_member(), and interp_new().

◆ detach_scope()

static HRESULT detach_scope ( script_ctx_t ctx,
call_frame_t frame,
scope_chain_t scope 
)
static

Definition at line 743 of file engine.c.

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}
#define index(s, c)
Definition: various.h:29
#define NULL
Definition: types.h:112
#define assert(_expr)
Definition: assert.h:32
static unsigned local_off(call_frame_t *frame, int ref)
Definition: engine.c:157
static HRESULT alloc_detached_vars(script_ctx_t *ctx, call_frame_t *frame, scope_chain_t *scope)
Definition: engine.c:720
#define INVALID_LOCAL_REF
Definition: engine.h:152
GLuint index
Definition: glext.h:6031
HRESULT jsdisp_propput_name(jsdisp_t *obj, const WCHAR *name, jsval_t val)
Definition: dispex.c:2859
jsdisp_t * as_jsdisp(IDispatch *disp)
Definition: dispex.c:2441
HRESULT create_dispex(script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype, jsdisp_t **dispex)
Definition: dispex.c:2493
#define SCRIPTLANGUAGEVERSION_ES5
Definition: jscript.h:53
static jsval_t jsval_obj(jsdisp_t *obj)
Definition: jsval.h:125
short WCHAR
Definition: pedump.c:58
jsdisp_t * variable_obj
Definition: engine.h:289
jsdisp_t * function_instance
Definition: engine.h:288
struct _function_code_t::@436 * variables
local_ref_scopes_t * local_scopes
Definition: engine.h:180
IDispatch * obj
Definition: engine.h:235
unsigned int scope_index
Definition: engine.h:236
struct _call_frame_t * frame
Definition: engine.h:238
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
Definition: send.c:48

Referenced by detach_scope_chain().

◆ detach_scope_chain()

static HRESULT detach_scope_chain ( script_ctx_t ctx,
call_frame_t frame,
scope_chain_t scope 
)
static

Definition at line 790 of file engine.c.

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}
static HRESULT detach_scope(script_ctx_t *ctx, call_frame_t *frame, scope_chain_t *scope)
Definition: engine.c:743
static HRESULT detach_scope_chain(script_ctx_t *ctx, call_frame_t *frame, scope_chain_t *scope)
Definition: engine.c:790
struct _scope_chain_t * next
Definition: engine.h:239

Referenced by detach_scope_chain(), and detach_variable_object().

◆ detach_variable_object()

static HRESULT detach_variable_object ( script_ctx_t ctx,
call_frame_t frame,
BOOL  from_release 
)
static

Definition at line 803 of file engine.c.

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}
HRESULT setup_arguments_object(script_ctx_t *, call_frame_t *)
Definition: function.c:259
#define TRACE(s)
Definition: solgame.cpp:4
jsdisp_t * arguments_obj
Definition: engine.h:290

Referenced by exec_source(), identifier_eval(), interp_pop_scope(), and pop_call_frame().

◆ disp_cmp()

static HRESULT disp_cmp ( IDispatch disp1,
IDispatch disp2,
BOOL ret 
)
static

Definition at line 633 of file engine.c.

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}
const GUID IID_IUnknown
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
return ret
Definition: mutex.c:146
IWineJSDispatchHost * get_host_dispatch(IDispatch *disp)
Definition: dispex.c:3584
static DWORD unk1
Definition: cursoricon.c:1804

Referenced by interp_instanceof(), and jsval_strict_equal().

◆ disp_get_id()

static HRESULT disp_get_id ( script_ctx_t ctx,
IDispatch disp,
const WCHAR name,
BSTR  name_bstr,
DWORD  flags,
DISPID id 
)
static

Definition at line 599 of file engine.c.

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}
OLECHAR * BSTR
Definition: compat.h:2293
GLbitfield flags
Definition: glext.h:7161
HRESULT jsdisp_get_id(jsdisp_t *jsdisp, const WCHAR *name, DWORD flags, DISPID *id)
Definition: dispex.c:2550
jsdisp_t * to_jsdisp(IDispatch *disp)
Definition: dispex.c:2447
static DWORD make_grfdex(script_ctx_t *ctx, DWORD flags)
Definition: jscript.h:513
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
#define IID_NULL
Definition: guiddef.h:98

Referenced by do_mcall(), exec_source(), identifier_eval(), interp_array(), interp_assign_member(), interp_in(), interp_member(), interp_memberid(), interp_set_member(), lookup_global_members(), and lookup_identifier().

◆ enter_bytecode()

static HRESULT enter_bytecode ( script_ctx_t ctx,
jsval_t r 
)
static

Definition at line 3271 of file engine.c.

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}
UINT op
Definition: effect.c:236
static void pop_call_frame(script_ctx_t *ctx)
Definition: engine.c:3113
static HRESULT unwind_exception(script_ctx_t *ctx, HRESULT exception_hres)
Definition: engine.c:3183
static const unsigned op_move[]
Definition: engine.c:3107
static const op_func_t op_funcs[]
Definition: engine.c:3101
static jsval_t steal_ret(call_frame_t *frame)
Definition: engine.c:451
#define EXEC_RETURN_TO_INTERP
Definition: engine.h:307
jsop_t
Definition: engine.h:105
unsigned long DWORD
Definition: ntddk_ex.h:95
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
instr_t * instrs
Definition: engine.h:195
unsigned ip
Definition: engine.h:279
bytecode_t * bytecode
Definition: engine.h:299
DWORD flags
Definition: engine.h:291
scope_chain_t * scope
Definition: engine.h:282
unsigned stack_base
Definition: engine.h:281
jsop_t op
Definition: engine.h:133

Referenced by exec_source().

◆ equal_values()

static HRESULT equal_values ( script_ctx_t ctx,
jsval_t  lval,
jsval_t  rval,
BOOL ret 
)
static

Definition at line 2539 of file engine.c.

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}
float rval
Definition: cylfrac.c:48
static BOOL get_bool(D3DXPARAMETER_TYPE type, const void *data)
static HRESULT equal_values(script_ctx_t *ctx, jsval_t lval, jsval_t rval, BOOL *ret)
Definition: engine.c:2539
HRESULT jsval_strict_equal(jsval_t lval, jsval_t rval, BOOL *ret)
Definition: engine.c:684
GLdouble n
Definition: glext.h:7729
@ NO_HINT
Definition: jscript.h:309
HRESULT to_primitive(script_ctx_t *, jsval_t, jsval_t *, hint_t)
Definition: jsutils.c:423
HRESULT to_number(script_ctx_t *, jsval_t, double *)
Definition: jsutils.c:630
static BOOL is_number(jsval_t v)
Definition: jsval.h:200
static jsval_type_t jsval_type(jsval_t v)
Definition: jsval.h:219
static BOOL is_undefined(jsval_t v)
Definition: jsval.h:180
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
LOCAL int prim(arg_t *ap)
Definition: match.c:440
static BOOL is_string(parse_buffer *buf)
Definition: parsing.c:600

Referenced by equal_values(), interp_eq(), and interp_neq().

◆ exec_source()

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 at line 3425 of file engine.c.

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}
#define free
Definition: debug_ros.c:5
HRESULT create_named_item_script_obj(script_ctx_t *ctx, named_item_t *item)
Definition: jscript.c:124
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 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 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 const size_t stack_size
Definition: engine.c:61
static HRESULT enter_bytecode(script_ctx_t *ctx, jsval_t *r)
Definition: engine.c:3271
static scope_chain_t * scope_addref(scope_chain_t *scope)
Definition: engine.h:242
#define EXEC_GLOBAL
Definition: engine.h:305
HRESULT create_source_function(script_ctx_t *, bytecode_t *, function_code_t *, scope_chain_t *, jsdisp_t **)
Definition: function.c:953
#define EXEC_EVAL
Definition: engine.h:308
GLuint id
Definition: glext.h:5910
void release_bytecode(bytecode_t *code)
Definition: compile.c:2459
ULONG jsdisp_release(jsdisp_t *obj)
Definition: dispex.c:1911
jsdisp_t * jsdisp_addref(jsdisp_t *obj)
Definition: dispex.c:1902
@ JSCLASS_GLOBAL
Definition: jscript.h:110
#define debugstr_w
Definition: kernel32.h:32
static VARIANTARG static DISPID
Definition: ordinal.c:49
#define argv
Definition: mplay32.c:18
#define calloc
Definition: rosglue.h:14
named_item_t * named_item
Definition: engine.h:199
IDispatch * this_obj
Definition: engine.h:287
struct _call_frame_t * prev_frame
Definition: engine.h:302
jsval_t ret
Definition: engine.h:285
unsigned var_cnt
Definition: engine.h:171
struct _function_code_t * funcs
Definition: engine.h:169
unsigned func_cnt
Definition: engine.h:168
unsigned instr_off
Definition: engine.h:163
jsclass_t class
Definition: jscript.h:183
const builtin_info_t * builtin_info
Definition: jscript.h:218
jsdisp_t * script_obj
Definition: jscript.h:150

Referenced by builtin_eval(), exec_global_code(), and InterpretedFunction_call().

◆ exprval_call()

static HRESULT exprval_call ( script_ctx_t ctx,
exprval_t ref,
WORD  flags,
unsigned  argc,
jsval_t argv,
jsval_t r 
)
static

Definition at line 349 of file engine.c.

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}
#define E_FAIL
Definition: ddrawi.h:102
HRESULT disp_propget(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t *val)
Definition: dispex.c:2994
HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, unsigned argc, jsval_t *argv, jsval_t *ret)
Definition: dispex.c:2666
static 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
HRESULT to_object(script_ctx_t *, jsval_t, IDispatch **)
Definition: jsutils.c:864
@ JSCLASS_NONE
Definition: jscript.h:103

Referenced by interp_assign_call(), interp_call_eval(), and interp_call_member().

◆ exprval_propget()

static HRESULT exprval_propget ( script_ctx_t ctx,
exprval_t ref,
jsval_t r 
)
static

Definition at line 334 of file engine.c.

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}
HRESULT jsval_copy(jsval_t v, jsval_t *r)
Definition: jsutils.c:225

Referenced by exprval_to_value(), interp_call_eval(), interp_postinc(), interp_preinc(), interp_refval(), and interp_typeofid().

◆ exprval_propput()

static HRESULT exprval_propput ( script_ctx_t ctx,
exprval_t ref,
jsval_t  v 
)
static

Definition at line 315 of file engine.c.

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}
HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t val)
Definition: dispex.c:2872

Referenced by interp_assign(), interp_forin(), interp_postinc(), and interp_preinc().

◆ exprval_release()

static void exprval_release ( exprval_t val)
static

Definition at line 417 of file engine.c.

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}
GLuint GLfloat * val
Definition: glext.h:7180

Referenced by interp_assign(), interp_call_eval(), interp_delete_ident(), interp_identifier_ref(), interp_postinc(), interp_preinc(), and interp_typeofid().

◆ exprval_set_disp_ref()

static void exprval_set_disp_ref ( exprval_t ref,
IDispatch obj,
DISPID  id 
)
inlinestatic

Definition at line 439 of file engine.c.

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}

Referenced by identifier_eval(), interp_identifier_ref(), and lookup_global_members().

◆ exprval_set_exception()

static void exprval_set_exception ( exprval_t val,
HRESULT  hres 
)
inlinestatic

Definition at line 433 of file engine.c.

434{
435 val->type = EXPRVAL_INVALID;
436 val->u.hres = hres;
437}

Referenced by identifier_eval(), interp_identifier_ref(), and interp_memberid().

◆ exprval_to_value()

static HRESULT exprval_to_value ( script_ctx_t ctx,
exprval_t ref,
jsval_t r 
)
static

Definition at line 401 of file engine.c.

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}
static HRESULT exprval_propget(script_ctx_t *ctx, exprval_t *ref, jsval_t *r)
Definition: engine.c:334

Referenced by bind_event_target(), identifier_value(), and interp_typeofident().

◆ get_detached_var_dispid()

static HRESULT get_detached_var_dispid ( scope_chain_t scope,
const WCHAR name,
DISPID id 
)
static

Definition at line 180 of file engine.c.

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}
static jsval_t * get_detached_var_ref(scope_chain_t *scope, const WCHAR *name)
Definition: engine.c:169
HRESULT jsdisp_get_idx_id(jsdisp_t *jsdisp, DWORD idx, DISPID *id)
Definition: dispex.c:2573
jsdisp_t dispex
Definition: engine.h:234
#define DISP_E_UNKNOWNNAME
Definition: winerror.h:3618

Referenced by identifier_eval(), and stack_topn_exprval().

◆ get_detached_var_ref()

static jsval_t * get_detached_var_ref ( scope_chain_t scope,
const WCHAR name 
)
static

Definition at line 169 of file engine.c.

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}
local_ref_t * lookup_local(const function_code_t *function, const WCHAR *identifier, unsigned int scope)
Definition: engine.c:865
jsval_t var[]
Definition: engine.h:230
function_code_t * func_code
Definition: engine.h:228

Referenced by get_detached_var_dispid().

◆ get_op_bstr()

static BSTR get_op_bstr ( script_ctx_t ctx,
int  i 
)
inlinestatic

Definition at line 962 of file engine.c.

963{
964 call_frame_t *frame = ctx->call_ctx;
965 return frame->bytecode->instrs[frame->ip].u.arg[i].bstr;
966}
instr_arg_t arg[2]
Definition: engine.h:136
union instr_t::@435 u
BSTR bstr
Definition: engine.h:115

Referenced by interp_delete_ident(), interp_enter_catch(), interp_ident(), interp_identid(), interp_member(), and interp_typeofident().

◆ get_op_double()

static double get_op_double ( script_ctx_t ctx)
inlinestatic

Definition at line 986 of file engine.c.

987{
988 call_frame_t *frame = ctx->call_ctx;
989 return frame->bytecode->instrs[frame->ip].u.dbl;
990}
double dbl
Definition: engine.h:137

Referenced by interp_double().

◆ get_op_int()

static unsigned get_op_int ( script_ctx_t ctx,
int  i 
)
inlinestatic

Definition at line 974 of file engine.c.

975{
976 call_frame_t *frame = ctx->call_ctx;
977 return frame->bytecode->instrs[frame->ip].u.arg[i].lng;
978}
LONG lng
Definition: engine.h:116

Referenced by interp_bool(), interp_call(), interp_call_eval(), interp_call_member(), interp_int(), interp_local(), interp_local_ref(), interp_postinc(), and interp_preinc().

◆ get_op_str()

static jsstr_t * get_op_str ( script_ctx_t ctx,
int  i 
)
inlinestatic

Definition at line 980 of file engine.c.

981{
982 call_frame_t *frame = ctx->call_ctx;
983 return frame->bytecode->instrs[frame->ip].u.arg[i].str;
984}
jsstr_t * str
Definition: engine.h:117

Referenced by interp_obj_prop(), interp_regexp(), interp_str(), and interp_throw_type().

◆ get_op_uint()

◆ identifier_eval()

static HRESULT identifier_eval ( script_ctx_t ctx,
BSTR  identifier,
exprval_t ret 
)
static

Definition at line 872 of file engine.c.

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}
named_item_t * lookup_named_item(script_ctx_t *ctx, const WCHAR *item_name, unsigned flags)
Definition: jscript.c:162
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
#define L(x)
Definition: resources.c:13
static void exprval_set_disp_ref(exprval_t *ref, IDispatch *obj, DISPID id)
Definition: engine.c:439
static void exprval_set_exception(exprval_t *val, HRESULT hres)
Definition: engine.c:433
static HRESULT get_detached_var_dispid(scope_chain_t *scope, const WCHAR *name, DISPID *id)
Definition: engine.c:180
#define JS_E_UNDEFINED_VARIABLE
Definition: jscript.h:557
static jsval_t jsval_disp(IDispatch *obj)
Definition: jsval.h:117

Referenced by bind_event_target(), identifier_value(), interp_call_eval(), interp_delete_ident(), interp_identifier_ref(), and interp_typeofident().

◆ identifier_value()

static HRESULT identifier_value ( script_ctx_t ctx,
BSTR  identifier 
)
static

Definition at line 1680 of file engine.c.

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}
HRESULT throw_error(script_ctx_t *ctx, HRESULT error, const WCHAR *str)
Definition: error.c:398
static HRESULT stack_push(script_ctx_t *ctx, jsval_t v)
Definition: engine.c:63
HRESULT hres
Definition: engine.c:57
union exprval_t::@433 u
enum exprval_t::@432 type

Referenced by interp_ident(), and interp_local().

◆ interp_add()

static HRESULT interp_add ( script_ctx_t ctx)
static

Definition at line 2113 of file engine.c.

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}
r l[0]
Definition: byte_order.h:168
static jsval_t stack_pop(script_ctx_t *ctx)
Definition: engine.c:108
static HRESULT to_string(VARIANT *src, BSTR *dst)
Definition: host.c:46
jsstr_t * jsstr_concat(jsstr_t *str1, jsstr_t *str2)
Definition: jsstr.c:214
static void jsstr_release(jsstr_t *str)
Definition: jsstr.h:107
static jsval_t jsval_string(jsstr_t *str)
Definition: jsval.h:109
ULONG nr
Definition: thread.c:7
LOCAL char * rstr(char *s1, char *s2)
Definition: tree.c:165
Definition: jsstr.h:36

◆ interp_and()

static HRESULT interp_and ( script_ctx_t ctx)
static

Definition at line 2000 of file engine.c.

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}
static HRESULT stack_pop_int(script_ctx_t *ctx, INT *r)
Definition: engine.c:147
int32_t INT
Definition: typedefs.h:58

◆ interp_array()

static HRESULT interp_array ( script_ctx_t ctx)
static

Definition at line 1399 of file engine.c.

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}
static HRESULT stack_pop_object(script_ctx_t *ctx, IDispatch **r)
Definition: engine.c:131
HRESULT to_flat_string(script_ctx_t *, jsval_t, jsstr_t **, const WCHAR **)
Definition: jsutils.c:846

◆ interp_assign()

static HRESULT interp_assign ( script_ctx_t ctx)
static

Definition at line 2925 of file engine.c.

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}
static HRESULT exprval_propput(script_ctx_t *ctx, exprval_t *ref, jsval_t v)
Definition: engine.c:315
static void exprval_release(exprval_t *val)
Definition: engine.c:417
static BOOL stack_pop_exprval(script_ctx_t *ctx, exprval_t *r)
Definition: engine.c:308
#define JS_E_ILLEGAL_ASSIGN
Definition: jscript.h:556

◆ interp_assign_call()

static HRESULT interp_assign_call ( script_ctx_t ctx)
static

Definition at line 2986 of file engine.c.

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}
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 jsval_t * stack_args(script_ctx_t *ctx, unsigned n)
Definition: engine.c:100
static unsigned get_op_uint(script_ctx_t *ctx, int i)
Definition: engine.c:968
static void stack_popn(script_ctx_t *ctx, unsigned n)
Definition: engine.c:114
static BOOL stack_topn_exprval(script_ctx_t *ctx, unsigned n, exprval_t *r)
Definition: engine.c:220
#define DISPATCH_PROPERTYPUT
Definition: oleauto.h:1008

◆ interp_bneg()

static HRESULT interp_bneg ( script_ctx_t ctx)
static

Definition at line 2817 of file engine.c.

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}
HRESULT to_int32(script_ctx_t *, jsval_t, INT *)
Definition: jsutils.c:735

◆ interp_bool()

static HRESULT interp_bool ( script_ctx_t ctx)
static

Definition at line 1767 of file engine.c.

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}
static unsigned get_op_int(script_ctx_t *ctx, int i)
Definition: engine.c:974
static jsval_t jsval_bool(BOOL b)
Definition: jsval.h:101

◆ interp_call()

static HRESULT interp_call ( script_ctx_t ctx)
static

Definition at line 1559 of file engine.c.

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}
static jsval_t stack_topn(script_ctx_t *ctx, unsigned n)
Definition: engine.c:95
static void clear_acc(script_ctx_t *ctx)
Definition: engine.c:458
#define DISPATCH_JSCRIPT_CALLEREXECSSOURCE
Definition: jscript.h:98
#define JS_E_INVALID_PROPERTY
Definition: jscript.h:532
#define DISPATCH_METHOD
Definition: oleauto.h:1006

◆ interp_call_eval()

static HRESULT interp_call_eval ( script_ctx_t ctx)
static

Definition at line 1594 of file engine.c.

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}
BOOL is_builtin_eval_func(jsdisp_t *jsdisp)
Definition: function.c:1470
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
script_ctx_t * ctx
Definition: jscript.h:214

◆ interp_call_member()

static HRESULT interp_call_member ( script_ctx_t ctx)
static

Definition at line 1577 of file engine.c.

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}

◆ interp_carray()

static HRESULT interp_carray ( script_ctx_t ctx)
static

Definition at line 1824 of file engine.c.

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}
HRESULT create_array(script_ctx_t *ctx, DWORD length, jsdisp_t **ret)
Definition: array.c:1780
Definition: undname.c:54

◆ interp_carray_set()

static HRESULT interp_carray_set ( script_ctx_t ctx)
static

Definition at line 1839 of file engine.c.

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}
static jsval_t stack_top(script_ctx_t *ctx)
Definition: engine.c:83
HRESULT jsdisp_propput_idx(jsdisp_t *obj, DWORD idx, jsval_t val)
Definition: dispex.c:2864
Definition: pdh_main.c:96

◆ interp_case()

static HRESULT interp_case ( script_ctx_t ctx)
static

Definition at line 1189 of file engine.c.

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}
static void jmp_abs(script_ctx_t *ctx, unsigned dst)
Definition: engine.c:997
static void jmp_next(script_ctx_t *ctx)
Definition: engine.c:992
unsigned int BOOL
Definition: ntddk_ex.h:94
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define b
Definition: ke_i.h:79

◆ interp_cnd_nz()

static HRESULT interp_cnd_nz ( script_ctx_t ctx)
static

Definition at line 1918 of file engine.c.

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}
HRESULT to_boolean(jsval_t, BOOL *)
Definition: jsutils.c:489

◆ interp_cnd_z()

static HRESULT interp_cnd_z ( script_ctx_t ctx)
static

Definition at line 1940 of file engine.c.

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}

◆ interp_delete()

static HRESULT interp_delete ( script_ctx_t ctx)
static

Definition at line 2250 of file engine.c.

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}
HRESULT disp_delete_name(script_ctx_t *ctx, IDispatch *disp, jsstr_t *name, BOOL *ret)
Definition: dispex.c:3112

◆ interp_delete_ident()

static HRESULT interp_delete_ident ( script_ctx_t ctx)
static

Definition at line 2287 of file engine.c.

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}
#define E_NOTIMPL
Definition: ddrawi.h:99
static BSTR get_op_bstr(script_ctx_t *ctx, int i)
Definition: engine.c:962
HRESULT disp_delete(IDispatch *disp, DISPID id, BOOL *ret)
Definition: dispex.c:3038
struct exprval_t::@433::@434 idref

◆ interp_div()

static HRESULT interp_div ( script_ctx_t ctx)
static

Definition at line 2212 of file engine.c.

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}
static HRESULT stack_pop_number(script_ctx_t *ctx, double *r)
Definition: engine.c:120

◆ interp_double()

static HRESULT interp_double ( script_ctx_t ctx)
static

Definition at line 1787 of file engine.c.

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}
static double get_op_double(script_ctx_t *ctx)
Definition: engine.c:986

◆ interp_end_finally()

static HRESULT interp_end_finally ( script_ctx_t ctx)
static

Definition at line 1337 of file engine.c.

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}
static void set_error_value(script_ctx_t *ctx, jsval_t value)
Definition: engine.c:1213
static double get_number(jsval_t v)
Definition: jsval.h:233
#define DISP_E_EXCEPTION
Definition: winerror.h:3621

◆ interp_enter_catch()

static HRESULT interp_enter_catch ( script_ctx_t ctx)
static

Definition at line 1360 of file engine.c.

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}
static HRESULT scope_push(script_ctx_t *ctx, scope_chain_t *scope, IDispatch *obj, scope_chain_t **ret)
Definition: engine.c:564
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3994

◆ interp_eq()

static HRESULT interp_eq ( script_ctx_t ctx)
static

Definition at line 2613 of file engine.c.

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}

◆ interp_eq2()

static HRESULT interp_eq2 ( script_ctx_t ctx)
static

Definition at line 2655 of file engine.c.

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}

◆ interp_forin()

static HRESULT interp_forin ( script_ctx_t ctx)
static

Definition at line 1003 of file engine.c.

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}
jsstr_t * jsstr_alloc_len(const WCHAR *buf, unsigned len)
Definition: jsstr.c:86
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:196
const WCHAR * str

◆ interp_func()

static HRESULT interp_func ( script_ctx_t ctx)
static

Definition at line 1381 of file engine.c.

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}

◆ interp_gt()

static HRESULT interp_gt ( script_ctx_t ctx)
static

Definition at line 2775 of file engine.c.

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}
static HRESULT less_eval(script_ctx_t *ctx, jsval_t lval, jsval_t rval, BOOL greater, BOOL *ret)
Definition: engine.c:2697

◆ interp_gteq()

static HRESULT interp_gteq ( script_ctx_t ctx)
static

Definition at line 2796 of file engine.c.

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}

◆ interp_ident()

static HRESULT interp_ident ( script_ctx_t ctx)
static

Definition at line 1738 of file engine.c.

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}
static HRESULT identifier_value(script_ctx_t *ctx, BSTR identifier)
Definition: engine.c:1680

◆ interp_identid()

static HRESULT interp_identid ( script_ctx_t ctx)
static

Definition at line 1748 of file engine.c.

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}
static HRESULT interp_identifier_ref(script_ctx_t *ctx, BSTR identifier, unsigned flags)
Definition: engine.c:1647

◆ interp_identifier_ref()

static HRESULT interp_identifier_ref ( script_ctx_t ctx,
BSTR  identifier,
unsigned  flags 
)
static

Definition at line 1647 of file engine.c.

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}
static HRESULT stack_push_exprval(script_ctx_t *ctx, exprval_t *val)
Definition: engine.c:187
#define JS_E_OBJECT_EXPECTED
Definition: jscript.h:555

Referenced by interp_identid(), and interp_local_ref().

◆ interp_in()

static HRESULT interp_in ( script_ctx_t ctx)
static

Definition at line 2074 of file engine.c.

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}

◆ interp_instanceof()

static HRESULT interp_instanceof ( script_ctx_t ctx)
static

Definition at line 2019 of file engine.c.

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}
static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, BOOL *ret)
Definition: engine.c:633
jsdisp_t * iface_to_jsdisp(IDispatch *iface)
Definition: dispex.c:2543
HRESULT jsdisp_propget_name(jsdisp_t *obj, const WCHAR *name, jsval_t *val)
Definition: dispex.c:2946
#define JS_E_FUNCTION_EXPECTED
Definition: jscript.h:552
static BOOL is_null_disp(jsval_t v)
Definition: jsval.h:190
jsdisp_t * prototype
Definition: jscript.h:216

◆ interp_int()

static HRESULT interp_int ( script_ctx_t ctx)
static

Definition at line 1777 of file engine.c.

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}

◆ interp_jmp()

static HRESULT interp_jmp ( script_ctx_t ctx)
static

Definition at line 3014 of file engine.c.

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}

◆ interp_jmp_z()

static HRESULT interp_jmp_z ( script_ctx_t ctx)
static

Definition at line 3024 of file engine.c.

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}

◆ interp_local()

static HRESULT interp_local ( script_ctx_t ctx)
static

Definition at line 1717 of file engine.c.

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}
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
static BSTR local_name(call_frame_t *frame, int ref)
Definition: engine.c:164

◆ interp_local_ref()

static HRESULT interp_local_ref ( script_ctx_t ctx)
static

Definition at line 1700 of file engine.c.

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}

◆ interp_lshift()

static HRESULT interp_lshift ( script_ctx_t ctx)
static

Definition at line 2853 of file engine.c.

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}
static HRESULT stack_pop_uint(script_ctx_t *ctx, UINT32 *r)
Definition: engine.c:152
uint32_t UINT32
Definition: typedefs.h:59

◆ interp_lt()

static HRESULT interp_lt ( script_ctx_t ctx)
static

Definition at line 2733 of file engine.c.

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}

◆ interp_lteq()

static HRESULT interp_lteq ( script_ctx_t ctx)
static

Definition at line 2754 of file engine.c.

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}

◆ interp_member()

static HRESULT interp_member ( script_ctx_t ctx)
static

Definition at line 1441 of file engine.c.

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}

◆ interp_memberid()

static HRESULT interp_memberid ( script_ctx_t ctx)
static

Definition at line 1470 of file engine.c.

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}
#define ERR(fmt,...)
Definition: precomp.h:57

◆ interp_minus()

static HRESULT interp_minus ( script_ctx_t ctx)
static

Definition at line 2444 of file engine.c.

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}

◆ interp_mod()

static HRESULT interp_mod ( script_ctx_t ctx)
static

Definition at line 2231 of file engine.c.

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}
_ACRTIMP double __cdecl fmod(double, double)

◆ interp_mul()

static HRESULT interp_mul ( script_ctx_t ctx)
static

Definition at line 2193 of file engine.c.

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}

◆ interp_neg()

static HRESULT interp_neg ( script_ctx_t ctx)
static

Definition at line 2835 of file engine.c.

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}

◆ interp_neq()

static HRESULT interp_neq ( script_ctx_t ctx)
static

Definition at line 2634 of file engine.c.

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}

◆ interp_neq2()

static HRESULT interp_neq2 ( script_ctx_t ctx)
static

Definition at line 2676 of file engine.c.

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}

◆ interp_new()

static HRESULT interp_new ( script_ctx_t ctx)
static

Definition at line 1537 of file engine.c.

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}
#define JS_E_INVALID_ACTION
Definition: jscript.h:533

◆ interp_new_obj()

static HRESULT interp_new_obj ( script_ctx_t ctx)
static

Definition at line 1858 of file engine.c.

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}
HRESULT create_object(script_ctx_t *, jsdisp_t *, jsdisp_t **)
Definition: object.c:1131

◆ interp_null()

static HRESULT interp_null ( script_ctx_t ctx)
static

Definition at line 1759 of file engine.c.

1760{
1761 TRACE("\n");
1762
1763 return stack_push(ctx, jsval_null());
1764}
static jsval_t jsval_null(void)
Definition: jsval.h:130

◆ interp_obj_prop()

static HRESULT interp_obj_prop ( script_ctx_t ctx)
static

Definition at line 1873 of file engine.c.

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}
static jsstr_t * get_op_str(script_ctx_t *ctx, int i)
Definition: engine.c:980
@ PROPERTY_DEFINITION_GETTER
Definition: engine.h:143
@ PROPERTY_DEFINITION_VALUE
Definition: engine.h:142
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
HRESULT jsdisp_define_property(jsdisp_t *obj, const WCHAR *name, property_desc_t *desc)
Definition: dispex.c:3216
const unsigned int PROPF_ENUMERABLE
Definition: jsdisp.idl:36
const unsigned int PROPF_CONFIGURABLE
Definition: jsdisp.idl:38
const char * debugstr_jsstr(jsstr_t *str)
Definition: jsstr.c:37
static const WCHAR * jsstr_flatten(jsstr_t *str)
Definition: jsstr.h:136
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1204

◆ interp_or()

static HRESULT interp_or ( script_ctx_t ctx)
static

Definition at line 1962 of file engine.c.

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}

◆ interp_pop()

static HRESULT interp_pop ( script_ctx_t ctx)
static

Definition at line 3046 of file engine.c.

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}

◆ interp_pop_except()

static HRESULT interp_pop_except ( script_ctx_t ctx)
static

Definition at line 1303 of file engine.c.

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}
#define except(x)
Definition: btrfs_drv.h:136
except_frame_t * except_frame
Definition: engine.h:280
struct define * next
Definition: compiler.c:65

◆ interp_pop_scope()

static HRESULT interp_pop_scope ( script_ctx_t ctx)
static

Definition at line 1174 of file engine.c.

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}
static void scope_pop(scope_chain_t **scope)
Definition: engine.c:590

◆ interp_postinc()

static HRESULT interp_postinc ( script_ctx_t ctx)
static

Definition at line 2477 of file engine.c.

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}

◆ interp_preinc()

static HRESULT interp_preinc ( script_ctx_t ctx)
static

Definition at line 2507 of file engine.c.

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}
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:91

◆ interp_push_acc()

static HRESULT interp_push_acc ( script_ctx_t ctx)
static

Definition at line 3087 of file engine.c.

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}

◆ interp_push_block_scope()

static HRESULT interp_push_block_scope ( script_ctx_t ctx)
static

Definition at line 1155 of file engine.c.

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}
static HRESULT scope_init_locals(script_ctx_t *ctx)
Definition: engine.c:1064

◆ interp_push_except()

static HRESULT interp_push_except ( script_ctx_t ctx)
static

Definition at line 1280 of file engine.c.

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}

◆ interp_push_with_scope()

static HRESULT interp_push_with_scope ( script_ctx_t ctx)
static

Definition at line 1135 of file engine.c.

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}

◆ interp_refval()

static HRESULT interp_refval ( script_ctx_t ctx)
static

Definition at line 1518 of file engine.c.

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}

◆ interp_regexp()

static HRESULT interp_regexp ( script_ctx_t ctx)
static

Definition at line 1807 of file engine.c.

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}
HRESULT create_regexp(script_ctx_t *, jsstr_t *, DWORD, jsdisp_t **)
Definition: jsregexp.c:626

◆ interp_ret()

static HRESULT interp_ret ( script_ctx_t ctx)
static

Definition at line 3056 of file engine.c.

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}
#define EXEC_CONSTRUCTOR
Definition: engine.h:306

◆ interp_rshift()

static HRESULT interp_rshift ( script_ctx_t ctx)
static

Definition at line 2871 of file engine.c.

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}

◆ interp_rshift2()

static HRESULT interp_rshift2 ( script_ctx_t ctx)
static

Definition at line 2889 of file engine.c.

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}

◆ interp_set_member()

static HRESULT interp_set_member ( script_ctx_t ctx)
static

Definition at line 2951 of file engine.c.

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}
HRESULT disp_propput_name(script_ctx_t *ctx, IDispatch *disp, const WCHAR *name, jsval_t val)
Definition: dispex.c:2910
static jsstr_t * get_string(jsval_t v)
Definition: jsval.h:238

◆ interp_setret()

static HRESULT interp_setret ( script_ctx_t ctx)
static

Definition at line 3076 of file engine.c.

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}

◆ interp_str()

static HRESULT interp_str ( script_ctx_t ctx)
static

Definition at line 1797 of file engine.c.

1798{
1799 jsstr_t *str = get_op_str(ctx, 0);
1800
1801 TRACE("%s\n", debugstr_jsstr(str));
1802
1804}
static jsstr_t * jsstr_addref(jsstr_t *str)
Definition: jsstr.h:113

◆ interp_sub()

static HRESULT interp_sub ( script_ctx_t ctx)
static

Definition at line 2174 of file engine.c.

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}

◆ interp_this()

static HRESULT interp_this ( script_ctx_t ctx)
static

Definition at line 1628 of file engine.c.

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}
IDispatch * lookup_global_host(script_ctx_t *ctx)
Definition: engine.c:845

◆ interp_throw()

static HRESULT interp_throw ( script_ctx_t ctx)
static

Definition at line 1250 of file engine.c.

1251{
1252 TRACE("\n");
1253
1255 return DISP_E_EXCEPTION;
1256}

◆ interp_throw_ref()

static HRESULT interp_throw_ref ( script_ctx_t ctx)
static

Definition at line 1258 of file engine.c.

1259{
1260 const HRESULT arg = get_op_uint(ctx, 0);
1261
1262 TRACE("%08lx\n", arg);
1263
1264 return arg;
1265}
void * arg
Definition: msvc.h:10

◆ interp_throw_type()

static HRESULT interp_throw_type ( script_ctx_t ctx)
static

Definition at line 1267 of file engine.c.

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}
static PVOID ptr
Definition: dispmode.c:27

◆ interp_to_string()

static HRESULT interp_to_string ( script_ctx_t ctx)
static

Definition at line 2906 of file engine.c.

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}

◆ interp_tonum()

static HRESULT interp_tonum ( script_ctx_t ctx)
static

Definition at line 2459 of file engine.c.

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}

◆ interp_typeof()

static HRESULT interp_typeof ( script_ctx_t ctx)
static

Definition at line 2426 of file engine.c.

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}
static HRESULT typeof_string(jsval_t v, const WCHAR **ret)
Definition: engine.c:2333
static HRESULT stack_push_string(script_ctx_t *ctx, const WCHAR *str)
Definition: engine.c:72

◆ interp_typeofid()

static HRESULT interp_typeofid ( script_ctx_t ctx)
static

Definition at line 2370 of file engine.c.

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}
jsstr_t * jsstr_undefined(void)
Definition: jsstr.c:296

◆ interp_typeofident()

static HRESULT interp_typeofident ( script_ctx_t ctx)
static

Definition at line 2396 of file engine.c.

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}

◆ interp_undefined()

static HRESULT interp_undefined ( script_ctx_t ctx)
static

Definition at line 3007 of file engine.c.

3008{
3009 TRACE("\n");
3010
3011 return stack_push(ctx, jsval_undefined());
3012}

◆ interp_void()

static HRESULT interp_void ( script_ctx_t ctx)
static

Definition at line 2324 of file engine.c.

2325{
2326 TRACE("\n");
2327
2328 stack_popn(ctx, 1);
2329 return stack_push(ctx, jsval_undefined());
2330}

◆ interp_xor()

static HRESULT interp_xor ( script_ctx_t ctx)
static

Definition at line 1981 of file engine.c.

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}

◆ jmp_abs()

static void jmp_abs ( script_ctx_t ctx,
unsigned  dst 
)
inlinestatic

Definition at line 997 of file engine.c.

998{
999 ctx->call_ctx->ip = dst;
1000}
GLenum GLenum dst
Definition: glext.h:6340

Referenced by interp_case(), interp_cnd_nz(), interp_cnd_z(), interp_forin(), interp_jmp(), interp_jmp_z(), and interp_ret().

◆ jmp_next()

static void jmp_next ( script_ctx_t ctx)
inlinestatic

Definition at line 992 of file engine.c.

993{
994 ctx->call_ctx->ip++;
995}

Referenced by interp_case(), interp_cnd_nz(), interp_cnd_z(), interp_forin(), and interp_jmp_z().

◆ jsval_strict_equal()

HRESULT jsval_strict_equal ( jsval_t  lval,
jsval_t  rval,
BOOL ret 
)

Definition at line 684 of file engine.c.

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}
static BOOL jsstr_eq(jsstr_t *left, jsstr_t *right)
Definition: jsstr.h:173
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

Referenced by Array_indexOf(), Array_lastIndexOf(), equal_values(), interp_case(), interp_eq2(), interp_neq2(), and jsdisp_define_property().

◆ less_eval()

static HRESULT less_eval ( script_ctx_t ctx,
jsval_t  lval,
jsval_t  rval,
BOOL  greater,
BOOL ret 
)
static

Definition at line 2697 of file engine.c.

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}
#define isnan(x)
Definition: math.h:360
int jsstr_cmp(jsstr_t *str1, jsstr_t *str2)
Definition: jsstr.c:192

Referenced by interp_gt(), interp_gteq(), interp_lt(), and interp_lteq().

◆ local_name()

◆ local_off()

static unsigned local_off ( call_frame_t frame,
int  ref 
)
inlinestatic

Definition at line 157 of file engine.c.

158{
159 return ref < 0
160 ? frame->arguments_off - ref-1
161 : frame->variables_off + ref;
162}
unsigned variables_off
Definition: engine.h:296

Referenced by detach_scope(), identifier_eval(), interp_local(), interp_local_ref(), print_backtrace(), scope_init_locals(), and setup_scope().

◆ local_ref_cmp()

static int __cdecl local_ref_cmp ( const void key,
const void ref 
)
static

Definition at line 860 of file engine.c.

861{
862 return wcscmp((const WCHAR*)key, ((const local_ref_t*)ref)->name);
863}
Definition: copy.c:22

Referenced by lookup_local().

◆ lookup_global_host()

IDispatch * lookup_global_host ( script_ctx_t ctx)

Definition at line 845 of file engine.c.

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}
uint32_t entry
Definition: isohybrid.c:63
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198

Referenced by HostFunction_call(), interp_this(), and WineJSDispatch_GetScriptGlobal().

◆ lookup_global_members()

static BOOL lookup_global_members ( script_ctx_t ctx,
BSTR  identifier,
exprval_t ret 
)
static

Definition at line 825 of file engine.c.

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}

Referenced by exec_source(), and identifier_eval().

◆ lookup_local()

local_ref_t * lookup_local ( const function_code_t function,
const WCHAR identifier,
unsigned int  scope 
)

Definition at line 865 of file engine.c.

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}
static int __cdecl local_ref_cmp(const void *key, const void *ref)
Definition: engine.c:860
#define bsearch

Referenced by bind_local(), compile_function(), get_detached_var_ref(), and identifier_eval().

◆ pop_call_frame()

static void pop_call_frame ( script_ctx_t ctx)
static

Definition at line 3113 of file engine.c.

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}
void detach_arguments_object(call_frame_t *)
Definition: function.c:293
static void scope_release(scope_chain_t *scope)
Definition: engine.h:248
unsigned pop_locals
Definition: engine.h:294
unsigned pop_variables
Definition: engine.h:297
LONG ref
Definition: jscript.h:204

Referenced by enter_bytecode(), and unwind_exception().

◆ print_backtrace()

static void print_backtrace ( script_ctx_t ctx)
static

Definition at line 3150 of file engine.c.

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}
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
unsigned get_location_line(bytecode_t *code, unsigned loc, unsigned *char_pos)
Definition: compile.c:2445
UINT64 source_context
Definition: engine.h:202
unsigned loc
Definition: engine.h:134
Definition: parser.c:49

Referenced by unwind_exception().

◆ scope_destructor()

static void scope_destructor ( jsdisp_t dispex)
static

Definition at line 469 of file engine.c.

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}
static scope_chain_t * scope_from_dispex(jsdisp_t *dispex)
Definition: engine.c:464
bytecode_t * bytecode
Definition: engine.h:185
unsigned argc
Definition: engine.h:229
_In_ size_t cnt
Definition: wcstombs.cpp:43

◆ scope_from_dispex()

static scope_chain_t * scope_from_dispex ( jsdisp_t dispex)
inlinestatic

Definition at line 464 of file engine.c.

465{
466 return CONTAINING_RECORD(dispex, scope_chain_t, dispex);
467}
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by scope_destructor(), scope_gc_traverse(), scope_lookup_prop(), scope_prop_get(), and scope_prop_put().

◆ scope_gc_traverse()

static HRESULT scope_gc_traverse ( struct gc_ctx gc_ctx,
enum gc_traverse_op  op,
jsdisp_t dispex 
)
static

Definition at line 520 of file engine.c.

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}
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 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
@ GC_TRAVERSE_UNLINK
Definition: jscript.h:162
Definition: dispex.c:889

◆ scope_init_locals()

static HRESULT scope_init_locals ( script_ctx_t ctx)
static

Definition at line 1064 of file engine.c.

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}

Referenced by interp_push_block_scope().

◆ scope_lookup_prop()

static HRESULT scope_lookup_prop ( jsdisp_t jsdisp,
const WCHAR name,
unsigned  flags,
struct property_info desc 
)
static

Definition at line 490 of file engine.c.

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}
HRESULT jsdisp_index_lookup(jsdisp_t *obj, const WCHAR *name, unsigned length, struct property_info *desc)
Definition: dispex.c:481

◆ scope_pop()

static void scope_pop ( scope_chain_t **  scope)
static

Definition at line 590 of file engine.c.

591{
592 scope_chain_t *tmp;
593
594 tmp = *scope;
595 *scope = tmp->next;
596 scope_release(tmp);
597}

Referenced by interp_pop_scope(), and unwind_exception().

◆ scope_prop_get()

static HRESULT scope_prop_get ( jsdisp_t dispex,
unsigned  idx,
jsval_t r 
)
static

Definition at line 497 of file engine.c.

498{
499 scope_chain_t *scope = scope_from_dispex(dispex);
500
501 return jsval_copy(scope->detached_vars->var[idx], r);
502}
unsigned int idx
Definition: utils.c:41

◆ scope_prop_put()

static HRESULT scope_prop_put ( jsdisp_t dispex,
unsigned  idx,
jsval_t  val 
)
static

Definition at line 504 of file engine.c.

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}

◆ scope_push()

static HRESULT scope_push ( script_ctx_t ctx,
scope_chain_t scope,
IDispatch obj,
scope_chain_t **  ret 
)
static

Definition at line 564 of file engine.c.

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}
static const builtin_info_t scope_info
Definition: engine.c:555
HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype)
Definition: dispex.c:2454

Referenced by interp_enter_catch(), interp_push_block_scope(), interp_push_with_scope(), and setup_scope().

◆ set_error_value()

static void set_error_value ( script_ctx_t ctx,
jsval_t  value 
)
static

Definition at line 1213 of file engine.c.

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}
void reset_ei(jsexcept_t *)
Definition: jscript.c:314
HRESULT to_uint32(script_ctx_t *, jsval_t, UINT32 *)
Definition: jsutils.c:754
#define JS_E_EXCEPTION_THROWN
Definition: jscript.h:566
static unsigned int number
Definition: dsound.c:1479
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

Referenced by interp_end_finally(), and interp_throw().

◆ setup_scope()

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 
)
static

Definition at line 3346 of file engine.c.

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}
unsigned param_cnt
Definition: engine.h:177

Referenced by exec_source().

◆ stack_args()

static jsval_t * stack_args ( script_ctx_t ctx,
unsigned  n 
)
inlinestatic

Definition at line 100 of file engine.c.

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}

Referenced by interp_assign_call(), interp_call(), interp_call_eval(), interp_call_member(), and interp_new().

◆ stack_pop()

◆ stack_pop_exprval()

static BOOL stack_pop_exprval ( script_ctx_t ctx,
exprval_t r 
)
inlinestatic

Definition at line 308 of file engine.c.

309{
311 ctx->stack_top -= 2;
312 return ret;
313}

Referenced by interp_assign(), interp_postinc(), interp_preinc(), and interp_typeofid().

◆ stack_pop_int()

static HRESULT stack_pop_int ( script_ctx_t ctx,
INT r 
)
inlinestatic

Definition at line 147 of file engine.c.

148{
149 return to_int32(ctx, stack_pop(ctx), r);
150}

Referenced by interp_and(), interp_lshift(), interp_or(), interp_rshift(), and interp_xor().

◆ stack_pop_number()

static HRESULT stack_pop_number ( script_ctx_t ctx,
double r 
)
static

Definition at line 120 of file engine.c.

121{
122 jsval_t v;
124
125 v = stack_pop(ctx);
126 hres = to_number(ctx, v, r);
128 return hres;
129}

Referenced by interp_div(), interp_minus(), interp_mod(), interp_mul(), and interp_sub().

◆ stack_pop_object()

static HRESULT stack_pop_object ( script_ctx_t ctx,
IDispatch **  r 
)
static

Definition at line 131 of file engine.c.

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}

Referenced by interp_array(), and interp_member().

◆ stack_pop_uint()

static HRESULT stack_pop_uint ( script_ctx_t ctx,
UINT32 r 
)
inlinestatic

Definition at line 152 of file engine.c.

153{
154 return to_uint32(ctx, stack_pop(ctx), r);
155}

Referenced by interp_lshift(), interp_rshift(), and interp_rshift2().

◆ stack_popn()

static void stack_popn ( script_ctx_t ctx,
unsigned  n 
)
static

◆ stack_push()

◆ stack_push_exprval()

static HRESULT stack_push_exprval ( script_ctx_t ctx,
exprval_t val 
)
static

Definition at line 187 of file engine.c.

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}

Referenced by interp_identifier_ref(), interp_local_ref(), and interp_memberid().

◆ stack_push_string()

static HRESULT stack_push_string ( script_ctx_t ctx,
const WCHAR str 
)
inlinestatic

Definition at line 72 of file engine.c.

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}
static jsstr_t * jsstr_alloc(const WCHAR *str)
Definition: jsstr.h:100

Referenced by interp_typeof(), interp_typeofid(), and interp_typeofident().

◆ stack_top()

◆ stack_top_ref()

static jsval_t * stack_top_ref ( script_ctx_t ctx,
unsigned  n 
)
inlinestatic

Definition at line 89 of file engine.c.

90{
91 assert(ctx->stack_top > ctx->call_ctx->stack_base+n);
92 return ctx->stack+ctx->stack_top-1-n;
93}

Referenced by stack_topn(), and stack_topn_exprval().

◆ stack_topn()

static jsval_t stack_topn ( script_ctx_t ctx,
unsigned  n 
)
inlinestatic

Definition at line 95 of file engine.c.

96{
97 return *stack_top_ref(ctx, n);
98}
static jsval_t * stack_top_ref(script_ctx_t *ctx, unsigned n)
Definition: engine.c:89

Referenced by interp_call(), interp_forin(), interp_new(), and stack_topn_exprval().

◆ stack_topn_exprval()

static BOOL stack_topn_exprval ( script_ctx_t ctx,
unsigned  n,
exprval_t r 
)
static

Definition at line 220 of file engine.c.

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}

Referenced by interp_assign_call(), interp_call_member(), interp_forin(), interp_refval(), and stack_pop_exprval().

◆ steal_ret()

static jsval_t steal_ret ( call_frame_t frame)
inlinestatic

Definition at line 451 of file engine.c.

452{
453 jsval_t r = frame->ret;
454 frame->ret = jsval_undefined();
455 return r;
456}

Referenced by enter_bytecode(), and interp_ret().

◆ typeof_string()

static HRESULT typeof_string ( jsval_t  v,
const WCHAR **  ret 
)
static

Definition at line 2333 of file engine.c.

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}
static const char * debugstr_variant(const VARIANT *var)
Definition: dom.c:505
@ JSCLASS_FUNCTION
Definition: jscript.h:109
static BOOL is_class(jsdisp_t *jsdisp, jsclass_t class)
Definition: jscript.h:503
static VARIANT * get_variant(jsval_t v)
Definition: jsval.h:243

Referenced by interp_typeof(), interp_typeofid(), and interp_typeofident().

◆ unwind_exception()

static HRESULT unwind_exception ( script_ctx_t ctx,
HRESULT  exception_hres 
)
static

Definition at line 3183 of file engine.c.

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}
#define msg(x)
Definition: auth_time.c:54
jsdisp_t * create_builtin_error(script_ctx_t *ctx)
Definition: error.c:448
#define IDS_RUNTIME_ERROR
Definition: resource.h:90
static void print_backtrace(script_ctx_t *ctx)
Definition: engine.c:3150
void set_error_location(jsexcept_t *, bytecode_t *, unsigned, unsigned, jsstr_t *)
Definition: error.c:426
#define WARN_ON(c)
Definition: module.h:257
#define err(...)
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

Referenced by enter_bytecode().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( jscript  )

Variable Documentation

◆ op_funcs

const op_func_t op_funcs[]
static
Initial value:
= {
#define X(x,a,b,c)
}
#define OP_LIST
Definition: engine.h:21

Definition at line 3101 of file engine.c.

Referenced by enter_bytecode().

◆ op_move

const unsigned op_move[]
static
Initial value:
= {
#define X(a,x,b,c)
}

Definition at line 3107 of file engine.c.

Referenced by enter_bytecode().

◆ scope_info

const builtin_info_t scope_info
static
Initial value:
= {
.destructor = scope_destructor,
.lookup_prop = scope_lookup_prop,
.prop_get = scope_prop_get,
.prop_put = scope_prop_put,
.gc_traverse = scope_gc_traverse
}
static HRESULT scope_prop_get(jsdisp_t *dispex, unsigned idx, jsval_t *r)
Definition: engine.c:497
static HRESULT scope_gc_traverse(struct gc_ctx *gc_ctx, enum gc_traverse_op op, jsdisp_t *dispex)
Definition: engine.c:520
static void scope_destructor(jsdisp_t *dispex)
Definition: engine.c:469
static HRESULT scope_lookup_prop(jsdisp_t *jsdisp, const WCHAR *name, unsigned flags, struct property_info *desc)
Definition: engine.c:490
static HRESULT scope_prop_put(jsdisp_t *dispex, unsigned idx, jsval_t val)
Definition: engine.c:504

Definition at line 555 of file engine.c.

Referenced by scope_push().

◆ stack_size