func (v *MrbValue) call(method string, args []Value, block Value) (*MrbValue, error) { var argv []C.mrb_value = nil var argvPtr *C.mrb_value = nil if len(args) > 0 { // Make the raw byte slice to hold our arguments we'll pass to C argv = make([]C.mrb_value, len(args)) for i, arg := range args { argv[i] = arg.MrbValue(&Mrb{v.state}).value } argvPtr = &argv[0] } var blockV *C.mrb_value if block != nil { val := block.MrbValue(&Mrb{v.state}).value blockV = &val } cs := C.CString(method) defer C.free(unsafe.Pointer(cs)) // If we have a block, we have to call a separate function to // pass a block in. Otherwise, we just call it directly. var result C.mrb_value if blockV == nil { result = C.mrb_funcall_argv( v.state, v.value, C.mrb_intern_cstr(v.state, cs), C.mrb_int(len(argv)), argvPtr) } else { result = C.mrb_funcall_with_block( v.state, v.value, C.mrb_intern_cstr(v.state, cs), C.mrb_int(len(argv)), argvPtr, *blockV) } if exc := checkException(v.state); exc != nil { return nil, exc } return newValue(v.state, result), nil }
// Call calls a method with the given name and arguments on this // value. func (v *MrbValue) Call(method string, args ...Value) (*MrbValue, error) { var argv []C.mrb_value = nil var argvPtr *C.mrb_value = nil if len(args) > 0 { // Make the raw byte slice to hold our arguments we'll pass to C argv = make([]C.mrb_value, len(args)) for i, arg := range args { argv[i] = arg.MrbValue(&Mrb{v.state}).value } argvPtr = &argv[0] } result := C.mrb_funcall_argv( v.state, v.value, C.mrb_intern_cstr(v.state, C.CString(method)), C.int(len(argv)), argvPtr) if v.state.exc != nil { return nil, newExceptionValue(v.state) } return newValue(v.state, result), nil }
// ConstDefined checks if the given constant is defined in the scope. // // This should be used, for example, before a call to Class, because a // failure in Class will crash your program (by design). You can retrieve // the Value of a Class by calling Value(). func (m *Mrb) ConstDefined(name string, scope Value) bool { cs := C.CString(name) defer C.free(unsafe.Pointer(cs)) scopeV := scope.MrbValue(m).value b := C.mrb_const_defined( m.state, scopeV, C.mrb_intern_cstr(m.state, cs)) return C.ushort(b) != 0 }
func insertMethod(s *C.mrb_state, c *C.struct_RClass, n string, f Func) { classLookup := stateMethodTable[s] if classLookup == nil { classLookup = make(classMethodMap) stateMethodTable[s] = classLookup } methodLookup := classLookup[c] if methodLookup == nil { methodLookup = make(methodMap) classLookup[c] = methodLookup } sym := C.mrb_intern_cstr(s, C.CString(n)) methodLookup[sym] = f }
func insertMethod(s *C.mrb_state, c *C.struct_RClass, n string, f Func) { classLookup := stateMethodTable[s] if classLookup == nil { classLookup = make(classMethodMap) stateMethodTable[s] = classLookup } methodLookup := classLookup[c] if methodLookup == nil { methodLookup = make(methodMap) classLookup[c] = methodLookup } cs := C.CString(n) defer C.free(unsafe.Pointer(cs)) sym := C.mrb_intern_cstr(s, cs) methodLookup[sym] = f }
// v.inspect() func (m *MRuby) inspect(v C.mrb_value) string { v = C.mrb_funcall_argv(m.state, v, C.mrb_intern_cstr(m.state, inspectCS), 0, nil) cs := C.mrb_string_value_ptr(m.state, v) return C.GoString(cs) }
// ConstDefined checks if the given constant is defined in the scope. // // This should be used, for example, before a call to Class, because a // failure in Class will crash your program (by design). You can retrieve // the Value of a Class by calling Value(). func (m *Mrb) ConstDefined(name string, scope Value) bool { scopeV := scope.MrbValue(m).value b := C.mrb_const_defined( m.state, scopeV, C.mrb_intern_cstr(m.state, C.CString(name))) return C.ushort(b) != 0 }