Enforce hasKw argument in function signatures for native bindings (so we can stop cheating in wasm)

This commit is contained in:
K. Lange 2021-02-11 19:31:06 +09:00
parent ee50eda05b
commit e6b6fd1f29
21 changed files with 114 additions and 116 deletions

View File

@ -7,11 +7,11 @@
KrkClass * Helper;
KrkClass * LicenseReader;
KrkValue krk_dirObject(int argc, KrkValue argv[]) {
KrkValue krk_dirObject(int argc, KrkValue argv[], int hasKw) {
if (argc != 1) return krk_runtimeError(vm.exceptions->argumentError, "wrong number of arguments or bad type, got %d\n", argc);
/* Create a new list instance */
KrkValue myList = krk_list_of(0,NULL);
KrkValue myList = krk_list_of(0,NULL,0);
krk_push(myList);
if (IS_INSTANCE(argv[0])) {
@ -65,7 +65,7 @@ KrkValue krk_dirObject(int argc, KrkValue argv[]) {
}
static KrkValue _len(int argc, KrkValue argv[]) {
static KrkValue _len(int argc, KrkValue argv[], int hasKw) {
if (argc != 1) return krk_runtimeError(vm.exceptions->argumentError, "len() takes exactly one argument");
/* Shortcuts */
if (IS_STRING(argv[0])) return INTEGER_VAL(AS_STRING(argv[0])->codesLength);
@ -78,17 +78,17 @@ static KrkValue _len(int argc, KrkValue argv[]) {
return krk_callSimple(OBJECT_VAL(type->_len), 1, 0);
}
static KrkValue _dir(int argc, KrkValue argv[]) {
static KrkValue _dir(int argc, KrkValue argv[], int hasKw) {
if (argc != 1) return krk_runtimeError(vm.exceptions->argumentError, "dir() takes exactly one argument");
KrkClass * type = krk_getType(argv[0]);
if (!type->_dir) {
return krk_dirObject(argc,argv); /* Fallback */
return krk_dirObject(argc,argv,hasKw); /* Fallback */
}
krk_push(argv[0]);
return krk_callSimple(OBJECT_VAL(type->_dir), 1, 0);
}
static KrkValue _repr(int argc, KrkValue argv[]) {
static KrkValue _repr(int argc, KrkValue argv[], int hasKw) {
if (argc != 1) return krk_runtimeError(vm.exceptions->argumentError, "repr() takes exactly one argument");
/* Everything should have a __repr__ */
@ -97,7 +97,7 @@ static KrkValue _repr(int argc, KrkValue argv[]) {
return krk_callSimple(OBJECT_VAL(type->_reprer), 1, 0);
}
static KrkValue _ord(int argc, KrkValue argv[]) {
static KrkValue _ord(int argc, KrkValue argv[], int hasKw) {
if (argc != 1) return krk_runtimeError(vm.exceptions->argumentError, "ord() takes exactly one argument");
KrkClass * type = krk_getType(argv[0]);
@ -109,7 +109,7 @@ static KrkValue _ord(int argc, KrkValue argv[]) {
return krk_runtimeError(vm.exceptions->argumentError, "ord() expected string of length 1, but got %s", krk_typeName(argv[0]));
}
static KrkValue _chr(int argc, KrkValue argv[]) {
static KrkValue _chr(int argc, KrkValue argv[], int hasKw) {
if (argc != 1) return krk_runtimeError(vm.exceptions->argumentError, "chr() takes exactly one argument");
KrkClass * type = krk_getType(argv[0]);
@ -121,7 +121,7 @@ static KrkValue _chr(int argc, KrkValue argv[]) {
return krk_runtimeError(vm.exceptions->argumentError, "chr() expected an integer, but got %s", krk_typeName(argv[0]));
}
static KrkValue _hex(int argc, KrkValue argv[]) {
static KrkValue _hex(int argc, KrkValue argv[], int hasKw) {
if (argc != 1 || !IS_INTEGER(argv[0])) return krk_runtimeError(vm.exceptions->argumentError, "hex() expects one int argument");
char tmp[20];
krk_integer_type x = AS_INTEGER(argv[0]);
@ -129,7 +129,7 @@ static KrkValue _hex(int argc, KrkValue argv[]) {
return OBJECT_VAL(krk_copyString(tmp,len));
}
static KrkValue _any(int argc, KrkValue argv[]) {
static KrkValue _any(int argc, KrkValue argv[], int hasKw) {
#define unpackArray(counter, indexer) do { \
for (size_t i = 0; i < counter; ++i) { \
if (!krk_isFalsey(indexer)) return BOOLEAN_VAL(1); \
@ -177,7 +177,7 @@ static KrkValue _any(int argc, KrkValue argv[]) {
return BOOLEAN_VAL(0);
}
static KrkValue _all(int argc, KrkValue argv[]) {
static KrkValue _all(int argc, KrkValue argv[], int hasKw) {
#define unpackArray(counter, indexer) do { \
for (size_t i = 0; i < counter; ++i) { \
if (krk_isFalsey(indexer)) return BOOLEAN_VAL(0); \
@ -264,9 +264,9 @@ static KrkValue _print(int argc, KrkValue argv[], int hasKw) {
*
* Returns a dict of names -> values for all the globals.
*/
static KrkValue _globals(int argc, KrkValue argv[]) {
static KrkValue _globals(int argc, KrkValue argv[], int hasKw) {
/* Make a new empty dict */
KrkValue dict = krk_dict_of(0, NULL);
KrkValue dict = krk_dict_of(0, NULL, 0);
krk_push(dict);
/* Copy the globals table into it */
krk_tableAddAll(krk_currentThread.frames[krk_currentThread.frameCount-1].globals, AS_DICT(dict));
@ -275,14 +275,14 @@ static KrkValue _globals(int argc, KrkValue argv[]) {
return dict;
}
static KrkValue _isinstance(int argc, KrkValue argv[]) {
static KrkValue _isinstance(int argc, KrkValue argv[], int hasKw) {
if (argc != 2) return krk_runtimeError(vm.exceptions->argumentError, "isinstance expects 2 arguments, got %d", argc);
if (!IS_CLASS(argv[1])) return krk_runtimeError(vm.exceptions->typeError, "isinstance() arg 2 must be class");
return BOOLEAN_VAL(krk_isInstanceOf(argv[0], AS_CLASS(argv[1])));
}
static KrkValue _module_repr(int argc, KrkValue argv[]) {
static KrkValue _module_repr(int argc, KrkValue argv[], int hasKw) {
KrkInstance * self = AS_INSTANCE(argv[0]);
KrkValue name = NONE_VAL();
@ -320,7 +320,7 @@ static KrkValue _module_repr(int argc, KrkValue argv[]) {
* all types should have a string representation available through
* those methods.
*/
static KrkValue _strBase(int argc, KrkValue argv[]) {
static KrkValue _strBase(int argc, KrkValue argv[], int hasKw) {
KrkClass * type = krk_getType(argv[0]);
size_t len = sizeof("<instance of . at 0x1234567812345678>") + type->name->length;
char * tmp = malloc(len);
@ -334,7 +334,7 @@ static KrkValue _strBase(int argc, KrkValue argv[]) {
return out;
}
static KrkValue _type(int argc, KrkValue argv[]) {
static KrkValue _type(int argc, KrkValue argv[], int hasKw) {
return OBJECT_VAL(krk_getType(argv[0]));
}

View File

@ -13,7 +13,7 @@
/**
* Exception.__init__(arg)
*/
static KrkValue krk_initException(int argc, KrkValue argv[]) {
static KrkValue krk_initException(int argc, KrkValue argv[], int hasKw) {
KrkInstance * self = AS_INSTANCE(argv[0]);
if (argc > 0) {
@ -25,7 +25,7 @@ static KrkValue krk_initException(int argc, KrkValue argv[]) {
return argv[0];
}
static KrkValue _exception_repr(int argc, KrkValue argv[]) {
static KrkValue _exception_repr(int argc, KrkValue argv[], int hasKw) {
KrkInstance * self = AS_INSTANCE(argv[0]);
/* .arg */
KrkValue arg;
@ -41,7 +41,7 @@ static KrkValue _exception_repr(int argc, KrkValue argv[]) {
}
}
static KrkValue _syntaxerror_repr(int argc, KrkValue argv[]) {
static KrkValue _syntaxerror_repr(int argc, KrkValue argv[], int hasKw) {
KrkInstance * self = AS_INSTANCE(argv[0]);
/* .arg */
KrkValue file, line, lineno, colno, arg, func;

View File

@ -34,13 +34,13 @@
static int enableRline = 1;
static int exitRepl = 0;
static KrkValue exitFunc(int argc, KrkValue argv[]) {
static KrkValue exitFunc(int argc, KrkValue argv[], int hasKw) {
exitRepl = 1;
return NONE_VAL();
}
static int pasteEnabled = 0;
static KrkValue paste(int argc, KrkValue argv[]) {
static KrkValue paste(int argc, KrkValue argv[], int hasKw) {
pasteEnabled = !pasteEnabled;
fprintf(stderr, "Pasting is %s.\n", pasteEnabled ? "enabled" : "disabled");
return NONE_VAL();
@ -151,7 +151,7 @@ static void tab_complete_func(rline_context_t * c) {
/* Take the last symbol name from the chain and get its member list from dir() */
for (;;) {
KrkValue dirList = krk_dirObject(1,(KrkValue[]){root});
KrkValue dirList = krk_dirObject(1,(KrkValue[]){root},0);
krk_push(dirList);
if (!IS_INSTANCE(dirList)) {
fprintf(stderr,"\nInternal error while tab completting.\n");
@ -453,7 +453,7 @@ _finishArgs:
for (int arg = optind; arg < argc; ++arg) {
krk_push(OBJECT_VAL(krk_copyString(argv[arg],strlen(argv[arg]))));
}
KrkValue argList = krk_list_of(argc - optind + (optind == argc), &krk_currentThread.stackTop[-(argc - optind + (optind == argc))]);
KrkValue argList = krk_list_of(argc - optind + (optind == argc), &krk_currentThread.stackTop[-(argc - optind + (optind == argc))],0);
krk_push(argList);
krk_attachNamedValue(&vm.system->fields, "argv", argList);
krk_pop();

View File

@ -293,12 +293,12 @@ size_t krk_collectGarbage(void) {
return out;
}
static KrkValue krk_collectGarbage_wrapper(int argc, KrkValue argv[]) {
static KrkValue krk_collectGarbage_wrapper(int argc, KrkValue argv[], int hasKw) {
if (&krk_currentThread != vm.threads) return krk_runtimeError(vm.exceptions->valueError, "only the main thread can do that");
return INTEGER_VAL(krk_collectGarbage());
}
static KrkValue krk_generations(int argc, KrkValue argv[]) {
static KrkValue krk_generations(int argc, KrkValue argv[], int hasKw) {
#define MAX_GEN 4
krk_integer_type generations[MAX_GEN] = {0,0,0,0};
KrkObj * object = vm.objects;
@ -316,12 +316,12 @@ static KrkValue krk_generations(int argc, KrkValue argv[]) {
return OBJECT_VAL(outTuple);
}
static KrkValue _gc_pause(int argc, KrkValue argv[]) {
static KrkValue _gc_pause(int argc, KrkValue argv[], int hasKw) {
vm.globalFlags |= (KRK_GC_PAUSED);
return NONE_VAL();
}
static KrkValue _gc_resume(int argc, KrkValue argv[]) {
static KrkValue _gc_resume(int argc, KrkValue argv[], int hasKw) {
vm.globalFlags &= ~(KRK_GC_PAUSED);
return NONE_VAL();
}

View File

@ -17,7 +17,7 @@
/**
* dis.dis(object)
*/
static KrkValue krk_dis(int argc, KrkValue argv[]) {
static KrkValue krk_dis(int argc, KrkValue argv[], int hasKw) {
if (argc < 1) {
krk_runtimeError(vm.exceptions->argumentError, "dis() takes ");
return BOOLEAN_VAL(0);

View File

@ -142,7 +142,7 @@ _finish_line: (void)0;
KRK_METHOD(File,readlines,{
METHOD_TAKES_NONE();
KrkValue myList = krk_list_of(0,NULL);
KrkValue myList = krk_list_of(0,NULL,0);
krk_push(myList);
for (;;) {
@ -303,7 +303,7 @@ _finish_line: (void)0;
KRK_METHOD(BinaryFile,readlines,{
METHOD_TAKES_NONE();
KrkValue myList = krk_list_of(0,NULL);
KrkValue myList = krk_list_of(0,NULL,0);
krk_push(myList);
for (;;) {
@ -427,7 +427,7 @@ KRK_METHOD(Directory,__call__,{
struct dirent * entry = readdir(self->dirPtr);
if (!entry) return argv[0];
KrkValue outDict = krk_dict_of(0, NULL);
KrkValue outDict = krk_dict_of(0, NULL, 0);
krk_push(outDict);
krk_attachNamedValue(AS_DICT(outDict), "name", OBJECT_VAL(krk_copyString(entry->d_name,strlen(entry->d_name))));

View File

@ -39,7 +39,7 @@
}
#define MATH_DELEGATE(func) \
static KrkValue _math_ ## func(int argc, KrkValue argv[]) { \
static KrkValue _math_ ## func(int argc, KrkValue argv[], int hasKw) { \
ONE_ARGUMENT(func) \
if (IS_FLOATING(argv[0])) { \
return INTEGER_VAL(func(AS_FLOATING(argv[0]))); \
@ -60,7 +60,7 @@ MATH_DELEGATE(trunc)
#endif
#define MATH_ONE_NAME(func,name) \
static KrkValue _math_ ## name(int argc, KrkValue argv[]) { \
static KrkValue _math_ ## name(int argc, KrkValue argv[], int hasKw) { \
ONE_ARGUMENT(name) \
FORCE_FLOAT(argv[0]) \
if (IS_FLOATING(argv[0])) { \
@ -101,7 +101,7 @@ MATH_ONE(lgamma)
MATH_ONE_NAME(log,log1p)
#define MATH_TWO(func) \
static KrkValue _math_ ## func(int argc, KrkValue argv[]) { \
static KrkValue _math_ ## func(int argc, KrkValue argv[], int hasKw) { \
TWO_ARGUMENTS(func) \
FORCE_FLOAT(argv[0]) \
FORCE_FLOAT(argv[1]) \
@ -120,7 +120,7 @@ MATH_TWO(remainder)
MATH_TWO(pow)
MATH_TWO(atan2)
static KrkValue _math_frexp(int argc, KrkValue argv[]) {
static KrkValue _math_frexp(int argc, KrkValue argv[], int hasKw) {
ONE_ARGUMENT(frexp)
FORCE_FLOAT(argv[0])
if (!IS_FLOATING(argv[0])) {
@ -136,7 +136,7 @@ static KrkValue _math_frexp(int argc, KrkValue argv[]) {
}
#define MATH_IS(func) \
static KrkValue _math_ ## func(int argc, KrkValue argv[]) { \
static KrkValue _math_ ## func(int argc, KrkValue argv[], int hasKw) { \
ONE_ARGUMENT(func) \
if (!IS_FLOATING(argv[0])) REAL_NUMBER_NOT(func,argv[0]) \
return BOOLEAN_VAL(func(AS_FLOATING(argv[0]))); \

View File

@ -31,7 +31,7 @@ KRK_FUNC(uname,{
struct utsname buf;
if (uname(&buf) < 0) return NONE_VAL();
KrkValue result = krk_dict_of(0, NULL);
KrkValue result = krk_dict_of(0, NULL, 0);
krk_push(result);
DO_KEY(sysname);
@ -44,7 +44,7 @@ KRK_FUNC(uname,{
})
#else
KRK_FUNC(uname,{
KrkValue result = krk_dict_of(0, NULL);
KrkValue result = krk_dict_of(0, NULL, 0);
krk_push(result);
TCHAR buffer[256] = TEXT("");
@ -90,7 +90,7 @@ KRK_FUNC(uname,{
KrkClass * environClass;
KrkValue krk_os_setenviron(int argc, KrkValue argv[]) {
KrkValue krk_os_setenviron(int argc, KrkValue argv[], int hasKw) {
if (argc < 3 || !krk_isInstanceOf(argv[0], environClass) ||
!IS_STRING(argv[1]) || !IS_STRING(argv[2])) {
return krk_runtimeError(vm.exceptions->argumentError, "Invalid arguments to environ.__set__");
@ -110,7 +110,7 @@ KrkValue krk_os_setenviron(int argc, KrkValue argv[]) {
}
}
KrkValue krk_os_unsetenviron(int argc, KrkValue argv[]) {
KrkValue krk_os_unsetenviron(int argc, KrkValue argv[], int hasKw) {
if (argc < 2 || !krk_isInstanceOf(argv[0], environClass) ||
!IS_STRING(argv[1])) {
return krk_runtimeError(vm.exceptions->argumentError, "Invalid arguments to environ.__delitem__");
@ -142,7 +142,7 @@ static void _loadEnviron(KrkInstance * module) {
krk_finalizeClass(environClass);
/* Start with an empty dictionary */
KrkInstance * environObj = AS_INSTANCE(krk_dict_of(0,NULL));
KrkInstance * environObj = AS_INSTANCE(krk_dict_of(0,NULL,0));
krk_push(OBJECT_VAL(environObj));
/* Transform it into an _Environ */

View File

@ -17,7 +17,7 @@
/**
* system.sleep(seconds)
*/
static KrkValue _time_sleep(int argc, KrkValue argv[]) {
static KrkValue _time_sleep(int argc, KrkValue argv[], int hasKw) {
if (argc < 1) {
krk_runtimeError(vm.exceptions->argumentError, "sleep: expect at least one argument.");
return BOOLEAN_VAL(0);
@ -33,7 +33,7 @@ static KrkValue _time_sleep(int argc, KrkValue argv[]) {
return BOOLEAN_VAL(1);
}
static KrkValue _time_time(int argc, KrkValue argv[]) {
static KrkValue _time_time(int argc, KrkValue argv[], int hasKw) {
time_t out = time(NULL);
return FLOATING_VAL(out); /* TODO actually support subsecond values */
}

View File

@ -4,37 +4,37 @@
#include "memory.h"
#include "util.h"
static KrkValue _type_init(int argc, KrkValue argv[]) {
static KrkValue _type_init(int argc, KrkValue argv[], int hasKw) {
if (argc != 2) return krk_runtimeError(vm.exceptions->argumentError, "type() takes 1 argument");
return OBJECT_VAL(krk_getType(argv[1]));
}
/* Class.__base__ */
static KrkValue krk_baseOfClass(int argc, KrkValue argv[]) {
static KrkValue krk_baseOfClass(int argc, KrkValue argv[], int hasKw) {
if (!IS_CLASS(argv[0])) return krk_runtimeError(vm.exceptions->typeError, "expected class");
return AS_CLASS(argv[0])->base ? OBJECT_VAL(AS_CLASS(argv[0])->base) : NONE_VAL();
}
/* Class.__name */
static KrkValue krk_nameOfClass(int argc, KrkValue argv[]) {
static KrkValue krk_nameOfClass(int argc, KrkValue argv[], int hasKw) {
if (!IS_CLASS(argv[0])) return krk_runtimeError(vm.exceptions->typeError, "expected class");
return AS_CLASS(argv[0])->name ? OBJECT_VAL(AS_CLASS(argv[0])->name) : NONE_VAL();
}
/* Class.__file__ */
static KrkValue krk_fileOfClass(int argc, KrkValue argv[]) {
static KrkValue krk_fileOfClass(int argc, KrkValue argv[], int hasKw) {
if (!IS_CLASS(argv[0])) return krk_runtimeError(vm.exceptions->typeError, "expected class");
return AS_CLASS(argv[0])->filename ? OBJECT_VAL(AS_CLASS(argv[0])->filename) : NONE_VAL();
}
/* Class.__doc__ */
static KrkValue krk_docOfClass(int argc, KrkValue argv[]) {
static KrkValue krk_docOfClass(int argc, KrkValue argv[], int hasKw) {
if (!IS_CLASS(argv[0])) return krk_runtimeError(vm.exceptions->typeError, "expected class");
return AS_CLASS(argv[0])->docstring ? OBJECT_VAL(AS_CLASS(argv[0])->docstring) : NONE_VAL();
}
/* Class.__str__() (and Class.__repr__) */
static KrkValue _class_to_str(int argc, KrkValue argv[]) {
static KrkValue _class_to_str(int argc, KrkValue argv[], int hasKw) {
if (!IS_CLASS(argv[0])) return krk_runtimeError(vm.exceptions->typeError, "expected class");
char * tmp = malloc(sizeof("<type ''>") + AS_CLASS(argv[0])->name->length);
size_t l = sprintf(tmp, "<type '%s'>", AS_CLASS(argv[0])->name->chars);

View File

@ -4,7 +4,7 @@
#include "memory.h"
#include "util.h"
static KrkValue _bytes_init(int argc, KrkValue argv[]) {
static KrkValue _bytes_init(int argc, KrkValue argv[], int hasKw) {
if (argc == 1) {
return OBJECT_VAL(krk_newBytes(0,NULL));
}
@ -26,7 +26,7 @@ static KrkValue _bytes_init(int argc, KrkValue argv[]) {
}
/* bytes objects are not interned; need to do this the old-fashioned way. */
static KrkValue _bytes_eq(int argc, KrkValue argv[]) {
static KrkValue _bytes_eq(int argc, KrkValue argv[], int hasKw) {
if (!IS_BYTES(argv[1])) return BOOLEAN_VAL(0);
KrkBytes * self = AS_BYTES(argv[0]);
KrkBytes * them = AS_BYTES(argv[1]);
@ -44,7 +44,7 @@ static KrkValue _bytes_eq(int argc, KrkValue argv[]) {
} stringBytes[stringLength++] = c; } while (0)
#define AT_END() (self->length == 0 || i == self->length - 1)
static KrkValue _bytes_repr(int argc, KrkValue argv[]) {
static KrkValue _bytes_repr(int argc, KrkValue argv[], int hasKw) {
size_t stringCapacity = 0;
size_t stringLength = 0;
char * stringBytes = NULL;
@ -87,7 +87,7 @@ static KrkValue _bytes_repr(int argc, KrkValue argv[]) {
return tmp;
}
static KrkValue _bytes_get(int argc, KrkValue argv[]) {
static KrkValue _bytes_get(int argc, KrkValue argv[], int hasKw) {
if (argc < 2) return krk_runtimeError(vm.exceptions->argumentError, "bytes.__get__(): expected one argument");
KrkBytes * self = AS_BYTES(argv[0]);
long asInt = AS_INTEGER(argv[1]);
@ -100,16 +100,16 @@ static KrkValue _bytes_get(int argc, KrkValue argv[]) {
return INTEGER_VAL(self->bytes[asInt]);
}
static KrkValue _bytes_len(int argc, KrkValue argv[]) {
static KrkValue _bytes_len(int argc, KrkValue argv[], int hasKw) {
return INTEGER_VAL(AS_BYTES(argv[0])->length);
}
static KrkValue _bytes_contains(int argc, KrkValue argv[]) {
static KrkValue _bytes_contains(int argc, KrkValue argv[], int hasKw) {
if (argc < 2) krk_runtimeError(vm.exceptions->argumentError, "bytes.__contains__(): expected one argument");
return krk_runtimeError(vm.exceptions->notImplementedError, "not implemented");
}
static KrkValue _bytes_decode(int argc, KrkValue argv[]) {
static KrkValue _bytes_decode(int argc, KrkValue argv[], int hasKw) {
/* TODO: Actually bother checking if this explodes, or support other encodings... */
return OBJECT_VAL(krk_copyString((char*)AS_BYTES(argv[0])->bytes, AS_BYTES(argv[0])->length));
}

View File

@ -15,7 +15,7 @@
* Exposed method called to produce dictionaries from {expr: expr, ...} sequences in managed code.
* Presented in the global namespace as dictOf(...). Expects arguments as key,value,key,value...
*/
KrkValue krk_dict_of(int argc, KrkValue argv[]) {
KrkValue krk_dict_of(int argc, KrkValue argv[], int hasKw) {
if (argc % 2 != 0) return krk_runtimeError(vm.exceptions->argumentError, "Expected even number of arguments to dictOf");
KrkInstance * outDict = krk_newInstance(vm.baseClasses->dictClass);
krk_push(OBJECT_VAL(outDict));
@ -59,7 +59,7 @@ KRK_METHOD(dict,__set__,{
KRK_METHOD(dict,__or__,{
METHOD_TAKES_EXACTLY(1);
CHECK_ARG(1,dict,KrkDict*,them);
KrkValue outDict = krk_dict_of(0,NULL);
KrkValue outDict = krk_dict_of(0,NULL,0);
krk_push(outDict);
krk_tableAddAll(&self->entries, AS_DICT(outDict));
krk_tableAddAll(&them->entries, AS_DICT(outDict));
@ -134,7 +134,7 @@ KRK_METHOD(dict,__repr__,{
KRK_METHOD(dict,copy,{
METHOD_TAKES_NONE();
KrkValue dictOut = krk_dict_of(0,NULL);
KrkValue dictOut = krk_dict_of(0,NULL,0);
krk_push(dictOut);
krk_tableAddAll(&self->entries, AS_DICT(dictOut));
return krk_pop();

View File

@ -5,7 +5,7 @@
#include "util.h"
/* function.__doc__ */
static KrkValue _closure_get_doc(int argc, KrkValue argv[]) {
static KrkValue _closure_get_doc(int argc, KrkValue argv[], int hasKw) {
if (IS_NATIVE(argv[0]) && AS_NATIVE(argv[0])->doc) {
return OBJECT_VAL(krk_copyString(AS_NATIVE(argv[0])->doc, strlen(AS_NATIVE(argv[0])->doc)));
} else if (IS_CLOSURE(argv[0]) && AS_CLOSURE(argv[0])->function->docstring) {
@ -16,9 +16,9 @@ static KrkValue _closure_get_doc(int argc, KrkValue argv[]) {
}
/* method.__doc__ */
static KrkValue _bound_get_doc(int argc, KrkValue argv[]) {
static KrkValue _bound_get_doc(int argc, KrkValue argv[], int hasKw) {
KrkBoundMethod * boundMethod = AS_BOUND_METHOD(argv[0]);
return _closure_get_doc(1, (KrkValue[]){OBJECT_VAL(boundMethod->method)});
return _closure_get_doc(1, (KrkValue[]){OBJECT_VAL(boundMethod->method)}, 0);
}
/* Check for and return the name of a native function as a string object */
@ -29,20 +29,20 @@ static KrkValue nativeFunctionName(KrkValue func) {
}
/* function.__name__ */
static KrkValue _closure_get_name(int argc, KrkValue argv[]) {
static KrkValue _closure_get_name(int argc, KrkValue argv[], int hasKw) {
if (!IS_CLOSURE(argv[0])) return nativeFunctionName(argv[0]);
return AS_CLOSURE(argv[0])->function->name ? OBJECT_VAL(AS_CLOSURE(argv[0])->function->name) : OBJECT_VAL(S(""));
}
/* method.__name__ */
static KrkValue _bound_get_name(int argc, KrkValue argv[]) {
static KrkValue _bound_get_name(int argc, KrkValue argv[], int hasKw) {
KrkBoundMethod * boundMethod = AS_BOUND_METHOD(argv[0]);
return _closure_get_name(1, (KrkValue[]){OBJECT_VAL(boundMethod->method)});
return _closure_get_name(1, (KrkValue[]){OBJECT_VAL(boundMethod->method)}, hasKw);
}
/* function.__str__ / function.__repr__ */
static KrkValue _closure_str(int argc, KrkValue argv[]) {
KrkValue s = _closure_get_name(argc, argv);
static KrkValue _closure_str(int argc, KrkValue argv[], int hasKw) {
KrkValue s = _closure_get_name(argc, argv, hasKw);
krk_push(s);
size_t len = AS_STRING(s)->length + sizeof("<function >");
@ -55,8 +55,8 @@ static KrkValue _closure_str(int argc, KrkValue argv[]) {
}
/* method.__str__ / method.__repr__ */
static KrkValue _bound_str(int argc, KrkValue argv[]) {
KrkValue s = _bound_get_name(argc, argv);
static KrkValue _bound_str(int argc, KrkValue argv[], int hasKw) {
KrkValue s = _bound_get_name(argc, argv, hasKw);
krk_push(s);
const char * typeName = krk_typeName(AS_BOUND_METHOD(argv[0])->receiver);
@ -71,19 +71,19 @@ static KrkValue _bound_str(int argc, KrkValue argv[]) {
}
/* function.__file__ */
static KrkValue _closure_get_file(int argc, KrkValue argv[]) {
static KrkValue _closure_get_file(int argc, KrkValue argv[], int hasKw) {
if (!IS_CLOSURE(argv[0])) return OBJECT_VAL(S("<builtin>"));
return AS_CLOSURE(argv[0])->function->chunk.filename ? OBJECT_VAL(AS_CLOSURE(argv[0])->function->chunk.filename) : OBJECT_VAL(S(""));
}
/* method.__file__ */
static KrkValue _bound_get_file(int argc, KrkValue argv[]) {
static KrkValue _bound_get_file(int argc, KrkValue argv[], int hasKw) {
KrkBoundMethod * boundMethod = AS_BOUND_METHOD(argv[0]);
return _closure_get_file(1, (KrkValue[]){OBJECT_VAL(boundMethod->method)});
return _closure_get_file(1, (KrkValue[]){OBJECT_VAL(boundMethod->method)}, 0);
}
/* function.__args__ */
static KrkValue _closure_get_argnames(int argc, KrkValue argv[]) {
static KrkValue _closure_get_argnames(int argc, KrkValue argv[], int hasKw) {
if (!IS_CLOSURE(argv[0])) return OBJECT_VAL(krk_newTuple(0));
KrkFunction * self = AS_CLOSURE(argv[0])->function;
KrkTuple * tuple = krk_newTuple(self->requiredArgs + self->keywordArgs);
@ -98,9 +98,9 @@ static KrkValue _closure_get_argnames(int argc, KrkValue argv[]) {
return OBJECT_VAL(tuple);
}
static KrkValue _bound_get_argnames(int argc, KrkValue argv[]) {
static KrkValue _bound_get_argnames(int argc, KrkValue argv[], int hasKw) {
KrkBoundMethod * boundMethod = AS_BOUND_METHOD(argv[0]);
return _closure_get_argnames(1, (KrkValue[]){OBJECT_VAL(boundMethod->method)});
return _closure_get_argnames(1, (KrkValue[]){OBJECT_VAL(boundMethod->method)}, 0);
}

View File

@ -28,7 +28,7 @@ static void _list_gcsweep(KrkInstance * self) {
* Exposed method called to produce lists from [expr,...] sequences in managed code.
* Presented in the global namespace as listOf(...)
*/
KrkValue krk_list_of(int argc, KrkValue argv[]) {
KrkValue krk_list_of(int argc, KrkValue argv[], int hasKw) {
KrkValue outList = OBJECT_VAL(krk_newInstance(vm.baseClasses->listClass));
krk_push(outList);
krk_initValueArray(AS_LIST(outList));
@ -184,7 +184,7 @@ KRK_METHOD(list,__mul__,{
METHOD_TAKES_EXACTLY(1);
CHECK_ARG(1,int,krk_integer_type,howMany);
KrkValue out = krk_list_of(0, NULL);
KrkValue out = krk_list_of(0, NULL, 0);
krk_push(out);
@ -225,7 +225,7 @@ KRK_METHOD(list,__getslice__,{
if (end < start) end = start;
krk_integer_type len = end - start;
KrkValue result = krk_list_of(len, &AS_LIST(argv[0])->values[start]);
KrkValue result = krk_list_of(len, &AS_LIST(argv[0])->values[start], 0);
pthread_rwlock_unlock(&self->rwlock);
return result;
})
@ -379,7 +379,7 @@ KRK_METHOD(list,count,{
KRK_METHOD(list,copy,{
METHOD_TAKES_NONE();
pthread_rwlock_rdlock(&self->rwlock);
KrkValue result = krk_list_of(self->values.count, self->values.values);
KrkValue result = krk_list_of(self->values.count, self->values.values, 0);
pthread_rwlock_unlock(&self->rwlock);
return result;
})
@ -420,7 +420,7 @@ KRK_METHOD(list,__add__,{
if (!IS_list(argv[1])) return TYPE_ERROR(list,argv[1]);
pthread_rwlock_rdlock(&self->rwlock);
KrkValue outList = krk_list_of(self->values.count, self->values.values); /* copy */
KrkValue outList = krk_list_of(self->values.count, self->values.values, 0); /* copy */
pthread_rwlock_unlock(&self->rwlock);
FUNC_NAME(list,extend)(2,(KrkValue[]){outList,argv[1]},0); /* extend */
return outList;
@ -482,7 +482,7 @@ _corrupt:
static KrkValue _sorted(int argc, KrkValue argv[], int hasKw) {
if (argc != 1) return krk_runtimeError(vm.exceptions->argumentError,"%s() takes %s %d argument%s (%d given)","sorted","exactly",1,argc);
KrkValue listOut = krk_list_of(0,NULL);
KrkValue listOut = krk_list_of(0,NULL,0);
krk_push(listOut);
FUNC_NAME(list,extend)(2,(KrkValue[]){listOut,argv[0]},0);
if (!IS_NONE(krk_currentThread.currentException)) return NONE_VAL();

View File

@ -10,7 +10,7 @@ struct Range {
krk_integer_type max;
};
static KrkValue _range_init(int argc, KrkValue argv[]) {
static KrkValue _range_init(int argc, KrkValue argv[], int hasKw) {
KrkInstance * self = AS_INSTANCE(argv[0]);
if (argc < 2 || argc > 3) {
return krk_runtimeError(vm.exceptions->argumentError, "range expected at least 1 and and at most 2 arguments");
@ -36,7 +36,7 @@ static KrkValue _range_init(int argc, KrkValue argv[]) {
return argv[0];
}
static KrkValue _range_repr(int argc, KrkValue argv[]) {
static KrkValue _range_repr(int argc, KrkValue argv[], int hasKw) {
KrkInstance * self = AS_INSTANCE(argv[0]);
krk_integer_type min = ((struct Range*)self)->min;
@ -54,7 +54,7 @@ struct RangeIterator {
krk_integer_type max;
};
static KrkValue _rangeiterator_init(int argc, KrkValue argv[]) {
static KrkValue _rangeiterator_init(int argc, KrkValue argv[], int hasKw) {
KrkInstance * self = AS_INSTANCE(argv[0]);
((struct RangeIterator*)self)->i = AS_INTEGER(argv[1]);
@ -63,7 +63,7 @@ static KrkValue _rangeiterator_init(int argc, KrkValue argv[]) {
return argv[0];
}
static KrkValue _rangeiterator_call(int argc, KrkValue argv[]) {
static KrkValue _rangeiterator_call(int argc, KrkValue argv[], int hasKw) {
KrkInstance * self = AS_INSTANCE(argv[0]);
krk_integer_type i, max;
@ -78,7 +78,7 @@ static KrkValue _rangeiterator_call(int argc, KrkValue argv[]) {
}
}
static KrkValue _range_iter(int argc, KrkValue argv[]) {
static KrkValue _range_iter(int argc, KrkValue argv[], int hasKw) {
KrkInstance * self = AS_INSTANCE(argv[0]);
KrkInstance * output = krk_newInstance(vm.baseClasses->rangeiteratorClass);
@ -86,7 +86,7 @@ static KrkValue _range_iter(int argc, KrkValue argv[]) {
krk_integer_type max = ((struct Range*)self)->max;
krk_push(OBJECT_VAL(output));
_rangeiterator_init(3, (KrkValue[]){krk_peek(0), INTEGER_VAL(min), INTEGER_VAL(max)});
_rangeiterator_init(3, (KrkValue[]){krk_peek(0), INTEGER_VAL(min), INTEGER_VAL(max)},0);
krk_pop();
return OBJECT_VAL(output);

View File

@ -225,7 +225,7 @@ KRK_METHOD(setiterator,__call__,{
} while (1);
})
KrkValue krk_set_of(int argc, KrkValue argv[]) {
KrkValue krk_set_of(int argc, KrkValue argv[], int hasKw) {
KrkValue outSet = OBJECT_VAL(krk_newInstance(set));
krk_push(outSet);
krk_initTable(&AS_set(outSet)->entries);

View File

@ -502,7 +502,7 @@ KRK_METHOD(str,split,{
}
}
KrkValue myList = krk_list_of(0,NULL);
KrkValue myList = krk_list_of(0,NULL,0);
krk_push(myList);
size_t i = 0;

View File

@ -8,12 +8,12 @@
if (index < 0) index += self->values.count; \
if (index < 0 || index >= (krk_integer_type)self->values.count) return krk_runtimeError(vm.exceptions->indexError, "tuple index out of range: " PRIkrk_int, index)
static KrkValue _tuple_init(int argc, KrkValue argv[]) {
static KrkValue _tuple_init(int argc, KrkValue argv[], int hasKw) {
return krk_runtimeError(vm.exceptions->typeError,"tuple() initializier unsupported");
}
/* tuple creator */
static KrkValue _tuple_of(int argc, KrkValue argv[]) {
static KrkValue _tuple_of(int argc, KrkValue argv[], int hasKw) {
KrkTuple * self = krk_newTuple(argc);
krk_push(OBJECT_VAL(self));
for (size_t i = 0; i < (size_t)argc; ++i) {
@ -23,7 +23,7 @@ static KrkValue _tuple_of(int argc, KrkValue argv[]) {
return OBJECT_VAL(self);
}
KrkValue krk_tuple_of(int argc, KrkValue argv[]) __attribute__((alias("_tuple_of")));
KrkValue krk_tuple_of(int argc, KrkValue argv[], int hasKw) __attribute__((alias("_tuple_of")));
#define IS_tuple(o) IS_TUPLE(o)
#define AS_tuple(o) AS_TUPLE(o)
@ -96,7 +96,7 @@ struct TupleIter {
int i;
};
static KrkValue _tuple_iter_init(int argc, KrkValue argv[]) {
static KrkValue _tuple_iter_init(int argc, KrkValue argv[], int hasKw) {
struct TupleIter * self = (struct TupleIter *)AS_OBJECT(argv[0]);
self->myTuple = argv[1];
self->i = 0;
@ -107,7 +107,7 @@ static void _tuple_iter_gcscan(KrkInstance * self) {
krk_markValue(((struct TupleIter*)self)->myTuple);
}
static KrkValue _tuple_iter_call(int argc, KrkValue argv[]) {
static KrkValue _tuple_iter_call(int argc, KrkValue argv[], int hasKw) {
struct TupleIter * self = (struct TupleIter *)AS_OBJECT(argv[0]);
KrkValue t = self->myTuple; /* Tuple to iterate */
int i = self->i;
@ -122,7 +122,7 @@ static KrkValue _tuple_iter_call(int argc, KrkValue argv[]) {
KRK_METHOD(tuple,__iter__,{
KrkInstance * output = krk_newInstance(vm.baseClasses->tupleiteratorClass);
krk_push(OBJECT_VAL(output));
_tuple_iter_init(2, (KrkValue[]){krk_peek(0), argv[0]});
_tuple_iter_init(2, (KrkValue[]){krk_peek(0), argv[0]}, 0);
krk_pop();
return OBJECT_VAL(output);
})

View File

@ -170,8 +170,7 @@ typedef struct {
KrkObj * method;
} KrkBoundMethod;
typedef KrkValue (*NativeFn)();
typedef KrkValue (*NativeFnKw)(int argCount, KrkValue* args, int hasKwargs);
typedef KrkValue (*NativeFn)(int argCount, KrkValue* args, int hasKwargs);
typedef struct {
KrkObj obj;
NativeFn function;

View File

@ -628,9 +628,9 @@ static int call(KrkClosure * closure, int argCount, int extra) {
if (argCount && IS_KWARGS(krk_currentThread.stackTop[-1])) {
KrkValue myList = krk_list_of(0,NULL);
KrkValue myList = krk_list_of(0,NULL,0);
krk_currentThread.scratchSpace[0] = myList;
KrkValue myDict = krk_dict_of(0,NULL);
KrkValue myDict = krk_dict_of(0,NULL,0);
krk_currentThread.scratchSpace[1] = myDict;
positionals = AS_LIST(myList);
keywords = AS_DICT(myDict);
@ -670,7 +670,7 @@ static int call(KrkClosure * closure, int argCount, int extra) {
if (closure->function->collectsArguments) {
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));
krk_push(krk_list_of(count, offset, 0));
argCount++;
}
@ -721,7 +721,7 @@ _finishKwarg:
/* If this function takes a **kwargs, we need to provide it as a dict */
if (closure->function->collectsKeywords) {
krk_push(krk_dict_of(0,NULL));
krk_push(krk_dict_of(0,NULL,0));
argCount++;
krk_tableAddAll(keywords, AS_DICT(krk_peek(0)));
}
@ -744,7 +744,7 @@ _finishKwarg:
if ((size_t)argCount > potentialPositionalArgs && closure->function->collectsArguments) {
krk_push(NONE_VAL()); krk_push(NONE_VAL()); krk_pop(); krk_pop();
startOfPositionals[offsetOfExtraArgs] = krk_list_of(argCount - potentialPositionalArgs,
&startOfPositionals[potentialPositionalArgs]);
&startOfPositionals[potentialPositionalArgs], 0);
argCount = closure->function->requiredArgs + 1;
argCountX = argCount - 1;
while (krk_currentThread.stackTop > startOfPositionals + argCount) krk_pop();
@ -804,11 +804,11 @@ int krk_callValue(KrkValue callee, int argCount, int extra) {
case OBJ_CLOSURE:
return call(AS_CLOSURE(callee), argCount, extra);
case OBJ_NATIVE: {
NativeFnKw native = (NativeFnKw)AS_NATIVE(callee)->function;
NativeFn native = (NativeFn)AS_NATIVE(callee)->function;
if (argCount && IS_KWARGS(krk_currentThread.stackTop[-1])) {
KrkValue myList = krk_list_of(0,NULL);
KrkValue myList = krk_list_of(0,NULL,0);
krk_currentThread.scratchSpace[0] = myList;
KrkValue myDict = krk_dict_of(0,NULL);
KrkValue myDict = krk_dict_of(0,NULL,0);
krk_currentThread.scratchSpace[1] = myDict;
if (!krk_processComplexArguments(argCount, AS_LIST(myList), AS_DICT(myDict))) {
return 0;
@ -902,7 +902,7 @@ int krk_bindMethod(KrkClass * _class, KrkString * name) {
KrkValue method, out;
if (!krk_tableGet(&_class->methods, OBJECT_VAL(name), &method)) return 0;
if (IS_NATIVE(method) && ((KrkNative*)AS_OBJECT(method))->isMethod == 2) {
out = AS_NATIVE(method)->function(1, (KrkValue[]){krk_peek(0)});
out = AS_NATIVE(method)->function(1, (KrkValue[]){krk_peek(0)}, 0);
} else {
out = OBJECT_VAL(krk_newBoundMethod(krk_peek(0), AS_OBJECT(method)));
}
@ -1009,7 +1009,7 @@ int krk_isFalsey(KrkValue value) {
return 0; /* Assume anything else is truthy */
}
static KrkValue krk_getsize(int argc, KrkValue argv[]) {
static KrkValue krk_getsize(int argc, KrkValue argv[], int hasKw) {
if (argc < 1) return INTEGER_VAL(0);
if (!IS_OBJECT(argv[0])) return INTEGER_VAL(sizeof(KrkValue));
size_t mySize = sizeof(KrkValue);
@ -1071,7 +1071,7 @@ static KrkValue krk_getsize(int argc, KrkValue argv[]) {
return INTEGER_VAL(mySize);
}
static KrkValue krk_setclean(int argc, KrkValue argv[]) {
static KrkValue krk_setclean(int argc, KrkValue argv[], int hasKw) {
if (!argc || (IS_BOOLEAN(argv[0]) && AS_BOOLEAN(argv[0]))) {
vm.globalFlags |= KRK_CLEAN_OUTPUT;
} else {
@ -1185,7 +1185,7 @@ void krk_initVM(int flags) {
krk_defineNative(&vm.system->fields, "set_clean_output", krk_setclean);
krk_defineNative(&vm.system->fields, "set_tracing", krk_set_tracing)->doc = "Toggle debugging modes.";
krk_attachNamedObject(&vm.system->fields, "path_sep", (KrkObj*)S(PATH_SEP));
KrkValue module_paths = krk_list_of(0,NULL);
KrkValue module_paths = krk_list_of(0,NULL,0);
krk_attachNamedValue(&vm.system->fields, "module_paths", module_paths);
krk_writeValueArray(AS_LIST(module_paths), OBJECT_VAL(S("./")));
if (vm.binpath) {
@ -2199,7 +2199,7 @@ static KrkValue run() {
case OP_TUPLE: {
size_t count = readBytes(frame, operandWidth);
krk_reserve_stack(4);
KrkValue tuple = krk_tuple_of(count,&krk_currentThread.stackTop[-count]);
KrkValue tuple = krk_tuple_of(count,&krk_currentThread.stackTop[-count],0);
if (count) {
krk_currentThread.stackTop[-count] = tuple;
while (count > 1) {

View File

@ -190,14 +190,15 @@ extern int krk_isInstanceOf(KrkValue obj, KrkClass * type);
extern int krk_bindMethod(KrkClass * _class, KrkString * name);
extern int krk_callValue(KrkValue callee, int argCount, int extra);
extern KrkValue krk_list_of(int argc, KrkValue argv[]);
extern KrkValue krk_dict_of(int argc, KrkValue argv[]);
extern KrkValue krk_list_of(int argc, KrkValue argv[], int hasKw);
extern KrkValue krk_dict_of(int argc, KrkValue argv[], int hasKw);
extern KrkValue krk_tuple_of(int argc, KrkValue argv[], int hasKw);
extern KrkValue krk_callSimple(KrkValue value, int argCount, int isMethod);
extern KrkClass * krk_makeClass(KrkInstance * module, KrkClass ** _class, const char * name, KrkClass * base);
extern void krk_finalizeClass(KrkClass * _class);
extern void krk_dumpTraceback();
extern KrkInstance * krk_startModule(const char * name);
extern KrkValue krk_dirObject(int argc, KrkValue argv[]);
extern KrkValue krk_dirObject(int argc, KrkValue argv[], int hasKw);
extern int krk_loadModule(KrkString * name, KrkValue * moduleOut, KrkString * runAs);
/* obj_str.h */
@ -211,8 +212,6 @@ extern KrkValue krk_string_format(int argc, KrkValue argv[], int hasKw);
/* obj_dict.h */
extern KrkValue krk_dict_nth_key_fast(size_t capacity, KrkTableEntry * entries, size_t index);
extern KrkValue krk_tuple_of(int argc, KrkValue argv[]);
extern int krk_isFalsey(KrkValue value);
extern void _createAndBind_numericClasses(void);