export hookGoValueCallMethod
(enginep, foldp unsafe.Pointer, reflectIndex C.int, args *C.DataValue)
| 484 | |
| 485 | //export hookGoValueCallMethod |
| 486 | func hookGoValueCallMethod(enginep, foldp unsafe.Pointer, reflectIndex C.int, args *C.DataValue) { |
| 487 | fold := ensureEngine(enginep, foldp) |
| 488 | v := reflect.ValueOf(fold.gvalue) |
| 489 | |
| 490 | // TODO Must assert that v is necessarily a pointer here, but we shouldn't have to manipulate |
| 491 | // gvalue here for that. This should happen in a sensible place in the wrapping functions |
| 492 | // that can still error out to the user in due time. |
| 493 | |
| 494 | method := v.Method(int(reflectIndex)) |
| 495 | methodt := method.Type() |
| 496 | methodName := v.Type().Method(int(reflectIndex)).Name |
| 497 | |
| 498 | // TODO Ensure methods with more parameters than this are not registered. |
| 499 | var params [C.MaxParams]reflect.Value |
| 500 | var err error |
| 501 | |
| 502 | numIn := methodt.NumIn() |
| 503 | for i := 0; i < numIn; i++ { |
| 504 | paramdv := (*C.DataValue)(unsafe.Pointer(uintptr(unsafe.Pointer(args)) + (uintptr(i)+1)*dataValueSize)) |
| 505 | param := reflect.ValueOf(unpackDataValue(paramdv, fold.engine)) |
| 506 | if argt := methodt.In(i); param.Type() != argt { |
| 507 | param, err = convertParam(methodName, i, param, argt) |
| 508 | if err != nil { |
| 509 | panic(err.Error()) |
| 510 | } |
| 511 | } |
| 512 | params[i] = param |
| 513 | } |
| 514 | |
| 515 | result := method.Call(params[:numIn]) |
| 516 | |
| 517 | if len(result) == 1 { |
| 518 | packDataValue(result[0].Interface(), args, fold.engine, jsOwner) |
| 519 | } else if len(result) > 1 { |
| 520 | if len(result) > len(dataValueArray) { |
| 521 | panic("function has too many results") |
| 522 | } |
| 523 | for i, v := range result { |
| 524 | packDataValue(v.Interface(), &dataValueArray[i], fold.engine, jsOwner) |
| 525 | } |
| 526 | args.dataType = C.DTVariantList |
| 527 | *(*unsafe.Pointer)(unsafe.Pointer(&args.data)) = C.newVariantList(&dataValueArray[0], C.int(len(result))) |
| 528 | } |
| 529 | } |
| 530 | |
| 531 | func convertParam(methodName string, index int, param reflect.Value, argt reflect.Type) (reflect.Value, error) { |
| 532 | out := reflect.New(argt).Elem() |
nothing calls this directly
no test coverage detected