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