jscript: Inherit Function_valueOf from Object.
This commit is contained in:
parent
91ce0dd6a3
commit
42f9608269
|
@ -41,7 +41,6 @@ static const WCHAR prototypeW[] = {'p','r','o','t','o','t', 'y', 'p','e',0};
|
||||||
static const WCHAR lengthW[] = {'l','e','n','g','t','h',0};
|
static const WCHAR lengthW[] = {'l','e','n','g','t','h',0};
|
||||||
static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
|
static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
|
||||||
static const WCHAR toLocaleStringW[] = {'t','o','L','o','c','a','l','e','S','t','r','i','n','g',0};
|
static const WCHAR toLocaleStringW[] = {'t','o','L','o','c','a','l','e','S','t','r','i','n','g',0};
|
||||||
static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0};
|
|
||||||
static const WCHAR applyW[] = {'a','p','p','l','y',0};
|
static const WCHAR applyW[] = {'a','p','p','l','y',0};
|
||||||
static const WCHAR callW[] = {'c','a','l','l',0};
|
static const WCHAR callW[] = {'c','a','l','l',0};
|
||||||
static const WCHAR hasOwnPropertyW[] = {'h','a','s','O','w','n','P','r','o','p','e','r','t','y',0};
|
static const WCHAR hasOwnPropertyW[] = {'h','a','s','O','w','n','P','r','o','p','e','r','t','y',0};
|
||||||
|
@ -299,21 +298,6 @@ static HRESULT Function_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT Function_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
|
||||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
|
||||||
{
|
|
||||||
WARN("should be inherited from Object\n");
|
|
||||||
|
|
||||||
if(retv) {
|
|
||||||
IDispatchEx_AddRef(_IDispatchEx_(dispex));
|
|
||||||
|
|
||||||
V_VT(retv) = VT_DISPATCH;
|
|
||||||
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(dispex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT Function_apply(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
static HRESULT Function_apply(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
||||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||||
{
|
{
|
||||||
|
@ -416,8 +400,7 @@ static const builtin_prop_t Function_props[] = {
|
||||||
{lengthW, Function_length, 0},
|
{lengthW, Function_length, 0},
|
||||||
{propertyIsEnumerableW, Function_propertyIsEnumerable, PROPF_METHOD},
|
{propertyIsEnumerableW, Function_propertyIsEnumerable, PROPF_METHOD},
|
||||||
{toLocaleStringW, Function_toLocaleString, PROPF_METHOD},
|
{toLocaleStringW, Function_toLocaleString, PROPF_METHOD},
|
||||||
{toStringW, Function_toString, PROPF_METHOD},
|
{toStringW, Function_toString, PROPF_METHOD}
|
||||||
{valueOfW, Function_valueOf, PROPF_METHOD}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const builtin_info_t Function_info = {
|
static const builtin_info_t Function_info = {
|
||||||
|
@ -465,35 +448,38 @@ static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_
|
||||||
function->flags = flags;
|
function->flags = flags;
|
||||||
function->length = flags & PROPF_ARGMASK;
|
function->length = flags & PROPF_ARGMASK;
|
||||||
|
|
||||||
if(prototype) {
|
|
||||||
jsexcept_t jsexcept;
|
|
||||||
VARIANT var;
|
|
||||||
|
|
||||||
V_VT(&var) = VT_DISPATCH;
|
|
||||||
V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(prototype);
|
|
||||||
memset(&jsexcept, 0, sizeof(jsexcept));
|
|
||||||
|
|
||||||
hres = jsdisp_propput_name(&function->dispex, prototypeW, ctx->lcid, &var, &jsexcept, NULL/*FIXME*/);
|
|
||||||
if(FAILED(hres)) {
|
|
||||||
IDispatchEx_Release(_IDispatchEx_(&function->dispex));
|
|
||||||
return hres;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*ret = function;
|
*ret = function;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT set_prototype(script_ctx_t *ctx, DispatchEx *dispex, DispatchEx *prototype)
|
||||||
|
{
|
||||||
|
jsexcept_t jsexcept;
|
||||||
|
VARIANT var;
|
||||||
|
|
||||||
|
V_VT(&var) = VT_DISPATCH;
|
||||||
|
V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(prototype);
|
||||||
|
memset(&jsexcept, 0, sizeof(jsexcept));
|
||||||
|
|
||||||
|
return jsdisp_propput_name(dispex, prototypeW, ctx->lcid, &var, &jsexcept, NULL/*FIXME*/);
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT create_builtin_function(script_ctx_t *ctx, builtin_invoke_t value_proc,
|
HRESULT create_builtin_function(script_ctx_t *ctx, builtin_invoke_t value_proc,
|
||||||
const builtin_info_t *builtin_info, DWORD flags, DispatchEx *prototype, DispatchEx **ret)
|
const builtin_info_t *builtin_info, DWORD flags, DispatchEx *prototype, DispatchEx **ret)
|
||||||
{
|
{
|
||||||
FunctionInstance *function;
|
FunctionInstance *function;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
hres = create_function(ctx, builtin_info, flags, FALSE, prototype, &function);
|
hres = create_function(ctx, builtin_info, flags, FALSE, NULL, &function);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
|
hres = set_prototype(ctx, &function->dispex, prototype);
|
||||||
|
if(FAILED(hres)) {
|
||||||
|
jsdisp_release(&function->dispex);
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
|
||||||
function->value_proc = value_proc;
|
function->value_proc = value_proc;
|
||||||
|
|
||||||
*ret = &function->dispex;
|
*ret = &function->dispex;
|
||||||
|
@ -513,7 +499,12 @@ HRESULT create_source_function(parser_ctx_t *ctx, parameter_t *parameters, sourc
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = create_function(ctx->script, NULL, PROPF_CONSTR, FALSE, prototype, &function);
|
hres = create_function(ctx->script, NULL, PROPF_CONSTR, FALSE, NULL, &function);
|
||||||
|
if(SUCCEEDED(hres)) {
|
||||||
|
hres = set_prototype(ctx->script, &function->dispex, prototype);
|
||||||
|
if(FAILED(hres))
|
||||||
|
jsdisp_release(&function->dispex);
|
||||||
|
}
|
||||||
jsdisp_release(prototype);
|
jsdisp_release(prototype);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -540,23 +531,28 @@ HRESULT create_source_function(parser_ctx_t *ctx, parameter_t *parameters, sourc
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT init_function_constr(script_ctx_t *ctx)
|
HRESULT init_function_constr(script_ctx_t *ctx, DispatchEx *object_prototype)
|
||||||
{
|
{
|
||||||
FunctionInstance *prot, *constr;
|
FunctionInstance *prot, *constr;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
hres = create_function(ctx, NULL, PROPF_CONSTR, TRUE, NULL, &prot);
|
hres = create_function(ctx, NULL, PROPF_CONSTR, TRUE, object_prototype, &prot);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
prot->value_proc = FunctionProt_value;
|
prot->value_proc = FunctionProt_value;
|
||||||
|
|
||||||
hres = create_function(ctx, NULL, PROPF_CONSTR, TRUE, &prot->dispex, &constr);
|
hres = create_function(ctx, NULL, PROPF_CONSTR, TRUE, &prot->dispex, &constr);
|
||||||
|
if(SUCCEEDED(hres)) {
|
||||||
|
constr->value_proc = FunctionConstr_value;
|
||||||
|
hres = set_prototype(ctx, &constr->dispex, &prot->dispex);
|
||||||
|
if(FAILED(hres))
|
||||||
|
jsdisp_release(&constr->dispex);
|
||||||
|
}
|
||||||
jsdisp_release(&prot->dispex);
|
jsdisp_release(&prot->dispex);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
constr->value_proc = FunctionConstr_value;
|
|
||||||
ctx->function_constr = &constr->dispex;
|
ctx->function_constr = &constr->dispex;
|
||||||
return hres;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -574,15 +574,15 @@ static const builtin_info_t JSGlobal_info = {
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static HRESULT init_constructors(script_ctx_t *ctx)
|
static HRESULT init_constructors(script_ctx_t *ctx, DispatchEx *object_prototype)
|
||||||
{
|
{
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
hres = init_function_constr(ctx);
|
hres = init_function_constr(ctx, object_prototype);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = create_object_constr(ctx, &ctx->object_constr);
|
hres = create_object_constr(ctx, object_prototype, &ctx->object_constr);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
|
@ -615,14 +615,19 @@ static HRESULT init_constructors(script_ctx_t *ctx)
|
||||||
|
|
||||||
HRESULT init_global(script_ctx_t *ctx)
|
HRESULT init_global(script_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
DispatchEx *math;
|
DispatchEx *math, *object_prototype;
|
||||||
VARIANT var;
|
VARIANT var;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
if(ctx->global)
|
if(ctx->global)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
hres = init_constructors(ctx);
|
hres = create_object_prototype(ctx, &object_prototype);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
hres = init_constructors(ctx, object_prototype);
|
||||||
|
jsdisp_release(object_prototype);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
|
|
|
@ -200,13 +200,14 @@ static inline void script_addref(script_ctx_t *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT init_global(script_ctx_t*);
|
HRESULT init_global(script_ctx_t*);
|
||||||
HRESULT init_function_constr(script_ctx_t*);
|
HRESULT init_function_constr(script_ctx_t*,DispatchEx*);
|
||||||
|
HRESULT create_object_prototype(script_ctx_t*,DispatchEx**);
|
||||||
|
|
||||||
HRESULT create_array_constr(script_ctx_t*,DispatchEx**);
|
HRESULT create_array_constr(script_ctx_t*,DispatchEx**);
|
||||||
HRESULT create_bool_constr(script_ctx_t*,DispatchEx**);
|
HRESULT create_bool_constr(script_ctx_t*,DispatchEx**);
|
||||||
HRESULT create_date_constr(script_ctx_t*,DispatchEx**);
|
HRESULT create_date_constr(script_ctx_t*,DispatchEx**);
|
||||||
HRESULT create_number_constr(script_ctx_t*,DispatchEx**);
|
HRESULT create_number_constr(script_ctx_t*,DispatchEx**);
|
||||||
HRESULT create_object_constr(script_ctx_t*,DispatchEx**);
|
HRESULT create_object_constr(script_ctx_t*,DispatchEx*,DispatchEx**);
|
||||||
HRESULT create_regexp_constr(script_ctx_t*,DispatchEx**);
|
HRESULT create_regexp_constr(script_ctx_t*,DispatchEx**);
|
||||||
HRESULT create_string_constr(script_ctx_t*,DispatchEx**);
|
HRESULT create_string_constr(script_ctx_t*,DispatchEx**);
|
||||||
|
|
||||||
|
|
|
@ -161,19 +161,15 @@ static HRESULT ObjectConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DIS
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT create_object_constr(script_ctx_t *ctx, DispatchEx **ret)
|
HRESULT create_object_constr(script_ctx_t *ctx, DispatchEx *object_prototype, DispatchEx **ret)
|
||||||
{
|
{
|
||||||
DispatchEx *object;
|
return create_builtin_function(ctx, ObjectConstr_value, NULL, PROPF_CONSTR,
|
||||||
HRESULT hres;
|
object_prototype, ret);
|
||||||
|
}
|
||||||
|
|
||||||
hres = create_dispex(ctx, &Object_info, NULL, &object);
|
HRESULT create_object_prototype(script_ctx_t *ctx, DispatchEx **ret)
|
||||||
if(FAILED(hres))
|
{
|
||||||
return hres;
|
return create_dispex(ctx, &Object_info, NULL, ret);
|
||||||
|
|
||||||
hres = create_builtin_function(ctx, ObjectConstr_value, NULL, PROPF_CONSTR, object, ret);
|
|
||||||
|
|
||||||
jsdisp_release(object);
|
|
||||||
return hres;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT create_object(script_ctx_t *ctx, DispatchEx *constr, DispatchEx **ret)
|
HRESULT create_object(script_ctx_t *ctx, DispatchEx *constr, DispatchEx **ret)
|
||||||
|
|
|
@ -972,16 +972,18 @@ ok(isNaN(tmp), "Math.tan(-Infinity) is not NaN");
|
||||||
var func = function (a) {
|
var func = function (a) {
|
||||||
var a = 1;
|
var a = 1;
|
||||||
if(a) return;
|
if(a) return;
|
||||||
}.toString();
|
};
|
||||||
ok(func.toString() === "function (a) {\n var a = 1;\n if(a) return;\n }",
|
ok(func.toString() === "function (a) {\n var a = 1;\n if(a) return;\n }",
|
||||||
"func.toString() = " + func.toString());
|
"func.toString() = " + func.toString());
|
||||||
ok("" + func === "function (a) {\n var a = 1;\n if(a) return;\n }",
|
ok("" + func === "function (a) {\n var a = 1;\n if(a) return;\n }",
|
||||||
"'' + func.toString() = " + func);
|
"'' + func.toString() = " + func);
|
||||||
|
|
||||||
|
ok(func.valueOf === Object.prototype.valueOf, "func.valueOf !== Object.prototype.valueOf");
|
||||||
|
ok(func === func.valueOf(), "func !== func.valueOf()");
|
||||||
|
|
||||||
function testFuncToString(x,y) {
|
function testFuncToString(x,y) {
|
||||||
return x+y;
|
return x+y;
|
||||||
}
|
}
|
||||||
|
|
||||||
ok(testFuncToString.toString() === "function testFuncToString(x,y) {\n return x+y;\n}",
|
ok(testFuncToString.toString() === "function testFuncToString(x,y) {\n return x+y;\n}",
|
||||||
"testFuncToString.toString() = " + testFuncToString.toString());
|
"testFuncToString.toString() = " + testFuncToString.toString());
|
||||||
ok("" + testFuncToString === "function testFuncToString(x,y) {\n return x+y;\n}",
|
ok("" + testFuncToString === "function testFuncToString(x,y) {\n return x+y;\n}",
|
||||||
|
|
|
@ -84,7 +84,7 @@ ok(RegExp.prototype !== undefined, "RegExp.prototype is undefined");
|
||||||
ok(Math !== undefined, "Math is undefined");
|
ok(Math !== undefined, "Math is undefined");
|
||||||
ok(Math.prototype === undefined, "Math.prototype is not undefined");
|
ok(Math.prototype === undefined, "Math.prototype is not undefined");
|
||||||
ok(Function.prototype !== undefined, "Function.prototype is undefined");
|
ok(Function.prototype !== undefined, "Function.prototype is undefined");
|
||||||
ok(Function.prototype.prototype === undefined, "Function.prototype is not undefined");
|
ok(Function.prototype.prototype === undefined, "Function.prototype.prototype is not undefined");
|
||||||
ok(Date.prototype !== undefined, "Date.prototype is undefined");
|
ok(Date.prototype !== undefined, "Date.prototype is undefined");
|
||||||
ok(Date.prototype.prototype === undefined, "Date.prototype is not undefined");
|
ok(Date.prototype.prototype === undefined, "Date.prototype is not undefined");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue