mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 17:34:06 +00:00
jscript: Use custom string container instead of BSTR.
This commit is contained in:
parent
f8e1550ebb
commit
7f1e3300fe
|
@ -15,6 +15,7 @@ C_SRCS = \
|
|||
global.c \
|
||||
jscript.c \
|
||||
jscript_main.c \
|
||||
jsstr.c \
|
||||
jsutils.c \
|
||||
lex.c \
|
||||
math.c \
|
||||
|
|
|
@ -141,9 +141,9 @@ 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,
|
||||
jsval_t *r)
|
||||
{
|
||||
jsstr_t * progid;
|
||||
IDispatch *disp;
|
||||
IUnknown *obj;
|
||||
BSTR progid;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
@ -168,8 +168,8 @@ static HRESULT ActiveXObject_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
obj = create_activex_object(ctx, progid);
|
||||
SysFreeString(progid);
|
||||
obj = create_activex_object(ctx, progid->str);
|
||||
jsstr_release(progid);
|
||||
if(!obj)
|
||||
return throw_generic_error(ctx, JS_E_CANNOT_CREATE_OBJ, NULL);
|
||||
|
||||
|
|
|
@ -234,22 +234,18 @@ 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)
|
||||
{
|
||||
BSTR *str_tab, ret = NULL;
|
||||
jsstr_t **str_tab, *ret = NULL;
|
||||
jsval_t val;
|
||||
DWORD i;
|
||||
HRESULT hres = E_FAIL;
|
||||
|
||||
if(!length) {
|
||||
if(r) {
|
||||
BSTR ret = SysAllocStringLen(NULL, 0);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
*r = jsval_string(ret);
|
||||
}
|
||||
if(r)
|
||||
*r = jsval_string(jsstr_empty());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
str_tab = heap_alloc_zero(length * sizeof(BSTR));
|
||||
str_tab = heap_alloc_zero(length * sizeof(*str_tab));
|
||||
if(!str_tab)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
|
@ -276,20 +272,30 @@ static HRESULT array_join(script_ctx_t *ctx, jsdisp_t *array, DWORD length, cons
|
|||
seplen = strlenW(sep);
|
||||
|
||||
if(str_tab[0])
|
||||
len = SysStringLen(str_tab[0]);
|
||||
for(i=1; i < length; i++)
|
||||
len += seplen + SysStringLen(str_tab[i]);
|
||||
len = jsstr_length(str_tab[0]);
|
||||
for(i=1; i < length; i++) {
|
||||
len += seplen;
|
||||
if(str_tab[i])
|
||||
len += jsstr_length(str_tab[i]);
|
||||
if(len > JSSTR_MAX_LENGTH) {
|
||||
hres = E_OUTOFMEMORY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret = SysAllocStringLen(NULL, len);
|
||||
if(SUCCEEDED(hres))
|
||||
ret = jsstr_alloc_buf(len);
|
||||
if(ret) {
|
||||
DWORD tmplen = 0;
|
||||
unsigned tmplen;
|
||||
|
||||
ptr = ret->str;
|
||||
|
||||
if(str_tab[0]) {
|
||||
tmplen = SysStringLen(str_tab[0]);
|
||||
memcpy(ret, str_tab[0], tmplen*sizeof(WCHAR));
|
||||
tmplen = jsstr_length(str_tab[0]);
|
||||
memcpy(ptr, str_tab[0]->str, tmplen*sizeof(WCHAR));
|
||||
ptr += tmplen;
|
||||
}
|
||||
|
||||
ptr = ret + tmplen;
|
||||
for(i=1; i < length; i++) {
|
||||
if(seplen) {
|
||||
memcpy(ptr, sep, seplen*sizeof(WCHAR));
|
||||
|
@ -297,8 +303,8 @@ static HRESULT array_join(script_ctx_t *ctx, jsdisp_t *array, DWORD length, cons
|
|||
}
|
||||
|
||||
if(str_tab[i]) {
|
||||
tmplen = SysStringLen(str_tab[i]);
|
||||
memcpy(ptr, str_tab[i], tmplen*sizeof(WCHAR));
|
||||
tmplen = jsstr_length(str_tab[i]);
|
||||
memcpy(ptr, str_tab[i]->str, tmplen*sizeof(WCHAR));
|
||||
ptr += tmplen;
|
||||
}
|
||||
}
|
||||
|
@ -308,26 +314,20 @@ static HRESULT array_join(script_ctx_t *ctx, jsdisp_t *array, DWORD length, cons
|
|||
}
|
||||
}
|
||||
|
||||
for(i=0; i < length; i++)
|
||||
SysFreeString(str_tab[i]);
|
||||
for(i=0; i < length; i++) {
|
||||
if(str_tab[i])
|
||||
jsstr_release(str_tab[i]);
|
||||
}
|
||||
heap_free(str_tab);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
TRACE("= %s\n", debugstr_w(ret));
|
||||
|
||||
if(r) {
|
||||
if(!ret) {
|
||||
ret = SysAllocStringLen(NULL, 0);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
*r = jsval_string(ret);
|
||||
}else {
|
||||
SysFreeString(ret);
|
||||
}
|
||||
TRACE("= %s\n", debugstr_jsstr(ret));
|
||||
|
||||
if(r)
|
||||
*r = ret ? jsval_string(ret) : jsval_string(jsstr_empty());
|
||||
else
|
||||
jsstr_release(ret);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -346,15 +346,15 @@ static HRESULT Array_join(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigne
|
|||
return hres;
|
||||
|
||||
if(argc) {
|
||||
BSTR sep;
|
||||
jsstr_t *sep;
|
||||
|
||||
hres = to_string(ctx, argv[0], &sep);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = array_join(ctx, jsthis, length, sep, r);
|
||||
hres = array_join(ctx, jsthis, length, sep->str, r);
|
||||
|
||||
SysFreeString(sep);
|
||||
jsstr_release(sep);
|
||||
}else {
|
||||
hres = array_join(ctx, jsthis, length, default_separatorW, r);
|
||||
}
|
||||
|
@ -653,7 +653,7 @@ static HRESULT sort_cmp(script_ctx_t *ctx, jsdisp_t *cmp_func, jsval_t v1, jsval
|
|||
else
|
||||
*cmp = d < -0.0 ? -1 : 0;
|
||||
}else {
|
||||
BSTR x, y;
|
||||
jsstr_t *x, *y;
|
||||
|
||||
hres = to_string(ctx, v1, &x);
|
||||
if(FAILED(hres))
|
||||
|
@ -661,10 +661,10 @@ static HRESULT sort_cmp(script_ctx_t *ctx, jsdisp_t *cmp_func, jsval_t v1, jsval
|
|||
|
||||
hres = to_string(ctx, v2, &y);
|
||||
if(SUCCEEDED(hres)) {
|
||||
*cmp = strcmpW(x, y);
|
||||
SysFreeString(y);
|
||||
*cmp = jsstr_cmp(x, y);
|
||||
jsstr_release(y);
|
||||
}
|
||||
SysFreeString(x);
|
||||
jsstr_release(x);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}
|
||||
|
|
|
@ -51,11 +51,9 @@ static HRESULT Bool_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
|
|||
return throw_type_error(ctx, JS_E_BOOLEAN_EXPECTED, NULL);
|
||||
|
||||
if(r) {
|
||||
BSTR val;
|
||||
|
||||
if(bool->val) val = SysAllocString(trueW);
|
||||
else val = SysAllocString(falseW);
|
||||
jsstr_t *val;
|
||||
|
||||
val = jsstr_alloc(bool->val ? trueW : falseW);
|
||||
if(!val)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
|
|
|
@ -766,8 +766,18 @@ static HRESULT literal_as_bstr(compiler_ctx_t *ctx, literal_t *literal, BSTR *st
|
|||
case LT_STRING:
|
||||
*str = compiler_alloc_bstr(ctx, literal->u.wstr);
|
||||
break;
|
||||
case LT_DOUBLE:
|
||||
return double_to_bstr(literal->u.dval, str);
|
||||
case LT_DOUBLE: {
|
||||
jsstr_t *jsstr;
|
||||
HRESULT hres;
|
||||
|
||||
hres = double_to_string(literal->u.dval, &jsstr);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
*str = SysAllocStringLen(jsstr->str, jsstr_length(jsstr));
|
||||
jsstr_release(jsstr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
|
|
@ -467,7 +467,6 @@ static SYSTEMTIME create_systemtime(DOUBLE time)
|
|||
|
||||
static inline HRESULT date_to_string(DOUBLE time, BOOL show_offset, int offset, jsval_t *r)
|
||||
{
|
||||
static const WCHAR NaNW[] = { 'N','a','N',0 };
|
||||
static const WCHAR formatW[] = { '%','s',' ','%','s',' ','%','d',' ',
|
||||
'%','0','2','d',':','%','0','2','d',':','%','0','2','d',' ',
|
||||
'U','T','C','%','c','%','0','2','d','%','0','2','d',' ','%','d','%','s',0 };
|
||||
|
@ -492,18 +491,14 @@ static inline HRESULT date_to_string(DOUBLE time, BOOL show_offset, int offset,
|
|||
|
||||
BOOL formatAD = TRUE;
|
||||
BSTR week, month;
|
||||
BSTR date_str;
|
||||
jsstr_t *date_str;
|
||||
int len, size, year, day;
|
||||
DWORD lcid_en, week_id, month_id;
|
||||
WCHAR sign = '-';
|
||||
|
||||
if(isnan(time)) {
|
||||
if(r) {
|
||||
BSTR ret = SysAllocString(NaNW);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
*r = jsval_string(ret);
|
||||
}
|
||||
if(r)
|
||||
*r = jsval_string(jsstr_nan());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -559,7 +554,7 @@ static inline HRESULT date_to_string(DOUBLE time, BOOL show_offset, int offset,
|
|||
offset = -offset;
|
||||
}
|
||||
|
||||
date_str = SysAllocStringLen(NULL, len);
|
||||
date_str = jsstr_alloc_buf(len);
|
||||
if(!date_str) {
|
||||
SysFreeString(week);
|
||||
SysFreeString(month);
|
||||
|
@ -567,16 +562,16 @@ static inline HRESULT date_to_string(DOUBLE time, BOOL show_offset, int offset,
|
|||
}
|
||||
|
||||
if(!show_offset)
|
||||
sprintfW(date_str, formatNoOffsetW, week, month, day,
|
||||
sprintfW(date_str->str, formatNoOffsetW, week, month, day,
|
||||
(int)hour_from_time(time), (int)min_from_time(time),
|
||||
(int)sec_from_time(time), year, formatAD?ADW:BCW);
|
||||
else if(offset)
|
||||
sprintfW(date_str, formatW, week, month, day,
|
||||
sprintfW(date_str->str, formatW, week, month, day,
|
||||
(int)hour_from_time(time), (int)min_from_time(time),
|
||||
(int)sec_from_time(time), sign, offset/60, offset%60,
|
||||
year, formatAD?ADW:BCW);
|
||||
else
|
||||
sprintfW(date_str, formatUTCW, week, month, day,
|
||||
sprintfW(date_str->str, formatUTCW, week, month, day,
|
||||
(int)hour_from_time(time), (int)min_from_time(time),
|
||||
(int)sec_from_time(time), year, formatAD?ADW:BCW);
|
||||
|
||||
|
@ -617,10 +612,9 @@ static HRESULT Date_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
|
|||
static HRESULT Date_toLocaleString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||
jsval_t *r)
|
||||
{
|
||||
static const WCHAR NaNW[] = { 'N','a','N',0 };
|
||||
SYSTEMTIME st;
|
||||
DateInstance *date;
|
||||
BSTR date_str;
|
||||
jsstr_t *date_str;
|
||||
int date_len, time_len;
|
||||
|
||||
TRACE("\n");
|
||||
|
@ -629,12 +623,8 @@ static HRESULT Date_toLocaleString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
|
|||
return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
|
||||
|
||||
if(isnan(date->time)) {
|
||||
if(r) {
|
||||
BSTR ret = SysAllocString(NaNW);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
*r = jsval_string(ret);
|
||||
}
|
||||
if(r)
|
||||
*r = jsval_string(jsstr_nan());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -646,12 +636,12 @@ static HRESULT Date_toLocaleString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
|
|||
if(r) {
|
||||
date_len = GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, NULL, 0);
|
||||
time_len = GetTimeFormatW(ctx->lcid, 0, &st, NULL, NULL, 0);
|
||||
date_str = SysAllocStringLen(NULL, date_len+time_len-1);
|
||||
date_str = jsstr_alloc_buf(date_len+time_len-1);
|
||||
if(!date_str)
|
||||
return E_OUTOFMEMORY;
|
||||
GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, date_str, date_len);
|
||||
GetTimeFormatW(ctx->lcid, 0, &st, NULL, &date_str[date_len], time_len);
|
||||
date_str[date_len-1] = ' ';
|
||||
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);
|
||||
date_str->str[date_len-1] = ' ';
|
||||
|
||||
*r = jsval_string(date_str);
|
||||
}
|
||||
|
@ -675,7 +665,6 @@ static HRESULT Date_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
|
|||
|
||||
static inline HRESULT create_utc_string(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r)
|
||||
{
|
||||
static const WCHAR NaNW[] = { 'N','a','N',0 };
|
||||
static const WCHAR formatADW[] = { '%','s',',',' ','%','d',' ','%','s',' ','%','d',' ',
|
||||
'%','0','2','d',':','%','0','2','d',':','%','0','2','d',' ','U','T','C',0 };
|
||||
static const WCHAR formatBCW[] = { '%','s',',',' ','%','d',' ','%','s',' ','%','d',' ','B','.','C','.',' ',
|
||||
|
@ -694,7 +683,7 @@ static inline HRESULT create_utc_string(script_ctx_t *ctx, vdisp_t *jsthis, jsva
|
|||
BOOL formatAD = TRUE;
|
||||
BSTR week, month;
|
||||
DateInstance *date;
|
||||
BSTR date_str;
|
||||
jsstr_t *date_str;
|
||||
int len, size, year, day;
|
||||
DWORD lcid_en, week_id, month_id;
|
||||
|
||||
|
@ -702,12 +691,8 @@ static inline HRESULT create_utc_string(script_ctx_t *ctx, vdisp_t *jsthis, jsva
|
|||
return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
|
||||
|
||||
if(isnan(date->time)) {
|
||||
if(r) {
|
||||
BSTR ret = SysAllocString(NaNW);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
*r = jsval_string(ret);
|
||||
}
|
||||
if(r)
|
||||
*r = jsval_string(jsstr_nan());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -756,13 +741,13 @@ static inline HRESULT create_utc_string(script_ctx_t *ctx, vdisp_t *jsthis, jsva
|
|||
} while(day);
|
||||
day = date_from_time(date->time);
|
||||
|
||||
date_str = SysAllocStringLen(NULL, len);
|
||||
date_str = jsstr_alloc_buf(len);
|
||||
if(!date_str) {
|
||||
SysFreeString(week);
|
||||
SysFreeString(month);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
sprintfW(date_str, formatAD?formatADW:formatBCW, week, day, month, year,
|
||||
sprintfW(date_str->str, formatAD?formatADW:formatBCW, week, day, month, year,
|
||||
(int)hour_from_time(date->time), (int)min_from_time(date->time),
|
||||
(int)sec_from_time(date->time));
|
||||
|
||||
|
@ -792,7 +777,6 @@ static HRESULT Date_toGMTString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
|||
/* ECMA-262 3rd Edition 15.9.5.3 */
|
||||
static HRESULT dateobj_to_date_string(DateInstance *date, jsval_t *r)
|
||||
{
|
||||
static const WCHAR NaNW[] = { 'N','a','N',0 };
|
||||
static const WCHAR formatADW[] = { '%','s',' ','%','s',' ','%','d',' ','%','d',0 };
|
||||
static const WCHAR formatBCW[] = { '%','s',' ','%','s',' ','%','d',' ','%','d',' ','B','.','C','.',0 };
|
||||
|
||||
|
@ -808,18 +792,14 @@ static HRESULT dateobj_to_date_string(DateInstance *date, jsval_t *r)
|
|||
|
||||
BOOL formatAD = TRUE;
|
||||
BSTR week, month;
|
||||
BSTR date_str;
|
||||
jsstr_t *date_str;
|
||||
DOUBLE time;
|
||||
int len, size, year, day;
|
||||
DWORD lcid_en, week_id, month_id;
|
||||
|
||||
if(isnan(date->time)) {
|
||||
if(r) {
|
||||
BSTR ret = SysAllocString(NaNW);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
*r = jsval_string(ret);
|
||||
}
|
||||
if(r)
|
||||
*r = jsval_string(jsstr_nan());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -870,13 +850,13 @@ static HRESULT dateobj_to_date_string(DateInstance *date, jsval_t *r)
|
|||
} while(day);
|
||||
day = date_from_time(time);
|
||||
|
||||
date_str = SysAllocStringLen(NULL, len);
|
||||
date_str = jsstr_alloc_buf(len);
|
||||
if(!date_str) {
|
||||
SysFreeString(week);
|
||||
SysFreeString(month);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
sprintfW(date_str, formatAD?formatADW:formatBCW, week, month, day, year);
|
||||
sprintfW(date_str->str, formatAD?formatADW:formatBCW, week, month, day, year);
|
||||
|
||||
SysFreeString(week);
|
||||
SysFreeString(month);
|
||||
|
@ -901,13 +881,12 @@ static HRESULT Date_toDateString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
|||
static HRESULT Date_toTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||
jsval_t *r)
|
||||
{
|
||||
static const WCHAR NaNW[] = { 'N','a','N',0 };
|
||||
static const WCHAR formatW[] = { '%','0','2','d',':','%','0','2','d',':','%','0','2','d',
|
||||
' ','U','T','C','%','c','%','0','2','d','%','0','2','d',0 };
|
||||
static const WCHAR formatUTCW[] = { '%','0','2','d',':','%','0','2','d',
|
||||
':','%','0','2','d',' ','U','T','C',0 };
|
||||
DateInstance *date;
|
||||
BSTR date_str;
|
||||
jsstr_t *date_str;
|
||||
DOUBLE time;
|
||||
WCHAR sign;
|
||||
int offset;
|
||||
|
@ -918,18 +897,15 @@ static HRESULT Date_toTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
|||
return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
|
||||
|
||||
if(isnan(date->time)) {
|
||||
if(r) {
|
||||
BSTR ret = SysAllocString(NaNW);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
*r = jsval_string(ret);
|
||||
}
|
||||
if(r)
|
||||
*r = jsval_string(jsstr_nan());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
time = local_time(date->time, date);
|
||||
|
||||
if(r) {
|
||||
date_str = SysAllocStringLen(NULL, 17);
|
||||
date_str = jsstr_alloc_buf(17);
|
||||
if(!date_str)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
|
@ -943,11 +919,11 @@ static HRESULT Date_toTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
|||
else sign = '-';
|
||||
|
||||
if(offset)
|
||||
sprintfW(date_str, formatW, (int)hour_from_time(time),
|
||||
sprintfW(date_str->str, formatW, (int)hour_from_time(time),
|
||||
(int)min_from_time(time), (int)sec_from_time(time),
|
||||
sign, offset/60, offset%60);
|
||||
else
|
||||
sprintfW(date_str, formatUTCW, (int)hour_from_time(time),
|
||||
sprintfW(date_str->str, formatUTCW, (int)hour_from_time(time),
|
||||
(int)min_from_time(time), (int)sec_from_time(time));
|
||||
|
||||
*r = jsval_string(date_str);
|
||||
|
@ -959,10 +935,9 @@ static HRESULT Date_toTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
|||
static HRESULT Date_toLocaleDateString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||
jsval_t *r)
|
||||
{
|
||||
static const WCHAR NaNW[] = { 'N','a','N',0 };
|
||||
SYSTEMTIME st;
|
||||
DateInstance *date;
|
||||
BSTR date_str;
|
||||
jsstr_t *date_str;
|
||||
int len;
|
||||
|
||||
TRACE("\n");
|
||||
|
@ -971,12 +946,8 @@ static HRESULT Date_toLocaleDateString(script_ctx_t *ctx, vdisp_t *jsthis, WORD
|
|||
return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
|
||||
|
||||
if(isnan(date->time)) {
|
||||
if(r) {
|
||||
BSTR ret = SysAllocString(NaNW);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
*r = jsval_string(ret);
|
||||
}
|
||||
if(r)
|
||||
*r = jsval_string(jsstr_nan());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -987,10 +958,10 @@ static HRESULT Date_toLocaleDateString(script_ctx_t *ctx, vdisp_t *jsthis, WORD
|
|||
|
||||
if(r) {
|
||||
len = GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, NULL, 0);
|
||||
date_str = SysAllocStringLen(NULL, len);
|
||||
date_str = jsstr_alloc_buf(len);
|
||||
if(!date_str)
|
||||
return E_OUTOFMEMORY;
|
||||
GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, date_str, len);
|
||||
GetDateFormatW(ctx->lcid, DATE_LONGDATE, &st, NULL, date_str->str, len);
|
||||
|
||||
*r = jsval_string(date_str);
|
||||
}
|
||||
|
@ -1001,10 +972,9 @@ static HRESULT Date_toLocaleDateString(script_ctx_t *ctx, vdisp_t *jsthis, WORD
|
|||
static HRESULT Date_toLocaleTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||
jsval_t *r)
|
||||
{
|
||||
static const WCHAR NaNW[] = { 'N','a','N',0 };
|
||||
SYSTEMTIME st;
|
||||
DateInstance *date;
|
||||
BSTR date_str;
|
||||
jsstr_t *date_str;
|
||||
int len;
|
||||
|
||||
TRACE("\n");
|
||||
|
@ -1013,12 +983,8 @@ static HRESULT Date_toLocaleTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD
|
|||
return throw_type_error(ctx, JS_E_DATE_EXPECTED, NULL);
|
||||
|
||||
if(isnan(date->time)) {
|
||||
if(r) {
|
||||
BSTR ret = SysAllocString(NaNW);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
*r = jsval_string(ret);
|
||||
}
|
||||
if(r)
|
||||
*r = jsval_string(jsstr_nan());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -1029,10 +995,10 @@ static HRESULT Date_toLocaleTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD
|
|||
|
||||
if(r) {
|
||||
len = GetTimeFormatW(ctx->lcid, 0, &st, NULL, NULL, 0);
|
||||
date_str = SysAllocStringLen(NULL, len);
|
||||
date_str = jsstr_alloc_buf(len);
|
||||
if(!date_str)
|
||||
return E_OUTOFMEMORY;
|
||||
GetTimeFormatW(ctx->lcid, 0, &st, NULL, date_str, len);
|
||||
GetTimeFormatW(ctx->lcid, 0, &st, NULL, date_str->str, len);
|
||||
|
||||
*r = jsval_string(date_str);
|
||||
}
|
||||
|
@ -2099,7 +2065,7 @@ static HRESULT create_date(script_ctx_t *ctx, jsdisp_t *object_prototype, DOUBLE
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static inline HRESULT date_parse(BSTR input, double *ret) {
|
||||
static inline HRESULT date_parse(jsstr_t *input_str, double *ret) {
|
||||
static const DWORD string_ids[] = { LOCALE_SMONTHNAME12, LOCALE_SMONTHNAME11,
|
||||
LOCALE_SMONTHNAME10, LOCALE_SMONTHNAME9, LOCALE_SMONTHNAME8,
|
||||
LOCALE_SMONTHNAME7, LOCALE_SMONTHNAME6, LOCALE_SMONTHNAME5,
|
||||
|
@ -2117,10 +2083,13 @@ static inline HRESULT date_parse(BSTR input, double *ret) {
|
|||
BOOL set_offset = FALSE, set_era = FALSE, ad = TRUE, set_am = FALSE, am = TRUE;
|
||||
BOOL set_hour_adjust = TRUE;
|
||||
TIME_ZONE_INFORMATION tzi;
|
||||
const WCHAR *input;
|
||||
DateInstance di;
|
||||
DWORD lcid_en;
|
||||
|
||||
input_len = SysStringLen(input);
|
||||
input_len = jsstr_length(input_str);
|
||||
input = input_str->str;
|
||||
|
||||
for(i=0; i<input_len; i++) {
|
||||
if(input[i] == '(') nest_level++;
|
||||
else if(input[i] == ')') {
|
||||
|
@ -2363,7 +2332,7 @@ static inline HRESULT date_parse(BSTR input, double *ret) {
|
|||
static HRESULT DateConstr_parse(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||
jsval_t *r)
|
||||
{
|
||||
BSTR parse_str;
|
||||
jsstr_t *parse_str;
|
||||
double n;
|
||||
HRESULT hres;
|
||||
|
||||
|
@ -2380,7 +2349,7 @@ static HRESULT DateConstr_parse(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
|||
return hres;
|
||||
|
||||
hres = date_parse(parse_str, &n);
|
||||
SysFreeString(parse_str);
|
||||
jsstr_release(parse_str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
|
|
@ -467,6 +467,8 @@ static HRESULT prop_put(jsdisp_t *This, dispex_prop_t *prop, jsval_t val, IServi
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
TRACE("%s = %s\n", debugstr_w(prop->name), debugstr_jsval(val));
|
||||
|
||||
hres = jsval_copy(val, &prop->u.val);
|
||||
if(FAILED(hres)) {
|
||||
prop->u.val = jsval_undefined();
|
||||
|
@ -1408,7 +1410,7 @@ HRESULT jsdisp_delete_idx(jsdisp_t *obj, DWORD idx)
|
|||
return delete_prop(prop);
|
||||
}
|
||||
|
||||
HRESULT jsdisp_is_own_prop(jsdisp_t *obj, BSTR name, BOOL *ret)
|
||||
HRESULT jsdisp_is_own_prop(jsdisp_t *obj, const WCHAR *name, BOOL *ret)
|
||||
{
|
||||
dispex_prop_t *prop;
|
||||
HRESULT hres;
|
||||
|
|
|
@ -72,9 +72,9 @@ static HRESULT stack_push(exec_ctx_t *ctx, jsval_t v)
|
|||
|
||||
static inline HRESULT stack_push_string(exec_ctx_t *ctx, const WCHAR *str)
|
||||
{
|
||||
BSTR v;
|
||||
jsstr_t *v;
|
||||
|
||||
v = SysAllocString(str);
|
||||
v = jsstr_alloc(str);
|
||||
if(!v)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
|
@ -332,23 +332,37 @@ void exec_release(exec_ctx_t *ctx)
|
|||
heap_free(ctx);
|
||||
}
|
||||
|
||||
static HRESULT disp_get_id(script_ctx_t *ctx, IDispatch *disp, BSTR name, DWORD flags, DISPID *id)
|
||||
static HRESULT disp_get_id(script_ctx_t *ctx, IDispatch *disp, WCHAR *name, BSTR name_bstr, DWORD flags, DISPID *id)
|
||||
{
|
||||
IDispatchEx *dispex;
|
||||
jsdisp_t *jsdisp;
|
||||
HRESULT hres;
|
||||
|
||||
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
|
||||
if(FAILED(hres)) {
|
||||
TRACE("using IDispatch\n");
|
||||
|
||||
*id = 0;
|
||||
return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id);
|
||||
jsdisp = iface_to_jsdisp((IUnknown*)disp);
|
||||
if(jsdisp) {
|
||||
hres = jsdisp_get_id(jsdisp, name, flags, id);
|
||||
jsdisp_release(jsdisp);
|
||||
return hres;
|
||||
}
|
||||
|
||||
*id = 0;
|
||||
hres = IDispatchEx_GetDispID(dispex, name, make_grfdex(ctx, flags|fdexNameCaseSensitive), id);
|
||||
IDispatchEx_Release(dispex);
|
||||
return hres;
|
||||
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
|
||||
if(SUCCEEDED(hres)) {
|
||||
BSTR str = name_bstr;
|
||||
|
||||
if(!str)
|
||||
str = SysAllocString(name);
|
||||
if(str)
|
||||
hres = IDispatchEx_GetDispID(dispex, str, make_grfdex(ctx, flags|fdexNameCaseSensitive), id);
|
||||
else
|
||||
hres = E_OUTOFMEMORY;
|
||||
IDispatchEx_Release(dispex);
|
||||
return hres;
|
||||
}
|
||||
|
||||
TRACE("using IDispatch\n");
|
||||
|
||||
return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id);
|
||||
}
|
||||
|
||||
static inline BOOL var_is_null(const VARIANT *v)
|
||||
|
@ -423,12 +437,7 @@ static HRESULT equal2_values(jsval_t lval, jsval_t rval, BOOL *ret)
|
|||
case JSV_OBJECT:
|
||||
return disp_cmp(get_object(lval), get_object(rval), ret);
|
||||
case JSV_STRING:
|
||||
if(!get_string(lval))
|
||||
*ret = !SysStringLen(get_string(rval));
|
||||
else if(!get_string(rval))
|
||||
*ret = !SysStringLen(get_string(lval));
|
||||
else
|
||||
*ret = !strcmpW(get_string(lval), get_string(rval));
|
||||
*ret = jsstr_eq(get_string(lval), get_string(rval));
|
||||
break;
|
||||
case JSV_NUMBER:
|
||||
*ret = get_number(lval) == get_number(rval);
|
||||
|
@ -452,7 +461,7 @@ static BOOL lookup_global_members(script_ctx_t *ctx, BSTR identifier, exprval_t
|
|||
|
||||
for(item = ctx->named_items; item; item = item->next) {
|
||||
if(item->flags & SCRIPTITEM_GLOBALMEMBERS) {
|
||||
hres = disp_get_id(ctx, item->disp, identifier, 0, &id);
|
||||
hres = disp_get_id(ctx, item->disp, identifier, identifier, 0, &id);
|
||||
if(SUCCEEDED(hres)) {
|
||||
if(ret)
|
||||
exprval_set_idref(ret, item->disp, id);
|
||||
|
@ -478,7 +487,7 @@ static HRESULT identifier_eval(script_ctx_t *ctx, BSTR identifier, exprval_t *re
|
|||
if(scope->jsobj)
|
||||
hres = jsdisp_get_id(scope->jsobj, identifier, fdexNameImplicit, &id);
|
||||
else
|
||||
hres = disp_get_id(ctx, scope->obj, identifier, fdexNameImplicit, &id);
|
||||
hres = disp_get_id(ctx, scope->obj, identifier, identifier, fdexNameImplicit, &id);
|
||||
if(SUCCEEDED(hres)) {
|
||||
exprval_set_idref(ret, scope->obj, id);
|
||||
return S_OK;
|
||||
|
@ -608,12 +617,19 @@ static HRESULT interp_forin(exec_ctx_t *ctx)
|
|||
}
|
||||
|
||||
if(name) {
|
||||
jsstr_t *str;
|
||||
|
||||
str = jsstr_alloc_len(name, SysStringLen(name));
|
||||
SysFreeString(name);
|
||||
if(!str)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
jsval_release(val);
|
||||
stack_pop(ctx);
|
||||
stack_push(ctx, jsval_number(id)); /* safe, just after pop() */
|
||||
|
||||
hres = disp_propput(ctx->script, var_obj, var_id, jsval_string(name));
|
||||
SysFreeString(name);
|
||||
hres = disp_propput(ctx->script, var_obj, var_id, jsval_string(str));
|
||||
jsstr_release(str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -806,8 +822,8 @@ static HRESULT interp_array(exec_ctx_t *ctx)
|
|||
{
|
||||
jsval_t v, namev;
|
||||
IDispatch *obj;
|
||||
jsstr_t *name;
|
||||
DISPID id;
|
||||
BSTR name;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
@ -827,8 +843,8 @@ static HRESULT interp_array(exec_ctx_t *ctx)
|
|||
return hres;
|
||||
}
|
||||
|
||||
hres = disp_get_id(ctx->script, obj, name, 0, &id);
|
||||
SysFreeString(name);
|
||||
hres = disp_get_id(ctx->script, obj, name->str, NULL, 0, &id);
|
||||
jsstr_release(name);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = disp_propget(ctx->script, obj, id, &v);
|
||||
}else if(hres == DISP_E_UNKNOWNNAME) {
|
||||
|
@ -857,7 +873,7 @@ static HRESULT interp_member(exec_ctx_t *ctx)
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = disp_get_id(ctx->script, obj, arg, 0, &id);
|
||||
hres = disp_get_id(ctx->script, obj, arg, arg, 0, &id);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = disp_propget(ctx->script, obj, id, &v);
|
||||
}else if(hres == DISP_E_UNKNOWNNAME) {
|
||||
|
@ -877,7 +893,7 @@ static HRESULT interp_memberid(exec_ctx_t *ctx)
|
|||
const unsigned arg = get_op_uint(ctx, 0);
|
||||
jsval_t objv, namev;
|
||||
IDispatch *obj;
|
||||
BSTR name;
|
||||
jsstr_t *name;
|
||||
DISPID id;
|
||||
HRESULT hres;
|
||||
|
||||
|
@ -897,8 +913,8 @@ static HRESULT interp_memberid(exec_ctx_t *ctx)
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = disp_get_id(ctx->script, obj, name, arg, &id);
|
||||
SysFreeString(name);
|
||||
hres = disp_get_id(ctx->script, obj, name->str, NULL, arg, &id);
|
||||
jsstr_release(name);
|
||||
if(FAILED(hres)) {
|
||||
IDispatch_Release(obj);
|
||||
if(hres == DISP_E_UNKNOWNNAME && !(arg & fdexNameEnsure)) {
|
||||
|
@ -1118,16 +1134,16 @@ static HRESULT interp_double(exec_ctx_t *ctx)
|
|||
/* ECMA-262 3rd Edition 7.8.4 */
|
||||
static HRESULT interp_str(exec_ctx_t *ctx)
|
||||
{
|
||||
const WCHAR *str = get_op_str(ctx, 0);
|
||||
BSTR bstr;
|
||||
const WCHAR *arg = get_op_str(ctx, 0);
|
||||
jsstr_t *str;
|
||||
|
||||
TRACE("%s\n", debugstr_w(str));
|
||||
TRACE("%s\n", debugstr_w(arg));
|
||||
|
||||
bstr = SysAllocString(str);
|
||||
if(!bstr)
|
||||
str = jsstr_alloc(arg);
|
||||
if(!str)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
return stack_push(ctx, jsval_string(bstr));
|
||||
return stack_push(ctx, jsval_string(str));
|
||||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 7.8 */
|
||||
|
@ -1376,7 +1392,7 @@ static HRESULT interp_in(exec_ctx_t *ctx)
|
|||
jsval_t obj, v;
|
||||
DISPID id = 0;
|
||||
BOOL ret;
|
||||
BSTR str;
|
||||
jsstr_t *str;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
@ -1395,9 +1411,9 @@ static HRESULT interp_in(exec_ctx_t *ctx)
|
|||
return hres;
|
||||
}
|
||||
|
||||
hres = disp_get_id(ctx->script, get_object(obj), str, 0, &id);
|
||||
hres = disp_get_id(ctx->script, get_object(obj), str->str, NULL, 0, &id);
|
||||
IDispatch_Release(get_object(obj));
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
if(SUCCEEDED(hres))
|
||||
ret = TRUE;
|
||||
else if(hres == DISP_E_UNKNOWNNAME)
|
||||
|
@ -1425,40 +1441,34 @@ static HRESULT add_eval(script_ctx_t *ctx, jsval_t lval, jsval_t rval, jsval_t *
|
|||
}
|
||||
|
||||
if(is_string(l) || is_string(r)) {
|
||||
BSTR lstr = NULL, rstr = NULL;
|
||||
jsstr_t *lstr, *rstr = NULL;
|
||||
|
||||
if(is_string(l))
|
||||
lstr = get_string(l);
|
||||
else
|
||||
hres = to_string(ctx, l, &lstr);
|
||||
hres = to_string(ctx, l, &lstr);
|
||||
if(SUCCEEDED(hres))
|
||||
hres = to_string(ctx, r, &rstr);
|
||||
|
||||
if(SUCCEEDED(hres)) {
|
||||
if(is_string(r))
|
||||
rstr = get_string(r);
|
||||
else
|
||||
hres = to_string(ctx, r, &rstr);
|
||||
unsigned len1, len2;
|
||||
jsstr_t *ret_str;
|
||||
|
||||
len1 = jsstr_length(lstr);
|
||||
len2 = jsstr_length(rstr);
|
||||
|
||||
ret_str = jsstr_alloc_buf(len1+len2);
|
||||
if(ret_str) {
|
||||
if(len1)
|
||||
memcpy(ret_str->str, lstr->str, len1*sizeof(WCHAR));
|
||||
if(len2)
|
||||
memcpy(ret_str->str+len1, rstr->str, len2*sizeof(WCHAR));
|
||||
*ret = jsval_string(ret_str);
|
||||
}else {
|
||||
hres = E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hres)) {
|
||||
int len1, len2;
|
||||
BSTR ret_str;
|
||||
|
||||
len1 = SysStringLen(lstr);
|
||||
len2 = SysStringLen(rstr);
|
||||
|
||||
ret_str = SysAllocStringLen(NULL, len1+len2);
|
||||
if(len1)
|
||||
memcpy(ret_str, lstr, len1*sizeof(WCHAR));
|
||||
if(len2)
|
||||
memcpy(ret_str+len1, rstr, len2*sizeof(WCHAR));
|
||||
ret_str[len1+len2] = 0;
|
||||
*ret = jsval_string(ret_str);
|
||||
}
|
||||
|
||||
if(!is_string(l))
|
||||
SysFreeString(lstr);
|
||||
else if(!is_string(r))
|
||||
SysFreeString(rstr);
|
||||
jsstr_release(lstr);
|
||||
if(rstr)
|
||||
jsstr_release(rstr);
|
||||
}else {
|
||||
double nl, nr;
|
||||
|
||||
|
@ -1577,7 +1587,7 @@ static HRESULT interp_delete(exec_ctx_t *ctx)
|
|||
jsval_t objv, namev;
|
||||
IDispatchEx *dispex;
|
||||
IDispatch *obj;
|
||||
BSTR name;
|
||||
jsstr_t *name;
|
||||
BOOL ret;
|
||||
HRESULT hres;
|
||||
|
||||
|
@ -1602,8 +1612,17 @@ static HRESULT interp_delete(exec_ctx_t *ctx)
|
|||
|
||||
hres = IDispatch_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = IDispatchEx_DeleteMemberByName(dispex, name, make_grfdex(ctx->script, fdexNameCaseSensitive));
|
||||
ret = TRUE;
|
||||
BSTR bstr;
|
||||
|
||||
bstr = SysAllocStringLen(name->str, jsstr_length(name));
|
||||
if(bstr) {
|
||||
hres = IDispatchEx_DeleteMemberByName(dispex, bstr, make_grfdex(ctx->script, fdexNameCaseSensitive));
|
||||
SysFreeString(bstr);
|
||||
ret = TRUE;
|
||||
}else {
|
||||
hres = E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
IDispatchEx_Release(dispex);
|
||||
}else {
|
||||
hres = S_OK;
|
||||
|
@ -1611,7 +1630,7 @@ static HRESULT interp_delete(exec_ctx_t *ctx)
|
|||
}
|
||||
|
||||
IDispatch_Release(obj);
|
||||
SysFreeString(name);
|
||||
jsstr_release(name);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -2063,9 +2082,9 @@ static HRESULT less_eval(script_ctx_t *ctx, jsval_t lval, jsval_t rval, BOOL gre
|
|||
}
|
||||
|
||||
if(is_string(l) && is_string(r)) {
|
||||
*ret = (strcmpW(get_string(l), get_string(r)) < 0) ^ greater;
|
||||
SysFreeString(get_string(l));
|
||||
SysFreeString(get_string(r));
|
||||
*ret = (jsstr_cmp(get_string(l), get_string(r)) < 0) ^ greater;
|
||||
jsstr_release(get_string(l));
|
||||
jsstr_release(get_string(r));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -2456,7 +2475,6 @@ static HRESULT enter_bytecode(script_ctx_t *ctx, bytecode_t *code, function_code
|
|||
|
||||
while(exec_ctx->ip != -1) {
|
||||
op = code->instrs[exec_ctx->ip].op;
|
||||
TRACE("top %d\n", exec_ctx->top);
|
||||
hres = op_funcs[op](exec_ctx);
|
||||
if(FAILED(hres)) {
|
||||
TRACE("EXCEPTION\n");
|
||||
|
|
|
@ -38,7 +38,7 @@ static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags,
|
|||
unsigned argc, jsval_t *argv, jsval_t *r)
|
||||
{
|
||||
jsdisp_t *jsthis;
|
||||
BSTR name = NULL, msg = NULL, ret = NULL;
|
||||
jsstr_t *name = NULL, *msg = NULL, *ret = NULL;
|
||||
jsval_t v;
|
||||
HRESULT hres;
|
||||
|
||||
|
@ -49,10 +49,12 @@ static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags,
|
|||
jsthis = get_jsdisp(vthis);
|
||||
if(!jsthis || ctx->version < 2) {
|
||||
if(r) {
|
||||
BSTR ret = SysAllocString(object_errorW);
|
||||
if(!ret)
|
||||
jsstr_t *str;
|
||||
|
||||
str = jsstr_alloc(object_errorW);
|
||||
if(!str)
|
||||
return E_OUTOFMEMORY;
|
||||
*r = jsval_string(ret);
|
||||
*r = jsval_string(str);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -66,10 +68,6 @@ static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags,
|
|||
jsval_release(v);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
if(!*name) {
|
||||
SysFreeString(name);
|
||||
name = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
hres = jsdisp_propget_name(jsthis, messageW, &v);
|
||||
|
@ -77,40 +75,36 @@ static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags,
|
|||
if(!is_undefined(v)) {
|
||||
hres = to_string(ctx, v, &msg);
|
||||
jsval_release(v);
|
||||
if(SUCCEEDED(hres) && !*msg) {
|
||||
SysFreeString(msg);
|
||||
msg = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hres)) {
|
||||
if(name && msg) {
|
||||
DWORD name_len, msg_len;
|
||||
unsigned name_len = name ? jsstr_length(name) : 0;
|
||||
unsigned msg_len = msg ? jsstr_length(msg) : 0;
|
||||
|
||||
name_len = SysStringLen(name);
|
||||
msg_len = SysStringLen(msg);
|
||||
|
||||
ret = SysAllocStringLen(NULL, name_len + msg_len + 2);
|
||||
if(name_len && msg_len) {
|
||||
ret = jsstr_alloc_buf(name_len + msg_len + 2);
|
||||
if(ret) {
|
||||
memcpy(ret, name, name_len*sizeof(WCHAR));
|
||||
ret[name_len] = ':';
|
||||
ret[name_len+1] = ' ';
|
||||
memcpy(ret+name_len+2, msg, msg_len*sizeof(WCHAR));
|
||||
memcpy(ret->str, name->str, name_len*sizeof(WCHAR));
|
||||
ret->str[name_len] = ':';
|
||||
ret->str[name_len+1] = ' ';
|
||||
memcpy(ret->str+name_len+2, msg->str, msg_len*sizeof(WCHAR));
|
||||
}
|
||||
}else if(name) {
|
||||
}else if(name_len) {
|
||||
ret = name;
|
||||
name = NULL;
|
||||
}else if(msg) {
|
||||
}else if(msg_len) {
|
||||
ret = msg;
|
||||
msg = NULL;
|
||||
}else {
|
||||
ret = SysAllocString(object_errorW);
|
||||
ret = jsstr_alloc(object_errorW);
|
||||
}
|
||||
}
|
||||
|
||||
SysFreeString(msg);
|
||||
SysFreeString(name);
|
||||
if(msg)
|
||||
jsstr_release(msg);
|
||||
if(name)
|
||||
jsstr_release(name);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
if(!ret)
|
||||
|
@ -119,7 +113,7 @@ static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags,
|
|||
if(r)
|
||||
*r = jsval_string(ret);
|
||||
else
|
||||
SysFreeString(ret);
|
||||
jsstr_release(ret);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -189,7 +183,7 @@ static HRESULT create_error(script_ctx_t *ctx, jsdisp_t *constr,
|
|||
UINT number, const WCHAR *msg, jsdisp_t **ret)
|
||||
{
|
||||
jsdisp_t *err;
|
||||
BSTR str;
|
||||
jsstr_t *str;
|
||||
HRESULT hres;
|
||||
|
||||
hres = alloc_error(ctx, NULL, constr, &err);
|
||||
|
@ -202,13 +196,13 @@ static HRESULT create_error(script_ctx_t *ctx, jsdisp_t *constr,
|
|||
return hres;
|
||||
}
|
||||
|
||||
if(msg) str = SysAllocString(msg);
|
||||
else str = SysAllocStringLen(NULL, 0);
|
||||
if(msg) str = jsstr_alloc(msg);
|
||||
else str = jsstr_empty();
|
||||
if(str) {
|
||||
hres = jsdisp_propput_name(err, messageW, jsval_string(str));
|
||||
if(SUCCEEDED(hres))
|
||||
hres = jsdisp_propput_name(err, descriptionW, jsval_string(str));
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
}else {
|
||||
hres = E_OUTOFMEMORY;
|
||||
}
|
||||
|
@ -225,7 +219,7 @@ static HRESULT error_constr(script_ctx_t *ctx, WORD flags, unsigned argc, jsval_
|
|||
jsval_t *r, jsdisp_t *constr) {
|
||||
jsdisp_t *err;
|
||||
UINT num = 0;
|
||||
BSTR msg = NULL;
|
||||
jsstr_t *msg = NULL;
|
||||
HRESULT hres;
|
||||
|
||||
if(argc) {
|
||||
|
@ -250,8 +244,9 @@ static HRESULT error_constr(script_ctx_t *ctx, WORD flags, unsigned argc, jsval_
|
|||
switch(flags) {
|
||||
case INVOKE_FUNC:
|
||||
case DISPATCH_CONSTRUCT:
|
||||
hres = create_error(ctx, constr, num, msg, &err);
|
||||
SysFreeString(msg);
|
||||
hres = create_error(ctx, constr, num, msg ? msg->str : NULL, &err);
|
||||
if(msg)
|
||||
jsstr_release(msg);
|
||||
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -263,6 +258,8 @@ static HRESULT error_constr(script_ctx_t *ctx, WORD flags, unsigned argc, jsval_
|
|||
return S_OK;
|
||||
|
||||
default:
|
||||
if(msg)
|
||||
jsstr_release(msg);
|
||||
FIXME("unimplemented flags %x\n", flags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
@ -346,7 +343,7 @@ HRESULT init_error_constr(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
|||
|
||||
jsdisp_t *err;
|
||||
INT i;
|
||||
BSTR str;
|
||||
jsstr_t *str;
|
||||
HRESULT hres;
|
||||
|
||||
for(i=0; i < sizeof(names)/sizeof(names[0]); i++) {
|
||||
|
@ -354,14 +351,14 @@ HRESULT init_error_constr(script_ctx_t *ctx, jsdisp_t *object_prototype)
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
str = SysAllocString(names[i]);
|
||||
str = jsstr_alloc(names[i]);
|
||||
if(!str) {
|
||||
jsdisp_release(err);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
hres = jsdisp_propput_name(err, nameW, jsval_string(str));
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
if(SUCCEEDED(hres))
|
||||
hres = create_builtin_constructor(ctx, constr_val[i], names[i], NULL,
|
||||
PROPF_CONSTR|1, err, constr_addr[i]);
|
||||
|
|
|
@ -245,9 +245,9 @@ static HRESULT call_function(script_ctx_t *ctx, FunctionInstance *function, IDis
|
|||
return invoke_source(ctx, function, this_obj, argc, argv, r);
|
||||
}
|
||||
|
||||
static HRESULT function_to_string(FunctionInstance *function, BSTR *ret)
|
||||
static HRESULT function_to_string(FunctionInstance *function, jsstr_t **ret)
|
||||
{
|
||||
BSTR str;
|
||||
jsstr_t *str;
|
||||
|
||||
static const WCHAR native_prefixW[] = {'\n','f','u','n','c','t','i','o','n',' '};
|
||||
static const WCHAR native_suffixW[] =
|
||||
|
@ -257,15 +257,15 @@ static HRESULT function_to_string(FunctionInstance *function, BSTR *ret)
|
|||
DWORD name_len;
|
||||
|
||||
name_len = strlenW(function->name);
|
||||
str = SysAllocStringLen(NULL, sizeof(native_prefixW) + name_len*sizeof(WCHAR) + sizeof(native_suffixW));
|
||||
str = jsstr_alloc_buf((sizeof(native_prefixW)+sizeof(native_suffixW))/sizeof(WCHAR) + name_len);
|
||||
if(!str)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
memcpy(str, native_prefixW, sizeof(native_prefixW));
|
||||
memcpy(str + sizeof(native_prefixW)/sizeof(WCHAR), function->name, name_len*sizeof(WCHAR));
|
||||
memcpy(str + sizeof(native_prefixW)/sizeof(WCHAR) + name_len, native_suffixW, sizeof(native_suffixW));
|
||||
memcpy(str->str, native_prefixW, sizeof(native_prefixW));
|
||||
memcpy(str->str + 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));
|
||||
}else {
|
||||
str = SysAllocStringLen(function->func_code->source, function->func_code->source_len);
|
||||
str = jsstr_alloc_len(function->func_code->source, function->func_code->source_len);
|
||||
if(!str)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
@ -316,7 +316,7 @@ static HRESULT Function_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
|||
jsval_t *r)
|
||||
{
|
||||
FunctionInstance *function;
|
||||
BSTR str;
|
||||
jsstr_t *str;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
@ -331,7 +331,7 @@ static HRESULT Function_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
|||
if(r)
|
||||
*r = jsval_string(str);
|
||||
else
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -475,7 +475,7 @@ HRESULT Function_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned
|
|||
|
||||
case DISPATCH_PROPERTYGET: {
|
||||
HRESULT hres;
|
||||
BSTR str;
|
||||
jsstr_t *str;
|
||||
|
||||
hres = function_to_string(function, &str);
|
||||
if(FAILED(hres))
|
||||
|
@ -689,7 +689,7 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg
|
|||
DWORD len = 0, l;
|
||||
bytecode_t *code;
|
||||
jsdisp_t *function;
|
||||
BSTR *params = NULL;
|
||||
jsstr_t **params = NULL;
|
||||
int i=0, j=0;
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
|
@ -698,7 +698,7 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg
|
|||
static const WCHAR function_endW[] = {'\n','}',0};
|
||||
|
||||
if(argc) {
|
||||
params = heap_alloc(argc*sizeof(BSTR));
|
||||
params = heap_alloc(argc*sizeof(*params));
|
||||
if(!params)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
|
@ -708,7 +708,7 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg
|
|||
hres = to_string(ctx, argv[i], params+i);
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
len += SysStringLen(params[i]);
|
||||
len += jsstr_length(params[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -720,8 +720,8 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg
|
|||
ptr = str + sizeof(function_anonymousW)/sizeof(WCHAR);
|
||||
if(argc > 1) {
|
||||
while(1) {
|
||||
l = SysStringLen(params[j]);
|
||||
memcpy(ptr, params[j], l*sizeof(WCHAR));
|
||||
l = jsstr_length(params[j]);
|
||||
memcpy(ptr, params[j]->str, l*sizeof(WCHAR));
|
||||
ptr += l;
|
||||
if(++j == argc-1)
|
||||
break;
|
||||
|
@ -732,8 +732,8 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg
|
|||
memcpy(ptr, function_beginW, sizeof(function_beginW));
|
||||
ptr += sizeof(function_beginW)/sizeof(WCHAR);
|
||||
if(argc) {
|
||||
l = SysStringLen(params[argc-1]);
|
||||
memcpy(ptr, params[argc-1], l*sizeof(WCHAR));
|
||||
l = jsstr_length(params[argc-1]);
|
||||
memcpy(ptr, params[argc-1]->str, l*sizeof(WCHAR));
|
||||
ptr += l;
|
||||
}
|
||||
memcpy(ptr, function_endW, sizeof(function_endW));
|
||||
|
@ -745,7 +745,7 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg
|
|||
}
|
||||
|
||||
while(--i >= 0)
|
||||
SysFreeString(params[i]);
|
||||
jsstr_release(params[i]);
|
||||
heap_free(params);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
|
|
@ -277,20 +277,21 @@ static HRESULT JSGlobal_Enumerator(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
|
|||
static HRESULT JSGlobal_escape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||
jsval_t *r)
|
||||
{
|
||||
BSTR ret, str;
|
||||
jsstr_t *ret_str, *str;
|
||||
const WCHAR *ptr;
|
||||
DWORD len = 0;
|
||||
WCHAR *ret;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(!argc) {
|
||||
if(r) {
|
||||
ret = SysAllocString(undefinedW);
|
||||
if(!ret)
|
||||
ret_str = jsstr_alloc(undefinedW);
|
||||
if(!ret_str)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
*r = jsval_string(ret);
|
||||
*r = jsval_string(ret_str);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
@ -300,7 +301,7 @@ static HRESULT JSGlobal_escape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
for(ptr=str; *ptr; ptr++) {
|
||||
for(ptr = str->str; *ptr; ptr++) {
|
||||
if(*ptr > 0xff)
|
||||
len += 6;
|
||||
else if(is_ecma_nonblank(*ptr))
|
||||
|
@ -309,14 +310,15 @@ static HRESULT JSGlobal_escape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
|
|||
len += 3;
|
||||
}
|
||||
|
||||
ret = SysAllocStringLen(NULL, len);
|
||||
if(!ret) {
|
||||
SysFreeString(str);
|
||||
ret_str = jsstr_alloc_buf(len);
|
||||
if(!ret_str) {
|
||||
jsstr_release(str);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
len = 0;
|
||||
for(ptr=str; *ptr; ptr++) {
|
||||
ret = ret_str->str;
|
||||
for(ptr = str->str; *ptr; ptr++) {
|
||||
if(*ptr > 0xff) {
|
||||
ret[len++] = '%';
|
||||
ret[len++] = 'u';
|
||||
|
@ -334,12 +336,12 @@ static HRESULT JSGlobal_escape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
|
|||
}
|
||||
}
|
||||
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
|
||||
if(r)
|
||||
*r = jsval_string(ret);
|
||||
*r = jsval_string(ret_str);
|
||||
else
|
||||
SysFreeString(ret);
|
||||
jsstr_release(ret_str);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -370,7 +372,7 @@ static HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
|
|||
}
|
||||
|
||||
TRACE("parsing %s\n", debugstr_jsval(argv[0]));
|
||||
hres = compile_script(ctx, get_string(argv[0]), NULL, NULL, TRUE, FALSE, &code);
|
||||
hres = compile_script(ctx, get_string(argv[0])->str, NULL, NULL, TRUE, FALSE, &code);
|
||||
if(FAILED(hres)) {
|
||||
WARN("parse (%s) failed: %08x\n", debugstr_jsval(argv[0]), hres);
|
||||
return throw_syntax_error(ctx, hres, NULL);
|
||||
|
@ -445,8 +447,8 @@ static HRESULT JSGlobal_parseInt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
|||
BOOL neg = FALSE, empty = TRUE;
|
||||
DOUBLE ret = 0.0;
|
||||
INT radix=0, i;
|
||||
jsstr_t *str;
|
||||
WCHAR *ptr;
|
||||
BSTR str;
|
||||
HRESULT hres;
|
||||
|
||||
if(!argc) {
|
||||
|
@ -472,7 +474,7 @@ static HRESULT JSGlobal_parseInt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
for(ptr = str; isspaceW(*ptr); ptr++);
|
||||
for(ptr = str->str; isspaceW(*ptr); ptr++);
|
||||
|
||||
switch(*ptr) {
|
||||
case '+':
|
||||
|
@ -509,7 +511,7 @@ static HRESULT JSGlobal_parseInt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
|||
ret = NAN;
|
||||
}
|
||||
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
|
||||
if(neg)
|
||||
ret = -ret;
|
||||
|
@ -523,9 +525,9 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
|
|||
jsval_t *r)
|
||||
{
|
||||
LONGLONG d = 0, hlp;
|
||||
jsstr_t *val_str;
|
||||
int exp = 0;
|
||||
WCHAR *str;
|
||||
BSTR val_str = NULL;
|
||||
BOOL ret_nan = TRUE, positive = TRUE;
|
||||
HRESULT hres;
|
||||
|
||||
|
@ -539,7 +541,7 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
str = val_str;
|
||||
str = val_str->str;
|
||||
|
||||
while(isspaceW(*str)) str++;
|
||||
|
||||
|
@ -605,7 +607,7 @@ static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
|
|||
else exp += e;
|
||||
}
|
||||
|
||||
SysFreeString(val_str);
|
||||
jsstr_release(val_str);
|
||||
|
||||
if(ret_nan) {
|
||||
if(r)
|
||||
|
@ -629,19 +631,20 @@ static inline int hex_to_int(const WCHAR wch) {
|
|||
static HRESULT JSGlobal_unescape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||
jsval_t *r)
|
||||
{
|
||||
BSTR ret, str;
|
||||
jsstr_t *ret_str, *str;
|
||||
const WCHAR *ptr;
|
||||
DWORD len = 0;
|
||||
WCHAR *ret;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(!argc) {
|
||||
if(r) {
|
||||
ret = SysAllocString(undefinedW);
|
||||
if(!ret)
|
||||
ret_str = jsstr_alloc(undefinedW);
|
||||
if(!ret_str)
|
||||
return E_OUTOFMEMORY;
|
||||
*r = jsval_string(ret);
|
||||
*r = jsval_string(ret_str);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
@ -651,7 +654,7 @@ static HRESULT JSGlobal_unescape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
for(ptr=str; *ptr; ptr++) {
|
||||
for(ptr = str->str; *ptr; ptr++) {
|
||||
if(*ptr == '%') {
|
||||
if(hex_to_int(*(ptr+1))!=-1 && hex_to_int(*(ptr+2))!=-1)
|
||||
ptr += 2;
|
||||
|
@ -663,14 +666,15 @@ static HRESULT JSGlobal_unescape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
|||
len++;
|
||||
}
|
||||
|
||||
ret = SysAllocStringLen(NULL, len);
|
||||
if(!ret) {
|
||||
SysFreeString(str);
|
||||
ret_str = jsstr_alloc_buf(len);
|
||||
if(!ret_str) {
|
||||
jsstr_release(str);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
ret = ret_str->str;
|
||||
len = 0;
|
||||
for(ptr=str; *ptr; ptr++) {
|
||||
for(ptr = str->str; *ptr; ptr++) {
|
||||
if(*ptr == '%') {
|
||||
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));
|
||||
|
@ -691,12 +695,12 @@ static HRESULT JSGlobal_unescape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
|||
len++;
|
||||
}
|
||||
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
|
||||
if(r)
|
||||
*r = jsval_string(ret);
|
||||
*r = jsval_string(ret_str);
|
||||
else
|
||||
SysFreeString(ret);
|
||||
jsstr_release(ret_str);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -715,9 +719,9 @@ static HRESULT JSGlobal_ScriptEngine(script_ctx_t *ctx, vdisp_t *jsthis, WORD fl
|
|||
TRACE("\n");
|
||||
|
||||
if(r) {
|
||||
BSTR ret;
|
||||
jsstr_t *ret;
|
||||
|
||||
ret = SysAllocString(JScriptW);
|
||||
ret = jsstr_alloc(JScriptW);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
|
@ -767,10 +771,10 @@ 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,
|
||||
jsval_t *r)
|
||||
{
|
||||
jsstr_t *str, *ret;
|
||||
const WCHAR *ptr;
|
||||
DWORD len = 0, i;
|
||||
char buf[4];
|
||||
BSTR str, ret;
|
||||
WCHAR *rptr;
|
||||
HRESULT hres;
|
||||
|
||||
|
@ -778,7 +782,7 @@ static HRESULT JSGlobal_encodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
|||
|
||||
if(!argc) {
|
||||
if(r) {
|
||||
ret = SysAllocString(undefinedW);
|
||||
ret = jsstr_alloc(undefinedW);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
|
@ -792,13 +796,13 @@ static HRESULT JSGlobal_encodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
for(ptr = str; *ptr; ptr++) {
|
||||
for(ptr = str->str; *ptr; ptr++) {
|
||||
if(is_uri_unescaped(*ptr) || is_uri_reserved(*ptr) || *ptr == '#') {
|
||||
len++;
|
||||
}else {
|
||||
i = WideCharToMultiByte(CP_UTF8, 0, ptr, 1, NULL, 0, NULL, NULL)*3;
|
||||
if(!i) {
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
return throw_uri_error(ctx, JS_E_INVALID_URI_CHAR, NULL);
|
||||
}
|
||||
|
||||
|
@ -806,13 +810,14 @@ static HRESULT JSGlobal_encodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
|||
}
|
||||
}
|
||||
|
||||
rptr = ret = SysAllocStringLen(NULL, len);
|
||||
ret = jsstr_alloc_buf(len);
|
||||
if(!ret) {
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
rptr = ret->str;
|
||||
|
||||
for(ptr = str; *ptr; ptr++) {
|
||||
for(ptr = str->str; *ptr; ptr++) {
|
||||
if(is_uri_unescaped(*ptr) || is_uri_reserved(*ptr) || *ptr == '#') {
|
||||
*rptr++ = *ptr;
|
||||
}else {
|
||||
|
@ -825,20 +830,20 @@ static HRESULT JSGlobal_encodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
|||
}
|
||||
}
|
||||
|
||||
TRACE("%s -> %s\n", debugstr_w(str), debugstr_w(ret));
|
||||
SysFreeString(str);
|
||||
TRACE("%s -> %s\n", debugstr_jsstr(str), debugstr_jsstr(ret));
|
||||
jsstr_release(str);
|
||||
|
||||
if(r)
|
||||
*r = jsval_string(ret);
|
||||
else
|
||||
SysFreeString(ret);
|
||||
jsstr_release(ret);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT JSGlobal_decodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||
jsval_t *r)
|
||||
{
|
||||
BSTR str, ret;
|
||||
jsstr_t *str, *ret;
|
||||
WCHAR *ptr;
|
||||
int i, len = 0, val, res;
|
||||
char buf[4];
|
||||
|
@ -849,7 +854,7 @@ static HRESULT JSGlobal_decodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
|||
|
||||
if(!argc) {
|
||||
if(r) {
|
||||
ret = SysAllocString(undefinedW);
|
||||
ret = jsstr_alloc(undefinedW);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
|
@ -863,7 +868,7 @@ static HRESULT JSGlobal_decodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
for(ptr=str; *ptr; ptr++) {
|
||||
for(ptr = str->str; *ptr; ptr++) {
|
||||
if(*ptr != '%') {
|
||||
len++;
|
||||
}else {
|
||||
|
@ -880,7 +885,7 @@ static HRESULT JSGlobal_decodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
|||
}
|
||||
|
||||
if(!res) {
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
return throw_uri_error(ctx, JS_E_INVALID_URI_CODING, NULL);
|
||||
}
|
||||
|
||||
|
@ -889,16 +894,16 @@ static HRESULT JSGlobal_decodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
|||
}
|
||||
}
|
||||
|
||||
ret = SysAllocStringLen(NULL, len);
|
||||
ret = jsstr_alloc_buf(len);
|
||||
if(!ret) {
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
len = 0;
|
||||
for(ptr=str; *ptr; ptr++) {
|
||||
for(ptr = str->str; *ptr; ptr++) {
|
||||
if(*ptr != '%') {
|
||||
ret[len] = *ptr;
|
||||
ret->str[len] = *ptr;
|
||||
len++;
|
||||
}else {
|
||||
for(i=0; i<4; i++) {
|
||||
|
@ -907,7 +912,7 @@ static HRESULT JSGlobal_decodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
|||
val += hex_to_int(ptr[i*3+1])<<4;
|
||||
buf[i] = val;
|
||||
|
||||
res = MultiByteToWideChar(CP_UTF8, 0, buf, i+1, ret+len, 1);
|
||||
res = MultiByteToWideChar(CP_UTF8, 0, buf, i+1, ret->str+len, 1);
|
||||
if(res)
|
||||
break;
|
||||
}
|
||||
|
@ -917,20 +922,20 @@ static HRESULT JSGlobal_decodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
|||
}
|
||||
}
|
||||
|
||||
TRACE("%s -> %s\n", debugstr_w(str), debugstr_w(ret));
|
||||
SysFreeString(str);
|
||||
TRACE("%s -> %s\n", debugstr_jsstr(str), debugstr_jsstr(ret));
|
||||
jsstr_release(str);
|
||||
|
||||
if(r)
|
||||
*r = jsval_string(ret);
|
||||
else
|
||||
SysFreeString(ret);
|
||||
jsstr_release(ret);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT JSGlobal_encodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||
jsval_t *r)
|
||||
{
|
||||
BSTR str, ret;
|
||||
jsstr_t *str, *ret;
|
||||
char buf[4];
|
||||
const WCHAR *ptr;
|
||||
DWORD len = 0, size, i;
|
||||
|
@ -940,7 +945,7 @@ static HRESULT JSGlobal_encodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, W
|
|||
|
||||
if(!argc) {
|
||||
if(r) {
|
||||
ret = SysAllocString(undefinedW);
|
||||
ret = jsstr_alloc(undefinedW);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
|
@ -954,45 +959,45 @@ static HRESULT JSGlobal_encodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, W
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
for(ptr=str; *ptr; ptr++) {
|
||||
for(ptr = str->str; *ptr; ptr++) {
|
||||
if(is_uri_unescaped(*ptr))
|
||||
len++;
|
||||
else {
|
||||
size = WideCharToMultiByte(CP_UTF8, 0, ptr, 1, NULL, 0, NULL, NULL);
|
||||
if(!size) {
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
return throw_uri_error(ctx, JS_E_INVALID_URI_CHAR, NULL);
|
||||
}
|
||||
len += size*3;
|
||||
}
|
||||
}
|
||||
|
||||
ret = SysAllocStringLen(NULL, len);
|
||||
ret = jsstr_alloc_buf(len);
|
||||
if(!ret) {
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
len = 0;
|
||||
for(ptr=str; *ptr; ptr++) {
|
||||
if(is_uri_unescaped(*ptr))
|
||||
ret[len++] = *ptr;
|
||||
else {
|
||||
for(ptr = str->str; *ptr; ptr++) {
|
||||
if(is_uri_unescaped(*ptr)) {
|
||||
ret->str[len++] = *ptr;
|
||||
}else {
|
||||
size = WideCharToMultiByte(CP_UTF8, 0, ptr, 1, buf, sizeof(buf), NULL, NULL);
|
||||
for(i=0; i<size; i++) {
|
||||
ret[len++] = '%';
|
||||
ret[len++] = int_to_char((BYTE)buf[i] >> 4);
|
||||
ret[len++] = int_to_char(buf[i] & 0x0f);
|
||||
ret->str[len++] = '%';
|
||||
ret->str[len++] = int_to_char((BYTE)buf[i] >> 4);
|
||||
ret->str[len++] = int_to_char(buf[i] & 0x0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
|
||||
if(r)
|
||||
*r = jsval_string(ret);
|
||||
else
|
||||
SysFreeString(ret);
|
||||
jsstr_release(ret);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -1000,7 +1005,7 @@ 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,
|
||||
jsval_t *r)
|
||||
{
|
||||
BSTR str, ret;
|
||||
jsstr_t *str, *ret;
|
||||
const WCHAR *ptr;
|
||||
WCHAR *out_ptr;
|
||||
DWORD len = 0;
|
||||
|
@ -1010,7 +1015,7 @@ static HRESULT JSGlobal_decodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, W
|
|||
|
||||
if(!argc) {
|
||||
if(r) {
|
||||
ret = SysAllocString(undefinedW);
|
||||
ret = jsstr_alloc(undefinedW);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
|
@ -1024,7 +1029,7 @@ static HRESULT JSGlobal_decodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, W
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
ptr = str;
|
||||
ptr = str->str;
|
||||
while(*ptr) {
|
||||
if(*ptr == '%') {
|
||||
char octets[4];
|
||||
|
@ -1032,7 +1037,7 @@ static HRESULT JSGlobal_decodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, W
|
|||
int i, size, num_bytes = 0;
|
||||
if(hex_to_int(*(ptr+1)) < 0 || hex_to_int(*(ptr+2)) < 0) {
|
||||
FIXME("Throw URIError: Invalid hex sequence\n");
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
return E_FAIL;
|
||||
}
|
||||
octets[0] = (hex_to_int(*(ptr+1)) << 4) + hex_to_int(*(ptr+2));
|
||||
|
@ -1043,18 +1048,18 @@ static HRESULT JSGlobal_decodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, W
|
|||
}
|
||||
if(num_bytes == 1 || num_bytes > 4) {
|
||||
FIXME("Throw URIError: Invalid initial UTF character\n");
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
return E_FAIL;
|
||||
}
|
||||
for(i = 1; i < num_bytes; ++i) {
|
||||
if(*ptr != '%'){
|
||||
FIXME("Throw URIError: Incomplete UTF sequence\n");
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
return E_FAIL;
|
||||
}
|
||||
if(hex_to_int(*(ptr+1)) < 0 || hex_to_int(*(ptr+2)) < 0) {
|
||||
FIXME("Throw URIError: Invalid hex sequence\n");
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
return E_FAIL;
|
||||
}
|
||||
octets[i] = (hex_to_int(*(ptr+1)) << 4) + hex_to_int(*(ptr+2));
|
||||
|
@ -1064,7 +1069,7 @@ static HRESULT JSGlobal_decodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, W
|
|||
num_bytes ? num_bytes : 1, NULL, 0);
|
||||
if(size == 0) {
|
||||
FIXME("Throw URIError: Invalid UTF sequence\n");
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
return E_FAIL;
|
||||
}
|
||||
len += size;
|
||||
|
@ -1074,13 +1079,14 @@ static HRESULT JSGlobal_decodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, W
|
|||
}
|
||||
}
|
||||
|
||||
out_ptr = ret = SysAllocStringLen(NULL, len);
|
||||
ret = jsstr_alloc_buf(len);
|
||||
if(!ret) {
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
out_ptr = ret->str;
|
||||
|
||||
ptr = str;
|
||||
ptr = str->str;
|
||||
while(*ptr) {
|
||||
if(*ptr == '%') {
|
||||
char octets[4];
|
||||
|
@ -1106,12 +1112,12 @@ static HRESULT JSGlobal_decodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, W
|
|||
}
|
||||
}
|
||||
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
|
||||
if(r)
|
||||
*r = jsval_string(ret);
|
||||
else
|
||||
SysFreeString(ret);
|
||||
jsstr_release(ret);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,8 @@ void script_release(script_ctx_t *ctx)
|
|||
if(ctx->cc)
|
||||
release_cc(ctx->cc);
|
||||
jsheap_free(&ctx->tmp_heap);
|
||||
SysFreeString(ctx->last_match);
|
||||
if(ctx->last_match)
|
||||
jsstr_release(ctx->last_match);
|
||||
|
||||
ctx->jscaller->ctx = NULL;
|
||||
IServiceProvider_Release(&ctx->jscaller->IServiceProvider_iface);
|
||||
|
@ -724,6 +725,8 @@ static HRESULT WINAPI JScriptParse_InitNew(IActiveScriptParse *iface)
|
|||
return hres;
|
||||
}
|
||||
|
||||
ctx->last_match = jsstr_empty();
|
||||
|
||||
ctx = InterlockedCompareExchangePointer((void**)&This->ctx, ctx, NULL);
|
||||
if(ctx) {
|
||||
script_release(ctx);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "wine/list.h"
|
||||
|
||||
typedef struct _jsval_t jsval_t;
|
||||
typedef struct _jsstr_t jsstr_t;
|
||||
typedef struct _script_ctx_t script_ctx_t;
|
||||
typedef struct _exec_ctx_t exec_ctx_t;
|
||||
typedef struct _dispex_prop_t dispex_prop_t;
|
||||
|
@ -54,6 +55,41 @@ void jsheap_clear(jsheap_t*) DECLSPEC_HIDDEN;
|
|||
void jsheap_free(jsheap_t*) DECLSPEC_HIDDEN;
|
||||
jsheap_t *jsheap_mark(jsheap_t*) DECLSPEC_HIDDEN;
|
||||
|
||||
static inline void *heap_alloc(size_t len)
|
||||
{
|
||||
return HeapAlloc(GetProcessHeap(), 0, len);
|
||||
}
|
||||
|
||||
static inline void *heap_alloc_zero(size_t len)
|
||||
{
|
||||
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
|
||||
}
|
||||
|
||||
static inline void *heap_realloc(void *mem, size_t len)
|
||||
{
|
||||
return HeapReAlloc(GetProcessHeap(), 0, mem, len);
|
||||
}
|
||||
|
||||
static inline BOOL heap_free(void *mem)
|
||||
{
|
||||
return HeapFree(GetProcessHeap(), 0, mem);
|
||||
}
|
||||
|
||||
static inline LPWSTR heap_strdupW(LPCWSTR str)
|
||||
{
|
||||
LPWSTR ret = NULL;
|
||||
|
||||
if(str) {
|
||||
DWORD size;
|
||||
|
||||
size = (strlenW(str)+1)*sizeof(WCHAR);
|
||||
ret = heap_alloc(size);
|
||||
memcpy(ret, str, size);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct jsdisp_t jsdisp_t;
|
||||
|
||||
extern HINSTANCE jscript_hinstance DECLSPEC_HIDDEN;
|
||||
|
@ -219,7 +255,7 @@ HRESULT jsdisp_propget_name(jsdisp_t*,LPCWSTR,jsval_t*) DECLSPEC_HIDDEN;
|
|||
HRESULT jsdisp_get_idx(jsdisp_t*,DWORD,jsval_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT jsdisp_get_id(jsdisp_t*,const WCHAR*,DWORD,DISPID*) DECLSPEC_HIDDEN;
|
||||
HRESULT jsdisp_delete_idx(jsdisp_t*,DWORD) DECLSPEC_HIDDEN;
|
||||
HRESULT jsdisp_is_own_prop(jsdisp_t*,BSTR,BOOL*) DECLSPEC_HIDDEN;
|
||||
HRESULT jsdisp_is_own_prop(jsdisp_t*,const WCHAR*,BOOL*) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,const WCHAR*,const builtin_info_t*,DWORD,
|
||||
jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDEN;
|
||||
|
@ -242,7 +278,7 @@ HRESULT create_math(script_ctx_t*,jsdisp_t**) DECLSPEC_HIDDEN;
|
|||
HRESULT create_array(script_ctx_t*,DWORD,jsdisp_t**) DECLSPEC_HIDDEN;
|
||||
HRESULT create_regexp(script_ctx_t*,const WCHAR *,int,DWORD,jsdisp_t**) DECLSPEC_HIDDEN;
|
||||
HRESULT create_regexp_var(script_ctx_t*,jsval_t,jsval_t*,jsdisp_t**) DECLSPEC_HIDDEN;
|
||||
HRESULT create_string(script_ctx_t*,const WCHAR*,DWORD,jsdisp_t**) DECLSPEC_HIDDEN;
|
||||
HRESULT create_string(script_ctx_t*,jsstr_t*,jsdisp_t**) DECLSPEC_HIDDEN;
|
||||
HRESULT create_bool(script_ctx_t*,BOOL,jsdisp_t**) DECLSPEC_HIDDEN;
|
||||
HRESULT create_number(script_ctx_t*,double,jsdisp_t**) DECLSPEC_HIDDEN;
|
||||
HRESULT create_vbarray(script_ctx_t*,SAFEARRAY*,jsdisp_t**) DECLSPEC_HIDDEN;
|
||||
|
@ -259,14 +295,14 @@ HRESULT to_number(script_ctx_t*,jsval_t,double*) DECLSPEC_HIDDEN;
|
|||
HRESULT to_integer(script_ctx_t*,jsval_t,double*) DECLSPEC_HIDDEN;
|
||||
HRESULT to_int32(script_ctx_t*,jsval_t,INT*) DECLSPEC_HIDDEN;
|
||||
HRESULT to_uint32(script_ctx_t*,jsval_t,DWORD*) DECLSPEC_HIDDEN;
|
||||
HRESULT to_string(script_ctx_t*,jsval_t,BSTR*) DECLSPEC_HIDDEN;
|
||||
HRESULT to_string(script_ctx_t*,jsval_t,jsstr_t**) 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 decode_source(WCHAR*) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT double_to_bstr(double,BSTR*) DECLSPEC_HIDDEN;
|
||||
HRESULT double_to_string(double,jsstr_t**) DECLSPEC_HIDDEN;
|
||||
|
||||
typedef struct named_item_t {
|
||||
IDispatch *disp;
|
||||
|
@ -325,7 +361,7 @@ struct _script_ctx_t {
|
|||
|
||||
IDispatch *host_global;
|
||||
|
||||
BSTR last_match;
|
||||
jsstr_t *last_match;
|
||||
match_result_t match_parens[9];
|
||||
DWORD last_match_index;
|
||||
DWORD last_match_length;
|
||||
|
@ -383,7 +419,7 @@ HRESULT create_jscaller(script_ctx_t*) DECLSPEC_HIDDEN;
|
|||
HRESULT regexp_match_next(script_ctx_t*,jsdisp_t*,DWORD,const WCHAR*,DWORD,const WCHAR**,match_result_t**,
|
||||
DWORD*,DWORD*,match_result_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT parse_regexp_flags(const WCHAR*,DWORD,DWORD*) DECLSPEC_HIDDEN;
|
||||
HRESULT regexp_string_match(script_ctx_t*,jsdisp_t*,BSTR,jsval_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT regexp_string_match(script_ctx_t*,jsdisp_t*,jsstr_t*,jsval_t*) DECLSPEC_HIDDEN;
|
||||
|
||||
static inline BOOL is_class(jsdisp_t *jsdisp, jsclass_t class)
|
||||
{
|
||||
|
@ -475,38 +511,3 @@ static inline void unlock_module(void)
|
|||
{
|
||||
InterlockedDecrement(&module_ref);
|
||||
}
|
||||
|
||||
static inline void *heap_alloc(size_t len)
|
||||
{
|
||||
return HeapAlloc(GetProcessHeap(), 0, len);
|
||||
}
|
||||
|
||||
static inline void *heap_alloc_zero(size_t len)
|
||||
{
|
||||
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
|
||||
}
|
||||
|
||||
static inline void *heap_realloc(void *mem, size_t len)
|
||||
{
|
||||
return HeapReAlloc(GetProcessHeap(), 0, mem, len);
|
||||
}
|
||||
|
||||
static inline BOOL heap_free(void *mem)
|
||||
{
|
||||
return HeapFree(GetProcessHeap(), 0, mem);
|
||||
}
|
||||
|
||||
static inline LPWSTR heap_strdupW(LPCWSTR str)
|
||||
{
|
||||
LPWSTR ret = NULL;
|
||||
|
||||
if(str) {
|
||||
DWORD size;
|
||||
|
||||
size = (strlenW(str)+1)*sizeof(WCHAR);
|
||||
ret = heap_alloc(size);
|
||||
memcpy(ret, str, size);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -140,7 +140,11 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
|||
case DLL_PROCESS_ATTACH:
|
||||
DisableThreadLibraryCalls(hInstDLL);
|
||||
jscript_hinstance = hInstDLL;
|
||||
if(!init_strings())
|
||||
return FALSE;
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
free_strings();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
96
dlls/jscript/jsstr.c
Normal file
96
dlls/jscript/jsstr.c
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright 2012 Jacek Caban for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "jscript.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
const char *debugstr_jsstr(jsstr_t *str)
|
||||
{
|
||||
return debugstr_wn(str->str, jsstr_length(str));
|
||||
}
|
||||
|
||||
jsstr_t *jsstr_alloc_buf(unsigned len)
|
||||
{
|
||||
jsstr_t *ret;
|
||||
|
||||
if(len > JSSTR_MAX_LENGTH)
|
||||
return NULL;
|
||||
|
||||
ret = heap_alloc(FIELD_OFFSET(jsstr_t, str[len+1]));
|
||||
if(!ret)
|
||||
return NULL;
|
||||
|
||||
ret->length_flags = len << JSSTR_LENGTH_SHIFT;
|
||||
ret->ref = 1;
|
||||
ret->str[len] = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
jsstr_t *jsstr_alloc_len(const WCHAR *buf, unsigned len)
|
||||
{
|
||||
jsstr_t *ret;
|
||||
|
||||
ret = jsstr_alloc_buf(len);
|
||||
if(ret)
|
||||
memcpy(ret->str, buf, len*sizeof(WCHAR));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int jsstr_cmp(jsstr_t *str1, jsstr_t *str2)
|
||||
{
|
||||
int len1 = jsstr_length(str1);
|
||||
int len2 = jsstr_length(str2);
|
||||
int ret;
|
||||
|
||||
ret = memcmp(str1->str, str2->str, min(len1, len2)*sizeof(WCHAR));
|
||||
if(!ret)
|
||||
ret = len1 - len2;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static jsstr_t *empty_str, *nan_str;
|
||||
|
||||
jsstr_t *jsstr_nan(void)
|
||||
{
|
||||
return jsstr_addref(nan_str);
|
||||
}
|
||||
|
||||
jsstr_t *jsstr_empty(void)
|
||||
{
|
||||
return jsstr_addref(empty_str);
|
||||
}
|
||||
|
||||
BOOL init_strings(void)
|
||||
{
|
||||
static const WCHAR NaNW[] = { 'N','a','N',0 };
|
||||
|
||||
if(!(empty_str = jsstr_alloc_buf(0)))
|
||||
return FALSE;
|
||||
if(!(nan_str = jsstr_alloc(NaNW)))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void free_strings(void)
|
||||
{
|
||||
jsstr_release(empty_str);
|
||||
jsstr_release(nan_str);
|
||||
}
|
70
dlls/jscript/jsstr.h
Normal file
70
dlls/jscript/jsstr.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright 2012 Jacek Caban for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
struct _jsstr_t {
|
||||
unsigned length_flags;
|
||||
unsigned ref;
|
||||
WCHAR str[1];
|
||||
};
|
||||
|
||||
#define JSSTR_LENGTH_SHIFT 4
|
||||
#define JSSTR_MAX_LENGTH (1 << (32-JSSTR_LENGTH_SHIFT))
|
||||
#define JSSTR_FLAGS_MASK ((1 << JSSTR_LENGTH_SHIFT)-1)
|
||||
|
||||
#define JSSTR_FLAG_NULLBSTR 1
|
||||
|
||||
static unsigned inline jsstr_length(jsstr_t *str)
|
||||
{
|
||||
return str->length_flags >> JSSTR_LENGTH_SHIFT;
|
||||
}
|
||||
|
||||
jsstr_t *jsstr_alloc_len(const WCHAR*,unsigned) DECLSPEC_HIDDEN;
|
||||
jsstr_t *jsstr_alloc_buf(unsigned) DECLSPEC_HIDDEN;
|
||||
|
||||
static inline jsstr_t *jsstr_alloc(const WCHAR *str)
|
||||
{
|
||||
return jsstr_alloc_len(str, strlenW(str));
|
||||
}
|
||||
|
||||
static inline void jsstr_release(jsstr_t *str)
|
||||
{
|
||||
if(!--str->ref)
|
||||
heap_free(str);
|
||||
}
|
||||
|
||||
static inline jsstr_t *jsstr_addref(jsstr_t *str)
|
||||
{
|
||||
str->ref++;
|
||||
return str;
|
||||
}
|
||||
|
||||
static inline BOOL jsstr_eq(jsstr_t *str1, jsstr_t *str2)
|
||||
{
|
||||
unsigned len = jsstr_length(str1);
|
||||
return len == jsstr_length(str2) && !memcmp(str1->str, str2->str, len*sizeof(WCHAR));
|
||||
}
|
||||
|
||||
int jsstr_cmp(jsstr_t*,jsstr_t*) DECLSPEC_HIDDEN;
|
||||
|
||||
jsstr_t *jsstr_nan(void) DECLSPEC_HIDDEN;
|
||||
jsstr_t *jsstr_empty(void) DECLSPEC_HIDDEN;
|
||||
|
||||
BOOL init_strings(void) DECLSPEC_HIDDEN;
|
||||
void free_strings(void) DECLSPEC_HIDDEN;
|
||||
|
||||
const char *debugstr_jsstr(jsstr_t*) DECLSPEC_HIDDEN;
|
|
@ -69,7 +69,7 @@ const char *debugstr_jsval(const jsval_t v)
|
|||
case JSV_OBJECT:
|
||||
return wine_dbg_sprintf("obj(%p)", get_object(v));
|
||||
case JSV_STRING:
|
||||
return debugstr_w(get_string(v));
|
||||
return wine_dbg_sprintf("str(%s)", debugstr_jsstr(get_string(v)));
|
||||
case JSV_NUMBER:
|
||||
return wine_dbg_sprintf("%lf", get_number(v));
|
||||
case JSV_BOOL:
|
||||
|
@ -210,11 +210,6 @@ jsheap_t *jsheap_mark(jsheap_t *heap)
|
|||
return heap;
|
||||
}
|
||||
|
||||
static BSTR clone_bstr(BSTR str)
|
||||
{
|
||||
return SysAllocStringLen(str, str ? SysStringLen(str) : 0);
|
||||
}
|
||||
|
||||
void jsval_release(jsval_t val)
|
||||
{
|
||||
switch(jsval_type(val)) {
|
||||
|
@ -223,7 +218,7 @@ void jsval_release(jsval_t val)
|
|||
IDispatch_Release(get_object(val));
|
||||
break;
|
||||
case JSV_STRING:
|
||||
SysFreeString(get_string(val));
|
||||
jsstr_release(get_string(val));
|
||||
break;
|
||||
case JSV_VARIANT:
|
||||
VariantClear(get_variant(val));
|
||||
|
@ -266,10 +261,8 @@ HRESULT jsval_copy(jsval_t v, jsval_t *r)
|
|||
*r = v;
|
||||
return S_OK;
|
||||
case JSV_STRING: {
|
||||
BSTR str = clone_bstr(get_string(v));
|
||||
if(!str)
|
||||
return E_OUTOFMEMORY;
|
||||
*r = jsval_string(str);
|
||||
jsstr_addref(get_string(v));
|
||||
*r = v;
|
||||
return S_OK;
|
||||
}
|
||||
case JSV_VARIANT:
|
||||
|
@ -299,15 +292,14 @@ HRESULT variant_to_jsval(VARIANT *var, jsval_t *r)
|
|||
*r = jsval_number(V_R8(var));
|
||||
return S_OK;
|
||||
case VT_BSTR: {
|
||||
BSTR str;
|
||||
jsstr_t *str;
|
||||
|
||||
str = jsstr_alloc_len(V_BSTR(var), SysStringLen(V_BSTR(var)));
|
||||
if(!str)
|
||||
return E_OUTOFMEMORY;
|
||||
if(!V_BSTR(var))
|
||||
str->length_flags |= JSSTR_FLAG_NULLBSTR;
|
||||
|
||||
if(V_BSTR(var)) {
|
||||
str = clone_bstr(V_BSTR(var));
|
||||
if(!str)
|
||||
return E_OUTOFMEMORY;
|
||||
}else {
|
||||
str = NULL;
|
||||
}
|
||||
*r = jsval_string(str);
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -343,16 +335,19 @@ HRESULT jsval_to_variant(jsval_t val, VARIANT *retv)
|
|||
IDispatch_AddRef(get_object(val));
|
||||
V_DISPATCH(retv) = get_object(val);
|
||||
return S_OK;
|
||||
case JSV_STRING:
|
||||
case JSV_STRING: {
|
||||
jsstr_t *str = get_string(val);
|
||||
|
||||
V_VT(retv) = VT_BSTR;
|
||||
if(get_string(val)) {
|
||||
V_BSTR(retv) = clone_bstr(get_string(val));
|
||||
if(str->length_flags & JSSTR_FLAG_NULLBSTR) {
|
||||
V_BSTR(retv) = NULL;
|
||||
}else {
|
||||
V_BSTR(retv) = SysAllocStringLen(str->str, jsstr_length(str));
|
||||
if(!V_BSTR(retv))
|
||||
return E_OUTOFMEMORY;
|
||||
}else {
|
||||
V_BSTR(retv) = NULL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
case JSV_NUMBER: {
|
||||
double n = get_number(val);
|
||||
|
||||
|
@ -459,7 +454,7 @@ HRESULT to_boolean(jsval_t val, BOOL *ret)
|
|||
*ret = get_object(val) != NULL;
|
||||
return S_OK;
|
||||
case JSV_STRING:
|
||||
*ret = get_string(val) && *get_string(val);
|
||||
*ret = jsstr_length(get_string(val)) != 0;
|
||||
return S_OK;
|
||||
case JSV_NUMBER:
|
||||
*ret = !isnan(get_number(val)) && get_number(val);
|
||||
|
@ -491,9 +486,9 @@ static int hex_to_int(WCHAR c)
|
|||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 9.3.1 */
|
||||
static HRESULT str_to_number(BSTR str, double *ret)
|
||||
static HRESULT str_to_number(jsstr_t *str, double *ret)
|
||||
{
|
||||
const WCHAR *ptr = str;
|
||||
const WCHAR *ptr = str->str;
|
||||
BOOL neg = FALSE;
|
||||
DOUBLE d = 0.0;
|
||||
|
||||
|
@ -669,14 +664,14 @@ HRESULT to_uint32(script_ctx_t *ctx, jsval_t val, DWORD *ret)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static BSTR int_to_bstr(int i)
|
||||
static jsstr_t *int_to_string(int i)
|
||||
{
|
||||
WCHAR buf[12], *p;
|
||||
BOOL neg = FALSE;
|
||||
|
||||
if(!i) {
|
||||
static const WCHAR zeroW[] = {'0',0};
|
||||
return SysAllocString(zeroW);
|
||||
return jsstr_alloc(zeroW);
|
||||
}
|
||||
|
||||
if(i < 0) {
|
||||
|
@ -696,24 +691,24 @@ static BSTR int_to_bstr(int i)
|
|||
else
|
||||
p++;
|
||||
|
||||
return SysAllocString(p);
|
||||
return jsstr_alloc(p);
|
||||
}
|
||||
|
||||
HRESULT double_to_bstr(double n, BSTR *str)
|
||||
HRESULT double_to_string(double n, jsstr_t **str)
|
||||
{
|
||||
const WCHAR NaNW[] = {'N','a','N',0};
|
||||
const WCHAR InfinityW[] = {'-','I','n','f','i','n','i','t','y',0};
|
||||
|
||||
if(isnan(n)) {
|
||||
*str = SysAllocString(NaNW);
|
||||
*str = jsstr_nan();
|
||||
}else if(isinf(n)) {
|
||||
*str = SysAllocString(n<0 ? InfinityW : InfinityW+1);
|
||||
*str = jsstr_alloc(n<0 ? InfinityW : InfinityW+1);
|
||||
}else if(is_int32(n)) {
|
||||
*str = int_to_bstr(n);
|
||||
*str = int_to_string(n);
|
||||
}else {
|
||||
VARIANT strv, v;
|
||||
HRESULT hres;
|
||||
|
||||
/* FIXME: Don't use VariantChangeTypeEx */
|
||||
V_VT(&v) = VT_R8;
|
||||
V_R8(&v) = n;
|
||||
V_VT(&strv) = VT_EMPTY;
|
||||
|
@ -721,14 +716,15 @@ HRESULT double_to_bstr(double n, BSTR *str)
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
*str = V_BSTR(&strv);
|
||||
*str = jsstr_alloc(V_BSTR(&strv));
|
||||
SysFreeString(V_BSTR(&strv));
|
||||
}
|
||||
|
||||
return *str ? S_OK : E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 9.8 */
|
||||
HRESULT to_string(script_ctx_t *ctx, jsval_t val, BSTR *str)
|
||||
HRESULT to_string(script_ctx_t *ctx, jsval_t val, jsstr_t **str)
|
||||
{
|
||||
const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
|
||||
const WCHAR nullW[] = {'n','u','l','l',0};
|
||||
|
@ -737,15 +733,15 @@ HRESULT to_string(script_ctx_t *ctx, jsval_t val, BSTR *str)
|
|||
|
||||
switch(jsval_type(val)) {
|
||||
case JSV_UNDEFINED:
|
||||
*str = SysAllocString(undefinedW);
|
||||
*str = jsstr_alloc(undefinedW);
|
||||
break;
|
||||
case JSV_NULL:
|
||||
*str = SysAllocString(nullW);
|
||||
*str = jsstr_alloc(nullW);
|
||||
break;
|
||||
case JSV_NUMBER:
|
||||
return double_to_bstr(get_number(val), str);
|
||||
return double_to_string(get_number(val), str);
|
||||
case JSV_STRING:
|
||||
*str = clone_bstr(get_string(val));
|
||||
*str = jsstr_addref(get_string(val));
|
||||
break;
|
||||
case JSV_OBJECT: {
|
||||
jsval_t prim;
|
||||
|
@ -760,7 +756,7 @@ HRESULT to_string(script_ctx_t *ctx, jsval_t val, BSTR *str)
|
|||
return hres;
|
||||
}
|
||||
case JSV_BOOL:
|
||||
*str = SysAllocString(get_bool(val) ? trueW : falseW);
|
||||
*str = jsstr_alloc(get_bool(val) ? trueW : falseW);
|
||||
break;
|
||||
default:
|
||||
FIXME("unsupported %s\n", debugstr_jsval(val));
|
||||
|
@ -778,7 +774,7 @@ HRESULT to_object(script_ctx_t *ctx, jsval_t val, IDispatch **disp)
|
|||
|
||||
switch(jsval_type(val)) {
|
||||
case JSV_STRING:
|
||||
hres = create_string(ctx, get_string(val), SysStringLen(get_string(val)), &dispex);
|
||||
hres = create_string(ctx, get_string(val), &dispex);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -883,11 +879,20 @@ HRESULT variant_change_type(script_ctx_t *ctx, VARIANT *dst, VARIANT *src, VARTY
|
|||
break;
|
||||
}
|
||||
case VT_BSTR: {
|
||||
BSTR str;
|
||||
jsstr_t *str;
|
||||
|
||||
hres = to_string(ctx, val, &str);
|
||||
if(SUCCEEDED(hres))
|
||||
V_BSTR(dst) = str;
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
|
||||
if(str->length_flags & JSSTR_FLAG_NULLBSTR) {
|
||||
V_BSTR(dst) = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
V_BSTR(dst) = SysAllocStringLen(str->str, jsstr_length(str));
|
||||
if(!V_BSTR(dst))
|
||||
hres = E_OUTOFMEMORY;
|
||||
break;
|
||||
}
|
||||
case VT_EMPTY:
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#ifndef JSVAL_H
|
||||
#define JSVAL_H
|
||||
|
||||
#include "jsstr.h"
|
||||
|
||||
/*
|
||||
* jsval_t structure is used to represent JavaScript dynamically-typed values.
|
||||
* It's a (type,value) pair, usually represented as a structure of enum (type)
|
||||
|
@ -56,7 +58,7 @@ struct _jsval_t {
|
|||
struct {
|
||||
union {
|
||||
IDispatch *obj;
|
||||
BSTR str;
|
||||
jsstr_t *str;
|
||||
BOOL b;
|
||||
VARIANT *v;
|
||||
UINT_PTR as_uintptr;
|
||||
|
@ -68,7 +70,7 @@ struct _jsval_t {
|
|||
jsval_type_t type;
|
||||
union {
|
||||
IDispatch *obj;
|
||||
BSTR str;
|
||||
jsstr_t *str;
|
||||
double n;
|
||||
BOOL b;
|
||||
VARIANT *v;
|
||||
|
@ -104,7 +106,7 @@ static inline jsval_t jsval_bool(BOOL b)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline jsval_t jsval_string(BSTR str)
|
||||
static inline jsval_t jsval_string(jsstr_t *str)
|
||||
{
|
||||
jsval_t ret;
|
||||
__JSVAL_TYPE(ret) = JSV_STRING;
|
||||
|
@ -224,7 +226,7 @@ static inline double get_number(jsval_t v)
|
|||
return v.u.n;
|
||||
}
|
||||
|
||||
static inline BSTR get_string(jsval_t v)
|
||||
static inline jsstr_t *get_string(jsval_t v)
|
||||
{
|
||||
return __JSVAL_STR(v);
|
||||
}
|
||||
|
|
|
@ -91,12 +91,13 @@ static inline void dtoa(double d, WCHAR *buf, int size, int *dec_point)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void number_to_fixed(double val, int prec, BSTR *out)
|
||||
static inline jsstr_t *number_to_fixed(double val, int prec)
|
||||
{
|
||||
WCHAR buf[NUMBER_DTOA_SIZE];
|
||||
int dec_point, size, buf_size, buf_pos;
|
||||
BOOL neg = FALSE;
|
||||
BSTR str;
|
||||
jsstr_t *ret;
|
||||
WCHAR *str;
|
||||
|
||||
if(val < 0) {
|
||||
neg = TRUE;
|
||||
|
@ -122,7 +123,11 @@ static inline void number_to_fixed(double val, int prec, BSTR *out)
|
|||
if(prec)
|
||||
size += prec+1;
|
||||
|
||||
str = SysAllocStringLen(NULL, size);
|
||||
ret = jsstr_alloc_buf(size);
|
||||
if(!ret)
|
||||
return NULL;
|
||||
|
||||
str = ret->str;
|
||||
size = buf_pos = 0;
|
||||
if(neg)
|
||||
str[size++] = '-';
|
||||
|
@ -146,16 +151,16 @@ static inline void number_to_fixed(double val, int prec, BSTR *out)
|
|||
}
|
||||
}
|
||||
str[size++] = 0;
|
||||
|
||||
*out = str;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void number_to_exponential(double val, int prec, BSTR *out)
|
||||
static inline jsstr_t *number_to_exponential(double val, int prec)
|
||||
{
|
||||
WCHAR buf[NUMBER_DTOA_SIZE], *pbuf;
|
||||
int dec_point, size, buf_size, exp_size = 1;
|
||||
BOOL neg = FALSE;
|
||||
BSTR str;
|
||||
jsstr_t *ret;
|
||||
WCHAR *str;
|
||||
|
||||
if(val < 0) {
|
||||
neg = TRUE;
|
||||
|
@ -185,8 +190,12 @@ static inline void number_to_exponential(double val, int prec, BSTR *out)
|
|||
size = prec+4+exp_size; /* 4 = strlen(0.e+) */
|
||||
if(neg)
|
||||
size++;
|
||||
str = SysAllocStringLen(NULL, size);
|
||||
|
||||
ret = jsstr_alloc_buf(size);
|
||||
if(!ret)
|
||||
return NULL;
|
||||
|
||||
str = ret->str;
|
||||
size = 0;
|
||||
pbuf = buf;
|
||||
if(neg)
|
||||
|
@ -214,7 +223,7 @@ static inline void number_to_exponential(double val, int prec, BSTR *out)
|
|||
size += exp_size;
|
||||
str[size] = 0;
|
||||
|
||||
*out = str;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 15.7.4.2 */
|
||||
|
@ -224,7 +233,7 @@ static HRESULT Number_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
|
|||
NumberInstance *number;
|
||||
INT radix = 10;
|
||||
DOUBLE val;
|
||||
BSTR str;
|
||||
jsstr_t *str;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
@ -326,7 +335,7 @@ static HRESULT Number_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
|
|||
}
|
||||
else buf[idx] = '\0';
|
||||
|
||||
str = SysAllocString(buf);
|
||||
str = jsstr_alloc(buf);
|
||||
if(!str)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
@ -334,7 +343,7 @@ static HRESULT Number_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
|
|||
if(r)
|
||||
*r = jsval_string(str);
|
||||
else
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -351,7 +360,7 @@ static HRESULT Number_toFixed(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
|||
NumberInstance *number;
|
||||
DOUBLE val;
|
||||
INT prec = 0;
|
||||
BSTR str;
|
||||
jsstr_t *str;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
@ -374,13 +383,15 @@ static HRESULT Number_toFixed(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
}else {
|
||||
number_to_fixed(val, prec, &str);
|
||||
str = number_to_fixed(val, prec);
|
||||
if(!str)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if(r)
|
||||
*r = jsval_string(str);
|
||||
else
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -390,7 +401,7 @@ static HRESULT Number_toExponential(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla
|
|||
NumberInstance *number;
|
||||
DOUBLE val;
|
||||
INT prec = 0;
|
||||
BSTR str;
|
||||
jsstr_t *str;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
@ -415,13 +426,15 @@ static HRESULT Number_toExponential(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla
|
|||
}else {
|
||||
if(!prec)
|
||||
prec--;
|
||||
number_to_exponential(val, prec, &str);
|
||||
str = number_to_exponential(val, prec);
|
||||
if(!str)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if(r)
|
||||
*r = jsval_string(str);
|
||||
else
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -430,8 +443,8 @@ static HRESULT Number_toPrecision(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
|||
{
|
||||
NumberInstance *number;
|
||||
INT prec = 0, size;
|
||||
jsstr_t *str;
|
||||
DOUBLE val;
|
||||
BSTR str;
|
||||
HRESULT hres;
|
||||
|
||||
if(!(number = number_this(jsthis)))
|
||||
|
@ -458,15 +471,17 @@ static HRESULT Number_toPrecision(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
|||
size = 1;
|
||||
|
||||
if(size > prec)
|
||||
number_to_exponential(val, prec-1, &str);
|
||||
str = number_to_exponential(val, prec-1);
|
||||
else
|
||||
number_to_fixed(val, prec-size, &str);
|
||||
str = number_to_fixed(val, prec-size);
|
||||
if(!str)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if(r)
|
||||
*r = jsval_string(str);
|
||||
else
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,11 +67,13 @@ static HRESULT Object_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
|
|||
}
|
||||
|
||||
if(r) {
|
||||
BSTR ret = SysAllocStringLen(NULL, 9+strlenW(str));
|
||||
jsstr_t *ret;
|
||||
|
||||
ret = jsstr_alloc_buf(9+strlenW(str));
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
sprintfW(ret, formatW, str);
|
||||
sprintfW(ret->str, formatW, str);
|
||||
*r = jsval_string(ret);
|
||||
}
|
||||
|
||||
|
@ -106,7 +108,7 @@ static HRESULT Object_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
|||
static HRESULT Object_hasOwnProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
|
||||
jsval_t *r)
|
||||
{
|
||||
BSTR name;
|
||||
jsstr_t *name;
|
||||
DISPID id;
|
||||
HRESULT hres;
|
||||
|
||||
|
@ -125,7 +127,7 @@ static HRESULT Object_hasOwnProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD fl
|
|||
if(is_jsdisp(jsthis)) {
|
||||
BOOL result;
|
||||
|
||||
hres = jsdisp_is_own_prop(jsthis->u.jsdisp, name, &result);
|
||||
hres = jsdisp_is_own_prop(jsthis->u.jsdisp, name->str, &result);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -135,11 +137,19 @@ static HRESULT Object_hasOwnProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD fl
|
|||
}
|
||||
|
||||
if(is_dispex(jsthis)) {
|
||||
hres = IDispatchEx_GetDispID(jsthis->u.dispex, name,
|
||||
BSTR bstr;
|
||||
|
||||
bstr = SysAllocStringLen(name->str, jsstr_length(name));
|
||||
if(!bstr)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
hres = IDispatchEx_GetDispID(jsthis->u.dispex, bstr,
|
||||
make_grfdex(ctx, fdexNameCaseSensitive), &id);
|
||||
SysFreeString(bstr);
|
||||
} else {
|
||||
OLECHAR *names = name->str;
|
||||
hres = IDispatch_GetIDsOfNames(jsthis->u.disp, &IID_NULL,
|
||||
&name, 1, ctx->lcid, &id);
|
||||
&names, 1, ctx->lcid, &id);
|
||||
}
|
||||
|
||||
if(r)
|
||||
|
@ -170,7 +180,7 @@ static HRESULT Object_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
|
|||
case INVOKE_FUNC:
|
||||
return throw_type_error(ctx, JS_E_FUNCTION_EXPECTED, NULL);
|
||||
case DISPATCH_PROPERTYGET: {
|
||||
BSTR ret = SysAllocString(default_valueW);
|
||||
jsstr_t *ret = jsstr_alloc(default_valueW);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
*r = jsval_string(ret);
|
||||
|
|
|
@ -3372,13 +3372,13 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, D
|
|||
|
||||
/* FIXME: We often already have a copy of input string that we could use to store last match */
|
||||
if(!(rem_flags & REM_NO_CTX_UPDATE) &&
|
||||
(!ctx->last_match || len != SysStringLen(ctx->last_match) || strncmpW(ctx->last_match, str, len))) {
|
||||
BSTR last_match;
|
||||
(!ctx->last_match || len != jsstr_length(ctx->last_match) || strncmpW(ctx->last_match->str, str, len))) {
|
||||
jsstr_t *last_match;
|
||||
|
||||
last_match = SysAllocStringLen(str, len);
|
||||
last_match = jsstr_alloc_len(str, len);
|
||||
if(!last_match)
|
||||
return E_OUTOFMEMORY;
|
||||
SysFreeString(ctx->last_match);
|
||||
jsstr_release(ctx->last_match);
|
||||
ctx->last_match = last_match;
|
||||
}
|
||||
|
||||
|
@ -3406,7 +3406,7 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, D
|
|||
ctx->match_parens[i].str = NULL;
|
||||
ctx->match_parens[i].len = 0;
|
||||
}else {
|
||||
ctx->match_parens[i].str = ctx->last_match + result->parens[i].index;
|
||||
ctx->match_parens[i].str = ctx->last_match->str + result->parens[i].index;
|
||||
ctx->match_parens[i].len = result->parens[i].length;
|
||||
}
|
||||
}
|
||||
|
@ -3508,7 +3508,7 @@ static HRESULT RegExp_source(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
|
|||
switch(flags) {
|
||||
case DISPATCH_PROPERTYGET: {
|
||||
RegExpInstance *This = regexp_from_vdisp(jsthis);
|
||||
BSTR ret = SysAllocString(This->str);
|
||||
jsstr_t *ret = jsstr_alloc(This->str);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
*r = jsval_string(ret);
|
||||
|
@ -3595,11 +3595,11 @@ static HRESULT RegExp_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT create_match_array(script_ctx_t *ctx, BSTR input, const match_result_t *result,
|
||||
static HRESULT create_match_array(script_ctx_t *ctx, jsstr_t *input, const match_result_t *result,
|
||||
const match_result_t *parens, DWORD parens_cnt, IDispatch **ret)
|
||||
{
|
||||
jsdisp_t *array;
|
||||
BSTR str;
|
||||
jsstr_t *str;
|
||||
int i;
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
|
@ -3613,38 +3613,38 @@ static HRESULT create_match_array(script_ctx_t *ctx, BSTR input, const match_res
|
|||
return hres;
|
||||
|
||||
for(i=0; i < parens_cnt; i++) {
|
||||
str = SysAllocStringLen(parens[i].str, parens[i].len);
|
||||
str = jsstr_alloc_len(parens[i].str, parens[i].len);
|
||||
if(!str) {
|
||||
hres = E_OUTOFMEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
hres = jsdisp_propput_idx(array, i+1, jsval_string(str));
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
}
|
||||
|
||||
while(SUCCEEDED(hres)) {
|
||||
hres = jsdisp_propput_name(array, indexW, jsval_number(result->str-input));
|
||||
hres = jsdisp_propput_name(array, indexW, jsval_number(result->str-input->str));
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
|
||||
hres = jsdisp_propput_name(array, lastIndexW, jsval_number(result->str-input+result->len));
|
||||
hres = jsdisp_propput_name(array, lastIndexW, jsval_number(result->str-input->str+result->len));
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
|
||||
hres = jsdisp_propput_name(array, inputW, jsval_string(input));
|
||||
hres = jsdisp_propput_name(array, inputW, jsval_string(jsstr_addref(input)));
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
|
||||
str = SysAllocStringLen(result->str, result->len);
|
||||
str = jsstr_alloc_len(result->str, result->len);
|
||||
if(!str) {
|
||||
hres = E_OUTOFMEMORY;
|
||||
break;
|
||||
}
|
||||
hres = jsdisp_propput_name(array, zeroW, jsval_string(str));
|
||||
SysFreeString(str);
|
||||
jsstr_release(str);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3657,13 +3657,13 @@ static HRESULT create_match_array(script_ctx_t *ctx, BSTR input, const match_res
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT run_exec(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t arg, BSTR *input,
|
||||
static HRESULT run_exec(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t arg, jsstr_t **input,
|
||||
match_result_t *match, match_result_t **parens, DWORD *parens_cnt, BOOL *ret)
|
||||
{
|
||||
RegExpInstance *regexp;
|
||||
DWORD parens_size = 0, last_index = 0, length;
|
||||
const WCHAR *cp;
|
||||
BSTR string;
|
||||
jsstr_t *string;
|
||||
HRESULT hres;
|
||||
|
||||
if(!is_vclass(jsthis, JSCLASS_REGEXP)) {
|
||||
|
@ -3676,36 +3676,34 @@ static HRESULT run_exec(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t arg, BSTR *i
|
|||
hres = to_string(ctx, arg, &string);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
length = SysStringLen(string);
|
||||
length = jsstr_length(string);
|
||||
|
||||
if(regexp->jsregexp->flags & JSREG_GLOB) {
|
||||
if(regexp->last_index < 0) {
|
||||
SysFreeString(string);
|
||||
jsstr_release(string);
|
||||
set_last_index(regexp, 0);
|
||||
*ret = FALSE;
|
||||
if(input) {
|
||||
*input = NULL;
|
||||
}
|
||||
if(input)
|
||||
*input = jsstr_empty();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
last_index = regexp->last_index;
|
||||
}
|
||||
|
||||
cp = string + last_index;
|
||||
hres = regexp_match_next(ctx, ®exp->dispex, REM_RESET_INDEX, string, length, &cp, parens,
|
||||
cp = string->str + last_index;
|
||||
hres = regexp_match_next(ctx, ®exp->dispex, REM_RESET_INDEX, string->str, length, &cp, parens,
|
||||
parens ? &parens_size : NULL, parens_cnt, match);
|
||||
if(FAILED(hres)) {
|
||||
SysFreeString(string);
|
||||
jsstr_release(string);
|
||||
return hres;
|
||||
}
|
||||
|
||||
*ret = hres == S_OK;
|
||||
if(input) {
|
||||
if(input)
|
||||
*input = string;
|
||||
}else {
|
||||
SysFreeString(string);
|
||||
}
|
||||
else
|
||||
jsstr_release(string);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -3715,12 +3713,12 @@ static HRESULT RegExp_exec(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsig
|
|||
match_result_t *parens = NULL, match;
|
||||
DWORD parens_cnt = 0;
|
||||
BOOL b;
|
||||
BSTR string;
|
||||
jsstr_t *string;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
hres = run_exec(ctx, jsthis, argc ? argv[0] : jsval_string(NULL), &string, &match, &parens, &parens_cnt, &b);
|
||||
hres = run_exec(ctx, jsthis, argc ? argv[0] : jsval_string(jsstr_empty()), &string, &match, &parens, &parens_cnt, &b);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -3737,7 +3735,7 @@ static HRESULT RegExp_exec(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsig
|
|||
}
|
||||
|
||||
heap_free(parens);
|
||||
SysFreeString(string);
|
||||
jsstr_release(string);
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
@ -3745,21 +3743,21 @@ static HRESULT RegExp_test(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsig
|
|||
jsval_t *r)
|
||||
{
|
||||
match_result_t match;
|
||||
BSTR undef_str;
|
||||
jsstr_t *undef_str;
|
||||
BOOL b;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(!argc) {
|
||||
undef_str = SysAllocString(undefinedW);
|
||||
undef_str = jsstr_alloc(undefinedW);
|
||||
if(!undef_str)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
hres = run_exec(ctx, jsthis, argc ? argv[0] : jsval_string(undef_str), NULL, &match, NULL, NULL, &b);
|
||||
if(!argc)
|
||||
SysFreeString(undef_str);
|
||||
jsstr_release(undef_str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -3890,7 +3888,7 @@ HRESULT create_regexp(script_ctx_t *ctx, const WCHAR *exp, int len, DWORD flags,
|
|||
|
||||
HRESULT create_regexp_var(script_ctx_t *ctx, jsval_t src_arg, jsval_t *flags_arg, jsdisp_t **ret)
|
||||
{
|
||||
const WCHAR *opt = emptyW, *src;
|
||||
jsstr_t *src, *opt = NULL;
|
||||
DWORD flags;
|
||||
HRESULT hres;
|
||||
|
||||
|
@ -3927,14 +3925,14 @@ HRESULT create_regexp_var(script_ctx_t *ctx, jsval_t src_arg, jsval_t *flags_arg
|
|||
opt = get_string(*flags_arg);
|
||||
}
|
||||
|
||||
hres = parse_regexp_flags(opt, strlenW(opt), &flags);
|
||||
hres = parse_regexp_flags(opt ? opt->str : NULL, opt ? jsstr_length(opt) : 0, &flags);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
return create_regexp(ctx, src, -1, flags, ret);
|
||||
return create_regexp(ctx, src->str, -1, flags, ret);
|
||||
}
|
||||
|
||||
HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, BSTR str, jsval_t *r)
|
||||
HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, jsstr_t *str, jsval_t *r)
|
||||
{
|
||||
static const WCHAR indexW[] = {'i','n','d','e','x',0};
|
||||
static const WCHAR inputW[] = {'i','n','p','u','t',0};
|
||||
|
@ -3942,18 +3940,18 @@ HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, BSTR str, jsval_t *
|
|||
|
||||
RegExpInstance *regexp = (RegExpInstance*)re;
|
||||
match_result_t *match_result;
|
||||
DWORD match_cnt, i, length;
|
||||
unsigned match_cnt, i, length;
|
||||
jsdisp_t *array;
|
||||
HRESULT hres;
|
||||
|
||||
length = SysStringLen(str);
|
||||
length = jsstr_length(str);
|
||||
|
||||
if(!(regexp->jsregexp->flags & JSREG_GLOB)) {
|
||||
match_result_t match, *parens = NULL;
|
||||
DWORD parens_cnt, parens_size = 0;
|
||||
const WCHAR *cp = str;
|
||||
const WCHAR *cp = str->str;
|
||||
|
||||
hres = regexp_match_next(ctx, ®exp->dispex, 0, str, length, &cp, &parens, &parens_size, &parens_cnt, &match);
|
||||
hres = regexp_match_next(ctx, ®exp->dispex, 0, str->str, length, &cp, &parens, &parens_size, &parens_cnt, &match);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -3973,7 +3971,7 @@ HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, BSTR str, jsval_t *
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
hres = regexp_match(ctx, ®exp->dispex, str, length, FALSE, &match_result, &match_cnt);
|
||||
hres = regexp_match(ctx, ®exp->dispex, str->str, length, FALSE, &match_result, &match_cnt);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -3990,27 +3988,27 @@ HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, BSTR str, jsval_t *
|
|||
return hres;
|
||||
|
||||
for(i=0; i < match_cnt; i++) {
|
||||
BSTR tmp_str;
|
||||
jsstr_t *tmp_str;
|
||||
|
||||
tmp_str = SysAllocStringLen(match_result[i].str, match_result[i].len);
|
||||
tmp_str = jsstr_alloc_len(match_result[i].str, match_result[i].len);
|
||||
if(!tmp_str) {
|
||||
hres = E_OUTOFMEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
hres = jsdisp_propput_idx(array, i, jsval_string(tmp_str));
|
||||
SysFreeString(tmp_str);
|
||||
jsstr_release(tmp_str);
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
}
|
||||
|
||||
while(SUCCEEDED(hres)) {
|
||||
hres = jsdisp_propput_name(array, indexW, jsval_number(match_result[match_cnt-1].str-str));
|
||||
hres = jsdisp_propput_name(array, indexW, jsval_number(match_result[match_cnt-1].str-str->str));
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
|
||||
hres = jsdisp_propput_name(array, lastIndexW,
|
||||
jsval_number(match_result[match_cnt-1].str-str+match_result[match_cnt-1].len));
|
||||
jsval_number(match_result[match_cnt-1].str-str->str+match_result[match_cnt-1].len));
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
|
||||
|
@ -4031,9 +4029,9 @@ static HRESULT global_idx(script_ctx_t *ctx, DWORD flags, DWORD idx, jsval_t *r)
|
|||
{
|
||||
switch(flags) {
|
||||
case DISPATCH_PROPERTYGET: {
|
||||
BSTR ret = NULL;
|
||||
jsstr_t *ret;
|
||||
|
||||
ret = SysAllocStringLen(ctx->match_parens[idx].str, ctx->match_parens[idx].len);
|
||||
ret = jsstr_alloc_len(ctx->match_parens[idx].str, ctx->match_parens[idx].len);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
|
@ -4120,9 +4118,9 @@ static HRESULT RegExpConstr_leftContext(script_ctx_t *ctx, vdisp_t *jsthis, WORD
|
|||
|
||||
switch(flags) {
|
||||
case DISPATCH_PROPERTYGET: {
|
||||
BSTR ret;
|
||||
jsstr_t *ret;
|
||||
|
||||
ret = SysAllocStringLen(ctx->last_match, ctx->last_match_index);
|
||||
ret = jsstr_alloc_len(ctx->last_match->str, ctx->last_match_index);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
|
@ -4146,9 +4144,9 @@ static HRESULT RegExpConstr_rightContext(script_ctx_t *ctx, vdisp_t *jsthis, WOR
|
|||
|
||||
switch(flags) {
|
||||
case DISPATCH_PROPERTYGET: {
|
||||
BSTR ret;
|
||||
jsstr_t *ret;
|
||||
|
||||
ret = SysAllocString(ctx->last_match+ctx->last_match_index+ctx->last_match_length);
|
||||
ret = jsstr_alloc(ctx->last_match->str+ctx->last_match_index+ctx->last_match_length);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue