Module: c-ffi-implementation Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND // // ELEMENT // define sideways inline method element (ptr :: , index :: , #key default) => (o :: ); pointer-value(ptr, index: index); end method element; // // ELEMENT-SETTER // define sideways inline method element-setter (new :: , ptr :: , index :: ) => (o :: ); pointer-value-setter(new, ptr, index: index); new; end method element-setter; // // POINTER-ADDRESS // define inline function pointer-address (ptr :: ) => (a :: ); primitive-wrap-machine-word (primitive-cast-pointer-as-raw(primitive-unwrap-c-pointer(ptr))) end function pointer-address; // // POINTER-VALUE & POINTER-VALUE-SETTER // define macro pointer-value-method-definer { define pointer-value-method ?pointer-class:name ?accessor:name ?result-class:name } => { define sideways method pointer-value (ptr :: ?pointer-class, #key index :: = 0) => (result :: ?result-class); ?accessor(ptr, scaled-index: index) end method pointer-value; define sideways method pointer-value-setter (new-value :: ?result-class, ptr :: ?pointer-class, #key index :: = 0) => (new-value :: ?result-class); ?accessor(ptr, scaled-index: index) := new-value end method pointer-value-setter; } end macro pointer-value-method-definer; define pointer-value-method C-signed-int-at ; define pointer-value-method C-unsigned-int-at ; define pointer-value-method C-unsigned-char-at ; define pointer-value-method C-signed-char-at ; // define pointer-value-method C-char-at ; define pointer-value-method C-unsigned-short-at ; define pointer-value-method C-signed-short-at ; define pointer-value-method C-unsigned-long-at ; define pointer-value-method C-signed-long-at ; define pointer-value-method C-float-at ; define pointer-value-method C-double-at ; /* define pointer-value-method C-long-double-at ; */ // TODO: CORRECTNESS: Pointers to pointers don't seem to have // as a superclass uniformly. As a hack, // we can detect pointers to pointers by omission - i.e. if // it ain't caught by one of the above methods, then it may be // a pointer type... define sideways method pointer-value (ptr :: , /* */ #key index :: = 0) => (p1 :: ); let ref-type = referenced-type(object-class(ptr)); if (subtype?(ref-type, )) make-c-pointer(ref-type, primitive-cast-pointer-as-raw (primitive-c-pointer-at (primitive-unwrap-c-pointer(ptr), integer-as-raw(index), integer-as-raw(0))), #[]); else next-method(); end if; end method pointer-value; define sideways method pointer-value-setter (new :: , ptr :: , /* */ #key index :: = 0) => (new :: ); let ref-type = referenced-type(object-class(ptr)); if (subtype?(ref-type, )) primitive-c-pointer-at-setter(primitive-unwrap-c-pointer(new), primitive-unwrap-c-pointer(ptr), integer-as-raw(index), integer-as-raw(0)); new; else next-method(); end if; end method pointer-value-setter; // // POINTER-VALUE-ADDRESS // define inline sideways method pointer-value-address (ptr :: , #key index :: = 0) => (value :: ) let clss = object-class(ptr); let object-size :: = size-of(referenced-type(clss)); make-c-pointer(clss, primitive-machine-word-add (primitive-cast-pointer-as-raw (primitive-unwrap-c-pointer(ptr)), integer-as-raw(index * object-size)), #[]); end method pointer-value-address;