]> Untitled Git - axy/ft/c-cera.git/commitdiff
Impl is back and even better :D
authorAxy <gilliardmarthey.axel@gmail.com>
Tue, 12 May 2026 14:11:08 +0000 (16:11 +0200)
committerAxy <gilliardmarthey.axel@gmail.com>
Tue, 12 May 2026 14:11:08 +0000 (16:11 +0200)
13 files changed:
Makefile
src/align.h [new file with mode: 0644]
src/ccera.h
src/defer.c
src/defer.h
src/framealloc.c [new file with mode: 0644]
src/framealloc.h [new file with mode: 0644]
src/jmp.c [deleted file]
src/jmp.h
src/panic.c
src/panic.h
src/return_patch.h [new file with mode: 0644]
test.c

index 275ecad17430ef963999e6635a04af3a35276f34..e09a1fce6b89614aac494a363a8dbce863f11a32 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 NAME=ccera.a
 
-SRCS=src/arc.c src/defer.c src/eval.c src/jmp.c src/panic.c src/value_destroy.c src/value_get.c src/value_lifetime.c src/value_new.c src/value_readf.c
+SRCS=src/arc.c src/defer.c src/eval.c src/framealloc.c src/panic.c src/value_destroy.c src/value_get.c src/value_lifetime.c src/value_new.c src/value_readf.c
 
-HEADERS=src/ccera.h src/defer.h src/jmp.h src/panic.h
+HEADERS=src/align.h src/ccera.h src/defer.h src/framealloc.h src/jmp.h src/panic.h src/return_patch.h
 
 BUILDDIR=.build
 
@@ -15,7 +15,8 @@ CFLAGS += -g
 #CFLAGS += -O3
 #CFLAGS += -flto -ffat-lto-objects
 
-CC=clang
+#CC=clang
+CC=gcc
 
 AR=ar
 
diff --git a/src/align.h b/src/align.h
new file mode 100644 (file)
index 0000000..371cd30
--- /dev/null
@@ -0,0 +1,43 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   align.h                                            :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/12 10:03:30 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/12 13:36:28 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#ifndef ALIGN_H
+# define ALIGN_H
+
+# include <stdint.h>
+
+# ifdef __builtin_align_up
+
+__attribute__((always_inline))
+static inline void     *align_up(void *p, uintptr_t align)
+{
+       return (__builtin_align_up(p, align));
+}
+
+# else
+
+__attribute__((always_inline))
+static inline void     *align_up(void *p, uintptr_t align)
+{
+       uintptr_t       n;
+
+       n = (intptr_t) p;
+       if (n % align)
+               n = ((n / align) + n % align) * align;
+       n -= (intptr_t) p;
+       p = &((char *) p)[n];
+       return (p);
+}
+
+# endif
+
+#endif
index 06a714ff4aed6ea98a4a72ea456f9639b1d26a84..dd5e495a6e3fbd7593b2956fffaa98493bb13975 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/04/29 16:08:57 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/10 22:11:53 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/11 19:26:32 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -20,6 +20,7 @@
 # include "jmp.h"
 # include "defer.h"
 # include "panic.h"
+# include "framealloc.h"
 
 # if UINTPTR_MAX != 0xFFFFFFFFFFFFFFFF
 #  error "Platform's pointers are not 64 bits"
index f1fe0e31f3408397b55b34fc4a7ef9c8d167f717..c0336ac2e6fd74255530c1806aa6c86f379f50d6 100644 (file)
@@ -6,76 +6,20 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/05 17:31:36 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/11 04:13:54 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/12 14:02:39 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "defer.h"
-#include <assert.h>
 
