Jacek Caban : jscript: Added RegExp function call implementation.

Alexandre Julliard julliard at winehq.org
Wed Sep 23 11:03:36 CDT 2009


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Sep 23 16:09:22 2009 +0200

jscript: Added RegExp function call implementation.

---

 dlls/jscript/error.c         |   24 +++++++++++++++++++-----
 dlls/jscript/jscript.h       |    2 ++
 dlls/jscript/jscript_En.rc   |    1 +
 dlls/jscript/regexp.c        |   33 +++++++++++++++++++++++++++++++--
 dlls/jscript/resource.h      |    1 +
 dlls/jscript/tests/api.js    |    1 +
 dlls/jscript/tests/regexp.js |   12 ++++++++++++
 7 files changed, 67 insertions(+), 7 deletions(-)

diff --git a/dlls/jscript/error.c b/dlls/jscript/error.c
index 2aa5436..bced477 100644
--- a/dlls/jscript/error.c
+++ b/dlls/jscript/error.c
@@ -310,6 +310,14 @@ static HRESULT ReferenceErrorConstr_value(DispatchEx *dispex, LCID lcid, WORD fl
             dispex->ctx->reference_error_constr);
 }
 
+static HRESULT RegExpErrorConstr_value(DispatchEx *dispex, LCID lcid, WORD flags,
+        DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
+{
+    TRACE("\n");
+    return error_constr(dispex, flags, dp, retv, ei,
+            dispex->ctx->regexp_error_constr);
+}
+
 static HRESULT SyntaxErrorConstr_value(DispatchEx *dispex, LCID lcid, WORD flags,
         DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
@@ -341,25 +349,26 @@ HRESULT init_error_constr(script_ctx_t *ctx, DispatchEx *object_prototype)
     static const WCHAR EvalErrorW[] = {'E','v','a','l','E','r','r','o','r',0};
     static const WCHAR RangeErrorW[] = {'R','a','n','g','e','E','r','r','o','r',0};
     static const WCHAR ReferenceErrorW[] = {'R','e','f','e','r','e','n','c','e','E','r','r','o','r',0};
+    static const WCHAR RegExpErrorW[] = {'R','e','g','E','x','p','E','r','r','o','r',0};
     static const WCHAR SyntaxErrorW[] = {'S','y','n','t','a','x','E','r','r','o','r',0};
     static const WCHAR TypeErrorW[] = {'T','y','p','e','E','r','r','o','r',0};
     static const WCHAR URIErrorW[] = {'U','R','I','E','r','r','o','r',0};
     static const WCHAR *names[] = {ErrorW, EvalErrorW, RangeErrorW,
-        ReferenceErrorW, SyntaxErrorW, TypeErrorW, URIErrorW};
+        ReferenceErrorW, RegExpErrorW, SyntaxErrorW, TypeErrorW, URIErrorW};
     DispatchEx **constr_addr[] = {&ctx->error_constr, &ctx->eval_error_constr,
-        &ctx->range_error_constr, &ctx->reference_error_constr,
+        &ctx->range_error_constr, &ctx->reference_error_constr, &ctx->regexp_error_constr,
         &ctx->syntax_error_constr, &ctx->type_error_constr,
         &ctx->uri_error_constr};
     static builtin_invoke_t constr_val[] = {ErrorConstr_value, EvalErrorConstr_value,
-        RangeErrorConstr_value, ReferenceErrorConstr_value, SyntaxErrorConstr_value,
-        TypeErrorConstr_value, URIErrorConstr_value};
+        RangeErrorConstr_value, ReferenceErrorConstr_value, RegExpErrorConstr_value,
+        SyntaxErrorConstr_value, TypeErrorConstr_value, URIErrorConstr_value};
 
     ErrorInstance *err;
     INT i;
     VARIANT v;
     HRESULT hres;
 
