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