Skip to content

Commit a65ffee

Browse files
committed
Add Proxy support for JSON.stringify
JerryScript-DCO-1.0-Signed-off-by: Adam Szilagyi aszilagy@inf.u-szeged.hu
1 parent 4be9ffd commit a65ffee

File tree

2 files changed

+75
-3
lines changed

2 files changed

+75
-3
lines changed

jerry-core/ecma/builtin-objects/ecma-builtin-json.c

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,7 +1005,17 @@ static ecma_value_t
10051005
ecma_builtin_json_serialize_array (ecma_json_stringify_context_t *context_p, /**< context*/
10061006
ecma_object_t *obj_p) /**< the array object*/
10071007
{
1008-
JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY);
1008+
ecma_value_t obj_value = ecma_make_object_value (obj_p);
1009+
ecma_value_t is_array = ecma_is_value_array (obj_value);
1010+
1011+
#if ENABLED (JERRY_ES2015)
1012+
if (ECMA_IS_VALUE_ERROR (is_array))
1013+
{
1014+
return is_array;
1015+
}
1016+
#endif /* ENABLED (JERRY_ES2015) */
1017+
1018+
JERRY_ASSERT (ecma_is_value_true (is_array));
10091019

10101020
/* 1. */
10111021
if (ecma_json_has_object_in_stack (context_p->occurence_stack_last_p, obj_p))
@@ -1026,8 +1036,43 @@ ecma_builtin_json_serialize_array (ecma_json_stringify_context_t *context_p, /**
10261036

10271037
const bool has_gap = !ecma_compare_ecma_string_to_magic_id (context_p->gap_str_p, LIT_MAGIC_STRING__EMPTY);
10281038

1039+
bool obj_is_proxy = false;
1040+
1041+
#if ENABLED (JERRY_ES2015)
1042+
if (ECMA_OBJECT_IS_PROXY (obj_p))
1043+
{
1044+
obj_is_proxy = true;
1045+
}
1046+
#endif /* ENABLED (JERRY_ES2015) */
1047+
10291048
/* 6. */
1030-
uint32_t array_length = ((ecma_extended_object_t *) obj_p)->u.array.length;
1049+
uint32_t array_length;
1050+
1051+
if (obj_is_proxy)
1052+
{
1053+
ecma_value_t length_value = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_LENGTH);
1054+
1055+
if (ECMA_IS_VALUE_ERROR (length_value))
1056+
{
1057+
return length_value;
1058+
}
1059+
1060+
ecma_number_t length_number;
1061+
1062+
if (ECMA_IS_VALUE_ERROR (ecma_get_number (length_value, &length_number)))
1063+
{
1064+
ecma_free_value (length_value);
1065+
return ECMA_VALUE_ERROR;
1066+
}
1067+
1068+
ecma_free_value (length_value);
1069+
1070+
array_length = ecma_number_to_uint32 (length_number);
1071+
}
1072+
else
1073+
{
1074+
array_length = ((ecma_extended_object_t *) obj_p)->u.array.length;
1075+
}
10311076

10321077
ecma_stringbuilder_append_byte (&context_p->result_builder, LIT_CHAR_LEFT_SQUARE);
10331078

@@ -1260,11 +1305,21 @@ ecma_builtin_json_serialize_property (ecma_json_stringify_context_t *context_p,
12601305
/* 11. */
12611306
if (ecma_is_value_object (value) && !ecma_op_is_callable (value))
12621307
{
1308+
ecma_value_t is_array = ecma_is_value_array (value);
1309+
1310+
#if ENABLED (JERRY_ES2015)
1311+
if (ECMA_IS_VALUE_ERROR (is_array))
1312+
{
1313+
return is_array;
1314+
}
1315+
#endif /* ENABLED (JERRY_ES2015) */
1316+
12631317
ecma_object_t *obj_p = ecma_get_object_from_value (value);
12641318

12651319
ecma_value_t ret_value;
1320+
12661321
/* 10.a */
1267-
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY)
1322+
if (ecma_is_value_true (is_array))
12681323
{
12691324
ret_value = ecma_builtin_json_serialize_array (context_p, obj_p);
12701325
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright JS Foundation and other contributors, http://js.foundation
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// Test with proxy
16+
assert(JSON.stringify(new Proxy(['foo'], {})) === '["foo"]');
17+
assert(JSON.stringify(new Proxy({0:"foo"}, {})) === '{"0":"foo"}');

0 commit comments

Comments
 (0)