// This file is part of Jiffy released under the MIT license. // See the LICENSE file for more information. #include #include #include #include "jiffy.h" #include "termstack.h" ERL_NIF_TERM termstack_save(ErlNifEnv* env, TermStack* stack) { return enif_make_tuple_from_array(env, stack->elements, stack->top); } int termstack_restore(ErlNifEnv* env, ERL_NIF_TERM from, TermStack* stack) { const ERL_NIF_TERM* elements; int arity; if(enif_get_tuple(env, from, &arity, &elements)) { stack->top = arity; if(arity <= SMALL_TERMSTACK_SIZE) { stack->elements = &stack->__default_elements[0]; stack->size = SMALL_TERMSTACK_SIZE; } else { stack->size = arity * 2; stack->elements = enif_alloc(stack->size * sizeof(ERL_NIF_TERM)); if(!stack->elements) { return 0; } } memcpy(stack->elements, elements, arity * sizeof(ERL_NIF_TERM)); return 1; } return 0; } void termstack_destroy(TermStack* stack) { if(stack->elements != &stack->__default_elements[0]) { enif_free(stack->elements); } } inline void termstack_push(TermStack* stack, ERL_NIF_TERM term) { if(stack->top == stack->size) { size_t new_size = stack->size * 2; size_t num_bytes = new_size * sizeof(ERL_NIF_TERM); if (stack->elements == &stack->__default_elements[0]) { ERL_NIF_TERM* elems = enif_alloc(num_bytes); memcpy(elems, stack->elements, num_bytes); stack->elements = elems; } else { stack->elements = enif_realloc(stack->elements, num_bytes); } stack->size = new_size; } assert(stack->top < stack->size); stack->elements[stack->top++] = term; } inline ERL_NIF_TERM termstack_pop(TermStack* stack) { assert(stack->top > 0 && stack->top <= stack->size); return stack->elements[--stack->top]; } inline int termstack_is_empty(TermStack* stack) { return stack->top == 0; }