Don't use prefix characters in defineNative to mark methods (was a no-op anyway)

This commit is contained in:
K. Lange 2021-03-23 10:21:42 +09:00
parent 3c861ca167
commit d874ad0537
18 changed files with 71 additions and 87 deletions

View File

@ -891,11 +891,11 @@ 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));
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 */
krk_defineNative(&vm.baseClasses->objectClass->methods, ".__hash__", obj_hash);
krk_defineNative(&vm.baseClasses->objectClass->methods, "__class__", FUNC_NAME(krk,type))->isDynamicProperty = 1;
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 */
krk_defineNative(&vm.baseClasses->objectClass->methods, "__hash__", obj_hash);
krk_finalizeClass(vm.baseClasses->objectClass);
KRK_DOC(vm.baseClasses->objectClass,
"@brief Base class for all types.\n\n"
@ -905,8 +905,8 @@ void _createAndBind_builtins(void) {
vm.baseClasses->moduleClass = krk_newClass(S("module"), vm.baseClasses->objectClass);
krk_push(OBJECT_VAL(vm.baseClasses->moduleClass));
krk_defineNative(&vm.baseClasses->moduleClass->methods, ".__repr__", _module_repr);
krk_defineNative(&vm.baseClasses->moduleClass->methods, ".__str__", _module_repr);
krk_defineNative(&vm.baseClasses->moduleClass->methods, "__repr__", _module_repr);
krk_defineNative(&vm.baseClasses->moduleClass->methods, "__str__", _module_repr);
krk_finalizeClass(vm.baseClasses->moduleClass);
KRK_DOC(vm.baseClasses->moduleClass, "Type of imported modules and packages.");

View File

@ -142,9 +142,9 @@ void _createAndBind_exceptions(void) {
/* Add exception classes */
ADD_EXCEPTION_CLASS(vm.exceptions->baseException, "Exception", vm.baseClasses->objectClass);
/* base exception class gets an init that takes an optional string */
krk_defineNative(&vm.exceptions->baseException->methods, ".__init__", krk_initException);
krk_defineNative(&vm.exceptions->baseException->methods, ".__repr__", _exception_repr);
krk_defineNative(&vm.exceptions->baseException->methods, ".__str__", _exception_str);
krk_defineNative(&vm.exceptions->baseException->methods, "__init__", krk_initException);
krk_defineNative(&vm.exceptions->baseException->methods, "__repr__", _exception_repr);
krk_defineNative(&vm.exceptions->baseException->methods, "__str__", _exception_str);
krk_finalizeClass(vm.exceptions->baseException);
ADD_EXCEPTION_CLASS(vm.exceptions->typeError, "TypeError", vm.exceptions->baseException);
ADD_EXCEPTION_CLASS(vm.exceptions->argumentError, "ArgumentError", vm.exceptions->baseException);
@ -160,7 +160,7 @@ void _createAndBind_exceptions(void) {
ADD_EXCEPTION_CLASS(vm.exceptions->notImplementedError, "NotImplementedError", vm.exceptions->baseException);
ADD_EXCEPTION_CLASS(vm.exceptions->assertionError, "AssertionError", vm.exceptions->baseException);
ADD_EXCEPTION_CLASS(vm.exceptions->syntaxError, "SyntaxError", vm.exceptions->baseException);
krk_defineNative(&vm.exceptions->syntaxError->methods, ".__str__", _syntaxerror_str);
krk_defineNative(&vm.exceptions->syntaxError->methods, "__str__", _syntaxerror_str);
krk_finalizeClass(vm.exceptions->syntaxError);
}

View File

@ -527,7 +527,7 @@ void _createAndBind_fileioMod(void) {
"Use the <a class=\"el\" href=\"#open\">open()</a> function instead.}");
BIND_METHOD(File,__enter__);
BIND_METHOD(File,__exit__);
krk_defineNative(&File->methods, ".__repr__", FUNC_NAME(File,__str__));
krk_defineNative(&File->methods, "__repr__", FUNC_NAME(File,__str__));
krk_finalizeClass(File);
krk_makeClass(module, &BinaryFile, "BinaryFile", File);

View File

@ -262,7 +262,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))->isMethod != 2)) {
(IS_NATIVE(thisValue) && !((KrkNative*)AS_OBJECT(thisValue))->isDynamicProperty)) {
size_t allocSize = s->length + 2;
char * tmp = malloc(allocSize);
size_t len = snprintf(tmp, allocSize, "%s(", s->chars);

View File

@ -230,7 +230,7 @@ typedef struct {
NativeFn function;
const char * name;
const char * doc;
int isMethod;
unsigned int isDynamicProperty:1;
} KrkNative;
/**

View File

@ -24,8 +24,8 @@
#define ADD_BASE_CLASS(obj, name, baseClass) krk_makeClass(vm.builtins, &obj, name, baseClass)
#define ATTRIBUTE_NOT_ASSIGNABLE() do { if (argc != 1) return krk_runtimeError(vm.exceptions->attributeError, "attribute '%s' is not assignable", \
_method_name); } while (0)
#define ATTRIBUTE_NOT_ASSIGNABLE() do { if (argc != 1) return krk_runtimeError(vm.exceptions->attributeError, "'%s' object has no attribute '%s'", \
krk_typeName(argv[0]), _method_name); } while (0)
#define METHOD_TAKES_NONE() do { if (argc != 1) return krk_runtimeError(vm.exceptions->argumentError, "%s() takes no arguments (%d given)", \
_method_name, (argc-1)); } while (0)
@ -54,11 +54,10 @@
#define TYPE_ERROR(expected,value) krk_runtimeError(vm.exceptions->typeError, "%s() expects %s, not '%s'", \
/* Function name */ _method_name, /* expected type */ #expected, krk_typeName(value))
#define NOT_ENOUGH_ARGS() krk_runtimeError(vm.exceptions->argumentError, "%s() missing required positional argument", \
/* Function name */ _method_name)
#define NOT_ENOUGH_ARGS(name) krk_runtimeError(vm.exceptions->argumentError, "")
#define CHECK_ARG(i, type, ctype, name) \
if (argc < (i+1)) return NOT_ENOUGH_ARGS(); \
if (argc < (i+1)) return NOT_ENOUGH_ARGS(name); \
if (!IS_ ## type (argv[i])) return TYPE_ERROR(type,argv[i]); \
ctype name __attribute__((unused)) = AS_ ## type (argv[i])
@ -75,8 +74,7 @@
/* This assumes you have a KrkInstance called `module` in the current scope. */
#define MAKE_CLASS(klass) do { krk_makeClass(module,&klass,#klass,vm.baseClasses->objectClass); klass ->allocSize = sizeof(struct klass); } while (0)
#define BIND_METHOD(klass,method) krk_defineNative(&klass->methods, "." #method, _ ## klass ## _ ## method)
#define BIND_FIELD(klass,method) krk_defineNative(&klass->methods, ":" #method, _ ## klass ## _ ## method)
#define BIND_METHOD(klass,method) krk_defineNative(&klass->methods, #method, _ ## klass ## _ ## method)
#define BIND_PROP(klass,method) krk_defineNativeProperty(&klass->methods, #method, _ ## klass ## _ ## method)
#define BIND_FUNC(module,func) krk_defineNative(&module->fields, #func, _krk_ ## func)

View File

@ -415,7 +415,7 @@ KrkValue krk_module_onload_socket(void) {
"@arguments level,optname,value\n\n"
"@p level and @p optname should be integer values defined by @c SOL and @c SO options. "
"@p value must be either an @ref int or a @ref bytes object.");
krk_defineNative(&socket->methods,".__str__", FUNC_NAME(socket,__repr__));
krk_defineNative(&socket->methods,"__str__", FUNC_NAME(socket,__repr__));
krk_finalizeClass(SocketClass);
BIND_FUNC(module, htons);

View File

@ -62,13 +62,13 @@ static KrkValue _class_to_str(int argc, KrkValue argv[], int hasKw) {
_noexport
void _createAndBind_type(void) {
ADD_BASE_CLASS(vm.baseClasses->typeClass, "type", vm.baseClasses->objectClass);
krk_defineNative(&vm.baseClasses->typeClass->methods, ":__base__", krk_baseOfClass);
krk_defineNative(&vm.baseClasses->typeClass->methods, ":__file__", krk_fileOfClass);
krk_defineNative(&vm.baseClasses->typeClass->methods, ":__doc__", krk_docOfClass);
krk_defineNative(&vm.baseClasses->typeClass->methods, ":__name__", krk_nameOfClass);
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);
krk_defineNative(&vm.baseClasses->typeClass->methods, "__base__", krk_baseOfClass)->isDynamicProperty = 1;
krk_defineNative(&vm.baseClasses->typeClass->methods, "__file__", krk_fileOfClass)->isDynamicProperty = 1;
krk_defineNative(&vm.baseClasses->typeClass->methods, "__doc__", krk_docOfClass)->isDynamicProperty = 1;
krk_defineNative(&vm.baseClasses->typeClass->methods, "__name__", krk_nameOfClass)->isDynamicProperty = 1;
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);
krk_finalizeClass(vm.baseClasses->typeClass);
KRK_DOC(vm.baseClasses->typeClass, "Obtain the object representation of the class of an object.");
}

