Merge flags
This commit is contained in:
parent
c785b2580e
commit
fa2b2c053b
@ -615,13 +615,13 @@ KRK_FUNC(locals,{
|
||||
krk_currentThread.stack[frame->slots + 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),
|
||||
func->requiredArgNames.values[func->requiredArgs],
|
||||
krk_currentThread.stack[frame->slots + 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),
|
||||
func->keywordArgNames.values[func->keywordArgs],
|
||||
krk_currentThread.stack[frame->slots + slot]);
|
||||
@ -971,7 +971,7 @@ void _createAndBind_builtins(void) {
|
||||
vm.baseClasses->objectClass = krk_newClass(S("object"), NULL);
|
||||
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, "__str__", _strBase);
|
||||
krk_defineNative(&vm.baseClasses->objectClass->methods, "__repr__", _strBase); /* Override if necesary */
|
||||
|
@ -533,7 +533,7 @@ static KrkCodeObject * endCompiler(void) {
|
||||
krk_pop();
|
||||
}
|
||||
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,
|
||||
current->locals[args].name.length));
|
||||
krk_push(value);
|
||||
@ -541,7 +541,7 @@ static KrkCodeObject * endCompiler(void) {
|
||||
krk_pop();
|
||||
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,
|
||||
current->locals[args].name.length));
|
||||
krk_push(value);
|
||||
@ -1353,14 +1353,14 @@ static int argumentList(FunctionType type) {
|
||||
return 1;
|
||||
}
|
||||
hasCollectors = 2;
|
||||
current->codeobject->flags |= KRK_CODEOBJECT_FLAGS_COLLECTS_KWS;
|
||||
current->codeobject->obj.flags |= KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS;
|
||||
} else {
|
||||
if (hasCollectors) {
|
||||
error("Syntax error.");
|
||||
return 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 */
|
||||
ssize_t paramConstant = parseVariable(
|
||||
@ -1420,7 +1420,7 @@ static void function(FunctionType type, size_t blockWidth) {
|
||||
beginScope();
|
||||
|
||||
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.");
|
||||
startEatingWhitespace();
|
||||
@ -2382,7 +2382,7 @@ static void yield(int exprType) {
|
||||
error("'yield' outside function");
|
||||
return;
|
||||
}
|
||||
current->codeobject->flags |= KRK_CODEOBJECT_FLAGS_IS_GENERATOR;
|
||||
current->codeobject->obj.flags |= KRK_OBJ_FLAGS_CODEOBJECT_IS_GENERATOR;
|
||||
if (match(TOKEN_FROM)) {
|
||||
parsePrecedence(PREC_ASSIGNMENT);
|
||||
emitByte(OP_INVOKE_ITER);
|
||||
@ -2869,7 +2869,7 @@ static void generatorExpression(KrkScanner scannerBefore, Parser parserBefore, v
|
||||
Compiler subcompiler;
|
||||
initCompiler(&subcompiler, TYPE_FUNCTION);
|
||||
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();
|
||||
comprehensionInner(scannerBefore, parserBefore, body, 0);
|
||||
|
10
src/debug.c
10
src/debug.c
@ -67,17 +67,17 @@ void krk_disassembleCodeObject(FILE * f, KrkCodeObject * func, const char * name
|
||||
fprintf(f, "<%s(", name);
|
||||
for (int i = 0; i < func->requiredArgs; ++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) {
|
||||
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]));
|
||||
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, ") from %s>\n", chunk->filename->chars);
|
||||
|
@ -254,7 +254,7 @@ static void tab_complete_func(rline_context_t * c) {
|
||||
KrkValue thisValue = findFromProperty(root, asToken);
|
||||
krk_push(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;
|
||||
char * tmp = malloc(allocSize);
|
||||
size_t len = snprintf(tmp, allocSize, "%s(", s->chars);
|
||||
|
@ -45,12 +45,28 @@ typedef struct KrkObj {
|
||||
struct KrkObj * next; /**< @brief Invasive linked list of all objects in the VM */
|
||||
} KrkObj;
|
||||
|
||||
#define KRK_OBJ_FLAGS_SECOND_CHANCE 0x0001
|
||||
#define KRK_OBJ_FLAGS_STRING_MASK 0x0003
|
||||
#define KRK_OBJ_FLAGS_STRING_ASCII 0x0000
|
||||
#define KRK_OBJ_FLAGS_STRING_UCS1 0x0001
|
||||
#define KRK_OBJ_FLAGS_STRING_UCS2 0x0002
|
||||
#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.
|
||||
*
|
||||
@ -62,11 +78,11 @@ typedef struct KrkObj {
|
||||
* but this is not possible for UCS1.
|
||||
*/
|
||||
typedef enum {
|
||||
KRK_STRING_ASCII = 0, /**< Codepoints can be extracted directly from UTF8 data. */
|
||||
KRK_STRING_UCS1 = 1, /**< Codepoints are one byte. */
|
||||
KRK_STRING_UCS2 = 2, /**< Codepoints are two bytes. */
|
||||
KRK_STRING_UCS4 = 4, /**< Codepoints are four bytes. */
|
||||
KRK_STRING_INVALID = 5, /**< This is an invalid string. */
|
||||
/* For compatibility */
|
||||
KRK_STRING_ASCII = KRK_OBJ_FLAGS_STRING_ASCII, /**< Codepoints can be extracted directly from UTF8 data. */
|
||||
KRK_STRING_UCS1 = KRK_OBJ_FLAGS_STRING_UCS1, /**< Codepoints are one byte. */
|
||||
KRK_STRING_UCS2 = KRK_OBJ_FLAGS_STRING_UCS2, /**< Codepoints are two bytes. */
|
||||
KRK_STRING_UCS4 = KRK_OBJ_FLAGS_STRING_UCS4, /**< Codepoints are four bytes. */
|
||||
} KrkStringType;
|
||||
|
||||
#undef KrkString
|
||||
@ -76,7 +92,6 @@ typedef enum {
|
||||
*/
|
||||
typedef struct KrkString {
|
||||
KrkObj obj; /**< @protected @brief Base */
|
||||
KrkStringType type; /**< @brief String codepoint storage format */
|
||||
size_t length; /**< @brief String length in bytes */
|
||||
size_t codesLength; /**< @brief String length in Unicode codepoints */
|
||||
char * chars; /**< @brief UTF8 canonical data */
|
||||
@ -139,15 +154,10 @@ typedef struct {
|
||||
size_t localNameCapacity; /**< @brief Capacity of @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 */
|
||||
unsigned int flags; /**< @brief Function type flags */
|
||||
struct KrkInstance * globalsContext; /**< @brief The globals namespace the function should reference when called */
|
||||
KrkString * qualname; /**< @brief The dotted name of the function */
|
||||
} 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.
|
||||
@ -160,14 +170,10 @@ typedef struct {
|
||||
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 */
|
||||
size_t upvalueCount; /**< @brief Number of entries in @ref upvalues */
|
||||
unsigned int flags; /**< @brief Closure type flags */
|
||||
KrkValue annotations; /**< @brief Dictionary of type hints */
|
||||
KrkTable fields; /**< @brief Object attributes table */
|
||||
} KrkClosure;
|
||||
|
||||
#define KRK_FUNCTION_FLAGS_IS_CLASS_METHOD 0x0001
|
||||
#define KRK_FUNCTION_FLAGS_IS_STATIC_METHOD 0x0002
|
||||
|
||||
typedef void (*KrkCleanupCallback)(struct KrkInstance *);
|
||||
|
||||
/**
|
||||
@ -251,13 +257,8 @@ typedef struct {
|
||||
NativeFn function; /**< @brief C function pointer */
|
||||
const char * name; /**< @brief Name to use when repring */
|
||||
const char * doc; /**< @brief Docstring to supply from @c %__doc__ */
|
||||
unsigned int flags; /**< @brief Binding flags */
|
||||
} 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.
|
||||
* @extends KrkObj
|
||||
|
@ -80,10 +80,10 @@ _noexport
|
||||
void _createAndBind_type(void) {
|
||||
ADD_BASE_CLASS(vm.baseClasses->typeClass, "type", vm.baseClasses->objectClass);
|
||||
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, "__file__", krk_fileOfClass)->flags = KRK_NATIVE_FLAGS_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, "__name__", krk_nameOfClass)->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)->obj.flags = KRK_OBJ_FLAGS_FUNCTION_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)->obj.flags = KRK_OBJ_FLAGS_FUNCTION_IS_DYNAMIC_PROPERTY;
|
||||
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, "__repr__", _class_to_str);
|
||||
|
@ -510,7 +510,7 @@ void _createAndBind_dictClass(void) {
|
||||
BIND_METHOD(dict,update);
|
||||
krk_defineNative(&dict->methods, "__iter__", FUNC_NAME(dict,keys));
|
||||
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_finalizeClass(dict);
|
||||
KRK_DOC(dict, "Mapping of arbitrary keys to values.");
|
||||
|
@ -104,7 +104,7 @@ KRK_METHOD(function,__args__,{
|
||||
ATTRIBUTE_NOT_ASSIGNABLE();
|
||||
if (!IS_CLOSURE(self)) return OBJECT_VAL(krk_newTuple(0));
|
||||
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));
|
||||
|
||||
for (short i = 0; i < _self->requiredArgs; ++i) {
|
||||
@ -118,14 +118,14 @@ KRK_METHOD(function,__args__,{
|
||||
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};
|
||||
pushStringBuilder(&sb, '*');
|
||||
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);
|
||||
}
|
||||
|
||||
if (_self->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_KWS) {
|
||||
if (_self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS) {
|
||||
struct StringBuilder sb = {0};
|
||||
pushStringBuilder(&sb, '*');
|
||||
pushStringBuilder(&sb, '*');
|
||||
@ -199,10 +199,10 @@ KRK_METHOD(codeobject,co_flags,{
|
||||
/* For compatibility with Python, mostly because these are specified
|
||||
* in at least one doc page with their raw values, we convert
|
||||
* our flags to the useful CPython flag values... */
|
||||
if (self->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS) out |= 0x04;
|
||||
if (self->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_KWS) out |= 0x08;
|
||||
if (self->flags & KRK_CODEOBJECT_FLAGS_IS_GENERATOR) out |= 0x20;
|
||||
if (self->flags & KRK_CODEOBJECT_FLAGS_IS_COROUTINE) out |= 0x80;
|
||||
if (self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS) out |= 0x04;
|
||||
if (self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_KWS) out |= 0x08;
|
||||
if (self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_IS_GENERATOR) out |= 0x20;
|
||||
if (self->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_IS_COROUTINE) out |= 0x80;
|
||||
|
||||
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))->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();
|
||||
})
|
||||
|
||||
@ -304,7 +304,7 @@ KRK_FUNC(classmethod,{
|
||||
AS_CLOSURE(krk_peek(0))->upvalues[i] = method->upvalues[i];
|
||||
}
|
||||
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();
|
||||
})
|
||||
|
||||
@ -332,7 +332,7 @@ void _createAndBind_functionClass(void) {
|
||||
BIND_PROP(function,__annotations__);
|
||||
BIND_PROP(function,__code__);
|
||||
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);
|
||||
|
||||
KrkClass * method = ADD_BASE_CLASS(vm.baseClasses->methodClass, "method", vm.baseClasses->objectClass);
|
||||
|
@ -76,7 +76,7 @@ KrkInstance * krk_buildGenerator(KrkClosure * closure, KrkValue * argsIn, size_t
|
||||
self->closure = closure;
|
||||
self->ip = self->closure->function->chunk.code;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -84,10 +84,10 @@ KRK_METHOD(generator,__repr__,{
|
||||
METHOD_TAKES_NONE();
|
||||
|
||||
char * typeStr = "generator";
|
||||
if (self->type == KRK_CODEOBJECT_FLAGS_IS_COROUTINE) {
|
||||
if (self->type == KRK_OBJ_FLAGS_CODEOBJECT_IS_COROUTINE) {
|
||||
/* Regular 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";
|
||||
}
|
||||
|
||||
@ -195,7 +195,7 @@ KRK_METHOD(generator,gi_running,{
|
||||
})
|
||||
|
||||
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 */
|
||||
return 1;
|
||||
}
|
||||
|
@ -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 "
|
||||
"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, "__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_finalizeClass(list);
|
||||
KRK_DOC(list, "Mutable sequence of arbitrary values.");
|
||||
|
@ -19,8 +19,8 @@ static KrkValue FUNC_NAME(striterator,__init__)(int,const KrkValue[],int);
|
||||
} stringBytes[stringLength++] = c; } while (0)
|
||||
|
||||
#define KRK_STRING_FAST(string,offset) (uint32_t)\
|
||||
(string->type <= 1 ? ((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_UCS1) ? ((uint8_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]))
|
||||
|
||||
#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';
|
||||
|
||||
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 */
|
||||
uint32_t hash = self->obj.hash;
|
||||
@ -127,7 +131,7 @@ KRK_METHOD(str,__getitem__,{
|
||||
if (asInt < 0 || asInt >= (int)AS_STRING(argv[0])->codesLength) {
|
||||
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));
|
||||
} else {
|
||||
krk_unicodeString(self);
|
||||
@ -142,7 +146,7 @@ KRK_METHOD(str,__getitem__,{
|
||||
|
||||
if (step == 1) {
|
||||
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));
|
||||
} else {
|
||||
size_t offset = 0;
|
||||
@ -413,7 +417,7 @@ static int charIn(char c, const char * str) {
|
||||
* Set which = 0, 1, 2 respectively
|
||||
*/
|
||||
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");
|
||||
}
|
||||
size_t start = 0;
|
||||
|
41
src/object.c
41
src/object.c
@ -113,17 +113,17 @@ static int checkString(const char * chars, size_t length, size_t *codepointCount
|
||||
_release_lock(_stringLock);
|
||||
krk_runtimeError(vm.exceptions->valueError, "Invalid UTF-8 sequence in string.");
|
||||
*codepointCount = 0;
|
||||
return KRK_STRING_INVALID;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (maxCodepoint > 0xFFFF) {
|
||||
return KRK_STRING_UCS4;
|
||||
return KRK_OBJ_FLAGS_STRING_UCS4;
|
||||
} else if (maxCodepoint > 0xFF) {
|
||||
return KRK_STRING_UCS2;
|
||||
return KRK_OBJ_FLAGS_STRING_UCS2;
|
||||
} else if (maxCodepoint > 0x7F) {
|
||||
return KRK_STRING_UCS1;
|
||||
return KRK_OBJ_FLAGS_STRING_UCS1;
|
||||
} else {
|
||||
return KRK_STRING_ASCII;
|
||||
return KRK_OBJ_FLAGS_STRING_ASCII;
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,20 +149,20 @@ GENREADY(4,uint32_t)
|
||||
|
||||
void * krk_unicodeString(KrkString * string) {
|
||||
if (string->codes) return string->codes;
|
||||
if (string->type == KRK_STRING_UCS1) _readyUCS1(string);
|
||||
else if (string->type == KRK_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_UCS1) _readyUCS1(string);
|
||||
else if ((string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) == KRK_OBJ_FLAGS_STRING_UCS2) _readyUCS2(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.");
|
||||
return string->codes;
|
||||
}
|
||||
|
||||
uint32_t krk_unicodeCodepoint(KrkString * string, size_t index) {
|
||||
krk_unicodeString(string);
|
||||
switch (string->type) {
|
||||
case KRK_STRING_ASCII: return string->chars[index];
|
||||
case KRK_STRING_UCS1: return ((uint8_t*)string->codes)[index];
|
||||
case KRK_STRING_UCS2: return ((uint16_t*)string->codes)[index];
|
||||
case KRK_STRING_UCS4: return ((uint32_t*)string->codes)[index];
|
||||
switch (string->obj.flags & KRK_OBJ_FLAGS_STRING_MASK) {
|
||||
case KRK_OBJ_FLAGS_STRING_ASCII:
|
||||
case KRK_OBJ_FLAGS_STRING_UCS1: return ((uint8_t*)string->codes)[index];
|
||||
case KRK_OBJ_FLAGS_STRING_UCS2: return ((uint16_t*)string->codes)[index];
|
||||
case KRK_OBJ_FLAGS_STRING_UCS4: return ((uint32_t*)string->codes)[index];
|
||||
default:
|
||||
krk_runtimeError(vm.exceptions->valueError, "Internal string error.");
|
||||
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) {
|
||||
size_t codesLength = 0;
|
||||
int type = checkString(chars,length,&codesLength);
|
||||
if (type == KRK_STRING_INVALID) {
|
||||
if (type == -1) {
|
||||
return krk_copyString("",0);
|
||||
}
|
||||
KrkString * string = ALLOCATE_OBJECT(KrkString, KRK_OBJ_STRING);
|
||||
string->length = length;
|
||||
string->chars = chars;
|
||||
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->type = type;
|
||||
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_tableSet(&vm.strings, OBJECT_VAL(string), NONE_VAL());
|
||||
krk_pop();
|
||||
@ -246,11 +245,10 @@ KrkString * krk_takeStringVetted(char * chars, size_t length, size_t codesLength
|
||||
string->length = length;
|
||||
string->chars = chars;
|
||||
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->type = type;
|
||||
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_tableSet(&vm.strings, OBJECT_VAL(string), NONE_VAL());
|
||||
krk_pop();
|
||||
@ -265,7 +263,6 @@ KrkCodeObject * krk_newCodeObject(void) {
|
||||
codeobject->upvalueCount = 0;
|
||||
codeobject->name = NULL;
|
||||
codeobject->docstring = NULL;
|
||||
codeobject->flags = 0;
|
||||
codeobject->localNameCount = 0;
|
||||
codeobject->localNames = NULL;
|
||||
codeobject->globalsContext = NULL;
|
||||
@ -278,7 +275,7 @@ KrkCodeObject * krk_newCodeObject(void) {
|
||||
KrkNative * krk_newNative(NativeFn function, const char * name, int type) {
|
||||
KrkNative * native = ALLOCATE_OBJECT(KrkNative, KRK_OBJ_NATIVE);
|
||||
native->function = function;
|
||||
native->flags = type;
|
||||
native->obj.flags = type;
|
||||
native->name = name;
|
||||
native->doc = NULL;
|
||||
return native;
|
||||
|
74
src/vm.c
74
src/vm.c
@ -91,7 +91,7 @@ void krk_forceThreadData(void) {
|
||||
#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_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; \
|
||||
struct timespec 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) {
|
||||
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 argCountX = argCount;
|
||||
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 */
|
||||
|
||||
/* 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);
|
||||
goto _errorDuringPositionals;
|
||||
}
|
||||
@ -649,7 +649,7 @@ static int call(KrkClosure * closure, int argCount, int returnDepth) {
|
||||
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;
|
||||
KrkValue * offset = (count == 0) ? NULL : &positionals->values[potentialPositionalArgs];
|
||||
krk_push(krk_list_of(count, offset, 0));
|
||||
@ -687,7 +687,7 @@ static int call(KrkClosure * closure, int argCount, int returnDepth) {
|
||||
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'",
|
||||
closure->function->name ? closure->function->name->chars : "<unnamed>",
|
||||
AS_CSTRING(name));
|
||||
@ -702,7 +702,7 @@ _finishKwarg:
|
||||
}
|
||||
|
||||
/* 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));
|
||||
argCount++;
|
||||
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));
|
||||
} else if ((size_t)argCount > potentialPositionalArgs && (closure->function->flags & KRK_CODEOBJECT_FLAGS_COLLECTS_ARGS)) {
|
||||
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->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_COLLECTS_ARGS)) {
|
||||
krk_push(NONE_VAL()); krk_push(NONE_VAL()); krk_pop(); krk_pop();
|
||||
KrkValue * startOfPositionals = &krk_currentThread.stackTop[-argCount];
|
||||
KrkValue tmp = krk_list_of(argCount - potentialPositionalArgs,
|
||||
@ -740,7 +740,7 @@ _finishKwarg:
|
||||
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);
|
||||
krk_currentThread.stackTop = krk_currentThread.stackTop - argCount - returnDepth;
|
||||
krk_push(OBJECT_VAL(gen));
|
||||
@ -936,21 +936,13 @@ int krk_bindMethod(KrkClass * _class, KrkString * name) {
|
||||
_class = _class->base;
|
||||
}
|
||||
if (!_class) return 0;
|
||||
if (IS_NATIVE(method)) {
|
||||
if (((KrkNative*)AS_OBJECT(method))->flags & KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY) {
|
||||
if (IS_NATIVE(method)||IS_CLOSURE(method)) {
|
||||
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);
|
||||
} 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 {
|
||||
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;
|
||||
}
|
||||
if (!_class) return 0;
|
||||
if (IS_NATIVE(method)) {
|
||||
if (((KrkNative*)AS_OBJECT(method))->flags & KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY) {
|
||||
if (IS_NATIVE(method) || IS_CLOSURE(method)) {
|
||||
if (AS_OBJECT(method)->flags & KRK_OBJ_FLAGS_FUNCTION_IS_DYNAMIC_PROPERTY) {
|
||||
out = AS_NATIVE(method)->function(1, (KrkValue[]){krk_peek(0)}, 0);
|
||||
} else if (((KrkNative*)AS_OBJECT(method))->flags & KRK_NATIVE_FLAGS_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) {
|
||||
} else if (AS_CLOSURE(method)->obj.flags & KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD) {
|
||||
krk_pop();
|
||||
krk_push(OBJECT_VAL(originalClass));
|
||||
krk_push(method);
|
||||
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;
|
||||
} else {
|
||||
krk_push(method);
|
||||
@ -1153,7 +1133,11 @@ KRK_FUNC(getsizeof,{
|
||||
case KRK_OBJ_STRING: {
|
||||
KrkString * self = AS_STRING(argv[0]);
|
||||
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;
|
||||
}
|
||||
case KRK_OBJ_CODEOBJECT: {
|
||||
@ -2130,8 +2114,7 @@ static int valueGetProperty(KrkString * name) {
|
||||
KrkClass * _class = AS_CLASS(this);
|
||||
do {
|
||||
if (krk_tableGet_fast(&_class->methods, name, &value)) {
|
||||
if ((IS_CLOSURE(value) && (AS_CLOSURE(value)->flags & KRK_FUNCTION_FLAGS_IS_CLASS_METHOD)) ||
|
||||
(IS_NATIVE(value) && (AS_NATIVE(value)->flags & KRK_NATIVE_FLAGS_IS_CLASS_METHOD))) {
|
||||
if ((IS_NATIVE(value) || IS_CLOSURE(value)) && (AS_OBJECT(value)->flags & KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD)) {
|
||||
value = OBJECT_VAL(krk_newBoundMethod(this, AS_OBJECT(value)));
|
||||
}
|
||||
krk_currentThread.stackTop[-1] = value;
|
||||
@ -2185,8 +2168,7 @@ static int valueGetMethod(KrkString * name) {
|
||||
KrkClass * _class = AS_CLASS(this);
|
||||
do {
|
||||
if (krk_tableGet_fast(&_class->methods, name, &value)) {
|
||||
if ((IS_CLOSURE(value) && (AS_CLOSURE(value)->flags & KRK_FUNCTION_FLAGS_IS_CLASS_METHOD)) ||
|
||||
(IS_NATIVE(value) && (AS_NATIVE(value)->flags & KRK_NATIVE_FLAGS_IS_CLASS_METHOD))) {
|
||||
if ((IS_CLOSURE(value)||IS_NATIVE(value)) && (AS_OBJECT(value)->flags & KRK_OBJ_FLAGS_FUNCTION_IS_CLASS_METHOD)) {
|
||||
krk_push(value);
|
||||
return 1;
|
||||
}
|
||||
@ -2464,7 +2446,7 @@ _finishReturn: (void)0;
|
||||
}
|
||||
krk_currentThread.stackTop = &krk_currentThread.stack[frame->outSlots];
|
||||
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);
|
||||
return KWARGS_VAL(0);
|
||||
}
|
||||
@ -3061,7 +3043,7 @@ _finishReturn: (void)0;
|
||||
KrkValue name = OBJECT_VAL(READ_STRING(OPERAND));
|
||||
krk_tableSet(&_class->methods, name, 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();
|
||||
break;
|
||||
|
@ -219,11 +219,11 @@ static int doFirstPass(FILE * out) {
|
||||
if (func->docstring) internString(func->docstring);
|
||||
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]));
|
||||
}
|
||||
|
||||
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]));
|
||||
}
|
||||
|
||||
@ -259,7 +259,7 @@ static int doSecondPass(FILE * out) {
|
||||
for (size_t funcIndex = 0; funcIndex < AS_LIST(SeenFunctions)->count; ++funcIndex) {
|
||||
KrkCodeObject * func = AS_codeobject(AS_LIST(SeenFunctions)->values[funcIndex]);
|
||||
|
||||
uint8_t flags = func->flags;
|
||||
uint8_t flags = func->obj.flags;
|
||||
|
||||
struct FunctionHeader header = {
|
||||
func->name ? internString(func->name) : UINT32_MAX,
|
||||
@ -278,11 +278,11 @@ static int doSecondPass(FILE * out) {
|
||||
fwrite(&header, 1, sizeof(struct FunctionHeader), out);
|
||||
|
||||
/* 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]));
|
||||
}
|
||||
|
||||
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]));
|
||||
}
|
||||
|
||||
@ -542,18 +542,18 @@ static int readFile(char * fileName) {
|
||||
|
||||
self->requiredArgs = function.reqArgs;
|
||||
self->keywordArgs = function.kwArgs;
|
||||
self->flags = function.flags;
|
||||
self->obj.flags = function.flags;
|
||||
self->globalsContext = krk_currentThread.module;
|
||||
self->upvalueCount = function.upvalues;
|
||||
|
||||
/* Read argument names */
|
||||
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));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user