HRESULT variant_to_jsval(VARIANT *var, jsval_t *r) { switch(V_VT(var)) { case VT_EMPTY: *r = jsval_undefined(); return S_OK; case VT_NULL: *r = jsval_null(); return S_OK; case VT_BOOL: *r = jsval_bool(V_BOOL(var)); return S_OK; case VT_I4: *r = jsval_number(V_I4(var)); return S_OK; case VT_R8: *r = jsval_number(V_R8(var)); return S_OK; case VT_BSTR: { 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; *r = jsval_string(str); return S_OK; } case VT_DISPATCH: { if(V_DISPATCH(var)) IDispatch_AddRef(V_DISPATCH(var)); *r = jsval_disp(V_DISPATCH(var)); return S_OK; } case VT_I2: *r = jsval_number(V_I2(var)); return S_OK; case VT_INT: *r = jsval_number(V_INT(var)); return S_OK; case VT_UNKNOWN: if(V_UNKNOWN(var)) { IDispatch *disp; HRESULT hres; hres = IUnknown_QueryInterface(V_UNKNOWN(var), &IID_IDispatch, (void**)&disp); if(SUCCEEDED(hres)) { *r = jsval_disp(disp); return S_OK; } } /* fall through */ default: return jsval_variant(r, var); } }
static HRESULT FunctionConstr_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 DISPATCH_CONSTRUCT: { IDispatch *ret; hres = construct_function(ctx, argc, argv, &ret); if(FAILED(hres)) return hres; *r = jsval_disp(ret); break; } default: FIXME("unimplemented flags %x\n", flags); return E_NOTIMPL; } return S_OK; }
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 get_string_val(script_ctx_t *ctx, vdisp_t *jsthis, jsstr_t **val) { StringInstance *string; if((string = string_this(jsthis))) { *val = jsstr_addref(string->str); return S_OK; } return to_string(ctx, jsval_disp(jsthis->u.disp), val); }
static HRESULT create_arguments(script_ctx_t *ctx, FunctionInstance *calee, jsdisp_t *var_obj, unsigned argc, jsval_t *argv, jsdisp_t **ret) { ArgumentsInstance *args; unsigned i; HRESULT hres; static const WCHAR caleeW[] = {'c','a','l','l','e','e',0}; args = heap_alloc_zero(sizeof(*args)); if(!args) return E_OUTOFMEMORY; hres = init_dispex_from_constr(&args->jsdisp, ctx, &Arguments_info, ctx->object_constr); if(FAILED(hres)) { heap_free(args); return hres; } jsdisp_addref(&calee->dispex); args->function = calee; args->var_obj = jsdisp_addref(var_obj); /* Store unnamed arguments directly in arguments object */ for(i = calee->length; i < argc; i++) { WCHAR buf[12]; static const WCHAR formatW[] = {'%','d',0}; sprintfW(buf, formatW, i); hres = jsdisp_propput_dontenum(&args->jsdisp, buf, argv[i]); if(FAILED(hres)) break; } if(SUCCEEDED(hres)) { hres = jsdisp_propput_dontenum(&args->jsdisp, lengthW, jsval_number(argc)); if(SUCCEEDED(hres)) hres = jsdisp_propput_dontenum(&args->jsdisp, caleeW, jsval_disp(to_disp(&calee->dispex))); } if(FAILED(hres)) { jsdisp_release(&args->jsdisp); return hres; } *ret = &args->jsdisp; return S_OK; }
static HRESULT concat_obj(jsdisp_t *array, IDispatch *obj, DWORD *len) { jsdisp_t *jsobj; HRESULT hres; jsobj = iface_to_jsdisp((IUnknown*)obj); if(jsobj) { if(is_class(jsobj, JSCLASS_ARRAY)) { hres = concat_array(array, (ArrayInstance*)jsobj, len); jsdisp_release(jsobj); return hres; } jsdisp_release(jsobj); } return jsdisp_propput_idx(array, (*len)++, jsval_disp(obj)); }
static HRESULT ActiveXObject_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { jsstr_t * progid_str; const WCHAR *progid; IDispatch *disp; IUnknown *obj; HRESULT hres; TRACE("\n"); if(flags != DISPATCH_CONSTRUCT) { FIXME("unsupported flags %x\n", flags); return E_NOTIMPL; } if(ctx->safeopt != (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER) && ctx->safeopt != INTERFACE_USES_DISPEX) { FIXME("Unsupported safeopt %x\n", ctx->safeopt); return E_NOTIMPL; } if(argc != 1) { FIXME("unsupported argc %d\n", argc); return E_NOTIMPL; } hres = to_flat_string(ctx, argv[0], &progid_str, &progid); if(FAILED(hres)) return hres; obj = create_activex_object(ctx, progid); jsstr_release(progid_str); if(!obj) return throw_generic_error(ctx, JS_E_CANNOT_CREATE_OBJ, NULL); hres = IUnknown_QueryInterface(obj, &IID_IDispatch, (void**)&disp); IUnknown_Release(obj); if(FAILED(hres)) { FIXME("Object does not support IDispatch\n"); return E_NOTIMPL; } *r = jsval_disp(disp); return S_OK; }
static HRESULT create_arguments(script_ctx_t *ctx, IDispatch *calee, unsigned argc, jsval_t *argv, jsdisp_t **ret) { jsdisp_t *args; DWORD i; HRESULT hres; static const WCHAR caleeW[] = {'c','a','l','l','e','e',0}; args = heap_alloc_zero(sizeof(jsdisp_t)); if(!args) return E_OUTOFMEMORY; hres = init_dispex_from_constr(args, ctx, &Arguments_info, ctx->object_constr); if(FAILED(hres)) { heap_free(args); return hres; } for(i=0; i < argc; i++) { hres = jsdisp_propput_idx(args, i, argv[i]); if(FAILED(hres)) break; } if(SUCCEEDED(hres)) { hres = jsdisp_propput_name(args, lengthW, jsval_number(argc)); if(SUCCEEDED(hres)) hres = jsdisp_propput_name(args, caleeW, jsval_disp(calee)); } if(FAILED(hres)) { jsdisp_release(args); return hres; } *ret = args; return S_OK; }
HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, jsstr_t *str, jsval_t *r) { static const WCHAR indexW[] = {'i','n','d','e','x',0}; static const WCHAR inputW[] = {'i','n','p','u','t',0}; static const WCHAR lastIndexW[] = {'l','a','s','t','I','n','d','e','x',0}; RegExpInstance *regexp = (RegExpInstance*)re; match_result_t *match_result; unsigned match_cnt, i; jsdisp_t *array; HRESULT hres; if(!(regexp->jsregexp->flags & REG_GLOB)) { match_state_t *match; heap_pool_t *mark; mark = heap_pool_mark(&ctx->tmp_heap); match = alloc_match_state(regexp->jsregexp, &ctx->tmp_heap, str->str); if(!match) { heap_pool_clear(mark); return E_OUTOFMEMORY; } hres = regexp_match_next(ctx, ®exp->dispex, 0, str, &match); if(FAILED(hres)) { heap_pool_clear(mark); return hres; } if(r) { if(hres == S_OK) { IDispatch *ret; hres = create_match_array(ctx, str, match, &ret); if(SUCCEEDED(hres)) *r = jsval_disp(ret); }else { *r = jsval_null(); } } heap_pool_clear(mark); return S_OK; } hres = regexp_match(ctx, ®exp->dispex, str, FALSE, &match_result, &match_cnt); if(FAILED(hres)) return hres; if(!match_cnt) { TRACE("no match\n"); if(r) *r = jsval_null(); return S_OK; } hres = create_array(ctx, match_cnt, &array); if(FAILED(hres)) return hres; for(i=0; i < match_cnt; i++) { jsstr_t *tmp_str; tmp_str = jsstr_substr(str, match_result[i].index, match_result[i].length); if(!tmp_str) { hres = E_OUTOFMEMORY; break; } hres = jsdisp_propput_idx(array, i, jsval_string(tmp_str)); jsstr_release(tmp_str); if(FAILED(hres)) break; } while(SUCCEEDED(hres)) { hres = jsdisp_propput_name(array, indexW, jsval_number(match_result[match_cnt-1].index)); if(FAILED(hres)) break; hres = jsdisp_propput_name(array, lastIndexW, jsval_number(match_result[match_cnt-1].index + match_result[match_cnt-1].length)); if(FAILED(hres)) break; hres = jsdisp_propput_name(array, inputW, jsval_string(str)); break; } heap_free(match_result); if(SUCCEEDED(hres) && r) *r = jsval_obj(array); else jsdisp_release(array); return hres; }
HRESULT variant_to_jsval(VARIANT *var, jsval_t *r) { if(V_VT(var) == (VT_VARIANT|VT_BYREF)) var = V_VARIANTREF(var); switch(V_VT(var)) { case VT_EMPTY: *r = jsval_undefined(); return S_OK; case VT_NULL: *r = jsval_null(); return S_OK; case VT_BOOL: *r = jsval_bool(V_BOOL(var)); return S_OK; case VT_I4: *r = jsval_number(V_I4(var)); return S_OK; case VT_R8: *r = jsval_number(V_R8(var)); return S_OK; case VT_BSTR: { jsstr_t *str; if(V_BSTR(var)) { str = jsstr_alloc_len(V_BSTR(var), SysStringLen(V_BSTR(var))); if(!str) return E_OUTOFMEMORY; }else { str = jsstr_null_bstr(); } *r = jsval_string(str); return S_OK; } case VT_DISPATCH: { if(V_DISPATCH(var)) IDispatch_AddRef(V_DISPATCH(var)); *r = jsval_disp(V_DISPATCH(var)); return S_OK; } case VT_I2: *r = jsval_number(V_I2(var)); return S_OK; case VT_UI2: *r = jsval_number(V_UI2(var)); return S_OK; case VT_INT: *r = jsval_number(V_INT(var)); return S_OK; case VT_UI4: *r = jsval_number(V_UI4(var)); return S_OK; case VT_UI8: /* * Native doesn't support VT_UI8 here, but it's needed for IE9+ APIs * (native IE9 doesn't use jscript.dll for JavaScript). */ *r = jsval_number(V_UI8(var)); return S_OK; case VT_R4: *r = jsval_number(V_R4(var)); return S_OK; case VT_UNKNOWN: if(V_UNKNOWN(var)) { IDispatch *disp; HRESULT hres; hres = IUnknown_QueryInterface(V_UNKNOWN(var), &IID_IDispatch, (void**)&disp); if(SUCCEEDED(hres)) { *r = jsval_disp(disp); return S_OK; } }else { *r = jsval_disp(NULL); return S_OK; } /* fall through */ default: return jsval_variant(r, var); } }