300x250 AD TOP

Search This Blog

Pages

Paling Dilihat

Powered by Blogger.

Showing posts with label node. Show all posts
Showing posts with label node. Show all posts

Friday, May 26, 2017

Node js C++ Addon Overload Resolution - v1.2.0

Major feature implemented for namespace and class wrapping, no more SetMethod/SetPrototypeMethod and target tracking, all is done automatically. 


Since its inefficient to write so much code, while making sure SetMethod and SetPrototypeMethod is called on each overload and track the namespaces used to store the callbacks manually, an experimental namespace_wrap and class_wrap were introduced, these two classes wrap the needed calls as well as track the targets (v8::Object).
The wrappers do add overhead to function execution time but it didn't even register when I did performance analysis.
to use the wrappers you'll need to initialize an overload_resolution instance normally but also start tracking a root target:
void init(v8::Handle<v8::Object> target) {
 auto overload = std::make_shared<overload_resolution>();
 auto base_overload = overload->register_module(target);
    ...
}
NODE_MODULE(tester, init);
once you have the base_overload you can start attaching methods:
base_overload->add_overload("standalone_function_construct", {}, standalone_function_construct);
nest methods:
auto nested = base_overload->add_namespace("namespace_construct");
nested->add_overload("nc_standalone_function_construct", {}, nc_standalone_function_construct_nc);
add classes:
auto class_def = base_overload->add_class("class_constructs");
class_def->add_overload_constructor({}, New);
class_def->add_static_overload("test_static", {}, test_static);
class_def->add_overload("test_member", {}, test_member);

constructor.Reset(class_def->done<class_constructs>());
note: you must call done<T>() when you're done defining the class methods, otherwise the class won't register in both the overload_resolution and V8.
for now classes can be nested inside namespaces but not the other way around, though it should be theoretically possible.

Minor build and bug fixes:
- integration with node-addon-tracer npm package so build is simpler.
- expose node-overload-resolution as an npm module, so require("node-overload-resolution") works in parent module gyp files.
- remove support for node 0.11
- fix travis ci builds

Tags: , ,

Friday, January 13, 2017

Node OpenCV Addon

I'm glad to finally say I have a good start as far as I can tell for implementing a good OpenCV addon for node js.

Its not a sprint but a marathon, OpenCV is one of the largest, most complex libraries I had to deal with and I've tested many ways to implement it. finally found a sound way to actually do it.


The adventure started some time ago when I attempted to use a few functions to display an augmented reality diffusion tensor file on a marker with a tablet (I got some help from Frank from DSI Studio, Thanks Frank!), it later became a challenge as I learned more and more about C++, Node js and OpenCV.


The first few things I've tried was using ffmpeg api in node js, ffmpeg is written in C, which lacks automatic object lifetime management (constructors/destructors) but contains allocators where you need to explicitly free unused objects and buffers.


I've decided the best way was to try and implement a C++ wrapper on top of these APIs. it was challenging to find the appropriate lifecycle from the documentation but reading the C code helped a lot, eventually I've completed a C++ wrapper which could access most of ffmpeg API with an intuitive API.


The adventure didn't end there, I've used OpenCV Matrix (cv::Mat) as the base container for both image and audio frames which allowed me to explore the OpenCV API with both video and passthrough audio but with a possibility to eventually process the audio as well since its easily accessible.


I've started to explore the OpenCV API and I really liked the idea to manipulate the video frames with Node js, so I decided to implement a few of OpenCV APIs but then I thought how hard would it be to implement the entire OpenCV API in node js, so I went ahead and learned about Node Addons, V8 and NAN.


Many people think that Javascript is not suitable for processing Video/Audio but the truth of the matter is that Javascript is not really processing anything, its just a scripting engine. The real magic stays in C/C++ domain and the delay Node js/v8 adds is negligible when you see how much time compressing a frame or executing canny on it takes, those microseconds do add up, but in terms of percentage, it should be nearly invisible in the total program execution time, besides, this is more for fun than for science.

But... Javascript is not entirely suitable for scripting complex APIs and if you add the number of function overloads possible in OpenCV, it will probably be hell to use not to talk about development, this made me think in the Typescript direction, which can both help the intellisense and make development easier since it enforces some type checking at development time and that could eventually be used to make the API a lot more readable and intuitive.

A few things made developing the API not the most fun thing in the world, for example, the way v8 exposes its internal objects, everything looks like an object, all numbers are actually a double and there is no possibility to overload function implementation internally.


These reasons and more made me think and develop node-overload-resolution project, which addressed most of these problems by allowing me to add overloads to functions, add parameter validations, automatic conversion between v8 data types and C++ data types, automatically execute function implementations in the libuv threadpool as async functions and handling return values and exceptions without explicitly writing a single line of code in the addon itself.


So why am I writing all of this today?

Today the first test passed, not my tests, not all the tests, but the first OpenCV test which I ported to typescript to make sure the API is working properly.

Hopefully its not the last :-)


But let me be completely honest, it is by no way or shape ready for anything, the amount of APIs implemented are very little, even the build at the moment is complex and takes anywhere between 30 minutes to an hour. Since I've created the opencv_ts branch I didn't even check if the code compiles on linux, which it did before, on linux32/64 and even arm and NDK, sorry linux guys, in terms of IDE for C++, I have yet to see anything which comes close to Visual Studio ;-)
Tags: , ,

Saturday, October 22, 2016

Node js C++ Addon Overload Resolution


Function overloads is not part of javascript as functions are objects inside object properties and object property names are unique.


