diff --git a/conn.go b/conn.go index 85fc6cc..e0a7861 100644 --- a/conn.go +++ b/conn.go @@ -9,8 +9,6 @@ import ( "strings" "sync/atomic" "unsafe" - - "github.com/tetratelabs/wazero/api" ) // Conn is a database connection handle. @@ -325,98 +323,6 @@ func (c *Conn) error(rc uint64, sql ...string) error { return c.module.error(rc, c.handle, sql...) } -func (c *Conn) call(fn api.Function, params ...uint64) []uint64 { - r, err := fn.Call(c.ctx, params...) - if err != nil { - panic(err) - } - return r -} - -func (c *Conn) free(ptr uint32) { - if ptr == 0 { - return - } - c.call(c.api.free, uint64(ptr)) -} - -func (c *Conn) new(size uint64) uint32 { - if size > _MAX_ALLOCATION_SIZE { - panic(oomErr) - } - r := c.call(c.api.malloc, size) - ptr := uint32(r[0]) - if ptr == 0 && size != 0 { - panic(oomErr) - } - return ptr -} - -func (c *Conn) newBytes(b []byte) uint32 { - if b == nil { - return 0 - } - ptr := c.new(uint64(len(b))) - c.mem.writeBytes(ptr, b) - return ptr -} - -func (c *Conn) newString(s string) uint32 { - ptr := c.new(uint64(len(s) + 1)) - c.mem.writeString(ptr, s) - return ptr -} - -func (c *Conn) newArena(size uint64) arena { - return arena{ - c: c, - base: c.new(size), - size: uint32(size), - } -} - -type arena struct { - c *Conn - base uint32 - next uint32 - size uint32 - ptrs []uint32 -} - -func (a *arena) free() { - if a.c == nil { - return - } - a.reset() - a.c.free(a.base) - a.c = nil -} - -func (a *arena) reset() { - for _, ptr := range a.ptrs { - a.c.free(ptr) - } - a.ptrs = nil - a.next = 0 -} - -func (a *arena) new(size uint64) uint32 { - if size <= uint64(a.size-a.next) { - ptr := a.base + a.next - a.next += uint32(size) - return ptr - } - ptr := a.c.new(size) - a.ptrs = append(a.ptrs, ptr) - return ptr -} - -func (a *arena) string(s string) uint32 { - ptr := a.new(uint64(len(s) + 1)) - a.c.mem.writeString(ptr, s) - return ptr -} - // DriverConn is implemented by the SQLite [database/sql] driver connection. // // It can be used to access advanced SQLite features like diff --git a/module.go b/module.go index efc524e..29d6d4e 100644 --- a/module.go +++ b/module.go @@ -201,6 +201,98 @@ func (m *module) error(rc uint64, handle uint32, sql ...string) error { return &err } +func (m *module) call(fn api.Function, params ...uint64) []uint64 { + r, err := fn.Call(m.ctx, params...) + if err != nil { + panic(err) + } + return r +} + +func (m *module) free(ptr uint32) { + if ptr == 0 { + return + } + m.call(m.api.free, uint64(ptr)) +} + +func (m *module) new(size uint64) uint32 { + if size > _MAX_ALLOCATION_SIZE { + panic(oomErr) + } + r := m.call(m.api.malloc, size) + ptr := uint32(r[0]) + if ptr == 0 && size != 0 { + panic(oomErr) + } + return ptr +} + +func (m *module) newBytes(b []byte) uint32 { + if b == nil { + return 0 + } + ptr := m.new(uint64(len(b))) + m.mem.writeBytes(ptr, b) + return ptr +} + +func (m *module) newString(s string) uint32 { + ptr := m.new(uint64(len(s) + 1)) + m.mem.writeString(ptr, s) + return ptr +} + +func (m *module) newArena(size uint64) arena { + return arena{ + m: m, + base: m.new(size), + size: uint32(size), + } +} + +type arena struct { + m *module + base uint32 + next uint32 + size uint32 + ptrs []uint32 +} + +func (a *arena) free() { + if a.m == nil { + return + } + a.reset() + a.m.free(a.base) + a.m = nil +} + +func (a *arena) reset() { + for _, ptr := range a.ptrs { + a.m.free(ptr) + } + a.ptrs = nil + a.next = 0 +} + +func (a *arena) new(size uint64) uint32 { + if size <= uint64(a.size-a.next) { + ptr := a.base + a.next + a.next += uint32(size) + return ptr + } + ptr := a.m.new(size) + a.ptrs = append(a.ptrs, ptr) + return ptr +} + +func (a *arena) string(s string) uint32 { + ptr := a.new(uint64(len(s) + 1)) + a.m.mem.writeString(ptr, s) + return ptr +} + type sqliteAPI struct { free api.Function malloc api.Function