global dummy dummy: ; ret global __unsafe_get_addr; convert uint32 to pointer __unsafe_get_addr: push ebp mov ebp, esp mov eax, [ebp+8] mov esp, ebp pop ebp ret
__go_new = go.runtime.New; __go_new_nopointers = go.runtime.New; __go_print_string = go.screen.PrintStr; __go_print_empty_interface = go.screen.PrintInterface; __go_print_nl = go.screen.PrintNl; __go_print_pointer = go.screen.PrintHex; __go_print_uint64 = go.screen.PrintUint64; __go_runtime_error = go.runtime.RuntimeError; __go_panic = go.runtime.Panic; runtime.efacetype = go.runtime.InterfaceType; runtime.ifacetypeeq = go.runtime.InterfaceTypeEq; runtime.ifaceE2T2 = go.runtime.InterfaceE2T2; __go_type_hash_identity = go.runtime.TypeHashIdentity; __go_type_equal_identity = go.runtime.TypeEqualIdentity; __go_strcmp = go.runtime.StrCmp; __go_type_hash_error = dummy; __go_type_equal_error = dummy; __go_register_gc_roots = dummy; __go_type_hash_identity_descriptor = dummy; __go_type_equal_error_descriptor = dummy; __go_type_equal_identity_descriptor = dummy; __go_type_hash_error_descriptor = dummy; __go_type_hash_empty_interface = dummy; __go_empty_interface_compare = dummy; __go_type_hash_string = dummy; __go_type_equal_string = dummy; __go_type_equal_empty_interface = dummy; __go_type_hash_string_descriptor = dummy; __go_type_equal_string_descriptor = dummy; __go_type_hash_empty_interface_descriptor = dummy; __go_type_equal_empty_interface_descriptor = dummy;
//, type PanicStack struct { Next *PanicStack // Arg interface{} // WasRecovered bool // IsForeign bool // } // panic() func Panic(arg interface{}) { //stackTrace(3) //, , , =) p := PanicStack{} // . : , p.Arg = arg // PrintPanic(&p) // for { // } } // func PrintPanic(p *PanicStack) { if p.Next != nil { // , () PrintPanic(p.Next) print("\t") } print("panic: ") // print(p.Arg) // if p.WasRecovered { // print("[recovered]") // } print("\n") }
// func StrCmp(s1, s2 string) int { if len(s1) < len(s2) { return -1 } if len(s2) < len(s1) { return 1 } for i := 0; i < len(s1); i++ { if s1[i] < s2[i] { return -1 } if s2[i] < s1[i] { return 1 } } return 0 } // TypeDescriptor func InterfaceType(arg *EmptyInterface) TypeDescriptor { return *(arg.__type_descriptor) } // , , func InterfaceTypeEq(arg1, arg2 *EmptyInterface) bool { return *(arg1.__type_descriptor.string) == *(arg2.__type_descriptor.string) } // //iface - TypeDescriptor //e - //ret - , // ok - func InterfaceE2T2(iface *TypeDescriptor, e EmptyInterface, ret uint32) (ok bool) { if *(iface.string) == *(e.__type_descriptor.string) { // memcpy(ret, e.__object, uint32(iface.size)) // return true } else { return false } }
// , func PrintInterface(arg interface{}) { v, ok := arg.(string) if ok { print(v) } }
panic("Habrahabr")
panic: Habrahabr
// const ( SLICE_INDEX_OUT_OF_BOUNDS = uint32(iota) ARRAY_INDEX_OUT_OF_BOUNDS STRING_INDEX_OUT_OF_BOUNDS SLICE_SLICE_OUT_OF_BOUNDS ARRAY_SLICE_OUT_OF_BOUNDS STRING_SLICE_OUT_OF_BOUNDS NIL_DEREFERENCE MAKE_SLICE_OUT_OF_BOUNDS MAKE_MAP_OUT_OF_BOUNDS MAKE_CHAN_OUT_OF_BOUNDS DIVISION_BY_ZERO MSG_INDEX_OUT_OF_RANGE = "index out of range" MSG_SLICE_BOUNDS_OUT_OF_RANGE = "slice vounds out of range" MSG_NIL_DEREFERENCE = "nil pointer dereference" MSG_MAKE_SLICE_OUT_OF_BOUNDS = "make slice len or cap out of range" MSG_MAKE_MAP_OUT_OF_BOUNDS = "make map len out of range" MSG_MAKE_CHAN_OUT_OF_BOUNDS = "make chan len out of range" MSG_DIVISION_BY_ZERO = "integer divide by zero" MSG_UNKNOWN = "unknown" ) // , , , , func RuntimeError(i uint32) { switch i { case SLICE_INDEX_OUT_OF_BOUNDS, ARRAY_INDEX_OUT_OF_BOUNDS, STRING_INDEX_OUT_OF_BOUNDS: panic(MSG_INDEX_OUT_OF_RANGE) case SLICE_SLICE_OUT_OF_BOUNDS, ARRAY_SLICE_OUT_OF_BOUNDS, STRING_SLICE_OUT_OF_BOUNDS: panic(MSG_SLICE_BOUNDS_OUT_OF_RANGE) case NIL_DEREFERENCE: panic(MSG_NIL_DEREFERENCE) case MAKE_SLICE_OUT_OF_BOUNDS: panic(MSG_MAKE_SLICE_OUT_OF_BOUNDS) case MAKE_MAP_OUT_OF_BOUNDS: panic(MSG_MAKE_MAP_OUT_OF_BOUNDS) case MAKE_CHAN_OUT_OF_BOUNDS: panic(MSG_MAKE_CHAN_OUT_OF_BOUNDS) case DIVISION_BY_ZERO: panic(MSG_DIVISION_BY_ZERO) default: panic(MSG_UNKNOWN) } }
Kirill:
look what my thoughts are
[12:09:22 PM] Ivan:
I read carefully)
[12:09:35 PM] Kirill:
lines in goshka are immutable
[12:09:45 PM] Ivan:
Yep
Change leads to the creation of a new
[12:10:25 PM] Kirill:
and InterfaceE2T2 can, in theory, and not copy data
rather refer to existing
[12:12:47 PM] Ivan:
It cannot, a) it should work not only with strings, b) we get the return address and have to write data, which is what is expected, but not a pointer
[12:13:31 PM] Kirill:
something I overlooked means
sorry i can't
I always rest on this restriction
it turns out here it will not work to fix
[12:16:05 PM] Ivan:
Why, it is possible, runtime extension, i.e. implement the InterfaceToString method (iface interface {}) (str * string, ok bool)
But this is not a runtime method, but a custom
Hmm ... add this little discussion to the article?
[12:17:01 PM] Kirill:
come on
This is an interesting task, it must be solved sooner or later.
exactly the same interface {} -> [] byte
Source: https://habr.com/ru/post/315566/
All Articles