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_STR, ARG_UINT) \ 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_acc, 1, 0,0) \ 79 X(push_except,1, ARG_ADDR, ARG_UINT) \ 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 enum { 135 PROPERTY_DEFINITION_VALUE, 136 PROPERTY_DEFINITION_GETTER, 137 PROPERTY_DEFINITION_SETTER 138 } property_definition_type_t; 139 140 typedef struct { 141 BSTR name; 142 int ref; 143 } local_ref_t; 144 145 typedef struct _function_code_t { 146 BSTR name; 147 int local_ref; 148 BSTR event_target; 149 unsigned instr_off; 150 151 const WCHAR *source; 152 unsigned source_len; 153 154 unsigned func_cnt; 155 struct _function_code_t *funcs; 156 157 unsigned var_cnt; 158 struct { 159 BSTR name; 160 int func_id; /* -1 if not a function */ 161 } *variables; 162 163 unsigned param_cnt; 164 BSTR *params; 165 166 unsigned locals_cnt; 167 local_ref_t *locals; 168 } function_code_t; 169 170 local_ref_t *lookup_local(const function_code_t*,const WCHAR*) DECLSPEC_HIDDEN; 171 172 typedef struct _bytecode_t { 173 LONG ref; 174 175 instr_t *instrs; 176 heap_pool_t heap; 177 178 function_code_t global_code; 179 180 WCHAR *source; 181 182 BSTR *bstr_pool; 183 unsigned bstr_pool_size; 184 unsigned bstr_cnt; 185 186 jsstr_t **str_pool; 187 unsigned str_pool_size; 188 unsigned str_cnt; 189 190 struct _bytecode_t *next; 191 } bytecode_t; 192 193 HRESULT compile_script(script_ctx_t*,const WCHAR*,const WCHAR*,const WCHAR*,BOOL,BOOL,bytecode_t**) DECLSPEC_HIDDEN; 194 void release_bytecode(bytecode_t*) DECLSPEC_HIDDEN; 195 196 static inline bytecode_t *bytecode_addref(bytecode_t *code) 197 { 198 code->ref++; 199 return code; 200 } 201 202 typedef struct _scope_chain_t { 203 LONG ref; 204 jsdisp_t *jsobj; 205 IDispatch *obj; 206 struct _call_frame_t *frame; 207 struct _scope_chain_t *next; 208 } scope_chain_t; 209 210 void scope_release(scope_chain_t*) DECLSPEC_HIDDEN; 211 212 static inline scope_chain_t *scope_addref(scope_chain_t *scope) 213 { 214 scope->ref++; 215 return scope; 216 } 217 218 typedef struct _except_frame_t except_frame_t; 219 struct _parser_ctx_t; 220 221 typedef struct _call_frame_t { 222 unsigned ip; 223 except_frame_t *except_frame; 224 unsigned stack_base; 225 scope_chain_t *scope; 226 scope_chain_t *base_scope; 227 228 jsval_t ret; 229 230 IDispatch *this_obj; 231 jsdisp_t *function_instance; 232 jsdisp_t *variable_obj; 233 jsdisp_t *arguments_obj; 234 DWORD flags; 235 236 unsigned argc; 237 unsigned pop_locals; 238 unsigned arguments_off; 239 unsigned variables_off; 240 unsigned pop_variables; 241 242 bytecode_t *bytecode; 243 function_code_t *function; 244 245 struct _call_frame_t *prev_frame; 246 } call_frame_t; 247 248 #define EXEC_GLOBAL 0x0001 249 #define EXEC_CONSTRUCTOR 0x0002 250 #define EXEC_RETURN_TO_INTERP 0x0004 251 #define EXEC_EVAL 0x0008 252 253 HRESULT exec_source(script_ctx_t*,DWORD,bytecode_t*,function_code_t*,scope_chain_t*,IDispatch*, 254 jsdisp_t*,jsdisp_t*,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN; 255 256 HRESULT create_source_function(script_ctx_t*,bytecode_t*,function_code_t*,scope_chain_t*,jsdisp_t**) DECLSPEC_HIDDEN; 257 HRESULT setup_arguments_object(script_ctx_t*,call_frame_t*) DECLSPEC_HIDDEN; 258 void detach_arguments_object(jsdisp_t*) DECLSPEC_HIDDEN; 259