View File

@ -233,7 +233,7 @@ void _createAndBind_bytesClass(void) {
BIND_METHOD(bytes,__iter__);
BIND_METHOD(bytes,decode);
BIND_METHOD(bytes,join);
krk_defineNative(&bytes->methods,".__str__",FUNC_NAME(bytes,__repr__)); /* alias */
krk_defineNative(&bytes->methods,"__str__",FUNC_NAME(bytes,__repr__)); /* alias */
krk_finalizeClass(bytes);
KrkClass * bytesiterator = ADD_BASE_CLASS(vm.baseClasses->bytesiteratorClass, "bytesiterator", vm.baseClasses->objectClass);

View File

@ -385,8 +385,8 @@ void _createAndBind_dictClass(void) {
BIND_METHOD(dict,get);
BIND_METHOD(dict,setdefault);
BIND_METHOD(dict,update);
krk_defineNative(&dict->methods, ".__str__", FUNC_NAME(dict,__repr__));
krk_defineNative(&dict->methods, ".__class_getitem__", KrkGenericAlias);
krk_defineNative(&dict->methods, "__str__", FUNC_NAME(dict,__repr__));
krk_defineNative(&dict->methods, "__class_getitem__", KrkGenericAlias);
krk_finalizeClass(dict);
KRK_DOC(dict, "Mapping of arbitrary keys to values.");

View File

@ -268,7 +268,7 @@ void _createAndBind_functionClass(void) {
BIND_METHOD(codeobject,__str__);
BIND_METHOD(codeobject,_ip_to_line);
BIND_PROP(codeobject,__name__);
krk_defineNative(&codeobject->methods, ".__repr__", FUNC_NAME(codeobject,__str__));
krk_defineNative(&codeobject->methods, "__repr__", FUNC_NAME(codeobject,__str__));
krk_finalizeClass(codeobject);
KrkClass * function = ADD_BASE_CLASS(vm.baseClasses->functionClass, "function", vm.baseClasses->objectClass);
@ -280,8 +280,8 @@ void _createAndBind_functionClass(void) {
BIND_PROP(function,__file__);
BIND_PROP(function,__args__);
BIND_PROP(function,__annotations__);
krk_defineNative(&function->methods, ".__repr__", FUNC_NAME(function,__str__));
krk_defineNative(&function->methods, ".__class_getitem__", KrkGenericAlias);
krk_defineNative(&function->methods, "__repr__", FUNC_NAME(function,__str__));
krk_defineNative(&function->methods, "__class_getitem__", KrkGenericAlias);
krk_finalizeClass(function);
KrkClass * method = ADD_BASE_CLASS(vm.baseClasses->methodClass, "method", vm.baseClasses->objectClass);
@ -293,7 +293,7 @@ void _createAndBind_functionClass(void) {
BIND_PROP(method,__file__);
BIND_PROP(method,__args__);
BIND_PROP(method,__annotations__);
krk_defineNative(&method->methods, ".__repr__", FUNC_NAME(method,__str__));
krk_defineNative(&method->methods, "__repr__", FUNC_NAME(method,__str__));
krk_finalizeClass(method);
BUILTIN_FUNCTION("staticmethod", FUNC_NAME(krk,staticmethod), "A static method does not take an implicit self or cls argument.");

View File

@ -309,14 +309,14 @@ KRK_METHOD(list,index,{
if (IS_INTEGER(argv[2]))
min = AS_INTEGER(argv[2]);
else
return krk_runtimeError(vm.exceptions->typeError, "min must be int, not '%s'", krk_typeName(argv[2]));
return krk_runtimeError(vm.exceptions->typeError, "%s must be int, not '%s'", "min", krk_typeName(argv[2]));
}
if (argc > 3) {
if (IS_INTEGER(argv[3]))
max = AS_INTEGER(argv[3]);
else
return krk_runtimeError(vm.exceptions->typeError, "max must be int, not '%s'", krk_typeName(argv[3]));
return krk_runtimeError(vm.exceptions->typeError, "%s must be int, not '%s'", "max", krk_typeName(argv[3]));
}
pthread_rwlock_rdlock(&self->rwlock);
@ -504,9 +504,9 @@ void _createAndBind_listClass(void) {
BIND_METHOD(list,remove);
BIND_METHOD(list,reverse);
BIND_METHOD(list,sort);
krk_defineNative(&list->methods, ".__delitem__", FUNC_NAME(list,pop));
krk_defineNative(&list->methods, ".__str__", FUNC_NAME(list,__repr__));
krk_defineNative(&list->methods, ".__class_getitem__", KrkGenericAlias);
krk_defineNative(&list->methods, "__delitem__", FUNC_NAME(list,pop));
krk_defineNative(&list->methods, "__str__", FUNC_NAME(list,__repr__));
krk_defineNative(&list->methods, "__class_getitem__", KrkGenericAlias);
krk_finalizeClass(list);
KRK_DOC(list, "Mutable sequence of arbitrary values.");

View File

@ -96,7 +96,7 @@ KRK_METHOD(NoneType,__str__,{
})
#undef BIND_METHOD
#define BIND_METHOD(klass,method) do { krk_defineNative(& _ ## klass->methods, "." #method, _ ## klass ## _ ## method); } while (0)
#define BIND_METHOD(klass,method) do { krk_defineNative(& _ ## klass->methods, #method, _ ## klass ## _ ## method); } while (0)
_noexport
void _createAndBind_numericClasses(void) {
KrkClass * _int = ADD_BASE_CLASS(vm.baseClasses->intClass, "int", vm.baseClasses->objectClass);
@ -105,7 +105,7 @@ void _createAndBind_numericClasses(void) {
BIND_METHOD(int,__int__);
BIND_METHOD(int,__chr__);
BIND_METHOD(int,__float__);
krk_defineNative(&_int->methods, ".__repr__", FUNC_NAME(int,__str__));
krk_defineNative(&_int->methods, "__repr__", FUNC_NAME(int,__str__));
krk_finalizeClass(_int);
KRK_DOC(_int, "Convert a number or string type to an integer representation.");
@ -114,19 +114,19 @@ void _createAndBind_numericClasses(void) {
BIND_METHOD(float,__int__);
BIND_METHOD(float,__float__);
BIND_METHOD(float,__str__);
krk_defineNative(&_float->methods, ".__repr__", FUNC_NAME(float,__str__));
krk_defineNative(&_float->methods, "__repr__", FUNC_NAME(float,__str__));
krk_finalizeClass(_float);
KRK_DOC(_float, "Convert a number or string type to a float representation.");
KrkClass * _bool = ADD_BASE_CLASS(vm.baseClasses->boolClass, "bool", vm.baseClasses->intClass);
BIND_METHOD(bool,__init__);
BIND_METHOD(bool,__str__);
krk_defineNative(&_bool->methods, ".__repr__", FUNC_NAME(bool,__str__));
krk_defineNative(&_bool->methods, "__repr__", FUNC_NAME(bool,__str__));
krk_finalizeClass(_bool);
KRK_DOC(_bool, "Returns False if the argument is 'falsey', otherwise True.");
KrkClass * _NoneType = ADD_BASE_CLASS(vm.baseClasses->noneTypeClass, "NoneType", vm.baseClasses->objectClass);
BIND_METHOD(NoneType, __str__);
krk_defineNative(&_NoneType->methods, ".__repr__", FUNC_NAME(NoneType,__str__));
krk_defineNative(&_NoneType->methods, "__repr__", FUNC_NAME(NoneType,__str__));
krk_finalizeClass(_NoneType);
}

View File

@ -232,7 +232,7 @@ void _createAndBind_setClass(void) {
BIND_METHOD(set,remove);
BIND_METHOD(set,discard);
BIND_METHOD(set,clear);
krk_defineNative(&set->methods, ".__str__", FUNC_NAME(set,__repr__));
krk_defineNative(&set->methods, "__str__", FUNC_NAME(set,__repr__));
krk_finalizeClass(set);
BUILTIN_FUNCTION("setOf", krk_set_of, "Convert argument sequence to set object.");

View File

@ -922,9 +922,9 @@ void _createAndBind_strClass(void) {
BIND_METHOD(str,upper);
BIND_METHOD(str,title);
krk_defineNative(&str->methods,".__setslice__",FUNC_NAME(str,__setitem__));
krk_defineNative(&str->methods,".__delslice__",FUNC_NAME(str,__setitem__));
krk_defineNative(&str->methods,".__delitem__",FUNC_NAME(str,__setitem__));
krk_defineNative(&str->methods,"__setslice__",FUNC_NAME(str,__setitem__));
krk_defineNative(&str->methods,"__delslice__",FUNC_NAME(str,__setitem__));
krk_defineNative(&str->methods,"__delitem__",FUNC_NAME(str,__setitem__));
krk_finalizeClass(str);
KRK_DOC(str, "Obtain a string representation of an object.");

View File

@ -22,7 +22,9 @@ static KrkValue _tuple_init(int argc, KrkValue argv[], int hasKw) {
krk_push(krk_callSimple(tupleOf, 3, 0));
return krk_pop();
} else {
return krk_runtimeError(vm.exceptions->argumentError, "tuple() takes at most one argument");
return krk_runtimeError(vm.exceptions->argumentError,
"%s() takes %s %d argument%s (%d given)",
"tuple","at most",1,"",argc-1);
}
}
@ -162,8 +164,8 @@ void _createAndBind_tupleClass(void) {
BIND_METHOD(tuple,__contains__);
BIND_METHOD(tuple,__iter__);
BIND_METHOD(tuple,__eq__);
krk_defineNative(&tuple->methods, ".__init__", _tuple_init);
krk_defineNative(&tuple->methods, ".__str__", FUNC_NAME(tuple,__repr__));
krk_defineNative(&tuple->methods, "__init__", _tuple_init);
krk_defineNative(&tuple->methods, "__str__", FUNC_NAME(tuple,__repr__));
krk_finalizeClass(tuple);
BUILTIN_FUNCTION("tupleOf",krk_tuple_of,"Convert argument sequence to tuple object.");
@ -171,8 +173,8 @@ void _createAndBind_tupleClass(void) {
ADD_BASE_CLASS(vm.baseClasses->tupleiteratorClass, "tupleiterator", vm.baseClasses->objectClass);
vm.baseClasses->tupleiteratorClass->allocSize = sizeof(struct TupleIter);
vm.baseClasses->tupleiteratorClass->_ongcscan = _tuple_iter_gcscan;
krk_defineNative(&vm.baseClasses->tupleiteratorClass->methods, ".__init__", _tuple_iter_init);
krk_defineNative(&vm.baseClasses->tupleiteratorClass->methods, ".__call__", _tuple_iter_call);
krk_defineNative(&vm.baseClasses->tupleiteratorClass->methods, "__init__", _tuple_iter_init);
krk_defineNative(&vm.baseClasses->tupleiteratorClass->methods, "__call__", _tuple_iter_call);
krk_finalizeClass(vm.baseClasses->tupleiteratorClass);
}

View File

@ -252,7 +252,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->isMethod = type;
native->isDynamicProperty = type;
native->name = name;
native->doc = NULL;
return native;

View File

@ -324,21 +324,8 @@ inline void krk_swap(int distance) {
* GC safe: pushes allocated values.
*/
KrkNative * krk_defineNative(KrkTable * table, const char * name, NativeFn function) {
int functionType = 0;
if (*name == '.') {
name++;
functionType = 1;
}
if (*name == ':') {
name++;
functionType = 2;
}
KrkNative * func = krk_newNative(function, name, functionType);
krk_push(OBJECT_VAL(func));
krk_push(OBJECT_VAL(krk_copyString(name, (int)strlen(name))));
krk_tableSet(table, krk_peek(0), krk_peek(1));
krk_pop();
krk_pop();
KrkNative * func = krk_newNative(function, name, 0);
krk_attachNamedObject(table, name, (KrkObj*)func);
return func;
}
@ -349,7 +336,7 @@ KrkNative * krk_defineNative(KrkTable * table, const char * name, NativeFn funct
* the ":field" option for defineNative().
*/
KrkNative * krk_defineNativeProperty(KrkTable * table, const char * name, NativeFn function) {
KrkNative * func = krk_newNative(function, name, 1);
KrkNative * func = krk_newNative(function, name, 0);
krk_push(OBJECT_VAL(func));
KrkInstance * property = krk_newInstance(vm.baseClasses->propertyClass);
krk_attachNamedObject(table, name, (KrkObj*)property);
@ -884,7 +871,7 @@ int krk_bindMethod(KrkClass * _class, KrkString * name) {
_class = _class->base;
}
if (!_class) return 0;
if (IS_NATIVE(method) && ((KrkNative*)AS_OBJECT(method))->isMethod == 2) {
if (IS_NATIVE(method) && ((KrkNative*)AS_OBJECT(method))->isDynamicProperty) {
out = AS_NATIVE(method)->function(1, (KrkValue[]){krk_peek(0)}, 0);
} else if (IS_CLOSURE(method) && (AS_CLOSURE(method)->isClassMethod)) {
out = OBJECT_VAL(krk_newBoundMethod(OBJECT_VAL(_class), AS_OBJECT(method)));
@ -947,20 +934,6 @@ static void closeUpvalues(int last) {
}
}
/**
* Attach an object to a table.
*
* Generally used to attach classes or objects to the globals table, or to
* a native module's export object.
*/
void krk_attachNamedObject(KrkTable * table, const char name[], KrkObj * obj) {
krk_push(OBJECT_VAL(obj));
krk_push(OBJECT_VAL(krk_copyString(name,strlen(name))));
krk_tableSet(table, krk_peek(0), krk_peek(1));
krk_pop();
krk_pop();
}
/**
* Same as above, but the object has already been wrapped in a value.
*/
@ -972,6 +945,17 @@ void krk_attachNamedValue(KrkTable * table, const char name[], KrkValue obj) {
krk_pop();
}
/**
* Attach an object to a table.
*
* Generally used to attach classes or objects to the globals table, or to
* a native module's export object.
*/
void krk_attachNamedObject(KrkTable * table, const char name[], KrkObj * obj) {
krk_attachNamedValue(table,name,OBJECT_VAL(obj));
}
/**
* Inverse of truthiness.
*