1 /* 2 * Copyright 2008,2011 Jacek Caban for CodeWeavers 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 */ 18 19 #pragma once 20 21 #define OP_LIST \ 22 X(add, 1, 0,0) \ 23 X(and, 1, 0,0) \ 24 X(array, 1, 0,0) \ 25 X(assign, 1, 0,0) \ 26 X(assign_call,1, ARG_UINT, 0) \ 27 X(bool, 1, ARG_INT, 0) \ 28 X(bneg, 1, 0,0) \ 29 X(call, 1, ARG_UINT, ARG_UINT) \ 30 X(call_member,1, ARG_UINT, ARG_UINT) \ 31 X(carray, 1, ARG_UINT, 0) \ 32 X(carray_set, 1, ARG_UINT, 0) \ 33 X(case, 0, ARG_ADDR, 0) \ 34 X(cnd_nz, 0, ARG_ADDR, 0) \ 35 X(cnd_z, 0, ARG_ADDR, 0) \ 36 X(delete, 1, 0,0) \ 37 X(delete_ident,1,ARG_BSTR, 0) \ 38 X(div, 1, 0,0) \ 39 X(double, 1, ARG_DBL, 0) \ 40 X(end_finally,0, 0,0) \ 41 X(enter_catch,1, ARG_BSTR, 0) \ 42 X(eq, 1, 0,0) \ 43 X(eq2, 1, 0,0) \ 44 X(forin, 0, ARG_ADDR, 0) \ 45 X(func, 1, ARG_UINT, 0) \ 46 X(gt, 1, 0,0) \ 47 X(gteq, 1, 0,0) \ 48 X(ident, 1, ARG_BSTR, 0) \ 49 X(identid, 1, ARG_BSTR, ARG_INT) \ 50 X(in, 1, 0,0) \ 51 X(instanceof, 1, 0,0) \ 52 X(int, 1, ARG_INT, 0) \ 53 X(jmp, 0, ARG_ADDR, 0) \ 54 X(jmp_z, 0, ARG_ADDR, 0) \ 55 X(local, 1, ARG_INT, 0) \ 56 X(local_ref, 1, ARG_INT, ARG_UINT) \ 57 X(lshift, 1, 0,0) \ 58 X(lt, 1, 0,0) \ 59 X(lteq, 1, 0,0) \ 60 X(member, 1, ARG_BSTR, 0) \ 61 X(memberid, 1, ARG_UINT, 0) \ 62 X(minus, 1, 0,0) \ 63 X(mod, 1, 0,0) \ 64 X(mul, 1, 0,0) \ 65 X(neg, 1, 0,0) \ 66 X(neq, 1, 0,0) \ 67 X(neq2, 1, 0,0) \ 68 X(new, 1, ARG_UINT, 0) \ 69 X(new_obj, 1, 0,0) \ 70 X(null, 1, 0,0) \ 71 X(obj_prop, 1, ARG_BSTR, 0) \ 72 X(or, 1, 0,0) \ 73 X(pop, 1, ARG_UINT, 0) \ 74 X(pop_except, 0, ARG_ADDR, 0) \ 75 X(pop_scope, 1, 0,0) \ 76 X(postinc, 1, ARG_INT, 0) \ 77 X(preinc, 1, ARG_INT, 0) \ 78 X(push_except,1, ARG_ADDR, ARG_UINT) \ 79 X(push_ret, 1, 0,0) \ 80 X(push_scope, 1, 0,0) \ 81 X(regexp, 1, ARG_STR, ARG_UINT) \ 82 X(rshift, 1, 0,0) \ 83 X(rshift2, 1, 0,0) \ 84 X(str, 1, ARG_STR, 0) \ 85 X(this, 1, 0,0) \ 86 X(throw, 0, 0,0) \ 87 X(throw_ref, 0, ARG_UINT, 0) \ 88 X(throw_type, 0, ARG_UINT, ARG_STR) \ 89 X(tonum, 1, 0,0) \ 90 X(typeof, 1, 0,0) \ 91 X(typeofid, 1, 0,0) \ 92 X(typeofident,1, 0,0) \ 93 X(refval, 1, 0,0) \ 94 X(ret, 0, ARG_UINT, 0) \ 95 X(setret, 1, 0,0) \ 96 X(sub, 1, 0,0) \ 97 X(undefined, 1, 0,0) \ 98 X(void, 1, 0,0) \ 99 X(xor, 1, 0,0) 100 101 typedef enum { 102 #define X(x,a,b,c) OP_##x, 103 OP_LIST 104 #undef X 105 OP_LAST 106 } jsop_t; 107 108 typedef union { 109 BSTR bstr; 110 LONG lng; 111 jsstr_t *str; 112 unsigned uint; 113 } instr_arg_t; 114 115 typedef enum { 116 ARG_NONE = 0, 117 ARG_ADDR, 118 ARG_BSTR, 119 ARG_DBL, 120 ARG_FUNC, 121 ARG_INT, 122 ARG_STR, 123 ARG_UINT 124 } instr_arg_type_t; 125 126 typedef struct { 127 jsop_t op; 128 union { 129 instr_arg_t arg[2]; 130 double dbl; 131 } u; 132 } instr_t; 133 134 typedef struct { 135 BSTR name; 136 int ref; 137 } local_ref_t; 138 139 typedef struct _function_code_t { 140 BSTR name; 141 int local_ref; 142 BSTR event_target; 143 unsigned instr_off; 144 145 const WCHAR *source; 146 unsigned source_len; 147 148 unsigned func_cnt; 149 struct _function_code_t *funcs; 150 151 unsigned var_cnt; 152 struct { 153 BSTR name; 154 int func_id; /* -1 if not a function */ 155 } *variables; 156 157 unsigned param_cnt; 158 BSTR *params; 159 160 unsigned locals_cnt; 161 local_ref_t *locals; 162 } function_code_t; 163 164 local_ref_t *lookup_local(const function_code_t*,const WCHAR*) DECLSPEC_HIDDEN; 165 166 typedef struct _bytecode_t { 167 LONG ref; 168 169 instr_t *instrs; 170 heap_pool_t heap; 171 172 function_code_t global_code; 173 174 WCHAR *source; 175 176 BSTR *bstr_pool; 177 unsigned bstr_pool_size; 178 unsigned bstr_cnt; 179 180 jsstr_t **str_pool; 181 unsigned str_pool_size; 182 unsigned str_cnt; 183 184 struct _bytecode_t *next; 185 } bytecode_t; 186 187 HRESULT compile_script(script_ctx_t*,const WCHAR*,const WCHAR*,const WCHAR*,BOOL,BOOL,bytecode_t**) DECLSPEC_HIDDEN; 188 void release_bytecode(bytecode_t*) DECLSPEC_HIDDEN; 189 190 static inline bytecode_t *bytecode_addref(bytecode_t *code) 191 { 192 code->ref++; 193 return code; 194 } 195 196 typedef struct _scope_chain_t { 197 LONG ref; 198 jsdisp_t *jsobj; 199 IDispatch *obj; 200 struct _call_frame_t *frame; 201 struct _scope_chain_t *next; 202 } scope_chain_t; 203 204 void scope_release(scope_chain_t*) DECLSPEC_HIDDEN; 205 206 static inline scope_chain_t *scope_addref(scope_chain_t *scope) 207 { 208 scope->ref++; 209 return scope; 210 } 211 212 typedef struct _except_frame_t except_frame_t; 213 struct _parser_ctx_t; 214 215 typedef struct _call_frame_t { 216 unsigned ip; 217 except_frame_t *except_frame; 218 unsigned stack_base; 219 scope_chain_t *scope; 220 scope_chain_t *base_scope; 221 222 jsval_t ret; 223 224 IDispatch *this_obj; 225 jsdisp_t *function_instance; 226 jsdisp_t *variable_obj; 227 jsdisp_t *arguments_obj; 228 DWORD flags; 229 230 unsigned argc; 231 unsigned pop_locals; 232 unsigned arguments_off; 233 unsigned variables_off; 234 unsigned pop_variables; 235 236 bytecode_t *bytecode; 237 function_code_t *function; 238 239 struct _call_frame_t *prev_frame; 240 } call_frame_t; 241 242 #define EXEC_GLOBAL 0x0001 243 #define EXEC_CONSTRUCTOR 0x0002 244 #define EXEC_RETURN_TO_INTERP 0x0004 245 #define EXEC_EVAL 0x0008 246 247 HRESULT exec_source(script_ctx_t*,DWORD,bytecode_t*,function_code_t*,scope_chain_t*,IDispatch*, 248 jsdisp_t*,jsdisp_t*,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN; 249 250 HRESULT create_source_function(script_ctx_t*,bytecode_t*,function_code_t*,scope_chain_t*,jsdisp_t**) DECLSPEC_HIDDEN; 251 HRESULT setup_arguments_object(script_ctx_t*,call_frame_t*) DECLSPEC_HIDDEN; 252 void detach_arguments_object(jsdisp_t*) DECLSPEC_HIDDEN; 253