jscript: Added support for host objects being part of scope chain.
This commit is contained in:
parent
fdbd536983
commit
8c5f5b49ec
|
@ -268,7 +268,7 @@ static void exprval_set_idref(exprval_t *val, IDispatch *disp, DISPID id)
|
||||||
IDispatch_AddRef(disp);
|
IDispatch_AddRef(disp);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT scope_push(scope_chain_t *scope, jsdisp_t *obj, scope_chain_t **ret)
|
HRESULT scope_push(scope_chain_t *scope, jsdisp_t *jsobj, IDispatch *obj, scope_chain_t **ret)
|
||||||
{
|
{
|
||||||
scope_chain_t *new_scope;
|
scope_chain_t *new_scope;
|
||||||
|
|
||||||
|
@ -278,7 +278,8 @@ HRESULT scope_push(scope_chain_t *scope, jsdisp_t *obj, scope_chain_t **ret)
|
||||||
|
|
||||||
new_scope->ref = 1;
|
new_scope->ref = 1;
|
||||||
|
|
||||||
jsdisp_addref(obj);
|
IDispatch_AddRef(obj);
|
||||||
|
new_scope->jsobj = jsobj;
|
||||||
new_scope->obj = obj;
|
new_scope->obj = obj;
|
||||||
|
|
||||||
if(scope) {
|
if(scope) {
|
||||||
|
@ -309,7 +310,7 @@ void scope_release(scope_chain_t *scope)
|
||||||
if(scope->next)
|
if(scope->next)
|
||||||
scope_release(scope->next);
|
scope_release(scope->next);
|
||||||
|
|
||||||
jsdisp_release(scope->obj);
|
IDispatch_Release(scope->obj);
|
||||||
heap_free(scope);
|
heap_free(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,9 +512,12 @@ static HRESULT identifier_eval(script_ctx_t *ctx, BSTR identifier, exprval_t *re
|
||||||
TRACE("%s\n", debugstr_w(identifier));
|
TRACE("%s\n", debugstr_w(identifier));
|
||||||
|
|
||||||
for(scope = ctx->exec_ctx->scope_chain; scope; scope = scope->next) {
|
for(scope = ctx->exec_ctx->scope_chain; scope; scope = scope->next) {
|
||||||
hres = jsdisp_get_id(scope->obj, identifier, 0, &id);
|
if(scope->jsobj)
|
||||||
|
hres = jsdisp_get_id(scope->jsobj, identifier, fdexNameImplicit, &id);
|
||||||
|
else
|
||||||
|
hres = disp_get_id(ctx, scope->obj, identifier, fdexNameImplicit, &id);
|
||||||
if(SUCCEEDED(hres)) {
|
if(SUCCEEDED(hres)) {
|
||||||
exprval_set_idref(ret, to_disp(scope->obj), id);
|
exprval_set_idref(ret, scope->obj, id);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -668,7 +672,6 @@ static HRESULT interp_forin(exec_ctx_t *ctx)
|
||||||
static HRESULT interp_push_scope(exec_ctx_t *ctx)
|
static HRESULT interp_push_scope(exec_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
IDispatch *disp;
|
IDispatch *disp;
|
||||||
jsdisp_t *obj;
|
|
||||||
VARIANT *v;
|
VARIANT *v;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
|
@ -680,15 +683,8 @@ static HRESULT interp_push_scope(exec_ctx_t *ctx)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
obj = to_jsdisp(disp);
|
hres = scope_push(ctx->scope_chain, to_jsdisp(disp), disp, &ctx->scope_chain);
|
||||||
if(!obj) {
|
IDispatch_Release(disp);
|
||||||
IDispatch_Release(disp);
|
|
||||||
FIXME("disp is not jsdisp\n");
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
hres = scope_push(ctx->scope_chain, obj, &ctx->scope_chain);
|
|
||||||
jsdisp_release(obj);
|
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2509,7 +2505,7 @@ static HRESULT unwind_exception(exec_ctx_t *ctx)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = scope_push(ctx->scope_chain, scope_obj, &ctx->scope_chain);
|
hres = scope_push(ctx->scope_chain, scope_obj, to_disp(scope_obj), &ctx->scope_chain);
|
||||||
jsdisp_release(scope_obj);
|
jsdisp_release(scope_obj);
|
||||||
}else {
|
}else {
|
||||||
VARIANT v;
|
VARIANT v;
|
||||||
|
|
|
@ -203,11 +203,12 @@ static inline void *parser_alloc_tmp(parser_ctx_t *ctx, DWORD size)
|
||||||
|
|
||||||
typedef struct _scope_chain_t {
|
typedef struct _scope_chain_t {
|
||||||
LONG ref;
|
LONG ref;
|
||||||
jsdisp_t *obj;
|
jsdisp_t *jsobj;
|
||||||
|
IDispatch *obj;
|
||||||
struct _scope_chain_t *next;
|
struct _scope_chain_t *next;
|
||||||
} scope_chain_t;
|
} scope_chain_t;
|
||||||
|
|
||||||
HRESULT scope_push(scope_chain_t*,jsdisp_t*,scope_chain_t**) DECLSPEC_HIDDEN;
|
HRESULT scope_push(scope_chain_t*,jsdisp_t*,IDispatch*,scope_chain_t**) DECLSPEC_HIDDEN;
|
||||||
void scope_release(scope_chain_t*) DECLSPEC_HIDDEN;
|
void scope_release(scope_chain_t*) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
static inline void scope_addref(scope_chain_t *scope)
|
static inline void scope_addref(scope_chain_t *scope)
|
||||||
|
|
|
@ -182,7 +182,7 @@ static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDis
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
hres = scope_push(function->scope_chain, var_disp, &scope);
|
hres = scope_push(function->scope_chain, var_disp, to_disp(var_disp), &scope);
|
||||||
if(SUCCEEDED(hres)) {
|
if(SUCCEEDED(hres)) {
|
||||||
hres = create_exec_ctx(ctx, this_obj, var_disp, scope, FALSE, &exec_ctx);
|
hres = create_exec_ctx(ctx, this_obj, var_disp, scope, FALSE, &exec_ctx);
|
||||||
scope_release(scope);
|
scope_release(scope);
|
||||||
|
|
|
@ -88,6 +88,8 @@ DEFINE_EXPECT(puredisp_noprop_d);
|
||||||
DEFINE_EXPECT(testobj_delete);
|
DEFINE_EXPECT(testobj_delete);
|
||||||
DEFINE_EXPECT(testobj_value);
|
DEFINE_EXPECT(testobj_value);
|
||||||
DEFINE_EXPECT(testobj_prop_d);
|
DEFINE_EXPECT(testobj_prop_d);
|
||||||
|
DEFINE_EXPECT(testobj_withprop_d);
|
||||||
|
DEFINE_EXPECT(testobj_withprop_i);
|
||||||
DEFINE_EXPECT(testobj_noprop_d);
|
DEFINE_EXPECT(testobj_noprop_d);
|
||||||
DEFINE_EXPECT(testobj_onlydispid_d);
|
DEFINE_EXPECT(testobj_onlydispid_d);
|
||||||
DEFINE_EXPECT(testobj_onlydispid_i);
|
DEFINE_EXPECT(testobj_onlydispid_i);
|
||||||
|
@ -124,6 +126,7 @@ DEFINE_EXPECT(DeleteMemberByDispID);
|
||||||
|
|
||||||
#define DISPID_TESTOBJ_PROP 0x2000
|
#define DISPID_TESTOBJ_PROP 0x2000
|
||||||
#define DISPID_TESTOBJ_ONLYDISPID 0x2001
|
#define DISPID_TESTOBJ_ONLYDISPID 0x2001
|
||||||
|
#define DISPID_TESTOBJ_WITHPROP 0x2002
|
||||||
|
|
||||||
#define JS_E_INVALID_CHAR 0x800a03f6
|
#define JS_E_INVALID_CHAR 0x800a03f6
|
||||||
|
|
||||||
|
@ -297,6 +300,12 @@ static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD
|
||||||
*pid = DISPID_TESTOBJ_PROP;
|
*pid = DISPID_TESTOBJ_PROP;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
if(!strcmp_wa(bstrName, "withProp")) {
|
||||||
|
CHECK_EXPECT(testobj_withprop_d);
|
||||||
|
test_grfdex(grfdex, fdexNameCaseSensitive|fdexNameImplicit);
|
||||||
|
*pid = DISPID_TESTOBJ_WITHPROP;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
if(!strcmp_wa(bstrName, "noprop")) {
|
if(!strcmp_wa(bstrName, "noprop")) {
|
||||||
CHECK_EXPECT(testobj_noprop_d);
|
CHECK_EXPECT(testobj_noprop_d);
|
||||||
test_grfdex(grfdex, fdexNameCaseSensitive);
|
test_grfdex(grfdex, fdexNameCaseSensitive);
|
||||||
|
@ -360,6 +369,23 @@ static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
|
||||||
ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
|
ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
|
||||||
ok(pei != NULL, "pei == NULL\n");
|
ok(pei != NULL, "pei == NULL\n");
|
||||||
return DISP_E_MEMBERNOTFOUND;
|
return DISP_E_MEMBERNOTFOUND;
|
||||||
|
case DISPID_TESTOBJ_WITHPROP:
|
||||||
|
CHECK_EXPECT(testobj_withprop_i);
|
||||||
|
|
||||||
|
ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
|
||||||
|
ok(pdp != NULL, "pdp == NULL\n");
|
||||||
|
ok(!pdp->rgvarg, "rgvarg != NULL\n");
|
||||||
|
ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
|
||||||
|
ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
|
||||||
|
ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
|
||||||
|
ok(pvarRes != NULL, "pvarRes == NULL\n");
|
||||||
|
ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes));
|
||||||
|
ok(pei != NULL, "pei == NULL\n");
|
||||||
|
|
||||||
|
V_VT(pvarRes) = VT_I4;
|
||||||
|
V_I4(pvarRes) = 1;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ok(0, "unexpected call %x\n", id);
|
ok(0, "unexpected call %x\n", id);
|
||||||
|
@ -1754,6 +1780,12 @@ static BOOL run_tests(void)
|
||||||
"});");
|
"});");
|
||||||
CHECK_CALLED(global_testargtypes_i);
|
CHECK_CALLED(global_testargtypes_i);
|
||||||
|
|
||||||
|
SET_EXPECT(testobj_withprop_d);
|
||||||
|
SET_EXPECT(testobj_withprop_i);
|
||||||
|
parse_script_a("var t = (function () { with(testObj) { return withProp; }})(); ok(t === 1, 't = ' + t);");
|
||||||
|
CHECK_CALLED(testobj_withprop_d);
|
||||||
|
CHECK_CALLED(testobj_withprop_i);
|
||||||
|
|
||||||
run_from_res("lang.js");
|
run_from_res("lang.js");
|
||||||
run_from_res("api.js");
|
run_from_res("api.js");
|
||||||
run_from_res("regexp.js");
|
run_from_res("regexp.js");
|
||||||
|
|
Loading…
Reference in New Issue