diff options
Diffstat (limited to 'src/node_file.cc')
-rw-r--r-- | src/node_file.cc | 162 |
1 files changed, 67 insertions, 95 deletions
diff --git a/src/node_file.cc b/src/node_file.cc index c29c0fda50..fa49dd4bcc 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -24,6 +24,9 @@ #include "node_buffer.h" #include "node_internals.h" #include "node_stat_watcher.h" + +#include "env.h" +#include "env-inl.h" #include "req_wrap.h" #include "string_bytes.h" @@ -42,6 +45,7 @@ namespace node { using v8::Array; +using v8::Context; using v8::Function; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; @@ -51,7 +55,6 @@ using v8::Integer; using v8::Local; using v8::Number; using v8::Object; -using v8::Persistent; using v8::String; using v8::Value; @@ -63,8 +66,9 @@ using v8::Value; class FSReqWrap: public ReqWrap<uv_fs_t> { public: - explicit FSReqWrap(const char* syscall, char* data = NULL) - : syscall_(syscall) + FSReqWrap(Environment* env, const char* syscall, char* data = NULL) + : ReqWrap<uv_fs_t>(env) + , syscall_(syscall) , data_(data) { } @@ -82,9 +86,6 @@ class FSReqWrap: public ReqWrap<uv_fs_t> { }; -static Cached<String> oncomplete_sym; - - #define ASSERT_OFFSET(a) \ if (!(a)->IsUndefined() && !(a)->IsNull() && !IsInt64((a)->NumberValue())) { \ return ThrowTypeError("Not an integer"); \ @@ -102,12 +103,14 @@ static inline int IsInt64(double x) { static void After(uv_fs_t *req) { - HandleScope scope(node_isolate); - FSReqWrap* req_wrap = static_cast<FSReqWrap*>(req->data); assert(&req_wrap->req_ == req); req_wrap->ReleaseEarly(); // Free memory that's no longer used now. + Environment* env = req_wrap->env(); + Context::Scope context_scope(env->context()); + HandleScope handle_scope(env->isolate()); + // there is always at least one argument. "error" int argc = 1; @@ -168,7 +171,8 @@ static void After(uv_fs_t *req) { case UV_FS_STAT: case UV_FS_LSTAT: case UV_FS_FSTAT: - argv[1] = BuildStatsObject(static_cast<const uv_stat_t*>(req->ptr)); + argv[1] = BuildStatsObject(env, + static_cast<const uv_stat_t*>(req->ptr)); break; case UV_FS_READLINK: @@ -209,7 +213,7 @@ static void After(uv_fs_t *req) { } } - MakeCallback(req_wrap->object(), oncomplete_sym, argc, argv); + MakeCallback(env, req_wrap->object(), env->oncomplete_string(), argc, argv); uv_fs_req_cleanup(&req_wrap->req_); delete req_wrap; @@ -227,27 +231,31 @@ struct fs_req_wrap { }; -#define ASYNC_CALL(func, callback, ...) \ - FSReqWrap* req_wrap = new FSReqWrap(#func); \ - int err = uv_fs_ ## func(uv_default_loop(), &req_wrap->req_, \ - __VA_ARGS__, After); \ - req_wrap->object()->Set(oncomplete_sym, callback); \ - req_wrap->Dispatched(); \ - if (err < 0) { \ - uv_fs_t* req = &req_wrap->req_; \ - req->result = err; \ - req->path = NULL; \ - After(req); \ - } \ +#define ASYNC_CALL(func, callback, ...) \ + Environment* env = Environment::GetCurrent(args.GetIsolate()); \ + FSReqWrap* req_wrap = new FSReqWrap(env, #func); \ + int err = uv_fs_ ## func(env->event_loop(), \ + &req_wrap->req_, \ + __VA_ARGS__, \ + After); \ + req_wrap->object()->Set(env->oncomplete_string(), callback); \ + req_wrap->Dispatched(); \ + if (err < 0) { \ + uv_fs_t* req = &req_wrap->req_; \ + req->result = err; \ + req->path = NULL; \ + After(req); \ + } \ args.GetReturnValue().Set(req_wrap->persistent()); -#define SYNC_CALL(func, path, ...) \ - fs_req_wrap req_wrap; \ - int err = uv_fs_ ## func(uv_default_loop(), \ - &req_wrap.req, \ - __VA_ARGS__, \ - NULL); \ - if (err < 0) return ThrowUVException(err, #func, NULL, path); \ +#define SYNC_CALL(func, path, ...) \ + fs_req_wrap req_wrap; \ + Environment* env = Environment::GetCurrent(args.GetIsolate()); \ + int err = uv_fs_ ## func(env->event_loop(), \ + &req_wrap.req, \ + __VA_ARGS__, \ + NULL); \ + if (err < 0) return ThrowUVException(err, #func, NULL, path); \ #define SYNC_REQ req_wrap.req @@ -271,47 +279,16 @@ static void Close(const FunctionCallbackInfo<Value>& args) { } -static Persistent<Function> stats_constructor; - -static Cached<String> dev_symbol; -static Cached<String> ino_symbol; -static Cached<String> mode_symbol; -static Cached<String> nlink_symbol; -static Cached<String> uid_symbol; -static Cached<String> gid_symbol; -static Cached<String> rdev_symbol; -static Cached<String> size_symbol; -static Cached<String> blksize_symbol; -static Cached<String> blocks_symbol; -static Cached<String> atime_symbol; -static Cached<String> mtime_symbol; -static Cached<String> ctime_symbol; -static Cached<String> birthtime_symbol; - -Local<Object> BuildStatsObject(const uv_stat_t* s) { - HandleScope scope(node_isolate); +Local<Object> BuildStatsObject(Environment* env, const uv_stat_t* s) { + // If you hit this assertion, you forgot to enter the v8::Context first. + assert(env->context() == env->isolate()->GetCurrentContext()); - if (dev_symbol.IsEmpty()) { - dev_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "dev"); - ino_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "ino"); - mode_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "mode"); - nlink_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "nlink"); - uid_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "uid"); - gid_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "gid"); - rdev_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "rdev"); - size_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "size"); - blksize_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "blksize"); - blocks_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "blocks"); - atime_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "atime"); - mtime_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "mtime"); - ctime_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "ctime"); - birthtime_symbol = FIXED_ONE_BYTE_STRING(node_isolate, "birthtime"); - } + HandleScope handle_scope(env->isolate()); - Local<Function> constructor = - PersistentToLocal(node_isolate, stats_constructor); - Local<Object> stats = constructor->NewInstance(); - if (stats.IsEmpty()) return Local<Object>(); + Local<Object> stats = env->stats_constructor_function()->NewInstance(); + if (stats.IsEmpty()) { + return Local<Object>(); + } // The code below is very nasty-looking but it prevents a segmentation fault // when people run JS code like the snippet below. It's apparently more @@ -328,7 +305,7 @@ Local<Object> BuildStatsObject(const uv_stat_t* s) { { \ Local<Value> val = Integer::New(s->st_##name, node_isolate); \ if (val.IsEmpty()) return Local<Object>(); \ - stats->Set(name##_symbol, val); \ + stats->Set(env->name ## _string(), val); \ } X(dev) X(mode) @@ -345,7 +322,7 @@ Local<Object> BuildStatsObject(const uv_stat_t* s) { { \ Local<Value> val = Number::New(static_cast<double>(s->st_##name)); \ if (val.IsEmpty()) return Local<Object>(); \ - stats->Set(name##_symbol, val); \ + stats->Set(env->name ## _string(), val); \ } X(ino) X(size) @@ -360,7 +337,7 @@ Local<Object> BuildStatsObject(const uv_stat_t* s) { msecs += static_cast<double>(s->st_##rec.tv_nsec / 1000000); \ Local<Value> val = v8::Date::New(msecs); \ if (val.IsEmpty()) return Local<Object>(); \ - stats->Set(name##_symbol, val); \ + stats->Set(env->name ## _string(), val); \ } X(atime, atim) X(mtime, mtim) @@ -368,7 +345,7 @@ Local<Object> BuildStatsObject(const uv_stat_t* s) { X(birthtime, birthtim) #undef X - return scope.Close(stats); + return handle_scope.Close(stats); } static void Stat(const FunctionCallbackInfo<Value>& args) { @@ -384,7 +361,7 @@ static void Stat(const FunctionCallbackInfo<Value>& args) { } else { SYNC_CALL(stat, *path, *path) args.GetReturnValue().Set( - BuildStatsObject(static_cast<const uv_stat_t*>(SYNC_REQ.ptr))); + BuildStatsObject(env, static_cast<const uv_stat_t*>(SYNC_REQ.ptr))); } } @@ -401,7 +378,7 @@ static void LStat(const FunctionCallbackInfo<Value>& args) { } else { SYNC_CALL(lstat, *path, *path) args.GetReturnValue().Set( - BuildStatsObject(static_cast<const uv_stat_t*>(SYNC_REQ.ptr))); + BuildStatsObject(env, static_cast<const uv_stat_t*>(SYNC_REQ.ptr))); } } @@ -419,7 +396,7 @@ static void FStat(const FunctionCallbackInfo<Value>& args) { } else { SYNC_CALL(fstat, 0, fd) args.GetReturnValue().Set( - BuildStatsObject(static_cast<const uv_stat_t*>(SYNC_REQ.ptr))); + BuildStatsObject(env, static_cast<const uv_stat_t*>(SYNC_REQ.ptr))); } } @@ -719,7 +696,8 @@ static void WriteBuffer(const FunctionCallbackInfo<Value>& args) { // if null, write from the current position // 3 enc encoding of string static void WriteString(const FunctionCallbackInfo<Value>& args) { - HandleScope scope(node_isolate); + Environment* env = Environment::GetCurrent(args.GetIsolate()); + HandleScope handle_scope(args.GetIsolate()); if (!args[0]->IsInt32()) return ThrowTypeError("First argument must be file descriptor"); @@ -753,15 +731,15 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) { return args.GetReturnValue().Set(SYNC_RESULT); } - FSReqWrap* req_wrap = new FSReqWrap("write", must_free ? buf : NULL); - int err = uv_fs_write(uv_default_loop(), + FSReqWrap* req_wrap = new FSReqWrap(env, "write", must_free ? buf : NULL); + int err = uv_fs_write(env->event_loop(), &req_wrap->req_, fd, buf, len, pos, After); - req_wrap->object()->Set(oncomplete_sym, cb); + req_wrap->object()->Set(env->oncomplete_string(), cb); req_wrap->Dispatched(); if (err < 0) { uv_fs_t* req = &req_wrap->req_; @@ -972,8 +950,15 @@ static void FUTimes(const FunctionCallbackInfo<Value>& args) { } -void File::Initialize(Handle<Object> target) { - HandleScope scope(node_isolate); +void InitFs(Handle<Object> target, + Handle<Value> unused, + Handle<Context> context) { + Environment* env = Environment::GetCurrent(context); + + // Initialize the stats object + Local<Function> constructor = FunctionTemplate::New()->GetFunction(); + target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "Stats"), constructor); + env->set_stats_constructor_function(constructor); NODE_SET_METHOD(target, "close", Close); NODE_SET_METHOD(target, "open", Open); @@ -1005,23 +990,10 @@ void File::Initialize(Handle<Object> target) { NODE_SET_METHOD(target, "utimes", UTimes); NODE_SET_METHOD(target, "futimes", FUTimes); -} - -void InitFs(Handle<Object> target) { - HandleScope scope(node_isolate); - - // Initialize the stats object - Local<Function> constructor = FunctionTemplate::New()->GetFunction(); - target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "Stats"), constructor); - stats_constructor.Reset(node_isolate, constructor); - - File::Initialize(target); - - oncomplete_sym = FIXED_ONE_BYTE_STRING(node_isolate, "oncomplete"); StatWatcher::Initialize(target); } } // end namespace node -NODE_MODULE(node_fs, node::InitFs) +NODE_MODULE_CONTEXT_AWARE(node_fs, node::InitFs) |