@@ -76,7 +76,7 @@ const v8::Local<v8::String> transformJSObject(v8::Isolate* isolate, v8::Local<v8
76
76
auto objToString = object->ToString (isolate);
77
77
v8::Local<v8::String> resultString;
78
78
79
- auto hasCustomToStringImplementation = !objToString-> SameValue ( ArgConverter::ConvertToV8String (isolate, " [object Object]" )) ;
79
+ auto hasCustomToStringImplementation = ArgConverter::ConvertToString (objToString). find ( " [object Object]" ) == std::string::npos ;
80
80
81
81
if (hasCustomToStringImplementation) {
82
82
resultString = objToString;
@@ -87,6 +87,52 @@ const v8::Local<v8::String> transformJSObject(v8::Isolate* isolate, v8::Local<v8
87
87
return resultString;
88
88
}
89
89
90
+ const v8::Local<v8::String> buildStringFromArg (v8::Isolate* isolate, const v8::Local<v8::Value>& val) {
91
+ v8::Local<v8::String> argString;
92
+ if (val->IsFunction ()) {
93
+ val->ToDetailString (isolate->GetCurrentContext ()).ToLocal (&argString);
94
+ } else if (val->IsArray ()) {
95
+ auto cachedSelf = val;
96
+ auto array = val->ToObject ();
97
+ auto arrayEntryKeys = array->GetPropertyNames (isolate->GetCurrentContext ()).ToLocalChecked ();
98
+ auto context = isolate->GetCurrentContext ();
99
+
100
+ auto arrayLength = arrayEntryKeys->Length ();
101
+
102
+ argString = ArgConverter::ConvertToV8String (isolate, " [" );
103
+
104
+ for (int i = 0 ; i < arrayLength; i++) {
105
+ auto propertyName = arrayEntryKeys->Get (context, i).ToLocalChecked ();
106
+
107
+ auto propertyValue = array->Get (context, propertyName).ToLocalChecked ();
108
+
109
+ // avoid bottomless recursion with cyclic reference to the same array
110
+ if (propertyValue->StrictEquals (cachedSelf)) {
111
+ argString = v8::String::Concat (argString, ArgConverter::ConvertToV8String (isolate, " [Circular]" ));
112
+ continue ;
113
+ }
114
+
115
+ auto objectString = buildStringFromArg (isolate, propertyValue);
116
+
117
+ argString = v8::String::Concat (argString, objectString);
118
+
119
+ if (i != arrayLength - 1 ) {
120
+ argString = v8::String::Concat (argString, ArgConverter::ConvertToV8String (isolate, " , " ));
121
+ }
122
+ }
123
+
124
+ argString = v8::String::Concat (argString, ArgConverter::ConvertToV8String (isolate, " ]" ));
125
+ } else if (val->IsObject ()) {
126
+ v8::Local<v8::Object> obj = val.As <v8::Object>();
127
+
128
+ argString = transformJSObject (isolate, obj);
129
+ } else {
130
+ val->ToDetailString (isolate->GetCurrentContext ()).ToLocal (&argString);
131
+ }
132
+
133
+ return argString;
134
+ }
135
+
90
136
const std::string buildLogString (const v8::FunctionCallbackInfo<v8::Value>& info, int startingIndex = 0 ) {
91
137
auto isolate = info.GetIsolate ();
92
138
@@ -98,15 +144,8 @@ const std::string buildLogString(const v8::FunctionCallbackInfo<v8::Value>& info
98
144
if (argLen) {
99
145
for (int i = startingIndex; i < argLen; i++) {
100
146
v8::Local<v8::String> argString;
101
- if (info[i]->IsFunction ()) {
102
- info[i]->ToDetailString (isolate->GetCurrentContext ()).ToLocal (&argString);
103
- } else if (info[i]->IsObject ()) {
104
- v8::Local<v8::Object> obj = info[i].As <v8::Object>();
105
-
106
- argString = transformJSObject (isolate, obj);
107
- } else {
108
- info[i]->ToDetailString (isolate->GetCurrentContext ()).ToLocal (&argString);
109
- }
147
+
148
+ argString = buildStringFromArg (isolate, info[i]);
110
149
111
150
// separate args with a space
112
151
if (i != 0 ) {
0 commit comments