Bug 1528784 - Pass BigInt as receiver when retrieving "toJSON" property r=anba
authorAndy Wingo <wingo@igalia.com>
Mon, 25 Feb 2019 10:41:47 +0000
changeset 460868 c6ae678d11d159f9678fd81a2d19f1327973c2da
parent 460867 80c2261aa69446b93b1df3cb0454c45074863a5f
child 460869 1293aa5ed1925f8979f1b77ff9dc2c4dd542e909
push id35610
push useropoprus@mozilla.com
push dateMon, 25 Feb 2019 16:35:27 +0000
treeherdermozilla-central@80e4f0ce3dd4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersanba
bugs1528784
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1528784 - Pass BigInt as receiver when retrieving "toJSON" property r=anba Differential Revision: https://phabricator.services.mozilla.com/D20304
js/src/builtin/JSON.cpp
js/src/tests/test262/built-ins/JSON/stringify/bigint-tojson-receiver.js
--- a/js/src/builtin/JSON.cpp
+++ b/js/src/builtin/JSON.cpp
@@ -283,25 +283,26 @@ static bool PreprocessValue(JSContext* c
   // since the stuff we do here can have side-effects.
   if (scx->maybeSafely) {
     return true;
   }
 
   RootedString keyStr(cx);
 
   // Step 2. Modified by BigInt spec 6.1 to check for a toJSON method on the
-  // BigInt prototype when the value is a BigInt.
+  // BigInt prototype when the value is a BigInt, and to pass the BigInt
+  // primitive value as receiver.
   if (vp.isObject() || vp.isBigInt()) {
     RootedValue toJSON(cx);
     RootedObject obj(cx, JS::ToObject(cx, vp));
     if (!obj) {
       return false;
     }
 
-    if (!GetProperty(cx, obj, obj, cx->names().toJSON, &toJSON)) {
+    if (!GetProperty(cx, obj, vp, cx->names().toJSON, &toJSON)) {
       return false;
     }
 
     if (IsCallable(toJSON)) {
       keyStr = KeyStringifier<KeyType>::toString(cx, key);
       if (!keyStr) {
         return false;
       }
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/JSON/stringify/bigint-tojson-receiver.js
@@ -0,0 +1,28 @@
+// |reftest| skip-if(!this.hasOwnProperty('BigInt')) -- BigInt is not enabled unconditionally
+// Copyright 2019 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+// Test case written by André Bargull.
+
+/*---
+esid: sec-serializejsonproperty
+description: toJSON method called with BigInt as receiver
+features: [BigInt]
+---*/
+
+assert.throws(TypeError, () => JSON.stringify(1n),
+              "toString throws for BigInt object");
+
+// The BigInt proposal changes the SerializeJSONProperty algorithm to
+// specifically allow passing BigInt objects as receivers for the toJSON
+// method.
+Object.defineProperty(BigInt.prototype, "toJSON", {
+    get() {
+       "use strict";
+        return () => typeof this;
+    }
+});
+
+assert.sameValue(JSON.stringify(1n), "\"bigint\"",
+                 "BigInt toJSON method called with value as receiver");
+
+reportCompare(0, 0);