From e4f92ef473726a4a9bf86487985fc9b96aeb99fb Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 24 Nov 2011 14:23:39 +0100 Subject: [PATCH] jscript: Use bytecode for regexp literals. --- dlls/jscript/compile.c | 26 +++++++++++++++++++++----- dlls/jscript/engine.c | 23 +++++++++++++++++++++-- dlls/jscript/engine.h | 35 ++++++++++++++++++----------------- 3 files changed, 60 insertions(+), 24 deletions(-) diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c index 0f4381ad276..9542912f922 100644 --- a/dlls/jscript/compile.c +++ b/dlls/jscript/compile.c @@ -168,10 +168,8 @@ static HRESULT compile_interp_fallback(compiler_ctx_t *ctx, expression_t *expr) return S_OK; } -static HRESULT compile_literal(compiler_ctx_t *ctx, literal_expression_t *expr) +static HRESULT compile_literal(compiler_ctx_t *ctx, literal_t *literal) { - literal_t *literal = expr->literal; - switch(literal->type) { case LT_BOOL: return push_instr_int(ctx, OP_bool, literal->u.bval); @@ -183,8 +181,26 @@ static HRESULT compile_literal(compiler_ctx_t *ctx, literal_expression_t *expr) return push_instr(ctx, OP_null); case LT_STRING: return push_instr_str(ctx, OP_str, literal->u.wstr); + case LT_REGEXP: { + unsigned instr; + WCHAR *str; + + str = compiler_alloc(ctx->code, (literal->u.regexp.str_len+1)*sizeof(WCHAR)); + if(!str) + return E_OUTOFMEMORY; + memcpy(str, literal->u.regexp.str, literal->u.regexp.str_len*sizeof(WCHAR)); + str[literal->u.regexp.str_len] = 0; + + instr = push_instr(ctx, OP_regexp); + if(instr == -1) + return E_OUTOFMEMORY; + + instr_ptr(ctx, instr)->arg1.str = str; + instr_ptr(ctx, instr)->arg2.lng = literal->u.regexp.flags; + return S_OK; + } default: - return compile_interp_fallback(ctx, &expr->expr); + assert(0); } } @@ -200,7 +216,7 @@ static HRESULT compile_expression(compiler_ctx_t *ctx, expression_t *expr) case EXPR_IN: return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_in); case EXPR_LITERAL: - return compile_literal(ctx, (literal_expression_t*)expr); + return compile_literal(ctx, ((literal_expression_t*)expr)->literal); case EXPR_LOGNEG: return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_neg); case EXPR_NOTEQEQ: diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 66d10d677c6..e004ffaf0e7 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -1787,6 +1787,25 @@ HRESULT interp_str(exec_ctx_t *ctx) return stack_push(ctx, &v); } +/* ECMA-262 3rd Edition 7.8 */ +HRESULT interp_regexp(exec_ctx_t *ctx) +{ + const WCHAR *source = ctx->parser->code->instrs[ctx->ip].arg1.str; + const LONG flags = ctx->parser->code->instrs[ctx->ip].arg2.lng; + jsdisp_t *regexp; + VARIANT v; + HRESULT hres; + + TRACE("%s %x\n", debugstr_w(source), flags); + + hres = create_regexp(ctx->parser->script, source, strlenW(source), flags, ®exp); + if(FAILED(hres)) + return hres; + + var_set_jsdisp(&v, regexp); + return stack_push(ctx, &v); +} + /* ECMA-262 3rd Edition 7.8 */ HRESULT literal_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) { @@ -3382,13 +3401,13 @@ static HRESULT interp_tree(exec_ctx_t *ctx) typedef HRESULT (*op_func_t)(exec_ctx_t*); static const op_func_t op_funcs[] = { -#define X(x,a,b) interp_##x, +#define X(x,a,b,c) interp_##x, OP_LIST #undef X }; static const unsigned op_move[] = { -#define X(a,x,b) x, +#define X(a,x,b,c) x, OP_LIST #undef X }; diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index b48f04c0e9e..eb67050f383 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -41,24 +41,25 @@ typedef struct _func_stack { struct _func_stack *next; } func_stack_t; -#define OP_LIST \ - X(add, 1, 0) \ - X(bool, 1, 0) \ - X(bneg, 1, 0) \ - X(double, 1, 0) \ - X(eq2, 1, 0) \ - X(in, 1, 0) \ - X(int, 1, ARG_INT) \ - X(neg, 1, 0) \ - X(neq2, 1, 0) \ - X(null, 1, 0) \ - X(str, 1, 0) \ - X(tonum, 1, 0) \ - X(tree, 1, ARG_EXPR) \ - X(ret, 0, 0) +#define OP_LIST \ + X(add, 1, 0,0) \ + X(bool, 1, ARG_INT, 0) \ + X(bneg, 1, 0,0) \ + X(double, 1, ARG_SBL, 0) \ + X(eq2, 1, 0,0) \ + X(in, 1, 0,0) \ + X(int, 1, ARG_INT, 0) \ + X(neg, 1, 0,0) \ + X(neq2, 1, 0,0) \ + X(null, 1, 0,0) \ + X(regexp, 1, ARG_STR, ARG_INT) \ + X(str, 1, ARG_STR, 0) \ + X(tonum, 1, 0,0) \ + X(tree, 1, ARG_EXPR, 0) \ + X(ret, 0, 0,0) typedef enum { -#define X(x,a,b) OP_##x, +#define X(x,a,b,c) OP_##x, OP_LIST #undef X OP_LAST @@ -80,6 +81,7 @@ typedef enum { typedef struct { jsop_t op; instr_arg_t arg1; + instr_arg_t arg2; } instr_t; typedef struct { @@ -199,7 +201,6 @@ typedef struct { double dval; const WCHAR *wstr; VARIANT_BOOL bval; - IDispatch *disp; struct { const WCHAR *str; DWORD str_len;