Jacek Caban : jscript: Added IActiveScript::ParseScriptText implementation.

Alexandre Julliard julliard at winehq.org
Fri Sep 5 06:57:56 CDT 2008


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Sep  5 02:37:59 2008 +0200

jscript: Added IActiveScript::ParseScriptText implementation.

---

 dlls/jscript/Makefile.in |    2 +-
 dlls/jscript/engine.c    |   77 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/jscript/engine.h    |   34 ++++++++++++++------
 dlls/jscript/jscript.c   |   72 +++++++++++++++++++++++++++++++++++++++++-
 dlls/jscript/jscript.h   |    7 ++++
 5 files changed, 179 insertions(+), 13 deletions(-)

diff --git a/dlls/jscript/Makefile.in b/dlls/jscript/Makefile.in
index 96d8c37..095659b 100644
--- a/dlls/jscript/Makefile.in
+++ b/dlls/jscript/Makefile.in
@@ -3,7 +3,7 @@ TOPOBJDIR = ../..
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = jscript.dll
-IMPORTS   = kernel32
+IMPORTS   = oleaut32 kernel32
 
 RC_SRCS = rsrc.rc
 
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c
index a65e5d8..827087f 100644
--- a/dlls/jscript/engine.c
+++ b/dlls/jscript/engine.c
@@ -23,6 +23,83 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
 
+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);
+}
+
+HRESULT create_exec_ctx(exec_ctx_t **ret)
+{
+    exec_ctx_t *ctx;
+
+    ctx = heap_alloc_zero(sizeof(exec_ctx_t));
+    if(!ctx)
+        return E_OUTOFMEMORY;
+
+    *ret = ctx;
+    return S_OK;
+}
+
+void exec_release(exec_ctx_t *ctx)
+{
+    if(--ctx->ref)
+        return;
+
+    heap_free(ctx);
+}
+
+HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, jsexcept_t *ei, VARIANT *retv)
+{
+    script_ctx_t *script = parser->script;
+    parser_ctx_t *prev_parser;
+    VARIANT val, tmp;
+    statement_t *stat;
+    exec_ctx_t *prev_ctx;
+    return_type_t rt;
+    HRESULT hres = S_OK;
+
+    prev_ctx = script->exec_ctx;
+    script->exec_ctx = ctx;
+
+    prev_parser = ctx->parser;
+    ctx->parser = parser;
+
+    V_VT(&val) = VT_EMPTY;
+    memset(&rt, 0, sizeof(rt));
+    rt.type = RT_NORMAL;
+
+    for(stat = source->statement; stat; stat = stat->next) {
+        hres = stat_eval(ctx, stat, &rt, &tmp);
+        if(FAILED(hres))
+            break;
+
+        VariantClear(&val);
+        val = tmp;
+        if(rt.type != RT_NORMAL)
+            break;
+    }
+
+    script->exec_ctx = prev_ctx;
+    ctx->parser = prev_parser;
+
+    if(rt.type != RT_NORMAL && rt.type != RT_RETURN) {
+        FIXME("wrong rt %d\n", rt.type);
+        hres = E_FAIL;
+    }
+
+    *ei = rt.ei;
+    if(FAILED(hres)) {
+        VariantClear(&val);
+        return hres;
+    }
+
+    if(retv)
+        *retv = val;
+    else
+        VariantClear(&val);
+    return S_OK;
+}
+
 HRESULT block_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
 {
     FIXME("\n");
diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h
index 1fad3dd..6e91178 100644
--- a/dlls/jscript/engine.h
+++ b/dlls/jscript/engine.h
@@ -32,6 +32,8 @@ typedef struct _parser_ctx_t {
 
     jsheap_t tmp_heap;
     jsheap_t heap;
+
+    struct _parser_ctx_t *next;
 } parser_ctx_t;
 
 HRESULT script_parse(script_ctx_t*,const WCHAR*,parser_ctx_t**);
@@ -54,17 +56,20 @@ static inline void *parser_alloc_tmp(parser_ctx_t *ctx, DWORD size)
     return jsheap_alloc(&ctx->tmp_heap, size);
 }
 
-typedef struct {
-    enum{
-        RT_NORMAL,
-        RT_RETURN,
-        RT_BREAK
-    } type;
-} return_type_t;
+struct _exec_ctx_t {
+    LONG ref;
 
-typedef struct _exec_ctx_t {
     parser_ctx_t *parser;
-} exec_ctx_t;
+};
+
+static inline void exec_addref(exec_ctx_t *ctx)
+{
+    ctx->ref++;
+}
+
+void exec_release(exec_ctx_t*);
+HRESULT create_exec_ctx(exec_ctx_t**);
+HRESULT exec_source(exec_ctx_t*,parser_ctx_t*,source_elements_t*,jsexcept_t*,VARIANT*);
 
 typedef struct _statement_t statement_t;
 typedef struct _expression_t expression_t;
@@ -88,6 +93,16 @@ typedef struct _variable_declaration_t {
     struct _variable_declaration_t *next;
 } variable_declaration_t;
 
