shithub: libmujs

Download patch

ref: 8e7d57959c9c69930d4cc5df8130ae4ebb87e5c0
parent: 58b44200948f0691f34b45b2718ec572f4261277
author: Tor Andersson <tor.andersson@gmail.com>
date: Wed Apr 19 09:22:36 EDT 2017

JSON.parse reviver callback.

--- a/json.c
+++ b/json.c
@@ -92,13 +92,68 @@
 	}
 }
 
+static void jsonrevive(js_State *J, const char *name)
+{
+	const char *key;
+	char buf[32];
+
+	/* revive is in 2 */
+	/* holder is in -1 */
+
+	js_getproperty(J, -1, name); /* get value from holder */
+
+	if (js_isobject(J, -1)) {
+		if (js_isarray(J, -1)) {
+			int i = 0;
+			int n = js_getlength(J, -1);
+			for (i = 0; i < n; ++i) {
+				jsonrevive(J, js_itoa(buf, i));
+				if (js_isundefined(J, -1)) {
+					js_pop(J, 1);
+					js_delproperty(J, -1, buf);
+				} else {
+					js_setproperty(J, -2, buf);
+				}
+			}
+		} else {
+			js_pushiterator(J, -1, 1);
+			while ((key = js_nextiterator(J, -1))) {
+				js_rot2(J);
+				jsonrevive(J, key);
+				if (js_isundefined(J, -1)) {
+					js_pop(J, 1);
+					js_delproperty(J, -1, key);
+				} else {
+					js_setproperty(J, -2, key);
+				}
+				js_rot2(J);
+			}
+			js_pop(J, 1);
+		}
+	}
+
+	js_copy(J, 2); /* reviver function */
+	js_copy(J, -3); /* holder as this */
+	js_pushstring(J, name); /* name */
+	js_copy(J, -4); /* value */
+	js_call(J, 2);
+	js_rot2pop1(J); /* pop old value, leave new value on stack */
+}
+
 static void JSON_parse(js_State *J)
 {
 	const char *source = js_tostring(J, 1);
 	jsY_initlex(J, "JSON", source);
 	jsonnext(J);
-	jsonvalue(J);
-	/* TODO: reviver Walk() */
+
+	if (js_iscallable(J, 2)) {
+		js_newobject(J);
+		jsonvalue(J);
+		js_defproperty(J, -2, "", 0);
+		jsonrevive(J, "");
+	} else {
+		jsonvalue(J);
+	}
 }
 
 static void fmtnum(js_State *J, js_Buffer **sb, double n)