I've attempted to add overload resolution on top of node js c++ addons for easily importing c++ libraries by having a middleware between v8 and the actual code executed.


Before you read on, make sure you understand Native Abstractions for Node.js (NAN) as it relies on it for some of its functionality and builds on top of it.

You can find the project and its tests at:
https://github.com/drorgl/node-overload-resolution

Structure

overload_resolution - the main class that registers and calls the overloaded functions, it provides a macro POLY_METHOD which is almost identical to NAN_METHOD for declaring functions and calling them after the correct overload has been determined.
by itself, the class does nothing, you will still have to register all the callbacks to overload_resolution::execute function for it to do anything:
Declare a callback:
namespace general_callback {
    std::shared_ptr<overload_resolution> overload;
    NAN_METHOD(tester_callback) {
        return overload->execute("current_namespace", info);
    }
}
in the init function, populate general_callback::overload with overload resolution instance:
general_callback::overload = overload;
and tell v8 you want to callback into tester_callback:
Nan::SetMethod(target, "overloaded_function", general_callback::tester_callback);
now the hook is ready to call overload_resolution::execute whenever overloaded_function is called, but we need to tell overload_resolution which function to call when an overload is matched:
constructor:
overload->addOverloadConstructor(
            "", 
                    "constructor_class_tester", 
                            { std::make_shared<overload_info>("a","Number",Nan::Undefined()) }, 
                                    New_number);
            ^ namespace or empty
                    ^ class name 
                            ^ array of parameter names, types and default values
                              note that Nan::Undefined is used as no default
                                    ^ callback POLY_METHOD
static:
overload->addStaticOverload(
            "", 
                    "constructor_class_tester", 
                            "static_function", 
                                    { std::make_shared<overload_info>("a","String",Nan::Undefined()) }, 
                                            static_function_static_string);
            ^ namespace or empty
                    ^ class name or function group name or empty
                            ^ function name
                                    ^ array of parameter names, types and default values
                                            ^ callback POLY_METHOD
member:
overload->addOverload(
            "", 
                    "constructor_class_tester", 
                            "member_function", 
                                    { std::make_shared<overload_info>("a","Map",Nan::Undefined()) }, 
                                            static_function_instance_map);
            ^ namespace or empty
                    ^ class name
                            ^ function name
                                    ^ array of parameter names, types and default values
                                            ^ callback POLY_METHOD

Issues

Currently the project is working but inefficient, it does a lot behind the scenes to determine which overload should be called and hopefully the performance issues will be resolved in the future, the slowest actions are around structs, which are very slow, they were intended as automatic object structure recognition and overload resolution accordingly.

Tests

Attempts were made to have as many tests as possible, at the moment of this update there are 2336 tests, all pass.

Future

If there will be future development, it should do the following:
  • performance analysis, solve the struct performance, check prototype inheritance performance and correctness, check big arrays performance.
  • implement macros
  • cleanup function registration
  • add logging and instrumentation
Tags: , , ,

Saturday, September 24, 2016

Learning about V8 Objects

V8 Objects are documented thoroughly, however, reading documentation doesn't always help when you want to know how exactly it will manifest when calling a function with particular set of parameters in a particular state.

I've wrote this helper project to determine the exact values for each function call.

for example:

- calling a function without any parameters yields the following Nan::NAN_METHOD_ARGS_TYPE info

