@@ -23,12 +23,12 @@ import (
23
23
)
24
24
25
25
var (
26
- guiFunc = make (chan func ())
27
- guiDone = make (chan struct {})
28
- guiLock = 0
29
- guiMainRef uintptr
30
- guiPaintRef uintptr
31
- guiIdleRun int32
26
+ guiFunc = make (chan func ())
27
+ guiDone = make (chan struct {})
28
+ guiLock = 0
29
+ guiMainRef uintptr
30
+ guiPaintRef uintptr
31
+ guiIdleRun int32
32
32
33
33
initialized int32
34
34
)
@@ -187,6 +187,7 @@ func hookIdleTimer() {
187
187
return
188
188
}
189
189
}
190
+ // fmt.Fprintf(os.Stderr, "hookIdleTimer: %v\n", runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name())
190
191
f ()
191
192
guiDone <- struct {}{}
192
193
atomic .AddInt32 (& guiIdleRun , - 1 )
@@ -230,10 +231,17 @@ func wrapGoValue(engine *Engine, gvalue interface{}, owner valueOwner) (cvalue u
230
231
231
232
painting := cdata .Ref () == atomic .LoadUintptr (& guiPaintRef )
232
233
234
+ hashableGvalue := gvalue
235
+ if gvaluev .Kind () == reflect .Slice {
236
+ hashableGvalue = * (* reflect .SliceHeader )(unsafe .Pointer (gvaluev .Pointer ()))
237
+ } else if ! hashable (gvalue ) {
238
+ panic (fmt .Sprintf ("gvalue not hashable: %v %v" , gvaluev .Type (), gvaluev .Kind ()))
239
+ }
240
+
233
241
// Cannot reuse a jsOwner because the QML runtime may choose to destroy
234
242
// the value _after_ we hand it a new reference to the same value.
235
243
// See issue #68 for details.
236
- prev , ok := engine .values [gvalue ]
244
+ prev , ok := engine .values [hashableGvalue ]
237
245
if ok && (prev .owner == cppOwner || painting ) {
238
246
return prev .cvalue
239
247
}
@@ -257,7 +265,7 @@ func wrapGoValue(engine *Engine, gvalue interface{}, owner valueOwner) (cvalue u
257
265
fold .next = prev
258
266
prev .prev = fold
259
267
}
260
- engine .values [gvalue ] = fold
268
+ engine .values [hashableGvalue ] = fold
261
269
262
270
//fmt.Printf("[DEBUG] value alive (wrapped): cvalue=%x gvalue=%x/%#v\n", fold.cvalue, addrOf(fold.gvalue), fold.gvalue)
263
271
stats .valuesAlive (+ 1 )
@@ -356,7 +364,6 @@ func deref(value reflect.Value) reflect.Value {
356
364
}
357
365
return value
358
366
}
359
- panic ("cannot happen" )
360
367
}
361
368
362
369
//export hookGoValueReadField
@@ -367,7 +374,18 @@ func hookGoValueReadField(enginep, foldp unsafe.Pointer, reflectIndex, getIndex,
367
374
if getIndex >= 0 {
368
375
field = reflect .ValueOf (fold .gvalue ).Method (int (getIndex )).Call (nil )[0 ]
369
376
} else {
370
- field = deref (reflect .ValueOf (fold .gvalue )).Field (int (reflectIndex ))
377
+ val := deref (reflect .ValueOf (fold .gvalue ))
378
+ // defer func() {
379
+ // if r := recover(); r != nil {
380
+ // fmt.Fprintf(os.Stderr, "panic in hookGoValueReadField %v %v\n", val, reflectIndex)
381
+ // }
382
+ // }()
383
+ if ! val .IsValid () {
384
+ // panic(fmt.Sprintf("invalid value in hookGoValueReadField %#v\n", fold))
385
+ resultdv .dataType = C .DTInvalid
386
+ return
387
+ }
388
+ field = val .Field (int (reflectIndex ))
371
389
}
372
390
field = deref (field )
373
391
@@ -503,7 +521,11 @@ func hookGoValueCallMethod(enginep, foldp unsafe.Pointer, reflectIndex C.int, ar
503
521
for i := 0 ; i < numIn ; i ++ {
504
522
paramdv := (* C .DataValue )(unsafe .Pointer (uintptr (unsafe .Pointer (args )) + (uintptr (i )+ 1 )* dataValueSize ))
505
523
param := reflect .ValueOf (unpackDataValue (paramdv , fold .engine ))
506
- if argt := methodt .In (i ); param .Type () != argt {
524
+ argt := methodt .In (i )
525
+ if ! param .IsValid () {
526
+ fmt .Printf ("Warning: %s called with zero parameter\n " , methodName )
527
+ param = reflect .Zero (argt )
528
+ } else if param .Type () != argt {
507
529
param , err = convertParam (methodName , i , param , argt )
508
530
if err != nil {
509
531
panic (err .Error ())
@@ -562,7 +584,7 @@ func hookGoValuePaint(enginep, foldp unsafe.Pointer, reflectIndex C.intptr_t) {
562
584
return
563
585
}
564
586
565
- painter := & Painter {engine : fold .engine , obj : & Common { fold .cvalue , fold .engine } }
587
+ painter := & Painter {engine : fold .engine , obj : CommonOf ( fold .cvalue , fold .engine ) }
566
588
v := reflect .ValueOf (fold .gvalue )
567
589
method := v .Method (int (reflectIndex ))
568
590
method .Call ([]reflect.Value {reflect .ValueOf (painter )})
@@ -617,7 +639,7 @@ func _initGoType(fold *valueFold, schedulePaint bool) {
617
639
return
618
640
}
619
641
// TODO Would be good to preserve identity on the Go side. See unpackDataValue as well.
620
- obj := & Common { engine : fold .engine , addr : fold .cvalue }
642
+ obj := CommonOf ( fold .cvalue , fold .engine )
621
643
fold .init .Call ([]reflect.Value {reflect .ValueOf (fold .gvalue ), reflect .ValueOf (obj )})
622
644
fold .init = reflect.Value {}
623
645
if schedulePaint {
0 commit comments