Commit 34a9c343 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

jscript: Support replacer argument in JSON.stringify.

parent 6a58d990
...@@ -320,6 +320,8 @@ typedef struct { ...@@ -320,6 +320,8 @@ typedef struct {
size_t stack_size; size_t stack_size;
WCHAR gap[11]; /* according to the spec, it's no longer than 10 chars */ WCHAR gap[11]; /* according to the spec, it's no longer than 10 chars */
jsdisp_t *replacer;
} stringify_ctx_t; } stringify_ctx_t;
static BOOL stringify_push_obj(stringify_ctx_t *ctx, jsdisp_t *obj) 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 ...@@ -656,7 +658,22 @@ static HRESULT stringify(stringify_ctx_t *ctx, jsdisp_t *object, const WCHAR *na
FIXME("Use toJSON.\n"); 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; v = value;
hres = maybe_to_primitive(ctx->ctx, 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 ...@@ -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 */ /* 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, 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}}; stringify_ctx_t stringify_ctx = { ctx };
jsdisp_t *obj; jsdisp_t *obj = NULL, *replacer;
HRESULT hres; HRESULT hres;
TRACE("\n"); TRACE("\n");
...@@ -748,9 +765,14 @@ static HRESULT JSON_stringify(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un ...@@ -748,9 +765,14 @@ static HRESULT JSON_stringify(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
return S_OK; return S_OK;
} }
if(argc >= 2 && is_object_instance(argv[1])) { if(argc >= 2 && is_object_instance(argv[1]) && get_object(argv[1]) &&
FIXME("Replacer %s not yet supported\n", debugstr_jsval(argv[1])); (replacer = to_jsdisp(get_object(argv[1])))) {
return E_NOTIMPL; 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) { if(argc >= 3) {
...@@ -758,7 +780,7 @@ static HRESULT JSON_stringify(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un ...@@ -758,7 +780,7 @@ static HRESULT JSON_stringify(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
hres = maybe_to_primitive(ctx, argv[2], &space_val); hres = maybe_to_primitive(ctx, argv[2], &space_val);
if(FAILED(hres)) if(FAILED(hres))
return hres; goto fail;
if(is_number(space_val)) { if(is_number(space_val)) {
double n = get_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 ...@@ -805,6 +827,8 @@ static HRESULT JSON_stringify(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
fail: fail:
if(obj) if(obj)
jsdisp_release(obj); jsdisp_release(obj);
if(stringify_ctx.replacer)
jsdisp_release(stringify_ctx.replacer);
heap_free(stringify_ctx.buf); heap_free(stringify_ctx.buf);
heap_free(stringify_ctx.stack); heap_free(stringify_ctx.stack);
return hres; return hres;
......
...@@ -1923,7 +1923,7 @@ ok(isNaN(tmp), "Math.tan(-Infinity) is not NaN"); ...@@ -1923,7 +1923,7 @@ ok(isNaN(tmp), "Math.tan(-Infinity) is not NaN");
[[NaN], "null"], [[NaN], "null"],
[[Infinity], "null"], [[Infinity], "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: testObj, prop3: undefined}], "{\"prop1\":true}"],
[[{prop1: true, prop2: {prop: "string"}},undefined," "], [[{prop1: true, prop2: {prop: "string"}},undefined," "],
"{\n \"prop1\": true,\n \"prop2\": {\n \"prop\": \"string\"\n }\n}"], "{\n \"prop1\": true,\n \"prop2\": {\n \"prop\": \"string\"\n }\n}"],
...@@ -1951,6 +1951,25 @@ ok(isNaN(tmp), "Math.tan(-Infinity) is not NaN"); ...@@ -1951,6 +1951,25 @@ ok(isNaN(tmp), "Math.tan(-Infinity) is not NaN");
ok(s === undefined || s === "undefined" /* broken on some old versions */, ok(s === undefined || s === "undefined" /* broken on some old versions */,
"stringify(undefined) returned " + s + " expected undefined"); "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 = [ var parse_tests = [
["true", true], ["true", true],
[" \nnull ", null], [" \nnull ", null],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment