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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
|
nsgenbind
=========
This is a tool to generate JavaScript to DOM bindings from w3c webidl
files and a binding configuration file.
Building
--------
The tool requires bison and flex as pre-requisites
Commandline
-----------
nsgenbind [-v] [-n] [-g] [-D] [-W] [-I idlpath] inputfile outputdir
-v
The verbose switch makes the tool verbose about what operations it
is performing instead of the default of only reporting errors.
-n
The tool will not generate any output but will perform all other
operations as if it was. Useful for debugging bindings
-g
The generated code will be augmented with runtime debug logging so
it can be traced
-D
The tool will generate output to allow debugging of output
conversion. This includes dumps of the binding and IDL files AST
-W
This switch will make the tool generate warnings about various
issues with the binding or IDL files being processed.
-I
An additional search path may be given so idl files can be located.
The tool requires a binding file as input and an output directory in
which to place its output.
Debug output
------------
In addition to the generated source the tool will output several
debugging files with the -D switch in use.
interface.dot
The interfaces IDL dot file contains all the interfaces and their
relationship. graphviz can be used to convert this into a visual
representation which is sometimes useful to help in debugging
missing or incorrect interface inheritance.
Processing the dot file with graphviz can produce very large files
so care must be taken with options. Some examples that produce
adequate output:
# classical tree
dot -O -Tsvg interface.dot
# radial output
twopi -Granksep=10.0 -Gnodesep=1.0 -Groot=0009 -O -Tsvg interface.dot
Web IDL
-------
The IDL is specified in a w3c document[1] but the second edition is in
draft[2] and covers many of the features actually used in the whatwg
dom and HTML spec.
The principal usage of the IDL is to define the interface between
scripts and a browsers internal state. For example the DOM[3] and
HTML[4] specs contain all the IDL for accessing the DOM and interacting
with a web browser (this not strictly true as there are several
interfaces simply not in the standards such as console).
The IDL uses some slightly strange names than other object orientated
systems.
IDL | JS | OOP | Notes
-----------+------------------+----------------+----------------------------
interface | prototype | class | The data definition of
| | | the object
constants | read-only value | class variable | Belong to class, one copy
| property on the | |
| prototype | |
operation | method | method | functions that can be called
attribute | property | property | Variables set per instance
-----------+------------------+----------------+----------------------------
Binding file
------------
The binding file controls how the code generator constructs its
output. It is deliberately similar to c++ in syntax and uses OOP
nomenclature to describe the annotations (class, method, etc. instead
of interface, operation, etc.)
The binding file consists of three types of element:
binding
The binding element has an identifier controlling which type of
output is produced (currently duk_libdom and jsapi_libdom).
The binding block may contain one or more directives which
control overall generation behaviour:
webidl
This takes a quoted string which identifies a WebIDL file to
process. There may be many of these directives as required
but without at least one the binding is not very useful as
it will generate no output.
preface
This takes a cdata block. There may only be one of these per
binding, subsequent directives will be ignored.
The preface is emitted in every generated source file before
any other output and generally is used for copyright
comments and similar. It is immediately followed by the
binding tools preamble comments.
prologue
This takes a cdata block. There may only be one of these per
binding, subsequent directives will be ignored.
The prologue is emitted in every generated source file after
the class preface has been generated. It is often used for
include directives required across all modules.
epilogue
This takes a cdata block. There may only be one of these per
binding, subsequent directives will be ignored.
The epilogue is emitted after the generated code and the
class epilogue
postface
This takes a cdata block. There may only be one of these per
binding, subsequent directives will be ignored.
The postface is emitted as the very last element of the
generated source files.
class
The class controls the generation of source for an IDL interface
private member variables are declared here and header and
footer elements specific to this class.
Although not generally useful, because methods that reference a
class cause it to be implicitly created, empty definitions are
permitted.
private
variables added to the private structure for the class.
preface
This takes a cdata block. There may only be one of these per
class, subsequent directives will be ignored.
The preface is emitted in every generated source file after
the binding preface and tool preamble.
prologue
This takes a cdata block. There may only be one of these per
class, subsequent directives will be ignored.
The prologue is emitted in every generated source file after
the binding prologue has been generated.
epilogue
This takes a cdata block. There may only be one of these per
class, subsequent directives will be ignored.
The epilogue is emitted after the generated code and before
the binding epilogue
postface
This takes a cdata block. There may only be one of these per
class, subsequent directives will be ignored.
The postface is emitted after the binding epilogue.
methods
The methods allow a binding to provide code to be inserted in
the output and to control the class initializer and finalizer
(note not the constructor/destructor)
All these are in the syntax of:
methodtype declarator ( parameters )
They may optionally be followed by a cdata block which will be
added to the appropriate method in the output. A semicolon may
be used instead of the cdata block but this is not obviously
useful except in the case of the init type.
methods and getters/setters for properties must specify both
class and name using the c++ style double colon separated
identifiers i.e. class::identifier
Note: the class names must match the IDL interface names in the
binding but they will almost certainly have to be translated
into more suitable class names for generated output.
preface
The declarator for this method type need only identify the
class (an identifier may be provided but will be ignored).
This takes a cdata block. There may only be one of these per
class, subsequent directives will be ignored.
The preface is emitted in every generated source file after
the binding preface and tool preamble.
prologue
The declarator for this method type need only identify the
class (an identifier may be provided but will be ignored).
This takes a cdata block. There may only be one of these per
class, subsequent directives will be ignored.
The prologue is emitted in every generated source file after
the binding prologue has been generated.
epilogue
The declarator for this method type need only identify the
class (an identifier may be provided but will be ignored).
This takes a cdata block. There may only be one of these per
class, subsequent directives will be ignored.
The epilogue is emitted after the generated code and before
the binding epilogue
postface
The declarator for this method type need only identify the
class (an identifier may be provided but will be ignored).
This takes a cdata block. There may only be one of these per
class, subsequent directives will be ignored.
The postface is emitted after the binding epilogue.
init
The declarator for this method type need only identify the
class (an identifier may be provided but will be ignored).
TODO: should it become necessary to defeat the automated
generation of an initializer altogether the identifier can
be checked and if set to the class name (like a
constructor) output body simply becomes a verbatim copy of
the cdata block.
The parameter list may be empty or contain type/identifier
tuples. If there is a parent interface it will be called
with the parameters necessary for its initializer, hence the
entire ancestry will be initialised.
The parameters passed to the parent are identified by
matching the identifier with the parents initializer
parameter identifier, if the type does not match a type
cast is inserted.
It is sometimes desirable for the parent initializer
identifier to be different from the childs identifier. In
this case the identifier may have an alias added by having
a double colon followed by a second identifier.
For example consider the case below where HTMLElement
inherits from Element which inherits from Node.
init Node("struct dom_node *" node);
init Element("struct dom_element *" element::node);
init HTMLElement("struct dom_html_element *" html_element::element);
The three initializers have parameters with different
identifiers but specify the identifier as it appears in
their parents parameter list. This allows for differing
parameter ordering and identifier naming while allowing the
automated enforcement of correct initializer calling
chains.
fini
The declarator for this method type need only identify the
class (an identifier may be provided but will be ignored).
The cdata block is output.
The parent finalizer is called (finalizers have no parameters
so do not need the complexity of initializers.
method
The declarator for this method type must contain both the
class and the identifier.
The cdata block is output.
getter
The declarator for this method type must contain both the
class and the identifier.
The cdata block is output.
setter
The declarator for this method type must contain both the
class and the identifier.
The cdata block is output.
Generated source
----------------
duk_libdom
This binding type generates several files as output:
- binding.c
support function source
- binding.h
header to declare the support functions and magic constant
- prototype.h
header which declares all the prototype builder, initialiser
and finalizer functions.
- private.h
Which defines all the private structures for all classes
- C source file per class
These are the main output of the tool and are structured to
give the binding author control of the output while
automatically generating as much code as possible.
The files are generated in sections:
tool preface
binding preface
class preface
tool prologue
binding prologue
class prologue
initialiser
finalizer
constructor
destructor
methods
getters and setters
prototype
class epilogue
binding epilogue
tool epilogue
class postface
binding postface
tool postface
The preface, prologue, epilogue and postface are all
verbaitum output from the binding and class elements in the
binding. All the other sections are generated code augmented
and controlled by the binding.
Method generation produces a method with appropriate
signature added to the prototype. Any verbatum cdata from
the binding is added after the code that automatically
populates a private pointer of the appropriate type
(named priv).
References
----------
[1] http://www.w3.org/TR/WebIDL/
[2] https://heycam.github.io/webidl/
[3] https://dom.spec.whatwg.org/
[4] https://html.spec.whatwg.org/
|