Jacek Caban : jscript: Added lastIndex setter implementation.

Alexandre Julliard julliard at winehq.org
Tue Dec 1 09:19:41 CST 2009


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Nov 30 21:12:13 2009 +0100

jscript: Added lastIndex setter implementation.

---

 dlls/jscript/regexp.c |   64 +++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 59 insertions(+), 5 deletions(-)

diff --git a/dlls/jscript/regexp.c b/dlls/jscript/regexp.c
index 6c4af84..0c8a419 100644
--- a/dlls/jscript/regexp.c
+++ b/dlls/jscript/regexp.c
@@ -32,6 +32,7 @@
  */
 
 #include <assert.h>
+#include <math.h>
 
 #include "jscript.h"
 
@@ -82,7 +83,8 @@ typedef struct {
 
     JSRegExp *jsregexp;
     BSTR str;
-    DWORD last_index;
+    INT last_index;
+    VARIANT last_index_var;
 } RegExpInstance;
 
 static const WCHAR sourceW[] = {'s','o','u','r','c','e',0};
@@ -3430,6 +3432,13 @@ HRESULT regexp_match(script_ctx_t *ctx, DispatchEx *dispex, const WCHAR *str, DW
     return S_OK;
 }
 
+static void set_last_index(RegExpInstance *This, DWORD last_index)
+{
+    This->last_index = last_index;
+    VariantClear(&This->last_index_var);
+    num_set_val(&This->last_index_var, last_index);
+}
+
 static HRESULT RegExp_source(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
@@ -3474,6 +3483,27 @@ static HRESULT RegExp_multiline(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
     return E_NOTIMPL;
 }
 
+static INT index_from_var(script_ctx_t *ctx, VARIANT *v)
+{
+    jsexcept_t ei;
+    VARIANT num;
+    HRESULT hres;
+
+    memset(&ei, 0, sizeof(ei));
+    hres = to_number(ctx, v, &ei, &num);
+    if(FAILED(hres)) { /* FIXME: Move ignoring exceptions to to_promitive */
+        VariantClear(&ei.var);
+        return 0;
+    }
+
+    if(V_VT(&num) == VT_R8) {
+        DOUBLE d = floor(V_R8(&num));
+        return (DOUBLE)(INT)d == d ? d : 0;
+    }
+
+    return V_I4(&num);
+}
+
 static HRESULT RegExp_lastIndex(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
@@ -3482,8 +3512,21 @@ static HRESULT RegExp_lastIndex(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
     switch(flags) {
     case DISPATCH_PROPERTYGET: {
         RegExpInstance *regexp = regexp_from_vdisp(jsthis);
-        V_VT(retv) = VT_I4;
-        V_I4(retv) = regexp->last_index;
+
+        V_VT(retv) = VT_EMPTY;
+        return VariantCopy(retv, &regexp->last_index_var);
+    }
+    case DISPATCH_PROPERTYPUT: {
+        RegExpInstance *regexp = regexp_from_vdisp(jsthis);
+        VARIANT *arg;
+        HRESULT hres;
+
+        arg = get_arg(dp,0);
+        hres = VariantCopy(&regexp->last_index_var, arg);
+        if(FAILED(hres))
+            return hres;
+
+        regexp->last_index = index_from_var(ctx, arg);
         break;
     }
     default:
@@ -3589,6 +3632,13 @@ static HRESULT run_exec(script_ctx_t *ctx, vdisp_t *jsthis, VARIANT *arg, jsexce
             return E_OUTOFMEMORY;
     }
 
+    if(regexp->last_index < 0) {
+        SysFreeString(string);
+        set_last_index(regexp, 0);
+        *ret = VARIANT_FALSE;
+        return S_OK;
+    }
+
     length = SysStringLen(string);
     if(regexp->jsregexp->flags & JSREG_GLOB)
         last_index = regexp->last_index;
@@ -3602,10 +3652,10 @@ static HRESULT run_exec(script_ctx_t *ctx, vdisp_t *jsthis, VARIANT *arg, jsexce
     }
 
     if(hres == S_OK) {
-        regexp->last_index = cp-string;
+        set_last_index(regexp, cp-string);
         *ret = VARIANT_TRUE;
     }else {
-        regexp->last_index = 0;
+        set_last_index(regexp, 0);
         *ret = VARIANT_FALSE;
     }
 
@@ -3690,6 +3740,7 @@ static void RegExp_destructor(DispatchEx *dispex)
 
     if(This->jsregexp)
         js_DestroyRegExp(This->jsregexp);
+    VariantClear(&This->last_index_var);
     SysFreeString(This->str);
     heap_free(This);
 }
@@ -3764,6 +3815,9 @@ HRESULT create_regexp(script_ctx_t *ctx, const WCHAR *exp, int len, DWORD flags,
         return E_FAIL;
     }
 
+    V_VT(&regexp->last_index_var) = VT_I4;
+    V_I4(&regexp->last_index_var) = 0;
+
     *ret = &regexp->dispex;
     return S_OK;
 }




More information about the wine-cvs mailing list