jscript: Use custom string container instead of BSTR.

oldstable
Jacek Caban 2012-10-11 12:16:01 +02:00 committed by Alexandre Julliard
parent f8e1550ebb
commit 7f1e3300fe
22 changed files with 971 additions and 833 deletions

View File

@ -15,6 +15,7 @@ C_SRCS = \
global.c \
jscript.c \
jscript_main.c \
jsstr.c \
jsutils.c \
lex.c \
math.c \

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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");

View File

@ -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]);

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

@ -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:

View File

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

View File

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

View File

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

View File

@ -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, &regexp->dispex, REM_RESET_INDEX, string, length, &cp, parens,
cp = string->str + last_index;
hres = regexp_match_next(ctx, &regexp->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, &regexp->dispex, 0, str, length, &cp, &parens, &parens_size, &parens_cnt, &match);
hres = regexp_match_next(ctx, &regexp->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, &regexp->dispex, str, length, FALSE, &match_result, &match_cnt);
hres = regexp_match(ctx, &regexp->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