File: m4macros.txt

package info (click to toggle)
sablevm 1.13-1.1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 10,084 kB
  • ctags: 9,231
  • sloc: ansic: 127,926; sh: 8,886; asm: 5,548; makefile: 693
file content (156 lines) | stat: -rw-r--r-- 4,546 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * This source file is part of SableVM.                            *
 *                                                                 *
 * See the file "LICENSE" for the copyright information and for    *
 * the terms and conditions for copying, distribution and          *
 * modification of this source file.                               *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

m4 macros in SableVM
====================

SableVM provides a set of powerful m4 macros.  This document describes
their usage, problems that may occur, and walks through the
complexities of instructions_preparation.m4.c.  More documentation can
be found in ./src/libsablevm/macros.m4

Mixed C and m4 files
====================

Oftentimes it may be convenient to have m4 macros inside certain
portions of a C file.  Here is an easy way to convert from .c/.h to
.m4.c/.m4.h

If you change a file like this, you need to change Makefile.am to
build it properly.  This is relatively easy, and there are many
examples to follow.  You should also use 

  'svn mv <filename>.c <filename>.m4.c' 

so that the file keeps sandbox history.  Then, make sure the file
follows this format, defining macros wherever you need them:

/* m4svm_file_name */      <---- 1st line of file
/* m4svm_on(0)m4_dnl */

  << ordinary C code >>

/* some comment *[::]/
   m4svm_off ();
*/

m4svm_define_begin v = ":], [:m4svm_macro_name:])";

  << C macro body here >>

m4svm_define_end v = ":])";
/* m4svm_macro_name(arg1,arg2,...,argN)
   m4_undefine([:m4svm_macro_name:])
   m4svm_on(0)m4_dnl */

  << more ordinary C code >>

EOF

C comments with commas inside macro bodies
==========================================

If you have C comments in a macro body, you cannot put a `,' inside
them.  Rather, you must quote them using the redefined quote tokens, like so:

[:,:]

Usually it's easier just to write the C comments without commas in the
first place.

Mismatched C parentheses in a macro body
========================================

If for some reason you have mismatched parentheses in a macro body,
this will confuse m4 even if the mismatch is only relevant to the
generated C code.  You might think it is an m4 bug when really it's
the C code that's at fault.

Maximum macro body length
=========================

At some point, while writing a long instruction in instructions.m4.c,
I came across a maximum where m4 would no longer recognize the
m4svm_instruction_tail() macro properly.  If you have really long
macro bodies (500+ lines), and are getting confusing m4 errors, try
cutting down the size of the macro body.

Details on instructions_preparation.m4.c
========================================

Here we'll cover m4svm_instruction_1, m4svm_instruction_2$1, and the
rest of the stuff in ./src/libsablevm/instructions_preparation.m4.c

The problem is that GNU indent puts a space between the function and
the left parenthesis, e.g. 'foo (arg1, arg2);'.  Unfortunately m4 does
not allow for a space between the parenthesis and the macro name.  So,
we have to play tricks. :-)  Let's do it in steps.

STEP 1.

  m4svm_instruction_head (NOP, SVM_INTRP_FLAG_INLINEABLE, 0);

expands to:
 
  m4svm_instruction_1( (NOP, SVM_INTRP_FLAG_INLINEABLE, 0);
    << instruction body in C >>
  m4svm_instruction_tail ();

Now, 

  m4svm_instruction_tail 

expands to:
  
  ))m4_dnl ();
  
This whole thing (after applying m4_dnl) becomes:
  
  m4svm_instruction_1( (NOP, SVM_INTRP_FLAG_INLINEABLE, 0);
    << instruction body in C >>
  ))

STEP 2.
 
The above result becomes a call to m4svm_instruction_1 with a single
parameter [delimited by parentheses].  The argument is:

  (NOP, SVM_INTRP_FLAG_INLINEABLE, 0);
    << instruction body in C >>
  )

STEP 3.
  
m4svm_instruction_1 is expanded and we get:  

  m4svm_instruction_2(NOP, SVM_INTRP_FLAG_INLINEABLE, 0);

Which ends with a ";", and it does not include the instruction body.
So, we must expand m4svm_instruction_2.

STEP 4.
  
  m4svm_instruction_2(NOP, SVM_INTRP_FLAG_INLINEABLE, 0);

expands to:

  m4svm_instruction($1, $2, $3,m4_dnl

or, more precisely:

  m4svm_instruction(NOP, SVM_INTRP_FLAG_INLINEABLE, 0,m4_dnl;

So, after applying m4_dnl, the whole thing now looks as:
  
  m4svm_instruction(NOP, SVM_INTRP_FLAG_INLINEABLE, 0,
    << instruction body in C >>
  )

Which also gets rid of the ";" at the end of the
m4svm_instruction_head line.  Now m4svm_instruction has all the
params that we wanted it to have.