@@ -38,6 +38,11 @@ func init() {
38
38
guiMainRef = cdata .Ref ()
39
39
}
40
40
41
+ // foldRefs holds all fold values that are created. Since Go Pointer
42
+ // are not allowed to be held by cgo. We need a lookup table to
43
+ // interface the two space.
44
+ var foldRefs = make (map [uintptr ]* valueFold )
45
+
41
46
// Run runs the main QML event loop, runs f, and then terminates the
42
47
// event loop once f returns.
43
48
//
@@ -210,6 +215,16 @@ const (
210
215
jsOwner
211
216
)
212
217
218
+ func storeFold (fold * valueFold ) C.GoRef {
219
+ foldRef := uintptr (unsafe .Pointer (fold ))
220
+ foldRefs [foldRef ] = fold
221
+ return C .GoRef (foldRef )
222
+ }
223
+
224
+ func restoreFold (ref uintptr ) * valueFold {
225
+ return foldRefs [ref ]
226
+ }
227
+
213
228
// wrapGoValue creates a new GoValue object in C++ land wrapping
214
229
// the Go value contained in the given interface.
215
230
//
@@ -251,7 +266,7 @@ func wrapGoValue(engine *Engine, gvalue interface{}, owner valueOwner) (cvalue u
251
266
gvalue : gvalue ,
252
267
owner : owner ,
253
268
}
254
- fold .cvalue = C .newGoValue (unsafe . Pointer (fold ), typeInfo (gvalue ), parent )
269
+ fold .cvalue = C .newGoValue (storeFold (fold ), typeInfo (gvalue ), parent )
255
270
if prev != nil {
256
271
// Put new fold first so the single cppOwner, if any, is always the first entry.
257
272
fold .next = prev
@@ -289,7 +304,7 @@ func addrOf(gvalue interface{}) uintptr {
289
304
var typeNew = make (map [* valueFold ]bool )
290
305
291
306
//export hookGoValueTypeNew
292
- func hookGoValueTypeNew (cvalue unsafe.Pointer , specp unsafe.Pointer ) (foldp unsafe. Pointer ) {
307
+ func hookGoValueTypeNew (cvalue unsafe.Pointer , specp unsafe.Pointer ) (foldr C. GoRef ) {
293
308
// Initialization is postponed until the engine is available, so that
294
309
// we can hand Init the qml.Object that represents the object.
295
310
init := reflect .ValueOf ((* TypeSpec )(specp ).Init )
@@ -299,15 +314,17 @@ func hookGoValueTypeNew(cvalue unsafe.Pointer, specp unsafe.Pointer) (foldp unsa
299
314
cvalue : cvalue ,
300
315
owner : jsOwner ,
301
316
}
317
+
302
318
typeNew [fold ] = true
303
319
//fmt.Printf("[DEBUG] value alive (type-created): cvalue=%x gvalue=%x/%#v\n", fold.cvalue, addrOf(fold.gvalue), fold.gvalue)
304
320
stats .valuesAlive (+ 1 )
305
- return unsafe . Pointer (fold )
321
+ return storeFold (fold )
306
322
}
307
323
308
324
//export hookGoValueDestroyed
309
- func hookGoValueDestroyed (enginep unsafe.Pointer , foldp unsafe.Pointer ) {
310
- fold := (* valueFold )(foldp )
325
+ func hookGoValueDestroyed (enginep unsafe.Pointer , foldr uintptr ) {
326
+ fold := restoreFold (foldr )
327
+
311
328
engine := fold .engine
312
329
if engine == nil {
313
330
before := len (typeNew )
@@ -360,8 +377,8 @@ func deref(value reflect.Value) reflect.Value {
360
377
}
361
378
362
379
//export hookGoValueReadField
363
- func hookGoValueReadField (enginep , foldp unsafe.Pointer , reflectIndex , getIndex , setIndex C.int , resultdv * C.DataValue ) {
364
- fold := ensureEngine (enginep , foldp )
380
+ func hookGoValueReadField (enginep unsafe.Pointer , foldr uintptr , reflectIndex , getIndex , setIndex C.int , resultdv * C.DataValue ) {
381
+ fold := ensureEngine (enginep , foldr )
365
382
366
383
var field reflect.Value
367
384
if getIndex >= 0 {
@@ -376,7 +393,7 @@ func hookGoValueReadField(enginep, foldp unsafe.Pointer, reflectIndex, getIndex,
376
393
// TODO Handle getters that return []qml.Object.
377
394
// TODO Handle other GoValue slices (!= []qml.Object).
378
395
resultdv .dataType = C .DTListProperty
379
- * (* unsafe .Pointer )(unsafe .Pointer (& resultdv .data )) = C .newListProperty (foldp , C .intptr_t (reflectIndex ), C .intptr_t (setIndex ))
396
+ * (* unsafe .Pointer )(unsafe .Pointer (& resultdv .data )) = C .newListProperty (C . GoRef ( foldr ) , C .intptr_t (reflectIndex ), C .intptr_t (setIndex ))
380
397
return
381
398
}
382
399
@@ -406,8 +423,8 @@ func hookGoValueReadField(enginep, foldp unsafe.Pointer, reflectIndex, getIndex,
406
423
}
407
424
408
425
//export hookGoValueWriteField
409
- func hookGoValueWriteField (enginep , foldp unsafe.Pointer , reflectIndex , setIndex C.int , assigndv * C.DataValue ) {
410
- fold := ensureEngine (enginep , foldp )
426
+ func hookGoValueWriteField (enginep unsafe.Pointer , foldr uintptr , reflectIndex , setIndex C.int , assigndv * C.DataValue ) {
427
+ fold := ensureEngine (enginep , foldr )
411
428
v := reflect .ValueOf (fold .gvalue )
412
429
ve := v
413
430
for ve .Type ().Kind () == reflect .Ptr {
@@ -483,8 +500,8 @@ var (
483
500
)
484
501
485
502
//export hookGoValueCallMethod
486
- func hookGoValueCallMethod (enginep , foldp unsafe.Pointer , reflectIndex C.int , args * C.DataValue ) {
487
- fold := ensureEngine (enginep , foldp )
503
+ func hookGoValueCallMethod (enginep unsafe.Pointer , foldr uintptr , reflectIndex C.int , args * C.DataValue ) {
504
+ fold := ensureEngine (enginep , foldr )
488
505
v := reflect .ValueOf (fold .gvalue )
489
506
490
507
// TODO Must assert that v is necessarily a pointer here, but we shouldn't have to manipulate
@@ -548,7 +565,7 @@ func printPaintPanic() {
548
565
}
549
566
550
567
//export hookGoValuePaint
551
- func hookGoValuePaint (enginep , foldp unsafe.Pointer , reflectIndex C.intptr_t ) {
568
+ func hookGoValuePaint (enginep unsafe.Pointer , foldr uintptr , reflectIndex C.intptr_t ) {
552
569
// Besides a convenience this is a workaround for http://golang.org/issue/8588
553
570
defer printPaintPanic ()
554
571
defer atomic .StoreUintptr (& guiPaintRef , 0 )
@@ -557,7 +574,7 @@ func hookGoValuePaint(enginep, foldp unsafe.Pointer, reflectIndex C.intptr_t) {
557
574
// so no two paintings should be happening at the same time.
558
575
atomic .StoreUintptr (& guiPaintRef , cdata .Ref ())
559
576
560
- fold := ensureEngine (enginep , foldp )
577
+ fold := ensureEngine (enginep , foldr )
561
578
if fold .init .IsValid () {
562
579
return
563
580
}
@@ -568,8 +585,8 @@ func hookGoValuePaint(enginep, foldp unsafe.Pointer, reflectIndex C.intptr_t) {
568
585
method .Call ([]reflect.Value {reflect .ValueOf (painter )})
569
586
}
570
587
571
- func ensureEngine (enginep , foldp unsafe.Pointer ) * valueFold {
572
- fold := ( * valueFold )( foldp )
588
+ func ensureEngine (enginep unsafe.Pointer , foldr uintptr ) * valueFold {
589
+ fold := restoreFold ( foldr )
573
590
if fold .engine != nil {
574
591
if fold .init .IsValid () {
575
592
initGoType (fold )
@@ -637,22 +654,22 @@ func listSlice(fold *valueFold, reflectIndex C.intptr_t) *[]Object {
637
654
}
638
655
639
656
//export hookListPropertyAt
640
- func hookListPropertyAt (foldp unsafe. Pointer , reflectIndex , setIndex C.intptr_t , index C.int ) (objp unsafe.Pointer ) {
641
- fold := ( * valueFold )( foldp )
657
+ func hookListPropertyAt (foldr uintptr , reflectIndex , setIndex C.intptr_t , index C.int ) (objp unsafe.Pointer ) {
658
+ fold := restoreFold ( foldr )
642
659
slice := listSlice (fold , reflectIndex )
643
660
return (* slice )[int (index )].Common ().addr
644
661
}
645
662
646
663
//export hookListPropertyCount
647
- func hookListPropertyCount (foldp unsafe. Pointer , reflectIndex , setIndex C.intptr_t ) C.int {
648
- fold := ( * valueFold )( foldp )
664
+ func hookListPropertyCount (foldr uintptr , reflectIndex , setIndex C.intptr_t ) C.int {
665
+ fold := restoreFold ( foldr )
649
666
slice := listSlice (fold , reflectIndex )
650
667
return C .int (len (* slice ))
651
668
}
652
669
653
670
//export hookListPropertyAppend
654
- func hookListPropertyAppend (foldp unsafe. Pointer , reflectIndex , setIndex C.intptr_t , objp unsafe.Pointer ) {
655
- fold := ( * valueFold )( foldp )
671
+ func hookListPropertyAppend (foldr uintptr , reflectIndex , setIndex C.intptr_t , objp unsafe.Pointer ) {
672
+ fold := restoreFold ( foldr )
656
673
slice := listSlice (fold , reflectIndex )
657
674
var objdv C.DataValue
658
675
objdv .dataType = C .DTObject
@@ -666,8 +683,8 @@ func hookListPropertyAppend(foldp unsafe.Pointer, reflectIndex, setIndex C.intpt
666
683
}
667
684
668
685
//export hookListPropertyClear
669
- func hookListPropertyClear (foldp unsafe. Pointer , reflectIndex , setIndex C.intptr_t ) {
670
- fold := ( * valueFold )( foldp )
686
+ func hookListPropertyClear (foldr uintptr , reflectIndex , setIndex C.intptr_t ) {
687
+ fold := restoreFold ( foldr )
671
688
slice := listSlice (fold , reflectIndex )
672
689
newslice := (* slice )[0 :0 ]
673
690
if setIndex >= 0 {
0 commit comments