Simplify cached method things; don't expose the enum in headers

This commit is contained in:
K. Lange 2022-05-30 13:47:27 +09:00
parent a41410dcd9
commit 65f7ae3f22
8 changed files with 71 additions and 109 deletions

View File

@ -5,6 +5,8 @@
#include <kuroko/util.h>
#include <kuroko/debug.h>
#include "private.h"
static KrkClass * Helper;
static KrkClass * LicenseReader;
static KrkClass * property;

View File

@ -42,6 +42,8 @@
#include <kuroko/vm.h>
#include <kuroko/util.h>
#include "private.h"
/**
* @brief Token parser state.
*

View File

@ -52,53 +52,6 @@ typedef struct {
struct timespec in_time;
} KrkCallFrame;
/**
* @brief Index numbers for always-available interned strings representing important method and member names.
*
* The VM must look up many methods and members by fixed names. To avoid
* continuously having to box and unbox these from C strings to the appropriate
* interned @c KrkString, we keep an array of the @c KrkString pointers in the global VM state.
*
* These values are the offsets into that index for each of the relevant
* function names (generally with extra underscores removed). For example
* @c METHOD_INIT is the offset for the string value for @c "__init__".
*/
typedef enum {
METHOD_INIT,
METHOD_STR,
METHOD_REPR,
METHOD_GET,
METHOD_SET,
METHOD_CLASS,
METHOD_NAME,
METHOD_FILE,
METHOD_INT,
METHOD_FLOAT,
METHOD_CHR,
METHOD_LEN,
METHOD_DOC,
METHOD_BASE,
METHOD_GETSLICE,
METHOD_ORD,
METHOD_CALL,
METHOD_EQ,
METHOD_ENTER,
METHOD_EXIT,
METHOD_DELITEM,
METHOD_ITER,
METHOD_GETATTR,
METHOD_DIR,
METHOD_SETSLICE,
METHOD_DELSLICE,
METHOD_CONTAINS,
METHOD_DESCGET,
METHOD_DESCSET,
METHOD_CLASSGETITEM,
METHOD_HASH,
METHOD__MAX,
} KrkSpecialMethods;
/**
* @brief Table of basic exception types.
*

View File

@ -5,6 +5,8 @@
#include <kuroko/table.h>
#include <kuroko/util.h>
#include "private.h"
#if defined(KRK_EXTENSIVE_MEMORY_DEBUGGING)
/**
* Extensive Memory Debugging

31
src/methods.h Normal file
View File

@ -0,0 +1,31 @@
CACHED_METHOD(INIT, "__init__", _init)
CACHED_METHOD(GET, "__getitem__", _getter)
CACHED_METHOD(SET, "__setitem__", _setter)
CACHED_METHOD(REPR, "__repr__", _reprer)
CACHED_METHOD(STR, "__str__", _tostr)
CACHED_METHOD(CALL, "__call__", _call)
CACHED_METHOD(EQ, "__eq__", _eq)
CACHED_METHOD(LEN, "__len__", _len)
CACHED_METHOD(ENTER, "__enter__", _enter)
CACHED_METHOD(EXIT, "__exit__", _exit)
CACHED_METHOD(DELITEM, "__delitem__", _delitem)
CACHED_METHOD(ITER, "__iter__", _iter)
CACHED_METHOD(GETATTR, "__getattr__", _getattr)
CACHED_METHOD(DIR, "__dir__", _dir)
CACHED_METHOD(CONTAINS, "__contains__", _contains)
CACHED_METHOD(DESCGET, "__get__", _descget)
CACHED_METHOD(DESCSET, "__set__", _descset)
CACHED_METHOD(CLASSGETITEM, "__class_getitem__", _classgetitem)
CACHED_METHOD(HASH, "__hash__", _hash)
/* These are not methods */
SPECIAL_ATTRS(CLASS, "__class__")
SPECIAL_ATTRS(NAME, "__name__")
SPECIAL_ATTRS(DOC, "__doc__")
SPECIAL_ATTRS(BASE, "__base__")
SPECIAL_ATTRS(FILE, "__file__")
/* These should probably also be cached */
SPECIAL_ATTRS(INT, "__int__")
SPECIAL_ATTRS(CHR, "__chr__")
SPECIAL_ATTRS(ORD, "__ord__")
SPECIAL_ATTRS(FLOAT, "__float__")

View File

@ -4,6 +4,8 @@
#include <kuroko/memory.h>
#include <kuroko/util.h>
#include "private.h"
static KrkValue FUNC_NAME(striterator,__init__)(int,const KrkValue[],int);
#define CURRENT_CTYPE KrkString *

View File

@ -30,3 +30,23 @@ extern void _createAndBind_threadsMod(void);
#endif
/**
* @brief Index numbers for always-available interned strings representing important method and member names.
*
* The VM must look up many methods and members by fixed names. To avoid
* continuously having to box and unbox these from C strings to the appropriate
* interned @c KrkString, we keep an array of the @c KrkString pointers in the global VM state.
*
* These values are the offsets into that index for each of the relevant
* function names (generally with extra underscores removed). For example
* @c METHOD_INIT is the offset for the string value for @c "__init__".
*/
typedef enum {
#define CACHED_METHOD(a,b,c) METHOD_ ## a,
#define SPECIAL_ATTRS(a,b) METHOD_ ## a,
#include "methods.h"
#undef CACHED_METHOD
#undef SPECIAL_ATTRS
METHOD__MAX,
} KrkSpecialMethods;

