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