Skip to content

Instantly share code, notes, and snippets.

@shirok
Created September 14, 2014 00:01
Show Gist options
  • Save shirok/c8efc349caa0b66be1c9 to your computer and use it in GitHub Desktop.
Save shirok/c8efc349caa0b66be1c9 to your computer and use it in GitHub Desktop.
diff --git a/src/class.c b/src/class.c
index cdebd2c..9b6a1e3 100644
--- a/src/class.c
+++ b/src/class.c
@@ -2701,6 +2701,11 @@ static void accessor_method_slot_accessor_set(ScmAccessorMethod *m, ScmObj v)
* Foreign pointer mechanism
*/
+/* foreign pointer instance flags */
+enum {
+ SCM_FOREIGN_POINTER_INVALID = (1L<<0) /* The pointer is no longer valid. */
+};
+
struct foreign_data_rec {
int flags;
ScmForeignCleanupProc cleanup;
@@ -2767,6 +2772,7 @@ static ScmForeignPointer *make_foreign_int(ScmClass *klass, void *ptr,
SCM_SET_CLASS(obj, klass);
obj->ptr = ptr;
obj->attributes = attr;
+ obj->flags = 0;
if (data->cleanup) {
Scm_RegisterFinalizer(SCM_OBJ(obj), fp_finalize, data->cleanup);
}
@@ -2818,6 +2824,26 @@ ScmObj Scm_MakeForeignPointerWithAttr(ScmClass *klass, void *ptr, ScmObj attr)
return SCM_OBJ(obj);
}
+void *Scm_ForeignPointerRef(ScmForeignPointer *fp)
+{
+ if (!Scm_ForeignPointerValidP(fp)) {
+ Scm_Error("attempt to dereference a foreign pointer "
+ "that is no longer valid: %S", SCM_OBJ(fp));
+
+ }
+ return fp->ptr;
+}
+
+int Scm_ForeignPointerValidP(ScmForeignPointer *fp)
+{
+ return (fp->flags & SCM_FOREIGN_POINTER_INVALID);
+}
+
+void Scm_ForeignPointerInvalidate(ScmForeignPointer *fp)
+{
+ fp->flags |= SCM_FOREIGN_POINTER_INVALID;
+}
+
ScmObj Scm_ForeignPointerAttr(ScmForeignPointer *fp)
{
return fp->attributes;
diff --git a/src/gauche.h b/src/gauche.h
index 33e7796..9dceaa1 100644
--- a/src/gauche.h
+++ b/src/gauche.h
@@ -924,12 +924,14 @@ typedef struct ScmForeignPointerRec {
constructed by Scm_MakeForeignPointer. */
ScmObj attributes; /* alist. useful to store e.g. callbacks.
use accessor procedures. */
+ ScmWord flags; /* used internally. We use ScmWord to keep
+ ScmForeignPointer fit in 4 words. */
} ScmForeignPointer;
#define SCM_FOREIGN_POINTER_P(obj) SCM_ISA(obj, SCM_CLASS_FOREIGN_POINTER)
#define SCM_FOREIGN_POINTER(obj) ((ScmForeignPointer*)(obj))
#define SCM_FOREIGN_POINTER_REF(type, obj) \
- ((type)(SCM_FOREIGN_POINTER(obj)->ptr))
+ ((type)(Scm_ForeignPointerRef(SCM_FOREIGN_POINTER(obj))))
typedef void (*ScmForeignCleanupProc)(ScmObj);
@@ -941,8 +943,11 @@ SCM_EXTERN ScmClass *Scm_MakeForeignPointerClass(ScmModule *module,
SCM_EXTERN ScmObj Scm_MakeForeignPointer(ScmClass *klass, void *ptr);
SCM_EXTERN ScmObj Scm_MakeForeignPointerWithAttr(ScmClass *klass, void *ptr,
ScmObj attr);
+SCM_EXTERN void *Scm_ForeignPointerRef(ScmForeignPointer *fp);
+SCM_EXTERN int Scm_ForeignPointerValidP(ScmForeignPointer *fp);
+SCM_EXTERN void Scm_ForeignPointerInvalidate(ScmForeignPointer *fp);
-/* foreign pointer flags */
+/* foreign pointer class flags */
enum {
SCM_FOREIGN_POINTER_KEEP_IDENTITY = (1L<<0),
/* If set, a foreign pointer class keeps a weak hash table that maps
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment