Skip to content

Commit 9d77322

Browse files
committed
Memory management.
1 parent c1915fe commit 9d77322

13 files changed

+64
-70
lines changed

const.go

+4-7
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,10 @@ const (
77
_ROW = 100 /* sqlite3_step() has another row ready */
88
_DONE = 101 /* sqlite3_step() has finished executing */
99

10-
_UTF8 = 1
11-
12-
_MAX_NAME = 1e6 // Self-imposed limit for most NUL terminated strings.
13-
_MAX_LENGTH = 1e9
14-
_MAX_SQL_LENGTH = 1e9
15-
_MAX_ALLOCATION_SIZE = 0x7ffffeff
16-
_MAX_FUNCTION_ARG = 100
10+
_MAX_NAME = 1e6 // Self-imposed limit for most NUL terminated strings.
11+
_MAX_LENGTH = 1e9
12+
_MAX_SQL_LENGTH = 1e9
13+
_MAX_FUNCTION_ARG = 100
1714

1815
ptrlen = 4
1916
)

context.go

+8-12
Original file line numberDiff line numberDiff line change
@@ -84,19 +84,17 @@ func (ctx Context) ResultFloat(value float64) {
8484
// https://sqlite.org/c3ref/result_blob.html
8585
func (ctx Context) ResultText(value string) {
8686
ptr := ctx.c.newString(value)
87-
ctx.c.call("sqlite3_result_text64",
88-
uint64(ctx.handle), uint64(ptr), uint64(len(value)),
89-
uint64(ctx.c.freer), _UTF8)
87+
ctx.c.call("sqlite3_result_text_go",
88+
uint64(ctx.handle), uint64(ptr), uint64(len(value)))
9089
}
9190

9291
// ResultRawText sets the text result of the function to a []byte.
9392
//
9493
// https://sqlite.org/c3ref/result_blob.html
9594
func (ctx Context) ResultRawText(value []byte) {
9695
ptr := ctx.c.newBytes(value)
97-
ctx.c.call("sqlite3_result_text64",
98-
uint64(ctx.handle), uint64(ptr), uint64(len(value)),
99-
uint64(ctx.c.freer), _UTF8)
96+
ctx.c.call("sqlite3_result_text_go",
97+
uint64(ctx.handle), uint64(ptr), uint64(len(value)))
10098
}
10199

102100
// ResultBlob sets the result of the function to a []byte.
@@ -105,9 +103,8 @@ func (ctx Context) ResultRawText(value []byte) {
105103
// https://sqlite.org/c3ref/result_blob.html
106104
func (ctx Context) ResultBlob(value []byte) {
107105
ptr := ctx.c.newBytes(value)
108-
ctx.c.call("sqlite3_result_blob64",
109-
uint64(ctx.handle), uint64(ptr), uint64(len(value)),
110-
uint64(ctx.c.freer))
106+
ctx.c.call("sqlite3_result_blob_go",
107+
uint64(ctx.handle), uint64(ptr), uint64(len(value)))
111108
}
112109

113110
// ResultZeroBlob sets the result of the function to a zero-filled, length n BLOB.
@@ -154,9 +151,8 @@ func (ctx Context) resultRFC3339Nano(value time.Time) {
154151
buf := util.View(ctx.c.mod, ptr, maxlen)
155152
buf = value.AppendFormat(buf[:0], time.RFC3339Nano)
156153

157-
ctx.c.call("sqlite3_result_text64",
158-
uint64(ctx.handle), uint64(ptr), uint64(len(buf)),
159-
uint64(ctx.c.freer), _UTF8)
154+
ctx.c.call("sqlite3_result_text_go",
155+
uint64(ctx.handle), uint64(ptr), uint64(len(buf)))
160156
}
161157

162158
// ResultPointer sets the result of the function to NULL, just like [Context.ResultNull],

embed/bcw2/bcw2.wasm

244 Bytes
Binary file not shown.

embed/exports.txt

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
11
aligned_alloc
2-
free
3-
malloc
4-
malloc_destructor
52
sqlite3_anycollseq_init
63
sqlite3_autovacuum_pages_go
74
sqlite3_backup_finish
85
sqlite3_backup_init
96
sqlite3_backup_pagecount
107
sqlite3_backup_remaining
118
sqlite3_backup_step
12-
sqlite3_bind_blob64
9+
sqlite3_bind_blob_go
1310
sqlite3_bind_double
1411
sqlite3_bind_int64
1512
sqlite3_bind_null
1613
sqlite3_bind_parameter_count
1714
sqlite3_bind_parameter_index
1815
sqlite3_bind_parameter_name
1916
sqlite3_bind_pointer_go
20-
sqlite3_bind_text64
17+
sqlite3_bind_text_go
2118
sqlite3_bind_value
2219
sqlite3_bind_zeroblob64
2320
sqlite3_blob_bytes
@@ -74,17 +71,20 @@ sqlite3_filename_database
7471
sqlite3_filename_journal
7572
sqlite3_filename_wal
7673
sqlite3_finalize
74+
sqlite3_free
7775
sqlite3_get_autocommit
7876
sqlite3_get_auxdata
7977
sqlite3_interrupt
8078
sqlite3_last_insert_rowid
8179
sqlite3_limit
80+
sqlite3_malloc64
8281
sqlite3_open_v2
8382
sqlite3_overload_function
8483
sqlite3_prepare_v3
8584
sqlite3_progress_handler_go
85+
sqlite3_realloc64
8686
sqlite3_reset
87-
sqlite3_result_blob64
87+
sqlite3_result_blob_go
8888
sqlite3_result_double
8989
sqlite3_result_error
9090
sqlite3_result_error_code
@@ -93,7 +93,7 @@ sqlite3_result_error_toobig
9393
sqlite3_result_int64
9494
sqlite3_result_null
9595
sqlite3_result_pointer_go
96-
sqlite3_result_text64
96+
sqlite3_result_text_go
9797
sqlite3_result_value
9898
sqlite3_result_zeroblob64
9999
sqlite3_rollback_hook_go

embed/sqlite3.wasm

244 Bytes
Binary file not shown.

go.work.sum

+1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
55
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
66
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
77
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
8+
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
89
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
910
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=

sqlite.go

+6-14
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ type sqlite struct {
8686
mask uint32
8787
}
8888
stack [9]uint64
89-
freer uint32
9089
}
9190

9291
func instantiateSQLite() (sqlt *sqlite, err error) {
@@ -102,14 +101,7 @@ func instantiateSQLite() (sqlt *sqlite, err error) {
102101
if err != nil {
103102
return nil, err
104103
}
105-
106-
global := sqlt.mod.ExportedGlobal("malloc_destructor")
107-
if global == nil {
108-
return nil, util.BadBinaryErr
109-
}
110-
111-
sqlt.freer = util.ReadUint32(sqlt.mod, uint32(global.Get()))
112-
if sqlt.freer == 0 {
104+
if sqlt.getfn("sqlite3_progress_handler_go") == nil {
113105
return nil, util.BadBinaryErr
114106
}
115107
return sqlt, nil
@@ -196,15 +188,15 @@ func (sqlt *sqlite) free(ptr uint32) {
196188
if ptr == 0 {
197189
return
198190
}
199-
sqlt.call("free", uint64(ptr))
191+
sqlt.call("sqlite3_free", uint64(ptr))
200192
}
201193

202194
func (sqlt *sqlite) new(size uint64) uint32 {
203-
if size > _MAX_ALLOCATION_SIZE {
204-
panic(util.OOMErr)
195+
if size == 0 {
196+
size = 1
205197
}
206-
ptr := uint32(sqlt.call("malloc", size))
207-
if ptr == 0 && size != 0 {
198+
ptr := uint32(sqlt.call("sqlite3_malloc64", size))
199+
if ptr == 0 {
208200
panic(util.OOMErr)
209201
}
210202
return ptr

sqlite3/bind.c

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <stdlib.h>
2+
3+
#include "sqlite3.h"
4+
5+
int sqlite3_bind_text_go(sqlite3_stmt* stmt, int i, const char* zData,
6+
sqlite3_uint64 nData) {
7+
return sqlite3_bind_text64(stmt, i, zData, nData, &sqlite3_free, SQLITE_UTF8);
8+
}
9+
10+
int sqlite3_bind_blob_go(sqlite3_stmt* stmt, int i, const char* zData,
11+
sqlite3_uint64 nData) {
12+
return sqlite3_bind_blob64(stmt, i, zData, nData, &sqlite3_free);
13+
}

sqlite3/main.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@
99
#include "ext/series.c"
1010
#include "ext/uint.c"
1111
// Bindings
12+
#include "bind.c"
1213
#include "column.c"
1314
#include "func.c"
1415
#include "hooks.c"
1516
#include "pointer.c"
17+
#include "result.c"
1618
#include "time.c"
1719
#include "vfs.c"
1820
#include "vtab.c"
1921

20-
sqlite3_destructor_type malloc_destructor = &free;
21-
2222
__attribute__((constructor)) void init() {
2323
sqlite3_initialize();
2424
sqlite3_auto_extension((void (*)(void))sqlite3_base_init);

sqlite3/result.c

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <stdlib.h>
2+
3+
#include "sqlite3.h"
4+
5+
void sqlite3_result_text_go(sqlite3_context* ctx, const char* zData,
6+
sqlite3_uint64 nData) {
7+
sqlite3_result_text64(ctx, zData, nData, &sqlite3_free, SQLITE_UTF8);
8+
}
9+
10+
void sqlite3_result_blob_go(sqlite3_context* ctx, const void* zData,
11+
sqlite3_uint64 nData) {
12+
sqlite3_result_blob64(ctx, zData, nData, &sqlite3_free);
13+
}

sqlite_test.go

+1-15
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package sqlite3
33
import (
44
"bytes"
55
"math"
6-
"os"
76
"testing"
87

98
"github.com/ncruces/go-sqlite3/internal/util"
@@ -39,7 +38,7 @@ func Test_sqlite_call_closed(t *testing.T) {
3938
sqlite.close()
4039

4140
defer func() { _ = recover() }()
42-
sqlite.call("free")
41+
sqlite.call("sqlite3_free")
4342
t.Error("want panic")
4443
}
4544

@@ -57,19 +56,6 @@ func Test_sqlite_new(t *testing.T) {
5756
sqlite.new(math.MaxUint32)
5857
t.Error("want panic")
5958
})
60-
61-
t.Run("_MAX_ALLOCATION_SIZE", func(t *testing.T) {
62-
if testing.Short() {
63-
t.Skip("skipping in short mode")
64-
}
65-
if os.Getenv("CI") != "" {
66-
t.Skip("skipping in CI")
67-
}
68-
defer func() { _ = recover() }()
69-
sqlite.new(_MAX_ALLOCATION_SIZE)
70-
sqlite.new(_MAX_ALLOCATION_SIZE)
71-
t.Error("want panic")
72-
})
7359
}
7460

7561
func Test_sqlite_newArena(t *testing.T) {

stmt.go

+8-12
Original file line numberDiff line numberDiff line change
@@ -246,10 +246,9 @@ func (s *Stmt) BindText(param int, value string) error {
246246
return TOOBIG
247247
}
248248
ptr := s.c.newString(value)
249-
r := s.c.call("sqlite3_bind_text64",
249+
r := s.c.call("sqlite3_bind_text_go",
250250
uint64(s.handle), uint64(param),
251-
uint64(ptr), uint64(len(value)),
252-
uint64(s.c.freer), _UTF8)
251+
uint64(ptr), uint64(len(value)))
253252
return s.c.error(r)
254253
}
255254

@@ -262,10 +261,9 @@ func (s *Stmt) BindRawText(param int, value []byte) error {
262261
return TOOBIG
263262
}
264263
ptr := s.c.newBytes(value)
265-
r := s.c.call("sqlite3_bind_text64",
264+
r := s.c.call("sqlite3_bind_text_go",
266265
uint64(s.handle), uint64(param),
267-
uint64(ptr), uint64(len(value)),
268-
uint64(s.c.freer), _UTF8)
266+
uint64(ptr), uint64(len(value)))
269267
return s.c.error(r)
270268
}
271269

@@ -279,10 +277,9 @@ func (s *Stmt) BindBlob(param int, value []byte) error {
279277
return TOOBIG
280278
}
281279
ptr := s.c.newBytes(value)
282-
r := s.c.call("sqlite3_bind_blob64",
280+
r := s.c.call("sqlite3_bind_blob_go",
283281
uint64(s.handle), uint64(param),
284-
uint64(ptr), uint64(len(value)),
285-
uint64(s.c.freer))
282+
uint64(ptr), uint64(len(value)))
286283
return s.c.error(r)
287284
}
288285

@@ -335,10 +332,9 @@ func (s *Stmt) bindRFC3339Nano(param int, value time.Time) error {
335332
buf := util.View(s.c.mod, ptr, maxlen)
336333
buf = value.AppendFormat(buf[:0], time.RFC3339Nano)
337334

338-
r := s.c.call("sqlite3_bind_text64",
335+
r := s.c.call("sqlite3_bind_text_go",
339336
uint64(s.handle), uint64(param),
340-
uint64(ptr), uint64(len(buf)),
341-
uint64(s.c.freer), _UTF8)
337+
uint64(ptr), uint64(len(buf)))
342338
return s.c.error(r)
343339
}
344340

vfs/vfs.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ func vfsFileControl(ctx context.Context, mod api.Module, pFile uint32, op _Fcntl
356356
out = err.Error()
357357
}
358358
if out != "" {
359-
fn := mod.ExportedFunction("malloc")
359+
fn := mod.ExportedFunction("sqlite3_malloc64")
360360
stack := [...]uint64{uint64(len(out) + 1)}
361361
if err := fn.CallWithStack(ctx, stack[:]); err != nil {
362362
panic(err)

0 commit comments

Comments
 (0)