Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ idris2docs_venv
.vscode/*
# JetBrains IDEs
.idea/
# Zed editor
.zed/

# macOS
.DS_Store
7 changes: 5 additions & 2 deletions CHANGELOG_NEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,13 @@ should target this file (`CHANGELOG_NEXT`).
systems, the compiler will now use `posix_memalign`.
* Fixed integer comparison operators returning incorrect results on WASM32.
The `idris2_extractInt` function incorrectly used `idris2_vp_to_Int32` for
unboxed values, which dereferences unboxed pointers as `Value_Int32*` on
32-bit platforms when `UINTPTR_WIDTH` is not defined (common in Emscripten).
unboxed values, which dereferences unboxed pointers as `Idris2_Int32*`
(previously `Value_Int32*`) on 32-bit platforms when `UINTPTR_WIDTH` is not
defined (common in Emscripten).
* Fix missing support for sized, signed integers in FFI.
* Fix headers for numeric negation.
* Prefix RefC Idris values with `Idris2_` to prevent name collisions with third
partly libraries.

### Library changes

Expand Down
88 changes: 44 additions & 44 deletions src/Compiler/RefC/RefC.idr

Large diffs are not rendered by default.

111 changes: 56 additions & 55 deletions support/refc/_datatypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,42 +38,43 @@ typedef struct {
uint16_t refCounter;
uint8_t tag;
uint8_t reserved;
} Value_header;
} Idris2_header;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure about this rename

#define IDRIS2_STOCKVAL(t) \
{ IDRIS2_VP_REFCOUNTER_MAX, t, 0 }

typedef struct {
Value_header header;
// `Value` is an "abstract" struct,
Idris2_header header;
// `Idris2_Value` is an "abstract" struct,
// `Value_Xxx` structs have the same header
// followed by type-specific payload.
} Value;
} Idris2_Value;

/*
We expect at least 4 bytes for `Value_header` alignment, to use bit0 and bit1 of
pointer as flags.
We expect at least 4 bytes for `Idris2_header` alignment, to use bit0 and bit1
of pointer as flags.

RefC does not have complete static tracking of type information, so types are
identified at runtime using Value_Header's tag field. However, Int that are
identified at runtime using Idris2_header's tag field. However, Int that are
pretending to be pointers cannot have that tag, so use that flag to identify
them first. Of course, this flag is not used if it is clear that Value* is
actually an Int. But places like newReference/removeReference require this flag.
them first. Of course, this flag is not used if it is clear that Idris2_Value*
is actually an Int. But places like newReference/removeReference require this
flag.
*/
#define idris2_vp_is_unboxed(p) ((uintptr_t)(p)&3)

#define idris2_vp_int_shift \
((sizeof(uintptr_t) >= 8 && sizeof(Value *) >= 8) ? 32 : 16)
((sizeof(uintptr_t) >= 8 && sizeof(Idris2_Value *) >= 8) ? 32 : 16)

#define idris2_vp_to_Bits64(p) (((Value_Bits64 *)(p))->ui64)
#define idris2_vp_to_Bits64(p) (((Idris2_Bits64 *)(p))->ui64)

#if !defined(UINTPTR_WIDTH)
#define idris2_vp_to_Bits32(p) \
((idris2_vp_int_shift == 16) \
? (((Value_Bits32 *)(p))->ui32) \
? (((Idris2_Bits32 *)(p))->ui32) \
: ((uint32_t)((uintptr_t)(p) >> idris2_vp_int_shift)))
#define idris2_vp_to_Int32(p) \
((idris2_vp_int_shift == 16) \
? (((Value_Int32 *)(p))->i32) \
? (((Idris2_Int32 *)(p))->i32) \
: ((int32_t)((uintptr_t)(p) >> idris2_vp_int_shift)))

#elif UINTPTR_WIDTH >= 64
Expand All @@ -84,8 +85,8 @@ actually an Int. But places like newReference/removeReference require this flag.
#define idris2_vp_to_Int32(p) ((int32_t)((uintptr_t)(p) >> idris2_vp_int_shift))

