@@ -434,6 +434,8 @@ static jl_value_t *scm_to_julia(fl_context_t *fl_ctx, value_t e, jl_module_t *mo
434434 }
435435 JL_CATCH {
436436 // if expression cannot be converted, replace with error expr
437+ //jl_(jl_current_exception());
438+ //jlbacktrace();
437439 jl_expr_t * ex = jl_exprn (jl_error_sym , 1 );
438440 v = (jl_value_t * )ex ;
439441 jl_array_ptr_set (ex -> args , 0 , jl_cstr_to_string ("invalid AST" ));
@@ -998,7 +1000,59 @@ int jl_has_meta(jl_array_t *body, jl_sym_t *sym) JL_NOTSAFEPOINT
9981000 return 0 ;
9991001}
10001002
1001- static jl_value_t * jl_invoke_julia_macro (jl_array_t * args , jl_module_t * inmodule , jl_module_t * * ctx , size_t world , int throw_load_error )
1003+ // Utility function to return whether `e` is any of the special AST types or
1004+ // will always evaluate to itself exactly unchanged. This corresponds to
1005+ // `is_self_quoting` in Core.Compiler utilities.
1006+ int jl_is_ast_node (jl_value_t * e ) JL_NOTSAFEPOINT
1007+ {
1008+ return jl_is_newvarnode (e )
1009+ || jl_is_code_info (e )
1010+ || jl_is_linenode (e )
1011+ || jl_is_gotonode (e )
1012+ || jl_is_gotoifnot (e )
1013+ || jl_is_returnnode (e )
1014+ || jl_is_ssavalue (e )
1015+ || jl_is_slotnumber (e )
1016+ || jl_is_argument (e )
1017+ || jl_is_quotenode (e )
1018+ || jl_is_globalref (e )
1019+ || jl_is_symbol (e )
1020+ || jl_is_pinode (e )
1021+ || jl_is_phinode (e )
1022+ || jl_is_phicnode (e )
1023+ || jl_is_upsilonnode (e )
1024+ || jl_is_expr (e );
1025+ }
1026+
1027+ static int is_self_quoting_expr (jl_expr_t * e )
1028+ {
1029+ return (e -> head == jl_inert_sym ||
1030+ e -> head == jl_core_sym ||
1031+ e -> head == jl_line_sym ||
1032+ e -> head == jl_lineinfo_sym ||
1033+ e -> head == jl_meta_sym ||
1034+ e -> head == jl_boundscheck_sym ||
1035+ e -> head == jl_inline_sym ||
1036+ e -> head == jl_noinline_sym );
1037+ }
1038+
1039+ // any AST, except those that cannot contain symbols
1040+ // and have no side effects
1041+ int need_esc_node (jl_value_t * e ) JL_NOTSAFEPOINT
1042+ {
1043+ if (jl_is_linenode (e )
1044+ || jl_is_ssavalue (e )
1045+ || jl_is_slotnumber (e )
1046+ || jl_is_argument (e )
1047+ || jl_is_quotenode (e ))
1048+ return 0 ;
1049+ if (jl_is_expr (e ))
1050+ return !is_self_quoting_expr ((jl_expr_t * )e );
1051+ // note: jl_is_globalref(e) is not included here, since we care a little about about having a line number for it
1052+ return jl_is_ast_node (e );
1053+ }
1054+
1055+ static jl_value_t * jl_invoke_julia_macro (jl_array_t * args , jl_module_t * inmodule , jl_module_t * * ctx , jl_value_t * * lineinfo , size_t world , int throw_load_error )
10021056{
10031057 jl_task_t * ct = jl_current_task ;
10041058 JL_TIMING (MACRO_INVOCATION , MACRO_INVOCATION );
@@ -1010,10 +1064,9 @@ static jl_value_t *jl_invoke_julia_macro(jl_array_t *args, jl_module_t *inmodule
10101064 margs [0 ] = jl_array_ptr_ref (args , 0 );
10111065 // __source__ argument
10121066 jl_value_t * lno = jl_array_ptr_ref (args , 1 );
1067+ if (!jl_is_linenode (lno ))
1068+ lno = jl_new_struct (jl_linenumbernode_type , jl_box_long (0 ), jl_nothing );
10131069 margs [1 ] = lno ;
1014- if (!jl_typetagis (lno , jl_linenumbernode_type )) {
1015- margs [1 ] = jl_new_struct (jl_linenumbernode_type , jl_box_long (0 ), jl_nothing );
1016- }
10171070 margs [2 ] = (jl_value_t * )inmodule ;
10181071 for (i = 3 ; i < nargs ; i ++ )
10191072 margs [i ] = jl_array_ptr_ref (args , i - 1 );
@@ -1052,6 +1105,7 @@ static jl_value_t *jl_invoke_julia_macro(jl_array_t *args, jl_module_t *inmodule
10521105 }
10531106 }
10541107 ct -> world_age = last_age ;
1108+ * lineinfo = margs [1 ];
10551109 JL_GC_POP ();
10561110 return result ;
10571111}
@@ -1074,36 +1128,47 @@ static jl_value_t *jl_expand_macros(jl_value_t *expr, jl_module_t *inmodule, str
10741128 JL_GC_POP ();
10751129 return expr ;
10761130 }
1077- if (e -> head == jl_hygienicscope_sym && jl_expr_nargs (e ) = = 2 ) {
1131+ if (e -> head == jl_hygienicscope_sym && jl_expr_nargs (e ) > = 2 ) {
10781132 struct macroctx_stack newctx ;
10791133 newctx .m = (jl_module_t * )jl_exprarg (e , 1 );
10801134 JL_TYPECHK (hygienic - scope , module , (jl_value_t * )newctx .m );
10811135 newctx .parent = macroctx ;
10821136 jl_value_t * a = jl_exprarg (e , 0 );
10831137 jl_value_t * a2 = jl_expand_macros (a , inmodule , & newctx , onelevel , world , throw_load_error );
1084- if (a != a2 )
1138+ if (jl_is_expr (a2 ) && ((jl_expr_t * )a2 )-> head == jl_escape_sym && !need_esc_node (jl_exprarg (a2 , 0 )))
1139+ expr = jl_exprarg (a2 , 0 );
1140+ else if (!need_esc_node (a2 ))
1141+ expr = a2 ;
1142+ else if (a != a2 )
10851143 jl_array_ptr_set (e -> args , 0 , a2 );
10861144 return expr ;
10871145 }
10881146 if (e -> head == jl_macrocall_sym ) {
10891147 struct macroctx_stack newctx ;
10901148 newctx .m = macroctx ? macroctx -> m : inmodule ;
10911149 newctx .parent = macroctx ;
1092- jl_value_t * result = jl_invoke_julia_macro (e -> args , inmodule , & newctx .m , world , throw_load_error );
1150+ jl_value_t * lineinfo = NULL ;
1151+ jl_value_t * result = jl_invoke_julia_macro (e -> args , inmodule , & newctx .m , & lineinfo , world , throw_load_error );
1152+ if (!need_esc_node (result ))
1153+ return result ;
10931154 jl_value_t * wrap = NULL ;
1094- JL_GC_PUSH3 (& result , & wrap , & newctx .m );
1155+ JL_GC_PUSH4 (& result , & wrap , & newctx .m , & lineinfo );
10951156 // copy and wrap the result in `(hygienic-scope ,result ,newctx)
10961157 if (jl_is_expr (result ) && ((jl_expr_t * )result )-> head == jl_escape_sym )
10971158 result = jl_exprarg (result , 0 );
10981159 else
1099- wrap = (jl_value_t * )jl_exprn (jl_hygienicscope_sym , 2 );
1160+ wrap = (jl_value_t * )jl_exprn (jl_hygienicscope_sym , 3 );
11001161 result = jl_copy_ast (result );
11011162 if (!onelevel )
11021163 result = jl_expand_macros (result , inmodule , wrap ? & newctx : macroctx , onelevel , world , throw_load_error );
1103- if (wrap ) {
1164+ if (wrap && need_esc_node ( result ) ) {
11041165 jl_exprargset (wrap , 0 , result );
11051166 jl_exprargset (wrap , 1 , newctx .m );
1106- result = wrap ;
1167+ jl_exprargset (wrap , 2 , lineinfo );
1168+ if (jl_is_expr (result ) && ((jl_expr_t * )result )-> head == jl_escape_sym )
1169+ result = jl_exprarg (result , 0 );
1170+ else
1171+ result = wrap ;
11071172 }
11081173 JL_GC_POP ();
11091174 return result ;
0 commit comments