Jacek Caban : jscript: Added expression statement implementation.

Alexandre Julliard julliard at winehq.org
Tue Sep 9 05:50:41 CDT 2008


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Sep  9 01:21:55 2008 +0200

jscript: Added expression statement implementation.

---

 dlls/jscript/dispex.c  |   35 ++++++++++++++++++++
 dlls/jscript/engine.c  |   83 ++++++++++++++++++++++++++++++++++++++++++++++--
 dlls/jscript/engine.h  |   19 ++++++++++-
 dlls/jscript/jscript.h |    1 +
 4 files changed, 134 insertions(+), 4 deletions(-)

diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index 270e172..f279655 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -837,3 +837,38 @@ HRESULT disp_call(IDispatch *disp, DISPID id, LCID lcid, WORD flags, DISPPARAMS
 
     return hres;
 }
+
+HRESULT disp_propget(IDispatch *disp, DISPID id, LCID lcid, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller)
+{
+    DISPPARAMS dp  = {NULL,NULL,0,0};
+    IDispatchEx *dispex;
+    DispatchEx *jsdisp;
+    HRESULT hres;
+
+    jsdisp = iface_to_jsdisp((IUnknown*)disp);
+    if(jsdisp) {
+        dispex_prop_t *prop;
+
+        prop = get_prop(jsdisp, id);
+        if(prop)
+            hres = prop_get(jsdisp, prop, lcid, &dp, val, ei, caller);
+        else
+            hres = DISP_E_MEMBERNOTFOUND;
+
+        IDispatchEx_Release(_IDispatchEx_(jsdisp));
+        return hres;
+    }
+
+    hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
+    if(FAILED(hres)) {
+        ULONG err = 0;
+
+        TRACE("uding IDispatch\n");
+        return IDispatchEx_Invoke(dispex, id, &IID_NULL, lcid, INVOKE_PROPERTYGET, &dp, val, &ei->ei, &err);
+    }
+
+    hres = IDispatchEx_InvokeEx(dispex, id, lcid, INVOKE_PROPERTYGET, &dp, val, &ei->ei, caller);
+    IDispatchEx_Release(dispex);
+
+    return hres;
+}
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c
index ef66c97..72f723d 100644
--- a/dlls/jscript/engine.c
+++ b/dlls/jscript/engine.c
@@ -23,11 +23,69 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
 
+#define EXPR_NOVAL   0x0001
+#define EXPR_NEWREF  0x0002
+#define EXPR_STRREF  0x0004
+
 static inline HRESULT stat_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
 {
     return stat->eval(ctx, stat, rt, ret);
 }
 
+static inline HRESULT expr_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
+{
+    return _expr->eval(ctx, _expr, flags, ei, ret);
+}
+
+static void exprval_release(exprval_t *val)
+{
+    switch(val->type) {
+    case EXPRVAL_VARIANT:
+        VariantClear(&val->u.var);
+        return;
+    case EXPRVAL_IDREF:
+        if(val->u.idref.disp)
+            IDispatch_Release(val->u.idref.disp);
+        return;
+    case EXPRVAL_NAMEREF:
+        if(val->u.nameref.disp)
+            IDispatch_Release(val->u.nameref.disp);
+        SysFreeString(val->u.nameref.name);
+    }
+}
+
+/* ECMA-262 3rd Edition    8.7.1 */
+static HRESULT exprval_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret)
+{
+    V_VT(ret) = VT_EMPTY;
+
+    switch(val->type) {
+    case EXPRVAL_VARIANT:
+        return VariantCopy(ret, &val->u.var);
+    case EXPRVAL_IDREF:
+        if(!val->u.idref.disp) {
+            FIXME("throw ReferenceError\n");
+            return E_FAIL;
+        }
+
+        return disp_propget(val->u.idref.disp, val->u.idref.id, ctx->lcid, ret, ei, NULL/*FIXME*/);
+    default:
+        ERR("type %d\n", val->type);
+        return E_FAIL;
+    }
+}
+
+static HRESULT exprval_to_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret)
+{
+    if(val->type == EXPRVAL_VARIANT) {
+        *ret = val->u.var;
+        V_VT(&val->u.var) = VT_EMPTY;
+        return S_OK;
+    }
+
+    return exprval_value(ctx, val, ei, ret);
+}
+
 HRESULT create_exec_ctx(exec_ctx_t **ret)
 {
     exec_ctx_t *ctx;
@@ -112,6 +170,7 @@ HRESULT var_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt
     return E_NOTIMPL;
 }
 
+/* ECMA-262 3rd Edition    12.3 */
 HRESULT empty_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
 {
     TRACE("\n");
@@ -120,10 +179,28 @@ HRESULT empty_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *
     return S_OK;
 }
 
-HRESULT expression_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
+/* ECMA-262 3rd Edition    12.4 */
+HRESULT expression_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    expression_statement_t *stat = (expression_statement_t*)_stat;
+    exprval_t exprval;
+    VARIANT val;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    hres = expr_eval(ctx, stat->expr, EXPR_NOVAL, &rt->ei, &exprval);
+    if(FAILED(hres))
+        return hres;
+
+    hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
+    exprval_release(&exprval);
+    if(FAILED(hres))
+        return hres;
+
+    *ret = val;
+    TRACE("= %s\n", debugstr_variant(ret));
+    return S_OK;
 }
 
 HRESULT if_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h
index 6e91178..c8dcfba 100644
--- a/dlls/jscript/engine.h
+++ b/dlls/jscript/engine.h
@@ -215,7 +215,24 @@ HRESULT switch_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
 HRESULT throw_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
 HRESULT try_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
 
-typedef struct exprval_t exprval_t;
+typedef struct {
+    enum {
+        EXPRVAL_VARIANT,
+        EXPRVAL_IDREF,
+        EXPRVAL_NAMEREF
+    } type;
+    union {
+        VARIANT var;
+        struct {
+            IDispatch *disp;
+            DISPID id;
+        } idref;
+        struct {
+            IDispatch *disp;
+            BSTR name;
+        } nameref;
+    } u;
+} exprval_t;
 
 typedef HRESULT (*expression_eval_t)(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
 
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index b676198..a8cfad2 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -87,6 +87,7 @@ struct DispatchEx {
 
 HRESULT create_dispex(script_ctx_t*,const builtin_info_t*,DispatchEx*,DispatchEx**);
 HRESULT disp_call(IDispatch*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
+HRESULT disp_propget(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
 
 struct _script_ctx_t {
     LONG ref;




More information about the wine-cvs mailing list