Skip to content
This repository was archived by the owner on Oct 15, 2020. It is now read-only.

Commit 4be96a0

Browse files
boingoingkfarnung
authored andcommitted
chakrashim: add shim for JSON methods
Add v8::JSON::Parse and v8::JSON::Stringify to chakrashim. Also fixes some cpplint errors in v8.h and adds v8.h to the set of files we lint in vcbuild.bat. Fix the MacOS build to make sure that all chakrashim exports are re-exported by node. PR-URL: #313 Reviewed-By: Kunal Pathak <kunal.pathak@microsoft.com> Reviewed-By: Kyle Farnung <kfarnung@microsoft.com> Reviewed-By: Jimmy Thomson <jithomso@microsoft.com>
1 parent 360e93e commit 4be96a0

File tree

12 files changed

+206
-30
lines changed

12 files changed

+206
-30
lines changed

deps/chakrashim/chakrashim.gyp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
'src/v8int32.cc',
133133
'src/v8integer.cc',
134134
'src/v8isolate.cc',
135+
'src/v8json.cc',
135136
'src/v8map.cc',
136137
'src/v8message.cc',
137138
'src/v8microtasksscope.cc',

deps/chakrashim/include/v8.h

Lines changed: 56 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2626
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2727

28-
#pragma once
28+
#ifndef DEPS_CHAKRASHIM_INCLUDE_V8_H_
29+
#define DEPS_CHAKRASHIM_INCLUDE_V8_H_
2930

