2828#include "ruby/encoding.h"
2929#include "ruby/util.h"
3030#include "ruby_assert.h"
31+ #include "vm_core.h"
3132#include "vm_sync.h"
3233#include "ruby_atomic.h"
3334
@@ -344,6 +345,7 @@ static int
344345enc_table_expand (struct enc_table * enc_table , int newsize )
345346{
346347 if (newsize > ENCODING_LIST_CAPA ) {
348+ RB_VM_UNLOCK ();
347349 rb_raise (rb_eEncodingError , "too many encoding (> %d)" , ENCODING_LIST_CAPA );
348350 }
349351 return newsize ;
421423rb_enc_register (const char * name , rb_encoding * encoding )
422424{
423425 int index ;
426+ bool set_const = false;
424427
425428 GLOBAL_ENC_TABLE_LOCKING (enc_table ) {
426429 index = enc_registered (enc_table , name );
@@ -439,9 +442,12 @@ rb_enc_register(const char *name, rb_encoding *encoding)
439442 }
440443 else {
441444 index = enc_register (enc_table , name , encoding );
442- set_encoding_const ( name , rb_enc_from_index ( index )) ;
445+ set_const = true ;
443446 }
444447 }
448+ if (set_const ) {
449+ set_encoding_const (name , rb_enc_from_index (index ));
450+ }
445451 return index ;
446452}
447453
@@ -472,22 +478,25 @@ rb_enc_registered(const char *name)
472478void
473479rb_encdb_declare (const char * name )
474480{
481+ int idx ;
475482 GLOBAL_ENC_TABLE_LOCKING (enc_table ) {
476- int idx = enc_registered (enc_table , name );
483+ idx = enc_registered (enc_table , name );
477484 if (idx < 0 ) {
478485 idx = enc_register (enc_table , name , 0 );
479486 }
480- set_encoding_const (name , rb_enc_from_index (idx ));
481487 }
488+ set_encoding_const (name , rb_enc_from_index (idx ));
482489}
483490
484491static void
485492enc_check_addable (struct enc_table * enc_table , const char * name )
486493{
487494 if (enc_registered (enc_table , name ) >= 0 ) {
495+ RB_VM_UNLOCK ();
488496 rb_raise (rb_eArgError , "encoding %s is already registered" , name );
489497 }
490498 else if (!valid_encoding_name_p (name )) {
499+ RB_VM_UNLOCK ();
491500 rb_raise (rb_eArgError , "invalid encoding name: %s" , name );
492501 }
493502}
@@ -535,9 +544,11 @@ enc_replicate(struct enc_table *enc_table, const char *name, rb_encoding *encodi
535544
536545 enc_check_addable (enc_table , name );
537546 idx = enc_register (enc_table , name , encoding );
538- if (idx < 0 ) rb_raise (rb_eArgError , "invalid encoding name: %s" , name );
547+ if (idx < 0 ) {
548+ RB_VM_UNLOCK ();
549+ rb_raise (rb_eArgError , "invalid encoding name: %s" , name );
550+ }
539551 set_base_encoding (enc_table , idx , encoding );
540- set_encoding_const (name , rb_enc_from_index (idx ));
541552 return idx ;
542553}
543554
@@ -552,9 +563,9 @@ enc_replicate_with_index(struct enc_table *enc_table, const char *name, rb_encod
552563 }
553564 if (idx >= 0 ) {
554565 set_base_encoding (enc_table , idx , origenc );
555- set_encoding_const (name , rb_enc_from_index (idx ));
556566 }
557567 else {
568+ RB_VM_UNLOCK ();
558569 rb_raise (rb_eArgError , "failed to replicate encoding" );
559570 }
560571 return idx ;
@@ -575,6 +586,8 @@ rb_encdb_replicate(const char *name, const char *orig)
575586 r = enc_replicate_with_index (enc_table , name , rb_enc_from_index (origidx ), idx );
576587 }
577588
589+ set_encoding_const (name , rb_enc_from_index (r ));
590+
578591 return r ;
579592}
580593
@@ -588,6 +601,7 @@ rb_define_dummy_encoding(const char *name)
588601 rb_encoding * enc = enc_table -> list [index ].enc ;
589602 ENC_SET_DUMMY ((rb_raw_encoding * )enc );
590603 }
604+ set_encoding_const (name , rb_enc_from_index (index ));
591605
592606 return index ;
593607}
@@ -605,6 +619,8 @@ rb_encdb_dummy(const char *name)
605619 ENC_SET_DUMMY ((rb_raw_encoding * )enc );
606620 }
607621
622+ set_encoding_const (name , rb_enc_from_index (index ));
623+
608624 return index ;
609625}
610626
@@ -671,18 +687,20 @@ enc_alias_internal(struct enc_table *enc_table, const char *alias, int idx)
671687}
672688
673689static int
674- enc_alias (struct enc_table * enc_table , const char * alias , int idx )
690+ enc_alias (struct enc_table * enc_table , const char * alias , int idx , bool * set_const )
675691{
676692 if (!valid_encoding_name_p (alias )) return -1 ;
677- if (!enc_alias_internal (enc_table , alias , idx ))
678- set_encoding_const (alias , enc_from_index (enc_table , idx ));
693+ if (!enc_alias_internal (enc_table , alias , idx )) {
694+ * set_const = true;
695+ }
679696 return idx ;
680697}
681698
682699int
683700rb_enc_alias (const char * alias , const char * orig )
684701{
685702 int idx , r ;
703+ bool set_const = false;
686704 GLOBAL_ENC_TABLE_LOCKING (enc_table ) {
687705 enc_check_addable (enc_table , alias ); // can raise
688706 }
@@ -691,7 +709,11 @@ rb_enc_alias(const char *alias, const char *orig)
691709 if (idx < 0 ) return -1 ;
692710
693711 GLOBAL_ENC_TABLE_LOCKING (enc_table ) {
694- r = enc_alias (enc_table , alias , idx );
712+ r = enc_alias (enc_table , alias , idx , & set_const );
713+ }
714+
715+ if (set_const ) {
716+ set_encoding_const (alias , rb_enc_from_index (idx ));
695717 }
696718
697719 return r ;
@@ -701,14 +723,18 @@ int
701723rb_encdb_alias (const char * alias , const char * orig )
702724{
703725 int r ;
726+ bool set_const = false;
704727
705728 GLOBAL_ENC_TABLE_LOCKING (enc_table ) {
706729 int idx = enc_registered (enc_table , orig );
707730
708731 if (idx < 0 ) {
709732 idx = enc_register (enc_table , orig , 0 );
710733 }
711- r = enc_alias (enc_table , alias , idx );
734+ r = enc_alias (enc_table , alias , idx , & set_const );
735+ }
736+ if (set_const ) {
737+ set_encoding_const (alias , rb_enc_from_index (r ));
712738 }
713739
714740 return r ;
@@ -717,34 +743,35 @@ rb_encdb_alias(const char *alias, const char *orig)
717743static void
718744rb_enc_init (struct enc_table * enc_table )
719745{
720- ASSERT_vm_locking ();
721- enc_table_expand (enc_table , ENCODING_COUNT + 1 );
722- if (!enc_table -> names ) {
723- enc_table -> names = st_init_strcasetable_with_size (ENCODING_LIST_CAPA );
724- }
746+ RB_VM_LOCKING () {
747+ enc_table_expand (enc_table , ENCODING_COUNT + 1 );
748+ if (!enc_table -> names ) {
749+ enc_table -> names = st_init_strcasetable_with_size (ENCODING_LIST_CAPA );
750+ }
725751#define OnigEncodingASCII_8BIT OnigEncodingASCII
726752#define ENC_REGISTER (enc ) enc_register_at(enc_table, ENCINDEX_##enc, rb_enc_name(&OnigEncoding##enc), &OnigEncoding##enc)
727- ENC_REGISTER (ASCII_8BIT );
728- ENC_REGISTER (UTF_8 );
729- ENC_REGISTER (US_ASCII );
730- global_enc_ascii = enc_table -> list [ENCINDEX_ASCII_8BIT ].enc ;
731- global_enc_utf_8 = enc_table -> list [ENCINDEX_UTF_8 ].enc ;
732- global_enc_us_ascii = enc_table -> list [ENCINDEX_US_ASCII ].enc ;
753+ ENC_REGISTER (ASCII_8BIT );
754+ ENC_REGISTER (UTF_8 );
755+ ENC_REGISTER (US_ASCII );
756+ global_enc_ascii = enc_table -> list [ENCINDEX_ASCII_8BIT ].enc ;
757+ global_enc_utf_8 = enc_table -> list [ENCINDEX_UTF_8 ].enc ;
758+ global_enc_us_ascii = enc_table -> list [ENCINDEX_US_ASCII ].enc ;
733759#undef ENC_REGISTER
734760#undef OnigEncodingASCII_8BIT
735761#define ENCDB_REGISTER (name , enc ) enc_register_at(enc_table, ENCINDEX_##enc, name, NULL)
736- ENCDB_REGISTER ("UTF-16BE" , UTF_16BE );
737- ENCDB_REGISTER ("UTF-16LE" , UTF_16LE );
738- ENCDB_REGISTER ("UTF-32BE" , UTF_32BE );
739- ENCDB_REGISTER ("UTF-32LE" , UTF_32LE );
740- ENCDB_REGISTER ("UTF-16" , UTF_16 );
741- ENCDB_REGISTER ("UTF-32" , UTF_32 );
742- ENCDB_REGISTER ("UTF8-MAC" , UTF8_MAC );
743-
744- ENCDB_REGISTER ("EUC-JP" , EUC_JP );
745- ENCDB_REGISTER ("Windows-31J" , Windows_31J );
762+ ENCDB_REGISTER ("UTF-16BE" , UTF_16BE );
763+ ENCDB_REGISTER ("UTF-16LE" , UTF_16LE );
764+ ENCDB_REGISTER ("UTF-32BE" , UTF_32BE );
765+ ENCDB_REGISTER ("UTF-32LE" , UTF_32LE );
766+ ENCDB_REGISTER ("UTF-16" , UTF_16 );
767+ ENCDB_REGISTER ("UTF-32" , UTF_32 );
768+ ENCDB_REGISTER ("UTF8-MAC" , UTF8_MAC );
769+
770+ ENCDB_REGISTER ("EUC-JP" , EUC_JP );
771+ ENCDB_REGISTER ("Windows-31J" , Windows_31J );
746772#undef ENCDB_REGISTER
747- enc_table -> count = ENCINDEX_BUILTIN_MAX ;
773+ enc_table -> count = ENCINDEX_BUILTIN_MAX ;
774+ }
748775}
749776
750777rb_encoding *
865892rb_enc_find_index (const char * name )
866893{
867894 int i ;
868- ASSERT_vm_unlocking (); // it needs to be unlocked so it can call `load_encoding` if necessary
895+ #if RUBY_DEBUG
896+ if (rb_multi_ractor_p () || !rb_enc_registered (name )) {
897+ ASSERT_vm_unlocking (); // it needs to be unlocked so it can call `load_encoding` if necessary
898+ }
899+ #endif
869900 GLOBAL_ENC_TABLE_LOCKING (enc_table ) {
870901 i = enc_registered (enc_table , name );
871902 }
@@ -1812,6 +1843,7 @@ set_default_internal(VALUE klass, VALUE encoding)
18121843static void
18131844set_encoding_const (const char * name , rb_encoding * enc )
18141845{
1846+ ASSERT_vm_unlocking ();
18151847 VALUE encoding = rb_enc_from_encoding (enc );
18161848 char * s = (char * )name ;
18171849 int haslower = 0 , hasupper = 0 , valid = 0 ;
0 commit comments