Jacek Caban : jscript: Compile all function from given source in one run.

Alexandre Julliard julliard at winehq.org
Tue Mar 13 13:50:35 CDT 2012


Module: wine
Branch: master
Commit: 825eb76321d3a7aaaa9c0d7ddc6081ba6e0ce277
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=825eb76321d3a7aaaa9c0d7ddc6081ba6e0ce277

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Mar 12 19:22:36 2012 +0100

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 0a84aef..8d1487b 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 a949f5c..37e0f66 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 f608374..7135578 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 8b57721..abccae5 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 35f6b2f..620b554 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 45edeb1..8b0c28b 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 7938968..2a42034 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;
     }




More information about the wine-cvs mailing list