Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
Note that we have to move the non-persistent vbscode from the context's list,
so it can be freed by the dispatch object only when it is released.
This is needed for the TypeInfo (and named contexts).
dlls/vbscript/compile.c | 15 ++++----
dlls/vbscript/interp.c | 39 +++++++++++----------
dlls/vbscript/vbdisp.c | 38 +++++++++++++++-----
dlls/vbscript/vbscript.c | 75 +++++++++++++++-------------------------
dlls/vbscript/vbscript.h | 43 ++++++++++++-----------
5 files changed, 107 insertions(+), 103 deletions(-)
diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index bc00209..9ddfacf 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -1758,21 +1758,22 @@ static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl)
static BOOL lookup_script_identifier(script_ctx_t *script, const WCHAR *identifier)
{
+ ScriptDisp *obj = script->script_obj;
class_desc_t *class;
vbscode_t *code;
unsigned i;
- for(i = 0; i < script->global_vars_cnt; i++) {
- if(!wcsicmp(script->global_vars[i]->name, identifier))
+ for(i = 0; i < obj->global_vars_cnt; i++) {
+ if(!wcsicmp(obj->global_vars[i]->name, identifier))
return TRUE;
}
- for(i = 0; i < script->global_funcs_cnt; i++) {
- if(!wcsicmp(script->global_funcs[i]->name, identifier))
+ for(i = 0; i < obj->global_funcs_cnt; i++) {
+ if(!wcsicmp(obj->global_funcs[i]->name, identifier))
return TRUE;
}
- for(class = script->classes; class; class = class->next) {
+ for(class = obj->classes; class; class = class->next) {
if(!wcsicmp(class->name, identifier))
return TRUE;
}
@@ -1977,8 +1978,8 @@ HRESULT compile_procedure(script_ctx_t *script, const WCHAR *src, const WCHAR *d
desc->func_cnt = 1;
desc->funcs->entries[VBDISP_CALLGET] = &code->main_code;
- desc->next = script->procs;
- script->procs = desc;
+ desc->next = script->script_obj->procs;
+ script->script_obj->procs = desc;
*ret = desc;
return S_OK;
diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index d15a1b5..66ad206 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -94,7 +94,7 @@ static BOOL lookup_dynamic_vars(dynamic_var_t *var, const WCHAR *name, ref_t *re
return FALSE;
}
-static BOOL lookup_global_vars(script_ctx_t *script, const WCHAR *name, ref_t *ref)
+static BOOL lookup_global_vars(ScriptDisp *script, const WCHAR *name, ref_t *ref)
{
dynamic_var_t **vars = script->global_vars;
size_t i, cnt = script->global_vars_cnt;
@@ -112,6 +112,7 @@ static BOOL lookup_global_vars(script_ctx_t *script, const WCHAR *name, ref_t *r
static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_t invoke_type, ref_t *ref)
{
+ ScriptDisp *script_obj = ctx->script->script_obj;
named_item_t *item;
IDispatch *disp;
unsigned i;
@@ -175,11 +176,11 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
}
}
- if(lookup_global_vars(ctx->script, name, ref))
+ if(lookup_global_vars(script_obj, name, ref))
return S_OK;
- for(i = 0; i < ctx->script->global_funcs_cnt; i++) {
- function_t *func = ctx->script->global_funcs[i];
+ for(i = 0; i < script_obj->global_funcs_cnt; i++) {
+ function_t *func = script_obj->global_funcs[i];
if(!wcsicmp(func->name, name)) {
ref->type = REF_FUNC;
ref->u.f = func;
@@ -221,12 +222,13 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_
static HRESULT add_dynamic_var(exec_ctx_t *ctx, const WCHAR *name,
BOOL is_const, VARIANT **out_var)
{
+ ScriptDisp *script_obj = ctx->script->script_obj;
dynamic_var_t *new_var;
heap_pool_t *heap;
WCHAR *str;
unsigned size;
- heap = ctx->func->type == FUNC_GLOBAL ? &ctx->script->heap : &ctx->heap;
+ heap = ctx->func->type == FUNC_GLOBAL ? &script_obj->heap : &ctx->heap;
new_var = heap_pool_alloc(heap, sizeof(*new_var));
if(!new_var)
@@ -243,19 +245,19 @@ static HRESULT add_dynamic_var(exec_ctx_t *ctx, const WCHAR *name,
V_VT(&new_var->v) = VT_EMPTY;
if(ctx->func->type == FUNC_GLOBAL) {
- size_t cnt = ctx->script->global_vars_cnt + 1;
- if(cnt > ctx->script->global_vars_size) {
+ size_t cnt = script_obj->global_vars_cnt + 1;
+ if(cnt > script_obj->global_vars_size) {
dynamic_var_t **new_vars;
- if(ctx->script->global_vars)
- new_vars = heap_realloc(ctx->script->global_vars, cnt * 2 * sizeof(*new_vars));
+ if(script_obj->global_vars)
+ new_vars = heap_realloc(script_obj->global_vars, cnt * 2 * sizeof(*new_vars));
else
new_vars = heap_alloc(cnt * 2 * sizeof(*new_vars));
if(!new_vars)
return E_OUTOFMEMORY;
- ctx->script->global_vars = new_vars;
- ctx->script->global_vars_size = cnt * 2;
+ script_obj->global_vars = new_vars;
+ script_obj->global_vars_size = cnt * 2;
}
- ctx->script->global_vars[ctx->script->global_vars_cnt++] = new_var;
+ script_obj->global_vars[script_obj->global_vars_cnt++] = new_var;
}else {
new_var->next = ctx->dynamic_vars;
ctx->dynamic_vars = new_var;
@@ -1113,7 +1115,7 @@ static HRESULT interp_new(exec_ctx_t *ctx)
return stack_push(ctx, &v);
}
- for(class_desc = ctx->script->classes; class_desc; class_desc = class_desc->next) {
+ for(class_desc = ctx->script->script_obj->classes; class_desc; class_desc = class_desc->next) {
if(!wcsicmp(class_desc->name, arg))
break;
}
@@ -1133,6 +1135,7 @@ static HRESULT interp_new(exec_ctx_t *ctx)
static HRESULT interp_dim(exec_ctx_t *ctx)
{
+ ScriptDisp *script_obj = ctx->script->script_obj;
const BSTR ident = ctx->instr->arg1.bstr;
const unsigned array_id = ctx->instr->arg2.uint;
const array_desc_t *array_desc;
@@ -1146,13 +1149,13 @@ static HRESULT interp_dim(exec_ctx_t *ctx)
if(ctx->func->type == FUNC_GLOBAL) {
unsigned i;
- for(i = 0; i < ctx->script->global_vars_cnt; i++) {
- if(!wcsicmp(ctx->script->global_vars[i]->name, ident))
+ for(i = 0; i < script_obj->global_vars_cnt; i++) {
+ if(!wcsicmp(script_obj->global_vars[i]->name, ident))
break;
}
- assert(i < ctx->script->global_vars_cnt);
- v = &ctx->script->global_vars[i]->v;
- array_ref = &ctx->script->global_vars[i]->array;
+ assert(i < script_obj->global_vars_cnt);
+ v = &script_obj->global_vars[i]->v;
+ array_ref = &script_obj->global_vars[i]->array;
}else {
ref_t ref;
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 12626e0..8bb2b68 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -569,11 +569,29 @@ static ULONG WINAPI ScriptDisp_Release(IDispatchEx *iface)
{
ScriptDisp *This = ScriptDisp_from_IDispatchEx(iface);
LONG ref = InterlockedDecrement(&This->ref);
+ unsigned i;
TRACE("(%p) ref=%d\n", This, ref);
if(!ref) {
assert(!This->ctx);
+
+ while (This->procs)
+ {
+ class_desc_t *class_desc = This->procs;
+ This->procs = class_desc->next;
+ heap_free(class_desc);
+ }
+
+ for (i = 0; i < This->global_vars_cnt; i++)
+ release_dynamic_var(This->global_vars[i]);
+
+ while (!list_empty(&This->code_list))
+ release_vbscode(LIST_ENTRY(list_head(&This->code_list), vbscode_t, entry));
+
+ heap_pool_free(&This->heap);
+ heap_free(This->global_vars);
+ heap_free(This->global_funcs);
heap_free(This);
}
@@ -639,15 +657,15 @@ static HRESULT WINAPI ScriptDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DW
if(!This->ctx)
return E_UNEXPECTED;
- for(i = 0; i < This->ctx->global_vars_cnt; i++) {
- if(!wcsicmp(This->ctx->global_vars[i]->name, bstrName)) {
+ for(i = 0; i < This->global_vars_cnt; i++) {
+ if(!wcsicmp(This->global_vars[i]->name, bstrName)) {
*pid = i + 1;
return S_OK;
}
}
- for(i = 0; i < This->ctx->global_funcs_cnt; i++) {
- if(!wcsicmp(This->ctx->global_funcs[i]->name, bstrName)) {
+ for(i = 0; i < This->global_funcs_cnt; i++) {
+ if(!wcsicmp(This->global_funcs[i]->name, bstrName)) {
*pid = i + 1 + DISPID_FUNCTION_MASK;
return S_OK;
}
@@ -668,14 +686,14 @@ static HRESULT WINAPI ScriptDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
if (id & DISPID_FUNCTION_MASK)
{
id &= ~DISPID_FUNCTION_MASK;
- if (id > This->ctx->global_funcs_cnt)
+ if (id > This->global_funcs_cnt)
return DISP_E_MEMBERNOTFOUND;
switch (wFlags)
{
case DISPATCH_METHOD:
case DISPATCH_METHOD | DISPATCH_PROPERTYGET:
- hres = exec_script(This->ctx, TRUE, This->ctx->global_funcs[id - 1], NULL, pdp, pvarRes);
+ hres = exec_script(This->ctx, TRUE, This->global_funcs[id - 1], NULL, pdp, pvarRes);
break;
default:
FIXME("Unsupported flags %x\n", wFlags);
@@ -685,16 +703,16 @@ static HRESULT WINAPI ScriptDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
return hres;
}
- if (id > This->ctx->global_vars_cnt)
+ if (id > This->global_vars_cnt)
return DISP_E_MEMBERNOTFOUND;
- if (This->ctx->global_vars[id - 1]->is_const)
+ if (This->global_vars[id - 1]->is_const)
{
FIXME("const not supported\n");
return E_NOTIMPL;
}
- return invoke_variant_prop(This->ctx, &This->ctx->global_vars[id - 1]->v, wFlags, pdp, pvarRes);
+ return invoke_variant_prop(This->ctx, &This->global_vars[id - 1]->v, wFlags, pdp, pvarRes);
}
static HRESULT WINAPI ScriptDisp_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
@@ -768,6 +786,8 @@ HRESULT create_script_disp(script_ctx_t *ctx, ScriptDisp **ret)
script_disp->IDispatchEx_iface.lpVtbl = &ScriptDispVtbl;
script_disp->ref = 1;
script_disp->ctx = ctx;
+ heap_pool_init(&script_disp->heap);
+ list_init(&script_disp->code_list);
*ret = script_disp;
return S_OK;
diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c
index fdade9f..9d20433 100644
--- a/dlls/vbscript/vbscript.c
+++ b/dlls/vbscript/vbscript.c
@@ -82,41 +82,42 @@ static inline BOOL is_started(VBScript *This)
static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code, VARIANT *res)
{
+ ScriptDisp *obj = ctx->script_obj;
function_t *func_iter, **new_funcs;
dynamic_var_t *var, **new_vars;
size_t cnt, i;
- cnt = ctx->global_vars_cnt + code->main_code.var_cnt;
- if (cnt > ctx->global_vars_size)
+ cnt = obj->global_vars_cnt + code->main_code.var_cnt;
+ if (cnt > obj->global_vars_size)
{
- if (ctx->global_vars)
- new_vars = heap_realloc(ctx->global_vars, cnt * sizeof(*new_vars));
+ if (obj->global_vars)
+ new_vars = heap_realloc(obj->global_vars, cnt * sizeof(*new_vars));
else
new_vars = heap_alloc(cnt * sizeof(*new_vars));
if (!new_vars)
return E_OUTOFMEMORY;
- ctx->global_vars = new_vars;
- ctx->global_vars_size = cnt;
+ obj->global_vars = new_vars;
+ obj->global_vars_size = cnt;
}
- cnt = ctx->global_funcs_cnt;
+ cnt = obj->global_funcs_cnt;
for (func_iter = code->funcs; func_iter; func_iter = func_iter->next)
cnt++;
- if (cnt > ctx->global_funcs_size)
+ if (cnt > obj->global_funcs_size)
{
- if (ctx->global_funcs)
- new_funcs = heap_realloc(ctx->global_funcs, cnt * sizeof(*new_funcs));
+ if (obj->global_funcs)
+ new_funcs = heap_realloc(obj->global_funcs, cnt * sizeof(*new_funcs));
else
new_funcs = heap_alloc(cnt * sizeof(*new_funcs));
if (!new_funcs)
return E_OUTOFMEMORY;
- ctx->global_funcs = new_funcs;
- ctx->global_funcs_size = cnt;
+ obj->global_funcs = new_funcs;
+ obj->global_funcs_size = cnt;
}
for (i = 0; i < code->main_code.var_cnt; i++)
{
- if (!(var = heap_pool_alloc(&ctx->heap, sizeof(*var))))
+ if (!(var = heap_pool_alloc(&obj->heap, sizeof(*var))))
return E_OUTOFMEMORY;
var->name = code->main_code.vars[i].name;
@@ -124,24 +125,24 @@ static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code, VARIANT *res
var->is_const = FALSE;
var->array = NULL;
- ctx->global_vars[ctx->global_vars_cnt + i] = var;
+ obj->global_vars[obj->global_vars_cnt + i] = var;
}
- ctx->global_vars_cnt += code->main_code.var_cnt;
+ obj->global_vars_cnt += code->main_code.var_cnt;
for (func_iter = code->funcs; func_iter; func_iter = func_iter->next)
{
- for (i = 0; i < ctx->global_funcs_cnt; i++)
+ for (i = 0; i < obj->global_funcs_cnt; i++)
{
- if (!wcsicmp(ctx->global_funcs[i]->name, func_iter->name))
+ if (!wcsicmp(obj->global_funcs[i]->name, func_iter->name))
{
/* global function already exists, replace it */
- ctx->global_funcs[i] = func_iter;
+ obj->global_funcs[i] = func_iter;
break;
}
}
- if (i == ctx->global_funcs_cnt)
- ctx->global_funcs[ctx->global_funcs_cnt++] = func_iter;
+ if (i == obj->global_funcs_cnt)
+ obj->global_funcs[obj->global_funcs_cnt++] = func_iter;
}
if (code->classes)
@@ -156,8 +157,8 @@ static HRESULT exec_global_code(script_ctx_t *ctx, vbscode_t *code, VARIANT *res
class = class->next;
}
- class->next = ctx->classes;
- ctx->classes = code->classes;
+ class->next = obj->classes;
+ obj->classes = code->classes;
code->last_class = class;
}
@@ -210,24 +211,10 @@ IDispatch *lookup_named_item(script_ctx_t *ctx, const WCHAR *name, unsigned flag
static void release_script(script_ctx_t *ctx)
{
vbscode_t *code, *code_next;
- class_desc_t *class_desc;
- unsigned i;
collect_objects(ctx);
clear_ei(&ctx->ei);
- for(i = 0; i < ctx->global_vars_cnt; i++)
- release_dynamic_var(ctx->global_vars[i]);
-
- heap_free(ctx->global_vars);
- heap_free(ctx->global_funcs);
- ctx->global_vars = NULL;
- ctx->global_vars_cnt = 0;
- ctx->global_vars_size = 0;
- ctx->global_funcs = NULL;
- ctx->global_funcs_cnt = 0;
- ctx->global_funcs_size = 0;
-
LIST_FOR_EACH_ENTRY_SAFE(code, code_next, &ctx->code_list, vbscode_t, entry)
{
if(code->is_persistent)
@@ -236,7 +223,10 @@ static void release_script(script_ctx_t *ctx)
if(code->last_class) code->last_class->next = NULL;
}
else
- release_vbscode(code);
+ {
+ list_remove(&code->entry);
+ list_add_tail(&ctx->script_obj->code_list, &code->entry);
+ }
}
while(!list_empty(&ctx->named_items)) {
@@ -249,13 +239,6 @@ static void release_script(script_ctx_t *ctx)
heap_free(iter);
}
- while(ctx->procs) {
- class_desc = ctx->procs;
- ctx->procs = class_desc->next;
-
- heap_free(class_desc);
- }
-
if(ctx->host_global) {
IDispatch_Release(ctx->host_global);
ctx->host_global = NULL;
@@ -278,9 +261,6 @@ static void release_script(script_ctx_t *ctx)
script_obj->ctx = NULL;
IDispatchEx_Release(&script_obj->IDispatchEx_iface);
}
-
- heap_pool_free(&ctx->heap);
- heap_pool_init(&ctx->heap);
}
static void release_code_list(script_ctx_t *ctx)
@@ -1054,7 +1034,6 @@ HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory *iface, IUnknown *pU
}
ctx->safeopt = INTERFACE_USES_DISPEX;
- heap_pool_init(&ctx->heap);
list_init(&ctx->objects);
list_init(&ctx->code_list);
list_init(&ctx->named_items);
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 1cc36fd..58db0b5 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -120,11 +120,33 @@ struct _vbdisp_t {
VARIANT props[1];
};
+typedef struct _dynamic_var_t {
+ struct _dynamic_var_t *next;
+ VARIANT v;
+ const WCHAR *name;
+ BOOL is_const;
+ SAFEARRAY *array;
+} dynamic_var_t;
+
typedef struct {
IDispatchEx IDispatchEx_iface;
LONG ref;
+ dynamic_var_t **global_vars;
+ size_t global_vars_cnt;
+ size_t global_vars_size;
+
+ function_t **global_funcs;
+ size_t global_funcs_cnt;
+ size_t global_funcs_size;
+
+ class_desc_t *classes;
+ class_desc_t *procs;
+
script_ctx_t *ctx;
+ heap_pool_t heap;
+
+ struct list code_list;
} ScriptDisp;
typedef struct _builtin_prop_t builtin_prop_t;
@@ -158,14 +180,6 @@ static inline VARIANT *get_arg(DISPPARAMS *dp, DWORD i)
return dp->rgvarg + dp->cArgs-i-1;
}
-typedef struct _dynamic_var_t {
- struct _dynamic_var_t *next;
- VARIANT v;
- const WCHAR *name;
- BOOL is_const;
- SAFEARRAY *array;
-} dynamic_var_t;
-
struct _script_ctx_t {
IActiveScriptSite *site;
LCID lcid;
@@ -182,19 +196,6 @@ struct _script_ctx_t {
EXCEPINFO ei;
- dynamic_var_t **global_vars;
- size_t global_vars_cnt;
- size_t global_vars_size;
-
- function_t **global_funcs;
- size_t global_funcs_cnt;
- size_t global_funcs_size;
-
- class_desc_t *classes;
- class_desc_t *procs;
-
- heap_pool_t heap;
-
struct list objects;
struct list code_list;
struct list named_items;
--
2.21.0