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