1:  {  
2:      "Length": 0,  
3:      "Callee": {  
4:          "IsUndefined": false,  
5:          "IsNull": false,  
6:          "IsTrue": false,  
7:          "IsFalse": false,  
8:          "IsName": false,  
9:          "IsString": false,  
10:          "IsSymbol": false,  
11:          "IsFunction": true,  
12:          "GetName": "test",  
13:          "GetInferredName": "",  
14:          "GetDebugName": "test",  
15:          "GetScriptLineNumber": -1,  
16:          "GetScriptColumnNumber": -1,  
17:          "IsBuiltin": true,  
18:          "ScriptId": 0,  
19:          "GetScriptOrigin": {  
20:              "Options": {  
21:                  "IsEmbedderDebugScript": false,  
22:                  "IsSharedCrossOrigin": false,  
23:                  "IsOpaque": false,  
24:                  "Flags": 0  
25:              }  
26:          },  
27:          "IsArray": false,  
28:          "IsObject": true,  
29:          "PropertyNames": [],  
30:          "GetConstructorName": "Function",  
31:          "InternalFieldCount": 0,  
32:          "HasNamedLookupInterceptor": false,  
33:          "HasIndexedLookupInterceptor": false,  
34:          "GetIdentityHash": 535707258,  
35:          "IsCallable": true,  
36:          "GetPrototype": {  
37:              "IsUndefined": false,  
38:              "IsNull": false,  
39:              "IsTrue": false,  
40:              "IsFalse": false,  
41:              "IsName": false,  
42:              "IsString": false,  
43:              "IsSymbol": false,  
44:              "IsFunction": true,  
45:              "IsArray": false,  
46:              "IsObject": true,  
47:              "IsBoolean": false,  
48:              "IsNumber": false,  
49:              "IsExternal": false,  
50:              "IsInt32": false,  
51:              "IsUint32": false,  
52:              "IsDate": false,  
53:              "IsArgumentsObject": false,  
54:              "IsBooleanObject": false,  
55:              "IsNumberObject": false,  
56:              "IsStringObject": false,  
57:              "IsSymbolObject": false,  
58:              "IsNativeError": false,  
59:              "IsRegExp": false,  
60:              "IsGeneratorFunction": false,  
61:              "IsGeneratorObject": false,  
62:              "IsPromise": false,  
63:              "IsMap": false,  
64:              "IsSet": false,  
65:              "IsMapIterator": false,  
66:              "IsSetIterator": false,  
67:              "IsWeakMap": false,  
68:              "IsWeakSet": false,  
69:              "IsArrayBuffer": false,  
70:              "IsArrayBufferView": false,  
71:              "IsTypedArray": false,  
72:              "IsUint8Array": false,  
73:              "IsUint8ClampedArray": false,  
74:              "IsInt8Array": false,  
75:              "IsUint16Array": false,  
76:              "IsInt16Array": false,  
77:              "IsUint32Array": false,  
78:              "IsInt32Array": false,  
79:              "IsFloat32Array": false,  
80:              "IsFloat64Array": false,  
81:              "IsDataView": false,  
82:              "IsSharedArrayBuffer": false,  
83:              "IsProxy": false,  
84:              "ToBoolean": true,  
85:              "ToNumber": null,  
86:              "ToString": "function () {}",  
87:              "ToDetailString": "function () {}",  
88:              "ToInteger": 0,  
89:              "ToUint32": 0,  
90:              "ToInt32": 0,  
91:              "BooleanValue": true,  
92:              "NumberValue": null,  
93:              "IntegerValue": 0,  
94:              "Uint32Value": 0,  
95:              "Int32Value": 0,  
96:              "PropertyNames": [],  
97:              "GetConstructorName": "Function",  
98:              "InternalFieldCount": 0,  
99:              "HasNamedLookupInterceptor": false,  
100:              "HasIndexedLookupInterceptor": false,  
101:              "GetIdentityHash": 2033009011,  
102:              "IsCallable": true  
103:          },  
104:          "IsBoolean": false,  
105:          "IsNumber": false,  
106:          "IsExternal": false,  
107:          "IsInt32": false,  
108:          "IsUint32": false,  
109:          "IsDate": false,  
110:          "IsArgumentsObject": false,  
111:          "IsBooleanObject": false,  
112:          "IsNumberObject": false,  
113:          "IsStringObject": false,  
114:          "IsSymbolObject": false,  
115:          "IsNativeError": false,  
116:          "IsRegExp": false,  
117:          "IsGeneratorFunction": false,  
118:          "IsGeneratorObject": false,  
119:          "IsPromise": false,  
120:          "IsMap": false,  
121:          "IsSet": false,  
122:          "IsMapIterator": false,  
123:          "IsSetIterator": false,  
124:          "IsWeakMap": false,  
125:          "IsWeakSet": false,  
126:          "IsArrayBuffer": false,  
127:          "IsArrayBufferView": false,  
128:          "IsTypedArray": false,  
129:          "IsUint8Array": false,  
130:          "IsUint8ClampedArray": false,  
131:          "IsInt8Array": false,  
132:          "IsUint16Array": false,  
133:          "IsInt16Array": false,  
134:          "IsUint32Array": false,  
135:          "IsInt32Array": false,  
136:          "IsFloat32Array": false,  
137:          "IsFloat64Array": false,  
138:          "IsDataView": false,  
139:          "IsSharedArrayBuffer": false,  
140:          "IsProxy": false,  
141:          "ToBoolean": true,  
142:          "ToNumber": null,  
143:          "ToString": "function test() { [native code] }",  
144:          "ToDetailString": "function test() { [native code] }",  
145:          "ToInteger": 0,  
146:          "ToUint32": 0,  
147:          "ToInt32": 0,  
148:          "BooleanValue": true,  
149:          "NumberValue": null,  
150:          "IntegerValue": 0,  
151:          "Uint32Value": 0,  
152:          "Int32Value": 0  
153:      },  
154:      "IsConstructCall": false,  
155:      "This": {  
156:          "IsUndefined": false,  
157:          "IsNull": false,  
158:          "IsTrue": false,  
159:          "IsFalse": false,  
160:          "IsName": false,  
161:          "IsString": false,  
162:          "IsSymbol": false,  
163:          "IsFunction": false,  
164:          "IsArray": false,  
165:          "IsObject": true,  
166:          "PropertyNames": [],  
167:          "GetConstructorName": "Object",  
168:          "InternalFieldCount": 0,  
169:          "HasNamedLookupInterceptor": false,  
170:          "HasIndexedLookupInterceptor": false,  
171:          "GetIdentityHash": 716126579,  
172:          "IsCallable": false,  
173:          "GetPrototype": {  
174:              "IsUndefined": false,  
175:              "IsNull": false,  
176:              "IsTrue": false,  
177:              "IsFalse": false,  
178:              "IsName": false,  
179:              "IsString": false,  
180:              "IsSymbol": false,  
181:              "IsFunction": false,  
182:              "IsArray": false,  
183:              "IsObject": true,  
184:              "IsBoolean": false,  
185:              "IsNumber": false,  
186:              "IsExternal": false,  
187:              "IsInt32": false,  
188:              "IsUint32": false,  
189:              "IsDate": false,  
190:              "IsArgumentsObject": false,  
191:              "IsBooleanObject": false,  
192:              "IsNumberObject": false,  
193:              "IsStringObject": false,  
194:              "IsSymbolObject": false,  
195:              "IsNativeError": false,  
196:              "IsRegExp": false,  
197:              "IsGeneratorFunction": false,  
198:              "IsGeneratorObject": false,  
199:              "IsPromise": false,  
200:              "IsMap": false,  
201:              "IsSet": false,  
202:              "IsMapIterator": false,  
203:              "IsSetIterator": false,  
204:              "IsWeakMap": false,  
205:              "IsWeakSet": false,  
206:              "IsArrayBuffer": false,  
207:              "IsArrayBufferView": false,  
208:              "IsTypedArray": false,  
209:              "IsUint8Array": false,  
210:              "IsUint8ClampedArray": false,  
211:              "IsInt8Array": false,  
212:              "IsUint16Array": false,  
213:              "IsInt16Array": false,  
214:              "IsUint32Array": false,  
215:              "IsInt32Array": false,  
216:              "IsFloat32Array": false,  
217:              "IsFloat64Array": false,  
218:              "IsDataView": false,  
219:              "IsSharedArrayBuffer": false,  
220:              "IsProxy": false,  
221:              "ToBoolean": true,  
222:              "ToNumber": null,  
223:              "ToString": "[object Object]",  
224:              "ToDetailString": "#<Object>",  
225:              "ToObject": {},  
226:              "ToInteger": 0,  
227:              "ToUint32": 0,  
228:              "ToInt32": 0,  
229:              "BooleanValue": true,  
230:              "NumberValue": null,  
231:              "IntegerValue": 0,  
232:              "Uint32Value": 0,  
233:              "Int32Value": 0,  
234:              "PropertyNames": [],  
235:              "GetConstructorName": "Object",  
236:              "InternalFieldCount": 0,  
237:              "HasNamedLookupInterceptor": false,  
238:              "HasIndexedLookupInterceptor": false,  
239:              "GetIdentityHash": 1536014436,  
240:              "IsCallable": false  
241:          },  
242:          "IsBoolean": false,  
243:          "IsNumber": false,  
244:          "IsExternal": false,  
245:          "IsInt32": false,  
246:          "IsUint32": false,  
247:          "IsDate": false,  
248:          "IsArgumentsObject": false,  
249:          "IsBooleanObject": false,  
250:          "IsNumberObject": false,  
251:          "IsStringObject": false,  
252:          "IsSymbolObject": false,  
253:          "IsNativeError": false,  
254:          "IsRegExp": false,  
255:          "IsGeneratorFunction": false,  
256:          "IsGeneratorObject": false,  
257:          "IsPromise": false,  
258:          "IsMap": false,  
259:          "IsSet": false,  
260:          "IsMapIterator": false,  
261:          "IsSetIterator": false,  
262:          "IsWeakMap": false,  
263:          "IsWeakSet": false,  
264:          "IsArrayBuffer": false,  
265:          "IsArrayBufferView": false,  
266:          "IsTypedArray": false,  
267:          "IsUint8Array": false,  
268:          "IsUint8ClampedArray": false,  
269:          "IsInt8Array": false,  
270:          "IsUint16Array": false,  
271:          "IsInt16Array": false,  
272:          "IsUint32Array": false,  
273:          "IsInt32Array": false,  
274:          "IsFloat32Array": false,  
275:          "IsFloat64Array": false,  
276:          "IsDataView": false,  
277:          "IsSharedArrayBuffer": false,  
278:          "IsProxy": false,  
279:          "ToBoolean": true,  
280:          "ToNumber": null,  
281:          "ToString": "[object Object]",  
282:          "ToDetailString": "#<Object>",  
283:          "ToObject": {},  
284:          "ToInteger": 0,  
285:          "ToUint32": 0,  
286:          "ToInt32": 0,  
287:          "BooleanValue": true,  
288:          "NumberValue": null,  
289:          "IntegerValue": 0,  
290:          "Uint32Value": 0,  
291:          "Int32Value": 0  
292:      },  
293:      "Info": []  
294:  }  


