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 = \ ...@@ -15,6 +15,7 @@ C_SRCS = \
global.c \ global.c \
jscript.c \ jscript.c \
jscript_main.c \ jscript_main.c \
jsstr.c \
jsutils.c \ jsutils.c \
lex.c \ lex.c \
math.c \ math.c \
......
...@@ -141,9 +141,9 @@ static IUnknown *create_activex_object(script_ctx_t *ctx, const WCHAR *progid) ...@@ -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, static HRESULT ActiveXObject_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r) jsval_t *r)
{ {
jsstr_t * progid;
IDispatch *disp; IDispatch *disp;
IUnknown *obj; IUnknown *obj;
BSTR progid;
HRESULT hres; HRESULT hres;
TRACE("\n"); TRACE("\n");
...@@ -168,8 +168,8 @@ static HRESULT ActiveXObject_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag ...@@ -168,8 +168,8 @@ static HRESULT ActiveXObject_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
obj = create_activex_object(ctx, progid); obj = create_activex_object(ctx, progid->str);
SysFreeString(progid); jsstr_release(progid);
if(!obj) if(!obj)
return throw_generic_error(ctx, JS_E_CANNOT_CREATE_OBJ, NULL); return throw_generic_error(ctx, JS_E_CANNOT_CREATE_OBJ, NULL);
......
...@@ -234,22 +234,18 @@ static HRESULT Array_concat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi ...@@ -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) 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; jsval_t val;
DWORD i; DWORD i;
HRESULT hres = E_FAIL; HRESULT hres = E_FAIL;
if(!length) { if(!length) {
if(r) { if(r)
BSTR ret = SysAllocStringLen(NULL, 0); *r = jsval_string(jsstr_empty());
if(!ret)
return E_OUTOFMEMORY;
*r = jsval_string(ret);
}
return S_OK; return S_OK;
} }
str_tab = heap_alloc_zero(length * sizeof(BSTR)); str_tab = heap_alloc_zero(length * sizeof(*str_tab));
if(!str_tab) if(!str_tab)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
...@@ -276,20 +272,30 @@ static HRESULT array_join(script_ctx_t *ctx, jsdisp_t *array, DWORD length, cons ...@@ -276,20 +272,30 @@ static HRESULT array_join(script_ctx_t *ctx, jsdisp_t *array, DWORD length, cons
seplen = strlenW(sep); seplen = strlenW(sep);
if(str_tab[0]) if(str_tab[0])
len = SysStringLen(str_tab[0]); len = jsstr_length(str_tab[0]);
for(i=1; i < length; i++) for(i=1; i < length; i++) {
len += seplen + SysStringLen(str_tab[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) { if(ret) {
DWORD tmplen = 0; unsigned tmplen;
ptr = ret->str;
if(str_tab[0]) { if(str_tab[0]) {
tmplen = SysStringLen(str_tab[0]); tmplen = jsstr_length(str_tab[0]);
memcpy(ret, str_tab[0], tmplen*sizeof(WCHAR)); memcpy(ptr, str_tab[0]->str, tmplen*sizeof(WCHAR));
ptr += tmplen;
} }
ptr = ret + tmplen;
for(i=1; i < length; i++) { for(i=1; i < length; i++) {
if(seplen) { if(seplen) {
memcpy(ptr, sep, seplen*sizeof(WCHAR)); memcpy(ptr, sep, seplen*sizeof(WCHAR));
...@@ -297,8 +303,8 @@ static HRESULT array_join(script_ctx_t *ctx, jsdisp_t *array, DWORD length, cons ...@@ -297,8 +303,8 @@ static HRESULT array_join(script_ctx_t *ctx, jsdisp_t *array, DWORD length, cons
} }
if(str_tab[i]) { if(str_tab[i]) {
tmplen = SysStringLen(str_tab[i]); tmplen = jsstr_length(str_tab[i]);
memcpy(ptr, str_tab[i], tmplen*sizeof(WCHAR)); memcpy(ptr, str_tab[i]->str, tmplen*sizeof(WCHAR));
ptr += tmplen; ptr += tmplen;
} }
} }
...@@ -308,26 +314,20 @@ static HRESULT array_join(script_ctx_t *ctx, jsdisp_t *array, DWORD length, cons ...@@ -308,26 +314,20 @@ static HRESULT array_join(script_ctx_t *ctx, jsdisp_t *array, DWORD length, cons
} }
} }
for(i=0; i < length; i++) for(i=0; i < length; i++) {
SysFreeString(str_tab[i]); if(str_tab[i])
jsstr_release(str_tab[i]);
}
heap_free(str_tab); heap_free(str_tab);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
TRACE("= %s\n", debugstr_w(ret)); TRACE("= %s\n", debugstr_jsstr(ret));
if(r) {
if(!ret) {
ret = SysAllocStringLen(NULL, 0);
if(!ret)
return E_OUTOFMEMORY;
}
*r = jsval_string(ret);
}else {
SysFreeString(ret);
}
if(r)
*r = ret ? jsval_string(ret) : jsval_string(jsstr_empty());
else
jsstr_release(ret);
return S_OK; return S_OK;
} }
...@@ -346,15 +346,15 @@ static HRESULT Array_join(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigne ...@@ -346,15 +346,15 @@ static HRESULT Array_join(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigne
return hres; return hres;
if(argc) { if(argc) {
BSTR sep; jsstr_t *sep;
hres = to_string(ctx, argv[0], &sep); hres = to_string(ctx, argv[0], &sep);
if(FAILED(hres)) if(FAILED(hres))
return 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 { }else {
hres = array_join(ctx, jsthis, length, default_separatorW, r); 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 ...@@ -653,7 +653,7 @@ static HRESULT sort_cmp(script_ctx_t *ctx, jsdisp_t *cmp_func, jsval_t v1, jsval
else else
*cmp = d < -0.0 ? -1 : 0; *cmp = d < -0.0 ? -1 : 0;
}else { }else {
BSTR x, y; jsstr_t *x, *y;
hres = to_string(ctx, v1, &x); hres = to_string(ctx, v1, &x);
if(FAILED(hres)) if(FAILED(hres))
...@@ -661,10 +661,10 @@ static HRESULT sort_cmp(script_ctx_t *ctx, jsdisp_t *cmp_func, jsval_t v1, jsval ...@@ -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); hres = to_string(ctx, v2, &y);
if(SUCCEEDED(hres)) { if(SUCCEEDED(hres)) {
*cmp = strcmpW(x, y); *cmp = jsstr_cmp(x, y);
SysFreeString(y); jsstr_release(y);
} }
SysFreeString(x); jsstr_release(x);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
} }
......
...@@ -51,11 +51,9 @@ static HRESULT Bool_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns ...@@ -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); return throw_type_error(ctx, JS_E_BOOLEAN_EXPECTED, NULL);
if(r) { if(r) {
BSTR val; jsstr_t *val;
if(bool->val) val = SysAllocString(trueW);
else val = SysAllocString(falseW);
val = jsstr_alloc(bool->val ? trueW : falseW);
if(!val) if(!val)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
......
...@@ -766,8 +766,18 @@ static HRESULT literal_as_bstr(compiler_ctx_t *ctx, literal_t *literal, BSTR *st ...@@ -766,8 +766,18 @@ static HRESULT literal_as_bstr(compiler_ctx_t *ctx, literal_t *literal, BSTR *st
case LT_STRING: case LT_STRING:
*str = compiler_alloc_bstr(ctx, literal->u.wstr); *str = compiler_alloc_bstr(ctx, literal->u.wstr);
break; break;
case LT_DOUBLE: case LT_DOUBLE: {
return double_to_bstr(literal->u.dval, str); 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: default:
assert(0); assert(0);
} }
......
...@@ -467,6 +467,8 @@ static HRESULT prop_put(jsdisp_t *This, dispex_prop_t *prop, jsval_t val, IServi ...@@ -467,6 +467,8 @@ static HRESULT prop_put(jsdisp_t *This, dispex_prop_t *prop, jsval_t val, IServi
return E_FAIL; return E_FAIL;
} }
TRACE("%s = %s\n", debugstr_w(prop->name), debugstr_jsval(val));
hres = jsval_copy(val, &prop->u.val); hres = jsval_copy(val, &prop->u.val);
if(FAILED(hres)) { if(FAILED(hres)) {
prop->u.val = jsval_undefined(); prop->u.val = jsval_undefined();
...@@ -1408,7 +1410,7 @@ HRESULT jsdisp_delete_idx(jsdisp_t *obj, DWORD idx) ...@@ -1408,7 +1410,7 @@ HRESULT jsdisp_delete_idx(jsdisp_t *obj, DWORD idx)
return delete_prop(prop); 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; dispex_prop_t *prop;
HRESULT hres; HRESULT hres;
......
...@@ -38,7 +38,7 @@ static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, ...@@ -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) unsigned argc, jsval_t *argv, jsval_t *r)
{ {
jsdisp_t *jsthis; jsdisp_t *jsthis;
BSTR name = NULL, msg = NULL, ret = NULL; jsstr_t *name = NULL, *msg = NULL, *ret = NULL;
jsval_t v; jsval_t v;
HRESULT hres; HRESULT hres;
...@@ -49,10 +49,12 @@ static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, ...@@ -49,10 +49,12 @@ static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags,
jsthis = get_jsdisp(vthis); jsthis = get_jsdisp(vthis);
if(!jsthis || ctx->version < 2) { if(!jsthis || ctx->version < 2) {
if(r) { if(r) {
BSTR ret = SysAllocString(object_errorW); jsstr_t *str;
if(!ret)
str = jsstr_alloc(object_errorW);
if(!str)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
*r = jsval_string(ret); *r = jsval_string(str);
} }
return S_OK; return S_OK;
} }
...@@ -66,10 +68,6 @@ static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, ...@@ -66,10 +68,6 @@ static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags,
jsval_release(v); jsval_release(v);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
if(!*name) {
SysFreeString(name);
name = NULL;
}
} }
hres = jsdisp_propget_name(jsthis, messageW, &v); hres = jsdisp_propget_name(jsthis, messageW, &v);
...@@ -77,40 +75,36 @@ static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, ...@@ -77,40 +75,36 @@ static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags,
if(!is_undefined(v)) { if(!is_undefined(v)) {
hres = to_string(ctx, v, &msg); hres = to_string(ctx, v, &msg);
jsval_release(v); jsval_release(v);
if(SUCCEEDED(hres) && !*msg) {
SysFreeString(msg);
msg = NULL;
}
} }
} }
if(SUCCEEDED(hres)) { if(SUCCEEDED(hres)) {
if(name && msg) { unsigned name_len = name ? jsstr_length(name) : 0;
DWORD name_len, msg_len; unsigned msg_len = msg ? jsstr_length(msg) : 0;
name_len = SysStringLen(name);
msg_len = SysStringLen(msg);
ret = SysAllocStringLen(NULL, name_len + msg_len + 2); if(name_len && msg_len) {
ret = jsstr_alloc_buf(name_len + msg_len + 2);
if(ret) { if(ret) {
memcpy(ret, name, name_len*sizeof(WCHAR)); memcpy(ret->str, name->str, name_len*sizeof(WCHAR));
ret[name_len] = ':'; ret->str[name_len] = ':';
ret[name_len+1] = ' '; ret->str[name_len+1] = ' ';
memcpy(ret+name_len+2, msg, msg_len*sizeof(WCHAR)); memcpy(ret->str+name_len+2, msg->str, msg_len*sizeof(WCHAR));
} }
}else if(name) { }else if(name_len) {
ret = name; ret = name;
name = NULL; name = NULL;
}else if(msg) { }else if(msg_len) {
ret = msg; ret = msg;
msg = NULL; msg = NULL;
}else { }else {
ret = SysAllocString(object_errorW); ret = jsstr_alloc(object_errorW);
} }
} }
SysFreeString(msg); if(msg)
SysFreeString(name); jsstr_release(msg);
if(name)
jsstr_release(name);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
if(!ret) if(!ret)
...@@ -119,7 +113,7 @@ static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, ...@@ -119,7 +113,7 @@ static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags,
if(r) if(r)
*r = jsval_string(ret); *r = jsval_string(ret);
else else
SysFreeString(ret); jsstr_release(ret);
return S_OK; return S_OK;
} }
...@@ -189,7 +183,7 @@ static HRESULT create_error(script_ctx_t *ctx, jsdisp_t *constr, ...@@ -189,7 +183,7 @@ static HRESULT create_error(script_ctx_t *ctx, jsdisp_t *constr,
UINT number, const WCHAR *msg, jsdisp_t **ret) UINT number, const WCHAR *msg, jsdisp_t **ret)
{ {
jsdisp_t *err; jsdisp_t *err;
BSTR str; jsstr_t *str;
HRESULT hres; HRESULT hres;
hres = alloc_error(ctx, NULL, constr, &err); hres = alloc_error(ctx, NULL, constr, &err);
...@@ -202,13 +196,13 @@ static HRESULT create_error(script_ctx_t *ctx, jsdisp_t *constr, ...@@ -202,13 +196,13 @@ static HRESULT create_error(script_ctx_t *ctx, jsdisp_t *constr,
return hres; return hres;
} }
if(msg) str = SysAllocString(msg); if(msg) str = jsstr_alloc(msg);
else str = SysAllocStringLen(NULL, 0); else str = jsstr_empty();
if(str) { if(str) {
hres = jsdisp_propput_name(err, messageW, jsval_string(str)); hres = jsdisp_propput_name(err, messageW, jsval_string(str));
if(SUCCEEDED(hres)) if(SUCCEEDED(hres))
hres = jsdisp_propput_name(err, descriptionW, jsval_string(str)); hres = jsdisp_propput_name(err, descriptionW, jsval_string(str));
SysFreeString(str); jsstr_release(str);
}else { }else {
hres = E_OUTOFMEMORY; hres = E_OUTOFMEMORY;
} }
...@@ -225,7 +219,7 @@ static HRESULT error_constr(script_ctx_t *ctx, WORD flags, unsigned argc, jsval_ ...@@ -225,7 +219,7 @@ static HRESULT error_constr(script_ctx_t *ctx, WORD flags, unsigned argc, jsval_
jsval_t *r, jsdisp_t *constr) { jsval_t *r, jsdisp_t *constr) {
jsdisp_t *err; jsdisp_t *err;
UINT num = 0; UINT num = 0;
BSTR msg = NULL; jsstr_t *msg = NULL;
HRESULT hres; HRESULT hres;
if(argc) { if(argc) {
...@@ -250,8 +244,9 @@ static HRESULT error_constr(script_ctx_t *ctx, WORD flags, unsigned argc, jsval_ ...@@ -250,8 +244,9 @@ static HRESULT error_constr(script_ctx_t *ctx, WORD flags, unsigned argc, jsval_
switch(flags) { switch(flags) {
case INVOKE_FUNC: case INVOKE_FUNC:
case DISPATCH_CONSTRUCT: case DISPATCH_CONSTRUCT:
hres = create_error(ctx, constr, num, msg, &err); hres = create_error(ctx, constr, num, msg ? msg->str : NULL, &err);
SysFreeString(msg); if(msg)
jsstr_release(msg);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
...@@ -263,6 +258,8 @@ static HRESULT error_constr(script_ctx_t *ctx, WORD flags, unsigned argc, jsval_ ...@@ -263,6 +258,8 @@ static HRESULT error_constr(script_ctx_t *ctx, WORD flags, unsigned argc, jsval_
return S_OK; return S_OK;
default: default:
if(msg)
jsstr_release(msg);
FIXME("unimplemented flags %x\n", flags); FIXME("unimplemented flags %x\n", flags);
return E_NOTIMPL; return E_NOTIMPL;
} }
...@@ -346,7 +343,7 @@ HRESULT init_error_constr(script_ctx_t *ctx, jsdisp_t *object_prototype) ...@@ -346,7 +343,7 @@ HRESULT init_error_constr(script_ctx_t *ctx, jsdisp_t *object_prototype)
jsdisp_t *err; jsdisp_t *err;
INT i; INT i;
BSTR str; jsstr_t *str;
HRESULT hres; HRESULT hres;
for(i=0; i < sizeof(names)/sizeof(names[0]); i++) { 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) ...@@ -354,14 +351,14 @@ HRESULT init_error_constr(script_ctx_t *ctx, jsdisp_t *object_prototype)
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
str = SysAllocString(names[i]); str = jsstr_alloc(names[i]);
if(!str) { if(!str) {
jsdisp_release(err); jsdisp_release(err);
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
hres = jsdisp_propput_name(err, nameW, jsval_string(str)); hres = jsdisp_propput_name(err, nameW, jsval_string(str));
SysFreeString(str); jsstr_release(str);
if(SUCCEEDED(hres)) if(SUCCEEDED(hres))
hres = create_builtin_constructor(ctx, constr_val[i], names[i], NULL, hres = create_builtin_constructor(ctx, constr_val[i], names[i], NULL,
PROPF_CONSTR|1, err, constr_addr[i]); PROPF_CONSTR|1, err, constr_addr[i]);
......
...@@ -245,9 +245,9 @@ static HRESULT call_function(script_ctx_t *ctx, FunctionInstance *function, IDis ...@@ -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); 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_prefixW[] = {'\n','f','u','n','c','t','i','o','n',' '};
static const WCHAR native_suffixW[] = static const WCHAR native_suffixW[] =
...@@ -257,15 +257,15 @@ static HRESULT function_to_string(FunctionInstance *function, BSTR *ret) ...@@ -257,15 +257,15 @@ static HRESULT function_to_string(FunctionInstance *function, BSTR *ret)
DWORD name_len; DWORD name_len;
name_len = strlenW(function->name); 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) if(!str)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
memcpy(str, native_prefixW, sizeof(native_prefixW)); memcpy(str->str, native_prefixW, sizeof(native_prefixW));
memcpy(str + sizeof(native_prefixW)/sizeof(WCHAR), function->name, name_len*sizeof(WCHAR)); memcpy(str->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 + sizeof(native_prefixW)/sizeof(WCHAR) + name_len, native_suffixW, sizeof(native_suffixW));
}else { }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) if(!str)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
...@@ -316,7 +316,7 @@ static HRESULT Function_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, ...@@ -316,7 +316,7 @@ static HRESULT Function_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
jsval_t *r) jsval_t *r)
{ {
FunctionInstance *function; FunctionInstance *function;
BSTR str; jsstr_t *str;
HRESULT hres; HRESULT hres;
TRACE("\n"); TRACE("\n");
...@@ -331,7 +331,7 @@ static HRESULT Function_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, ...@@ -331,7 +331,7 @@ static HRESULT Function_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
if(r) if(r)
*r = jsval_string(str); *r = jsval_string(str);
else else
SysFreeString(str); jsstr_release(str);
return S_OK; return S_OK;
} }
...@@ -475,7 +475,7 @@ HRESULT Function_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned ...@@ -475,7 +475,7 @@ HRESULT Function_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned
case DISPATCH_PROPERTYGET: { case DISPATCH_PROPERTYGET: {
HRESULT hres; HRESULT hres;
BSTR str; jsstr_t *str;
hres = function_to_string(function, &str); hres = function_to_string(function, &str);
if(FAILED(hres)) if(FAILED(hres))
...@@ -689,7 +689,7 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg ...@@ -689,7 +689,7 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg
DWORD len = 0, l; DWORD len = 0, l;
bytecode_t *code; bytecode_t *code;
jsdisp_t *function; jsdisp_t *function;
BSTR *params = NULL; jsstr_t **params = NULL;
int i=0, j=0; int i=0, j=0;
HRESULT hres = S_OK; HRESULT hres = S_OK;
...@@ -698,7 +698,7 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg ...@@ -698,7 +698,7 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg
static const WCHAR function_endW[] = {'\n','}',0}; static const WCHAR function_endW[] = {'\n','}',0};
if(argc) { if(argc) {
params = heap_alloc(argc*sizeof(BSTR)); params = heap_alloc(argc*sizeof(*params));
if(!params) if(!params)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
...@@ -708,7 +708,7 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg ...@@ -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); hres = to_string(ctx, argv[i], params+i);
if(FAILED(hres)) if(FAILED(hres))
break; 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 ...@@ -720,8 +720,8 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg
ptr = str + sizeof(function_anonymousW)/sizeof(WCHAR); ptr = str + sizeof(function_anonymousW)/sizeof(WCHAR);
if(argc > 1) { if(argc > 1) {
while(1) { while(1) {
l = SysStringLen(params[j]); l = jsstr_length(params[j]);
memcpy(ptr, params[j], l*sizeof(WCHAR)); memcpy(ptr, params[j]->str, l*sizeof(WCHAR));
ptr += l; ptr += l;
if(++j == argc-1) if(++j == argc-1)
break; break;
...@@ -732,8 +732,8 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg ...@@ -732,8 +732,8 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg
memcpy(ptr, function_beginW, sizeof(function_beginW)); memcpy(ptr, function_beginW, sizeof(function_beginW));
ptr += sizeof(function_beginW)/sizeof(WCHAR); ptr += sizeof(function_beginW)/sizeof(WCHAR);
if(argc) { if(argc) {
l = SysStringLen(params[argc-1]); l = jsstr_length(params[argc-1]);
memcpy(ptr, params[argc-1], l*sizeof(WCHAR)); memcpy(ptr, params[argc-1]->str, l*sizeof(WCHAR));
ptr += l; ptr += l;
} }
memcpy(ptr, function_endW, sizeof(function_endW)); memcpy(ptr, function_endW, sizeof(function_endW));
...@@ -745,7 +745,7 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg ...@@ -745,7 +745,7 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg
} }
while(--i >= 0) while(--i >= 0)
SysFreeString(params[i]); jsstr_release(params[i]);
heap_free(params); heap_free(params);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
......
...@@ -72,7 +72,8 @@ void script_release(script_ctx_t *ctx) ...@@ -72,7 +72,8 @@ void script_release(script_ctx_t *ctx)
if(ctx->cc) if(ctx->cc)
release_cc(ctx->cc); release_cc(ctx->cc);
jsheap_free(&ctx->tmp_heap); jsheap_free(&ctx->tmp_heap);
SysFreeString(ctx->last_match); if(ctx->last_match)
jsstr_release(ctx->last_match);
ctx->jscaller->ctx = NULL; ctx->jscaller->ctx = NULL;
IServiceProvider_Release(&ctx->jscaller->IServiceProvider_iface); IServiceProvider_Release(&ctx->jscaller->IServiceProvider_iface);
...@@ -724,6 +725,8 @@ static HRESULT WINAPI JScriptParse_InitNew(IActiveScriptParse *iface) ...@@ -724,6 +725,8 @@ static HRESULT WINAPI JScriptParse_InitNew(IActiveScriptParse *iface)
return hres; return hres;
} }
ctx->last_match = jsstr_empty();
ctx = InterlockedCompareExchangePointer((void**)&This->ctx, ctx, NULL); ctx = InterlockedCompareExchangePointer((void**)&This->ctx, ctx, NULL);
if(ctx) { if(ctx) {
script_release(ctx); script_release(ctx);
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "wine/list.h" #include "wine/list.h"
typedef struct _jsval_t jsval_t; typedef struct _jsval_t jsval_t;
typedef struct _jsstr_t jsstr_t;
typedef struct _script_ctx_t script_ctx_t; typedef struct _script_ctx_t script_ctx_t;
typedef struct _exec_ctx_t exec_ctx_t; typedef struct _exec_ctx_t exec_ctx_t;
typedef struct _dispex_prop_t dispex_prop_t; typedef struct _dispex_prop_t dispex_prop_t;
...@@ -54,6 +55,41 @@ void jsheap_clear(jsheap_t*) DECLSPEC_HIDDEN; ...@@ -54,6 +55,41 @@ void jsheap_clear(jsheap_t*) DECLSPEC_HIDDEN;
void jsheap_free(jsheap_t*) DECLSPEC_HIDDEN; void jsheap_free(jsheap_t*) DECLSPEC_HIDDEN;
jsheap_t *jsheap_mark(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; typedef struct jsdisp_t jsdisp_t;
extern HINSTANCE jscript_hinstance DECLSPEC_HIDDEN; extern HINSTANCE jscript_hinstance DECLSPEC_HIDDEN;
...@@ -219,7 +255,7 @@ HRESULT jsdisp_propget_name(jsdisp_t*,LPCWSTR,jsval_t*) 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_idx(jsdisp_t*,DWORD,jsval_t*) DECLSPEC_HIDDEN;
HRESULT jsdisp_get_id(jsdisp_t*,const WCHAR*,DWORD,DISPID*) 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_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, HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,const WCHAR*,const builtin_info_t*,DWORD,
jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDEN; jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDEN;
...@@ -242,7 +278,7 @@ HRESULT create_math(script_ctx_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_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(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_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_bool(script_ctx_t*,BOOL,jsdisp_t**) DECLSPEC_HIDDEN;
HRESULT create_number(script_ctx_t*,double,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; 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; ...@@ -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_integer(script_ctx_t*,jsval_t,double*) DECLSPEC_HIDDEN;
HRESULT to_int32(script_ctx_t*,jsval_t,INT*) DECLSPEC_HIDDEN; HRESULT to_int32(script_ctx_t*,jsval_t,INT*) DECLSPEC_HIDDEN;
HRESULT to_uint32(script_ctx_t*,jsval_t,DWORD*) 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 to_object(script_ctx_t*,jsval_t,IDispatch**) DECLSPEC_HIDDEN;
HRESULT variant_change_type(script_ctx_t*,VARIANT*,VARIANT*,VARTYPE) DECLSPEC_HIDDEN; HRESULT variant_change_type(script_ctx_t*,VARIANT*,VARIANT*,VARTYPE) DECLSPEC_HIDDEN;
HRESULT decode_source(WCHAR*) 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 { typedef struct named_item_t {
IDispatch *disp; IDispatch *disp;
...@@ -325,7 +361,7 @@ struct _script_ctx_t { ...@@ -325,7 +361,7 @@ struct _script_ctx_t {
IDispatch *host_global; IDispatch *host_global;
BSTR last_match; jsstr_t *last_match;
match_result_t match_parens[9]; match_result_t match_parens[9];
DWORD last_match_index; DWORD last_match_index;
DWORD last_match_length; DWORD last_match_length;
...@@ -383,7 +419,7 @@ HRESULT create_jscaller(script_ctx_t*) DECLSPEC_HIDDEN; ...@@ -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**, 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; DWORD*,DWORD*,match_result_t*) DECLSPEC_HIDDEN;
HRESULT parse_regexp_flags(const WCHAR*,DWORD,DWORD*) 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) static inline BOOL is_class(jsdisp_t *jsdisp, jsclass_t class)
{ {
...@@ -475,38 +511,3 @@ static inline void unlock_module(void) ...@@ -475,38 +511,3 @@ static inline void unlock_module(void)
{ {
InterlockedDecrement(&module_ref); 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) ...@@ -140,7 +140,11 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hInstDLL); DisableThreadLibraryCalls(hInstDLL);
jscript_hinstance = hInstDLL; jscript_hinstance = hInstDLL;
if(!init_strings())
return FALSE;
break; break;
case DLL_PROCESS_DETACH:
free_strings();
} }
return TRUE; 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) ...@@ -69,7 +69,7 @@ const char *debugstr_jsval(const jsval_t v)
case JSV_OBJECT: case JSV_OBJECT:
return wine_dbg_sprintf("obj(%p)", get_object(v)); return wine_dbg_sprintf("obj(%p)", get_object(v));
case JSV_STRING: case JSV_STRING:
return debugstr_w(get_string(v)); return wine_dbg_sprintf("str(%s)", debugstr_jsstr(get_string(v)));
case JSV_NUMBER: case JSV_NUMBER:
return wine_dbg_sprintf("%lf", get_number(v)); return wine_dbg_sprintf("%lf", get_number(v));
case JSV_BOOL: case JSV_BOOL:
...@@ -210,11 +210,6 @@ jsheap_t *jsheap_mark(jsheap_t *heap) ...@@ -210,11 +210,6 @@ jsheap_t *jsheap_mark(jsheap_t *heap)
return heap; return heap;
} }
static BSTR clone_bstr(BSTR str)
{
return SysAllocStringLen(str, str ? SysStringLen(str) : 0);
}
void jsval_release(jsval_t val) void jsval_release(jsval_t val)
{ {
switch(jsval_type(val)) { switch(jsval_type(val)) {
...@@ -223,7 +218,7 @@ void jsval_release(jsval_t val) ...@@ -223,7 +218,7 @@ void jsval_release(jsval_t val)
IDispatch_Release(get_object(val)); IDispatch_Release(get_object(val));
break; break;
case JSV_STRING: case JSV_STRING:
SysFreeString(get_string(val)); jsstr_release(get_string(val));
break; break;
case JSV_VARIANT: case JSV_VARIANT:
VariantClear(get_variant(val)); VariantClear(get_variant(val));
...@@ -266,10 +261,8 @@ HRESULT jsval_copy(jsval_t v, jsval_t *r) ...@@ -266,10 +261,8 @@ HRESULT jsval_copy(jsval_t v, jsval_t *r)
*r = v; *r = v;
return S_OK; return S_OK;
case JSV_STRING: { case JSV_STRING: {
BSTR str = clone_bstr(get_string(v)); jsstr_addref(get_string(v));
if(!str) *r = v;
return E_OUTOFMEMORY;
*r = jsval_string(str);
return S_OK; return S_OK;
} }
case JSV_VARIANT: case JSV_VARIANT:
...@@ -299,15 +292,14 @@ HRESULT variant_to_jsval(VARIANT *var, jsval_t *r) ...@@ -299,15 +292,14 @@ HRESULT variant_to_jsval(VARIANT *var, jsval_t *r)
*r = jsval_number(V_R8(var)); *r = jsval_number(V_R8(var));
return S_OK; return S_OK;
case VT_BSTR: { case VT_BSTR: {
BSTR str; jsstr_t *str;
if(V_BSTR(var)) { str = jsstr_alloc_len(V_BSTR(var), SysStringLen(V_BSTR(var)));
str = clone_bstr(V_BSTR(var));
if(!str) if(!str)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
}else { if(!V_BSTR(var))
str = NULL; str->length_flags |= JSSTR_FLAG_NULLBSTR;
}
*r = jsval_string(str); *r = jsval_string(str);
return S_OK; return S_OK;
} }
...@@ -343,16 +335,19 @@ HRESULT jsval_to_variant(jsval_t val, VARIANT *retv) ...@@ -343,16 +335,19 @@ HRESULT jsval_to_variant(jsval_t val, VARIANT *retv)
IDispatch_AddRef(get_object(val)); IDispatch_AddRef(get_object(val));
V_DISPATCH(retv) = get_object(val); V_DISPATCH(retv) = get_object(val);
return S_OK; return S_OK;
case JSV_STRING: case JSV_STRING: {
jsstr_t *str = get_string(val);
V_VT(retv) = VT_BSTR; V_VT(retv) = VT_BSTR;
if(get_string(val)) { if(str->length_flags & JSSTR_FLAG_NULLBSTR) {
V_BSTR(retv) = clone_bstr(get_string(val)); V_BSTR(retv) = NULL;
}else {
V_BSTR(retv) = SysAllocStringLen(str->str, jsstr_length(str));
if(!V_BSTR(retv)) if(!V_BSTR(retv))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
}else {
V_BSTR(retv) = NULL;
} }
return S_OK; return S_OK;
}
case JSV_NUMBER: { case JSV_NUMBER: {
double n = get_number(val); double n = get_number(val);
...@@ -459,7 +454,7 @@ HRESULT to_boolean(jsval_t val, BOOL *ret) ...@@ -459,7 +454,7 @@ HRESULT to_boolean(jsval_t val, BOOL *ret)
*ret = get_object(val) != NULL; *ret = get_object(val) != NULL;
return S_OK; return S_OK;
case JSV_STRING: case JSV_STRING:
*ret = get_string(val) && *get_string(val); *ret = jsstr_length(get_string(val)) != 0;
return S_OK; return S_OK;
case JSV_NUMBER: case JSV_NUMBER:
*ret = !isnan(get_number(val)) && get_number(val); *ret = !isnan(get_number(val)) && get_number(val);
...@@ -491,9 +486,9 @@ static int hex_to_int(WCHAR c) ...@@ -491,9 +486,9 @@ static int hex_to_int(WCHAR c)
} }
/* ECMA-262 3rd Edition 9.3.1 */ /* ECMA-262 3rd Edition 9.3.1 */
static HRESULT str_to_number(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; BOOL neg = FALSE;
DOUBLE d = 0.0; DOUBLE d = 0.0;
...@@ -669,14 +664,14 @@ HRESULT to_uint32(script_ctx_t *ctx, jsval_t val, DWORD *ret) ...@@ -669,14 +664,14 @@ HRESULT to_uint32(script_ctx_t *ctx, jsval_t val, DWORD *ret)
return S_OK; return S_OK;
} }
static BSTR int_to_bstr(int i) static jsstr_t *int_to_string(int i)
{ {
WCHAR buf[12], *p; WCHAR buf[12], *p;
BOOL neg = FALSE; BOOL neg = FALSE;
if(!i) { if(!i) {
static const WCHAR zeroW[] = {'0',0}; static const WCHAR zeroW[] = {'0',0};
return SysAllocString(zeroW); return jsstr_alloc(zeroW);
} }
if(i < 0) { if(i < 0) {
...@@ -696,24 +691,24 @@ static BSTR int_to_bstr(int i) ...@@ -696,24 +691,24 @@ static BSTR int_to_bstr(int i)
else else
p++; 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}; const WCHAR InfinityW[] = {'-','I','n','f','i','n','i','t','y',0};
if(isnan(n)) { if(isnan(n)) {
*str = SysAllocString(NaNW); *str = jsstr_nan();
}else if(isinf(n)) { }else if(isinf(n)) {
*str = SysAllocString(n<0 ? InfinityW : InfinityW+1); *str = jsstr_alloc(n<0 ? InfinityW : InfinityW+1);
}else if(is_int32(n)) { }else if(is_int32(n)) {
*str = int_to_bstr(n); *str = int_to_string(n);
}else { }else {
VARIANT strv, v; VARIANT strv, v;
HRESULT hres; HRESULT hres;
/* FIXME: Don't use VariantChangeTypeEx */
V_VT(&v) = VT_R8; V_VT(&v) = VT_R8;
V_R8(&v) = n; V_R8(&v) = n;
V_VT(&strv) = VT_EMPTY; V_VT(&strv) = VT_EMPTY;
...@@ -721,14 +716,15 @@ HRESULT double_to_bstr(double n, BSTR *str) ...@@ -721,14 +716,15 @@ HRESULT double_to_bstr(double n, BSTR *str)
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
*str = V_BSTR(&strv); *str = jsstr_alloc(V_BSTR(&strv));
SysFreeString(V_BSTR(&strv));
} }
return *str ? S_OK : E_OUTOFMEMORY; return *str ? S_OK : E_OUTOFMEMORY;
} }
/* ECMA-262 3rd Edition 9.8 */ /* 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 undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
const WCHAR nullW[] = {'n','u','l','l',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) ...@@ -737,15 +733,15 @@ HRESULT to_string(script_ctx_t *ctx, jsval_t val, BSTR *str)
switch(jsval_type(val)) { switch(jsval_type(val)) {
case JSV_UNDEFINED: case JSV_UNDEFINED:
*str = SysAllocString(undefinedW); *str = jsstr_alloc(undefinedW);
break; break;
case JSV_NULL: case JSV_NULL:
*str = SysAllocString(nullW); *str = jsstr_alloc(nullW);
break; break;
case JSV_NUMBER: case JSV_NUMBER:
return double_to_bstr(get_number(val), str); return double_to_string(get_number(val), str);
case JSV_STRING: case JSV_STRING:
*str = clone_bstr(get_string(val)); *str = jsstr_addref(get_string(val));
break; break;
case JSV_OBJECT: { case JSV_OBJECT: {
jsval_t prim; jsval_t prim;
...@@ -760,7 +756,7 @@ HRESULT to_string(script_ctx_t *ctx, jsval_t val, BSTR *str) ...@@ -760,7 +756,7 @@ HRESULT to_string(script_ctx_t *ctx, jsval_t val, BSTR *str)
return hres; return hres;
} }
case JSV_BOOL: case JSV_BOOL:
*str = SysAllocString(get_bool(val) ? trueW : falseW); *str = jsstr_alloc(get_bool(val) ? trueW : falseW);
break; break;
default: default:
FIXME("unsupported %s\n", debugstr_jsval(val)); FIXME("unsupported %s\n", debugstr_jsval(val));
...@@ -778,7 +774,7 @@ HRESULT to_object(script_ctx_t *ctx, jsval_t val, IDispatch **disp) ...@@ -778,7 +774,7 @@ HRESULT to_object(script_ctx_t *ctx, jsval_t val, IDispatch **disp)
switch(jsval_type(val)) { switch(jsval_type(val)) {
case JSV_STRING: 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)) if(FAILED(hres))
return hres; return hres;
...@@ -883,11 +879,20 @@ HRESULT variant_change_type(script_ctx_t *ctx, VARIANT *dst, VARIANT *src, VARTY ...@@ -883,11 +879,20 @@ HRESULT variant_change_type(script_ctx_t *ctx, VARIANT *dst, VARIANT *src, VARTY
break; break;
} }
case VT_BSTR: { case VT_BSTR: {
BSTR str; jsstr_t *str;
hres = to_string(ctx, val, &str); hres = to_string(ctx, val, &str);
if(SUCCEEDED(hres)) if(FAILED(hres))
V_BSTR(dst) = str; 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; break;
} }
case VT_EMPTY: case VT_EMPTY:
......
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
#ifndef JSVAL_H #ifndef JSVAL_H
#define JSVAL_H #define JSVAL_H
#include "jsstr.h"
/* /*
* jsval_t structure is used to represent JavaScript dynamically-typed values. * 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) * It's a (type,value) pair, usually represented as a structure of enum (type)
...@@ -56,7 +58,7 @@ struct _jsval_t { ...@@ -56,7 +58,7 @@ struct _jsval_t {
struct { struct {
union { union {
IDispatch *obj; IDispatch *obj;
BSTR str; jsstr_t *str;
BOOL b; BOOL b;
VARIANT *v; VARIANT *v;
UINT_PTR as_uintptr; UINT_PTR as_uintptr;
...@@ -68,7 +70,7 @@ struct _jsval_t { ...@@ -68,7 +70,7 @@ struct _jsval_t {
jsval_type_t type; jsval_type_t type;
union { union {
IDispatch *obj; IDispatch *obj;
BSTR str; jsstr_t *str;
double n; double n;
BOOL b; BOOL b;
VARIANT *v; VARIANT *v;
...@@ -104,7 +106,7 @@ static inline jsval_t jsval_bool(BOOL b) ...@@ -104,7 +106,7 @@ static inline jsval_t jsval_bool(BOOL b)
return ret; return ret;
} }
static inline jsval_t jsval_string(BSTR str) static inline jsval_t jsval_string(jsstr_t *str)
{ {
jsval_t ret; jsval_t ret;
__JSVAL_TYPE(ret) = JSV_STRING; __JSVAL_TYPE(ret) = JSV_STRING;
...@@ -224,7 +226,7 @@ static inline double get_number(jsval_t v) ...@@ -224,7 +226,7 @@ static inline double get_number(jsval_t v)
return v.u.n; 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); return __JSVAL_STR(v);
} }
......
...@@ -91,12 +91,13 @@ static inline void dtoa(double d, WCHAR *buf, int size, int *dec_point) ...@@ -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]; WCHAR buf[NUMBER_DTOA_SIZE];
int dec_point, size, buf_size, buf_pos; int dec_point, size, buf_size, buf_pos;
BOOL neg = FALSE; BOOL neg = FALSE;
BSTR str; jsstr_t *ret;
WCHAR *str;
if(val < 0) { if(val < 0) {
neg = TRUE; neg = TRUE;
...@@ -122,7 +123,11 @@ static inline void number_to_fixed(double val, int prec, BSTR *out) ...@@ -122,7 +123,11 @@ static inline void number_to_fixed(double val, int prec, BSTR *out)
if(prec) if(prec)
size += prec+1; size += prec+1;
str = SysAllocStringLen(NULL, size); ret = jsstr_alloc_buf(size);
if(!ret)
return NULL;
str = ret->str;
size = buf_pos = 0; size = buf_pos = 0;
if(neg) if(neg)
str[size++] = '-'; str[size++] = '-';
...@@ -146,16 +151,16 @@ static inline void number_to_fixed(double val, int prec, BSTR *out) ...@@ -146,16 +151,16 @@ static inline void number_to_fixed(double val, int prec, BSTR *out)
} }
} }
str[size++] = 0; str[size++] = 0;
return ret;
*out = str;
} }
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; WCHAR buf[NUMBER_DTOA_SIZE], *pbuf;
int dec_point, size, buf_size, exp_size = 1; int dec_point, size, buf_size, exp_size = 1;
BOOL neg = FALSE; BOOL neg = FALSE;
BSTR str; jsstr_t *ret;
WCHAR *str;
if(val < 0) { if(val < 0) {
neg = TRUE; neg = TRUE;
...@@ -185,8 +190,12 @@ static inline void number_to_exponential(double val, int prec, BSTR *out) ...@@ -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+) */ size = prec+4+exp_size; /* 4 = strlen(0.e+) */
if(neg) if(neg)
size++; size++;
str = SysAllocStringLen(NULL, size);
ret = jsstr_alloc_buf(size);
if(!ret)
return NULL;
str = ret->str;
size = 0; size = 0;
pbuf = buf; pbuf = buf;
if(neg) if(neg)
...@@ -214,7 +223,7 @@ static inline void number_to_exponential(double val, int prec, BSTR *out) ...@@ -214,7 +223,7 @@ static inline void number_to_exponential(double val, int prec, BSTR *out)
size += exp_size; size += exp_size;
str[size] = 0; str[size] = 0;
*out = str; return ret;
} }
/* ECMA-262 3rd Edition 15.7.4.2 */ /* 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 ...@@ -224,7 +233,7 @@ static HRESULT Number_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
NumberInstance *number; NumberInstance *number;
INT radix = 10; INT radix = 10;
DOUBLE val; DOUBLE val;
BSTR str; jsstr_t *str;
HRESULT hres; HRESULT hres;
TRACE("\n"); TRACE("\n");
...@@ -326,7 +335,7 @@ static HRESULT Number_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u ...@@ -326,7 +335,7 @@ static HRESULT Number_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
} }
else buf[idx] = '\0'; else buf[idx] = '\0';
str = SysAllocString(buf); str = jsstr_alloc(buf);
if(!str) if(!str)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
...@@ -334,7 +343,7 @@ static HRESULT Number_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u ...@@ -334,7 +343,7 @@ static HRESULT Number_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
if(r) if(r)
*r = jsval_string(str); *r = jsval_string(str);
else else
SysFreeString(str); jsstr_release(str);
return S_OK; return S_OK;
} }
...@@ -351,7 +360,7 @@ static HRESULT Number_toFixed(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un ...@@ -351,7 +360,7 @@ static HRESULT Number_toFixed(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
NumberInstance *number; NumberInstance *number;
DOUBLE val; DOUBLE val;
INT prec = 0; INT prec = 0;
BSTR str; jsstr_t *str;
HRESULT hres; HRESULT hres;
TRACE("\n"); TRACE("\n");
...@@ -374,13 +383,15 @@ static HRESULT Number_toFixed(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un ...@@ -374,13 +383,15 @@ static HRESULT Number_toFixed(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
}else { }else {
number_to_fixed(val, prec, &str); str = number_to_fixed(val, prec);
if(!str)
return E_OUTOFMEMORY;
} }
if(r) if(r)
*r = jsval_string(str); *r = jsval_string(str);
else else
SysFreeString(str); jsstr_release(str);
return S_OK; return S_OK;
} }
...@@ -390,7 +401,7 @@ static HRESULT Number_toExponential(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla ...@@ -390,7 +401,7 @@ static HRESULT Number_toExponential(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla
NumberInstance *number; NumberInstance *number;
DOUBLE val; DOUBLE val;
INT prec = 0; INT prec = 0;
BSTR str; jsstr_t *str;
HRESULT hres; HRESULT hres;
TRACE("\n"); TRACE("\n");
...@@ -415,13 +426,15 @@ static HRESULT Number_toExponential(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla ...@@ -415,13 +426,15 @@ static HRESULT Number_toExponential(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla
}else { }else {
if(!prec) if(!prec)
prec--; prec--;
number_to_exponential(val, prec, &str); str = number_to_exponential(val, prec);
if(!str)
return E_OUTOFMEMORY;
} }
if(r) if(r)
*r = jsval_string(str); *r = jsval_string(str);
else else
SysFreeString(str); jsstr_release(str);
return S_OK; return S_OK;
} }
...@@ -430,8 +443,8 @@ static HRESULT Number_toPrecision(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags ...@@ -430,8 +443,8 @@ static HRESULT Number_toPrecision(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
{ {
NumberInstance *number; NumberInstance *number;
INT prec = 0, size; INT prec = 0, size;
jsstr_t *str;
DOUBLE val; DOUBLE val;
BSTR str;
HRESULT hres; HRESULT hres;
if(!(number = number_this(jsthis))) if(!(number = number_this(jsthis)))
...@@ -458,15 +471,17 @@ static HRESULT Number_toPrecision(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags ...@@ -458,15 +471,17 @@ static HRESULT Number_toPrecision(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
size = 1; size = 1;
if(size > prec) if(size > prec)
number_to_exponential(val, prec-1, &str); str = number_to_exponential(val, prec-1);
else else
number_to_fixed(val, prec-size, &str); str = number_to_fixed(val, prec-size);
if(!str)
return E_OUTOFMEMORY;
} }
if(r) if(r)
*r = jsval_string(str); *r = jsval_string(str);
else else
SysFreeString(str); jsstr_release(str);
return S_OK; return S_OK;
} }
......
...@@ -67,11 +67,13 @@ static HRESULT Object_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u ...@@ -67,11 +67,13 @@ static HRESULT Object_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
} }
if(r) { if(r) {
BSTR ret = SysAllocStringLen(NULL, 9+strlenW(str)); jsstr_t *ret;
ret = jsstr_alloc_buf(9+strlenW(str));
if(!ret) if(!ret)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
sprintfW(ret, formatW, str); sprintfW(ret->str, formatW, str);
*r = jsval_string(ret); *r = jsval_string(ret);
} }
...@@ -106,7 +108,7 @@ static HRESULT Object_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un ...@@ -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, static HRESULT Object_hasOwnProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r) jsval_t *r)
{ {
BSTR name; jsstr_t *name;
DISPID id; DISPID id;
HRESULT hres; HRESULT hres;
...@@ -125,7 +127,7 @@ static HRESULT Object_hasOwnProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD fl ...@@ -125,7 +127,7 @@ static HRESULT Object_hasOwnProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD fl
if(is_jsdisp(jsthis)) { if(is_jsdisp(jsthis)) {
BOOL result; 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)) if(FAILED(hres))
return hres; return hres;
...@@ -135,11 +137,19 @@ static HRESULT Object_hasOwnProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD fl ...@@ -135,11 +137,19 @@ static HRESULT Object_hasOwnProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD fl
} }
if(is_dispex(jsthis)) { 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); make_grfdex(ctx, fdexNameCaseSensitive), &id);
SysFreeString(bstr);
} else { } else {
OLECHAR *names = name->str;
hres = IDispatch_GetIDsOfNames(jsthis->u.disp, &IID_NULL, hres = IDispatch_GetIDsOfNames(jsthis->u.disp, &IID_NULL,
&name, 1, ctx->lcid, &id); &names, 1, ctx->lcid, &id);
} }
if(r) if(r)
...@@ -170,7 +180,7 @@ static HRESULT Object_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi ...@@ -170,7 +180,7 @@ static HRESULT Object_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
case INVOKE_FUNC: case INVOKE_FUNC:
return throw_type_error(ctx, JS_E_FUNCTION_EXPECTED, NULL); return throw_type_error(ctx, JS_E_FUNCTION_EXPECTED, NULL);
case DISPATCH_PROPERTYGET: { case DISPATCH_PROPERTYGET: {
BSTR ret = SysAllocString(default_valueW); jsstr_t *ret = jsstr_alloc(default_valueW);
if(!ret) if(!ret)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
*r = jsval_string(ret); *r = jsval_string(ret);
......
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