@@ -99,14 +99,20 @@ void Reference::IndexedPropertyGetCallback(uint32_t index, const PropertyCallbac
9999 Local<Object> thiz = info.This ();
100100 Local<Context> context = isolate->GetCurrentContext ();
101101
102- DataPair pair = Reference::GetTypeEncodingDataPair (thiz);
102+ DataPair pair = Reference::GetDataPair (thiz);
103103 const TypeEncoding* typeEncoding = pair.typeEncoding_ ;
104104 size_t size = pair.size_ ;
105105 void * data = pair.data_ ;
106106
107107 void * ptr = (uint8_t *)data + index * size;
108108 BaseCall call ((uint8_t *)ptr);
109- Local<Value> result = Interop::GetResult (context, typeEncoding, &call, false );
109+
110+ Local<Value> result;
111+ if (typeEncoding != nullptr ) {
112+ result = Interop::GetResult (context, typeEncoding, &call, false );
113+ } else {
114+ result = Interop::GetResultByType (context, pair.typeWrapper_ , &call);
115+ }
110116 info.GetReturnValue ().Set (result);
111117}
112118
@@ -115,13 +121,17 @@ void Reference::IndexedPropertySetCallback(uint32_t index, Local<Value> value, c
115121 Local<Context> context = isolate->GetCurrentContext ();
116122 Local<Object> thiz = info.This ();
117123
118- DataPair pair = Reference::GetTypeEncodingDataPair (thiz);
124+ DataPair pair = Reference::GetDataPair (thiz);
119125 const TypeEncoding* typeEncoding = pair.typeEncoding_ ;
120126 size_t size = pair.size_ ;
121127 void * data = pair.data_ ;
122-
123128 void * ptr = (uint8_t *)data + index * size;
124- Interop::WriteValue (context, typeEncoding, ptr, value);
129+
130+ if (typeEncoding != nullptr ) {
131+ Interop::WriteValue (context, typeEncoding, ptr, value);
132+ } else {
133+ Interop::WriteTypeValue (context, pair.typeWrapper_ , ptr, value);
134+ }
125135}
126136
127137void Reference::GetValueCallback (Local<v8::Name> name, const PropertyCallbackInfo<Value>& info) {
@@ -186,11 +196,17 @@ Local<Value> Reference::GetReferredValue(Local<Context> context, Local<Value> va
186196 }
187197
188198 BaseDataWrapper* typeWrapper = wrapper->TypeWrapper ();
189- if (typeWrapper != nullptr && typeWrapper->Type () == WrapperType::Primitive && baseWrapper != nullptr && baseWrapper->Type () == WrapperType::Pointer) {
190- Reference::DataPair pair = GetTypeEncodingDataPair (value.As <Object>());
191- if (pair.data_ != nullptr && pair. typeEncoding_ != nullptr ) {
199+ if (typeWrapper != nullptr && Reference::IsSupportedType ( typeWrapper->Type ()) && baseWrapper != nullptr && baseWrapper->Type () == WrapperType::Pointer) {
200+ Reference::DataPair pair = Reference::GetDataPair (value.As <Object>());
201+ if (pair.data_ != nullptr ) {
192202 BaseCall call ((uint8_t *)pair.data_ );
193- Local<Value> result = Interop::GetResult (context, pair.typeEncoding_ , &call, false );
203+ Local<Value> result;
204+
205+ if (pair.typeEncoding_ != nullptr ) {
206+ result = Interop::GetResult (context, pair.typeEncoding_ , &call, false );
207+ } else {
208+ result = Interop::GetResultByType (context, typeWrapper, &call);
209+ }
194210 return result;
195211 }
196212 }
@@ -203,7 +219,6 @@ void* Reference::GetWrappedPointer(Local<Context> context, Local<Value> referenc
203219 return nullptr ;
204220 }
205221
206-
207222 Isolate* isolate = context->GetIsolate ();
208223 BaseDataWrapper* wrapper = tns::GetValue (isolate, reference);
209224 tns::Assert (wrapper != nullptr && wrapper->Type () == WrapperType::Reference, isolate);
@@ -313,47 +328,76 @@ void Reference::RegisterToStringMethod(Local<Context> context, Local<Object> pro
313328 tns::Assert (success, isolate);
314329}
315330
316- Reference::DataPair Reference::GetTypeEncodingDataPair (Local<Object> obj) {
331+ Reference::DataPair Reference::GetDataPair (Local<Object> obj) {
317332 Local<Context> context;
318333 bool success = obj->GetCreationContext ().ToLocal (&context);
319334 tns::Assert (success);
320335 Isolate* isolate = context->GetIsolate ();
321336 BaseDataWrapper* wrapper = tns::GetValue (isolate, obj);
322337 tns::Assert (wrapper != nullptr && wrapper->Type () == WrapperType::Reference, isolate);
323338 ReferenceWrapper* refWrapper = static_cast <ReferenceWrapper*>(wrapper);
324-
325339 BaseDataWrapper* typeWrapper = refWrapper->TypeWrapper ();
326- if (typeWrapper == nullptr ) {
327- // TODO: Missing type when creating the Reference instance
328- tns::Assert (false , isolate);
329- }
330-
331- if (typeWrapper->Type () != WrapperType::Primitive) {
332- // TODO: Currently only PrimitiveDataWrappers are supported as type parameters
333- // Objective C class classes and structures should also be handled
334- tns::Assert (false , isolate);
335- }
336-
337- PrimitiveDataWrapper* primitiveWrapper = static_cast <PrimitiveDataWrapper*>(typeWrapper);
340+
341+ size_t size = 0 ;
342+
343+ if (typeWrapper != nullptr ) {
344+ const TypeEncoding* typeEncoding = nullptr ;
345+
346+ if (Reference::IsSupportedType (typeWrapper->Type ())) {
347+ switch (typeWrapper->Type ()) {
348+ case WrapperType::Primitive: {
349+ PrimitiveDataWrapper* primitiveWrapper = static_cast <PrimitiveDataWrapper*>(typeWrapper);
350+
351+ size = primitiveWrapper->Size ();
352+ typeEncoding = primitiveWrapper->TypeEncoding ();
353+ break ;
354+ }
355+ case WrapperType::StructType: {
356+ StructTypeWrapper* structTypeWrapper = static_cast <StructTypeWrapper*>(refWrapper->TypeWrapper ());
357+ StructInfo structInfo = structTypeWrapper->StructInfo ();
358+
359+ size = structInfo.FFIType ()->size ;
360+ break ;
361+ }
362+ default : {
363+ break ;
364+ }
365+ }
366+ } else {
367+ // TODO: Currently only PrimitiveDataWrappers and Structs are supported as type parameters
368+ // Objective C class classes should also be handled
369+ tns::Assert (false , isolate);
370+ }
338371
339- Local<Value> value = refWrapper->Value ()->Get (isolate);
340- BaseDataWrapper* wrappedValue = tns::GetValue (isolate, value);
341- if (wrappedValue != nullptr && wrappedValue->Type () == WrapperType::Pointer) {
342- const TypeEncoding* typeEncoding = primitiveWrapper->TypeEncoding ();
343- PointerWrapper* pw = static_cast <PointerWrapper*>(wrappedValue);
344- void * data = pw->Data ();
372+ Local<Value> value = refWrapper->Value ()->Get (isolate);
373+ BaseDataWrapper* wrappedValue = tns::GetValue (isolate, value);
374+ if (wrappedValue != nullptr && wrappedValue->Type () == WrapperType::Pointer) {
375+ PointerWrapper* pw = static_cast <PointerWrapper*>(wrappedValue);
376+ void * data = pw->Data ();
345377
346- DataPair pair (typeEncoding, data, primitiveWrapper->Size ());
347- return pair;
378+ DataPair pair (typeWrapper, typeEncoding, data, size);
379+ return pair;
380+ }
348381 }
349382
350383 if (refWrapper->Encoding () != nullptr && refWrapper->Data () != nullptr ) {
351- DataPair pair (refWrapper->Encoding (), refWrapper->Data (), primitiveWrapper->Size ());
384+ const TypeEncoding* typeEncoding = refWrapper->Encoding ();
385+
386+ if (typeWrapper == nullptr ) {
387+ ffi_type* ffiType = FFICall::GetArgumentType (typeEncoding);
388+ size = ffiType->size ;
389+ FFICall::DisposeFFIType (ffiType, typeEncoding);
390+ }
391+
392+ DataPair pair (typeWrapper, typeEncoding, refWrapper->Data (), size);
352393 return pair;
353394 }
354395
355396 tns::Assert (false , isolate);
356- return DataPair (nullptr , nullptr , 0 );
397+ return DataPair (typeWrapper, nullptr , nullptr , size );
357398}
358399
400+ bool Reference::IsSupportedType (WrapperType type) {
401+ return type == WrapperType::Primitive || type == WrapperType::StructType;
402+ }
359403}
0 commit comments