[PATCH 1/5] jscript: Pass a jsval "this" to builtin functions.

Gabriel Ivăncescu gabrielopcode at gmail.com
Thu Mar 17 11:25:39 CDT 2022


And get rid of vdisp_t since it's no longer needed.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---

The spec says that in ES3, apply and call convert null or undefined arguments
to the global object, but that's wrong for builtins. Or at least, it's
not how it works on Windows. In fact, passing them to builtin functions
results in exceptions in many cases, because they're not objects or can't
be converted to objects. So the ES5 checks are still needed.

 dlls/jscript/activex.c    |   2 +-
 dlls/jscript/array.c      | 250 +++++++++++++++++++++++---------------
 dlls/jscript/bool.c       |  44 ++++---
 dlls/jscript/date.c       | 199 +++++++++++++++---------------
 dlls/jscript/dispex.c     |  17 +--
 dlls/jscript/enumerator.c |  28 ++---
 dlls/jscript/error.c      |  28 +++--
 dlls/jscript/function.c   |  51 ++++----
 dlls/jscript/global.c     |  34 +++---
 dlls/jscript/jscript.h    |  75 +-----------
 dlls/jscript/json.c       |   4 +-
 dlls/jscript/jsregexp.c   |  32 +++--
 dlls/jscript/math.c       |  36 +++---
 dlls/jscript/number.c     |  69 ++++++-----
 dlls/jscript/object.c     | 182 ++++++++++++++++++---------
 dlls/jscript/set.c        |  81 +++++++-----
 dlls/jscript/string.c     | 180 +++++++++++++--------------
 dlls/jscript/vbarray.c    |  24 ++--
 18 files changed, 696 insertions(+), 640 deletions(-)

diff --git a/dlls/jscript/activex.c b/dlls/jscript/activex.c
index 42cb513..5d79d2b 100644
--- a/dlls/jscript/activex.c
+++ b/dlls/jscript/activex.c
@@ -138,7 +138,7 @@ static IUnknown *create_activex_object(script_ctx_t *ctx, const WCHAR *progid)
     return obj;
 }
 
-static HRESULT ActiveXObject_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT ActiveXObject_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsstr_t * progid_str;
diff --git a/dlls/jscript/array.c b/dlls/jscript/array.c
index 6ee1809..9b97ef2 100644
--- a/dlls/jscript/array.c
+++ b/dlls/jscript/array.c
@@ -37,14 +37,10 @@ static inline ArrayInstance *array_from_jsdisp(jsdisp_t *jsdisp)
     return CONTAINING_RECORD(jsdisp, ArrayInstance, dispex);
 }
 
-static inline ArrayInstance *array_from_vdisp(vdisp_t *vdisp)
+static inline ArrayInstance *array_this(jsval_t vthis)
 {
-    return array_from_jsdisp(vdisp->u.jsdisp);
-}
-
-static inline ArrayInstance *array_this(vdisp_t *jsthis)
-{
-    return is_vclass(jsthis, JSCLASS_ARRAY) ? array_from_vdisp(jsthis) : NULL;
+    jsdisp_t *jsdisp = is_object_instance(vthis) ? to_jsdisp(get_object(vthis)) : NULL;
+    return (jsdisp && is_class(jsdisp, JSCLASS_ARRAY)) ? array_from_jsdisp(jsdisp) : NULL;
 }
 
 unsigned array_get_length(jsdisp_t *array)
@@ -53,33 +49,38 @@ unsigned array_get_length(jsdisp_t *array)
     return array_from_jsdisp(array)->length;
 }
 
-static HRESULT get_length(script_ctx_t *ctx, vdisp_t *vdisp, jsdisp_t **jsthis, UINT32 *ret)
+static HRESULT get_length(script_ctx_t *ctx, jsval_t vthis, jsdisp_t **jsthis, UINT32 *ret)
 {
-    ArrayInstance *array;
+    jsdisp_t *jsdisp;
+    IDispatch *disp;
     jsval_t val;
     HRESULT hres;
 
-    array = array_this(vdisp);
-    if(array) {
-        *jsthis = &array->dispex;
-        *ret = array->length;
-        return S_OK;
-    }
+    hres = to_object(ctx, vthis, &disp);
+    if(FAILED(hres))
+        return hres;
 
-    if(!is_jsdisp(vdisp))
+    jsdisp = iface_to_jsdisp(disp);
+    IDispatch_Release(disp);
+    if(!jsdisp)
         return JS_E_JSCRIPT_EXPECTED;
+    *jsthis = jsdisp;
 
-    hres = jsdisp_propget_name(vdisp->u.jsdisp, L"length", &val);
-    if(FAILED(hres))
-        return hres;
+    if(is_class(jsdisp, JSCLASS_ARRAY)) {
+        *ret = array_from_jsdisp(jsdisp)->length;
+        return S_OK;
+    }
 
-    hres = to_uint32(ctx, val, ret);
-    jsval_release(val);
-    if(FAILED(hres))
-        return hres;
+    hres = jsdisp_propget_name(jsdisp, L"length", &val);
+    if(SUCCEEDED(hres)) {
+        hres = to_uint32(ctx, val, ret);
+        jsval_release(val);
+        if(SUCCEEDED(hres))
+            return hres;
+    }
 
-    *jsthis = vdisp->u.jsdisp;
-    return S_OK;
+    jsdisp_release(jsdisp);
+    return hres;
 }
 
 static HRESULT set_length(jsdisp_t *obj, DWORD length)
@@ -183,20 +184,25 @@ static HRESULT concat_obj(jsdisp_t *array, IDispatch *obj, DWORD *len)
     return jsdisp_propput_idx(array, (*len)++, jsval_disp(obj));
 }
 
-static HRESULT Array_concat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Array_concat(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
+    IDispatch *jsthis;
     jsdisp_t *ret;
     DWORD len = 0;
     HRESULT hres;
 
     TRACE("\n");
 
-    hres = create_array(ctx, 0, &ret);
+    hres = to_object(ctx, vthis, &jsthis);
     if(FAILED(hres))
         return hres;
 
-    hres = concat_obj(ret, jsthis->u.disp, &len);
+    hres = create_array(ctx, 0, &ret);
+    if(FAILED(hres))
+        goto done;
+
+    hres = concat_obj(ret, jsthis, &len);
     if(SUCCEEDED(hres)) {
         DWORD i;
 
@@ -211,12 +217,14 @@ static HRESULT Array_concat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
     }
 
     if(FAILED(hres))
-        return hres;
+        goto done;
 
     if(r)
         *r = jsval_obj(ret);
     else
         jsdisp_release(ret);
+done:
+    IDispatch_Release(jsthis);
     return S_OK;
 }
 
@@ -310,7 +318,7 @@ static HRESULT array_join(script_ctx_t *ctx, jsdisp_t *array, DWORD length, cons
 }
 
 /* ECMA-262 3rd Edition    15.4.4.5 */
