Jacek Caban : jscript: Introduce function vtbl and use it for toString implementation.

Alexandre Julliard julliard at winehq.org
Wed Aug 14 20:17:23 CDT 2019


Module: wine
Branch: master
Commit: bad132acae32e47b471ceb712774a49973596597
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=bad132acae32e47b471ceb712774a49973596597

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Aug 14 13:17:51 2019 +0200

jscript: Introduce function vtbl and use it for toString implementation.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/jscript/function.c | 123 +++++++++++++++++++++++++++++-------------------
 1 file changed, 74 insertions(+), 49 deletions(-)

diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c
index 3c95d7b..54ff411 100644
--- a/dlls/jscript/function.c
+++ b/dlls/jscript/function.c
@@ -25,8 +25,11 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
 
+typedef struct _function_vtbl_t function_vtbl_t;
+
 typedef struct {
     jsdisp_t dispex;
+    const function_vtbl_t *vtbl;
     builtin_invoke_t value_proc;
     const WCHAR *name;
     DWORD flags;
@@ -36,6 +39,14 @@ typedef struct {
     DWORD length;
 } FunctionInstance;
 
+struct _function_vtbl_t {
+    HRESULT (*toString)(FunctionInstance*,jsstr_t**);
+};
+
+typedef struct {
+    FunctionInstance function;
+} NativeFunction;
+
 typedef struct {
     jsdisp_t jsdisp;
     FunctionInstance *function;
@@ -291,36 +302,6 @@ static HRESULT call_function(script_ctx_t *ctx, FunctionInstance *function, IDis
     return invoke_source(ctx, function, this_obj, argc, argv, FALSE, caller_execs_source, r);
 }
 
-static HRESULT function_to_string(FunctionInstance *function, jsstr_t **ret)
-{
-    jsstr_t *str;
-
-    static const WCHAR native_prefixW[] = {'\n','f','u','n','c','t','i','o','n',' '};
-    static const WCHAR native_suffixW[] =
-        {'(',')',' ','{','\n',' ',' ',' ',' ','[','n','a','t','i','v','e',' ','c','o','d','e',']','\n','}','\n'};
-
-    if(function->value_proc) {
-        DWORD name_len;
-        WCHAR *ptr;
-
-        name_len = lstrlenW(function->name);
-        str = jsstr_alloc_buf(ARRAY_SIZE(native_prefixW) + ARRAY_SIZE(native_suffixW) + name_len, &ptr);
-        if(!str)
-            return E_OUTOFMEMORY;
-
-        memcpy(ptr, native_prefixW, sizeof(native_prefixW));
-        memcpy(ptr += ARRAY_SIZE(native_prefixW), function->name, name_len*sizeof(WCHAR));
-        memcpy(ptr + name_len, native_suffixW, sizeof(native_suffixW));
-    }else {
-        str = jsstr_alloc_len(function->func_code->source, function->func_code->source_len);
-        if(!str)
-            return E_OUTOFMEMORY;
-    }
-
-    *ret = str;
-    return S_OK;
-}
-
 HRESULT Function_invoke(jsdisp_t *func_this, IDispatch *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 {
     const BOOL caller_execs_source = (flags & DISPATCH_JSCRIPT_CALLEREXECSSOURCE) != 0;
@@ -372,7 +353,7 @@ static HRESULT Function_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
     if(!(function = function_this(jsthis)))
         return throw_type_error(ctx, JS_E_FUNCTION_EXPECTED, NULL);
 
-    hres = function_to_string(function, &str);
+    hres = function->vtbl->toString(function, &str);
     if(FAILED(hres))
         return hres;
 
@@ -534,12 +515,13 @@ HRESULT Function_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned
 
 HRESULT Function_get_value(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
 {
+    FunctionInstance *function = function_from_jsdisp(jsthis);
     jsstr_t *str;
     HRESULT hres;
 
     TRACE("\n");
 
-    hres = function_to_string(function_from_jsdisp(jsthis), &str);
+    hres = function->vtbl->toString(function, &str);
     if(FAILED(hres))
         return hres;
 
@@ -613,13 +595,13 @@ static const builtin_info_t FunctionInst_info = {
     NULL
 };
 
-static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_info, DWORD flags,
-        BOOL funcprot, jsdisp_t *prototype, FunctionInstance **ret)
+static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_info, const function_vtbl_t *vtbl, size_t size,
+        DWORD flags, BOOL funcprot, jsdisp_t *prototype, void **ret)
 {
     FunctionInstance *function;
     HRESULT hres;
 
-    function = heap_alloc_zero(sizeof(FunctionInstance));
+    function = heap_alloc_zero(size);
     if(!function)
         return E_OUTOFMEMORY;
 
@@ -634,6 +616,7 @@ static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_
         return hres;
     }
 
+    function->vtbl = vtbl;
     function->flags = flags;
     function->length = flags & PROPF_ARGMASK;
 
@@ -641,13 +624,42 @@ static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_
     return S_OK;
 }
 
+static HRESULT NativeFunction_toString(FunctionInstance *function, jsstr_t **ret)
+{
+    DWORD name_len;
+    jsstr_t *str;
+    WCHAR *ptr;
+
+    static const WCHAR native_prefixW[] = {'\n','f','u','n','c','t','i','o','n',' '};
+    static const WCHAR native_suffixW[] =
+        {'(',')',' ','{','\n',' ',' ',' ',' ','[','n','a','t','i','v','e',' ','c','o','d','e',']','\n','}','\n'};
+
+    name_len = function->name ? lstrlenW(function->name) : 0;
+    str = jsstr_alloc_buf(ARRAY_SIZE(native_prefixW) + ARRAY_SIZE(native_suffixW) + name_len, &ptr);
+    if(!str)
+        return E_OUTOFMEMORY;
+
+    memcpy(ptr, native_prefixW, sizeof(native_prefixW));
+    ptr += ARRAY_SIZE(native_prefixW);
+    memcpy(ptr, function->name, name_len*sizeof(WCHAR));
+    ptr += name_len;
+    memcpy(ptr, native_suffixW, sizeof(native_suffixW));
+
+    *ret = str;
+    return S_OK;
+}
+
+static const function_vtbl_t NativeFunctionVtbl = {
+    NativeFunction_toString,
+};
+
 HRESULT create_builtin_function(script_ctx_t *ctx, builtin_invoke_t value_proc, const WCHAR *name,
         const builtin_info_t *builtin_info, DWORD flags, jsdisp_t *prototype, jsdisp_t **ret)
 {
     FunctionInstance *function;
     HRESULT hres;
 
-    hres = create_function(ctx, builtin_info, flags, FALSE, NULL, &function);
+    hres = create_function(ctx, builtin_info, &NativeFunctionVtbl, sizeof(NativeFunction), flags, FALSE, NULL, (void**)&function);
     if(FAILED(hres))
         return hres;
 
@@ -696,6 +708,16 @@ HRESULT create_builtin_constructor(script_ctx_t *ctx, builtin_invoke_t value_pro
     return S_OK;
 }
 
+static HRESULT InterpretedFunction_toString(FunctionInstance *function, jsstr_t **ret)
+{
+    *ret = jsstr_alloc_len(function->func_code->source, function->func_code->source_len);
+    return *ret ? S_OK : E_OUTOFMEMORY;
+}
+
+static const function_vtbl_t InterpretedFunctionVtbl = {
+    InterpretedFunction_toString,
+};
+
 HRESULT create_source_function(script_ctx_t *ctx, bytecode_t *code, function_code_t *func_code,
         scope_chain_t *scope_chain, jsdisp_t **ret)
 {
@@ -707,7 +729,8 @@ HRESULT create_source_function(script_ctx_t *ctx, bytecode_t *code, function_cod
     if(FAILED(hres))
         return hres;
 
-    hres = create_function(ctx, NULL, PROPF_CONSTR, FALSE, NULL, &function);
+    hres = create_function(ctx, NULL, &InterpretedFunctionVtbl, sizeof(FunctionInstance), PROPF_CONSTR,
+                           FALSE, NULL, (void**)&function);
     if(SUCCEEDED(hres)) {
         hres = jsdisp_define_data_property(&function->dispex, prototypeW, PROPF_WRITABLE,
                                            jsval_obj(prototype));
@@ -852,32 +875,34 @@ static HRESULT FunctionProt_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
 
 HRESULT init_function_constr(script_ctx_t *ctx, jsdisp_t *object_prototype)
 {
-    FunctionInstance *prot, *constr;
+    NativeFunction *prot, *constr;
     HRESULT hres;
 
     static const WCHAR FunctionW[] = {'F','u','n','c','t','i','o','n',0};
 
-    hres = create_function(ctx, &Function_info, PROPF_CONSTR, TRUE, object_prototype, &prot);
+    hres = create_function(ctx, &Function_info, &NativeFunctionVtbl, sizeof(NativeFunction), PROPF_CONSTR,
+                           TRUE, object_prototype, (void**)&prot);
     if(FAILED(hres))
         return hres;
 
-    prot->value_proc = FunctionProt_value;
-    prot->name = prototypeW;
+    prot->function.value_proc = FunctionProt_value;
+    prot->function.name = prototypeW;
 
-    hres = create_function(ctx, &FunctionInst_info, PROPF_CONSTR|1, TRUE, &prot->dispex, &constr);
+    hres = create_function(ctx, &FunctionInst_info, &NativeFunctionVtbl, sizeof(NativeFunction), PROPF_CONSTR|1,
+                           TRUE, &prot->function.dispex, (void**)&constr);
     if(SUCCEEDED(hres)) {
-        constr->value_proc = FunctionConstr_value;
-        constr->name = FunctionW;
-        hres = jsdisp_define_data_property(&constr->dispex, prototypeW, 0, jsval_obj(&prot->dispex));
+        constr->function.value_proc = FunctionConstr_value;
+        constr->function.name = FunctionW;
+        hres = jsdisp_define_data_property(&constr->function.dispex, prototypeW, 0, jsval_obj(&prot->function.dispex));
         if(SUCCEEDED(hres))
-            hres = set_constructor_prop(ctx, &constr->dispex, &prot->dispex);
+            hres = set_constructor_prop(ctx, &constr->function.dispex, &prot->function.dispex);
         if(FAILED(hres))
-            jsdisp_release(&constr->dispex);
+            jsdisp_release(&constr->function.dispex);
     }
-    jsdisp_release(&prot->dispex);
+    jsdisp_release(&prot->function.dispex);
     if(FAILED(hres))
         return hres;
 
-    ctx->function_constr = &constr->dispex;
+    ctx->function_constr = &constr->function.dispex;
     return S_OK;
 }




More information about the wine-cvs mailing list