github.com/goccy/go-jit@v0.0.0-20200514131505-ff78d45cf6af/internal/ccall/func.go (about) 1 package ccall 2 3 /* 4 #cgo CFLAGS: -I../ 5 #cgo CFLAGS: -Iinclude 6 7 #include <jit/jit.h> 8 */ 9 import "C" 10 import ( 11 "errors" 12 "io" 13 "io/ioutil" 14 "os" 15 "reflect" 16 "unsafe" 17 ) 18 19 type Function struct { 20 c C.jit_function_t 21 name string 22 crosscall2 *Function 23 cgo_wait_runtime_init_done *Function 24 } 25 26 func toFunction(c C.jit_function_t) *Function { 27 return &Function{c: c} 28 } 29 30 func (f *Function) Label(label *Label) bool { 31 return int(C.jit_insn_label(f.c, &label.c)) == 1 32 } 33 34 func (f *Function) LabelRight(label *Label) bool { 35 return int(C.jit_insn_label_tight(f.c, &label.c)) == 1 36 } 37 38 func (f *Function) NewBlock(label *Label) bool { 39 return int(C.jit_insn_new_block(f.c)) == 1 40 } 41 42 func (f *Function) Load(value *Value) *Value { 43 return toValue(C.jit_insn_load(f.c, value.c)) 44 } 45 46 func (f *Function) Dup(value *Value) *Value { 47 return toValue(C.jit_insn_dup(f.c, value.c)) 48 } 49 50 func (f *Function) Store(dest, value *Value) bool { 51 return int(C.jit_insn_store(f.c, dest.c, value.c)) == 1 52 } 53 54 func (f *Function) LoadRelative(value *Value, offset int, typ *Type) *Value { 55 return toValue(C.jit_insn_load_relative(f.c, value.c, C.jit_nint(offset), typ.c)) 56 } 57 58 func (f *Function) StoreRelative(dest *Value, offset int, value *Value) bool { 59 return int(C.jit_insn_store_relative(f.c, dest.c, C.jit_nint(offset), value.c)) == 1 60 } 61 62 func (f *Function) AddRelative(value *Value, offset int) *Value { 63 return toValue(C.jit_insn_add_relative(f.c, value.c, C.jit_nint(offset))) 64 } 65 66 func (f *Function) LoadElem(baseAddr *Value, index *Value, elemType *Type) *Value { 67 return toValue(C.jit_insn_load_elem(f.c, baseAddr.c, index.c, elemType.c)) 68 } 69 70 func (f *Function) LoadElemAddress(baseAddr *Value, index *Value, elemType *Type) *Value { 71 return toValue(C.jit_insn_load_elem_address(f.c, baseAddr.c, index.c, elemType.c)) 72 } 73 74 func (f *Function) StoreElem(baseAddr, index, value *Value) bool { 75 return int(C.jit_insn_store_elem(f.c, baseAddr.c, index.c, value.c)) == 1 76 } 77 78 func (f *Function) CheckNull(value *Value) bool { 79 return int(C.jit_insn_check_null(f.c, value.c)) == 1 80 } 81 82 func (f *Function) Nop() bool { 83 return int(C.jit_insn_nop(f.c)) == 1 84 } 85 86 func (f *Function) Add(value1, value2 *Value) *Value { 87 return toValue(C.jit_insn_add(f.c, value1.c, value2.c)) 88 } 89 90 func (f *Function) AddOvf(value1, value2 *Value) *Value { 91 return toValue(C.jit_insn_add_ovf(f.c, value1.c, value2.c)) 92 } 93 94 func (f *Function) Sub(value1, value2 *Value) *Value { 95 return toValue(C.jit_insn_sub(f.c, value1.c, value2.c)) 96 } 97 98 func (f *Function) SubOvf(value1, value2 *Value) *Value { 99 return toValue(C.jit_insn_sub_ovf(f.c, value1.c, value2.c)) 100 } 101 102 func (f *Function) Mul(value1, value2 *Value) *Value { 103 return toValue(C.jit_insn_mul(f.c, value1.c, value2.c)) 104 } 105 106 func (f *Function) MulOvf(value1, value2 *Value) *Value { 107 return toValue(C.jit_insn_mul_ovf(f.c, value1.c, value2.c)) 108 } 109 110 func (f *Function) Div(value1, value2 *Value) *Value { 111 return toValue(C.jit_insn_div(f.c, value1.c, value2.c)) 112 } 113 114 func (f *Function) Rem(value1, value2 *Value) *Value { 115 return toValue(C.jit_insn_rem(f.c, value1.c, value2.c)) 116 } 117 118 func (f *Function) RemIEEE(value1, value2 *Value) *Value { 119 return toValue(C.jit_insn_rem_ieee(f.c, value1.c, value2.c)) 120 } 121 122 func (f *Function) Neg(value1 *Value) *Value { 123 return toValue(C.jit_insn_neg(f.c, value1.c)) 124 } 125 126 func (f *Function) And(value1, value2 *Value) *Value { 127 return toValue(C.jit_insn_and(f.c, value1.c, value2.c)) 128 } 129 130 func (f *Function) Or(value1, value2 *Value) *Value { 131 return toValue(C.jit_insn_or(f.c, value1.c, value2.c)) 132 } 133 134 func (f *Function) Xor(value1, value2 *Value) *Value { 135 return toValue(C.jit_insn_xor(f.c, value1.c, value2.c)) 136 } 137 138 func (f *Function) Not(value1 *Value) *Value { 139 return toValue(C.jit_insn_not(f.c, value1.c)) 140 } 141 142 func (f *Function) Shl(value1, value2 *Value) *Value { 143 return toValue(C.jit_insn_shl(f.c, value1.c, value2.c)) 144 } 145 146 func (f *Function) Shr(value1, value2 *Value) *Value { 147 return toValue(C.jit_insn_shr(f.c, value1.c, value2.c)) 148 } 149 150 func (f *Function) Ushr(value1, value2 *Value) *Value { 151 return toValue(C.jit_insn_ushr(f.c, value1.c, value2.c)) 152 } 153 154 func (f *Function) Sshr(value1, value2 *Value) *Value { 155 return toValue(C.jit_insn_sshr(f.c, value1.c, value2.c)) 156 } 157 158 func (f *Function) Eq(value1, value2 *Value) *Value { 159 return toValue(C.jit_insn_eq(f.c, value1.c, value2.c)) 160 } 161 162 func (f *Function) Ne(value1, value2 *Value) *Value { 163 return toValue(C.jit_insn_ne(f.c, value1.c, value2.c)) 164 } 165 166 func (f *Function) Lt(value1, value2 *Value) *Value { 167 return toValue(C.jit_insn_lt(f.c, value1.c, value2.c)) 168 } 169 170 func (f *Function) Le(value1, value2 *Value) *Value { 171 return toValue(C.jit_insn_le(f.c, value1.c, value2.c)) 172 } 173 174 func (f *Function) Gt(value1, value2 *Value) *Value { 175 return toValue(C.jit_insn_gt(f.c, value1.c, value2.c)) 176 } 177 178 func (f *Function) Ge(value1, value2 *Value) *Value { 179 return toValue(C.jit_insn_ge(f.c, value1.c, value2.c)) 180 } 181 182 func (f *Function) Cmpl(value1, value2 *Value) *Value { 183 return toValue(C.jit_insn_cmpl(f.c, value1.c, value2.c)) 184 } 185 186 func (f *Function) Cmpg(value1, value2 *Value) *Value { 187 return toValue(C.jit_insn_cmpg(f.c, value1.c, value2.c)) 188 } 189 190 func (f *Function) ToBool(value1 *Value) *Value { 191 return toValue(C.jit_insn_to_bool(f.c, value1.c)) 192 } 193 194 func (f *Function) ToNotBool(value1 *Value) *Value { 195 return toValue(C.jit_insn_to_not_bool(f.c, value1.c)) 196 } 197 198 func (f *Function) Acos(value1 *Value) *Value { 199 return toValue(C.jit_insn_acos(f.c, value1.c)) 200 } 201 202 func (f *Function) Asin(value1 *Value) *Value { 203 return toValue(C.jit_insn_asin(f.c, value1.c)) 204 } 205 206 func (f *Function) Atan(value1 *Value) *Value { 207 return toValue(C.jit_insn_atan(f.c, value1.c)) 208 } 209 210 func (f *Function) Atan2(value1, value2 *Value) *Value { 211 return toValue(C.jit_insn_atan2(f.c, value1.c, value2.c)) 212 } 213 214 func (f *Function) Ceil(value1 *Value) *Value { 215 return toValue(C.jit_insn_ceil(f.c, value1.c)) 216 } 217 218 func (f *Function) Cos(value1 *Value) *Value { 219 return toValue(C.jit_insn_cos(f.c, value1.c)) 220 } 221 222 func (f *Function) Cosh(value1 *Value) *Value { 223 return toValue(C.jit_insn_cosh(f.c, value1.c)) 224 } 225 226 func (f *Function) Exp(value1 *Value) *Value { 227 return toValue(C.jit_insn_exp(f.c, value1.c)) 228 } 229 230 func (f *Function) Floor(value1 *Value) *Value { 231 return toValue(C.jit_insn_floor(f.c, value1.c)) 232 } 233 234 func (f *Function) Log(value1 *Value) *Value { 235 return toValue(C.jit_insn_log(f.c, value1.c)) 236 } 237 238 func (f *Function) Log10(value1 *Value) *Value { 239 return toValue(C.jit_insn_log10(f.c, value1.c)) 240 } 241 242 func (f *Function) Pow(value1, value2 *Value) *Value { 243 return toValue(C.jit_insn_pow(f.c, value1.c, value2.c)) 244 } 245 246 func (f *Function) Rint(value1 *Value) *Value { 247 return toValue(C.jit_insn_rint(f.c, value1.c)) 248 } 249 250 func (f *Function) Round(value1 *Value) *Value { 251 return toValue(C.jit_insn_round(f.c, value1.c)) 252 } 253 254 func (f *Function) Sin(value1 *Value) *Value { 255 return toValue(C.jit_insn_sin(f.c, value1.c)) 256 } 257 258 func (f *Function) Sinh(value1 *Value) *Value { 259 return toValue(C.jit_insn_sinh(f.c, value1.c)) 260 } 261 262 func (f *Function) Sqrt(value1 *Value) *Value { 263 return toValue(C.jit_insn_sqrt(f.c, value1.c)) 264 } 265 266 func (f *Function) Tan(value1 *Value) *Value { 267 return toValue(C.jit_insn_tan(f.c, value1.c)) 268 } 269 270 func (f *Function) Tanh(value1 *Value) *Value { 271 return toValue(C.jit_insn_tanh(f.c, value1.c)) 272 } 273 274 func (f *Function) Trunc(value1 *Value) *Value { 275 return toValue(C.jit_insn_trunc(f.c, value1.c)) 276 } 277 278 func (f *Function) IsNan(value1 *Value) *Value { 279 return toValue(C.jit_insn_is_nan(f.c, value1.c)) 280 } 281 282 func (f *Function) IsFinite(value1 *Value) *Value { 283 return toValue(C.jit_insn_is_finite(f.c, value1.c)) 284 } 285 286 func (f *Function) IsInf(value1 *Value) *Value { 287 return toValue(C.jit_insn_is_inf(f.c, value1.c)) 288 } 289 290 func (f *Function) Abs(value1 *Value) *Value { 291 return toValue(C.jit_insn_abs(f.c, value1.c)) 292 } 293 294 func (f *Function) Min(value1, value2 *Value) *Value { 295 return toValue(C.jit_insn_min(f.c, value1.c, value2.c)) 296 } 297 298 func (f *Function) Max(value1, value2 *Value) *Value { 299 return toValue(C.jit_insn_max(f.c, value1.c, value2.c)) 300 } 301 302 func (f *Function) Sign(value1 *Value) *Value { 303 return toValue(C.jit_insn_sign(f.c, value1.c)) 304 } 305 306 func (f *Function) Branch(label *Label) bool { 307 return int(C.jit_insn_branch(f.c, &label.c)) == 1 308 } 309 310 func (f *Function) BranchIf(value *Value, label *Label) bool { 311 return int(C.jit_insn_branch_if(f.c, value.c, &label.c)) == 1 312 } 313 314 func (f *Function) BranchIfNot(value *Value, label *Label) bool { 315 return int(C.jit_insn_branch_if_not(f.c, value.c, &label.c)) == 1 316 } 317 318 func (f *Function) JumpTable(value *Value, labels Labels) bool { 319 return int(C.jit_insn_jump_table(f.c, value.c, labels.c(), C.uint(len(labels)))) == 1 320 } 321 322 func (f *Function) AddressOf(value1 *Value) *Value { 323 return toValue(C.jit_insn_address_of(f.c, value1.c)) 324 } 325 326 func (f *Function) AddressOfLabel(label *Label) *Value { 327 return toValue(C.jit_insn_address_of_label(f.c, &label.c)) 328 } 329 330 func (f *Function) Convert(value *Value, typ *Type, overflowCheck int) *Value { 331 return toValue(C.jit_insn_convert(f.c, value.c, typ.c, C.int(overflowCheck))) 332 } 333 334 func (f *Function) Call(name string, fn *Function, args Values) *Value { 335 return toValue(C.jit_insn_call(f.c, C.CString(name), fn.c, nil, args.c(), C.uint(len(args)), C.JIT_CALL_NOTHROW)) 336 } 337 338 func (f *Function) CallIndirect(fn *Function, value *Value, signature *Type, args Values) *Value { 339 return toValue(C.jit_insn_call_indirect(f.c, value.c, signature.c, args.c(), C.uint(len(args)), C.JIT_CALL_NOTHROW)) 340 } 341 342 func (f *Function) CallNestedIndirect(fn *Function, value *Value, parentFrame *Value, signature *Type, args Values) *Value { 343 return toValue(C.jit_insn_call_nested_indirect(f.c, value.c, parentFrame.c, signature.c, args.c(), C.uint(len(args)), C.JIT_CALL_NOTHROW)) 344 } 345 346 func (f *Function) CallIndirectVtable(fn *Function, value *Value, signature *Type, args Values) *Value { 347 return toValue(C.jit_insn_call_indirect_vtable(f.c, value.c, signature.c, args.c(), C.uint(len(args)), C.JIT_CALL_NOTHROW)) 348 } 349 350 func (f *Function) CallNative(fn *Function, name string, nativeFunc unsafe.Pointer, signature *Type, args Values) *Value { 351 return toValue(C.jit_insn_call_native(f.c, C.CString(name), nativeFunc, signature.c, args.c(), C.uint(len(args)), C.JIT_CALL_NOTHROW)) 352 } 353 354 //func (f *Function) CallIntrinsic(fn *Function, name string, intrinsicFunc unsafe.Pointer, desc *IntrinsicDescriptor, arg1, arg2 *Value) *Value { 355 // return toValue(C.jit_insn_call_intrinsic(f.c, C.CString(name), intrinsicFunc, desc.c, arg1.c, arg2.c)) 356 //} 357 358 func (f *Function) IncomingReg(value *Value, reg int) int { 359 return int(C.jit_insn_incoming_reg(f.c, value.c, C.int(reg))) 360 } 361 362 func (f *Function) Return(value *Value) int { 363 return int(C.jit_insn_return(f.c, value.c)) 364 } 365 366 func (f *Function) ReturnPtr(value *Value, typ *Type) int { 367 return int(C.jit_insn_return_ptr(f.c, value.c, typ.c)) 368 } 369 370 func (f *Function) DefaultReturn() int { 371 return int(C.jit_insn_default_return(f.c)) 372 } 373 374 func (f *Function) Memcpy(dest, src, size *Value) int { 375 return int(C.jit_insn_memcpy(f.c, dest.c, src.c, size.c)) 376 } 377 378 func (f *Function) Memmove(dest, src, size *Value) int { 379 return int(C.jit_insn_memmove(f.c, dest.c, src.c, size.c)) 380 } 381 382 func (f *Function) Memset(dest, src, size *Value) int { 383 return int(C.jit_insn_memset(f.c, dest.c, src.c, size.c)) 384 } 385 386 func (f *Function) Alloca(size *Value) *Value { 387 return toValue(C.jit_insn_alloca(f.c, size.c)) 388 } 389 390 func (f *Function) MoveBlocksToStart(fromLabel *Label, toLabel *Label) int { 391 return int(C.jit_insn_move_blocks_to_start(f.c, fromLabel.c, toLabel.c)) 392 } 393 394 func (f *Function) MoveBlocksToEnd(fromLabel *Label, toLabel *Label) int { 395 return int(C.jit_insn_move_blocks_to_end(f.c, fromLabel.c, toLabel.c)) 396 } 397 398 func (f *Function) MarkOffset(offset int) int { 399 return int(C.jit_insn_mark_offset(f.c, C.int(offset))) 400 } 401 402 func (f *Function) MarkBreakpoint(data1, data2 int) int { 403 return int(C.jit_insn_mark_breakpoint(f.c, C.jit_nint(data1), C.jit_nint(data2))) 404 } 405 406 func (f *Function) MarkBreakpointVariable(data1, data2 *Value) int { 407 return int(C.jit_insn_mark_breakpoint_variable(f.c, data1.c, data2.c)) 408 } 409 410 func (f *Function) Abandon() { 411 C.jit_function_abandon(f.c) 412 } 413 414 func (f *Function) Context() *Context { 415 return toContext(C.jit_function_get_context(f.c)) 416 } 417 418 func (f *Function) Signature() *Type { 419 return toType(C.jit_function_get_signature(f.c)) 420 } 421 422 func (f *Function) Meta(typ int) unsafe.Pointer { 423 return C.jit_function_get_meta(f.c, C.int(typ)) 424 } 425 426 func (f *Function) FreeMeta(typ int) { 427 C.jit_function_free_meta(f.c, C.int(typ)) 428 } 429 430 func (f *Function) Entry() *Block { 431 return toBlock(C.jit_function_get_entry(f.c)) 432 } 433 434 func (f *Function) Current() *Block { 435 return toBlock(C.jit_function_get_current(f.c)) 436 } 437 438 func (f *Function) NestedParent() *Function { 439 return toFunction(C.jit_function_get_nested_parent(f.c)) 440 } 441 442 func (f *Function) SetParentFrame(parentFrame *Value) { 443 C.jit_function_set_parent_frame(f.c, parentFrame.c) 444 } 445 446 func (f *Function) Compile() bool { 447 return int(C.jit_function_compile(f.c)) == 1 448 } 449 450 func (f *Function) IsCompiled() bool { 451 return int(C.jit_function_is_compiled(f.c)) == 1 452 } 453 454 func (f *Function) SetRecompilable() { 455 C.jit_function_set_recompilable(f.c) 456 } 457 458 func (f *Function) ClearRecompilable() { 459 C.jit_function_clear_recompilable(f.c) 460 } 461 462 func (f *Function) IsRecompilable() bool { 463 return int(C.jit_function_is_recompilable(f.c)) == 1 464 } 465 466 func (f *Function) SetupEntry(entryPoint unsafe.Pointer) { 467 C.jit_function_setup_entry(f.c, entryPoint) 468 } 469 470 func (f *Function) ToClosure() unsafe.Pointer { 471 return C.jit_function_to_closure(f.c) 472 } 473 474 func (f *Function) ToVtablePointer() unsafe.Pointer { 475 return C.jit_function_to_vtable_pointer(f.c) 476 } 477 478 type interfaceHeader struct { 479 typ unsafe.Pointer 480 ptr unsafe.Pointer 481 } 482 483 func (f *Function) Apply(args []interface{}) interface{} { 484 params := make([]unsafe.Pointer, len(args)) 485 for idx, arg := range args { 486 header := (*interfaceHeader)(unsafe.Pointer(&arg)) 487 params[idx] = header.ptr 488 } 489 cparams := (*unsafe.Pointer)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(¶ms)).Data)) 490 var result int 491 C.jit_function_apply(f.c, cparams, unsafe.Pointer(&result)) 492 return result 493 } 494 495 func (f *Function) SetOptimizationLevel(level uint) { 496 C.jit_function_set_optimization_level(f.c, C.uint(level)) 497 } 498 499 func (f *Function) OptimizationLevel() uint { 500 return uint(C.jit_function_get_optimization_level(f.c)) 501 } 502 503 func MaxOptimizationLevel() uint { 504 return uint(C.jit_function_get_max_optimization_level()) 505 } 506 507 func (f *Function) ReserveLabel() *Label { 508 return toLabel(C.jit_function_reserve_label(f.c)) 509 } 510 511 func (f *Function) LabelsEqual(label *Label, label2 *Label) bool { 512 return int(C.jit_function_labels_equal(f.c, label.c, label2.c)) == 1 513 } 514 515 func (f *Function) Optimize() bool { 516 return int(C.jit_optimize(f.c)) == 1 517 } 518 519 func (f *Function) CreateValue(typ *Type) *Value { 520 return toValue(C.jit_value_create(f.c, typ.c)) 521 } 522 523 func (f *Function) CreatePtrValue(ptr unsafe.Pointer) *Value { 524 return toValue(C.jit_value_create_nint_constant(f.c, C.jit_type_void_ptr, C.jit_nint(uintptr(ptr)))) 525 } 526 527 func (f *Function) CreateNintConstant(typ *Type, constValue int) *Value { 528 return toValue(C.jit_value_create_nint_constant(f.c, typ.c, C.jit_nint(constValue))) 529 } 530 531 func (f *Function) CreateLongConstant(typ *Type, constValue int64) *Value { 532 return toValue(C.jit_value_create_long_constant(f.c, typ.c, C.jit_long(constValue))) 533 } 534 535 func (f *Function) CreateFloat32Constant(typ *Type, constValue float32) *Value { 536 return toValue(C.jit_value_create_float32_constant(f.c, typ.c, C.jit_float32(constValue))) 537 } 538 539 func (f *Function) CreateFloat64Constant(typ *Type, constValue float64) *Value { 540 return toValue(C.jit_value_create_float64_constant(f.c, typ.c, C.jit_float64(constValue))) 541 } 542 543 func (f *Function) CreateIntValue(value int) *Value { 544 return f.CreateNintConstant(TypeGoInt, value) 545 } 546 547 func (f *Function) Param(param uint) *Value { 548 return toValue(C.jit_value_get_param(f.c, C.uint(param))) 549 } 550 551 func (f *Function) StructPointer() *Value { 552 return toValue(C.jit_value_get_struct_pointer(f.c)) 553 } 554 555 func (f *Function) ValueRef(value *Value) { 556 C.jit_value_ref(f.c, value.c) 557 } 558 559 func (f *Function) NextBlock(next *Block) *Block { 560 return toBlock(C.jit_block_next(f.c, next.c)) 561 } 562 563 func (f *Function) PreviousBlock(previous *Block) *Block { 564 return toBlock(C.jit_block_previous(f.c, previous.c)) 565 } 566 567 func (f *Function) BlockFromLabel(label *Label) *Block { 568 return toBlock(C.jit_block_from_label(f.c, label.c)) 569 } 570 571 func (f *Function) IsDeadCurrentBlock() bool { 572 return int(C.jit_block_current_is_dead(f.c)) == 1 573 } 574 575 func (f *Function) Dump(name string, w io.Writer) error { 576 tmpfile, err := ioutil.TempFile("", "") 577 if err != nil { 578 return err 579 } 580 defer os.Remove(tmpfile.Name()) 581 file := C.fdopen(C.int(tmpfile.Fd()), C.CString("w")) 582 C.jit_dump_function(file, f.c, C.CString(name)) 583 C.fclose(file) 584 contents, err := ioutil.ReadFile(tmpfile.Name()) 585 if err != nil { 586 return err 587 } 588 if _, err := w.Write(contents); err != nil { 589 return err 590 } 591 return nil 592 } 593 594 func (f *Function) DumpValue(value *Value, prefix string, w io.Writer) error { 595 tmpfile, err := ioutil.TempFile("", "") 596 if err != nil { 597 return err 598 } 599 defer os.Remove(tmpfile.Name()) 600 file := C.fdopen(C.int(tmpfile.Fd()), C.CString("w")) 601 C.jit_dump_value(file, f.c, value.c, C.CString(prefix)) 602 C.fclose(file) 603 contents, err := ioutil.ReadFile(tmpfile.Name()) 604 if err != nil { 605 return err 606 } 607 if _, err := w.Write(contents); err != nil { 608 return err 609 } 610 return nil 611 } 612 613 func (f *Function) DumpInstruction(insn *Instruction, w io.Writer) error { 614 tmpfile, err := ioutil.TempFile("", "") 615 if err != nil { 616 return err 617 } 618 defer os.Remove(tmpfile.Name()) 619 file := C.fdopen(C.int(tmpfile.Fd()), C.CString("w")) 620 C.jit_dump_insn(file, f.c, insn.c) 621 C.fclose(file) 622 contents, err := ioutil.ReadFile(tmpfile.Name()) 623 if err != nil { 624 return err 625 } 626 if _, err := w.Write(contents); err != nil { 627 return err 628 } 629 return nil 630 } 631 632 func (f *Function) GoCall(fn interface{}, args []*Value) ([]*Value, error) { 633 typ := reflect.TypeOf(fn) 634 if typ.Kind() != reflect.Func { 635 return nil, errors.New("invalid type") 636 } 637 fargs := []*Type{} 638 for i := 0; i < typ.NumIn(); i++ { 639 fargs = append(fargs, ReflectTypeToType(typ.In(i))) 640 } 641 rtypes := []*Type{} 642 for i := 0; i < typ.NumOut(); i++ { 643 rtypes = append(rtypes, ReflectTypeToType(typ.Out(i))) 644 } 645 rtype := TypeVoid 646 if len(rtypes) > 0 { 647 rtype = CreateStruct(rtypes, 0) 648 } 649 sig := CreateSignature(fargs, rtype) 650 defer sig.Free() 651 652 p := (*interfaceHeader)(unsafe.Pointer(&fn)).ptr 653 entryPoint := *(*unsafe.Pointer)(p) 654 ctxt := f.call_cgo_wait_runtime_init_done() 655 crossargs := append(args, ctxt) 656 rvalues := f.call_crosscall2(fargs, rtypes, entryPoint, crossargs) 657 return rvalues, nil 658 } 659 660 func (f *Function) call_cgo_wait_runtime_init_done() *Value { 661 fn := f.cgo_wait_runtime_init_done 662 return f.Call("_cgo_wait_runtime_init_done", fn, nil) 663 } 664 665 //go:linkname cgo_runtime_cgocallback runtime.cgocallback 666 func cgo_runtime_cgocallback(unsafe.Pointer, unsafe.Pointer, uintptr, uintptr) 667 668 func (f *Function) call_crosscall2(argtypes []*Type, rtypes []*Type, entryPoint unsafe.Pointer, args []*Value) []*Value { 669 crosscall2 := f.crosscall2 670 671 fields := []*Type{} 672 fields = append(fields, argtypes...) 673 fields = append(fields, rtypes...) 674 fields = append(fields, TypeVoidPtr) 675 argtype := CreateStruct(fields, 0) 676 fargs := f.CreateValue(argtype) 677 678 wrapper := func(a unsafe.Pointer, n int32, ctxt uintptr) { 679 addr := *(*unsafe.Pointer)(unsafe.Pointer(uintptr(a) + uintptr(n) - uintptr(ptrsize))) 680 cgo_runtime_cgocallback(addr, a, uintptr(n), ctxt) 681 } 682 wrapperptr := **(**unsafe.Pointer)(unsafe.Pointer(&wrapper)) 683 684 ep := f.CreatePtrValue(entryPoint) 685 argsref := f.AddressOf(fargs) 686 offset := 0 687 for i := 0; i < len(argtypes); i++ { 688 f.StoreRelative(argsref, offset, args[i]) 689 offset += int(argtypes[i].Size()) 690 } 691 f.StoreRelative(argsref, int(argtype.Size()-ptrsize), ep) 692 fp := f.CreatePtrValue(wrapperptr) 693 size := f.CreateNintConstant(TypeInt, int(argtype.Size())) 694 f.Call("crosscall2", crosscall2, []*Value{fp, argsref, size, args[len(args)-1]}) 695 696 rvalues := []*Value{} 697 for i := 0; i < len(rtypes); i++ { 698 rvalues = append(rvalues, f.LoadRelative(argsref, offset, rtypes[i])) 699 offset += int(rtypes[i].Size()) 700 } 701 return rvalues 702 }