From 825eb76321d3a7aaaa9c0d7ddc6081ba6e0ce277 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Mon, 12 Mar 2012 19:22:36 +0100 Subject: [PATCH] jscript: Compile all function from given source in one run. --- dlls/jscript/compile.c | 39 +++++++++++++++++++++++++++------------ dlls/jscript/engine.c | 12 +++++------- dlls/jscript/engine.h | 4 ++-- dlls/jscript/function.c | 2 +- dlls/jscript/global.c | 2 +- dlls/jscript/jscript.c | 6 +++--- dlls/jscript/parser.y | 25 +++++++++++++------------ 7 files changed, 52 insertions(+), 38 deletions(-) diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c index 0a84aef6516..8d1487baa12 100644 --- a/dlls/jscript/compile.c +++ b/dlls/jscript/compile.c @@ -1744,32 +1744,47 @@ static HRESULT init_compiler(parser_ctx_t *parser) return S_OK; } -HRESULT compile_subscript_stat(parser_ctx_t *parser, statement_t *stat, BOOL from_eval, unsigned *ret_off) +static HRESULT compile_function(compiler_ctx_t *ctx, source_elements_t *source, BOOL from_eval) { + function_declaration_t *iter; unsigned off; HRESULT hres; TRACE("\n"); - hres = init_compiler(parser); + off = ctx->code_off; + hres = compile_block_statement(ctx, source->statement); if(FAILED(hres)) return hres; - off = parser->compiler->code_off; - hres = compile_block_statement(parser->compiler, stat); - if(FAILED(hres)) - return hres; + resolve_labels(ctx, off); - resolve_labels(parser->compiler, off); - - if(!from_eval && !push_instr(parser->compiler, OP_pop)) + if(!from_eval && !push_instr(ctx, OP_pop)) return E_OUTOFMEMORY; - if(!push_instr(parser->compiler, OP_ret)) + if(!push_instr(ctx, OP_ret)) return E_OUTOFMEMORY; if(TRACE_ON(jscript_disas)) - dump_code(parser->compiler, off); + dump_code(ctx, off); + + source->instr_off = off; + + for(iter = source->functions; iter; iter = iter->next) { + hres = compile_function(ctx, iter->expr->source_elements, FALSE); + if(FAILED(hres)) + return hres; + } - *ret_off = off; return S_OK; } + +HRESULT compile_script(parser_ctx_t *parser, BOOL from_eval) +{ + HRESULT hres; + + hres = init_compiler(parser); + if(FAILED(hres)) + return hres; + + return compile_function(parser->compiler, parser->source, from_eval); +} diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index a949f5c3d57..37e0f668fe2 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -2581,6 +2581,9 @@ HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *so jsdisp_t *func_obj; VARIANT var; + if(!func->expr->identifier) + continue; + hres = create_source_function(parser, func->expr->parameter_list, func->expr->source_elements, ctx->scope_chain, func->expr->src_str, func->expr->src_len, &func_obj); if(FAILED(hres)) @@ -2615,13 +2618,8 @@ HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *so ctx->parser = parser; if(source->statement) { - if(!source->instr_off) { - hres = compile_subscript_stat(ctx->parser, source->statement, from_eval, &source->instr_off); - if(FAILED(hres) && is_jscript_error(hres)) - hres = throw_syntax_error(script, ei, hres, NULL); - } - if(SUCCEEDED(hres)) - hres = enter_bytecode(script, parser->code, source->instr_off, ei, &val); + assert(source->instr_off); + hres = enter_bytecode(script, parser->code, source->instr_off, ei, &val); }else { V_VT(&val) = VT_EMPTY; } diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index f608374fa54..71355784a6c 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -188,7 +188,7 @@ typedef struct _parser_ctx_t { struct _parser_ctx_t *next; } parser_ctx_t; -HRESULT script_parse(script_ctx_t*,const WCHAR*,const WCHAR*,parser_ctx_t**) DECLSPEC_HIDDEN; +HRESULT script_parse(script_ctx_t*,const WCHAR*,const WCHAR*,BOOL,parser_ctx_t**) DECLSPEC_HIDDEN; void parser_release(parser_ctx_t*) DECLSPEC_HIDDEN; int parser_lex(void*,parser_ctx_t*) DECLSPEC_HIDDEN; @@ -577,4 +577,4 @@ typedef struct { prop_val_t *property_list; } property_value_expression_t; -HRESULT compile_subscript_stat(parser_ctx_t*,statement_t*,BOOL,unsigned*) DECLSPEC_HIDDEN; +HRESULT compile_script(parser_ctx_t*,BOOL) DECLSPEC_HIDDEN; diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 8b57721f611..abccae59024 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -774,7 +774,7 @@ static HRESULT construct_function(script_ctx_t *ctx, DISPPARAMS *dp, jsexcept_t if(FAILED(hres)) return hres; - hres = script_parse(ctx, str, NULL, &parser); + hres = script_parse(ctx, str, NULL, FALSE, &parser); heap_free(str); if(FAILED(hres)) return hres; diff --git a/dlls/jscript/global.c b/dlls/jscript/global.c index 35f6b2feb06..620b554fdc3 100644 --- a/dlls/jscript/global.c +++ b/dlls/jscript/global.c @@ -371,7 +371,7 @@ static HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DIS } TRACE("parsing %s\n", debugstr_w(V_BSTR(arg))); - hres = script_parse(ctx, V_BSTR(arg), NULL, &parser_ctx); + hres = script_parse(ctx, V_BSTR(arg), NULL, TRUE, &parser_ctx); if(FAILED(hres)) { WARN("parse (%s) failed: %08x\n", debugstr_w(V_BSTR(arg)), hres); return throw_syntax_error(ctx, ei, hres, NULL); diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index 45edeb105f1..8b0c28b64fc 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -762,7 +762,7 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface, if(This->thread_id != GetCurrentThreadId() || This->ctx->state == SCRIPTSTATE_CLOSED) return E_UNEXPECTED; - hres = script_parse(This->ctx, pstrCode, pstrDelimiter, &parser_ctx); + hres = script_parse(This->ctx, pstrCode, pstrDelimiter, FALSE, &parser_ctx); if(FAILED(hres)) return hres; @@ -775,8 +775,8 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface, } hres = exec_global_code(This, parser_ctx); - parser_release(parser_ctx); + parser_release(parser_ctx); return hres; } @@ -829,7 +829,7 @@ static HRESULT WINAPI JScriptParseProcedure_ParseProcedureText(IActiveScriptPars if(This->thread_id != GetCurrentThreadId() || This->ctx->state == SCRIPTSTATE_CLOSED) return E_UNEXPECTED; - hres = script_parse(This->ctx, pstrCode, pstrDelimiter, &parser_ctx); + hres = script_parse(This->ctx, pstrCode, pstrDelimiter, FALSE, &parser_ctx); if(FAILED(hres)) { WARN("Parse failed %08x\n", hres); return hres; diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y index 7938968ab63..2a420346911 100644 --- a/dlls/jscript/parser.y +++ b/dlls/jscript/parser.y @@ -1315,6 +1315,7 @@ static expression_t *new_function_expression(parser_ctx_t *ctx, const WCHAR *ide parameter_list_t *parameter_list, source_elements_t *source_elements, const WCHAR *src_str, DWORD src_len) { function_expression_t *ret = new_expression(ctx, EXPR_FUNC, sizeof(*ret)); + function_declaration_t *decl; ret->identifier = identifier; ret->parameter_list = parameter_list ? parameter_list->head : NULL; @@ -1322,17 +1323,15 @@ static expression_t *new_function_expression(parser_ctx_t *ctx, const WCHAR *ide ret->src_str = src_str; ret->src_len = src_len; - if(ret->identifier) { - function_declaration_t *decl = parser_alloc(ctx, sizeof(function_declaration_t)); + decl = parser_alloc(ctx, sizeof(function_declaration_t)); - decl->expr = ret; - decl->next = NULL; + decl->expr = ret; + decl->next = NULL; - if(ctx->func_stack->func_tail) - ctx->func_stack->func_tail = ctx->func_stack->func_tail->next = decl; - else - ctx->func_stack->func_head = ctx->func_stack->func_tail = decl; - } + if(ctx->func_stack->func_tail) + ctx->func_stack->func_tail = ctx->func_stack->func_tail->next = decl; + else + ctx->func_stack->func_head = ctx->func_stack->func_tail = decl; return &ret->expr; } @@ -1546,7 +1545,7 @@ void parser_release(parser_ctx_t *ctx) heap_free(ctx); } -HRESULT script_parse(script_ctx_t *ctx, const WCHAR *code, const WCHAR *delimiter, +HRESULT script_parse(script_ctx_t *ctx, const WCHAR *code, const WCHAR *delimiter, BOOL from_eval, parser_ctx_t **ret) { parser_ctx_t *parser_ctx; @@ -1582,8 +1581,10 @@ HRESULT script_parse(script_ctx_t *ctx, const WCHAR *code, const WCHAR *delimite parser_parse(parser_ctx); jsheap_clear(mark); - if(FAILED(parser_ctx->hres)) { - hres = parser_ctx->hres; + hres = parser_ctx->hres; + if(SUCCEEDED(hres)) + hres = compile_script(parser_ctx, from_eval); + if(FAILED(hres)) { parser_release(parser_ctx); return hres; } -- 2.11.4.GIT