Module: wine Branch: master Commit: b268e41da6367ea6cb9b24b4450ee94ddb6222a4 URL: http://source.winehq.org/git/wine.git/?a=commit;h=b268e41da6367ea6cb9b24b445...
Author: Jacek Caban jacek@codeweavers.com Date: Fri Dec 16 11:42:57 2011 +0100
jscript: Use bytecode for function expression implementation.
---
dlls/jscript/compile.c | 17 +++++++++++++++++ dlls/jscript/engine.c | 30 ++++++++++-------------------- dlls/jscript/engine.h | 4 +++- dlls/jscript/parser.y | 2 +- dlls/jscript/tests/lang.js | 6 ++++++ dlls/jscript/tests/run.c | 2 ++ 6 files changed, 39 insertions(+), 22 deletions(-)
diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c index 9718c69..9331910 100644 --- a/dlls/jscript/compile.c +++ b/dlls/jscript/compile.c @@ -646,6 +646,21 @@ static HRESULT compile_array_literal(compiler_ctx_t *ctx, array_literal_expressi return push_instr_uint(ctx, OP_carray, elem_cnt); }
+static HRESULT compile_function_expression(compiler_ctx_t *ctx, function_expression_t *expr) +{ + unsigned instr; + + /* FIXME: not exactly right */ + if(expr->identifier) + return push_instr_bstr(ctx, OP_ident, expr->identifier); + + instr = push_instr(ctx, OP_func); + if(instr == -1) + return E_OUTOFMEMORY; + + instr_ptr(ctx, instr)->arg1.func = expr; + return S_OK; +}
static HRESULT compile_expression_noret(compiler_ctx_t *ctx, expression_t *expr, BOOL *no_ret) { @@ -702,6 +717,8 @@ static HRESULT compile_expression_noret(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_FUNC: + return compile_function_expression(ctx, (function_expression_t*)expr); case EXPR_GREATER: return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_gt); case EXPR_GREATEREQ: diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 98e4158..23f457d 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -1420,32 +1420,22 @@ HRESULT try_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_t }
/* ECMA-262 3rd Edition 13 */ -HRESULT function_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) +static HRESULT interp_func(exec_ctx_t *ctx) { - function_expression_t *expr = (function_expression_t*)_expr; - VARIANT var; + function_expression_t *expr = ctx->parser->code->instrs[ctx->ip].arg1.func; + jsdisp_t *dispex; + VARIANT v; HRESULT hres;
TRACE("\n");
- if(expr->identifier) { - hres = jsdisp_propget_name(ctx->exec_ctx->var_disp, expr->identifier, &var, ei, NULL/*FIXME*/); - if(FAILED(hres)) - return hres; - }else { - jsdisp_t *dispex; - - hres = create_source_function(ctx->exec_ctx->parser, expr->parameter_list, expr->source_elements, ctx->exec_ctx->scope_chain, - expr->src_str, expr->src_len, &dispex); - if(FAILED(hres)) - return hres; - - var_set_jsdisp(&var, dispex); - } + hres = create_source_function(ctx->parser, expr->parameter_list, expr->source_elements, ctx->scope_chain, + expr->src_str, expr->src_len, &dispex); + if(FAILED(hres)) + return hres;
- ret->type = EXPRVAL_VARIANT; - ret->u.var = var; - return S_OK; + var_set_jsdisp(&v, dispex); + return stack_push(ctx, &v); }
/* ECMA-262 3rd Edition 11.2.1 */ diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index 2cea63d..fcdc093 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -57,6 +57,7 @@ typedef struct _func_stack { X(double, 1, ARG_SBL, 0) \ X(eq, 1, 0,0) \ X(eq2, 1, 0,0) \ + X(func, 1, ARG_FUNC, 0) \ X(gt, 1, 0,0) \ X(gteq, 1, 0,0) \ X(ident, 1, ARG_BSTR, 0) \ @@ -117,6 +118,7 @@ typedef union { LONG lng; WCHAR *str; unsigned uint; + function_expression_t *func; /* FIXME */ } instr_arg_t;
typedef enum { @@ -124,6 +126,7 @@ typedef enum { ARG_ADDR, ARG_BSTR, ARG_EXPR, + ARG_FUNC, ARG_INT, ARG_STR } instr_arg_type_t; @@ -565,7 +568,6 @@ typedef struct { prop_val_t *property_list; } property_value_expression_t;
-HRESULT function_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN; HRESULT property_value_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
HRESULT compiled_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN; diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y index c791e9c..41481ab 100644 --- a/dlls/jscript/parser.y +++ b/dlls/jscript/parser.y @@ -1357,7 +1357,7 @@ static const expression_eval_t expression_eval_table[] = { compiled_expression_eval, compiled_expression_eval, compiled_expression_eval, - function_expression_eval, + compiled_expression_eval, compiled_expression_eval, compiled_expression_eval, property_value_expression_eval, diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index 165e70e..13c90fa 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -1110,6 +1110,12 @@ ok(newValue === 1, "newValue = " + newValue);
obj = {undefined: 3};
+ok(typeof(name_override_func) === "function", "typeof(name_override_func) = " + typeof(name_override_func)); +name_override_func = 3; +ok(name_override_func === 3, "name_override_func = " + name_override_func); +function name_override_func() {}; +ok(name_override_func === 3, "name_override_func = " + name_override_func); + /* Keep this test in the end of file */ undefined = 6; ok(undefined === 6, "undefined = " + undefined); diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c index 890809c..5626bd8 100644 --- a/dlls/jscript/tests/run.c +++ b/dlls/jscript/tests/run.c @@ -1487,6 +1487,8 @@ static void run_tests(void) CHECK_CALLED(global_propdelete_d); CHECK_CALLED(DeleteMemberByDispID);
+ parse_script_a("(function reportSuccess() {})()"); + parse_script_a("ok(typeof(test) === 'object', "typeof(test) != 'object'");");
parse_script_a("function reportSuccess() {}; reportSuccess();");