3031
// Stops windows.h from including winsock.h (conflicting with winsock2.h).
3132
#ifndef _WINSOCKAPI_
@@ -324,6 +325,7 @@ class Local {
324325
friend class TryCatch;
325326
friend class UnboundScript;
326327
friend class Value;
328+
friend class JSON;
327329
template <class F> friend class FunctionCallbackInfo;
328330
template <class F> friend class MaybeLocal;
329331
template <class F> friend class PersistentBase;
@@ -364,7 +366,7 @@ class MaybeLocal {
364366
public:
365367
MaybeLocal() : val_(nullptr) {}
366368
template <class S>
367-
MaybeLocal(Local<S> that)
369+
MaybeLocal(Local<S> that) // NOLINT(runtime/explicit)
368370
: val_(reinterpret_cast<T*>(*that)) {
369371
TYPE_CHECK(T, S);
370372
}
@@ -821,6 +823,7 @@ class ScriptOrigin {
821823
V8_INLINE Local<Integer> ScriptID() const {
822824
return script_id_;
823825
}
826+
824827
private:
825828
Local<Value> resource_name_;
826829
Local<Integer> resource_line_offset_;
@@ -886,7 +889,8 @@ class V8_EXPORT ScriptCompiler {
886889
: source_string(source_string), resource_name(origin.ResourceName()) {
887890
}
888891

889-
Source(Local<String> source_string, CachedData * cached_data = NULL)
892+
Source(Local<String> source_string, // NOLINT(runtime/explicit)
893+
CachedData * cached_data = NULL)
890894
: source_string(source_string) {
891895
}
892896

@@ -995,7 +999,9 @@ class V8_EXPORT StackFrame {
995999

9961000
enum class PromiseHookType { kInit, kResolve, kBefore, kAfter };
9971001

998-
typedef void(*PromiseHook)(PromiseHookType type, Local<Promise> promise, Local<Value> parent);
1002+
typedef void(*PromiseHook)(PromiseHookType type,
1003+
Local<Promise> promise,
1004+
Local<Value> parent);
9991005

10001006

10011007
class V8_EXPORT Value : public Data {
@@ -1283,7 +1289,7 @@ class V8_EXPORT Symbol : public Name {
12831289
public:
12841290
// Returns the print name string of the symbol, or undefined if none.
12851291
Local<Value> Name() const;
1286-
static Local<Symbol> New(Isolate* isolate,
1292+
static Local<Symbol> New(Isolate* isolate,
12871293
Local<String> name = Local<String>());
12881294
static Symbol* Cast(Value* obj);
12891295

@@ -1354,8 +1360,9 @@ class V8_EXPORT Object : public Value {
13541360
Local<Context> context, Local<Name> key, Local<Value> value,
13551361
PropertyAttribute attributes = None);
13561362

1357-
V8_WARN_UNUSED_RESULT Maybe<bool> DefineProperty(
1358-
Local<Context> context, Local<Name>, PropertyDescriptor& decriptor);
1363+
V8_WARN_UNUSED_RESULT Maybe<bool> DefineProperty(Local<Context> context,
1364+
Local<Name>,
1365+
PropertyDescriptor& decriptor); // NOLINT(runtime/references)
13591366

13601367
V8_DEPRECATE_SOON("Use maybe version",
13611368
bool ForceSet(Handle<Value> key, Handle<Value> value,
@@ -1764,16 +1771,17 @@ enum class ConstructorBehavior { kThrow, kAllow };
17641771

17651772
class V8_EXPORT Function : public Object {
17661773
public:
1767-
static MaybeLocal<Function> New(Local<Context> context,
1768-
FunctionCallback callback,
1769-
Local<Value> data = Local<Value>(),
1770-
int length = 0,
1771-
ConstructorBehavior behavior = ConstructorBehavior::kAllow);
1774+
static MaybeLocal<Function> New(
1775+
Local<Context> context,
1776+
FunctionCallback callback,
1777+
Local<Value> data = Local<Value>(),
1778+
int length = 0,
1779+
ConstructorBehavior behavior = ConstructorBehavior::kAllow);
17721780
static V8_DEPRECATE_SOON("Use maybe version",
1773-
Local<Function> New(Isolate* isolate,
1774-
FunctionCallback callback,
1775-
Local<Value> data = Local<Value>(),
1776-
int length = 0));
1781+
Local<Function> New(Isolate* isolate,
1782+
FunctionCallback callback,
1783+
Local<Value> data = Local<Value>(),
1784+
int length = 0));
17771785

17781786
V8_DEPRECATE_SOON("Use maybe version",
17791787
Local<Object> NewInstance(int argc,
@@ -1847,6 +1855,7 @@ class V8_EXPORT Promise : public Object {
18471855

18481856
bool HasHandler();
18491857
static Promise* Cast(Value* obj);
1858+
18501859
private:
18511860
Promise();
18521861
};
@@ -2061,17 +2070,32 @@ class V8_EXPORT Float64Array : public TypedArray {
20612070
};
20622071

20632072
class V8_EXPORT SharedArrayBuffer : public Object {
2064-
public:
2073+
public:
20652074
static SharedArrayBuffer* Cast(Value* obj);
20662075

2067-
private:
2076+
private:
20682077
SharedArrayBuffer();
20692078
};
20702079

2080+
class V8_EXPORT JSON {
2081+
public:
2082+
static V8_DEPRECATED("Use the maybe version taking context",
2083+
Local<Value> Parse(Local<String> json_string));
2084+
static V8_DEPRECATE_SOON("Use the maybe version taking context",
2085+
MaybeLocal<Value> Parse(Isolate* isolate,
2086+
Local<String> json_string));
2087+
static V8_WARN_UNUSED_RESULT MaybeLocal<Value> Parse(
2088+
Local<Context> context, Local<String> json_string);
2089+
2090+
static V8_WARN_UNUSED_RESULT MaybeLocal<String> Stringify(
2091+
Local<Context> context, Local<Object> json_object,
2092+
Local<String> gap = Local<String>());
2093+
};
2094+
20712095
class V8_EXPORT ValueSerializer {
2072-
public:
2096+
public:
20732097
class V8_EXPORT Delegate {
2074-
public:
2098+
public:
20752099
virtual ~Delegate() {}
20762100

20772101
virtual void ThrowDataCloneError(Local<String> message) = 0;
@@ -2099,15 +2123,15 @@ class V8_EXPORT ValueSerializer {
20992123
void WriteDouble(double value);
21002124
void WriteRawBytes(const void* source, size_t length);
21012125

2102-
private:
2126+
private:
21032127
ValueSerializer(const ValueSerializer&) = delete;
21042128
void operator=(const ValueSerializer&) = delete;
21052129
};
21062130

21072131
class V8_EXPORT ValueDeserializer {
2108-
public:
2132+
public:
21092133
class V8_EXPORT Delegate {
2110-
public:
2134+
public:
21112135
virtual ~Delegate() {}
21122136

21132137
virtual MaybeLocal<Object> ReadHostObject(Isolate* isolate);
@@ -2129,7 +2153,7 @@ class V8_EXPORT ValueDeserializer {
21292153
V8_WARN_UNUSED_RESULT bool ReadDouble(double* value);
21302154
V8_WARN_UNUSED_RESULT bool ReadRawBytes(size_t length, const void** data);
21312155

2132-
private:
2156+
private:
21332157
ValueDeserializer(const ValueDeserializer&) = delete;
21342158
void operator=(const ValueDeserializer&) = delete;
21352159
};
@@ -2354,7 +2378,7 @@ class V8_EXPORT Exception {
23542378
};
23552379

23562380
class V8_EXPORT MicrotasksScope {
2357-
public:
2381+
public:
23582382
enum Type { kRunMicrotasks, kDoNotRunMicrotasks };
23592383

23602384
MicrotasksScope(Isolate* isolate, Type type);
@@ -2532,8 +2556,11 @@ class V8_EXPORT Isolate {
25322556
};
25332557

25342558
static Isolate* NewWithTTDSupport(const CreateParams& params,
2535-
size_t optReplayUriLength, const char* optReplayUri,
2536-
bool doRecord, bool doReplay, bool doDebug,
2559+
size_t optReplayUriLength,
2560+
const char* optReplayUri,
2561+
bool doRecord,
2562+
bool doReplay,
2563+
bool doDebug,
25372564
uint32_t snapInterval,
25382565
uint32_t snapHistoryLength);
25392566
static Isolate* New(const CreateParams& params);
@@ -3023,3 +3050,5 @@ Isolate* PropertyCallbackInfo<T>::GetIsolate() const {
30233050
}
30243051

30253052
} // namespace v8
3053+
3054+
#endif // DEPS_CHAKRASHIM_INCLUDE_V8_H_

deps/chakrashim/lib/chakra_shim.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@
3838
Set_values = Set.prototype.values,
3939
Symbol_keyFor = Symbol.keyFor,
4040
Symbol_for = Symbol.for,
41-
Global_ParseInt = parseInt;
41+
Global_ParseInt = parseInt,
42+
JSON_parse = JSON.parse,
43+
JSON_stringify = JSON.stringify;
4244
var BuiltInError = Error;
4345
var global = this;
4446

@@ -585,6 +587,12 @@
585587
utils.getSymbolFor = function(key) {
586588
return Symbol_for(key);
587589
};
590+
utils.jsonParse = function(text, reviver) {
591+
return JSON_parse(text, reviver);
592+
};
593+
utils.jsonStringify = function(value, replacer, space) {
594+
return JSON_stringify(value, replacer, space);
595+
};
588596
utils.ensureDebug = ensureDebug;
589597
utils.enqueueMicrotask = function(task) {
590598
microTasks.push(task);

deps/chakrashim/src/jsrtcachedpropertyidref.inc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ DEF(getLineNumber)
8383
DEF(prototype)
8484
DEF(toString)
8585
DEF(valueOf)
86+
DEF(jsonParse)
87+
DEF(jsonStringify)
8688

8789
DEF(arguments)
8890
DEF(breakpointId)

deps/chakrashim/src/jsrtcontextshim.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ ContextShim::ContextShim(IsolateShim * isolateShim,
9999
enqueueMicrotaskFunction(JS_INVALID_REFERENCE),
100100
dequeueMicrotaskFunction(JS_INVALID_REFERENCE),
101101
getPropertyAttributesFunction(JS_INVALID_REFERENCE),
102-
getOwnPropertyNamesFunction(JS_INVALID_REFERENCE) {
102+
getOwnPropertyNamesFunction(JS_INVALID_REFERENCE),
103+
jsonParseFunction(JS_INVALID_REFERENCE),
104+
jsonStringifyFunction(JS_INVALID_REFERENCE) {
103105
memset(globalConstructor, 0, sizeof(globalConstructor));
104106
memset(globalPrototypeFunction, 0, sizeof(globalPrototypeFunction));
105107
}
@@ -635,6 +637,8 @@ CHAKRASHIM_FUNCTION_GETTER(enqueueMicrotask);
635637
CHAKRASHIM_FUNCTION_GETTER(dequeueMicrotask);
636638
CHAKRASHIM_FUNCTION_GETTER(getPropertyAttributes);
637639
CHAKRASHIM_FUNCTION_GETTER(getOwnPropertyNames);
640+
CHAKRASHIM_FUNCTION_GETTER(jsonParse);
641+
CHAKRASHIM_FUNCTION_GETTER(jsonStringify);
638642

639643
#define DEF_IS_TYPE(F) CHAKRASHIM_FUNCTION_GETTER(F)
640644
#include "jsrtcachedpropertyidref.inc"

deps/chakrashim/src/jsrtcontextshim.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ class ContextShim {
167167
DECLARE_CHAKRASHIM_FUNCTION_GETTER(dequeueMicrotask);
168168
DECLARE_CHAKRASHIM_FUNCTION_GETTER(getPropertyAttributes);
169169
DECLARE_CHAKRASHIM_FUNCTION_GETTER(getOwnPropertyNames);
170+
DECLARE_CHAKRASHIM_FUNCTION_GETTER(jsonParse);
171+
DECLARE_CHAKRASHIM_FUNCTION_GETTER(jsonStringify);
170172
};
171173

172174
} // namespace jsrt

deps/chakrashim/src/v8json.cc

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright Microsoft. All rights reserved.
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy
4+
// of this software and associated documentation files(the "Software"), to
5+
// deal in the Software without restriction, including without limitation the
6+
// rights to use, copy, modify, merge, publish, distribute, sublicense, and / or
7+
// sell copies of the Software, and to permit persons to whom the Software is
8+
// furnished to do so, subject to the following conditions :
9+
//
10+
// The above copyright notice and this permission notice shall be included in
11+
// all copies or substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
16+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19+
// IN THE SOFTWARE.
20+
21+
#include "v8chakra.h"
22+
23+
namespace v8 {
24+
Local<Value> JSON::Parse(Local<String> json_string) {
25+
v8::Isolate* iso = jsrt::IsolateShim::GetCurrentAsIsolate();
26+
return FromMaybe(JSON::Parse(iso, json_string));
27+
}
28+
29+
MaybeLocal<Value> JSON::Parse(Isolate* isolate,
30+
Local<String> json_string) {
31+
Local<Context> context = isolate->GetCurrentContext();
32+
return JSON::Parse(context, json_string);
33+
}
34+
35+
MaybeLocal<Value> JSON::Parse(Local<Context> context,
36+
Local<String> json_string) {
37+
jsrt::ContextShim *contextShim = jsrt::IsolateShim::GetContextShim(
38+
(JsContextRef)*context);
39+
40+
JsValueRef jsonParseFunction = contextShim->GetjsonParseFunction();
41+
JsValueRef obj = JS_INVALID_REFERENCE;
42+
43+
if (jsrt::CallFunction(jsonParseFunction, (JsValueRef)*json_string,
44+
&obj) != JsNoError) {
45+
return Local<Value>();
46+
}
47+
48+
return Local<Value>::New(obj);
49+
}
50+
51+
MaybeLocal<String> JSON::Stringify(Local<Context> context,
52+
Local<Object> json_object,
53+
Local<String> gap) {
54+
jsrt::ContextShim *contextShim = jsrt::IsolateShim::GetContextShim(
55+
(JsContextRef)*context);
56+
57+
JsValueRef jsonStringifyFunction = contextShim->GetjsonStringifyFunction();
58+
JsValueRef str = JS_INVALID_REFERENCE;
59+
JsValueRef actualGap =
60+
gap.IsEmpty() ? jsrt::GetUndefined() : static_cast<JsValueRef>(*gap);
61+
62+
if (jsrt::CallFunction(jsonStringifyFunction, (JsValueRef)*json_object,
63+
jsrt::GetUndefined(), actualGap, &str) != JsNoError) {
64+
return Local<String>();
65+
}
66+
67+
return Local<String>::New(str);
68+
}
69+
} // namespace v8

node.gypi

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,16 @@
246246
'dependencies': [
247247
'deps/chakrashim/chakrashim.gyp:chakrashim'
248248
],
249+
'conditions': [
250+
# -force_load is not applicable for the static library
251+
[ 'node_target_type!="static_library"', {
252+
'xcode_settings': {
253+
'OTHER_LDFLAGS': [
254+
'-Wl,-force_load,<(CHAKRASHIM_BASE)',
255+
],
256+
},
257+
}],
258+
],
249259
}],
250260
[ 'node_shared_zlib=="false"', {
251261
'dependencies': [ 'deps/zlib/zlib.gyp:zlib' ],

test/addons/json/binding.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include <node.h>
2+
#include <v8.h>
3+
4+
namespace {
5+
6+
void Stringify(const v8::FunctionCallbackInfo<v8::Value>& args) {
7+
auto result = v8::JSON::Stringify(args.GetIsolate()->GetCurrentContext(),
8+
args[0].As<v8::Object>(),
9+
args[1].As<v8::String>());
10+
args.GetReturnValue().Set(result.ToLocalChecked());
11+
}
12+
13+
void Parse(const v8::FunctionCallbackInfo<v8::Value>& args) {
14+
auto result = v8::JSON::Parse(args.GetIsolate()->GetCurrentContext(),
15+
args[0].As<v8::String>());
16+
args.GetReturnValue().Set(result.ToLocalChecked());
17+
}
18+
19+
inline void Initialize(v8::Local<v8::Object> binding) {
20+
NODE_SET_METHOD(binding, "stringify", Stringify);
21+
NODE_SET_METHOD(binding, "parse", Parse);
22+
}
23+
24+
NODE_MODULE(binding, Initialize)
25+
26+
} // anonymous namespace

test/addons/json/binding.gyp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
'targets': [
3+
{
4+
'target_name': 'binding',
5+
'defines': [ 'V8_DEPRECATION_WARNINGS=1' ],
6+
'sources': [ 'binding.cc' ]
7+
}
8+
]
9+
}

0 commit comments

Comments
 (0)