mirror of
https://github.com/reactos/reactos.git
synced 2025-06-19 08:25:27 +00:00
[JSCRIPT]
* Sync with Wine 1.7.1. CORE-7469 svn path=/trunk/; revision=60246
This commit is contained in:
parent
528ebe204e
commit
6cc49a4a0b
23 changed files with 1872 additions and 1314 deletions
|
@ -1,13 +1,9 @@
|
||||||
|
|
||||||
remove_definitions(-D_WIN32_WINNT=0x502)
|
|
||||||
add_definitions(-D_WIN32_WINNT=0x600)
|
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-D__WINESRC__
|
-D__WINESRC__
|
||||||
-D_USE_MATH_DEFINES)
|
-D_USE_MATH_DEFINES)
|
||||||
|
|
||||||
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine)
|
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine)
|
||||||
|
|
||||||
spec2def(jscript.dll jscript.spec)
|
spec2def(jscript.dll jscript.spec)
|
||||||
|
|
||||||
list(APPEND SOURCE
|
list(APPEND SOURCE
|
||||||
|
@ -37,11 +33,6 @@ list(APPEND SOURCE
|
||||||
vbarray.c
|
vbarray.c
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/jscript.def)
|
${CMAKE_CURRENT_BINARY_DIR}/jscript.def)
|
||||||
|
|
||||||
add_library(jscript SHARED ${SOURCE} rsrc.rc)
|
|
||||||
add_idl_headers(jscript_idlheader jscript_classes.idl)
|
|
||||||
|
|
||||||
add_typelib(jsglobal.idl)
|
|
||||||
|
|
||||||
list(APPEND jscript_rc_deps
|
list(APPEND jscript_rc_deps
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/jscript.rgs
|
${CMAKE_CURRENT_SOURCE_DIR}/jscript.rgs
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/jscript_classes.rgs
|
${CMAKE_CURRENT_SOURCE_DIR}/jscript_classes.rgs
|
||||||
|
@ -49,16 +40,10 @@ list(APPEND jscript_rc_deps
|
||||||
|
|
||||||
set_source_files_properties(rsrc.rc PROPERTIES OBJECT_DEPENDS "${jscript_rc_deps}")
|
set_source_files_properties(rsrc.rc PROPERTIES OBJECT_DEPENDS "${jscript_rc_deps}")
|
||||||
|
|
||||||
# jsglobal.tlb needs stdole2.tlb
|
add_library(jscript SHARED ${SOURCE} rsrc.rc)
|
||||||
add_dependencies(jscript jscript_idlheader stdole2)
|
add_idl_headers(jscript_idlheader jscript_classes.idl)
|
||||||
|
add_typelib(jsglobal.idl)
|
||||||
|
add_dependencies(jscript jscript_idlheader stdole2) # jsglobal.tlb needs stdole2.tlb
|
||||||
if(NOT MSVC)
|
|
||||||
# FIXME: http://www.cmake.org/Bug/view.php?id=12998
|
|
||||||
#allow_warnings(jscript)
|
|
||||||
set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "-Wno-error")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set_module_type(jscript win32dll)
|
set_module_type(jscript win32dll)
|
||||||
target_link_libraries(jscript wine)
|
target_link_libraries(jscript wine)
|
||||||
add_importlibs(jscript user32 ole32 oleaut32 advapi32 msvcrt kernel32 ntdll)
|
add_importlibs(jscript user32 ole32 oleaut32 advapi32 msvcrt kernel32 ntdll)
|
||||||
|
|
|
@ -143,7 +143,8 @@ static IUnknown *create_activex_object(script_ctx_t *ctx, const WCHAR *progid)
|
||||||
static HRESULT ActiveXObject_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
static HRESULT ActiveXObject_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||||
jsval_t *r)
|
jsval_t *r)
|
||||||
{
|
{
|
||||||
jsstr_t * progid;
|
jsstr_t * progid_str;
|
||||||
|
const WCHAR *progid;
|
||||||
IDispatch *disp;
|
IDispatch *disp;
|
||||||
IUnknown *obj;
|
IUnknown *obj;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
@ -166,12 +167,12 @@ static HRESULT ActiveXObject_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = to_string(ctx, argv[0], &progid);
|
hres = to_flat_string(ctx, argv[0], &progid_str, &progid);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
obj = create_activex_object(ctx, progid->str);
|
obj = create_activex_object(ctx, progid);
|
||||||
jsstr_release(progid);
|
jsstr_release(progid_str);
|
||||||
if(!obj)
|
if(!obj)
|
||||||
return throw_generic_error(ctx, JS_E_CANNOT_CREATE_OBJ, NULL);
|
return throw_generic_error(ctx, JS_E_CANNOT_CREATE_OBJ, NULL);
|
||||||
|
|
||||||
|
|
|
@ -234,7 +234,7 @@ static HRESULT Array_concat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
|
||||||
|
|
||||||
static HRESULT array_join(script_ctx_t *ctx, jsdisp_t *array, DWORD length, const WCHAR *sep, jsval_t *r)
|
static HRESULT array_join(script_ctx_t *ctx, jsdisp_t *array, DWORD length, const WCHAR *sep, jsval_t *r)
|
||||||
{
|
{
|
||||||
jsstr_t **str_tab, *ret = NULL;
|
jsstr_t **str_tab, *ret;
|
||||||
jsval_t val;
|
jsval_t val;
|
||||||
DWORD i;
|
DWORD i;
|
||||||
HRESULT hres = E_FAIL;
|
HRESULT hres = E_FAIL;
|
||||||
|
@ -267,7 +267,6 @@ static HRESULT array_join(script_ctx_t *ctx, jsdisp_t *array, DWORD length, cons
|
||||||
|
|
||||||
if(SUCCEEDED(hres)) {
|
if(SUCCEEDED(hres)) {
|
||||||
DWORD seplen = 0, len = 0;
|
DWORD seplen = 0, len = 0;
|
||||||
WCHAR *ptr;
|
|
||||||
|
|
||||||
seplen = strlenW(sep);
|
seplen = strlenW(sep);
|
||||||
|
|
||||||
|
@ -283,25 +282,26 @@ static HRESULT array_join(script_ctx_t *ctx, jsdisp_t *array, DWORD length, cons
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SUCCEEDED(hres))
|
if(SUCCEEDED(hres)) {
|
||||||
ret = jsstr_alloc_buf(len);
|
WCHAR *ptr = NULL;
|
||||||
if(ret) {
|
|
||||||
ptr = ret->str;
|
|
||||||
|
|
||||||
if(str_tab[0])
|
ptr = jsstr_alloc_buf(len, &ret);
|
||||||
ptr += jsstr_flush(str_tab[0], ptr);
|
if(ptr) {
|
||||||
|
if(str_tab[0])
|
||||||
|
ptr += jsstr_flush(str_tab[0], ptr);
|
||||||
|
|
||||||
for(i=1; i < length; i++) {
|
for(i=1; i < length; i++) {
|
||||||
if(seplen) {
|
if(seplen) {
|
||||||
memcpy(ptr, sep, seplen*sizeof(WCHAR));
|
memcpy(ptr, sep, seplen*sizeof(WCHAR));
|
||||||
ptr += seplen;
|
ptr += seplen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(str_tab[i])
|
||||||
|
ptr += jsstr_flush(str_tab[i], ptr);
|
||||||
}
|
}
|
||||||
|
}else {
|
||||||
if(str_tab[i])
|
hres = E_OUTOFMEMORY;
|
||||||
ptr += jsstr_flush(str_tab[i], ptr);
|
|
||||||
}
|
}
|
||||||
}else {
|
|
||||||
hres = E_OUTOFMEMORY;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,15 +337,16 @@ static HRESULT Array_join(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigne
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
if(argc) {
|
if(argc) {
|
||||||
jsstr_t *sep;
|
const WCHAR *sep;
|
||||||
|
jsstr_t *sep_str;
|
||||||
|
|
||||||
hres = to_string(ctx, argv[0], &sep);
|
hres = to_flat_string(ctx, argv[0], &sep_str, &sep);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = array_join(ctx, jsthis, length, sep->str, r);
|
hres = array_join(ctx, jsthis, length, sep, r);
|
||||||
|
|
||||||
jsstr_release(sep);
|
jsstr_release(sep_str);
|
||||||
}else {
|
}else {
|
||||||
hres = array_join(ctx, jsthis, length, default_separatorW, r);
|
hres = array_join(ctx, jsthis, length, default_separatorW, r);
|
||||||
}
|
}
|
||||||
|
|
|
@ -771,6 +771,7 @@ static HRESULT compile_literal(compiler_ctx_t *ctx, literal_t *literal)
|
||||||
}
|
}
|
||||||
DEFAULT_UNREACHABLE;
|
DEFAULT_UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT literal_as_bstr(compiler_ctx_t *ctx, literal_t *literal, BSTR *str)
|
static HRESULT literal_as_bstr(compiler_ctx_t *ctx, literal_t *literal, BSTR *str)
|
||||||
|
|
|
@ -492,7 +492,7 @@ static inline HRESULT date_to_string(DOUBLE time, BOOL show_offset, int offset,
|
||||||
|
|
||||||
BOOL formatAD = TRUE;
|
BOOL formatAD = TRUE;
|
||||||
WCHAR week[64], month[64];
|
WCHAR week[64], month[64];
|
||||||
jsstr_t *date_str;
|
jsstr_t *date_jsstr;
|
||||||
int len, size, year, day;
|
int len, size, year, day;
|
||||||
DWORD lcid_en;
|
DWORD lcid_en;
|
||||||
WCHAR sign = '-';
|
WCHAR sign = '-';
|
||||||
|
@ -504,6 +504,8 @@ static inline HRESULT date_to_string(DOUBLE time, BOOL show_offset, int offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
if(r) {
|
if(r) {
|
||||||
|
WCHAR *date_str;
|
||||||
|
|
||||||
len = 21;
|
len = 21;
|
||||||
|
|
||||||
lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
|
lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
|
||||||
|
@ -544,25 +546,25 @@ static inline HRESULT date_to_string(DOUBLE time, BOOL show_offset, int offset,
|
||||||
offset = -offset;
|
offset = -offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
date_str = jsstr_alloc_buf(len);
|
date_str = jsstr_alloc_buf(len, &date_jsstr);
|
||||||
if(!date_str)
|
if(!date_str)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
if(!show_offset)
|
if(!show_offset)
|
||||||
sprintfW(date_str->str, formatNoOffsetW, week, month, day,
|
sprintfW(date_str, formatNoOffsetW, week, month, day,
|
||||||
(int)hour_from_time(time), (int)min_from_time(time),
|
(int)hour_from_time(time), (int)min_from_time(time),
|
||||||
(int)sec_from_time(time), year, formatAD?ADW:BCW);
|
(int)sec_from_time(time), year, formatAD?ADW:BCW);
|
||||||
else if(offset)
|
else if(offset)
|
||||||
sprintfW(date_str->str, formatW, week, month, day,
|
sprintfW(date_str, formatW, week, month, day,
|
||||||
(int)hour_from_time(time), (int)min_from_time(time),
|
(int)hour_from_time(time), (int)min_from_time(time),
|
||||||
(int)sec_from_time(time), sign, offset/60, offset%60,
|
(int)sec_from_time(time), sign, offset/60, offset%60,
|
||||||
year, formatAD?ADW:BCW);
|
year, formatAD?ADW:BCW);
|
||||||
else
|
else
|
||||||
sprintfW(date_str->str, formatUTCW, week, month, day,
|
sprintfW(date_str, formatUTCW, week, month, day,
|
||||||
(int)hour_from_time(time), (int)min_from_time(time),
|
(int)hour_from_time(time), (int)min_from_time(time),
|
||||||
(int)sec_from_time(time), year, formatAD?ADW:BCW);
|
(int)sec_from_time(time), year, formatAD?ADW:BCW);
|
||||||
|
|
||||||
*r = jsval_string(date_str);
|
*r = jsval_string(date_jsstr);
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -618,14 +620,18 @@ static HRESULT Date_toLocaleString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
|
||||||
return dateobj_to_string(date, r);
|
return dateobj_to_string(date, r);
|
||||||
|
|
||||||
if(r) {
|
if(r) {
|
||||||
|
WCHAR *ptr;
|
||||||
|
|
||||||
date_len = GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, NULL, 0);
|
date_len = GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, NULL, 0);
|
||||||
time_len = GetTimeFormatW(ctx->lcid, 0, &st, NULL, NULL, 0);
|
time_len = GetTimeFormatW(ctx->lcid, 0, &st, NULL, NULL, 0);
|
||||||
date_str = jsstr_alloc_buf(date_len+time_len-1);
|
|
||||||
|
ptr = jsstr_alloc_buf(date_len+time_len-1, &date_str);
|
||||||
if(!date_str)
|
if(!date_str)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, date_str->str, date_len);
|
|
||||||
GetTimeFormatW(ctx->lcid, 0, &st, NULL, date_str->str+date_len, time_len);
|
GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, ptr, date_len);
|
||||||
date_str->str[date_len-1] = ' ';
|
GetTimeFormatW(ctx->lcid, 0, &st, NULL, ptr+date_len, time_len);
|
||||||
|
ptr[date_len-1] = ' ';
|
||||||
|
|
||||||
*r = jsval_string(date_str);
|
*r = jsval_string(date_str);
|
||||||
}
|
}
|
||||||
|
@ -681,6 +687,8 @@ static inline HRESULT create_utc_string(script_ctx_t *ctx, vdisp_t *jsthis, jsva
|
||||||
}
|
}
|
||||||
|
|
||||||
if(r) {
|
if(r) {
|
||||||
|
WCHAR *ptr;
|
||||||
|
|
||||||
len = 17;
|
len = 17;
|
||||||
|
|
||||||
lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
|
lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
|
||||||
|
@ -713,11 +721,11 @@ static inline HRESULT create_utc_string(script_ctx_t *ctx, vdisp_t *jsthis, jsva
|
||||||
} while(day);
|
} while(day);
|
||||||
day = date_from_time(date->time);
|
day = date_from_time(date->time);
|
||||||
|
|
||||||
date_str = jsstr_alloc_buf(len);
|
ptr = jsstr_alloc_buf(len, &date_str);
|
||||||
if(!date_str)
|
if(!date_str)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
sprintfW(date_str->str, formatAD?formatADW:formatBCW, week, day, month, year,
|
sprintfW(ptr, formatAD?formatADW:formatBCW, week, day, month, year,
|
||||||
(int)hour_from_time(date->time), (int)min_from_time(date->time),
|
(int)hour_from_time(date->time), (int)min_from_time(date->time),
|
||||||
(int)sec_from_time(date->time));
|
(int)sec_from_time(date->time));
|
||||||
|
|
||||||
|
@ -773,6 +781,8 @@ static HRESULT dateobj_to_date_string(DateInstance *date, jsval_t *r)
|
||||||
time = local_time(date->time, date);
|
time = local_time(date->time, date);
|
||||||
|
|
||||||
if(r) {
|
if(r) {
|
||||||
|
WCHAR *ptr;
|
||||||
|
|
||||||
len = 5;
|
len = 5;
|
||||||
|
|
||||||
lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
|
lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
|
||||||
|
@ -807,10 +817,10 @@ static HRESULT dateobj_to_date_string(DateInstance *date, jsval_t *r)
|
||||||
} while(day);
|
} while(day);
|
||||||
day = date_from_time(time);
|
day = date_from_time(time);
|
||||||
|
|
||||||
date_str = jsstr_alloc_buf(len);
|
ptr = jsstr_alloc_buf(len, &date_str);
|
||||||
if(!date_str)
|
if(!ptr)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
sprintfW(date_str->str, formatAD?formatADW:formatBCW, week, month, day, year);
|
sprintfW(ptr, formatAD?formatADW:formatBCW, week, month, day, year);
|
||||||
|
|
||||||
*r = jsval_string(date_str);
|
*r = jsval_string(date_str);
|
||||||
}
|
}
|
||||||
|
@ -856,7 +866,9 @@ static HRESULT Date_toTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
||||||
time = local_time(date->time, date);
|
time = local_time(date->time, date);
|
||||||
|
|
||||||
if(r) {
|
if(r) {
|
||||||
date_str = jsstr_alloc_buf(17);
|
WCHAR *ptr;
|
||||||
|
|
||||||
|
ptr = jsstr_alloc_buf(17, &date_str);
|
||||||
if(!date_str)
|
if(!date_str)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
@ -870,11 +882,11 @@ static HRESULT Date_toTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
||||||
else sign = '-';
|
else sign = '-';
|
||||||
|
|
||||||
if(offset)
|
if(offset)
|
||||||
sprintfW(date_str->str, formatW, (int)hour_from_time(time),
|
sprintfW(ptr, formatW, (int)hour_from_time(time),
|
||||||
(int)min_from_time(time), (int)sec_from_time(time),
|
(int)min_from_time(time), (int)sec_from_time(time),
|
||||||
sign, offset/60, offset%60);
|
sign, offset/60, offset%60);
|
||||||
else
|
else
|
||||||
sprintfW(date_str->str, formatUTCW, (int)hour_from_time(time),
|
sprintfW(ptr, formatUTCW, (int)hour_from_time(time),
|
||||||
(int)min_from_time(time), (int)sec_from_time(time));
|
(int)min_from_time(time), (int)sec_from_time(time));
|
||||||
|
|
||||||
*r = jsval_string(date_str);
|
*r = jsval_string(date_str);
|
||||||
|
@ -908,11 +920,13 @@ static HRESULT Date_toLocaleDateString(script_ctx_t *ctx, vdisp_t *jsthis, WORD
|
||||||
return dateobj_to_date_string(date, r);
|
return dateobj_to_date_string(date, r);
|
||||||
|
|
||||||
if(r) {
|
if(r) {
|
||||||
|
WCHAR *ptr;
|
||||||
|
|
||||||
len = GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, NULL, 0);
|
len = GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, NULL, 0);
|
||||||
date_str = jsstr_alloc_buf(len);
|
ptr = jsstr_alloc_buf(len, &date_str);
|
||||||
if(!date_str)
|
if(!ptr)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, date_str->str, len);
|
GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, ptr, len);
|
||||||
|
|
||||||
*r = jsval_string(date_str);
|
*r = jsval_string(date_str);
|
||||||
}
|
}
|
||||||
|
@ -945,11 +959,13 @@ static HRESULT Date_toLocaleTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD
|
||||||
return Date_toTimeString(ctx, jsthis, flags, argc, argv, r);
|
return Date_toTimeString(ctx, jsthis, flags, argc, argv, r);
|
||||||
|
|
||||||
if(r) {
|
if(r) {
|
||||||
|
WCHAR *ptr;
|
||||||
|
|
||||||
len = GetTimeFormatW(ctx->lcid, 0, &st, NULL, NULL, 0);
|
len = GetTimeFormatW(ctx->lcid, 0, &st, NULL, NULL, 0);
|
||||||
date_str = jsstr_alloc_buf(len);
|
ptr = jsstr_alloc_buf(len, &date_str);
|
||||||
if(!date_str)
|
if(!ptr)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
GetTimeFormatW(ctx->lcid, 0, &st, NULL, date_str->str, len);
|
GetTimeFormatW(ctx->lcid, 0, &st, NULL, ptr, len);
|
||||||
|
|
||||||
*r = jsval_string(date_str);
|
*r = jsval_string(date_str);
|
||||||
}
|
}
|
||||||
|
@ -2038,7 +2054,9 @@ static inline HRESULT date_parse(jsstr_t *input_str, double *ret) {
|
||||||
DWORD lcid_en;
|
DWORD lcid_en;
|
||||||
|
|
||||||
input_len = jsstr_length(input_str);
|
input_len = jsstr_length(input_str);
|
||||||
input = input_str->str;
|
input = jsstr_flatten(input_str);
|
||||||
|
if(!input)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
for(i=0; i<input_len; i++) {
|
for(i=0; i<input_len; i++) {
|
||||||
if(input[i] == '(') nest_level++;
|
if(input[i] == '(') nest_level++;
|
||||||
|
|
|
@ -1524,8 +1524,15 @@ HRESULT disp_delete_name(script_ctx_t *ctx, IDispatch *disp, jsstr_t *name, BOOL
|
||||||
jsdisp = iface_to_jsdisp((IUnknown*)disp);
|
jsdisp = iface_to_jsdisp((IUnknown*)disp);
|
||||||
if(jsdisp) {
|
if(jsdisp) {
|
||||||
dispex_prop_t *prop;
|
dispex_prop_t *prop;
|
||||||
|
const WCHAR *ptr;
|
||||||
|
|
||||||
hres = find_prop_name(jsdisp, string_hash(name->str), name->str, &prop);
|
ptr = jsstr_flatten(name);
|
||||||
|
if(!ptr) {
|
||||||
|
jsdisp_release(jsdisp);
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
hres = find_prop_name(jsdisp, string_hash(ptr), ptr, &prop);
|
||||||
if(prop) {
|
if(prop) {
|
||||||
hres = delete_prop(prop, ret);
|
hres = delete_prop(prop, ret);
|
||||||
}else {
|
}else {
|
||||||
|
|
|
@ -346,7 +346,7 @@ void exec_release(exec_ctx_t *ctx)
|
||||||
heap_free(ctx);
|
heap_free(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT disp_get_id(script_ctx_t *ctx, IDispatch *disp, WCHAR *name, BSTR name_bstr, DWORD flags, DISPID *id)
|
static HRESULT disp_get_id(script_ctx_t *ctx, IDispatch *disp, const WCHAR *name, BSTR name_bstr, DWORD flags, DISPID *id)
|
||||||
{
|
{
|
||||||
IDispatchEx *dispex;
|
IDispatchEx *dispex;
|
||||||
jsdisp_t *jsdisp;
|
jsdisp_t *jsdisp;
|
||||||
|
@ -375,7 +375,7 @@ static HRESULT disp_get_id(script_ctx_t *ctx, IDispatch *disp, WCHAR *name, BSTR
|
||||||
IDispatchEx_Release(dispex);
|
IDispatchEx_Release(dispex);
|
||||||
}else {
|
}else {
|
||||||
TRACE("using IDispatch\n");
|
TRACE("using IDispatch\n");
|
||||||
hres = IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id);
|
hres = IDispatch_GetIDsOfNames(disp, &IID_NULL, &bstr, 1, 0, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(name_bstr != bstr)
|
if(name_bstr != bstr)
|
||||||
|
@ -729,10 +729,12 @@ static HRESULT interp_throw_type(exec_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
const HRESULT hres = get_op_uint(ctx, 0);
|
const HRESULT hres = get_op_uint(ctx, 0);
|
||||||
jsstr_t *str = get_op_str(ctx, 1);
|
jsstr_t *str = get_op_str(ctx, 1);
|
||||||
|
const WCHAR *ptr;
|
||||||
|
|
||||||
TRACE("%08x %s\n", hres, debugstr_jsstr(str));
|
TRACE("%08x %s\n", hres, debugstr_jsstr(str));
|
||||||
|
|
||||||
return throw_type_error(ctx->script, hres, str->str);
|
ptr = jsstr_flatten(str);
|
||||||
|
return ptr ? throw_type_error(ctx->script, hres, ptr) : E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ECMA-262 3rd Edition 12.14 */
|
/* ECMA-262 3rd Edition 12.14 */
|
||||||
|
@ -828,9 +830,10 @@ static HRESULT interp_func(exec_ctx_t *ctx)
|
||||||
/* ECMA-262 3rd Edition 11.2.1 */
|
/* ECMA-262 3rd Edition 11.2.1 */
|
||||||
static HRESULT interp_array(exec_ctx_t *ctx)
|
static HRESULT interp_array(exec_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
|
jsstr_t *name_str;
|
||||||
|
const WCHAR *name;
|
||||||
jsval_t v, namev;
|
jsval_t v, namev;
|
||||||
IDispatch *obj;
|
IDispatch *obj;
|
||||||
jsstr_t *name;
|
|
||||||
DISPID id;
|
DISPID id;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
|
@ -844,15 +847,15 @@ static HRESULT interp_array(exec_ctx_t *ctx)
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = to_string(ctx->script, namev, &name);
|
hres = to_flat_string(ctx->script, namev, &name_str, &name);
|
||||||
jsval_release(namev);
|
jsval_release(namev);
|
||||||
if(FAILED(hres)) {
|
if(FAILED(hres)) {
|
||||||
IDispatch_Release(obj);
|
IDispatch_Release(obj);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = disp_get_id(ctx->script, obj, name->str, NULL, 0, &id);
|
hres = disp_get_id(ctx->script, obj, name, NULL, 0, &id);
|
||||||
jsstr_release(name);
|
jsstr_release(name_str);
|
||||||
if(SUCCEEDED(hres)) {
|
if(SUCCEEDED(hres)) {
|
||||||
hres = disp_propget(ctx->script, obj, id, &v);
|
hres = disp_propget(ctx->script, obj, id, &v);
|
||||||
}else if(hres == DISP_E_UNKNOWNNAME) {
|
}else if(hres == DISP_E_UNKNOWNNAME) {
|
||||||
|
@ -900,8 +903,9 @@ static HRESULT interp_memberid(exec_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
const unsigned arg = get_op_uint(ctx, 0);
|
const unsigned arg = get_op_uint(ctx, 0);
|
||||||
jsval_t objv, namev;
|
jsval_t objv, namev;
|
||||||
|
const WCHAR *name;
|
||||||
|
jsstr_t *name_str;
|
||||||
IDispatch *obj;
|
IDispatch *obj;
|
||||||
jsstr_t *name;
|
|
||||||
DISPID id;
|
DISPID id;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
|
@ -913,7 +917,7 @@ static HRESULT interp_memberid(exec_ctx_t *ctx)
|
||||||
hres = to_object(ctx->script, objv, &obj);
|
hres = to_object(ctx->script, objv, &obj);
|
||||||
jsval_release(objv);
|
jsval_release(objv);
|
||||||
if(SUCCEEDED(hres)) {
|
if(SUCCEEDED(hres)) {
|
||||||
hres = to_string(ctx->script, namev, &name);
|
hres = to_flat_string(ctx->script, namev, &name_str, &name);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
IDispatch_Release(obj);
|
IDispatch_Release(obj);
|
||||||
}
|
}
|
||||||
|
@ -921,8 +925,8 @@ static HRESULT interp_memberid(exec_ctx_t *ctx)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = disp_get_id(ctx->script, obj, name->str, NULL, arg, &id);
|
hres = disp_get_id(ctx->script, obj, name, NULL, arg, &id);
|
||||||
jsstr_release(name);
|
jsstr_release(name_str);
|
||||||
if(FAILED(hres)) {
|
if(FAILED(hres)) {
|
||||||
IDispatch_Release(obj);
|
IDispatch_Release(obj);
|
||||||
if(hres == DISP_E_UNKNOWNNAME && !(arg & fdexNameEnsure)) {
|
if(hres == DISP_E_UNKNOWNNAME && !(arg & fdexNameEnsure)) {
|
||||||
|
@ -1392,10 +1396,11 @@ static HRESULT interp_instanceof(exec_ctx_t *ctx)
|
||||||
/* ECMA-262 3rd Edition 11.8.7 */
|
/* ECMA-262 3rd Edition 11.8.7 */
|
||||||
static HRESULT interp_in(exec_ctx_t *ctx)
|
static HRESULT interp_in(exec_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
|
const WCHAR *str;
|
||||||
|
jsstr_t *jsstr;
|
||||||
jsval_t obj, v;
|
jsval_t obj, v;
|
||||||
DISPID id = 0;
|
DISPID id = 0;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
jsstr_t *str;
|
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
@ -1407,16 +1412,16 @@ static HRESULT interp_in(exec_ctx_t *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
v = stack_pop(ctx);
|
v = stack_pop(ctx);
|
||||||
hres = to_string(ctx->script, v, &str);
|
hres = to_flat_string(ctx->script, v, &jsstr, &str);
|
||||||
jsval_release(v);
|
jsval_release(v);
|
||||||
if(FAILED(hres)) {
|
if(FAILED(hres)) {
|
||||||
IDispatch_Release(get_object(obj));
|
IDispatch_Release(get_object(obj));
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = disp_get_id(ctx->script, get_object(obj), str->str, NULL, 0, &id);
|
hres = disp_get_id(ctx->script, get_object(obj), str, NULL, 0, &id);
|
||||||
IDispatch_Release(get_object(obj));
|
IDispatch_Release(get_object(obj));
|
||||||
jsstr_release(str);
|
jsstr_release(jsstr);
|
||||||
if(SUCCEEDED(hres))
|
if(SUCCEEDED(hres))
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
else if(hres == DISP_E_UNKNOWNNAME)
|
else if(hres == DISP_E_UNKNOWNNAME)
|
||||||
|
@ -2001,11 +2006,11 @@ static HRESULT interp_eq2(exec_ctx_t *ctx)
|
||||||
BOOL b;
|
BOOL b;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
TRACE("\n");
|
|
||||||
|
|
||||||
r = stack_pop(ctx);
|
r = stack_pop(ctx);
|
||||||
l = stack_pop(ctx);
|
l = stack_pop(ctx);
|
||||||
|
|
||||||
|
TRACE("%s === %s\n", debugstr_jsval(l), debugstr_jsval(r));
|
||||||
|
|
||||||
hres = equal2_values(r, l, &b);
|
hres = equal2_values(r, l, &b);
|
||||||
jsval_release(l);
|
jsval_release(l);
|
||||||
jsval_release(r);
|
jsval_release(r);
|
||||||
|
|
|
@ -82,12 +82,16 @@ static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags,
|
||||||
unsigned msg_len = msg ? jsstr_length(msg) : 0;
|
unsigned msg_len = msg ? jsstr_length(msg) : 0;
|
||||||
|
|
||||||
if(name_len && msg_len) {
|
if(name_len && msg_len) {
|
||||||
ret = jsstr_alloc_buf(name_len + msg_len + 2);
|
WCHAR *ptr;
|
||||||
if(ret) {
|
|
||||||
jsstr_flush(name, ret->str);
|
ptr = jsstr_alloc_buf(name_len + msg_len + 2, &ret);
|
||||||
ret->str[name_len] = ':';
|
if(ptr) {
|
||||||
ret->str[name_len+1] = ' ';
|
jsstr_flush(name, ptr);
|
||||||
jsstr_flush(msg, ret->str+name_len+2);
|
ptr[name_len] = ':';
|
||||||
|
ptr[name_len+1] = ' ';
|
||||||
|
jsstr_flush(msg, ptr+name_len+2);
|
||||||
|
}else {
|
||||||
|
hres = E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
}else if(name_len) {
|
}else if(name_len) {
|
||||||
ret = name;
|
ret = name;
|
||||||
|
|
|
@ -318,15 +318,16 @@ static HRESULT function_to_string(FunctionInstance *function, jsstr_t **ret)
|
||||||
|
|
||||||
if(function->value_proc) {
|
if(function->value_proc) {
|
||||||
DWORD name_len;
|
DWORD name_len;
|
||||||
|
WCHAR *ptr;
|
||||||
|
|
||||||
name_len = strlenW(function->name);
|
name_len = strlenW(function->name);
|
||||||
str = jsstr_alloc_buf((sizeof(native_prefixW)+sizeof(native_suffixW))/sizeof(WCHAR) + name_len);
|
ptr = jsstr_alloc_buf((sizeof(native_prefixW)+sizeof(native_suffixW))/sizeof(WCHAR) + name_len, &str);
|
||||||
if(!str)
|
if(!ptr)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
memcpy(str->str, native_prefixW, sizeof(native_prefixW));
|
memcpy(ptr, native_prefixW, sizeof(native_prefixW));
|
||||||
memcpy(str->str + sizeof(native_prefixW)/sizeof(WCHAR), function->name, name_len*sizeof(WCHAR));
|
memcpy(ptr += sizeof(native_prefixW)/sizeof(WCHAR), function->name, name_len*sizeof(WCHAR));
|
||||||
memcpy(str->str + sizeof(native_prefixW)/sizeof(WCHAR) + name_len, native_suffixW, sizeof(native_suffixW));
|
memcpy(ptr + name_len, native_suffixW, sizeof(native_suffixW));
|
||||||
}else {
|
}else {
|
||||||
str = jsstr_alloc_len(function->func_code->source, function->func_code->source_len);
|
str = jsstr_alloc_len(function->func_code->source, function->func_code->source_len);
|
||||||
if(!str)
|
if(!str)
|
||||||
|
|
|
@ -278,7 +278,7 @@ static HRESULT JSGlobal_escape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
|
||||||
jsval_t *r)
|
jsval_t *r)
|
||||||
{
|
{
|
||||||
jsstr_t *ret_str, *str;
|
jsstr_t *ret_str, *str;
|
||||||
const WCHAR *ptr;
|
const WCHAR *ptr, *buf;
|
||||||
DWORD len = 0;
|
DWORD len = 0;
|
||||||
WCHAR *ret;
|
WCHAR *ret;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
@ -291,11 +291,11 @@ static HRESULT JSGlobal_escape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = to_string(ctx, argv[0], &str);
|
hres = to_flat_string(ctx, argv[0], &str, &buf);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
for(ptr = str->str; *ptr; ptr++) {
|
for(ptr = buf; *ptr; ptr++) {
|
||||||
if(*ptr > 0xff)
|
if(*ptr > 0xff)
|
||||||
len += 6;
|
len += 6;
|
||||||
else if(is_ecma_nonblank(*ptr))
|
else if(is_ecma_nonblank(*ptr))
|
||||||
|
@ -304,15 +304,14 @@ static HRESULT JSGlobal_escape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
|
||||||
len += 3;
|
len += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret_str = jsstr_alloc_buf(len);
|
ret = jsstr_alloc_buf(len, &ret_str);
|
||||||
if(!ret_str) {
|
if(!ret) {
|
||||||
jsstr_release(str);
|
jsstr_release(str);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = 0;
|
len = 0;
|
||||||
ret = ret_str->str;
|
for(ptr = buf; *ptr; ptr++) {
|
||||||
for(ptr = str->str; *ptr; ptr++) {
|
|
||||||
if(*ptr > 0xff) {
|
if(*ptr > 0xff) {
|
||||||
ret[len++] = '%';
|
ret[len++] = '%';
|
||||||
ret[len++] = 'u';
|
ret[len++] = 'u';
|
||||||
|
@ -344,6 +343,7 @@ static HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
|
||||||
jsval_t *r)
|
jsval_t *r)
|
||||||
{
|
{
|
||||||
bytecode_t *code;
|
bytecode_t *code;
|
||||||
|
const WCHAR *src;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
@ -365,8 +365,12 @@ static HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
|
||||||
return E_UNEXPECTED;
|
return E_UNEXPECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
src = jsstr_flatten(get_string(argv[0]));
|
||||||
|
if(!src)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
TRACE("parsing %s\n", debugstr_jsval(argv[0]));
|
TRACE("parsing %s\n", debugstr_jsval(argv[0]));
|
||||||
hres = compile_script(ctx, get_string(argv[0])->str, NULL, NULL, TRUE, FALSE, &code);
|
hres = compile_script(ctx, src, NULL, NULL, TRUE, FALSE, &code);
|
||||||
if(FAILED(hres)) {
|
if(FAILED(hres)) {
|
||||||
WARN("parse (%s) failed: %08x\n", debugstr_jsval(argv[0]), hres);
|
WARN("parse (%s) failed: %08x\n", debugstr_jsval(argv[0]), hres);
|
||||||
return throw_syntax_error(ctx, hres, NULL);
|
return throw_syntax_error(ctx, hres, NULL);
|
||||||
|
@ -439,10 +443,10 @@ static HRESULT JSGlobal_parseInt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
||||||
jsval_t *r)
|
jsval_t *r)
|
||||||
{
|
{
|
||||||
BOOL neg = FALSE, empty = TRUE;
|
BOOL neg = FALSE, empty = TRUE;
|
||||||
|
const WCHAR *ptr;
|
||||||
DOUBLE ret = 0.0;
|
DOUBLE ret = 0.0;
|
||||||
INT radix=0, i;
|
INT radix=0, i;
|
||||||
jsstr_t *str;
|
jsstr_t *str;
|
||||||
WCHAR *ptr;
|
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
if(!argc) {
|
if(!argc) {
|
||||||
|
@ -464,11 +468,12 @@ static HRESULT JSGlobal_parseInt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = to_string(ctx, argv[0], &str);
|
hres = to_flat_string(ctx, argv[0], &str, &ptr);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
for(ptr = str->str; isspaceW(*ptr); ptr++);
|
while(isspaceW(*ptr))
|
||||||
|
ptr++;
|
||||||
|
|
||||||
switch(*ptr) {
|
switch(*ptr) {
|
||||||
case '+':
|
case '+':
|
||||||
|
@ -521,7 +526,7 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
|
||||||
LONGLONG d = 0, hlp;
|
LONGLONG d = 0, hlp;
|
||||||
jsstr_t *val_str;
|
jsstr_t *val_str;
|
||||||
int exp = 0;
|
int exp = 0;
|
||||||
WCHAR *str;
|
const WCHAR *str;
|
||||||
BOOL ret_nan = TRUE, positive = TRUE;
|
BOOL ret_nan = TRUE, positive = TRUE;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
|
@ -531,12 +536,10 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = to_string(ctx, argv[0], &val_str);
|
hres = to_flat_string(ctx, argv[0], &val_str, &str);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
str = val_str->str;
|
|
||||||
|
|
||||||
while(isspaceW(*str)) str++;
|
while(isspaceW(*str)) str++;
|
||||||
|
|
||||||
if(*str == '+')
|
if(*str == '+')
|
||||||
|
@ -626,7 +629,7 @@ static HRESULT JSGlobal_unescape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
||||||
jsval_t *r)
|
jsval_t *r)
|
||||||
{
|
{
|
||||||
jsstr_t *ret_str, *str;
|
jsstr_t *ret_str, *str;
|
||||||
const WCHAR *ptr;
|
const WCHAR *ptr, *buf;
|
||||||
DWORD len = 0;
|
DWORD len = 0;
|
||||||
WCHAR *ret;
|
WCHAR *ret;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
@ -639,11 +642,11 @@ static HRESULT JSGlobal_unescape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = to_string(ctx, argv[0], &str);
|
hres = to_flat_string(ctx, argv[0], &str, &buf);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
for(ptr = str->str; *ptr; ptr++) {
|
for(ptr = buf; *ptr; ptr++) {
|
||||||
if(*ptr == '%') {
|
if(*ptr == '%') {
|
||||||
if(hex_to_int(*(ptr+1))!=-1 && hex_to_int(*(ptr+2))!=-1)
|
if(hex_to_int(*(ptr+1))!=-1 && hex_to_int(*(ptr+2))!=-1)
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
|
@ -655,15 +658,14 @@ static HRESULT JSGlobal_unescape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
||||||
len++;
|
len++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret_str = jsstr_alloc_buf(len);
|
ret = jsstr_alloc_buf(len, &ret_str);
|
||||||
if(!ret_str) {
|
if(!ret) {
|
||||||
jsstr_release(str);
|
jsstr_release(str);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ret_str->str;
|
|
||||||
len = 0;
|
len = 0;
|
||||||
for(ptr = str->str; *ptr; ptr++) {
|
for(ptr = buf; *ptr; ptr++) {
|
||||||
if(*ptr == '%') {
|
if(*ptr == '%') {
|
||||||
if(hex_to_int(*(ptr+1))!=-1 && hex_to_int(*(ptr+2))!=-1) {
|
if(hex_to_int(*(ptr+1))!=-1 && hex_to_int(*(ptr+2))!=-1) {
|
||||||
ret[len] = (hex_to_int(*(ptr+1))<<4) + hex_to_int(*(ptr+2));
|
ret[len] = (hex_to_int(*(ptr+1))<<4) + hex_to_int(*(ptr+2));
|
||||||
|
@ -760,8 +762,8 @@ static HRESULT JSGlobal_CollectGarbage(script_ctx_t *ctx, vdisp_t *jsthis, WORD
|
||||||
static HRESULT JSGlobal_encodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
static HRESULT JSGlobal_encodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||||
jsval_t *r)
|
jsval_t *r)
|
||||||
{
|
{
|
||||||
|
const WCHAR *ptr, *uri;
|
||||||
jsstr_t *str, *ret;
|
jsstr_t *str, *ret;
|
||||||
const WCHAR *ptr;
|
|
||||||
DWORD len = 0, i;
|
DWORD len = 0, i;
|
||||||
char buf[4];
|
char buf[4];
|
||||||
WCHAR *rptr;
|
WCHAR *rptr;
|
||||||
|
@ -775,11 +777,11 @@ static HRESULT JSGlobal_encodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = to_string(ctx, argv[0], &str);
|
hres = to_flat_string(ctx, argv[0], &str, &uri);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
for(ptr = str->str; *ptr; ptr++) {
|
for(ptr = uri; *ptr; ptr++) {
|
||||||
if(is_uri_unescaped(*ptr) || is_uri_reserved(*ptr) || *ptr == '#') {
|
if(is_uri_unescaped(*ptr) || is_uri_reserved(*ptr) || *ptr == '#') {
|
||||||
len++;
|
len++;
|
||||||
}else {
|
}else {
|
||||||
|
@ -793,14 +795,13 @@ static HRESULT JSGlobal_encodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = jsstr_alloc_buf(len);
|
rptr = jsstr_alloc_buf(len, &ret);
|
||||||
if(!ret) {
|
if(!rptr) {
|
||||||
jsstr_release(str);
|
jsstr_release(str);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
rptr = ret->str;
|
|
||||||
|
|
||||||
for(ptr = str->str; *ptr; ptr++) {
|
for(ptr = uri; *ptr; ptr++) {
|
||||||
if(is_uri_unescaped(*ptr) || is_uri_reserved(*ptr) || *ptr == '#') {
|
if(is_uri_unescaped(*ptr) || is_uri_reserved(*ptr) || *ptr == '#') {
|
||||||
*rptr++ = *ptr;
|
*rptr++ = *ptr;
|
||||||
}else {
|
}else {
|
||||||
|
@ -826,9 +827,11 @@ static HRESULT JSGlobal_encodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
||||||
static HRESULT JSGlobal_decodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
static HRESULT JSGlobal_decodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||||
jsval_t *r)
|
jsval_t *r)
|
||||||
{
|
{
|
||||||
jsstr_t *str, *ret;
|
const WCHAR *ptr, *uri;
|
||||||
WCHAR *ptr;
|
jsstr_t *str, *ret_str;
|
||||||
int i, len = 0, val, res;
|
unsigned len = 0;
|
||||||
|
int i, val, res;
|
||||||
|
WCHAR *ret;
|
||||||
char buf[4];
|
char buf[4];
|
||||||
WCHAR out;
|
WCHAR out;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
@ -841,11 +844,11 @@ static HRESULT JSGlobal_decodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = to_string(ctx, argv[0], &str);
|
hres = to_flat_string(ctx, argv[0], &str, &uri);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
for(ptr = str->str; *ptr; ptr++) {
|
for(ptr = uri; *ptr; ptr++) {
|
||||||
if(*ptr != '%') {
|
if(*ptr != '%') {
|
||||||
len++;
|
len++;
|
||||||
}else {
|
}else {
|
||||||
|
@ -871,17 +874,15 @@ static HRESULT JSGlobal_decodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = jsstr_alloc_buf(len);
|
ret = jsstr_alloc_buf(len, &ret_str);
|
||||||
if(!ret) {
|
if(!ret) {
|
||||||
jsstr_release(str);
|
jsstr_release(str);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = 0;
|
for(ptr = uri; *ptr; ptr++) {
|
||||||
for(ptr = str->str; *ptr; ptr++) {
|
|
||||||
if(*ptr != '%') {
|
if(*ptr != '%') {
|
||||||
ret->str[len] = *ptr;
|
*ret++ = *ptr;
|
||||||
len++;
|
|
||||||
}else {
|
}else {
|
||||||
for(i=0; i<4; i++) {
|
for(i=0; i<4; i++) {
|
||||||
if(ptr[i*3]!='%' || hex_to_int(ptr[i*3+1])==-1 || (val=hex_to_int(ptr[i*3+2]))==-1)
|
if(ptr[i*3]!='%' || hex_to_int(ptr[i*3+1])==-1 || (val=hex_to_int(ptr[i*3+2]))==-1)
|
||||||
|
@ -889,33 +890,34 @@ static HRESULT JSGlobal_decodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
||||||
val += hex_to_int(ptr[i*3+1])<<4;
|
val += hex_to_int(ptr[i*3+1])<<4;
|
||||||
buf[i] = val;
|
buf[i] = val;
|
||||||
|
|
||||||
res = MultiByteToWideChar(CP_UTF8, 0, buf, i+1, ret->str+len, 1);
|
res = MultiByteToWideChar(CP_UTF8, 0, buf, i+1, ret, 1);
|
||||||
if(res)
|
if(res)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr += i*3+2;
|
ptr += i*3+2;
|
||||||
len++;
|
ret++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("%s -> %s\n", debugstr_jsstr(str), debugstr_jsstr(ret));
|
TRACE("%s -> %s\n", debugstr_jsstr(str), debugstr_jsstr(ret_str));
|
||||||
jsstr_release(str);
|
jsstr_release(str);
|
||||||
|
|
||||||
if(r)
|
if(r)
|
||||||
*r = jsval_string(ret);
|
*r = jsval_string(ret_str);
|
||||||
else
|
else
|
||||||
jsstr_release(ret);
|
jsstr_release(ret_str);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT JSGlobal_encodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
static HRESULT JSGlobal_encodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||||
jsval_t *r)
|
jsval_t *r)
|
||||||
{
|
{
|
||||||
jsstr_t *str, *ret;
|
jsstr_t *str, *ret_str;
|
||||||
char buf[4];
|
char buf[4];
|
||||||
const WCHAR *ptr;
|
const WCHAR *ptr, *uri;
|
||||||
DWORD len = 0, size, i;
|
DWORD len = 0, size, i;
|
||||||
|
WCHAR *ret;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
@ -926,11 +928,11 @@ static HRESULT JSGlobal_encodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, W
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = to_string(ctx, argv[0], &str);
|
hres = to_flat_string(ctx, argv[0], &str, &uri);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
for(ptr = str->str; *ptr; ptr++) {
|
for(ptr = uri; *ptr; ptr++) {
|
||||||
if(is_uri_unescaped(*ptr))
|
if(is_uri_unescaped(*ptr))
|
||||||
len++;
|
len++;
|
||||||
else {
|
else {
|
||||||
|
@ -943,22 +945,21 @@ static HRESULT JSGlobal_encodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, W
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = jsstr_alloc_buf(len);
|
ret = jsstr_alloc_buf(len, &ret_str);
|
||||||
if(!ret) {
|
if(!ret) {
|
||||||
jsstr_release(str);
|
jsstr_release(str);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = 0;
|
for(ptr = uri; *ptr; ptr++) {
|
||||||
for(ptr = str->str; *ptr; ptr++) {
|
|
||||||
if(is_uri_unescaped(*ptr)) {
|
if(is_uri_unescaped(*ptr)) {
|
||||||
ret->str[len++] = *ptr;
|
*ret++ = *ptr;
|
||||||
}else {
|
}else {
|
||||||
size = WideCharToMultiByte(CP_UTF8, 0, ptr, 1, buf, sizeof(buf), NULL, NULL);
|
size = WideCharToMultiByte(CP_UTF8, 0, ptr, 1, buf, sizeof(buf), NULL, NULL);
|
||||||
for(i=0; i<size; i++) {
|
for(i=0; i<size; i++) {
|
||||||
ret->str[len++] = '%';
|
*ret++ = '%';
|
||||||
ret->str[len++] = int_to_char((BYTE)buf[i] >> 4);
|
*ret++ = int_to_char((BYTE)buf[i] >> 4);
|
||||||
ret->str[len++] = int_to_char(buf[i] & 0x0f);
|
*ret++ = int_to_char(buf[i] & 0x0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -966,9 +967,9 @@ static HRESULT JSGlobal_encodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, W
|
||||||
jsstr_release(str);
|
jsstr_release(str);
|
||||||
|
|
||||||
if(r)
|
if(r)
|
||||||
*r = jsval_string(ret);
|
*r = jsval_string(ret_str);
|
||||||
else
|
else
|
||||||
jsstr_release(ret);
|
jsstr_release(ret_str);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -976,8 +977,8 @@ static HRESULT JSGlobal_encodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, W
|
||||||
static HRESULT JSGlobal_decodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
static HRESULT JSGlobal_decodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||||
jsval_t *r)
|
jsval_t *r)
|
||||||
{
|
{
|
||||||
|
const WCHAR *ptr, *uri;
|
||||||
jsstr_t *str, *ret;
|
jsstr_t *str, *ret;
|
||||||
const WCHAR *ptr;
|
|
||||||
WCHAR *out_ptr;
|
WCHAR *out_ptr;
|
||||||
DWORD len = 0;
|
DWORD len = 0;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
@ -990,11 +991,11 @@ static HRESULT JSGlobal_decodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, W
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = to_string(ctx, argv[0], &str);
|
hres = to_flat_string(ctx, argv[0], &str, &uri);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
ptr = str->str;
|
ptr = uri;
|
||||||
while(*ptr) {
|
while(*ptr) {
|
||||||
if(*ptr == '%') {
|
if(*ptr == '%') {
|
||||||
char octets[4];
|
char octets[4];
|
||||||
|
@ -1044,14 +1045,13 @@ static HRESULT JSGlobal_decodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, W
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = jsstr_alloc_buf(len);
|
out_ptr = jsstr_alloc_buf(len, &ret);
|
||||||
if(!ret) {
|
if(!ret) {
|
||||||
jsstr_release(str);
|
jsstr_release(str);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
out_ptr = ret->str;
|
|
||||||
|
|
||||||
ptr = str->str;
|
ptr = uri;
|
||||||
while(*ptr) {
|
while(*ptr) {
|
||||||
if(*ptr == '%') {
|
if(*ptr == '%') {
|
||||||
char octets[4];
|
char octets[4];
|
||||||
|
|
|
@ -326,6 +326,7 @@ HRESULT to_integer(script_ctx_t*,jsval_t,double*) DECLSPEC_HIDDEN;
|
||||||
HRESULT to_int32(script_ctx_t*,jsval_t,INT*) DECLSPEC_HIDDEN;
|
HRESULT to_int32(script_ctx_t*,jsval_t,INT*) DECLSPEC_HIDDEN;
|
||||||
HRESULT to_uint32(script_ctx_t*,jsval_t,UINT32*) DECLSPEC_HIDDEN;
|
HRESULT to_uint32(script_ctx_t*,jsval_t,UINT32*) DECLSPEC_HIDDEN;
|
||||||
HRESULT to_string(script_ctx_t*,jsval_t,jsstr_t**) DECLSPEC_HIDDEN;
|
HRESULT to_string(script_ctx_t*,jsval_t,jsstr_t**) DECLSPEC_HIDDEN;
|
||||||
|
HRESULT to_flat_string(script_ctx_t*,jsval_t,jsstr_t**,const WCHAR**) DECLSPEC_HIDDEN;
|
||||||
HRESULT to_object(script_ctx_t*,jsval_t,IDispatch**) DECLSPEC_HIDDEN;
|
HRESULT to_object(script_ctx_t*,jsval_t,IDispatch**) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
HRESULT variant_change_type(script_ctx_t*,VARIANT*,VARIANT*,VARTYPE) DECLSPEC_HIDDEN;
|
HRESULT variant_change_type(script_ctx_t*,VARIANT*,VARIANT*,VARTYPE) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -144,6 +144,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
|
if (lpv) break;
|
||||||
free_strings();
|
free_strings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,12 +73,12 @@ static void set_last_index(RegExpInstance *This, DWORD last_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp,
|
static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp,
|
||||||
DWORD rem_flags, jsstr_t *str, match_state_t *ret)
|
DWORD rem_flags, jsstr_t *jsstr, const WCHAR *str, match_state_t *ret)
|
||||||
{
|
{
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
hres = regexp_execute(regexp->jsregexp, ctx, &ctx->tmp_heap,
|
hres = regexp_execute(regexp->jsregexp, ctx, &ctx->tmp_heap,
|
||||||
str->str, jsstr_length(str), ret);
|
str, jsstr_length(jsstr), ret);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
if(hres == S_FALSE) {
|
if(hres == S_FALSE) {
|
||||||
|
@ -87,9 +87,9 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp,
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(rem_flags & REM_NO_CTX_UPDATE) && ctx->last_match != str) {
|
if(!(rem_flags & REM_NO_CTX_UPDATE) && ctx->last_match != jsstr) {
|
||||||
jsstr_release(ctx->last_match);
|
jsstr_release(ctx->last_match);
|
||||||
ctx->last_match = jsstr_addref(str);
|
ctx->last_match = jsstr_addref(jsstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(rem_flags & REM_NO_CTX_UPDATE)) {
|
if(!(rem_flags & REM_NO_CTX_UPDATE)) {
|
||||||
|
@ -109,10 +109,10 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp,
|
||||||
memset(ctx->match_parens+n, 0, sizeof(ctx->match_parens) - n*sizeof(ctx->match_parens[0]));
|
memset(ctx->match_parens+n, 0, sizeof(ctx->match_parens) - n*sizeof(ctx->match_parens[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
set_last_index(regexp, ret->cp-str->str);
|
set_last_index(regexp, ret->cp-str);
|
||||||
|
|
||||||
if(!(rem_flags & REM_NO_CTX_UPDATE)) {
|
if(!(rem_flags & REM_NO_CTX_UPDATE)) {
|
||||||
ctx->last_match_index = ret->cp-str->str-ret->match_len;
|
ctx->last_match_index = ret->cp-str-ret->match_len;
|
||||||
ctx->last_match_length = ret->match_len;
|
ctx->last_match_length = ret->match_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,11 +120,12 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp,
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT regexp_match_next(script_ctx_t *ctx, jsdisp_t *dispex,
|
HRESULT regexp_match_next(script_ctx_t *ctx, jsdisp_t *dispex,
|
||||||
DWORD rem_flags, jsstr_t *str, match_state_t **ret)
|
DWORD rem_flags, jsstr_t *jsstr, match_state_t **ret)
|
||||||
{
|
{
|
||||||
RegExpInstance *regexp = (RegExpInstance*)dispex;
|
RegExpInstance *regexp = (RegExpInstance*)dispex;
|
||||||
match_state_t *match;
|
match_state_t *match;
|
||||||
heap_pool_t *mark;
|
heap_pool_t *mark;
|
||||||
|
const WCHAR *str;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
if((rem_flags & REM_CHECK_GLOBAL) && !(regexp->jsregexp->flags & REG_GLOB)) {
|
if((rem_flags & REM_CHECK_GLOBAL) && !(regexp->jsregexp->flags & REG_GLOB)) {
|
||||||
|
@ -133,8 +134,12 @@ HRESULT regexp_match_next(script_ctx_t *ctx, jsdisp_t *dispex,
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
str = jsstr_flatten(jsstr);
|
||||||
|
if(!str)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
if(rem_flags & REM_ALLOC_RESULT) {
|
if(rem_flags & REM_ALLOC_RESULT) {
|
||||||
match = alloc_match_state(regexp->jsregexp, NULL, str->str);
|
match = alloc_match_state(regexp->jsregexp, NULL, str);
|
||||||
if(!match)
|
if(!match)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
*ret = match;
|
*ret = match;
|
||||||
|
@ -154,7 +159,7 @@ HRESULT regexp_match_next(script_ctx_t *ctx, jsdisp_t *dispex,
|
||||||
match = *ret;
|
match = *ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = do_regexp_match_next(ctx, regexp, rem_flags, str, match);
|
hres = do_regexp_match_next(ctx, regexp, rem_flags, jsstr, str, match);
|
||||||
|
|
||||||
if(rem_flags & REM_NO_PARENS) {
|
if(rem_flags & REM_NO_PARENS) {
|
||||||
(*ret)->cp = match->cp;
|
(*ret)->cp = match->cp;
|
||||||
|
@ -171,7 +176,7 @@ HRESULT regexp_match_next(script_ctx_t *ctx, jsdisp_t *dispex,
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT regexp_match(script_ctx_t *ctx, jsdisp_t *dispex, jsstr_t *str, BOOL gflag,
|
static HRESULT regexp_match(script_ctx_t *ctx, jsdisp_t *dispex, jsstr_t *jsstr, BOOL gflag,
|
||||||
match_result_t **match_result, DWORD *result_cnt)
|
match_result_t **match_result, DWORD *result_cnt)
|
||||||
{
|
{
|
||||||
RegExpInstance *This = (RegExpInstance*)dispex;
|
RegExpInstance *This = (RegExpInstance*)dispex;
|
||||||
|
@ -179,18 +184,23 @@ static HRESULT regexp_match(script_ctx_t *ctx, jsdisp_t *dispex, jsstr_t *str, B
|
||||||
match_state_t *result;
|
match_state_t *result;
|
||||||
DWORD i=0, ret_size = 0;
|
DWORD i=0, ret_size = 0;
|
||||||
heap_pool_t *mark;
|
heap_pool_t *mark;
|
||||||
|
const WCHAR *str;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
mark = heap_pool_mark(&ctx->tmp_heap);
|
mark = heap_pool_mark(&ctx->tmp_heap);
|
||||||
|
|
||||||
result = alloc_match_state(This->jsregexp, &ctx->tmp_heap, str->str);
|
str = jsstr_flatten(jsstr);
|
||||||
|
if(!str)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
result = alloc_match_state(This->jsregexp, &ctx->tmp_heap, str);
|
||||||
if(!result) {
|
if(!result) {
|
||||||
heap_pool_clear(mark);
|
heap_pool_clear(mark);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
hres = do_regexp_match_next(ctx, This, 0, str, result);
|
hres = do_regexp_match_next(ctx, This, 0, jsstr, str, result);
|
||||||
if(hres == S_FALSE) {
|
if(hres == S_FALSE) {
|
||||||
hres = S_OK;
|
hres = S_OK;
|
||||||
break;
|
break;
|
||||||
|
@ -215,7 +225,7 @@ static HRESULT regexp_match(script_ctx_t *ctx, jsdisp_t *dispex, jsstr_t *str, B
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret[i].index = result->cp - str->str - result->match_len;
|
ret[i].index = result->cp - str - result->match_len;
|
||||||
ret[i++].length = result->match_len;
|
ret[i++].length = result->match_len;
|
||||||
|
|
||||||
if(!gflag && !(This->jsregexp->flags & REG_GLOB)) {
|
if(!gflag && !(This->jsregexp->flags & REG_GLOB)) {
|
||||||
|
@ -323,13 +333,56 @@ static HRESULT RegExp_lastIndex(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
||||||
static HRESULT RegExp_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
static HRESULT RegExp_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||||
jsval_t *r)
|
jsval_t *r)
|
||||||
{
|
{
|
||||||
FIXME("\n");
|
RegExpInstance *regexp;
|
||||||
return E_NOTIMPL;
|
unsigned len, f;
|
||||||
|
jsstr_t *ret;
|
||||||
|
WCHAR *ptr;
|
||||||
|
|
||||||
|
TRACE("\n");
|
||||||
|
|
||||||
|
if(!is_vclass(jsthis, JSCLASS_REGEXP)) {
|
||||||
|
FIXME("Not a RegExp\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
regexp = regexp_from_vdisp(jsthis);
|
||||||
|
|
||||||
|
if(!r)
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
len = jsstr_length(regexp->str) + 2;
|
||||||
|
|
||||||
|
f = regexp->jsregexp->flags;
|
||||||
|
if(f & REG_FOLD)
|
||||||
|
len++;
|
||||||
|
if(f & REG_GLOB)
|
||||||
|
len++;
|
||||||
|
if(f & REG_MULTILINE)
|
||||||
|
len++;
|
||||||
|
|
||||||
|
ptr = jsstr_alloc_buf(len, &ret);
|
||||||
|
if(!ptr)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
*ptr++ = '/';
|
||||||
|
ptr += jsstr_flush(regexp->str, ptr);
|
||||||
|
*ptr++ = '/';
|
||||||
|
|
||||||
|
if(f & REG_FOLD)
|
||||||
|
*ptr++ = 'i';
|
||||||
|
if(f & REG_GLOB)
|
||||||
|
*ptr++ = 'g';
|
||||||
|
if(f & REG_MULTILINE)
|
||||||
|
*ptr++ = 'm';
|
||||||
|
|
||||||
|
*r = jsval_string(ret);
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT create_match_array(script_ctx_t *ctx, jsstr_t *input,
|
static HRESULT create_match_array(script_ctx_t *ctx, jsstr_t *input_str,
|
||||||
const match_state_t *result, IDispatch **ret)
|
const match_state_t *result, IDispatch **ret)
|
||||||
{
|
{
|
||||||
|
const WCHAR *input;
|
||||||
jsdisp_t *array;
|
jsdisp_t *array;
|
||||||
jsstr_t *str;
|
jsstr_t *str;
|
||||||
DWORD i;
|
DWORD i;
|
||||||
|
@ -340,13 +393,17 @@ static HRESULT create_match_array(script_ctx_t *ctx, jsstr_t *input,
|
||||||
static const WCHAR lastIndexW[] = {'l','a','s','t','I','n','d','e','x',0};
|
static const WCHAR lastIndexW[] = {'l','a','s','t','I','n','d','e','x',0};
|
||||||
static const WCHAR zeroW[] = {'0',0};
|
static const WCHAR zeroW[] = {'0',0};
|
||||||
|
|
||||||
|
input = jsstr_flatten(input_str);
|
||||||
|
if(!input)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
hres = create_array(ctx, result->paren_count+1, &array);
|
hres = create_array(ctx, result->paren_count+1, &array);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
for(i=0; i < result->paren_count; i++) {
|
for(i=0; i < result->paren_count; i++) {
|
||||||
if(result->parens[i].index != -1)
|
if(result->parens[i].index != -1)
|
||||||
str = jsstr_substr(input, result->parens[i].index, result->parens[i].length);
|
str = jsstr_substr(input_str, result->parens[i].index, result->parens[i].length);
|
||||||
else
|
else
|
||||||
str = jsstr_empty();
|
str = jsstr_empty();
|
||||||
if(!str) {
|
if(!str) {
|
||||||
|
@ -361,15 +418,15 @@ static HRESULT create_match_array(script_ctx_t *ctx, jsstr_t *input,
|
||||||
}
|
}
|
||||||
|
|
||||||
while(SUCCEEDED(hres)) {
|
while(SUCCEEDED(hres)) {
|
||||||
hres = jsdisp_propput_name(array, indexW, jsval_number(result->cp-input->str-result->match_len));
|
hres = jsdisp_propput_name(array, indexW, jsval_number(result->cp-input-result->match_len));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
hres = jsdisp_propput_name(array, lastIndexW, jsval_number(result->cp-input->str));
|
hres = jsdisp_propput_name(array, lastIndexW, jsval_number(result->cp-input));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
hres = jsdisp_propput_name(array, inputW, jsval_string(jsstr_addref(input)));
|
hres = jsdisp_propput_name(array, inputW, jsval_string(jsstr_addref(input_str)));
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -398,7 +455,8 @@ static HRESULT run_exec(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t arg,
|
||||||
RegExpInstance *regexp;
|
RegExpInstance *regexp;
|
||||||
match_state_t *match;
|
match_state_t *match;
|
||||||
DWORD last_index = 0;
|
DWORD last_index = 0;
|
||||||
jsstr_t *string;
|
const WCHAR *string;
|
||||||
|
jsstr_t *jsstr;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
if(!is_vclass(jsthis, JSCLASS_REGEXP)) {
|
if(!is_vclass(jsthis, JSCLASS_REGEXP)) {
|
||||||
|
@ -408,13 +466,13 @@ static HRESULT run_exec(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t arg,
|
||||||
|
|
||||||
regexp = regexp_from_vdisp(jsthis);
|
regexp = regexp_from_vdisp(jsthis);
|
||||||
|
|
||||||
hres = to_string(ctx, arg, &string);
|
hres = to_flat_string(ctx, arg, &jsstr, &string);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
if(regexp->jsregexp->flags & REG_GLOB) {
|
if(regexp->jsregexp->flags & REG_GLOB) {
|
||||||
if(regexp->last_index < 0) {
|
if(regexp->last_index < 0) {
|
||||||
jsstr_release(string);
|
jsstr_release(jsstr);
|
||||||
set_last_index(regexp, 0);
|
set_last_index(regexp, 0);
|
||||||
*ret = FALSE;
|
*ret = FALSE;
|
||||||
if(input)
|
if(input)
|
||||||
|
@ -425,24 +483,24 @@ static HRESULT run_exec(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t arg,
|
||||||
last_index = regexp->last_index;
|
last_index = regexp->last_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
match = alloc_match_state(regexp->jsregexp, &ctx->tmp_heap, string->str+last_index);
|
match = alloc_match_state(regexp->jsregexp, &ctx->tmp_heap, string+last_index);
|
||||||
if(!match) {
|
if(!match) {
|
||||||
jsstr_release(string);
|
jsstr_release(jsstr);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = regexp_match_next(ctx, ®exp->dispex, REM_RESET_INDEX, string, &match);
|
hres = regexp_match_next(ctx, ®exp->dispex, REM_RESET_INDEX, jsstr, &match);
|
||||||
if(FAILED(hres)) {
|
if(FAILED(hres)) {
|
||||||
jsstr_release(string);
|
jsstr_release(jsstr);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
*result = match;
|
*result = match;
|
||||||
*ret = hres == S_OK;
|
*ret = hres == S_OK;
|
||||||
if(input)
|
if(input)
|
||||||
*input = string;
|
*input = jsstr;
|
||||||
else
|
else
|
||||||
jsstr_release(string);
|
jsstr_release(jsstr);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,10 +654,15 @@ static HRESULT alloc_regexp(script_ctx_t *ctx, jsdisp_t *object_prototype, RegEx
|
||||||
HRESULT create_regexp(script_ctx_t *ctx, jsstr_t *src, DWORD flags, jsdisp_t **ret)
|
HRESULT create_regexp(script_ctx_t *ctx, jsstr_t *src, DWORD flags, jsdisp_t **ret)
|
||||||
{
|
{
|
||||||
RegExpInstance *regexp;
|
RegExpInstance *regexp;
|
||||||
|
const WCHAR *str;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
TRACE("%s %x\n", debugstr_jsstr(src), flags);
|
TRACE("%s %x\n", debugstr_jsstr(src), flags);
|
||||||
|
|
||||||
|
str = jsstr_flatten(src);
|
||||||
|
if(!str)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
hres = alloc_regexp(ctx, NULL, ®exp);
|
hres = alloc_regexp(ctx, NULL, ®exp);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -607,9 +670,8 @@ HRESULT create_regexp(script_ctx_t *ctx, jsstr_t *src, DWORD flags, jsdisp_t **r
|
||||||
regexp->str = jsstr_addref(src);
|
regexp->str = jsstr_addref(src);
|
||||||
regexp->last_index_val = jsval_number(0);
|
regexp->last_index_val = jsval_number(0);
|
||||||
|
|
||||||
regexp->jsregexp = regexp_new(ctx, &ctx->tmp_heap, regexp->str->str,
|
regexp->jsregexp = regexp_new(ctx, &ctx->tmp_heap, str, jsstr_length(regexp->str), flags, FALSE);
|
||||||
jsstr_length(regexp->str), flags, FALSE);
|
if(!regexp->jsregexp) {
|
||||||
if(FAILED(hres)) {
|
|
||||||
WARN("regexp_new failed\n");
|
WARN("regexp_new failed\n");
|
||||||
jsdisp_release(®exp->dispex);
|
jsdisp_release(®exp->dispex);
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
@ -621,8 +683,9 @@ HRESULT create_regexp(script_ctx_t *ctx, jsstr_t *src, DWORD flags, jsdisp_t **r
|
||||||
|
|
||||||
HRESULT create_regexp_var(script_ctx_t *ctx, jsval_t src_arg, jsval_t *flags_arg, jsdisp_t **ret)
|
HRESULT create_regexp_var(script_ctx_t *ctx, jsval_t src_arg, jsval_t *flags_arg, jsdisp_t **ret)
|
||||||
{
|
{
|
||||||
jsstr_t *src, *opt = NULL;
|
unsigned flags, opt_len = 0;
|
||||||
DWORD flags;
|
const WCHAR *opt = NULL;
|
||||||
|
jsstr_t *src;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
if(is_object_instance(src_arg)) {
|
if(is_object_instance(src_arg)) {
|
||||||
|
@ -650,22 +713,28 @@ HRESULT create_regexp_var(script_ctx_t *ctx, jsval_t src_arg, jsval_t *flags_arg
|
||||||
src = get_string(src_arg);
|
src = get_string(src_arg);
|
||||||
|
|
||||||
if(flags_arg) {
|
if(flags_arg) {
|
||||||
|
jsstr_t *opt_str;
|
||||||
|
|
||||||
if(!is_string(*flags_arg)) {
|
if(!is_string(*flags_arg)) {
|
||||||
FIXME("unimplemented for %s\n", debugstr_jsval(*flags_arg));
|
FIXME("unimplemented for %s\n", debugstr_jsval(*flags_arg));
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
opt = get_string(*flags_arg);
|
opt_str = get_string(*flags_arg);
|
||||||
|
opt = jsstr_flatten(opt_str);
|
||||||
|
if(!opt)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
opt_len = jsstr_length(opt_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = parse_regexp_flags(opt ? opt->str : NULL, opt ? jsstr_length(opt) : 0, &flags);
|
hres = parse_regexp_flags(opt, opt_len, &flags);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
return create_regexp(ctx, src, flags, ret);
|
return create_regexp(ctx, src, flags, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, jsstr_t *str, jsval_t *r)
|
HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, jsstr_t *jsstr, jsval_t *r)
|
||||||
{
|
{
|
||||||
static const WCHAR indexW[] = {'i','n','d','e','x',0};
|
static const WCHAR indexW[] = {'i','n','d','e','x',0};
|
||||||
static const WCHAR inputW[] = {'i','n','p','u','t',0};
|
static const WCHAR inputW[] = {'i','n','p','u','t',0};
|
||||||
|
@ -674,21 +743,26 @@ HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, jsstr_t *str, jsval
|
||||||
RegExpInstance *regexp = (RegExpInstance*)re;
|
RegExpInstance *regexp = (RegExpInstance*)re;
|
||||||
match_result_t *match_result;
|
match_result_t *match_result;
|
||||||
unsigned match_cnt, i;
|
unsigned match_cnt, i;
|
||||||
|
const WCHAR *str;
|
||||||
jsdisp_t *array;
|
jsdisp_t *array;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
|
str = jsstr_flatten(jsstr);
|
||||||
|
if(!str)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
if(!(regexp->jsregexp->flags & REG_GLOB)) {
|
if(!(regexp->jsregexp->flags & REG_GLOB)) {
|
||||||
match_state_t *match;
|
match_state_t *match;
|
||||||
heap_pool_t *mark;
|
heap_pool_t *mark;
|
||||||
|
|
||||||
mark = heap_pool_mark(&ctx->tmp_heap);
|
mark = heap_pool_mark(&ctx->tmp_heap);
|
||||||
match = alloc_match_state(regexp->jsregexp, &ctx->tmp_heap, str->str);
|
match = alloc_match_state(regexp->jsregexp, &ctx->tmp_heap, str);
|
||||||
if(!match) {
|
if(!match) {
|
||||||
heap_pool_clear(mark);
|
heap_pool_clear(mark);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = regexp_match_next(ctx, ®exp->dispex, 0, str, &match);
|
hres = regexp_match_next(ctx, ®exp->dispex, 0, jsstr, &match);
|
||||||
if(FAILED(hres)) {
|
if(FAILED(hres)) {
|
||||||
heap_pool_clear(mark);
|
heap_pool_clear(mark);
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -698,7 +772,7 @@ HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, jsstr_t *str, jsval
|
||||||
if(hres == S_OK) {
|
if(hres == S_OK) {
|
||||||
IDispatch *ret;
|
IDispatch *ret;
|
||||||
|
|
||||||
hres = create_match_array(ctx, str, match, &ret);
|
hres = create_match_array(ctx, jsstr, match, &ret);
|
||||||
if(SUCCEEDED(hres))
|
if(SUCCEEDED(hres))
|
||||||
*r = jsval_disp(ret);
|
*r = jsval_disp(ret);
|
||||||
}else {
|
}else {
|
||||||
|
@ -710,7 +784,7 @@ HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, jsstr_t *str, jsval
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = regexp_match(ctx, ®exp->dispex, str, FALSE, &match_result, &match_cnt);
|
hres = regexp_match(ctx, ®exp->dispex, jsstr, FALSE, &match_result, &match_cnt);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
|
@ -729,7 +803,7 @@ HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, jsstr_t *str, jsval
|
||||||
for(i=0; i < match_cnt; i++) {
|
for(i=0; i < match_cnt; i++) {
|
||||||
jsstr_t *tmp_str;
|
jsstr_t *tmp_str;
|
||||||
|
|
||||||
tmp_str = jsstr_substr(str, match_result[i].index, match_result[i].length);
|
tmp_str = jsstr_substr(jsstr, match_result[i].index, match_result[i].length);
|
||||||
if(!tmp_str) {
|
if(!tmp_str) {
|
||||||
hres = E_OUTOFMEMORY;
|
hres = E_OUTOFMEMORY;
|
||||||
break;
|
break;
|
||||||
|
@ -751,7 +825,7 @@ HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, jsstr_t *str, jsval
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
hres = jsdisp_propput_name(array, inputW, jsval_string(str));
|
hres = jsdisp_propput_name(array, inputW, jsval_string(jsstr));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,60 +16,203 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "jscript.h"
|
#include "jscript.h"
|
||||||
|
|
||||||
#include <wine/debug.h>
|
#include <wine/debug.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the length of a string that is considered to be long enough to be
|
||||||
|
* worth the rope to avoid copy.
|
||||||
|
* This probably could be tuned, but keep it low for a while to better test rope's code.
|
||||||
|
*/
|
||||||
|
#define JSSTR_SHORT_STRING_LENGTH 8
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the max rope depth. While faster to allocate, ropes may become slow at access.
|
||||||
|
*/
|
||||||
|
#define JSSTR_MAX_ROPE_DEPTH 100
|
||||||
|
|
||||||
const char *debugstr_jsstr(jsstr_t *str)
|
const char *debugstr_jsstr(jsstr_t *str)
|
||||||
{
|
{
|
||||||
return debugstr_wn(str->str, jsstr_length(str));
|
return jsstr_is_inline(str) ? debugstr_wn(jsstr_as_inline(str)->buf, jsstr_length(str))
|
||||||
|
: jsstr_is_heap(str) ? debugstr_wn(jsstr_as_heap(str)->buf, jsstr_length(str))
|
||||||
|
: wine_dbg_sprintf("%s...", debugstr_jsstr(jsstr_as_rope(str)->left));
|
||||||
}
|
}
|
||||||
|
|
||||||
jsstr_t *jsstr_alloc_buf(unsigned len)
|
void jsstr_free(jsstr_t *str)
|
||||||
{
|
{
|
||||||
jsstr_t *ret;
|
switch(jsstr_tag(str)) {
|
||||||
|
case JSSTR_HEAP:
|
||||||
|
heap_free(jsstr_as_heap(str)->buf);
|
||||||
|
break;
|
||||||
|
case JSSTR_ROPE: {
|
||||||
|
jsstr_rope_t *rope = jsstr_as_rope(str);
|
||||||
|
jsstr_release(rope->left);
|
||||||
|
jsstr_release(rope->right);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case JSSTR_INLINE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
heap_free(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void jsstr_init(jsstr_t *str, unsigned len, jsstr_tag_t tag)
|
||||||
|
{
|
||||||
|
str->length_flags = len << JSSTR_LENGTH_SHIFT | tag;
|
||||||
|
str->ref = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
WCHAR *jsstr_alloc_buf(unsigned len, jsstr_t **r)
|
||||||
|
{
|
||||||
|
jsstr_inline_t *ret;
|
||||||
|
|
||||||
if(len > JSSTR_MAX_LENGTH)
|
if(len > JSSTR_MAX_LENGTH)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ret = heap_alloc(FIELD_OFFSET(jsstr_t, str[len+1]));
|
ret = heap_alloc(FIELD_OFFSET(jsstr_inline_t, buf[len+1]));
|
||||||
if(!ret)
|
if(!ret)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ret->length_flags = len << JSSTR_LENGTH_SHIFT;
|
jsstr_init(&ret->str, len, JSSTR_INLINE);
|
||||||
ret->ref = 1;
|
ret->buf[len] = 0;
|
||||||
ret->str[len] = 0;
|
*r = &ret->str;
|
||||||
return ret;
|
return ret->buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
jsstr_t *jsstr_alloc_len(const WCHAR *buf, unsigned len)
|
jsstr_t *jsstr_alloc_len(const WCHAR *buf, unsigned len)
|
||||||
{
|
{
|
||||||
jsstr_t *ret;
|
jsstr_t *ret;
|
||||||
|
WCHAR *ptr;
|
||||||
|
|
||||||
ret = jsstr_alloc_buf(len);
|
ptr = jsstr_alloc_buf(len, &ret);
|
||||||
if(ret)
|
if(ptr)
|
||||||
memcpy(ret->str, buf, len*sizeof(WCHAR));
|
memcpy(ptr, buf, len*sizeof(WCHAR));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int jsstr_cmp(jsstr_t *str1, jsstr_t *str2)
|
static void jsstr_rope_extract(jsstr_rope_t *str, unsigned off, unsigned len, WCHAR *buf)
|
||||||
|
{
|
||||||
|
unsigned left_len = jsstr_length(str->left);
|
||||||
|
|
||||||
|
if(left_len <= off) {
|
||||||
|
jsstr_extract(str->right, off-left_len, len, buf);
|
||||||
|
}else if(left_len >= len+off) {
|
||||||
|
jsstr_extract(str->left, off, len, buf);
|
||||||
|
}else {
|
||||||
|
left_len -= off;
|
||||||
|
jsstr_extract(str->left, off, left_len, buf);
|
||||||
|
jsstr_extract(str->right, 0, len-left_len, buf+left_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void jsstr_extract(jsstr_t *str, unsigned off, unsigned len, WCHAR *buf)
|
||||||
|
{
|
||||||
|
switch(jsstr_tag(str)) {
|
||||||
|
case JSSTR_INLINE:
|
||||||
|
memcpy(buf, jsstr_as_inline(str)->buf+off, len*sizeof(WCHAR));
|
||||||
|
return;
|
||||||
|
case JSSTR_HEAP:
|
||||||
|
memcpy(buf, jsstr_as_heap(str)->buf+off, len*sizeof(WCHAR));
|
||||||
|
return;
|
||||||
|
case JSSTR_ROPE:
|
||||||
|
jsstr_rope_extract(jsstr_as_rope(str), off, len, buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jsstr_cmp_str(jsstr_t *jsstr, const WCHAR *str, unsigned len)
|
||||||
{
|
{
|
||||||
int len1 = jsstr_length(str1);
|
|
||||||
int len2 = jsstr_length(str2);
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = memcmp(str1->str, str2->str, min(len1, len2)*sizeof(WCHAR));
|
switch(jsstr_tag(jsstr)) {
|
||||||
if(!ret)
|
case JSSTR_INLINE:
|
||||||
ret = len1 - len2;
|
ret = memcmp(jsstr_as_inline(jsstr)->buf, str, len*sizeof(WCHAR));
|
||||||
|
return ret || jsstr_length(jsstr) == len ? ret : 1;
|
||||||
|
case JSSTR_HEAP:
|
||||||
|
ret = memcmp(jsstr_as_heap(jsstr)->buf, str, len*sizeof(WCHAR));
|
||||||
|
return ret || jsstr_length(jsstr) == len ? ret : 1;
|
||||||
|
case JSSTR_ROPE: {
|
||||||
|
jsstr_rope_t *rope = jsstr_as_rope(jsstr);
|
||||||
|
unsigned left_len = jsstr_length(rope->left);
|
||||||
|
|
||||||
return ret;
|
ret = jsstr_cmp_str(rope->left, str, min(len, left_len));
|
||||||
|
if(ret || len <= left_len)
|
||||||
|
return ret;
|
||||||
|
return jsstr_cmp_str(rope->right, str+left_len, len-left_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TMP_BUF_SIZE 256
|
||||||
|
|
||||||
|
static int ropes_cmp(jsstr_rope_t *left, jsstr_rope_t *right)
|
||||||
|
{
|
||||||
|
WCHAR left_buf[TMP_BUF_SIZE], right_buf[TMP_BUF_SIZE];
|
||||||
|
unsigned left_len = jsstr_length(&left->str);
|
||||||
|
unsigned right_len = jsstr_length(&right->str);
|
||||||
|
unsigned cmp_off = 0, cmp_size;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* FIXME: We can avoid temporary buffers here. */
|
||||||
|
while(cmp_off < min(left_len, right_len)) {
|
||||||
|
cmp_size = min(left_len, right_len) - cmp_off;
|
||||||
|
if(cmp_size > TMP_BUF_SIZE)
|
||||||
|
cmp_size = TMP_BUF_SIZE;
|
||||||
|
|
||||||
|
jsstr_rope_extract(left, cmp_off, cmp_size, left_buf);
|
||||||
|
jsstr_rope_extract(right, cmp_off, cmp_size, right_buf);
|
||||||
|
ret = memcmp(left_buf, right_buf, cmp_size);
|
||||||
|
if(ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
cmp_off += cmp_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return left_len - right_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const WCHAR *jsstr_try_flat(jsstr_t *str)
|
||||||
|
{
|
||||||
|
return jsstr_is_inline(str) ? jsstr_as_inline(str)->buf
|
||||||
|
: jsstr_is_heap(str) ? jsstr_as_heap(str)->buf
|
||||||
|
: NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int jsstr_cmp(jsstr_t *str1, jsstr_t *str2)
|
||||||
|
{
|
||||||
|
unsigned len1 = jsstr_length(str1);
|
||||||
|
unsigned len2 = jsstr_length(str2);
|
||||||
|
const WCHAR *str;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
str = jsstr_try_flat(str2);
|
||||||
|
if(str) {
|
||||||
|
ret = jsstr_cmp_str(str1, str, min(len1, len2));
|
||||||
|
return ret || len1 == len2 ? ret : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
str = jsstr_try_flat(str1);
|
||||||
|
if(str) {
|
||||||
|
ret = jsstr_cmp_str(str2, str, min(len1, len2));
|
||||||
|
return ret || len1 == len2 ? -ret : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ropes_cmp(jsstr_as_rope(str1), jsstr_as_rope(str2));
|
||||||
}
|
}
|
||||||
|
|
||||||
jsstr_t *jsstr_concat(jsstr_t *str1, jsstr_t *str2)
|
jsstr_t *jsstr_concat(jsstr_t *str1, jsstr_t *str2)
|
||||||
{
|
{
|
||||||
unsigned len1, len2;
|
unsigned len1, len2;
|
||||||
jsstr_t *ret;
|
jsstr_t *ret;
|
||||||
|
WCHAR *ptr;
|
||||||
|
|
||||||
len1 = jsstr_length(str1);
|
len1 = jsstr_length(str1);
|
||||||
if(!len1)
|
if(!len1)
|
||||||
|
@ -79,16 +222,63 @@ jsstr_t *jsstr_concat(jsstr_t *str1, jsstr_t *str2)
|
||||||
if(!len2)
|
if(!len2)
|
||||||
return jsstr_addref(str1);
|
return jsstr_addref(str1);
|
||||||
|
|
||||||
ret = jsstr_alloc_buf(len1+len2);
|
if(len1 + len2 >= JSSTR_SHORT_STRING_LENGTH) {
|
||||||
|
unsigned depth, depth2;
|
||||||
|
jsstr_rope_t *rope;
|
||||||
|
|
||||||
|
depth = jsstr_is_rope(str1) ? jsstr_as_rope(str1)->depth : 0;
|
||||||
|
depth2 = jsstr_is_rope(str2) ? jsstr_as_rope(str2)->depth : 0;
|
||||||
|
if(depth2 > depth)
|
||||||
|
depth = depth2;
|
||||||
|
|
||||||
|
if(depth++ < JSSTR_MAX_ROPE_DEPTH) {
|
||||||
|
if(len1+len2 > JSSTR_MAX_LENGTH)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
rope = heap_alloc(sizeof(*rope));
|
||||||
|
if(!rope)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
jsstr_init(&rope->str, len1+len2, JSSTR_ROPE);
|
||||||
|
rope->left = jsstr_addref(str1);
|
||||||
|
rope->right = jsstr_addref(str2);
|
||||||
|
rope->depth = depth;
|
||||||
|
return &rope->str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = jsstr_alloc_buf(len1+len2, &ret);
|
||||||
if(!ret)
|
if(!ret)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
jsstr_flush(str1, ret->str);
|
jsstr_flush(str1, ptr);
|
||||||
jsstr_flush(str2, ret->str+len1);
|
jsstr_flush(str2, ptr+len1);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static jsstr_t *empty_str, *nan_str, *undefined_str;
|
C_ASSERT(sizeof(jsstr_heap_t) <= sizeof(jsstr_rope_t));
|
||||||
|
|
||||||
|
const WCHAR *jsstr_rope_flatten(jsstr_rope_t *str)
|
||||||
|
{
|
||||||
|
WCHAR *buf;
|
||||||
|
|
||||||
|
buf = heap_alloc((jsstr_length(&str->str)+1) * sizeof(WCHAR));
|
||||||
|
if(!buf)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
jsstr_flush(str->left, buf);
|
||||||
|
jsstr_flush(str->right, buf+jsstr_length(str->left));
|
||||||
|
buf[jsstr_length(&str->str)] = 0;
|
||||||
|
|
||||||
|
/* Trasform to heap string */
|
||||||
|
jsstr_release(str->left);
|
||||||
|
jsstr_release(str->right);
|
||||||
|
str->str.length_flags |= JSSTR_FLAG_FLAT;
|
||||||
|
return jsstr_as_heap(&str->str)->buf = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static jsstr_t *empty_str, *nan_str, *undefined_str, *null_bstr_str;
|
||||||
|
|
||||||
jsstr_t *jsstr_nan(void)
|
jsstr_t *jsstr_nan(void)
|
||||||
{
|
{
|
||||||
|
@ -105,23 +295,40 @@ jsstr_t *jsstr_undefined(void)
|
||||||
return jsstr_addref(undefined_str);
|
return jsstr_addref(undefined_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jsstr_t *jsstr_null_bstr(void)
|
||||||
|
{
|
||||||
|
return jsstr_addref(null_bstr_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL is_null_bstr(jsstr_t *str)
|
||||||
|
{
|
||||||
|
return str == null_bstr_str;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL init_strings(void)
|
BOOL init_strings(void)
|
||||||
{
|
{
|
||||||
static const WCHAR NaNW[] = { 'N','a','N',0 };
|
static const WCHAR NaNW[] = { 'N','a','N',0 };
|
||||||
static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
|
static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
|
||||||
|
|
||||||
if(!(empty_str = jsstr_alloc_buf(0)))
|
if(!jsstr_alloc_buf(0, &empty_str))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if(!(nan_str = jsstr_alloc(NaNW)))
|
if(!(nan_str = jsstr_alloc(NaNW)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if(!(undefined_str = jsstr_alloc(undefinedW)))
|
if(!(undefined_str = jsstr_alloc(undefinedW)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
return TRUE;
|
if(!jsstr_alloc_buf(0, &null_bstr_str))
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_strings(void)
|
void free_strings(void)
|
||||||
{
|
{
|
||||||
jsstr_release(empty_str);
|
if(empty_str)
|
||||||
jsstr_release(nan_str);
|
jsstr_release(empty_str);
|
||||||
jsstr_release(undefined_str);
|
if(nan_str)
|
||||||
|
jsstr_release(nan_str);
|
||||||
|
if(undefined_str)
|
||||||
|
jsstr_release(undefined_str);
|
||||||
|
if(null_bstr_str)
|
||||||
|
jsstr_release(null_bstr_str);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,35 +16,102 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* jsstr_t is a common header for all string representations. The exact layout of the string
|
||||||
|
* representation may be:
|
||||||
|
*
|
||||||
|
* - inline string - string bytes directly follow string headers.
|
||||||
|
* - heap string - a structure containing a pointer to buffer on the heap.
|
||||||
|
* - roper string - a product of concatenation of two strings. Instead of copying whole
|
||||||
|
* buffers, we may store just references to concatenated strings.
|
||||||
|
*
|
||||||
|
* String layout may change over life time of the string. Currently possible transformation
|
||||||
|
* is when a rope string becomes a heap stream. That happens when we need a real, linear
|
||||||
|
* zero-terminated buffer (a flat buffer). At this point the type of the string is changed
|
||||||
|
* and the new buffer is stored in the string, so that subsequent operations requiring
|
||||||
|
* a flat string won't need to flatten it again.
|
||||||
|
*
|
||||||
|
* In the future more layouts and transformations may be added.
|
||||||
|
*/
|
||||||
struct _jsstr_t {
|
struct _jsstr_t {
|
||||||
unsigned length_flags;
|
unsigned length_flags;
|
||||||
unsigned ref;
|
unsigned ref;
|
||||||
WCHAR str[1];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define JSSTR_LENGTH_SHIFT 4
|
#define JSSTR_LENGTH_SHIFT 4
|
||||||
#define JSSTR_MAX_LENGTH (1 << (32-JSSTR_LENGTH_SHIFT))
|
#define JSSTR_MAX_LENGTH (1 << (32-JSSTR_LENGTH_SHIFT))
|
||||||
#define JSSTR_FLAGS_MASK ((1 << JSSTR_LENGTH_SHIFT)-1)
|
#define JSSTR_FLAGS_MASK ((1 << JSSTR_LENGTH_SHIFT)-1)
|
||||||
|
|
||||||
#define JSSTR_FLAG_NULLBSTR 1
|
#define JSSTR_FLAG_LBIT 1
|
||||||
|
#define JSSTR_FLAG_FLAT 2
|
||||||
|
#define JSSTR_FLAG_TAG_MASK 3
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
JSSTR_INLINE = JSSTR_FLAG_FLAT,
|
||||||
|
JSSTR_HEAP = JSSTR_FLAG_FLAT|JSSTR_FLAG_LBIT,
|
||||||
|
JSSTR_ROPE = JSSTR_FLAG_LBIT
|
||||||
|
} jsstr_tag_t;
|
||||||
|
|
||||||
static inline unsigned jsstr_length(jsstr_t *str)
|
static inline unsigned jsstr_length(jsstr_t *str)
|
||||||
{
|
{
|
||||||
return str->length_flags >> JSSTR_LENGTH_SHIFT;
|
return str->length_flags >> JSSTR_LENGTH_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline jsstr_tag_t jsstr_tag(jsstr_t *str)
|
||||||
|
{
|
||||||
|
return str->length_flags & JSSTR_FLAG_TAG_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline BOOL jsstr_is_inline(jsstr_t *str)
|
||||||
|
{
|
||||||
|
return jsstr_tag(str) == JSSTR_INLINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline BOOL jsstr_is_heap(jsstr_t *str)
|
||||||
|
{
|
||||||
|
return jsstr_tag(str) == JSSTR_HEAP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline BOOL jsstr_is_rope(jsstr_t *str)
|
||||||
|
{
|
||||||
|
return jsstr_tag(str) == JSSTR_ROPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
jsstr_t str;
|
||||||
|
WCHAR buf[1];
|
||||||
|
} jsstr_inline_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
jsstr_t str;
|
||||||
|
WCHAR *buf;
|
||||||
|
} jsstr_heap_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
jsstr_t str;
|
||||||
|
jsstr_t *left;
|
||||||
|
jsstr_t *right;
|
||||||
|
unsigned depth;
|
||||||
|
} jsstr_rope_t;
|
||||||
|
|
||||||
jsstr_t *jsstr_alloc_len(const WCHAR*,unsigned) DECLSPEC_HIDDEN;
|
jsstr_t *jsstr_alloc_len(const WCHAR*,unsigned) DECLSPEC_HIDDEN;
|
||||||
jsstr_t *jsstr_alloc_buf(unsigned) DECLSPEC_HIDDEN;
|
WCHAR *jsstr_alloc_buf(unsigned,jsstr_t**) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
static inline jsstr_t *jsstr_alloc(const WCHAR *str)
|
static inline jsstr_t *jsstr_alloc(const WCHAR *str)
|
||||||
{
|
{
|
||||||
return jsstr_alloc_len(str, strlenW(str));
|
return jsstr_alloc_len(str, strlenW(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void jsstr_free(jsstr_t*) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
static inline void jsstr_release(jsstr_t *str)
|
static inline void jsstr_release(jsstr_t *str)
|
||||||
{
|
{
|
||||||
if(!--str->ref)
|
if(!--str->ref) {
|
||||||
heap_free(str);
|
if(jsstr_is_inline(str))
|
||||||
|
heap_free(str);
|
||||||
|
else
|
||||||
|
jsstr_free(str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline jsstr_t *jsstr_addref(jsstr_t *str)
|
static inline jsstr_t *jsstr_addref(jsstr_t *str)
|
||||||
|
@ -53,31 +120,74 @@ static inline jsstr_t *jsstr_addref(jsstr_t *str)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline BOOL jsstr_eq(jsstr_t *str1, jsstr_t *str2)
|
static inline jsstr_inline_t *jsstr_as_inline(jsstr_t *str)
|
||||||
{
|
{
|
||||||
unsigned len = jsstr_length(str1);
|
return CONTAINING_RECORD(str, jsstr_inline_t, str);
|
||||||
return len == jsstr_length(str2) && !memcmp(str1->str, str2->str, len*sizeof(WCHAR));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline jsstr_heap_t *jsstr_as_heap(jsstr_t *str)
|
||||||
|
{
|
||||||
|
return CONTAINING_RECORD(str, jsstr_heap_t, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline jsstr_rope_t *jsstr_as_rope(jsstr_t *str)
|
||||||
|
{
|
||||||
|
return CONTAINING_RECORD(str, jsstr_rope_t, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
const WCHAR *jsstr_rope_flatten(jsstr_rope_t*) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
static inline const WCHAR *jsstr_flatten(jsstr_t *str)
|
||||||
|
{
|
||||||
|
return jsstr_is_inline(str) ? jsstr_as_inline(str)->buf
|
||||||
|
: jsstr_is_heap(str) ? jsstr_as_heap(str)->buf
|
||||||
|
: jsstr_rope_flatten(jsstr_as_rope(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
void jsstr_extract(jsstr_t*,unsigned,unsigned,WCHAR*) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
static inline unsigned jsstr_flush(jsstr_t *str, WCHAR *buf)
|
static inline unsigned jsstr_flush(jsstr_t *str, WCHAR *buf)
|
||||||
{
|
{
|
||||||
unsigned len = jsstr_length(str);
|
unsigned len = jsstr_length(str);
|
||||||
memcpy(buf, str->str, len*sizeof(WCHAR));
|
if(jsstr_is_inline(str)) {
|
||||||
|
memcpy(buf, jsstr_as_inline(str)->buf, len*sizeof(WCHAR));
|
||||||
|
}else if(jsstr_is_heap(str)) {
|
||||||
|
memcpy(buf, jsstr_as_heap(str)->buf, len*sizeof(WCHAR));
|
||||||
|
}else {
|
||||||
|
jsstr_rope_t *rope = jsstr_as_rope(str);
|
||||||
|
jsstr_flush(rope->left, buf);
|
||||||
|
jsstr_flush(rope->right, buf+jsstr_length(rope->left));
|
||||||
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline jsstr_t *jsstr_substr(jsstr_t *str, unsigned off, unsigned len)
|
static inline jsstr_t *jsstr_substr(jsstr_t *str, unsigned off, unsigned len)
|
||||||
{
|
{
|
||||||
return jsstr_alloc_len(str->str+off, len);
|
jsstr_t *ret;
|
||||||
|
WCHAR *ptr;
|
||||||
|
|
||||||
|
ptr = jsstr_alloc_buf(len, &ret);
|
||||||
|
if(ptr)
|
||||||
|
jsstr_extract(str, off, len, ptr);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int jsstr_cmp(jsstr_t*,jsstr_t*) DECLSPEC_HIDDEN;
|
int jsstr_cmp(jsstr_t*,jsstr_t*) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
static inline BOOL jsstr_eq(jsstr_t *left, jsstr_t *right)
|
||||||
|
{
|
||||||
|
return jsstr_length(left) == jsstr_length(right) && !jsstr_cmp(left, right);
|
||||||
|
}
|
||||||
|
|
||||||
jsstr_t *jsstr_concat(jsstr_t*,jsstr_t*) DECLSPEC_HIDDEN;
|
jsstr_t *jsstr_concat(jsstr_t*,jsstr_t*) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
jsstr_t *jsstr_nan(void) DECLSPEC_HIDDEN;
|
jsstr_t *jsstr_nan(void) DECLSPEC_HIDDEN;
|
||||||
jsstr_t *jsstr_empty(void) DECLSPEC_HIDDEN;
|
jsstr_t *jsstr_empty(void) DECLSPEC_HIDDEN;
|
||||||
jsstr_t *jsstr_undefined(void) DECLSPEC_HIDDEN;
|
jsstr_t *jsstr_undefined(void) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
jsstr_t *jsstr_null_bstr(void) DECLSPEC_HIDDEN;
|
||||||
|
BOOL is_null_bstr(jsstr_t*) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
BOOL init_strings(void) DECLSPEC_HIDDEN;
|
BOOL init_strings(void) DECLSPEC_HIDDEN;
|
||||||
void free_strings(void) DECLSPEC_HIDDEN;
|
void free_strings(void) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
|
|
@ -294,11 +294,13 @@ HRESULT variant_to_jsval(VARIANT *var, jsval_t *r)
|
||||||
case VT_BSTR: {
|
case VT_BSTR: {
|
||||||
jsstr_t *str;
|
jsstr_t *str;
|
||||||
|
|
||||||
str = jsstr_alloc_len(V_BSTR(var), SysStringLen(V_BSTR(var)));
|
if(V_BSTR(var)) {
|
||||||
if(!str)
|
str = jsstr_alloc_len(V_BSTR(var), SysStringLen(V_BSTR(var)));
|
||||||
return E_OUTOFMEMORY;
|
if(!str)
|
||||||
if(!V_BSTR(var))
|
return E_OUTOFMEMORY;
|
||||||
str->length_flags |= JSSTR_FLAG_NULLBSTR;
|
}else {
|
||||||
|
str = jsstr_null_bstr();
|
||||||
|
}
|
||||||
|
|
||||||
*r = jsval_string(str);
|
*r = jsval_string(str);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -351,7 +353,7 @@ HRESULT jsval_to_variant(jsval_t val, VARIANT *retv)
|
||||||
jsstr_t *str = get_string(val);
|
jsstr_t *str = get_string(val);
|
||||||
|
|
||||||
V_VT(retv) = VT_BSTR;
|
V_VT(retv) = VT_BSTR;
|
||||||
if(str->length_flags & JSSTR_FLAG_NULLBSTR) {
|
if(is_null_bstr(str)) {
|
||||||
V_BSTR(retv) = NULL;
|
V_BSTR(retv) = NULL;
|
||||||
}else {
|
}else {
|
||||||
V_BSTR(retv) = SysAllocStringLen(NULL, jsstr_length(str));
|
V_BSTR(retv) = SysAllocStringLen(NULL, jsstr_length(str));
|
||||||
|
@ -502,16 +504,15 @@ static int hex_to_int(WCHAR c)
|
||||||
/* ECMA-262 3rd Edition 9.3.1 */
|
/* ECMA-262 3rd Edition 9.3.1 */
|
||||||
static HRESULT str_to_number(jsstr_t *str, double *ret)
|
static HRESULT str_to_number(jsstr_t *str, double *ret)
|
||||||
{
|
{
|
||||||
const WCHAR *ptr = str->str;
|
const WCHAR *ptr;
|
||||||
BOOL neg = FALSE;
|
BOOL neg = FALSE;
|
||||||
DOUBLE d = 0.0;
|
DOUBLE d = 0.0;
|
||||||
|
|
||||||
static const WCHAR infinityW[] = {'I','n','f','i','n','i','t','y'};
|
static const WCHAR infinityW[] = {'I','n','f','i','n','i','t','y'};
|
||||||
|
|
||||||
if(!ptr) {
|
ptr = jsstr_flatten(str);
|
||||||
*ret = 0;
|
if(!ptr)
|
||||||
return S_OK;
|
return E_OUTOFMEMORY;
|
||||||
}
|
|
||||||
|
|
||||||
while(isspaceW(*ptr))
|
while(isspaceW(*ptr))
|
||||||
ptr++;
|
ptr++;
|
||||||
|
@ -777,6 +778,23 @@ HRESULT to_string(script_ctx_t *ctx, jsval_t val, jsstr_t **str)
|
||||||
return *str ? S_OK : E_OUTOFMEMORY;
|
return *str ? S_OK : E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT to_flat_string(script_ctx_t *ctx, jsval_t val, jsstr_t **str, const WCHAR **ret_str)
|
||||||
|
{
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
hres = to_string(ctx, val, str);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
*ret_str = jsstr_flatten(*str);
|
||||||
|
if(!*ret_str) {
|
||||||
|
jsstr_release(*str);
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* ECMA-262 3rd Edition 9.9 */
|
/* ECMA-262 3rd Edition 9.9 */
|
||||||
HRESULT to_object(script_ctx_t *ctx, jsval_t val, IDispatch **disp)
|
HRESULT to_object(script_ctx_t *ctx, jsval_t val, IDispatch **disp)
|
||||||
{
|
{
|
||||||
|
@ -897,7 +915,7 @@ HRESULT variant_change_type(script_ctx_t *ctx, VARIANT *dst, VARIANT *src, VARTY
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(str->length_flags & JSSTR_FLAG_NULLBSTR) {
|
if(is_null_bstr(str)) {
|
||||||
V_BSTR(dst) = NULL;
|
V_BSTR(dst) = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ static inline NumberInstance *number_this(vdisp_t *jsthis)
|
||||||
return is_vclass(jsthis, JSCLASS_NUMBER) ? number_from_vdisp(jsthis) : NULL;
|
return is_vclass(jsthis, JSCLASS_NUMBER) ? number_from_vdisp(jsthis) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void dtoa(double d, WCHAR *buf, int size, int *dec_point)
|
static inline void number_to_str(double d, WCHAR *buf, int size, int *dec_point)
|
||||||
{
|
{
|
||||||
ULONGLONG l;
|
ULONGLONG l;
|
||||||
int i;
|
int i;
|
||||||
|
@ -113,7 +113,7 @@ static inline jsstr_t *number_to_fixed(double val, int prec)
|
||||||
if(buf_size > NUMBER_DTOA_SIZE)
|
if(buf_size > NUMBER_DTOA_SIZE)
|
||||||
buf_size = NUMBER_DTOA_SIZE;
|
buf_size = NUMBER_DTOA_SIZE;
|
||||||
|
|
||||||
dtoa(val, buf, buf_size, &dec_point);
|
number_to_str(val, buf, buf_size, &dec_point);
|
||||||
dec_point++;
|
dec_point++;
|
||||||
size = 0;
|
size = 0;
|
||||||
if(neg)
|
if(neg)
|
||||||
|
@ -125,11 +125,10 @@ static inline jsstr_t *number_to_fixed(double val, int prec)
|
||||||
if(prec)
|
if(prec)
|
||||||
size += prec+1;
|
size += prec+1;
|
||||||
|
|
||||||
ret = jsstr_alloc_buf(size);
|
str = jsstr_alloc_buf(size, &ret);
|
||||||
if(!ret)
|
if(!ret)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
str = ret->str;
|
|
||||||
size = buf_pos = 0;
|
size = buf_pos = 0;
|
||||||
if(neg)
|
if(neg)
|
||||||
str[size++] = '-';
|
str[size++] = '-';
|
||||||
|
@ -172,7 +171,7 @@ static inline jsstr_t *number_to_exponential(double val, int prec)
|
||||||
buf_size = prec+2;
|
buf_size = prec+2;
|
||||||
if(buf_size<2 || buf_size>NUMBER_DTOA_SIZE)
|
if(buf_size<2 || buf_size>NUMBER_DTOA_SIZE)
|
||||||
buf_size = NUMBER_DTOA_SIZE;
|
buf_size = NUMBER_DTOA_SIZE;
|
||||||
dtoa(val, buf, buf_size, &dec_point);
|
number_to_str(val, buf, buf_size, &dec_point);
|
||||||
buf_size--;
|
buf_size--;
|
||||||
if(prec == -1)
|
if(prec == -1)
|
||||||
for(; buf_size>1 && buf[buf_size-1]=='0'; buf_size--)
|
for(; buf_size>1 && buf[buf_size-1]=='0'; buf_size--)
|
||||||
|
@ -193,11 +192,10 @@ static inline jsstr_t *number_to_exponential(double val, int prec)
|
||||||
if(neg)
|
if(neg)
|
||||||
size++;
|
size++;
|
||||||
|
|
||||||
ret = jsstr_alloc_buf(size);
|
str = jsstr_alloc_buf(size, &ret);
|
||||||
if(!ret)
|
if(!ret)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
str = ret->str;
|
|
||||||
size = 0;
|
size = 0;
|
||||||
pbuf = buf;
|
pbuf = buf;
|
||||||
if(neg)
|
if(neg)
|
||||||
|
|
|
@ -71,12 +71,13 @@ static HRESULT Object_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
|
||||||
|
|
||||||
if(r) {
|
if(r) {
|
||||||
jsstr_t *ret;
|
jsstr_t *ret;
|
||||||
|
WCHAR *ptr;
|
||||||
|
|
||||||
ret = jsstr_alloc_buf(9+strlenW(str));
|
ptr = jsstr_alloc_buf(9+strlenW(str), &ret);
|
||||||
if(!ret)
|
if(!ptr)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
sprintfW(ret->str, formatW, str);
|
sprintfW(ptr, formatW, str);
|
||||||
*r = jsval_string(ret);
|
*r = jsval_string(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,9 +130,14 @@ static HRESULT Object_hasOwnProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD fl
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
if(is_jsdisp(jsthis)) {
|
if(is_jsdisp(jsthis)) {
|
||||||
|
const WCHAR *name_str;
|
||||||
BOOL result;
|
BOOL result;
|
||||||
|
|
||||||
hres = jsdisp_is_own_prop(jsthis->u.jsdisp, name->str, &result);
|
name_str = jsstr_flatten(name);
|
||||||
|
if(name_str)
|
||||||
|
hres = jsdisp_is_own_prop(jsthis->u.jsdisp, name_str, &result);
|
||||||
|
else
|
||||||
|
hres = E_OUTOFMEMORY;
|
||||||
jsstr_release(name);
|
jsstr_release(name);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -163,7 +169,8 @@ static HRESULT Object_hasOwnProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD fl
|
||||||
static HRESULT Object_propertyIsEnumerable(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
static HRESULT Object_propertyIsEnumerable(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||||
jsval_t *r)
|
jsval_t *r)
|
||||||
{
|
{
|
||||||
jsstr_t *name;
|
const WCHAR *name;
|
||||||
|
jsstr_t *name_str;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
|
@ -179,12 +186,12 @@ static HRESULT Object_propertyIsEnumerable(script_ctx_t *ctx, vdisp_t *jsthis, W
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = to_string(ctx, argv[0], &name);
|
hres = to_flat_string(ctx, argv[0], &name_str, &name);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = jsdisp_is_enumerable(jsthis->u.jsdisp, name->str, &ret);
|
hres = jsdisp_is_enumerable(jsthis->u.jsdisp, name, &ret);
|
||||||
jsstr_release(name);
|
jsstr_release(name_str);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,10 +1,8 @@
|
||||||
|
/* A Bison parser, made by GNU Bison 2.5. */
|
||||||
|
|
||||||
/* A Bison parser, made by GNU Bison 2.4.1. */
|
/* Bison interface for Yacc-like parsers in C
|
||||||
|
|
||||||
/* Skeleton interface for Bison's Yacc-like parsers in C
|
Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
|
||||||
|
|
||||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
|
||||||
Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -92,8 +90,8 @@
|
||||||
typedef union YYSTYPE
|
typedef union YYSTYPE
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Line 1676 of yacc.c */
|
/* Line 2068 of yacc.c */
|
||||||
#line 145 "parser.y"
|
#line 144 "parser.y"
|
||||||
|
|
||||||
int ival;
|
int ival;
|
||||||
const WCHAR *srcptr;
|
const WCHAR *srcptr;
|
||||||
|
@ -116,8 +114,8 @@ typedef union YYSTYPE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Line 1676 of yacc.c */
|
/* Line 2068 of yacc.c */
|
||||||
#line 121 "parser.tab.h"
|
#line 119 "parser.tab.h"
|
||||||
} YYSTYPE;
|
} YYSTYPE;
|
||||||
# define YYSTYPE_IS_TRIVIAL 1
|
# define YYSTYPE_IS_TRIVIAL 1
|
||||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||||
|
|
|
@ -25,10 +25,7 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(jscript);
|
WINE_DEFAULT_DEBUG_CHANNEL(jscript);
|
||||||
|
|
||||||
#define YYLEX_PARAM ctx
|
static int parser_error(parser_ctx_t*,const char*);
|
||||||
#define YYPARSE_PARAM ctx
|
|
||||||
|
|
||||||
static int parser_error(const char*);
|
|
||||||
static void set_error(parser_ctx_t*,UINT);
|
static void set_error(parser_ctx_t*,UINT);
|
||||||
static BOOL explicit_error(parser_ctx_t*,void*,WCHAR);
|
static BOOL explicit_error(parser_ctx_t*,void*,WCHAR);
|
||||||
static BOOL allow_auto_semicolon(parser_ctx_t*);
|
static BOOL allow_auto_semicolon(parser_ctx_t*);
|
||||||
|
@ -139,7 +136,9 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%pure_parser
|
%lex-param { parser_ctx_t *ctx }
|
||||||
|
%parse-param { parser_ctx_t *ctx }
|
||||||
|
%pure-parser
|
||||||
%start Program
|
%start Program
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
|
|
|
@ -90,6 +90,22 @@ static HRESULT get_string_val(script_ctx_t *ctx, vdisp_t *jsthis, jsstr_t **val)
|
||||||
return to_string(ctx, jsval_disp(jsthis->u.disp), val);
|
return to_string(ctx, jsval_disp(jsthis->u.disp), val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT get_string_flat_val(script_ctx_t *ctx, vdisp_t *jsthis, jsstr_t **jsval, const WCHAR **val)
|
||||||
|
{
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
hres = get_string_val(ctx, jsthis, jsval);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
*val = jsstr_flatten(*jsval);
|
||||||
|
if(*val)
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
jsstr_release(*jsval);
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT String_length(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
static HRESULT String_length(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||||
jsval_t *r)
|
jsval_t *r)
|
||||||
{
|
{
|
||||||
|
@ -160,13 +176,12 @@ static HRESULT do_attributeless_tag_format(script_ctx_t *ctx, vdisp_t *jsthis, j
|
||||||
|
|
||||||
tagname_len = strlenW(tagname);
|
tagname_len = strlenW(tagname);
|
||||||
|
|
||||||
ret = jsstr_alloc_buf(jsstr_length(str) + 2*tagname_len + 5);
|
ptr = jsstr_alloc_buf(jsstr_length(str) + 2*tagname_len + 5, &ret);
|
||||||
if(!ret) {
|
if(!ret) {
|
||||||
jsstr_release(str);
|
jsstr_release(str);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = ret->str;
|
|
||||||
*ptr++ = '<';
|
*ptr++ = '<';
|
||||||
memcpy(ptr, tagname, tagname_len*sizeof(WCHAR));
|
memcpy(ptr, tagname, tagname_len*sizeof(WCHAR));
|
||||||
ptr += tagname_len;
|
ptr += tagname_len;
|
||||||
|
@ -209,11 +224,10 @@ static HRESULT do_attribute_tag_format(script_ctx_t *ctx, vdisp_t *jsthis, unsig
|
||||||
unsigned attrname_len = strlenW(attrname);
|
unsigned attrname_len = strlenW(attrname);
|
||||||
unsigned tagname_len = strlenW(tagname);
|
unsigned tagname_len = strlenW(tagname);
|
||||||
jsstr_t *ret;
|
jsstr_t *ret;
|
||||||
|
WCHAR *ptr;
|
||||||
|
|
||||||
ret = jsstr_alloc_buf(2*tagname_len + attrname_len + jsstr_length(attr_value) + jsstr_length(str) + 9);
|
ptr = jsstr_alloc_buf(2*tagname_len + attrname_len + jsstr_length(attr_value) + jsstr_length(str) + 9, &ret);
|
||||||
if(ret) {
|
if(ptr) {
|
||||||
WCHAR *ptr = ret->str;
|
|
||||||
|
|
||||||
*ptr++ = '<';
|
*ptr++ = '<';
|
||||||
memcpy(ptr, tagname, tagname_len*sizeof(WCHAR));
|
memcpy(ptr, tagname, tagname_len*sizeof(WCHAR));
|
||||||
ptr += tagname_len;
|
ptr += tagname_len;
|
||||||
|
@ -349,8 +363,11 @@ static HRESULT String_charCodeAt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
||||||
idx = d;
|
idx = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(r)
|
if(r) {
|
||||||
*r = jsval_number(str->str[idx]);
|
WCHAR c;
|
||||||
|
jsstr_extract(str, idx, 1, &c);
|
||||||
|
*r = jsval_number(c);
|
||||||
|
}
|
||||||
|
|
||||||
jsstr_release(str);
|
jsstr_release(str);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -360,52 +377,80 @@ static HRESULT String_charCodeAt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
||||||
static HRESULT String_concat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
static HRESULT String_concat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||||
jsval_t *r)
|
jsval_t *r)
|
||||||
{
|
{
|
||||||
unsigned len = 0, i, str_cnt;
|
jsstr_t *ret, *str;
|
||||||
jsstr_t **strs, *ret = NULL;
|
|
||||||
WCHAR *ptr;
|
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
str_cnt = argc+1;
|
hres = get_string_val(ctx, jsthis, &str);
|
||||||
strs = heap_alloc_zero(str_cnt * sizeof(*strs));
|
if(FAILED(hres))
|
||||||
if(!strs)
|
return hres;
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
|
|
||||||
hres = to_string(ctx, jsval_disp(jsthis->u.disp), strs);
|
switch(argc) {
|
||||||
if(SUCCEEDED(hres)) {
|
case 0:
|
||||||
|
ret = str;
|
||||||
|
break;
|
||||||
|
case 1: {
|
||||||
|
jsstr_t *arg_str;
|
||||||
|
|
||||||
|
hres = to_string(ctx, argv[0], &arg_str);
|
||||||
|
if(FAILED(hres)) {
|
||||||
|
jsstr_release(str);
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = jsstr_concat(str, arg_str);
|
||||||
|
jsstr_release(str);
|
||||||
|
if(!ret)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
const unsigned str_cnt = argc+1;
|
||||||
|
unsigned len = 0, i;
|
||||||
|
jsstr_t **strs;
|
||||||
|
WCHAR *ptr;
|
||||||
|
|
||||||
|
strs = heap_alloc_zero(str_cnt * sizeof(*strs));
|
||||||
|
if(!strs) {
|
||||||
|
jsstr_release(str);
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
strs[0] = str;
|
||||||
for(i=0; i < argc; i++) {
|
for(i=0; i < argc; i++) {
|
||||||
hres = to_string(ctx, argv[i], strs+i+1);
|
hres = to_string(ctx, argv[i], strs+i+1);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(SUCCEEDED(hres)) {
|
if(SUCCEEDED(hres)) {
|
||||||
for(i=0; i < str_cnt; i++) {
|
for(i=0; i < str_cnt; i++) {
|
||||||
len += jsstr_length(strs[i]);
|
len += jsstr_length(strs[i]);
|
||||||
if(len > JSSTR_MAX_LENGTH) {
|
if(len > JSSTR_MAX_LENGTH) {
|
||||||
hres = E_OUTOFMEMORY;
|
hres = E_OUTOFMEMORY;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(SUCCEEDED(hres)) {
|
||||||
|
ptr = jsstr_alloc_buf(len, &ret);
|
||||||
|
if(ptr) {
|
||||||
|
for(i=0; i < str_cnt; i++)
|
||||||
|
ptr += jsstr_flush(strs[i], ptr);
|
||||||
|
}else {
|
||||||
|
hres = E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = jsstr_alloc_buf(len);
|
while(i--)
|
||||||
if(ret) {
|
jsstr_release(strs[i]);
|
||||||
ptr = ret->str;
|
heap_free(strs);
|
||||||
for(i=0; i < str_cnt; i++)
|
if(FAILED(hres))
|
||||||
ptr += jsstr_flush(strs[i], ptr);
|
return hres;
|
||||||
}else {
|
}
|
||||||
hres = E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=0; i < str_cnt; i++)
|
|
||||||
jsstr_release(strs[i]);
|
|
||||||
heap_free(strs);
|
|
||||||
|
|
||||||
if(FAILED(hres))
|
|
||||||
return hres;
|
|
||||||
|
|
||||||
if(r)
|
if(r)
|
||||||
*r = jsval_string(ret);
|
*r = jsval_string(ret);
|
||||||
|
@ -442,28 +487,29 @@ static HRESULT String_fontsize(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
|
||||||
static HRESULT String_indexOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
static HRESULT String_indexOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||||
jsval_t *r)
|
jsval_t *r)
|
||||||
{
|
{
|
||||||
jsstr_t *search_str, *str;
|
jsstr_t *search_jsstr, *jsstr;
|
||||||
|
const WCHAR *search_str, *str;
|
||||||
int length, pos = 0;
|
int length, pos = 0;
|
||||||
INT ret = -1;
|
INT ret = -1;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
hres = get_string_val(ctx, jsthis, &str);
|
hres = get_string_flat_val(ctx, jsthis, &jsstr, &str);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
length = jsstr_length(str);
|
length = jsstr_length(jsstr);
|
||||||
if(!argc) {
|
if(!argc) {
|
||||||
if(r)
|
if(r)
|
||||||
*r = jsval_number(-1);
|
*r = jsval_number(-1);
|
||||||
jsstr_release(str);
|
jsstr_release(jsstr);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = to_string(ctx, argv[0], &search_str);
|
hres = to_flat_string(ctx, argv[0], &search_jsstr, &search_str);
|
||||||
if(FAILED(hres)) {
|
if(FAILED(hres)) {
|
||||||
jsstr_release(str);
|
jsstr_release(jsstr);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,15 +524,15 @@ static HRESULT String_indexOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
||||||
if(SUCCEEDED(hres)) {
|
if(SUCCEEDED(hres)) {
|
||||||
const WCHAR *ptr;
|
const WCHAR *ptr;
|
||||||
|
|
||||||
ptr = strstrW(str->str+pos, search_str->str);
|
ptr = strstrW(str+pos, search_str);
|
||||||
if(ptr)
|
if(ptr)
|
||||||
ret = ptr - str->str;
|
ret = ptr - str;
|
||||||
else
|
else
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
jsstr_release(search_str);
|
jsstr_release(search_jsstr);
|
||||||
jsstr_release(str);
|
jsstr_release(jsstr);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
|
@ -507,31 +553,32 @@ static HRESULT String_lastIndexOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
||||||
jsval_t *r)
|
jsval_t *r)
|
||||||
{
|
{
|
||||||
unsigned pos = 0, search_len, length;
|
unsigned pos = 0, search_len, length;
|
||||||
jsstr_t *search_str, *str;
|
jsstr_t *search_jsstr, *jsstr;
|
||||||
|
const WCHAR *search_str, *str;
|
||||||
INT ret = -1;
|
INT ret = -1;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
hres = get_string_val(ctx, jsthis, &str);
|
hres = get_string_flat_val(ctx, jsthis, &jsstr, &str);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
if(!argc) {
|
if(!argc) {
|
||||||
if(r)
|
if(r)
|
||||||
*r = jsval_number(-1);
|
*r = jsval_number(-1);
|
||||||
jsstr_release(str);
|
jsstr_release(jsstr);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = to_string(ctx, argv[0], &search_str);
|
hres = to_flat_string(ctx, argv[0], &search_jsstr, &search_str);
|
||||||
if(FAILED(hres)) {
|
if(FAILED(hres)) {
|
||||||
jsstr_release(str);
|
jsstr_release(jsstr);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
search_len = jsstr_length(search_str);
|
search_len = jsstr_length(search_jsstr);
|
||||||
length = jsstr_length(str);
|
length = jsstr_length(jsstr);
|
||||||
|
|
||||||
if(argc >= 2) {
|
if(argc >= 2) {
|
||||||
double d;
|
double d;
|
||||||
|
@ -546,16 +593,16 @@ static HRESULT String_lastIndexOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
||||||
if(SUCCEEDED(hres) && length >= search_len) {
|
if(SUCCEEDED(hres) && length >= search_len) {
|
||||||
const WCHAR *ptr;
|
const WCHAR *ptr;
|
||||||
|
|
||||||
for(ptr = str->str+min(pos, length-search_len); ptr >= str->str; ptr--) {
|
for(ptr = str+min(pos, length-search_len); ptr >= str; ptr--) {
|
||||||
if(!memcmp(ptr, search_str->str, search_len*sizeof(WCHAR))) {
|
if(!memcmp(ptr, search_str, search_len*sizeof(WCHAR))) {
|
||||||
ret = ptr-str->str;
|
ret = ptr-str;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jsstr_release(search_str);
|
jsstr_release(search_jsstr);
|
||||||
jsstr_release(str);
|
jsstr_release(jsstr);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
|
@ -625,36 +672,54 @@ typedef struct {
|
||||||
DWORD len;
|
DWORD len;
|
||||||
} strbuf_t;
|
} strbuf_t;
|
||||||
|
|
||||||
|
static BOOL strbuf_ensure_size(strbuf_t *buf, unsigned len)
|
||||||
|
{
|
||||||
|
WCHAR *new_buf;
|
||||||
|
DWORD new_size;
|
||||||
|
|
||||||
|
if(len <= buf->size)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
new_size = buf->size ? buf->size<<1 : 16;
|
||||||
|
if(new_size < len)
|
||||||
|
new_size = len;
|
||||||
|
if(buf->buf)
|
||||||
|
new_buf = heap_realloc(buf->buf, new_size*sizeof(WCHAR));
|
||||||
|
else
|
||||||
|
new_buf = heap_alloc(new_size*sizeof(WCHAR));
|
||||||
|
if(!new_buf)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
buf->buf = new_buf;
|
||||||
|
buf->size = new_size;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT strbuf_append(strbuf_t *buf, const WCHAR *str, DWORD len)
|
static HRESULT strbuf_append(strbuf_t *buf, const WCHAR *str, DWORD len)
|
||||||
{
|
{
|
||||||
if(!len)
|
if(!len)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
if(len + buf->len > buf->size) {
|
if(!strbuf_ensure_size(buf, buf->len+len))
|
||||||
WCHAR *new_buf;
|
return E_OUTOFMEMORY;
|
||||||
DWORD new_size;
|
|
||||||
|
|
||||||
new_size = buf->size ? buf->size<<1 : 16;
|
|
||||||
if(new_size < buf->len+len)
|
|
||||||
new_size = buf->len+len;
|
|
||||||
if(buf->buf)
|
|
||||||
new_buf = heap_realloc(buf->buf, new_size*sizeof(WCHAR));
|
|
||||||
else
|
|
||||||
new_buf = heap_alloc(new_size*sizeof(WCHAR));
|
|
||||||
if(!new_buf)
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
|
|
||||||
buf->buf = new_buf;
|
|
||||||
buf->size = new_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(buf->buf+buf->len, str, len*sizeof(WCHAR));
|
memcpy(buf->buf+buf->len, str, len*sizeof(WCHAR));
|
||||||
buf->len += len;
|
buf->len += len;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT strbuf_append_jsstr(strbuf_t *buf, jsstr_t *str)
|
||||||
|
{
|
||||||
|
if(!strbuf_ensure_size(buf, buf->len+jsstr_length(str)))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
jsstr_flush(str, buf->buf+buf->len);
|
||||||
|
buf->len += jsstr_length(str);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT rep_call(script_ctx_t *ctx, jsdisp_t *func,
|
static HRESULT rep_call(script_ctx_t *ctx, jsdisp_t *func,
|
||||||
jsstr_t *str, match_state_t *match, jsstr_t **ret)
|
jsstr_t *jsstr, const WCHAR *str, match_state_t *match, jsstr_t **ret)
|
||||||
{
|
{
|
||||||
jsval_t *argv;
|
jsval_t *argv;
|
||||||
unsigned argc;
|
unsigned argc;
|
||||||
|
@ -676,7 +741,7 @@ static HRESULT rep_call(script_ctx_t *ctx, jsdisp_t *func,
|
||||||
if(SUCCEEDED(hres)) {
|
if(SUCCEEDED(hres)) {
|
||||||
for(i=0; i < match->paren_count; i++) {
|
for(i=0; i < match->paren_count; i++) {
|
||||||
if(match->parens[i].index != -1)
|
if(match->parens[i].index != -1)
|
||||||
tmp_str = jsstr_substr(str, match->parens[i].index, match->parens[i].length);
|
tmp_str = jsstr_substr(jsstr, match->parens[i].index, match->parens[i].length);
|
||||||
else
|
else
|
||||||
tmp_str = jsstr_empty();
|
tmp_str = jsstr_empty();
|
||||||
if(!tmp_str) {
|
if(!tmp_str) {
|
||||||
|
@ -688,8 +753,8 @@ static HRESULT rep_call(script_ctx_t *ctx, jsdisp_t *func,
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SUCCEEDED(hres)) {
|
if(SUCCEEDED(hres)) {
|
||||||
argv[match->paren_count+1] = jsval_number(match->cp-str->str - match->match_len);
|
argv[match->paren_count+1] = jsval_number(match->cp-str - match->match_len);
|
||||||
argv[match->paren_count+2] = jsval_string(str);
|
argv[match->paren_count+2] = jsval_string(jsstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SUCCEEDED(hres))
|
if(SUCCEEDED(hres))
|
||||||
|
@ -711,25 +776,26 @@ static HRESULT rep_call(script_ctx_t *ctx, jsdisp_t *func,
|
||||||
static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||||
jsval_t *r)
|
jsval_t *r)
|
||||||
{
|
{
|
||||||
DWORD rep_len=0;
|
const WCHAR *str, *match_str = NULL, *rep_str = NULL;
|
||||||
jsstr_t *rep_str = NULL, *match_str = NULL, *str;
|
jsstr_t *rep_jsstr, *match_jsstr, *jsstr;
|
||||||
jsdisp_t *rep_func = NULL, *regexp = NULL;
|
jsdisp_t *rep_func = NULL, *regexp = NULL;
|
||||||
match_state_t *match = NULL, last_match = {0};
|
match_state_t *match = NULL, last_match = {0};
|
||||||
strbuf_t ret = {NULL,0,0};
|
strbuf_t ret = {NULL,0,0};
|
||||||
DWORD re_flags = REM_NO_CTX_UPDATE|REM_ALLOC_RESULT;
|
DWORD re_flags = REM_NO_CTX_UPDATE|REM_ALLOC_RESULT;
|
||||||
|
DWORD rep_len=0;
|
||||||
HRESULT hres = S_OK;
|
HRESULT hres = S_OK;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
hres = get_string_val(ctx, jsthis, &str);
|
hres = get_string_flat_val(ctx, jsthis, &jsstr, &str);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
if(!argc) {
|
if(!argc) {
|
||||||
if(r)
|
if(r)
|
||||||
*r = jsval_string(str);
|
*r = jsval_string(jsstr);
|
||||||
else
|
else
|
||||||
jsstr_release(str);
|
jsstr_release(jsstr);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -742,9 +808,9 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!regexp) {
|
if(!regexp) {
|
||||||
hres = to_string(ctx, argv[0], &match_str);
|
hres = to_flat_string(ctx, argv[0], &match_jsstr, &match_str);
|
||||||
if(FAILED(hres)) {
|
if(FAILED(hres)) {
|
||||||
jsstr_release(str);
|
jsstr_release(jsstr);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -759,18 +825,18 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!rep_func) {
|
if(!rep_func) {
|
||||||
hres = to_string(ctx, argv[1], &rep_str);
|
hres = to_flat_string(ctx, argv[1], &rep_jsstr, &rep_str);
|
||||||
if(SUCCEEDED(hres))
|
if(SUCCEEDED(hres))
|
||||||
rep_len = jsstr_length(rep_str);
|
rep_len = jsstr_length(rep_jsstr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SUCCEEDED(hres)) {
|
if(SUCCEEDED(hres)) {
|
||||||
const WCHAR *ecp = str->str;
|
const WCHAR *ecp = str;
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(regexp) {
|
if(regexp) {
|
||||||
hres = regexp_match_next(ctx, regexp, re_flags, str, &match);
|
hres = regexp_match_next(ctx, regexp, re_flags, jsstr, &match);
|
||||||
re_flags = (re_flags | REM_CHECK_GLOBAL) & (~REM_ALLOC_RESULT);
|
re_flags = (re_flags | REM_CHECK_GLOBAL) & (~REM_ALLOC_RESULT);
|
||||||
|
|
||||||
if(hres == S_FALSE) {
|
if(hres == S_FALSE) {
|
||||||
|
@ -786,13 +852,13 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
||||||
if(re_flags & REM_ALLOC_RESULT) {
|
if(re_flags & REM_ALLOC_RESULT) {
|
||||||
re_flags &= ~REM_ALLOC_RESULT;
|
re_flags &= ~REM_ALLOC_RESULT;
|
||||||
match = &last_match;
|
match = &last_match;
|
||||||
match->cp = str->str;
|
match->cp = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
match->cp = strstrW(match->cp, match_str->str);
|
match->cp = strstrW(match->cp, match_str);
|
||||||
if(!match->cp)
|
if(!match->cp)
|
||||||
break;
|
break;
|
||||||
match->match_len = jsstr_length(match_str);
|
match->match_len = jsstr_length(match_jsstr);
|
||||||
match->cp += match->match_len;
|
match->cp += match->match_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -804,16 +870,16 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
||||||
if(rep_func) {
|
if(rep_func) {
|
||||||
jsstr_t *cstr;
|
jsstr_t *cstr;
|
||||||
|
|
||||||
hres = rep_call(ctx, rep_func, str, match, &cstr);
|
hres = rep_call(ctx, rep_func, jsstr, str, match, &cstr);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
hres = strbuf_append(&ret, cstr->str, jsstr_length(cstr));
|
hres = strbuf_append_jsstr(&ret, cstr);
|
||||||
jsstr_release(cstr);
|
jsstr_release(cstr);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
break;
|
break;
|
||||||
}else if(rep_str && regexp) {
|
}else if(rep_str && regexp) {
|
||||||
const WCHAR *ptr = rep_str->str, *ptr2;
|
const WCHAR *ptr = rep_str, *ptr2;
|
||||||
|
|
||||||
while((ptr2 = strchrW(ptr, '$'))) {
|
while((ptr2 = strchrW(ptr, '$'))) {
|
||||||
hres = strbuf_append(&ret, ptr, ptr2-ptr);
|
hres = strbuf_append(&ret, ptr, ptr2-ptr);
|
||||||
|
@ -830,11 +896,11 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
||||||
ptr = ptr2+2;
|
ptr = ptr2+2;
|
||||||
break;
|
break;
|
||||||
case '`':
|
case '`':
|
||||||
hres = strbuf_append(&ret, str->str, match->cp-str->str-match->match_len);
|
hres = strbuf_append(&ret, str, match->cp-str-match->match_len);
|
||||||
ptr = ptr2+2;
|
ptr = ptr2+2;
|
||||||
break;
|
break;
|
||||||
case '\'':
|
case '\'':
|
||||||
hres = strbuf_append(&ret, ecp, (str->str+jsstr_length(str))-ecp);
|
hres = strbuf_append(&ret, ecp, (str+jsstr_length(jsstr))-ecp);
|
||||||
ptr = ptr2+2;
|
ptr = ptr2+2;
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
|
@ -859,7 +925,7 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
||||||
}
|
}
|
||||||
|
|
||||||
if(match->parens[idx-1].index != -1)
|
if(match->parens[idx-1].index != -1)
|
||||||
hres = strbuf_append(&ret, str->str+match->parens[idx-1].index,
|
hres = strbuf_append(&ret, str+match->parens[idx-1].index,
|
||||||
match->parens[idx-1].length);
|
match->parens[idx-1].length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -869,11 +935,11 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SUCCEEDED(hres))
|
if(SUCCEEDED(hres))
|
||||||
hres = strbuf_append(&ret, ptr, (rep_str->str+rep_len)-ptr);
|
hres = strbuf_append(&ret, ptr, (rep_str+rep_len)-ptr);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
break;
|
break;
|
||||||
}else if(rep_str) {
|
}else if(rep_str) {
|
||||||
hres = strbuf_append(&ret, rep_str->str, rep_len);
|
hres = strbuf_append(&ret, rep_str, rep_len);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
break;
|
break;
|
||||||
}else {
|
}else {
|
||||||
|
@ -891,28 +957,28 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SUCCEEDED(hres))
|
if(SUCCEEDED(hres))
|
||||||
hres = strbuf_append(&ret, ecp, str->str+jsstr_length(str)-ecp);
|
hres = strbuf_append(&ret, ecp, str+jsstr_length(jsstr)-ecp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rep_func)
|
if(rep_func)
|
||||||
jsdisp_release(rep_func);
|
jsdisp_release(rep_func);
|
||||||
if(rep_str)
|
if(rep_str)
|
||||||
jsstr_release(rep_str);
|
jsstr_release(rep_jsstr);
|
||||||
if(match_str)
|
if(match_str)
|
||||||
jsstr_release(match_str);
|
jsstr_release(match_jsstr);
|
||||||
if(regexp)
|
if(regexp)
|
||||||
heap_free(match);
|
heap_free(match);
|
||||||
|
|
||||||
if(SUCCEEDED(hres) && last_match.cp && regexp) {
|
if(SUCCEEDED(hres) && last_match.cp && regexp) {
|
||||||
jsstr_release(ctx->last_match);
|
jsstr_release(ctx->last_match);
|
||||||
ctx->last_match = jsstr_addref(str);
|
ctx->last_match = jsstr_addref(jsstr);
|
||||||
ctx->last_match_index = last_match.cp-str->str-last_match.match_len;
|
ctx->last_match_index = last_match.cp-str-last_match.match_len;
|
||||||
ctx->last_match_length = last_match.match_len;
|
ctx->last_match_length = last_match.match_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(regexp)
|
if(regexp)
|
||||||
jsdisp_release(regexp);
|
jsdisp_release(regexp);
|
||||||
jsstr_release(str);
|
jsstr_release(jsstr);
|
||||||
|
|
||||||
if(SUCCEEDED(hres) && r) {
|
if(SUCCEEDED(hres) && r) {
|
||||||
jsstr_t *ret_str;
|
jsstr_t *ret_str;
|
||||||
|
@ -933,20 +999,21 @@ static HRESULT String_search(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
|
||||||
jsval_t *r)
|
jsval_t *r)
|
||||||
{
|
{
|
||||||
jsdisp_t *regexp = NULL;
|
jsdisp_t *regexp = NULL;
|
||||||
jsstr_t *str;
|
const WCHAR *str;
|
||||||
|
jsstr_t *jsstr;
|
||||||
match_state_t match, *match_ptr = &match;
|
match_state_t match, *match_ptr = &match;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
hres = get_string_val(ctx, jsthis, &str);
|
hres = get_string_flat_val(ctx, jsthis, &jsstr, &str);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
if(!argc) {
|
if(!argc) {
|
||||||
if(r)
|
if(r)
|
||||||
*r = jsval_null();
|
*r = jsval_null();
|
||||||
jsstr_release(str);
|
jsstr_release(jsstr);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -961,20 +1028,20 @@ static HRESULT String_search(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
|
||||||
if(!regexp) {
|
if(!regexp) {
|
||||||
hres = create_regexp_var(ctx, argv[0], NULL, ®exp);
|
hres = create_regexp_var(ctx, argv[0], NULL, ®exp);
|
||||||
if(FAILED(hres)) {
|
if(FAILED(hres)) {
|
||||||
jsstr_release(str);
|
jsstr_release(jsstr);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match.cp = str->str;
|
match.cp = str;
|
||||||
hres = regexp_match_next(ctx, regexp, REM_RESET_INDEX|REM_NO_PARENS, str, &match_ptr);
|
hres = regexp_match_next(ctx, regexp, REM_RESET_INDEX|REM_NO_PARENS, jsstr, &match_ptr);
|
||||||
jsstr_release(str);
|
jsstr_release(jsstr);
|
||||||
jsdisp_release(regexp);
|
jsdisp_release(regexp);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
if(r)
|
if(r)
|
||||||
*r = jsval_number(hres == S_OK ? match.cp-match.match_len-str->str : -1);
|
*r = jsval_number(hres == S_OK ? match.cp-match.match_len-str : -1);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1067,10 +1134,10 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
|
||||||
{
|
{
|
||||||
match_state_t match_result, *match_ptr = &match_result;
|
match_state_t match_result, *match_ptr = &match_result;
|
||||||
DWORD length, i, match_len = 0;
|
DWORD length, i, match_len = 0;
|
||||||
const WCHAR *ptr, *ptr2;
|
const WCHAR *ptr, *ptr2, *str, *match_str = NULL;
|
||||||
unsigned limit = UINT32_MAX;
|
unsigned limit = UINT32_MAX;
|
||||||
jsdisp_t *array, *regexp = NULL;
|
jsdisp_t *array, *regexp = NULL;
|
||||||
jsstr_t *str, *match_str = NULL, *tmp_str;
|
jsstr_t *jsstr, *match_jsstr, *tmp_str;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
@ -1080,16 +1147,16 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = get_string_val(ctx, jsthis, &str);
|
hres = get_string_flat_val(ctx, jsthis, &jsstr, &str);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
length = jsstr_length(str);
|
length = jsstr_length(jsstr);
|
||||||
|
|
||||||
if(argc > 1 && !is_undefined(argv[1])) {
|
if(argc > 1 && !is_undefined(argv[1])) {
|
||||||
hres = to_uint32(ctx, argv[1], &limit);
|
hres = to_uint32(ctx, argv[1], &limit);
|
||||||
if(FAILED(hres)) {
|
if(FAILED(hres)) {
|
||||||
jsstr_release(str);
|
jsstr_release(jsstr);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1105,15 +1172,15 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!regexp) {
|
if(!regexp) {
|
||||||
hres = to_string(ctx, argv[0], &match_str);
|
hres = to_flat_string(ctx, argv[0], &match_jsstr, &match_str);
|
||||||
if(FAILED(hres)) {
|
if(FAILED(hres)) {
|
||||||
jsstr_release(str);
|
jsstr_release(jsstr);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
match_len = jsstr_length(match_str);
|
match_len = jsstr_length(match_jsstr);
|
||||||
if(!match_len) {
|
if(!match_len) {
|
||||||
jsstr_release(match_str);
|
jsstr_release(match_jsstr);
|
||||||
match_str = NULL;
|
match_str = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1121,16 +1188,16 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
|
||||||
hres = create_array(ctx, 0, &array);
|
hres = create_array(ctx, 0, &array);
|
||||||
|
|
||||||
if(SUCCEEDED(hres)) {
|
if(SUCCEEDED(hres)) {
|
||||||
ptr = str->str;
|
ptr = str;
|
||||||
match_result.cp = str->str;
|
match_result.cp = str;
|
||||||
for(i=0; i<limit; i++) {
|
for(i=0; i<limit; i++) {
|
||||||
if(regexp) {
|
if(regexp) {
|
||||||
hres = regexp_match_next(ctx, regexp, REM_NO_PARENS, str, &match_ptr);
|
hres = regexp_match_next(ctx, regexp, REM_NO_PARENS, jsstr, &match_ptr);
|
||||||
if(hres != S_OK)
|
if(hres != S_OK)
|
||||||
break;
|
break;
|
||||||
ptr2 = match_result.cp - match_result.match_len;
|
ptr2 = match_result.cp - match_result.match_len;
|
||||||
}else if(match_str) {
|
}else if(match_str) {
|
||||||
ptr2 = strstrW(ptr, match_str->str);
|
ptr2 = strstrW(ptr, match_str);
|
||||||
if(!ptr2)
|
if(!ptr2)
|
||||||
break;
|
break;
|
||||||
}else {
|
}else {
|
||||||
|
@ -1160,7 +1227,7 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SUCCEEDED(hres) && (match_str || regexp) && i<limit) {
|
if(SUCCEEDED(hres) && (match_str || regexp) && i<limit) {
|
||||||
DWORD len = (str->str+length) - ptr;
|
DWORD len = (str+length) - ptr;
|
||||||
|
|
||||||
if(len || match_str) {
|
if(len || match_str) {
|
||||||
tmp_str = jsstr_alloc_len(ptr, len);
|
tmp_str = jsstr_alloc_len(ptr, len);
|
||||||
|
@ -1177,8 +1244,8 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
|
||||||
if(regexp)
|
if(regexp)
|
||||||
jsdisp_release(regexp);
|
jsdisp_release(regexp);
|
||||||
if(match_str)
|
if(match_str)
|
||||||
jsstr_release(match_str);
|
jsstr_release(match_jsstr);
|
||||||
jsstr_release(str);
|
jsstr_release(jsstr);
|
||||||
|
|
||||||
if(SUCCEEDED(hres) && r)
|
if(SUCCEEDED(hres) && r)
|
||||||
*r = jsval_obj(array);
|
*r = jsval_obj(array);
|
||||||
|
@ -1337,15 +1404,16 @@ static HRESULT String_toLowerCase(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
||||||
|
|
||||||
if(r) {
|
if(r) {
|
||||||
jsstr_t *ret;
|
jsstr_t *ret;
|
||||||
|
WCHAR *buf;
|
||||||
|
|
||||||
ret = jsstr_alloc_buf(jsstr_length(str));
|
buf = jsstr_alloc_buf(jsstr_length(str), &ret);
|
||||||
if(!ret) {
|
if(!buf) {
|
||||||
jsstr_release(str);
|
jsstr_release(str);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
jsstr_flush(str, ret->str);
|
jsstr_flush(str, buf);
|
||||||
strlwrW(ret->str);
|
strlwrW(buf);
|
||||||
*r = jsval_string(ret);
|
*r = jsval_string(ret);
|
||||||
}
|
}
|
||||||
jsstr_release(str);
|
jsstr_release(str);
|
||||||
|
@ -1366,15 +1434,16 @@ static HRESULT String_toUpperCase(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
||||||
|
|
||||||
if(r) {
|
if(r) {
|
||||||
jsstr_t *ret;
|
jsstr_t *ret;
|
||||||
|
WCHAR *buf;
|
||||||
|
|
||||||
ret = jsstr_alloc_buf(jsstr_length(str));
|
buf = jsstr_alloc_buf(jsstr_length(str), &ret);
|
||||||
if(!ret) {
|
if(!buf) {
|
||||||
jsstr_release(str);
|
jsstr_release(str);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
jsstr_flush(str, ret->str);
|
jsstr_flush(str, buf);
|
||||||
struprW(ret->str);
|
struprW(buf);
|
||||||
*r = jsval_string(ret);
|
*r = jsval_string(ret);
|
||||||
}
|
}
|
||||||
jsstr_release(str);
|
jsstr_release(str);
|
||||||
|
@ -1525,14 +1594,15 @@ static const builtin_info_t StringInst_info = {
|
||||||
static HRESULT StringConstr_fromCharCode(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
static HRESULT StringConstr_fromCharCode(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
||||||
unsigned argc, jsval_t *argv, jsval_t *r)
|
unsigned argc, jsval_t *argv, jsval_t *r)
|
||||||
{
|
{
|
||||||
|
WCHAR *ret_str;
|
||||||
DWORD i, code;
|
DWORD i, code;
|
||||||
jsstr_t *ret;
|
jsstr_t *ret;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
ret = jsstr_alloc_buf(argc);
|
ret_str = jsstr_alloc_buf(argc, &ret);
|
||||||
if(!ret)
|
if(!ret_str)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
for(i=0; i<argc; i++) {
|
for(i=0; i<argc; i++) {
|
||||||
|
@ -1542,7 +1612,7 @@ static HRESULT StringConstr_fromCharCode(script_ctx_t *ctx, vdisp_t *jsthis, WOR
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret->str[i] = code;
|
ret_str[i] = code;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(r)
|
if(r)
|
||||||
|
|
|
@ -91,7 +91,7 @@ reactos/dll/win32/inseng # Synced to Wine-1.7.1
|
||||||
reactos/dll/win32/iphlpapi # Out of sync
|
reactos/dll/win32/iphlpapi # Out of sync
|
||||||
reactos/dll/win32/itircl # Synced to Wine-1.7.1
|
reactos/dll/win32/itircl # Synced to Wine-1.7.1
|
||||||
reactos/dll/win32/itss # Synced to Wine-1.7.1
|
reactos/dll/win32/itss # Synced to Wine-1.7.1
|
||||||
reactos/dll/win32/jscript # Synced to Wine-1.5.26
|
reactos/dll/win32/jscript # Synced to Wine-1.7.1
|
||||||
reactos/dll/win32/loadperf # Synced to Wine-1.5.19
|
reactos/dll/win32/loadperf # Synced to Wine-1.5.19
|
||||||
reactos/dll/win32/localspl # Synced to Wine-1.5.26
|
reactos/dll/win32/localspl # Synced to Wine-1.5.26
|
||||||
reactos/dll/win32/localui # Synced to Wine-1.5.19
|
reactos/dll/win32/localui # Synced to Wine-1.5.19
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue