[JSCRIPT]

sync to wine 1.2 RC2

svn path=/trunk/; revision=47413
This commit is contained in:
Christoph von Wittich 2010-05-29 14:21:43 +00:00
parent e2a40983d0
commit b2caf487ee
10 changed files with 222 additions and 19 deletions

View 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];

View 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;

View 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++;

View 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);
}

View 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*);

View file

@ -20,10 +20,13 @@
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"
}

View file

@ -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"
}

View 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);

View 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"

View 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)