From fe9025e471578cbdef8ee21e0f9dc51f0f2107ce Mon Sep 17 00:00:00 2001 From: Adam Chlipala Date: Thu, 11 Sep 2008 12:40:40 -0400 Subject: Region memory allocation for query parameters --- include/urweb.h | 3 +++ src/c/urweb.c | 31 +++++++++++++++++++++++++++++++ src/cjr_print.sml | 6 ++++-- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/include/urweb.h b/include/urweb.h index c05b49d5..2d201125 100644 --- a/include/urweb.h +++ b/include/urweb.h @@ -21,6 +21,9 @@ __attribute__((noreturn)) void uw_error(uw_context, failure_kind, const char *fm char *uw_error_message(uw_context); void *uw_malloc(uw_context, size_t); +void uw_begin_region(uw_context); +void uw_end_region(uw_context); + int uw_send(uw_context, int sock); void uw_set_input(uw_context, char *name, char *value); diff --git a/src/c/urweb.c b/src/c/urweb.c index d8d1ab18..7c7b057f 100644 --- a/src/c/urweb.c +++ b/src/c/urweb.c @@ -11,6 +11,10 @@ uw_unit uw_unit_v = {}; #define ERROR_BUF_LEN 1024 +typedef struct regions { + struct regions *next; +} regions; + struct uw_context { char *page, *page_front, *page_back; char *heap, *heap_front, *heap_back; @@ -20,6 +24,8 @@ struct uw_context { jmp_buf jmp_buf; + regions *regions; + char error_message[ERROR_BUF_LEN]; }; @@ -38,6 +44,8 @@ uw_context uw_init(size_t page_len, size_t heap_len) { ctx->db = NULL; + ctx->regions = NULL; + ctx->error_message[0] = 0; return ctx; @@ -61,6 +69,7 @@ void uw_free(uw_context ctx) { void uw_reset_keep_request(uw_context ctx) { ctx->page_front = ctx->page; ctx->heap_front = ctx->heap; + ctx->regions = NULL; ctx->error_message[0] = 0; } @@ -68,6 +77,7 @@ void uw_reset_keep_request(uw_context ctx) { void uw_reset_keep_error_message(uw_context ctx) { ctx->page_front = ctx->page; ctx->heap_front = ctx->heap; + ctx->regions = NULL; } void uw_reset(uw_context ctx) { @@ -176,6 +186,27 @@ void *uw_malloc(uw_context ctx, size_t len) { return result; } +void uw_begin_region(uw_context ctx) { + regions *r = (regions *) ctx->heap_front; + + uw_check_heap(ctx, sizeof(regions)); + + ctx->heap_front += sizeof(regions); + + r->next = ctx->regions; + ctx->regions = r; +} + +void uw_end_region(uw_context ctx) { + regions *r = ctx->regions; + + if (r == NULL) + uw_error(ctx, FATAL, "Region stack underflow"); + + ctx->heap_front = (char *) r; + ctx->regions = r->next; +} + int uw_really_send(int sock, const void *buf, ssize_t len) { while (len > 0) { ssize_t n = send(sock, buf, len, 0); diff --git a/src/cjr_print.sml b/src/cjr_print.sml index 73a4f0fc..8bdb1ba5 100644 --- a/src/cjr_print.sml +++ b/src/cjr_print.sml @@ -712,7 +712,7 @@ fun p_exp' par env (e, loc) = val outputs = exps @ tables in - box [string "({", + box [string "(uw_begin_region(ctx), ({", newline, string "PGconn *conn = uw_get_db(ctx);", newline, @@ -791,6 +791,8 @@ fun p_exp' par env (e, loc) = newline, newline, + string "uw_end_region(ctx);", + newline, string "n = PQntuples(res);", newline, string "for (i = 0; i < n; ++i) {", @@ -851,7 +853,7 @@ fun p_exp' par env (e, loc) = newline, string "acc;", newline, - string "})"] + string "}))"] end | EDml {dml, prepared} => -- cgit v1.2.3