ValueCreation.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #include "pocketpy/common/str.h"
  2. #include "pocketpy/common/vector.h"
  3. #include "pocketpy/pocketpy.h"
  4. #include "pocketpy/common/utils.h"
  5. #include "pocketpy/objects/object.h"
  6. #include "pocketpy/interpreter/vm.h"
  7. #include "pocketpy/compiler/compiler.h"
  8. void py_newint(py_OutRef out, py_i64 val) {
  9. out->type = tp_int;
  10. out->is_ptr = false;
  11. out->_i64 = val;
  12. }
  13. void py_newtrivial(py_OutRef out, py_Type type, void* data, int size) {
  14. out->type = type;
  15. out->is_ptr = false;
  16. assert(size <= 16);
  17. memcpy(&out->_chars, data, size);
  18. }
  19. void py_newfloat(py_OutRef out, py_f64 val) {
  20. out->type = tp_float;
  21. out->is_ptr = false;
  22. out->_f64 = val;
  23. }
  24. void py_newbool(py_OutRef out, bool val) {
  25. out->type = tp_bool;
  26. out->is_ptr = false;
  27. out->_bool = val;
  28. }
  29. void py_newstr(py_OutRef out, const char* data) { py_newstrv(out, (c11_sv){data, strlen(data)}); }
  30. char* py_newstrn(py_OutRef out, int size) {
  31. if(size < 16) {
  32. out->type = tp_str;
  33. out->is_ptr = false;
  34. c11_string* ud = (c11_string*)(&out->extra);
  35. c11_string__ctor3(ud, size);
  36. return ud->data;
  37. }
  38. ManagedHeap* heap = &pk_current_vm->heap;
  39. int total_size = sizeof(c11_string) + size + 1;
  40. PyObject* obj = ManagedHeap__gcnew(heap, tp_str, 0, total_size);
  41. c11_string* ud = PyObject__userdata(obj);
  42. c11_string__ctor3(ud, size);
  43. out->type = tp_str;
  44. out->is_ptr = true;
  45. out->_obj = obj;
  46. return ud->data;
  47. }
  48. void py_newstrv(py_OutRef out, c11_sv sv) {
  49. char* data = py_newstrn(out, sv.size);
  50. memcpy(data, sv.data, sv.size);
  51. }
  52. void py_newfstr(py_OutRef out, const char* fmt, ...) {
  53. c11_sbuf buf;
  54. c11_sbuf__ctor(&buf);
  55. va_list args;
  56. va_start(args, fmt);
  57. pk_vsprintf(&buf, fmt, args);
  58. va_end(args);
  59. c11_sbuf__py_submit(&buf, out);
  60. }
  61. unsigned char* py_newbytes(py_OutRef out, int size) {
  62. ManagedHeap* heap = &pk_current_vm->heap;
  63. // 4 bytes size + data
  64. PyObject* obj = ManagedHeap__gcnew(heap, tp_bytes, 0, sizeof(c11_bytes) + size);
  65. c11_bytes* ud = PyObject__userdata(obj);
  66. ud->size = size;
  67. out->type = tp_bytes;
  68. out->is_ptr = true;
  69. out->_obj = obj;
  70. return ud->data;
  71. }
  72. void py_newnone(py_OutRef out) {
  73. out->type = tp_NoneType;
  74. out->is_ptr = false;
  75. }
  76. void py_newnotimplemented(py_OutRef out) {
  77. out->type = tp_NotImplementedType;
  78. out->is_ptr = false;
  79. }
  80. void py_newellipsis(py_OutRef out) {
  81. out->type = tp_ellipsis;
  82. out->is_ptr = false;
  83. }
  84. void py_newnil(py_OutRef out) {
  85. out->type = tp_nil;
  86. out->is_ptr = false;
  87. }
  88. void py_newnativefunc(py_OutRef out, py_CFunction f) {
  89. out->type = tp_nativefunc;
  90. out->is_ptr = false;
  91. out->_cfunc = f;
  92. }
  93. py_Name py_newfunction(py_OutRef out,
  94. const char* sig,
  95. py_CFunction f,
  96. const char* docstring,
  97. int slots) {
  98. char buffer[256];
  99. snprintf(buffer, sizeof(buffer), "def %s: pass", sig);
  100. // fn(a, b, *c, d=1) -> None
  101. CodeObject code;
  102. SourceData_ source = SourceData__rcnew(buffer, "<bind>", EXEC_MODE, false);
  103. Error* err = pk_compile(source, &code);
  104. if(err || code.func_decls.length != 1) {
  105. c11__abort("py_newfunction(): invalid signature '%s'", sig);
  106. }
  107. FuncDecl_ decl = c11__getitem(FuncDecl_, &code.func_decls, 0);
  108. if(docstring) decl->docstring = c11_strdup(docstring);
  109. // construct the function
  110. Function* ud = py_newobject(out, tp_function, slots, sizeof(Function));
  111. Function__ctor(ud, decl, NULL, NULL);
  112. ud->cfunc = f;
  113. CodeObject__dtor(&code);
  114. PK_DECREF(source);
  115. assert(decl->rc.count == 1);
  116. py_Name decl_name = py_name(ud->decl->code.name->data);
  117. if(decl_name == __new__ || decl_name == __init__) {
  118. if(ud->decl->args.length == 0) {
  119. c11__abort("%s() should have at least one positional argument", py_name2str(decl_name));
  120. }
  121. }
  122. return decl_name;
  123. }
  124. void py_newboundmethod(py_OutRef out, py_Ref self, py_Ref func) {
  125. py_newobject(out, tp_boundmethod, 2, 0);
  126. py_setslot(out, 0, self);
  127. py_setslot(out, 1, func);
  128. }
  129. void* py_newobject(py_OutRef out, py_Type type, int slots, int udsize) {
  130. ManagedHeap* heap = &pk_current_vm->heap;
  131. PyObject* obj = ManagedHeap__gcnew(heap, type, slots, udsize);
  132. out->type = type;
  133. out->is_ptr = true;
  134. out->_obj = obj;
  135. return PyObject__userdata(obj);
  136. }