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

oldstable
Jacek Caban 2012-03-12 19:22:36 +01:00 committed by Alexandre Julliard
parent 4fb1cad149
commit 825eb76321
7 changed files with 58 additions and 44 deletions

View File

@ -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");
off = ctx->code_off;
hres = compile_block_statement(ctx, source->statement);
if(FAILED(hres))
return hres;
resolve_labels(ctx, off);
if(!from_eval && !push_instr(ctx, OP_pop))
return E_OUTOFMEMORY;
if(!push_instr(ctx, OP_ret))
return E_OUTOFMEMORY;
if(TRACE_ON(jscript_disas))
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;
}
return S_OK;
}
HRESULT compile_script(parser_ctx_t *parser, BOOL from_eval)
{
HRESULT hres;
hres = init_compiler(parser);
if(FAILED(hres))
return hres;
off = parser->compiler->code_off;
hres = compile_block_statement(parser->compiler, stat);
if(FAILED(hres))
return hres;
resolve_labels(parser->compiler, off);
if(!from_eval && !push_instr(parser->compiler, OP_pop))
return E_OUTOFMEMORY;
if(!push_instr(parser->compiler, OP_ret))
return E_OUTOFMEMORY;
if(TRACE_ON(jscript_disas))
dump_code(parser->compiler, off);
*ret_off = off;
return S_OK;
return compile_function(parser->compiler, parser->source, from_eval);
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;
}