diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c index 492ca3c928b..3ee3d4063a0 100644 --- a/dlls/jscript/compile.c +++ b/dlls/jscript/compile.c @@ -53,6 +53,31 @@ static WCHAR *compiler_alloc_string(bytecode_t *code, const WCHAR *str) 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) { 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; } +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) { 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); case EXPR_EQEQ: 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: return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_in); case EXPR_LITERAL: @@ -346,7 +390,13 @@ static HRESULT compile_expression(compiler_ctx_t *ctx, expression_t *expr) 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); + heap_free(code->bstr_pool); heap_free(code->instrs); heap_free(code); } diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 7e78c83118b..273281edfb1 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -1738,6 +1738,28 @@ HRESULT identifier_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD 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 */ HRESULT interp_null(exec_ctx_t *ctx) { diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index c5681f74542..807bb8a640e 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -48,6 +48,7 @@ typedef struct _func_stack { X(double, 1, ARG_SBL, 0) \ X(eq, 1, 0,0) \ X(eq2, 1, 0,0) \ + X(ident, 1, ARG_BSTR, 0) \ X(in, 1, 0,0) \ X(int, 1, ARG_INT, 0) \ X(jmp, 0, ARG_ADDR, 0) \ @@ -78,6 +79,7 @@ OP_LIST typedef union { expression_t *expr; + BSTR bstr; double *dbl; LONG lng; WCHAR *str; @@ -87,6 +89,7 @@ typedef union { typedef enum { ARG_NONE = 0, ARG_ADDR, + ARG_BSTR, ARG_EXPR, ARG_INT, ARG_STR @@ -101,6 +104,10 @@ typedef struct { typedef struct { instr_t *instrs; jsheap_t heap; + + BSTR *bstr_pool; + unsigned bstr_pool_size; + unsigned bstr_cnt; } bytecode_t; void release_bytecode(bytecode_t*);