-static_assert((sizeof(t_defer_frame)) == 32);
-#define T_DEFER_FRAME_SIZE "32"
-
-static_assert((alignof(t_defer_frame)) == 8);
-#define T_DEFER_FRAME_ALIGN "8"
-
-asm (
-       ".globl _defer_store\n"
-       ".section       .tbss,\"awT\",@nobits\n"
-       ".align " T_DEFER_FRAME_ALIGN "\n"
-       ".type  _defer_store, @object\n"
-       ".size  _defer_store, " T_DEFER_FRAME_SIZE "\n"
-       "_defer_store:\n"
-       ".zero  " T_DEFER_FRAME_SIZE "\n"
-       ".text\n"
-       );
-
-// TODO: impl
-//
-//typedef struct s_defer_frame
-//{
-//     void                                    *ret_ptr;
-//     void                                    *stack_ptr;
-//     struct s_defer_frame    *prev;
-//     t_defer                                 *frame;
-//}    t_defer_frame;
-
-__attribute__((naked))
-void   defer_unpatch_exit(void)
+t_defer_frame  *defer_store(void)
 {
-       asm (
-               "movq %%rax, %%rdi\n"
-               "movq %%rdx, %%rsi\n"
-               "movq %%rsp, %%rdx\n"
-               "movq %%fs:_defer_store@TPOFF+%c0, %%rsp\n"
-               "pushq %%rdi\n"
-               "pushq %%rsi\n"
-               "pushq %%rdx\n"
-               "pushq %%fs:_defer_store@TPOFF+%c1\n"
-               "callq defer_pop_frame\n"
-               "popq %%rdi\n"
-               "popq %%rsi\n"
-               "popq %%rdx\n"
-               "popq %%rax\n"
-               "movq %%rsi, %%rsp\n"
-               "movq %%rdi, -8(%%rsp)\n"
-               "jmpq *%%rdi\n"
-               ::
-               "n" (offsetof(t_defer_frame, stack_ptr)),
-               "n" (offsetof(t_defer_frame, ret_ptr)));
-}
+       static __thread t_defer_frame   store;
 
-// TODO: impl
-//typedef struct s_defer
-//{
-//     struct s_defer          *prev;
-//     void                            (*f)(void *);
-//     void                            *dat;
-//     bool                            err;
-//}    t_defer;
+       return (&store);
+}
 
-__attribute__((used))
-void   defer_pop_frame(bool err)
+void   defer_pop(bool err)
 {
        t_defer *curr;
 
@@ -89,3 +33,28 @@ void defer_pop_frame(bool err)
        if (defer_store()->prev)
                *defer_store() = *defer_store()->prev;
 }
+
+__attribute__((used))
+void   *defer_pop_ret(void)
+{
+       void    *ret;
+
+       ret = defer_store()->ret_ptr;
+       defer_pop(false);
+       return (ret);
+}
+
+__attribute__((naked))
+void   defer_pop_shim(void)
+{
+       asm (
+               "pushq %rax\n"
+               "pushq %rdx\n"
+               "callq defer_pop_ret\n"
+               "movq %rax, %rsi\n"
+               "popq %rdx\n"
+               "popq %rax\n"
+               "pushq %rsi\n"
+               "ret\n"
+               );
+}
index 6e3e62bafb6dc264a009a7df86841ef4a300b252..25f5225a1686f2631f0ccba3d7a09d52f6582a89 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/10 22:08:53 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/11 04:46:59 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/12 14:01:36 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -14,6 +14,8 @@
 # define DEFER_H
 
 # include <stddef.h>
