jscript: Use bytecode for string literal.
This commit is contained in:
parent
13d96df4bd
commit
e5e7803a55
|
@ -36,6 +36,23 @@ struct _compiler_ctx_t {
|
||||||
|
|
||||||
static HRESULT compile_expression(compiler_ctx_t*,expression_t*);
|
static HRESULT compile_expression(compiler_ctx_t*,expression_t*);
|
||||||
|
|
||||||
|
static inline void *compiler_alloc(bytecode_t *code, size_t size)
|
||||||
|
{
|
||||||
|
return jsheap_alloc(&code->heap, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static WCHAR *compiler_alloc_string(bytecode_t *code, const WCHAR *str)
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
WCHAR *ret;
|
||||||
|
|
||||||
|
size = (strlenW(str)+1)*sizeof(WCHAR);
|
||||||
|
ret = compiler_alloc(code, size);
|
||||||
|
if(ret)
|
||||||
|
memcpy(ret, str, size);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
@ -78,6 +95,23 @@ static HRESULT push_instr_int(compiler_ctx_t *ctx, jsop_t op, LONG arg)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT push_instr_str(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
|
||||||
|
{
|
||||||
|
unsigned instr;
|
||||||
|
WCHAR *str;
|
||||||
|
|
||||||
|
str = compiler_alloc_string(ctx->code, arg);
|
||||||
|
if(!str)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
instr = push_instr(ctx, op);
|
||||||
|
if(instr == -1)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
instr_ptr(ctx, instr)->arg1.str = str;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT compile_binary_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
|
static HRESULT compile_binary_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
|
||||||
{
|
{
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
@ -125,6 +159,8 @@ static HRESULT compile_literal(compiler_ctx_t *ctx, literal_expression_t *expr)
|
||||||
return push_instr_int(ctx, OP_bool, literal->u.bval);
|
return push_instr_int(ctx, OP_bool, literal->u.bval);
|
||||||
case LT_INT:
|
case LT_INT:
|
||||||
return push_instr_int(ctx, OP_int, literal->u.lval);
|
return push_instr_int(ctx, OP_int, literal->u.lval);
|
||||||
|
case LT_STRING:
|
||||||
|
return push_instr_str(ctx, OP_str, literal->u.wstr);
|
||||||
default:
|
default:
|
||||||
return compile_interp_fallback(ctx, &expr->expr);
|
return compile_interp_fallback(ctx, &expr->expr);
|
||||||
}
|
}
|
||||||
|
@ -159,6 +195,7 @@ static HRESULT compile_expression(compiler_ctx_t *ctx, expression_t *expr)
|
||||||
|
|
||||||
void release_bytecode(bytecode_t *code)
|
void release_bytecode(bytecode_t *code)
|
||||||
{
|
{
|
||||||
|
jsheap_free(&code->heap);
|
||||||
heap_free(code->instrs);
|
heap_free(code->instrs);
|
||||||
heap_free(code);
|
heap_free(code);
|
||||||
}
|
}
|
||||||
|
@ -176,6 +213,7 @@ HRESULT compile_subscript(parser_ctx_t *parser, expression_t *expr, unsigned *re
|
||||||
parser->code = heap_alloc_zero(sizeof(bytecode_t));
|
parser->code = heap_alloc_zero(sizeof(bytecode_t));
|
||||||
if(!parser->code)
|
if(!parser->code)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
jsheap_init(&parser->code->heap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!parser->compiler) {
|
if(!parser->compiler) {
|
||||||
|
|
|
@ -1747,6 +1747,22 @@ HRESULT interp_int(exec_ctx_t *ctx)
|
||||||
return stack_push(ctx, &v);
|
return stack_push(ctx, &v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ECMA-262 3rd Edition 7.8.4 */
|
||||||
|
HRESULT interp_str(exec_ctx_t *ctx)
|
||||||
|
{
|
||||||
|
const WCHAR *str = ctx->parser->code->instrs[ctx->ip].arg1.str;
|
||||||
|
VARIANT v;
|
||||||
|
|
||||||
|
TRACE("%s\n", debugstr_w(str));
|
||||||
|
|
||||||
|
V_VT(&v) = VT_BSTR;
|
||||||
|
V_BSTR(&v) = SysAllocString(str);
|
||||||
|
if(!V_BSTR(&v))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
return stack_push(ctx, &v);
|
||||||
|
}
|
||||||
|
|
||||||
/* ECMA-262 3rd Edition 7.8 */
|
/* 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)
|
HRESULT literal_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
|
||||||
{
|
{
|
||||||
|
|
|
@ -50,6 +50,7 @@ typedef struct _func_stack {
|
||||||
X(int, 1, ARG_INT) \
|
X(int, 1, ARG_INT) \
|
||||||
X(neg, 1, 0) \
|
X(neg, 1, 0) \
|
||||||
X(neq2, 1, 0) \
|
X(neq2, 1, 0) \
|
||||||
|
X(str, 1, 0) \
|
||||||
X(tonum, 1, 0) \
|
X(tonum, 1, 0) \
|
||||||
X(tree, 1, ARG_EXPR) \
|
X(tree, 1, ARG_EXPR) \
|
||||||
X(ret, 0, 0)
|
X(ret, 0, 0)
|
||||||
|
@ -64,6 +65,7 @@ OP_LIST
|
||||||
typedef union {
|
typedef union {
|
||||||
expression_t *expr;
|
expression_t *expr;
|
||||||
LONG lng;
|
LONG lng;
|
||||||
|
WCHAR *str;
|
||||||
} instr_arg_t;
|
} instr_arg_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -79,6 +81,7 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
instr_t *instrs;
|
instr_t *instrs;
|
||||||
|
jsheap_t heap;
|
||||||
} bytecode_t;
|
} bytecode_t;
|
||||||
|
|
||||||
void release_bytecode(bytecode_t*);
|
void release_bytecode(bytecode_t*);
|
||||||
|
|
Loading…
Reference in New Issue