Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

82 wiersze
2.0 KiB

  1. // This file is part of Jiffy released under the MIT license.
  2. // See the LICENSE file for more information.
  3. #include <assert.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include "jiffy.h"
  7. #include "termstack.h"
  8. inline void
  9. termstack_push(TermStack *stack, ERL_NIF_TERM term)
  10. {
  11. if(stack->top == stack->size) {
  12. size_t new_size = stack->size * 2;
  13. if (stack->elements == &stack->__default_elements[0]) {
  14. stack->elements = enif_alloc(new_size * sizeof(ERL_NIF_TERM));
  15. } else {
  16. stack->elements = enif_realloc(stack->elements,
  17. new_size * sizeof(ERL_NIF_TERM));
  18. }
  19. stack->size = new_size;
  20. }
  21. assert(stack->top < stack->size);
  22. stack->elements[stack->top++] = term;
  23. }
  24. inline ERL_NIF_TERM
  25. termstack_pop(TermStack *stack)
  26. {
  27. assert(stack->top > 0 && stack->top <= stack->size);
  28. return stack->elements[--stack->top];
  29. }
  30. inline int
  31. termstack_is_empty(TermStack *stack)
  32. {
  33. return stack->top == 0;
  34. }
  35. ERL_NIF_TERM termstack_save(ErlNifEnv *env, TermStack *stack)
  36. {
  37. return enif_make_tuple_from_array(env, stack->elements, stack->top);
  38. }
  39. int termstack_restore(ErlNifEnv *env, ERL_NIF_TERM from, TermStack *stack)
  40. {
  41. const ERL_NIF_TERM *elements;
  42. int arity;
  43. if(enif_get_tuple(env, from, &arity, &elements)) {
  44. stack->top = arity;
  45. if(arity <= SMALL_TERMSTACK_SIZE) {
  46. stack->elements = &stack->__default_elements[0];
  47. stack->size = SMALL_TERMSTACK_SIZE;
  48. } else {
  49. stack->size = arity * 2;
  50. stack->elements = enif_alloc(stack->size * sizeof(ERL_NIF_TERM));
  51. if(!stack->elements) {
  52. return 0;
  53. }
  54. }
  55. memcpy(stack->elements, elements, arity * sizeof(ERL_NIF_TERM));
  56. return 1;
  57. }
  58. return 0;
  59. }
  60. void
  61. termstack_destroy(TermStack *stack)
  62. {
  63. if(stack->elements != &stack->__default_elements[0]) {
  64. enif_free(stack->elements);
  65. }
  66. }