[JSCRIPT]
authorChristoph von Wittich <christoph_vw@reactos.org>
Sat, 29 May 2010 14:21:43 +0000 (14:21 +0000)
committerChristoph von Wittich <christoph_vw@reactos.org>
Sat, 29 May 2010 14:21:43 +0000 (14:21 +0000)
sync to wine 1.2 RC2

svn path=/trunk/; revision=47413

reactos/dll/win32/jscript/dispex.c
reactos/dll/win32/jscript/function.c
reactos/dll/win32/jscript/global.c
reactos/dll/win32/jscript/jscript.c
reactos/dll/win32/jscript/jscript.h
reactos/dll/win32/jscript/jscript_Nl.rc
reactos/dll/win32/jscript/jscript_Si.rc [new file with mode: 0644]
reactos/dll/win32/jscript/regexp.c
reactos/dll/win32/jscript/rsrc.rc
reactos/dll/win32/jscript/string.c

index 6894eae..07880bc 100644 (file)
@@ -358,6 +358,9 @@ static HRESULT prop_put(DispatchEx *This, dispex_prop_t *prop, VARIANT *val,
 {
     HRESULT hres;
 
+    if(prop->flags & PROPF_CONST)
+        return S_OK;
+
     switch(prop->type) {
     case PROP_BUILTIN:
         if(!(prop->flags & PROPF_METHOD)) {
@@ -974,6 +977,18 @@ HRESULT jsdisp_propput_name(DispatchEx *obj, const WCHAR *name, VARIANT *val, js
     return prop_put(obj, prop, val, ei, caller);
 }
 
+HRESULT jsdisp_propput_const(DispatchEx *obj, const WCHAR *name, VARIANT *val)
+{
+    dispex_prop_t *prop;
+    HRESULT hres;
+
+    hres = ensure_prop_name(obj, name, FALSE, PROPF_ENUM|PROPF_CONST, &prop);
+    if(FAILED(hres))
+        return hres;
+
+    return VariantCopy(&prop->u.var, val);
+}
+
 HRESULT jsdisp_propput_idx(DispatchEx *obj, DWORD idx, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller)
 {
     WCHAR buf[12];
index c7494cf..df46f1d 100644 (file)
@@ -606,7 +606,16 @@ HRESULT create_builtin_function(script_ctx_t *ctx, builtin_invoke_t value_proc,
     if(FAILED(hres))
         return hres;
 
-    hres = set_prototype(ctx, &function->dispex, prototype);
+    if(builtin_info) {
+        VARIANT var;
+
+        V_VT(&var) = VT_I4;
+        V_I4(&var) = function->length;
+        hres = jsdisp_propput_const(&function->dispex, lengthW, &var);
+    }
+
+    if(SUCCEEDED(hres))
+        hres = set_prototype(ctx, &function->dispex, prototype);
     if(FAILED(hres)) {
         jsdisp_release(&function->dispex);
         return hres;
index af142ed..92a0cbe 100644 (file)
@@ -550,7 +550,7 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
     LONGLONG d = 0, hlp;
-    int exp = 0, length;
+    int exp = 0;
     VARIANT *arg;
     WCHAR *str;
     BSTR val_str = NULL;
@@ -569,7 +569,6 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
         return hres;
 
     str = val_str;
-    length = SysStringLen(val_str);
 
     while(isspaceW(*str)) str++;
 
index 9a516aa..c7c77e3 100644 (file)
@@ -71,6 +71,7 @@ void script_release(script_ctx_t *ctx)
         return;
 
     jsheap_free(&ctx->tmp_heap);
+    SysFreeString(ctx->last_match);
     heap_free(ctx);
 }
 
index c1c8e60..901f25d 100644 (file)
@@ -68,6 +68,7 @@ extern HINSTANCE jscript_hinstance;
 #define PROPF_METHOD  0x0100
 #define PROPF_ENUM    0x0200
 #define PROPF_CONSTR  0x0400
+#define PROPF_CONST   0x0800
 
 /* NOTE: Keep in sync with names in Object.toString implementation */
 typedef enum {
@@ -203,6 +204,7 @@ HRESULT disp_propget(script_ctx_t*,IDispatch*,DISPID,VARIANT*,jsexcept_t*,IServi
 HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,VARIANT*,jsexcept_t*,IServiceProvider*);
 HRESULT jsdisp_propget(DispatchEx*,DISPID,VARIANT*,jsexcept_t*,IServiceProvider*);
 HRESULT jsdisp_propput_name(DispatchEx*,const WCHAR*,VARIANT*,jsexcept_t*,IServiceProvider*);
+HRESULT jsdisp_propput_const(DispatchEx*,const WCHAR*,VARIANT*);
 HRESULT jsdisp_propput_idx(DispatchEx*,DWORD,VARIANT*,jsexcept_t*,IServiceProvider*);
 HRESULT jsdisp_propget_name(DispatchEx*,LPCWSTR,VARIANT*,jsexcept_t*,IServiceProvider*);
 HRESULT jsdisp_get_idx(DispatchEx*,DWORD,VARIANT*,jsexcept_t*,IServiceProvider*);
@@ -270,6 +272,10 @@ struct _script_ctx_t {
 
     IDispatch *host_global;
 
+    BSTR last_match;
+    DWORD last_match_index;
+    DWORD last_match_length;
+
     DispatchEx *global;
     DispatchEx *function_constr;
     DispatchEx *activex_constr;
@@ -318,8 +324,9 @@ typedef struct {
     DWORD len;
 } match_result_t;
 
-#define REM_CHECK_GLOBAL 0x0001
-#define REM_RESET_INDEX  0x0002
+#define REM_CHECK_GLOBAL   0x0001
+#define REM_RESET_INDEX    0x0002
+#define REM_NO_CTX_UPDATE  0x0004
 HRESULT regexp_match_next(script_ctx_t*,DispatchEx*,DWORD,const WCHAR*,DWORD,const WCHAR**,match_result_t**,
         DWORD*,DWORD*,match_result_t*);
 HRESULT regexp_match(script_ctx_t*,DispatchEx*,const WCHAR*,DWORD,BOOL,match_result_t**,DWORD*);
index c4f761a..fec11a0 100644 (file)
 
 LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL
 
+#pragma code_page(65001)
+
 STRINGTABLE DISCARDABLE
 {
     IDS_TO_PRIMITIVE        "Fout bij het omzetten van het object naar een primitief type"
     IDS_INVALID_CALL_ARG    "Ongeldige procedure-aanroep of argument"
+    IDS_CREATE_OBJ_ERROR    "Automatiseringsserver kan het object niet creëren"
     IDS_NO_PROPERTY         "Dit object ondersteunt deze eigenschap of methode niet"
     IDS_ARG_NOT_OPT         "Argument is niet optioneel"
     IDS_SYNTAX_ERROR        "Syntax fout"
@@ -40,6 +43,7 @@ STRINGTABLE DISCARDABLE
     IDS_NOT_BOOL            "Boolean object verwacht"
     IDS_JSCRIPT_EXPECTED    "JScript object verwacht"
     IDS_REGEXP_SYNTAX_ERROR "Syntax fout in reguliere expressie"
+    IDS_URI_INVALID_CHAR    "De te coderen URI bevat ongeldige tekens"
     IDS_INVALID_LENGTH      "Array lengte moet een eindig, positief geheel getal zijn"
     IDS_ARRAY_EXPECTED      "Array object verwacht"
 }
diff --git a/reactos/dll/win32/jscript/jscript_Si.rc b/reactos/dll/win32/jscript/jscript_Si.rc
new file mode 100644 (file)
index 0000000..0ddeab1
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010 Matej Spindler
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "resource.h"
+
+#pragma code_page(65001)
+
+LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+{
+    IDS_TO_PRIMITIVE        "Napaka med spreminjanjem v primitivni tip"
+    IDS_INVALID_CALL_ARG    "Napačen klic postopka ali argument"
+    IDS_CREATE_OBJ_ERROR    "Avtomatizacijski server ne more ustvariti objekta"
+    IDS_NO_PROPERTY         "Objekt ne podpira atributa ali metode"
+    IDS_ARG_NOT_OPT         "Argument je obvezen"
+    IDS_SYNTAX_ERROR        "Napačna sintaksa"
+    IDS_SEMICOLON           "Pričakujem ';'"
+    IDS_LBRACKET            "Pričakujem '('"
+    IDS_RBRACKET            "Pričakujem ')'"
+    IDS_UNTERMINATED_STR    "Nezaključen niz"
+    IDS_NOT_FUNC            "Pričakujem funkcijo"
+    IDS_NOT_DATE            "'[object]' ni date objekt"
+    IDS_NOT_NUM             "Pričakujem število"
+    IDS_OBJECT_EXPECTED     "Pričakujem objekt"
+    IDS_ILLEGAL_ASSIGN      "Napačna prireditev"
+    IDS_UNDEFINED           "'|' je nedifiniran"
+    IDS_NOT_BOOL            "Pričakujem Boolean objekt"
+    IDS_JSCRIPT_EXPECTED    "Pričakujem JScript objekt"
+    IDS_REGEXP_SYNTAX_ERROR "Napačna sintaksa v regularnem izrazu"
+    IDS_URI_INVALID_CHAR    "URI vsebuje neveljavne znake"
+    IDS_INVALID_LENGTH      "Dožina polja mora bit pozitivno celo število"
+    IDS_ARRAY_EXPECTED      "Pričakujem Array objekt"
+}
index 7861d22..fb54189 100644 (file)
@@ -96,6 +96,12 @@ static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
 static const WCHAR execW[] = {'e','x','e','c',0};
 static const WCHAR testW[] = {'t','e','s','t',0};
 
+static const WCHAR leftContextW[] =
+    {'l','e','f','t','C','o','n','t','e','x','t',0};
+static const WCHAR rightContextW[] =
+    {'r','i','g','h','t','C','o','n','t','e','x','t',0};
+
+static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
 static const WCHAR emptyW[] = {0};
 
 /* FIXME: Better error handling */
@@ -1977,7 +1983,7 @@ PushBackTrackState(REGlobalData *gData, REOp op,
     ptrdiff_t btincr = ((char *)result + sz) -
                        ((char *)gData->backTrackStack + btsize);
 
-    TRACE("\tBT_Push: %lu,%lu\n", (unsigned long) parenIndex, (unsigned long) parenCount);
+    TRACE("\tBT_Push: %lu,%lu\n", (ULONG_PTR)parenIndex, (ULONG_PTR)parenCount);
 
     JS_COUNT_OPERATION(gData->cx, JSOW_JUMP * (1 + parenCount));
     if (btincr > 0) {
@@ -2729,7 +2735,7 @@ ExecuteREBytecode(REGlobalData *gData, REMatchState *x)
 
               case REOP_LPAREN:
                 pc = ReadCompactIndex(pc, &parenIndex);
-                TRACE("[ %lu ]\n", (unsigned long) parenIndex);
+                TRACE("[ %lu ]\n", (ULONG_PTR)parenIndex);
                 assert(parenIndex < gData->regexp->parenCount);
                 if (parenIndex + 1 > parenSoFar)
                     parenSoFar = parenIndex + 1;
@@ -3093,8 +3099,8 @@ ExecuteREBytecode(REGlobalData *gData, REMatchState *x)
             }
 
             TRACE("\tBT_Pop: %ld,%ld\n",
-                     (unsigned long) backTrackData->parenIndex,
-                     (unsigned long) backTrackData->parenCount);
+                     (ULONG_PTR)backTrackData->parenIndex,
+                     (ULONG_PTR)backTrackData->parenCount);
             continue;
         }
         x = result;
@@ -3342,8 +3348,6 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, D
     }
 
     if(parens) {
-        DWORD i;
-
         if(regexp->jsregexp->parenCount > *parens_size) {
             match_result_t *new_parens;
 
@@ -3356,6 +3360,22 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, D
 
             *parens = new_parens;
         }
+    }
+
+    /* FIXME: We often already have a copy of input string that we could use to store last match */
+    if(!(rem_flags & REM_NO_CTX_UPDATE) &&
+       (!ctx->last_match || len != SysStringLen(ctx->last_match) || strncmpW(ctx->last_match, str, len))) {
+        BSTR last_match;
+
+        last_match = SysAllocStringLen(str, len);
+        if(!last_match)
+            return E_OUTOFMEMORY;
+        SysFreeString(ctx->last_match);
+        ctx->last_match = last_match;
+    }
+
+    if(parens) {
+        DWORD i;
 
         *parens_cnt = regexp->jsregexp->parenCount;
 
@@ -3376,6 +3396,11 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, D
     ret->len = matchlen;
     set_last_index(regexp, result->cp-str);
 
+    if(!(rem_flags & REM_NO_CTX_UPDATE)) {
+        ctx->last_match_index = ret->str-str;
+        ctx->last_match_length = matchlen;
+    }
+
     return S_OK;
 }
 
@@ -3712,12 +3737,24 @@ static HRESULT RegExp_test(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPP
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
     match_result_t match;
+    VARIANT undef_var;
     VARIANT_BOOL b;
+    DWORD argc;
     HRESULT hres;
 
     TRACE("\n");
 
-    hres = run_exec(ctx, jsthis, arg_cnt(dp) ? get_arg(dp,0) : NULL, ei, NULL, &match, NULL, NULL, &b);
+    argc = arg_cnt(dp);
+    if(!argc) {
+        V_VT(&undef_var) = VT_BSTR;
+        V_BSTR(&undef_var) = SysAllocString(undefinedW);
+        if(!V_BSTR(&undef_var))
+            return E_OUTOFMEMORY;
+    }
+
+    hres = run_exec(ctx, jsthis, argc ? get_arg(dp,0) : &undef_var, ei, NULL, &match, NULL, NULL, &b);
+    if(!argc)
+        SysFreeString(V_BSTR(&undef_var));
     if(FAILED(hres))
         return hres;
 
@@ -3959,6 +3996,58 @@ HRESULT regexp_string_match(script_ctx_t *ctx, DispatchEx *re, BSTR str,
     return hres;
 }
 
+static HRESULT RegExpConstr_leftContext(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+         DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
+{
+    TRACE("\n");
+
+    switch(flags) {
+    case DISPATCH_PROPERTYGET: {
+        BSTR ret;
+
+        ret = SysAllocStringLen(ctx->last_match, ctx->last_match_index);
+        if(!ret)
+            return E_OUTOFMEMORY;
+
+        V_VT(retv) = VT_BSTR;
+        V_BSTR(retv) = ret;
+    }
+    case DISPATCH_PROPERTYPUT:
+        return S_OK;
+    default:
+        FIXME("unsupported flags\n");
+        return E_NOTIMPL;
+    }
+
+    return S_OK;
+}
+
+static HRESULT RegExpConstr_rightContext(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+         DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
+{
+    TRACE("\n");
+
+    switch(flags) {
+    case DISPATCH_PROPERTYGET: {
+        BSTR ret;
+
+        ret = SysAllocString(ctx->last_match+ctx->last_match_index+ctx->last_match_length);
+        if(!ret)
+            return E_OUTOFMEMORY;
+
+        V_VT(retv) = VT_BSTR;
+        V_BSTR(retv) = ret;
+    }
+    case DISPATCH_PROPERTYPUT:
+        return S_OK;
+    default:
+        FIXME("unsupported flags\n");
+        return E_NOTIMPL;
+    }
+
+    return S_OK;
+}
+
 static HRESULT RegExpConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
 {
@@ -4019,6 +4108,20 @@ static HRESULT RegExpConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
     return S_OK;
 }
 
+static const builtin_prop_t RegExpConstr_props[] = {
+    {leftContextW,    RegExpConstr_leftContext,    0},
+    {rightContextW,   RegExpConstr_rightContext,   0}
+};
+
+static const builtin_info_t RegExpConstr_info = {
+    JSCLASS_FUNCTION,
+    {NULL, Function_value, 0},
+    sizeof(RegExpConstr_props)/sizeof(*RegExpConstr_props),
+    RegExpConstr_props,
+    NULL,
+    NULL
+};
+
 HRESULT create_regexp_constr(script_ctx_t *ctx, DispatchEx *object_prototype, DispatchEx **ret)
 {
     RegExpInstance *regexp;
@@ -4030,7 +4133,7 @@ HRESULT create_regexp_constr(script_ctx_t *ctx, DispatchEx *object_prototype, Di
     if(FAILED(hres))
         return hres;
 
-    hres = create_builtin_function(ctx, RegExpConstr_value, RegExpW, NULL,
+    hres = create_builtin_function(ctx, RegExpConstr_value, RegExpW, &RegExpConstr_info,
             PROPF_CONSTR|2, &regexp->dispex, ret);
 
     jsdisp_release(&regexp->dispex);
index d23ea33..db7e0ff 100644 (file)
@@ -30,3 +30,4 @@ REGINST REGINST jscript.inf
 #include "jscript_Nl.rc"
 #include "jscript_Pt.rc"
 #include "jscript_Ru.rc"
+#include "jscript_Si.rc"
index 510dcc2..05b9eba 100644 (file)
@@ -779,9 +779,9 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI
     DWORD parens_cnt = 0, parens_size=0, rep_len=0, length;
     BSTR rep_str = NULL, match_str = NULL, ret_str, val_str;
     DispatchEx *rep_func = NULL, *regexp = NULL;
-    match_result_t *parens = NULL, match, **parens_ptr = &parens;
+    match_result_t *parens = NULL, match = {NULL,0}, **parens_ptr = &parens;
     strbuf_t ret = {NULL,0,0};
-    DWORD re_flags = 0;
+    DWORD re_flags = REM_NO_CTX_UPDATE;
     VARIANT *arg_var;
     HRESULT hres = S_OK;
 
@@ -860,7 +860,7 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI
             if(regexp) {
                 hres = regexp_match_next(ctx, regexp, re_flags, str, length, &cp, parens_ptr,
                         &parens_size, &parens_cnt, &match);
-                re_flags = REM_CHECK_GLOBAL;
+                re_flags |= REM_CHECK_GLOBAL;
 
                 if(hres == S_FALSE) {
                     hres = S_OK;
@@ -969,13 +969,28 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI
 
     if(rep_func)
         jsdisp_release(rep_func);
-    if(regexp)
-        jsdisp_release(regexp);
-    SysFreeString(val_str);
     SysFreeString(rep_str);
     SysFreeString(match_str);
     heap_free(parens);
 
+    if(SUCCEEDED(hres) && match.str && regexp) {
+        if(!val_str)
+            val_str = SysAllocStringLen(str, length);
+        if(val_str) {
+            SysFreeString(ctx->last_match);
+            ctx->last_match = val_str;
+            val_str = NULL;
+            ctx->last_match_index = match.str-str;
+            ctx->last_match_length = match.len;
+        }else {
+            hres = E_OUTOFMEMORY;
+        }
+    }
+
+    if(regexp)
+        jsdisp_release(regexp);
+    SysFreeString(val_str);
+
     if(SUCCEEDED(hres) && retv) {
         ret_str = SysAllocStringLen(ret.buf, ret.len);
         if(!ret_str)