jscript: Support replacer argument in JSON.stringify.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
6a58d990e7
commit
34a9c34380
|
@ -320,6 +320,8 @@ typedef struct {
|
|||
size_t stack_size;
|
||||
|
||||
WCHAR gap[11]; /* according to the spec, it's no longer than 10 chars */
|
||||
|
||||
jsdisp_t *replacer;
|
||||
} stringify_ctx_t;
|
||||
|
||||
static BOOL stringify_push_obj(stringify_ctx_t *ctx, jsdisp_t *obj)
|
||||
|
@ -656,7 +658,22 @@ static HRESULT stringify(stringify_ctx_t *ctx, jsdisp_t *object, const WCHAR *na
|
|||
FIXME("Use toJSON.\n");
|
||||
}
|
||||
|
||||
/* FIXME: Support replacer replacer. */
|
||||
if(ctx->replacer) {
|
||||
jsstr_t *name_str;
|
||||
jsval_t args[2];
|
||||
if(!(name_str = jsstr_alloc(name))) {
|
||||
jsval_release(value);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
args[0] = jsval_string(name_str);
|
||||
args[1] = value;
|
||||
hres = jsdisp_call_value(ctx->replacer, to_disp(object), DISPATCH_METHOD, ARRAY_SIZE(args), args, &v);
|
||||
jsstr_release(name_str);
|
||||
jsval_release(value);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
value = v;
|
||||
}
|
||||
|
||||
v = value;
|
||||
hres = maybe_to_primitive(ctx->ctx, v, &value);
|
||||
|
@ -736,8 +753,8 @@ 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)
|
||||
{
|
||||
stringify_ctx_t stringify_ctx = {ctx, NULL,0,0, NULL,0,0, {0}};
|
||||
jsdisp_t *obj;
|
||||
stringify_ctx_t stringify_ctx = { ctx };
|
||||
jsdisp_t *obj = NULL, *replacer;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
@ -748,17 +765,22 @@ static HRESULT JSON_stringify(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
if(argc >= 2 && is_object_instance(argv[1])) {
|
||||
FIXME("Replacer %s not yet supported\n", debugstr_jsval(argv[1]));
|
||||
if(argc >= 2 && is_object_instance(argv[1]) && get_object(argv[1]) &&
|
||||
(replacer = to_jsdisp(get_object(argv[1])))) {
|
||||
if(is_callable(replacer)) {
|
||||
stringify_ctx.replacer = jsdisp_addref(replacer);
|
||||
}else if(is_class(replacer, JSCLASS_ARRAY)) {
|
||||
FIXME("Array replacer not yet supported\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
}
|
||||
|
||||
if(argc >= 3) {
|
||||
jsval_t space_val;
|
||||
|
||||
hres = maybe_to_primitive(ctx, argv[2], &space_val);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
goto fail;
|
||||
|
||||
if(is_number(space_val)) {
|
||||
double n = get_number(space_val);
|
||||
|
@ -805,6 +827,8 @@ static HRESULT JSON_stringify(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
|
|||
fail:
|
||||
if(obj)
|
||||
jsdisp_release(obj);
|
||||
if(stringify_ctx.replacer)
|
||||
jsdisp_release(stringify_ctx.replacer);
|
||||
heap_free(stringify_ctx.buf);
|
||||
heap_free(stringify_ctx.stack);
|
||||
return hres;
|
||||
|
|
|
@ -1923,7 +1923,7 @@ ok(isNaN(tmp), "Math.tan(-Infinity) is not NaN");
|
|||
[[NaN], "null"],
|
||||
[[Infinity], "null"],
|
||||
[[-Infinity], "null"],
|
||||
[[{prop1: true, prop2: "string"}], "{\"prop1\":true,\"prop2\":\"string\"}"],
|
||||
[[{prop1: true, prop2: "string", func1: function() {}}], "{\"prop1\":true,\"prop2\":\"string\"}"],
|
||||
[[{prop1: true, prop2: testObj, prop3: undefined}], "{\"prop1\":true}"],
|
||||
[[{prop1: true, prop2: {prop: "string"}},undefined," "],
|
||||
"{\n \"prop1\": true,\n \"prop2\": {\n \"prop\": \"string\"\n }\n}"],
|
||||
|
@ -1951,6 +1951,25 @@ ok(isNaN(tmp), "Math.tan(-Infinity) is not NaN");
|
|||
ok(s === undefined || s === "undefined" /* broken on some old versions */,
|
||||
"stringify(undefined) returned " + s + " expected undefined");
|
||||
|
||||
s = JSON.stringify(1, function(name, value) {
|
||||
ok(name === "", "name = " + name);
|
||||
ok(value === 1, "value = " + value);
|
||||
ok(this[name] === value, "this[" + name + "] = " + this[name] + " expected " + value);
|
||||
return 2;
|
||||
});
|
||||
ok(s == "2", "s = " + s);
|
||||
|
||||
var o = { prop: 1 };
|
||||
s = JSON.stringify(1, function(name, value) {
|
||||
ok(name === "" || name === "prop", "name = " + name);
|
||||
ok(value === 1 || value === true, "value = " + value);
|
||||
ok(this[name] === value, "this[" + name + "] = " + this[name] + " expected " + value);
|
||||
if(name === "") return o;
|
||||
ok(this === o, "this != o");
|
||||
return value;
|
||||
});
|
||||
ok(s == "{\"prop\":1}", "s = " + s);
|
||||
|
||||
var parse_tests = [
|
||||
["true", true],
|
||||
[" \nnull ", null],
|
||||
|
|
Loading…
Reference in New Issue