diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c index 40ad7820415..bb00aecec56 100644 --- a/dlls/jscript/compile.c +++ b/dlls/jscript/compile.c @@ -1694,6 +1694,12 @@ void release_bytecode(bytecode_t *code) { unsigned i; + if(--code->ref) + return; + + if(code->parser) + parser_release(code->parser); + for(i=0; i < code->bstr_cnt; i++) SysFreeString(code->bstr_pool[i]); @@ -1709,6 +1715,7 @@ static HRESULT init_code(compiler_ctx_t *compiler) if(!compiler->code) return E_OUTOFMEMORY; + compiler->code->ref = 1; jsheap_init(&compiler->code->heap); compiler->code->instrs = heap_alloc(64 * sizeof(instr_t)); @@ -1757,7 +1764,7 @@ static HRESULT compile_function(compiler_ctx_t *ctx, source_elements_t *source, } HRESULT compile_script(script_ctx_t *ctx, const WCHAR *code, const WCHAR *delimiter, BOOL from_eval, - parser_ctx_t **ret) + bytecode_t **ret) { compiler_ctx_t compiler = {0}; HRESULT hres; @@ -1767,18 +1774,19 @@ HRESULT compile_script(script_ctx_t *ctx, const WCHAR *code, const WCHAR *delimi return hres; hres = init_code(&compiler); - if(SUCCEEDED(hres)) { - hres = compile_function(&compiler, compiler.parser->source, from_eval); - if(FAILED(hres)) - release_bytecode(compiler.code); - } - if(FAILED(hres)) { parser_release(compiler.parser); return hres; } - compiler.parser->code = compiler.code; - *ret = compiler.parser; + compiler.code->parser = compiler.parser; + + hres = compile_function(&compiler, compiler.parser->source, from_eval); + if(FAILED(hres)) { + release_bytecode(compiler.code); + return hres; + } + + *ret = compiler.code; return S_OK; } diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index c03e3fd9ea5..892cb1e75b6 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -810,7 +810,7 @@ static HRESULT interp_func(exec_ctx_t *ctx) TRACE("\n"); - hres = create_source_function(ctx->parser, expr->parameter_list, expr->source_elements, ctx->scope_chain, + hres = create_source_function(ctx->script, ctx->code, expr->parameter_list, expr->source_elements, ctx->scope_chain, expr->src_str, expr->src_len, &dispex); if(FAILED(hres)) return hres; @@ -2571,12 +2571,10 @@ static HRESULT enter_bytecode(script_ctx_t *ctx, bytecode_t *code, unsigned ip, return S_OK; } -HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, BOOL from_eval, +HRESULT exec_source(exec_ctx_t *ctx, bytecode_t *code, source_elements_t *source, BOOL from_eval, jsexcept_t *ei, VARIANT *retv) { - script_ctx_t *script = parser->script; function_declaration_t *func; - parser_ctx_t *prev_parser; var_list_t *var; VARIANT val; exec_ctx_t *prev_ctx; @@ -2589,7 +2587,7 @@ HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *so if(!func->expr->identifier) continue; - hres = create_source_function(parser, func->expr->parameter_list, func->expr->source_elements, + hres = create_source_function(ctx->script, code, func->expr->parameter_list, func->expr->source_elements, ctx->scope_chain, func->expr->src_str, func->expr->src_len, &func_obj); if(FAILED(hres)) return hres; @@ -2609,28 +2607,25 @@ HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *so if(!name) return E_OUTOFMEMORY; - if(!ctx->is_global || !lookup_global_members(parser->script, name, NULL)) + if(!ctx->is_global || !lookup_global_members(ctx->script, name, NULL)) hres = jsdisp_get_id(ctx->var_disp, var->identifier, fdexNameEnsure, &id); SysFreeString(name); if(FAILED(hres)) return hres; } - prev_ctx = script->exec_ctx; - script->exec_ctx = ctx; - - prev_parser = ctx->parser; - ctx->parser = parser; + prev_ctx = ctx->script->exec_ctx; + ctx->script->exec_ctx = ctx; if(source->statement) { assert(source->instr_off); - hres = enter_bytecode(script, parser->code, source->instr_off, ei, &val); + hres = enter_bytecode(ctx->script, code, source->instr_off, ei, &val); }else { V_VT(&val) = VT_EMPTY; } - script->exec_ctx = prev_ctx; - ctx->parser = prev_parser; + assert(ctx->script->exec_ctx == ctx); + ctx->script->exec_ctx = prev_ctx; if(FAILED(hres)) { VariantClear(&val); diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index b5cf0442b5a..65b3a60e780 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -42,6 +42,25 @@ typedef struct _func_stack { struct _func_stack *next; } func_stack_t; +typedef struct { + LONG ref; + + WCHAR *begin; + const WCHAR *end; + const WCHAR *ptr; + + script_ctx_t *script; + source_elements_t *source; + BOOL nl; + BOOL is_html; + BOOL lexer_error; + HRESULT hres; + + jsheap_t heap; + + func_stack_t *func_stack; +} parser_ctx_t; + #define OP_LIST \ X(add, 1, 0,0) \ X(and, 1, 0,0) \ @@ -149,39 +168,28 @@ typedef struct { instr_arg_t arg2; } instr_t; -typedef struct { +typedef struct _bytecode_t { + LONG ref; + instr_t *instrs; jsheap_t heap; BSTR *bstr_pool; unsigned bstr_pool_size; unsigned bstr_cnt; + + parser_ctx_t *parser; + + struct _bytecode_t *next; } bytecode_t; -void release_bytecode(bytecode_t*); +HRESULT compile_script(script_ctx_t*,const WCHAR*,const WCHAR*,BOOL,bytecode_t**) DECLSPEC_HIDDEN; +void release_bytecode(bytecode_t*) DECLSPEC_HIDDEN; -typedef struct _parser_ctx_t { - LONG ref; - - WCHAR *begin; - const WCHAR *end; - const WCHAR *ptr; - - script_ctx_t *script; - source_elements_t *source; - BOOL nl; - BOOL is_html; - BOOL lexer_error; - HRESULT hres; - - jsheap_t heap; - - func_stack_t *func_stack; - - bytecode_t *code; - - struct _parser_ctx_t *next; -} parser_ctx_t; +static inline void bytecode_addref(bytecode_t *code) +{ + code->ref++; +} HRESULT script_parse(script_ctx_t*,const WCHAR*,const WCHAR*,BOOL,parser_ctx_t**) DECLSPEC_HIDDEN; void parser_release(parser_ctx_t*) DECLSPEC_HIDDEN; @@ -246,11 +254,11 @@ static inline void exec_addref(exec_ctx_t *ctx) void exec_release(exec_ctx_t*) DECLSPEC_HIDDEN; HRESULT create_exec_ctx(script_ctx_t*,IDispatch*,jsdisp_t*,scope_chain_t*,BOOL,exec_ctx_t**) DECLSPEC_HIDDEN; -HRESULT exec_source(exec_ctx_t*,parser_ctx_t*,source_elements_t*,BOOL,jsexcept_t*,VARIANT*) DECLSPEC_HIDDEN; +HRESULT exec_source(exec_ctx_t*,bytecode_t*,source_elements_t*,BOOL,jsexcept_t*,VARIANT*) DECLSPEC_HIDDEN; typedef struct _parameter_t parameter_t; -HRESULT create_source_function(parser_ctx_t*,parameter_t*,source_elements_t*,scope_chain_t*, +HRESULT create_source_function(script_ctx_t*,bytecode_t*,parameter_t*,source_elements_t*,scope_chain_t*, const WCHAR*,DWORD,jsdisp_t**) DECLSPEC_HIDDEN; typedef enum { @@ -572,5 +580,3 @@ typedef struct { expression_t expr; prop_val_t *property_list; } property_value_expression_t; - -HRESULT compile_script(script_ctx_t*,const WCHAR*,const WCHAR*,BOOL,parser_ctx_t**) DECLSPEC_HIDDEN; diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 23f7e47aabb..bd4b4a09553 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -31,7 +31,7 @@ typedef struct { source_elements_t *source; parameter_t *parameters; scope_chain_t *scope_chain; - parser_ctx_t *parser; + bytecode_t *code; const WCHAR *src_str; DWORD src_len; DWORD length; @@ -217,7 +217,7 @@ static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDis prev_args = function->arguments; function->arguments = arg_disp; - hres = exec_source(exec_ctx, function->parser, function->source, FALSE, ei, retv); + hres = exec_source(exec_ctx, function->code, function->source, FALSE, ei, retv); function->arguments = prev_args; jsdisp_release(arg_disp); @@ -567,8 +567,8 @@ static void Function_destructor(jsdisp_t *dispex) { FunctionInstance *This = (FunctionInstance*)dispex; - if(This->parser) - parser_release(This->parser); + if(This->code) + release_bytecode(This->code); if(This->scope_chain) scope_release(This->scope_chain); heap_free(This); @@ -660,7 +660,7 @@ HRESULT create_builtin_function(script_ctx_t *ctx, builtin_invoke_t value_proc, return S_OK; } -HRESULT create_source_function(parser_ctx_t *ctx, parameter_t *parameters, source_elements_t *source, +HRESULT create_source_function(script_ctx_t *ctx, bytecode_t *code, parameter_t *parameters, source_elements_t *source, scope_chain_t *scope_chain, const WCHAR *src_str, DWORD src_len, jsdisp_t **ret) { FunctionInstance *function; @@ -669,13 +669,13 @@ HRESULT create_source_function(parser_ctx_t *ctx, parameter_t *parameters, sourc DWORD length = 0; HRESULT hres; - hres = create_object(ctx->script, NULL, &prototype); + hres = create_object(ctx, NULL, &prototype); if(FAILED(hres)) return hres; - hres = create_function(ctx->script, NULL, PROPF_CONSTR, FALSE, NULL, &function); + hres = create_function(ctx, NULL, PROPF_CONSTR, FALSE, NULL, &function); if(SUCCEEDED(hres)) { - hres = set_prototype(ctx->script, &function->dispex, prototype); + hres = set_prototype(ctx, &function->dispex, prototype); if(FAILED(hres)) jsdisp_release(&function->dispex); } @@ -691,8 +691,8 @@ HRESULT create_source_function(parser_ctx_t *ctx, parameter_t *parameters, sourc function->scope_chain = scope_chain; } - parser_addref(ctx); - function->parser = ctx; + bytecode_addref(code); + function->code = code; for(iter = parameters; iter; iter = iter->next) length++; @@ -711,6 +711,7 @@ static HRESULT construct_function(script_ctx_t *ctx, DISPPARAMS *dp, jsexcept_t WCHAR *str = NULL, *ptr; DWORD argc, len = 0, l; parser_ctx_t *parser; + bytecode_t *code; jsdisp_t *function; BSTR *params = NULL; int i=0, j=0; @@ -774,21 +775,22 @@ static HRESULT construct_function(script_ctx_t *ctx, DISPPARAMS *dp, jsexcept_t if(FAILED(hres)) return hres; - hres = compile_script(ctx, str, NULL, FALSE, &parser); + hres = compile_script(ctx, str, NULL, FALSE, &code); heap_free(str); if(FAILED(hres)) return hres; + parser = code->parser; if(!parser->source || !parser->source->functions || parser->source->functions->next || parser->source->variables) { ERR("Invalid parser result!\n"); - parser_release(parser); + release_bytecode(code); return E_UNEXPECTED; } expr = parser->source->functions->expr; - hres = create_source_function(parser, expr->parameter_list, expr->source_elements, NULL, expr->src_str, + hres = create_source_function(ctx, code, expr->parameter_list, expr->source_elements, NULL, expr->src_str, expr->src_len, &function); - parser_release(parser); + release_bytecode(code); if(FAILED(hres)) return hres; diff --git a/dlls/jscript/global.c b/dlls/jscript/global.c index 8a6fe380d13..99bbc010b4c 100644 --- a/dlls/jscript/global.c +++ b/dlls/jscript/global.c @@ -344,7 +344,7 @@ static HRESULT JSGlobal_escape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, D static HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - parser_ctx_t *parser_ctx; + bytecode_t *code; VARIANT *arg; HRESULT hres; @@ -371,15 +371,15 @@ static HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DIS } TRACE("parsing %s\n", debugstr_w(V_BSTR(arg))); - hres = compile_script(ctx, V_BSTR(arg), NULL, TRUE, &parser_ctx); + hres = compile_script(ctx, V_BSTR(arg), NULL, TRUE, &code); if(FAILED(hres)) { WARN("parse (%s) failed: %08x\n", debugstr_w(V_BSTR(arg)), hres); return throw_syntax_error(ctx, ei, hres, NULL); } - hres = exec_source(ctx->exec_ctx, parser_ctx, parser_ctx->source, TRUE, ei, retv); - parser_release(parser_ctx); + hres = exec_source(ctx->exec_ctx, code, code->parser->source, TRUE, ei, retv); + release_bytecode(code); return hres; } diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index 81c8f21c791..5bd5db4807e 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -58,8 +58,8 @@ typedef struct { IActiveScriptSite *site; - parser_ctx_t *queue_head; - parser_ctx_t *queue_tail; + bytecode_t *queue_head; + bytecode_t *queue_tail; } JScript; void script_release(script_ctx_t *ctx) @@ -95,7 +95,7 @@ static inline BOOL is_started(script_ctx_t *ctx) || ctx->state == SCRIPTSTATE_DISCONNECTED; } -static HRESULT exec_global_code(JScript *This, parser_ctx_t *parser_ctx) +static HRESULT exec_global_code(JScript *This, bytecode_t *code) { exec_ctx_t *exec_ctx; jsexcept_t jsexcept; @@ -108,7 +108,7 @@ static HRESULT exec_global_code(JScript *This, parser_ctx_t *parser_ctx) IActiveScriptSite_OnEnterScript(This->site); memset(&jsexcept, 0, sizeof(jsexcept)); - hres = exec_source(exec_ctx, parser_ctx, parser_ctx->source, FALSE, &jsexcept, NULL); + hres = exec_source(exec_ctx, code, code->parser->source, FALSE, &jsexcept, NULL); VariantClear(&jsexcept.var); exec_release(exec_ctx); @@ -118,7 +118,7 @@ static HRESULT exec_global_code(JScript *This, parser_ctx_t *parser_ctx) static void clear_script_queue(JScript *This) { - parser_ctx_t *iter, *iter2; + bytecode_t *iter, *iter2; if(!This->queue_head) return; @@ -127,7 +127,7 @@ static void clear_script_queue(JScript *This) while(iter) { iter2 = iter->next; iter->next = NULL; - parser_release(iter); + release_bytecode(iter); iter = iter2; } @@ -136,7 +136,7 @@ static void clear_script_queue(JScript *This) static void exec_queued_code(JScript *This) { - parser_ctx_t *iter; + bytecode_t *iter; for(iter = This->queue_head; iter; iter = iter->next) exec_global_code(This, iter); @@ -752,7 +752,7 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface, DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo) { JScript *This = impl_from_IActiveScriptParse(iface); - parser_ctx_t *parser_ctx; + bytecode_t *code; HRESULT hres; TRACE("(%p)->(%s %s %p %s %s %u %x %p %p)\n", This, debugstr_w(pstrCode), @@ -762,21 +762,21 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface, if(This->thread_id != GetCurrentThreadId() || This->ctx->state == SCRIPTSTATE_CLOSED) return E_UNEXPECTED; - hres = compile_script(This->ctx, pstrCode, pstrDelimiter, FALSE, &parser_ctx); + hres = compile_script(This->ctx, pstrCode, pstrDelimiter, FALSE, &code); if(FAILED(hres)) return hres; if(!is_started(This->ctx)) { if(This->queue_tail) - This->queue_tail = This->queue_tail->next = parser_ctx; + This->queue_tail = This->queue_tail->next = code; else - This->queue_head = This->queue_tail = parser_ctx; + This->queue_head = This->queue_tail = code; return S_OK; } - hres = exec_global_code(This, parser_ctx); + hres = exec_global_code(This, code); - parser_release(parser_ctx); + release_bytecode(code); return hres; } @@ -818,7 +818,7 @@ static HRESULT WINAPI JScriptParseProcedure_ParseProcedureText(IActiveScriptPars CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags, IDispatch **ppdisp) { JScript *This = impl_from_IActiveScriptParseProcedure2(iface); - parser_ctx_t *parser_ctx; + bytecode_t *code; jsdisp_t *dispex; HRESULT hres; @@ -829,14 +829,14 @@ static HRESULT WINAPI JScriptParseProcedure_ParseProcedureText(IActiveScriptPars if(This->thread_id != GetCurrentThreadId() || This->ctx->state == SCRIPTSTATE_CLOSED) return E_UNEXPECTED; - hres = compile_script(This->ctx, pstrCode, pstrDelimiter, FALSE, &parser_ctx); + hres = compile_script(This->ctx, pstrCode, pstrDelimiter, FALSE, &code); if(FAILED(hres)) { WARN("Parse failed %08x\n", hres); return hres; } - hres = create_source_function(parser_ctx, NULL, parser_ctx->source, NULL, NULL, 0, &dispex); - parser_release(parser_ctx); + hres = create_source_function(This->ctx, code, NULL, code->parser->source, NULL, NULL, 0, &dispex); + release_bytecode(code); if(FAILED(hres)) return hres; diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y index 41a99c40ced..af6933f7987 100644 --- a/dlls/jscript/parser.y +++ b/dlls/jscript/parser.y @@ -1535,8 +1535,6 @@ void parser_release(parser_ctx_t *ctx) if(--ctx->ref) return; - if(ctx->code) - release_bytecode(ctx->code); script_release(ctx->script); heap_free(ctx->begin); jsheap_free(&ctx->heap);