Bound methods can be bound to non-function callables

This commit is contained in:
K. Lange 2022-06-02 14:29:57 +09:00
parent 55849aa4f0
commit 2e7bf54d9a
2 changed files with 11 additions and 9 deletions

View File

@ -218,6 +218,8 @@ KRK_METHOD(codeobject,co_flags,{
#undef CURRENT_CTYPE
#define CURRENT_CTYPE KrkBoundMethod*
/* __init__ here will be called with a dummy instance as argv[0]; avoid
* complications with method argument checking by not using KRK_METHOD. */
FUNC_SIG(method,__init__) {
static __attribute__ ((unused)) const char* _method_name = "__init__";
METHOD_TAKES_EXACTLY(2);
@ -227,17 +229,17 @@ FUNC_SIG(method,__init__) {
KRK_METHOD(method,__name__,{
ATTRIBUTE_NOT_ASSIGNABLE();
return FUNC_NAME(function,__name__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0);
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__name__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
})
KRK_METHOD(method,__qualname__,{
ATTRIBUTE_NOT_ASSIGNABLE();
return FUNC_NAME(function,__qualname__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0);
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__qualname__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
})
KRK_METHOD(method,_ip_to_line,{
METHOD_TAKES_EXACTLY(1);
return FUNC_NAME(function,_ip_to_line)(2,(KrkValue[]){OBJECT_VAL(self->method),argv[1]},0);
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,_ip_to_line)(2,(KrkValue[]){OBJECT_VAL(self->method),argv[1]},0) : OBJECT_VAL(S("?"));
})
KRK_METHOD(method,__str__,{
@ -262,27 +264,27 @@ KRK_METHOD(method,__str__,{
KRK_METHOD(method,__file__,{
ATTRIBUTE_NOT_ASSIGNABLE();
return FUNC_NAME(function,__file__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0);
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__file__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
})
KRK_METHOD(method,__args__,{
ATTRIBUTE_NOT_ASSIGNABLE();
return FUNC_NAME(function,__args__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0);
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__args__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
})
KRK_METHOD(method,__doc__,{
ATTRIBUTE_NOT_ASSIGNABLE();
return FUNC_NAME(function,__doc__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0);
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__doc__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
})
KRK_METHOD(method,__annotations__,{
ATTRIBUTE_NOT_ASSIGNABLE();
return FUNC_NAME(function,__annotations__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0);
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__annotations__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
})
KRK_METHOD(method,__code__,{
ATTRIBUTE_NOT_ASSIGNABLE();
return FUNC_NAME(function,__code__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0);
return IS_function(OBJECT_VAL(self->method)) ? FUNC_NAME(function,__code__)(1,(KrkValue[]){OBJECT_VAL(self->method)},0) : OBJECT_VAL(S("?"));
})
KRK_METHOD(method,__func__,{

View File

@ -131,7 +131,7 @@ void krk_printValueSafe(FILE * f, KrkValue printable) {
case KRK_OBJ_BOUND_METHOD: fprintf(f, "<method %s>",
AS_BOUND_METHOD(printable)->method ? (
AS_BOUND_METHOD(printable)->method->type == KRK_OBJ_CLOSURE ? ((KrkClosure*)AS_BOUND_METHOD(printable)->method)->function->name->chars :
((KrkNative*)AS_BOUND_METHOD(printable)->method)->name) : "(corrupt bound method)"); break;
(AS_BOUND_METHOD(printable)->method->type == KRK_OBJ_NATIVE ? ((KrkNative*)AS_BOUND_METHOD(printable)->method)->name : "(unknown)")) : "(corrupt bound method)"); break;
default: fprintf(f, "<%s>", krk_typeName(printable)); break;
}
}