object.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /**
  2. ******************************************************************************
  3. * @file : object.cpp
  4. * @author : simon
  5. * @brief : None
  6. * @attention : None
  7. * @date : 2023/8/23
  8. ******************************************************************************
  9. */
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include "memory.h"
  13. #include "object.h"
  14. #include "table.h"
  15. #include "vm.h"
  16. static Obj *allocateObject(size_t size, ObjType type);
  17. static uint32_t hashString(const char *key, int length);
  18. #define ALLOCATE_OBJ(type, objectType) \
  19. (type *) allocateObject(sizeof(type), objectType)
  20. static ObjString *allocateString(char *chars, int length,
  21. uint32_t hash) {
  22. ObjString *string = ALLOCATE_OBJ(ObjString, OBJ_STRING);
  23. string->length = length;
  24. string->chars = chars;
  25. string->hash = hash;
  26. tableSet(&vm.strings, string, NIL_VAL);
  27. return string;
  28. }
  29. ObjString *copyString(const char *chars, int length) {
  30. uint32_t hash = hashString(chars, length);
  31. ObjString *interned = tableFindString(&vm.strings, chars, length, hash);
  32. if (interned != NULL) return interned;
  33. char *heapChars = ALLOCATE(char, length + 1);
  34. memcpy(heapChars, chars, length);
  35. heapChars[length] = '\0';
  36. return allocateString(heapChars, length, hash);
  37. }
  38. static void printFunction(ObjFunction *function) {
  39. if (function->name == NULL) {
  40. printf("<script>");
  41. return;
  42. }
  43. printf("<fn %s>", function->name->chars);
  44. }
  45. /// 打印对象
  46. /// \param value
  47. void printObject(Value value) {
  48. switch (OBJ_TYPE(value)) {
  49. case OBJ_NATIVE:
  50. printf("<native fn>");
  51. break;
  52. case OBJ_FUNCTION:
  53. printFunction(AS_FUNCTION(value));
  54. break;
  55. case OBJ_STRING:
  56. printf("%s", AS_CSTRING(value));
  57. break;
  58. }
  59. }
  60. ObjFunction *newFunction() {
  61. ObjFunction *function = ALLOCATE_OBJ(ObjFunction, OBJ_FUNCTION);
  62. function->arity = 0;
  63. function->name = NULL;
  64. initChunk(&function->chunk);
  65. return function;
  66. }
  67. ObjString *takeString(char *chars, int length) {
  68. uint32_t hash = hashString(chars, length);
  69. ObjString *interned = tableFindString(&vm.strings, chars, length, hash);
  70. if (interned != NULL) {
  71. FREE_ARRAY(char, chars, length + 1);
  72. return interned;
  73. }
  74. return allocateString(chars, length, hash);
  75. }
  76. ObjNative *newNative(NativeFn function) {
  77. ObjNative *native = ALLOCATE_OBJ(ObjNative, OBJ_NATIVE);
  78. native->function = function;
  79. return native;
  80. }
  81. /// 分配内在空间
  82. /// \param size 空间大小
  83. /// \param type 对象类型
  84. /// \return Obj*
  85. static Obj *allocateObject(size_t size, ObjType type) {
  86. Obj *object = (Obj *) reallocate(NULL, 0, size);
  87. object->type = type;
  88. object->next = vm.objects;
  89. vm.objects = object;
  90. return object;
  91. }
  92. /// Hash 函数 -- 使用 FNV-1a 算法
  93. /// \param key
  94. /// \param length
  95. /// \return
  96. static uint32_t hashString(const char *key, int length) {
  97. uint32_t hash = 2166136261u;
  98. for (int i = 0; i < length; i++) {
  99. hash ^= (uint8_t) key[i];
  100. hash *= 16777619;
  101. }
  102. return hash;
  103. }