mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-07 08:27:54 +00:00
jscript: Handle detached scope objects 'this' in all calls.
Not just for interpreted functions. Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com> Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
bb791a7dd0
commit
5007c4d72f
|
@ -314,9 +314,13 @@ static HRESULT exprval_propget(script_ctx_t *ctx, exprval_t *ref, jsval_t *r)
|
||||||
|
|
||||||
static HRESULT exprval_call(script_ctx_t *ctx, exprval_t *ref, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
|
static HRESULT exprval_call(script_ctx_t *ctx, exprval_t *ref, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
|
||||||
{
|
{
|
||||||
|
jsdisp_t *jsdisp;
|
||||||
|
HRESULT hres;
|
||||||
|
jsval_t v;
|
||||||
|
|
||||||
switch(ref->type) {
|
switch(ref->type) {
|
||||||
case EXPRVAL_STACK_REF: {
|
case EXPRVAL_STACK_REF: {
|
||||||
jsval_t v = ctx->stack[ref->u.off];
|
v = ctx->stack[ref->u.off];
|
||||||
|
|
||||||
if(!is_object_instance(v)) {
|
if(!is_object_instance(v)) {
|
||||||
FIXME("invoke %s\n", debugstr_jsval(v));
|
FIXME("invoke %s\n", debugstr_jsval(v));
|
||||||
|
@ -326,10 +330,24 @@ static HRESULT exprval_call(script_ctx_t *ctx, exprval_t *ref, WORD flags, unsig
|
||||||
return disp_call_value(ctx, get_object(v), NULL, flags, argc, argv, r);
|
return disp_call_value(ctx, get_object(v), NULL, flags, argc, argv, r);
|
||||||
}
|
}
|
||||||
case EXPRVAL_IDREF:
|
case EXPRVAL_IDREF:
|
||||||
|
/* ECMA-262 3rd Edition 11.2.3.7 / ECMA-262 5.1 Edition 11.2.3.6 *
|
||||||
|
* Don't treat scope object props as PropertyReferences. */
|
||||||
|
if((jsdisp = to_jsdisp(ref->u.idref.disp)) && jsdisp->builtin_info->class == JSCLASS_NONE) {
|
||||||
|
hres = disp_propget(ctx, ref->u.idref.disp, ref->u.idref.id, &v);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
if(!is_object_instance(v)) {
|
||||||
|
FIXME("invoke %s\n", debugstr_jsval(v));
|
||||||
|
hres = E_FAIL;
|
||||||
|
}else {
|
||||||
|
hres = disp_call_value(ctx, get_object(v), NULL, flags, argc, argv, r);
|
||||||
|
}
|
||||||
|
jsval_release(v);
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
return disp_call(ctx, ref->u.idref.disp, ref->u.idref.id, flags, argc, argv, r);
|
return disp_call(ctx, ref->u.idref.disp, ref->u.idref.id, flags, argc, argv, r);
|
||||||
case EXPRVAL_JSVAL: {
|
case EXPRVAL_JSVAL: {
|
||||||
IDispatch *obj;
|
IDispatch *obj;
|
||||||
HRESULT hres;
|
|
||||||
|
|
||||||
hres = to_object(ctx, ref->u.val, &obj);
|
hres = to_object(ctx, ref->u.val, &obj);
|
||||||
if(SUCCEEDED(hres)) {
|
if(SUCCEEDED(hres)) {
|
||||||
|
@ -3300,16 +3318,11 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ECMA-262 3rd Edition 11.2.3.7 */
|
|
||||||
if(this_obj) {
|
if(this_obj) {
|
||||||
jsdisp_t *jsthis;
|
jsdisp_t *jsthis = to_jsdisp(this_obj);
|
||||||
|
|
||||||
jsthis = iface_to_jsdisp(this_obj);
|
if(jsthis && jsthis->builtin_info->class == JSCLASS_GLOBAL)
|
||||||
if(jsthis) {
|
this_obj = NULL;
|
||||||
if(jsthis->builtin_info->class == JSCLASS_GLOBAL || jsthis->builtin_info->class == JSCLASS_NONE)
|
|
||||||
this_obj = NULL;
|
|
||||||
jsdisp_release(jsthis);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ctx->call_ctx && (flags & EXEC_EVAL)) {
|
if(ctx->call_ctx && (flags & EXEC_EVAL)) {
|
||||||
|
|
|
@ -2634,6 +2634,8 @@ testException(function() {null.toString();}, "E_OBJECT_EXPECTED");
|
||||||
testException(function() {RegExp.prototype.toString.call(new Object());}, "E_REGEXP_EXPECTED");
|
testException(function() {RegExp.prototype.toString.call(new Object());}, "E_REGEXP_EXPECTED");
|
||||||
testException(function() {/a/.lastIndex();}, "E_NOT_FUNC");
|
testException(function() {/a/.lastIndex();}, "E_NOT_FUNC");
|
||||||
testException(function() {"a".length();}, "E_NOT_FUNC");
|
testException(function() {"a".length();}, "E_NOT_FUNC");
|
||||||
|
testException(function() {((function() { var f = Number.prototype.toString; return (function() { return f(); }); })())();}, "E_NOT_NUM");
|
||||||
|
testException(function() {((function() { var f = Object.prototype.hasOwnProperty; return (function() { return f("f"); }); })())();}, "E_OBJECT_EXPECTED");
|
||||||
|
|
||||||
testException(function() { return arguments.callee(); }, "E_STACK_OVERFLOW");
|
testException(function() { return arguments.callee(); }, "E_STACK_OVERFLOW");
|
||||||
|
|
||||||
|
|
|
@ -310,6 +310,9 @@ argumentsTest();
|
||||||
ok(callAsExprTest.arguments === null, "callAsExprTest.arguments = " + callAsExprTest.arguments);
|
ok(callAsExprTest.arguments === null, "callAsExprTest.arguments = " + callAsExprTest.arguments);
|
||||||
})(1,2);
|
})(1,2);
|
||||||
|
|
||||||
|
tmp = ((function() { var f = function() {return this}; return (function() { return f(); }); })())();
|
||||||
|
ok(tmp === this, "detached scope function call this != global this");
|
||||||
|
|
||||||
tmp = (function() {1;})();
|
tmp = (function() {1;})();
|
||||||
ok(tmp === undefined, "tmp = " + tmp);
|
ok(tmp === undefined, "tmp = " + tmp);
|
||||||
tmp = eval("1;");
|
tmp = eval("1;");
|
||||||
|
|
|
@ -1791,6 +1791,26 @@ sync_test("let scope instances", function() {
|
||||||
ok(f() == 2, "f() = " + f());
|
ok(f() == 2, "f() = " + f());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
sync_test("substituted this", function() {
|
||||||
|
try {
|
||||||
|
((function() { var f = Number.prototype.toString; return (function() { return f(); }); })())();
|
||||||
|
}catch(ex) {
|
||||||
|
var n = ex.number >>> 0;
|
||||||
|
ok(n === JS_E_NUMBER_EXPECTED, "Number.toString threw " + n);
|
||||||
|
}
|
||||||
|
|
||||||
|
var r = ((function() { var f = Object.prototype.toString; return (function() { return f(); }); })())();
|
||||||
|
todo_wine.
|
||||||
|
ok(r === "[object Undefined]", "detached scope Object.toString returned " + r);
|
||||||
|
|
||||||
|
var r = (function() { this.f = Object.prototype.toString; return this.f(); })();
|
||||||
|
todo_wine.
|
||||||
|
ok(r === "[object Window]", "Object.toString returned " + r);
|
||||||
|
|
||||||
|
var r = ((function() { return (function() { return this; }); })())();
|
||||||
|
ok(r === window, "detached scope this = " + r);
|
||||||
|
});
|
||||||
|
|
||||||
sync_test("functions scope", function() {
|
sync_test("functions scope", function() {
|
||||||
function f(){ return 1; }
|
function f(){ return 1; }
|
||||||
function f(){ return 2; }
|
function f(){ return 2; }
|
||||||
|
|
Loading…
Reference in a new issue