#elif UINTPTR_WIDTH >= 32
#define idris2_vp_to_Bits32(p) (((Value_Bits32 *)(p))->ui32)
#define idris2_vp_to_Int32(p) (((Value_Int32 *)(p))->i32)
#define idris2_vp_to_Bits32(p) (((Idris2_Bits32 *)(p))->ui32)
#define idris2_vp_to_Int32(p) (((Idris2_Int32 *)(p))->i32)

#else
#error "unsupported uintptr_t width"
Expand All @@ -94,101 +95,101 @@ actually an Int. But places like newReference/removeReference require this flag.
#define idris2_vp_to_Bits16(p) \
((uint16_t)((uintptr_t)(p) >> idris2_vp_int_shift))
#define idris2_vp_to_Bits8(p) ((uint8_t)((uintptr_t)(p) >> idris2_vp_int_shift))
#define idris2_vp_to_Int64(p) (((Value_Int64 *)(p))->i64)
#define idris2_vp_to_Int64(p) (((Idris2_Int64 *)(p))->i64)
#define idris2_vp_to_Int16(p) ((int16_t)((uintptr_t)(p) >> idris2_vp_int_shift))
#define idris2_vp_to_Int8(p) ((int8_t)((uintptr_t)(p) >> idris2_vp_int_shift))
#define idris2_vp_to_Char(p) \
((unsigned char)((uintptr_t)(p) >> idris2_vp_int_shift))
#define idris2_vp_to_Double(p) (((Value_Double *)(p))->d)
#define idris2_vp_to_Double(p) (((Idris2_Double *)(p))->d)
#define idris2_vp_to_Bool(p) (idris2_vp_to_Int8(p))

typedef struct {
Value_header header;
Idris2_header header;
uint32_t ui32;
} Value_Bits32;
} Idris2_Bits32;

typedef struct {
Value_header header;
Idris2_header header;
uint64_t ui64;
} Value_Bits64;
} Idris2_Bits64;

typedef struct {
Value_header header;
Idris2_header header;
int32_t i32;
} Value_Int32;
} Idris2_Int32;

typedef struct {
Value_header header;
Idris2_header header;
int64_t i64;
} Value_Int64;
} Idris2_Int64;

typedef struct {
Value_header header;
Idris2_header header;
mpz_t i;
} Value_Integer;
} Idris2_Integer;

typedef struct {
Value_header header;
Idris2_header header;
double d;
} Value_Double;
} Idris2_Double;

typedef struct {
Value_header header;
Idris2_header header;
char *str;
} Value_String;
} Idris2_String;

typedef struct {
Value_header header;
Idris2_header header;
int32_t total;
int32_t tag;
char const *name;
Value *args[];
} Value_Constructor;
Idris2_Value *args[];
} Idris2_Constructor;

typedef struct {
Value_header header;
Idris2_header header;
// function type depends on arity, see idris2_dispatch_closure
void *f;
uint8_t arity;
uint8_t filled; // length of args.
Value *args[];
} Value_Closure;
Idris2_Value *args[];
} Idris2_Closure;

typedef struct {
Value_header header;
Value *v;
} Value_IORef;
Idris2_header header;
Idris2_Value *v;
} Idris2_IORef;

typedef struct {
Value_header header;
Idris2_header header;
void *p;
} Value_Pointer;
} Idris2_Pointer;

typedef struct {
Value_header header;
Value_Pointer *p;
Value_Closure *onCollectFct;
} Value_GCPointer;
Idris2_header header;
Idris2_Pointer *p;
Idris2_Closure *onCollectFct;
} Idris2_GCPointer;

typedef struct {
Value_header header;
Idris2_header header;
int capacity;
Value **arr;
} Value_Array;
Idris2_Value **arr;
} Idris2_Array;

typedef struct {
Value_header header;
Idris2_header header;
Buffer *buffer;
} Value_Buffer;
} Idris2_Buffer;

typedef struct {
Value_header header;
Idris2_header header;
pthread_mutex_t *mutex;
} Value_Mutex;
} Idris2_Mutex;

typedef struct {
Value_header header;
Idris2_header header;
pthread_cond_t *cond;
} Value_Condition;
} Idris2_Condition;

void idris2_dumpMemoryStats(void);
Loading
Loading