+# include "framealloc.h"
+# include "return_patch.h"
 
 typedef struct s_defer
 {
@@ -26,53 +28,35 @@ typedef struct s_defer
 typedef struct s_defer_frame
 {
        void                                    *ret_ptr;
-       void                                    *stack_ptr;
+       void                                    *frame_ptr;
        struct s_defer_frame    *prev;
        t_defer                                 *frame;
 }      t_defer_frame;
 
-__attribute__((always_inline))
-static inline t_defer_frame    *defer_store(void)
-{
-       extern __thread t_defer_frame   _defer_store;
-
-       return (&_defer_store);
-}
-void                                           defer_unpatch_exit(void)
+t_defer_frame                          *defer_store(void);
+void                                           defer_pop(bool err);
+void                                           defer_pop_shim(void)
                                                        __attribute__((naked));
 
-// Store current rsp + red zone, aligned down to stack align
-// No clang 22, so no __builtin_stack_address
-__attribute__((always_inline))
-static inline void     defer_stack_update(void)
-{
-       void    *addr;
-
-       asm ("leaq -128(%%rsp), %0\n" : "=r" (addr));
-       //defer_store()->stack_ptr = __builtin_align_down(addr, 16);
-       defer_store()->stack_ptr = (void *)((unsigned long long )addr & ~16ull);
-}
-
 __attribute__((always_inline))
 static inline void     defer_patch(void)
 {
-       void                    *ret_ptr;
        t_defer_frame   *prev;
        t_defer_frame   *curr;
+       void                    *ret;
 
-       ret_ptr = __builtin_return_address(0);
-       if (&defer_unpatch_exit != ret_ptr)
+       if (defer_store()->frame_ptr != __builtin_frame_address(0))
        {
-               asm ("movq %0, 8(%%rbp)\n" : : "r" (&defer_unpatch_exit));
-               prev = __builtin_alloca(sizeof(t_defer_frame));
+               ret = __builtin_return_address(0);
+               return_patch(&defer_pop_shim);
+               prev = cera_alloca_align(sizeof(t_defer_frame), alignof(t_defer_frame));
                curr = defer_store();
                *prev = *curr;
-               curr->ret_ptr = ret_ptr;
+               curr->ret_ptr = ret;
                curr->frame = NULL;
+               curr->prev = prev;
+               defer_store()->frame_ptr = __builtin_frame_address(0);
        }
-       defer_stack_update();
-       ret_ptr = __builtin_return_address(0);
-       __builtin_assume(&defer_unpatch_exit == ret_ptr);
 }
 
 __attribute__((always_inline))
@@ -80,7 +64,7 @@ static inline void    defer(void *f, void *dat)
 {
        t_defer *curr;
 
-       curr = __builtin_alloca(sizeof(t_defer));
+       curr = cera_alloca_align(sizeof(t_defer), alignof(t_defer));
        defer_patch();
        curr->prev = defer_store()->frame;
        curr->f = f;
@@ -94,7 +78,7 @@ static inline void    errdefer(void *f, void *dat)
 {
        t_defer *curr;
 
-       curr = __builtin_alloca(sizeof(t_defer));
+       curr = cera_alloca_align(sizeof(t_defer), alignof(t_defer));
        defer_patch();
        curr->prev = defer_store()->frame;
        curr->f = f;
diff --git a/src/framealloc.c b/src/framealloc.c
new file mode 100644 (file)
index 0000000..4089208
--- /dev/null
@@ -0,0 +1,53 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   framealloc.c                                       :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/11 19:22:02 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/12 14:01:24 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "framealloc.h"
+
+t_framealloc   *framealloc_store(void)
+{
+       static __thread t_framealloc    store;
+
+       return (&store);
+}
+
+void   framealloc_pop(void)
+{
+       t_framealloc    *store;
+
+       store = framealloc_store();
+       store->frame = *store->frame.prev;
+}
+
+__attribute__((used))
+void   *framealloc_pop_ret(void)
+{
+       void    *ret_ptr;
+
+       ret_ptr = framealloc_store()->frame.ret_ptr;
+       framealloc_pop();
+       return (ret_ptr);
+}
+
+__attribute__((naked))
+void   framealloc_pop_shim(void)
+{
+       asm (
+               "pushq %rax\n"
+               "pushq %rdx\n"
+               "callq framealloc_pop_ret\n"
+               "movq %rax, %rsi\n"
+               "popq %rdx\n"
+               "popq %rax\n"
+               "pushq %rsi\n"
+               "retq\n"
+               );
+}
diff --git a/src/framealloc.h b/src/framealloc.h
new file mode 100644 (file)
index 0000000..a97b755
--- /dev/null
@@ -0,0 +1,87 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   framealloc.h                                       :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/11 19:17:56 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/12 13:35:45 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#ifndef FRAMEALLOC_H
+# define FRAMEALLOC_H
+
+# include <stdint.h>
+# include "return_patch.h"
+# include "align.h"
+
+# ifndef FRAMEALLOC_SIZE
+#  define FRAMEALLOC_SIZE 32768
+# endif
+
+typedef struct s_framealloc_frame
+{
+       uintptr_t                                       used;
+       struct s_framealloc_frame       *prev;
+       void                                            *ret_ptr;
+       void                                            *frame_ptr;
+}      t_framealloc_frame;
+
+typedef struct s_framealloc
+{
+       t_framealloc_frame      frame;
+       char                            buf[FRAMEALLOC_SIZE];
+}      t_framealloc;
+
+t_framealloc           *framealloc_store(void);
+void                           framealloc_pop_shim(void)
+                                       __attribute__((naked));
+void                           framealloc_pop(void);
+
+__attribute__((always_inline, malloc, alloc_size(1), alloc_align(2)))
+static inline void     *cera_alloca_align_nopatch(uintptr_t len, uintptr_t align)
+{
+       t_framealloc    *store;
+       void                    *res;
+
+       store = framealloc_store();
+       res = &store->buf[store->frame.used];
+       store->frame.used += ((uintptr_t)(align_up(res, align) - res))
+               + len;
+       res = align_up(res, align);
+       return (res);
+}
+
+__attribute__((always_inline))
+static inline void     cera_alloca_patch(void)
+{
+       t_framealloc            *store;
+       t_framealloc_frame      prev_frame;
+       t_framealloc_frame      *frame_p;
+       void                            *ret;
+
+       store = framealloc_store();
+       if (store->frame.frame_ptr != __builtin_frame_address(0))
+       {
+               ret = __builtin_return_address(0);
+               return_patch(&framealloc_pop_shim);
+               prev_frame = store->frame;
+               frame_p = cera_alloca_align_nopatch(sizeof(t_framealloc_frame),
+                               alignof(t_framealloc_frame));
+               *frame_p = prev_frame;
+               store->frame.prev = frame_p;
+               store->frame.ret_ptr = ret;
+               store->frame.frame_ptr = __builtin_frame_address(0);
+       }
+}
+
+__attribute__((always_inline, malloc, alloc_size(1), alloc_align(2)))
+static inline void     *cera_alloca_align(uintptr_t len, uintptr_t align)
+{
+       cera_alloca_patch();
+       return (cera_alloca_align_nopatch(len, align));
+}
+
+#endif
diff --git a/src/jmp.c b/src/jmp.c
deleted file mode 100644 (file)
index 6771dba..0000000
--- a/src/jmp.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* ************************************************************************** */
-/*                                                                            */
-/*                                                        :::      ::::::::   */
-/*   jmp.c                                              :+:      :+:    :+:   */
-/*                                                    +:+ +:+         +:+     */
-/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
-/*                                                +#+#+#+#+#+   +#+           */
-/*   Created: 2026/05/10 06:19:18 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/11 04:24:42 by agilliar         ###   ########.fr       */
-/*                                                                            */
-/* ************************************************************************** */
-
-#include <stddef.h>
-#include "jmp.h"
-
-__attribute__((returns_twice, naked))
-bool   cera_setjmp(void *buf[2])
-{
-       asm (
-               "movq %%rbp, %c0(%%rdi)\n"
-               "movq %%rsp, %c1(%%rdi)\n"
-               "movq 0(%%rsp), %%rax\n"
-               "movq %%rax, %c2(%%rdi)\n"
-               "xorq %%rax, %%rax\n"
-               "retq\n"
-               ::
-               "n" (offsetof(t_jmp, base)),
-               "n" (offsetof(t_jmp, top)),
-               "n" (offsetof(t_jmp, ret)));
-}
-
-__attribute__((noreturn, naked))
-void   cera_longjmp(void *buf[2])
-{
-       asm (
-               "movq %c0(%%rdi), %%rbp\n"
-               "movq %c1(%%rdi), %%rsp\n"
-               "movq %c2(%%rdi), %%rax\n"
-               "movq %%rax, 0(%%rsp)\n"
-               "movl $1, %%eax\n"
-               "retq\n"
-               ::
-               "n" (offsetof(t_jmp, base)),
-               "n" (offsetof(t_jmp, top)),
-               "n" (offsetof(t_jmp, ret)));
-}
index 841045c633934a00a5085e69868dcdb195aae487..746e9fe319b2ef1a7a3ff153603b4a56c6f8d4f0 100644 (file)
--- a/src/jmp.h
+++ b/src/jmp.h
@@ -6,28 +6,15 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/10 22:08:02 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/11 01:43:42 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/12 13:12:47 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #ifndef JMP_H
 # define JMP_H
 
-// We are storing the return address so as to always return to the right
-// function, as a defer might have patched the return address of any later 
-// stack frames
-// Clang's impl would doom us
-typedef struct s_jmp
-{
-       void    *base;
-       void    *top;
-       void    *ret;
-}      t_jmp;
+# include <stdint.h>
 
-bool                   cera_setjmp(void *buf[2])
-                               __attribute__((returns_twice, naked));
-
-void                   cera_longjmp(void *buf[2])
-                               __attribute__((noreturn, naked));
+typedef intptr_t       t_jmp[3];
 
 #endif
index eb1eb1013ff2dc1eb127e2b7e0cacc143ec99eca..be746043f978de82389f12bbfe09d5044ab0b57c 100644 (file)
@@ -6,13 +6,12 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/05 15:38:33 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/11 02:26:13 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/12 13:13:03 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "ccera.h"
 
-/*
 t_panic_info   *panic_store(void)
 {
        static __thread t_panic_info    store;
@@ -23,13 +22,13 @@ t_panic_info        *panic_store(void)
 void   *catch(void *f, void *dat)
 {
        void                    *res;
-       t_defer                 defer_store;
        t_panic_info    prev;
 
+       cera_alloca_patch();
+       defer_patch();
        prev = *panic_store();
-       panic_store()->defer = &defer_store;
-       defer_new(&defer_store);
-       if (__builtin_setjmp(panic_store()->jmp))
+       panic_store()->frame_ptr = __builtin_frame_address(0);
+       if (__builtin_setjmp(&panic_store()->jmp))
        {
                res = panic_store()->data;
                *panic_store() = prev;
@@ -43,13 +42,15 @@ void        *catch(void *f, void *dat)
 __attribute__((noreturn, nonnull(1)))
 void   panic(void *err)
 {
-       defer_exit(panic_store()->defer);
+       while (defer_store()->frame_ptr != panic_store()->frame_ptr)
+               defer_pop(true);
+       while (framealloc_store()->frame.frame_ptr != panic_store()->frame_ptr)
+               framealloc_pop();
        panic_store()->data = err;
-       __builtin_longjmp(panic_store()->jmp, 1);
+       __builtin_longjmp(&panic_store()->jmp, 1);
 }
 
 bool   panicking(void)
 {
        return (panic_store()->data != NULL);
 }
-*/
index abee2f63756c19f00674821a8cf36c3de5cda204..213fbf5d14b7c005f9f015a74943dcd8d57a1464 100644 (file)
@@ -6,23 +6,27 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/05/10 22:11:10 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/10 22:11:44 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/12 12:16:56 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #ifndef PANIC_H
 # define PANIC_H
 
+# include "jmp.h"
+
 typedef struct s_panic_info
 {
        void            *data;
-       void            *jmp[2];
-       t_defer         *defer;
+       t_jmp           jmp;
+       void            *frame_ptr;
 }      t_panic_info;
 
-void                   *catch(void *f, void *dat);
-void                   panic(void *err)
-                               __attribute__((noreturn, nonnull(1)));
-bool                   panicking(void);
+t_panic_info           *panic_store(void);
+
+void                           panic(void *err)
+                                       __attribute__((noreturn, nonnull(1)));
+void                           *catch(void *f, void *dat);
+bool                           panicking(void);
 
 #endif
diff --git a/src/return_patch.h b/src/return_patch.h
new file mode 100644 (file)
index 0000000..a30ed14
--- /dev/null
@@ -0,0 +1,25 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   return_patch.h                                     :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2026/05/11 20:08:23 by agilliar          #+#    #+#             */
+/*   Updated: 2026/05/12 08:54:17 by agilliar         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#ifndef RETURN_PATCH_H
+# define RETURN_PATCH_H
+
+__attribute__((always_inline))
+static inline void     return_patch(void *p)
+{
+       void    **frame_addr;
+
+       frame_addr = __builtin_frame_address(0);
+       frame_addr[1] = p;
+}
+
+#endif
diff --git a/test.c b/test.c
index 373e1aa461f39f4d4a1690201c2aa491a693f329..d1b29849034ea8e44288d0d55e42a94fe7cefbcb 100644 (file)
--- a/test.c
+++ b/test.c
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2026/04/30 17:19:58 by agilliar          #+#    #+#             */
-/*   Updated: 2026/05/11 04:12:03 by agilliar         ###   ########.fr       */
+/*   Updated: 2026/05/12 14:07:55 by agilliar         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include <stdio.h>
 #include <stdlib.h>
 
-/*
-void   main2(void *s)
+void main2(char *orig)
 {
-       t_defer defer_store __attribute__((cleanup(defer_exit)));
-       defer_new(&defer_store);
-
-       t_value arg = value_bytes_new(strlen(s) + 1);
-       defer(value_destroy, &arg);
-       panic("A");
-       t_value state = value_list_new(0);
-       defer(value_destroy, &state);
-       //panic("B");
-       t_value idx = value_int_new(0);
-       t_value fn = value_list_new(2);
-       defer(value_destroy, &fn);
-       //panic("C");
-       t_value expr = value_list_new(2);
-       defer(value_destroy, &expr);
-       //panic("D");
-       defer_re(&defer_store);
-       value_list_get(fn)->list[0] = state;
-       value_list_get(fn)->list[1] = idx;
-       value_list_get(expr)->list[0] = fn;
-       value_list_get(expr)->list[1] = arg;
-       defer(value_destroy, &expr);
-       //panic("E");
-       t_value val = value_copy(expr);
-       errdefer(value_destroy, &val);
-       //panic("F");
-}
-
-int    main(void)
-{
-       char *err = catch(main2, "hello cera");
-       if (err)
-       {
-               printf("%s\n", err);
-               return (1);
-       }
+       char *s = malloc(strlen(orig) + 1);
+       defer(free, s);
+       char *s2 = malloc(strlen(orig) + 1);
+       defer(free, s2);
+       panic("error!");
 }
-*/
 
 int main(void)
 {
+       char    *msg;
+
        char *orig = "hello cera!";
        char *s = malloc(strlen(orig) + 1);
+       cera_alloca_align(10, 30);
        defer(free, s);
+       msg = catch(main2, orig);
+       if (msg)
+       {
+               printf("%s\n", msg);
+               return (-1);
+       }
        char *s2 = malloc(strlen(orig) + 1);
        defer(free, s2);
 }