jscript: Compile all function from given source in one run.
This commit is contained in:
parent
4fb1cad149
commit
825eb76321
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue