src: add multi-context support
[platform/upstream/nodejs.git] / src / node_buffer.cc
index 519fddf..2e73749 100644 (file)
 
 #include "node.h"
 #include "node_buffer.h"
+
+#include "env.h"
+#include "env-inl.h"
 #include "smalloc.h"
 #include "string_bytes.h"
-
-#include "v8.h"
 #include "v8-profiler.h"
+#include "v8.h"
 
 #include <assert.h>
 #include <string.h>
@@ -55,6 +57,7 @@
 namespace node {
 namespace Buffer {
 
+using v8::Context;
 using v8::Function;
 using v8::FunctionCallbackInfo;
 using v8::FunctionTemplate;
@@ -63,13 +66,10 @@ using v8::HandleScope;
 using v8::Local;
 using v8::Number;
 using v8::Object;
-using v8::Persistent;
 using v8::String;
 using v8::Uint32;
 using v8::Value;
 
-static Persistent<Function> p_buffer_fn;
-
 
 bool HasInstance(Handle<Value> val) {
   return val->IsObject() && HasInstance(val.As<Object>());
@@ -124,12 +124,20 @@ Local<Object> New(Handle<String> string, enum encoding enc) {
 
 
 Local<Object> New(size_t length) {
+  Environment* env = Environment::GetCurrent(node_isolate);
+  return Buffer::New(env, length);
+}
+
+
+// TODO(trevnorris): these have a flaw by needing to call the Buffer inst then
+// Alloc. continue to look for a better architecture.
+Local<Object> New(Environment* env, size_t length) {
   HandleScope scope(node_isolate);
 
   assert(length <= kMaxLength);
 
   Local<Value> arg = Uint32::NewFromUnsigned(length, node_isolate);
-  Local<Object> obj = NewInstance(p_buffer_fn, 1, &arg);
+  Local<Object> obj = env->buffer_constructor_function()->NewInstance(1, &arg);
 
   // TODO(trevnorris): done like this to handle HasInstance since only checks
   // if external array data has been set, but would like to use a better
@@ -148,16 +156,22 @@ Local<Object> New(size_t length) {
 }
 
 
+Local<Object> New(const char* data, size_t length) {
+  Environment* env = Environment::GetCurrent(node_isolate);
+  return Buffer::New(env, data, length);
+}
+
+
 // TODO(trevnorris): for backwards compatibility this is left to copy the data,
 // but for consistency w/ the other should use data. And a copy version renamed
 // to something else.
-Local<Object> New(const char* data, size_t length) {
+Local<Object> New(Environment* env, const char* data, size_t length) {
   HandleScope scope(node_isolate);
 
   assert(length <= kMaxLength);
 
   Local<Value> arg = Uint32::NewFromUnsigned(length, node_isolate);
-  Local<Object> obj = NewInstance(p_buffer_fn, 1, &arg);
+  Local<Object> obj = env->buffer_constructor_function()->NewInstance(1, &arg);
 
   // TODO(trevnorris): done like this to handle HasInstance since only checks
   // if external array data has been set, but would like to use a better
@@ -182,12 +196,22 @@ Local<Object> New(char* data,
                   size_t length,
                   smalloc::FreeCallback callback,
                   void* hint) {
+  Environment* env = Environment::GetCurrent(node_isolate);
+  return Buffer::New(env, data, length, callback, hint);
+}
+
+
+Local<Object> New(Environment* env,
+                  char* data,
+                  size_t length,
+                  smalloc::FreeCallback callback,
+                  void* hint) {
   HandleScope scope(node_isolate);
 
   assert(length <= kMaxLength);
 
   Local<Value> arg = Uint32::NewFromUnsigned(length, node_isolate);
-  Local<Object> obj = NewInstance(p_buffer_fn, 1, &arg);
+  Local<Object> obj = env->buffer_constructor_function()->NewInstance(1, &arg);
 
   smalloc::Alloc(obj, data, length, callback, hint);
 
@@ -196,12 +220,18 @@ Local<Object> New(char* data,
 
 
 Local<Object> Use(char* data, uint32_t length) {
+  Environment* env = Environment::GetCurrent(node_isolate);
+  return Buffer::Use(env, data, length);
+}
+
+
+Local<Object> Use(Environment* env, char* data, uint32_t length) {
   HandleScope scope(node_isolate);
 
   assert(length <= kMaxLength);
 
   Local<Value> arg = Uint32::NewFromUnsigned(length, node_isolate);
-  Local<Object> obj = NewInstance(p_buffer_fn, 1, &arg);
+  Local<Object> obj = env->buffer_constructor_function()->NewInstance(1, &arg);
 
   smalloc::Alloc(obj, data, length);
 
@@ -534,12 +564,13 @@ void ByteLength(const FunctionCallbackInfo<Value> &args) {
 
 // pass Buffer object to load prototype methods
 void SetupBufferJS(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope handle_scope(args.GetIsolate());
 
   assert(args[0]->IsFunction());
 
   Local<Function> bv = args[0].As<Function>();
-  p_buffer_fn.Reset(node_isolate, bv);
+  env->set_buffer_constructor_function(bv);
   Local<Value> proto_v =
       bv->Get(FIXED_ONE_BYTE_STRING(node_isolate, "prototype"));
 
@@ -588,10 +619,12 @@ void SetupBufferJS(const FunctionCallbackInfo<Value>& args) {
 }
 
 
-void Initialize(Handle<Object> target) {
-  HandleScope scope(node_isolate);
-
-  target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "setupBufferJS"),
+void Initialize(Handle<Object> target,
+                Handle<Value> unused,
+                Handle<Context> context) {
+  Environment* env = Environment::GetCurrent(context);
+  HandleScope handle_scope(env->isolate());
+  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "setupBufferJS"),
               FunctionTemplate::New(SetupBufferJS)->GetFunction());
 }
 
@@ -599,4 +632,4 @@ void Initialize(Handle<Object> target) {
 }  // namespace Buffer
 }  // namespace node
 
-NODE_MODULE(node_buffer, node::Buffer::Initialize)
+NODE_MODULE_CONTEXT_AWARE(node_buffer, node::Buffer::Initialize)