Merge flags

This commit is contained in:
K. Lange 2022-05-31 17:31:35 +09:00
parent c785b2580e
commit fa2b2c053b
14 changed files with 127 additions and 143 deletions

View File

@ -615,13 +615,13 @@ KRK_FUNC(locals,{
krk_currentThread.stack[frame->slots + slot]); krk_currentThread.stack[frame->slots + slot]);
slot++; slot++;
} }
if (func->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS) { if (func->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) {
krk_tableSet(AS_DICT(dict), krk_tableSet(AS_DICT(dict),
func->requiredArgNames.values[func->requiredArgs], func->requiredArgNames.values[func->requiredArgs],
krk_currentThread.stack[frame->slots + slot]); krk_currentThread.stack[frame->slots + slot]);
slot++; slot++;
} }
if (func->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_KWS) { if (func->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS) {
krk_tableSet(AS_DICT(dict), krk_tableSet(AS_DICT(dict),
func->keywordArgNames.values[func->keywordArgs], func->keywordArgNames.values[func->keywordArgs],
krk_currentThread.stack[frame->slots + slot]); krk_currentThread.stack[frame->slots + slot]);
@ -971,7 +971,7 @@ void _createAndBind_builtins(void) {
vm.baseClasses->objectClass = krk_newClass(S("object"), NULL); vm.baseClasses->objectClass = krk_newClass(S("object"), NULL);
krk_push(OBJECT_VAL(vm.baseClasses->objectClass)); krk_push(OBJECT_VAL(vm.baseClasses->objectClass));
krk_defineNative(&vm.baseClasses->objectClass->methods, "__class__", FUNC_NAME(krk,type))->flags = KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY; krk_defineNative(&vm.baseClasses->objectClass->methods, "__class__", FUNC_NAME(krk,type))->obj.flags = KRK_OBJ_FLAGS_FUNCTION_IS_DYNAMIC_PROPERTY;
krk_defineNative(&vm.baseClasses->objectClass->methods, "__dir__", krk_dirObject); krk_defineNative(&vm.baseClasses->objectClass->methods, "__dir__", krk_dirObject);
krk_defineNative(&vm.baseClasses->objectClass->methods, "__str__", _strBase); krk_defineNative(&vm.baseClasses->objectClass->methods, "__str__", _strBase);
krk_defineNative(&vm.baseClasses->objectClass->methods, "__repr__", _strBase); /* Override if necesary */ krk_defineNative(&vm.baseClasses->objectClass->methods, "__repr__", _strBase); /* Override if necesary */

View File

@ -533,7 +533,7 @@ static KrkCodeObject * endCompiler(void) {
krk_pop(); krk_pop();
} }
size_t args = current->codeobject->requiredArgs + current->codeobject->keywordArgs; size_t args = current->codeobject->requiredArgs + current->codeobject->keywordArgs;
if (current->codeobject->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS) { if (current->codeobject->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) {
KrkValue value = OBJECT_VAL(krk_copyString(current->locals[args].name.start, KrkValue value = OBJECT_VAL(krk_copyString(current->locals[args].name.start,
current->locals[args].name.length)); current->locals[args].name.length));
krk_push(value); krk_push(value);
@ -541,7 +541,7 @@ static KrkCodeObject * endCompiler(void) {
krk_pop(); krk_pop();
args++; args++;
} }
if (current->codeobject->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_KWS) { if (current->codeobject->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS) {
KrkValue value = OBJECT_VAL(krk_copyString(current->locals[args].name.start, KrkValue value = OBJECT_VAL(krk_copyString(current->locals[args].name.start,
current->locals[args].name.length)); current->locals[args].name.length));
krk_push(value); krk_push(value);
@ -1353,14 +1353,14 @@ static int argumentList(FunctionType type) {
return 1; return 1;
} }
hasCollectors = 2; hasCollectors = 2;
current->codeobject->flags |= KRK_CODEOBJECT_FLAGS_COLLECTS_KWS; current->codeobject->obj.flags |= KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS;
} else { } else {
if (hasCollectors) { if (hasCollectors) {
error("Syntax error."); error("Syntax error.");
return 1; return 1;
} }
hasCollectors = 1; hasCollectors = 1;
current->codeobject->flags |= KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS; current->codeobject->obj.flags |= KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS;
} }
/* Collect a name, specifically "args" or "kwargs" are commont */ /* Collect a name, specifically "args" or "kwargs" are commont */
ssize_t paramConstant = parseVariable( ssize_t paramConstant = parseVariable(
@ -1420,7 +1420,7 @@ static void function(FunctionType type, size_t blockWidth) {
beginScope(); beginScope();
if (isMethod(type)) current->codeobject->requiredArgs = 1; if (isMethod(type)) current->codeobject->requiredArgs = 1;
if (isCoroutine(type)) current->codeobject->flags |= KRK_CODEOBJECT_FLAGS_IS_COROUTINE; if (isCoroutine(type)) current->codeobject->obj.flags |= KRK_OBJ_FLAGS_CODEOBJECT_IS_COROUTINE;
consume(TOKEN_LEFT_PAREN, "Expected start of parameter list after function name."); consume(TOKEN_LEFT_PAREN, "Expected start of parameter list after function name.");
startEatingWhitespace(); startEatingWhitespace();
@ -2382,7 +2382,7 @@ static void yield(int exprType) {
error("'yield' outside function"); error("'yield' outside function");
return; return;
} }
current->codeobject->flags |= KRK_CODEOBJECT_FLAGS_IS_GENERATOR; current->codeobject->obj.flags |= KRK_OBJ_FLAGS_CODEOBJECT_IS_GENERATOR;
if (match(TOKEN_FROM)) { if (match(TOKEN_FROM)) {
parsePrecedence(PREC_ASSIGNMENT); parsePrecedence(PREC_ASSIGNMENT);
emitByte(OP_INVOKE_ITER); emitByte(OP_INVOKE_ITER);
@ -2869,7 +2869,7 @@ static void generatorExpression(KrkScanner scannerBefore, Parser parserBefore, v
Compiler subcompiler; Compiler subcompiler;
initCompiler(&subcompiler, TYPE_FUNCTION); initCompiler(&subcompiler, TYPE_FUNCTION);
subcompiler.codeobject->chunk.filename = subcompiler.enclosing->codeobject->chunk.filename; subcompiler.codeobject->chunk.filename = subcompiler.enclosing->codeobject->chunk.filename;
subcompiler.codeobject->flags |= KRK_CODEOBJECT_FLAGS_IS_GENERATOR; subcompiler.codeobject->obj.flags |= KRK_OBJ_FLAGS_CODEOBJECT_IS_GENERATOR;
beginScope(); beginScope();
comprehensionInner(scannerBefore, parserBefore, body, 0); comprehensionInner(scannerBefore, parserBefore, body, 0);

View File

@ -67,17 +67,17 @@ void krk_disassembleCodeObject(FILE * f, KrkCodeObject * func, const char * name
fprintf(f, "<%s(", name); fprintf(f, "<%s(", name);
for (int i = 0; i < func->requiredArgs; ++i) { for (int i = 0; i < func->requiredArgs; ++i) {
fprintf(f,"%s",AS_CSTRING(func->requiredArgNames.values[i])); fprintf(f,"%s",AS_CSTRING(func->requiredArgNames.values[i]));
if (i + 1 < func->requiredArgs || func->keywordArgs || !!(func->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS) || !!(func->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_KWS)) fprintf(f,","); if (i + 1 < func->requiredArgs || func->keywordArgs || !!(func->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) || !!(func->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS)) fprintf(f,",");
} }
for (int i = 0; i < func->keywordArgs; ++i) { for (int i = 0; i < func->keywordArgs; ++i) {
fprintf(f,"%s=...",AS_CSTRING(func->keywordArgNames.values[i])); fprintf(f,"%s=...",AS_CSTRING(func->keywordArgNames.values[i]));
if (i + 1 < func->keywordArgs || !!(func->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS) || !!(func->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_KWS)) fprintf(f,","); if (i + 1 < func->keywordArgs || !!(func->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) || !!(func->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS)) fprintf(f,",");
} }
if (func->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS) { if (func->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) {
fprintf(f,"*%s", AS_CSTRING(func->requiredArgNames.values[func->requiredArgs])); fprintf(f,"*%s", AS_CSTRING(func->requiredArgNames.values[func->requiredArgs]));
if (func->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_KWS) fprintf(f,","); if (func->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS) fprintf(f,",");
} }
if (func->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_KWS) { if (func->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS) {
fprintf(f,"**%s", AS_CSTRING(func->keywordArgNames.values[func->keywordArgs])); fprintf(f,"**%s", AS_CSTRING(func->keywordArgNames.values[func->keywordArgs]));
} }
fprintf(f, ") from %s>\n", chunk->filename->chars); fprintf(f, ") from %s>\n", chunk->filename->chars);

View File

@ -254,7 +254,7 @@ static void tab_complete_func(rline_context_t * c) {
KrkValue thisValue = findFromProperty(root, asToken); KrkValue thisValue = findFromProperty(root, asToken);
krk_push(thisValue); krk_push(thisValue);
if (IS_CLOSURE(thisValue) || IS_BOUND_METHOD(thisValue) || if (IS_CLOSURE(thisValue) || IS_BOUND_METHOD(thisValue) ||
(IS_NATIVE(thisValue) && !(((KrkNative*)AS_OBJECT(thisValue))->flags & KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY))) { (IS_NATIVE(thisValue) && !((AS_OBJECT(thisValue)->flags & KRK_OBJ_FLAGS_FUNCTION_IS_DYNAMIC_PROPERTY)))) {
size_t allocSize = s->length + 2; size_t allocSize = s->length + 2;
char * tmp = malloc(allocSize); char * tmp = malloc(allocSize);
size_t len = snprintf(tmp, allocSize, "%s(", s->chars); size_t len = snprintf(tmp, allocSize, "%s(", s->chars);

View File

@ -45,11 +45,27 @@ typedef struct KrkObj {
struct KrkObj * next; /**< @brief Invasive linked list of all objects in the VM */ struct KrkObj * next; /**< @brief Invasive linked list of all objects in the VM */
} KrkObj; } KrkObj;
#define KRK_OBJ_FLAGS_SECOND_CHANCE 0x0001 #define KRK_OBJ_FLAGS_STRING_MASK 0x0003
#define KRK_OBJ_FLAGS_IS_MARKED 0x0010 #define KRK_OBJ_FLAGS_STRING_ASCII 0x0000
#define KRK_OBJ_FLAGS_IN_REPR 0x0020 #define KRK_OBJ_FLAGS_STRING_UCS1 0x0001
#define KRK_OBJ_FLAGS_IMMORTAL 0x0040 #define KRK_OBJ_FLAGS_STRING_UCS2 0x0002
#define KRK_OBJ_FLAGS_VALID_HASH 0x0080 #define KRK_OBJ_FLAGS_STRING_UCS4 0x0003
#define KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS 0x0001
#define KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS 0x0002
#define KRK_OBJ_FLAGS_CODEOBJECT_IS_GENERATOR 0x0004
#define KRK_OBJ_FLAGS_CODEOBJECT_IS_COROUTINE 0x0008
#define KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD 0x0001
#define KRK_OBJ_FLAGS_FUNCTION_IS_STATIC_METHOD 0x0002
#define KRK_OBJ_FLAGS_FUNCTION_IS_DYNAMIC_PROPERTY 0x0004
#define KRK_OBJ_FLAGS_SECOND_CHANCE 0x0100
#define KRK_OBJ_FLAGS_IS_MARKED 0x0010
#define KRK_OBJ_FLAGS_IN_REPR 0x0020
#define KRK_OBJ_FLAGS_IMMORTAL 0x0040
#define KRK_OBJ_FLAGS_VALID_HASH 0x0080
/** /**
* @brief String compact storage type. * @brief String compact storage type.
@ -62,11 +78,11 @@ typedef struct KrkObj {
* but this is not possible for UCS1. * but this is not possible for UCS1.
*/ */
typedef enum { typedef enum {
KRK_STRING_ASCII = 0, /**< Codepoints can be extracted directly from UTF8 data. */ /* For compatibility */
KRK_STRING_UCS1 = 1, /**< Codepoints are one byte. */ KRK_STRING_ASCII = KRK_OBJ_FLAGS_STRING_ASCII, /**< Codepoints can be extracted directly from UTF8 data. */
KRK_STRING_UCS2 = 2, /**< Codepoints are two bytes. */ KRK_STRING_UCS1 = KRK_OBJ_FLAGS_STRING_UCS1, /**< Codepoints are one byte. */
KRK_STRING_UCS4 = 4, /**< Codepoints are four bytes. */ KRK_STRING_UCS2 = KRK_OBJ_FLAGS_STRING_UCS2, /**< Codepoints are two bytes. */
KRK_STRING_INVALID = 5, /**< This is an invalid string. */ KRK_STRING_UCS4 = KRK_OBJ_FLAGS_STRING_UCS4, /**< Codepoints are four bytes. */
} KrkStringType; } KrkStringType;
#undef KrkString #undef KrkString
@ -76,7 +92,6 @@ typedef enum {
*/ */
typedef struct KrkString { typedef struct KrkString {
KrkObj obj; /**< @protected @brief Base */ KrkObj obj; /**< @protected @brief Base */
KrkStringType type; /**< @brief String codepoint storage format */
size_t length; /**< @brief String length in bytes */ size_t length; /**< @brief String length in bytes */
size_t codesLength; /**< @brief String length in Unicode codepoints */ size_t codesLength; /**< @brief String length in Unicode codepoints */
char * chars; /**< @brief UTF8 canonical data */ char * chars; /**< @brief UTF8 canonical data */
@ -139,15 +154,10 @@ typedef struct {
size_t localNameCapacity; /**< @brief Capacity of @ref localNames */ size_t localNameCapacity; /**< @brief Capacity of @ref localNames */
size_t localNameCount; /**< @brief Number of entries in @ref localNames */ size_t localNameCount; /**< @brief Number of entries in @ref localNames */
KrkLocalEntry * localNames; /**< @brief Stores the names of local variables used in the function, for debugging */ KrkLocalEntry * localNames; /**< @brief Stores the names of local variables used in the function, for debugging */
unsigned int flags; /**< @brief Function type flags */
struct KrkInstance * globalsContext; /**< @brief The globals namespace the function should reference when called */ struct KrkInstance * globalsContext; /**< @brief The globals namespace the function should reference when called */
KrkString * qualname; /**< @brief The dotted name of the function */ KrkString * qualname; /**< @brief The dotted name of the function */
} KrkCodeObject; } KrkCodeObject;
#define KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS 0x0001
#define KRK_CODEOBJECT_FLAGS_COLLECTS_KWS 0x0002
#define KRK_CODEOBJECT_FLAGS_IS_GENERATOR 0x0004
#define KRK_CODEOBJECT_FLAGS_IS_COROUTINE 0x0008
/** /**
* @brief Function object. * @brief Function object.
@ -160,14 +170,10 @@ typedef struct {
KrkCodeObject * function; /**< @brief The codeobject containing the bytecode run when this function is called */ KrkCodeObject * function; /**< @brief The codeobject containing the bytecode run when this function is called */
KrkUpvalue ** upvalues; /**< @brief Array of upvalues collected from the surrounding context when the closure was created */ KrkUpvalue ** upvalues; /**< @brief Array of upvalues collected from the surrounding context when the closure was created */
size_t upvalueCount; /**< @brief Number of entries in @ref upvalues */ size_t upvalueCount; /**< @brief Number of entries in @ref upvalues */
unsigned int flags; /**< @brief Closure type flags */
KrkValue annotations; /**< @brief Dictionary of type hints */ KrkValue annotations; /**< @brief Dictionary of type hints */
KrkTable fields; /**< @brief Object attributes table */ KrkTable fields; /**< @brief Object attributes table */
} KrkClosure; } KrkClosure;
#define KRK_FUNCTION_FLAGS_IS_CLASS_METHOD 0x0001
#define KRK_FUNCTION_FLAGS_IS_STATIC_METHOD 0x0002
typedef void (*KrkCleanupCallback)(struct KrkInstance *); typedef void (*KrkCleanupCallback)(struct KrkInstance *);
/** /**
@ -251,13 +257,8 @@ typedef struct {
NativeFn function; /**< @brief C function pointer */ NativeFn function; /**< @brief C function pointer */
const char * name; /**< @brief Name to use when repring */ const char * name; /**< @brief Name to use when repring */
const char * doc; /**< @brief Docstring to supply from @c %__doc__ */ const char * doc; /**< @brief Docstring to supply from @c %__doc__ */
unsigned int flags; /**< @brief Binding flags */
} KrkNative; } KrkNative;
#define KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY 0x0001
#define KRK_NATIVE_FLAGS_IS_STATIC_METHOD 0x0002
#define KRK_NATIVE_FLAGS_IS_CLASS_METHOD 0x0004
/** /**
* @brief Immutable sequence of arbitrary values. * @brief Immutable sequence of arbitrary values.
* @extends KrkObj * @extends KrkObj

View File

@ -80,10 +80,10 @@ _noexport
void _createAndBind_type(void) { void _createAndBind_type(void) {
ADD_BASE_CLASS(vm.baseClasses->typeClass, "type", vm.baseClasses->objectClass); ADD_BASE_CLASS(vm.baseClasses->typeClass, "type", vm.baseClasses->objectClass);
vm.baseClasses->typeClass->allocSize = 0; vm.baseClasses->typeClass->allocSize = 0;
krk_defineNative(&vm.baseClasses->typeClass->methods, "__base__", krk_baseOfClass)->flags = KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY; krk_defineNative(&vm.baseClasses->typeClass->methods, "__base__", krk_baseOfClass)->obj.flags = KRK_OBJ_FLAGS_FUNCTION_IS_DYNAMIC_PROPERTY;
krk_defineNative(&vm.baseClasses->typeClass->methods, "__file__", krk_fileOfClass)->flags = KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY; krk_defineNative(&vm.baseClasses->typeClass->methods, "__file__", krk_fileOfClass)->obj.flags = KRK_OBJ_FLAGS_FUNCTION_IS_DYNAMIC_PROPERTY;
krk_defineNative(&vm.baseClasses->typeClass->methods, "__doc__", krk_docOfClass) ->flags = KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY; krk_defineNative(&vm.baseClasses->typeClass->methods, "__doc__", krk_docOfClass) ->obj.flags = KRK_OBJ_FLAGS_FUNCTION_IS_DYNAMIC_PROPERTY;
krk_defineNative(&vm.baseClasses->typeClass->methods, "__name__", krk_nameOfClass)->flags = KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY; krk_defineNative(&vm.baseClasses->typeClass->methods, "__name__", krk_nameOfClass)->obj.flags = KRK_OBJ_FLAGS_FUNCTION_IS_DYNAMIC_PROPERTY;
krk_defineNative(&vm.baseClasses->typeClass->methods, "__init__", _type_init); krk_defineNative(&vm.baseClasses->typeClass->methods, "__init__", _type_init);
krk_defineNative(&vm.baseClasses->typeClass->methods, "__str__", _class_to_str); krk_defineNative(&vm.baseClasses->typeClass->methods, "__str__", _class_to_str);
krk_defineNative(&vm.baseClasses->typeClass->methods, "__repr__", _class_to_str); krk_defineNative(&vm.baseClasses->typeClass->methods, "__repr__", _class_to_str);

View File

@ -510,7 +510,7 @@ void _createAndBind_dictClass(void) {
BIND_METHOD(dict,update); BIND_METHOD(dict,update);
krk_defineNative(&dict->methods, "__iter__", FUNC_NAME(dict,keys)); krk_defineNative(&dict->methods, "__iter__", FUNC_NAME(dict,keys));
krk_defineNative(&dict->methods, "__str__", FUNC_NAME(dict,__repr__)); krk_defineNative(&dict->methods, "__str__", FUNC_NAME(dict,__repr__));
krk_defineNative(&dict->methods, "__class_getitem__", KrkGenericAlias)->flags |= KRK_NATIVE_FLAGS_IS_CLASS_METHOD; krk_defineNative(&dict->methods, "__class_getitem__", KrkGenericAlias)->obj.flags |= KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD;
krk_attachNamedValue(&dict->methods, "__hash__", NONE_VAL()); krk_attachNamedValue(&dict->methods, "__hash__", NONE_VAL());
krk_finalizeClass(dict); krk_finalizeClass(dict);
KRK_DOC(dict, "Mapping of arbitrary keys to values."); KRK_DOC(dict, "Mapping of arbitrary keys to values.");

View File

@ -104,7 +104,7 @@ KRK_METHOD(function,__args__,{
ATTRIBUTE_NOT_ASSIGNABLE(); ATTRIBUTE_NOT_ASSIGNABLE();
if (!IS_CLOSURE(self)) return OBJECT_VAL(krk_newTuple(0)); if (!IS_CLOSURE(self)) return OBJECT_VAL(krk_newTuple(0));
KrkCodeObject * _self = AS_CLOSURE(self)->function; KrkCodeObject * _self = AS_CLOSURE(self)->function;
KrkTuple * tuple = krk_newTuple(_self->requiredArgs + _self->keywordArgs + !!(_self->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS) + !!(_self->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_KWS)); KrkTuple * tuple = krk_newTuple(_self->requiredArgs + _self->keywordArgs + !!(_self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) + !!(_self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS));
krk_push(OBJECT_VAL(tuple)); krk_push(OBJECT_VAL(tuple));
for (short i = 0; i < _self->requiredArgs; ++i) { for (short i = 0; i < _self->requiredArgs; ++i) {
@ -118,14 +118,14 @@ KRK_METHOD(function,__args__,{
tuple->values.values[tuple->values.count++] = finishStringBuilder(&sb); tuple->values.values[tuple->values.count++] = finishStringBuilder(&sb);
} }
if (_self->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS) { if (_self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) {
struct StringBuilder sb = {0}; struct StringBuilder sb = {0};
pushStringBuilder(&sb, '*'); pushStringBuilder(&sb, '*');
pushStringBuilderStr(&sb, AS_CSTRING(_self->requiredArgNames.values[_self->requiredArgs]), AS_STRING(_self->requiredArgNames.values[_self->requiredArgs])->length); pushStringBuilderStr(&sb, AS_CSTRING(_self->requiredArgNames.values[_self->requiredArgs]), AS_STRING(_self->requiredArgNames.values[_self->requiredArgs])->length);
tuple->values.values[tuple->values.count++] = finishStringBuilder(&sb); tuple->values.values[tuple->values.count++] = finishStringBuilder(&sb);
} }
if (_self->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_KWS) { if (_self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS) {
struct StringBuilder sb = {0}; struct StringBuilder sb = {0};
pushStringBuilder(&sb, '*'); pushStringBuilder(&sb, '*');
pushStringBuilder(&sb, '*'); pushStringBuilder(&sb, '*');
@ -199,10 +199,10 @@ KRK_METHOD(codeobject,co_flags,{
/* For compatibility with Python, mostly because these are specified /* For compatibility with Python, mostly because these are specified
* in at least one doc page with their raw values, we convert * in at least one doc page with their raw values, we convert
* our flags to the useful CPython flag values... */ * our flags to the useful CPython flag values... */
if (self->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS) out |= 0x04; if (self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) out |= 0x04;
if (self->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_KWS) out |= 0x08; if (self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS) out |= 0x08;
if (self->flags & KRK_CODEOBJECT_FLAGS_IS_GENERATOR) out |= 0x20; if (self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_IS_GENERATOR) out |= 0x20;
if (self->flags & KRK_CODEOBJECT_FLAGS_IS_COROUTINE) out |= 0x80; if (self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_IS_COROUTINE) out |= 0x80;
return INTEGER_VAL(out); return INTEGER_VAL(out);
}) })
@ -290,7 +290,7 @@ KRK_FUNC(staticmethod,{
AS_CLOSURE(krk_peek(0))->upvalues[i] = method->upvalues[i]; AS_CLOSURE(krk_peek(0))->upvalues[i] = method->upvalues[i];
} }
AS_CLOSURE(krk_peek(0))->annotations = method->annotations; AS_CLOSURE(krk_peek(0))->annotations = method->annotations;
AS_CLOSURE(krk_peek(0))->flags |= KRK_FUNCTION_FLAGS_IS_STATIC_METHOD; AS_CLOSURE(krk_peek(0))->obj.flags |= KRK_OBJ_FLAGS_FUNCTION_IS_STATIC_METHOD;
return krk_pop(); return krk_pop();
}) })
@ -304,7 +304,7 @@ KRK_FUNC(classmethod,{
AS_CLOSURE(krk_peek(0))->upvalues[i] = method->upvalues[i]; AS_CLOSURE(krk_peek(0))->upvalues[i] = method->upvalues[i];
} }
AS_CLOSURE(krk_peek(0))->annotations = method->annotations; AS_CLOSURE(krk_peek(0))->annotations = method->annotations;
AS_CLOSURE(krk_peek(0))->flags |= KRK_FUNCTION_FLAGS_IS_CLASS_METHOD; AS_CLOSURE(krk_peek(0))->obj.flags |= KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD;
return krk_pop(); return krk_pop();
}) })
@ -332,7 +332,7 @@ void _createAndBind_functionClass(void) {
BIND_PROP(function,__annotations__); BIND_PROP(function,__annotations__);
BIND_PROP(function,__code__); BIND_PROP(function,__code__);
krk_defineNative(&function->methods, "__repr__", FUNC_NAME(function,__str__)); krk_defineNative(&function->methods, "__repr__", FUNC_NAME(function,__str__));
krk_defineNative(&function->methods, "__class_getitem__", KrkGenericAlias)->flags |= KRK_NATIVE_FLAGS_IS_CLASS_METHOD; krk_defineNative(&function->methods, "__class_getitem__", KrkGenericAlias)->obj.flags |= KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD;
krk_finalizeClass(function); krk_finalizeClass(function);
KrkClass * method = ADD_BASE_CLASS(vm.baseClasses->methodClass, "method", vm.baseClasses->objectClass); KrkClass * method = ADD_BASE_CLASS(vm.baseClasses->methodClass, "method", vm.baseClasses->objectClass);

View File

@ -76,7 +76,7 @@ KrkInstance * krk_buildGenerator(KrkClosure * closure, KrkValue * argsIn, size_t
self->closure = closure; self->closure = closure;
self->ip = self->closure->function->chunk.code; self->ip = self->closure->function->chunk.code;
self->result = NONE_VAL(); self->result = NONE_VAL();
self->type = closure->function->flags & (KRK_CODEOBJECT_FLAGS_IS_GENERATOR | KRK_CODEOBJECT_FLAGS_IS_COROUTINE); self->type = closure->function->obj.flags & (KRK_OBJ_FLAGS_CODEOBJECT_IS_GENERATOR | KRK_OBJ_FLAGS_CODEOBJECT_IS_COROUTINE);
return (KrkInstance *)self; return (KrkInstance *)self;
} }
@ -84,10 +84,10 @@ KRK_METHOD(generator,__repr__,{
METHOD_TAKES_NONE(); METHOD_TAKES_NONE();
char * typeStr = "generator"; char * typeStr = "generator";
if (self->type == KRK_CODEOBJECT_FLAGS_IS_COROUTINE) { if (self->type == KRK_OBJ_FLAGS_CODEOBJECT_IS_COROUTINE) {
/* Regular coroutine */ /* Regular coroutine */
typeStr = "coroutine"; typeStr = "coroutine";
} else if (self->type == (KRK_CODEOBJECT_FLAGS_IS_COROUTINE | KRK_CODEOBJECT_FLAGS_IS_GENERATOR)) { } else if (self->type == (KRK_OBJ_FLAGS_CODEOBJECT_IS_COROUTINE | KRK_OBJ_FLAGS_CODEOBJECT_IS_GENERATOR)) {
typeStr = "async_generator"; typeStr = "async_generator";
} }
@ -195,7 +195,7 @@ KRK_METHOD(generator,gi_running,{
}) })
int krk_getAwaitable(void) { int krk_getAwaitable(void) {
if (IS_generator(krk_peek(0)) && AS_generator(krk_peek(0))->type == KRK_CODEOBJECT_FLAGS_IS_COROUTINE) { if (IS_generator(krk_peek(0)) && AS_generator(krk_peek(0))->type == KRK_OBJ_FLAGS_CODEOBJECT_IS_COROUTINE) {
/* Good to go */ /* Good to go */
return 1; return 1;
} }

View File

@ -582,7 +582,7 @@ void _createAndBind_listClass(void) {
"Performs an in-place sort of the elements in the list, returning @c None as a gentle reminder " "Performs an in-place sort of the elements in the list, returning @c None as a gentle reminder "
"that the sort is in-place. If a sorted copy is desired, use @ref sorted instead."); "that the sort is in-place. If a sorted copy is desired, use @ref sorted instead.");
krk_defineNative(&list->methods, "__str__", FUNC_NAME(list,__repr__)); krk_defineNative(&list->methods, "__str__", FUNC_NAME(list,__repr__));
krk_defineNative(&list->methods, "__class_getitem__", KrkGenericAlias)->flags |= KRK_NATIVE_FLAGS_IS_CLASS_METHOD; krk_defineNative(&list->methods, "__class_getitem__", KrkGenericAlias)->obj.flags |= KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD;
krk_attachNamedValue(&list->methods, "__hash__", NONE_VAL()); krk_attachNamedValue(&list->methods, "__hash__", NONE_VAL());
krk_finalizeClass(list); krk_finalizeClass(list);
KRK_DOC(list, "Mutable sequence of arbitrary values."); KRK_DOC(list, "Mutable sequence of arbitrary values.");

View File

@ -19,8 +19,8 @@ static KrkValue FUNC_NAME(striterator,__init__)(int,const KrkValue[],int);
} stringBytes[stringLength++] = c; } while (0) } stringBytes[stringLength++] = c; } while (0)
#define KRK_STRING_FAST(string,offset) (uint32_t)\ #define KRK_STRING_FAST(string,offset) (uint32_t)\
(string->type <= 1 ? ((uint8_t*)string->codes)[offset] : \ ((string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) <= (KRK_OBJ_FLAGS_STRING_UCS1) ? ((uint8_t*)string->codes)[offset] : \
(string->type == 2 ? ((uint16_t*)string->codes)[offset] : \ ((string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) == (KRK_OBJ_FLAGS_STRING_UCS2) ? ((uint16_t*)string->codes)[offset] : \
((uint32_t*)string->codes)[offset])) ((uint32_t*)string->codes)[offset]))
#define CODEPOINT_BYTES(cp) (cp < 0x80 ? 1 : (cp < 0x800 ? 2 : (cp < 0x10000 ? 3 : 4))) #define CODEPOINT_BYTES(cp) (cp < 0x80 ? 1 : (cp < 0x800 ? 2 : (cp < 0x10000 ? 3 : 4)))
@ -67,7 +67,11 @@ KRK_METHOD(str,__add__,{
chars[length] = '\0'; chars[length] = '\0';
size_t cpLength = self->codesLength + them->codesLength; size_t cpLength = self->codesLength + them->codesLength;
KrkStringType type = self->type > them->type ? self->type : them->type;
int self_type = (self->obj.flags & KRK_OBJ_FLAGS_STRING_MASK);
int them_type = (them->obj.flags & KRK_OBJ_FLAGS_STRING_MASK);
KrkStringType type = self_type > them_type ? self_type : them_type;
/* Hashes can be extended, which saves us calculating the whole thing */ /* Hashes can be extended, which saves us calculating the whole thing */
uint32_t hash = self->obj.hash; uint32_t hash = self->obj.hash;
@ -127,7 +131,7 @@ KRK_METHOD(str,__getitem__,{
if (asInt < 0 || asInt >= (int)AS_STRING(argv[0])->codesLength) { if (asInt < 0 || asInt >= (int)AS_STRING(argv[0])->codesLength) {
return krk_runtimeError(vm.exceptions->indexError, "String index out of range: " PRIkrk_int, asInt); return krk_runtimeError(vm.exceptions->indexError, "String index out of range: " PRIkrk_int, asInt);
} }
if (self->type == KRK_STRING_ASCII) { if ((self->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) == KRK_OBJ_FLAGS_STRING_ASCII) {
return OBJECT_VAL(krk_copyString(self->chars + asInt, 1)); return OBJECT_VAL(krk_copyString(self->chars + asInt, 1));
} else { } else {
krk_unicodeString(self); krk_unicodeString(self);
@ -142,7 +146,7 @@ KRK_METHOD(str,__getitem__,{
if (step == 1) { if (step == 1) {
long len = end - start; long len = end - start;
if (self->type == KRK_STRING_ASCII) { if ((self->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) == KRK_OBJ_FLAGS_STRING_ASCII) {
return OBJECT_VAL(krk_copyString(self->chars + start, len)); return OBJECT_VAL(krk_copyString(self->chars + start, len));
} else { } else {
size_t offset = 0; size_t offset = 0;
@ -413,7 +417,7 @@ static int charIn(char c, const char * str) {
* Set which = 0, 1, 2 respectively * Set which = 0, 1, 2 respectively
*/ */
static KrkValue _string_strip_shared(int argc, const KrkValue argv[], int which) { static KrkValue _string_strip_shared(int argc, const KrkValue argv[], int which) {
if (argc > 1 && IS_STRING(argv[1]) && AS_STRING(argv[1])->type != KRK_STRING_ASCII) { if (argc > 1 && IS_STRING(argv[1]) && (AS_STRING(argv[1])->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) != KRK_OBJ_FLAGS_STRING_ASCII) {
return krk_runtimeError(vm.exceptions->notImplementedError, "str.strip() not implemented for Unicode strip lists"); return krk_runtimeError(vm.exceptions->notImplementedError, "str.strip() not implemented for Unicode strip lists");
} }
size_t start = 0; size_t start = 0;

View File

@ -113,17 +113,17 @@ static int checkString(const char * chars, size_t length, size_t *codepointCount
_release_lock(_stringLock); _release_lock(_stringLock);
krk_runtimeError(vm.exceptions->valueError, "Invalid UTF-8 sequence in string."); krk_runtimeError(vm.exceptions->valueError, "Invalid UTF-8 sequence in string.");
*codepointCount = 0; *codepointCount = 0;
return KRK_STRING_INVALID; return -1;
} }
} }
if (maxCodepoint > 0xFFFF) { if (maxCodepoint > 0xFFFF) {
return KRK_STRING_UCS4; return KRK_OBJ_FLAGS_STRING_UCS4;
} else if (maxCodepoint > 0xFF) { } else if (maxCodepoint > 0xFF) {
return KRK_STRING_UCS2; return KRK_OBJ_FLAGS_STRING_UCS2;
} else if (maxCodepoint > 0x7F) { } else if (maxCodepoint > 0x7F) {
return KRK_STRING_UCS1; return KRK_OBJ_FLAGS_STRING_UCS1;
} else { } else {
return KRK_STRING_ASCII; return KRK_OBJ_FLAGS_STRING_ASCII;
} }
} }
@ -149,20 +149,20 @@ GENREADY(4,uint32_t)
void * krk_unicodeString(KrkString * string) { void * krk_unicodeString(KrkString * string) {
if (string->codes) return string->codes; if (string->codes) return string->codes;
if (string->type == KRK_STRING_UCS1) _readyUCS1(string); else if ((string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) == KRK_OBJ_FLAGS_STRING_UCS1) _readyUCS1(string);
else if (string->type == KRK_STRING_UCS2) _readyUCS2(string); else if ((string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) == KRK_OBJ_FLAGS_STRING_UCS2) _readyUCS2(string);
else if (string->type == KRK_STRING_UCS4) _readyUCS4(string); else if ((string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) == KRK_OBJ_FLAGS_STRING_UCS4) _readyUCS4(string);
else krk_runtimeError(vm.exceptions->valueError, "Internal string error."); else krk_runtimeError(vm.exceptions->valueError, "Internal string error.");
return string->codes; return string->codes;
} }
uint32_t krk_unicodeCodepoint(KrkString * string, size_t index) { uint32_t krk_unicodeCodepoint(KrkString * string, size_t index) {
krk_unicodeString(string); krk_unicodeString(string);
switch (string->type) { switch (string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) {
case KRK_STRING_ASCII: return string->chars[index]; case KRK_OBJ_FLAGS_STRING_ASCII:
case KRK_STRING_UCS1: return ((uint8_t*)string->codes)[index]; case KRK_OBJ_FLAGS_STRING_UCS1: return ((uint8_t*)string->codes)[index];
case KRK_STRING_UCS2: return ((uint16_t*)string->codes)[index]; case KRK_OBJ_FLAGS_STRING_UCS2: return ((uint16_t*)string->codes)[index];
case KRK_STRING_UCS4: return ((uint32_t*)string->codes)[index]; case KRK_OBJ_FLAGS_STRING_UCS4: return ((uint32_t*)string->codes)[index];
default: default:
krk_runtimeError(vm.exceptions->valueError, "Internal string error."); krk_runtimeError(vm.exceptions->valueError, "Internal string error.");
return 0; return 0;
@ -172,18 +172,17 @@ uint32_t krk_unicodeCodepoint(KrkString * string, size_t index) {
static KrkString * allocateString(char * chars, size_t length, uint32_t hash) { static KrkString * allocateString(char * chars, size_t length, uint32_t hash) {
size_t codesLength = 0; size_t codesLength = 0;
int type = checkString(chars,length,&codesLength); int type = checkString(chars,length,&codesLength);
if (type == KRK_STRING_INVALID) { if (type == -1) {
return krk_copyString("",0); return krk_copyString("",0);
} }
KrkString * string = ALLOCATE_OBJECT(KrkString, KRK_OBJ_STRING); KrkString * string = ALLOCATE_OBJECT(KrkString, KRK_OBJ_STRING);
string->length = length; string->length = length;
string->chars = chars; string->chars = chars;
string->obj.hash = hash; string->obj.hash = hash;
string->obj.flags |= KRK_OBJ_FLAGS_VALID_HASH; string->obj.flags |= KRK_OBJ_FLAGS_VALID_HASH | type;
string->codesLength = codesLength; string->codesLength = codesLength;
string->type = type;
string->codes = NULL; string->codes = NULL;
if (string->type == KRK_STRING_ASCII) string->codes = string->chars; if (type == KRK_OBJ_FLAGS_STRING_ASCII) string->codes = string->chars;
krk_push(OBJECT_VAL(string)); krk_push(OBJECT_VAL(string));
krk_tableSet(&vm.strings, OBJECT_VAL(string), NONE_VAL()); krk_tableSet(&vm.strings, OBJECT_VAL(string), NONE_VAL());
krk_pop(); krk_pop();
@ -246,11 +245,10 @@ KrkString * krk_takeStringVetted(char * chars, size_t length, size_t codesLength
string->length = length; string->length = length;
string->chars = chars; string->chars = chars;
string->obj.hash = hash; string->obj.hash = hash;
string->obj.flags |= KRK_OBJ_FLAGS_VALID_HASH; string->obj.flags |= KRK_OBJ_FLAGS_VALID_HASH | type;
string->codesLength = codesLength; string->codesLength = codesLength;
string->type = type;
string->codes = NULL; string->codes = NULL;
if (string->type == KRK_STRING_ASCII) string->codes = string->chars; if (type == KRK_OBJ_FLAGS_STRING_ASCII) string->codes = string->chars;
krk_push(OBJECT_VAL(string)); krk_push(OBJECT_VAL(string));
krk_tableSet(&vm.strings, OBJECT_VAL(string), NONE_VAL()); krk_tableSet(&vm.strings, OBJECT_VAL(string), NONE_VAL());
krk_pop(); krk_pop();
@ -265,7 +263,6 @@ KrkCodeObject * krk_newCodeObject(void) {
codeobject->upvalueCount = 0; codeobject->upvalueCount = 0;
codeobject->name = NULL; codeobject->name = NULL;
codeobject->docstring = NULL; codeobject->docstring = NULL;
codeobject->flags = 0;
codeobject->localNameCount = 0; codeobject->localNameCount = 0;
codeobject->localNames = NULL; codeobject->localNames = NULL;
codeobject->globalsContext = NULL; codeobject->globalsContext = NULL;
@ -278,7 +275,7 @@ KrkCodeObject * krk_newCodeObject(void) {
KrkNative * krk_newNative(NativeFn function, const char * name, int type) { KrkNative * krk_newNative(NativeFn function, const char * name, int type) {
KrkNative * native = ALLOCATE_OBJECT(KrkNative, KRK_OBJ_NATIVE); KrkNative * native = ALLOCATE_OBJECT(KrkNative, KRK_OBJ_NATIVE);
native->function = function; native->function = function;
native->flags = type; native->obj.flags = type;
native->name = name; native->name = name;
native->doc = NULL; native->doc = NULL;
return native; return native;

View File

@ -91,7 +91,7 @@ void krk_forceThreadData(void) {
#if !defined(KRK_NO_TRACING) && !defined(__EMSCRIPTEN__) #if !defined(KRK_NO_TRACING) && !defined(__EMSCRIPTEN__)
# define FRAME_IN(frame) if (vm.globalFlags & KRK_GLOBAL_CALLGRIND) { clock_gettime(CLOCK_MONOTONIC, &frame->in_time); } # define FRAME_IN(frame) if (vm.globalFlags & KRK_GLOBAL_CALLGRIND) { clock_gettime(CLOCK_MONOTONIC, &frame->in_time); }
# define FRAME_OUT(frame) \ # define FRAME_OUT(frame) \
if (vm.globalFlags & KRK_GLOBAL_CALLGRIND && !(frame->closure->function->flags & KRK_CODEOBJECT_FLAGS_IS_GENERATOR)) { \ if (vm.globalFlags & KRK_GLOBAL_CALLGRIND && !(frame->closure->function->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_IS_GENERATOR)) { \
KrkCallFrame * caller = krk_currentThread.frameCount > 1 ? &krk_currentThread.frames[krk_currentThread.frameCount-2] : NULL; \ KrkCallFrame * caller = krk_currentThread.frameCount > 1 ? &krk_currentThread.frames[krk_currentThread.frameCount-2] : NULL; \
struct timespec outTime; \ struct timespec outTime; \
clock_gettime(CLOCK_MONOTONIC, &outTime); \ clock_gettime(CLOCK_MONOTONIC, &outTime); \
@ -602,7 +602,7 @@ int krk_processComplexArguments(int argCount, KrkValueArray * positionals, KrkTa
*/ */
static int call(KrkClosure * closure, int argCount, int returnDepth) { static int call(KrkClosure * closure, int argCount, int returnDepth) {
size_t potentialPositionalArgs = closure->function->requiredArgs + closure->function->keywordArgs; size_t potentialPositionalArgs = closure->function->requiredArgs + closure->function->keywordArgs;
size_t totalArguments = closure->function->requiredArgs + closure->function->keywordArgs + !!(closure->function->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS) + !!(closure->function->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_KWS); size_t totalArguments = closure->function->requiredArgs + closure->function->keywordArgs + !!(closure->function->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) + !!(closure->function->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS);
size_t offsetOfExtraArgs = closure->function->requiredArgs + closure->function->keywordArgs; size_t offsetOfExtraArgs = closure->function->requiredArgs + closure->function->keywordArgs;
size_t argCountX = argCount; size_t argCountX = argCount;
KrkValueArray * positionals; KrkValueArray * positionals;
@ -622,7 +622,7 @@ static int call(KrkClosure * closure, int argCount, int returnDepth) {
argCount--; /* It popped the KWARGS value from the top, so we have one less argument */ argCount--; /* It popped the KWARGS value from the top, so we have one less argument */
/* Do we already know we have too many arguments? Let's bail before doing a bunch of work. */ /* Do we already know we have too many arguments? Let's bail before doing a bunch of work. */
if ((positionals->count > potentialPositionalArgs) && !(closure->function->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS)) { if ((positionals->count > potentialPositionalArgs) && !(closure->function->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS)) {
checkArgumentCount(closure,positionals->count); checkArgumentCount(closure,positionals->count);
goto _errorDuringPositionals; goto _errorDuringPositionals;
} }
@ -649,7 +649,7 @@ static int call(KrkClosure * closure, int argCount, int returnDepth) {
krk_currentThread.stackTop[-argCount + i] = positionals->values[i]; krk_currentThread.stackTop[-argCount + i] = positionals->values[i];
} }
if (closure->function->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS) { if (closure->function->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) {
size_t count = (positionals->count > potentialPositionalArgs) ? (positionals->count - potentialPositionalArgs) : 0; size_t count = (positionals->count > potentialPositionalArgs) ? (positionals->count - potentialPositionalArgs) : 0;
KrkValue * offset = (count == 0) ? NULL : &positionals->values[potentialPositionalArgs]; KrkValue * offset = (count == 0) ? NULL : &positionals->values[potentialPositionalArgs];
krk_push(krk_list_of(count, offset, 0)); krk_push(krk_list_of(count, offset, 0));
@ -687,7 +687,7 @@ static int call(KrkClosure * closure, int argCount, int returnDepth) {
goto _finishKwarg; goto _finishKwarg;
} }
} }
if (!(closure->function->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_KWS)) { if (!(closure->function->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS)) {
krk_runtimeError(vm.exceptions->typeError, "%s() got an unexpected keyword argument '%s'", krk_runtimeError(vm.exceptions->typeError, "%s() got an unexpected keyword argument '%s'",
closure->function->name ? closure->function->name->chars : "<unnamed>", closure->function->name ? closure->function->name->chars : "<unnamed>",
AS_CSTRING(name)); AS_CSTRING(name));
@ -702,7 +702,7 @@ _finishKwarg:
} }
/* If this function takes a **kwargs, we need to provide it as a dict */ /* If this function takes a **kwargs, we need to provide it as a dict */
if (closure->function->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_KWS) { if (closure->function->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS) {
krk_push(krk_dict_of(0,NULL,0)); krk_push(krk_dict_of(0,NULL,0));
argCount++; argCount++;
krk_tableAddAll(keywords, AS_DICT(krk_peek(0))); krk_tableAddAll(keywords, AS_DICT(krk_peek(0)));
@ -720,8 +720,8 @@ _finishKwarg:
} }
} }
argCountX = argCount - (!!(closure->function->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS) + !!(closure->function->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_KWS)); argCountX = argCount - (!!(closure->function->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) + !!(closure->function->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS));
} else if ((size_t)argCount > potentialPositionalArgs && (closure->function->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS)) { } else if ((size_t)argCount > potentialPositionalArgs && (closure->function->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS)) {
krk_push(NONE_VAL()); krk_push(NONE_VAL()); krk_pop(); krk_pop(); krk_push(NONE_VAL()); krk_push(NONE_VAL()); krk_pop(); krk_pop();
KrkValue * startOfPositionals = &krk_currentThread.stackTop[-argCount]; KrkValue * startOfPositionals = &krk_currentThread.stackTop[-argCount];
KrkValue tmp = krk_list_of(argCount - potentialPositionalArgs, KrkValue tmp = krk_list_of(argCount - potentialPositionalArgs,
@ -740,7 +740,7 @@ _finishKwarg:
argCount++; argCount++;
} }
if (unlikely(closure->function->flags & (KRK_CODEOBJECT_FLAGS_IS_GENERATOR | KRK_CODEOBJECT_FLAGS_IS_COROUTINE))) { if (unlikely(closure->function->obj.flags & (KRK_OBJ_FLAGS_CODEOBJECT_IS_GENERATOR | KRK_OBJ_FLAGS_CODEOBJECT_IS_COROUTINE))) {
KrkInstance * gen = krk_buildGenerator(closure, krk_currentThread.stackTop - argCount, argCount); KrkInstance * gen = krk_buildGenerator(closure, krk_currentThread.stackTop - argCount, argCount);
krk_currentThread.stackTop = krk_currentThread.stackTop - argCount - returnDepth; krk_currentThread.stackTop = krk_currentThread.stackTop - argCount - returnDepth;
krk_push(OBJECT_VAL(gen)); krk_push(OBJECT_VAL(gen));
@ -936,21 +936,13 @@ int krk_bindMethod(KrkClass * _class, KrkString * name) {
_class = _class->base; _class = _class->base;
} }
if (!_class) return 0; if (!_class) return 0;
if (IS_NATIVE(method)) { if (IS_NATIVE(method)||IS_CLOSURE(method)) {
if (((KrkNative*)AS_OBJECT(method))->flags & KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY) { if (AS_OBJECT(method)->flags & KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD) {
out = OBJECT_VAL(krk_newBoundMethod(OBJECT_VAL(originalClass), AS_OBJECT(method)));
} else if (AS_OBJECT(method)->flags & KRK_OBJ_FLAGS_FUNCTION_IS_STATIC_METHOD) {
out = method;
} else if (AS_OBJECT(method)->flags & KRK_OBJ_FLAGS_FUNCTION_IS_DYNAMIC_PROPERTY) {
out = AS_NATIVE(method)->function(1, (KrkValue[]){krk_peek(0)}, 0); out = AS_NATIVE(method)->function(1, (KrkValue[]){krk_peek(0)}, 0);
} else if (((KrkNative*)AS_OBJECT(method))->flags & KRK_NATIVE_FLAGS_IS_CLASS_METHOD) {
out = OBJECT_VAL(krk_newBoundMethod(OBJECT_VAL(originalClass), AS_OBJECT(method)));
} else if (((KrkNative*)AS_OBJECT(method))->flags & KRK_NATIVE_FLAGS_IS_STATIC_METHOD) {
out = method;
} else {
out = OBJECT_VAL(krk_newBoundMethod(krk_peek(0), AS_OBJECT(method)));
}
} else if (IS_CLOSURE(method)) {
if (AS_CLOSURE(method)->flags & KRK_FUNCTION_FLAGS_IS_CLASS_METHOD) {
out = OBJECT_VAL(krk_newBoundMethod(OBJECT_VAL(originalClass), AS_OBJECT(method)));
} else if (AS_CLOSURE(method)->flags & KRK_FUNCTION_FLAGS_IS_STATIC_METHOD) {
out = method;
} else { } else {
out = OBJECT_VAL(krk_newBoundMethod(krk_peek(0), AS_OBJECT(method))); out = OBJECT_VAL(krk_newBoundMethod(krk_peek(0), AS_OBJECT(method)));
} }
@ -982,27 +974,15 @@ int krk_unbindMethod(KrkClass * _class, KrkString * name) {
_class = _class->base; _class = _class->base;
} }
if (!_class) return 0; if (!_class) return 0;
if (IS_NATIVE(method)) { if (IS_NATIVE(method) || IS_CLOSURE(method)) {
if (((KrkNative*)AS_OBJECT(method))->flags & KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY) { if (AS_OBJECT(method)->flags & KRK_OBJ_FLAGS_FUNCTION_IS_DYNAMIC_PROPERTY) {
out = AS_NATIVE(method)->function(1, (KrkValue[]){krk_peek(0)}, 0); out = AS_NATIVE(method)->function(1, (KrkValue[]){krk_peek(0)}, 0);
} else if (((KrkNative*)AS_OBJECT(method))->flags & KRK_NATIVE_FLAGS_IS_CLASS_METHOD) { } else if (AS_CLOSURE(method)->obj.flags & KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD) {
krk_pop(); /* the object */
krk_push(OBJECT_VAL(originalClass));
krk_push(method);
return 1;
} else if (((KrkNative*)AS_OBJECT(method))->flags & KRK_NATIVE_FLAGS_IS_STATIC_METHOD) {
out = method;
} else {
krk_push(method);
return 1;
}
} else if (IS_CLOSURE(method)) {
if (AS_CLOSURE(method)->flags & KRK_FUNCTION_FLAGS_IS_CLASS_METHOD) {
krk_pop(); krk_pop();
krk_push(OBJECT_VAL(originalClass)); krk_push(OBJECT_VAL(originalClass));
krk_push(method); krk_push(method);
return 1; return 1;
} else if (AS_CLOSURE(method)->flags & KRK_FUNCTION_FLAGS_IS_STATIC_METHOD) { } else if (AS_CLOSURE(method)->obj.flags & KRK_OBJ_FLAGS_FUNCTION_IS_STATIC_METHOD) {
out = method; out = method;
} else { } else {
krk_push(method); krk_push(method);
@ -1153,7 +1133,11 @@ KRK_FUNC(getsizeof,{
case KRK_OBJ_STRING: { case KRK_OBJ_STRING: {
KrkString * self = AS_STRING(argv[0]); KrkString * self = AS_STRING(argv[0]);
mySize += sizeof(KrkString) + self->length + 1; /* For the UTF8 */ mySize += sizeof(KrkString) + self->length + 1; /* For the UTF8 */
mySize += ((self->codes && (self->chars != self->codes)) ? (self->type * self->codesLength) : 0); if (self->codes && self->chars != self->codes) {
if ((self->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) <= KRK_OBJ_FLAGS_STRING_UCS1) mySize += self->codesLength;
else if ((self->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) == KRK_OBJ_FLAGS_STRING_UCS2) mySize += 2 * self->codesLength;
else if ((self->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) == KRK_OBJ_FLAGS_STRING_UCS4) mySize += 4 * self->codesLength;
}
break; break;
} }
case KRK_OBJ_CODEOBJECT: { case KRK_OBJ_CODEOBJECT: {
@ -2130,8 +2114,7 @@ static int valueGetProperty(KrkString * name) {
KrkClass * _class = AS_CLASS(this); KrkClass * _class = AS_CLASS(this);
do { do {
if (krk_tableGet_fast(&_class->methods, name, &value)) { if (krk_tableGet_fast(&_class->methods, name, &value)) {
if ((IS_CLOSURE(value) && (AS_CLOSURE(value)->flags & KRK_FUNCTION_FLAGS_IS_CLASS_METHOD)) || if ((IS_NATIVE(value) || IS_CLOSURE(value)) && (AS_OBJECT(value)->flags & KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD)) {
(IS_NATIVE(value) && (AS_NATIVE(value)->flags & KRK_NATIVE_FLAGS_IS_CLASS_METHOD))) {
value = OBJECT_VAL(krk_newBoundMethod(this, AS_OBJECT(value))); value = OBJECT_VAL(krk_newBoundMethod(this, AS_OBJECT(value)));
} }
krk_currentThread.stackTop[-1] = value; krk_currentThread.stackTop[-1] = value;
@ -2185,8 +2168,7 @@ static int valueGetMethod(KrkString * name) {
KrkClass * _class = AS_CLASS(this); KrkClass * _class = AS_CLASS(this);
do { do {
if (krk_tableGet_fast(&_class->methods, name, &value)) { if (krk_tableGet_fast(&_class->methods, name, &value)) {
if ((IS_CLOSURE(value) && (AS_CLOSURE(value)->flags & KRK_FUNCTION_FLAGS_IS_CLASS_METHOD)) || if ((IS_CLOSURE(value)||IS_NATIVE(value)) && (AS_OBJECT(value)->flags & KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD)) {
(IS_NATIVE(value) && (AS_NATIVE(value)->flags & KRK_NATIVE_FLAGS_IS_CLASS_METHOD))) {
krk_push(value); krk_push(value);
return 1; return 1;
} }
@ -2464,7 +2446,7 @@ _finishReturn: (void)0;
} }
krk_currentThread.stackTop = &krk_currentThread.stack[frame->outSlots]; krk_currentThread.stackTop = &krk_currentThread.stack[frame->outSlots];
if (krk_currentThread.frameCount == (size_t)krk_currentThread.exitOnFrame) { if (krk_currentThread.frameCount == (size_t)krk_currentThread.exitOnFrame) {
if (frame->closure->function->flags & (KRK_CODEOBJECT_FLAGS_IS_GENERATOR | KRK_CODEOBJECT_FLAGS_IS_COROUTINE)) { if (frame->closure->function->obj.flags & (KRK_OBJ_FLAGS_CODEOBJECT_IS_GENERATOR | KRK_OBJ_FLAGS_CODEOBJECT_IS_COROUTINE)) {
krk_push(result); krk_push(result);
return KWARGS_VAL(0); return KWARGS_VAL(0);
} }
@ -3061,7 +3043,7 @@ _finishReturn: (void)0;
KrkValue name = OBJECT_VAL(READ_STRING(OPERAND)); KrkValue name = OBJECT_VAL(READ_STRING(OPERAND));
krk_tableSet(&_class->methods, name, method); krk_tableSet(&_class->methods, name, method);
if (AS_STRING(name) == S("__class_getitem__") && IS_CLOSURE(method)) { if (AS_STRING(name) == S("__class_getitem__") && IS_CLOSURE(method)) {
AS_CLOSURE(method)->flags |= KRK_FUNCTION_FLAGS_IS_CLASS_METHOD; AS_CLOSURE(method)->obj.flags |= KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD;
} }
krk_pop(); krk_pop();
break; break;

View File

@ -219,11 +219,11 @@ static int doFirstPass(FILE * out) {
if (func->docstring) internString(func->docstring); if (func->docstring) internString(func->docstring);
if (func->qualname) internString(func->qualname); if (func->qualname) internString(func->qualname);
for (size_t i = 0; i < (size_t)func->requiredArgs + !!(func->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS); ++i) { for (size_t i = 0; i < (size_t)func->requiredArgs + !!(func->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS); ++i) {
internString(AS_STRING(func->requiredArgNames.values[i])); internString(AS_STRING(func->requiredArgNames.values[i]));
} }
for (size_t i = 0; i < (size_t)func->keywordArgs + !!(func->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_KWS); ++i) { for (size_t i = 0; i < (size_t)func->keywordArgs + !!(func->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS); ++i) {
internString(AS_STRING(func->keywordArgNames.values[i])); internString(AS_STRING(func->keywordArgNames.values[i]));
} }
@ -259,7 +259,7 @@ static int doSecondPass(FILE * out) {
for (size_t funcIndex = 0; funcIndex < AS_LIST(SeenFunctions)->count; ++funcIndex) { for (size_t funcIndex = 0; funcIndex < AS_LIST(SeenFunctions)->count; ++funcIndex) {
KrkCodeObject * func = AS_codeobject(AS_LIST(SeenFunctions)->values[funcIndex]); KrkCodeObject * func = AS_codeobject(AS_LIST(SeenFunctions)->values[funcIndex]);
uint8_t flags = func->flags; uint8_t flags = func->obj.flags;
struct FunctionHeader header = { struct FunctionHeader header = {
func->name ? internString(func->name) : UINT32_MAX, func->name ? internString(func->name) : UINT32_MAX,
@ -278,11 +278,11 @@ static int doSecondPass(FILE * out) {
fwrite(&header, 1, sizeof(struct FunctionHeader), out); fwrite(&header, 1, sizeof(struct FunctionHeader), out);
/* Argument names first */ /* Argument names first */
for (size_t i = 0; i < (size_t)func->requiredArgs + !!(func->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS); ++i) { for (size_t i = 0; i < (size_t)func->requiredArgs + !!(func->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS); ++i) {
WRITE_STRING(AS_STRING(func->requiredArgNames.values[i])); WRITE_STRING(AS_STRING(func->requiredArgNames.values[i]));
} }
for (size_t i = 0; i < (size_t)func->keywordArgs + !!(func->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_KWS); ++i) { for (size_t i = 0; i < (size_t)func->keywordArgs + !!(func->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS); ++i) {
WRITE_STRING(AS_STRING(func->keywordArgNames.values[i])); WRITE_STRING(AS_STRING(func->keywordArgNames.values[i]));
} }
@ -542,18 +542,18 @@ static int readFile(char * fileName) {
self->requiredArgs = function.reqArgs; self->requiredArgs = function.reqArgs;
self->keywordArgs = function.kwArgs; self->keywordArgs = function.kwArgs;
self->flags = function.flags; self->obj.flags = function.flags;
self->globalsContext = krk_currentThread.module; self->globalsContext = krk_currentThread.module;
self->upvalueCount = function.upvalues; self->upvalueCount = function.upvalues;
/* Read argument names */ /* Read argument names */
DEBUGOUT(" [Required Arguments]\n"); DEBUGOUT(" [Required Arguments]\n");
for (size_t i = 0; i < (size_t)function.reqArgs + !!(self->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS); i++) { for (size_t i = 0; i < (size_t)function.reqArgs + !!(self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS); i++) {
krk_writeValueArray(&self->requiredArgNames, valueFromConstant(i,inFile)); krk_writeValueArray(&self->requiredArgNames, valueFromConstant(i,inFile));
} }
DEBUGOUT(" [Keyword Arguments]\n"); DEBUGOUT(" [Keyword Arguments]\n");
for (size_t i = 0; i < (size_t)function.kwArgs + !!(self->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_KWS); i++) { for (size_t i = 0; i < (size_t)function.kwArgs + !!(self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS); i++) {
krk_writeValueArray(&self->keywordArgNames, valueFromConstant(i,inFile)); krk_writeValueArray(&self->keywordArgNames, valueFromConstant(i,inFile));
} }