summaryrefslogtreecommitdiff
path: root/src/node_file.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/node_file.cc')
-rw-r--r--src/node_file.cc162
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)