-    for(i=0; i<7; i++) {
+    for(i=0; i < sizeof(names)/sizeof(names[0]); i++) {
         hres = alloc_error(ctx, i==0 ? object_prototype : NULL, NULL, &err);
         if(FAILED(hres))
             return hres;
@@ -433,6 +442,11 @@ HRESULT throw_reference_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const
     return throw_error(ctx, ei, id, str, ctx->reference_error_constr);
 }
 
+HRESULT throw_regexp_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
+{
+    return throw_error(ctx, ei, id, str, ctx->regexp_error_constr);
+}
+
 HRESULT throw_syntax_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
 {
     return throw_error(ctx, ei, id, str, ctx->syntax_error_constr);
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index f09e257..6f861b8 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -151,6 +151,7 @@ HRESULT Function_value(DispatchEx*,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IS
 HRESULT throw_eval_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
 HRESULT throw_range_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
 HRESULT throw_reference_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
+HRESULT throw_regexp_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
 HRESULT throw_syntax_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
 HRESULT throw_type_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
 HRESULT throw_uri_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
@@ -208,6 +209,7 @@ struct _script_ctx_t {
     DispatchEx *eval_error_constr;
     DispatchEx *range_error_constr;
     DispatchEx *reference_error_constr;
+    DispatchEx *regexp_error_constr;
     DispatchEx *syntax_error_constr;
     DispatchEx *type_error_constr;
     DispatchEx *uri_error_constr;
diff --git a/dlls/jscript/jscript_En.rc b/dlls/jscript/jscript_En.rc
index eca9bc8..b7f8744 100644
--- a/dlls/jscript/jscript_En.rc
+++ b/dlls/jscript/jscript_En.rc
@@ -38,5 +38,6 @@ STRINGTABLE DISCARDABLE
     IDS_ILLEGAL_ASSIGN      "Illegal assignment"
     IDS_UNDEFINED           "'|' is undefined"
     IDS_NOT_BOOL            "Boolean object expected"
+    IDS_REGEXP_SYNTAX_ERROR "Syntax error in regular expression"
     IDS_INVALID_LENGTH      "Array length must be a finite positive integer"
 }
diff --git a/dlls/jscript/regexp.c b/dlls/jscript/regexp.c
index 1c017b0..28154da 100644
--- a/dlls/jscript/regexp.c
+++ b/dlls/jscript/regexp.c
@@ -3819,8 +3819,12 @@ static HRESULT regexp_constructor(script_ctx_t *ctx, DISPPARAMS *dp, VARIANT *re
     if(FAILED(hres))
         return hres;
 
-    V_VT(retv) = VT_DISPATCH;
-    V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(ret);
+    if(retv) {
+        V_VT(retv) = VT_DISPATCH;
+        V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(ret);
+    }else {
+        jsdisp_release(ret);
+    }
     return S_OK;
 }
 
@@ -3830,6 +3834,31 @@ static HRESULT RegExpConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DIS
     TRACE("\n");
 
     switch(flags) {
+    case DISPATCH_METHOD:
+        if(arg_cnt(dp)) {
+            VARIANT *arg = get_arg(dp,0);
+            if(V_VT(arg) == VT_DISPATCH) {
+                DispatchEx *jsdisp = iface_to_jsdisp((IUnknown*)V_DISPATCH(arg));
+                if(jsdisp) {
+                    if(is_class(jsdisp, JSCLASS_REGEXP)) {
+                        if(arg_cnt(dp) > 1 && V_VT(get_arg(dp,1)) != VT_EMPTY) {
+                            jsdisp_release(jsdisp);
+                            return throw_regexp_error(dispex->ctx, ei, IDS_REGEXP_SYNTAX_ERROR, NULL);
+                        }
+
+                        if(retv) {
+                            V_VT(retv) = VT_DISPATCH;
+                            V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(jsdisp);
+                        }else {
+                            jsdisp_release(jsdisp);
+                        }
+                        return S_OK;
+                    }
+                    jsdisp_release(jsdisp);
+                }
+            }
+        }
+        /* fall through */
     case DISPATCH_CONSTRUCT:
         return regexp_constructor(dispex->ctx, dp, retv);
     default:
diff --git a/dlls/jscript/resource.h b/dlls/jscript/resource.h
index 2749bd6..9e33ebc 100644
--- a/dlls/jscript/resource.h
+++ b/dlls/jscript/resource.h
@@ -34,4 +34,5 @@
 #define IDS_ILLEGAL_ASSIGN                  0x1390
 #define IDS_UNDEFINED                       0x1391
 #define IDS_NOT_BOOL                        0x1392
+#define IDS_REGEXP_SYNTAX_ERROR             0x1399
 #define IDS_INVALID_LENGTH                  0x13A5
diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js
index 7a39d0f..7b22212 100644
--- a/dlls/jscript/tests/api.js
+++ b/dlls/jscript/tests/api.js
@@ -1617,6 +1617,7 @@ exception_test(function() {eval("while(")}, "SyntaxError", -2146827286);
 exception_test(function() {eval("if(")}, "SyntaxError", -2146827286);
 exception_test(function() {eval("'unterminated")}, "SyntaxError", -2146827273);
 exception_test(function() {eval("nonexistingfunc()")}, "TypeError", -2146823281);
+exception_test(function() {RegExp(/a/, "g");}, "RegExpError", -2146823271);
 
 function testObjectInherit(obj, constr, ts, tls, vo) {
     ok(obj instanceof Object, "obj is not instance of Object");
diff --git a/dlls/jscript/tests/regexp.js b/dlls/jscript/tests/regexp.js
index a839adb..ff98b48 100644
--- a/dlls/jscript/tests/regexp.js
+++ b/dlls/jscript/tests/regexp.js
@@ -286,4 +286,16 @@ ok(re.source === "abc[^d]", "re.source = '" + re.source + "', expected 'abc[^d]'
 re = /a\bc[^d]/g;
 ok(re.source === "a\\bc[^d]", "re.source = '" + re.source + "', expected 'a\\bc[^d]'");
 
+re = /abc/;
+ok(re === RegExp(re), "re !== RegExp(re)");
+
+re = RegExp("abc[^d]", "g");
+ok(re.source === "abc[^d]", "re.source = '" + re.source + "', expected 'abc[^d]'");
+
+re = /abc/;
+ok(re === RegExp(re, undefined), "re !== RegExp(re, undefined)");
+
+re = /abc/;
+ok(re === RegExp(re, undefined, 1), "re !== RegExp(re, undefined, 1)");
+
 reportSuccess();




More information about the wine-cvs mailing list