Jacek Caban : jscript: Use bytecode for function expression implementation.

Alexandre Julliard julliard at winehq.org
Fri Dec 16 11:22:53 CST 2011


Module: wine
Branch: master
Commit: b268e41da6367ea6cb9b24b4450ee94ddb6222a4
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=b268e41da6367ea6cb9b24b4450ee94ddb6222a4

Author: Jacek Caban <jacek at 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();");




More information about the wine-cvs mailing list