@@ -946,52 +946,79 @@ typedef void *rb_jmpbuf_t[5];
946
946
Therefore, we allocates the buffer on the heap on such
947
947
environments.
948
948
*/
949
- typedef rb_jmpbuf_t * rb_vm_tag_jmpbuf_t ;
949
+ typedef struct _rb_vm_tag_jmpbuf {
950
+ struct _rb_vm_tag_jmpbuf * next ;
951
+ rb_jmpbuf_t buf ;
952
+ } * rb_vm_tag_jmpbuf_t ;
950
953
951
- #define RB_VM_TAG_JMPBUF_GET (buf ) (*buf)
954
+ #define RB_VM_TAG_JMPBUF_GET (jmpbuf ) ((jmpbuf)->buf)
955
+ #else
956
+ typedef rb_jmpbuf_t rb_vm_tag_jmpbuf_t ;
957
+
958
+ #define RB_VM_TAG_JMPBUF_GET (jmpbuf ) (jmpbuf)
959
+ #endif
960
+
961
+ /*
962
+ the members which are written in EC_PUSH_TAG() should be placed at
963
+ the beginning and the end, so that entire region is accessible.
964
+ */
965
+ struct rb_vm_tag {
966
+ VALUE tag ;
967
+ VALUE retval ;
968
+ rb_vm_tag_jmpbuf_t buf ;
969
+ struct rb_vm_tag * prev ;
970
+ enum ruby_tag_type state ;
971
+ unsigned int lock_rec ;
972
+ };
973
+
974
+ #if defined(__wasm__ ) && !defined(__EMSCRIPTEN__ )
975
+ static inline void
976
+ _rb_vm_tag_jmpbuf_deinit_internal (rb_vm_tag_jmpbuf_t jmpbuf )
977
+ {
978
+ rb_vm_tag_jmpbuf_t buf = jmpbuf ;
979
+ while (buf != NULL ) {
980
+ rb_vm_tag_jmpbuf_t next = buf -> next ;
981
+ ruby_xfree (buf );
982
+ buf = next ;
983
+ }
984
+ }
952
985
953
986
static inline void
954
- rb_vm_tag_jmpbuf_init (rb_vm_tag_jmpbuf_t * jmpbuf )
987
+ rb_vm_tag_jmpbuf_init (struct rb_vm_tag * tag )
955
988
{
956
- * jmpbuf = ruby_xmalloc (sizeof (rb_jmpbuf_t ));
989
+ if (tag -> prev != NULL && tag -> prev -> buf -> next != NULL ) {
990
+ _rb_vm_tag_jmpbuf_deinit_internal (tag -> prev -> buf -> next );
991
+ tag -> prev -> buf -> next = NULL ;
992
+ }
993
+ tag -> buf = ruby_xmalloc (sizeof * tag -> buf );
994
+ tag -> buf -> next = NULL ;
995
+ if (tag -> prev != NULL ) {
996
+ tag -> prev -> buf -> next = tag -> buf ;
997
+ }
957
998
}
958
999
959
1000
static inline void
960
- rb_vm_tag_jmpbuf_deinit (const rb_vm_tag_jmpbuf_t * jmpbuf )
1001
+ rb_vm_tag_jmpbuf_deinit (struct rb_vm_tag * tag )
961
1002
{
962
- ruby_xfree (* jmpbuf );
1003
+ if (tag -> prev != NULL ) {
1004
+ tag -> prev -> buf -> next = NULL ;
1005
+ }
1006
+ _rb_vm_tag_jmpbuf_deinit_internal (tag -> buf );
963
1007
}
964
1008
#else
965
- typedef rb_jmpbuf_t rb_vm_tag_jmpbuf_t ;
966
-
967
- #define RB_VM_TAG_JMPBUF_GET (buf ) (buf)
968
-
969
1009
static inline void
970
- rb_vm_tag_jmpbuf_init (rb_vm_tag_jmpbuf_t * jmpbuf )
1010
+ rb_vm_tag_jmpbuf_init (struct rb_vm_tag * tag )
971
1011
{
972
1012
// no-op
973
1013
}
974
1014
975
1015
static inline void
976
- rb_vm_tag_jmpbuf_deinit (const rb_vm_tag_jmpbuf_t * jmpbuf )
1016
+ rb_vm_tag_jmpbuf_deinit (struct rb_vm_tag * tag )
977
1017
{
978
1018
// no-op
979
1019
}
980
1020
#endif
981
1021
982
- /*
983
- the members which are written in EC_PUSH_TAG() should be placed at
984
- the beginning and the end, so that entire region is accessible.
985
- */
986
- struct rb_vm_tag {
987
- VALUE tag ;
988
- VALUE retval ;
989
- rb_vm_tag_jmpbuf_t buf ;
990
- struct rb_vm_tag * prev ;
991
- enum ruby_tag_type state ;
992
- unsigned int lock_rec ;
993
- };
994
-
995
1022
STATIC_ASSERT (rb_vm_tag_buf_offset , offsetof(struct rb_vm_tag , buf ) > 0 );
996
1023
STATIC_ASSERT (rb_vm_tag_buf_end ,
997
1024
offsetof(struct rb_vm_tag , buf ) + sizeof (rb_vm_tag_jmpbuf_t ) <
0 commit comments