static HRESULT array_to_args(script_ctx_t *ctx, jsdisp_t *arg_array, unsigned *argc, jsval_t **ret) { jsval_t *argv, val; DWORD length, i; HRESULT hres; hres = jsdisp_propget_name(arg_array, lengthW, &val); if(FAILED(hres)) return hres; hres = to_uint32(ctx, val, &length); jsval_release(val); if(FAILED(hres)) return hres; argv = heap_alloc(length * sizeof(*argv)); if(!argv) return E_OUTOFMEMORY; for(i=0; i<length; i++) { hres = jsdisp_get_idx(arg_array, i, argv+i); if(hres == DISP_E_UNKNOWNNAME) { argv[i] = jsval_undefined(); }else if(FAILED(hres)) { while(i--) jsval_release(argv[i]); heap_free(argv); return hres; } } *argc = length; *ret = argv; return S_OK; }
static HRESULT get_length(script_ctx_t *ctx, vdisp_t *vdisp, jsexcept_t *ei, jsdisp_t **jsthis, DWORD *ret) { ArrayInstance *array; VARIANT var; HRESULT hres; array = array_this(vdisp); if(array) { *jsthis = &array->dispex; *ret = array->length; return S_OK; } if(!is_jsdisp(vdisp)) return throw_type_error(ctx, ei, JS_E_JSCRIPT_EXPECTED, NULL); hres = jsdisp_propget_name(vdisp->u.jsdisp, lengthW, &var, ei); if(FAILED(hres)) return hres; hres = to_uint32(ctx, &var, ei, ret); VariantClear(&var); if(FAILED(hres)) return hres; *jsthis = vdisp->u.jsdisp; return S_OK; }
static HRESULT get_length(script_ctx_t *ctx, vdisp_t *vdisp, jsdisp_t **jsthis, DWORD *ret) { ArrayInstance *array; jsval_t val; HRESULT hres; array = array_this(vdisp); if(array) { *jsthis = &array->dispex; *ret = array->length; return S_OK; } if(!is_jsdisp(vdisp)) return throw_type_error(ctx, JS_E_JSCRIPT_EXPECTED, NULL); hres = jsdisp_propget_name(vdisp->u.jsdisp, lengthW, &val); if(FAILED(hres)) return hres; hres = to_uint32(ctx, val, ret); jsval_release(val); if(FAILED(hres)) return hres; *jsthis = vdisp->u.jsdisp; return S_OK; }
static HRESULT array_to_args(script_ctx_t *ctx, jsdisp_t *arg_array, jsexcept_t *ei, DISPPARAMS *args) { VARIANT var, *argv; DWORD length, i; HRESULT hres; hres = jsdisp_propget_name(arg_array, lengthW, &var, ei); if(FAILED(hres)) return hres; hres = to_uint32(ctx, &var, ei, &length); VariantClear(&var); if(FAILED(hres)) return hres; argv = heap_alloc(length * sizeof(VARIANT)); if(!argv) return E_OUTOFMEMORY; for(i=0; i<length; i++) { hres = jsdisp_get_idx(arg_array, i, argv+i, ei); if(hres == DISP_E_UNKNOWNNAME) V_VT(argv+i) = VT_EMPTY; else if(FAILED(hres)) { while(i--) VariantClear(argv+i); heap_free(argv); return hres; } } args->cArgs = length; args->rgvarg = argv; return S_OK; }
static HRESULT Arguments_idx_get(jsdisp_t *jsdisp, unsigned idx, jsval_t *res) { ArgumentsInstance *arguments = (ArgumentsInstance*)jsdisp; TRACE("%p[%u]\n", arguments, idx); /* FIXME: Accessing by name won't work for duplicated argument names */ return jsdisp_propget_name(arguments->var_obj, arguments->function->func_code->params[idx], res); }
HRESULT jsdisp_propget_idx(DispatchEx *obj, DWORD idx, LCID lcid, VARIANT *var, jsexcept_t *ei, IServiceProvider *caller) { WCHAR buf[12]; static const WCHAR formatW[] = {'%','d',0}; sprintfW(buf, formatW, idx); return jsdisp_propget_name(obj, buf, lcid, var, ei, caller); }
/* ECMA-262 3rd Edition 15.11.4.4 */ static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) { ErrorInstance *error; BSTR name, msg = NULL, ret = NULL; VARIANT v; HRESULT hres; static const WCHAR str[] = {'[','o','b','j','e','c','t',' ','E','r','r','o','r',']',0}; TRACE("\n"); error = error_this(jsthis); if(ctx->version < 2 || !error) { if(retv) { V_VT(retv) = VT_BSTR; V_BSTR(retv) = SysAllocString(str); if(!V_BSTR(retv)) return E_OUTOFMEMORY; } return S_OK; } hres = jsdisp_propget_name(&error->dispex, nameW, &v, ei, caller); if(FAILED(hres)) return hres; hres = to_string(ctx, &v, ei, &name); VariantClear(&v); if(FAILED(hres)) return hres; if(V_VT(&error->message) != VT_EMPTY) { hres = to_string(ctx, &error->message, ei, &msg); if(SUCCEEDED(hres) && !*msg) { SysFreeString(msg); msg = NULL; } } if(SUCCEEDED(hres)) { if(msg) { DWORD name_len, msg_len; name_len = SysStringLen(name); msg_len = SysStringLen(msg); ret = SysAllocStringLen(NULL, 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)); } }else { ret = name; name = NULL; } } SysFreeString(msg); SysFreeString(name); if(FAILED(hres)) return hres; if(!ret) return E_OUTOFMEMORY; if(retv) { V_VT(retv) = VT_BSTR; V_BSTR(retv) = ret; }else { SysFreeString(ret); } return S_OK; }
/* ECMA-262 3rd Edition 15.11.4.4 */ static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { jsdisp_t *jsthis; jsstr_t *name = NULL, *msg = NULL, *ret = NULL; jsval_t v; HRESULT hres; static const WCHAR object_errorW[] = {'[','o','b','j','e','c','t',' ','E','r','r','o','r',']',0}; TRACE("\n"); jsthis = get_jsdisp(vthis); if(!jsthis || ctx->version < 2) { if(r) { jsstr_t *str; str = jsstr_alloc(object_errorW); if(!str) return E_OUTOFMEMORY; *r = jsval_string(str); } return S_OK; } hres = jsdisp_propget_name(jsthis, nameW, &v); if(FAILED(hres)) return hres; if(!is_undefined(v)) { hres = to_string(ctx, v, &name); jsval_release(v); if(FAILED(hres)) return hres; } hres = jsdisp_propget_name(jsthis, messageW, &v); if(SUCCEEDED(hres)) { if(!is_undefined(v)) { hres = to_string(ctx, v, &msg); jsval_release(v); } } if(SUCCEEDED(hres)) { unsigned name_len = name ? jsstr_length(name) : 0; unsigned msg_len = msg ? jsstr_length(msg) : 0; if(name_len && msg_len) { ret = jsstr_alloc_buf(name_len + msg_len + 2); if(ret) { jsstr_flush(name, ret->str); ret->str[name_len] = ':'; ret->str[name_len+1] = ' '; jsstr_flush(msg, ret->str+name_len+2); } }else if(name_len) { ret = name; name = NULL; }else if(msg_len) { ret = msg; msg = NULL; }else { ret = jsstr_alloc(object_errorW); } } if(msg) jsstr_release(msg); if(name) jsstr_release(name); if(FAILED(hres)) return hres; if(!ret) return E_OUTOFMEMORY; if(r) *r = jsval_string(ret); else jsstr_release(ret); return S_OK; }