Jacek Caban : jscript: Added Function constructor implementation.

Alexandre Julliard julliard at winehq.org
Thu Dec 10 10:01:00 CST 2009


Module: wine
Branch: master
Commit: 538e15a0d720b7649d8363ef27c50f7aea1e77ac
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=538e15a0d720b7649d8363ef27c50f7aea1e77ac

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Dec 10 01:14:58 2009 +0100

jscript: Added Function constructor implementation.

---

 dlls/jscript/function.c |  115 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 113 insertions(+), 2 deletions(-)

diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c
index 49f8267..7819bc4 100644
--- a/dlls/jscript/function.c
+++ b/dlls/jscript/function.c
@@ -661,11 +661,122 @@ HRESULT create_source_function(parser_ctx_t *ctx, parameter_t *parameters, sourc
     return S_OK;
 }
 
+static HRESULT construct_function(script_ctx_t *ctx, DISPPARAMS *dp, jsexcept_t *ei, IDispatch **ret)
+{
+    function_expression_t *expr;
+    WCHAR *str = NULL, *ptr;
+    DWORD argc, len = 0, l;
+    parser_ctx_t *parser;
+    DispatchEx *function;
+    BSTR *params = NULL;
+    int i, j=0;
+    HRESULT hres = S_OK;
+
+    static const WCHAR function_anonymousW[] = {'f','u','n','c','t','i','o','n',' ','a','n','o','n','y','m','o','u','s','('};
+    static const WCHAR function_beginW[] = {')',' ','{','\n'};
+    static const WCHAR function_endW[] = {'\n','}',0};
+
+    argc = arg_cnt(dp);
+    if(argc) {
+        params = heap_alloc(argc*sizeof(BSTR));
+        if(!params)
+            return E_OUTOFMEMORY;
+
+        if(argc > 2)
+            len = (argc-2)*2; /* separating commas */
+        for(i=0; i < argc; i++) {
+            hres = to_string(ctx, get_arg(dp,i), ei, params+i);
+            if(FAILED(hres))
+                break;
+            len += SysStringLen(params[i]);
+        }
+    }
+
+    if(SUCCEEDED(hres)) {
+        len += (sizeof(function_anonymousW) + sizeof(function_beginW) + sizeof(function_endW)) / sizeof(WCHAR);
+        str = heap_alloc(len*sizeof(WCHAR));
+        if(str) {
+            memcpy(str, function_anonymousW, sizeof(function_anonymousW));
+            ptr = str + sizeof(function_anonymousW)/sizeof(WCHAR);
+            if(argc > 1) {
+                while(1) {
+                    l = SysStringLen(params[j]);
+                    memcpy(ptr, params[j], l*sizeof(WCHAR));
+                    ptr += l;
+                    if(++j == argc-1)
+                        break;
+                    *ptr++ = ',';
+                    *ptr++ = ' ';
+                }
+            }
+            memcpy(ptr, function_beginW, sizeof(function_beginW));
+            ptr += sizeof(function_beginW)/sizeof(WCHAR);
+            if(argc) {
+                l = SysStringLen(params[argc-1]);
+                memcpy(ptr, params[argc-1], l*sizeof(WCHAR));
+                ptr += l;
+            }
+            memcpy(ptr, function_endW, sizeof(function_endW));
+
+            TRACE("%s\n", debugstr_w(str));
+        }else {
+            hres = E_OUTOFMEMORY;
+        }
+    }
+
+    while(--i >= 0)
+        SysFreeString(params[i]);
+    heap_free(params);
+    if(FAILED(hres))
+        return hres;
+
+    hres = script_parse(ctx, str, NULL, &parser);
+    heap_free(str);
+    if(FAILED(hres))
+        return hres;
+
+    if(!parser->source || !parser->source->functions || parser->source->functions->next || parser->source->variables) {
+        ERR("Invalid parser result!\n");
+        parser_release(parser);
+        return E_UNEXPECTED;
+    }
+    expr = parser->source->functions->expr;
+
+    hres = create_source_function(parser, expr->parameter_list, expr->source_elements, NULL, expr->src_str,
+            expr->src_len, &function);
+    parser_release(parser);
+    if(FAILED(hres))
+        return hres;
+
+    *ret = (IDispatch*)_IDispatchEx_(function);
+    return S_OK;
+}
+
 static HRESULT FunctionConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    switch(flags) {
+    case DISPATCH_CONSTRUCT: {
+        IDispatch *ret;
+
+        hres = construct_function(ctx, dp, ei, &ret);
+        if(FAILED(hres))
+            return hres;
+
+        V_VT(retv) = VT_DISPATCH;
+        V_DISPATCH(retv) = ret;
+        break;
+    }
+    default:
+        FIXME("unimplemented flags %x\n", flags);
+        return E_NOTIMPL;
+    }
+
+    return S_OK;
 }
 
 static HRESULT FunctionProt_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,




More information about the wine-cvs mailing list