# HG changeset patch # User Paul Boddie # Date 1480283315 -3600 # Node ID 45e5c06ead64482e39c06616b919ccf081fbb9f7 # Parent a5ab50def31fb009de650d4d0b5b2632e9db0d54 Tidied up memory allocation and error handling. diff -r a5ab50def31f -r 45e5c06ead64 generator.py --- a/generator.py Sun Nov 27 22:47:09 2016 +0100 +++ b/generator.py Sun Nov 27 22:48:35 2016 +0100 @@ -53,6 +53,7 @@ function_type = "__builtins__.core.function" type_error_type = "__builtins__.core.TypeError" + memory_error_type = "__builtins__.core.MemoryError" # NOTE: These must be synchronised with the library. @@ -350,11 +351,13 @@ #define __FUNCTION_TYPE %s #define __FUNCTION_INSTANCE_SIZE %s #define __TYPE_ERROR_INSTANTIATOR %s +#define __MEMORY_ERROR_INSTANTIATOR %s #endif /* __PROGTYPES_H__ */""" % ( encode_path(self.function_type), encode_size("", self.function_type), - encode_instantiator_pointer(self.type_error_type) + encode_instantiator_pointer(self.type_error_type), + encode_instantiator_pointer(self.memory_error_type) ) print >>f_signatures, """\ diff -r a5ab50def31f -r 45e5c06ead64 lib/__builtins__/__init__.py --- a/lib/__builtins__/__init__.py Sun Nov 27 22:47:09 2016 +0100 +++ b/lib/__builtins__/__init__.py Sun Nov 27 22:48:35 2016 +0100 @@ -20,7 +20,7 @@ """ from __builtins__.core import function, get_using, object, type, \ - BaseException, Exception, TypeError, \ + BaseException, Exception, MemoryError, TypeError, \ UnboundMethodInvocation, Warning # Exceptions. @@ -43,7 +43,6 @@ KeyError, KeyboardInterrupt, LookupError, - MemoryError, NameError, NotImplementedError, OSError, diff -r a5ab50def31f -r 45e5c06ead64 lib/__builtins__/core.py --- a/lib/__builtins__/core.py Sun Nov 27 22:47:09 2016 +0100 +++ b/lib/__builtins__/core.py Sun Nov 27 22:48:35 2016 +0100 @@ -91,6 +91,7 @@ pass class Exception(BaseException): pass +class MemoryError(Exception): pass class TypeError(Exception): pass class UnboundMethodInvocation(Exception): pass class Warning(object): pass diff -r a5ab50def31f -r 45e5c06ead64 lib/__builtins__/exception/__init__.py --- a/lib/__builtins__/exception/__init__.py Sun Nov 27 22:47:09 2016 +0100 +++ b/lib/__builtins__/exception/__init__.py Sun Nov 27 22:48:35 2016 +0100 @@ -69,7 +69,6 @@ from __builtins__.exception.system import ( EnvironmentError, - MemoryError, OSError, RuntimeError, RuntimeWarning, diff -r a5ab50def31f -r 45e5c06ead64 lib/__builtins__/exception/system.py --- a/lib/__builtins__/exception/system.py Sun Nov 27 22:47:09 2016 +0100 +++ b/lib/__builtins__/exception/system.py Sun Nov 27 22:48:35 2016 +0100 @@ -3,7 +3,7 @@ """ System exception objects. -Copyright (C) 2015 Paul Boddie +Copyright (C) 2015, 2016 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,6 @@ """ class EnvironmentError(Exception): pass -class MemoryError(Exception): pass class OSError(Exception): pass class RuntimeError(Exception): pass class RuntimeWarning(Warning): pass diff -r a5ab50def31f -r 45e5c06ead64 templates/native.c --- a/templates/native.c Sun Nov 27 22:47:09 2016 +0100 +++ b/templates/native.c Sun Nov 27 22:48:35 2016 +0100 @@ -1,4 +1,4 @@ -#include /* calloc, exit, realloc */ +#include /* exit */ #include /* read, write */ #include /* ceil, log10, pow */ #include /* strcmp, strncpy, strlen */ @@ -252,7 +252,7 @@ /* self.__data__ interpreted as int */ int i = __load_via_object(self->value, __pos___data__).intvalue; int n = i != 0 ? (int) ceil(log10(i+1)) + 1 : 2; - char *s = calloc(n, sizeof(char)); + char *s = (char *) __ALLOCATE(n, sizeof(char)); if (i < 0) n++; snprintf(s, n, "%d", i); @@ -269,7 +269,7 @@ char *s = __load_via_object(self->value, __pos___data__).strvalue; char *o = __load_via_object(other->value, __pos___data__).strvalue; int n = strlen(s) + strlen(o) + 1; - char *r = calloc(n, sizeof(char)); + char *r = (char *) __ALLOCATE(n, sizeof(char)); strncpy(r, s, n); strncpy(r + strlen(s), o, n - strlen(s)); @@ -340,7 +340,7 @@ unsigned int n = __load_via_object(size->value, __pos___data__).intvalue; /* Allocate space for the list. */ - __fragment *data = calloc(1, __FRAGMENT_SIZE(n)); + __fragment *data = (__fragment *) __ALLOCATE(1, __FRAGMENT_SIZE(n)); __attr attr = {0, .data=data}; /* The initial capacity is the same as the given size. */ @@ -377,7 +377,7 @@ { /* NOTE: Consider various restrictions on capacity increases. */ n = capacity ? capacity * 2 : 1; - newdata = realloc(data, __FRAGMENT_SIZE(n)); + newdata = (__fragment *) __REALLOCATE(data, __FRAGMENT_SIZE(n)); newdata->capacity = n; } @@ -407,7 +407,7 @@ if (size + other_size >= capacity) { n = size + other_size; - newdata = realloc(data, __FRAGMENT_SIZE(n)); + newdata = (__fragment *) __REALLOCATE(data, __FRAGMENT_SIZE(n)); newdata->capacity = n; } @@ -479,7 +479,7 @@ size += strlen(__load_via_object(data->attrs[i].value, __pos___data__).strvalue); /* Reserve space for a new string. */ - s = calloc(size + 1, sizeof(char)); + s = (char *) __ALLOCATE(size + 1, sizeof(char)); /* Build a single string from the buffer contents. */ for (i = 0, j = 0; i < data->size; i++) diff -r a5ab50def31f -r 45e5c06ead64 templates/ops.c --- a/templates/ops.c Sun Nov 27 22:47:09 2016 +0100 +++ b/templates/ops.c Sun Nov 27 22:48:35 2016 +0100 @@ -5,6 +5,9 @@ #include "progconsts.h" #include "progtypes.h" +extern void __raise_type_error(); +extern void __raise_memory_error(); + /* Direct access and manipulation of static objects. */ __attr __load_static(__ref parent, __ref obj) @@ -272,11 +275,29 @@ return obj->pos; } +/* Memory allocation. */ + +void *__ALLOCATE(size_t nmemb, size_t size) +{ + void *ptr = calloc(nmemb, size); + if (ptr == NULL) + __raise_memory_error(); + return ptr; +} + +void *__REALLOCATE(void *ptr, size_t size) +{ + void *nptr = realloc(ptr, size); + if (nptr == NULL) + __raise_memory_error(); + return nptr; +} + /* Copying of structures. */ __ref __COPY(__ref obj, int size) { - __ref copy = calloc(1, size); + __ref copy = (__ref) __ALLOCATE(1, size); memcpy(copy, obj, size); return copy; } diff -r a5ab50def31f -r 45e5c06ead64 templates/ops.h --- a/templates/ops.h Sun Nov 27 22:47:09 2016 +0100 +++ b/templates/ops.h Sun Nov 27 22:48:35 2016 +0100 @@ -89,6 +89,11 @@ #define __ATTRCODE(__ATTRNAME) (__code_##__ATTRNAME) #define __ATTRPOS(__ATTRNAME) (__pos_##__ATTRNAME) +/* Memory allocation. */ + +void *__ALLOCATE(size_t nmemb, size_t size); +void *__REALLOCATE(void *ptr, size_t size); + /* Copying of structures. */ __ref __COPY(__ref obj, int size); diff -r a5ab50def31f -r 45e5c06ead64 templates/progops.c --- a/templates/progops.c Sun Nov 27 22:47:09 2016 +0100 +++ b/templates/progops.c Sun Nov 27 22:48:35 2016 +0100 @@ -14,7 +14,7 @@ __attr __new(const __table * table, __ref cls, size_t size) { - __ref obj = (__ref) calloc(1, size); + __ref obj = (__ref) __ALLOCATE(1, size); __attr self = {obj, obj}; __attr tmp = {0, cls}; obj->table = table; @@ -28,7 +28,7 @@ { /* Calculate the size of the fragment. */ - __fragment *data = (__fragment *) calloc(1, __FRAGMENT_SIZE(number)); + __fragment *data = (__fragment *) __ALLOCATE(1, __FRAGMENT_SIZE(number)); __attr attr = {0, .data=data}; unsigned int i, j; @@ -51,6 +51,15 @@ __Raise(exc); } +/* A helper for raising memory errors within common operations. */ + +void __raise_memory_error() +{ + __attr args[1]; + __attr exc = __MEMORY_ERROR_INSTANTIATOR(args); + __Raise(exc); +} + /* Generic invocation operations. */ /* Invoke the given callable, supplying keyword argument details in the given