Skip to content

Commit b98d707

Browse files
committed
Updated memory code. Preliminary implementation of the db global object.
1 parent 0f21f19 commit b98d707

File tree

2 files changed

+95
-29
lines changed

2 files changed

+95
-29
lines changed

src/sqlitejs.c

Lines changed: 91 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ typedef struct {
4545
JSValue inverse_func; // to release (window functions only)
4646
} functionjs_context;
4747

48+
static char *sqlite_strdup (const char *str);
49+
static bool js_global_init (JSContext *ctx);
50+
4851
#define SQLITEJS_VERSION "1.0.0"
4952
static char gversion[128];
5053

@@ -54,8 +57,9 @@ static globaljs_context *globaljs_init (sqlite3 *db) {
5457
JSRuntime *rt = NULL;
5558
JSContext *ctx = NULL;
5659

57-
globaljs_context *js = (globaljs_context *)calloc(1, sizeof(globaljs_context));
60+
globaljs_context *js = (globaljs_context *)sqlite3_malloc(sizeof(globaljs_context));
5861
if (!js) return NULL;
62+
bzero(js, sizeof(globaljs_context));
5963

6064
rt = JS_NewRuntime();
6165
if (!rt) goto abort_init;
@@ -66,9 +70,8 @@ static globaljs_context *globaljs_init (sqlite3 *db) {
6670
ctx = JS_NewContext(rt);
6771
if (!ctx) goto abort_init;
6872

69-
JSValue global = JS_GetGlobalObject(ctx);
70-
// add any global objects or functions here
71-
JS_FreeValue(ctx, global);
73+
JS_SetContextOpaque(ctx, db);
74+
js_global_init(ctx);
7275

7376
js->db = db;
7477
js->runtime = rt;
@@ -78,7 +81,7 @@ static globaljs_context *globaljs_init (sqlite3 *db) {
7881
abort_init:
7982
if (rt) JS_FreeRuntime(rt);
8083
if (ctx) JS_FreeContext(ctx);
81-
if (js) free(js);
84+
if (js) sqlite3_free(js);
8285
return NULL;
8386
}
8487

@@ -87,7 +90,7 @@ static void globaljs_free (globaljs_context *js) {
8790

8891
if (js->runtime) JS_FreeRuntime(js->runtime);
8992
if (js->context) JS_FreeContext(js->context);
90-
free(js);
93+
sqlite3_free(js);
9194
}
9295

9396
static functionjs_context *functionjs_init (globaljs_context *jsctx, const char *init_code, const char *step_code, const char *final_code, const char *value_code, const char *inverse_code) {
@@ -99,31 +102,32 @@ static functionjs_context *functionjs_init (globaljs_context *jsctx, const char
99102
char *value_code_copy = NULL;
100103
char *inverse_code_copy = NULL;
101104

102-
fctx = (functionjs_context *)calloc(1, sizeof(functionjs_context));
105+
fctx = (functionjs_context *)sqlite3_malloc(sizeof(functionjs_context));
103106
if (!fctx) goto cleanup;
107+
bzero(fctx, sizeof(functionjs_context));
104108

105109
if (init_code) {
106-
init_code_copy = strdup(init_code);
110+
init_code_copy = sqlite_strdup(init_code);
107111
if (!init_code_copy) goto cleanup;
108112
}
109113

110114
if (step_code) {
111-
step_code_copy = strdup(step_code);
115+
step_code_copy = sqlite_strdup(step_code);
112116
if (!step_code_copy) goto cleanup;
113117
}
114118

115119
if (final_code) {
116-
final_code_copy = strdup(final_code);
120+
final_code_copy = sqlite_strdup(final_code);
117121
if (!final_code_copy) goto cleanup;
118122
}
119123

120124
if (value_code) {
121-
value_code_copy = strdup(value_code);
125+
value_code_copy = sqlite_strdup(value_code);
122126
if (!value_code_copy) goto cleanup;
123127
}
124128

125129
if (inverse_code) {
126-
inverse_code_copy = strdup(inverse_code);
130+
inverse_code_copy = sqlite_strdup(inverse_code);
127131
if (!inverse_code_copy) goto cleanup;
128132
}
129133

@@ -145,12 +149,12 @@ static functionjs_context *functionjs_init (globaljs_context *jsctx, const char
145149
return fctx;
146150

147151
cleanup:
148-
if (init_code_copy) free(init_code_copy);
149-
if (step_code_copy) free(step_code_copy);
150-
if (final_code_copy) free(final_code_copy);
151-
if (value_code_copy) free(value_code_copy);
152-
if (inverse_code_copy) free(inverse_code_copy);
153-
if (fctx) free(fctx);
152+
if (init_code_copy) sqlite3_free(init_code_copy);
153+
if (step_code_copy) sqlite3_free(step_code_copy);
154+
if (final_code_copy) sqlite3_free(final_code_copy);
155+
if (value_code_copy) sqlite3_free(value_code_copy);
156+
if (inverse_code_copy) sqlite3_free(inverse_code_copy);
157+
if (fctx) sqlite3_free(fctx);
154158
return NULL;
155159
}
156160

@@ -172,17 +176,15 @@ static void functionjs_free (functionjs_context *fctx, bool complete) {
172176
fctx->agg_ctx = NULL;
173177

174178
if (complete) {
175-
if (fctx->init_code) free((void *)fctx->init_code);
176-
if (fctx->step_code) free((void *)fctx->step_code);
177-
if (fctx->final_code) free((void *)fctx->final_code);
178-
if (fctx->value_code) free((void *)fctx->value_code);
179-
if (fctx->inverse_code) free((void *)fctx->inverse_code);
180-
free(fctx);
179+
if (fctx->init_code) sqlite3_free((void *)fctx->init_code);
180+
if (fctx->step_code) sqlite3_free((void *)fctx->step_code);
181+
if (fctx->final_code) sqlite3_free((void *)fctx->final_code);
182+
if (fctx->value_code) sqlite3_free((void *)fctx->value_code);
183+
if (fctx->inverse_code) sqlite3_free((void *)fctx->inverse_code);
184+
sqlite3_free(fctx);
181185
}
182186
}
183187

184-
// MARK: - Utils -
185-
186188
static void compute_version_string (void) {
187189
const char *s1 = SQLITEJS_VERSION;
188190
const char *s2 = JS_GetVersion();
@@ -230,6 +232,52 @@ static void compute_version_string (void) {
230232
}
231233
}
232234

235+
// MARK: - Utils -
236+
237+
static JSValue js_sqlite_exec (JSContext *ctx, sqlite3 *db, const char *sql) {
238+
//int rc = sqlite3_prepare_v2(db, sql, -1, sqlite3_stmt **ppStmt, const char **pzTail)
239+
return JS_NewNumber(ctx, 3.1415);
240+
}
241+
242+
static JSValue js_dbfunc_exec (JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
243+
// check if we have at least one argument
244+
if (argc < 1) return JS_EXCEPTION;
245+
246+
// get the SQL string from the first argument
247+
size_t len;
248+
const char *sql = JS_ToCStringLen(ctx, &len, argv[0]);
249+
if (!sql) return JS_EXCEPTION;
250+
251+
// perform statement
252+
sqlite3 *db = (sqlite3 *)JS_GetContextOpaque(ctx);
253+
JSValue value = js_sqlite_exec(ctx, db, sql);
254+
255+
// free the string when done
256+
JS_FreeCString(ctx, sql);
257+
258+
return value;
259+
}
260+
261+
static bool js_global_init (JSContext *ctx) {
262+
// add any global objects or functions here
263+
JSValue global_obj = JS_GetGlobalObject(ctx);
264+
265+
// create a new db object
266+
JSValue db_obj = JS_NewObject(ctx);
267+
268+
// add the exec function to the db object
269+
JS_SetPropertyStr(ctx, db_obj, "exec", JS_NewCFunction(ctx, js_dbfunc_exec, "exec", 1));
270+
271+
// set the db object as a property of the global object
272+
JS_SetPropertyStr(ctx, global_obj, "db", db_obj);
273+
274+
// release the global object reference
275+
JS_FreeValue(ctx, global_obj);
276+
277+
// we don't free db_obj because it's now owned by the global object
278+
return true;
279+
}
280+
233281
static void js_dump_globals (JSContext *ctx) {
234282
JSValue global_obj = JS_GetGlobalObject(ctx);
235283
JSPropertyEnum *props;
@@ -360,6 +408,10 @@ static bool js_setup_aggregate (sqlite3_context *context, globaljs_context *js,
360408
return false;
361409
}
362410

411+
// setup global object
412+
JS_SetContextOpaque(ctx, sqlite3_context_db_handle(context));
413+
js_global_init(ctx);
414+
363415
// init code is optional
364416
if (init_code) {
365417
JSValue result = JS_Eval(ctx, init_code, strlen(init_code), NULL, JS_EVAL_TYPE_GLOBAL);
@@ -455,6 +507,16 @@ static const char *sqlite_value_text (sqlite3_value *value) {
455507
return (const char *)sqlite3_value_text(value);
456508
}
457509

510+
static char *sqlite_strdup (const char *str) {
511+
if (!str) return NULL;
512+
513+
size_t len = strlen(str) + 1;
514+
char *result = (char*)sqlite3_malloc((int)len);
515+
if (result) memcpy(result, str, len);
516+
517+
return result;
518+
}
519+
458520
// MARK: - Execution -
459521

460522
static void js_execute_commong (sqlite3_context *context, int nvalues, sqlite3_value **values, JSValue func, JSValue this_obj, bool return_value) {
@@ -710,7 +772,7 @@ static void js_load_file (sqlite3_context *context, int argc, sqlite3_value **ar
710772
size_t length = (size_t)ftell(f);
711773
fseek(f, 0, SEEK_SET);
712774

713-
char *buffer = malloc(length);
775+
char *buffer = (char *)sqlite3_malloc((int)length);
714776
if (!buffer) {
715777
fclose(f);
716778
sqlite3_result_error_nomem(context);
@@ -719,10 +781,10 @@ static void js_load_file (sqlite3_context *context, int argc, sqlite3_value **ar
719781

720782
size_t nread = fread(buffer, length, 1, f);
721783
if (nread == length) {
722-
(is_blob) ? sqlite3_result_blob(context, buffer, (int)length, free) : sqlite3_result_text(context, buffer, (int)length, free);
784+
(is_blob) ? sqlite3_result_blob(context, buffer, (int)length, sqlite3_free) : sqlite3_result_text(context, buffer, (int)length, sqlite3_free);
723785
} else {
724786
sqlite3_result_error(context, "Unable to correctly read the file", -1);
725-
if (buffer) free(buffer);
787+
if (buffer) sqlite3_free(buffer);
726788
}
727789

728790
fclose(f);

test/sqlitejs/main.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ int main (void) {
3535

3636
printf("SQLite-JS version: %s\n\n", sqlitejs_version());
3737

38+
// db object
39+
printf("Testing db\n");
40+
rc = db_exec(db, "SELECT js_eval('db.exec(''SELECT 134;'');');");
41+
3842
// context
3943
printf("Testing context\n");
4044
rc = db_exec(db, "SELECT js_eval('x = 100;');");

0 commit comments

Comments
 (0)