diff --git a/.gitignore b/.gitignore index 567609b..c742c05 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ build/ + +/node_modules/ diff --git a/binding.gyp b/binding.gyp index 8e08c90..4560994 100644 --- a/binding.gyp +++ b/binding.gyp @@ -4,11 +4,13 @@ "target_name": "fuse4js", "sources": [ "fuse4js.cc" ], "include_dirs": [ - ' #include -#include +#include +#include +using v8::FunctionTemplate; +using v8::Handle; +using v8::Object; +using v8::String; #define FUSE_USE_VERSION 26 @@ -413,7 +422,7 @@ void ConvertDate(Handle &stat, std::string name, struct timespec *out) { - Local prop = stat->Get(String::NewSymbol(name.c_str())); + Local prop = stat->Get(NanNew(name.c_str())); if (!prop->IsUndefined() && prop->IsDate()) { Local date = Local::Cast(prop); double dateVal = date->NumberValue(); // total milliseconds @@ -428,7 +437,7 @@ void ConvertDate(Handle &stat, // --------------------------------------------------------------------------- -void ProcessReturnValue(const Arguments& args) +NAN_METHOD(ProcessReturnValue) { if (args.Length() >= 1 && args[0]->IsNumber()) { Local retval = Local::Cast(args[0]); @@ -438,39 +447,39 @@ void ProcessReturnValue(const Arguments& args) // --------------------------------------------------------------------------- -Handle GetAttrCompletion(const Arguments& args) +NAN_METHOD(GetAttrCompletion) { - HandleScope scope; + NanEscapableScope(); ProcessReturnValue(args); if (f4js_cmd.retval == 0 && args.Length() >= 2 && args[1]->IsObject()) { memset(f4js_cmd.u.getattr.stbuf, 0, sizeof(*f4js_cmd.u.getattr.stbuf)); Handle stat = Handle::Cast(args[1]); - Local prop = stat->Get(String::NewSymbol("size")); + Local prop = stat->Get(NanNew("size")); if (!prop->IsUndefined() && prop->IsNumber()) { Local num = Local::Cast(prop); f4js_cmd.u.getattr.stbuf->st_size = (off_t)num->Value(); } - prop = stat->Get(String::NewSymbol("mode")); + prop = stat->Get(NanNew("mode")); if (!prop->IsUndefined() && prop->IsNumber()) { Local num = Local::Cast(prop); f4js_cmd.u.getattr.stbuf->st_mode = (mode_t)num->Value(); } - prop = stat->Get(String::NewSymbol("nlink")); + prop = stat->Get(NanNew("nlink")); if (!prop->IsUndefined() && prop->IsNumber()) { Local num = Local::Cast(prop); f4js_cmd.u.getattr.stbuf->st_nlink = (mode_t)num->Value(); } - prop = stat->Get(String::NewSymbol("uid")); + prop = stat->Get(NanNew("uid")); if (!prop->IsUndefined() && prop->IsNumber()) { Local num = Local::Cast(prop); f4js_cmd.u.getattr.stbuf->st_uid = (uid_t)num->Value(); } - prop = stat->Get(String::NewSymbol("gid")); + prop = stat->Get(NanNew("gid")); if (!prop->IsUndefined() && prop->IsNumber()) { Local num = Local::Cast(prop); f4js_cmd.u.getattr.stbuf->st_gid = (gid_t)num->Value(); @@ -489,14 +498,14 @@ Handle GetAttrCompletion(const Arguments& args) } sem_post(f4js.psem); - return scope.Close(Undefined()); + NanEscapeScope(NanUndefined()); } // --------------------------------------------------------------------------- -Handle ReadDirCompletion(const Arguments& args) +NAN_METHOD(ReadDirCompletion) { - HandleScope scope; + NanEscapableScope(); ProcessReturnValue(args); if (f4js_cmd.retval == 0 && args.Length() >= 2 && args[1]->IsArray()) { Handle ar = Handle::Cast(args[1]); @@ -513,94 +522,94 @@ Handle ReadDirCompletion(const Arguments& args) } } sem_post(f4js.psem); - return scope.Close(Undefined()); + NanEscapeScope(NanUndefined()); } // --------------------------------------------------------------------------- -Handle StatfsCompletion(const Arguments& args) +NAN_METHOD( StatfsCompletion ) { - HandleScope scope; + NanEscapableScope(); ProcessReturnValue(args); if (f4js_cmd.retval == 0 && args.Length() >= 2 && args[1]->IsObject()) { memset(f4js_cmd.u.statfs.buf, 0, sizeof(*f4js_cmd.u.statfs.buf)); Handle stat = Handle::Cast(args[1]); - Local prop = stat->Get(String::NewSymbol("bsize")); + Local prop = stat->Get(NanNew("bsize")); if (!prop->IsUndefined() && prop->IsNumber()) { Local num = Local::Cast(prop); f4js_cmd.u.statfs.buf->f_bsize = (off_t)num->Value(); } - prop = stat->Get(String::NewSymbol("frsize")); + prop = stat->Get(NanNew("frsize")); if (!prop->IsUndefined() && prop->IsNumber()) { Local num = Local::Cast(prop); f4js_cmd.u.statfs.buf->f_frsize = (off_t)num->Value(); } - prop = stat->Get(String::NewSymbol("blocks")); + prop = stat->Get(NanNew("blocks")); if (!prop->IsUndefined() && prop->IsNumber()) { Local num = Local::Cast(prop); f4js_cmd.u.statfs.buf->f_blocks = (off_t)num->Value(); } - prop = stat->Get(String::NewSymbol("bfree")); + prop = stat->Get(NanNew("bfree")); if (!prop->IsUndefined() && prop->IsNumber()) { Local num = Local::Cast(prop); f4js_cmd.u.statfs.buf->f_bfree = (off_t)num->Value(); } - prop = stat->Get(String::NewSymbol("bavail")); + prop = stat->Get(NanNew("bavail")); if (!prop->IsUndefined() && prop->IsNumber()) { Local num = Local::Cast(prop); f4js_cmd.u.statfs.buf->f_bavail = (off_t)num->Value(); } - prop = stat->Get(String::NewSymbol("files")); + prop = stat->Get(NanNew("files")); if (!prop->IsUndefined() && prop->IsNumber()) { Local num = Local::Cast(prop); f4js_cmd.u.statfs.buf->f_files = (off_t)num->Value(); } - prop = stat->Get(String::NewSymbol("ffree")); + prop = stat->Get(NanNew("ffree")); if (!prop->IsUndefined() && prop->IsNumber()) { Local num = Local::Cast(prop); f4js_cmd.u.statfs.buf->f_ffree = (off_t)num->Value(); } - prop = stat->Get(String::NewSymbol("favail")); + prop = stat->Get(NanNew("favail")); if (!prop->IsUndefined() && prop->IsNumber()) { Local num = Local::Cast(prop); f4js_cmd.u.statfs.buf->f_favail = (off_t)num->Value(); } - prop = stat->Get(String::NewSymbol("fsid")); + prop = stat->Get(NanNew("fsid")); if (!prop->IsUndefined() && prop->IsNumber()) { Local num = Local::Cast(prop); f4js_cmd.u.statfs.buf->f_fsid = (off_t)num->Value(); } - prop = stat->Get(String::NewSymbol("flag")); + prop = stat->Get(NanNew("flag")); if (!prop->IsUndefined() && prop->IsNumber()) { Local num = Local::Cast(prop); f4js_cmd.u.statfs.buf->f_flag = (off_t)num->Value(); } - prop = stat->Get(String::NewSymbol("namemax")); + prop = stat->Get(NanNew("namemax")); if (!prop->IsUndefined() && prop->IsNumber()) { Local num = Local::Cast(prop); f4js_cmd.u.statfs.buf->f_namemax = (off_t)num->Value(); } } sem_post(f4js.psem); - return scope.Close(Undefined()); + NanEscapeScope(NanUndefined()); } // --------------------------------------------------------------------------- -Handle ReadLinkCompletion(const Arguments& args) +NAN_METHOD( ReadLinkCompletion) { - HandleScope scope; + NanEscapableScope(); ProcessReturnValue(args); if (f4js_cmd.retval == 0 && args.Length() >= 2 && args[1]->IsString()) { String::Utf8Value av(args[1]); @@ -610,14 +619,14 @@ Handle ReadLinkCompletion(const Arguments& args) f4js_cmd.u.readlink.dstBuf[f4js_cmd.u.readlink.len - 1] = '\0'; } sem_post(f4js.psem); - return scope.Close(Undefined()); + NanEscapeScope(NanUndefined()); } // --------------------------------------------------------------------------- -Handle GenericCompletion(const Arguments& args) +NAN_METHOD(GenericCompletion) { - HandleScope scope; + NanEscapableScope(); bool exiting = (f4js_cmd.op == OP_DESTROY); ProcessReturnValue(args); @@ -628,14 +637,14 @@ Handle GenericCompletion(const Arguments& args) sem_close(f4js.psem); sem_unlink(f4js_semaphore_name().c_str()); } - return scope.Close(Undefined()); + NanEscapeScope(NanUndefined()); } // --------------------------------------------------------------------------- -Handle OpenCreateCompletion(const Arguments& args) +NAN_METHOD(OpenCreateCompletion) { - HandleScope scope; + NanEscapableScope(); ProcessReturnValue(args); if (f4js_cmd.retval == 0 && args.Length() >= 2 && args[1]->IsNumber()) { Local fileHandle = Local::Cast(args[1]); @@ -644,36 +653,36 @@ Handle OpenCreateCompletion(const Arguments& args) f4js_cmd.info->fh = 0; } sem_post(f4js.psem); - return scope.Close(Undefined()); + NanEscapeScope(NanUndefined()); } // --------------------------------------------------------------------------- -Handle ReadCompletion(const Arguments& args) +NAN_METHOD(ReadCompletion) { - HandleScope scope; + NanEscapableScope(); ProcessReturnValue(args); if (f4js_cmd.retval >= 0) { - char *buffer_data = node::Buffer::Data(f4js.nodeBuffer); + char *buffer_data = node::Buffer::Data(NanNew(f4js.nodeBuffer)); if ((size_t)f4js_cmd.retval > f4js_cmd.u.rw.len) { f4js_cmd.retval = f4js_cmd.u.rw.len; } memcpy(f4js_cmd.u.rw.dstBuf, buffer_data, f4js_cmd.retval); } - f4js.nodeBuffer.Dispose(); + NanDisposePersistent(f4js.nodeBuffer); sem_post(f4js.psem); - return scope.Close(Undefined()); + NanEscapeScope(NanUndefined()); } // --------------------------------------------------------------------------- -Handle WriteCompletion(const Arguments& args) +NAN_METHOD(WriteCompletion) { - HandleScope scope; + NanEscapableScope(); ProcessReturnValue(args); - f4js.nodeBuffer.Dispose(); + NanDisposePersistent(f4js.nodeBuffer); sem_post(f4js.psem); - return scope.Close(Undefined()); + NanEscapeScope(NanUndefined()); } // --------------------------------------------------------------------------- @@ -681,23 +690,20 @@ Handle WriteCompletion(const Arguments& args) // Called from the main thread. static void DispatchOp(uv_async_t* handle, int status) { - HandleScope scope; + NanEscapableScope(); std::string symName(fuseop_names[f4js_cmd.op]); - Persistent tpl = f4js.GenericFunc; // default f4js_cmd.retval = -EPERM; int argc = 0; Handle argv[6]; - Local path = String::New(f4js_cmd.in_path); + Local path = NanNew(f4js_cmd.in_path); argv[argc++] = path; - node::Buffer* buffer = NULL; // used for read/write operations - bool passHandle = false; - switch (f4js_cmd.op) { case OP_INIT: case OP_DESTROY: f4js_cmd.retval = 0; // Will be used as the return value of OP_INIT. --argc; // Ugly. Remove the first argument (path) because not needed. + argv[argc++] = NanNew(f4js.GenericFunc); break; case OP_TRUNCATE: @@ -705,116 +711,118 @@ static void DispatchOp(uv_async_t* handle, int status) break; case OP_GETATTR: - tpl = f4js.GetAttrFunc; + argv[argc++] = NanNew(f4js.GetAttrFunc); break; case OP_READDIR: - tpl = f4js.ReadDirFunc; + argv[argc++] = NanNew(f4js.ReadDirFunc); break; case OP_READLINK: - tpl = f4js.ReadLinkFunc; + argv[argc++] = NanNew(f4js.ReadLinkFunc); break; case OP_CHMOD: - argv[argc++] = Number::New((double)f4js_cmd.u.chmod.mode); + argv[argc++] = NanNew((double)f4js_cmd.u.chmod.mode); break; case OP_SETXATTR: - argv[argc++] = String::New(f4js_cmd.u.setxattr.name); - argv[argc++] = String::New(f4js_cmd.u.setxattr.value); - argv[argc++] = Number::New((double)f4js_cmd.u.setxattr.size); + argv[argc++] = NanNew(f4js_cmd.u.setxattr.name); + argv[argc++] = NanNew(f4js_cmd.u.setxattr.value); + argv[argc++] = NanNew((double)f4js_cmd.u.setxattr.size); #ifdef __APPLE__ - argv[argc++] = Number::New((double)f4js_cmd.u.setxattr.position); - argv[argc++] = Number::New((double)f4js_cmd.u.setxattr.options); + argv[argc++] = NanNew((double)f4js_cmd.u.setxattr.position); + argv[argc++] = NanNew((double)f4js_cmd.u.setxattr.options); #else - argv[argc++] = Number::New((double)f4js_cmd.u.setxattr.flags); + argv[argc++] = NanNew((double)f4js_cmd.u.setxattr.flags); #endif break; case OP_STATFS: --argc; // Ugly. Remove the first argument (path) because not needed. - tpl = f4js.StatfsFunc; + argv[argc++] = NanNew(f4js.StatfsFunc); break; case OP_RENAME: - argv[argc++] = String::New(f4js_cmd.u.rename.dst); + argv[argc++] = NanNew(f4js_cmd.u.rename.dst); + argv[argc++] = NanNew(f4js.GenericFunc); break; case OP_OPEN: - tpl = f4js.OpenCreateFunc; - argv[argc++] = Number::New((double)f4js_cmd.info->flags); + argv[argc++] = NanNew((double)f4js_cmd.info->flags); + argv[argc++] = NanNew(f4js.OpenCreateFunc); break; case OP_CREATE: - tpl = f4js.OpenCreateFunc; - argv[argc++] = Number::New((double)f4js_cmd.u.create_mkdir.mode); + argv[argc++] = NanNew((double)f4js_cmd.u.create_mkdir.mode); + argv[argc++] = NanNew(f4js.OpenCreateFunc); break; case OP_MKDIR: - argv[argc++] = Number::New((double)f4js_cmd.u.create_mkdir.mode); + argv[argc++] = NanNew((double)f4js_cmd.u.create_mkdir.mode); + argv[argc++] = NanNew(f4js.GenericFunc); break; case OP_READ: - tpl = f4js.ReadFunc; - buffer = node::Buffer::New(f4js_cmd.u.rw.len); - passHandle = true; + argv[argc++] = NanNew((double)f4js_cmd.u.rw.offset); + argv[argc++] = NanNew((double)f4js_cmd.u.rw.len); + NanAssignPersistent(f4js.nodeBuffer, NanNewBufferHandle(f4js_cmd.u.rw.len)); + argv[argc++] = NanNew(f4js.nodeBuffer); + argv[argc++] = NanNew((double)f4js_cmd.info->fh); // optional file handle returned by open() + argv[argc++] = NanNew(f4js.ReadFunc); + break; case OP_WRITE: - tpl = f4js.WriteFunc; - buffer = node::Buffer::New((char*)f4js_cmd.u.rw.srcBuf, f4js_cmd.u.rw.len); - passHandle = true; + argv[argc++] = NanNew((double)f4js_cmd.u.rw.offset); + argv[argc++] = NanNew((double)f4js_cmd.u.rw.len); + NanAssignPersistent(f4js.nodeBuffer, NanNewBufferHandle((char*)f4js_cmd.u.rw.srcBuf, f4js_cmd.u.rw.len)); + argv[argc++] = NanNew(f4js.nodeBuffer); + argv[argc++] = NanNew((double)f4js_cmd.info->fh); // optional file handle returned by open() + argv[argc++] = NanNew(f4js.WriteFunc); break; case OP_RELEASE: - passHandle = true; + argv[argc++] = NanNew((double)f4js_cmd.info->fh); // optional file handle returned by open() + argv[argc++] = NanNew(f4js.GenericFunc); break; default: + argv[argc++] = NanNew(f4js.GenericFunc); break; } - // Additional args for read/write operations - if (buffer) { - // FIXME: 64-bit off_t cannot always fit in a JS number - argv[argc++] = Number::New((double)f4js_cmd.u.rw.offset); - argv[argc++] = Number::New((double)f4js_cmd.u.rw.len); - f4js.nodeBuffer = Persistent::New(buffer->handle_); - argv[argc++] = f4js.nodeBuffer; - } - if (passHandle) { - argv[argc++] = Number::New((double)f4js_cmd.info->fh); // optional file handle returned by open() - } - Local handler = Local::Cast(f4js.handlers->Get(String::NewSymbol(symName.c_str()))); + Local handler = Local::Cast( + NanNew(f4js.handlers)->Get(NanNew(symName.c_str())) + ); if (handler->IsUndefined()) { sem_post(f4js.psem); return; } - argv[argc++] = tpl; - handler->Call(Context::GetCurrent()->Global(), argc, argv); + handler->Call(NanGetCurrentContext()->Global(), argc, argv); + NanEscapeScope( NanUndefined()); } // --------------------------------------------------------------------------- -Handle Start(const Arguments& args) +NAN_METHOD(Start) { - HandleScope scope; + NanEscapableScope(); if (args.Length() < 2) { - ThrowException(Exception::TypeError(String::New("Wrong number of arguments"))); - return scope.Close(Undefined()); + NanThrowTypeError("Wrong number of arguments"); + NanEscapeScope(NanUndefined()); } if (!args[0]->IsString() || !args[1]->IsObject()) { - ThrowException(Exception::TypeError(String::New("Wrong argument types"))); - return scope.Close(Undefined()); + NanThrowTypeError("Wrong argument types"); + NanEscapeScope(NanUndefined()); } String::Utf8Value av(args[0]); char *root = *av; if (root == NULL) { - ThrowException(Exception::TypeError(String::New("Path is incorrect"))); - return scope.Close(Undefined()); + NanThrowTypeError("Path is incorrect"); + NanEscapeScope(NanUndefined()); } f4js.enableFuseDebug = false; @@ -826,28 +834,33 @@ Handle Start(const Arguments& args) f4js.extraArgc = 0; if (args.Length() >= 4) { if (!args[3]->IsArray()) { - ThrowException(Exception::TypeError(String::New("Wrong argument types"))); - return scope.Close(Undefined()); + NanThrowTypeError("Wrong argument types"); + NanEscapeScope(NanUndefined()); } Handle mountArgs = Handle::Cast(args[3]); f4js.extraArgv = (char**)malloc(mountArgs->Length() * sizeof(char*)); - + int argLen = 0; + int argSize = 0; for (uint32_t i = 0; i < mountArgs->Length(); i++) { Local arg = mountArgs->Get(i); if (!arg->IsUndefined() && arg->IsString()) { Local stringArg = Local::Cast(arg); - String::AsciiValue av(stringArg); - f4js.extraArgv[f4js.extraArgc] = (char*)malloc(sizeof(av)); - memcpy(f4js.extraArgv[f4js.extraArgc], *av, sizeof(av)); + + char *handle = *NanAsciiString(stringArg); + argLen = std::strlen(handle)+1; + argSize = argLen * sizeof(char); + f4js.extraArgv[f4js.extraArgc] = (char*)malloc(argSize); + memcpy(f4js.extraArgv[f4js.extraArgc], (void *) handle, argSize); f4js.extraArgc++; } } } f4js.root = root; - f4js.handlers = Persistent::New(Local::Cast(args[1])); + NanAssignPersistent( f4js.handlers, Local::Cast(args[1]) ); + f4js.psem = sem_open(f4js_semaphore_name().c_str(), O_CREAT, S_IRUSR | S_IWUSR, 0); if (f4js.psem == SEM_FAILED) { @@ -855,28 +868,30 @@ Handle Start(const Arguments& args) exit(-1); } - f4js.GetAttrFunc = Persistent::New(FunctionTemplate::New(GetAttrCompletion)->GetFunction()); - f4js.ReadDirFunc = Persistent::New(FunctionTemplate::New(ReadDirCompletion)->GetFunction()); - f4js.ReadLinkFunc = Persistent::New(FunctionTemplate::New(ReadLinkCompletion)->GetFunction()); - f4js.StatfsFunc = Persistent::New(FunctionTemplate::New(StatfsCompletion)->GetFunction()); - f4js.OpenCreateFunc = Persistent::New(FunctionTemplate::New(OpenCreateCompletion)->GetFunction()); - f4js.ReadFunc = Persistent::New(FunctionTemplate::New(ReadCompletion)->GetFunction()); - f4js.WriteFunc = Persistent::New(FunctionTemplate::New(WriteCompletion)->GetFunction()); - f4js.GenericFunc = Persistent::New(FunctionTemplate::New(GenericCompletion)->GetFunction()); + // NanSetPrototypeTemplate() + // f4js.GetAttrFunc = Persistent::New(FunctionTemplate::New(GetAttrCompletion)->GetFunction()); + NanAssignPersistent(f4js.GetAttrFunc, NanNew(GetAttrCompletion)->GetFunction() ); + NanAssignPersistent(f4js.ReadDirFunc, NanNew(ReadDirCompletion)->GetFunction()); + NanAssignPersistent(f4js.ReadLinkFunc, NanNew(ReadLinkCompletion)->GetFunction()); + NanAssignPersistent(f4js.StatfsFunc, NanNew(StatfsCompletion)->GetFunction()); + NanAssignPersistent(f4js.OpenCreateFunc, NanNew(OpenCreateCompletion)->GetFunction()); + NanAssignPersistent(f4js.ReadFunc, NanNew(ReadCompletion)->GetFunction()); + NanAssignPersistent(f4js.WriteFunc, NanNew(WriteCompletion)->GetFunction()); + NanAssignPersistent(f4js.GenericFunc, NanNew(GenericCompletion)->GetFunction()); - uv_async_init(uv_default_loop(), &f4js.async, DispatchOp); + uv_async_init(uv_default_loop(), &f4js.async, (uv_async_cb) DispatchOp); pthread_attr_t attr; pthread_attr_init(&attr); pthread_create(&f4js.fuse_thread, &attr, fuse_thread, NULL); - return scope.Close(String::New("dummy")); + NanEscapeScope(NanNew("dummy")); } // --------------------------------------------------------------------------- void init(Handle target) { - target->Set(String::NewSymbol("start"), FunctionTemplate::New(Start)->GetFunction()); + target->Set(NanNew("start"), NanNew(Start)->GetFunction()); } // --------------------------------------------------------------------------- diff --git a/package.json b/package.json index 2a53921..656e35a 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ }, "main": "./build/Release/fuse4js.node", "dependencies": { + "nan": "^1.4.1" }, "scripts": { "install": "node-gyp rebuild"