Merge lp:~marcustomlinson/v8-cpp/lp-1474858 into lp:v8-cpp

Proposed by Marcus Tomlinson on 2015-07-16
Status: Merged
Merged at revision: 22
Proposed branch: lp:~marcustomlinson/v8-cpp/lp-1474858
Merge into: lp:v8-cpp
Diff against target: 350 lines (+109/-57)
10 files modified
example/module.cpp (+1/-1)
src/internal/class.h (+2/-2)
src/internal/class_info.h (+3/-3)
src/internal/function.h (+2/-2)
src/internal/require.h (+69/-40)
src/module.h (+2/-2)
src/run.h (+8/-5)
tests/errors/test.cpp (+20/-0)
tests/run/scripts/test.js (+1/-1)
tests/run/scripts/test2.js (+1/-1)
To merge this branch: bzr merge lp:~marcustomlinson/v8-cpp/lp-1474858
Reviewer Review Type Date Requested Status
Marcus Tomlinson Pending
Review via email: mp+264999@code.launchpad.net

Commit message

Fixed require() to load modules relative to script path

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'example/module.cpp'
--- example/module.cpp 2015-07-08 06:20:26 +0000
+++ example/module.cpp 2015-07-16 14:32:42 +0000
@@ -136,5 +136,5 @@
136 exports->SetPrototype(module.create_prototype());136 exports->SetPrototype(module.create_prototype());
137}137}
138138
139NODE_MODULE(addon, InitAll)139///!NODE_MODULE(addon, InitAll)
140V8CPP_MODULE(addon, InitAll)140V8CPP_MODULE(addon, InitAll)
141141
=== modified file 'src/internal/class.h'
--- src/internal/class.h 2015-06-23 08:40:22 +0000
+++ src/internal/class.h 2015-07-16 14:32:42 +0000
@@ -192,10 +192,10 @@
192 {192 {
193 return args.GetReturnValue().Set(instance(isolate).export_object(args));193 return args.GetReturnValue().Set(instance(isolate).export_object(args));
194 }194 }
195 catch (std::exception const& ex)195 catch (std::exception const& e)
196 {196 {
197 auto exception =197 auto exception =
198 isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(isolate, ex.what())));198 isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(isolate, e.what())));
199 args.GetReturnValue().Set(exception);199 args.GetReturnValue().Set(exception);
200 }200 }
201 });201 });
202202
=== modified file 'src/internal/class_info.h'
--- src/internal/class_info.h 2015-07-02 09:52:54 +0000
+++ src/internal/class_info.h 2015-07-16 14:32:42 +0000
@@ -42,7 +42,7 @@
4242
43 using CastFunction = void* (*)(void*);43 using CastFunction = void* (*)(void*);
4444
45 void add_base_class(ClassInfo* info, CastFunction cast)45 inline void add_base_class(ClassInfo* info, CastFunction cast)
46 {46 {
47 auto it = std::find_if(base_classes_.begin(), base_classes_.end(), [info](BaseClassInfo const& base_class)47 auto it = std::find_if(base_classes_.begin(), base_classes_.end(), [info](BaseClassInfo const& base_class)
48 {48 {
@@ -55,7 +55,7 @@
55 }55 }
56 }56 }
5757
58 bool cast(void*& ptr, size_t type) const58 inline bool cast(void*& ptr, size_t type) const
59 {59 {
60 // Type already matches60 // Type already matches
61 if (type == type_)61 if (type == type_)
@@ -111,7 +111,7 @@
111 }111 }
112112
113protected:113protected:
114 static size_t register_class()114 inline static size_t register_class()
115 {115 {
116 static size_t next_index = 0;116 static size_t next_index = 0;
117 return next_index++;117 return next_index++;
118118
=== modified file 'src/internal/function.h'
--- src/internal/function.h 2015-07-16 13:04:34 +0000
+++ src/internal/function.h 2015-07-16 14:32:42 +0000
@@ -102,9 +102,9 @@
102 {102 {
103 forward_invoke<F>(args);103 forward_invoke<F>(args);
104 }104 }
105 catch (std::exception const& ex)105 catch (std::exception const& e)
106 {106 {
107 auto exception = isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(isolate, ex.what())));107 auto exception = isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(isolate, e.what())));
108 args.GetReturnValue().Set(exception);108 args.GetReturnValue().Set(exception);
109 }109 }
110}110}
111111
=== modified file 'src/internal/require.h'
--- src/internal/require.h 2015-07-16 08:05:48 +0000
+++ src/internal/require.h 2015-07-16 14:32:42 +0000
@@ -29,7 +29,6 @@
2929
30using ModuleInitFunc = void(v8::Handle<v8::Object> exports);30using ModuleInitFunc = void(v8::Handle<v8::Object> exports);
31///!ModuleInitFunc* node_init_func_;31///!ModuleInitFunc* node_init_func_;
32///!std::shared_ptr<std::string> v8cpp_script_path_;
3332
34struct NodeModule33struct NodeModule
35{34{
@@ -62,27 +61,29 @@
62public:61public:
63 inline static void log(v8::FunctionCallbackInfo<v8::Value> const& args)62 inline static void log(v8::FunctionCallbackInfo<v8::Value> const& args)
64 {63 {
64 v8::Isolate* isolate = args.GetIsolate();
65
65 for (int i = 0; i < args.Length(); ++i)66 for (int i = 0; i < args.Length(); ++i)
66 {67 {
67 if (args[i]->IsUint32())68 if (args[i]->IsUint32())
68 {69 {
69 std::cout << v8cpp::from_v8<unsigned int>(v8::Isolate::GetCurrent(), args[i]);70 std::cout << v8cpp::from_v8<unsigned int>(isolate, args[i]);
70 }71 }
71 else if (args[i]->IsInt32())72 else if (args[i]->IsInt32())
72 {73 {
73 std::cout << v8cpp::from_v8<int>(v8::Isolate::GetCurrent(), args[i]);74 std::cout << v8cpp::from_v8<int>(isolate, args[i]);
74 }75 }
75 else if (args[i]->IsNumber())76 else if (args[i]->IsNumber())
76 {77 {
77 std::cout << v8cpp::from_v8<float>(v8::Isolate::GetCurrent(), args[i]);78 std::cout << v8cpp::from_v8<float>(isolate, args[i]);
78 }79 }
79 else if (args[i]->IsBoolean())80 else if (args[i]->IsBoolean())
80 {81 {
81 std::cout << v8cpp::from_v8<bool>(v8::Isolate::GetCurrent(), args[i]);82 std::cout << v8cpp::from_v8<bool>(isolate, args[i]);
82 }83 }
83 else if (args[i]->IsString())84 else if (args[i]->IsString())
84 {85 {
85 std::cout << v8cpp::from_v8<std::string>(v8::Isolate::GetCurrent(), args[i]);86 std::cout << v8cpp::from_v8<std::string>(isolate, args[i]);
86 }87 }
87 }88 }
88 std::cout << std::endl;89 std::cout << std::endl;
@@ -90,50 +91,78 @@
90 }91 }
91};92};
9293
93inline v8::Local<v8::Object> require(std::string const& module_path)94class Require
94{95{
95 ///!node_init_func_ = nullptr;96public:
96 std::string script_path; ///! = v8cpp_script_path_ ? *v8cpp_script_path_ : "";97 explicit Require(std::string const& script_path)
98 : script_path_(script_path) {}
9799
98 // Try append ".node" to module_path100 inline static void require(v8::FunctionCallbackInfo<v8::Value> const& args)
99 std::string suffixed_module_path = script_path + module_path + ".node";
100 auto module = dlopen(suffixed_module_path.c_str(), RTLD_LAZY);
101 if (!module)
102 {101 {
103 // Didn't work, now try append ".so" to module_path102 v8::Isolate* isolate = args.GetIsolate();
104 suffixed_module_path = script_path + module_path + ".so";103 v8::EscapableHandleScope scope(isolate);
105 module = dlopen(suffixed_module_path.c_str(), RTLD_LAZY);104
106 if (!module)105 try
107 {106 {
108 // Still didn't work, just try module_path as is107 Require* this_ = internal::import_value<Require*>(args.Data());
109 suffixed_module_path = script_path + module_path;108
110 module = dlopen(suffixed_module_path.c_str(), RTLD_LAZY);109 std::string module_path = from_v8<std::string>(isolate, args[0], "");
110 if (module_path.empty())
111 {
112 throw std::runtime_error("require() call missing string argument");
113 }
114
115 ///!node_init_func_ = nullptr;
116
117 // Try append ".node" to module_path
118 std::string suffixed_module_path = this_->script_path_ + module_path + ".node";
119 auto module = dlopen(suffixed_module_path.c_str(), RTLD_LAZY);
111 if (!module)120 if (!module)
112 {121 {
113 throw std::runtime_error("dlopen failed: " + std::string(dlerror()));122 // Didn't work, now try append ".so" to module_path
123 suffixed_module_path = this_->script_path_ + module_path + ".so";
124 module = dlopen(suffixed_module_path.c_str(), RTLD_LAZY);
125 if (!module)
126 {
127 // Still didn't work, just try module_path as is
128 suffixed_module_path = this_->script_path_ + module_path;
129 module = dlopen(suffixed_module_path.c_str(), RTLD_LAZY);
130 if (!module)
131 {
132 throw std::runtime_error("dlopen failed: " + std::string(dlerror()));
133 }
134 }
114 }135 }
136
137 v8::Local<v8::Object> exports = v8::Object::New(isolate);
138
139 ///!if (node_init_func_)
140 ///!{
141 ///! node_init_func_(exports);
142 ///!}
143 ///!else
144 ///!{
145 auto v8cpp_init_func = (ModuleInitFunc*)dlsym(module, "init_module");
146 if (!v8cpp_init_func)
147 {
148 throw std::runtime_error("dlsym failed: " + std::string(dlerror()));
149 }
150
151 v8cpp_init_func(exports);
152 ///!}
153
154 args.GetReturnValue().Set(scope.Escape(exports));
155 }
156 catch (std::exception const& e)
157 {
158 auto exception = isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(isolate, e.what())));
159 args.GetReturnValue().Set(scope.Escape(exception));
115 }160 }
116 }161 }
117162
118 v8::Local<v8::Object> exports = v8::Object::New(v8::Isolate::GetCurrent());163private:
119164 std::string script_path_;
120///! if (node_init_func_)165};
121///! {
122///! node_init_func_(exports);
123///! }
124///! else
125///! {
126 auto v8cpp_init_func = (ModuleInitFunc*)dlsym(module, "init_module");
127 if (!v8cpp_init_func)
128 {
129 throw std::runtime_error("dlsym failed: " + std::string(dlerror()));
130 }
131
132 v8cpp_init_func(exports);
133///! }
134
135 return exports;
136}
137166
138} // namespace internal167} // namespace internal
139} // namespace v8cpp168} // namespace v8cpp
140169
=== modified file 'src/module.h'
--- src/module.h 2015-06-18 12:32:56 +0000
+++ src/module.h 2015-07-16 14:32:42 +0000
@@ -53,12 +53,12 @@
53 }53 }
5454
55 // Create an instance of this module in V855 // Create an instance of this module in V8
56 v8::Local<v8::Object> create_prototype()56 inline v8::Local<v8::Object> create_prototype()
57 {57 {
58 return object_template_->NewInstance();58 return object_template_->NewInstance();
59 }59 }
6060
61 v8::Handle<v8::ObjectTemplate> object_template()61 inline v8::Handle<v8::ObjectTemplate> object_template()
62 {62 {
63 return object_template_;63 return object_template_;
64 }64 }
6565
=== modified file 'src/run.h'
--- src/run.h 2015-07-15 13:18:16 +0000
+++ src/run.h 2015-07-16 14:32:42 +0000
@@ -45,8 +45,6 @@
45 delete instances;45 delete instances;
46 isolate->SetData(0, nullptr);46 isolate->SetData(0, nullptr);
47 isolate->Dispose();47 isolate->Dispose();
48
49 ///!internal::v8cpp_script_path_.reset();
50 });48 });
5149
52 // Create an isolate scope.50 // Create an isolate scope.
@@ -67,13 +65,17 @@
67 v8::Context::Scope context_scope(v8::Context::New(isolate.get()));65 v8::Context::Scope context_scope(v8::Context::New(isolate.get()));
6866
69 // Store the script filename for use in require() later67 // Store the script filename for use in require() later
68 std::string script_path;
70 std::size_t found = filename.find_last_of("/");69 std::size_t found = filename.find_last_of("/");
71 if (found != std::string::npos)70 if (found != std::string::npos)
72 {71 {
73 ///!internal::v8cpp_script_path_ = std::make_shared<std::string>(filename.substr(0, found) + "/");72 script_path = filename.substr(0, found) + "/";
74 }73 }
7574
76 module.add_function("require", &internal::require);75 v8::Handle<v8::Value> require = internal::export_value(isolate.get(), new internal::Require(script_path));
76 module.object_template()->Set(isolate.get(), "require",
77 v8::FunctionTemplate::New(isolate.get(), internal::Require::require, require));
78
77 module.add_class("console", console);79 module.add_class("console", console);
78 }80 }
79 v8::Local<v8::Context> context = v8::Context::New(isolate.get(), nullptr, module.object_template());81 v8::Local<v8::Context> context = v8::Context::New(isolate.get(), nullptr, module.object_template());
@@ -82,7 +84,8 @@
82 v8::Context::Scope context_scope(context);84 v8::Context::Scope context_scope(context);
8385
84 // Compile the script.86 // Compile the script.
85 v8::Local<v8::Script> script = v8::Script::Compile(v8cpp::to_v8(isolate.get(), source), v8cpp::to_v8(isolate.get(), filename));87 v8::Local<v8::Script> script = v8::Script::Compile(v8cpp::to_v8(isolate.get(), source),
88 v8cpp::to_v8(isolate.get(), filename));
8689
87 // Run the script.90 // Run the script.
88 if (script.IsEmpty())91 if (script.IsEmpty())
8992
=== modified file 'tests/errors/test.cpp'
--- tests/errors/test.cpp 2015-07-08 09:29:21 +0000
+++ tests/errors/test.cpp 2015-07-16 14:32:42 +0000
@@ -22,6 +22,26 @@
2222
23#include <gtest/gtest.h>23#include <gtest/gtest.h>
2424
25TEST(Test, empty_module_path)
26{
27 try
28 {
29 v8cpp::run_script("require()");
30 }
31 catch (std::exception const& e)
32 {
33 EXPECT_STREQ(e.what(), "Uncaught Error: require() call missing string argument");
34 }
35 try
36 {
37 v8cpp::run_script("require('')");
38 }
39 catch (std::exception const& e)
40 {
41 EXPECT_STREQ(e.what(), "Uncaught Error: require() call missing string argument");
42 }
43}
44
25TEST(Test, non_existent_module)45TEST(Test, non_existent_module)
26{46{
27 try47 try
2848
=== modified file 'tests/run/scripts/test.js'
--- tests/run/scripts/test.js 2015-07-15 13:18:16 +0000
+++ tests/run/scripts/test.js 2015-07-16 14:32:42 +0000
@@ -16,6 +16,6 @@
16 * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>16 * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>
17 */17 */
1818
19var module = require("./test-run-module"); ///! ../19var module = require("../test-run-module");
20var test_object = new module.TestClass(1, 2);20var test_object = new module.TestClass(1, 2);
21test_object;21test_object;
2222
=== modified file 'tests/run/scripts/test2.js'
--- tests/run/scripts/test2.js 2015-07-15 13:18:16 +0000
+++ tests/run/scripts/test2.js 2015-07-16 14:32:42 +0000
@@ -21,5 +21,5 @@
21console.log(true, " > ", false);21console.log(true, " > ", false);
22console.log("hello", " ", "there");22console.log("hello", " ", "there");
2323
24var module = require("./test-run-module"); ///! ../24var module = require("../test-run-module");
25new module.TestClass(3, 4);25new module.TestClass(3, 4);

Subscribers

People subscribed via source and target branches

to all changes: