1 #include <v8.h>
2 #include <node.h>
3 #include <assert.h>
4
5 using v8::Array;
6 using v8::ArrayBuffer;
7 using v8::ArrayBufferView;
8 using v8::BackingStore;
9 using v8::Context;
10 using v8::FunctionCallbackInfo;
11 using v8::Isolate;
12 using v8::Local;
13 using v8::MaybeLocal;
14 using v8::Number;
15 using v8::Object;
16 using v8::String;
17 using v8::Uint32;
18 using v8::Value;
19
CallWithString(const FunctionCallbackInfo<Value> & args)20 void CallWithString(const FunctionCallbackInfo<Value>& args) {
21 assert(args.Length() == 1 && args[0]->IsString());
22 if (args.Length() == 1 && args[0]->IsString()) {
23 Local<String> str = args[0].As<String>();
24 const int32_t length = str->Utf8Length(args.GetIsolate()) + 1;
25 char* buf = new char[length];
26 str->WriteUtf8(args.GetIsolate(), buf, length);
27 delete[] buf;
28 }
29 }
30
CallWithArray(const FunctionCallbackInfo<Value> & args)31 void CallWithArray(const FunctionCallbackInfo<Value>& args) {
32 assert(args.Length() == 1 && args[0]->IsArray());
33 if (args.Length() == 1 && args[0]->IsArray()) {
34 const Local<Array> array = args[0].As<Array>();
35 uint32_t length = array->Length();
36 for (uint32_t i = 0; i < length; i++) {
37 Local<Value> v;
38 v = array->Get(args.GetIsolate()->GetCurrentContext(),
39 i).ToLocalChecked();
40 }
41 }
42 }
43
CallWithNumber(const FunctionCallbackInfo<Value> & args)44 void CallWithNumber(const FunctionCallbackInfo<Value>& args) {
45 assert(args.Length() == 1 && args[0]->IsNumber());
46 if (args.Length() == 1 && args[0]->IsNumber()) {
47 args[0].As<Number>()->Value();
48 }
49 }
50
CallWithObject(const FunctionCallbackInfo<Value> & args)51 void CallWithObject(const FunctionCallbackInfo<Value>& args) {
52 Isolate* isolate = args.GetIsolate();
53 Local<Context> context = isolate->GetCurrentContext();
54
55 assert(args.Length() == 1 && args[0]->IsObject());
56 if (args.Length() == 1 && args[0]->IsObject()) {
57 Local<Object> obj = args[0].As<Object>();
58
59 MaybeLocal<String> map_key = String::NewFromUtf8(isolate,
60 "map", v8::NewStringType::kNormal);
61 assert(!map_key.IsEmpty());
62 MaybeLocal<Value> map_maybe = obj->Get(context,
63 map_key.ToLocalChecked());
64 assert(!map_maybe.IsEmpty());
65 Local<Value> map;
66 map = map_maybe.ToLocalChecked();
67
68 MaybeLocal<String> operand_key = String::NewFromUtf8(isolate,
69 "operand", v8::NewStringType::kNormal);
70 assert(!operand_key.IsEmpty());
71 MaybeLocal<Value> operand_maybe = obj->Get(context,
72 operand_key.ToLocalChecked());
73 assert(!operand_maybe.IsEmpty());
74 Local<Value> operand;
75 operand = operand_maybe.ToLocalChecked();
76
77 MaybeLocal<String> data_key = String::NewFromUtf8(isolate,
78 "data", v8::NewStringType::kNormal);
79 assert(!data_key.IsEmpty());
80 MaybeLocal<Value> data_maybe = obj->Get(context,
81 data_key.ToLocalChecked());
82 assert(!data_maybe.IsEmpty());
83 Local<Value> data;
84 data = data_maybe.ToLocalChecked();
85
86 MaybeLocal<String> reduce_key = String::NewFromUtf8(isolate,
87 "reduce", v8::NewStringType::kNormal);
88 assert(!reduce_key.IsEmpty());
89 MaybeLocal<Value> reduce_maybe = obj->Get(context,
90 reduce_key.ToLocalChecked());
91 assert(!reduce_maybe.IsEmpty());
92 Local<Value> reduce;
93 reduce = reduce_maybe.ToLocalChecked();
94 }
95 }
96
CallWithTypedarray(const FunctionCallbackInfo<Value> & args)97 void CallWithTypedarray(const FunctionCallbackInfo<Value>& args) {
98 assert(args.Length() == 1 && args[0]->IsArrayBufferView());
99 if (args.Length() == 1 && args[0]->IsArrayBufferView()) {
100 assert(args[0]->IsArrayBufferView());
101 Local<ArrayBufferView> view = args[0].As<ArrayBufferView>();
102 const size_t byte_offset = view->ByteOffset();
103 const size_t byte_length = view->ByteLength();
104 assert(byte_length > 0);
105 assert(view->HasBuffer());
106 Local<ArrayBuffer> buffer = view->Buffer();
107 std::shared_ptr<BackingStore> bs = buffer->GetBackingStore();
108 const uint32_t* data = reinterpret_cast<uint32_t*>(
109 static_cast<uint8_t*>(bs->Data()) + byte_offset);
110 assert(data);
111 }
112 }
113
CallWithArguments(const FunctionCallbackInfo<Value> & args)114 void CallWithArguments(const FunctionCallbackInfo<Value>& args) {
115 assert(args.Length() > 1 && args[0]->IsNumber());
116 if (args.Length() > 1 && args[0]->IsNumber()) {
117 int32_t loop = args[0].As<Uint32>()->Value();
118 for (int32_t i = 1; i < loop; ++i) {
119 assert(i < args.Length());
120 assert(args[i]->IsUint32());
121 args[i].As<Uint32>()->Value();
122 }
123 }
124 }
125
Initialize(Local<Object> target,Local<Value> module,void * data)126 void Initialize(Local<Object> target,
127 Local<Value> module,
128 void* data) {
129 NODE_SET_METHOD(target, "callWithString", CallWithString);
130 NODE_SET_METHOD(target, "callWithLongString", CallWithString);
131
132 NODE_SET_METHOD(target, "callWithArray", CallWithArray);
133 NODE_SET_METHOD(target, "callWithLargeArray", CallWithArray);
134 NODE_SET_METHOD(target, "callWithHugeArray", CallWithArray);
135
136 NODE_SET_METHOD(target, "callWithNumber", CallWithNumber);
137 NODE_SET_METHOD(target, "callWithObject", CallWithObject);
138 NODE_SET_METHOD(target, "callWithTypedarray", CallWithTypedarray);
139
140 NODE_SET_METHOD(target, "callWith10Numbers", CallWithArguments);
141 NODE_SET_METHOD(target, "callWith100Numbers", CallWithArguments);
142 NODE_SET_METHOD(target, "callWith1000Numbers", CallWithArguments);
143 }
144
145 NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
146