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