2
2
#include " DataWrapper.h"
3
3
#include " Helpers.h"
4
4
#include " Interop.h"
5
- #include " Caches .h"
5
+ #include " IsolateWrapper .h"
6
6
7
7
using namespace tns ;
8
8
using namespace v8 ;
9
9
10
10
@implementation ArrayAdapter {
11
- Isolate* isolate_ ;
11
+ IsolateWrapper* wrapper_ ;
12
12
std::shared_ptr<Persistent<Value>> object_;
13
- std::shared_ptr<Caches> cache_;
13
+ // we're responsible for this wrapper
14
+ ObjCDataWrapper* dataWrapper_;
14
15
}
15
16
16
17
- (instancetype )initWithJSObject : (Local<Object>)jsObject isolate : (Isolate*)isolate {
17
18
if (self) {
18
- self->isolate_ = isolate;
19
- self->cache_ = Caches::Get (isolate);
19
+ self->wrapper_ = new IsolateWrapper (isolate);
20
20
self->object_ = std::make_shared<Persistent<Value>>(isolate, jsObject);
21
- self->cache_ ->Instances .emplace (self, self->object_ );
22
- tns::SetValue (isolate, jsObject, new ObjCDataWrapper (self));
21
+ self->wrapper_ -> GetCache () ->Instances .emplace (self, self->object_ );
22
+ tns::SetValue (isolate, jsObject, (self-> dataWrapper_ = new ObjCDataWrapper (self) ));
23
23
}
24
-
24
+
25
25
return self;
26
26
}
27
27
28
28
- (NSUInteger )count {
29
- v8::Locker locker (self->isolate_ );
30
- Isolate::Scope isolate_scope (self->isolate_ );
31
- HandleScope handle_scope (self->isolate_ );
32
-
33
- Local<Object> object = self->object_ ->Get (self->isolate_ ).As <Object>();
29
+ auto isolate = wrapper_->Isolate ();
30
+ if (!wrapper_->IsValid ()) {
31
+ return 0 ;
32
+ }
33
+ v8::Locker locker (isolate);
34
+ Isolate::Scope isolate_scope (isolate);
35
+ HandleScope handle_scope (isolate);
36
+
37
+ Local<Object> object = self->object_ ->Get (isolate).As <Object>();
34
38
if (object->IsArray ()) {
35
39
uint32_t length = object.As <v8::Array>()->Length ();
36
40
return length;
37
41
}
38
-
39
- Local<Context> context = self-> cache_ ->GetContext ();
42
+
43
+ Local<Context> context = wrapper_-> GetCache () ->GetContext ();
40
44
Local<v8::Array> propertyNames;
41
45
bool success = object->GetPropertyNames (context).ToLocal (&propertyNames);
42
- tns::Assert (success, self-> isolate_ );
46
+ tns::Assert (success, isolate );
43
47
uint32_t length = propertyNames->Length ();
44
48
return length;
45
49
}
46
50
47
51
- (id )objectAtIndex : (NSUInteger )index {
48
- v8::Locker locker (self->isolate_ );
49
- Isolate::Scope isolate_scope (self->isolate_ );
50
- HandleScope handle_scope (self->isolate_ );
51
-
52
+ auto isolate = wrapper_->Isolate ();
53
+ if (!wrapper_->IsValid ()) {
54
+ return nil ;
55
+ }
56
+ v8::Locker locker (isolate);
57
+ Isolate::Scope isolate_scope (isolate);
58
+ HandleScope handle_scope (isolate);
59
+
52
60
if (!(index < [self count ])) {
53
- tns::Assert (false , self-> isolate_ );
61
+ tns::Assert (false , isolate );
54
62
}
55
-
56
- Local<Object> object = self->object_ ->Get (self-> isolate_ ).As <Object>();
57
- Local<Context> context = self-> cache_ ->GetContext ();
63
+
64
+ Local<Object> object = self->object_ ->Get (isolate ).As <Object>();
65
+ Local<Context> context = wrapper_-> GetCache () ->GetContext ();
58
66
Local<Value> item;
59
67
bool success = object->Get (context, (uint)index).ToLocal (&item);
60
- tns::Assert (success, self-> isolate_ );
61
-
68
+ tns::Assert (success, isolate );
69
+
62
70
if (item->IsNullOrUndefined ()) {
63
71
return nil ;
64
72
}
@@ -68,16 +76,29 @@ - (id)objectAtIndex:(NSUInteger)index {
68
76
}
69
77
70
78
- (void )dealloc {
71
- self->cache_ ->Instances .erase (self);
72
- Local<Value> value = self->object_ ->Get (self->isolate_ );
73
- BaseDataWrapper* wrapper = tns::GetValue (self->isolate_ , value);
74
- if (wrapper != nullptr ) {
75
- tns::DeleteValue (self->isolate_ , value);
76
- delete wrapper;
79
+ if (wrapper_->IsValid ()) {
80
+ auto isolate = wrapper_->Isolate ();
81
+ v8::Locker locker (isolate);
82
+ Isolate::Scope isolate_scope (isolate);
83
+ HandleScope handle_scope (isolate);
84
+ wrapper_->GetCache ()->Instances .erase (self);
85
+ Local<Value> value = self->object_ ->Get (isolate);
86
+ BaseDataWrapper* wrapper = tns::GetValue (isolate, value);
87
+ if (wrapper != nullptr ) {
88
+ tns::DeleteValue (isolate, value);
89
+ // ensure we don't delete the same wrapper twice
90
+ // this is just needed as a failsafe in case some other wrapper is assigned to this object
91
+ if (wrapper == dataWrapper_) {
92
+ dataWrapper_ = nullptr ;
93
+ }
94
+ delete wrapper;
95
+ }
96
+ self->object_ ->Reset ();
97
+ }
98
+ delete wrapper_;
99
+ if (dataWrapper_ != nullptr ) {
100
+ delete dataWrapper_;
77
101
}
78
- self->object_ ->Reset ();
79
- self->isolate_ = nullptr ;
80
- self->cache_ = nullptr ;
81
102
self->object_ = nullptr ;
82
103
[super dealloc ];
83
104
}
0 commit comments