export hookGoValueReadField
(enginep, foldp unsafe.Pointer, reflectIndex, getIndex, setIndex C.int, resultdv *C.DataValue)
| 361 | |
| 362 | //export hookGoValueReadField |
| 363 | func hookGoValueReadField(enginep, foldp unsafe.Pointer, reflectIndex, getIndex, setIndex C.int, resultdv *C.DataValue) { |
| 364 | fold := ensureEngine(enginep, foldp) |
| 365 | |
| 366 | var field reflect.Value |
| 367 | if getIndex >= 0 { |
| 368 | field = reflect.ValueOf(fold.gvalue).Method(int(getIndex)).Call(nil)[0] |
| 369 | } else { |
| 370 | field = deref(reflect.ValueOf(fold.gvalue)).Field(int(reflectIndex)) |
| 371 | } |
| 372 | field = deref(field) |
| 373 | |
| 374 | // Cannot compare Type directly as field may be invalid (nil). |
| 375 | if field.Kind() == reflect.Slice && field.Type() == typeObjSlice { |
| 376 | // TODO Handle getters that return []qml.Object. |
| 377 | // TODO Handle other GoValue slices (!= []qml.Object). |
| 378 | resultdv.dataType = C.DTListProperty |
| 379 | *(*unsafe.Pointer)(unsafe.Pointer(&resultdv.data)) = C.newListProperty(foldp, C.intptr_t(reflectIndex), C.intptr_t(setIndex)) |
| 380 | return |
| 381 | } |
| 382 | |
| 383 | fieldk := field.Kind() |
| 384 | if fieldk == reflect.Slice || fieldk == reflect.Struct && field.Type() != typeRGBA { |
| 385 | if field.CanAddr() { |
| 386 | field = field.Addr() |
| 387 | } else if !hashable(field.Interface()) { |
| 388 | t := reflect.ValueOf(fold.gvalue).Type() |
| 389 | for t.Kind() == reflect.Ptr { |
| 390 | t = t.Elem() |
| 391 | } |
| 392 | panic(fmt.Sprintf("cannot access unaddressable and unhashable struct value on interface field %s.%s; value: %#v", t.Name(), t.Field(int(reflectIndex)).Name, field.Interface())) |
| 393 | } |
| 394 | } |
| 395 | var gvalue interface{} |
| 396 | if field.IsValid() { |
| 397 | gvalue = field.Interface() |
| 398 | } |
| 399 | |
| 400 | // TODO Strings are being passed in an unsafe manner here. There is a |
| 401 | // small chance that the field is changed and the garbage collector is run |
| 402 | // before C++ has a chance to look at the data. We can solve this problem |
| 403 | // by queuing up values in a stack, and cleaning the stack when the |
| 404 | // idle timer fires next. |
| 405 | packDataValue(gvalue, resultdv, fold.engine, jsOwner) |
| 406 | } |
| 407 | |
| 408 | //export hookGoValueWriteField |
| 409 | func hookGoValueWriteField(enginep, foldp unsafe.Pointer, reflectIndex, setIndex C.int, assigndv *C.DataValue) { |
nothing calls this directly
no test coverage detected