summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ffi.c8
-rw-r--r--share/txr/stdlib/ffi.tl8
-rw-r--r--txr.133
3 files changed, 42 insertions, 7 deletions
diff --git a/ffi.c b/ffi.c
index d411dda7..c18b7efe 100644
--- a/ffi.c
+++ b/ffi.c
@@ -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)))
diff --git a/txr.1 b/txr.1
index 8f826635..86520746 100644
--- a/txr.1
+++ b/txr.1
@@ -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