void pic_close(pic_state *pic) { pic_allocf allocf = pic->allocf; /* clear out root objects */ pic->cxt = &pic->default_cxt; pic->ai = 0; pic->halt = pic_invalid_value(pic); pic->globals = pic_invalid_value(pic); pic->features = pic_invalid_value(pic); pic->dyn_env = pic_invalid_value(pic); assert(pic->cxt->ai == 0); assert(pic->cxt->pc == NULL); assert(pic->cxt->fp == NULL); assert(pic->cxt->sp == NULL); assert(pic->cxt->irep == NULL); assert(pic->cxt->prev == NULL); /* free all heap objects */ pic_gc(pic); /* free heaps */ pic_heap_close(pic, pic->heap); /* free global stacks */ kh_destroy(oblist, &pic->oblist); /* free GC arena */ allocf(pic->userdata, pic->arena, 0); allocf(pic->userdata, pic, 0); }
static void *resizebox (lua_State *L, int idx, size_t newsize) { void *ud; lua_Alloc allocf = lua_getallocf(L, &ud); UBox *box = (UBox *)lua_touserdata(L, idx); void *temp = allocf(ud, box->box, box->bsize, newsize); if (temp == NULL && newsize > 0) /* allocation error? */ luaL_error(L, "not enough memory for buffer allocation"); box->box = temp; box->bsize = newsize; return temp; }
int main(void) { int width = 2560; int height = 1440; int i; int frames = 200; char fpath[100]; char **grid; /* init */ grid = allocf(width, height); double scale = 50.0; double offset = 1.0; double offset2 = 1.0; double offset3 = 1.0; double offset4 = 1.0; for (i = 0; i < frames; i++) { snprintf(fpath, 100, "plt_pbm_%05d.pbm", i); FILE *pbmf = fopen(fpath, "w"); clearf(grid, width, height); draw_sin(grid, width, height, scale, offset); draw_cos(grid, width, height, scale, offset2); draw_sin(grid, width, height, scale, offset3); draw_cos(grid, width, height, scale, offset4); offset += 0.09; offset2 += 0.11; offset3 += 0.13; offset4 += 0.16; pbmgrid(grid, width, height, pbmf); fclose(pbmf); fprintf(stderr, "i: %d\n", i); } /* clean up */ freef(grid, width); return 0; }
/* Takes an hmap, * converts it into nvars / vars / values / types, * calls the corresponding `set` C callback. */ static int api_set( lua_State *L) { // Initial stack state: ctx, hmap ExtVars_Mod_t *mod = checkmod(L); int n_entries = 0, n_ints = 0, n_numbers = 0; int val_false = 0, val_true = 1; luaL_checktype( L, 2, LUA_TTABLE); /* First pass: count entries and numbers, to determine how much malloc space is needed. */ lua_pushnil( L); // ctx, hmap, key==nil while( lua_next( L, -2)) { // ctx, hmap, key, value n_entries ++; if( lua_type( L, -1) == LUA_TNUMBER) { lua_Number n = lua_tonumber( L, -1); if( (lua_Number) (int) n == n) n_ints ++; else n_numbers ++; } lua_pop( L, 1); // ctx, hmap, key } // ctx, hmap /* Allocate all tables as a single memory chunk. * By using Lua's allocator, we avoid an unnecessary dependency to malloc(). */ int chunk_size = sizeof( int) * n_entries + /* variable ids */ sizeof( void*) * n_entries + /* values */ sizeof( ExtVars_type_t) * n_entries + /* types */ sizeof( int) * n_ints + /* ints */ sizeof( lua_Number) * n_numbers; /* doubles */ #ifdef NOMALLOC void *alloc_ctx; lua_Alloc allocf = lua_getallocf( L, & alloc_ctx); void *chunk = allocf( alloc_ctx, NULL, 0, chunk_size); #else void *chunk = malloc( chunk_size); #endif if( ! chunk) RETURN_ERROR_STRING( "Not enough memory"); int *variables = (int*) chunk; void **values = (void**) (variables + n_entries); ExtVars_type_t *types = (ExtVars_type_t*) (values + n_entries); int *ints = (int*) (types + n_entries); lua_Number *numbers = (lua_Number*) (ints + n_ints); int i=0, i_int=0, i_number=0; /* 2nd pass: actually fill the tables for the set callback. */ lua_pushnil( L); // ctx, hmap, key==nil while( lua_next( L, -2)) { // ctx, hmap, key, value /* Fill the variable id */ int var = lua_tonumber( L, -2); if( ! var) RETURN_ERROR_STRING( "Not a numeric variable name"); variables[i] = var; /* Fill type and value, allocate number value if necessary */ int ltype = lua_type( L, -1); if( isniltoken( L, -1)) { types[i] = EXTVARS_TYPE_NIL; } else if( ltype == LUA_TNUMBER) { lua_Number n = lua_tonumber( L, -1); if( (lua_Number) (int) n == n) { ints[i_int] = (int) n; types[i] = EXTVARS_TYPE_INT; values[i] = ints + i_int; i_int++; } else { numbers[i_number] = (lua_Number) n; types[i] = EXTVARS_TYPE_DOUBLE; values[i] = numbers + i_number; i_number++; } } else if( ltype == LUA_TSTRING) { types[i] = EXTVARS_TYPE_STR; values[i] = (void *) lua_tostring( L, -1); } else if( ltype == LUA_TBOOLEAN) { types[i] = EXTVARS_TYPE_BOOL; values[i] = lua_toboolean( L, -1) ? & val_true : & val_false; } else { RETURN_ERROR_STRING( "Unsupported Lua type"); } lua_pop( L, 1); // ctx, hmap, key i++; } // ctx, hmap swi_status_t r = mod->set(n_entries, variables, values, types); /* Lua-allocated chunks are freed by reallocating them to a 0 size. */ #ifdef NOMALLOC allocf( alloc_ctx, chunk, chunk_size, 0); #else free( chunk); #endif if( r) RETURN_ERROR_NUMBER( "set", r); else RETURN_OK; }
pic_state * pic_open(pic_allocf allocf, void *userdata) { pic_state *pic; pic = allocf(userdata, NULL, sizeof(pic_state)); if (! pic) { goto EXIT_PIC; } /* allocator */ pic->allocf = allocf; /* user data */ pic->userdata = userdata; /* context */ pic->default_cxt.ai = 0; pic->default_cxt.pc = NULL; pic->default_cxt.fp = NULL; pic->default_cxt.sp = NULL; pic->default_cxt.irep = NULL; pic->default_cxt.prev = NULL; pic->cxt = &pic->default_cxt; /* arena */ pic->arena = allocf(userdata, NULL, PIC_ARENA_SIZE * sizeof(struct object *)); pic->arena_size = PIC_ARENA_SIZE; pic->ai = 0; if (! pic->arena) { goto EXIT_ARENA; } /* turn off GC */ pic->gc_enable = false; /* memory heap */ pic->heap = pic_heap_open(pic); /* symbol table */ kh_init(oblist, &pic->oblist); /* global variables */ pic->globals = pic_make_dict(pic); /* features */ pic->features = pic_nil_value(pic); /* dynamic environment */ pic->dyn_env = pic_list(pic, 1, pic_make_weak(pic)); /* top continuation */ { static const code_t halt_code[] = { 0x00 }; struct irep *irep; struct proc *proc; irep = (struct irep *)pic_obj_alloc(pic, PIC_TYPE_IREP); irep->argc = 1; irep->flags = IREP_CODE_STATIC; irep->frame_size = 1; irep->irepc = 0; irep->objc = 0; irep->irep = NULL; irep->obj = NULL; irep->code = halt_code; irep->codec = sizeof halt_code / sizeof halt_code[0]; proc = (struct proc *)pic_obj_alloc(pic, PIC_TYPE_PROC_IREP); proc->u.irep = irep; proc->env = NULL; pic->halt = obj_value(pic, proc); } /* panic handler */ pic->panicf = NULL; /* turn on GC */ pic->gc_enable = true; pic_init_core(pic); pic_leave(pic, 0); /* empty arena */ return pic; EXIT_ARENA: allocf(userdata, pic, 0); EXIT_PIC: return NULL; }