@@ -436,6 +436,8 @@ static jl_value_t *scm_to_julia(fl_context_t *fl_ctx, value_t e, jl_module_t *mo
436436 }
437437 JL_CATCH {
438438 // if expression cannot be converted, replace with error expr
439+ //jl_(jl_current_exception());
440+ //jlbacktrace();
439441 jl_expr_t * ex = jl_exprn (jl_error_sym , 1 );
440442 v = (jl_value_t * )ex ;
441443 jl_array_ptr_set (ex -> args , 0 , jl_cstr_to_string ("invalid AST" ));
@@ -1000,7 +1002,59 @@ int jl_has_meta(jl_array_t *body, jl_sym_t *sym) JL_NOTSAFEPOINT
10001002 return 0 ;
10011003}
10021004
1003- 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 )
1005+ // Utility function to return whether `e` is any of the special AST types or
1006+ // will always evaluate to itself exactly unchanged. This corresponds to
1007+ // `is_self_quoting` in Core.Compiler utilities.
1008+ int jl_is_ast_node (jl_value_t * e ) JL_NOTSAFEPOINT
1009+ {
1010+ return jl_is_newvarnode (e )
1011+ || jl_is_code_info (e )
1012+ || jl_is_linenode (e )
1013+ || jl_is_gotonode (e )
1014+ || jl_is_gotoifnot (e )
1015+ || jl_is_returnnode (e )
1016+ || jl_is_ssavalue (e )
1017+ || jl_is_slotnumber (e )
1018+ || jl_is_argument (e )
1019+ || jl_is_quotenode (e )
1020+ || jl_is_globalref (e )
1021+ || jl_is_symbol (e )
1022+ || jl_is_pinode (e )
1023+ || jl_is_phinode (e )
1024+ || jl_is_phicnode (e )
1025+ || jl_is_upsilonnode (e )
1026+ || jl_is_expr (e );
1027+ }
1028+
1029+ static int is_self_quoting_expr (jl_expr_t * e ) JL_NOTSAFEPOINT
1030+ {
1031+ return (e -> head == jl_inert_sym ||
1032+ e -> head == jl_core_sym ||
1033+ e -> head == jl_line_sym ||
1034+ e -> head == jl_lineinfo_sym ||
1035+ e -> head == jl_meta_sym ||
1036+ e -> head == jl_boundscheck_sym ||
1037+ e -> head == jl_inline_sym ||
1038+ e -> head == jl_noinline_sym );
1039+ }
1040+
1041+ // any AST, except those that cannot contain symbols
1042+ // and have no side effects
1043+ int need_esc_node (jl_value_t * e ) JL_NOTSAFEPOINT
1044+ {
1045+ if (jl_is_linenode (e )
1046+ || jl_is_ssavalue (e )
1047+ || jl_is_slotnumber (e )
1048+ || jl_is_argument (e )
1049+ || jl_is_quotenode (e ))
1050+ return 0 ;
1051+ if (jl_is_expr (e ))
1052+ return !is_self_quoting_expr ((jl_expr_t * )e );
1053+ // note: jl_is_globalref(e) is not included here, since we care a little about about having a line number for it
1054+ return jl_is_ast_node (e );
1055+ }
1056+
1057+ 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 )
10041058{
10051059 jl_task_t * ct = jl_current_task ;
10061060 JL_TIMING (MACRO_INVOCATION , MACRO_INVOCATION );
@@ -1012,10 +1066,9 @@ static jl_value_t *jl_invoke_julia_macro(jl_array_t *args, jl_module_t *inmodule
10121066 margs [0 ] = jl_array_ptr_ref (args , 0 );
10131067 // __source__ argument
10141068 jl_value_t * lno = jl_array_ptr_ref (args , 1 );
1069+ if (!jl_is_linenode (lno ))
1070+ lno = jl_new_struct (jl_linenumbernode_type , jl_box_long (0 ), jl_nothing );
10151071 margs [1 ] = lno ;
1016- if (!jl_is_linenode (lno )) {
1017- margs [1 ] = jl_new_struct (jl_linenumbernode_type , jl_box_long (0 ), jl_nothing );
1018- }
10191072 margs [2 ] = (jl_value_t * )inmodule ;
10201073 for (i = 3 ; i < nargs ; i ++ )
10211074 margs [i ] = jl_array_ptr_ref (args , i - 1 );
@@ -1054,6 +1107,7 @@ static jl_value_t *jl_invoke_julia_macro(jl_array_t *args, jl_module_t *inmodule
10541107 }
10551108 }
10561109 ct -> world_age = last_age ;
1110+ * lineinfo = margs [1 ];
10571111 JL_GC_POP ();
10581112 return result ;
10591113}
@@ -1076,36 +1130,47 @@ static jl_value_t *jl_expand_macros(jl_value_t *expr, jl_module_t *inmodule, str
10761130 JL_GC_POP ();
10771131 return expr ;
10781132 }
1079- if (e -> head == jl_hygienicscope_sym && jl_expr_nargs (e ) = = 2 ) {
1133+ if (e -> head == jl_hygienicscope_sym && jl_expr_nargs (e ) > = 2 ) {
10801134 struct macroctx_stack newctx ;
10811135 newctx .m = (jl_module_t * )jl_exprarg (e , 1 );
10821136 JL_TYPECHK (hygienic - scope , module , (jl_value_t * )newctx .m );
10831137 newctx .parent = macroctx ;
10841138 jl_value_t * a = jl_exprarg (e , 0 );
10851139 jl_value_t * a2 = jl_expand_macros (a , inmodule , & newctx , onelevel , world , throw_load_error );
1086- if (a != a2 )
1140+ if (jl_is_expr (a2 ) && ((jl_expr_t * )a2 )-> head == jl_escape_sym && !need_esc_node (jl_exprarg (a2 , 0 )))
1141+ expr = jl_exprarg (a2 , 0 );
1142+ else if (!need_esc_node (a2 ))
1143+ expr = a2 ;
1144+ else if (a != a2 )
10871145 jl_array_ptr_set (e -> args , 0 , a2 );
10881146 return expr ;
10891147 }
10901148 if (e -> head == jl_macrocall_sym ) {
10911149 struct macroctx_stack newctx ;
10921150 newctx .m = macroctx ? macroctx -> m : inmodule ;
10931151 newctx .parent = macroctx ;
1094- jl_value_t * result = jl_invoke_julia_macro (e -> args , inmodule , & newctx .m , world , throw_load_error );
1152+ jl_value_t * lineinfo = NULL ;
1153+ jl_value_t * result = jl_invoke_julia_macro (e -> args , inmodule , & newctx .m , & lineinfo , world , throw_load_error );
1154+ if (!need_esc_node (result ))
1155+ return result ;
10951156 jl_value_t * wrap = NULL ;
1096- JL_GC_PUSH3 (& result , & wrap , & newctx .m );
1157+ JL_GC_PUSH4 (& result , & wrap , & newctx .m , & lineinfo );
10971158 // copy and wrap the result in `(hygienic-scope ,result ,newctx)
10981159 if (jl_is_expr (result ) && ((jl_expr_t * )result )-> head == jl_escape_sym )
10991160 result = jl_exprarg (result , 0 );
11001161 else
1101- wrap = (jl_value_t * )jl_exprn (jl_hygienicscope_sym , 2 );
1162+ wrap = (jl_value_t * )jl_exprn (jl_hygienicscope_sym , 3 );
11021163 result = jl_copy_ast (result );
11031164 if (!onelevel )
11041165 result = jl_expand_macros (result , inmodule , wrap ? & newctx : macroctx , onelevel , world , throw_load_error );
1105- if (wrap ) {
1166+ if (wrap && need_esc_node ( result ) ) {
11061167 jl_exprargset (wrap , 0 , result );
11071168 jl_exprargset (wrap , 1 , newctx .m );
1108- result = wrap ;
1169+ jl_exprargset (wrap , 2 , lineinfo );
1170+ if (jl_is_expr (result ) && ((jl_expr_t * )result )-> head == jl_escape_sym )
1171+ result = jl_exprarg (result , 0 );
1172+ else
1173+ result = wrap ;
11091174 }
11101175 JL_GC_POP ();
11111176 return result ;
0 commit comments