jscript: Use bytecode for regexp literals.
This commit is contained in:
parent
83c53d855a
commit
e4f92ef473
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue