@@ -897,12 +897,12 @@ rb_iseq_new_top(const VALUE ast_value, VALUE name, VALUE path, VALUE realpath, c
897897 * The main entry-point into the prism compiler when a file is required.
898898 */
899899rb_iseq_t *
900- pm_iseq_new_top (pm_scope_node_t * node , VALUE name , VALUE path , VALUE realpath , const rb_iseq_t * parent )
900+ pm_iseq_new_top (pm_scope_node_t * node , VALUE name , VALUE path , VALUE realpath , const rb_iseq_t * parent , int * error_state )
901901{
902902 iseq_new_setup_coverage (path , (int ) (node -> parser -> newline_list .size - 1 ));
903903
904904 return pm_iseq_new_with_opt (node , name , path , realpath , 0 , parent , 0 ,
905- ISEQ_TYPE_TOP , & COMPILE_OPTION_DEFAULT );
905+ ISEQ_TYPE_TOP , & COMPILE_OPTION_DEFAULT , error_state );
906906}
907907
908908rb_iseq_t *
@@ -921,13 +921,13 @@ rb_iseq_new_main(const VALUE ast_value, VALUE path, VALUE realpath, const rb_ise
921921 * main file in the program.
922922 */
923923rb_iseq_t *
924- pm_iseq_new_main (pm_scope_node_t * node , VALUE path , VALUE realpath , const rb_iseq_t * parent , int opt )
924+ pm_iseq_new_main (pm_scope_node_t * node , VALUE path , VALUE realpath , const rb_iseq_t * parent , int opt , int * error_state )
925925{
926926 iseq_new_setup_coverage (path , (int ) (node -> parser -> newline_list .size - 1 ));
927927
928928 return pm_iseq_new_with_opt (node , rb_fstring_lit ("<main>" ),
929929 path , realpath , 0 ,
930- parent , 0 , ISEQ_TYPE_MAIN , opt ? & COMPILE_OPTION_DEFAULT : & COMPILE_OPTION_FALSE );
930+ parent , 0 , ISEQ_TYPE_MAIN , opt ? & COMPILE_OPTION_DEFAULT : & COMPILE_OPTION_FALSE , error_state );
931931}
932932
933933rb_iseq_t *
@@ -947,7 +947,7 @@ rb_iseq_new_eval(const VALUE ast_value, VALUE name, VALUE path, VALUE realpath,
947947
948948rb_iseq_t *
949949pm_iseq_new_eval (pm_scope_node_t * node , VALUE name , VALUE path , VALUE realpath ,
950- int first_lineno , const rb_iseq_t * parent , int isolated_depth )
950+ int first_lineno , const rb_iseq_t * parent , int isolated_depth , int * error_state )
951951{
952952 if (rb_get_coverage_mode () & COVERAGE_TARGET_EVAL ) {
953953 VALUE coverages = rb_get_coverages ();
@@ -957,7 +957,7 @@ pm_iseq_new_eval(pm_scope_node_t *node, VALUE name, VALUE path, VALUE realpath,
957957 }
958958
959959 return pm_iseq_new_with_opt (node , name , path , realpath , first_lineno ,
960- parent , isolated_depth , ISEQ_TYPE_EVAL , & COMPILE_OPTION_DEFAULT );
960+ parent , isolated_depth , ISEQ_TYPE_EVAL , & COMPILE_OPTION_DEFAULT , error_state );
961961}
962962
963963static inline rb_iseq_t *
@@ -1013,6 +1013,25 @@ rb_iseq_new_with_opt(VALUE ast_value, VALUE name, VALUE path, VALUE realpath,
10131013 return iseq_translate (iseq );
10141014}
10151015
1016+ struct pm_iseq_new_with_opt_data {
1017+ rb_iseq_t * iseq ;
1018+ pm_scope_node_t * node ;
1019+ };
1020+
1021+ VALUE
1022+ pm_iseq_new_with_opt_try (VALUE d )
1023+ {
1024+ struct pm_iseq_new_with_opt_data * data = (struct pm_iseq_new_with_opt_data * )d ;
1025+
1026+ // This can compile child iseqs, which can raise syntax errors
1027+ pm_iseq_compile_node (data -> iseq , data -> node );
1028+
1029+ // This raises an exception if there is a syntax error
1030+ finish_iseq_build (data -> iseq );
1031+
1032+ return Qundef ;
1033+ }
1034+
10161035/**
10171036 * This is a step in the prism compiler that is called once all of the various
10181037 * options have been established. It is called from one of the pm_iseq_new_*
@@ -1028,7 +1047,7 @@ rb_iseq_new_with_opt(VALUE ast_value, VALUE name, VALUE path, VALUE realpath,
10281047rb_iseq_t *
10291048pm_iseq_new_with_opt (pm_scope_node_t * node , VALUE name , VALUE path , VALUE realpath ,
10301049 int first_lineno , const rb_iseq_t * parent , int isolated_depth ,
1031- enum rb_iseq_type type , const rb_compile_option_t * option )
1050+ enum rb_iseq_type type , const rb_compile_option_t * option , int * error_state )
10321051{
10331052 rb_iseq_t * iseq = iseq_alloc ();
10341053 ISEQ_BODY (iseq )-> prism = true;
@@ -1054,8 +1073,13 @@ pm_iseq_new_with_opt(pm_scope_node_t *node, VALUE name, VALUE path, VALUE realpa
10541073 prepare_iseq_build (iseq , name , path , realpath , first_lineno , & code_location , -1 ,
10551074 parent , isolated_depth , type , node -> script_lines == NULL ? Qnil : * node -> script_lines , option );
10561075
1057- pm_iseq_compile_node (iseq , node );
1058- finish_iseq_build (iseq );
1076+ struct pm_iseq_new_with_opt_data data = {
1077+ .iseq = iseq ,
1078+ .node = node
1079+ };
1080+ rb_protect (pm_iseq_new_with_opt_try , (VALUE )& data , error_state );
1081+
1082+ if (* error_state ) return NULL ;
10591083
10601084 return iseq_translate (iseq );
10611085}
@@ -1313,8 +1337,15 @@ pm_iseq_compile_with_option(VALUE src, VALUE file, VALUE realpath, VALUE line, V
13131337 }
13141338
13151339 if (error == Qnil ) {
1316- iseq = pm_iseq_new_with_opt (& result .node , name , file , realpath , ln , NULL , 0 , ISEQ_TYPE_TOP , & option );
1340+ int error_state ;
1341+ iseq = pm_iseq_new_with_opt (& result .node , name , file , realpath , ln , NULL , 0 , ISEQ_TYPE_TOP , & option , & error_state );
1342+
13171343 pm_parse_result_free (& result );
1344+
1345+ if (error_state ) {
1346+ RUBY_ASSERT (iseq == NULL );
1347+ rb_jump_tag (error_state );
1348+ }
13181349 }
13191350 else {
13201351 pm_parse_result_free (& result );
@@ -1771,11 +1802,20 @@ iseqw_s_compile_file_prism(int argc, VALUE *argv, VALUE self)
17711802 if (error == Qnil ) {
17721803 make_compile_option (& option , opt );
17731804
1774- ret = iseqw_new (pm_iseq_new_with_opt (& result .node , rb_fstring_lit ("<main>" ),
1775- file ,
1776- rb_realpath_internal (Qnil , file , 1 ),
1777- 1 , NULL , 0 , ISEQ_TYPE_TOP , & option ));
1805+ int error_state ;
1806+ rb_iseq_t * iseq = pm_iseq_new_with_opt (& result .node , rb_fstring_lit ("<main>" ),
1807+ file ,
1808+ rb_realpath_internal (Qnil , file , 1 ),
1809+ 1 , NULL , 0 , ISEQ_TYPE_TOP , & option , & error_state );
1810+
17781811 pm_parse_result_free (& result );
1812+
1813+ if (error_state ) {
1814+ RUBY_ASSERT (iseq == NULL );
1815+ rb_jump_tag (error_state );
1816+ }
1817+
1818+ ret = iseqw_new (iseq );
17791819 rb_vm_pop_frame (ec );
17801820 RB_GC_GUARD (v );
17811821 return ret ;
0 commit comments