提交 6e37e3c8 编写于 作者: 3 3dgen

1、变更wir.Module中关于函数类型的定义方法

2、运行时类型信息注入(WIP)
上级 e972d48d
......@@ -146,16 +146,15 @@ func (tLib *typeLib) compile(from types.Type) wir.ValueType {
var method wir.Method
method.Sig = tLib.GenFnSig(ut.Method(i).Type().(*types.Signature))
method.Name = ut.Method(i).Name()
method.FullFnName = pkg_name + "." + obj_name + "." + method.Name
newType.AddMethod(method)
var fnSig wir.FnSig
fnSig.Params = append(fnSig.Params, tLib.module.GenValueType_Ref(tLib.module.VOID))
fnSig.Params = append(fnSig.Params, method.Sig.Params...)
fnSig.Results = method.Sig.Results
method.FullFnName = tLib.module.AddFnSig(&fnSig)
var fntype wir.FnType
fntype.FnSig.Params = append(fntype.FnSig.Params, tLib.module.GenValueType_Ref(tLib.module.VOID))
fntype.FnSig.Params = append(fntype.FnSig.Params, method.Sig.Params...)
fntype.FnSig.Results = method.Sig.Results
fntype.Name = method.FullFnName
tLib.module.AddFnType(&fntype)
newType.AddMethod(method)
}
case *types.Signature:
......
......@@ -12,7 +12,7 @@ import (
Module:
**************************************/
type Module struct {
VOID, RUNE, I8, U8, I16, U16, I32, U32, I64, U64, F32, F64, STRING ValueType
VOID, RUNE, I8, U8, I16, U16, I32, U32, UPTR, I64, U64, F32, F64, STRING ValueType
types_map map[string]ValueType
usedConcreteTypes []ValueType
......@@ -20,8 +20,8 @@ type Module struct {
imports []wat.Import
fn_types []*FnType
fn_types_map map[string]int
fnSigs []*FnSig
fnSigsName map[string]string
funcs []*Function
funcs_map map[string]*Function
......@@ -54,6 +54,7 @@ func NewModule() *Module {
m.U16 = &tU16{}
m.I32 = &tI32{}
m.U32 = &tU32{}
m.UPTR = m.U32
m.I64 = &tI64{}
m.U64 = &tU64{}
m.F32 = &tF32{}
......@@ -75,13 +76,7 @@ func NewModule() *Module {
m.STRING = m.GenValueType_String()
m.fn_types_map = make(map[string]int)
{
var free_type FnType
free_type.Name = "$onFree"
free_type.Params = []ValueType{m.I32}
m.AddFnType(&free_type)
}
m.fnSigsName = make(map[string]string)
m.funcs_map = make(map[string]*Function)
......@@ -110,21 +105,23 @@ func (m *Module) AddImportFunc(moduleName string, objName string, funcName strin
m.imports = append(m.imports, wat.NewImpFunc(moduleName, objName, funcName, wat_sig))
}
func (m *Module) findFnType(name string) int {
if i, ok := m.fn_types_map[name]; ok {
return i
func (m *Module) FindFnSig(sig *FnSig) string {
if s, ok := m.fnSigsName[sig.String()]; ok {
return s
}
return 0
return ""
}
func (m *Module) AddFnType(typ *FnType) int {
if i := m.findFnType(typ.Name); i != 0 {
return i
func (m *Module) AddFnSig(sig *FnSig) string {
if s, ok := m.fnSigsName[sig.String()]; ok {
return s
}
i := len(m.fn_types)
m.fn_types = append(m.fn_types, typ)
m.fn_types_map[typ.Name] = i
return i
m.fnSigs = append(m.fnSigs, sig)
s := "$$fnSig" + strconv.Itoa(len(m.fnSigs))
m.fnSigsName[sig.String()] = s
return s
}
func (m *Module) findTableElem(elem string) int {
......@@ -234,9 +231,15 @@ func (m *Module) ToWatModule() *wat.Module {
wat_module.Imports = m.imports
wat_module.BaseWat = m.BaseWat
for _, t := range m.fn_types {
{
var onfree_type wat.FuncType
onfree_type.Name = "$onFree"
onfree_type.Params = m.I32.Raw()
wat_module.FuncTypes = append(wat_module.FuncTypes, onfree_type)
}
for _, t := range m.fnSigs {
var fn_type wat.FuncType
fn_type.Name = t.Name
fn_type.Name = m.fnSigsName[t.String()]
for _, i := range t.Params {
fn_type.Params = append(fn_type.Params, i.Raw()...)
}
......@@ -355,3 +358,158 @@ func (m *Module) buildItab() {
m.SetGlobalInitValue("$wa.RT._interfaceCount", strconv.Itoa(len(m.usedInterfaces)))
m.SetGlobalInitValue("$wa.RT._concretTypeCount", strconv.Itoa(len(m.usedConcreteTypes)))
}
func (m *Module) genTypeInfo(t ValueType) int {
_type := NewConst("0", m.types_map["runtime._type"]).(*aStruct)
_type.setFieldConstValue("size", NewConst(strconv.Itoa(t.Size()), m.U32))
_type.setFieldConstValue("hash", NewConst(strconv.Itoa(t.Hash()), m.I32))
_type.setFieldConstValue("kind", NewConst(strconv.Itoa(int(t.Kind())), m.U8))
_type.setFieldConstValue("align", NewConst(strconv.Itoa(t.align()), m.U8))
_type.setFieldConstValue("flag", NewConst("0", m.U16))
_type.setFieldConstValue("name", NewConst(t.Name(), m.STRING))
switch typ := t.(type) {
case *tI8:
if typ.addr != 0 {
return typ.addr
}
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tU8:
if typ.addr != 0 {
return typ.addr
}
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tI16:
if typ.addr != 0 {
return typ.addr
}
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tU16:
if typ.addr != 0 {
return typ.addr
}
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tI32:
if typ.addr != 0 {
return typ.addr
}
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tU32:
if typ.addr != 0 {
return typ.addr
}
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tI64:
if typ.addr != 0 {
return typ.addr
}
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tU64:
if typ.addr != 0 {
return typ.addr
}
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tF32:
if typ.addr != 0 {
return typ.addr
}
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tF64:
if typ.addr != 0 {
return typ.addr
}
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *tRune:
if typ.addr != 0 {
return typ.addr
}
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *String:
if typ.addr != 0 {
return typ.addr
}
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *Ptr:
if typ.addr != 0 {
return typ.addr
}
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *Block:
if typ.addr != 0 {
return typ.addr
}
typ.addr = m.DataSeg.Append(_type.Bin(), 8)
return typ.addr
case *Array:
if typ.addr != 0 {
return typ.addr
}
_array := NewConst("0", m.types_map["runtime._arrayType"]).(*aStruct)
_array.setFieldConstValue("$_type", _type)
_array.setFieldConstValue("elemType", NewConst(strconv.Itoa(m.genTypeInfo(typ.Base)), m.UPTR))
_array.setFieldConstValue("cap", NewConst(strconv.Itoa(typ.Capacity), m.UPTR))
typ.addr = m.DataSeg.Append(_array.Bin(), 8)
return typ.addr
case *Slice:
if typ.addr != 0 {
return typ.addr
}
_slice := NewConst("0", m.types_map["runtime._arrayType"]).(*aStruct)
_slice.setFieldConstValue("$_type", _type)
_slice.setFieldConstValue("elemType", NewConst(strconv.Itoa(m.genTypeInfo(typ.Base)), m.UPTR))
typ.addr = m.DataSeg.Append(_slice.Bin(), 8)
return typ.addr
/*
case *Ref:
if typ.addr != 0 {
return typ.addr
}
_ref := NewConst("0", m.types_map["runtime._refType"]).(*aStruct)
_ref.setFieldConstValue("$_type", _type)
_ref.setFieldConstValue("elemType", NewConst(strconv.Itoa(m.genTypeInfo(typ.Base)), m.UPTR))
if len(typ.methods) > 0 {
_uncommon := NewConst("0", m.types_map["runtime._uncommonType"]).(*aStruct)
_uncommon.setFieldConstValue("methodCount", NewConst(strconv.Itoa(len(typ.methods)), m.U32))
_uncommon_bin := _uncommon.Bin()
for _, method := range typ.methods {
_method := NewConst("0", m.types_map["runtime._method"]).(*aStruct)
_method.setFieldConstValue("name", NewConst(method.Name, m.STRING))
}
} //*/
default:
logger.Fatalf("Todo: %t", t)
return 0
}
}
......@@ -45,6 +45,7 @@ func (m *Module) GenValueType_Array(base ValueType, capacity int) *Array {
func (t *Array) Name() string { return t.Base.Name() + ".$array" + strconv.Itoa(t.Capacity) }
func (t *Array) Size() int { return t.underlying.Size() }
func (t *Array) align() int { return t.underlying.align() }
func (t *Array) Kind() TypeKind { return kArray }
func (t *Array) Raw() []wat.ValueType { return t.underlying.Raw() }
func (t *Array) onFree() int { return t.underlying.onFree() }
......
......@@ -35,6 +35,7 @@ func (m *Module) GenValueType_Block(base ValueType) *Block {
func (t *Block) Name() string { return t.Base.Name() + ".$$block" }
func (t *Block) Size() int { return 4 }
func (t *Block) align() int { return 4 }
func (t *Block) Kind() TypeKind { return kBlock }
func (t *Block) Raw() []wat.ValueType { return []wat.ValueType{wat.U32{}} }
func (t *Block) Equal(u ValueType) bool {
if ut, ok := u.(*Block); ok {
......
......@@ -52,38 +52,27 @@ func (s *FnSig) String() string {
return n
}
/**************************************
FnType:
**************************************/
type FnType struct {
Name string
FnSig
}
/**************************************
Closure:
**************************************/
type Closure struct {
tCommon
underlying *Struct
_fn_type FnType
_u32 ValueType
underlying *Struct
_fnSig FnSig
_fnTypeName string
_u32 ValueType
}
var _closure_id int
func (m *Module) GenValueType_Closure(sig FnSig) *Closure {
var closure_t Closure
closure_t._fn_type.FnSig = sig
closure_t._fnSig = sig
t, ok := m.findValueType(closure_t.Name())
if ok {
return t.(*Closure)
}
closure_t._u32 = m.U32
closure_t._fn_type.Name = "closure$" + strconv.Itoa(_closure_id)
_closure_id++
m.AddFnType(&closure_t._fn_type)
closure_t._fnTypeName = m.AddFnSig(&sig)
var found bool
closure_t.underlying, found = m.GenValueType_Struct(closure_t.Name() + ".underlying")
......@@ -98,15 +87,16 @@ func (m *Module) GenValueType_Closure(sig FnSig) *Closure {
return &closure_t
}
func (t *Closure) Name() string { return t._fn_type.String() }
func (t *Closure) Name() string { return t._fnSig.String() }
func (t *Closure) Size() int { return t.underlying.Size() }
func (t *Closure) align() int { return t.underlying.align() }
func (t *Closure) Kind() TypeKind { return kStruct }
func (t *Closure) onFree() int { return t.underlying.onFree() }
func (t *Closure) Raw() []wat.ValueType { return t.underlying.Raw() }
func (t *Closure) Equal(u ValueType) bool {
if ut, ok := u.(*Closure); ok {
return t._fn_type.FnSig.Equal(&ut._fn_type.FnSig)
return t._fnSig.Equal(&ut._fnSig)
}
return false
}
......@@ -157,6 +147,6 @@ func EmitCallClosure(c Value, params []Value) (insts []wat.Inst) {
insts = append(insts, closure.Extract("data").EmitPush()...)
insts = append(insts, currentModule.FindGlobalByName("$wa.RT.closure_data").EmitPop()...)
insts = append(insts, wat.NewInstCallIndirect(closure.typ._fn_type.Name))
insts = append(insts, wat.NewInstCallIndirect(closure.typ._fnTypeName))
return
}
......@@ -44,6 +44,7 @@ func (m *Module) GenValueType_Interface(name string) *Interface {
func (t *Interface) Name() string { return t.name }
func (t *Interface) Size() int { return t.underlying.Size() }
func (t *Interface) align() int { return t.underlying.align() }
func (t *Interface) Kind() TypeKind { return kInterface }
func (t *Interface) onFree() int { return t.underlying.onFree() }
func (t *Interface) Raw() []wat.ValueType { return t.underlying.Raw() }
func (t *Interface) Equal(u ValueType) bool {
......
......@@ -29,6 +29,7 @@ func (m *Module) GenValueType_Ptr(base ValueType) *Ptr {
func (t *Ptr) Name() string { return t.Base.Name() + ".$$ptr" }
func (t *Ptr) Size() int { return 4 }
func (t *Ptr) align() int { return 4 }
func (t *Ptr) Kind() TypeKind { return kPtr }
func (t *Ptr) onFree() int { return 0 }
func (t *Ptr) Raw() []wat.ValueType { return []wat.ValueType{toWatType(t)} }
func (t *Ptr) Equal(u ValueType) bool {
......
......@@ -48,6 +48,7 @@ func (m *Module) GenValueType_Ref(base ValueType) *Ref {
func (t *Ref) Name() string { return t.Base.Name() + ".$ref" }
func (t *Ref) Size() int { return t.underlying.Size() }
func (t *Ref) align() int { return t.underlying.align() }
func (t *Ref) Kind() TypeKind { return kRef }
func (t *Ref) onFree() int { return t.underlying.onFree() }
func (t *Ref) Raw() []wat.ValueType { return t.underlying.Raw() }
func (t *Ref) Equal(u ValueType) bool {
......
......@@ -53,6 +53,7 @@ func (m *Module) GenValueType_Slice(base ValueType) *Slice {
func (t *Slice) Name() string { return t.Base.Name() + ".$slice" }
func (t *Slice) Size() int { return t.underlying.Size() }
func (t *Slice) align() int { return t.underlying.align() }
func (t *Slice) Kind() TypeKind { return kSlice }
func (t *Slice) onFree() int { return t.underlying.onFree() }
func (t *Slice) Raw() []wat.ValueType { return t.underlying.Raw() }
func (t *Slice) Equal(u ValueType) bool {
......
......@@ -54,6 +54,7 @@ func (m *Module) GenValueType_String() *String {
func (t *String) Name() string { return "string" }
func (t *String) Size() int { return t.underlying.Size() }
func (t *String) align() int { return t.underlying.align() }
func (t *String) Kind() TypeKind { return kString }
func (t *String) onFree() int { return t.underlying.onFree() }
func (t *String) Raw() []wat.ValueType { return t.underlying.Raw() }
func (t *String) Equal(u ValueType) bool { _, ok := u.(*String); return ok }
......
......@@ -65,9 +65,10 @@ func (m *Module) GenValueType_Struct(name string) (*Struct, bool) {
return &struct_type, false
}
func (t *Struct) Name() string { return t.name }
func (t *Struct) Size() int { return t._size }
func (t *Struct) align() int { return t._align }
func (t *Struct) Name() string { return t.name }
func (t *Struct) Size() int { return t._size }
func (t *Struct) align() int { return t._align }
func (t *Struct) Kind() TypeKind { return kStruct }
func (t *Struct) AppendField(f *StructField) {
t.fields = append(t.fields, f)
......
......@@ -51,6 +51,7 @@ func (t *Tuple) Name() string {
func (t *Tuple) Size() int { return t.underlying.Size() }
func (t *Tuple) align() int { return t.underlying.align() }
func (t *Tuple) Kind() TypeKind { return kTuple }
func (t *Tuple) onFree() int { return t.underlying.onFree() }
func (t *Tuple) Raw() []wat.ValueType { return t.underlying.Raw() }
func (t *Tuple) Equal(u ValueType) bool {
......
......@@ -7,6 +7,34 @@ import (
"wa-lang.org/wa/internal/logger"
)
type TypeKind uint8
const (
kUnknown TypeKind = iota
kVoid
kU8
kU16
kU32
kU64
kI8
kI16
kI32
kI64
kF32
kF64
kRune
kPtr
kBlock
kStruct
kTuple
kRef
kString
kSlice
kArray
kMap
kInterface
)
func toWatType(t ValueType) wat.ValueType {
switch t.(type) {
case *tI32, *tRune, *tI8, *tI16:
......@@ -44,6 +72,7 @@ func toWatType(t ValueType) wat.ValueType {
tCommon:
**************************************/
type tCommon struct {
addr int
hash int
methods []Method
}
......@@ -76,6 +105,7 @@ type tVoid struct {
func (t *tVoid) Name() string { return "void" }
func (t *tVoid) Size() int { return 0 }
func (t *tVoid) align() int { return 0 }
func (t *tVoid) Kind() TypeKind { return kVoid }
func (t *tVoid) onFree() int { return 0 }
func (t *tVoid) Raw() []wat.ValueType { return []wat.ValueType{} }
func (t *tVoid) Equal(u ValueType) bool { _, ok := u.(*tVoid); return ok }
......@@ -94,6 +124,7 @@ type tRune struct {
func (t *tRune) Name() string { return "rune" }
func (t *tRune) Size() int { return 4 }
func (t *tRune) align() int { return 4 }
func (t *tRune) Kind() TypeKind { return kRune }
func (t *tRune) onFree() int { return 0 }
func (t *tRune) Raw() []wat.ValueType { return []wat.ValueType{wat.I32{}} }
func (t *tRune) Equal(u ValueType) bool { _, ok := u.(*tRune); return ok }
......@@ -117,6 +148,7 @@ type tI8 struct {
func (t *tI8) Name() string { return "i8" }
func (t *tI8) Size() int { return 1 }
func (t *tI8) align() int { return 1 }
func (t *tI8) Kind() TypeKind { return kI8 }
func (t *tI8) onFree() int { return 0 }
func (t *tI8) Raw() []wat.ValueType { return []wat.ValueType{wat.I32{}} }
func (t *tI8) Equal(u ValueType) bool { _, ok := u.(*tI8); return ok }
......@@ -140,6 +172,7 @@ type tU8 struct {
func (t *tU8) Name() string { return "u8" }
func (t *tU8) Size() int { return 1 }
func (t *tU8) align() int { return 1 }
func (t *tU8) Kind() TypeKind { return kU8 }
func (t *tU8) onFree() int { return 0 }
func (t *tU8) Raw() []wat.ValueType { return []wat.ValueType{wat.I32{}} }
func (t *tU8) Equal(u ValueType) bool { _, ok := u.(*tU8); return ok }
......@@ -163,6 +196,7 @@ type tI16 struct {
func (t *tI16) Name() string { return "i16" }
func (t *tI16) Size() int { return 2 }
func (t *tI16) align() int { return 2 }
func (t *tI16) Kind() TypeKind { return kI16 }
func (t *tI16) onFree() int { return 0 }
func (t *tI16) Raw() []wat.ValueType { return []wat.ValueType{wat.I32{}} }
func (t *tI16) Equal(u ValueType) bool { _, ok := u.(*tI16); return ok }
......@@ -186,6 +220,7 @@ type tU16 struct {
func (t *tU16) Name() string { return "u16" }
func (t *tU16) Size() int { return 2 }
func (t *tU16) align() int { return 2 }
func (t *tU16) Kind() TypeKind { return kU16 }
func (t *tU16) onFree() int { return 0 }
func (t *tU16) Raw() []wat.ValueType { return []wat.ValueType{wat.I32{}} }
func (t *tU16) Equal(u ValueType) bool { _, ok := u.(*tU16); return ok }
......@@ -209,6 +244,7 @@ type tI32 struct {
func (t *tI32) Name() string { return "i32" }
func (t *tI32) Size() int { return 4 }
func (t *tI32) align() int { return 4 }
func (t *tI32) Kind() TypeKind { return kI32 }
func (t *tI32) onFree() int { return 0 }
func (t *tI32) Raw() []wat.ValueType { return []wat.ValueType{wat.I32{}} }
func (t *tI32) Equal(u ValueType) bool { _, ok := u.(*tI32); return ok }
......@@ -232,6 +268,7 @@ type tU32 struct {
func (t *tU32) Name() string { return "u32" }
func (t *tU32) Size() int { return 4 }
func (t *tU32) align() int { return 4 }
func (t *tU32) Kind() TypeKind { return kU32 }
func (t *tU32) onFree() int { return 0 }
func (t *tU32) Raw() []wat.ValueType { return []wat.ValueType{wat.U32{}} }
func (t *tU32) Equal(u ValueType) bool { _, ok := u.(*tU32); return ok }
......@@ -255,6 +292,7 @@ type tI64 struct {
func (t *tI64) Name() string { return "i64" }
func (t *tI64) Size() int { return 8 }
func (t *tI64) align() int { return 8 }
func (t *tI64) Kind() TypeKind { return kI64 }
func (t *tI64) onFree() int { return 0 }
func (t *tI64) Raw() []wat.ValueType { return []wat.ValueType{wat.I64{}} }
func (t *tI64) Equal(u ValueType) bool { _, ok := u.(*tI64); return ok }
......@@ -278,6 +316,7 @@ type tU64 struct {
func (t *tU64) Name() string { return "u64" }
func (t *tU64) Size() int { return 8 }
func (t *tU64) align() int { return 8 }
func (t *tU64) Kind() TypeKind { return kU64 }
func (t *tU64) onFree() int { return 0 }
func (t *tU64) Raw() []wat.ValueType { return []wat.ValueType{wat.U64{}} }
func (t *tU64) Equal(u ValueType) bool { _, ok := u.(*tU64); return ok }
......@@ -301,6 +340,7 @@ type tF32 struct {
func (t *tF32) Name() string { return "f32" }
func (t *tF32) Size() int { return 4 }
func (t *tF32) align() int { return 4 }
func (t *tF32) Kind() TypeKind { return kF32 }
func (t *tF32) onFree() int { return 0 }
func (t *tF32) Raw() []wat.ValueType { return []wat.ValueType{wat.F32{}} }
func (t *tF32) Equal(u ValueType) bool { _, ok := u.(*tF32); return ok }
......@@ -324,6 +364,7 @@ type tF64 struct {
func (t *tF64) Name() string { return "f64" }
func (t *tF64) Size() int { return 8 }
func (t *tF64) align() int { return 8 }
func (t *tF64) Kind() TypeKind { return kF64 }
func (t *tF64) onFree() int { return 0 }
func (t *tF64) Raw() []wat.ValueType { return []wat.ValueType{wat.F64{}} }
func (t *tF64) Equal(u ValueType) bool { _, ok := u.(*tF64); return ok }
......
......@@ -54,6 +54,7 @@ type ValueType interface {
Name() string
Size() int
align() int
Kind() TypeKind
onFree() int
Raw() []wat.ValueType
Equal(ValueType) bool
......
......@@ -13,8 +13,8 @@ type _type struct {
type _refType struct {
_type
uncommon: uintptr //@_uncommonType
elemType: uintptr //@_type
uncommon: uintptr //@_uncommonType
}
type _arrayType struct {
......@@ -32,8 +32,7 @@ type _structType struct {
_type
uncommon: uintptr //@_uncommonType
fieldCount: i32
fieldPtr: uintptr //@_structField, len==fieldCount
}
} //followed by [fieldCount]_structField
type _structField struct {
name: string
......@@ -42,9 +41,8 @@ type _structField struct {
type _uncommonType struct {
pkgName: string
methodCount: i32
methodPtr: uintptr //@_method, len==methodCount
}
methodCount: u32
} //followed by [methodCount]_method
type _method struct {
name: string
......@@ -53,19 +51,16 @@ type _method struct {
}
type _fnType struct {
_type
//_type //Todo
paramCount: i32
paramPtr: uintptr //@@_type, len==paramCount
resultCount: i32
resultPtr: uintptr //@@_type, len==resultCount
}
} //followed by [paramCount]@_type + [resultCount]@_type
type _interfaceType struct {
_type
pkgName: string
methodCount: i32
methodPtr: uintptr //@_imethod, len==methodCount
}
} //followed by [methodCount]_imethod
type _imethod struct {
name: string
......@@ -75,7 +70,7 @@ type _imethod struct {
type _itab struct {
dtype: uintptr //@_type, ptr of (*data).(type)
itype: uintptr //@_interfacetype
} //紧接[itype.methodCound]fnID, fnID=id for call_indirect
} //followed by [itype.methodCound]fnID, fnID=>id for call_indirect
type _iface struct {
data: *i32
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册