-static HRESULT Array_join(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Array_join(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsdisp_t *jsthis;
@@ -329,7 +337,7 @@ static HRESULT Array_join(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigne
 
         hres = to_flat_string(ctx, argv[0], &sep_str, &sep);
         if(FAILED(hres))
-            return hres;
+            goto done;
 
         hres = array_join(ctx, jsthis, length, sep, jsstr_length(sep_str), r);
 
@@ -338,10 +346,12 @@ static HRESULT Array_join(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigne
         hres = array_join(ctx, jsthis, length, L",", 1, r);
     }
 
+done:
+    jsdisp_release(jsthis);
     return hres;
 }
 
-static HRESULT Array_pop(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Array_pop(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsdisp_t *jsthis;
@@ -358,11 +368,11 @@ static HRESULT Array_pop(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned
     if(!length) {
         hres = set_length(jsthis, 0);
         if(FAILED(hres))
-            return hres;
+            goto done;
 
         if(r)
             *r = jsval_undefined();
-        return S_OK;
+        goto done;
     }
 
     length--;
@@ -373,25 +383,27 @@ static HRESULT Array_pop(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned
         val = jsval_undefined();
         hres = S_OK;
     }else
-        return hres;
+        goto done;
 
     if(SUCCEEDED(hres))
         hres = set_length(jsthis, length);
 
     if(FAILED(hres)) {
         jsval_release(val);
-        return hres;
+        goto done;
     }
 
     if(r)
         *r = val;
     else
         jsval_release(val);
+done:
+    jsdisp_release(jsthis);
     return hres;
 }
 
 /* ECMA-262 3rd Edition    15.4.4.7 */
-static HRESULT Array_push(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Array_push(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsdisp_t *jsthis;
@@ -408,19 +420,21 @@ static HRESULT Array_push(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigne
     for(i=0; i < argc; i++) {
         hres = jsdisp_propput_idx(jsthis, length+i, argv[i]);
         if(FAILED(hres))
-            return hres;
+            goto done;
     }
 
     hres = set_length(jsthis, length+argc);
     if(FAILED(hres))
-        return hres;
+        goto done;
 
     if(r)
         *r = jsval_number(length+argc);
-    return S_OK;
+done:
+    jsdisp_release(jsthis);
+    return hres;
 }
 
-static HRESULT Array_reverse(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Array_reverse(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsdisp_t *jsthis;
@@ -439,12 +453,13 @@ static HRESULT Array_reverse(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsi
 
         hres1 = jsdisp_get_idx(jsthis, k, &v1);
         if(FAILED(hres1) && hres1!=DISP_E_UNKNOWNNAME)
-            return hres1;
+            goto done;
 
         hres2 = jsdisp_get_idx(jsthis, l, &v2);
         if(FAILED(hres2) && hres2!=DISP_E_UNKNOWNNAME) {
             jsval_release(v1);
-            return hres2;
+            hres1 = hres2;
+            goto done;
         }
 
         if(hres1 == DISP_E_UNKNOWNNAME)
@@ -455,7 +470,7 @@ static HRESULT Array_reverse(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsi
         if(FAILED(hres1)) {
             jsval_release(v1);
             jsval_release(v2);
-            return hres1;
+            goto done;
         }
 
         if(hres2 == DISP_E_UNKNOWNNAME)
@@ -465,17 +480,20 @@ static HRESULT Array_reverse(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsi
 
         if(FAILED(hres2)) {
             jsval_release(v2);
-            return hres2;
+            hres1 = hres2;
+            goto done;
         }
     }
 
     if(r)
         *r = jsval_obj(jsdisp_addref(jsthis));
-    return S_OK;
+done:
+    jsdisp_release(jsthis);
+    return hres1;
 }
 
 /* ECMA-262 3rd Edition    15.4.4.9 */
-static HRESULT Array_shift(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Array_shift(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsdisp_t *jsthis;
@@ -492,11 +510,11 @@ static HRESULT Array_shift(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsign
     if(!length) {
         hres = set_length(jsthis, 0);
         if(FAILED(hres))
-            return hres;
+            goto done;
 
         if(r)
             *r = jsval_undefined();
-        return S_OK;
+        goto done;
     }
 
     hres = jsdisp_get_idx(jsthis, 0, &ret);
@@ -520,17 +538,19 @@ static HRESULT Array_shift(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsign
     }
 
     if(FAILED(hres))
-        return hres;
+        goto done;
 
     if(r)
         *r = ret;
     else
         jsval_release(ret);
+done:
+    jsdisp_release(jsthis);
     return hres;
 }
 
 /* ECMA-262 3rd Edition    15.4.4.10 */
-static HRESULT Array_slice(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
+static HRESULT Array_slice(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 {
     jsdisp_t *arr, *jsthis;
     DOUBLE range;
@@ -546,7 +566,7 @@ static HRESULT Array_slice(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsign
     if(argc) {
         hres = to_number(ctx, argv[0], &range);
         if(FAILED(hres))
-            return hres;
+            goto done;
 
         range = floor(range);
         if(-range>length || isnan(range)) start = 0;
@@ -559,7 +579,7 @@ static HRESULT Array_slice(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsign
     if(argc > 1) {
         hres = to_number(ctx, argv[1], &range);
         if(FAILED(hres))
-            return hres;
+            goto done;
 
         range = floor(range);
         if(-range>length) end = 0;
@@ -571,7 +591,7 @@ static HRESULT Array_slice(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsign
 
     hres = create_array(ctx, (end>start)?end-start:0, &arr);
     if(FAILED(hres))
-        return hres;
+        goto done;
 
     for(idx=start; idx<end; idx++) {
         jsval_t v;
@@ -587,7 +607,7 @@ static HRESULT Array_slice(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsign
 
         if(FAILED(hres)) {
             jsdisp_release(arr);
-            return hres;
+            goto done;
         }
     }
 
@@ -595,8 +615,11 @@ static HRESULT Array_slice(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsign
         *r = jsval_obj(arr);
     else
         jsdisp_release(arr);
+    hres = S_OK;
 
-    return S_OK;
+done:
+    jsdisp_release(jsthis);
+    return hres;
 }
 
 static HRESULT sort_cmp(script_ctx_t *ctx, jsdisp_t *cmp_func, jsval_t v1, jsval_t v2, INT *cmp)
@@ -651,7 +674,7 @@ static HRESULT sort_cmp(script_ctx_t *ctx, jsdisp_t *cmp_func, jsval_t v1, jsval
 }
 
 /* ECMA-262 3rd Edition    15.4.4.11 */
-static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Array_sort(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsdisp_t *jsthis, *cmp_func = NULL;
@@ -670,18 +693,21 @@ static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigne
         if(is_object_instance(argv[0])) {
             if(argc > 1 && ctx->version < SCRIPTLANGUAGEVERSION_ES5) {
                 WARN("invalid arg_cnt %d\n", argc);
-                return JS_E_JSCRIPT_EXPECTED;
+                hres = JS_E_JSCRIPT_EXPECTED;
+                goto done;
             }
             cmp_func = iface_to_jsdisp(get_object(argv[0]));
             if(!cmp_func || !is_class(cmp_func, JSCLASS_FUNCTION)) {
                 WARN("cmp_func is not a function\n");
                 if(cmp_func)
                     jsdisp_release(cmp_func);
-                return JS_E_JSCRIPT_EXPECTED;
+                hres = JS_E_JSCRIPT_EXPECTED;
+                goto done;
             }
         }else if(ctx->version >= SCRIPTLANGUAGEVERSION_ES5 ? !is_undefined(argv[0]) : !is_null(argv[0])) {
             WARN("invalid arg %s\n", debugstr_jsval(argv[0]));
-            return JS_E_JSCRIPT_EXPECTED;
+            hres = JS_E_JSCRIPT_EXPECTED;
+            goto done;
         }
     }
 
@@ -690,7 +716,7 @@ static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigne
             jsdisp_release(cmp_func);
         if(r)
             *r = jsval_obj(jsdisp_addref(jsthis));
-        return S_OK;
+        goto done;
     }
 
     vtab = heap_alloc_zero(length * sizeof(*vtab));
@@ -789,15 +815,17 @@ static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigne
         jsdisp_release(cmp_func);
 
     if(FAILED(hres))
-        return hres;
+        goto done;
 
     if(r)
         *r = jsval_obj(jsdisp_addref(jsthis));
-    return S_OK;
+done:
+    jsdisp_release(jsthis);
+    return hres;
 }
 
 /* ECMA-262 3rd Edition    15.4.4.12 */
-static HRESULT Array_splice(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Array_splice(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     UINT32 length, start=0, delete_cnt=0, i, add_args = 0;
@@ -816,7 +844,7 @@ static HRESULT Array_splice(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsig
     if(argc) {
         hres = to_integer(ctx, argv[0], &d);
         if(FAILED(hres))
-            return hres;
+            goto done;
 
         if(is_int32(d)) {
             if((n = d) >= 0)
@@ -831,7 +859,7 @@ static HRESULT Array_splice(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsig
     if(argc >= 2) {
         hres = to_integer(ctx, argv[1], &d);
         if(FAILED(hres))
-            return hres;
+            goto done;
 
         if(is_int32(d)) {
             if((n = d) > 0)
@@ -846,7 +874,7 @@ static HRESULT Array_splice(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsig
     if(r) {
         hres = create_array(ctx, 0, &ret_array);
         if(FAILED(hres))
-            return hres;
+            goto done;
 
         for(i=0; SUCCEEDED(hres) && i < delete_cnt; i++) {
             hres = jsdisp_get_idx(jsthis, start+i, &val);
@@ -896,37 +924,39 @@ static HRESULT Array_splice(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsig
     if(FAILED(hres)) {
         if(ret_array)
             jsdisp_release(ret_array);
-        return hres;
+        goto done;
     }
 
     if(r)
         *r = jsval_obj(ret_array);
-    return S_OK;
+done:
+    jsdisp_release(jsthis);
+    return hres;
 }
 
 /* ECMA-262 3rd Edition    15.4.4.2 */
-static HRESULT Array_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Array_toString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     ArrayInstance *array;
 
     TRACE("\n");
 
-    array = array_this(jsthis);
+    array = array_this(vthis);
     if(!array)
         return JS_E_ARRAY_EXPECTED;
 
     return array_join(ctx, &array->dispex, array->length, L",", 1, r);
 }
 
-static HRESULT Array_toLocaleString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Array_toLocaleString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     FIXME("\n");
     return E_NOTIMPL;
 }
 
-static HRESULT Array_forEach(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Array_forEach(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     IDispatch *context_obj = NULL, *callback;
@@ -944,14 +974,16 @@ static HRESULT Array_forEach(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsi
     /* Fixme check IsCallable */
     if(!argc || !is_object_instance(argv[0]) || !get_object(argv[0])) {
         FIXME("Invalid arg %s\n", debugstr_jsval(argc ? argv[0] : jsval_undefined()));
-        return E_INVALIDARG;
+        hres = E_INVALIDARG;
+        goto done;
     }
     callback = get_object(argv[0]);
 
     if(argc > 1 && !is_undefined(argv[1])) {
         if(!is_object_instance(argv[1]) || !get_object(argv[1])) {
             FIXME("Unsupported context this %s\n", debugstr_jsval(argv[1]));
-            return E_NOTIMPL;
+            hres = E_NOTIMPL;
+            goto done;
         }
         context_obj = get_object(argv[1]);
     }
@@ -961,7 +993,7 @@ static HRESULT Array_forEach(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsi
         if(hres == DISP_E_UNKNOWNNAME)
             continue;
         if(FAILED(hres))
-            return hres;
+            goto done;
 
         args[0] = value;
         args[1] = jsval_number(i);
@@ -969,15 +1001,18 @@ static HRESULT Array_forEach(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsi
         hres = disp_call_value(ctx, callback, context_obj, DISPATCH_METHOD, ARRAY_SIZE(args), args, &res);
         jsval_release(value);
         if(FAILED(hres))
-            return hres;
+            goto done;
         jsval_release(res);
     }
 
     if(r) *r = jsval_undefined();
-    return S_OK;
+    hres = S_OK;
+done:
+    jsdisp_release(jsthis);
+    return hres;
 }
 
-static HRESULT Array_indexOf(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Array_indexOf(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsdisp_t *jsthis;
@@ -993,7 +1028,7 @@ static HRESULT Array_indexOf(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsi
         return hres;
     if(!length) {
         if(r) *r = jsval_number(-1);
-        return S_OK;
+        goto done;
     }
 
     search = argc ? argv[0] : jsval_undefined();
@@ -1003,7 +1038,7 @@ static HRESULT Array_indexOf(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsi
 
         hres = to_integer(ctx, argv[1], &from_arg);
         if(FAILED(hres))
-            return hres;
+            goto done;
 
         if(from_arg >= 0)
             from = min(from_arg, length);
@@ -1016,23 +1051,26 @@ static HRESULT Array_indexOf(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsi
         if(hres == DISP_E_UNKNOWNNAME)
             continue;
         if(FAILED(hres))
-            return hres;
+            goto done;
 
         hres = jsval_strict_equal(value, search, &eq);
         jsval_release(value);
         if(FAILED(hres))
-            return hres;
+            goto done;
         if(eq) {
             if(r) *r = jsval_number(i);
-            return S_OK;
+            goto done;
         }
     }
 
     if(r) *r = jsval_number(-1);
-    return S_OK;
+    hres = S_OK;
+done:
+    jsdisp_release(jsthis);
+    return hres;
 }
 
-static HRESULT Array_map(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
+static HRESULT Array_map(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 {
     IDispatch *context_this = NULL, *callback;
     jsval_t callback_args[3], mapped_value;
@@ -1051,7 +1089,8 @@ static HRESULT Array_map(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned
     /* FIXME: check IsCallable */
     if(!argc || !is_object_instance(argv[0]) || !get_object(argv[0])) {
         FIXME("Invalid arg %s\n", debugstr_jsval(argc ? argv[0] : jsval_undefined()));
-        return E_INVALIDARG;
+        hres = E_INVALIDARG;
+        goto done;
     }
     callback = get_object(argv[0]);
 
@@ -1060,13 +1099,14 @@ static HRESULT Array_map(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned
             context_this = get_object(argv[1]);
         }else if(!is_undefined(argv[1])) {
             FIXME("Unsupported context this %s\n", debugstr_jsval(argv[1]));
-            return E_NOTIMPL;
+            hres = E_NOTIMPL;
+            goto done;
         }
     }
 
     hres = create_array(ctx, length, &array);
     if(FAILED(hres))
-        return hres;
+        goto done;
 
     for(k = 0; k < length; k++) {
         hres = jsdisp_get_idx(jsthis, k, &callback_args[0]);
@@ -1091,10 +1131,12 @@ static HRESULT Array_map(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned
         *r = jsval_obj(array);
     else
         jsdisp_release(array);
+done:
+    jsdisp_release(jsthis);
     return hres;
 }
 
-static HRESULT Array_reduce(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
+static HRESULT Array_reduce(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 {
     IDispatch *context_this = NULL, *callback;
     jsval_t callback_args[4], acc, new_acc;
@@ -1114,7 +1156,8 @@ static HRESULT Array_reduce(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsig
     /* Fixme check IsCallable */
     if(!argc || !is_object_instance(argv[0]) || !get_object(argv[0])) {
         FIXME("Invalid arg %s\n", debugstr_jsval(argc ? argv[0] : jsval_undefined()));
-        return E_INVALIDARG;
+        hres = E_INVALIDARG;
+        goto done;
     }
     callback = get_object(argv[0]);
 
@@ -1122,7 +1165,7 @@ static HRESULT Array_reduce(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsig
         have_value = TRUE;
         hres = jsval_copy(argv[1], &acc);
         if(FAILED(hres))
-            return hres;
+            goto done;
     }
 
     for(k = 0; k < length; k++) {
@@ -1159,11 +1202,13 @@ static HRESULT Array_reduce(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsig
         *r = acc;
     else if(have_value)
         jsval_release(acc);
+done:
+    jsdisp_release(jsthis);
     return hres;
 }
 
 /* ECMA-262 3rd Edition    15.4.4.13 */
-static HRESULT Array_unshift(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Array_unshift(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsdisp_t *jsthis;
@@ -1191,35 +1236,38 @@ static HRESULT Array_unshift(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsi
             if(SUCCEEDED(hres)) {
                 hres = jsdisp_propget(jsthis, id, &val);
                 if(FAILED(hres))
-                    return hres;
+                    goto done;
 
                 hres = jsdisp_propput_idx(jsthis, i+argc, val);
                 jsval_release(val);
             }else if(hres == DISP_E_UNKNOWNNAME) {
-                hres = IDispatchEx_DeleteMemberByDispID(vthis->u.dispex, id);
+                hres = IDispatchEx_DeleteMemberByDispID(&jsthis->IDispatchEx_iface, id);
             }
         }
 
         if(FAILED(hres))
-            return hres;
+            goto done;
     }
 
     for(i=0; i<argc; i++) {
         hres = jsdisp_propput_idx(jsthis, i, argv[i]);
         if(FAILED(hres))
-            return hres;
+            goto done;
     }
 
     if(argc) {
         length += argc;
         hres = set_length(jsthis, length);
         if(FAILED(hres))
-            return hres;
+            goto done;
     }
 
     if(r)
         *r = ctx->version < 2 ? jsval_undefined() : jsval_number(length);
-    return S_OK;
+    hres = S_OK;
+done:
+    jsdisp_release(jsthis);
+    return hres;
 }
 
 static void Array_destructor(jsdisp_t *dispex)
@@ -1291,7 +1339,7 @@ static const builtin_info_t ArrayInst_info = {
 };
 
 /* ECMA-262 5.1 Edition    15.4.3.2 */
-static HRESULT ArrayConstr_isArray(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
+static HRESULT ArrayConstr_isArray(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 {
     jsdisp_t *obj;
 
@@ -1308,7 +1356,7 @@ static HRESULT ArrayConstr_isArray(script_ctx_t *ctx, vdisp_t *vthis, WORD flags
     return S_OK;
 }
 
-static HRESULT ArrayConstr_value(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT ArrayConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsdisp_t *obj;
diff --git a/dlls/jscript/bool.c b/dlls/jscript/bool.c
index 184d8d0..a230855 100644
--- a/dlls/jscript/bool.c
+++ b/dlls/jscript/bool.c
@@ -36,14 +36,16 @@ static inline BoolInstance *bool_from_jsdisp(jsdisp_t *jsdisp)
     return CONTAINING_RECORD(jsdisp, BoolInstance, dispex);
 }
 
-static inline BoolInstance *bool_from_vdisp(vdisp_t *vdisp)
+static inline HRESULT boolval_this(jsval_t vthis, BOOL *ret)
 {
-    return bool_from_jsdisp(vdisp->u.jsdisp);
-}
-
-static inline BoolInstance *bool_this(vdisp_t *jsthis)
-{
-    return is_vclass(jsthis, JSCLASS_BOOLEAN) ? bool_from_vdisp(jsthis) : NULL;
+    jsdisp_t *jsdisp;
+    if(is_bool(vthis))
+        *ret = get_bool(vthis);
+    else if(is_object_instance(vthis) && (jsdisp = to_jsdisp(get_object(vthis))) && is_class(jsdisp, JSCLASS_BOOLEAN))
+        *ret = bool_from_jsdisp(jsdisp)->val;
+    else
+        return JS_E_BOOLEAN_EXPECTED;
+    return S_OK;
 }
 
 BOOL bool_obj_value(jsdisp_t *obj)
@@ -53,19 +55,21 @@ BOOL bool_obj_value(jsdisp_t *obj)
 }
 
 /* ECMA-262 3rd Edition    15.6.4.2 */
-static HRESULT Bool_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
+static HRESULT Bool_toString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 {
-    BoolInstance *bool;
+    BOOL boolval;
+    HRESULT hres;
 
     TRACE("\n");
 
-    if(!(bool = bool_this(jsthis)))
-        return JS_E_BOOLEAN_EXPECTED;
+    hres = boolval_this(vthis, &boolval);
+    if(FAILED(hres))
+        return hres;
 
     if(r) {
         jsstr_t *val;
 
-        val = jsstr_alloc(bool->val ? L"true" : L"false");
+        val = jsstr_alloc(boolval ? L"true" : L"false");
         if(!val)
             return E_OUTOFMEMORY;
 
@@ -76,21 +80,23 @@ static HRESULT Bool_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
 }
 
 /* ECMA-262 3rd Edition    15.6.4.3 */
-static HRESULT Bool_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
+static HRESULT Bool_valueOf(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 {
-    BoolInstance *bool;
+    BOOL boolval;
+    HRESULT hres;
 
     TRACE("\n");
 
-    if(!(bool = bool_this(jsthis)))
-        return JS_E_BOOLEAN_EXPECTED;
+    hres = boolval_this(vthis, &boolval);
+    if(FAILED(hres))
+        return hres;
 
     if(r)
-        *r = jsval_bool(bool->val);
+        *r = jsval_bool(boolval);
     return S_OK;
 }
 
-static HRESULT Bool_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Bool_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     TRACE("\n");
@@ -129,7 +135,7 @@ static const builtin_info_t BoolInst_info = {
     NULL
 };
 
-static HRESULT BoolConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT BoolConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     BOOL value = FALSE;
diff --git a/dlls/jscript/date.c b/dlls/jscript/date.c
index b130c83..e482c4a 100644
--- a/dlls/jscript/date.c
+++ b/dlls/jscript/date.c
@@ -49,9 +49,10 @@ static inline DateInstance *date_from_jsdisp(jsdisp_t *jsdisp)
     return CONTAINING_RECORD(jsdisp, DateInstance, dispex);
 }
 
-static inline DateInstance *date_this(vdisp_t *jsthis)
+static inline DateInstance *date_this(jsval_t vthis)
 {
-    return is_vclass(jsthis, JSCLASS_DATE) ? date_from_jsdisp(jsthis->u.jsdisp) : NULL;
+    jsdisp_t *jsdisp = is_object_instance(vthis) ? to_jsdisp(get_object(vthis)) : NULL;
+    return (jsdisp && is_class(jsdisp, JSCLASS_DATE)) ? date_from_jsdisp(jsdisp) : NULL;
 }
 
 /*ECMA-262 3rd Edition    15.9.1.2 */
@@ -513,20 +514,20 @@ static HRESULT dateobj_to_string(DateInstance *date, jsval_t *r)
     return date_to_string(time, TRUE, offset, r);
 }
 
-static HRESULT Date_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
+static HRESULT Date_toString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 {
     DateInstance *date;
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     return dateobj_to_string(date, r);
 }
 
 /* ECMA-262 3rd Edition    15.9.1.5 */
-static HRESULT Date_toLocaleString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_toLocaleString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     SYSTEMTIME st;
@@ -536,7 +537,7 @@ static HRESULT Date_toLocaleString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(isnan(date->time)) {
@@ -569,7 +570,7 @@ static HRESULT Date_toLocaleString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
     return S_OK;
 }
 
-static HRESULT Date_toISOString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_toISOString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
@@ -578,7 +579,7 @@ static HRESULT Date_toISOString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     year = year_from_time(date->time);
@@ -611,14 +612,14 @@ static HRESULT Date_toISOString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
     return S_OK;
 }
 
-static HRESULT Date_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_valueOf(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(r)
@@ -626,7 +627,7 @@ static HRESULT Date_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
     return S_OK;
 }
 
-static inline HRESULT create_utc_string(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r)
+static inline HRESULT create_utc_string(script_ctx_t *ctx, jsval_t vthis, jsval_t *r)
 {
     static const DWORD week_ids[] = { LOCALE_SABBREVDAYNAME7, LOCALE_SABBREVDAYNAME1,
         LOCALE_SABBREVDAYNAME2, LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4,
@@ -646,7 +647,7 @@ static inline HRESULT create_utc_string(script_ctx_t *ctx, vdisp_t *jsthis, jsva
     int year, day;
     DWORD lcid_en;
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(isnan(date->time)) {
@@ -687,18 +688,18 @@ static inline HRESULT create_utc_string(script_ctx_t *ctx, vdisp_t *jsthis, jsva
 }
 
 /* ECMA-262 3rd Edition    15.9.5.42 */
-static HRESULT Date_toUTCString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_toUTCString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     TRACE("\n");
-    return create_utc_string(ctx, jsthis, r);
+    return create_utc_string(ctx, vthis, r);
 }
 
-static HRESULT Date_toGMTString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_toGMTString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     TRACE("\n");
-    return create_utc_string(ctx, jsthis, r);
+    return create_utc_string(ctx, vthis, r);
 }
 
 /* ECMA-262 3rd Edition    15.9.5.3 */
@@ -758,19 +759,19 @@ static HRESULT dateobj_to_date_string(DateInstance *date, jsval_t *r)
     return S_OK;
 }
 
-static HRESULT Date_toDateString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_toDateString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     return dateobj_to_date_string(date, r);
 }
 
 /* ECMA-262 3rd Edition    15.9.5.4 */
-static HRESULT Date_toTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_toTimeString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
@@ -782,7 +783,7 @@ static HRESULT Date_toTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(isnan(date->time)) {
@@ -821,7 +822,7 @@ static HRESULT Date_toTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
 }
 
 /* ECMA-262 3rd Edition    15.9.5.6 */
-static HRESULT Date_toLocaleDateString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_toLocaleDateString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     SYSTEMTIME st;
@@ -831,7 +832,7 @@ static HRESULT Date_toLocaleDateString(script_ctx_t *ctx, vdisp_t *jsthis, WORD
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(isnan(date->time)) {
@@ -860,7 +861,7 @@ static HRESULT Date_toLocaleDateString(script_ctx_t *ctx, vdisp_t *jsthis, WORD
 }
 
 /* ECMA-262 3rd Edition    15.9.5.7 */
-static HRESULT Date_toLocaleTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_toLocaleTimeString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     SYSTEMTIME st;
@@ -870,7 +871,7 @@ static HRESULT Date_toLocaleTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(isnan(date->time)) {
@@ -882,7 +883,7 @@ static HRESULT Date_toLocaleTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD
     st = create_systemtime(local_time(date->time, date));
 
     if(st.wYear<1601 || st.wYear>9999)
-        return Date_toTimeString(ctx, jsthis, flags, argc, argv, r);
+        return Date_toTimeString(ctx, vthis, flags, argc, argv, r);
 
     if(r) {
         WCHAR *ptr;
@@ -899,14 +900,14 @@ static HRESULT Date_toLocaleTimeString(script_ctx_t *ctx, vdisp_t *jsthis, WORD
 }
 
 /* ECMA-262 3rd Edition    15.9.5.9 */
-static HRESULT Date_getTime(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_getTime(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(r)
@@ -915,14 +916,14 @@ static HRESULT Date_getTime(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
 }
 
 /* ECMA-262 3rd Edition    15.9.5.10 */
-static HRESULT Date_getFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_getFullYear(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(r) {
@@ -934,14 +935,14 @@ static HRESULT Date_getFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
 }
 
 /* ECMA-262 3rd Edition    15.9.5.11 */
-static HRESULT Date_getUTCFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_getUTCFullYear(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(r)
@@ -950,13 +951,13 @@ static HRESULT Date_getUTCFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
 }
 
 /* ECMA-262 3rd Edition    15.9.5.12 */
-static HRESULT Date_getMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
+static HRESULT Date_getMonth(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 {
     DateInstance *date;
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(r)
@@ -965,14 +966,14 @@ static HRESULT Date_getMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
 }
 
 /* ECMA-262 3rd Edition    15.9.5.13 */
-static HRESULT Date_getUTCMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_getUTCMonth(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(r)
@@ -981,13 +982,13 @@ static HRESULT Date_getUTCMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
 }
 
 /* ECMA-262 3rd Edition    15.9.5.14 */
-static HRESULT Date_getDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
+static HRESULT Date_getDate(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 {
     DateInstance *date;
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(r)
@@ -996,14 +997,14 @@ static HRESULT Date_getDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
 }
 
 /* ECMA-262 3rd Edition    15.9.5.15 */
-static HRESULT Date_getUTCDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_getUTCDate(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(r)
@@ -1012,14 +1013,14 @@ static HRESULT Date_getUTCDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
 }
 
 /* ECMA-262 3rd Edition    15.9.5.16 */
-static HRESULT Date_getDay(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_getDay(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(r)
@@ -1028,14 +1029,14 @@ static HRESULT Date_getDay(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsig
 }
 
 /* ECMA-262 3rd Edition    15.9.5.17 */
-static HRESULT Date_getUTCDay(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_getUTCDay(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(r)
@@ -1044,14 +1045,14 @@ static HRESULT Date_getUTCDay(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
 }
 
 /* ECMA-262 3rd Edition    15.9.5.18 */
-static HRESULT Date_getHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_getHours(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(r)
@@ -1060,14 +1061,14 @@ static HRESULT Date_getHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
 }
 
 /* ECMA-262 3rd Edition    15.9.5.19 */
-static HRESULT Date_getUTCHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_getUTCHours(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(r)
@@ -1076,14 +1077,14 @@ static HRESULT Date_getUTCHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
 }
 
 /* ECMA-262 3rd Edition    15.9.5.20 */
-static HRESULT Date_getMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_getMinutes(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(r)
@@ -1092,14 +1093,14 @@ static HRESULT Date_getMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
 }
 
 /* ECMA-262 3rd Edition    15.9.5.21 */
-static HRESULT Date_getUTCMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_getUTCMinutes(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(r)
@@ -1108,13 +1109,13 @@ static HRESULT Date_getUTCMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
 }
 
 /* ECMA-262 3rd Edition    15.9.5.22 */
-static HRESULT Date_getSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
+static HRESULT Date_getSeconds(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 {
     DateInstance *date;
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(r)
@@ -1123,14 +1124,14 @@ static HRESULT Date_getSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
 }
 
 /* ECMA-262 3rd Edition    15.9.5.23 */
-static HRESULT Date_getUTCSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_getUTCSeconds(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(r)
@@ -1139,14 +1140,14 @@ static HRESULT Date_getUTCSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
 }
 
 /* ECMA-262 3rd Edition    15.9.5.24 */
-static HRESULT Date_getMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_getMilliseconds(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(r)
@@ -1155,14 +1156,14 @@ static HRESULT Date_getMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla
 }
 
 /* ECMA-262 3rd Edition    15.9.5.25 */
-static HRESULT Date_getUTCMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_getUTCMilliseconds(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(r)
@@ -1171,14 +1172,14 @@ static HRESULT Date_getUTCMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD
 }
 
 /* ECMA-262 3rd Edition    15.9.5.26 */
-static HRESULT Date_getTimezoneOffset(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_getTimezoneOffset(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(r)
@@ -1187,7 +1188,7 @@ static HRESULT Date_getTimezoneOffset(script_ctx_t *ctx, vdisp_t *jsthis, WORD f
 }
 
 /* ECMA-262 3rd Edition    15.9.5.27 */
-static HRESULT Date_setTime(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_setTime(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     double n;
@@ -1196,7 +1197,7 @@ static HRESULT Date_setTime(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(!argc)
@@ -1214,7 +1215,7 @@ static HRESULT Date_setTime(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
 }
 
 /* ECMA-262 3rd Edition    15.9.5.28 */
-static HRESULT Date_setMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_setMilliseconds(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
@@ -1223,7 +1224,7 @@ static HRESULT Date_setMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(!argc)
@@ -1244,7 +1245,7 @@ static HRESULT Date_setMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla
 }
 
 /* ECMA-262 3rd Edition    15.9.5.29 */
-static HRESULT Date_setUTCMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_setUTCMilliseconds(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
@@ -1253,7 +1254,7 @@ static HRESULT Date_setUTCMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(!argc)
@@ -1274,7 +1275,7 @@ static HRESULT Date_setUTCMilliseconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD
 }
 
 /* ECMA-262 3rd Edition    15.9.5.30 */
-static HRESULT Date_setSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_setSeconds(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
@@ -1283,7 +1284,7 @@ static HRESULT Date_setSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(!argc)
@@ -1313,7 +1314,7 @@ static HRESULT Date_setSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
 }
 
 /* ECMA-262 3rd Edition    15.9.5.31 */
-static HRESULT Date_setUTCSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_setUTCSeconds(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
@@ -1322,7 +1323,7 @@ static HRESULT Date_setUTCSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(!argc)
@@ -1352,7 +1353,7 @@ static HRESULT Date_setUTCSeconds(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
 }
 
 /* ECMA-262 3rd Edition    15.9.5.33 */
-static HRESULT Date_setMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_setMinutes(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
@@ -1361,7 +1362,7 @@ static HRESULT Date_setMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(!argc)
@@ -1399,7 +1400,7 @@ static HRESULT Date_setMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
 }
 
 /* ECMA-262 3rd Edition    15.9.5.34 */
-static HRESULT Date_setUTCMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_setUTCMinutes(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
@@ -1408,7 +1409,7 @@ static HRESULT Date_setUTCMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(!argc)
@@ -1446,7 +1447,7 @@ static HRESULT Date_setUTCMinutes(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
 }
 
 /* ECMA-262 3rd Edition    15.9.5.35 */
-static HRESULT Date_setHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_setHours(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
@@ -1455,7 +1456,7 @@ static HRESULT Date_setHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(!argc)
@@ -1500,7 +1501,7 @@ static HRESULT Date_setHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
 }
 
 /* ECMA-262 3rd Edition    15.9.5.36 */
-static HRESULT Date_setUTCHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_setUTCHours(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
@@ -1509,7 +1510,7 @@ static HRESULT Date_setUTCHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(!argc)
@@ -1554,7 +1555,7 @@ static HRESULT Date_setUTCHours(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
 }
 
 /* ECMA-262 3rd Edition    15.9.5.36 */
-static HRESULT Date_setDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_setDate(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
@@ -1563,7 +1564,7 @@ static HRESULT Date_setDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(!argc)
@@ -1583,7 +1584,7 @@ static HRESULT Date_setDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
 }
 
 /* ECMA-262 3rd Edition    15.9.5.37 */
-static HRESULT Date_setUTCDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_setUTCDate(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
@@ -1592,7 +1593,7 @@ static HRESULT Date_setUTCDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(!argc)
@@ -1612,7 +1613,7 @@ static HRESULT Date_setUTCDate(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
 }
 
 /* ECMA-262 3rd Edition    15.9.5.38 */
-static HRESULT Date_setMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_setMonth(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
@@ -1621,7 +1622,7 @@ static HRESULT Date_setMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(!argc)
@@ -1651,7 +1652,7 @@ static HRESULT Date_setMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
 }
 
 /* ECMA-262 3rd Edition    15.9.5.39 */
-static HRESULT Date_setUTCMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_setUTCMonth(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
@@ -1660,7 +1661,7 @@ static HRESULT Date_setUTCMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(!argc)
@@ -1690,7 +1691,7 @@ static HRESULT Date_setUTCMonth(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
 }
 
 /* ECMA-262 3rd Edition    15.9.5.40 */
-static HRESULT Date_setFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_setFullYear(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
@@ -1699,7 +1700,7 @@ static HRESULT Date_setFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(!argc)
@@ -1736,7 +1737,7 @@ static HRESULT Date_setFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
 }
 
 /* ECMA-262 3rd Edition    15.9.5.41 */
-static HRESULT Date_setUTCFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_setUTCFullYear(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
@@ -1745,7 +1746,7 @@ static HRESULT Date_setUTCFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(!argc)
@@ -1782,7 +1783,7 @@ static HRESULT Date_setUTCFullYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
 }
 
 /* ECMA-262 3rd Edition    B2.4 */
-static HRESULT Date_getYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_getYear(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
@@ -1790,7 +1791,7 @@ static HRESULT Date_getYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     t = local_time(date->time, date);
@@ -1807,7 +1808,7 @@ static HRESULT Date_getYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
 }
 
 /* ECMA-262 3rd Edition    B2.5 */
-static HRESULT Date_setYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Date_setYear(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
@@ -1816,7 +1817,7 @@ static HRESULT Date_setYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
 
     TRACE("\n");
 
-    if(!(date = date_this(jsthis)))
+    if(!(date = date_this(vthis)))
         return JS_E_DATE_EXPECTED;
 
     if(!argc)
@@ -2223,7 +2224,7 @@ static inline HRESULT date_parse(jsstr_t *input_str, double *ret) {
     return S_OK;
 }
 
-static HRESULT DateConstr_parse(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT DateConstr_parse(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsstr_t *parse_str;
@@ -2321,7 +2322,7 @@ static HRESULT date_utc(script_ctx_t *ctx, unsigned argc, jsval_t *argv, double
     return S_OK;
 }
 
-static HRESULT DateConstr_UTC(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT DateConstr_UTC(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     double n;
@@ -2336,7 +2337,7 @@ static HRESULT DateConstr_UTC(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
 }
 
 /* ECMA-262 5.1 Edition    15.9.4.4 */
-static HRESULT DateConstr_now(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
+static HRESULT DateConstr_now(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 {
     TRACE("\n");
 
@@ -2344,7 +2345,7 @@ static HRESULT DateConstr_now(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
     return S_OK;
 }
 
-static HRESULT DateConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT DateConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DateInstance *date;
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index f8c3b55..e140010 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -550,7 +550,7 @@ static HRESULT invoke_prop_func(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t
 
     switch(prop->type) {
     case PROP_BUILTIN: {
-        vdisp_t vthis;
+        jsval_t vthis;
 
         if(flags == DISPATCH_CONSTRUCT && (prop->flags & PROPF_METHOD)) {
             WARN("%s is not a constructor\n", debugstr_w(prop->name));
@@ -560,13 +560,10 @@ static HRESULT invoke_prop_func(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t
         if(This->builtin_info->class != JSCLASS_FUNCTION && prop->u.p->invoke != JSGlobal_eval)
             flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK;
         if(jsthis)
-            set_disp(&vthis, jsthis);
+            vthis = jsval_disp(jsthis);
         else
-            set_jsdisp(&vthis, This);
-        hres = prop->u.p->invoke(This->ctx, &vthis, flags, argc, argv, r);
-        vdisp_release(&vthis);
-
-        return hres;
+            vthis = jsval_obj(This);
+        return prop->u.p->invoke(This->ctx, vthis, flags, argc, argv, r);
     }
     case PROP_PROTREF:
         return invoke_prop_func(This->prototype, jsthis ? jsthis : (IDispatch *)&This->IDispatchEx_iface,
@@ -1979,17 +1976,13 @@ HRESULT jsdisp_call_value(jsdisp_t *jsfunc, IDispatch *jsthis, WORD flags, unsig
     if(is_class(jsfunc, JSCLASS_FUNCTION)) {
         hres = Function_invoke(jsfunc, jsthis, flags, argc, argv, r);
     }else {
-        vdisp_t vdisp;
-
         if(!jsfunc->builtin_info->call) {
             WARN("Not a function\n");
             return JS_E_FUNCTION_EXPECTED;
         }
 
-        set_disp(&vdisp, jsthis);
         flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK;
-        hres = jsfunc->builtin_info->call(jsfunc->ctx, &vdisp, flags, argc, argv, r);
-        vdisp_release(&vdisp);
+        hres = jsfunc->builtin_info->call(jsfunc->ctx, jsval_disp(jsthis), flags, argc, argv, r);
     }
     return hres;
 }
diff --git a/dlls/jscript/enumerator.c b/dlls/jscript/enumerator.c
index 038b474..0fc6750 100644
--- a/dlls/jscript/enumerator.c
+++ b/dlls/jscript/enumerator.c
@@ -38,14 +38,10 @@ static inline EnumeratorInstance *enumerator_from_jsdisp(jsdisp_t *jsdisp)
     return CONTAINING_RECORD(jsdisp, EnumeratorInstance, dispex);
 }
 
-static inline EnumeratorInstance *enumerator_from_vdisp(vdisp_t *vdisp)
+static inline EnumeratorInstance *enumerator_this(jsval_t vthis)
 {
-    return enumerator_from_jsdisp(vdisp->u.jsdisp);
-}
-
-static inline EnumeratorInstance *enumerator_this(vdisp_t *jsthis)
-{
-    return is_vclass(jsthis, JSCLASS_ENUMERATOR) ? enumerator_from_vdisp(jsthis) : NULL;
+    jsdisp_t *jsdisp = is_object_instance(vthis) ? to_jsdisp(get_object(vthis)) : NULL;
+    return (jsdisp && is_class(jsdisp, JSCLASS_ENUMERATOR)) ? enumerator_from_jsdisp(jsdisp) : NULL;
 }
 
 static inline HRESULT enumvar_get_next_item(EnumeratorInstance *This)
@@ -92,12 +88,12 @@ static void Enumerator_destructor(jsdisp_t *dispex)
     heap_free(dispex);
 }
 
-static HRESULT Enumerator_atEnd(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Enumerator_atEnd(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     EnumeratorInstance *This;
 
-    if (!(This = enumerator_this(jsthis)))
+    if (!(This = enumerator_this(vthis)))
         return JS_E_ENUMERATOR_EXPECTED;
 
     TRACE("%d\n", This->atend);
@@ -107,20 +103,20 @@ static HRESULT Enumerator_atEnd(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
     return S_OK;
 }
 
-static HRESULT Enumerator_item(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Enumerator_item(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     EnumeratorInstance *This;
 
     TRACE("\n");
 
-    if (!(This = enumerator_this(jsthis)))
+    if (!(This = enumerator_this(vthis)))
         return JS_E_ENUMERATOR_EXPECTED;
 
     return r ? jsval_copy(This->item, r) : S_OK;
 }
 
-static HRESULT Enumerator_moveFirst(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Enumerator_moveFirst(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     EnumeratorInstance *This;
@@ -128,7 +124,7 @@ static HRESULT Enumerator_moveFirst(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla
 
     TRACE("\n");
 
-    if (!(This = enumerator_this(jsthis)))
+    if (!(This = enumerator_this(vthis)))
         return JS_E_ENUMERATOR_EXPECTED;
 
     if (This->enumvar)
@@ -148,7 +144,7 @@ static HRESULT Enumerator_moveFirst(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla
     return S_OK;
 }
 
-static HRESULT Enumerator_moveNext(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Enumerator_moveNext(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     EnumeratorInstance *This;
@@ -156,7 +152,7 @@ static HRESULT Enumerator_moveNext(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
 
     TRACE("\n");
 
-    if (!(This = enumerator_this(jsthis)))
+    if (!(This = enumerator_this(vthis)))
         return JS_E_ENUMERATOR_EXPECTED;
 
     if (This->enumvar)
@@ -287,7 +283,7 @@ static HRESULT create_enumerator(script_ctx_t *ctx, jsval_t *argv, jsdisp_t **re
     return S_OK;
 }
 
-static HRESULT EnumeratorConstr_value(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT EnumeratorConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsdisp_t *obj;
diff --git a/dlls/jscript/error.c b/dlls/jscript/error.c
index 26f41fd..6f17699 100644
--- a/dlls/jscript/error.c
+++ b/dlls/jscript/error.c
@@ -29,17 +29,21 @@
 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
 
 /* ECMA-262 3rd Edition    15.11.4.4 */
-static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags,
+static HRESULT Error_toString(script_ctx_t *ctx, jsval_t vthis, WORD flags,
         unsigned argc, jsval_t *argv, jsval_t *r)
 {
-    jsdisp_t *jsthis;
     jsstr_t *name = NULL, *msg = NULL, *ret = NULL;
+    jsdisp_t *jsthis = NULL;
     jsval_t v;
     HRESULT hres;
 
     TRACE("\n");
 
-    jsthis = get_jsdisp(vthis);
+    if(is_object_instance(vthis))
+        jsthis = to_jsdisp(get_object(vthis));
+    else if(ctx->version >= SCRIPTLANGUAGEVERSION_ES5)
+        return JS_E_OBJECT_EXPECTED;
+
     if(!jsthis || ctx->version < 2) {
         if(r) {
             jsstr_t *str;
@@ -114,7 +118,7 @@ static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags,
     return S_OK;
 }
 
-static HRESULT Error_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+static HRESULT Error_value(script_ctx_t *ctx, jsval_t vthis, WORD flags,
         unsigned argc, jsval_t *argv, jsval_t *r)
 {
     TRACE("\n");
@@ -260,56 +264,56 @@ static HRESULT error_constr(script_ctx_t *ctx, WORD flags, unsigned argc, jsval_
     }
 }
 
-static HRESULT ErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+static HRESULT ErrorConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags,
         unsigned argc, jsval_t *argv, jsval_t *r)
 {
     TRACE("\n");
     return error_constr(ctx, flags, argc, argv, r, ctx->error_constr);
 }
 
-static HRESULT EvalErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+static HRESULT EvalErrorConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags,
         unsigned argc, jsval_t *argv, jsval_t *r)
 {
     TRACE("\n");
     return error_constr(ctx, flags, argc, argv, r, ctx->eval_error_constr);
 }
 
-static HRESULT RangeErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+static HRESULT RangeErrorConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags,
         unsigned argc, jsval_t *argv, jsval_t *r)
 {
     TRACE("\n");
     return error_constr(ctx, flags, argc, argv, r, ctx->range_error_constr);
 }
 
-static HRESULT ReferenceErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+static HRESULT ReferenceErrorConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags,
         unsigned argc, jsval_t *argv, jsval_t *r)
 {
     TRACE("\n");
     return error_constr(ctx, flags, argc, argv, r, ctx->reference_error_constr);
 }
 
-static HRESULT RegExpErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+static HRESULT RegExpErrorConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags,
         unsigned argc, jsval_t *argv, jsval_t *r)
 {
     TRACE("\n");
     return error_constr(ctx, flags, argc, argv, r, ctx->regexp_error_constr);
 }
 
-static HRESULT SyntaxErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+static HRESULT SyntaxErrorConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags,
         unsigned argc, jsval_t *argv, jsval_t *r)
 {
     TRACE("\n");
     return error_constr(ctx, flags, argc, argv, r, ctx->syntax_error_constr);
 }
 
-static HRESULT TypeErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+static HRESULT TypeErrorConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags,
         unsigned argc, jsval_t *argv, jsval_t *r)
 {
     TRACE("\n");
     return error_constr(ctx, flags, argc, argv, r, ctx->type_error_constr);
 }
 
-static HRESULT URIErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+static HRESULT URIErrorConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags,
         unsigned argc, jsval_t *argv, jsval_t *r)
 {
     TRACE("\n");
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c
index f24d539..fd1380d 100644
--- a/dlls/jscript/function.c
+++ b/dlls/jscript/function.c
@@ -77,14 +77,10 @@ static inline FunctionInstance *function_from_jsdisp(jsdisp_t *jsdisp)
     return CONTAINING_RECORD(jsdisp, FunctionInstance, dispex);
 }
 
-static inline FunctionInstance *function_from_vdisp(vdisp_t *vdisp)
+static inline FunctionInstance *function_this(jsval_t vthis)
 {
-    return function_from_jsdisp(vdisp->u.jsdisp);
-}
-
-static inline FunctionInstance *function_this(vdisp_t *jsthis)
-{
-    return is_vclass(jsthis, JSCLASS_FUNCTION) ? function_from_vdisp(jsthis) : NULL;
+    jsdisp_t *jsdisp = is_object_instance(vthis) ? to_jsdisp(get_object(vthis)) : NULL;
+    return (jsdisp && is_class(jsdisp, JSCLASS_FUNCTION)) ? function_from_jsdisp(jsdisp) : NULL;
 }
 
 static inline ArgumentsInstance *arguments_from_jsdisp(jsdisp_t *jsdisp)
@@ -92,7 +88,7 @@ static inline ArgumentsInstance *arguments_from_jsdisp(jsdisp_t *jsdisp)
     return CONTAINING_RECORD(jsdisp, ArgumentsInstance, jsdisp);
 }
 
-static HRESULT Arguments_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Arguments_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     FIXME("\n");
@@ -271,7 +267,7 @@ static HRESULT Function_get_length(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t
     return S_OK;
 }
 
-static HRESULT Function_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Function_toString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     FunctionInstance *function;
@@ -280,7 +276,7 @@ static HRESULT Function_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
 
     TRACE("\n");
 
-    if(!(function = function_this(jsthis)))
+    if(!(function = function_this(vthis)))
         return JS_E_FUNCTION_EXPECTED;
 
     hres = function->vtbl->toString(function, &str);
@@ -330,7 +326,7 @@ static HRESULT array_to_args(script_ctx_t *ctx, jsdisp_t *arg_array, unsigned *a
     return S_OK;
 }
 
-static HRESULT Function_apply(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
+static HRESULT Function_apply(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 {
     FunctionInstance *function;
     jsval_t *args = NULL;
@@ -340,7 +336,7 @@ static HRESULT Function_apply(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
 
     TRACE("\n");
 
-    if(!(function = function_this(jsthis)) && (jsthis->flags & VDISP_JSDISP))
+    if(!is_object_instance(vthis) || (!(function = function_this(vthis)) && to_jsdisp(get_object(vthis))))
         return JS_E_FUNCTION_EXPECTED;
 
     if(argc) {
@@ -377,7 +373,7 @@ static HRESULT Function_apply(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
             hres = function->vtbl->call(ctx, function, this_obj, flags, cnt, args, r);
         }else {
             jsval_t res;
-            hres = disp_call_value(ctx, jsthis->u.disp, this_obj, DISPATCH_METHOD, cnt, args, &res);
+            hres = disp_call_value(ctx, get_object(vthis), this_obj, DISPATCH_METHOD, cnt, args, &res);
             if(SUCCEEDED(hres)) {
                 if(r)
                     *r = res;
@@ -395,7 +391,7 @@ static HRESULT Function_apply(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
     return hres;
 }
 
-static HRESULT Function_call(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Function_call(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     FunctionInstance *function;
@@ -405,7 +401,7 @@ static HRESULT Function_call(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
 
     TRACE("\n");
 
-    if(!(function = function_this(jsthis)))
+    if(!(function = function_this(vthis)))
         return JS_E_FUNCTION_EXPECTED;
 
     if(argc) {
@@ -425,7 +421,7 @@ static HRESULT Function_call(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
     return hres;
 }
 
-static HRESULT Function_bind(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Function_bind(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     IDispatch *bound_this = NULL;
@@ -435,7 +431,7 @@ static HRESULT Function_bind(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
 
     TRACE("\n");
 
-    if(!(function = function_this(jsthis)))
+    if(!(function = function_this(vthis)))
         return JS_E_FUNCTION_EXPECTED;
 
     if(argc < 1) {
@@ -461,19 +457,18 @@ static HRESULT Function_bind(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
     return S_OK;
 }
 
-HRESULT Function_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+HRESULT Function_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     FunctionInstance *function;
 
     TRACE("\n");
 
-    if(!is_vclass(jsthis, JSCLASS_FUNCTION)) {
+    if(!(function = function_this(vthis))) {
         ERR("dispex is not a function\n");
         return E_FAIL;
     }
 
-    function = function_from_jsdisp(jsthis->u.jsdisp);
     return function->vtbl->call(ctx, function, NULL, flags, argc, argv, r);
 }
 
@@ -599,18 +594,14 @@ static HRESULT NativeFunction_call(script_ctx_t *ctx, FunctionInstance *func, ID
         unsigned argc, jsval_t *argv, jsval_t *r)
 {
     NativeFunction *function = (NativeFunction*)func;
-    vdisp_t vthis;
-    HRESULT hres;
+    jsval_t vthis;
 
     if(this_disp)
-        set_disp(&vthis, this_disp);
+        vthis = jsval_disp(this_disp);
     else
-        set_disp(&vthis, lookup_global_host(ctx));
-
-    hres = function->proc(ctx, &vthis, flags & ~DISPATCH_JSCRIPT_INTERNAL_MASK, argc, argv, r);
+        vthis = jsval_disp(lookup_global_host(ctx));
 
-    vdisp_release(&vthis);
-    return hres;
+    return function->proc(ctx, vthis, flags & ~DISPATCH_JSCRIPT_INTERNAL_MASK, argc, argv, r);
 }
 
 static HRESULT NativeFunction_toString(FunctionInstance *func, jsstr_t **ret)
@@ -984,7 +975,7 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg
     return S_OK;
 }
 
-static HRESULT FunctionConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT FunctionConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     HRESULT hres;
@@ -1011,7 +1002,7 @@ static HRESULT FunctionConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla
     return S_OK;
 }
 
-static HRESULT FunctionProt_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT FunctionProt_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     FIXME("\n");
diff --git a/dlls/jscript/global.c b/dlls/jscript/global.c
index d425c88..b9e3d89 100644
--- a/dlls/jscript/global.c
+++ b/dlls/jscript/global.c
@@ -65,7 +65,7 @@ static WCHAR int_to_char(int i)
     return 'A'+i-10;
 }
 
-static HRESULT JSGlobal_escape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT JSGlobal_escape(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsstr_t *ret_str, *str;
@@ -130,7 +130,7 @@ static HRESULT JSGlobal_escape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
 }
 
 /* ECMA-262 3rd Edition    15.1.2.1 */
-HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+HRESULT JSGlobal_eval(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     call_frame_t *frame = ctx->call_ctx;
@@ -174,7 +174,7 @@ HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned a
     return hres;
 }
 
-static HRESULT JSGlobal_isNaN(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT JSGlobal_isNaN(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     BOOL ret = TRUE;
@@ -197,7 +197,7 @@ static HRESULT JSGlobal_isNaN(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
     return S_OK;
 }
 
-static HRESULT JSGlobal_isFinite(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT JSGlobal_isFinite(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     BOOL ret = FALSE;
@@ -231,7 +231,7 @@ static INT char_to_int(WCHAR c)
     return 100;
 }
 
-static HRESULT JSGlobal_parseInt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT JSGlobal_parseInt(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     BOOL neg = FALSE, empty = TRUE;
@@ -314,7 +314,7 @@ static HRESULT JSGlobal_parseInt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
     return S_OK;
 }
 
-static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     LONGLONG d = 0, hlp;
@@ -421,7 +421,7 @@ static inline int hex_to_int(const WCHAR wch) {
     return -1;
 }
 
-static HRESULT JSGlobal_unescape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT JSGlobal_unescape(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsstr_t *ret_str, *str;
@@ -491,14 +491,14 @@ static HRESULT JSGlobal_unescape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
     return S_OK;
 }
 
-static HRESULT JSGlobal_GetObject(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT JSGlobal_GetObject(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     FIXME("\n");
     return E_NOTIMPL;
 }
 
-static HRESULT JSGlobal_ScriptEngine(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT JSGlobal_ScriptEngine(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     TRACE("\n");
@@ -516,7 +516,7 @@ static HRESULT JSGlobal_ScriptEngine(script_ctx_t *ctx, vdisp_t *jsthis, WORD fl
     return S_OK;
 }
 
-static HRESULT JSGlobal_ScriptEngineMajorVersion(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT JSGlobal_ScriptEngineMajorVersion(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     TRACE("\n");
@@ -526,7 +526,7 @@ static HRESULT JSGlobal_ScriptEngineMajorVersion(script_ctx_t *ctx, vdisp_t *jst
     return S_OK;
 }
 
-static HRESULT JSGlobal_ScriptEngineMinorVersion(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT JSGlobal_ScriptEngineMinorVersion(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     TRACE("\n");
@@ -536,7 +536,7 @@ static HRESULT JSGlobal_ScriptEngineMinorVersion(script_ctx_t *ctx, vdisp_t *jst
     return S_OK;
 }
 
-static HRESULT JSGlobal_ScriptEngineBuildVersion(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT JSGlobal_ScriptEngineBuildVersion(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     TRACE("\n");
@@ -546,7 +546,7 @@ static HRESULT JSGlobal_ScriptEngineBuildVersion(script_ctx_t *ctx, vdisp_t *jst
     return S_OK;
 }
 
-static HRESULT JSGlobal_CollectGarbage(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT JSGlobal_CollectGarbage(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     static int once = 0;
@@ -555,7 +555,7 @@ static HRESULT JSGlobal_CollectGarbage(script_ctx_t *ctx, vdisp_t *jsthis, WORD
     return S_OK;
 }
 
-static HRESULT JSGlobal_encodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT JSGlobal_encodeURI(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     const WCHAR *ptr, *uri;
@@ -620,7 +620,7 @@ static HRESULT JSGlobal_encodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
     return S_OK;
 }
 
-static HRESULT JSGlobal_decodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT JSGlobal_decodeURI(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     const WCHAR *ptr, *uri;
@@ -706,7 +706,7 @@ static HRESULT JSGlobal_decodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
     return S_OK;
 }
 
-static HRESULT JSGlobal_encodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT JSGlobal_encodeURIComponent(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsstr_t *str, *ret_str;
@@ -770,7 +770,7 @@ static HRESULT JSGlobal_encodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, W
 }
 
 /* ECMA-262 3rd Edition    15.1.3.2 */
-static HRESULT JSGlobal_decodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT JSGlobal_decodeURIComponent(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     const WCHAR *ptr, *uri;
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index 8ca2ea9..41b6c01 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -138,71 +138,7 @@ typedef enum {
 
 jsdisp_t *iface_to_jsdisp(IDispatch*) DECLSPEC_HIDDEN;
 
-typedef struct {
-    union {
-        IDispatch *disp;
-        IDispatchEx *dispex;
-        jsdisp_t *jsdisp;
-    } u;
-    DWORD flags;
-} vdisp_t;
-
-#define VDISP_DISPEX  0x0001
-#define VDISP_JSDISP  0x0002
-
-static inline void vdisp_release(vdisp_t *vdisp)
-{
-    IDispatch_Release(vdisp->u.disp);
-}
-
-static inline BOOL is_jsdisp(vdisp_t *vdisp)
-{
-    return (vdisp->flags & VDISP_JSDISP) != 0;
-}
-
-static inline BOOL is_dispex(vdisp_t *vdisp)
-{
-    return (vdisp->flags & VDISP_DISPEX) != 0;
-}
-
-static inline void set_jsdisp(vdisp_t *vdisp, jsdisp_t *jsdisp)
-{
-    vdisp->u.jsdisp = jsdisp;
-    vdisp->flags = VDISP_JSDISP | VDISP_DISPEX;
-    IDispatch_AddRef(vdisp->u.disp);
-}
-
-static inline void set_disp(vdisp_t *vdisp, IDispatch *disp)
-{
-    IDispatchEx *dispex;
-    jsdisp_t *jsdisp;
-    HRESULT hres;
-
-    jsdisp = iface_to_jsdisp(disp);
-    if(jsdisp) {
-        vdisp->u.jsdisp = jsdisp;
-        vdisp->flags = VDISP_JSDISP | VDISP_DISPEX;
-        return;
-    }
-
-    hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
-    if(SUCCEEDED(hres)) {
-        vdisp->u.dispex = dispex;
-        vdisp->flags = VDISP_DISPEX;
-        return;
-    }
-
-    IDispatch_AddRef(disp);
-    vdisp->u.disp = disp;
-    vdisp->flags = 0;
-}
-
-static inline jsdisp_t *get_jsdisp(vdisp_t *vdisp)
-{
-    return is_jsdisp(vdisp) ? vdisp->u.jsdisp : NULL;
-}
-
-typedef HRESULT (*builtin_invoke_t)(script_ctx_t*,vdisp_t*,WORD,unsigned,jsval_t*,jsval_t*);
+typedef HRESULT (*builtin_invoke_t)(script_ctx_t*,jsval_t,WORD,unsigned,jsval_t*,jsval_t*);
 typedef HRESULT (*builtin_getter_t)(script_ctx_t*,jsdisp_t*,jsval_t*);
 typedef HRESULT (*builtin_setter_t)(script_ctx_t*,jsdisp_t*,jsval_t);
 
@@ -337,7 +273,7 @@ HRESULT create_builtin_constructor(script_ctx_t*,builtin_invoke_t,const WCHAR*,c
         jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDEN;
 HRESULT Function_invoke(jsdisp_t*,IDispatch*,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN;
 
-HRESULT Function_value(script_ctx_t*,vdisp_t*,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN;
+HRESULT Function_value(script_ctx_t*,jsval_t,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN;
 HRESULT Function_get_value(script_ctx_t*,jsdisp_t*,jsval_t*) DECLSPEC_HIDDEN;
 struct _function_code_t *Function_get_code(jsdisp_t*) DECLSPEC_HIDDEN;
 
@@ -514,18 +450,13 @@ HRESULT regexp_string_match(script_ctx_t*,jsdisp_t*,jsstr_t*,jsval_t*) DECLSPEC_
 BOOL bool_obj_value(jsdisp_t*) DECLSPEC_HIDDEN;
 unsigned array_get_length(jsdisp_t*) DECLSPEC_HIDDEN;
 
-HRESULT JSGlobal_eval(script_ctx_t*,vdisp_t*,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN;
+HRESULT JSGlobal_eval(script_ctx_t*,jsval_t,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN;
 
 static inline BOOL is_class(jsdisp_t *jsdisp, jsclass_t class)
 {
     return jsdisp->builtin_info->class == class;
 }
 
-static inline BOOL is_vclass(vdisp_t *vdisp, jsclass_t class)
-{
-    return is_jsdisp(vdisp) && is_class(vdisp->u.jsdisp, class);
-}
-
 static inline BOOL is_int32(double d)
 {
     return INT32_MIN <= d && d <= INT32_MAX && (double)(int)d == d;
diff --git a/dlls/jscript/json.c b/dlls/jscript/json.c
index d3896ca..e0867eb 100644
--- a/dlls/jscript/json.c
+++ b/dlls/jscript/json.c
@@ -268,7 +268,7 @@ static HRESULT parse_json_value(json_parse_ctx_t *ctx, jsval_t *r)
 }
 
 /* ECMA-262 5.1 Edition    15.12.2 */
-static HRESULT JSON_parse(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
+static HRESULT JSON_parse(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 {
     json_parse_ctx_t parse_ctx;
     const WCHAR *buf;
@@ -749,7 +749,7 @@ static HRESULT stringify(stringify_ctx_t *ctx, jsdisp_t *object, const WCHAR *na
 }
 
 /* ECMA-262 5.1 Edition    15.12.3 */
-static HRESULT JSON_stringify(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
+static HRESULT JSON_stringify(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 {
     stringify_ctx_t stringify_ctx = { ctx };
     jsdisp_t *obj = NULL, *replacer;
diff --git a/dlls/jscript/jsregexp.c b/dlls/jscript/jsregexp.c
index 90663d3..15ebb11 100644
--- a/dlls/jscript/jsregexp.c
+++ b/dlls/jscript/jsregexp.c
@@ -39,9 +39,10 @@ static inline RegExpInstance *regexp_from_jsdisp(jsdisp_t *jsdisp)
     return CONTAINING_RECORD(jsdisp, RegExpInstance, dispex);
 }
 
-static inline RegExpInstance *regexp_from_vdisp(vdisp_t *vdisp)
+static inline RegExpInstance *regexp_this(jsval_t vthis)
 {
-    return regexp_from_jsdisp(vdisp->u.jsdisp);
+    jsdisp_t *jsdisp = is_object_instance(vthis) ? to_jsdisp(get_object(vthis)) : NULL;
+    return (jsdisp && is_class(jsdisp, JSCLASS_REGEXP)) ? regexp_from_jsdisp(jsdisp) : NULL;
 }
 
 static void set_last_index(RegExpInstance *This, DWORD last_index)
@@ -294,7 +295,7 @@ static HRESULT RegExp_set_lastIndex(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t
     return S_OK;
 }
 
-static HRESULT RegExp_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT RegExp_toString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     RegExpInstance *regexp;
@@ -304,12 +305,11 @@ static HRESULT RegExp_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
 
     TRACE("\n");
 
-    if(!is_vclass(jsthis, JSCLASS_REGEXP)) {
+    if(!(regexp = regexp_this(vthis))) {
         WARN("Not a RegExp\n");
         return JS_E_REGEXP_EXPECTED;
     }
 
-    regexp = regexp_from_vdisp(jsthis);
 
     if(!r)
         return S_OK;
@@ -408,7 +408,7 @@ static HRESULT create_match_array(script_ctx_t *ctx, jsstr_t *input_str,
     return S_OK;
 }
 
-static HRESULT run_exec(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t arg,
+static HRESULT run_exec(script_ctx_t *ctx, jsval_t vthis, jsval_t arg,
         jsstr_t **input, match_state_t **result, BOOL *ret)
 {
     RegExpInstance *regexp;
@@ -418,13 +418,11 @@ static HRESULT run_exec(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t arg,
     jsstr_t *jsstr;
     HRESULT hres;
 
-    if(!is_vclass(jsthis, JSCLASS_REGEXP)) {
-        FIXME("Not a RegExp\n");
-        return E_NOTIMPL;
+    if(!(regexp = regexp_this(vthis))) {
+        WARN("Not a RegExp\n");
+        return JS_E_REGEXP_EXPECTED;
     }
 
-    regexp = regexp_from_vdisp(jsthis);
-
     hres = to_flat_string(ctx, arg, &jsstr, &string);
     if(FAILED(hres))
         return hres;
@@ -463,7 +461,7 @@ static HRESULT run_exec(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t arg,
     return S_OK;
 }
 
-static HRESULT RegExp_exec(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT RegExp_exec(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     match_state_t *match;
@@ -476,7 +474,7 @@ static HRESULT RegExp_exec(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsig
 
     mark = heap_pool_mark(&ctx->tmp_heap);
 
-    hres = run_exec(ctx, jsthis, argc ? argv[0] : jsval_string(jsstr_empty()), &string, &match, &b);
+    hres = run_exec(ctx, vthis, argc ? argv[0] : jsval_string(jsstr_empty()), &string, &match, &b);
     if(FAILED(hres)) {
         heap_pool_clear(mark);
         return hres;
@@ -499,7 +497,7 @@ static HRESULT RegExp_exec(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsig
     return hres;
 }
 
-static HRESULT RegExp_test(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT RegExp_test(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     match_state_t *match;
@@ -511,7 +509,7 @@ static HRESULT RegExp_test(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsig
     TRACE("\n");
 
     mark = heap_pool_mark(&ctx->tmp_heap);
-    hres = run_exec(ctx, jsthis, argc ? argv[0] : jsval_string(undef_str = jsstr_undefined()), NULL, &match, &b);
+    hres = run_exec(ctx, vthis, argc ? argv[0] : jsval_string(undef_str = jsstr_undefined()), NULL, &match, &b);
     heap_pool_clear(mark);
     if(!argc)
         jsstr_release(undef_str);
@@ -523,7 +521,7 @@ static HRESULT RegExp_test(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsig
     return S_OK;
 }
 
-static HRESULT RegExp_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT RegExp_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     TRACE("\n");
@@ -886,7 +884,7 @@ static HRESULT RegExpConstr_get_rightContext(script_ctx_t *ctx, jsdisp_t *jsthis
     return S_OK;
 }
 
-static HRESULT RegExpConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT RegExpConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     TRACE("\n");
diff --git a/dlls/jscript/math.c b/dlls/jscript/math.c
index c65bbaf..46dd58c 100644
--- a/dlls/jscript/math.c
+++ b/dlls/jscript/math.c
@@ -29,7 +29,7 @@
 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
 
 /* ECMA-262 3rd Edition    15.8.2.12 */
-static HRESULT Math_abs(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Math_abs(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     double d;
@@ -52,7 +52,7 @@ static HRESULT Math_abs(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned
     return S_OK;
 }
 
-static HRESULT Math_acos(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Math_acos(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     double x;
@@ -75,7 +75,7 @@ static HRESULT Math_acos(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigne
     return S_OK;
 }
 
-static HRESULT Math_asin(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Math_asin(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     double x;
@@ -98,7 +98,7 @@ static HRESULT Math_asin(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigne
     return S_OK;
 }
 
-static HRESULT Math_atan(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Math_atan(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     double x;
@@ -121,7 +121,7 @@ static HRESULT Math_atan(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigne
     return S_OK;
 }
 
-static HRESULT Math_atan2(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Math_atan2(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     double x, y;
@@ -149,7 +149,7 @@ static HRESULT Math_atan2(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsign
 }
 
 /* ECMA-262 3rd Edition    15.8.2.6 */
-static HRESULT Math_ceil(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Math_ceil(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     double x;
@@ -172,7 +172,7 @@ static HRESULT Math_ceil(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigne
     return S_OK;
 }
 
-static HRESULT Math_cos(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Math_cos(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     double x;
@@ -195,7 +195,7 @@ static HRESULT Math_cos(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned
     return S_OK;
 }
 
-static HRESULT Math_exp(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Math_exp(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     double x;
@@ -218,7 +218,7 @@ static HRESULT Math_exp(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned
     return S_OK;
 }
 
-static HRESULT Math_floor(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Math_floor(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     double x;
@@ -241,7 +241,7 @@ static HRESULT Math_floor(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsign
     return S_OK;
 }
 
-static HRESULT Math_log(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Math_log(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     double x;
@@ -265,7 +265,7 @@ static HRESULT Math_log(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned
 }
 
 /* ECMA-262 3rd Edition    15.8.2.11 */
-static HRESULT Math_max(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Math_max(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DOUBLE max, d;
@@ -299,7 +299,7 @@ static HRESULT Math_max(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned
 }
 
 /* ECMA-262 3rd Edition    15.8.2.12 */
-static HRESULT Math_min(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Math_min(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     DOUBLE min, d;
@@ -333,7 +333,7 @@ static HRESULT Math_min(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned
 }
 
 /* ECMA-262 3rd Edition    15.8.2.13 */
-static HRESULT Math_pow(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Math_pow(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     double x, y;
@@ -361,7 +361,7 @@ static HRESULT Math_pow(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned
 }
 
 /* ECMA-262 3rd Edition    15.8.2.14 */
-static HRESULT Math_random(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Math_random(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     UINT x;
@@ -377,7 +377,7 @@ static HRESULT Math_random(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsig
 }
 
 /* ECMA-262 3rd Edition    15.8.2.15 */
-static HRESULT Math_round(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Math_round(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     double x;
@@ -400,7 +400,7 @@ static HRESULT Math_round(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsign
     return S_OK;
 }
 
-static HRESULT Math_sin(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Math_sin(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     double x;
@@ -423,7 +423,7 @@ static HRESULT Math_sin(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned
     return S_OK;
 }
 
-static HRESULT Math_sqrt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Math_sqrt(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     double x;
@@ -446,7 +446,7 @@ static HRESULT Math_sqrt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigne
     return S_OK;
 }
 
-static HRESULT Math_tan(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Math_tan(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     double x;
diff --git a/dlls/jscript/number.c b/dlls/jscript/number.c
index 410f27b..472acd0 100644
--- a/dlls/jscript/number.c
+++ b/dlls/jscript/number.c
@@ -39,14 +39,16 @@ static inline NumberInstance *number_from_jsdisp(jsdisp_t *jsdisp)
     return CONTAINING_RECORD(jsdisp, NumberInstance, dispex);
 }
 
-static inline NumberInstance *number_from_vdisp(vdisp_t *vdisp)
+static inline HRESULT numberval_this(jsval_t vthis, DOUBLE *ret)
 {
-    return number_from_jsdisp(vdisp->u.jsdisp);
-}
-
-static inline NumberInstance *number_this(vdisp_t *jsthis)
-{
-    return is_vclass(jsthis, JSCLASS_NUMBER) ? number_from_vdisp(jsthis) : NULL;
+    jsdisp_t *jsdisp;
+    if(is_number(vthis))
+        *ret = get_number(vthis);
+    else if(is_object_instance(vthis) && (jsdisp = to_jsdisp(get_object(vthis))) && is_class(jsdisp, JSCLASS_NUMBER))
+        *ret = number_from_jsdisp(jsdisp)->value;
+    else
+        return JS_E_NUMBER_EXPECTED;
+    return S_OK;
 }
 
 static inline void number_to_str(double d, WCHAR *buf, int size, int *dec_point)
@@ -222,10 +224,9 @@ static inline jsstr_t *number_to_exponential(double val, int prec)
 }
 
 /* ECMA-262 3rd Edition    15.7.4.2 */
-static HRESULT Number_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Number_toString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    NumberInstance *number;
     INT radix = 10;
     DOUBLE val;
     jsstr_t *str;
@@ -233,8 +234,9 @@ static HRESULT Number_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
 
     TRACE("\n");
 
-    if(!(number = number_this(jsthis)))
-        return JS_E_NUMBER_EXPECTED;
+    hres = numberval_this(vthis, &val);
+    if(FAILED(hres))
+        return hres;
 
     if(argc) {
         hres = to_int32(ctx, argv[0], &radix);
@@ -245,8 +247,6 @@ static HRESULT Number_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
             return JS_E_INVALIDARG;
     }
 
-    val = number->value;
-
     if(radix==10 || !isfinite(val)) {
         hres = to_string(ctx, jsval_number(val), &str);
         if(FAILED(hres))
@@ -341,17 +341,16 @@ static HRESULT Number_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
     return S_OK;
 }
 
-static HRESULT Number_toLocaleString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Number_toLocaleString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     FIXME("\n");
     return E_NOTIMPL;
 }
 
-static HRESULT Number_toFixed(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Number_toFixed(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    NumberInstance *number;
     DOUBLE val;
     INT prec = 0;
     jsstr_t *str;
@@ -359,8 +358,9 @@ static HRESULT Number_toFixed(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
 
     TRACE("\n");
 
-    if(!(number = number_this(jsthis)))
-        return JS_E_NUMBER_EXPECTED;
+    hres = numberval_this(vthis, &val);
+    if(FAILED(hres))
+        return hres;
 
     if(argc) {
         hres = to_int32(ctx, argv[0], &prec);
@@ -371,7 +371,6 @@ static HRESULT Number_toFixed(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
             return JS_E_FRACTION_DIGITS_OUT_OF_RANGE;
     }
 
-    val = number->value;
     if(!isfinite(val)) {
         hres = to_string(ctx, jsval_number(val), &str);
         if(FAILED(hres))
@@ -389,10 +388,9 @@ static HRESULT Number_toFixed(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
     return S_OK;
 }
 
-static HRESULT Number_toExponential(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Number_toExponential(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    NumberInstance *number;
     DOUBLE val;
     INT prec = 0;
     jsstr_t *str;
@@ -400,8 +398,9 @@ static HRESULT Number_toExponential(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla
 
     TRACE("\n");
 
-    if(!(number = number_this(jsthis)))
-        return JS_E_NUMBER_EXPECTED;
+    hres = numberval_this(vthis, &val);
+    if(FAILED(hres))
+        return hres;
 
     if(argc) {
         hres = to_int32(ctx, argv[0], &prec);
@@ -412,7 +411,6 @@ static HRESULT Number_toExponential(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla
             return JS_E_FRACTION_DIGITS_OUT_OF_RANGE;
     }
 
-    val = number->value;
     if(!isfinite(val)) {
         hres = to_string(ctx, jsval_number(val), &str);
         if(FAILED(hres))
@@ -432,17 +430,17 @@ static HRESULT Number_toExponential(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla
     return S_OK;
 }
 
-static HRESULT Number_toPrecision(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Number_toPrecision(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    NumberInstance *number;
     INT prec = 0, size;
     jsstr_t *str;
     DOUBLE val;
     HRESULT hres;
 
-    if(!(number = number_this(jsthis)))
-        return JS_E_NUMBER_EXPECTED;
+    hres = numberval_this(vthis, &val);
+    if(FAILED(hres))
+        return hres;
 
     if(argc) {
         hres = to_int32(ctx, argv[0], &prec);
@@ -453,7 +451,6 @@ static HRESULT Number_toPrecision(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
             return JS_E_PRECISION_OUT_OF_RANGE;
     }
 
-    val = number->value;
     if(!isfinite(val) || !prec) {
         hres = to_string(ctx, jsval_number(val), &str);
         if(FAILED(hres))
@@ -479,18 +476,20 @@ static HRESULT Number_toPrecision(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
     return S_OK;
 }
 
-static HRESULT Number_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Number_valueOf(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    NumberInstance *number;
+    HRESULT hres;
+    DOUBLE val;
 
     TRACE("\n");
 
-    if(!(number = number_this(jsthis)))
-        return JS_E_NUMBER_EXPECTED;
+    hres = numberval_this(vthis, &val);
+    if(FAILED(hres))
+        return hres;
 
     if(r)
-        *r = jsval_number(number->value);
+        *r = jsval_number(val);
     return S_OK;
 }
 
@@ -520,7 +519,7 @@ static const builtin_info_t NumberInst_info = {
     NULL
 };
 
-static HRESULT NumberConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT NumberConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     double n;
diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c
index 24692f8..3b5a1f8 100644
--- a/dlls/jscript/object.c
+++ b/dlls/jscript/object.c
@@ -24,11 +24,13 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
 
-static HRESULT Object_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Object_toString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsdisp_t *jsdisp;
     const WCHAR *str;
+    IDispatch *disp;
+    HRESULT hres;
 
     /* Keep in sync with jsclass_t enum */
     static const WCHAR *names[] = {
@@ -54,7 +56,16 @@ static HRESULT Object_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
 
     TRACE("\n");
 
-    jsdisp = get_jsdisp(jsthis);
+    if(is_undefined(vthis) || is_null(vthis)) {
+        str = L"[object Object]";
+        goto set_output;
+    }
+
+    hres = to_object(ctx, vthis, &disp);
+    if(FAILED(hres))
+        return hres;
+
+    jsdisp = to_jsdisp(disp);
     if(!jsdisp) {
         str = L"[object Object]";
     }else if(names[jsdisp->builtin_info->class]) {
@@ -62,9 +73,13 @@ static HRESULT Object_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
     }else {
         assert(jsdisp->builtin_info->class != JSCLASS_NONE);
         FIXME("jsdisp->builtin_info->class = %d\n", jsdisp->builtin_info->class);
-        return E_FAIL;
+        hres = E_FAIL;
     }
+    IDispatch_Release(disp);
+    if(FAILED(hres))
+        return hres;
 
+set_output:
     if(r) {
         jsstr_t *ret;
         ret = jsstr_alloc(str);
@@ -76,34 +91,56 @@ static HRESULT Object_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
     return S_OK;
 }
 
-static HRESULT Object_toLocaleString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Object_toLocaleString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
+    jsdisp_t *jsdisp;
+    IDispatch *disp;
+    HRESULT hres;
+
     TRACE("\n");
 
-    if(!is_jsdisp(jsthis)) {
+    hres = to_object(ctx, vthis, &disp);
+    if(FAILED(hres))
+        return hres;
+
+    if(!(jsdisp = to_jsdisp(disp))) {
         FIXME("Host object this\n");
-        return E_FAIL;
+        hres = E_FAIL;
+        goto done;
     }
 
-    return jsdisp_call_name(jsthis->u.jsdisp, L"toString", DISPATCH_METHOD, 0, NULL, r);
+    hres = jsdisp_call_name(jsdisp, L"toString", DISPATCH_METHOD, 0, NULL, r);
+done:
+    IDispatch_Release(disp);
+    return hres;
 }
 
-static HRESULT Object_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Object_valueOf(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
+    IDispatch *disp;
+    HRESULT hres;
+
     TRACE("\n");
 
-    if(r) {
-        IDispatch_AddRef(jsthis->u.disp);
-        *r = jsval_disp(jsthis->u.disp);
-    }
+    hres = to_object(ctx, vthis, &disp);
+    if(FAILED(hres))
+        return hres;
+
+    if(r)
+        *r = jsval_disp(disp);
+    else
+        IDispatch_Release(disp);
     return S_OK;
 }
 
-static HRESULT Object_hasOwnProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Object_hasOwnProperty(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
+    IDispatchEx *dispex;
+    jsdisp_t *jsdisp;
+    IDispatch *disp;
     jsstr_t *name;
     DISPID id;
     BSTR bstr;
@@ -111,33 +148,39 @@ static HRESULT Object_hasOwnProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD fl
 
     TRACE("\n");
 
+    hres = to_object(ctx, vthis, &disp);
+    if(FAILED(hres))
+        return hres;
+
     if(!argc) {
         if(r)
             *r = jsval_bool(FALSE);
-        return S_OK;
+        goto done;
     }
 
     hres = to_string(ctx, argv[0], &name);
     if(FAILED(hres))
-        return hres;
+        goto done;
 
-    if(is_jsdisp(jsthis)) {
+    if((jsdisp = to_jsdisp(disp))) {
         property_desc_t prop_desc;
         const WCHAR *name_str;
 
         name_str = jsstr_flatten(name);
         if(!name_str) {
             jsstr_release(name);
-            return E_OUTOFMEMORY;
+            hres = E_OUTOFMEMORY;
+            goto done;
         }
 
-        hres = jsdisp_get_own_property(jsthis->u.jsdisp, name_str, TRUE, &prop_desc);
+        hres = jsdisp_get_own_property(jsdisp, name_str, TRUE, &prop_desc);
         jsstr_release(name);
         if(FAILED(hres) && hres != DISP_E_UNKNOWNNAME)
-            return hres;
+            goto done;
 
         if(r) *r = jsval_bool(hres == S_OK);
-        return S_OK;
+        hres = S_OK;
+        goto done;
     }
 
 
@@ -145,66 +188,91 @@ static HRESULT Object_hasOwnProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD fl
     if(bstr)
         jsstr_flush(name, bstr);
     jsstr_release(name);
-    if(!bstr)
-        return E_OUTOFMEMORY;
-
-    if(is_dispex(jsthis))
-        hres = IDispatchEx_GetDispID(jsthis->u.dispex, bstr, make_grfdex(ctx, fdexNameCaseSensitive), &id);
-    else
-        hres = IDispatch_GetIDsOfNames(jsthis->u.disp, &IID_NULL, &bstr, 1, ctx->lcid, &id);
+    if(!bstr) {
+        hres = E_OUTOFMEMORY;
+        goto done;
+    }
 
+    hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
+    if(SUCCEEDED(hres)) {
+        hres = IDispatchEx_GetDispID(dispex, bstr, make_grfdex(ctx, fdexNameCaseSensitive), &id);
+        IDispatchEx_Release(dispex);
+    }else {
+        hres = IDispatch_GetIDsOfNames(disp, &IID_NULL, &bstr, 1, ctx->lcid, &id);
+    }
     SysFreeString(bstr);
     if(r)
         *r = jsval_bool(SUCCEEDED(hres));
-    return S_OK;
+    hres = S_OK;
+done:
+    IDispatch_Release(disp);
+    return hres;
 }
 
-static HRESULT Object_propertyIsEnumerable(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Object_propertyIsEnumerable(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     property_desc_t prop_desc;
     const WCHAR *name;
     jsstr_t *name_str;
+    jsdisp_t *jsdisp;
+    IDispatch *disp;
     HRESULT hres;
 
     TRACE("\n");
 
+    hres = to_object(ctx, vthis, &disp);
+    if(FAILED(hres))
+        return hres;
+
     if(argc != 1) {
         FIXME("argc %d not supported\n", argc);
-        return E_NOTIMPL;
+        hres = E_NOTIMPL;
+        goto done;
     }
 
-    if(!is_jsdisp(jsthis)) {
+    if(!(jsdisp = to_jsdisp(disp))) {
         FIXME("Host object this\n");
-        return E_FAIL;
+        hres = E_FAIL;
+        goto done;
     }
 
     hres = to_flat_string(ctx, argv[0], &name_str, &name);
     if(FAILED(hres))
-        return hres;
+        goto done;
 
-    hres = jsdisp_get_own_property(jsthis->u.jsdisp, name, TRUE, &prop_desc);
+    hres = jsdisp_get_own_property(jsdisp, name, TRUE, &prop_desc);
     jsstr_release(name_str);
     if(FAILED(hres) && hres != DISP_E_UNKNOWNNAME)
-        return hres;
+        goto done;
 
     if(r)
         *r = jsval_bool(hres == S_OK && (prop_desc.flags & PROPF_ENUMERABLE) != 0);
-    return S_OK;
+    hres = S_OK;
+done:
+    IDispatch_Release(disp);
+    return hres;
 }
 
-static HRESULT Object_isPrototypeOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Object_isPrototypeOf(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    jsdisp_t *jsdisp;
+    jsdisp_t *jsthis, *jsdisp;
+    IDispatch *disp;
     BOOL ret = FALSE;
+    HRESULT hres;
+
+    hres = to_object(ctx, vthis, &disp);
+    if(FAILED(hres))
+        return hres;
 
     if(!r)
-        return S_OK;
+        goto done;
 
-    if(argc && is_jsdisp(jsthis) && is_object_instance(argv[0]) && (jsdisp = to_jsdisp(get_object(argv[0])))) {
+    if(argc && (jsthis = to_jsdisp(disp)) && is_object_instance(argv[0]) &&
+       (jsdisp = to_jsdisp(get_object(argv[0])))) {
         while(jsdisp->prototype) {
-            if(jsdisp->prototype == jsthis->u.jsdisp) {
+            if(jsdisp->prototype == jsthis) {
                 ret = TRUE;
                 break;
             }
@@ -213,7 +281,9 @@ static HRESULT Object_isPrototypeOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla
     }
 
     *r = jsval_bool(ret);
-    return S_OK;
+done:
+    IDispatch_Release(disp);
+    return hres;
 }
 
 static HRESULT Object_get_proto_(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
@@ -466,7 +536,7 @@ static HRESULT jsdisp_define_properties(script_ctx_t *ctx, jsdisp_t *obj, jsval_
     return FAILED(hres) ? hres : S_OK;
 }
 
-static HRESULT Object_defineProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+static HRESULT Object_defineProperty(script_ctx_t *ctx, jsval_t vthis, WORD flags,
                                      unsigned argc, jsval_t *argv, jsval_t *r)
 {
     property_desc_t prop_desc;
@@ -515,7 +585,7 @@ static HRESULT Object_defineProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD fl
     return hres;
 }
 
-static HRESULT Object_defineProperties(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+static HRESULT Object_defineProperties(script_ctx_t *ctx, jsval_t vthis, WORD flags,
                                      unsigned argc, jsval_t *argv, jsval_t *r)
 {
     jsdisp_t *obj;
@@ -534,7 +604,7 @@ static HRESULT Object_defineProperties(script_ctx_t *ctx, vdisp_t *jsthis, WORD
     return hres;
 }
 
-static HRESULT Object_getOwnPropertyDescriptor(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+static HRESULT Object_getOwnPropertyDescriptor(script_ctx_t *ctx, jsval_t vthis, WORD flags,
                                                unsigned argc, jsval_t *argv, jsval_t *r)
 {
     property_desc_t prop_desc;
@@ -597,7 +667,7 @@ static HRESULT Object_getOwnPropertyDescriptor(script_ctx_t *ctx, vdisp_t *jsthi
     return hres;
 }
 
-static HRESULT Object_create(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+static HRESULT Object_create(script_ctx_t *ctx, jsval_t vthis, WORD flags,
                              unsigned argc, jsval_t *argv, jsval_t *r)
 {
     jsdisp_t *proto = NULL, *obj;
@@ -636,7 +706,7 @@ static HRESULT Object_create(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
     return hres;
 }
 
-static HRESULT Object_getPrototypeOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+static HRESULT Object_getPrototypeOf(script_ctx_t *ctx, jsval_t vthis, WORD flags,
                                      unsigned argc, jsval_t *argv, jsval_t *r)
 {
     jsdisp_t *obj;
@@ -704,7 +774,7 @@ static HRESULT object_keys(script_ctx_t *ctx, jsval_t arg, enum jsdisp_enum_type
     return hres;
 }
 
-static HRESULT Object_keys(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+static HRESULT Object_keys(script_ctx_t *ctx, jsval_t vthis, WORD flags,
                            unsigned argc, jsval_t *argv, jsval_t *r)
 {
     jsval_t arg = argc ? argv[0] : jsval_undefined();
@@ -714,7 +784,7 @@ static HRESULT Object_keys(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
     return object_keys(ctx, arg, JSDISP_ENUM_OWN_ENUMERABLE, r);
 }
 
-static HRESULT Object_getOwnPropertyNames(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+static HRESULT Object_getOwnPropertyNames(script_ctx_t *ctx, jsval_t vthis, WORD flags,
                                           unsigned argc, jsval_t *argv, jsval_t *r)
 {
     jsval_t arg = argc ? argv[0] : jsval_undefined();
@@ -724,7 +794,7 @@ static HRESULT Object_getOwnPropertyNames(script_ctx_t *ctx, vdisp_t *jsthis, WO
     return object_keys(ctx, arg, JSDISP_ENUM_OWN, r);
 }
 
-static HRESULT Object_preventExtensions(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
+static HRESULT Object_preventExtensions(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 {
     jsdisp_t *obj;
 
@@ -746,7 +816,7 @@ static HRESULT Object_preventExtensions(script_ctx_t *ctx, vdisp_t *jsthis, WORD
     return S_OK;
 }
 
-static HRESULT Object_freeze(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc,
+static HRESULT Object_freeze(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc,
                              jsval_t *argv, jsval_t *r)
 {
     jsdisp_t *obj;
@@ -769,7 +839,7 @@ static HRESULT Object_freeze(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
     return S_OK;
 }
 
-static HRESULT Object_seal(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc,
+static HRESULT Object_seal(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc,
                            jsval_t *argv, jsval_t *r)
 {
     jsdisp_t *obj;
@@ -792,7 +862,7 @@ static HRESULT Object_seal(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsig
     return S_OK;
 }
 
-static HRESULT Object_isExtensible(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
+static HRESULT Object_isExtensible(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 {
     jsdisp_t *obj;
 
@@ -813,7 +883,7 @@ static HRESULT Object_isExtensible(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
     return S_OK;
 }
 
-static HRESULT Object_isFrozen(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc,
+static HRESULT Object_isFrozen(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc,
                                jsval_t *argv, jsval_t *r)
 {
     jsdisp_t *obj;
@@ -835,7 +905,7 @@ static HRESULT Object_isFrozen(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
     return S_OK;
 }
 
-static HRESULT Object_isSealed(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc,
+static HRESULT Object_isSealed(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc,
                                jsval_t *argv, jsval_t *r)
 {
     jsdisp_t *obj;
@@ -882,7 +952,7 @@ static const builtin_info_t ObjectConstr_info = {
     NULL
 };
 
-static HRESULT ObjectConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT ObjectConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     HRESULT hres;
diff --git a/dlls/jscript/set.c b/dlls/jscript/set.c
index 5ae41d8..35edcf8 100644
--- a/dlls/jscript/set.c
+++ b/dlls/jscript/set.c
@@ -37,42 +37,42 @@ typedef struct {
     size_t size;
 } MapInstance;
 
-static HRESULT Set_add(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Set_add(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    FIXME("%p\n", jsthis);
+    FIXME("%p\n", debugstr_jsval(vthis));
     return E_NOTIMPL;
 }
 
-static HRESULT Set_clear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Set_clear(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    FIXME("%p\n", jsthis);
+    FIXME("%p\n", debugstr_jsval(vthis));
     return E_NOTIMPL;
 }
 
-static HRESULT Set_delete(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Set_delete(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    FIXME("%p\n", jsthis);
+    FIXME("%p\n", debugstr_jsval(vthis));
     return E_NOTIMPL;
 }
 
-static HRESULT Set_forEach(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Set_forEach(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    FIXME("%p\n", jsthis);
+    FIXME("%p\n", debugstr_jsval(vthis));
     return E_NOTIMPL;
 }
 
-static HRESULT Set_has(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Set_has(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    FIXME("%p\n", jsthis);
+    FIXME("%p\n", debugstr_jsval(vthis));
     return E_NOTIMPL;
 }
 
-static HRESULT Set_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Set_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     FIXME("\n");
@@ -104,7 +104,7 @@ static const builtin_info_t Set_info = {
     NULL
 };
 
-static HRESULT Set_constructor(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Set_constructor(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     SetInstance *set;
@@ -176,14 +176,19 @@ static int jsval_map_compare(const void *k, const struct wine_rb_entry *e)
     }
 }
 
-static MapInstance *get_map_this(vdisp_t *jsthis)
+static HRESULT get_map_this(jsval_t vthis, MapInstance **ret)
 {
-    if(!(jsthis->flags & VDISP_JSDISP) || !is_class(jsthis->u.jsdisp, JSCLASS_MAP)) {
+    jsdisp_t *jsdisp;
+
+    if(!is_object_instance(vthis))
+        return JS_E_OBJECT_EXPECTED;
+    if(!(jsdisp = to_jsdisp(get_object(vthis))) || !is_class(jsdisp, JSCLASS_MAP)) {
         WARN("not a Map object passed as 'this'\n");
-        return NULL;
+        return JS_E_MAP_EXPECTED;
     }
 
-    return CONTAINING_RECORD(jsthis->u.jsdisp, MapInstance, dispex);
+    *ret = CONTAINING_RECORD(jsdisp, MapInstance, dispex);
+    return S_OK;
 }
 
 static struct jsval_map_entry *get_map_entry(MapInstance *map, jsval_t key)
@@ -215,12 +220,15 @@ static void delete_map_entry(MapInstance *map, struct jsval_map_entry *entry)
     release_map_entry(entry);
 }
 
-static HRESULT Map_clear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Map_clear(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     MapInstance *map;
+    HRESULT hres;
 
-    if(!(map = get_map_this(jsthis))) return JS_E_MAP_EXPECTED;
+    hres = get_map_this(vthis, &map);
+    if(FAILED(hres))
+        return hres;
 
     TRACE("%p\n", map);
 
@@ -233,14 +241,17 @@ static HRESULT Map_clear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigne
     return S_OK;
 }
 
-static HRESULT Map_delete(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Map_delete(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsval_t key = argc >= 1 ? argv[0] : jsval_undefined();
     struct jsval_map_entry *entry;
     MapInstance *map;
+    HRESULT hres;
 
-    if(!(map = get_map_this(jsthis))) return JS_E_MAP_EXPECTED;
+    hres = get_map_this(vthis, &map);
+    if(FAILED(hres))
+        return hres;
 
     TRACE("%p (%s)\n", map, debugstr_jsval(key));
 
@@ -249,7 +260,7 @@ static HRESULT Map_delete(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsign
     return S_OK;
 }
 
-static HRESULT Map_forEach(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Map_forEach(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsval_t callback = argc ? argv[0] : jsval_undefined();
@@ -257,7 +268,9 @@ static HRESULT Map_forEach(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsig
     MapInstance *map;
     HRESULT hres;
 
-    if(!(map = get_map_this(jsthis))) return JS_E_MAP_EXPECTED;
+    hres = get_map_this(vthis, &map);
+    if(FAILED(hres))
+        return hres;
 
     TRACE("%p (%s)\n", map, debugstr_jsval(argc >= 1 ? argv[0] : jsval_undefined()));
 
@@ -290,14 +303,17 @@ static HRESULT Map_forEach(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsig
     return S_OK;
 }
 
-static HRESULT Map_get(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Map_get(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsval_t key = argc >= 1 ? argv[0] : jsval_undefined();
     struct jsval_map_entry *entry;
     MapInstance *map;
+    HRESULT hres;
 
-    if(!(map = get_map_this(jsthis))) return JS_E_MAP_EXPECTED;
+    hres = get_map_this(vthis, &map);
+    if(FAILED(hres))
+        return hres;
 
     TRACE("%p (%s)\n", map, debugstr_jsval(key));
 
@@ -309,7 +325,7 @@ static HRESULT Map_get(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned
     return r ? jsval_copy(entry->value, r) : S_OK;
 }
 
-static HRESULT Map_set(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Map_set(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsval_t key = argc >= 1 ? argv[0] : jsval_undefined();
@@ -318,7 +334,9 @@ static HRESULT Map_set(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned
     MapInstance *map;
     HRESULT hres;
 
-    if(!(map = get_map_this(jsthis))) return JS_E_MAP_EXPECTED;
+    hres = get_map_this(vthis, &map);
+    if(FAILED(hres))
+        return hres;
 
     TRACE("%p (%s %s)\n", map, debugstr_jsval(key), debugstr_jsval(value));
 
@@ -353,14 +371,17 @@ static HRESULT Map_set(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned
     return S_OK;
 }
 
-static HRESULT Map_has(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Map_has(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsval_t key = argc >= 1 ? argv[0] : jsval_undefined();
     struct jsval_map_entry *entry;
     MapInstance *map;
+    HRESULT hres;
 
-    if(!(map = get_map_this(jsthis))) return JS_E_MAP_EXPECTED;
+    hres = get_map_this(vthis, &map);
+    if(FAILED(hres))
+        return hres;
 
     TRACE("%p (%s)\n", map, debugstr_jsval(key));
 
@@ -379,7 +400,7 @@ static HRESULT Map_get_size(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
     return S_OK;
 }
 
-static HRESULT Map_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Map_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     FIXME("\n");
@@ -430,7 +451,7 @@ static const builtin_info_t Map_info = {
     NULL
 };
 
-static HRESULT Map_constructor(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT Map_constructor(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     MapInstance *map;
diff --git a/dlls/jscript/string.c b/dlls/jscript/string.c
index 4d65d6b..0b2e695 100644
--- a/dlls/jscript/string.c
+++ b/dlls/jscript/string.c
@@ -36,33 +36,32 @@ static inline StringInstance *string_from_jsdisp(jsdisp_t *jsdisp)
     return CONTAINING_RECORD(jsdisp, StringInstance, dispex);
 }
 
-static inline StringInstance *string_from_vdisp(vdisp_t *vdisp)
+static inline StringInstance *string_this(jsval_t vthis)
 {
-    return string_from_jsdisp(vdisp->u.jsdisp);
+    jsdisp_t *jsdisp = is_object_instance(vthis) ? to_jsdisp(get_object(vthis)) : NULL;
+    return (jsdisp && is_class(jsdisp, JSCLASS_STRING)) ? string_from_jsdisp(jsdisp) : NULL;
 }
 
-static inline StringInstance *string_this(vdisp_t *jsthis)
-{
-    return is_vclass(jsthis, JSCLASS_STRING) ? string_from_vdisp(jsthis) : NULL;
-}
-
-static HRESULT get_string_val(script_ctx_t *ctx, vdisp_t *jsthis, jsstr_t **val)
+static HRESULT get_string_val(script_ctx_t *ctx, jsval_t vthis, jsstr_t **val)
 {
     StringInstance *string;
 
-    if((string = string_this(jsthis))) {
+    if(ctx->version >= SCRIPTLANGUAGEVERSION_ES5 && (is_undefined(vthis) || is_null(vthis)))
+        return JS_E_OBJECT_EXPECTED;
+
+    if((string = string_this(vthis))) {
         *val = jsstr_addref(string->str);
         return S_OK;
     }
 
-    return to_string(ctx, jsval_disp(jsthis->u.disp), val);
+    return to_string(ctx, vthis, val);
 }
 
-static HRESULT get_string_flat_val(script_ctx_t *ctx, vdisp_t *jsthis, jsstr_t **jsval, const WCHAR **val)
+static HRESULT get_string_flat_val(script_ctx_t *ctx, jsval_t vthis, jsstr_t **jsval, const WCHAR **val)
 {
     HRESULT hres;
 
-    hres = get_string_val(ctx, jsthis, jsval);
+    hres = get_string_val(ctx, vthis, jsval);
     if(FAILED(hres))
         return hres;
 
@@ -84,11 +83,11 @@ static HRESULT String_get_length(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r
     return S_OK;
 }
 
-static HRESULT stringobj_to_string(vdisp_t *jsthis, jsval_t *r)
+static HRESULT stringobj_to_string(jsval_t vthis, jsval_t *r)
 {
     StringInstance *string;
 
-    if(!(string = string_this(jsthis))) {
+    if(!(string = string_this(vthis))) {
         WARN("this is not a string object\n");
         return E_FAIL;
     }
@@ -99,31 +98,31 @@ static HRESULT stringobj_to_string(vdisp_t *jsthis, jsval_t *r)
 }
 
 /* ECMA-262 3rd Edition    15.5.4.2 */
-static HRESULT String_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_toString(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     TRACE("\n");
 
-    return stringobj_to_string(jsthis, r);
+    return stringobj_to_string(vthis, r);
 }
 
 /* ECMA-262 3rd Edition    15.5.4.2 */
-static HRESULT String_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_valueOf(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     TRACE("\n");
 
-    return stringobj_to_string(jsthis, r);
+    return stringobj_to_string(vthis, r);
 }
 
-static HRESULT do_attributeless_tag_format(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r, const WCHAR *tagname)
+static HRESULT do_attributeless_tag_format(script_ctx_t *ctx, jsval_t vthis, jsval_t *r, const WCHAR *tagname)
 {
     unsigned tagname_len;
     jsstr_t *str, *ret;
     WCHAR *ptr;
     HRESULT hres;
 
-    hres = get_string_val(ctx, jsthis, &str);
+    hres = get_string_val(ctx, vthis, &str);
     if(FAILED(hres))
         return hres;
 
@@ -158,13 +157,13 @@ static HRESULT do_attributeless_tag_format(script_ctx_t *ctx, vdisp_t *jsthis, j
     return S_OK;
 }
 
-static HRESULT do_attribute_tag_format(script_ctx_t *ctx, vdisp_t *jsthis, unsigned argc, jsval_t *argv, jsval_t *r,
+static HRESULT do_attribute_tag_format(script_ctx_t *ctx, jsval_t vthis, unsigned argc, jsval_t *argv, jsval_t *r,
         const WCHAR *tagname, const WCHAR *attrname)
 {
     jsstr_t *str, *attr_value = NULL;
     HRESULT hres;
 
-    hres = get_string_val(ctx, jsthis, &str);
+    hres = get_string_val(ctx, vthis, &str);
     if(FAILED(hres))
         return hres;
 
@@ -216,32 +215,32 @@ static HRESULT do_attribute_tag_format(script_ctx_t *ctx, vdisp_t *jsthis, unsig
     return hres;
 }
 
-static HRESULT String_anchor(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_anchor(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    return do_attribute_tag_format(ctx, jsthis, argc, argv, r, L"A", L"NAME");
+    return do_attribute_tag_format(ctx, vthis, argc, argv, r, L"A", L"NAME");
 }
 
-static HRESULT String_big(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_big(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    return do_attributeless_tag_format(ctx, jsthis, r, L"BIG");
+    return do_attributeless_tag_format(ctx, vthis, r, L"BIG");
 }
 
-static HRESULT String_blink(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_blink(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    return do_attributeless_tag_format(ctx, jsthis, r, L"BLINK");
+    return do_attributeless_tag_format(ctx, vthis, r, L"BLINK");
 }
 
-static HRESULT String_bold(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_bold(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    return do_attributeless_tag_format(ctx, jsthis, r, L"B");
+    return do_attributeless_tag_format(ctx, vthis, r, L"B");
 }
 
 /* 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,
+static HRESULT String_charAt(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsstr_t *str, *ret;
@@ -250,7 +249,7 @@ static HRESULT String_charAt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
 
     TRACE("\n");
 
-    hres = get_string_val(ctx, jsthis, &str);
+    hres = get_string_val(ctx, vthis, &str);
     if(FAILED(hres))
         return hres;
 
@@ -283,7 +282,7 @@ static HRESULT String_charAt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
 }
 
 /* ECMA-262 3rd Edition    15.5.4.5 */
-static HRESULT String_charCodeAt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_charCodeAt(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsstr_t *str;
@@ -292,7 +291,7 @@ static HRESULT String_charCodeAt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
 
     TRACE("\n");
 
-    hres = get_string_val(ctx, jsthis, &str);
+    hres = get_string_val(ctx, vthis, &str);
     if(FAILED(hres))
         return hres;
 
@@ -326,7 +325,7 @@ static HRESULT String_charCodeAt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
 }
 
 /* ECMA-262 3rd Edition    15.5.4.6 */
-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, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsstr_t *ret = NULL, *str;
@@ -334,7 +333,7 @@ static HRESULT String_concat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
 
     TRACE("\n");
 
-    hres = get_string_val(ctx, jsthis, &str);
+    hres = get_string_val(ctx, vthis, &str);
     if(FAILED(hres))
         return hres;
 
@@ -411,25 +410,25 @@ static HRESULT String_concat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
     return S_OK;
 }
 
-static HRESULT String_fixed(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_fixed(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    return do_attributeless_tag_format(ctx, jsthis, r, L"TT");
+    return do_attributeless_tag_format(ctx, vthis, r, L"TT");
 }
 
-static HRESULT String_fontcolor(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_fontcolor(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    return do_attribute_tag_format(ctx, jsthis, argc, argv, r, L"FONT", L"COLOR");
+    return do_attribute_tag_format(ctx, vthis, argc, argv, r, L"FONT", L"COLOR");
 }
 
-static HRESULT String_fontsize(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_fontsize(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    return do_attribute_tag_format(ctx, jsthis, argc, argv, r, L"FONT", L"SIZE");
+    return do_attribute_tag_format(ctx, vthis, argc, argv, r, L"FONT", L"SIZE");
 }
 
-static HRESULT String_indexOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_indexOf(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     unsigned pos = 0, search_len, length;
@@ -440,7 +439,7 @@ static HRESULT String_indexOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
 
     TRACE("\n");
 
-    hres = get_string_flat_val(ctx, jsthis, &jsstr, &str);
+    hres = get_string_flat_val(ctx, vthis, &jsstr, &str);
     if(FAILED(hres))
         return hres;
 
@@ -490,14 +489,14 @@ static HRESULT String_indexOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
     return S_OK;
 }
 
-static HRESULT String_italics(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_italics(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    return do_attributeless_tag_format(ctx, jsthis, r, L"I");
+    return do_attributeless_tag_format(ctx, vthis, r, L"I");
 }
 
 /* ECMA-262 3rd Edition    15.5.4.8 */
-static HRESULT String_lastIndexOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_lastIndexOf(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     unsigned pos = 0, search_len, length;
@@ -508,7 +507,7 @@ static HRESULT String_lastIndexOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
 
     TRACE("\n");
 
-    hres = get_string_flat_val(ctx, jsthis, &jsstr, &str);
+    hres = get_string_flat_val(ctx, vthis, &jsstr, &str);
     if(FAILED(hres))
         return hres;
 
@@ -559,14 +558,14 @@ static HRESULT String_lastIndexOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
     return S_OK;
 }
 
-static HRESULT String_link(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_link(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    return do_attribute_tag_format(ctx, jsthis, argc, argv, r, L"A", L"HREF");
+    return do_attribute_tag_format(ctx, vthis, argc, argv, r, L"A", L"HREF");
 }
 
 /* ECMA-262 3rd Edition    15.5.4.10 */
-static HRESULT String_match(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_match(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsdisp_t *regexp = NULL;
@@ -602,7 +601,7 @@ static HRESULT String_match(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
             return hres;
     }
 
-    hres = get_string_val(ctx, jsthis, &str);
+    hres = get_string_val(ctx, vthis, &str);
     if(SUCCEEDED(hres))
         hres = regexp_string_match(ctx, regexp, str, r);
 
@@ -718,7 +717,7 @@ static HRESULT rep_call(script_ctx_t *ctx, jsdisp_t *func,
 }
 
 /* ECMA-262 3rd Edition    15.5.4.11 */
-static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_replace(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     const WCHAR *str, *match_str = NULL, *rep_str = NULL;
@@ -732,7 +731,7 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
 
     TRACE("\n");
 
-    hres = get_string_flat_val(ctx, jsthis, &jsstr, &str);
+    hres = get_string_flat_val(ctx, vthis, &jsstr, &str);
     if(FAILED(hres))
         return hres;
 
@@ -938,7 +937,7 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
     return hres;
 }
 
-static HRESULT String_search(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_search(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     jsdisp_t *regexp = NULL;
@@ -949,7 +948,7 @@ static HRESULT String_search(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
 
     TRACE("\n");
 
-    hres = get_string_flat_val(ctx, jsthis, &jsstr, &str);
+    hres = get_string_flat_val(ctx, vthis, &jsstr, &str);
     if(FAILED(hres))
         return hres;
 
@@ -989,7 +988,7 @@ static HRESULT String_search(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
 }
 
 /* ECMA-262 3rd Edition    15.5.4.13 */
-static HRESULT String_slice(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_slice(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     int start=0, end, length;
@@ -999,7 +998,7 @@ static HRESULT String_slice(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
 
     TRACE("\n");
 
-    hres = get_string_val(ctx, jsthis, &str);
+    hres = get_string_val(ctx, vthis, &str);
     if(FAILED(hres))
         return hres;
 
@@ -1065,13 +1064,13 @@ static HRESULT String_slice(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
     return S_OK;
 }
 
-static HRESULT String_small(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_small(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    return do_attributeless_tag_format(ctx, jsthis, r, L"SMALL");
+    return do_attributeless_tag_format(ctx, vthis, r, L"SMALL");
 }
 
-static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_split(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     match_state_t match_result, *match_ptr = &match_result;
@@ -1082,7 +1081,7 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
     jsstr_t *jsstr, *match_jsstr, *tmp_str;
     HRESULT hres;
 
-    hres = get_string_flat_val(ctx, jsthis, &jsstr, &str);
+    hres = get_string_flat_val(ctx, vthis, &jsstr, &str);
     if(FAILED(hres))
         return hres;
     length = jsstr_length(jsstr);
@@ -1231,20 +1230,20 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
     return hres;
 }
 
-static HRESULT String_strike(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_strike(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    return do_attributeless_tag_format(ctx, jsthis, r, L"STRIKE");
+    return do_attributeless_tag_format(ctx, vthis, r, L"STRIKE");
 }
 
-static HRESULT String_sub(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_sub(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    return do_attributeless_tag_format(ctx, jsthis, r, L"SUB");
+    return do_attributeless_tag_format(ctx, vthis, r, L"SUB");
 }
 
 /* ECMA-262 3rd Edition    15.5.4.15 */
-static HRESULT String_substring(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_substring(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     INT start=0, end, length;
@@ -1254,7 +1253,7 @@ static HRESULT String_substring(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
 
     TRACE("\n");
 
-    hres = get_string_val(ctx, jsthis, &str);
+    hres = get_string_val(ctx, vthis, &str);
     if(FAILED(hres))
         return hres;
 
@@ -1303,7 +1302,7 @@ static HRESULT String_substring(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
 }
 
 /* ECMA-262 3rd Edition    B.2.3 */
-static HRESULT String_substr(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_substr(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     int start=0, len, length;
@@ -1313,7 +1312,7 @@ static HRESULT String_substr(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
 
     TRACE("\n");
 
-    hres = get_string_val(ctx, jsthis, &str);
+    hres = get_string_val(ctx, vthis, &str);
     if(FAILED(hres))
         return hres;
 
@@ -1357,19 +1356,19 @@ static HRESULT String_substr(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
     return hres;
 }
 
-static HRESULT String_sup(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_sup(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
-    return do_attributeless_tag_format(ctx, jsthis, r, L"SUP");
+    return do_attributeless_tag_format(ctx, vthis, r, L"SUP");
 }
 
-static HRESULT to_upper_case(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r)
+static HRESULT to_upper_case(script_ctx_t *ctx, jsval_t vthis, jsval_t *r)
 {
     jsstr_t *str;
     HRESULT hres;
 
 
-    hres = get_string_val(ctx, jsthis, &str);
+    hres = get_string_val(ctx, vthis, &str);
     if(FAILED(hres))
         return hres;
 
@@ -1393,13 +1392,13 @@ static HRESULT to_upper_case(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r)
     return S_OK;
 }
 
-static HRESULT to_lower_case(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r)
+static HRESULT to_lower_case(script_ctx_t *ctx, jsval_t vthis, jsval_t *r)
 {
     jsstr_t *str;
     HRESULT hres;
 
 
-    hres = get_string_val(ctx, jsthis, &str);
+    hres = get_string_val(ctx, vthis, &str);
     if(FAILED(hres))
         return hres;
 
@@ -1423,35 +1422,35 @@ static HRESULT to_lower_case(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r)
     return S_OK;
 }
 
-static HRESULT String_toLowerCase(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_toLowerCase(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     TRACE("\n");
-    return to_lower_case(ctx, jsthis, r);
+    return to_lower_case(ctx, vthis, r);
 }
 
-static HRESULT String_toUpperCase(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_toUpperCase(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     TRACE("\n");
-    return to_upper_case(ctx, jsthis, r);
+    return to_upper_case(ctx, vthis, r);
 }
 
-static HRESULT String_toLocaleLowerCase(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_toLocaleLowerCase(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     TRACE("\n");
-    return to_lower_case(ctx, jsthis, r);
+    return to_lower_case(ctx, vthis, r);
 }
 
-static HRESULT String_toLocaleUpperCase(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_toLocaleUpperCase(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     TRACE("\n");
-    return to_upper_case(ctx, jsthis, r);
+    return to_upper_case(ctx, vthis, r);
 }
 
-static HRESULT String_trim(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc,
+static HRESULT String_trim(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc,
         jsval_t *argv, jsval_t *r)
 {
     const WCHAR *str, *begin, *end;
@@ -1459,7 +1458,10 @@ static HRESULT String_trim(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsig
     unsigned len;
     HRESULT hres;
 
-    hres = to_flat_string(ctx, jsval_disp(jsthis->u.disp), &jsstr, &str);
+    if(is_undefined(vthis) || is_null(vthis))
+        return JS_E_OBJECT_EXPECTED;
+
+    hres = to_flat_string(ctx, vthis, &jsstr, &str);
     if(FAILED(hres)) {
         WARN("to_flat_string failed: %08lx\n", hres);
         return hres;
@@ -1486,7 +1488,7 @@ static HRESULT String_trim(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsig
     return hres;
 }
 
-static HRESULT String_localeCompare(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT String_localeCompare(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     FIXME("\n");
@@ -1592,7 +1594,7 @@ static const builtin_info_t StringInst_info = {
 };
 
 /* ECMA-262 3rd Edition    15.5.3.2 */
-static HRESULT StringConstr_fromCharCode(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+static HRESULT StringConstr_fromCharCode(script_ctx_t *ctx, jsval_t vthis, WORD flags,
         unsigned argc, jsval_t *argv, jsval_t *r)
 {
     WCHAR *ret_str;
@@ -1623,7 +1625,7 @@ static HRESULT StringConstr_fromCharCode(script_ctx_t *ctx, vdisp_t *jsthis, WOR
     return S_OK;
 }
 
-static HRESULT StringConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT StringConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     HRESULT hres;
diff --git a/dlls/jscript/vbarray.c b/dlls/jscript/vbarray.c
index 74b9a29..881c45e 100644
--- a/dlls/jscript/vbarray.c
+++ b/dlls/jscript/vbarray.c
@@ -33,17 +33,13 @@ static inline VBArrayInstance *vbarray_from_jsdisp(jsdisp_t *jsdisp)
     return CONTAINING_RECORD(jsdisp, VBArrayInstance, dispex);
 }
 
-static inline VBArrayInstance *vbarray_from_vdisp(vdisp_t *vdisp)
+static inline VBArrayInstance *vbarray_this(jsval_t vthis)
 {
-    return vbarray_from_jsdisp(vdisp->u.jsdisp);
+    jsdisp_t *jsdisp = is_object_instance(vthis) ? to_jsdisp(get_object(vthis)) : NULL;
+    return (jsdisp && is_class(jsdisp, JSCLASS_VBARRAY)) ? vbarray_from_jsdisp(jsdisp) : NULL;
 }
 
-static inline VBArrayInstance *vbarray_this(vdisp_t *jsthis)
-{
-    return is_vclass(jsthis, JSCLASS_VBARRAY) ? vbarray_from_vdisp(jsthis) : NULL;
-}
-
-static HRESULT VBArray_dimensions(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT VBArray_dimensions(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     VBArrayInstance *vbarray;
@@ -59,7 +55,7 @@ static HRESULT VBArray_dimensions(script_ctx_t *ctx, vdisp_t *vthis, WORD flags,
     return S_OK;
 }
 
-static HRESULT VBArray_getItem(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT VBArray_getItem(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     VBArrayInstance *vbarray;
@@ -103,7 +99,7 @@ static HRESULT VBArray_getItem(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, un
     return hres;
 }
 
-static HRESULT VBArray_lbound(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT VBArray_lbound(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     VBArrayInstance *vbarray;
@@ -134,7 +130,7 @@ static HRESULT VBArray_lbound(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, uns
     return S_OK;
 }
 
-static HRESULT VBArray_toArray(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT VBArray_toArray(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     VBArrayInstance *vbarray;
@@ -189,7 +185,7 @@ static HRESULT VBArray_toArray(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, un
     return S_OK;
 }
 
-static HRESULT VBArray_ubound(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT VBArray_ubound(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     VBArrayInstance *vbarray;
@@ -220,7 +216,7 @@ static HRESULT VBArray_ubound(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, uns
     return S_OK;
 }
 
-static HRESULT VBArray_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT VBArray_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     FIXME("\n");
@@ -282,7 +278,7 @@ static HRESULT alloc_vbarray(script_ctx_t *ctx, jsdisp_t *object_prototype, VBAr
     return S_OK;
 }
 
-static HRESULT VBArrayConstr_value(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
+static HRESULT VBArrayConstr_value(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
     VBArrayInstance *vbarray;
-- 
2.34.1




More information about the wine-devel mailing list