提交 e82d0319 编写于 作者: H hannesw

8062141: Various performance issues parsing JSON

Reviewed-by: lagergren, attila
上级 f6bb0307
......@@ -580,13 +580,15 @@ public final class Global extends ScriptObject implements Scope {
} else if (obj instanceof String || obj instanceof ConsString) {
return new NativeString((CharSequence)obj, this);
} else if (obj instanceof Object[]) { // extension
return new NativeArray((Object[])obj);
return new NativeArray(ArrayData.allocate((Object[])obj), this);
} else if (obj instanceof double[]) { // extension
return new NativeArray((double[])obj);
return new NativeArray(ArrayData.allocate((double[])obj), this);
} else if (obj instanceof long[]) {
return new NativeArray((long[])obj);
return new NativeArray(ArrayData.allocate((long[])obj), this);
} else if (obj instanceof int[]) {
return new NativeArray((int[])obj);
return new NativeArray(ArrayData.allocate((int[]) obj), this);
} else if (obj instanceof ArrayData) {
return new NativeArray((ArrayData) obj, this);
} else {
// FIXME: more special cases? Map? List?
return obj;
......@@ -1028,14 +1030,19 @@ public final class Global extends ScriptObject implements Scope {
}
// builtin prototype accessors
ScriptObject getFunctionPrototype() {
return ScriptFunction.getPrototype(builtinFunction);
}
ScriptObject getObjectPrototype() {
/**
* Get the builtin Object prototype.
* @return the object prototype.
*/
public ScriptObject getObjectPrototype() {
return ScriptFunction.getPrototype(builtinObject);
}
ScriptObject getFunctionPrototype() {
return ScriptFunction.getPrototype(builtinFunction);
}
ScriptObject getArrayPrototype() {
return ScriptFunction.getPrototype(builtinArray);
}
......
......@@ -93,9 +93,6 @@ public class Lexer extends Scanner {
private static final String SPACETAB = " \t"; // ASCII space and tab
private static final String LFCR = "\n\r"; // line feed and carriage return (ctrl-m)
private static final String JSON_WHITESPACE_EOL = LFCR;
private static final String JSON_WHITESPACE = SPACETAB + LFCR;
private static final String JAVASCRIPT_WHITESPACE_EOL =
LFCR +
"\u2028" + // line separator
......@@ -384,24 +381,6 @@ public class Lexer extends Scanner {
return JAVASCRIPT_WHITESPACE_EOL.indexOf(ch) != -1;
}
/**
* Test whether a char is valid JSON whitespace
* @param ch a char
* @return true if valid JSON whitespace
*/
public static boolean isJsonWhitespace(final char ch) {
return JSON_WHITESPACE.indexOf(ch) != -1;
}
/**
* Test whether a char is valid JSON end of line
* @param ch a char
* @return true if valid JSON end of line
*/
public static boolean isJsonEOL(final char ch) {
return JSON_WHITESPACE_EOL.indexOf(ch) != -1;
}
/**
* Test if char is a string delimiter, e.g. '\' or '"'. Also scans exec
* strings ('`') in scripting mode.
......
......@@ -25,19 +25,11 @@
package jdk.nashorn.internal.runtime;
import static jdk.nashorn.internal.runtime.Source.sourceFor;
import java.lang.invoke.MethodHandle;
import java.util.Iterator;
import java.util.concurrent.Callable;
import jdk.nashorn.internal.ir.LiteralNode;
import jdk.nashorn.internal.ir.Node;
import jdk.nashorn.internal.ir.ObjectNode;
import jdk.nashorn.internal.ir.PropertyNode;
import jdk.nashorn.internal.ir.UnaryNode;
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.parser.JSONParser;
import jdk.nashorn.internal.parser.TokenType;
import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
import jdk.nashorn.internal.runtime.linker.Bootstrap;
......@@ -79,19 +71,17 @@ public final class JSONFunctions {
*/
public static Object parse(final Object text, final Object reviver) {
final String str = JSType.toString(text);
final JSONParser parser = new JSONParser(sourceFor("<json>", str), new Context.ThrowErrorManager());
Node node;
final Global global = Context.getGlobal();
final JSONParser parser = new JSONParser(str, global);
final Object value;
try {
node = parser.parse();
value = parser.parse();
} catch (final ParserException e) {
throw ECMAErrors.syntaxError(e, "invalid.json", e.getMessage());
}
final Global global = Context.getGlobal();
final Object unfiltered = convertNode(global, node);
return applyReviver(global, unfiltered, reviver);
return applyReviver(global, value, reviver);
}
// -- Internals only below this point
......@@ -137,61 +127,6 @@ public final class JSONFunctions {
}
}
// Converts IR node to runtime value
private static Object convertNode(final Global global, final Node node) {
if (node instanceof LiteralNode) {
// check for array literal
if (node.tokenType() == TokenType.ARRAY) {
assert node instanceof LiteralNode.ArrayLiteralNode;
final Node[] elements = ((LiteralNode.ArrayLiteralNode)node).getValue();
// NOTE: We cannot use LiteralNode.isNumericArray() here as that
// method uses symbols of element nodes. Since we don't do lower
// pass, there won't be any symbols!
if (isNumericArray(elements)) {
final double[] values = new double[elements.length];
int index = 0;
for (final Node elem : elements) {
values[index++] = JSType.toNumber(convertNode(global, elem));
}
return global.wrapAsObject(values);
}
final Object[] values = new Object[elements.length];
int index = 0;
for (final Node elem : elements) {
values[index++] = convertNode(global, elem);
}
return global.wrapAsObject(values);
}
return ((LiteralNode<?>)node).getValue();
} else if (node instanceof ObjectNode) {
final ObjectNode objNode = (ObjectNode) node;
final ScriptObject object = global.newObject();
for (final PropertyNode pNode: objNode.getElements()) {
final Node valueNode = pNode.getValue();
final String name = pNode.getKeyName();
final Object value = convertNode(global, valueNode);
setPropertyValue(object, name, value);
}
return object;
} else if (node instanceof UnaryNode) {
// UnaryNode used only to represent negative number JSON value
final UnaryNode unaryNode = (UnaryNode)node;
return -((LiteralNode<?>)unaryNode.getExpression()).getNumber();
} else {
return null;
}
}
// add a new property if does not exist already, or else set old property
private static void setPropertyValue(final ScriptObject sobj, final String name, final Object value) {
final int index = ArrayIndex.getArrayIndex(name);
......@@ -207,14 +142,4 @@ public final class JSONFunctions {
}
}
// does the given IR node represent a numeric array?
private static boolean isNumericArray(final Node[] values) {
for (final Node node : values) {
if (node instanceof LiteralNode && ((LiteralNode<?>)node).getValue() instanceof Number) {
continue;
}
return false;
}
return true;
}
}
......@@ -486,7 +486,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
*
* @return New {@link PropertyMap} with {@link Property} replaced.
*/
PropertyMap replaceProperty(final Property oldProperty, final Property newProperty) {
public PropertyMap replaceProperty(final Property oldProperty, final Property newProperty) {
if (listeners != null) {
listeners.propertyModified(oldProperty, newProperty);
}
......
......@@ -25,7 +25,6 @@
package jdk.nashorn.internal.scripts;
import jdk.nashorn.internal.codegen.SpillObjectCreator;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptObject;
......@@ -64,8 +63,9 @@ public class JO extends ScriptObject {
}
/**
* Constructor that takes a pre-initialized spill pool. Used for
* by {@link SpillObjectCreator} for intializing object literals
* Constructor that takes a pre-initialized spill pool. Used by
* {@link jdk.nashorn.internal.codegen.SpillObjectCreator} and
* {@link jdk.nashorn.internal.parser.JSONParser} for initializing object literals
*
* @param map property map
* @param primitiveSpill primitive spill pool
......
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
function bench() {
var start = Date.now();
for (var i = 0; i < 2000; i++) {
JSON.parse(String(json));
}
print("1000 iterations in", Date.now() - start, "millis");
}
var json = '[\
{\
"_id": "54ca34171d3ade49782294c8",\
"index": 0,\
"guid": "ed0e74d5-ac63-47b6-8938-1750abab5770",\
"isActive": false,\
"balance": "$1,996.19",\
"picture": "http://placehold.it/32x32",\
"age": 39,\
"eyeColor": "green",\
"name": "Rose Graham",\
"gender": "male",\
"company": "PRIMORDIA",\
"email": "rosegraham@primordia.com",\
"phone": "+1 (985) 600-3551",\
"address": "364 Melba Court, Succasunna, Texas, 8393",\
"about": "Sunt commodo cillum occaecat velit eu eiusmod ex eiusmod sunt deserunt nulla proident incididunt. Incididunt ullamco Lorem elit do culpa esse do ex dolor aliquip labore. Ullamco velit laboris incididunt dolor. Nostrud dolor sint pariatur fugiat ullamco exercitation. Eu laboris do cupidatat eiusmod incididunt mollit occaecat voluptate.",\
"registered": "2014-03-13T12:05:14 -01:00",\
"latitude": 18.55665,\
"longitude": 81.641001,\
"tags": [\
"sint",\
"Lorem",\
"veniam",\
"quis",\
"proident",\
"consectetur",\
"consequat"\
],\
"friends": [\
{\
"id": 0,\
"name": "Evangelina Morgan"\
},\
{\
"id": 1,\
"name": "Saunders Snyder"\
},\
{\
"id": 2,\
"name": "Walker Wood"\
}\
],\
"greeting": "Hello, Rose Graham! You have 1 unread messages.",\
"favoriteFruit": "strawberry"\
},\
{\
"_id": "54ca34176790c4c60fcae085",\
"index": 1,\
"guid": "9dc42e4c-b58f-4d92-a2ee-968d2b627d92",\
"isActive": true,\
"balance": "$3,832.97",\
"picture": "http://placehold.it/32x32",\
"age": 40,\
"eyeColor": "brown",\
"name": "Delaney Cherry",\
"gender": "male",\
"company": "INJOY",\
"email": "delaneycherry@injoy.com",\
"phone": "+1 (807) 463-2295",\
"address": "470 Hale Avenue, Mulberry, District Of Columbia, 5455",\
"about": "Deserunt sit cupidatat elit Lorem excepteur ex. Magna officia minim cupidatat nulla enim deserunt. Amet ex in tempor commodo consequat non ad qui elit cupidatat esse labore sint.",\
"registered": "2014-03-27T23:06:33 -01:00",\
"latitude": -4.984238,\
"longitude": 116.039285,\
"tags": [\
"minim",\
"velit",\
"aute",\
"minim",\
"id",\
"enim",\
"enim"\
],\
"friends": [\
{\
"id": 0,\
"name": "Barrera Flowers"\
},\
{\
"id": 1,\
"name": "Leann Larson"\
},\
{\
"id": 2,\
"name": "Latoya Petty"\
}\
],\
"greeting": "Hello, Delaney Cherry! You have 2 unread messages.",\
"favoriteFruit": "strawberry"\
},\
{\
"_id": "54ca3417920666f00c54bfc4",\
"index": 2,\
"guid": "f91e08f8-1598-49bc-a08b-bb48f0cc1751",\
"isActive": true,\
"balance": "$2,932.84",\
"picture": "http://placehold.it/32x32",\
"age": 28,\
"eyeColor": "brown",\
"name": "Mosley Hammond",\
"gender": "male",\
"company": "AQUACINE",\
"email": "mosleyhammond@aquacine.com",\
"phone": "+1 (836) 598-2591",\
"address": "879 Columbia Place, Seymour, Montana, 4897",\
"about": "Sunt laborum incididunt et elit in deserunt deserunt irure enim ea qui non. Minim nisi sint aute veniam reprehenderit veniam reprehenderit. Elit enim eu voluptate eu cupidatat nulla ea incididunt exercitation voluptate ut aliquip excepteur ipsum. Consequat anim fugiat irure Lorem anim consectetur est.",\
"registered": "2014-07-27T05:05:58 -02:00",\
"latitude": -43.608015,\
"longitude": -38.33894,\
"tags": [\
"proident",\
"incididunt",\
"eiusmod",\
"anim",\
"consectetur",\
"qui",\
"excepteur"\
],\
"friends": [\
{\
"id": 0,\
"name": "Hanson Davidson"\
},\
{\
"id": 1,\
"name": "Autumn Kaufman"\
},\
{\
"id": 2,\
"name": "Tammy Foley"\
}\
],\
"greeting": "Hello, Mosley Hammond! You have 4 unread messages.",\
"favoriteFruit": "apple"\
},\
{\
"_id": "54ca341753b67572a2b04935",\
"index": 3,\
"guid": "3377416b-43a2-4f9e-ada3-2479e13b44b8",\
"isActive": false,\
"balance": "$3,821.54",\
"picture": "http://placehold.it/32x32",\
"age": 31,\
"eyeColor": "green",\
"name": "Mueller Barrett",\
"gender": "male",\
"company": "GROK",\
"email": "muellerbarrett@grok.com",\
"phone": "+1 (890) 535-2834",\
"address": "571 Norwood Avenue, Westwood, Arkansas, 2164",\
"about": "Occaecat est sunt commodo ut ex excepteur elit nulla velit minim commodo commodo esse. Lorem quis eu minim consectetur. Cupidatat cupidatat consequat sit eu ex non quis nulla veniam sint enim excepteur. Consequat minim duis do do minim fugiat minim elit laborum ut velit. Occaecat laboris veniam sint reprehenderit.",\
"registered": "2014-07-18T17:15:35 -02:00",\
"latitude": 10.746577,\
"longitude": -160.266041,\
"tags": [\
"reprehenderit",\
"veniam",\
"sint",\
"commodo",\
"exercitation",\
"cillum",\
"sunt"\
],\
"friends": [\
{\
"id": 0,\
"name": "Summers Finch"\
},\
{\
"id": 1,\
"name": "Tracie Mcdaniel"\
},\
{\
"id": 2,\
"name": "Ayers Patrick"\
}\
],\
"greeting": "Hello, Mueller Barrett! You have 7 unread messages.",\
"favoriteFruit": "apple"\
},\
{\
"_id": "54ca34172775ab9615db0d1d",\
"index": 4,\
"guid": "a3102a3e-3f08-4df3-b5b5-62eff985d5ca",\
"isActive": true,\
"balance": "$3,962.27",\
"picture": "http://placehold.it/32x32",\
"age": 34,\
"eyeColor": "green",\
"name": "Patrick Foster",\
"gender": "male",\
"company": "QUAREX",\
"email": "patrickfoster@quarex.com",\
"phone": "+1 (805) 577-2362",\
"address": "640 Richards Street, Roberts, American Samoa, 5530",\
"about": "Aute occaecat occaecat ad eiusmod esse aliqua ullamco minim. Exercitation aute ut ex nostrud deserunt laboris officia amet enim do. Cillum officia laborum occaecat eiusmod reprehenderit ex et aliqua minim elit ex aliqua mollit. Occaecat dolor in fugiat laboris aliquip nisi ad voluptate duis eiusmod ad do.",\
"registered": "2014-07-22T16:45:35 -02:00",\
"latitude": 6.609025,\
"longitude": -5.357026,\
"tags": [\
"ea",\
"ut",\
"excepteur",\
"enim",\
"ad",\
"non",\
"sit"\
],\
"friends": [\
{\
"id": 0,\
"name": "Duncan Lewis"\
},\
{\
"id": 1,\
"name": "Alyce Benton"\
},\
{\
"id": 2,\
"name": "Angelique Larsen"\
}\
],\
"greeting": "Hello, Patrick Foster! You have 1 unread messages.",\
"favoriteFruit": "strawberry"\
},\
{\
"_id": "54ca3417a190f26fef815f6d",\
"index": 5,\
"guid": "c09663dd-bb0e-45a4-960c-232c0e8a9486",\
"isActive": false,\
"balance": "$1,871.12",\
"picture": "http://placehold.it/32x32",\
"age": 20,\
"eyeColor": "blue",\
"name": "Foreman Chaney",\
"gender": "male",\
"company": "DEMINIMUM",\
"email": "foremanchaney@deminimum.com",\
"phone": "+1 (966) 523-2182",\
"address": "960 Granite Street, Sunnyside, Tennessee, 1097",\
"about": "Adipisicing nisi qui id sit incididunt aute exercitation veniam consequat ipsum sit irure. Aute officia commodo Lorem consequat. Labore exercitation consequat voluptate deserunt consequat do est fugiat nisi eu dolor minim id ea.",\
"registered": "2015-01-21T00:18:00 -01:00",\
"latitude": -69.841726,\
"longitude": 121.809383,\
"tags": [\
"laboris",\
"sunt",\
"exercitation",\
"enim",\
"anim",\
"excepteur",\
"tempor"\
],\
"friends": [\
{\
"id": 0,\
"name": "Espinoza Johnston"\
},\
{\
"id": 1,\
"name": "Doreen Holder"\
},\
{\
"id": 2,\
"name": "William Ellison"\
}\
],\
"greeting": "Hello, Foreman Chaney! You have 5 unread messages.",\
"favoriteFruit": "strawberry"\
}\
]';
for (var i = 0; i < 100; i++) {
bench();
}
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* JDK-8062141: Various performance issues parsing JSON
*
* @test
* @run
*/
function testJson(json) {
try {
print(JSON.stringify(JSON.parse(json)));
} catch (error) {
print(error);
}
}
testJson('"\\u003f"');
testJson('"\\u0"');
testJson('"\\u0"');
testJson('"\\u00"');
testJson('"\\u003"');
testJson('"\\u003x"');
testJson('"\\"');
testJson('"');
testJson('+1');
testJson('-1');
testJson('1.');
testJson('.1');
testJson('01');
testJson('1e');
testJson('1e0');
testJson('1a');
testJson('1e+');
testJson('1e-');
testJson('0.0e+0');
testJson('0.0e-0');
testJson('[]');
testJson('[ 1 ]');
testJson('[1,]');
testJson('[ 1 , 2 ]');
testJson('[1, 2');
testJson('{}');
testJson('{ "a" : "b" }');
testJson('{ "a" : "b" ');
testJson('{ "a" : }');
testJson('true');
testJson('tru');
testJson('true1');
testJson('false');
testJson('fals');
testJson('falser');
testJson('null');
testJson('nul');
testJson('null0');
testJson('{} 0');
testJson('{} a');
testJson('[] 0');
testJson('[] a');
testJson('1 0');
testJson('1 a');
testJson('["a":true]');
testJson('{"a",truer}');
testJson('{"a":truer}');
testJson('[1, 2, 3]');
testJson('[9223372036854774000, 9223372036854775000, 9223372036854776000]');
testJson('[1.1, 1.2, 1.3]');
testJson('[1, 1.2, 9223372036854776000, null, true]');
testJson('{ "a" : "string" , "b": 1 , "c" : 1.2 , "d" : 9223372036854776000 , "e" : null , "f" : true }');
"?"
SyntaxError: Invalid JSON: <json>:1:4 Invalid hex digit
"\u0"
^
SyntaxError: Invalid JSON: <json>:1:4 Invalid hex digit
"\u0"
^
SyntaxError: Invalid JSON: <json>:1:5 Invalid hex digit
"\u00"
^
SyntaxError: Invalid JSON: <json>:1:6 Invalid hex digit
"\u003"
^
SyntaxError: Invalid JSON: <json>:1:6 Invalid hex digit
"\u003x"
^
SyntaxError: Invalid JSON: <json>:1:3 Missing close quote
"\"
^
SyntaxError: Invalid JSON: <json>:1:1 Missing close quote
"
^
SyntaxError: Invalid JSON: <json>:1:0 Expected json literal but found +
+1
^
-1
SyntaxError: Invalid JSON: <json>:1:2 Invalid JSON number format
1.
^
SyntaxError: Invalid JSON: <json>:1:0 Invalid JSON number format
.1
^
SyntaxError: Invalid JSON: <json>:1:1 Expected eof but found 1
01
^
SyntaxError: Invalid JSON: <json>:1:2 Invalid JSON number format
1e
^
1
SyntaxError: Invalid JSON: <json>:1:1 Expected eof but found a
1a
^
SyntaxError: Invalid JSON: <json>:1:3 Invalid JSON number format
1e+
^
SyntaxError: Invalid JSON: <json>:1:3 Invalid JSON number format
1e-
^
0
0
[]
[1]
SyntaxError: Invalid JSON: <json>:1:3 Trailing comma is not allowed in JSON
[1,]
^
[1,2]
SyntaxError: Invalid JSON: <json>:1:5 Expected , or ] but found eof
[1, 2
^
{}
{"a":"b"}
SyntaxError: Invalid JSON: <json>:1:12 Expected , or } but found eof
{ "a" : "b"
^
SyntaxError: Invalid JSON: <json>:1:8 Expected json literal but found }
{ "a" : }
^
true
SyntaxError: Invalid JSON: <json>:1:0 Expected json literal but found ident
tru
^
SyntaxError: Invalid JSON: <json>:1:4 Expected eof but found 1
true1
^
false
SyntaxError: Invalid JSON: <json>:1:0 Expected json literal but found ident
fals
^
SyntaxError: Invalid JSON: <json>:1:5 Expected eof but found r
falser
^
null
SyntaxError: Invalid JSON: <json>:1:0 Expected json literal but found ident
nul
^
SyntaxError: Invalid JSON: <json>:1:4 Expected eof but found 0
null0
^
SyntaxError: Invalid JSON: <json>:1:3 Expected eof but found 0
{} 0
^
SyntaxError: Invalid JSON: <json>:1:3 Expected eof but found a
{} a
^
SyntaxError: Invalid JSON: <json>:1:3 Expected eof but found 0
[] 0
^
SyntaxError: Invalid JSON: <json>:1:3 Expected eof but found a
[] a
^
SyntaxError: Invalid JSON: <json>:1:2 Expected eof but found 0
1 0
^
SyntaxError: Invalid JSON: <json>:1:2 Expected eof but found a
1 a
^
SyntaxError: Invalid JSON: <json>:1:4 Expected , or ] but found :
["a":true]
^
SyntaxError: Invalid JSON: <json>:1:4 Expected : but found ,
{"a",truer}
^
SyntaxError: Invalid JSON: <json>:1:9 Expected , or } but found r
{"a":truer}
^
[1,2,3]
[9223372036854773800,9223372036854774800,9223372036854776000]
[1.1,1.2,1.3]
[1,1.2,9223372036854776000,null,true]
{"a":"string","b":1,"c":1.2,"d":9223372036854776000,"e":null,"f":true}
SyntaxError: Invalid JSON: <json>:1:12 Expected number but found ident
SyntaxError: Invalid JSON: <json>:1:11 Invalid JSON number format
{ "test" : -xxx }
^
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册