- calling a member function (prototype) yields:

1:   {  
2:      "Length": 0,  
3:      "Callee": {  
4:          "IsUndefined": false,  
5:          "IsNull": false,  
6:          "IsTrue": false,  
7:          "IsFalse": false,  
8:          "IsName": false,  
9:          "IsString": false,  
10:          "IsSymbol": false,  
11:          "IsFunction": true,  
12:          "GetName": "test_member_function",  
13:          "GetInferredName": "",  
14:          "GetDebugName": "test_member_function",  
15:          "GetScriptLineNumber": -1,  
16:          "GetScriptColumnNumber": -1,  
17:          "IsBuiltin": true,  
18:          "ScriptId": 0,  
19:          "GetScriptOrigin": {  
20:              "Options": {  
21:                  "IsEmbedderDebugScript": false,  
22:                  "IsSharedCrossOrigin": false,  
23:                  "IsOpaque": false,  
24:                  "Flags": 0  
25:              }  
26:          },  
27:          "IsArray": false,  
28:          "IsObject": true,  
29:          "PropertyNames": [],  
30:          "GetConstructorName": "Function",  
31:          "InternalFieldCount": 0,  
32:          "HasNamedLookupInterceptor": false,  
33:          "HasIndexedLookupInterceptor": false,  
34:          "GetIdentityHash": 1864397598,  
35:          "IsCallable": true,  
36:          "GetPrototype": {  
37:              "IsUndefined": false,  
38:              "IsNull": false,  
39:              "IsTrue": false,  
40:              "IsFalse": false,  
41:              "IsName": false,  
42:              "IsString": false,  
43:              "IsSymbol": false,  
44:              "IsFunction": true,  
45:              "IsArray": false,  
46:              "IsObject": true,  
47:              "IsBoolean": false,  
48:              "IsNumber": false,  
49:              "IsExternal": false,  
50:              "IsInt32": false,  
51:              "IsUint32": false,  
52:              "IsDate": false,  
53:              "IsArgumentsObject": false,  
54:              "IsBooleanObject": false,  
55:              "IsNumberObject": false,  
56:              "IsStringObject": false,  
57:              "IsSymbolObject": false,  
58:              "IsNativeError": false,  
59:              "IsRegExp": false,  
60:              "IsGeneratorFunction": false,  
61:              "IsGeneratorObject": false,  
62:              "IsPromise": false,  
63:              "IsMap": false,  
64:              "IsSet": false,  
65:              "IsMapIterator": false,  
66:              "IsSetIterator": false,  
67:              "IsWeakMap": false,  
68:              "IsWeakSet": false,  
69:              "IsArrayBuffer": false,  
70:              "IsArrayBufferView": false,  
71:              "IsTypedArray": false,  
72:              "IsUint8Array": false,  
73:              "IsUint8ClampedArray": false,  
74:              "IsInt8Array": false,  
75:              "IsUint16Array": false,  
76:              "IsInt16Array": false,  
77:              "IsUint32Array": false,  
78:              "IsInt32Array": false,  
79:              "IsFloat32Array": false,  
80:              "IsFloat64Array": false,  
81:              "IsDataView": false,  
82:              "IsSharedArrayBuffer": false,  
83:              "IsProxy": false,  
84:              "ToBoolean": true,  
85:              "ToNumber": null,  
86:              "ToString": "function () {}",  
87:              "ToDetailString": "function () {}",  
88:              "ToInteger": 0,  
89:              "ToUint32": 0,  
90:              "ToInt32": 0,  
91:              "BooleanValue": true,  
92:              "NumberValue": null,  
93:              "IntegerValue": 0,  
94:              "Uint32Value": 0,  
95:              "Int32Value": 0,  
96:              "PropertyNames": [],  
97:              "GetConstructorName": "Function",  
98:              "InternalFieldCount": 0,  
99:              "HasNamedLookupInterceptor": false,  
100:              "HasIndexedLookupInterceptor": false,  
101:              "GetIdentityHash": 1117981863,  
102:              "IsCallable": true  
103:          },  
104:          "IsBoolean": false,  
105:          "IsNumber": false,  
106:          "IsExternal": false,  
107:          "IsInt32": false,  
108:          "IsUint32": false,  
109:          "IsDate": false,  
110:          "IsArgumentsObject": false,  
111:          "IsBooleanObject": false,  
112:          "IsNumberObject": false,  
113:          "IsStringObject": false,  
114:          "IsSymbolObject": false,  
115:          "IsNativeError": false,  
116:          "IsRegExp": false,  
117:          "IsGeneratorFunction": false,  
118:          "IsGeneratorObject": false,  
119:          "IsPromise": false,  
120:          "IsMap": false,  
121:          "IsSet": false,  
122:          "IsMapIterator": false,  
123:          "IsSetIterator": false,  
124:          "IsWeakMap": false,  
125:          "IsWeakSet": false,  
126:          "IsArrayBuffer": false,  
127:          "IsArrayBufferView": false,  
128:          "IsTypedArray": false,  
129:          "IsUint8Array": false,  
130:          "IsUint8ClampedArray": false,  
131:          "IsInt8Array": false,  
132:          "IsUint16Array": false,  
133:          "IsInt16Array": false,  
134:          "IsUint32Array": false,  
135:          "IsInt32Array": false,  
136:          "IsFloat32Array": false,  
137:          "IsFloat64Array": false,  
138:          "IsDataView": false,  
139:          "IsSharedArrayBuffer": false,  
140:          "IsProxy": false,  
141:          "ToBoolean": true,  
142:          "ToNumber": null,  
143:          "ToString": "function test_member_function() { [native code] }",  
144:          "ToDetailString": "function test_member_function() { [native code] }",  
145:          "ToInteger": 0,  
146:          "ToUint32": 0,  
147:          "ToInt32": 0,  
148:          "BooleanValue": true,  
149:          "NumberValue": null,  
150:          "IntegerValue": 0,  
151:          "Uint32Value": 0,  
152:          "Int32Value": 0  
153:      },  
154:      "IsConstructCall": false,  
155:      "This": {  
156:          "IsUndefined": false,  
157:          "IsNull": false,  
158:          "IsTrue": false,  
159:          "IsFalse": false,  
160:          "IsName": false,  
161:          "IsString": false,  
162:          "IsSymbol": false,  
163:          "IsFunction": false,  
164:          "IsArray": false,  
165:          "IsObject": true,  
166:          "PropertyNames": [],  
167:          "GetConstructorName": "base_class",  
168:          "InternalFieldCount": 1,  
169:          "HasNamedLookupInterceptor": false,  
170:          "HasIndexedLookupInterceptor": false,  
171:          "GetIdentityHash": 1554520219,  
172:          "IsCallable": false,  
173:          "GetPrototype": {  
174:              "IsUndefined": false,  
175:              "IsNull": false,  
176:              "IsTrue": false,  
177:              "IsFalse": false,  
178:              "IsName": false,  
179:              "IsString": false,  
180:              "IsSymbol": false,  
181:              "IsFunction": false,  
182:              "IsArray": false,  
183:              "IsObject": true,  
184:              "IsBoolean": false,  
185:              "IsNumber": false,  
186:              "IsExternal": false,  
187:              "IsInt32": false,  
188:              "IsUint32": false,  
189:              "IsDate": false,  
190:              "IsArgumentsObject": false,  
191:              "IsBooleanObject": false,  
192:              "IsNumberObject": false,  
193:              "IsStringObject": false,  
194:              "IsSymbolObject": false,  
195:              "IsNativeError": false,  
196:              "IsRegExp": false,  
197:              "IsGeneratorFunction": false,  
198:              "IsGeneratorObject": false,  
199:              "IsPromise": false,  
200:              "IsMap": false,  
201:              "IsSet": false,  
202:              "IsMapIterator": false,  
203:              "IsSetIterator": false,  
204:              "IsWeakMap": false,  
205:              "IsWeakSet": false,  
206:              "IsArrayBuffer": false,  
207:              "IsArrayBufferView": false,  
208:              "IsTypedArray": false,  
209:              "IsUint8Array": false,  
210:              "IsUint8ClampedArray": false,  
211:              "IsInt8Array": false,  
212:              "IsUint16Array": false,  
213:              "IsInt16Array": false,  
214:              "IsUint32Array": false,  
215:              "IsInt32Array": false,  
216:              "IsFloat32Array": false,  
217:              "IsFloat64Array": false,  
218:              "IsDataView": false,  
219:              "IsSharedArrayBuffer": false,  
220:              "IsProxy": false,  
221:              "ToBoolean": true,  
222:              "ToNumber": null,  
223:              "ToString": "[object Object]",  
224:              "ToDetailString": "#<base_class>",  
225:              "ToObject": {},  
226:              "ToInteger": 0,  
227:              "ToUint32": 0,  
228:              "ToInt32": 0,  
229:              "BooleanValue": true,  
230:              "NumberValue": null,  
231:              "IntegerValue": 0,  
232:              "Uint32Value": 0,  
233:              "Int32Value": 0,  
234:              "PropertyNames": [],  
235:              "GetConstructorName": "Object",  
236:              "InternalFieldCount": 0,  
237:              "HasNamedLookupInterceptor": false,  
238:              "HasIndexedLookupInterceptor": false,  
239:              "GetIdentityHash": 1008670604,  
240:              "IsCallable": false  
241:          },  
242:          "IsBoolean": false,  
243:          "IsNumber": false,  
244:          "IsExternal": false,  
245:          "IsInt32": false,  
246:          "IsUint32": false,  
247:          "IsDate": false,  
248:          "IsArgumentsObject": false,  
249:          "IsBooleanObject": false,  
250:          "IsNumberObject": false,  
251:          "IsStringObject": false,  
252:          "IsSymbolObject": false,  
253:          "IsNativeError": false,  
254:          "IsRegExp": false,  
255:          "IsGeneratorFunction": false,  
256:          "IsGeneratorObject": false,  
257:          "IsPromise": false,  
258:          "IsMap": false,  
259:          "IsSet": false,  
260:          "IsMapIterator": false,  
261:          "IsSetIterator": false,  
262:          "IsWeakMap": false,  
263:          "IsWeakSet": false,  
264:          "IsArrayBuffer": false,  
265:          "IsArrayBufferView": false,  
266:          "IsTypedArray": false,  
267:          "IsUint8Array": false,  
268:          "IsUint8ClampedArray": false,  
269:          "IsInt8Array": false,  
270:          "IsUint16Array": false,  
271:          "IsInt16Array": false,  
272:          "IsUint32Array": false,  
273:          "IsInt32Array": false,  
274:          "IsFloat32Array": false,  
275:          "IsFloat64Array": false,  
276:          "IsDataView": false,  
277:          "IsSharedArrayBuffer": false,  
278:          "IsProxy": false,  
279:          "ToBoolean": true,  
280:          "ToNumber": null,  
281:          "ToString": "[object base_class]",  
282:          "ToDetailString": "#<base_class>",  
283:          "ToObject": {},  
284:          "ToInteger": 0,  
285:          "ToUint32": 0,  
286:          "ToInt32": 0,  
287:          "BooleanValue": true,  
288:          "NumberValue": null,  
289:          "IntegerValue": 0,  
290:          "Uint32Value": 0,  
291:          "Int32Value": 0  
292:      },  
293:      "Info": []  
294:  }  