+typedef struct {
+    enum{
+        RT_NORMAL,
+        RT_RETURN,
+        RT_BREAK,
+        RT_CONTINUE
+    } type;
+    jsexcept_t ei;
+} return_type_t;
+
 typedef HRESULT (*statement_eval_t)(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
 
 struct _statement_t {
@@ -201,7 +216,6 @@ 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 jsexcept_t jsexcept_t;
 
 typedef HRESULT (*expression_eval_t)(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
 
diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c
index 27cf071..adfd73c 100644
--- a/dlls/jscript/jscript.c
+++ b/dlls/jscript/jscript.c
@@ -38,6 +38,9 @@ typedef struct {
     LONG thread_id;
 
     IActiveScriptSite *site;
+
+    parser_ctx_t *queue_head;
+    parser_ctx_t *queue_tail;
 } JScript;
 
 #define ACTSCRIPT(x)    ((IActiveScript*)                 &(x)->lpIActiveScriptVtbl)
@@ -63,6 +66,56 @@ static void change_state(JScript *This, SCRIPTSTATE state)
     IActiveScriptSite_OnStateChange(This->site, state);
 }
 
+static inline BOOL is_started(script_ctx_t *ctx)
+{
+    return ctx->state == SCRIPTSTATE_STARTED
+        || ctx->state == SCRIPTSTATE_CONNECTED
+        || ctx->state == SCRIPTSTATE_DISCONNECTED;
+}
+
+static HRESULT exec_global_code(JScript *This, parser_ctx_t *parser_ctx)
+{
+    exec_ctx_t *exec_ctx;
+    jsexcept_t jsexcept;
+    VARIANT var;
+    HRESULT hres;
+
+    hres = create_exec_ctx(&exec_ctx);
+    if(FAILED(hres))
+        return hres;
+
+    IActiveScriptSite_OnEnterScript(This->site);
+
+    memset(&jsexcept, 0, sizeof(jsexcept));
+    hres = exec_source(exec_ctx, parser_ctx, parser_ctx->source, &jsexcept, &var);
+    VariantClear(&jsexcept.var);
+    exec_release(exec_ctx);
+    if(SUCCEEDED(hres))
+        VariantClear(&var);
+
+    IActiveScriptSite_OnLeaveScript(This->site);
+
+    return hres;
+}
+
+static void clear_script_queue(JScript *This)
+{
+    parser_ctx_t *iter, *iter2;
+
+    if(!This->queue_head)
+        return;
+
+    iter = This->queue_head;
+    while(iter) {
+        iter2 = iter->next;
+        iter->next = NULL;
+        parser_release(iter);
+        iter = iter2;
+    }
+
+    This->queue_head = This->queue_tail = NULL;
+}
+
 #define ACTSCRIPT_THIS(iface) DEFINE_THIS(JScript, IActiveScript, iface)
 
 static HRESULT WINAPI JScript_QueryInterface(IActiveScript *iface, REFIID riid, void **ppv)
@@ -216,6 +269,8 @@ static HRESULT WINAPI JScript_Close(IActiveScript *iface)
     if(This->thread_id != GetCurrentThreadId())
         return E_UNEXPECTED;
 
+    clear_script_queue(This);
+
     if(This->ctx) {
         change_state(This, SCRIPTSTATE_CLOSED);
 
@@ -398,16 +453,29 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface,
     parser_ctx_t *parser_ctx;
     HRESULT hres;
 
-    FIXME("(%p)->(%s %s %p %s %x %u %x %p %p)\n", This, debugstr_w(pstrCode),
+    TRACE("(%p)->(%s %s %p %s %x %u %x %p %p)\n", This, debugstr_w(pstrCode),
           debugstr_w(pstrItemName), punkContext, debugstr_w(pstrDelimiter),
           dwSourceContextCookie, ulStartingLine, dwFlags, pvarResult, pexcepinfo);
 
+    if(This->thread_id != GetCurrentThreadId() || This->ctx->state == SCRIPTSTATE_CLOSED)
+        return E_UNEXPECTED;
+
     hres = script_parse(This->ctx, pstrCode, &parser_ctx);
     if(FAILED(hres))
         return hres;
 
+    if(!is_started(This->ctx)) {
+        if(This->queue_tail)
+            This->queue_tail = This->queue_tail->next = parser_ctx;
+        else
+            This->queue_head = This->queue_tail = parser_ctx;
+        return S_OK;
+    }
+
+    hres = exec_global_code(This, parser_ctx);
     parser_release(parser_ctx);
-    return E_NOTIMPL;
+
+    return hres;
 }
 
 #undef ASPARSE_THIS
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index 1f55604..0fff0e8 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -32,6 +32,12 @@
 #include "wine/list.h"
 
 typedef struct _script_ctx_t script_ctx_t;
+typedef struct _exec_ctx_t exec_ctx_t;
+
+typedef struct {
+    EXCEPINFO ei;
+    VARIANT var;
+} jsexcept_t;
 
 typedef struct DispatchEx {
     const IDispatchExVtbl  *lpIDispatchExVtbl;
@@ -49,6 +55,7 @@ struct _script_ctx_t {
     LONG ref;
 
     SCRIPTSTATE state;
+    exec_ctx_t *exec_ctx;
     LCID lcid;
 
     DispatchEx *script_disp;




More information about the wine-cvs mailing list