jscript: Added IActiveScript::ParseScriptText implementation.
This commit is contained in:
parent
fe64fe5ef8
commit
69f8b4b9b2
|
@ -3,7 +3,7 @@ TOPOBJDIR = ../..
|
||||||
SRCDIR = @srcdir@
|
SRCDIR = @srcdir@
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
MODULE = jscript.dll
|
MODULE = jscript.dll
|
||||||
IMPORTS = kernel32
|
IMPORTS = oleaut32 kernel32
|
||||||
|
|
||||||
RC_SRCS = rsrc.rc
|
RC_SRCS = rsrc.rc
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,83 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(jscript);
|
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)
|
HRESULT block_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
|
||||||
{
|
{
|
||||||
FIXME("\n");
|
FIXME("\n");
|
||||||
|
|
|
@ -32,6 +32,8 @@ typedef struct _parser_ctx_t {
|
||||||
|
|
||||||
jsheap_t tmp_heap;
|
jsheap_t tmp_heap;
|
||||||
jsheap_t heap;
|
jsheap_t heap;
|
||||||
|
|
||||||
|
struct _parser_ctx_t *next;
|
||||||
} parser_ctx_t;
|
} parser_ctx_t;
|
||||||
|
|
||||||
HRESULT script_parse(script_ctx_t*,const WCHAR*,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);
|
return jsheap_alloc(&ctx->tmp_heap, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
struct _exec_ctx_t {
|
||||||
enum{
|
LONG ref;
|
||||||
RT_NORMAL,
|
|
||||||
RT_RETURN,
|
|
||||||
RT_BREAK
|
|
||||||
} type;
|
|
||||||
} return_type_t;
|
|
||||||
|
|
||||||
typedef struct _exec_ctx_t {
|
|
||||||
parser_ctx_t *parser;
|
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 _statement_t statement_t;
|
||||||
typedef struct _expression_t expression_t;
|
typedef struct _expression_t expression_t;
|
||||||
|
@ -88,6 +93,16 @@ typedef struct _variable_declaration_t {
|
||||||
struct _variable_declaration_t *next;
|
struct _variable_declaration_t *next;
|
||||||
} variable_declaration_t;
|
} 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*);
|
typedef HRESULT (*statement_eval_t)(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
|
||||||
|
|
||||||
struct _statement_t {
|
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*);
|
HRESULT try_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
|
||||||
|
|
||||||
typedef struct exprval_t exprval_t;
|
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*);
|
typedef HRESULT (*expression_eval_t)(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,9 @@ typedef struct {
|
||||||
LONG thread_id;
|
LONG thread_id;
|
||||||
|
|
||||||
IActiveScriptSite *site;
|
IActiveScriptSite *site;
|
||||||
|
|
||||||
|
parser_ctx_t *queue_head;
|
||||||
|
parser_ctx_t *queue_tail;
|
||||||
} JScript;
|
} JScript;
|
||||||
|
|
||||||
#define ACTSCRIPT(x) ((IActiveScript*) &(x)->lpIActiveScriptVtbl)
|
#define ACTSCRIPT(x) ((IActiveScript*) &(x)->lpIActiveScriptVtbl)
|
||||||
|
@ -63,6 +66,56 @@ static void change_state(JScript *This, SCRIPTSTATE state)
|
||||||
IActiveScriptSite_OnStateChange(This->site, 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)
|
#define ACTSCRIPT_THIS(iface) DEFINE_THIS(JScript, IActiveScript, iface)
|
||||||
|
|
||||||
static HRESULT WINAPI JScript_QueryInterface(IActiveScript *iface, REFIID riid, void **ppv)
|
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())
|
if(This->thread_id != GetCurrentThreadId())
|
||||||
return E_UNEXPECTED;
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
|
clear_script_queue(This);
|
||||||
|
|
||||||
if(This->ctx) {
|
if(This->ctx) {
|
||||||
change_state(This, SCRIPTSTATE_CLOSED);
|
change_state(This, SCRIPTSTATE_CLOSED);
|
||||||
|
|
||||||
|
@ -398,16 +453,29 @@ static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface,
|
||||||
parser_ctx_t *parser_ctx;
|
parser_ctx_t *parser_ctx;
|
||||||
HRESULT hres;
|
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),
|
debugstr_w(pstrItemName), punkContext, debugstr_w(pstrDelimiter),
|
||||||
dwSourceContextCookie, ulStartingLine, dwFlags, pvarResult, pexcepinfo);
|
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);
|
hres = script_parse(This->ctx, pstrCode, &parser_ctx);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return 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);
|
parser_release(parser_ctx);
|
||||||
return E_NOTIMPL;
|
|
||||||
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef ASPARSE_THIS
|
#undef ASPARSE_THIS
|
||||||
|
|
|
@ -32,6 +32,12 @@
|
||||||
#include "wine/list.h"
|
#include "wine/list.h"
|
||||||
|
|
||||||
typedef struct _script_ctx_t script_ctx_t;
|
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 {
|
typedef struct DispatchEx {
|
||||||
const IDispatchExVtbl *lpIDispatchExVtbl;
|
const IDispatchExVtbl *lpIDispatchExVtbl;
|
||||||
|
@ -49,6 +55,7 @@ struct _script_ctx_t {
|
||||||
LONG ref;
|
LONG ref;
|
||||||
|
|
||||||
SCRIPTSTATE state;
|
SCRIPTSTATE state;
|
||||||
|
exec_ctx_t *exec_ctx;
|
||||||
LCID lcid;
|
LCID lcid;
|
||||||
|
|
||||||
DispatchEx *script_disp;
|
DispatchEx *script_disp;
|
||||||
|
|
Loading…
Reference in New Issue