jscript: Optimize String.concat implementation.

This commit is contained in:
Jacek Caban 2013-04-25 15:23:48 +02:00 committed by Alexandre Julliard
parent f5d64e0613
commit b46ace51f8
1 changed files with 59 additions and 30 deletions

View File

@ -377,26 +377,52 @@ 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, static HRESULT String_concat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r) jsval_t *r)
{ {
unsigned len = 0, i, str_cnt; jsstr_t *ret, *str;
jsstr_t **strs, *ret = NULL;
WCHAR *ptr;
HRESULT hres; HRESULT hres;
TRACE("\n"); TRACE("\n");
str_cnt = argc+1; hres = get_string_val(ctx, jsthis, &str);
strs = heap_alloc_zero(str_cnt * sizeof(*strs)); if(FAILED(hres))
if(!strs) return hres;
return E_OUTOFMEMORY;
hres = to_string(ctx, jsval_disp(jsthis->u.disp), strs); switch(argc) {
if(SUCCEEDED(hres)) { case 0:
ret = str;
break;
case 1: {
jsstr_t *arg_str;
hres = to_string(ctx, argv[0], &arg_str);
if(FAILED(hres)) {
jsstr_release(str);
return hres;
}
ret = jsstr_concat(str, arg_str);
jsstr_release(str);
if(!ret)
return E_OUTOFMEMORY;
break;
}
default: {
const unsigned str_cnt = argc+1;
unsigned len = 0, i;
jsstr_t **strs;
WCHAR *ptr;
strs = heap_alloc_zero(str_cnt * sizeof(*strs));
if(!strs) {
jsstr_release(str);
return E_OUTOFMEMORY;
}
strs[0] = str;
for(i=0; i < argc; i++) { for(i=0; i < argc; i++) {
hres = to_string(ctx, argv[i], strs+i+1); hres = to_string(ctx, argv[i], strs+i+1);
if(FAILED(hres)) if(FAILED(hres))
break; break;
} }
}
if(SUCCEEDED(hres)) { if(SUCCEEDED(hres)) {
for(i=0; i < str_cnt; i++) { for(i=0; i < str_cnt; i++) {
@ -407,6 +433,7 @@ static HRESULT String_concat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
} }
} }
if(SUCCEEDED(hres)) {
ptr = jsstr_alloc_buf(len, &ret); ptr = jsstr_alloc_buf(len, &ret);
if(ptr) { if(ptr) {
for(i=0; i < str_cnt; i++) for(i=0; i < str_cnt; i++)
@ -415,13 +442,15 @@ static HRESULT String_concat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
hres = E_OUTOFMEMORY; hres = E_OUTOFMEMORY;
} }
} }
}
for(i=0; i < str_cnt; i++) while(i--)
jsstr_release(strs[i]); jsstr_release(strs[i]);
heap_free(strs); heap_free(strs);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
}
}
if(r) if(r)
*r = jsval_string(ret); *r = jsval_string(ret);