Jacek Caban : vbscript: Added beginning bytecode compiler implementation.
Alexandre Julliard
julliard at winehq.org
Wed Sep 7 12:35:30 CDT 2011
Module: wine
Branch: master
Commit: c674c7a7ae4e0d1e6022d16d7e70ac67d4961133
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c674c7a7ae4e0d1e6022d16d7e70ac67d4961133
Author: Jacek Caban <jacek at codeweavers.com>
Date: Wed Sep 7 14:07:12 2011 +0200
vbscript: Added beginning bytecode compiler implementation.
---
dlls/vbscript/Makefile.in | 1 +
dlls/vbscript/compile.c | 125 +++++++++++++++++++++++++++++++++++++++++++++
dlls/vbscript/vbscript.c | 15 ++++--
dlls/vbscript/vbscript.h | 41 +++++++++++++++
4 files changed, 177 insertions(+), 5 deletions(-)
diff --git a/dlls/vbscript/Makefile.in b/dlls/vbscript/Makefile.in
index ba267f4..977bcde 100644
--- a/dlls/vbscript/Makefile.in
+++ b/dlls/vbscript/Makefile.in
@@ -1,6 +1,7 @@
MODULE = vbscript.dll
C_SRCS = \
+ compile.c \
lex.c \
vbdisp.c \
vbscript.c \
diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
new file mode 100644
index 0000000..c51dd97
--- /dev/null
+++ b/dlls/vbscript/compile.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2011 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <assert.h>
+
+#include "vbscript.h"
+#include "parse.h"
+#include "parser.tab.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
+
+typedef struct {
+ parser_ctx_t parser;
+
+ unsigned instr_cnt;
+ unsigned instr_size;
+ vbscode_t *code;
+} compile_ctx_t;
+
+static unsigned push_instr(compile_ctx_t *ctx, vbsop_t op)
+{
+ assert(ctx->instr_size && ctx->instr_size >= ctx->instr_cnt);
+
+ if(ctx->instr_size == ctx->instr_cnt) {
+ instr_t *new_instr;
+
+ new_instr = heap_realloc(ctx->code->instrs, ctx->instr_size*2*sizeof(instr_t));
+ if(!new_instr)
+ return -1;
+
+ ctx->code->instrs = new_instr;
+ ctx->instr_size *= 2;
+ }
+
+ ctx->code->instrs[ctx->instr_cnt].op = op;
+ return ctx->instr_cnt++;
+}
+
+static HRESULT compile_func(compile_ctx_t *ctx, function_t *func)
+{
+ func->code_off = ctx->instr_cnt;
+
+ if(push_instr(ctx, OP_ret) == -1)
+ return E_OUTOFMEMORY;
+
+ return S_OK;
+}
+
+void release_vbscode(vbscode_t *code)
+{
+ list_remove(&code->entry);
+ heap_free(code->source);
+ heap_free(code->instrs);
+ heap_free(code);
+}
+
+static vbscode_t *alloc_vbscode(compile_ctx_t *ctx, const WCHAR *source)
+{
+ vbscode_t *ret;
+
+ ret = heap_alloc(sizeof(*ret));
+ if(!ret)
+ return NULL;
+
+ ret->source = heap_strdupW(source);
+ if(!ret->source) {
+ heap_free(ret);
+ return NULL;
+ }
+
+ ret->instrs = heap_alloc(32*sizeof(instr_t));
+ if(!ret->instrs) {
+ release_vbscode(ret);
+ return NULL;
+ }
+
+ ctx->instr_cnt = 0;
+ ctx->instr_size = 32;
+
+ ret->global_code.code_ctx = ret;
+
+ list_init(&ret->entry);
+ return ret;
+}
+
+HRESULT compile_script(script_ctx_t *script, const WCHAR *src, vbscode_t **ret)
+{
+ compile_ctx_t ctx;
+ HRESULT hres;
+
+ hres = parse_script(&ctx.parser, src);
+ if(FAILED(hres))
+ return hres;
+
+ ctx.code = alloc_vbscode(&ctx, src);
+ if(!ctx.code)
+ return E_OUTOFMEMORY;
+
+ hres = compile_func(&ctx, &ctx.code->global_code);
+ if(FAILED(hres)) {
+ release_vbscode(ctx.code);
+ return hres;
+ }
+
+ list_add_tail(&script->code_list, &ctx.code->entry);
+ *ret = ctx.code;
+ return S_OK;
+}
diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c
index 53e90eb..ff9d2c9 100644
--- a/dlls/vbscript/vbscript.c
+++ b/dlls/vbscript/vbscript.c
@@ -20,8 +20,6 @@
#include <assert.h>
#include "vbscript.h"
-#include "parse.h"
-
#include "objsafe.h"
#include "wine/debug.h"
@@ -89,6 +87,9 @@ static HRESULT set_ctx_site(VBScript *This)
static void destroy_script(script_ctx_t *ctx)
{
+ while(!list_empty(&ctx->code_list))
+ release_vbscode(LIST_ENTRY(list_head(&ctx->code_list), vbscode_t, entry));
+
while(!list_empty(&ctx->named_items)) {
named_item_t *iter = LIST_ENTRY(list_head(&ctx->named_items), named_item_t, entry);
@@ -483,6 +484,7 @@ static HRESULT WINAPI VBScriptParse_InitNew(IActiveScriptParse *iface)
if(!ctx)
return E_OUTOFMEMORY;
+ list_init(&ctx->code_list);
list_init(&ctx->named_items);
old_ctx = InterlockedCompareExchangePointer((void**)&This->ctx, ctx, NULL);
@@ -514,18 +516,21 @@ static HRESULT WINAPI VBScriptParse_ParseScriptText(IActiveScriptParse *iface,
DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo)
{
VBScript *This = impl_from_IActiveScriptParse(iface);
- parser_ctx_t parser;
+ vbscode_t *code;
HRESULT hres;
TRACE("(%p)->(%s %s %p %s %s %u %x %p %p)\n", This, debugstr_w(pstrCode),
debugstr_w(pstrItemName), punkContext, debugstr_w(pstrDelimiter),
wine_dbgstr_longlong(dwSourceContextCookie), ulStartingLine, dwFlags, pvarResult, pexcepinfo);
- hres = parse_script(&parser, pstrCode);
+ if(This->thread_id != GetCurrentThreadId() || This->state == SCRIPTSTATE_CLOSED)
+ return E_UNEXPECTED;
+
+ hres = compile_script(This->ctx, pstrCode, &code);
if(FAILED(hres))
return hres;
- FIXME("compiling script not implemented\n");
+ FIXME("executing script not implemented\n");
return E_NOTIMPL;
}
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 9c1d35c..88f7552 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -31,6 +31,9 @@
#include "wine/list.h"
#include "wine/unicode.h"
+typedef struct _function_t function_t;
+typedef struct _vbscode_t vbscode_t;
+
typedef struct named_item_t {
IDispatch *disp;
DWORD flags;
@@ -53,11 +56,44 @@ typedef struct {
vbdisp_t *script_obj;
+ struct list code_list;
struct list named_items;
} script_ctx_t;
HRESULT init_global(script_ctx_t*);
+#define OP_LIST \
+ X(ret, 0)
+
+typedef enum {
+#define X(x,n) OP_##x,
+OP_LIST
+#undef X
+ OP_LAST
+} vbsop_t;
+
+typedef struct {
+ vbsop_t op;
+} instr_t;
+
+struct _function_t {
+ unsigned code_off;
+ vbscode_t *code_ctx;
+};
+
+struct _vbscode_t {
+ instr_t *instrs;
+ WCHAR *source;
+
+ BOOL global_executed;
+ function_t global_code;
+
+ struct list entry;
+};
+
+void release_vbscode(vbscode_t*) DECLSPEC_HIDDEN;
+HRESULT compile_script(script_ctx_t*,const WCHAR*,vbscode_t**) DECLSPEC_HIDDEN;
+
HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**);
static inline void *heap_alloc(size_t len)
@@ -70,6 +106,11 @@ static inline void *heap_alloc_zero(size_t len)
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
}
+static inline void *heap_realloc(void *mem, size_t len)
+{
+ return HeapReAlloc(GetProcessHeap(), 0, mem, len);
+}
+
static inline BOOL heap_free(void *mem)
{
return HeapFree(GetProcessHeap(), 0, mem);
More information about the wine-cvs
mailing list