Utilities for creating native bindings. More...
Go to the source code of this file.
Data Structures | |
struct | StringBuilder |
Inline flexible string array. More... | |
Macros | |
#define | S(c) (krk_copyString(c,sizeof(c)-1)) |
#define | likely(cond) __builtin_expect((cond), 1) |
#define | unlikely(cond) __builtin_expect((cond), 0) |
#define | __has_attribute(attr) 0 |
#define | _protected |
#define | _noexport __attribute__((visibility("hidden"))) |
#define | _unused |
#define | _hot |
#define | _cold |
#define | _nonnull |
#define | ADD_BASE_CLASS(obj, name, baseClass) krk_makeClass(vm.builtins, &obj, name, baseClass) |
#define | ATTRIBUTE_NOT_ASSIGNABLE() |
#define | METHOD_TAKES_NONE() |
#define | METHOD_TAKES_EXACTLY(n) |
#define | METHOD_TAKES_AT_LEAST(n) |
#define | METHOD_TAKES_AT_MOST(n) |
#define | FUNCTION_TAKES_NONE() |
#define | FUNCTION_TAKES_EXACTLY(n) |
#define | FUNCTION_TAKES_AT_LEAST(n) |
#define | FUNCTION_TAKES_AT_MOST(n) |
#define | TYPE_ERROR(expected, value) |
#define | NOT_ENOUGH_ARGS(name) krk_runtimeError(vm.exceptions->argumentError, "Expected more args.") |
#define | CHECK_ARG(i, type, ctype, name) |
#define | FUNC_NAME(klass, name) _ ## klass ## _ ## name |
#define | FUNC_SIG(klass, name) _noexport KrkValue FUNC_NAME(klass,name) (int argc, const KrkValue argv[], int hasKw) |
#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_PROP(klass, method) krk_defineNativeProperty(&klass->methods, #method, _ ## klass ## _ ## method) |
#define | BIND_FUNC(module, func) krk_defineNative(&module->fields, #func, _krk_ ## func) |
#define | BIND_STATICMETHOD(klass, method) krk_defineNativeStaticMethod(&klass->methods, #method, _ ## klass ## _ ## method) |
#define | BIND_CLASSMETHOD(klass, method) krk_defineNativeClassMethod(&klass->methods, #method, _ ## klass ## _ ## method) |
#define | KRK_Method_internal_name(klass, name) _krk_method_ ## klass ## _ ## name |
#define | KRK_Method_internal_sig(klass, name) static inline KrkValue KRK_Method_internal_name(klass,name) (const char * _method_name, CURRENT_CTYPE CURRENT_NAME, int argc, const KrkValue argv[], int hasKw) |
#define | KRK_Method(klass, name) |
#define | KRK_Function_internal_name(name) _krk_function_ ## name |
#define | KRK_Function_internal_sig(name) static inline KrkValue KRK_Function_internal_name(name) (const char * _method_name, int argc, const KrkValue argv[], int hasKw) |
#define | KRK_Function(name) |
#define | KRK_StaticMethod_internal_sig(klass, name) static inline KrkValue KRK_Method_internal_name(klass, name) (const char * _method_name, int argc, const KrkValue argv[], int hasKw) |
#define | KRK_StaticMethod(klass, name) |
#define | pushStringBuilder krk_pushStringBuilder |
#define | pushStringBuilderStr krk_pushStringBuilderStr |
#define | finishStringBuilder krk_finishStringBuilder |
#define | finishStringBuilderBytes krk_finishStringBuilderBytes |
#define | discardStringBuilder krk_discardStringBuilder |
#define | IS_int(o) (IS_INTEGER(o)) |
#define | AS_int(o) (AS_INTEGER(o)) |
#define | IS_bool(o) (IS_BOOLEAN(o)) |
#define | AS_bool(o) (AS_BOOLEAN(o)) |
#define | IS_float(o) (IS_FLOATING(o)) |
#define | AS_float(o) (AS_FLOATING(o)) |
#define | IS_list(o) ((IS_INSTANCE(o) && AS_INSTANCE(o)->_class == vm.baseClasses->listClass) || krk_isInstanceOf(o,vm.baseClasses->listClass)) |
#define | AS_list(o) (KrkList*)AS_OBJECT(o) |
#define | IS_tuple(o) IS_TUPLE(o) |
#define | AS_tuple(o) AS_TUPLE(o) |
#define | IS_bytes(o) IS_BYTES(o) |
#define | AS_bytes(o) AS_BYTES(o) |
#define | IS_class(o) IS_CLASS(o) |
#define | AS_class(o) AS_CLASS(o) |
#define | IS_str(o) (IS_STRING(o)||krk_isInstanceOf(o,vm.baseClasses->strClass)) |
#define | AS_str(o) (KrkString*)AS_OBJECT(o) |
#define | IS_striterator(o) (krk_isInstanceOf(o,vm.baseClasses->striteratorClass)) |
#define | AS_striterator(o) (AS_INSTANCE(o)) |
#define | IS_dict(o) ((IS_INSTANCE(o) && AS_INSTANCE(o)->_class == vm.baseClasses->dictClass) || krk_isInstanceOf(o,vm.baseClasses->dictClass)) |
#define | AS_dict(o) (KrkDict*)AS_OBJECT(o) |
#define | IS_dictitems(o) krk_isInstanceOf(o,vm.baseClasses->dictitemsClass) |
#define | AS_dictitems(o) ((struct DictItems*)AS_OBJECT(o)) |
#define | IS_dictkeys(o) krk_isInstanceOf(o,vm.baseClasses->dictkeysClass) |
#define | AS_dictkeys(o) ((struct DictKeys*)AS_OBJECT(o)) |
#define | IS_dictvalues(o) krk_isInstanceOf(o,vm.baseClasses->dictvaluesClass) |
#define | AS_dictvalues(o) ((struct DictValues*)AS_OBJECT(o)) |
#define | IS_bytearray(o) (krk_isInstanceOf(o,vm.baseClasses->bytearrayClass)) |
#define | AS_bytearray(o) ((struct ByteArray*)AS_INSTANCE(o)) |
#define | IS_slice(o) krk_isInstanceOf(o,vm.baseClasses->sliceClass) |
#define | AS_slice(o) ((struct KrkSlice*)AS_INSTANCE(o)) |
#define | krk_string_get FUNC_NAME(str,__getitem__) |
#define | krk_string_split FUNC_NAME(str,split) |
#define | krk_string_format FUNC_NAME(str,format) |
#define | KRK_DOC(thing, text) |
Attach documentation to a thing of various types. More... | |
#define | BUILTIN_FUNCTION(name, func, docStr) KRK_DOC(krk_defineNative(&vm.builtins->fields, name, func), docStr) |
#define | KRK_SLICER(arg, count) |
#define | KRK_BASE_CLASS(cls) (vm.baseClasses->cls ## Class) |
#define | KRK_EXC(exc) (vm.exceptions->exc) |
#define | krk_parseArgs(f, n, ...) krk_parseArgs_impl(_method_name,argc,argv,hasKw,f,n,__VA_ARGS__) |
Parse arguments to a function while accepting keyword arguments. More... | |
#define | KRK_Module_internal_name(name) _krk_module_onload_ ## name |
#define | KRK_Module_internal_sig(name) static inline void KRK_Module_internal_name(name) (KrkInstance * module, KrkString * runAs) |
#define | KRK_Module(name) |
Functions | |
void | krk_pushStringBuilder (struct StringBuilder *sb, char c) |
Add a character to the end of a string builder. More... | |
void | krk_pushStringBuilderStr (struct StringBuilder *sb, const char *str, size_t len) |
Append a string to the end of a string builder. More... | |
KrkValue | krk_finishStringBuilder (struct StringBuilder *sb) |
Finalize a string builder into a string object. More... | |
KrkValue | krk_finishStringBuilderBytes (struct StringBuilder *sb) |
Finalize a string builder in a bytes object. More... | |
KrkValue | krk_discardStringBuilder (struct StringBuilder *sb) |
Discard the contents of a string builder. More... | |
KrkValue | krk_dict_nth_key_fast (size_t capacity, KrkTableEntry *entries, size_t index) |
KrkValue | FUNC_NAME (str, __getitem__)(int |
KrkValue | FUNC_NAME (str, split)(int |
KrkValue | FUNC_NAME (str, format)(int |
int | krk_extractSlicer (const char *_method_name, KrkValue slicerVal, krk_integer_type count, krk_integer_type *start, krk_integer_type *end, krk_integer_type *step) |
int | krk_unpackIterable (KrkValue iterable, void *context, int callback(void *, const KrkValue *, size_t)) |
Unpack an iterable. More... | |
int | krk_parseVArgs (const char *_method_name, int argc, const KrkValue argv[], int hasKw, const char *fmt, const char **names, va_list args) |
Validate and parse arguments to a function similar to how managed function arguments are handled. More... | |
int | krk_parseArgs_impl (const char *_method_name, int argc, const KrkValue argv[], int hasKw, const char *format, const char **names,...) |
Variable argument version of krk_parseVArgs . | |
int | krk_pushStringBuilderFormatV (struct StringBuilder *sb, const char *fmt, va_list args) |
int | krk_pushStringBuilderFormat (struct StringBuilder *sb, const char *fmt,...) |
KrkValue | krk_stringFromFormat (const char *fmt,...) |
int | krk_long_to_int (KrkValue val, char size, void *out) |
Convert an int or long to a C integer. More... | |
int | krk_isSubClass (const KrkClass *cls, const KrkClass *base) |
Variables | |
KrkValue const KrkValue | int |
Detailed Description
Utilities for creating native bindings.
This is intended for use in C extensions to provide a uniform interface for defining extension methods and ensuring they have consistent argument and keyword argument usage.
Definition in file util.h.
Macro Definition Documentation
◆ ATTRIBUTE_NOT_ASSIGNABLE
#define ATTRIBUTE_NOT_ASSIGNABLE | ( | ) |
◆ CHECK_ARG
#define CHECK_ARG | ( | i, | |
type, | |||
ctype, | |||
name | |||
) |
◆ FUNCTION_TAKES_AT_LEAST
#define FUNCTION_TAKES_AT_LEAST | ( | n | ) |
◆ FUNCTION_TAKES_AT_MOST
#define FUNCTION_TAKES_AT_MOST | ( | n | ) |
◆ FUNCTION_TAKES_EXACTLY
#define FUNCTION_TAKES_EXACTLY | ( | n | ) |
◆ FUNCTION_TAKES_NONE
#define FUNCTION_TAKES_NONE | ( | ) |
◆ KRK_DOC
#define KRK_DOC | ( | thing, | |
text | |||
) |
Attach documentation to a thing of various types.
Classes store their docstrings directly, rather than in their attribute tables. Instances use the attribute table and store strings with the name __doc__
. Native functions store direct C string pointers for documentation.
This macro provides a generic interface for applying documentation strings to any of the above types, and handles not attaching documentation when built with KRK_NO_DOCUMENTATION.
◆ KRK_Function
#define KRK_Function | ( | name | ) |
◆ KRK_Method
#define KRK_Method | ( | klass, | |
name | |||
) |
◆ KRK_Module
#define KRK_Module | ( | name | ) |
◆ krk_parseArgs
#define krk_parseArgs | ( | f, | |
n, | |||
... | |||
) | krk_parseArgs_impl(_method_name,argc,argv,hasKw,f,n,__VA_ARGS__) |
Parse arguments to a function while accepting keyword arguments.
Convenience macro for krk_parseArgs_impl
to avoid needing to pass all of the implicit arguments normally provided to a KRK_Function or KRK_Method.
- Parameters
-
f Format string. n Names array.
- Returns
- 1 on success, 0 on failure with an exception set.
◆ KRK_SLICER
#define KRK_SLICER | ( | arg, | |
count | |||
) |
◆ KRK_StaticMethod
#define KRK_StaticMethod | ( | klass, | |
name | |||
) |
◆ METHOD_TAKES_AT_LEAST
#define METHOD_TAKES_AT_LEAST | ( | n | ) |
◆ METHOD_TAKES_AT_MOST
#define METHOD_TAKES_AT_MOST | ( | n | ) |
◆ METHOD_TAKES_EXACTLY
#define METHOD_TAKES_EXACTLY | ( | n | ) |
◆ METHOD_TAKES_NONE
#define METHOD_TAKES_NONE | ( | ) |
◆ TYPE_ERROR
#define TYPE_ERROR | ( | expected, | |
value | |||
) |
Function Documentation
◆ krk_discardStringBuilder()
KrkValue krk_discardStringBuilder | ( | struct StringBuilder * | sb | ) |
Discard the contents of a string builder.
Frees the resources allocated for the string builder without converting it to a string or bytes object. Call this when an error has been encountered and the contents of a string builder are no longer needed.
- Parameters
-
sb String builder to discard.
- Returns
- None, as a convenience.
◆ krk_finishStringBuilder()
KrkValue krk_finishStringBuilder | ( | struct StringBuilder * | sb | ) |
Finalize a string builder into a string object.
Creates a string object from the contents of the string builder and frees the space allocated for the builder, returning a value representing the newly created string object.
- Parameters
-
sb String builder to finalize.
- Returns
- A value representing a string object.
◆ krk_finishStringBuilderBytes()
KrkValue krk_finishStringBuilderBytes | ( | struct StringBuilder * | sb | ) |
◆ krk_long_to_int()
int krk_long_to_int | ( | KrkValue | val, |
char | size, | ||
void * | out | ||
) |
Convert an int or long to a C integer.
No overflow checking is performed in any case.
- Parameters
-
val int or long to convert. size Size in bytes of desired C integer type. out Pointer to resulting int.
Definition at line 3084 of file obj_long.c.
◆ krk_parseVArgs()
int krk_parseVArgs | ( | const char * | orig_method_name, |
int | argc, | ||
const KrkValue | argv[], | ||
int | hasKw, | ||
const char * | fmt, | ||
const char ** | names, | ||
va_list | args | ||
) |
Validate and parse arguments to a function similar to how managed function arguments are handled.
This works like a fancy scanf. We accept the original argument specification (argc,argv,hasKw), a format string, an array of argument names, and then var args that are generally pointers to where to stick results.
- Parameters
-
argc Original positional argument count. argv Original argument list, argv
[argc] should be a dict if hasKw is set.hasKw Whether argv
[argc] has a dict of keyword arguments.fmt String describing formats of expected arguments. names Array of strings of parameter names. args var args
- Returns
- 1 on success, 0 on error.
< Index into positional input arguments
< Index into names array
< Parser state, whether required arguments are being collected
< Whether extra keyword args should produce an error (0) or not (1)
If the format string starts with .
then argument processing skips the first argument on the assumption that this is a method and the first argument has already been handled by the method wrapper macros or directly by the function. This makes error messages a bit nicer, as argument counts will exclude the implicit self.
| begins optional arguments - eg. default args. Every format option after this point should be preset to usable default value, as it will not be touched if the argument is not found.
*
works like args
would in a Kuroko function signature, collecting all remaining positional arguments into a list. It does this be returning the count of remaining arguments (int) and the pointer to their start in the original argument list (KrkValue).
This also implicitly signals the end of required arguments and all later arguments are automatically optional, without needing to use |.
$
indicates the end of positional arguments. Everything after this point is only accepted as a keyword argument. $
must appear after one of | or
*
.
If any positional arguments remain when $
is encountred, a too-many arguments exception will be raised.
If ~
is encountered anywhere in the format string, then extraneous keyword arguments are left as-is and no exception is raised when they are found. As keyword arguments are deleted from the kwargs dict while processing other arguments, this means if hasKw
is set then argv
[argc] will be left with only the unhandled keyword arguments, same as for a **kwargs
argument in a Kuroko function signature.
O
Collect an object (with !
- of a given type) and place it in in the KrkObj**
var arg. The object must be a heap object, so this can not be used to collect boxed value types like int
or float
- use V
for those instead. As an exception to the heap object requirements, None
is accepted and will result in NULL
(but if a type is requested, the type check will fail before None
can be evaluated).
V
Accept any value (with !
- of a given type) and place a value reference in the KrkValue*
var arg. This works with boxed value types as well, so it is safe for use with int
and float
and so on. The type check is equivalent to instanceof
. As a special case - as with O
- the type may be NULL
in which case type checking is guaranteed to fail but parsing will not. The resulting error message is less informative in this case.
z
Collect one string or None and place a pointer to it in a const char **
. If #
is specified, the size of the string is also placed in a following size_t*
var arg. If the argument is None
the result is NULL
and the size is set to 0.
s
Same as z
but does not accept None.
Integer conversions.
TODO Currently no overflow checking is done for any case, but we should do it for at least the signed values to align with the CPython API this is all based on... The distinct signed vs. unsigned variants are intended both for future compatibility and to make intent clear, but have no functional difference at this point.
C
Accept a string of length one and convert it to a C int in a similar manner to ord
.
f
Accept a Kuroko float as C float.
d
Accept a Kuroko float as C double.
p
Accept any value and examine its truthiness, returning an int
. Python's docs call this "predicate", if you were wondering where the p
came from. If bool conversion raises an exception, arg parsing ends with failure and that exception remains set.
If we got through the format string and there are still positional arguments, we got more than we expected and should raise an exception.
If we don't accept extra keyword arguments and there's still anything left in the dict, raise an exception about unexpected keyword arguments. The remaining key (or keys) should be a string, so we should find at least one thing to complain about by name...
Definition at line 85 of file parseargs.c.
◆ krk_pushStringBuilder()
void krk_pushStringBuilder | ( | struct StringBuilder * | sb, |
char | c | ||
) |
◆ krk_pushStringBuilderStr()
void krk_pushStringBuilderStr | ( | struct StringBuilder * | sb, |
const char * | str, | ||
size_t | len | ||
) |
◆ krk_unpackIterable()
int krk_unpackIterable | ( | KrkValue | iterable, |
void * | context, | ||
int | callbackvoid *, const KrkValue *, size_t | ||
) |
Unpack an iterable.
Unpacks an iterable value, passing a series of arrays of values to a callback, callback
.
If iterable
is a list or tuple, callback
will be called once with the total size of the container. Otherwise, callback
will be called many times with a count of 1, until the iterable is exhausted.
If iterable
is not iterable, an exception is set and 1 is returned. If callback
returns non-zero, unpacking stops and 1 is returned, with no additional exception.
Definition at line 387 of file builtins.c.