- calling a "static" function yields:

1:  {  
2:      "Length": 0,  
3:      "Callee": {  
4:          "IsUndefined": false,  
5:          "IsNull": false,  
6:          "IsTrue": false,  
7:          "IsFalse": false,  
8:          "IsName": false,  
9:          "IsString": false,  
10:          "IsSymbol": false,  
11:          "IsFunction": true,  
12:          "GetName": "test_static_function",  
13:          "GetInferredName": "",  
14:          "GetDebugName": "test_static_function",  
15:          "GetScriptLineNumber": -1,  
16:          "GetScriptColumnNumber": -1,  
17:          "IsBuiltin": true,  
18:          "ScriptId": 0,  
19:          "GetScriptOrigin": {  
20:              "Options": {  
21:                  "IsEmbedderDebugScript": false,  
22:                  "IsSharedCrossOrigin": false,  
23:                  "IsOpaque": false,  
24:                  "Flags": 0  
25:              }  
26:          },  
27:          "IsArray": false,  
28:          "IsObject": true,  
29:          "PropertyNames": [],  
30:          "GetConstructorName": "Function",  
31:          "InternalFieldCount": 0,  
32:          "HasNamedLookupInterceptor": false,  
33:          "HasIndexedLookupInterceptor": false,  
34:          "GetIdentityHash": 994160730,  
35:          "IsCallable": true,  
36:          "GetPrototype": {  
37:              "IsUndefined": false,  
38:              "IsNull": false,  
39:              "IsTrue": false,  
40:              "IsFalse": false,  
41:              "IsName": false,  
42:              "IsString": false,  
43:              "IsSymbol": false,  
44:              "IsFunction": true,  
45:              "IsArray": false,  
46:              "IsObject": true,  
47:              "IsBoolean": false,  
48:              "IsNumber": false,  
49:              "IsExternal": false,  
50:              "IsInt32": false,  
51:              "IsUint32": false,  
52:              "IsDate": false,  
53:              "IsArgumentsObject": false,  
54:              "IsBooleanObject": false,  
55:              "IsNumberObject": false,  
56:              "IsStringObject": false,  
57:              "IsSymbolObject": false,  
58:              "IsNativeError": false,  
59:              "IsRegExp": false,  
60:              "IsGeneratorFunction": false,  
61:              "IsGeneratorObject": false,  
62:              "IsPromise": false,  
63:              "IsMap": false,  
64:              "IsSet": false,  
65:              "IsMapIterator": false,  
66:              "IsSetIterator": false,  
67:              "IsWeakMap": false,  
68:              "IsWeakSet": false,  
69:              "IsArrayBuffer": false,  
70:              "IsArrayBufferView": false,  
71:              "IsTypedArray": false,  
72:              "IsUint8Array": false,  
73:              "IsUint8ClampedArray": false,  
74:              "IsInt8Array": false,  
75:              "IsUint16Array": false,  
76:              "IsInt16Array": false,  
77:              "IsUint32Array": false,  
78:              "IsInt32Array": false,  
79:              "IsFloat32Array": false,  
80:              "IsFloat64Array": false,  
81:              "IsDataView": false,  
82:              "IsSharedArrayBuffer": false,  
83:              "IsProxy": false,  
84:              "ToBoolean": true,  
85:              "ToNumber": null,  
86:              "ToString": "function () {}",  
87:              "ToDetailString": "function () {}",  
88:              "ToInteger": 0,  
89:              "ToUint32": 0,  
90:              "ToInt32": 0,  
91:              "BooleanValue": true,  
92:              "NumberValue": null,  
93:              "IntegerValue": 0,  
94:              "Uint32Value": 0,  
95:              "Int32Value": 0,  
96:              "PropertyNames": [],  
97:              "GetConstructorName": "Function",  
98:              "InternalFieldCount": 0,  
99:              "HasNamedLookupInterceptor": false,  
100:              "HasIndexedLookupInterceptor": false,  
101:              "GetIdentityHash": 1329899702,  
102:              "IsCallable": true  
103:          },  
104:          "IsBoolean": false,  
105:          "IsNumber": false,  
106:          "IsExternal": false,  
107:          "IsInt32": false,  
108:          "IsUint32": false,  
109:          "IsDate": false,  
110:          "IsArgumentsObject": false,  
111:          "IsBooleanObject": false,  
112:          "IsNumberObject": false,  
113:          "IsStringObject": false,  
114:          "IsSymbolObject": false,  
115:          "IsNativeError": false,  
116:          "IsRegExp": false,  
117:          "IsGeneratorFunction": false,  
118:          "IsGeneratorObject": false,  
119:          "IsPromise": false,  
120:          "IsMap": false,  
121:          "IsSet": false,  
122:          "IsMapIterator": false,  
123:          "IsSetIterator": false,  
124:          "IsWeakMap": false,  
125:          "IsWeakSet": false,  
126:          "IsArrayBuffer": false,  
127:          "IsArrayBufferView": false,  
128:          "IsTypedArray": false,  
129:          "IsUint8Array": false,  
130:          "IsUint8ClampedArray": false,  
131:          "IsInt8Array": false,  
132:          "IsUint16Array": false,  
133:          "IsInt16Array": false,  
134:          "IsUint32Array": false,  
135:          "IsInt32Array": false,  
136:          "IsFloat32Array": false,  
137:          "IsFloat64Array": false,  
138:          "IsDataView": false,  
139:          "IsSharedArrayBuffer": false,  
140:          "IsProxy": false,  
141:          "ToBoolean": true,  
142:          "ToNumber": null,  
143:          "ToString": "function test_static_function() { [native code] }",  
144:          "ToDetailString": "function test_static_function() { [native code] }",  
145:          "ToInteger": 0,  
146:          "ToUint32": 0,  
147:          "ToInt32": 0,  
148:          "BooleanValue": true,  
149:          "NumberValue": null,  
150:          "IntegerValue": 0,  
151:          "Uint32Value": 0,  
152:          "Int32Value": 0  
153:      },  
154:      "IsConstructCall": false,  
155:      "This": {  
156:          "IsUndefined": false,  
157:          "IsNull": false,  
158:          "IsTrue": false,  
159:          "IsFalse": false,  
160:          "IsName": false,  
161:          "IsString": false,  
162:          "IsSymbol": false,  
163:          "IsFunction": true,  
164:          "GetName": "base_class",  
165:          "GetInferredName": "",  
166:          "GetDebugName": "base_class",  
167:          "GetScriptLineNumber": -1,  
168:          "GetScriptColumnNumber": -1,  
169:          "IsBuiltin": true,  
170:          "ScriptId": 0,  
171:          "GetScriptOrigin": {  
172:              "Options": {  
173:                  "IsEmbedderDebugScript": false,  
174:                  "IsSharedCrossOrigin": false,  
175:                  "IsOpaque": false,  
176:                  "Flags": 0  
177:              }  
178:          },  
179:          "IsArray": false,  
180:          "IsObject": true,  
181:          "PropertyNames": [],  
182:          "GetConstructorName": "Function",  
183:          "InternalFieldCount": 0,  
184:          "HasNamedLookupInterceptor": false,  
185:          "HasIndexedLookupInterceptor": false,  
186:          "GetIdentityHash": 612374797,  
187:          "IsCallable": true,  
188:          "GetPrototype": {  
189:              "IsUndefined": false,  
190:              "IsNull": false,  
191:              "IsTrue": false,  
192:              "IsFalse": false,  
193:              "IsName": false,  
194:              "IsString": false,  
195:              "IsSymbol": false,  
196:              "IsFunction": true,  
197:              "IsArray": false,  
198:              "IsObject": true,  
199:              "IsBoolean": false,  
200:              "IsNumber": false,  
201:              "IsExternal": false,  
202:              "IsInt32": false,  
203:              "IsUint32": false,  
204:              "IsDate": false,  
205:              "IsArgumentsObject": false,  
206:              "IsBooleanObject": false,  
207:              "IsNumberObject": false,  
208:              "IsStringObject": false,  
209:              "IsSymbolObject": false,  
210:              "IsNativeError": false,  
211:              "IsRegExp": false,  
212:              "IsGeneratorFunction": false,  
213:              "IsGeneratorObject": false,  
214:              "IsPromise": false,  
215:              "IsMap": false,  
216:              "IsSet": false,  
217:              "IsMapIterator": false,  
218:              "IsSetIterator": false,  
219:              "IsWeakMap": false,  
220:              "IsWeakSet": false,  
221:              "IsArrayBuffer": false,  
222:              "IsArrayBufferView": false,  
223:              "IsTypedArray": false,  
224:              "IsUint8Array": false,  
225:              "IsUint8ClampedArray": false,  
226:              "IsInt8Array": false,  
227:              "IsUint16Array": false,  
228:              "IsInt16Array": false,  
229:              "IsUint32Array": false,  
230:              "IsInt32Array": false,  
231:              "IsFloat32Array": false,  
232:              "IsFloat64Array": false,  
233:              "IsDataView": false,  
234:              "IsSharedArrayBuffer": false,  
235:              "IsProxy": false,  
236:              "ToBoolean": true,  
237:              "ToNumber": null,  
238:              "ToString": "function () {}",  
239:              "ToDetailString": "function () {}",  
240:              "ToInteger": 0,  
241:              "ToUint32": 0,  
242:              "ToInt32": 0,  
243:              "BooleanValue": true,  
244:              "NumberValue": null,  
245:              "IntegerValue": 0,  
246:              "Uint32Value": 0,  
247:              "Int32Value": 0,  
248:              "PropertyNames": [],  
249:              "GetConstructorName": "Function",  
250:              "InternalFieldCount": 0,  
251:              "HasNamedLookupInterceptor": false,  
252:              "HasIndexedLookupInterceptor": false,  
253:              "GetIdentityHash": 1329899702,  
254:              "IsCallable": true  
255:          },  
256:          "IsBoolean": false,  
257:          "IsNumber": false,  
258:          "IsExternal": false,  
259:          "IsInt32": false,  
260:          "IsUint32": false,  
261:          "IsDate": false,  
262:          "IsArgumentsObject": false,  
263:          "IsBooleanObject": false,  
264:          "IsNumberObject": false,  
265:          "IsStringObject": false,  
266:          "IsSymbolObject": false,  
267:          "IsNativeError": false,  
268:          "IsRegExp": false,  
269:          "IsGeneratorFunction": false,  
270:          "IsGeneratorObject": false,  
271:          "IsPromise": false,  
272:          "IsMap": false,  
273:          "IsSet": false,  
274:          "IsMapIterator": false,  
275:          "IsSetIterator": false,  
276:          "IsWeakMap": false,  
277:          "IsWeakSet": false,  
278:          "IsArrayBuffer": false,  
279:          "IsArrayBufferView": false,  
280:          "IsTypedArray": false,  
281:          "IsUint8Array": false,  
282:          "IsUint8ClampedArray": false,  
283:          "IsInt8Array": false,  
284:          "IsUint16Array": false,  
285:          "IsInt16Array": false,  
286:          "IsUint32Array": false,  
287:          "IsInt32Array": false,  
288:          "IsFloat32Array": false,  
289:          "IsFloat64Array": false,  
290:          "IsDataView": false,  
291:          "IsSharedArrayBuffer": false,  
292:          "IsProxy": false,  
293:          "ToBoolean": true,  
294:          "ToNumber": null,  
295:          "ToString": "function base_class() { [native code] }",  
296:          "ToDetailString": "function base_class() { [native code] }",  
297:          "ToInteger": 0,  
298:          "ToUint32": 0,  
299:          "ToInt32": 0,  
300:          "BooleanValue": true,  
301:          "NumberValue": null,  
302:          "IntegerValue": 0,  
303:          "Uint32Value": 0,  
304:          "Int32Value": 0  
305:      },  
306:      "Info": []  
307:  }  

There are many more parameters to explore, how does it show when an object is a child of another object? is there really an "int64" value in v8? spoiler: no. Can you do a ToInt32 on float numbers? What's the value of NumberValue for a particular string?

Have fun exploring :-)


Tags: ,