# HG changeset patch # User Paul Boddie # Date 1693266383 -7200 # Node ID 0be4f390513d27d3680955f20d7b75aaf6dd6813 # Parent 1e7ccc84119f6b71d82aaf2d697627364b8b711f Permit the replacement of floating-point values in locally-referenced objects. To achieve this, a result target parameter has been introduced in callable signatures alongside the existing context parameter so that references to objects can be propagated to operations that are able to replace the value of such objects. Result target objects are currently supported only for locals and intermediate results in functions and methods, with assignments to locals or the storage of intermediate results involving the copying of any given floating-point objects instead of merely referencing them. Such distinct copies may then be used as result targets when locals or intermediate result locations are subsequently reused. Value replacement avoids the allocation of temporary objects that can quickly dominate execution time in programs repeatedly performing large numbers of floating-point calculations. diff -r 1e7ccc84119f -r 0be4f390513d generator.py --- a/generator.py Thu Nov 04 23:44:29 2021 +0100 +++ b/generator.py Tue Aug 29 01:46:23 2023 +0200 @@ -3,7 +3,7 @@ """ Generate C code from object layouts and other deduced information. -Copyright (C) 2015-2019, 2021 Paul Boddie +Copyright (C) 2015-2019, 2021, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -40,6 +40,10 @@ "A code generator." + # Generated functions employ result target and context parameters. + + extra_args = 2 + # NOTE: These must be synchronised with the library. dict_type = "__builtins__.dict.dict" @@ -315,11 +319,12 @@ self.write_instance_structure(f_decls, path) extra_function_instances.append(path) - # Write function declarations. - # Signature: __attr (...); + # Write function declarations, including result target and + # context parameters. + # Signature: __attr (__attr, __attr, ...); parameters = self.importer.function_parameters[path] - l = ["__attr"] * (len(parameters) + 1) + l = ["__attr"] * (len(parameters) + self.extra_args) print >>f_signatures, "__attr %s(%s);" % (encode_function_pointer(path), ", ".join(l)) # Generate parameter table size data. @@ -903,7 +908,7 @@ parameters = self.importer.function_parameters[path] defaults = self.importer.function_defaults.get(path) - num_parameters = len(parameters) + 1 + num_parameters = len(parameters) + self.extra_args return num_parameters - (defaults and len(defaults) or 0), num_parameters def get_static_attributes(self, kind, name, attrnames): @@ -1270,9 +1275,9 @@ if path == self.int_type: print >>f_code, """\ -__attr %s(__attr __self, __attr number_or_string, __attr base) +__attr %s(__attr __result, __attr __self, __attr number_or_string, __attr base) { - return __fn___builtins___int_new_int(__NULL, number_or_string, base); + return __fn___builtins___int_new_int(__NULL, __NULL, number_or_string, base); } """ % ( encode_instantiator_pointer(path), @@ -1285,9 +1290,9 @@ elif path == self.string_type: print >>f_code, """\ -__attr %s(__attr __self, __attr obj) +__attr %s(__attr __result, __attr __self, __attr obj) { - return __fn___builtins___str_new_str(__NULL, obj); + return __fn___builtins___str_new_str(__NULL, __NULL, obj); } """ % ( encode_instantiator_pointer(path), @@ -1297,9 +1302,9 @@ else: print >>f_code, """\ -__attr %s(__attr __self%s) +__attr %s(__attr __result, __attr __self%s) { - return %s(__NEWINSTANCE(%s)%s); + return %s(__NULL, __NEWINSTANCE(%s)%s); } """ % ( encode_instantiator_pointer(path), @@ -1309,9 +1314,9 @@ parameters and ", %s" % ", ".join(parameters) or "" ) - # Signature: __new_typename(__attr __self, ...) + # Signature: __new_typename(__attr __result, __attr __self, ...) - print >>f_signatures, "__attr %s(__attr __self%s);" % ( + print >>f_signatures, "__attr %s(__attr __result, __attr __self%s);" % ( encode_instantiator_pointer(path), l and ", %s" % ", ".join(l) or "" ) @@ -1358,7 +1363,7 @@ fprintf(stderr, "Program terminated due to exception: %%s.\\n", __load_via_object( - __VALUE(%s(__NULL, __tmp_exc.arg)), + __VALUE(%s(__NULL, __NULL, __tmp_exc.arg)), __data__).strvalue); return 1; } diff -r 1e7ccc84119f -r 0be4f390513d templates/native/buffer.c --- a/templates/native/buffer.c Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/buffer.c Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for buffer operations. -Copyright (C) 2016, 2017, 2021 Paul Boddie +Copyright (C) 2016, 2017, 2021, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -26,7 +26,7 @@ #include "progtypes.h" #include "main.h" -__attr __fn_native_buffer_buffer_str(__attr __self, __attr _data) +__attr __fn_native_buffer_buffer_str(__attr __result, __attr __self, __attr _data) { /* _data interpreted as buffer.__data__ */ __fragment *data = _data.seqvalue; diff -r 1e7ccc84119f -r 0be4f390513d templates/native/buffer.h --- a/templates/native/buffer.h Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/buffer.h Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for buffer operations. -Copyright (C) 2016, 2017 Paul Boddie +Copyright (C) 2016, 2017, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,7 +23,7 @@ /* Buffer operations. */ -__attr __fn_native_buffer_buffer_str(__attr __self, __attr _data); +__attr __fn_native_buffer_buffer_str(__attr __result, __attr __self, __attr _data); /* Module initialisation. */ diff -r 1e7ccc84119f -r 0be4f390513d templates/native/common.c --- a/templates/native/common.c Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/common.c Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Common operations for native functions. -Copyright (C) 2016, 2017, 2018, 2021 Paul Boddie +Copyright (C) 2016, 2017, 2018, 2021, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -44,12 +44,33 @@ return attr; } -__attr __new_float(double n) +/* Temporary result target. */ + +__attr __new_float(__attr __result, double n) { - /* Create a new float and set the trailing data. */ - __attr attr = __NEWINSTANCEIM(__builtins___float_float); + __attr attr; + + /* Identify any suitable target for value replacement. The assumption is + that locally referenced float objects are always replaceable since they + will be appropriately initialised. */ + + __ref obj = __VALUE(__result); + int replace = (obj != NULL) && __is_instance(obj) && (__get_class(obj) == &__builtins___float_float); + + if (replace) + attr = __result; + + /* Alternatively, create a new float. */ + else + attr = __NEWINSTANCEIM(__builtins___float_float); + + /* Set the trailing data, replacing an existing value if applicable. */ __set_trailing_data(attr, __builtins___float_float, n); - return attr; + + if (replace) + return __REPLACEMENT(attr); + else + return attr; } __fragment *__fragment_append(__fragment *data, __attr value) diff -r 1e7ccc84119f -r 0be4f390513d templates/native/common.h --- a/templates/native/common.h Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/common.h Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Common operations for native functions. -Copyright (C) 2016, 2017, 2018, 2021 Paul Boddie +Copyright (C) 2016, 2017, 2018, 2021, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -29,7 +29,7 @@ __attr __new_str(char *s, __int size); __attr __new_list(__fragment *f); -__attr __new_float(double n); +__attr __new_float(__attr __result, double n); __fragment *__fragment_append(__fragment *data, __attr value); #endif /* __NATIVE_COMMON_H__ */ diff -r 1e7ccc84119f -r 0be4f390513d templates/native/float.c --- a/templates/native/float.c Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/float.c Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for floating point operations. -Copyright (C) 2016, 2017, 2018, 2019 Paul Boddie +Copyright (C) 2016, 2017, 2018, 2019, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -65,54 +65,54 @@ /* Floating point operations. Exceptions are raised in the signal handler. */ -__attr __fn_native_float_float_add(__attr __self, __attr self, __attr other) +__attr __fn_native_float_float_add(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as float */ double i = __TOFLOAT(self); double j = __TOFLOAT(other); - return __new_float(i + j); + return __new_float(__result, i + j); } -__attr __fn_native_float_float_sub(__attr __self, __attr self, __attr other) +__attr __fn_native_float_float_sub(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as float */ double i = __TOFLOAT(self); double j = __TOFLOAT(other); - return __new_float(i - j); + return __new_float(__result, i - j); } -__attr __fn_native_float_float_mul(__attr __self, __attr self, __attr other) +__attr __fn_native_float_float_mul(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as float */ double i = __TOFLOAT(self); double j = __TOFLOAT(other); - return __new_float(i * j); + return __new_float(__result, i * j); } -__attr __fn_native_float_float_div(__attr __self, __attr self, __attr other) +__attr __fn_native_float_float_div(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as float */ double i = __TOFLOAT(self); double j = __TOFLOAT(other); - return __new_float(i / j); + return __new_float(__result, i / j); } -__attr __fn_native_float_float_mod(__attr __self, __attr self, __attr other) +__attr __fn_native_float_float_mod(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as float */ double i = __TOFLOAT(self); double j = __TOFLOAT(other); - return __new_float(fmod(i, j)); + return __new_float(__result, fmod(i, j)); } -__attr __fn_native_float_float_neg(__attr __self, __attr self) +__attr __fn_native_float_float_neg(__attr __result, __attr __self, __attr self) { /* self interpreted as float */ double i = __TOFLOAT(self); - return __new_float(-i); + return __new_float(__result, -i); } -__attr __fn_native_float_float_pow(__attr __self, __attr self, __attr other) +__attr __fn_native_float_float_pow(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as float */ double i = __TOFLOAT(self); @@ -128,10 +128,10 @@ __raise_overflow_error(); /* Return the result. */ - return __new_float(result); + return __new_float(__result, result); } -__attr __fn_native_float_float_le(__attr __self, __attr self, __attr other) +__attr __fn_native_float_float_le(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as float */ double i = __TOFLOAT(self); @@ -141,7 +141,7 @@ return i <= j ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_float_float_lt(__attr __self, __attr self, __attr other) +__attr __fn_native_float_float_lt(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as float */ double i = __TOFLOAT(self); @@ -151,7 +151,7 @@ return i < j ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_float_float_ge(__attr __self, __attr self, __attr other) +__attr __fn_native_float_float_ge(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as float */ double i = __TOFLOAT(self); @@ -161,7 +161,7 @@ return i >= j ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_float_float_gt(__attr __self, __attr self, __attr other) +__attr __fn_native_float_float_gt(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as float */ double i = __TOFLOAT(self); @@ -171,7 +171,7 @@ return i > j ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_float_float_eq(__attr __self, __attr self, __attr other) +__attr __fn_native_float_float_eq(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as float */ double i = __TOFLOAT(self); @@ -181,7 +181,7 @@ return i == j ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_float_float_ne(__attr __self, __attr self, __attr other) +__attr __fn_native_float_float_ne(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as float */ double i = __TOFLOAT(self); @@ -191,7 +191,7 @@ return i != j ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_float_float_str(__attr __self, __attr self) +__attr __fn_native_float_float_str(__attr __result, __attr __self, __attr self) { /* self interpreted as float */ double i = __TOFLOAT(self); @@ -200,7 +200,7 @@ return format_number(i, 64); } -__attr __fn_native_float_float_int(__attr __self, __attr self) +__attr __fn_native_float_float_int(__attr __result, __attr __self, __attr self) { /* self interpreted as float */ double i = __TOFLOAT(self); diff -r 1e7ccc84119f -r 0be4f390513d templates/native/float.h --- a/templates/native/float.h Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/float.h Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for floating point operations. -Copyright (C) 2018 Paul Boddie +Copyright (C) 2018, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,23 +23,23 @@ /* Floating point operations. */ -__attr __fn_native_float_float_add(__attr __self, __attr self, __attr other); -__attr __fn_native_float_float_sub(__attr __self, __attr self, __attr other); -__attr __fn_native_float_float_mul(__attr __self, __attr self, __attr other); -__attr __fn_native_float_float_div(__attr __self, __attr self, __attr other); -__attr __fn_native_float_float_mod(__attr __self, __attr self, __attr other); -__attr __fn_native_float_float_neg(__attr __self, __attr self); -__attr __fn_native_float_float_pow(__attr __self, __attr self, __attr other); +__attr __fn_native_float_float_add(__attr __result, __attr __self, __attr self, __attr other); +__attr __fn_native_float_float_sub(__attr __result, __attr __self, __attr self, __attr other); +__attr __fn_native_float_float_mul(__attr __result, __attr __self, __attr self, __attr other); +__attr __fn_native_float_float_div(__attr __result, __attr __self, __attr self, __attr other); +__attr __fn_native_float_float_mod(__attr __result, __attr __self, __attr self, __attr other); +__attr __fn_native_float_float_neg(__attr __result, __attr __self, __attr self); +__attr __fn_native_float_float_pow(__attr __result, __attr __self, __attr self, __attr other); -__attr __fn_native_float_float_le(__attr __self, __attr self, __attr other); -__attr __fn_native_float_float_lt(__attr __self, __attr self, __attr other); -__attr __fn_native_float_float_ge(__attr __self, __attr self, __attr other); -__attr __fn_native_float_float_gt(__attr __self, __attr self, __attr other); -__attr __fn_native_float_float_eq(__attr __self, __attr self, __attr other); -__attr __fn_native_float_float_ne(__attr __self, __attr self, __attr other); +__attr __fn_native_float_float_le(__attr __result, __attr __self, __attr self, __attr other); +__attr __fn_native_float_float_lt(__attr __result, __attr __self, __attr self, __attr other); +__attr __fn_native_float_float_ge(__attr __result, __attr __self, __attr self, __attr other); +__attr __fn_native_float_float_gt(__attr __result, __attr __self, __attr self, __attr other); +__attr __fn_native_float_float_eq(__attr __result, __attr __self, __attr self, __attr other); +__attr __fn_native_float_float_ne(__attr __result, __attr __self, __attr self, __attr other); -__attr __fn_native_float_float_str(__attr __self, __attr self); -__attr __fn_native_float_float_int(__attr __self, __attr self); +__attr __fn_native_float_float_str(__attr __result, __attr __self, __attr self); +__attr __fn_native_float_float_int(__attr __result, __attr __self, __attr self); /* Module initialisation. */ diff -r 1e7ccc84119f -r 0be4f390513d templates/native/iconv.c --- a/templates/native/iconv.c Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/iconv.c Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for character set conversion. -Copyright (C) 2016, 2017, 2021 Paul Boddie +Copyright (C) 2016, 2017, 2021, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -33,20 +33,20 @@ static void __raise_incomplete_sequence_error(__attr value, __attr arg) { #ifdef __HAVE_posix_iconv_IncompleteSequenceError - __Raise(__new_posix_iconv_IncompleteSequenceError(__NULL, value, arg)); + __Raise(__new_posix_iconv_IncompleteSequenceError(__NULL, __NULL, value, arg)); #endif /* __HAVE_posix_iconv_IncompleteSequenceError */ } static void __raise_invalid_sequence_error(__attr value, __attr arg) { #ifdef __HAVE_posix_iconv_InvalidSequenceError - __Raise(__new_posix_iconv_InvalidSequenceError(__NULL, value, arg)); + __Raise(__new_posix_iconv_InvalidSequenceError(__NULL, __NULL, value, arg)); #endif /* __HAVE_posix_iconv_InvalidSequenceError */ } /* Character set conversion. */ -__attr __fn_native_iconv_iconv(__attr __self, __attr cd, __attr state) +__attr __fn_native_iconv_iconv(__attr __result, __attr __self, __attr cd, __attr state) { /* cd interpreted as iconv_t */ iconv_t c = (iconv_t) cd.datavalue; @@ -117,7 +117,7 @@ return __builtins___none_None; } -__attr __fn_native_iconv_iconv_close(__attr __self, __attr cd) +__attr __fn_native_iconv_iconv_close(__attr __result, __attr __self, __attr cd) { /* cd interpreted as iconv_t */ iconv_t c = (iconv_t) cd.datavalue; @@ -130,7 +130,7 @@ return __builtins___none_None; } -__attr __fn_native_iconv_iconv_open(__attr __self, __attr tocode, __attr fromcode) +__attr __fn_native_iconv_iconv_open(__attr __result, __attr __self, __attr tocode, __attr fromcode) { /* tocode.__data__ interpreted as string */ char *t = __load_via_object(__VALUE(tocode), __data__).strvalue; @@ -151,7 +151,7 @@ return attr; } -__attr __fn_native_iconv_iconv_reset(__attr __self, __attr cd) +__attr __fn_native_iconv_iconv_reset(__attr __result, __attr __self, __attr cd) { /* cd interpreted as iconv_t */ iconv_t c = (iconv_t) cd.datavalue; diff -r 1e7ccc84119f -r 0be4f390513d templates/native/iconv.h --- a/templates/native/iconv.h Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/iconv.h Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for character set conversion. -Copyright (C) 2016, 2017 Paul Boddie +Copyright (C) 2016, 2017, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,10 +23,10 @@ /* Input/output. */ -__attr __fn_native_iconv_iconv(__attr __self, __attr cd, __attr state); -__attr __fn_native_iconv_iconv_close(__attr __self, __attr cd); -__attr __fn_native_iconv_iconv_open(__attr __self, __attr tocode, __attr fromcode); -__attr __fn_native_iconv_iconv_reset(__attr __self, __attr cd); +__attr __fn_native_iconv_iconv(__attr __result, __attr __self, __attr cd, __attr state); +__attr __fn_native_iconv_iconv_close(__attr __result, __attr __self, __attr cd); +__attr __fn_native_iconv_iconv_open(__attr __result, __attr __self, __attr tocode, __attr fromcode); +__attr __fn_native_iconv_iconv_reset(__attr __result, __attr __self, __attr cd); /* Module initialisation. */ diff -r 1e7ccc84119f -r 0be4f390513d templates/native/identity.c --- a/templates/native/identity.c Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/identity.c Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for identity operations. -Copyright (C) 2016, 2017 Paul Boddie +Copyright (C) 2016, 2017, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -26,14 +26,14 @@ /* Identity testing. */ -__attr __fn_native_identity_is_(__attr __self, __attr x, __attr y) +__attr __fn_native_identity_is_(__attr __result, __attr __self, __attr x, __attr y) { /* NOTE: value member assumed equivalent to intvalue for comparison. */ return x.value == y.value ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_identity_is_not(__attr __self, __attr x, __attr y) +__attr __fn_native_identity_is_not(__attr __result, __attr __self, __attr x, __attr y) { /* NOTE: value member assumed equivalent to intvalue for comparison. */ diff -r 1e7ccc84119f -r 0be4f390513d templates/native/identity.h --- a/templates/native/identity.h Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/identity.h Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for identity operations. -Copyright (C) 2016, 2017 Paul Boddie +Copyright (C) 2016, 2017, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,8 +23,8 @@ /* Identity testing. */ -__attr __fn_native_identity_is_(__attr __self, __attr x, __attr y); -__attr __fn_native_identity_is_not(__attr __self, __attr x, __attr y); +__attr __fn_native_identity_is_(__attr __result, __attr __self, __attr x, __attr y); +__attr __fn_native_identity_is_not(__attr __result, __attr __self, __attr x, __attr y); /* Module initialisation. */ diff -r 1e7ccc84119f -r 0be4f390513d templates/native/int.c --- a/templates/native/int.c Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/int.c Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for integer operations. -Copyright (C) 2016, 2017, 2018, 2021 Paul Boddie +Copyright (C) 2016, 2017, 2018, 2021, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -31,12 +31,12 @@ /* Integer operations. */ -__attr __fn_native_int_is_int(__attr __self, __attr obj) +__attr __fn_native_int_is_int(__attr __result, __attr __self, __attr obj) { return __INTEGER(obj) ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_int_int_add(__attr __self, __attr self, __attr other) +__attr __fn_native_int_int_add(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as int */ __int i = __TOINT(self); @@ -52,7 +52,7 @@ return __new_int(i + j); } -__attr __fn_native_int_int_sub(__attr __self, __attr self, __attr other) +__attr __fn_native_int_int_sub(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as int */ __int i = __TOINT(self); @@ -68,7 +68,7 @@ return __new_int(i - j); } -__attr __fn_native_int_int_mul(__attr __self, __attr self, __attr other) +__attr __fn_native_int_int_mul(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as int */ __int i = __TOINT(self); @@ -86,7 +86,7 @@ return __new_int(i * j); } -__attr __fn_native_int_int_div(__attr __self, __attr self, __attr other) +__attr __fn_native_int_int_div(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as int */ __int i = __TOINT(self); @@ -102,7 +102,7 @@ return __new_int(i / j); } -__attr __fn_native_int_int_mod(__attr __self, __attr self, __attr other) +__attr __fn_native_int_int_mod(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as int */ __int i = __TOINT(self); @@ -118,7 +118,7 @@ return __new_int(i % j); } -__attr __fn_native_int_int_neg(__attr __self, __attr self) +__attr __fn_native_int_int_neg(__attr __result, __attr __self, __attr self) { /* self interpreted as int */ __int i = __TOINT(self); @@ -131,7 +131,7 @@ return __new_int(-i); } -__attr __fn_native_int_int_pow(__attr __self, __attr self, __attr other) +__attr __fn_native_int_int_pow(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as int */ __int i = __TOINT(self); @@ -154,7 +154,7 @@ return __new_int(k); } -__attr __fn_native_int_int_and(__attr __self, __attr self, __attr other) +__attr __fn_native_int_int_and(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as int */ __int i = __TOINT(self); @@ -165,7 +165,7 @@ return __new_int(i & j); } -__attr __fn_native_int_int_not(__attr __self, __attr self) +__attr __fn_native_int_int_not(__attr __result, __attr __self, __attr self) { /* self interpreted as int */ __int i = __TOINT(self); @@ -174,7 +174,7 @@ return __new_int(~i); } -__attr __fn_native_int_int_or(__attr __self, __attr self, __attr other) +__attr __fn_native_int_int_or(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as int */ __int i = __TOINT(self); @@ -185,7 +185,7 @@ return __new_int(i | j); } -__attr __fn_native_int_int_xor(__attr __self, __attr self, __attr other) +__attr __fn_native_int_int_xor(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as int */ __int i = __TOINT(self); @@ -196,7 +196,7 @@ return __new_int(i ^ j); } -__attr __fn_native_int_int_lshift(__attr __self, __attr self, __attr other) +__attr __fn_native_int_int_lshift(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as int */ __int i = __TOINT(self); @@ -207,7 +207,7 @@ return __new_int(i << j); } -__attr __fn_native_int_int_rshift(__attr __self, __attr self, __attr other) +__attr __fn_native_int_int_rshift(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as int */ __int i = __TOINT(self); @@ -218,7 +218,7 @@ return __new_int(i >> j); } -__attr __fn_native_int_int_le(__attr __self, __attr self, __attr other) +__attr __fn_native_int_int_le(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as int */ __int i = __TOINT(self); @@ -228,7 +228,7 @@ return i <= j ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_int_int_lt(__attr __self, __attr self, __attr other) +__attr __fn_native_int_int_lt(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as int */ __int i = __TOINT(self); @@ -238,7 +238,7 @@ return i < j ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_int_int_ge(__attr __self, __attr self, __attr other) +__attr __fn_native_int_int_ge(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as int */ __int i = __TOINT(self); @@ -248,7 +248,7 @@ return i >= j ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_int_int_gt(__attr __self, __attr self, __attr other) +__attr __fn_native_int_int_gt(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as int */ __int i = __TOINT(self); @@ -258,7 +258,7 @@ return i > j ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_int_int_eq(__attr __self, __attr self, __attr other) +__attr __fn_native_int_int_eq(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as int */ __int i = __TOINT(self); @@ -268,7 +268,7 @@ return i == j ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_int_int_ne(__attr __self, __attr self, __attr other) +__attr __fn_native_int_int_ne(__attr __result, __attr __self, __attr self, __attr other) { /* self and other interpreted as int */ __int i = __TOINT(self); @@ -278,7 +278,7 @@ return i != j ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_int_int_str(__attr __self, __attr self) +__attr __fn_native_int_int_str(__attr __result, __attr __self, __attr self) { /* self interpreted as int */ __int i = __TOINT(self); @@ -294,12 +294,12 @@ return __new_str(s, strlen(s)); } -__attr __fn_native_int_int_float(__attr __self, __attr self) +__attr __fn_native_int_int_float(__attr __result, __attr __self, __attr self) { /* self interpreted as int */ int i = __TOINT(self); - return __new_float((double) i); + return __new_float(__result, (double) i); } /* Module initialisation. */ diff -r 1e7ccc84119f -r 0be4f390513d templates/native/int.h --- a/templates/native/int.h Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/int.h Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for integer operations. -Copyright (C) 2016, 2017, 2018 Paul Boddie +Copyright (C) 2016, 2017, 2018, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,32 +23,32 @@ /* Integer operations. */ -__attr __fn_native_int_is_int(__attr __self, __attr obj); -__attr __fn_native_int_int_add(__attr __self, __attr _data, __attr other); -__attr __fn_native_int_int_sub(__attr __self, __attr _data, __attr other); -__attr __fn_native_int_int_mul(__attr __self, __attr _data, __attr other); -__attr __fn_native_int_int_div(__attr __self, __attr _data, __attr other); -__attr __fn_native_int_int_mod(__attr __self, __attr _data, __attr other); -__attr __fn_native_int_int_neg(__attr __self, __attr _data); -__attr __fn_native_int_int_pow(__attr __self, __attr _data, __attr other); +__attr __fn_native_int_is_int(__attr __result, __attr __self, __attr obj); +__attr __fn_native_int_int_add(__attr __result, __attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_sub(__attr __result, __attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_mul(__attr __result, __attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_div(__attr __result, __attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_mod(__attr __result, __attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_neg(__attr __result, __attr __self, __attr _data); +__attr __fn_native_int_int_pow(__attr __result, __attr __self, __attr _data, __attr other); -__attr __fn_native_int_int_and(__attr __self, __attr _data, __attr other); -__attr __fn_native_int_int_not(__attr __self, __attr _data); -__attr __fn_native_int_int_or(__attr __self, __attr _data, __attr other); -__attr __fn_native_int_int_xor(__attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_and(__attr __result, __attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_not(__attr __result, __attr __self, __attr _data); +__attr __fn_native_int_int_or(__attr __result, __attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_xor(__attr __result, __attr __self, __attr _data, __attr other); -__attr __fn_native_int_int_lshift(__attr __self, __attr _data, __attr other); -__attr __fn_native_int_int_rshift(__attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_lshift(__attr __result, __attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_rshift(__attr __result, __attr __self, __attr _data, __attr other); -__attr __fn_native_int_int_eq(__attr __self, __attr _data, __attr other); -__attr __fn_native_int_int_ge(__attr __self, __attr _data, __attr other); -__attr __fn_native_int_int_gt(__attr __self, __attr _data, __attr other); -__attr __fn_native_int_int_le(__attr __self, __attr _data, __attr other); -__attr __fn_native_int_int_lt(__attr __self, __attr _data, __attr other); -__attr __fn_native_int_int_ne(__attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_eq(__attr __result, __attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_ge(__attr __result, __attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_gt(__attr __result, __attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_le(__attr __result, __attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_lt(__attr __result, __attr __self, __attr _data, __attr other); +__attr __fn_native_int_int_ne(__attr __result, __attr __self, __attr _data, __attr other); -__attr __fn_native_int_int_str(__attr __self, __attr _data); -__attr __fn_native_int_int_float(__attr __self, __attr _data); +__attr __fn_native_int_int_str(__attr __result, __attr __self, __attr _data); +__attr __fn_native_int_int_float(__attr __result, __attr __self, __attr _data); /* Module initialisation. */ diff -r 1e7ccc84119f -r 0be4f390513d templates/native/introspection.c --- a/templates/native/introspection.c Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/introspection.c Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for introspection operations. -Copyright (C) 2016, 2017 Paul Boddie +Copyright (C) 2016, 2017, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -26,7 +26,7 @@ /* Introspection. */ -__attr __fn_native_introspection_object_getattr(__attr __self, __attr obj, __attr name, __attr _default) +__attr __fn_native_introspection_object_getattr(__attr __result, __attr __self, __attr obj, __attr name, __attr _default) { /* name interpreted as string */ __attr key = __load_via_object(__VALUE(name), __key__); @@ -54,7 +54,7 @@ return out; } -__attr __fn_native_introspection_isinstance(__attr __self, __attr obj, __attr cls) +__attr __fn_native_introspection_isinstance(__attr __result, __attr __self, __attr obj, __attr cls) { /* cls must be a class. */ if (__is_instance_subclass(__VALUE(obj), cls)) @@ -63,7 +63,7 @@ return __builtins___boolean_False; } -__attr __fn_native_introspection_issubclass(__attr __self, __attr obj, __attr cls) +__attr __fn_native_introspection_issubclass(__attr __result, __attr __self, __attr obj, __attr cls) { /* obj and cls must be classes. */ if (__is_subclass(__VALUE(obj), cls)) diff -r 1e7ccc84119f -r 0be4f390513d templates/native/introspection.h --- a/templates/native/introspection.h Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/introspection.h Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for introspection. -Copyright (C) 2016, 2017 Paul Boddie +Copyright (C) 2016, 2017, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,9 +23,9 @@ /* Introspection. */ -__attr __fn_native_introspection_object_getattr(__attr __self, __attr obj, __attr name, __attr _default); -__attr __fn_native_introspection_isinstance(__attr __self, __attr obj, __attr cls); -__attr __fn_native_introspection_issubclass(__attr __self, __attr obj, __attr cls); +__attr __fn_native_introspection_object_getattr(__attr __result, __attr __self, __attr obj, __attr name, __attr _default); +__attr __fn_native_introspection_isinstance(__attr __result, __attr __self, __attr obj, __attr cls); +__attr __fn_native_introspection_issubclass(__attr __result, __attr __self, __attr obj, __attr cls); /* Module initialisation. */ diff -r 1e7ccc84119f -r 0be4f390513d templates/native/io.c --- a/templates/native/io.c Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/io.c Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for input/output. -Copyright (C) 2016, 2017, 2021 Paul Boddie +Copyright (C) 2016, 2017, 2021, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -31,7 +31,7 @@ /* Input/output. */ -__attr __fn_native_io_fclose(__attr __self, __attr fp) +__attr __fn_native_io_fclose(__attr __result, __attr __self, __attr fp) { /* fp interpreted as FILE reference */ FILE *f = (FILE *) fp.datavalue; @@ -43,7 +43,7 @@ return __builtins___none_None; } -__attr __fn_native_io_fflush(__attr __self, __attr fp) +__attr __fn_native_io_fflush(__attr __result, __attr __self, __attr fp) { /* fp interpreted as FILE reference */ FILE *f = (FILE *) fp.datavalue; @@ -55,7 +55,7 @@ return __builtins___none_None; } -__attr __fn_native_io_fopen(__attr __self, __attr filename, __attr mode) +__attr __fn_native_io_fopen(__attr __result, __attr __self, __attr filename, __attr mode) { /* filename.__data__ interpreted as string */ char *fn = __load_via_object(__VALUE(filename), __data__).strvalue; @@ -85,7 +85,7 @@ return __builtins___none_None; } -__attr __fn_native_io_fdopen(__attr __self, __attr fd, __attr mode) +__attr __fn_native_io_fdopen(__attr __result, __attr __self, __attr fd, __attr mode) { /* fd interpreted as int */ int i = __TOINT(fd); @@ -115,7 +115,7 @@ return __builtins___none_None; } -__attr __fn_native_io_fread(__attr __self, __attr fp, __attr size) +__attr __fn_native_io_fread(__attr __result, __attr __self, __attr fp, __attr size) { /* fp interpreted as FILE reference */ FILE *f = (FILE *) fp.datavalue; @@ -143,7 +143,7 @@ return __new_str(s, have_read); } -__attr __fn_native_io_fwrite(__attr __self, __attr fp, __attr str) +__attr __fn_native_io_fwrite(__attr __result, __attr __self, __attr fp, __attr str) { /* fp interpreted as FILE reference */ FILE *f = (FILE *) fp.datavalue; @@ -165,7 +165,7 @@ return __builtins___none_None; } -__attr __fn_native_io_close(__attr __self, __attr fd) +__attr __fn_native_io_close(__attr __result, __attr __self, __attr fd) { /* fd interpreted as int */ int i = __TOINT(fd); @@ -177,7 +177,7 @@ return __builtins___none_None; } -__attr __fn_native_io_read(__attr __self, __attr fd, __attr n) +__attr __fn_native_io_read(__attr __result, __attr __self, __attr fd, __attr n) { /* fd interpreted as int */ int i = __TOINT(fd); @@ -200,7 +200,7 @@ return __new_str(s, have_read); } -__attr __fn_native_io_write(__attr __self, __attr fd, __attr str) +__attr __fn_native_io_write(__attr __result, __attr __self, __attr fd, __attr str) { /* fd interpreted as int */ int i = __TOINT(fd); diff -r 1e7ccc84119f -r 0be4f390513d templates/native/io.h --- a/templates/native/io.h Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/io.h Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for input/output. -Copyright (C) 2016, 2017 Paul Boddie +Copyright (C) 2016, 2017, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,15 +23,15 @@ /* Input/output. */ -__attr __fn_native_io_fclose(__attr __self, __attr fp); -__attr __fn_native_io_fflush(__attr __self, __attr fp); -__attr __fn_native_io_fopen(__attr __self, __attr filename, __attr mode); -__attr __fn_native_io_fdopen(__attr __self, __attr fd, __attr mode); -__attr __fn_native_io_fread(__attr __self, __attr fp, __attr size); -__attr __fn_native_io_fwrite(__attr __self, __attr fp, __attr str); -__attr __fn_native_io_close(__attr __self, __attr fd); -__attr __fn_native_io_read(__attr __self, __attr fd, __attr n); -__attr __fn_native_io_write(__attr __self, __attr fd, __attr str); +__attr __fn_native_io_fclose(__attr __result, __attr __self, __attr fp); +__attr __fn_native_io_fflush(__attr __result, __attr __self, __attr fp); +__attr __fn_native_io_fopen(__attr __result, __attr __self, __attr filename, __attr mode); +__attr __fn_native_io_fdopen(__attr __result, __attr __self, __attr fd, __attr mode); +__attr __fn_native_io_fread(__attr __result, __attr __self, __attr fp, __attr size); +__attr __fn_native_io_fwrite(__attr __result, __attr __self, __attr fp, __attr str); +__attr __fn_native_io_close(__attr __result, __attr __self, __attr fd); +__attr __fn_native_io_read(__attr __result, __attr __self, __attr fd, __attr n); +__attr __fn_native_io_write(__attr __result, __attr __self, __attr fd, __attr str); /* Module initialisation. */ diff -r 1e7ccc84119f -r 0be4f390513d templates/native/limits.c --- a/templates/native/limits.c Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/limits.c Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for limit definition. -Copyright (C) 2016, 2017 Paul Boddie +Copyright (C) 2016, 2017, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -27,12 +27,12 @@ /* Limit definition. */ -__attr __fn_native_limits_get_maxint(__attr __self) +__attr __fn_native_limits_get_maxint(__attr __result, __attr __self) { return __new_int(__MAXINT); } -__attr __fn_native_limits_get_minint(__attr __self) +__attr __fn_native_limits_get_minint(__attr __result, __attr __self) { return __new_int(__MININT); } diff -r 1e7ccc84119f -r 0be4f390513d templates/native/limits.h --- a/templates/native/limits.h Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/limits.h Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for limit definition. -Copyright (C) 2016, 2017 Paul Boddie +Copyright (C) 2016, 2017, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,8 +23,8 @@ /* Limit definition. */ -__attr __fn_native_limits_get_maxint(__attr __self); -__attr __fn_native_limits_get_minint(__attr __self); +__attr __fn_native_limits_get_maxint(__attr __result, __attr __self); +__attr __fn_native_limits_get_minint(__attr __result, __attr __self); /* Module initialisation. */ diff -r 1e7ccc84119f -r 0be4f390513d templates/native/list.c --- a/templates/native/list.c Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/list.c Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for list operations. -Copyright (C) 2016, 2017, 2021 Paul Boddie +Copyright (C) 2016, 2017, 2021, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -27,7 +27,7 @@ /* List operations. */ -__attr __fn_native_list_list_init(__attr __self, __attr size) +__attr __fn_native_list_list_init(__attr __result, __attr __self, __attr size) { /* size interpreted as int */ __int n = __TOINT(size); @@ -37,7 +37,7 @@ return attr; } -__attr __fn_native_list_list_setsize(__attr __self, __attr _data, __attr size) +__attr __fn_native_list_list_setsize(__attr __result, __attr __self, __attr _data, __attr size) { /* _data interpreted as list.__data__ */ __fragment *data = _data.seqvalue; @@ -48,7 +48,7 @@ return __builtins___none_None; } -__attr __fn_native_list_list_append(__attr __self, __attr self, __attr value) +__attr __fn_native_list_list_append(__attr __result, __attr __self, __attr self, __attr value) { /* self.__data__ interpreted as list */ __fragment *data = __load_via_object(__VALUE(self), __data__).seqvalue; @@ -60,7 +60,7 @@ return __builtins___none_None; } -__attr __fn_native_list_list_concat(__attr __self, __attr self, __attr other) +__attr __fn_native_list_list_concat(__attr __result, __attr __self, __attr self, __attr other) { /* self, interpreted as list, other interpreted as list.__data__ */ __fragment *data = __load_via_object(__VALUE(self), __data__).seqvalue; @@ -88,7 +88,7 @@ return __builtins___none_None; } -__attr __fn_native_list_list_len(__attr self, __attr _data) +__attr __fn_native_list_list_len(__attr __result, __attr __self, __attr _data) { /* _data interpreted as list.__data__ */ __int size = _data.seqvalue->size; @@ -97,12 +97,12 @@ return __new_int(size); } -__attr __fn_native_list_list_nonempty(__attr __self, __attr _data) +__attr __fn_native_list_list_nonempty(__attr __result, __attr __self, __attr _data) { return _data.seqvalue->size ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_list_list_element(__attr __self, __attr _data, __attr index) +__attr __fn_native_list_list_element(__attr __result, __attr __self, __attr _data, __attr index) { /* _data interpreted as list.__data__ */ __attr *elements = _data.seqvalue->attrs; @@ -112,7 +112,7 @@ return elements[i]; } -__attr __fn_native_list_list_setelement(__attr __self, __attr _data, __attr index, __attr value) +__attr __fn_native_list_list_setelement(__attr __result, __attr __self, __attr _data, __attr index, __attr value) { /* _data interpreted as list.__data__ */ __attr *elements = _data.seqvalue->attrs; diff -r 1e7ccc84119f -r 0be4f390513d templates/native/list.h --- a/templates/native/list.h Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/list.h Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for list operations. -Copyright (C) 2016, 2017 Paul Boddie +Copyright (C) 2016, 2017, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,14 +23,14 @@ /* List operations. */ -__attr __fn_native_list_list_init(__attr __self, __attr size); -__attr __fn_native_list_list_setsize(__attr __self, __attr _data, __attr size); -__attr __fn_native_list_list_append(__attr __self, __attr self, __attr value); -__attr __fn_native_list_list_concat(__attr __self, __attr self, __attr other); -__attr __fn_native_list_list_len(__attr self, __attr _data); -__attr __fn_native_list_list_nonempty(__attr __self, __attr _data); -__attr __fn_native_list_list_element(__attr __self, __attr _data, __attr index); -__attr __fn_native_list_list_setelement(__attr __self, __attr _data, __attr index, __attr value); +__attr __fn_native_list_list_init(__attr __result, __attr __self, __attr size); +__attr __fn_native_list_list_setsize(__attr __result, __attr __self, __attr _data, __attr size); +__attr __fn_native_list_list_append(__attr __result, __attr __self, __attr self, __attr value); +__attr __fn_native_list_list_concat(__attr __result, __attr __self, __attr self, __attr other); +__attr __fn_native_list_list_len(__attr __result, __attr __self, __attr _data); +__attr __fn_native_list_list_nonempty(__attr __result, __attr __self, __attr _data); +__attr __fn_native_list_list_element(__attr __result, __attr __self, __attr _data, __attr index); +__attr __fn_native_list_list_setelement(__attr __result, __attr __self, __attr _data, __attr index, __attr value); /* Module initialisation. */ diff -r 1e7ccc84119f -r 0be4f390513d templates/native/locale.c --- a/templates/native/locale.c Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/locale.c Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for locale handling. -Copyright (C) 2016, 2017, 2021 Paul Boddie +Copyright (C) 2016, 2017, 2021, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -29,7 +29,7 @@ /* Locales. */ -__attr __fn_native_locale_getlocale(__attr __self, __attr category) +__attr __fn_native_locale_getlocale(__attr __result, __attr __self, __attr category) { /* category interpreted as int */ int cat = __TOINT(category); @@ -48,7 +48,7 @@ return __new_str(result, length); } -__attr __fn_native_locale_setlocale(__attr __self, __attr category, __attr value) +__attr __fn_native_locale_setlocale(__attr __result, __attr __self, __attr category, __attr value) { /* category interpreted as int */ int cat = __TOINT(category); diff -r 1e7ccc84119f -r 0be4f390513d templates/native/locale.h --- a/templates/native/locale.h Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/locale.h Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for locale handling. -Copyright (C) 2016, 2017 Paul Boddie +Copyright (C) 2016, 2017, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,8 +23,8 @@ /* Input/output. */ -__attr __fn_native_locale_getlocale(__attr __self, __attr category); -__attr __fn_native_locale_setlocale(__attr __self, __attr category, __attr value); +__attr __fn_native_locale_getlocale(__attr __result, __attr __self, __attr category); +__attr __fn_native_locale_setlocale(__attr __result, __attr __self, __attr category, __attr value); /* Module initialisation. */ diff -r 1e7ccc84119f -r 0be4f390513d templates/native/program.c --- a/templates/native/program.c Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/program.c Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for program operations. -Copyright (C) 2016, 2017 Paul Boddie +Copyright (C) 2016, 2017, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -26,7 +26,7 @@ /* Method binding. */ -__attr __fn_native_program_get_using(__attr __self, __attr callable, __attr instance) +__attr __fn_native_program_get_using(__attr __result, __attr __self, __attr callable, __attr instance) { return __test_context(instance, callable); } diff -r 1e7ccc84119f -r 0be4f390513d templates/native/program.h --- a/templates/native/program.h Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/program.h Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for program operations. -Copyright (C) 2016, 2017 Paul Boddie +Copyright (C) 2016, 2017, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -21,7 +21,7 @@ /* Method binding. */ -__attr __fn_native_program_get_using(__attr __self, __attr callable, __attr instance); +__attr __fn_native_program_get_using(__attr __result, __attr __self, __attr callable, __attr instance); /* Module initialisation. */ diff -r 1e7ccc84119f -r 0be4f390513d templates/native/str.c --- a/templates/native/str.c Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/str.c Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for string operations. -Copyright (C) 2016, 2017, 2021 Paul Boddie +Copyright (C) 2016, 2017, 2021, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -28,7 +28,7 @@ /* String operations. */ -__attr __fn_native_str_str_add(__attr __self, __attr _data, __attr other, __attr _size, __attr othersize) +__attr __fn_native_str_str_add(__attr __result, __attr __self, __attr _data, __attr other, __attr _size, __attr othersize) { /* _data, other interpreted as string.__data__ */ char *s = _data.strvalue; @@ -45,7 +45,7 @@ return __new_str(r, n); } -__attr __fn_native_str_str_chr(__attr __self, __attr _data) +__attr __fn_native_str_str_chr(__attr __result, __attr __self, __attr _data) { /* data interpreted as int */ int n = __TOINT(_data); @@ -55,7 +55,7 @@ return __new_str(s, 1); } -__attr __fn_native_str_str_lt(__attr __self, __attr _data, __attr other) +__attr __fn_native_str_str_lt(__attr __result, __attr __self, __attr _data, __attr other) { /* _data, other interpreted as string.__data__ */ char *s = _data.strvalue; @@ -65,7 +65,7 @@ return strcmp(s, o) < 0 ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_str_str_gt(__attr __self, __attr _data, __attr other) +__attr __fn_native_str_str_gt(__attr __result, __attr __self, __attr _data, __attr other) { /* _data, other interpreted as string.__data__ */ char *s = _data.strvalue; @@ -75,7 +75,7 @@ return strcmp(s, o) > 0 ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_str_str_eq(__attr __self, __attr _data, __attr other) +__attr __fn_native_str_str_eq(__attr __result, __attr __self, __attr _data, __attr other) { /* _data, other interpreted as string.__data__ */ char *s = _data.strvalue; @@ -85,7 +85,7 @@ return strcmp(s, o) == 0 ? __builtins___boolean_True : __builtins___boolean_False; } -__attr __fn_native_str_str_ord(__attr __self, __attr _data) +__attr __fn_native_str_str_ord(__attr __result, __attr __self, __attr _data) { /* _data interpreted as string.__data__ */ char *s = _data.strvalue; @@ -93,12 +93,12 @@ return __new_int((__int) s[0]); } -__attr __fn_native_str_str_size(__attr __self, __attr _size) +__attr __fn_native_str_str_size(__attr __result, __attr __self, __attr _size) { return __new_int(_size.sizevalue); } -__attr __fn_native_str_str_substr(__attr __self, __attr _data, __attr start, __attr end, __attr step) +__attr __fn_native_str_str_substr(__attr __result, __attr __self, __attr _data, __attr start, __attr end, __attr step) { /* _data interpreted as string.__data__ */ char *s = _data.strvalue, *sub; diff -r 1e7ccc84119f -r 0be4f390513d templates/native/str.h --- a/templates/native/str.h Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/str.h Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for string operations. -Copyright (C) 2016, 2017, 2021 Paul Boddie +Copyright (C) 2016, 2017, 2021, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -21,14 +21,14 @@ /* String operations. */ -__attr __fn_native_str_str_add(__attr __self, __attr _data, __attr other, __attr _size, __attr othersize); -__attr __fn_native_str_str_chr(__attr __self, __attr _data); -__attr __fn_native_str_str_lt(__attr __self, __attr _data, __attr other); -__attr __fn_native_str_str_gt(__attr __self, __attr _data, __attr other); -__attr __fn_native_str_str_eq(__attr __self, __attr _data, __attr other); -__attr __fn_native_str_str_ord(__attr __self, __attr _data); -__attr __fn_native_str_str_size(__attr __self); -__attr __fn_native_str_str_substr(__attr __self, __attr _data, __attr start, __attr end, __attr step); +__attr __fn_native_str_str_add(__attr __result, __attr __self, __attr _data, __attr other, __attr _size, __attr othersize); +__attr __fn_native_str_str_chr(__attr __result, __attr __self, __attr _data); +__attr __fn_native_str_str_lt(__attr __result, __attr __self, __attr _data, __attr other); +__attr __fn_native_str_str_gt(__attr __result, __attr __self, __attr _data, __attr other); +__attr __fn_native_str_str_eq(__attr __result, __attr __self, __attr _data, __attr other); +__attr __fn_native_str_str_ord(__attr __result, __attr __self, __attr _data); +__attr __fn_native_str_str_size(__attr __result, __attr __self); +__attr __fn_native_str_str_substr(__attr __result, __attr __self, __attr _data, __attr start, __attr end, __attr step); /* Module initialisation. */ diff -r 1e7ccc84119f -r 0be4f390513d templates/native/system.c --- a/templates/native/system.c Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/system.c Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for system operations. -Copyright (C) 2016, 2017, 2021 Paul Boddie +Copyright (C) 2016, 2017, 2021, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -27,19 +27,19 @@ /* Environment support. */ -__attr __fn_native_system_exit(__attr __self, __attr status) +__attr __fn_native_system_exit(__attr __result, __attr __self, __attr status) { exit(__TOINT(status)); return __builtins___none_None; } -__attr __fn_native_system_get_argv(__attr __self) +__attr __fn_native_system_get_argv(__attr __result, __attr __self) { /* NOTE: To be written. */ return __builtins___none_None; } -__attr __fn_native_system_get_path(__attr __self) +__attr __fn_native_system_get_path(__attr __result, __attr __self) { /* NOTE: To be written. */ return __builtins___none_None; diff -r 1e7ccc84119f -r 0be4f390513d templates/native/system.h --- a/templates/native/system.h Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/system.h Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for system operations. -Copyright (C) 2016, 2017 Paul Boddie +Copyright (C) 2016, 2017, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,9 +23,9 @@ /* Environment support. */ -__attr __fn_native_system_exit(__attr __self, __attr status); -__attr __fn_native_system_get_argv(__attr __self); -__attr __fn_native_system_get_path(__attr __self); +__attr __fn_native_system_exit(__attr __result, __attr __self, __attr status); +__attr __fn_native_system_get_argv(__attr __result, __attr __self); +__attr __fn_native_system_get_path(__attr __result, __attr __self); /* Module initialisation. */ diff -r 1e7ccc84119f -r 0be4f390513d templates/native/tuple.c --- a/templates/native/tuple.c Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/tuple.c Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for tuple operations. -Copyright (C) 2016, 2017, 2021 Paul Boddie +Copyright (C) 2016, 2017, 2021, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -29,7 +29,7 @@ static __fragment __empty_fragment = {.size=0, .capacity=0}; -__attr __fn_native_tuple_tuple_init(__attr __self, __attr size) +__attr __fn_native_tuple_tuple_init(__attr __result, __attr __self, __attr size) { /* size interpreted as int */ __int n = __TOINT(size); diff -r 1e7ccc84119f -r 0be4f390513d templates/native/tuple.h --- a/templates/native/tuple.h Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/tuple.h Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for tuple operations. -Copyright (C) 2016, 2017 Paul Boddie +Copyright (C) 2016, 2017, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,7 +23,7 @@ /* List operations. */ -__attr __fn_native_tuple_tuple_init(__attr __self, __attr size); +__attr __fn_native_tuple_tuple_init(__attr __result, __attr __self, __attr size); /* Module initialisation. */ diff -r 1e7ccc84119f -r 0be4f390513d templates/native/unicode.c --- a/templates/native/unicode.c Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/unicode.c Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for Unicode operations. -Copyright (C) 2016, 2017, 2021 Paul Boddie +Copyright (C) 2016, 2017, 2021, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -69,7 +69,7 @@ /* Unicode operations. */ -__attr __fn_native_unicode_unicode_len(__attr __self, __attr _data, __attr _size) +__attr __fn_native_unicode_unicode_len(__attr __result, __attr __self, __attr _data, __attr _size) { /* _data interpreted as string.__data__ */ char *s = _data.strvalue; @@ -85,7 +85,7 @@ return __new_int(c); } -__attr __fn_native_unicode_unicode_ord(__attr __self, __attr _data, __attr _size) +__attr __fn_native_unicode_unicode_ord(__attr __result, __attr __self, __attr _data, __attr _size) { /* _data interpreted as string.__data__ */ char *s = _data.strvalue; @@ -119,7 +119,7 @@ return __new_int(c); } -__attr __fn_native_unicode_unicode_substr(__attr __self, __attr _data, __attr _size, __attr start, __attr end, __attr step) +__attr __fn_native_unicode_unicode_substr(__attr __result, __attr __self, __attr _data, __attr _size, __attr start, __attr end, __attr step) { /* _data interpreted as string.__data__ */ char *s = _data.strvalue, *sub; @@ -193,7 +193,7 @@ return __new_str(sub, resultsize); } -__attr __fn_native_unicode_unicode_unichr(__attr __self, __attr value) +__attr __fn_native_unicode_unicode_unichr(__attr __result, __attr __self, __attr value) { /* value interpreted as int */ int i = __TOINT(value); diff -r 1e7ccc84119f -r 0be4f390513d templates/native/unicode.h --- a/templates/native/unicode.h Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/native/unicode.h Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Native functions for Unicode operations. -Copyright (C) 2016, 2017 Paul Boddie +Copyright (C) 2016, 2017, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -21,10 +21,10 @@ /* Unicode operations. */ -__attr __fn_native_unicode_unicode_len(__attr __self, __attr _data, __attr _size); -__attr __fn_native_unicode_unicode_ord(__attr __self, __attr _data, __attr _size); -__attr __fn_native_unicode_unicode_substr(__attr __self, __attr _data, __attr _size, __attr start, __attr end, __attr step); -__attr __fn_native_unicode_unicode_unichr(__attr __self, __attr value); +__attr __fn_native_unicode_unicode_len(__attr __result, __attr __self, __attr _data, __attr _size); +__attr __fn_native_unicode_unicode_ord(__attr __result, __attr __self, __attr _data, __attr _size); +__attr __fn_native_unicode_unicode_substr(__attr __result, __attr __self, __attr _data, __attr _size, __attr start, __attr end, __attr step); +__attr __fn_native_unicode_unicode_unichr(__attr __result, __attr __self, __attr value); /* Module initialisation. */ diff -r 1e7ccc84119f -r 0be4f390513d templates/ops.c --- a/templates/ops.c Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/ops.c Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Common operations. -Copyright (C) 2015, 2016, 2017, 2018 Paul Boddie +Copyright (C) 2015, 2016, 2017, 2018, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -447,3 +447,38 @@ memcpy(copy, obj, size); return copy; } + +/* Return a suitable attribute for a local. For locals that support value + replacement, a copied object may be returned in certain cases. + NOTE: Only floats are currently supported for value replacement. */ + +void __set_local(volatile __attr *local, __attr attr) +{ + __ref obj; + + /* Value already replaced in target by an operation. */ + + if (__REPLACING(attr)) + return; + + obj = __VALUE(attr); + + /* Value not replaceable, suitable for direct propagation to a local. */ + + if ((obj == NULL) || !__is_instance(obj) || (__get_class(obj) != &__builtins___float_float)) + *local = attr; + + /* Value is replaceable and should be copied to avoid inadvertent + sharing. */ + + else + *local = __ATTRVALUE(__COPY(obj, sizeof(__obj___builtins___float_float))); +} + +/* Make sure that attributes indicating value replacement are usable as + arguments. */ + +__attr __to_arg(__attr attr) +{ + return __REPLACING(attr) ? __REPLACED(attr) : attr; +} diff -r 1e7ccc84119f -r 0be4f390513d templates/ops.h --- a/templates/ops.h Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/ops.h Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Common operations. -Copyright (C) 2015, 2016, 2017, 2018 Paul Boddie +Copyright (C) 2015, 2016, 2017, 2018, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -136,7 +136,7 @@ __ref __ISFUNC(__ref obj); -#define __ISNULL(__ATTR) (!__ATTR.value) +#define __ISNULL(__ATTR) (!(__ATTR).value) /* Attribute codes and positions for type objects. */ @@ -153,4 +153,9 @@ __ref __COPY(__ref obj, int size); +/* Result target administration for potential value replacement. */ + +void __set_local(volatile __attr *local, __attr attr); +__attr __to_arg(__attr attr); + #endif /* __OPS_H__ */ diff -r 1e7ccc84119f -r 0be4f390513d templates/progops.c --- a/templates/progops.c Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/progops.c Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Operations depending on program specifics. -Copyright (C) 2015-2019, 2021 Paul Boddie +Copyright (C) 2015-2019, 2021, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -44,7 +44,7 @@ __attr __new_wrapper(__attr context, __attr attr) { - return __new___builtins___core_wrapper(__NULL, context, attr); + return __new___builtins___core_wrapper(__NULL, __NULL, context, attr); } /* Generic internal data allocation. */ @@ -113,7 +113,7 @@ /* Call __init__ with the dict object and list argument. */ - __fn___builtins___dict_dict___init__(self, tmp); + __fn___builtins___dict_dict___init__(__NULL, self, tmp); return self; } #endif /* __HAVE___builtins___dict_dict */ @@ -123,73 +123,73 @@ void __raise_eof_error() { #ifdef __HAVE___builtins___exception_io_EOFError - __Raise(__new___builtins___exception_io_EOFError(__NULL)); + __Raise(__new___builtins___exception_io_EOFError(__NULL, __NULL)); #endif /* __HAVE___builtins___exception_io_EOFError */ } void __raise_floating_point_error() { - __Raise(__new___builtins___core_FloatingPointError(__NULL)); + __Raise(__new___builtins___core_FloatingPointError(__NULL, __NULL)); } void __raise_io_error(__attr value) { #ifdef __HAVE___builtins___exception_io_IOError - __Raise(__new___builtins___exception_io_IOError(__NULL, value)); + __Raise(__new___builtins___exception_io_IOError(__NULL, __NULL, value)); #endif /* __HAVE___builtins___exception_io_IOError */ } void __raise_memory_error() { - __Raise(__new___builtins___core_MemoryError(__NULL)); + __Raise(__new___builtins___core_MemoryError(__NULL, __NULL)); } void __raise_os_error(__attr value, __attr arg) { #ifdef __HAVE___builtins___exception_system_OSError - __Raise(__new___builtins___exception_system_OSError(__NULL, value, arg)); + __Raise(__new___builtins___exception_system_OSError(__NULL, __NULL, value, arg)); #endif /* __HAVE___builtins___exception_system_OSError */ } void __raise_overflow_error() { - __Raise(__new___builtins___core_OverflowError(__NULL)); + __Raise(__new___builtins___core_OverflowError(__NULL, __NULL)); } void __raise_unbound_method_error() { - __Raise(__new___builtins___core_UnboundMethodInvocation(__NULL)); + __Raise(__new___builtins___core_UnboundMethodInvocation(__NULL, __NULL)); } void __raise_type_error() { - __Raise(__new___builtins___core_TypeError(__NULL)); + __Raise(__new___builtins___core_TypeError(__NULL, __NULL)); } void __raise_underflow_error() { - __Raise(__new___builtins___core_UnderflowError(__NULL)); + __Raise(__new___builtins___core_UnderflowError(__NULL, __NULL)); } void __raise_value_error(__attr value) { #ifdef __HAVE___builtins___exception_base_ValueError - __Raise(__new___builtins___exception_base_ValueError(__NULL, value)); + __Raise(__new___builtins___exception_base_ValueError(__NULL, __NULL, value)); #endif /* __HAVE___builtins___exception_base_ValueError */ } void __raise_zero_division_error() { - __Raise(__new___builtins___core_ZeroDivisionError(__NULL)); + __Raise(__new___builtins___core_ZeroDivisionError(__NULL, __NULL)); } /* Helper for raising exception instances. */ __attr __ensure_instance(__attr arg) { - /* Reserve space for the instance. */ + /* Reserve space for the result target and instance. */ - __attr args[1] = {__NULL}; + __attr args[2] = {__NULL, __NULL}; /* Return instances as provided. */ @@ -199,7 +199,7 @@ /* Invoke non-instances to produce instances. */ else - return __invoke(arg, 0, 0, 0, 0, 1, args); + return __invoke(arg, 0, 0, 0, 0, 2, args); } /* Generic invocation operations. */ @@ -294,16 +294,20 @@ return __call_with_args( always_callable ? - __get_function_unwrapped(allargs[0], target) : - __check_and_get_function_unwrapped(allargs[0], target), + + /* Remember that the arguments start with the result target and then + the context. */ + + __get_function_unwrapped(allargs[1], target) : + __check_and_get_function_unwrapped(allargs[1], target), allargs, max); } /* Error routines. */ -__attr __unbound_method(__attr __self) +__attr __unbound_method(__attr __result, __attr __self) { - __Raise(__new___builtins___core_UnboundMethodInvocation(__NULL)); + __Raise(__new___builtins___core_UnboundMethodInvocation(__NULL, __NULL)); return __builtins___none_None; /* superfluous */ } @@ -336,5 +340,5 @@ return value == (__ref) &__predefined___builtins___boolean_True ? 1 : value == (__ref) &__predefined___builtins___boolean_False ? 0 : - __VALUE(__fn___builtins___boolean_bool(__NULL, attr)) == (__ref) &__predefined___builtins___boolean_True; + __VALUE(__fn___builtins___boolean_bool(__NULL, __NULL, attr)) == (__ref) &__predefined___builtins___boolean_True; } diff -r 1e7ccc84119f -r 0be4f390513d templates/progops.h --- a/templates/progops.h Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/progops.h Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Operations depending on program specifics. -Copyright (C) 2015-2019, 2021 Paul Boddie +Copyright (C) 2015-2019, 2021, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -71,7 +71,7 @@ /* Error routines. */ -__attr __unbound_method(__attr __self); +__attr __unbound_method(__attr __result, __attr __self); /* Generic operations depending on specific program details. */ @@ -86,7 +86,7 @@ #define __INSTANCETABLE(CLS) (__InstanceTable_##CLS) #define __NEWINSTANCE(CLS) __new(&__INSTANCETABLE(CLS), &CLS, __INSTANCESIZE(CLS), 0) #define __NEWINSTANCEIM(CLS) __new(&__INSTANCETABLE(CLS), &CLS, __INSTANCESIZE(CLS), 1) -#define __ISINSTANCE(ATTR, TYPE) __BOOL(__fn_native_introspection_isinstance(__NULL, ATTR, TYPE)) +#define __ISINSTANCE(ATTR, TYPE) __BOOL(__fn_native_introspection_isinstance(__NULL, __NULL, ATTR, TYPE)) /* Operations for accessing trailing data. */ diff -r 1e7ccc84119f -r 0be4f390513d templates/types.h --- a/templates/types.h Thu Nov 04 23:44:29 2021 +0100 +++ b/templates/types.h Tue Aug 29 01:46:23 2023 +0200 @@ -1,6 +1,6 @@ /* Runtime types. -Copyright (C) 2015-2019, 2021 Paul Boddie +Copyright (C) 2015-2019, 2021, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -75,6 +75,10 @@ typedef ssize_t __int; +/* Introduce a tagged pointer type. */ + +typedef uintptr_t __ref_tagged; + /* Attribute value interpretations. */ typedef union __attr @@ -83,6 +87,7 @@ __ref value; /* attribute value */ __int intvalue; /* integer value data (shifted value, tagged) */ + __ref_tagged refvalue; /* attribute value with tag */ /* Special case attribute members. */ @@ -127,8 +132,8 @@ #define __NUM_TAG_BITS 2 #define __TAG_INT 0b01 -#define __TAG_MASK 0b11 -#define __INTEGER(ATTR) (((ATTR).intvalue & __TAG_MASK) == __TAG_INT) +#define __TAG_REPLACING 0b10 +#define __INTEGER(ATTR) ((ATTR).intvalue & __TAG_INT) /* Attribute value setting. */ @@ -143,6 +148,12 @@ #define __MAXINT ((((__int) 1) << ((sizeof(__int) * 8) - 1 - __NUM_TAG_BITS)) - 1) #define __MININT (-(((__int) 1) << ((sizeof(__int) * 8) - 1 - __NUM_TAG_BITS))) +/* Attribute carrying replacement value. */ + +#define __REPLACEMENT(ATTR) ((__attr) {.refvalue=(((__ref_tagged) (ATTR).value) | __TAG_REPLACING)}) +#define __REPLACED(ATTR) ((__attr) {.value=((__ref) ((ATTR).refvalue & ~__TAG_REPLACING))}) +#define __REPLACING(ATTR) ((ATTR).refvalue & __TAG_REPLACING) + /* Argument lists. */ #define __ARGS(...) ((__attr[]) {__VA_ARGS__}) diff -r 1e7ccc84119f -r 0be4f390513d translator.py --- a/translator.py Thu Nov 04 23:44:29 2021 +0100 +++ b/translator.py Tue Aug 29 01:46:23 2023 +0200 @@ -3,7 +3,7 @@ """ Translate programs. -Copyright (C) 2015, 2016, 2017, 2018 Paul Boddie +Copyright (C) 2015, 2016, 2017, 2018, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -493,7 +493,7 @@ # Names and attributes are assigned the entire expression. if isinstance(n, compiler.ast.AssName): - name_ref = self.process_name_node(n, self.process_structure_node(expr)) + name_ref = self.process_name_node(n, expr, True) self.statement(name_ref) # Employ guards after assignments if required. @@ -858,6 +858,9 @@ self.max_context_index = 0 self.accessor_index = 0 self.max_accessor_index = 0 + self.result_target = 0 + self.max_result_target = 0 + self.result_target_name = None # Volatile locals for exception handling. @@ -1280,6 +1283,19 @@ if stores_accessor: self.record_temp("__tmp_values") + # Employ result targets only in functions. + + if self.in_function: + if self.result_target_name: + result_target = self.result_target_name + self.result_target_name = None + else: + result_target = "__tmp_results[%d]" % self.result_target + self.record_temp("__tmp_results") + self.next_result() + else: + result_target = "__NULL" + # Arguments are presented in a temporary frame array with any context # always being the first argument. Where it would be unused, it may be # set to null. @@ -1292,7 +1308,10 @@ else: context_arg = "__NULL" - args = [context_arg] + # Start with result target and context arguments for each invocation. + + args = [result_target, context_arg] + argstart = 2 # Complete the array with null values, permitting tests for a complete # set of arguments. @@ -1323,6 +1342,13 @@ for i, arg in enumerate(n.args): argexpr = self.process_structure_node(arg) + # Convert any attributes indicating value replacement. + + if isinstance(argexpr, InvocationResult): + argexprstr = "__to_arg(%s)" % argexpr + else: + argexprstr = str(argexpr) + # Store a keyword argument, either in the argument list or # in a separate keyword argument list for subsequent lookup. @@ -1337,12 +1363,12 @@ except ValueError: raise TranslateError("Argument %s is not recognised." % arg.name, self.get_namespace_path(), n) - args[argnum+1] = str(argexpr) + args[argnum+argstart] = argexprstr # Otherwise, store the details in a separate collection. else: - kwargs.append(str(argexpr)) + kwargs.append(argexprstr) kwcodes.append("{%s, %s}" % ( encode_ppos(arg.name), encode_pcode(arg.name))) @@ -1351,7 +1377,7 @@ else: try: - args[i+1] = str(argexpr) + args[i+argstart] = argexprstr except IndexError: raise TranslateError("Too many arguments specified.", self.get_namespace_path(), n) @@ -1375,8 +1401,8 @@ for i, (argname, default) in enumerate(function_defaults): argnum = parameters.index(argname) - if not args[argnum+1]: - args[argnum+1] = "__GETDEFAULT(%s, %d)" % (target_structure, i) + if not args[argnum+argstart]: + args[argnum+argstart] = "__GETDEFAULT(%s, %d)" % (target_structure, i) elif known_parameters: @@ -1387,7 +1413,7 @@ i = len(n.args) pos = i - (num_parameters - num_defaults) while i < num_parameters: - args[i+1] = "__GETDEFAULT(%s.value, %d)" % (target_var, pos) + args[i+argstart] = "__GETDEFAULT(%s.value, %d)" % (target_var, pos) i += 1 pos += 1 @@ -1400,10 +1426,10 @@ # Encode the arguments. # Where literal instantiation is occurring, add an argument indicating - # the number of values. The context is excluded. + # the number of values. The result target and context are excluded. if literal_instantiation: - argstr = "%d, %s" % (len(args) - 1, ", ".join(args[1:])) + argstr = "%d, %s" % (len(args) - 2, ", ".join(args[2:])) else: argstr = ", ".join(args) @@ -1492,6 +1518,13 @@ len(args), "__ARGS(%s)" % argstr)) return InvocationResult(stages) + def next_result(self): + + "Allocate the next result target storage." + + self.result_target += 1 + self.max_result_target = max(self.result_target, self.max_result_target) + def next_target(self): "Allocate the next function target storage." @@ -1605,7 +1638,7 @@ return LogicalOperationResult(results, conjunction) - def process_name_node(self, n, expr=None): + def process_name_node(self, n, expr=None, process_expr=False): "Process the given name node 'n' with the optional assignment 'expr'." @@ -1672,6 +1705,19 @@ if expr and self.in_function and not is_global and self.in_try_except: self.make_volatile(n.name) + # Set the replacement target for local objects. + # Note that this will not apply to all local objects, with only floats + # supporting replaceable values. + + if expr and self.in_function and not is_global: + self.result_target_name = encode_path(n.name) + + # Expression processing is deferred until after any result target has + # been set. + + if process_expr: + expr = self.process_structure_node(expr) + # Qualified names are used for resolved static references or for # static namespace members. The reference should be configured to return # such names. @@ -1746,7 +1792,11 @@ "Process the given return node 'n'." + if self.in_function: + self.result_target_name = "__result" + expr = self.process_structure_node(n.value) or PredefinedConstantRef("None") + if self.in_try_finally or self.in_try_except: self.writestmt("__Return(%s);" % expr) else: @@ -2145,6 +2195,7 @@ # Generate any self reference. l = [] + l.append("__attr __result") if self.is_method(name): l.append("__attr self") @@ -2178,6 +2229,9 @@ # Add temporary variable usage details. + if self.uses_temp(name, "__tmp_results"): + self.writeline("__attr __tmp_results[%d] = {0};" % self.max_result_target) + if self.uses_temp(name, "__tmp_private_context"): self.writeline("__attr __tmp_private_context;") if self.uses_temp(name, "__tmp_target_value"): diff -r 1e7ccc84119f -r 0be4f390513d transresults.py --- a/transresults.py Thu Nov 04 23:44:29 2021 +0100 +++ b/transresults.py Tue Aug 29 01:46:23 2023 +0200 @@ -3,7 +3,7 @@ """ Translation result abstractions. -Copyright (C) 2016, 2017, 2018 Paul Boddie +Copyright (C) 2016, 2017, 2018, 2023 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -20,7 +20,8 @@ """ from common import first, InstructionSequence -from encoders import encode_instructions, encode_literal_constant, encode_path +from encoders import encode_instructions, encode_literal_constant, encode_path, \ + encode_symbol from results import ConstantValueRef, InstanceRef, LiteralSequenceRef, NameRef, \ ResolvedNameRef, Result @@ -112,9 +113,10 @@ encode_path(parent), attrname, self.expr) # All other assignments involve the names as they were given. + # To support value replacement, a special operation is used. else: - return "%s = %s" % (attrname, self.expr) + return "__set_local(&%s, %s)" % (attrname, self.expr) # Expressions.