From cb68e2cd9be2b3054223a8608d935c258db27f33 Mon Sep 17 00:00:00 2001 From: "jochen@chromium.org" Date: Mon, 5 Aug 2013 11:14:46 +0000 Subject: [PATCH] Expose JSON parser through V8 API BUG=v8:2821 TEST=cctest/test-api/JSONParse R=yangguo@chromium.org Review URL: https://codereview.chromium.org/21959003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16048 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8.h | 16 ++++++++++++++++ src/api.cc | 24 ++++++++++++++++++++++++ src/runtime.cc | 2 +- test/cctest/test-api.cc | 10 ++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/include/v8.h b/include/v8.h index 4ba7dc277..8a6a8c67a 100644 --- a/include/v8.h +++ b/include/v8.h @@ -1254,6 +1254,22 @@ class V8EXPORT StackFrame { }; +/** + * A JSON Parser. + */ +class V8EXPORT JSON { + public: + /** + * Tries to parse the string |json_string| and returns it as object if + * successful. + * + * \param json_string The string to parse. + * \return The corresponding object if successfully parsed. + */ + static Local Parse(Local json_string); +}; + + // --- Value --- diff --git a/src/api.cc b/src/api.cc index 60627a397..100ddc21b 100644 --- a/src/api.cc +++ b/src/api.cc @@ -46,6 +46,7 @@ #include "heap-profiler.h" #include "heap-snapshot-generator-inl.h" #include "icu_util.h" +#include "json-parser.h" #include "messages.h" #ifdef COMPRESS_STARTUP_DATA_BZ2 #include "natives.h" @@ -2607,6 +2608,29 @@ bool StackFrame::IsConstructor() const { } +// --- J S O N --- + +Local JSON::Parse(Local json_string) { + i::Isolate* isolate = i::Isolate::Current(); + EnsureInitializedForIsolate(isolate, "v8::JSON::Parse"); + ENTER_V8(isolate); + i::HandleScope scope(isolate); + i::Handle source = i::Handle( + FlattenGetString(Utils::OpenHandle(*json_string))); + EXCEPTION_PREAMBLE(isolate); + i::Handle result; + if (source->IsSeqOneByteString()) { + result = i::JsonParser::Parse(source); + } else { + result = i::JsonParser::Parse(source); + } + has_pending_exception = result.is_null(); + EXCEPTION_BAILOUT_CHECK(isolate, Local()); + return Utils::ToLocal( + i::Handle::cast(scope.CloseAndEscape(result))); +} + + // --- D a t a --- bool Value::FullIsUndefined() const { diff --git a/src/runtime.cc b/src/runtime.cc index 977514704..6164e6631 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -9483,7 +9483,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) { ASSERT_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, source, 0); - source = Handle(source->TryFlattenGetString()); + source = Handle(FlattenGetString(source)); // Optimized fast case where we only have ASCII characters. Handle result; if (source->IsSeqOneByteString()) { diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index 92ab5b854..511a9440b 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -19863,6 +19863,16 @@ THREADED_TEST(Regress260106) { } +THREADED_TEST(JSONParse) { + LocalContext context; + HandleScope scope(context->GetIsolate()); + Local obj = v8::JSON::Parse(v8_str("{\"x\":42}")); + Handle global = context->Global(); + global->Set(v8_str("obj"), obj); + ExpectString("JSON.stringify(obj)", "{\"x\":42}"); +} + + #ifndef WIN32 class ThreadInterruptTest { public: -- 2.34.1