View File

@ -413,25 +413,11 @@ void krk_finalizeClass(KrkClass * _class) {
KrkSpecialMethods index;
};
struct TypeMap specials[] = {
{&_class->_getter, METHOD_GET},
{&_class->_setter, METHOD_SET},
{&_class->_reprer, METHOD_REPR},
{&_class->_tostr, METHOD_STR},
{&_class->_call, METHOD_CALL},
{&_class->_init, METHOD_INIT},
{&_class->_eq, METHOD_EQ},
{&_class->_len, METHOD_LEN},
{&_class->_enter, METHOD_ENTER},
{&_class->_exit, METHOD_EXIT},
{&_class->_delitem, METHOD_DELITEM},
{&_class->_iter, METHOD_ITER},
{&_class->_getattr, METHOD_GETATTR},
{&_class->_dir, METHOD_DIR},
{&_class->_contains, METHOD_CONTAINS},
{&_class->_descget, METHOD_DESCGET},
{&_class->_descset, METHOD_DESCSET},
{&_class->_classgetitem, METHOD_CLASSGETITEM},
{&_class->_hash, METHOD_HASH},
#define CACHED_METHOD(a,b,c) {&_class-> c, METHOD_ ## a},
#define SPECIAL_ATTRS(a,b)
#include "methods.h"
#undef CACHED_METHOD
#undef SPECIAL_ATTRS
{NULL, 0},
};
@ -1303,47 +1289,11 @@ void krk_initVM(int flags) {
* and unboxing, copying/hashing etc.
*/
struct { const char * s; size_t len; } _methods[] = {
#define _(m,s) [m] = {s,sizeof(s)-1}
_(METHOD_INIT, "__init__"),
/* String conversion */
_(METHOD_STR, "__str__"),
_(METHOD_REPR, "__repr__"),
/* Subscripting / Indexing */
_(METHOD_LEN, "__len__"),
_(METHOD_GET, "__getitem__"),
_(METHOD_SET, "__setitem__"),
_(METHOD_DELITEM, "__delitem__"),
/* Dynamic properties */
_(METHOD_CLASS, "__class__"),
_(METHOD_NAME, "__name__"),
_(METHOD_FILE, "__file__"),
_(METHOD_DOC, "__doc__"),
_(METHOD_BASE, "__base__"),
/* Numeric conversions */
_(METHOD_INT, "__int__"),
_(METHOD_CHR, "__chr__"),
_(METHOD_ORD, "__ord__"),
_(METHOD_FLOAT, "__float__"),
/* General overridable methods */
_(METHOD_CALL, "__call__"),
_(METHOD_EQ, "__eq__"),
/* Iterables */
_(METHOD_ITER, "__iter__"),
_(METHOD_CONTAINS, "__contains__"),
/* Context managers */
_(METHOD_ENTER, "__enter__"),
_(METHOD_EXIT, "__exit__"),
/* Attribute access */
_(METHOD_GETATTR, "__getattr__"),
_(METHOD_DIR, "__dir__"),
/* Descriptor methods */
_(METHOD_DESCGET, "__get__"),
_(METHOD_DESCSET, "__set__"),
/* Very special thing */
_(METHOD_CLASSGETITEM, "__class_getitem__"),
/* Hashing override */
_(METHOD_HASH, "__hash__"),
#undef _
#define CACHED_METHOD(a,b,c) [METHOD_ ## a] = {b,sizeof(b)-1},
#define SPECIAL_ATTRS(a,b) [METHOD_ ## a] = {b,sizeof(b)-1},
#include "methods.h"
#undef CACHED_METHOD
#undef SPECIAL_ATTRS
};
for (size_t i = 0; i < METHOD__MAX; ++i) {
vm.specialMethodNames[i] = OBJECT_VAL(krk_copyString(_methods[i].s, _methods[i].len));
@ -2283,7 +2233,7 @@ static int valueDelProperty(KrkString * name) {
if (!krk_tableDelete(&_class->methods, OBJECT_VAL(name))) {
return 0;
}
if (name->length && name->chars[0] == '_') {
if (name->length > 1 && name->chars[0] == '_' && name->chars[1] == '_') {
krk_finalizeClass(_class);
}
krk_pop(); /* the original value */
@ -2336,7 +2286,7 @@ static int valueSetProperty(KrkString * name) {
}
} else if (IS_CLASS(owner)) {
krk_tableSet(&AS_CLASS(owner)->methods, OBJECT_VAL(name), value);
if (name->length && name->chars[0] == '_') {
if (name->length > 1 && name->chars[0] == '_' && name->chars[1] == '_') {
/* Quietly call finalizeClass to update special method table if this looks like it might be one */
krk_finalizeClass(AS_CLASS(owner));
}