From e5e7803a550bf7b0f8621514e03553eba0010ad7 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Wed, 23 Nov 2011 12:14:15 +0100 Subject: [PATCH] jscript: Use bytecode for string literal. --- dlls/jscript/compile.c | 38 ++++++++++++++++++++++++++++++++++++++ dlls/jscript/engine.c | 16 ++++++++++++++++ dlls/jscript/engine.h | 3 +++ 3 files changed, 57 insertions(+) diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c index 2f2516bd99b..5b7d9d0eefc 100644 --- a/dlls/jscript/compile.c +++ b/dlls/jscript/compile.c @@ -36,6 +36,23 @@ struct _compiler_ctx_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) { 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; } +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) { 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); case LT_INT: return push_instr_int(ctx, OP_int, literal->u.lval); + case LT_STRING: + return push_instr_str(ctx, OP_str, literal->u.wstr); default: 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) { + jsheap_free(&code->heap); heap_free(code->instrs); 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)); if(!parser->code) return E_OUTOFMEMORY; + jsheap_init(&parser->code->heap); } if(!parser->compiler) { diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 1d35496b932..b894b44b7eb 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -1747,6 +1747,22 @@ HRESULT interp_int(exec_ctx_t *ctx) 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 */ HRESULT literal_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) { diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index 302f9a5289d..1e463cc9aa7 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -50,6 +50,7 @@ typedef struct _func_stack { X(int, 1, ARG_INT) \ X(neg, 1, 0) \ X(neq2, 1, 0) \ + X(str, 1, 0) \ X(tonum, 1, 0) \ X(tree, 1, ARG_EXPR) \ X(ret, 0, 0) @@ -64,6 +65,7 @@ OP_LIST typedef union { expression_t *expr; LONG lng; + WCHAR *str; } instr_arg_t; typedef enum { @@ -79,6 +81,7 @@ typedef struct { typedef struct { instr_t *instrs; + jsheap_t heap; } bytecode_t; void release_bytecode(bytecode_t*);