Commit 7f1e3300 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

jscript: Use custom string container instead of BSTR.

parent f8e1550e
......@@ -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;
jsdisp = iface_to_jsdisp((IUnknown*)disp);
if(jsdisp) {
hres = jsdisp_get_id(jsdisp, name, flags, id);
jsdisp_release(jsdisp);
return hres;
}
*id = 0;
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
if(FAILED(hres)) {
TRACE("using IDispatch\n");
if(SUCCEEDED(hres)) {
BSTR str = name_bstr;
*id = 0;
return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id);
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;
}
*id = 0;
hres = IDispatchEx_GetDispID(dispex, name, make_grfdex(ctx, flags|fdexNameCaseSensitive), id);
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);
if(SUCCEEDED(hres)) {
if(is_string(r))
rstr = get_string(r);
else
hres = to_string(ctx, r, &rstr);
}
hres = to_string(ctx, l, &lstr);
if(SUCCEEDED(hres))
hres = to_string(ctx, r, &rstr);
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);
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(!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;
name_len = SysStringLen(name);
msg_len = SysStringLen(msg);
unsigned name_len = name ? jsstr_length(name) : 0;
unsigned msg_len = msg ? jsstr_length(msg) : 0;
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;
......
/*
* 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);
}
/*
* 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, &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;
......
......@@ -29,9 +29,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(jscript);
typedef struct {
jsdisp_t dispex;
WCHAR *str;
DWORD length;
jsstr_t *str;
} StringInstance;
static const WCHAR lengthW[] = {'l','e','n','g','t','h',0};
......@@ -79,25 +77,16 @@ static inline StringInstance *string_this(vdisp_t *jsthis)
return is_vclass(jsthis, JSCLASS_STRING) ? string_from_vdisp(jsthis) : NULL;
}
static HRESULT get_string_val(script_ctx_t *ctx, vdisp_t *jsthis, const WCHAR **str, DWORD *len, BSTR *val_str)
static HRESULT get_string_val(script_ctx_t *ctx, vdisp_t *jsthis, jsstr_t **val)
{
StringInstance *string;
HRESULT hres;
if((string = string_this(jsthis))) {
*str = string->str;
*len = string->length;
*val_str = NULL;
*val = jsstr_addref(string->str);
return S_OK;
}
hres = to_string(ctx, jsval_disp(jsthis->u.disp), val_str);
if(FAILED(hres))
return hres;
*str = *val_str;
*len = SysStringLen(*val_str);
return S_OK;
return to_string(ctx, jsval_disp(jsthis->u.disp), val);
}
static HRESULT String_length(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
......@@ -109,7 +98,7 @@ static HRESULT String_length(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
case DISPATCH_PROPERTYGET: {
StringInstance *string = string_from_vdisp(jsthis);
*r = jsval_number(string->length);
*r = jsval_number(jsstr_length(string->str));
break;
}
default:
......@@ -129,13 +118,8 @@ static HRESULT stringobj_to_string(vdisp_t *jsthis, jsval_t *r)
return E_FAIL;
}
if(r) {
BSTR str = SysAllocString(string->str);
if(!str)
return E_OUTOFMEMORY;
*r = jsval_string(str);
}
if(r)
*r = jsval_string(jsstr_addref(string->str));
return S_OK;
}
......@@ -159,29 +143,27 @@ static HRESULT String_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
static HRESULT do_attributeless_tag_format(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r, const WCHAR *tagname)
{
const WCHAR *str;
DWORD length;
BSTR val_str = NULL;
jsstr_t *str;
HRESULT hres;
static const WCHAR tagfmt[] = {'<','%','s','>','%','s','<','/','%','s','>',0};
hres = get_string_val(ctx, jsthis, &str, &length, &val_str);
hres = get_string_val(ctx, jsthis, &str);
if(FAILED(hres))
return hres;
if(r) {
BSTR ret = SysAllocStringLen(NULL, length + 2*strlenW(tagname) + 5);
jsstr_t *ret = jsstr_alloc_buf(jsstr_length(str) + 2*strlenW(tagname) + 5);
if(!ret) {
SysFreeString(val_str);
jsstr_release(str);
return E_OUTOFMEMORY;
}
sprintfW(ret, tagfmt, tagname, str, tagname);
sprintfW(ret->str, tagfmt, tagname, str->str, tagname);
*r = jsval_string(ret);
}
SysFreeString(val_str);
jsstr_release(str);
return S_OK;
}
......@@ -192,56 +174,44 @@ static HRESULT do_attribute_tag_format(script_ctx_t *ctx, vdisp_t *jsthis, unsig
= {'<','%','s',' ','%','s','=','\"','%','s','\"','>','%','s','<','/','%','s','>',0};
static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
StringInstance *string;
const WCHAR *str;
DWORD length;
BSTR attr_value, val_str = NULL;
jsstr_t *str, *attr_value = NULL;
const WCHAR *attr_str;
unsigned attr_len;
HRESULT hres;
if(!(string = string_this(jsthis))) {
hres = to_string(ctx, jsval_disp(jsthis->u.disp), &val_str);
if(FAILED(hres))
return hres;
str = val_str;
length = SysStringLen(val_str);
}
else {
str = string->str;
length = string->length;
}
hres = get_string_val(ctx, jsthis, &str);
if(FAILED(hres))
return hres;
if(argc) {
hres = to_string(ctx, argv[0], &attr_value);
if(FAILED(hres)) {
SysFreeString(val_str);
jsstr_release(str);
return hres;
}
}
else {
attr_value = SysAllocString(undefinedW);
if(!attr_value) {
SysFreeString(val_str);
return E_OUTOFMEMORY;
}
attr_str = attr_value->str;
attr_len = jsstr_length(attr_value);
}else {
attr_str = undefinedW;
attr_len = sizeof(undefinedW)/sizeof(WCHAR)-1;
}
if(r) {
BSTR ret = SysAllocStringLen(NULL, length + 2*strlenW(tagname)
+ strlenW(attr) + SysStringLen(attr_value) + 9);
if(!ret) {
SysFreeString(attr_value);
SysFreeString(val_str);
return E_OUTOFMEMORY;
}
jsstr_t *ret;
sprintfW(ret, tagfmtW, tagname, attr, attr_value, str, tagname);
*r = jsval_string(ret);
ret = jsstr_alloc_buf(2*strlenW(tagname) + strlenW(attr) + attr_len + jsstr_length(str) + 9);
if(ret) {
sprintfW(ret->str, tagfmtW, tagname, attr, attr_str, str->str, tagname);
*r = jsval_string(ret);
}else {
hres = E_OUTOFMEMORY;
}
}
SysFreeString(attr_value);
SysFreeString(val_str);
return S_OK;
if(attr_value)
jsstr_release(attr_value);
jsstr_release(str);
return hres;
}
static HRESULT String_anchor(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
......@@ -278,15 +248,13 @@ static HRESULT String_bold(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsig
static HRESULT String_charAt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
{
const WCHAR *str;
DWORD length;
BSTR ret, val_str;
jsstr_t *str, *ret;
INT pos = 0;
HRESULT hres;
TRACE("\n");
hres = get_string_val(ctx, jsthis, &str, &length, &val_str);
hres = get_string_val(ctx, jsthis, &str);
if(FAILED(hres))
return hres;
......@@ -295,24 +263,23 @@ static HRESULT String_charAt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
hres = to_integer(ctx, argv[0], &d);
if(FAILED(hres)) {
SysFreeString(val_str);
jsstr_release(str);
return hres;
}
pos = is_int32(d) ? d : -1;
}
if(!r) {
SysFreeString(val_str);
jsstr_release(str);
return S_OK;
}
if(0 <= pos && pos < length)
ret = SysAllocStringLen(str+pos, 1);
else
ret = SysAllocStringLen(NULL, 0);
SysFreeString(val_str);
if(!ret) {
return E_OUTOFMEMORY;
if(0 <= pos && pos < jsstr_length(str)) {
ret = jsstr_alloc_len(str->str+pos, 1);
if(!ret)
return E_OUTOFMEMORY;
}else {
ret = jsstr_empty();
}
*r = jsval_string(ret);
......@@ -323,14 +290,13 @@ static HRESULT String_charAt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
static HRESULT String_charCodeAt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
{
const WCHAR *str;
BSTR val_str;
DWORD length, idx = 0;
jsstr_t *str;
DWORD idx = 0;
HRESULT hres;
TRACE("\n");
hres = get_string_val(ctx, jsthis, &str, &length, &val_str);
hres = get_string_val(ctx, jsthis, &str);
if(FAILED(hres))
return hres;
......@@ -339,12 +305,12 @@ static HRESULT String_charCodeAt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
hres = to_integer(ctx, argv[0], &d);
if(FAILED(hres)) {
SysFreeString(val_str);
jsstr_release(str);
return hres;
}
if(!is_int32(d) || d < 0 || d >= length) {
SysFreeString(val_str);
if(!is_int32(d) || d < 0 || d >= jsstr_length(str)) {
jsstr_release(str);
if(r)
*r = jsval_number(NAN);
return S_OK;
......@@ -354,9 +320,9 @@ static HRESULT String_charCodeAt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
}
if(r)
*r = jsval_number(str[idx]);
*r = jsval_number(str->str[idx]);
SysFreeString(val_str);
jsstr_release(str);
return S_OK;
}
......@@ -364,7 +330,7 @@ static HRESULT String_charCodeAt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
static HRESULT String_concat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
{
BSTR *strs = NULL, ret = NULL;
jsstr_t **strs, *ret = NULL;
DWORD len = 0, i, l, str_cnt;
WCHAR *ptr;
HRESULT hres;
......@@ -372,7 +338,7 @@ static HRESULT String_concat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
TRACE("\n");
str_cnt = argc+1;
strs = heap_alloc_zero(str_cnt * sizeof(BSTR));
strs = heap_alloc_zero(str_cnt * sizeof(*strs));
if(!strs)
return E_OUTOFMEMORY;
......@@ -386,20 +352,29 @@ static HRESULT String_concat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
}
if(SUCCEEDED(hres)) {
for(i=0; i < str_cnt; i++)
len += SysStringLen(strs[i]);
ptr = ret = SysAllocStringLen(NULL, len);
for(i=0; i < str_cnt; i++) {
l = SysStringLen(strs[i]);
memcpy(ptr, strs[i], l*sizeof(WCHAR));
ptr += l;
len += jsstr_length(strs[i]);
if(len > JSSTR_MAX_LENGTH) {
hres = E_OUTOFMEMORY;
break;
}
}
ret = jsstr_alloc_buf(len);
if(ret) {
ptr = ret->str;
for(i=0; i < str_cnt; i++) {
l = jsstr_length(strs[i]);
memcpy(ptr, strs[i]->str, l*sizeof(WCHAR));
ptr += l;
}
}else {
hres = E_OUTOFMEMORY;
}
}
for(i=0; i < str_cnt; i++)
SysFreeString(strs[i]);
jsstr_release(strs[i]);
heap_free(strs);
if(FAILED(hres))
......@@ -408,7 +383,7 @@ static HRESULT String_concat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
if(r)
*r = jsval_string(ret);
else
SysFreeString(ret);
jsstr_release(ret);
return S_OK;
}
......@@ -440,28 +415,28 @@ static HRESULT String_fontsize(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
static HRESULT String_indexOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
{
DWORD length, pos = 0;
const WCHAR *str;
BSTR search_str, val_str;
jsstr_t *search_str, *str;
int length, pos = 0;
INT ret = -1;
HRESULT hres;
TRACE("\n");
hres = get_string_val(ctx, jsthis, &str, &length, &val_str);
hres = get_string_val(ctx, jsthis, &str);
if(FAILED(hres))
return hres;
length = jsstr_length(str);
if(!argc) {
if(r)
*r = jsval_number(-1);
SysFreeString(val_str);
jsstr_release(str);
return S_OK;
}
hres = to_string(ctx, argv[0], &search_str);
if(FAILED(hres)) {
SysFreeString(val_str);
jsstr_release(str);
return hres;
}
......@@ -476,15 +451,15 @@ static HRESULT String_indexOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
if(SUCCEEDED(hres)) {
const WCHAR *ptr;
ptr = strstrW(str+pos, search_str);
ptr = strstrW(str->str+pos, search_str->str);
if(ptr)
ret = ptr - str;
ret = ptr - str->str;
else
ret = -1;
}
SysFreeString(search_str);
SysFreeString(val_str);
jsstr_release(search_str);
jsstr_release(str);
if(FAILED(hres))
return hres;
......@@ -504,32 +479,32 @@ static HRESULT String_italics(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
static HRESULT String_lastIndexOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
{
BSTR search_str, val_str;
DWORD length, pos = 0, search_len;
const WCHAR *str;
unsigned pos = 0, search_len, length;
jsstr_t *search_str, *str;
INT ret = -1;
HRESULT hres;
TRACE("\n");
hres = get_string_val(ctx, jsthis, &str, &length, &val_str);
hres = get_string_val(ctx, jsthis, &str);
if(FAILED(hres))
return hres;
if(!argc) {
if(r)
*r = jsval_number(-1);
SysFreeString(val_str);
jsstr_release(str);
return S_OK;
}
hres = to_string(ctx, argv[0], &search_str);
if(FAILED(hres)) {
SysFreeString(val_str);
jsstr_release(str);
return hres;
}
search_len = SysStringLen(search_str);
search_len = jsstr_length(search_str);
length = jsstr_length(str);
if(argc >= 2) {
double d;
......@@ -544,16 +519,16 @@ static HRESULT String_lastIndexOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
if(SUCCEEDED(hres) && length >= search_len) {
const WCHAR *ptr;
for(ptr = str+min(pos, length-search_len); ptr >= str; ptr--) {
if(!memcmp(ptr, search_str, search_len*sizeof(WCHAR))) {
ret = ptr-str;
for(ptr = str->str+min(pos, length-search_len); ptr >= str->str; ptr--) {
if(!memcmp(ptr, search_str->str, search_len*sizeof(WCHAR))) {
ret = ptr-str->str;
break;
}
}
}
SysFreeString(search_str);
SysFreeString(val_str);
jsstr_release(search_str);
jsstr_release(str);
if(FAILED(hres))
return hres;
......@@ -576,10 +551,8 @@ static HRESULT String_match(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
jsval_t *r)
{
jsdisp_t *regexp = NULL;
const WCHAR *str;
DWORD length;
BSTR val_str = NULL;
HRESULT hres = S_OK;
jsstr_t *str;
HRESULT hres;
TRACE("\n");
......@@ -598,30 +571,24 @@ static HRESULT String_match(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
}
if(!regexp) {
BSTR match_str;
jsstr_t *match_str;
hres = to_string(ctx, argv[0], &match_str);
if(FAILED(hres))
return hres;
hres = create_regexp(ctx, match_str, SysStringLen(match_str), 0, &regexp);
SysFreeString(match_str);
hres = create_regexp(ctx, match_str->str, jsstr_length(match_str), 0, &regexp);
jsstr_release(match_str);
if(FAILED(hres))
return hres;
}
hres = get_string_val(ctx, jsthis, &str, &length, &val_str);
if(SUCCEEDED(hres)) {
if(!val_str)
val_str = SysAllocStringLen(str, length);
if(val_str)
hres = regexp_string_match(ctx, regexp, val_str, r);
else
hres = E_OUTOFMEMORY;
}
hres = get_string_val(ctx, jsthis, &str);
if(SUCCEEDED(hres))
hres = regexp_string_match(ctx, regexp, str, r);
jsdisp_release(regexp);
SysFreeString(val_str);
jsstr_release(str);
return hres;
}
......@@ -659,13 +626,13 @@ static HRESULT strbuf_append(strbuf_t *buf, const WCHAR *str, DWORD len)
return S_OK;
}
static HRESULT rep_call(script_ctx_t *ctx, jsdisp_t *func, const WCHAR *str, match_result_t *match,
match_result_t *parens, DWORD parens_cnt, BSTR *ret)
static HRESULT rep_call(script_ctx_t *ctx, jsdisp_t *func, jsstr_t *str, match_result_t *match,
match_result_t *parens, DWORD parens_cnt, jsstr_t **ret)
{
jsval_t *argv;
unsigned argc;
jsval_t val;
BSTR tmp_str;
jsstr_t *tmp_str;
DWORD i;
HRESULT hres = S_OK;
......@@ -674,14 +641,14 @@ static HRESULT rep_call(script_ctx_t *ctx, jsdisp_t *func, const WCHAR *str, mat
if(!argv)
return E_OUTOFMEMORY;
tmp_str = SysAllocStringLen(match->str, match->len);
tmp_str = jsstr_alloc_len(match->str, match->len);
if(!tmp_str)
hres = E_OUTOFMEMORY;
argv[0] = jsval_string(tmp_str);
if(SUCCEEDED(hres)) {
for(i=0; i < parens_cnt; i++) {
tmp_str = SysAllocStringLen(parens[i].str, parens[i].len);
tmp_str = jsstr_alloc_len(parens[i].str, parens[i].len);
if(!tmp_str) {
hres = E_OUTOFMEMORY;
break;
......@@ -691,21 +658,15 @@ static HRESULT rep_call(script_ctx_t *ctx, jsdisp_t *func, const WCHAR *str, mat
}
if(SUCCEEDED(hres)) {
argv[parens_cnt+1] = jsval_number(match->str - str);
tmp_str = SysAllocString(str);
if(!tmp_str)
hres = E_OUTOFMEMORY;
argv[parens_cnt+2] = jsval_string(tmp_str);
argv[parens_cnt+1] = jsval_number(match->str - str->str);
argv[parens_cnt+2] = jsval_string(str);
}
if(SUCCEEDED(hres))
hres = jsdisp_call_value(func, NULL, DISPATCH_METHOD, argc, argv, &val);
for(i=0; i < parens_cnt+3; i++) {
if(i != parens_cnt+1)
SysFreeString(get_string(argv[i]));
}
for(i=0; i <= parens_cnt; i++)
jsstr_release(get_string(argv[i]));
heap_free(argv);
if(FAILED(hres))
......@@ -720,9 +681,8 @@ static HRESULT rep_call(script_ctx_t *ctx, jsdisp_t *func, const WCHAR *str, mat
static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
{
const WCHAR *str;
DWORD parens_cnt = 0, parens_size=0, rep_len=0, length;
BSTR rep_str = NULL, match_str = NULL, ret_str, val_str;
DWORD parens_cnt = 0, parens_size=0, rep_len=0;
jsstr_t *rep_str = NULL, *match_str = NULL, *str;
jsdisp_t *rep_func = NULL, *regexp = NULL;
match_result_t *parens = NULL, match = {NULL,0}, **parens_ptr = &parens;
strbuf_t ret = {NULL,0,0};
......@@ -731,20 +691,15 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
TRACE("\n");
hres = get_string_val(ctx, jsthis, &str, &length, &val_str);
hres = get_string_val(ctx, jsthis, &str);
if(FAILED(hres))
return hres;
if(!argc) {
if(r) {
if(!val_str) {
val_str = SysAllocStringLen(str, length);
if(!val_str)
return E_OUTOFMEMORY;
}
*r = jsval_string(val_str);
}
if(r)
*r = jsval_string(str);
else
jsstr_release(str);
return S_OK;
}
......@@ -759,7 +714,7 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
if(!regexp) {
hres = to_string(ctx, argv[0], &match_str);
if(FAILED(hres)) {
SysFreeString(val_str);
jsstr_release(str);
return hres;
}
}
......@@ -776,8 +731,8 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
if(!rep_func) {
hres = to_string(ctx, argv[1], &rep_str);
if(SUCCEEDED(hres)) {
rep_len = SysStringLen(rep_str);
if(!strchrW(rep_str, '$'))
rep_len = jsstr_length(rep_str);
if(!strchrW(rep_str->str, '$'))
parens_ptr = NULL;
}
}
......@@ -786,11 +741,11 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
if(SUCCEEDED(hres)) {
const WCHAR *cp, *ecp;
cp = ecp = str;
cp = ecp = str->str;
while(1) {
if(regexp) {
hres = regexp_match_next(ctx, regexp, re_flags, str, length, &cp, parens_ptr,
hres = regexp_match_next(ctx, regexp, re_flags, str->str, jsstr_length(str), &cp, parens_ptr,
&parens_size, &parens_cnt, &match);
re_flags |= REM_CHECK_GLOBAL;
......@@ -804,10 +759,10 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
if(!match.len)
cp++;
}else {
match.str = strstrW(cp, match_str);
match.str = strstrW(cp, match_str->str);
if(!match.str)
break;
match.len = SysStringLen(match_str);
match.len = jsstr_length(match_str);
cp = match.str+match.len;
}
......@@ -817,18 +772,18 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
break;
if(rep_func) {
BSTR cstr;
jsstr_t *cstr;
hres = rep_call(ctx, rep_func, str, &match, parens, parens_cnt, &cstr);
if(FAILED(hres))
break;
hres = strbuf_append(&ret, cstr, SysStringLen(cstr));
SysFreeString(cstr);
hres = strbuf_append(&ret, cstr->str, jsstr_length(cstr));
jsstr_release(cstr);
if(FAILED(hres))
break;
}else if(rep_str && regexp) {
const WCHAR *ptr = rep_str, *ptr2;
const WCHAR *ptr = rep_str->str, *ptr2;
while((ptr2 = strchrW(ptr, '$'))) {
hres = strbuf_append(&ret, ptr, ptr2-ptr);
......@@ -845,11 +800,11 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
ptr = ptr2+2;
break;
case '`':
hres = strbuf_append(&ret, str, match.str-str);
hres = strbuf_append(&ret, str->str, match.str-str->str);
ptr = ptr2+2;
break;
case '\'':
hres = strbuf_append(&ret, ecp, (str+length)-ecp);
hres = strbuf_append(&ret, ecp, (str->str+jsstr_length(str))-ecp);
ptr = ptr2+2;
break;
default: {
......@@ -882,11 +837,11 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
}
if(SUCCEEDED(hres))
hres = strbuf_append(&ret, ptr, (rep_str+rep_len)-ptr);
hres = strbuf_append(&ret, ptr, (rep_str->str+rep_len)-ptr);
if(FAILED(hres))
break;
}else if(rep_str) {
hres = strbuf_append(&ret, rep_str, rep_len);
hres = strbuf_append(&ret, rep_str->str, rep_len);
if(FAILED(hres))
break;
}else {
......@@ -902,39 +857,36 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
}
if(SUCCEEDED(hres))
hres = strbuf_append(&ret, ecp, (str+length)-ecp);
hres = strbuf_append(&ret, ecp, str->str+jsstr_length(str)-ecp);
}
if(rep_func)
jsdisp_release(rep_func);
SysFreeString(rep_str);
SysFreeString(match_str);
if(rep_str)
jsstr_release(rep_str);
if(match_str)
jsstr_release(match_str);
heap_free(parens);
if(SUCCEEDED(hres) && match.str && regexp) {
if(!val_str)
val_str = SysAllocStringLen(str, length);
if(val_str) {
SysFreeString(ctx->last_match);
ctx->last_match = val_str;
val_str = NULL;
ctx->last_match_index = match.str-str;
ctx->last_match_length = match.len;
}else {
hres = E_OUTOFMEMORY;
}
jsstr_release(ctx->last_match);
ctx->last_match = jsstr_addref(str);
ctx->last_match_index = match.str-str->str;
ctx->last_match_length = match.len;
}
if(regexp)
jsdisp_release(regexp);
SysFreeString(val_str);
jsstr_release(str);
if(SUCCEEDED(hres) && r) {
ret_str = SysAllocStringLen(ret.buf, ret.len);
jsstr_t *ret_str;
ret_str = jsstr_alloc_len(ret.buf, ret.len);
if(!ret_str)
return E_OUTOFMEMORY;
TRACE("= %s\n", debugstr_w(ret_str));
TRACE("= %s\n", debugstr_jsstr(ret_str));
*r = jsval_string(ret_str);
}
......@@ -946,22 +898,21 @@ static HRESULT String_search(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
jsval_t *r)
{
jsdisp_t *regexp = NULL;
const WCHAR *str, *cp;
const WCHAR *cp;
match_result_t match;
DWORD length;
BSTR val_str;
jsstr_t *str;
HRESULT hres;
TRACE("\n");
hres = get_string_val(ctx, jsthis, &str, &length, &val_str);
hres = get_string_val(ctx, jsthis, &str);
if(FAILED(hres))
return hres;
if(!argc) {
if(r)
*r = jsval_null();
SysFreeString(val_str);
jsstr_release(str);
return S_OK;
}
......@@ -976,20 +927,20 @@ static HRESULT String_search(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
if(!regexp) {
hres = create_regexp_var(ctx, argv[0], NULL, &regexp);
if(FAILED(hres)) {
SysFreeString(val_str);
jsstr_release(str);
return hres;
}
}
cp = str;
hres = regexp_match_next(ctx, regexp, REM_RESET_INDEX, str, length, &cp, NULL, NULL, NULL, &match);
SysFreeString(val_str);
cp = str->str;
hres = regexp_match_next(ctx, regexp, REM_RESET_INDEX, str->str, jsstr_length(str), &cp, NULL, NULL, NULL, &match);
jsstr_release(str);
jsdisp_release(regexp);
if(FAILED(hres))
return hres;
if(r)
*r = jsval_number(hres == S_OK ? match.str-str : -1);
*r = jsval_number(hres == S_OK ? match.str-str->str : -1);
return S_OK;
}
......@@ -997,23 +948,22 @@ static HRESULT String_search(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
static HRESULT String_slice(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
{
const WCHAR *str;
BSTR val_str;
DWORD length;
INT start=0, end;
int start=0, end, length;
jsstr_t *str;
double d;
HRESULT hres;
TRACE("\n");
hres = get_string_val(ctx, jsthis, &str, &length, &val_str);
hres = get_string_val(ctx, jsthis, &str);
if(FAILED(hres))
return hres;
length = jsstr_length(str);
if(argc) {
hres = to_integer(ctx, argv[0], &d);
if(FAILED(hres)) {
SysFreeString(val_str);
jsstr_release(str);
return hres;
}
......@@ -1034,7 +984,7 @@ static HRESULT String_slice(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
if(argc >= 2) {
hres = to_integer(ctx, argv[1], &d);
if(FAILED(hres)) {
SysFreeString(val_str);
jsstr_release(str);
return hres;
}
......@@ -1058,16 +1008,16 @@ static HRESULT String_slice(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
end = start;
if(r) {
BSTR retstr = SysAllocStringLen(str+start, end-start);
jsstr_t *retstr = jsstr_alloc_len(str->str+start, end-start);
if(!retstr) {
SysFreeString(val_str);
jsstr_release(str);
return E_OUTOFMEMORY;
}
*r = jsval_string(retstr);
}
SysFreeString(val_str);
jsstr_release(str);
return S_OK;
}
......@@ -1083,10 +1033,10 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
{
match_result_t match_result;
DWORD length, i, match_len = 0;
const WCHAR *str, *ptr, *ptr2, *cp;
const WCHAR *ptr, *ptr2, *cp;
unsigned limit = UINT32_MAX;
jsdisp_t *array, *regexp = NULL;
BSTR val_str, match_str = NULL, tmp_str;
jsstr_t *str, *match_str = NULL, *tmp_str;
HRESULT hres;
TRACE("\n");
......@@ -1096,14 +1046,16 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
return E_NOTIMPL;
}
hres = get_string_val(ctx, jsthis, &str, &length, &val_str);
hres = get_string_val(ctx, jsthis, &str);
if(FAILED(hres))
return hres;
length = jsstr_length(str);
if(argc > 1 && !is_undefined(argv[1])) {
hres = to_uint32(ctx, argv[1], &limit);
if(FAILED(hres)) {
SysFreeString(val_str);
jsstr_release(str);
return hres;
}
}
......@@ -1121,13 +1073,13 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
if(!regexp) {
hres = to_string(ctx, argv[0], &match_str);
if(FAILED(hres)) {
SysFreeString(val_str);
jsstr_release(str);
return hres;
}
match_len = SysStringLen(match_str);
match_len = jsstr_length(match_str);
if(!match_len) {
SysFreeString(match_str);
jsstr_release(match_str);
match_str = NULL;
}
}
......@@ -1135,15 +1087,15 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
hres = create_array(ctx, 0, &array);
if(SUCCEEDED(hres)) {
ptr = cp = str;
ptr = cp = str->str;
for(i=0; i<limit; i++) {
if(regexp) {
hres = regexp_match_next(ctx, regexp, 0, str, length, &cp, NULL, NULL, NULL, &match_result);
hres = regexp_match_next(ctx, regexp, 0, str->str, length, &cp, NULL, NULL, NULL, &match_result);
if(hres != S_OK)
break;
ptr2 = match_result.str;
}else if(match_str) {
ptr2 = strstrW(ptr, match_str);
ptr2 = strstrW(ptr, match_str->str);
if(!ptr2)
break;
}else {
......@@ -1152,14 +1104,14 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
ptr2 = ptr+1;
}
tmp_str = SysAllocStringLen(ptr, ptr2-ptr);
tmp_str = jsstr_alloc_len(ptr, ptr2-ptr);
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;
......@@ -1173,14 +1125,14 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
}
if(SUCCEEDED(hres) && (match_str || regexp) && i<limit) {
DWORD len = (str+length) - ptr;
DWORD len = (str->str+length) - ptr;
if(len || match_str) {
tmp_str = SysAllocStringLen(ptr, len);
tmp_str = jsstr_alloc_len(ptr, len);
if(tmp_str) {
hres = jsdisp_propput_idx(array, i, jsval_string(tmp_str));
SysFreeString(tmp_str);
jsstr_release(tmp_str);
}else {
hres = E_OUTOFMEMORY;
}
......@@ -1189,8 +1141,9 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
if(regexp)
jsdisp_release(regexp);
SysFreeString(match_str);
SysFreeString(val_str);
if(match_str)
jsstr_release(match_str);
jsstr_release(str);
if(SUCCEEDED(hres) && r)
*r = jsval_obj(array);
......@@ -1218,23 +1171,22 @@ static HRESULT String_sub(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsign
static HRESULT String_substring(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
{
const WCHAR *str;
BSTR val_str;
INT start=0, end;
DWORD length;
INT start=0, end, length;
jsstr_t *str;
double d;
HRESULT hres;
TRACE("\n");
hres = get_string_val(ctx, jsthis, &str, &length, &val_str);
hres = get_string_val(ctx, jsthis, &str);
if(FAILED(hres))
return hres;
length = jsstr_length(str);
if(argc >= 1) {
hres = to_integer(ctx, argv[0], &d);
if(FAILED(hres)) {
SysFreeString(val_str);
jsstr_release(str);
return hres;
}
......@@ -1245,7 +1197,7 @@ static HRESULT String_substring(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
if(argc >= 2) {
hres = to_integer(ctx, argv[1], &d);
if(FAILED(hres)) {
SysFreeString(val_str);
jsstr_release(str);
return hres;
}
......@@ -1264,14 +1216,14 @@ static HRESULT String_substring(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
}
if(r) {
BSTR ret = SysAllocStringLen(str+start, end-start);
jsstr_t *ret = jsstr_alloc_len(str->str+start, end-start);
if(!ret) {
SysFreeString(val_str);
jsstr_release(str);
return E_OUTOFMEMORY;
}
*r = jsval_string(ret);
}
SysFreeString(val_str);
jsstr_release(str);
return S_OK;
}
......@@ -1279,23 +1231,22 @@ static HRESULT String_substring(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
static HRESULT String_substr(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
{
BSTR val_str;
const WCHAR *str;
INT start=0, len;
DWORD length;
int start=0, len, length;
jsstr_t *str;
double d;
HRESULT hres;
TRACE("\n");
hres = get_string_val(ctx, jsthis, &str, &length, &val_str);
hres = get_string_val(ctx, jsthis, &str);
if(FAILED(hres))
return hres;
length = jsstr_length(str);
if(argc >= 1) {
hres = to_integer(ctx, argv[0], &d);
if(FAILED(hres)) {
SysFreeString(val_str);
jsstr_release(str);
return hres;
}
......@@ -1306,7 +1257,7 @@ static HRESULT String_substr(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
if(argc >= 2) {
hres = to_integer(ctx, argv[1], &d);
if(FAILED(hres)) {
SysFreeString(val_str);
jsstr_release(str);
return hres;
}
......@@ -1320,14 +1271,14 @@ static HRESULT String_substr(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
hres = S_OK;
if(r) {
BSTR ret = SysAllocStringLen(str+start, len);
jsstr_t *ret = jsstr_alloc_len(str->str+start, len);
if(ret)
*r = jsval_string(ret);
else
hres = E_OUTOFMEMORY;
}
SysFreeString(val_str);
jsstr_release(str);
return hres;
}
......@@ -1341,56 +1292,56 @@ static HRESULT String_sup(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsign
static HRESULT String_toLowerCase(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
{
const WCHAR* str;
DWORD length;
BSTR val_str;
jsstr_t *str;
HRESULT hres;
TRACE("\n");
hres = get_string_val(ctx, jsthis, &str, &length, &val_str);
hres = get_string_val(ctx, jsthis, &str);
if(FAILED(hres))
return hres;
if(r) {
if(!val_str) {
val_str = SysAllocStringLen(str, length);
if(!val_str)
return E_OUTOFMEMORY;
jsstr_t *ret;
ret = jsstr_alloc_len(str->str, jsstr_length(str));
if(!ret) {
jsstr_release(str);
return E_OUTOFMEMORY;
}
strlwrW(val_str);
*r = jsval_string(val_str);
strlwrW(ret->str);
*r = jsval_string(ret);
}
else SysFreeString(val_str);
jsstr_release(str);
return S_OK;
}
static HRESULT String_toUpperCase(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
{
const WCHAR* str;
DWORD length;
BSTR val_str;
jsstr_t *str;
HRESULT hres;
TRACE("\n");
hres = get_string_val(ctx, jsthis, &str, &length, &val_str);
hres = get_string_val(ctx, jsthis, &str);
if(FAILED(hres))
return hres;
if(r) {
if(!val_str) {
val_str = SysAllocStringLen(str, length);
if(!val_str)
return E_OUTOFMEMORY;
jsstr_t *ret;
ret = jsstr_alloc_len(str->str, jsstr_length(str));
if(!ret) {
jsstr_release(str);
return E_OUTOFMEMORY;
}
struprW(val_str);
*r = jsval_string(val_str);
struprW(ret->str);
*r = jsval_string(ret);
}
else SysFreeString(val_str);
jsstr_release(str);
return S_OK;
}
......@@ -1426,11 +1377,7 @@ static HRESULT String_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 str = SysAllocString(This->str);
if(!str)
return E_OUTOFMEMORY;
*r = jsval_string(str);
*r = jsval_string(jsstr_addref(This->str));
break;
}
default:
......@@ -1445,7 +1392,7 @@ static void String_destructor(jsdisp_t *dispex)
{
StringInstance *This = (StringInstance*)dispex;
heap_free(This->str);
jsstr_release(This->str);
heap_free(This);
}
......@@ -1512,29 +1459,29 @@ static HRESULT StringConstr_fromCharCode(script_ctx_t *ctx, vdisp_t *jsthis, WOR
unsigned argc, jsval_t *argv, jsval_t *r)
{
DWORD i, code;
BSTR ret;
jsstr_t *ret;
HRESULT hres;
TRACE("\n");
ret = SysAllocStringLen(NULL, argc);
ret = jsstr_alloc_buf(argc);
if(!ret)
return E_OUTOFMEMORY;
for(i=0; i<argc; i++) {
hres = to_uint32(ctx, argv[i], &code);
if(FAILED(hres)) {
SysFreeString(ret);
jsstr_release(ret);
return hres;
}
ret[i] = code;
ret->str[i] = code;
}
if(r)
*r = jsval_string(ret);
else
SysFreeString(ret);
jsstr_release(ret);
return S_OK;
}
......@@ -1547,16 +1494,14 @@ static HRESULT StringConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
switch(flags) {
case INVOKE_FUNC: {
BSTR str;
jsstr_t *str;
if(argc) {
hres = to_string(ctx, argv[0], &str);
if(FAILED(hres))
return hres;
}else {
str = SysAllocStringLen(NULL, 0);
if(!str)
return E_OUTOFMEMORY;
str = jsstr_empty();
}
*r = jsval_string(str);
......@@ -1566,16 +1511,16 @@ static HRESULT StringConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
jsdisp_t *ret;
if(argc) {
BSTR str;
jsstr_t *str;
hres = to_string(ctx, argv[0], &str);
if(FAILED(hres))
return hres;
hres = create_string(ctx, str, SysStringLen(str), &ret);
SysFreeString(str);
hres = create_string(ctx, str, &ret);
jsstr_release(str);
}else {
hres = create_string(ctx, NULL, 0, &ret);
hres = create_string(ctx, jsstr_empty(), &ret);
}
if(FAILED(hres))
......@@ -1593,7 +1538,7 @@ static HRESULT StringConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
return S_OK;
}
static HRESULT string_alloc(script_ctx_t *ctx, jsdisp_t *object_prototype, StringInstance **ret)
static HRESULT string_alloc(script_ctx_t *ctx, jsdisp_t *object_prototype, jsstr_t *str, StringInstance **ret)
{
StringInstance *string;
HRESULT hres;
......@@ -1611,6 +1556,7 @@ static HRESULT string_alloc(script_ctx_t *ctx, jsdisp_t *object_prototype, Strin
return hres;
}
string->str = jsstr_addref(str);
*ret = string;
return S_OK;
}
......@@ -1635,7 +1581,7 @@ HRESULT create_string_constr(script_ctx_t *ctx, jsdisp_t *object_prototype, jsdi
static const WCHAR StringW[] = {'S','t','r','i','n','g',0};
hres = string_alloc(ctx, object_prototype, &string);
hres = string_alloc(ctx, object_prototype, jsstr_empty(), &string);
if(FAILED(hres))
return hres;
......@@ -1646,28 +1592,15 @@ HRESULT create_string_constr(script_ctx_t *ctx, jsdisp_t *object_prototype, jsdi
return hres;
}
HRESULT create_string(script_ctx_t *ctx, const WCHAR *str, DWORD len, jsdisp_t **ret)
HRESULT create_string(script_ctx_t *ctx, jsstr_t *str, jsdisp_t **ret)
{
StringInstance *string;
HRESULT hres;
hres = string_alloc(ctx, NULL, &string);
hres = string_alloc(ctx, NULL, str, &string);
if(FAILED(hres))
return hres;
if(len == -1)
len = strlenW(str);
string->length = len;
string->str = heap_alloc((len+1)*sizeof(WCHAR));
if(!string->str) {
jsdisp_release(&string->dispex);
return E_OUTOFMEMORY;
}
memcpy(string->str, str, len*sizeof(WCHAR));
string->str[len] = 0;
*ret = &string->dispex;
return S_OK;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment