static HRESULT RegExp_exec(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { match_state_t *match; heap_pool_t *mark; BOOL b; jsstr_t *string; HRESULT hres; TRACE("\n"); mark = heap_pool_mark(&ctx->tmp_heap); hres = run_exec(ctx, jsthis, argc ? argv[0] : jsval_string(jsstr_empty()), &string, &match, &b); if(FAILED(hres)) { heap_pool_clear(mark); return hres; } if(r) { if(b) { IDispatch *ret; hres = create_match_array(ctx, string, match, &ret); if(SUCCEEDED(hres)) *r = jsval_disp(ret); }else { *r = jsval_null(); } } heap_pool_clear(mark); jsstr_release(string); return hres; }
static HRESULT StringConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { HRESULT hres; TRACE("\n"); switch(flags) { case INVOKE_FUNC: { jsstr_t *str; if(argc) { hres = to_string(ctx, argv[0], &str); if(FAILED(hres)) return hres; } else { str = jsstr_empty(); } *r = jsval_string(str); break; } case DISPATCH_CONSTRUCT: { jsstr_t *str; jsdisp_t *ret; if(argc) { hres = to_string(ctx, argv[0], &str); if(FAILED(hres)) return hres; } else { str = jsstr_empty(); } hres = create_string(ctx, str, &ret); if (SUCCEEDED(hres)) *r = jsval_obj(ret); jsstr_release(str); return hres; } default: FIXME("unimplemented flags: %x\n", flags); return E_NOTIMPL; } return S_OK; }
static HRESULT run_exec(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t arg, jsstr_t **input, match_state_t **result, BOOL *ret) { RegExpInstance *regexp; match_state_t *match; DWORD last_index = 0; const WCHAR *string; jsstr_t *jsstr; HRESULT hres; if(!is_vclass(jsthis, JSCLASS_REGEXP)) { FIXME("Not a RegExp\n"); return E_NOTIMPL; } regexp = regexp_from_vdisp(jsthis); hres = to_flat_string(ctx, arg, &jsstr, &string); if(FAILED(hres)) return hres; if(regexp->jsregexp->flags & REG_GLOB) { if(regexp->last_index < 0) { jsstr_release(jsstr); set_last_index(regexp, 0); *ret = FALSE; if(input) *input = jsstr_empty(); return S_OK; } last_index = regexp->last_index; } match = alloc_match_state(regexp->jsregexp, &ctx->tmp_heap, string+last_index); if(!match) { jsstr_release(jsstr); return E_OUTOFMEMORY; } hres = regexp_match_next(ctx, ®exp->dispex, REM_RESET_INDEX, jsstr, &match); if(FAILED(hres)) { jsstr_release(jsstr); return hres; } *result = match; *ret = hres == S_OK; if(input) *input = jsstr; else jsstr_release(jsstr); return S_OK; }
static HRESULT rep_call(script_ctx_t *ctx, jsdisp_t *func, jsstr_t *jsstr, const WCHAR *str, match_state_t *match, jsstr_t **ret) { jsval_t *argv; unsigned argc; jsval_t val; jsstr_t *tmp_str; DWORD i; HRESULT hres = S_OK; argc = match->paren_count+3; argv = heap_alloc_zero(sizeof(*argv)*argc); if(!argv) return E_OUTOFMEMORY; tmp_str = jsstr_alloc_len(match->cp-match->match_len, match->match_len); if(!tmp_str) hres = E_OUTOFMEMORY; argv[0] = jsval_string(tmp_str); if(SUCCEEDED(hres)) { for(i=0; i < match->paren_count; i++) { if(match->parens[i].index != -1) tmp_str = jsstr_substr(jsstr, match->parens[i].index, match->parens[i].length); else tmp_str = jsstr_empty(); if(!tmp_str) { hres = E_OUTOFMEMORY; break; } argv[i+1] = jsval_string(tmp_str); } } if(SUCCEEDED(hres)) { argv[match->paren_count+1] = jsval_number(match->cp-str - match->match_len); argv[match->paren_count+2] = jsval_string(jsstr); } if(SUCCEEDED(hres)) hres = jsdisp_call_value(func, NULL, DISPATCH_METHOD, argc, argv, &val); for(i=0; i <= match->paren_count; i++) jsstr_release(get_string(argv[i])); heap_free(argv); if(FAILED(hres)) return hres; hres = to_string(ctx, val, ret); jsval_release(val); return hres; }
static HRESULT error_constr(script_ctx_t *ctx, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r, jsdisp_t *constr) { jsdisp_t *err; UINT num = 0; jsstr_t *msg = NULL; HRESULT hres; if(argc) { double n; hres = to_number(ctx, argv[0], &n); if(FAILED(hres)) /* FIXME: really? */ n = NAN; if(isnan(n)) hres = to_string(ctx, argv[0], &msg); if(FAILED(hres)) return hres; num = n; } if(!msg) { if(argc > 1) { hres = to_string(ctx, argv[1], &msg); if(FAILED(hres)) return hres; }else { msg = jsstr_empty(); } } switch(flags) { case INVOKE_FUNC: case DISPATCH_CONSTRUCT: hres = create_error(ctx, constr, num, msg, &err); jsstr_release(msg); if(FAILED(hres)) return hres; if(r) *r = jsval_obj(err); else jsdisp_release(err); return S_OK; default: if(msg) jsstr_release(msg); FIXME("unimplemented flags %x\n", flags); return E_NOTIMPL; } }
HRESULT create_string_constr(script_ctx_t *ctx, jsdisp_t *object_prototype, jsdisp_t **ret) { StringInstance *string; HRESULT hres; static const WCHAR StringW[] = {'S','t','r','i','n','g',0}; hres = string_alloc(ctx, object_prototype, jsstr_empty(), &string); if(FAILED(hres)) return hres; hres = create_builtin_constructor(ctx, StringConstr_value, StringW, &StringConstr_info, PROPF_CONSTR|1, &string->dispex, ret); jsdisp_release(&string->dispex); return hres; }
static HRESULT WINAPI JScriptParse_InitNew(IActiveScriptParse *iface) { JScript *This = impl_from_IActiveScriptParse(iface); script_ctx_t *ctx; HRESULT hres; TRACE("(%p)\n", This); if(This->ctx) return E_UNEXPECTED; ctx = heap_alloc_zero(sizeof(script_ctx_t)); if(!ctx) return E_OUTOFMEMORY; ctx->ref = 1; ctx->state = SCRIPTSTATE_UNINITIALIZED; ctx->active_script = &This->IActiveScript_iface; ctx->safeopt = This->safeopt; ctx->version = This->version; ctx->html_mode = This->html_mode; ctx->ei.val = jsval_undefined(); ctx->acc = jsval_undefined(); heap_pool_init(&ctx->tmp_heap); hres = create_jscaller(ctx); if(FAILED(hres)) { heap_free(ctx); return hres; } ctx->last_match = jsstr_empty(); ctx = InterlockedCompareExchangePointer((void**)&This->ctx, ctx, NULL); if(ctx) { script_release(ctx); return E_UNEXPECTED; } return This->site ? set_ctx_site(This) : S_OK; }
/* ECMA-262 3rd Edition 15.5.4.5 */ static HRESULT String_charAt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { jsstr_t *str, *ret; INT pos = 0; HRESULT hres; TRACE("\n"); hres = get_string_val(ctx, jsthis, &str); if(FAILED(hres)) return hres; if(argc) { double d; hres = to_integer(ctx, argv[0], &d); if(FAILED(hres)) { jsstr_release(str); return hres; } pos = is_int32(d) ? d : -1; } if(!r) { jsstr_release(str); return S_OK; } if(0 <= pos && pos < jsstr_length(str)) { ret = jsstr_substr(str, pos, 1); if(!ret) return E_OUTOFMEMORY; } else { ret = jsstr_empty(); } *r = jsval_string(ret); return S_OK; }
static HRESULT array_join(script_ctx_t *ctx, jsdisp_t *array, DWORD length, const WCHAR *sep, jsval_t *r) { jsstr_t **str_tab, *ret; jsval_t val; DWORD i; HRESULT hres = E_FAIL; if(!length) { if(r) *r = jsval_string(jsstr_empty()); return S_OK; } str_tab = heap_alloc_zero(length * sizeof(*str_tab)); if(!str_tab) return E_OUTOFMEMORY; for(i=0; i < length; i++) { hres = jsdisp_get_idx(array, i, &val); if(hres == DISP_E_UNKNOWNNAME) { hres = S_OK; continue; } else if(FAILED(hres)) break; if(!is_undefined(val) && !is_null(val)) { hres = to_string(ctx, val, str_tab+i); jsval_release(val); if(FAILED(hres)) break; } } if(SUCCEEDED(hres)) { DWORD seplen = 0, len = 0; seplen = strlenW(sep); if(str_tab[0]) 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; } } if(SUCCEEDED(hres)) { WCHAR *ptr = NULL; ptr = jsstr_alloc_buf(len, &ret); if(ptr) { if(str_tab[0]) ptr += jsstr_flush(str_tab[0], ptr); for(i=1; i < length; i++) { if(seplen) { memcpy(ptr, sep, seplen*sizeof(WCHAR)); ptr += seplen; } if(str_tab[i]) ptr += jsstr_flush(str_tab[i], ptr); } }else { hres = E_OUTOFMEMORY; } } } 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_jsstr(ret)); if(r) *r = jsval_string(ret); else jsstr_release(ret); return S_OK; }
static HRESULT create_match_array(script_ctx_t *ctx, jsstr_t *input, const match_state_t *result, IDispatch **ret) { jsdisp_t *array; jsstr_t *str; DWORD i; HRESULT hres = S_OK; static const WCHAR indexW[] = {'i','n','d','e','x',0}; static const WCHAR inputW[] = {'i','n','p','u','t',0}; static const WCHAR lastIndexW[] = {'l','a','s','t','I','n','d','e','x',0}; static const WCHAR zeroW[] = {'0',0}; hres = create_array(ctx, result->paren_count+1, &array); if(FAILED(hres)) return hres; for(i=0; i < result->paren_count; i++) { if(result->parens[i].index != -1) str = jsstr_substr(input, result->parens[i].index, result->parens[i].length); else str = jsstr_empty(); if(!str) { hres = E_OUTOFMEMORY; break; } hres = jsdisp_propput_idx(array, i+1, jsval_string(str)); jsstr_release(str); if(FAILED(hres)) break; } while(SUCCEEDED(hres)) { hres = jsdisp_propput_name(array, indexW, jsval_number(result->cp-input->str-result->match_len)); if(FAILED(hres)) break; hres = jsdisp_propput_name(array, lastIndexW, jsval_number(result->cp-input->str)); if(FAILED(hres)) break; hres = jsdisp_propput_name(array, inputW, jsval_string(jsstr_addref(input))); if(FAILED(hres)) break; str = jsstr_alloc_len(result->cp-result->match_len, result->match_len); if(!str) { hres = E_OUTOFMEMORY; break; } hres = jsdisp_propput_name(array, zeroW, jsval_string(str)); jsstr_release(str); break; } if(FAILED(hres)) { jsdisp_release(array); return hres; } *ret = to_disp(array); return S_OK; }