Expose JSON stringifier through V8 API
BUG=602659 LOG=N Review URL: https://codereview.chromium.org/1891203002 Cr-Commit-Position: refs/heads/master@{#35543}
This commit is contained in:
parent
451fa77235
commit
0ba934d7bf
20
include/v8.h
20
include/v8.h
@ -1668,9 +1668,8 @@ struct SampleInfo {
|
||||
StateTag vm_state;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A JSON Parser.
|
||||
* A JSON Parser and Stringifier.
|
||||
*/
|
||||
class V8_EXPORT JSON {
|
||||
public:
|
||||
@ -1681,10 +1680,23 @@ class V8_EXPORT JSON {
|
||||
* \param json_string The string to parse.
|
||||
* \return The corresponding value if successfully parsed.
|
||||
*/
|
||||
static V8_DEPRECATED("Use maybe version",
|
||||
static V8_DEPRECATED("Use the maybe version taking context",
|
||||
Local<Value> Parse(Local<String> json_string));
|
||||
static V8_DEPRECATE_SOON("Use the maybe version taking context",
|
||||
MaybeLocal<Value> Parse(Isolate* isolate,
|
||||
Local<String> json_string));
|
||||
static V8_WARN_UNUSED_RESULT MaybeLocal<Value> Parse(
|
||||
Isolate* isolate, Local<String> json_string);
|
||||
Local<Context> context, Local<String> json_string);
|
||||
|
||||
/**
|
||||
* Tries to stringify the JSON-serializable object |json_object| and returns
|
||||
* it as string if successful.
|
||||
*
|
||||
* \param json_object The JSON-serializable object to stringify.
|
||||
* \return The corresponding string if successfully stringified.
|
||||
*/
|
||||
static V8_WARN_UNUSED_RESULT MaybeLocal<String> Stringify(
|
||||
Local<Context> context, Local<Object> json_object);
|
||||
};
|
||||
|
||||
|
||||
|
40
src/api.cc
40
src/api.cc
@ -49,12 +49,12 @@
|
||||
#include "src/profiler/heap-snapshot-generator-inl.h"
|
||||
#include "src/profiler/profile-generator-inl.h"
|
||||
#include "src/profiler/sampler.h"
|
||||
#include "src/property.h"
|
||||
#include "src/property-descriptor.h"
|
||||
#include "src/property-details.h"
|
||||
#include "src/property.h"
|
||||
#include "src/prototype.h"
|
||||
#include "src/runtime/runtime.h"
|
||||
#include "src/runtime-profiler.h"
|
||||
#include "src/runtime/runtime.h"
|
||||
#include "src/simulator.h"
|
||||
#include "src/snapshot/natives.h"
|
||||
#include "src/snapshot/snapshot.h"
|
||||
@ -66,7 +66,6 @@
|
||||
#include "src/version.h"
|
||||
#include "src/vm-state-inl.h"
|
||||
|
||||
|
||||
namespace v8 {
|
||||
|
||||
#define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
|
||||
@ -2747,13 +2746,38 @@ MaybeLocal<Value> JSON::Parse(Isolate* v8_isolate, Local<String> json_string) {
|
||||
RETURN_ESCAPED(result);
|
||||
}
|
||||
|
||||
|
||||
Local<Value> JSON::Parse(Local<String> json_string) {
|
||||
auto isolate = reinterpret_cast<v8::Isolate*>(
|
||||
Utils::OpenHandle(*json_string)->GetIsolate());
|
||||
RETURN_TO_LOCAL_UNCHECKED(Parse(isolate, json_string), Value);
|
||||
MaybeLocal<Value> JSON::Parse(Local<Context> context,
|
||||
Local<String> json_string) {
|
||||
PREPARE_FOR_EXECUTION(context, "JSON::Parse", Value);
|
||||
i::Handle<i::String> string = Utils::OpenHandle(*json_string);
|
||||
i::Handle<i::String> source = i::String::Flatten(string);
|
||||
auto maybe = source->IsSeqOneByteString()
|
||||
? i::JsonParser<true>::Parse(source)
|
||||
: i::JsonParser<false>::Parse(source);
|
||||
Local<Value> result;
|
||||
has_pending_exception = !ToLocal<Value>(maybe, &result);
|
||||
RETURN_ON_FAILED_EXECUTION(Value);
|
||||
RETURN_ESCAPED(result);
|
||||
}
|
||||
|
||||
Local<Value> JSON::Parse(Local<String> json_string) {
|
||||
RETURN_TO_LOCAL_UNCHECKED(Parse(Local<Context>(), json_string), Value);
|
||||
}
|
||||
|
||||
MaybeLocal<String> JSON::Stringify(Local<Context> context,
|
||||
Local<Object> json_object) {
|
||||
PREPARE_FOR_EXECUTION(context, "JSON::Stringify", String);
|
||||
i::Handle<i::Object> object = Utils::OpenHandle(*json_object);
|
||||
i::Handle<i::Object> maybe;
|
||||
has_pending_exception =
|
||||
!i::Runtime::BasicJsonStringify(isolate, object).ToHandle(&maybe);
|
||||
RETURN_ON_FAILED_EXECUTION(String);
|
||||
Local<String> result;
|
||||
has_pending_exception =
|
||||
!ToLocal<String>(i::Object::ToString(isolate, maybe), &result);
|
||||
RETURN_ON_FAILED_EXECUTION(String);
|
||||
RETURN_ESCAPED(result);
|
||||
}
|
||||
|
||||
// --- D a t a ---
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include "src/char-predicates-inl.h"
|
||||
#include "src/isolate-inl.h"
|
||||
#include "src/json-parser.h"
|
||||
#include "src/json-stringifier.h"
|
||||
#include "src/objects-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -20,23 +19,20 @@ RUNTIME_FUNCTION(Runtime_QuoteJSONString) {
|
||||
DCHECK(args.length() == 1);
|
||||
Handle<Object> result;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, result, BasicJsonStringifier::StringifyString(isolate, string));
|
||||
isolate, result, Runtime::BasicJsonStringifyString(isolate, string));
|
||||
return *result;
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_BasicJSONStringify) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK(args.length() == 1);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
|
||||
BasicJsonStringifier stringifier(isolate);
|
||||
Handle<Object> result;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
|
||||
stringifier.Stringify(object));
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, result, Runtime::BasicJsonStringify(isolate, object));
|
||||
return *result;
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_ParseJson) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "src/bootstrapper.h"
|
||||
#include "src/debug/debug.h"
|
||||
#include "src/isolate-inl.h"
|
||||
#include "src/json-stringifier.h"
|
||||
#include "src/messages.h"
|
||||
#include "src/property-descriptor.h"
|
||||
#include "src/runtime/runtime.h"
|
||||
@ -225,6 +226,15 @@ MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
|
||||
return value;
|
||||
}
|
||||
|
||||
MaybeHandle<Object> Runtime::BasicJsonStringify(Isolate* isolate,
|
||||
Handle<Object> object) {
|
||||
return BasicJsonStringifier(isolate).Stringify(object);
|
||||
}
|
||||
|
||||
MaybeHandle<Object> Runtime::BasicJsonStringifyString(Isolate* isolate,
|
||||
Handle<String> string) {
|
||||
return BasicJsonStringifier::StringifyString(isolate, string);
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_GetPrototype) {
|
||||
HandleScope scope(isolate);
|
||||
|
@ -1110,6 +1110,12 @@ class Runtime : public AllStatic {
|
||||
MUST_USE_RESULT static MaybeHandle<Object> GetObjectProperty(
|
||||
Isolate* isolate, Handle<Object> object, Handle<Object> key);
|
||||
|
||||
MUST_USE_RESULT static MaybeHandle<Object> BasicJsonStringify(
|
||||
Isolate* isolate, Handle<Object> object);
|
||||
|
||||
MUST_USE_RESULT static MaybeHandle<Object> BasicJsonStringifyString(
|
||||
Isolate* isolate, Handle<String> string);
|
||||
|
||||
enum TypedArrayId {
|
||||
// arrayIds below should be synchronized with typedarray.js natives.
|
||||
ARRAY_ID_UINT8 = 1,
|
||||
|
@ -21947,29 +21947,39 @@ THREADED_TEST(Regress260106) {
|
||||
CHECK(function->IsFunction());
|
||||
}
|
||||
|
||||
|
||||
THREADED_TEST(JSONParseObject) {
|
||||
LocalContext context;
|
||||
HandleScope scope(context->GetIsolate());
|
||||
Local<Value> obj =
|
||||
v8::JSON::Parse(context->GetIsolate(), v8_str("{\"x\":42}"))
|
||||
.ToLocalChecked();
|
||||
v8::JSON::Parse(context.local(), v8_str("{\"x\":42}")).ToLocalChecked();
|
||||
Local<Object> global = context->Global();
|
||||
global->Set(context.local(), v8_str("obj"), obj).FromJust();
|
||||
ExpectString("JSON.stringify(obj)", "{\"x\":42}");
|
||||
}
|
||||
|
||||
|
||||
THREADED_TEST(JSONParseNumber) {
|
||||
LocalContext context;
|
||||
HandleScope scope(context->GetIsolate());
|
||||
Local<Value> obj =
|
||||
v8::JSON::Parse(context->GetIsolate(), v8_str("42")).ToLocalChecked();
|
||||
v8::JSON::Parse(context.local(), v8_str("42")).ToLocalChecked();
|
||||
Local<Object> global = context->Global();
|
||||
global->Set(context.local(), v8_str("obj"), obj).FromJust();
|
||||
ExpectString("JSON.stringify(obj)", "42");
|
||||
}
|
||||
|
||||
THREADED_TEST(JSONStringifyObject) {
|
||||
LocalContext context;
|
||||
HandleScope scope(context->GetIsolate());
|
||||
Local<Value> value =
|
||||
v8::JSON::Parse(context.local(), v8_str("{\"x\":42}")).ToLocalChecked();
|
||||
Local<Object> obj = value->ToObject(context.local()).ToLocalChecked();
|
||||
Local<Object> global = context->Global();
|
||||
global->Set(context.local(), v8_str("obj"), obj).FromJust();
|
||||
Local<String> json =
|
||||
v8::JSON::Stringify(context.local(), obj).ToLocalChecked();
|
||||
v8::String::Utf8Value utf8(json);
|
||||
ExpectString("JSON.stringify(obj)", *utf8);
|
||||
}
|
||||
|
||||
#if V8_OS_POSIX && !V8_OS_NACL
|
||||
class ThreadInterruptTest {
|
||||
|
@ -26,6 +26,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
v8::JSON::Parse(isolate, source).IsEmpty();
|
||||
v8::JSON::Parse(support->GetContext(), source).IsEmpty();
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user