10 const char *
string = ((
KrkNative*)AS_OBJECT(func))->name;
11 if (!
string)
return OBJECT_VAL(S(
"<unnamed>"));
12 size_t len = strlen(
string);
24 if (_self->
obj.
flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) {
32 if (_self->
obj.
flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS) {
40 #define IS_method(o) IS_BOUND_METHOD(o)
41 #define IS_function(o) (IS_CLOSURE(o)|IS_NATIVE(o))
43 #define AS_method(o) AS_BOUND_METHOD(o)
44 #define AS_function(o) (o)
46 #define CURRENT_NAME self
47 #define CURRENT_CTYPE KrkValue
49 KRK_StaticMethod(
function,__new__) {
50 METHOD_TAKES_EXACTLY(3);
53 if (!IS_INSTANCE(argv[3]))
54 return TYPE_ERROR(dict or instance
object,argv[3]);
56 if (IS_CLOSURE(argv[2]) && AS_CLOSURE(argv[2])->upvalueCount == code->upvalueCount) {
65 memcpy(AS_CLOSURE(
krk_peek(0))->upvalues, AS_CLOSURE(argv[2])->upvalues,
68 }
else if (IS_TUPLE(argv[2]) && AS_TUPLE(argv[2])->values.count == code->upvalueCount) {
75 for (
size_t i = 0; i < code->upvalueCount; ++i) {
77 AS_CLOSURE(
krk_peek(0))->upvalues[i]->closed = AS_TUPLE(argv[2])->values.values[i];
82 return TYPE_ERROR(managed
function with equal upvalue count or tuple,argv[2]);
85 KRK_Method(
function,__doc__) {
86 ATTRIBUTE_NOT_ASSIGNABLE();
88 if (IS_NATIVE(
self) && AS_NATIVE(
self)->doc) {
89 return OBJECT_VAL(
krk_copyString(AS_NATIVE(
self)->doc, strlen(AS_NATIVE(
self)->doc)));
90 }
else if (IS_CLOSURE(
self) && AS_CLOSURE(
self)->function->docstring) {
91 return OBJECT_VAL(AS_CLOSURE(
self)->function->docstring);
97 KRK_Method(
function,__name__) {
98 ATTRIBUTE_NOT_ASSIGNABLE();
100 if (IS_NATIVE(
self)) {
101 return nativeFunctionName(
self);
102 }
else if (IS_CLOSURE(
self) && AS_CLOSURE(
self)->function->name) {
103 return OBJECT_VAL(AS_CLOSURE(
self)->function->name);
106 return OBJECT_VAL(S(
""));
109 KRK_Method(
function,__qualname__) {
110 ATTRIBUTE_NOT_ASSIGNABLE();
112 if (IS_CLOSURE(
self) && AS_CLOSURE(
self)->function->qualname) {
113 return OBJECT_VAL(AS_CLOSURE(
self)->function->qualname);
119 KRK_Method(
function,__globals__) {
120 ATTRIBUTE_NOT_ASSIGNABLE();
122 if (IS_CLOSURE(
self)) {
123 return AS_CLOSURE(
self)->globalsOwner;
129 KRK_Method(
function,_ip_to_line) {
130 METHOD_TAKES_EXACTLY(1);
131 CHECK_ARG(1,
int,krk_integer_type,ip);
133 if (!IS_CLOSURE(
self))
return NONE_VAL();
135 size_t line =
krk_lineNumber(&AS_CLOSURE(
self)->function->chunk, ip);
137 return INTEGER_VAL(line);
140 KRK_Method(
function,__repr__) {
144 KrkValue name = FUNC_NAME(
function,__qualname__)(1,&
self,0);
146 name = FUNC_NAME(
function,__name__)(1,&
self,0);
149 if (!IS_STRING(name)) name = OBJECT_VAL(S(
"<unnamed>"));
154 krk_pushStringBuilderFormat(&sb,
"<function %S at %p>", AS_STRING(name), (
void*)AS_OBJECT(
self));
161 KRK_Method(
function,__file__) {
162 ATTRIBUTE_NOT_ASSIGNABLE();
164 if (IS_NATIVE(
self))
return OBJECT_VAL(S(
"<builtin>"));
166 return AS_CLOSURE(
self)->function->chunk.filename ?
167 OBJECT_VAL(AS_CLOSURE(
self)->function->chunk.filename) :
171 KRK_Method(
function,__args__) {
172 ATTRIBUTE_NOT_ASSIGNABLE();
173 if (!IS_CLOSURE(
self))
return OBJECT_VAL(
krk_newTuple(0));
174 KrkTuple * tuple = functionArgs(AS_CLOSURE(
self)->
function);
175 return OBJECT_VAL(tuple);
178 KRK_Method(
function,__annotations__) {
179 ATTRIBUTE_NOT_ASSIGNABLE();
180 if (!IS_CLOSURE(
self))
return NONE_VAL();
181 return AS_CLOSURE(
self)->annotations;
184 KRK_Method(
function,__code__) {
185 ATTRIBUTE_NOT_ASSIGNABLE();
186 if (!IS_CLOSURE(
self))
return NONE_VAL();
187 return OBJECT_VAL(AS_CLOSURE(
self)->
function);
190 KRK_Method(
function,__closure__) {
191 ATTRIBUTE_NOT_ASSIGNABLE();
192 if (!IS_CLOSURE(
self)) {
196 size_t cnt = AS_CLOSURE(
self)->upvalueCount;
199 for (
size_t i = 0; i < cnt; ++i) {
207 #define CURRENT_CTYPE KrkCodeObject*
209 KRK_StaticMethod(codeobject,__new__) {
210 return krk_runtimeError(
vm.exceptions->typeError,
"codeobject object is not instantiable");
213 KRK_Method(codeobject,__name__) {
214 ATTRIBUTE_NOT_ASSIGNABLE();
215 return self->name ? OBJECT_VAL(self->name) : OBJECT_VAL(S(
""));
218 KRK_Method(codeobject,__repr__) {
220 KrkValue s = FUNC_NAME(codeobject,__name__)(1,argv,0);
221 if (!IS_STRING(s))
return NONE_VAL();
225 krk_pushStringBuilderFormat(&sb,
"<codeobject %S at %p>", AS_STRING(s), (
void*)
self);
232 KRK_Method(codeobject,_ip_to_line) {
233 METHOD_TAKES_EXACTLY(1);
234 CHECK_ARG(1,
int,krk_integer_type,ip);
236 return INTEGER_VAL(line);
239 KRK_Method(codeobject,__constants__) {
240 ATTRIBUTE_NOT_ASSIGNABLE();
242 memcpy(AS_TUPLE(
krk_peek(0))->values.values,
243 self->chunk.constants.values,
244 sizeof(
KrkValue) * self->chunk.constants.count);
245 AS_TUPLE(
krk_peek(0))->values.count =
self->chunk.constants.count;
249 KRK_Method(codeobject,co_code) {
250 return OBJECT_VAL(
krk_newBytes(self->chunk.count, self->chunk.code));
253 KRK_Method(codeobject,co_argcount) {
254 return INTEGER_VAL(self->potentialPositionals);
257 KRK_Method(codeobject,co_kwonlyargcount) {
258 return INTEGER_VAL(self->keywordArgs);
261 KRK_Method(codeobject,co_posonlyargcount) {
263 for (
size_t i = 0; i <
self->potentialPositionals; ++i) {
264 if (!IS_NONE(self->positionalArgNames.values[i]))
return INTEGER_VAL(i);
266 return INTEGER_VAL(0);
269 KRK_Method(codeobject,__locals__) {
271 for (
size_t i = 0; i <
self->localNameCount; ++i) {
273 AS_TUPLE(
krk_peek(0))->values.values[AS_TUPLE(
krk_peek(0))->values.count++] = INTEGER_VAL(self->localNames[i].id);
274 AS_TUPLE(
krk_peek(0))->values.values[AS_TUPLE(
krk_peek(0))->values.count++] = INTEGER_VAL(self->localNames[i].birthday);
275 AS_TUPLE(
krk_peek(0))->values.values[AS_TUPLE(
krk_peek(0))->values.count++] = INTEGER_VAL(self->localNames[i].deathday);
276 AS_TUPLE(
krk_peek(0))->values.values[AS_TUPLE(
krk_peek(0))->values.count++] = OBJECT_VAL(self->localNames[i].name);
284 KRK_Method(codeobject,co_flags) {
285 ATTRIBUTE_NOT_ASSIGNABLE();
292 if (self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) out |= 0x04;
293 if (self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS) out |= 0x08;
294 if (self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_IS_GENERATOR) out |= 0x20;
295 if (self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_IS_COROUTINE) out |= 0x80;
297 return INTEGER_VAL(out);
300 KRK_Method(codeobject,__args__) {
301 ATTRIBUTE_NOT_ASSIGNABLE();
302 KrkTuple * tuple = functionArgs(
self);
303 return OBJECT_VAL(tuple);
306 KRK_Method(codeobject,__file__) {
307 ATTRIBUTE_NOT_ASSIGNABLE();
308 return self->chunk.filename ? OBJECT_VAL(self->chunk.filename) : OBJECT_VAL(S(
""));
312 #define CURRENT_CTYPE KrkBoundMethod*
316 KRK_StaticMethod(method,__new__) {
317 FUNCTION_TAKES_EXACTLY(3);
318 if (!IS_OBJECT(argv[1]))
return krk_runtimeError(
vm.exceptions->typeError,
"first argument must be a heap object");
322 KRK_Method(method,__name__) {
323 ATTRIBUTE_NOT_ASSIGNABLE();
324 return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(
function,__name__)(1,(
KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S(
"?"));
327 KRK_Method(method,__qualname__) {
328 ATTRIBUTE_NOT_ASSIGNABLE();
329 return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(
function,__qualname__)(1,(
KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S(
"?"));
332 KRK_Method(method,_ip_to_line) {
333 METHOD_TAKES_EXACTLY(1);
334 return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(
function,_ip_to_line)(2,(
KrkValue[]){OBJECT_VAL(self->method),argv[1]},0) : OBJECT_VAL(S(
"?"));
337 KRK_Method(method,__repr__) {
339 KrkValue s = FUNC_NAME(method,__qualname__)(1,argv,0);
340 if (!IS_STRING(s)) s = FUNC_NAME(method,__name__)(1,argv,0);
341 if (!IS_STRING(s))
return NONE_VAL();
345 krk_pushStringBuilderFormat(&sb,
"<bound method '%S' of %T object", AS_STRING(s), self->receiver);
346 if (IS_OBJECT(self->receiver)) krk_pushStringBuilderFormat(&sb,
" at %p", (
void*)AS_OBJECT(self->receiver));
354 KRK_Method(method,__file__) {
355 ATTRIBUTE_NOT_ASSIGNABLE();
356 return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(
function,__file__)(1,(
KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S(
"?"));
359 KRK_Method(method,__args__) {
360 ATTRIBUTE_NOT_ASSIGNABLE();
361 return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(
function,__args__)(1,(
KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S(
"?"));
364 KRK_Method(method,__doc__) {
365 ATTRIBUTE_NOT_ASSIGNABLE();
366 return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(
function,__doc__)(1,(
KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S(
"?"));
369 KRK_Method(method,__annotations__) {
370 ATTRIBUTE_NOT_ASSIGNABLE();
371 return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(
function,__annotations__)(1,(
KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S(
"?"));
374 KRK_Method(method,__code__) {
375 ATTRIBUTE_NOT_ASSIGNABLE();
376 return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(
function,__code__)(1,(
KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S(
"?"));
379 KRK_Method(method,__func__) {
380 ATTRIBUTE_NOT_ASSIGNABLE();
381 return OBJECT_VAL(self->method);
384 KRK_Method(method,__self__) {
385 ATTRIBUTE_NOT_ASSIGNABLE();
386 return self->receiver;
389 KRK_Function(staticmethod) {
391 if (!
krk_parseArgs(
"O!", (
const char*[]){
"method"}, KRK_BASE_CLASS(
function), &method))
return NONE_VAL();
392 method->
flags &= ~(KRK_OBJ_FLAGS_FUNCTION_MASK);
393 method->
flags |= KRK_OBJ_FLAGS_FUNCTION_IS_STATIC_METHOD;
394 return OBJECT_VAL(method);
397 KRK_Function(classmethod) {
399 if (!
krk_parseArgs(
"O!", (
const char*[]){
"method"}, KRK_BASE_CLASS(
function), &method))
return NONE_VAL();
400 method->
flags &= ~(KRK_OBJ_FLAGS_FUNCTION_MASK);
401 method->
flags |= KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD;
402 return OBJECT_VAL(method);
406 void _createAndBind_functionClass(
void) {
407 KrkClass * codeobject = ADD_BASE_CLASS(
vm.baseClasses->codeobjectClass,
"codeobject",
vm.baseClasses->objectClass);
408 codeobject->
obj.
flags |= KRK_OBJ_FLAGS_NO_INHERIT;
410 BIND_STATICMETHOD(codeobject,__new__);
411 BIND_METHOD(codeobject,__repr__);
412 BIND_METHOD(codeobject,_ip_to_line);
413 BIND_PROP(codeobject,__constants__);
414 BIND_PROP(codeobject,__name__);
415 BIND_PROP(codeobject,co_flags);
416 BIND_PROP(codeobject,co_code);
417 BIND_PROP(codeobject,co_argcount);
418 BIND_PROP(codeobject,co_kwonlyargcount);
419 BIND_PROP(codeobject,co_posonlyargcount);
420 BIND_PROP(codeobject,__locals__);
421 BIND_PROP(codeobject,__args__);
422 BIND_PROP(codeobject,__file__);
425 KrkClass *
function = ADD_BASE_CLASS(
vm.baseClasses->functionClass,
"function",
vm.baseClasses->objectClass);
426 function->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
427 function->allocSize = 0;
428 BIND_STATICMETHOD(
function,__new__);
429 BIND_METHOD(
function,__repr__);
430 BIND_METHOD(
function,_ip_to_line);
431 BIND_PROP(
function,__doc__);
432 BIND_PROP(
function,__name__);
433 BIND_PROP(
function,__qualname__);
434 BIND_PROP(
function,__file__);
435 BIND_PROP(
function,__args__);
436 BIND_PROP(
function,__annotations__);
437 BIND_PROP(
function,__code__);
438 BIND_PROP(
function,__globals__);
439 BIND_PROP(
function,__closure__);
443 KrkClass * method = ADD_BASE_CLASS(
vm.baseClasses->methodClass,
"method",
vm.baseClasses->objectClass);
444 method->
obj.
flags |= KRK_OBJ_FLAGS_NO_INHERIT;
446 BIND_STATICMETHOD(method,__new__);
447 BIND_METHOD(method,__repr__);
448 BIND_METHOD(method,_ip_to_line);
449 BIND_PROP(method,__doc__);
450 BIND_PROP(method,__name__);
451 BIND_PROP(method,__qualname__);
452 BIND_PROP(method,__file__);
453 BIND_PROP(method,__args__);
454 BIND_PROP(method,__annotations__);
455 BIND_PROP(method,__self__);
456 BIND_PROP(method,__func__);
457 BIND_PROP(method,__code__);
460 BUILTIN_FUNCTION(
"staticmethod", FUNC_NAME(krk,staticmethod),
"A static method does not take an implicit self or cls argument.");
461 BUILTIN_FUNCTION(
"classmethod", FUNC_NAME(krk,classmethod),
"A class method takes an implicit cls argument, instead of self.");
Functions for debugging bytecode execution.
KrkValue krk_runtimeError(KrkClass *type, const char *fmt,...)
Produce and raise an exception with a formatted message.
Functions for dealing with garbage collection and memory allocation.
NativeFn krk_GenericAlias
Special value for type hint expressions.
KrkBoundMethod * krk_newBoundMethod(KrkValue receiver, KrkObj *method)
Create a new bound method.
KrkBytes * krk_newBytes(size_t length, uint8_t *source)
Create a new byte array.
size_t krk_lineNumber(KrkChunk *chunk, size_t offset)
Obtain the line number for a byte offset into a bytecode chunk.
size_t allocSize
Size to allocate when creating instances of this class.
void krk_finalizeClass(KrkClass *_class)
Finalize a class by collecting pointers to core methods.
KrkClosure * krk_newClosure(KrkCodeObject *function, KrkValue globals)
Create a new function object.
unsigned short potentialPositionals
Precalculated positional arguments for complex argument processing.
KrkValueArray positionalArgNames
Array of names for positional arguments (and *args)
unsigned short keywordArgs
Arity of keyword (default) arguments.
KrkValueArray keywordArgNames
Array of names for keyword-only arguments (and **kwargs)
unsigned short totalArguments
Total argument cells we can fill in complex argument processing.
Managed binding to a C function.
The most basic object type.
uint16_t flags
General object flags, mostly related to garbage collection.
KrkString * krk_copyString(const char *chars, size_t length)
Obtain a string object representation of the given C string.
KrkNative * krk_defineNative(KrkTable *table, const char *name, NativeFn function)
Attach a native C function to an attribute table.
Immutable sequence of arbitrary values.
KrkValueArray values
Stores the length, capacity, and actual values of the tuple.
KrkTuple * krk_newTuple(size_t length)
Create a new tuple.
Storage for values referenced from nested functions.
KrkUpvalue * krk_newUpvalue(int slot)
Create an upvalue slot.
Stack reference or primative value.
Inline flexible string array.
Utilities for creating native bindings.
#define krk_parseArgs(f, n,...)
Parse arguments to a function while accepting keyword arguments.
KrkValue krk_finishStringBuilder(struct StringBuilder *sb)
Finalize a string builder into a string object.
void krk_pushStringBuilder(struct StringBuilder *sb, char c)
Add a character to the end of a string builder.
Definitions for primitive stack references.
Core API for the bytecode virtual machine.
#define vm
Convenience macro for namespacing.
KrkValue krk_pop(void)
Pop the top of the stack.
void krk_push(KrkValue value)
Push a stack value.
KrkValue krk_peek(int distance)
Peek down from the top of the stack.