jscript: Store source position in instr_t.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
7828df17e2
commit
78853e3853
|
@ -67,6 +67,8 @@ typedef struct _compiler_ctx_t {
|
||||||
statement_ctx_t *stat_ctx;
|
statement_ctx_t *stat_ctx;
|
||||||
function_code_t *func;
|
function_code_t *func;
|
||||||
|
|
||||||
|
unsigned loc;
|
||||||
|
|
||||||
function_expression_t *func_head;
|
function_expression_t *func_head;
|
||||||
function_expression_t *func_tail;
|
function_expression_t *func_tail;
|
||||||
|
|
||||||
|
@ -208,6 +210,11 @@ static BSTR compiler_alloc_bstr_len(compiler_ctx_t *ctx, const WCHAR *str, size_
|
||||||
return ctx->code->bstr_pool[ctx->code->bstr_cnt++];
|
return ctx->code->bstr_pool[ctx->code->bstr_cnt++];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_compiler_loc(compiler_ctx_t *ctx, unsigned loc)
|
||||||
|
{
|
||||||
|
ctx->loc = loc;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
|
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
|
||||||
{
|
{
|
||||||
assert(ctx->code_size >= ctx->code_off);
|
assert(ctx->code_size >= ctx->code_off);
|
||||||
|
@ -224,6 +231,7 @@ static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->code->instrs[ctx->code_off].op = op;
|
ctx->code->instrs[ctx->code_off].op = op;
|
||||||
|
ctx->code->instrs[ctx->code_off].loc = ctx->loc;
|
||||||
return ctx->code_off++;
|
return ctx->code_off++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1245,6 +1253,7 @@ static HRESULT compile_while_statement(compiler_ctx_t *ctx, while_statement_t *s
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
|
set_compiler_loc(ctx, stat->stat.loc);
|
||||||
if(stat->do_while) {
|
if(stat->do_while) {
|
||||||
label_set_addr(ctx, stat_ctx.continue_label);
|
label_set_addr(ctx, stat_ctx.continue_label);
|
||||||
hres = compile_expression(ctx, stat->expr, TRUE);
|
hres = compile_expression(ctx, stat->expr, TRUE);
|
||||||
|
@ -1292,6 +1301,7 @@ static HRESULT compile_for_statement(compiler_ctx_t *ctx, for_statement_t *stat)
|
||||||
expr_off = ctx->code_off;
|
expr_off = ctx->code_off;
|
||||||
|
|
||||||
if(stat->expr) {
|
if(stat->expr) {
|
||||||
|
set_compiler_loc(ctx, stat->expr_loc);
|
||||||
hres = compile_expression(ctx, stat->expr, TRUE);
|
hres = compile_expression(ctx, stat->expr, TRUE);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -1308,6 +1318,7 @@ static HRESULT compile_for_statement(compiler_ctx_t *ctx, for_statement_t *stat)
|
||||||
label_set_addr(ctx, stat_ctx.continue_label);
|
label_set_addr(ctx, stat_ctx.continue_label);
|
||||||
|
|
||||||
if(stat->end_expr) {
|
if(stat->end_expr) {
|
||||||
|
set_compiler_loc(ctx, stat->end_loc);
|
||||||
hres = compile_expression(ctx, stat->end_expr, FALSE);
|
hres = compile_expression(ctx, stat->end_expr, FALSE);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -1613,6 +1624,7 @@ static HRESULT compile_switch_statement(compiler_ctx_t *ctx, switch_statement_t
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_compiler_loc(ctx, iter->loc);
|
||||||
hres = compile_expression(ctx, iter->expr, TRUE);
|
hres = compile_expression(ctx, iter->expr, TRUE);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
break;
|
break;
|
||||||
|
@ -1751,6 +1763,7 @@ static HRESULT compile_try_statement(compiler_ctx_t *ctx, try_statement_t *stat)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
|
set_compiler_loc(ctx, stat->finally_loc);
|
||||||
if(!push_instr(ctx, OP_end_finally))
|
if(!push_instr(ctx, OP_end_finally))
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
@ -1772,6 +1785,8 @@ static HRESULT compile_statement(compiler_ctx_t *ctx, statement_ctx_t *stat_ctx,
|
||||||
ctx->stat_ctx = stat_ctx;
|
ctx->stat_ctx = stat_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_compiler_loc(ctx, stat->loc);
|
||||||
|
|
||||||
switch(stat->type) {
|
switch(stat->type) {
|
||||||
case STAT_BLOCK:
|
case STAT_BLOCK:
|
||||||
hres = compile_block_statement(ctx, ((block_statement_t*)stat)->stat_list);
|
hres = compile_block_statement(ctx, ((block_statement_t*)stat)->stat_list);
|
||||||
|
|
|
@ -125,6 +125,7 @@ typedef enum {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
jsop_t op;
|
jsop_t op;
|
||||||
|
unsigned loc;
|
||||||
union {
|
union {
|
||||||
instr_arg_t arg[2];
|
instr_arg_t arg[2];
|
||||||
double dbl;
|
double dbl;
|
||||||
|
|
|
@ -158,7 +158,9 @@ typedef struct {
|
||||||
variable_declaration_t *variable_list;
|
variable_declaration_t *variable_list;
|
||||||
expression_t *begin_expr;
|
expression_t *begin_expr;
|
||||||
expression_t *expr;
|
expression_t *expr;
|
||||||
|
unsigned expr_loc;
|
||||||
expression_t *end_expr;
|
expression_t *end_expr;
|
||||||
|
unsigned end_loc;
|
||||||
statement_t *statement;
|
statement_t *statement;
|
||||||
} for_statement_t;
|
} for_statement_t;
|
||||||
|
|
||||||
|
@ -189,6 +191,7 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct _case_clausule_t {
|
typedef struct _case_clausule_t {
|
||||||
expression_t *expr;
|
expression_t *expr;
|
||||||
|
unsigned loc;
|
||||||
statement_t *stat;
|
statement_t *stat;
|
||||||
|
|
||||||
struct _case_clausule_t *next;
|
struct _case_clausule_t *next;
|
||||||
|
@ -210,6 +213,7 @@ typedef struct {
|
||||||
statement_t *try_statement;
|
statement_t *try_statement;
|
||||||
catch_block_t *catch_block;
|
catch_block_t *catch_block;
|
||||||
statement_t *finally_statement;
|
statement_t *finally_statement;
|
||||||
|
unsigned finally_loc;
|
||||||
} try_statement_t;
|
} try_statement_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -71,7 +71,7 @@ typedef struct _case_list_t {
|
||||||
} case_list_t;
|
} case_list_t;
|
||||||
|
|
||||||
static catch_block_t *new_catch_block(parser_ctx_t*,const WCHAR*,statement_t*);
|
static catch_block_t *new_catch_block(parser_ctx_t*,const WCHAR*,statement_t*);
|
||||||
static case_clausule_t *new_case_clausule(parser_ctx_t*,expression_t*,statement_list_t*);
|
static case_clausule_t *new_case_clausule(parser_ctx_t*,unsigned,expression_t*,statement_list_t*);
|
||||||
static case_list_t *new_case_list(parser_ctx_t*,case_clausule_t*);
|
static case_list_t *new_case_list(parser_ctx_t*,case_clausule_t*);
|
||||||
static case_list_t *case_list_add(parser_ctx_t*,case_list_t*,case_clausule_t*);
|
static case_list_t *case_list_add(parser_ctx_t*,case_list_t*,case_clausule_t*);
|
||||||
static case_clausule_t *new_case_block(parser_ctx_t*,case_list_t*,case_clausule_t*,case_list_t*);
|
static case_clausule_t *new_case_block(parser_ctx_t*,case_list_t*,case_clausule_t*,case_list_t*);
|
||||||
|
@ -91,8 +91,8 @@ static statement_t *new_var_statement(parser_ctx_t*,unsigned,variable_list_t*);
|
||||||
static statement_t *new_expression_statement(parser_ctx_t*,unsigned,expression_t*);
|
static statement_t *new_expression_statement(parser_ctx_t*,unsigned,expression_t*);
|
||||||
static statement_t *new_if_statement(parser_ctx_t*,unsigned,expression_t*,statement_t*,statement_t*);
|
static statement_t *new_if_statement(parser_ctx_t*,unsigned,expression_t*,statement_t*,statement_t*);
|
||||||
static statement_t *new_while_statement(parser_ctx_t*,unsigned,BOOL,expression_t*,statement_t*);
|
static statement_t *new_while_statement(parser_ctx_t*,unsigned,BOOL,expression_t*,statement_t*);
|
||||||
static statement_t *new_for_statement(parser_ctx_t*,unsigned,variable_list_t*,expression_t*,expression_t*,
|
static statement_t *new_for_statement(parser_ctx_t*,unsigned,variable_list_t*,expression_t*,expression_t*,unsigned,
|
||||||
expression_t*,statement_t*);
|
expression_t*,unsigned,statement_t*);
|
||||||
static statement_t *new_forin_statement(parser_ctx_t*,unsigned,variable_declaration_t*,expression_t*,expression_t*,statement_t*);
|
static statement_t *new_forin_statement(parser_ctx_t*,unsigned,variable_declaration_t*,expression_t*,expression_t*,statement_t*);
|
||||||
static statement_t *new_continue_statement(parser_ctx_t*,unsigned,const WCHAR*);
|
static statement_t *new_continue_statement(parser_ctx_t*,unsigned,const WCHAR*);
|
||||||
static statement_t *new_break_statement(parser_ctx_t*,unsigned,const WCHAR*);
|
static statement_t *new_break_statement(parser_ctx_t*,unsigned,const WCHAR*);
|
||||||
|
@ -101,7 +101,7 @@ static statement_t *new_with_statement(parser_ctx_t*,unsigned,expression_t*,stat
|
||||||
static statement_t *new_labelled_statement(parser_ctx_t*,unsigned,const WCHAR*,statement_t*);
|
static statement_t *new_labelled_statement(parser_ctx_t*,unsigned,const WCHAR*,statement_t*);
|
||||||
static statement_t *new_switch_statement(parser_ctx_t*,unsigned,expression_t*,case_clausule_t*);
|
static statement_t *new_switch_statement(parser_ctx_t*,unsigned,expression_t*,case_clausule_t*);
|
||||||
static statement_t *new_throw_statement(parser_ctx_t*,unsigned,expression_t*);
|
static statement_t *new_throw_statement(parser_ctx_t*,unsigned,expression_t*);
|
||||||
static statement_t *new_try_statement(parser_ctx_t*,statement_t*,catch_block_t*,statement_t*);
|
static statement_t *new_try_statement(parser_ctx_t*,statement_t*,catch_block_t*,statement_t*,unsigned);
|
||||||
|
|
||||||
struct statement_list_t {
|
struct statement_list_t {
|
||||||
statement_t *head;
|
statement_t *head;
|
||||||
|
@ -397,13 +397,13 @@ IterationStatement
|
||||||
semicolon Expression_opt
|
semicolon Expression_opt
|
||||||
{ if(!explicit_error(ctx, $6, ';')) YYABORT; }
|
{ if(!explicit_error(ctx, $6, ';')) YYABORT; }
|
||||||
semicolon Expression_opt right_bracket Statement
|
semicolon Expression_opt right_bracket Statement
|
||||||
{ $$ = new_for_statement(ctx, @$, NULL, $3, $6, $9, $11); }
|
{ $$ = new_for_statement(ctx, @3, NULL, $3, $6, @6, $9, @9, $11); }
|
||||||
| kFOR left_bracket kVAR VariableDeclarationListNoIn
|
| kFOR left_bracket kVAR VariableDeclarationListNoIn
|
||||||
{ if(!explicit_error(ctx, $4, ';')) YYABORT; }
|
{ if(!explicit_error(ctx, $4, ';')) YYABORT; }
|
||||||
semicolon Expression_opt
|
semicolon Expression_opt
|
||||||
{ if(!explicit_error(ctx, $7, ';')) YYABORT; }
|
{ if(!explicit_error(ctx, $7, ';')) YYABORT; }
|
||||||
semicolon Expression_opt right_bracket Statement
|
semicolon Expression_opt right_bracket Statement
|
||||||
{ $$ = new_for_statement(ctx, @$, $4, NULL, $7, $10, $12); }
|
{ $$ = new_for_statement(ctx, @3, $4, NULL, $7, @7, $10, @10, $12); }
|
||||||
| kFOR left_bracket LeftHandSideExpression kIN Expression_err right_bracket Statement
|
| kFOR left_bracket LeftHandSideExpression kIN Expression_err right_bracket Statement
|
||||||
{ $$ = new_forin_statement(ctx, @$, NULL, $3, $5, $7); }
|
{ $$ = new_forin_statement(ctx, @$, NULL, $3, $5, $7); }
|
||||||
| kFOR left_bracket kVAR VariableDeclarationNoIn kIN Expression_err right_bracket Statement
|
| kFOR left_bracket kVAR VariableDeclarationNoIn kIN Expression_err right_bracket Statement
|
||||||
|
@ -460,12 +460,12 @@ CaseClausules
|
||||||
/* ECMA-262 3rd Edition 12.11 */
|
/* ECMA-262 3rd Edition 12.11 */
|
||||||
CaseClausule
|
CaseClausule
|
||||||
: kCASE Expression ':' StatementList_opt
|
: kCASE Expression ':' StatementList_opt
|
||||||
{ $$ = new_case_clausule(ctx, $2, $4); }
|
{ $$ = new_case_clausule(ctx, @$, $2, $4); }
|
||||||
|
|
||||||
/* ECMA-262 3rd Edition 12.11 */
|
/* ECMA-262 3rd Edition 12.11 */
|
||||||
DefaultClausule
|
DefaultClausule
|
||||||
: kDEFAULT ':' StatementList_opt
|
: kDEFAULT ':' StatementList_opt
|
||||||
{ $$ = new_case_clausule(ctx, NULL, $3); }
|
{ $$ = new_case_clausule(ctx, @$, NULL, $3); }
|
||||||
|
|
||||||
/* ECMA-262 3rd Edition 12.13 */
|
/* ECMA-262 3rd Edition 12.13 */
|
||||||
ThrowStatement
|
ThrowStatement
|
||||||
|
@ -474,10 +474,10 @@ ThrowStatement
|
||||||
|
|
||||||
/* ECMA-262 3rd Edition 12.14 */
|
/* ECMA-262 3rd Edition 12.14 */
|
||||||
TryStatement
|
TryStatement
|
||||||
: kTRY Block Catch { $$ = new_try_statement(ctx, $2, $3, NULL); }
|
: kTRY Block Catch { $$ = new_try_statement(ctx, $2, $3, NULL, 0); }
|
||||||
| kTRY Block Finally { $$ = new_try_statement(ctx, $2, NULL, $3); }
|
| kTRY Block Finally { $$ = new_try_statement(ctx, $2, NULL, $3, @3); }
|
||||||
| kTRY Block Catch Finally
|
| kTRY Block Catch Finally
|
||||||
{ $$ = new_try_statement(ctx, $2, $3, $4); }
|
{ $$ = new_try_statement(ctx, $2, $3, $4, @4); }
|
||||||
|
|
||||||
/* ECMA-262 3rd Edition 12.14 */
|
/* ECMA-262 3rd Edition 12.14 */
|
||||||
Catch
|
Catch
|
||||||
|
@ -486,7 +486,7 @@ Catch
|
||||||
|
|
||||||
/* ECMA-262 3rd Edition 12.14 */
|
/* ECMA-262 3rd Edition 12.14 */
|
||||||
Finally
|
Finally
|
||||||
: kFINALLY Block { $$ = $2; }
|
: kFINALLY Block { @$ = @2; $$ = $2; }
|
||||||
|
|
||||||
/* ECMA-262 3rd Edition 11.14 */
|
/* ECMA-262 3rd Edition 11.14 */
|
||||||
Expression_opt
|
Expression_opt
|
||||||
|
@ -1025,12 +1025,13 @@ static catch_block_t *new_catch_block(parser_ctx_t *ctx, const WCHAR *identifier
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static case_clausule_t *new_case_clausule(parser_ctx_t *ctx, expression_t *expr, statement_list_t *stat_list)
|
static case_clausule_t *new_case_clausule(parser_ctx_t *ctx, unsigned loc, expression_t *expr, statement_list_t *stat_list)
|
||||||
{
|
{
|
||||||
case_clausule_t *ret = parser_alloc(ctx, sizeof(case_clausule_t));
|
case_clausule_t *ret = parser_alloc(ctx, sizeof(case_clausule_t));
|
||||||
|
|
||||||
ret->expr = expr;
|
ret->expr = expr;
|
||||||
ret->stat = stat_list ? stat_list->head : NULL;
|
ret->stat = stat_list ? stat_list->head : NULL;
|
||||||
|
ret->loc = loc;
|
||||||
ret->next = NULL;
|
ret->next = NULL;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1201,7 +1202,7 @@ static statement_t *new_while_statement(parser_ctx_t *ctx, unsigned loc, BOOL do
|
||||||
}
|
}
|
||||||
|
|
||||||
static statement_t *new_for_statement(parser_ctx_t *ctx, unsigned loc, variable_list_t *variable_list, expression_t *begin_expr,
|
static statement_t *new_for_statement(parser_ctx_t *ctx, unsigned loc, variable_list_t *variable_list, expression_t *begin_expr,
|
||||||
expression_t *expr, expression_t *end_expr, statement_t *statement)
|
expression_t *expr, unsigned expr_loc, expression_t *end_expr, unsigned end_loc, statement_t *statement)
|
||||||
{
|
{
|
||||||
for_statement_t *ret;
|
for_statement_t *ret;
|
||||||
|
|
||||||
|
@ -1212,7 +1213,9 @@ static statement_t *new_for_statement(parser_ctx_t *ctx, unsigned loc, variable_
|
||||||
ret->variable_list = variable_list ? variable_list->head : NULL;
|
ret->variable_list = variable_list ? variable_list->head : NULL;
|
||||||
ret->begin_expr = begin_expr;
|
ret->begin_expr = begin_expr;
|
||||||
ret->expr = expr;
|
ret->expr = expr;
|
||||||
|
ret->expr_loc = expr_loc;
|
||||||
ret->end_expr = end_expr;
|
ret->end_expr = end_expr;
|
||||||
|
ret->end_loc = end_loc;
|
||||||
ret->statement = statement;
|
ret->statement = statement;
|
||||||
|
|
||||||
return &ret->stat;
|
return &ret->stat;
|
||||||
|
@ -1330,7 +1333,7 @@ static statement_t *new_throw_statement(parser_ctx_t *ctx, unsigned loc, express
|
||||||
}
|
}
|
||||||
|
|
||||||
static statement_t *new_try_statement(parser_ctx_t *ctx, statement_t *try_statement,
|
static statement_t *new_try_statement(parser_ctx_t *ctx, statement_t *try_statement,
|
||||||
catch_block_t *catch_block, statement_t *finally_statement)
|
catch_block_t *catch_block, statement_t *finally_statement, unsigned finally_loc)
|
||||||
{
|
{
|
||||||
try_statement_t *ret;
|
try_statement_t *ret;
|
||||||
|
|
||||||
|
@ -1341,6 +1344,7 @@ static statement_t *new_try_statement(parser_ctx_t *ctx, statement_t *try_statem
|
||||||
ret->try_statement = try_statement;
|
ret->try_statement = try_statement;
|
||||||
ret->catch_block = catch_block;
|
ret->catch_block = catch_block;
|
||||||
ret->finally_statement = finally_statement;
|
ret->finally_statement = finally_statement;
|
||||||
|
ret->finally_loc = finally_loc;
|
||||||
|
|
||||||
return &ret->stat;
|
return &ret->stat;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue