Merge lp:~marcustomlinson/v8-cpp/test-gc into lp:v8-cpp

Proposed by Marcus Tomlinson
Status: Merged
Approved by: Marcus Tomlinson
Approved revision: 34
Merged at revision: 28
Proposed branch: lp:~marcustomlinson/v8-cpp/test-gc
Merge into: lp:v8-cpp
Diff against target: 533 lines (+222/-88)
7 files modified
src/internal/class.h (+102/-39)
src/internal/convert.h (+35/-27)
src/run.h (+5/-0)
tests/objects/module.cpp (+2/-0)
tests/objects/test.cpp (+59/-16)
tests/objects/test.h (+17/-5)
valgrind.supp (+2/-1)
To merge this branch: bzr merge lp:~marcustomlinson/v8-cpp/test-gc
Reviewer Review Type Date Requested Status
Alexandre Abreu (community) Approve
Review via email: mp+269594@code.launchpad.net

Commit message

Added support for shared_ptr and unique_ptr

To post a comment you must log in.
Revision history for this message
Alexandre Abreu (abreu-alexandre) wrote :

small comment inline

Revision history for this message
Marcus Tomlinson (marcustomlinson) wrote :

Replied to inline comments.

Revision history for this message
Alexandre Abreu (abreu-alexandre) wrote :

replied

Revision history for this message
Marcus Tomlinson (marcustomlinson) wrote :

> replied

Ok I see what you're saying. I'll try specifically set the internal field counts to 2 and 3 for non-shared_ptr and shared_ptr objects respectively.

Revision history for this message
Marcus Tomlinson (marcustomlinson) wrote :

Hmmm, so I've untangled my thoughts and realised again why it has to remain implemented this way.

The internal field count is set when creating the class template. This template is what we use to mould instances of the class as they are created. We only manage exported class types, even in the case of smart pointers, we are actually instantiating the underlying class type template and appending the extra smart pointer reference as the 3rd internal field.

Seeing that we need our class templates to support both normal instances as well as smart pointer instances, we have to make that 3rd internal field available in all of our templates as either variant may be constructed from them.

Hope I'm making sense?

Revision history for this message
Alexandre Abreu (abreu-alexandre) wrote :

> Hmmm, so I've untangled my thoughts and realised again why it has to remain
> implemented this way.
>
> The internal field count is set when creating the class template. This
> template is what we use to mould instances of the class as they are created.
> We only manage exported class types, even in the case of smart pointers, we
> are actually instantiating the underlying class type template and appending
> the extra smart pointer reference as the 3rd internal field.
>
> Seeing that we need our class templates to support both normal instances as
> well as smart pointer instances, we have to make that 3rd internal field
> available in all of our templates as either variant may be constructed from
> them.
>
> Hope I'm making sense?

totally,

mmh changing that would require quite a bit of "redoing", we might as well leave this as is, and update it if necessary,

