Skip to content

Commit

Permalink
smalloc: extend user API
Browse files Browse the repository at this point in the history
node::Environment isn't accessible to user APIs, so extend smalloc to
also accept v8::Isolate.

Fixes: 75adde0 "src: remove `node_isolate` from source"
PR-URL: #905
Reviewed-by: Fedor Indutny <[email protected]>
  • Loading branch information
trevnorris committed Feb 20, 2015
1 parent 329f364 commit 26ebe98
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 7 deletions.
50 changes: 50 additions & 0 deletions src/smalloc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,56 @@ RetainedObjectInfo* WrapperInfo(uint16_t class_id, Handle<Value> wrapper) {
}


// User facing API.

void Alloc(Isolate* isolate,
Handle<Object> obj,
size_t length,
enum ExternalArrayType type) {
Alloc(Environment::GetCurrent(isolate), obj, length, type);
}


void Alloc(Isolate* isolate,
Handle<Object> obj,
char* data,
size_t length,
enum ExternalArrayType type) {
Alloc(Environment::GetCurrent(isolate), obj, data, length, type);
}


void Alloc(Isolate* isolate,
Handle<Object> obj,
size_t length,
FreeCallback fn,
void* hint,
enum ExternalArrayType type) {
Alloc(Environment::GetCurrent(isolate), obj, length, fn, hint, type);
}


void Alloc(Isolate* isolate,
Handle<Object> obj,
char* data,
size_t length,
FreeCallback fn,
void* hint,
enum ExternalArrayType type) {
Alloc(Environment::GetCurrent(isolate), obj, data, length, fn, hint, type);
}


void AllocDispose(Isolate* isolate, Handle<Object> obj) {
AllocDispose(Environment::GetCurrent(isolate), obj);
}


bool HasExternalData(Isolate* isolate, Local<Object> obj) {
return HasExternalData(Environment::GetCurrent(isolate), obj);
}


void Initialize(Handle<Object> exports,
Handle<Value> unused,
Handle<Context> context) {
Expand Down
47 changes: 40 additions & 7 deletions src/smalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,30 +49,31 @@ NODE_EXTERN size_t ExternalArraySize(enum v8::ExternalArrayType type);
* v8::kExternalFloatArray);
* v8::Local<v8::Object> obj = v8::Object::New();
* char* data = static_cast<char*>(malloc(byte_length * array_length));
* node::smalloc::Alloc(env, obj, data, byte_length, v8::kExternalFloatArray);
* node::smalloc::Alloc(isolate, obj, data, byte_length,
* v8::kExternalFloatArray);
* obj->Set(v8::String::NewFromUtf8("length"),
* v8::Integer::NewFromUnsigned(array_length));
* \code
*/
NODE_EXTERN void Alloc(Environment* env,
NODE_EXTERN void Alloc(v8::Isolate* isolate,
v8::Handle<v8::Object> obj,
size_t length,
enum v8::ExternalArrayType type =
v8::kExternalUnsignedByteArray);
NODE_EXTERN void Alloc(Environment* env,
NODE_EXTERN void Alloc(v8::Isolate* isolate,
v8::Handle<v8::Object> obj,
char* data,
size_t length,
enum v8::ExternalArrayType type =
v8::kExternalUnsignedByteArray);
NODE_EXTERN void Alloc(Environment* env,
NODE_EXTERN void Alloc(v8::Isolate* isolate,
v8::Handle<v8::Object> obj,
size_t length,
FreeCallback fn,
void* hint,
enum v8::ExternalArrayType type =
v8::kExternalUnsignedByteArray);
NODE_EXTERN void Alloc(Environment* env,
NODE_EXTERN void Alloc(v8::Isolate* isolate,
v8::Handle<v8::Object> obj,
char* data,
size_t length,
Expand All @@ -85,13 +86,45 @@ NODE_EXTERN void Alloc(Environment* env,
* Free memory associated with an externally allocated object. If no external
* memory is allocated to the object then nothing will happen.
*/
NODE_EXTERN void AllocDispose(Environment* env, v8::Handle<v8::Object> obj);
NODE_EXTERN void AllocDispose(v8::Isolate* isolate, v8::Handle<v8::Object> obj);


/**
* Check if the Object has externally allocated memory.
*/
NODE_EXTERN bool HasExternalData(Environment* env, v8::Local<v8::Object> obj);
NODE_EXTERN bool HasExternalData(v8::Isolate* isolate,
v8::Local<v8::Object> obj);


// Internal use
void Alloc(Environment* env,
v8::Handle<v8::Object> obj,
size_t length,
enum v8::ExternalArrayType type =
v8::kExternalUnsignedByteArray);
void Alloc(Environment* env,
v8::Handle<v8::Object> obj,
char* data,
size_t length,
enum v8::ExternalArrayType type =
v8::kExternalUnsignedByteArray);
void Alloc(Environment* env,
v8::Handle<v8::Object> obj,
size_t length,
FreeCallback fn,
void* hint,
enum v8::ExternalArrayType type =
v8::kExternalUnsignedByteArray);
void Alloc(Environment* env,
v8::Handle<v8::Object> obj,
char* data,
size_t length,
FreeCallback fn,
void* hint,
enum v8::ExternalArrayType type =
v8::kExternalUnsignedByteArray);
void AllocDispose(Environment* env, v8::Handle<v8::Object> obj);
bool HasExternalData(Environment* env, v8::Local<v8::Object> obj);

} // namespace smalloc
} // namespace node
Expand Down
30 changes: 30 additions & 0 deletions test/addons/smalloc-alloc/binding.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include <node.h>
#include <smalloc.h>
#include <v8.h>

using namespace v8;

void Alloc(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Object> obj = Object::New(isolate);
size_t len = args[0]->Uint32Value();
node::smalloc::Alloc(isolate, obj, len);
args.GetReturnValue().Set(obj);
}

void Dispose(const FunctionCallbackInfo<Value>& args) {
node::smalloc::AllocDispose(args.GetIsolate(), args[0].As<Object>());
}

void HasExternalData(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(
node::smalloc::HasExternalData(args.GetIsolate(), args[0].As<Object>()));
}

void init(Handle<Object> target) {
NODE_SET_METHOD(target, "alloc", Alloc);
NODE_SET_METHOD(target, "dispose", Dispose);
NODE_SET_METHOD(target, "hasExternalData", HasExternalData);
}

NODE_MODULE(binding, init);
8 changes: 8 additions & 0 deletions test/addons/smalloc-alloc/binding.gyp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
'targets': [
{
'target_name': 'binding',
'sources': [ 'binding.cc' ]
}
]
}
9 changes: 9 additions & 0 deletions test/addons/smalloc-alloc/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
var assert = require('assert');
var binding = require('./build/Release/binding');
var obj = binding.alloc(16);
for (var i = 0; i < 16; i++) {
assert.ok(typeof obj[i] == 'number');
}
assert.ok(binding.hasExternalData(obj));
binding.dispose(obj);
assert.ok(typeof obj[0] !== 'number');

0 comments on commit 26ebe98

Please sign in to comment.