diff options
-rw-r--r-- | ffi.c | 8 | ||||
-rw-r--r-- | share/txr/stdlib/ffi.tl | 8 | ||||
-rw-r--r-- | txr.1 | 33 |
3 files changed, 42 insertions, 7 deletions
@@ -5494,6 +5494,13 @@ val fill_obj(val obj, val type, val stream) return tft->in(tft, 1, data, obj, self); } +static val dyn_size(val type, val obj) +{ + val self = lit("sizeof"); + struct txr_ffi_type *tft = ffi_type_struct_checked(self, type); + return num(tft->dynsize(tft, obj, self)); +} + void ffi_init(void) { prot1(&ffi_typedef_hash); @@ -5625,6 +5632,7 @@ void ffi_init(void) reg_fun(intern(lit("put-obj"), user_package), func_n3o(put_obj, 2)); reg_fun(intern(lit("get-obj"), user_package), func_n2o(get_obj, 1)); reg_fun(intern(lit("fill-obj"), user_package), func_n3o(fill_obj, 2)); + reg_fun(intern(lit("dyn-size"), system_package), func_n2(dyn_size)); ffi_typedef_hash = make_hash(nil, nil, nil); ffi_init_types(); ffi_init_extra_types(); diff --git a/share/txr/stdlib/ffi.tl b/share/txr/stdlib/ffi.tl index cf5bd8a1..99c0da72 100644 --- a/share/txr/stdlib/ffi.tl +++ b/share/txr/stdlib/ffi.tl @@ -122,8 +122,12 @@ (defvarl ,var-sym (carray-cptr ,var-ref ,type-sym 1)) (defsymacro ,name (carray-ref ,var-sym 0))))) -(defmacro sizeof (type) - (ffi-size (ffi-type-compile type))) +(defmacro sizeof (type : (obj nil obj-p) :env menv) + (if obj-p + (if (constantp obj menv) + (sys:dyn-size (ffi-type-compile type) obj) + ^(sys:dyn-size (load-time (ffi-type-compile ',type)) ,obj)) + (ffi-size (ffi-type-compile type)))) (defmacro alignof (type) (ffi-alignof (ffi-type-compile type))) @@ -64059,17 +64059,40 @@ as its value. .coNP Macro @ sizeof .synb -.mets (sizeof << type-syntax ) +.mets (sizeof < type-syntax <> [ object-expr ]) .syne .desc The macro .code sizeof calculates the size of the FFI type denoted by +.codn type-syntax . + +The +.meta type-syntax +expression is compiled to a type using +.codn ffi-type-compile . +The +.meta object-expr +expression is evaluated to an object value. + +If .code type-syntax -at macro-expansion time, and produces that -integer value as its expansion, such that there is no -run-time computation. It uses the -.code ffi-sizeof +denotes a variable length type, and the +.meta object-expr +argument is present, then a +.I "dynamic size" is computed: the actual number of bytes required to store +that object value as a foreign representation of the specified variable length +type. + +The +.code sizeof +macro arranges for the size calculation to be carried out at macro-expansion +time, if possible, so that the +.code sizeof +form is replaced by an integer constant. This is possible when the +.meta object-expr +is omitted, or if it is a constant expression according to the +.code constantp function. .coNP Macro @ alignof |