Revision history for this message
Alexandre Abreu (abreu-alexandre) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/internal/class.h'
--- src/internal/class.h 2015-08-05 18:57:44 +0000
+++ src/internal/class.h 2015-09-01 09:57:53 +0000
@@ -22,6 +22,12 @@
22#include <internal/function.h>22#include <internal/function.h>
23#include <internal/utility/object_factory.h>23#include <internal/utility/object_factory.h>
2424
25#include <memory>
26
27template <typename T> struct IsSharedPointer : std::false_type {};
28template <typename T> struct IsSharedPointer<std::shared_ptr<T>> : std::true_type { using type = T; };
29template <typename T> struct IsSharedPointer<std::shared_ptr<T const>> : std::true_type { using type = T; };
30
25namespace v8cpp31namespace v8cpp
26{32{
27namespace internal33namespace internal
@@ -44,7 +50,7 @@
44 }50 }
4551
46 // Find Class instance by class type52 // Find Class instance by class type
47 size_t my_type = class_type_();53 size_t my_type = class_type();
48 Class* result;54 Class* result;
49 if (my_type < instances->size())55 if (my_type < instances->size())
50 {56 {
@@ -96,50 +102,111 @@
96 proto_template()->Inherit(base_class->class_template());102 proto_template()->Inherit(base_class->class_template());
97 }103 }
98104
99 v8::Local<v8::Object> export_object(T* object)105 template <typename O>
106 typename std::enable_if<IsSharedPointer<O>::value, v8::Local<v8::Object>>::type export_object(O* object, bool)
100 {107 {
101 v8::EscapableHandleScope scope(isolate_);108 v8::EscapableHandleScope scope(isolate_);
102109
103 v8::Local<v8::Object> v8_object = class_template()->GetFunction()->NewInstance();110 using raw_ptr_class = Class<typename IsSharedPointer<T>::type>;
104 v8_object->SetAlignedPointerInInternalField(0, object);111 v8::Local<v8::Object> v8_object = raw_ptr_class::instance(isolate_).class_template()->GetFunction()->NewInstance();
105 v8_object->SetAlignedPointerInInternalField(1, this);112 v8_object->SetAlignedPointerInInternalField(0, object->get());
113 v8_object->SetAlignedPointerInInternalField(1, &raw_ptr_class::instance(isolate_));
114 v8_object->SetAlignedPointerInInternalField(2, object);
106115
107 MoveablePersistent<v8::Object> v8_object_p(isolate_, v8_object);116 MoveablePersistent<v8::Object> v8_object_p(isolate_, v8_object);
108 v8_object_p.SetWeak(object, [](v8::WeakCallbackData<v8::Object, T> const& data)117 v8_object_p.SetWeak(object, [](v8::WeakCallbackData<v8::Object, T> const& data)
109 {118 {
110 v8::Isolate* isolate = data.GetIsolate();119 v8::Isolate* isolate = data.GetIsolate();
111 T* object = data.GetParameter();120 T* object = data.GetParameter();
112 instance(isolate).destroy_object(object);121 raw_ptr_class::instance(isolate).remove_object<T>(isolate, object, &ObjectFactory<T>::delete_object);
113 });122 });
114123
115 ClassInfo::add_object(object, std::move(v8_object_p));124 raw_ptr_class::instance(isolate_).add_object(object, std::move(v8_object_p));
116125
117 return scope.Escape(v8_object);126 return scope.Escape(v8_object);
118 }127 }
119128
120 v8::Local<v8::Object> export_object(T const* object)129 template <typename O>
121 {130 typename std::enable_if<!IsSharedPointer<O>::value, v8::Local<v8::Object>>::type export_object(O* object, bool gc)
122 return export_object(const_cast<T*>(object));131 {
132 v8::EscapableHandleScope scope(isolate_);
133
134 v8::Local<v8::Object> v8_object = class_template()->GetFunction()->NewInstance();
135 v8_object->SetAlignedPointerInInternalField(0, object);
136 v8_object->SetAlignedPointerInInternalField(1, this);
137 v8_object->SetAlignedPointerInInternalField(2, nullptr);
138
139 MoveablePersistent<v8::Object> v8_object_p(isolate_, v8_object);
140 if (gc)
141 {
142 v8_object_p.SetWeak(object, [](v8::WeakCallbackData<v8::Object, T> const& data)
143 {
144 v8::Isolate* isolate = data.GetIsolate();
145 T* object = data.GetParameter();
146 instance(isolate).remove_object<T>(isolate, object, &ObjectFactory<T>::delete_object);
147 });
148 }
149 else
150 {
151 v8_object_p.SetWeak(object, [](v8::WeakCallbackData<v8::Object, T> const& data)
152 {
153 v8::Isolate* isolate = data.GetIsolate();
154 T* object = data.GetParameter();
155 instance(isolate).remove_object<T>(isolate, object, nullptr);
156 });
157 }
158
159 add_object(object, std::move(v8_object_p));
160
161 return scope.Escape(v8_object);
162 }
163
164 v8::Local<v8::Object> export_object(T const* object, bool gc)
165 {
166 return export_object(const_cast<T*>(object), gc);
123 }167 }
124168
125 v8::Local<v8::Object> export_object(v8::FunctionCallbackInfo<v8::Value> const& args)169 v8::Local<v8::Object> export_object(v8::FunctionCallbackInfo<v8::Value> const& args)
126 {170 {
127 return constructor_ ? export_object(constructor_(args)) :171 return constructor_ ? export_object(constructor_(args), true) :
128 throw std::runtime_error("exported class does not have a constructor specified");172 throw std::runtime_error("exported class does not have a constructor specified");
129 }173 }
130174
131 T* import_object(v8::Local<v8::Value> value)175 template <typename O>
132 {176 typename std::enable_if<IsSharedPointer<O>::value, O*>::type import_object(v8::Local<v8::Value> value)
133 v8::HandleScope scope(isolate_);177 {
134178 v8::HandleScope scope(isolate_);
135 while (value->IsObject())179
136 {180 while (value->IsObject())
137 v8::Local<v8::Object> object = value->ToObject();181 {
138 if (object->InternalFieldCount() == 2)182 v8::Local<v8::Object> object = value->ToObject();
139 {183 if (object->InternalFieldCount() == 3)
140 void* ptr = object->GetAlignedPointerFromInternalField(0);184 {
141 ClassInfo* info = static_cast<ClassInfo*>(object->GetAlignedPointerFromInternalField(1));185 void* ptr = object->GetAlignedPointerFromInternalField(0);
142 if (info && info->cast(ptr, class_type_()))186 ClassInfo* info = static_cast<ClassInfo*>(object->GetAlignedPointerFromInternalField(1));
187 if (info && info->cast(ptr, Class<typename IsSharedPointer<T>::type>::instance(isolate_).class_type()))
188 {
189 return static_cast<T*>(object->GetAlignedPointerFromInternalField(2));
190 }
191 }
192 value = object->GetPrototype();
193 }
194 return nullptr;
195 }
196
197 template <typename O>
198 typename std::enable_if<!IsSharedPointer<O>::value, O*>::type import_object(v8::Local<v8::Value> value)
199 {
200 v8::HandleScope scope(isolate_);
201
202 while (value->IsObject())
203 {
204 v8::Local<v8::Object> object = value->ToObject();
205 if (object->InternalFieldCount() == 3)
206 {
207 void* ptr = object->GetAlignedPointerFromInternalField(0);
208 ClassInfo* info = static_cast<ClassInfo*>(object->GetAlignedPointerFromInternalField(1));
209 if (info && info->cast(ptr, class_type()))
143 {210 {
144 return static_cast<T*>(ptr);211 return static_cast<T*>(ptr);
145 }212 }
@@ -149,11 +216,6 @@
149 return nullptr;216 return nullptr;
150 }217 }
151218
152 void destroy_object(T* object)
153 {
154 ClassInfo::remove_object(isolate_, object, &ObjectFactory<T>::delete_object);
155 }
156
157 template <typename P>219 template <typename P>
158 static void get_member(v8::Local<v8::String>, v8::PropertyCallbackInfo<v8::Value> const& info)220 static void get_member(v8::Local<v8::String>, v8::PropertyCallbackInfo<v8::Value> const& info)
159 {221 {
@@ -177,6 +239,12 @@
177 self.*property_ptr = from_v8<PropType>(isolate, value);239 self.*property_ptr = from_v8<PropType>(isolate, value);
178 }240 }
179241
242 static size_t class_type()
243 {
244 static size_t my_type = ClassInfo::register_class();
245 return my_type;
246 }
247
180private:248private:
181 explicit Class(v8::Isolate* isolate, size_t type)249 explicit Class(v8::Isolate* isolate, size_t type)
182 : ClassInfo(type)250 : ClassInfo(type)
@@ -205,13 +273,8 @@
205273
206 // Each JS instance has a built-in field holding a pointer to the C++ object274 // Each JS instance has a built-in field holding a pointer to the C++ object
207 // We add a second field to hold a pointer to this Class instance275 // We add a second field to hold a pointer to this Class instance
208 class_template->InstanceTemplate()->SetInternalFieldCount(2);276 // And an optional third field to hold a smart pointer
209 }277 class_template->InstanceTemplate()->SetInternalFieldCount(3);
210
211 static size_t class_type_()
212 {
213 static size_t my_type = ClassInfo::register_class();
214 return my_type;
215 }278 }
216279
217 v8::Isolate* isolate_;280 v8::Isolate* isolate_;
218281
=== modified file 'src/internal/convert.h'
--- src/internal/convert.h 2015-08-05 18:57:44 +0000
+++ src/internal/convert.h 2015-09-01 09:57:53 +0000
@@ -21,6 +21,7 @@
21#include <climits>21#include <climits>
22#include <vector>22#include <vector>
23#include <map>23#include <map>
24#include <memory>
2425
25#include <v8.h>26#include <v8.h>
2627
@@ -369,40 +370,38 @@
369370
370// Exported class converters371// Exported class converters
371template <typename T>372template <typename T>
372struct IsExportedClass : std::is_class<T>373struct IsExportedClass : std::is_class<T> {};
373{374
374};375template <typename T>
375376struct IsExportedClass<v8::Local<T>> : std::false_type {};
376template <typename T>377
377struct IsExportedClass<v8::Local<T>> : std::false_type378template <typename T>
378{379struct IsExportedClass<v8::Persistent<T>> : std::false_type {};
379};
380
381template <typename T>
382struct IsExportedClass<v8::Persistent<T>> : std::false_type
383{
384};
385380
386template <typename Char, typename Traits, typename Alloc>381template <typename Char, typename Traits, typename Alloc>
387struct IsExportedClass<std::basic_string<Char, Traits, Alloc>> : std::false_type382struct IsExportedClass<std::basic_string<Char, Traits, Alloc>> : std::false_type {};
388{
389};
390383
391template <typename T, typename Alloc>384template <typename T, typename Alloc>
392struct IsExportedClass<std::vector<T, Alloc>> : std::false_type385struct IsExportedClass<std::vector<T, Alloc>> : std::false_type {};
393{
394};
395386
396template <typename Key, typename Value, typename Less, typename Alloc>387template <typename Key, typename Value, typename Less, typename Alloc>
397struct IsExportedClass<std::map<Key, Value, Less, Alloc>> : std::false_type388struct IsExportedClass<std::map<Key, Value, Less, Alloc>> : std::false_type {};
398{389
399};390template <typename T>
391struct IsUniquePointer : std::false_type {};
392
393template <typename T>
394struct IsUniquePointer<std::unique_ptr<T>> : std::true_type { using type = T; };
395
396template <typename T>
397struct IsUniquePointer<std::unique_ptr<T const>> : std::true_type { using type = T; };
400398
401template <typename T>399template <typename T>
402struct Convert<T, typename std::enable_if<IsExportedClass<T>::value>::type>400struct Convert<T, typename std::enable_if<IsExportedClass<T>::value>::type>
403{401{
404 using FromType = T&;402 using FromType = T&;
405 using ToType = v8::Local<v8::Object>;403 using ToType = v8::Local<v8::Object>;
404 using ClassType = typename std::remove_cv<T>::type;
406405
407 static bool is_valid(v8::Isolate*, v8::Local<v8::Value> value)406 static bool is_valid(v8::Isolate*, v8::Local<v8::Value> value)
408 {407 {
@@ -422,9 +421,18 @@
422 throw std::runtime_error("expected an exported object");421 throw std::runtime_error("expected an exported object");
423 }422 }
424423
425 static ToType to_v8(v8::Isolate* isolate, T const& value)424 template <typename O>
426 {425 static typename std::enable_if<IsUniquePointer<O>::value, ToType>::type to_v8(v8::Isolate* isolate, O const& value)
427 return Convert<T*>::to_v8(isolate, new T(value));426 {
427 // Convert unique pointers to shared pointers before exposing them to v8
428 std::shared_ptr<typename IsUniquePointer<T>::type> s_ptr{std::move(const_cast<T&>(value))};
429 return Convert<std::shared_ptr<typename IsUniquePointer<T>::type>>::to_v8(isolate, s_ptr);
430 }
431
432 template <typename O>
433 static typename std::enable_if<!IsUniquePointer<O>::value, ToType>::type to_v8(v8::Isolate* isolate, O const& value)
434 {
435 return Class<ClassType>::instance(isolate).export_object(new T(value), true);
428 }436 }
429};437};
430438
@@ -446,12 +454,12 @@
446 {454 {
447 throw std::invalid_argument("expected an object");455 throw std::invalid_argument("expected an object");
448 }456 }
449 return Class<ClassType>::instance(isolate).import_object(value);457 return Class<ClassType>::instance(isolate).template import_object<T>(value);
450 }458 }
451459
452 static ToType to_v8(v8::Isolate* isolate, T const* value)460 static ToType to_v8(v8::Isolate* isolate, T const* value)
453 {461 {
454 return Class<ClassType>::instance(isolate).export_object(value);462 return Class<ClassType>::instance(isolate).export_object(value, false);
455 }463 }
456};464};
457465
458466
=== modified file 'src/run.h'
--- src/run.h 2015-08-05 18:57:44 +0000
+++ src/run.h 2015-09-01 09:57:53 +0000
@@ -32,6 +32,11 @@
32 // Create an isolate32 // Create an isolate
33 std::shared_ptr<v8::Isolate> isolate(v8::Isolate::New(), [](v8::Isolate* isolate)33 std::shared_ptr<v8::Isolate> isolate(v8::Isolate::New(), [](v8::Isolate* isolate)
34 {34 {
35 // Force garbage collection before returning
36 std::string const v8_flags = "--expose_gc";
37 v8::V8::SetFlagsFromString(v8_flags.data(), (int)v8_flags.length());
38 isolate->RequestGarbageCollectionForTesting(v8::Isolate::GarbageCollectionType::kFullGarbageCollection);
39
35 // Clean up40 // Clean up
36 using ClassInstances = std::vector<v8cpp::internal::Class<void>*>;41 using ClassInstances = std::vector<v8cpp::internal::Class<void>*>;
37 ClassInstances* instances = static_cast<ClassInstances*>(isolate->GetData(0));42 ClassInstances* instances = static_cast<ClassInstances*>(isolate->GetData(0));
3843
=== modified file 'tests/objects/module.cpp'
--- tests/objects/module.cpp 2015-08-05 18:57:44 +0000
+++ tests/objects/module.cpp 2015-09-01 09:57:53 +0000
@@ -32,6 +32,8 @@
32 testclass32 testclass
33 .set_constructor<int, int>()33 .set_constructor<int, int>()
34 .add_method("i", &TestClass::i)34 .add_method("i", &TestClass::i)
35 .add_method("embedded_class_sptr", &TestClass::embedded_class_sptr)
36 .add_method("embedded_class_uptr", &TestClass::embedded_class_uptr)
35 .add_method("embedded_class_ptr", &TestClass::embedded_class_ptr)37 .add_method("embedded_class_ptr", &TestClass::embedded_class_ptr)
36 .add_method("embedded_class_ref", &TestClass::embedded_class_ref)38 .add_method("embedded_class_ref", &TestClass::embedded_class_ref)
37 .add_method("embedded_class_copy", &TestClass::embedded_class_copy)39 .add_method("embedded_class_copy", &TestClass::embedded_class_copy)
3840
=== modified file 'tests/objects/test.cpp'
--- tests/objects/test.cpp 2015-07-08 09:29:21 +0000
+++ tests/objects/test.cpp 2015-09-01 09:57:53 +0000
@@ -54,32 +54,41 @@
5454
55TEST(Test, object_to_js)55TEST(Test, object_to_js)
56{56{
57 auto test_object = v8cpp::run_script<EmbeddedTestClass*>(57 auto test_object = v8cpp::run_script<std::shared_ptr<EmbeddedTestClass>>(
58 R"(
59 var module = require("./test-objects-module");
60 var test_object = module.new_TestClass(1, 2);
61 test_object.embedded_class_uptr();
62 )");
63
64 EXPECT_EQ(test_object->i(), -1);
65
66 auto test_object2 = v8cpp::run_script<std::shared_ptr<EmbeddedTestClass>>(
67 R"(
68 var module = require("./test-objects-module");
69 var test_object = module.new_TestClass(1, 2);
70 test_object.embedded_class_sptr();
71 )");
72
73 EXPECT_EQ(test_object2->i(), -1);
74
75 auto test_object3 = v8cpp::run_script<EmbeddedTestClass*>(
58 R"(76 R"(
59 var module = require("./test-objects-module");77 var module = require("./test-objects-module");
60 var test_object = module.new_TestClass(1, 2);78 var test_object = module.new_TestClass(1, 2);
61 test_object.embedded_class_ptr();79 test_object.embedded_class_ptr();
62 )");80 )");
6381
64 EXPECT_EQ(test_object->i(), -1);82 EXPECT_EQ(test_object3->i(), -1);
6583
66 auto test_object2 = v8cpp::run_script<EmbeddedTestClass&>(84 auto test_object4 = v8cpp::run_script<EmbeddedTestClass>(
67 R"(
68 var module = require("./test-objects-module");
69 var test_object = module.new_TestClass(1, 2);
70 test_object.embedded_class_ref();
71 )");
72
73 EXPECT_EQ(test_object2.i(), -1);
74
75 auto test_object3 = v8cpp::run_script<EmbeddedTestClass>(
76 R"(85 R"(
77 var module = require("./test-objects-module");86 var module = require("./test-objects-module");
78 var test_object = module.new_TestClass(1, 2);87 var test_object = module.new_TestClass(1, 2);
79 test_object.embedded_class_copy();88 test_object.embedded_class_copy();
80 )");89 )");
8190
82 EXPECT_EQ(test_object3.i(), -1);91 EXPECT_EQ(test_object4.i(), -1);
83}92}
8493
85TEST(Test, object_from_js)94TEST(Test, object_from_js)
@@ -94,9 +103,31 @@
94 test_object;103 test_object;
95 )");104 )");
96105
106 auto result = v8cpp::run_script<int>(
107 R"(
108 var module = require("./test-objects-module");
109 var test_object = module.new_TestClass(1, 2);
110
111 var embedded_object = test_object.embedded_class_uptr();
112 embedded_object.i();
113 )");
114
115 EXPECT_EQ(result, -1);
116
117 auto result2 = v8cpp::run_script<int>(
118 R"(
119 var module = require("./test-objects-module");
120 var test_object = module.new_TestClass(1, 2);
121
122 var embedded_object = test_object.embedded_class_sptr();
123 embedded_object.i();
124 )");
125
126 EXPECT_EQ(result2, -1);
127
97 EXPECT_EQ(test_object.i(), -1);128 EXPECT_EQ(test_object.i(), -1);
98129
99 auto result = v8cpp::run_script<int>(130 auto result3 = v8cpp::run_script<int>(
100 R"(131 R"(
101 var module = require("./test-objects-module");132 var module = require("./test-objects-module");
102 var test_object = module.new_TestClass(1, 2);133 var test_object = module.new_TestClass(1, 2);
@@ -106,5 +137,17 @@
106 test_object2.embedded_class_ref());137 test_object2.embedded_class_ref());
107 )");138 )");
108139
109 EXPECT_EQ(result, -2);140 EXPECT_EQ(result3, -2);
141
142 auto result4 = v8cpp::run_script<int>(
143 R"(
144 var module = require("./test-objects-module");
145 var test_object = module.new_TestClass(1, 2);
146 var test_object2 = module.new_TestClass(1, 2);
147
148 test_object.add_i(test_object.embedded_class_sptr(),
149 test_object2.embedded_class_uptr());
150 )");
151
152 EXPECT_EQ(result4, -2);
110}153}
111154
=== modified file 'tests/objects/test.h'
--- tests/objects/test.h 2015-07-08 06:20:26 +0000
+++ tests/objects/test.h 2015-09-01 09:57:53 +0000
@@ -20,6 +20,8 @@
2020
21#include <gtest/gtest.h>21#include <gtest/gtest.h>
2222
23#include <memory>
24
23class EmbeddedTestClass25class EmbeddedTestClass
24{26{
25public:27public:
@@ -43,7 +45,7 @@
43{45{
44public:46public:
45 TestClass(int a, int b)47 TestClass(int a, int b)
46 : embedded_class_(a, b)48 : embedded_class_(std::make_shared<EmbeddedTestClass>(a, b))
47 {49 {
48 EXPECT_EQ(a, 1);50 EXPECT_EQ(a, 1);
49 EXPECT_EQ(b, 2);51 EXPECT_EQ(b, 2);
@@ -55,19 +57,29 @@
55 return i_;57 return i_;
56 }58 }
5759
60 std::shared_ptr<EmbeddedTestClass> embedded_class_sptr()
61 {
62 return embedded_class_;
63 }
64
65 std::unique_ptr<EmbeddedTestClass> embedded_class_uptr()
66 {
67 return std::unique_ptr<EmbeddedTestClass>(new EmbeddedTestClass(1, 2));
68 }
69
58 EmbeddedTestClass* embedded_class_ptr()70 EmbeddedTestClass* embedded_class_ptr()
59 {71 {
60 return &embedded_class_;72 return embedded_class_.get();
61 }73 }
6274
63 EmbeddedTestClass& embedded_class_ref()75 EmbeddedTestClass& embedded_class_ref()
64 {76 {
65 return embedded_class_;77 return *embedded_class_;
66 }78 }
6779
68 EmbeddedTestClass embedded_class_copy()80 EmbeddedTestClass embedded_class_copy()
69 {81 {
70 return embedded_class_;82 return *embedded_class_;
71 }83 }
7284
73 void replace_i(EmbeddedTestClass const& other)85 void replace_i(EmbeddedTestClass const& other)
@@ -81,7 +93,7 @@
81 }93 }
8294
83private:95private:
84 EmbeddedTestClass embedded_class_;96 std::shared_ptr<EmbeddedTestClass> embedded_class_;
85 int i_;97 int i_;
86};98};
8799
88100
=== modified file 'valgrind.supp'
--- valgrind.supp 2015-07-08 09:37:32 +0000
+++ valgrind.supp 2015-09-01 09:57:53 +0000
@@ -21,7 +21,8 @@
21 GC not cleaning up exported objects (via to_v8)21 GC not cleaning up exported objects (via to_v8)
22 Memcheck:Leak22 Memcheck:Leak
23 fun:_Znwm23 fun:_Znwm
24 fun:_ZN5v8cpp8internal7Convert*to_v8EPN2v87IsolateERKS2_24 fun:_ZN5v8cpp8internal7Convert*to_v8*
25 ...
25 fun:_ZN5v8cpp5to_v8*26 fun:_ZN5v8cpp5to_v8*
26 fun:_ZN5v8cpp8internal14forward_invoke*27 fun:_ZN5v8cpp8internal14forward_invoke*
27 fun:_ZN5v8cpp8internal16forward_function*28 fun:_ZN5v8cpp8internal16forward_function*

Subscribers

People subscribed via source and target branches

to all changes: