jscript: Added bytecode-based version of identifier expression.
This commit is contained in:
parent
518f4c4983
commit
bd80daff96
|
@ -53,6 +53,31 @@ static WCHAR *compiler_alloc_string(bytecode_t *code, const WCHAR *str)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BSTR compiler_alloc_bstr(compiler_ctx_t *ctx, const WCHAR *str)
|
||||||
|
{
|
||||||
|
if(!ctx->code->bstr_pool_size) {
|
||||||
|
ctx->code->bstr_pool = heap_alloc(8 * sizeof(BSTR));
|
||||||
|
if(!ctx->code->bstr_pool)
|
||||||
|
return NULL;
|
||||||
|
ctx->code->bstr_pool_size = 8;
|
||||||
|
}else if(ctx->code->bstr_pool_size == ctx->code->bstr_cnt) {
|
||||||
|
BSTR *new_pool;
|
||||||
|
|
||||||
|
new_pool = heap_realloc(ctx->code->bstr_pool, ctx->code->bstr_pool_size*2*sizeof(BSTR));
|
||||||
|
if(!new_pool)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ctx->code->bstr_pool = new_pool;
|
||||||
|
ctx->code->bstr_pool_size *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->code->bstr_pool[ctx->code->bstr_cnt] = SysAllocString(str);
|
||||||
|
if(!ctx->code->bstr_pool[ctx->code->bstr_cnt])
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return ctx->code->bstr_pool[ctx->code->bstr_cnt++];
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
@ -112,6 +137,23 @@ static HRESULT push_instr_str(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT push_instr_bstr(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
|
||||||
|
{
|
||||||
|
unsigned instr;
|
||||||
|
WCHAR *str;
|
||||||
|
|
||||||
|
str = compiler_alloc_bstr(ctx, arg);
|
||||||
|
if(!str)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
instr = push_instr(ctx, op);
|
||||||
|
if(instr == -1)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
instr_ptr(ctx, instr)->arg1.bstr = str;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT push_instr_double(compiler_ctx_t *ctx, jsop_t op, double arg)
|
static HRESULT push_instr_double(compiler_ctx_t *ctx, jsop_t op, double arg)
|
||||||
{
|
{
|
||||||
unsigned instr;
|
unsigned instr;
|
||||||
|
@ -312,6 +354,8 @@ static HRESULT compile_expression(compiler_ctx_t *ctx, expression_t *expr)
|
||||||
return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_eq);
|
return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_eq);
|
||||||
case EXPR_EQEQ:
|
case EXPR_EQEQ:
|
||||||
return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_eq2);
|
return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_eq2);
|
||||||
|
case EXPR_IDENT:
|
||||||
|
return push_instr_bstr(ctx, OP_ident, ((identifier_expression_t*)expr)->identifier);
|
||||||
case EXPR_IN:
|
case EXPR_IN:
|
||||||
return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_in);
|
return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_in);
|
||||||
case EXPR_LITERAL:
|
case EXPR_LITERAL:
|
||||||
|
@ -346,7 +390,13 @@ static HRESULT compile_expression(compiler_ctx_t *ctx, expression_t *expr)
|
||||||
|
|
||||||
void release_bytecode(bytecode_t *code)
|
void release_bytecode(bytecode_t *code)
|
||||||
{
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for(i=0; i < code->bstr_cnt; i++)
|
||||||
|
SysFreeString(code->bstr_pool[i]);
|
||||||
|
|
||||||
jsheap_free(&code->heap);
|
jsheap_free(&code->heap);
|
||||||
|
heap_free(code->bstr_pool);
|
||||||
heap_free(code->instrs);
|
heap_free(code->instrs);
|
||||||
heap_free(code);
|
heap_free(code);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1738,6 +1738,28 @@ HRESULT identifier_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ECMA-262 3rd Edition 10.1.4 */
|
||||||
|
static HRESULT interp_ident(exec_ctx_t *ctx)
|
||||||
|
{
|
||||||
|
const BSTR arg = ctx->parser->code->instrs[ctx->ip].arg1.bstr;
|
||||||
|
exprval_t exprval;
|
||||||
|
VARIANT v;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
TRACE("%s\n", debugstr_w(arg));
|
||||||
|
|
||||||
|
hres = identifier_eval(ctx->parser->script, arg, 0, &ctx->ei, &exprval);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
hres = exprval_to_value(ctx->parser->script, &exprval, &ctx->ei, &v);
|
||||||
|
exprval_release(&exprval);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
return stack_push(ctx, &v);
|
||||||
|
}
|
||||||
|
|
||||||
/* ECMA-262 3rd Edition 7.8.1 */
|
/* ECMA-262 3rd Edition 7.8.1 */
|
||||||
HRESULT interp_null(exec_ctx_t *ctx)
|
HRESULT interp_null(exec_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,6 +48,7 @@ typedef struct _func_stack {
|
||||||
X(double, 1, ARG_SBL, 0) \
|
X(double, 1, ARG_SBL, 0) \
|
||||||
X(eq, 1, 0,0) \
|
X(eq, 1, 0,0) \
|
||||||
X(eq2, 1, 0,0) \
|
X(eq2, 1, 0,0) \
|
||||||
|
X(ident, 1, ARG_BSTR, 0) \
|
||||||
X(in, 1, 0,0) \
|
X(in, 1, 0,0) \
|
||||||
X(int, 1, ARG_INT, 0) \
|
X(int, 1, ARG_INT, 0) \
|
||||||
X(jmp, 0, ARG_ADDR, 0) \
|
X(jmp, 0, ARG_ADDR, 0) \
|
||||||
|
@ -78,6 +79,7 @@ OP_LIST
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
expression_t *expr;
|
expression_t *expr;
|
||||||
|
BSTR bstr;
|
||||||
double *dbl;
|
double *dbl;
|
||||||
LONG lng;
|
LONG lng;
|
||||||
WCHAR *str;
|
WCHAR *str;
|
||||||
|
@ -87,6 +89,7 @@ typedef union {
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ARG_NONE = 0,
|
ARG_NONE = 0,
|
||||||
ARG_ADDR,
|
ARG_ADDR,
|
||||||
|
ARG_BSTR,
|
||||||
ARG_EXPR,
|
ARG_EXPR,
|
||||||
ARG_INT,
|
ARG_INT,
|
||||||
ARG_STR
|
ARG_STR
|
||||||
|
@ -101,6 +104,10 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
instr_t *instrs;
|
instr_t *instrs;
|
||||||
jsheap_t heap;
|
jsheap_t heap;
|
||||||
|
|
||||||
|
BSTR *bstr_pool;
|
||||||
|
unsigned bstr_pool_size;
|
||||||
|
unsigned bstr_cnt;
|
||||||
} bytecode_t;
|
} bytecode_t;
|
||||||
|
|
||||||
void release_bytecode(bytecode_t*);
|
void release_bytecode(bytecode_t*);
|
||||||
|
|
Loading…
Reference in New Issue