Fix bytecode JMP slot range after const + and/or optimization.
[luajit-2.0.git] / doc / ext_ffi_api.html
blobc85b8560e8bcaea8651121821f0b521762b5e35e
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2 <html>
3 <head>
4 <title>ffi.* API Functions</title>
5 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6 <meta name="Author" content="Mike Pall">
7 <meta name="Copyright" content="Copyright (C) 2005-2012, Mike Pall">
8 <meta name="Language" content="en">
9 <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
10 <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
11 <style type="text/css">
12 table.abitable { width: 30em; line-height: 1.2; }
13 tr.abihead td { font-weight: bold; }
14 td.abiparam { font-weight: bold; width: 6em; }
15 </style>
16 </head>
17 <body>
18 <div id="site">
19 <a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
20 </div>
21 <div id="head">
22 <h1><tt>ffi.*</tt> API Functions</h1>
23 </div>
24 <div id="nav">
25 <ul><li>
26 <a href="luajit.html">LuaJIT</a>
27 <ul><li>
28 <a href="install.html">Installation</a>
29 </li><li>
30 <a href="running.html">Running</a>
31 </li></ul>
32 </li><li>
33 <a href="extensions.html">Extensions</a>
34 <ul><li>
35 <a href="ext_ffi.html">FFI Library</a>
36 <ul><li>
37 <a href="ext_ffi_tutorial.html">FFI Tutorial</a>
38 </li><li>
39 <a class="current" href="ext_ffi_api.html">ffi.* API</a>
40 </li><li>
41 <a href="ext_ffi_semantics.html">FFI Semantics</a>
42 </li></ul>
43 </li><li>
44 <a href="ext_jit.html">jit.* Library</a>
45 </li><li>
46 <a href="ext_c_api.html">Lua/C API</a>
47 </li></ul>
48 </li><li>
49 <a href="status.html">Status</a>
50 <ul><li>
51 <a href="changes.html">Changes</a>
52 </li></ul>
53 </li><li>
54 <a href="faq.html">FAQ</a>
55 </li><li>
56 <a href="http://luajit.org/performance.html">Performance <span class="ext">&raquo;</span></a>
57 </li><li>
58 <a href="http://luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
59 </li></ul>
60 </div>
61 <div id="main">
62 <p>
63 This page describes the API functions provided by the FFI library in
64 detail. It's recommended to read through the
65 <a href="ext_ffi.html">introduction</a> and the
66 <a href="ext_ffi_tutorial.html">FFI tutorial</a> first.
67 </p>
69 <h2 id="glossary">Glossary</h2>
70 <ul>
71 <li><b>cdecl</b> &mdash; An abstract C&nbsp;type declaration (a Lua
72 string).</li>
73 <li><b>ctype</b> &mdash; A C&nbsp;type object. This is a special kind of
74 <b>cdata</b> returned by <tt>ffi.typeof()</tt>. It serves as a
75 <b>cdata</b> <a href="#ffi_new">constructor</a> when called.</li>
76 <li><b>cdata</b> &mdash; A C&nbsp;data object. It holds a value of the
77 corresponding <b>ctype</b>.</li>
78 <li><b>ct</b> &mdash; A C&nbsp;type specification which can be used for
79 most of the API functions. Either a <b>cdecl</b>, a <b>ctype</b> or a
80 <b>cdata</b> serving as a template type.</li>
81 <li><b>cb</b> &mdash; A callback object. This is a C&nbsp;data object
82 holding a special function pointer. Calling this function from
83 C&nbsp;code runs an associated Lua function.</li>
84 <li><b>VLA</b> &mdash; A variable-length array is declared with a
85 <tt>?</tt> instead of the number of elements, e.g. <tt>"int[?]"</tt>.
86 The number of elements (<tt>nelem</tt>) must be given when it's
87 <a href="#ffi_new">created</a>.</li>
88 <li><b>VLS</b> &mdash; A variable-length struct is a <tt>struct</tt> C
89 type where the last element is a <b>VLA</b>. The same rules for
90 declaration and creation apply.</li>
91 </ul>
93 <h2 id="decl">Declaring and Accessing External Symbols</h2>
94 <p>
95 External symbols must be declared first and can then be accessed by
96 indexing a <a href="ext_ffi_semantics.html#clib">C&nbsp;library
97 namespace</a>, which automatically binds the symbol to a specific
98 library.
99 </p>
101 <h3 id="ffi_cdef"><tt>ffi.cdef(def)</tt></h3>
103 Adds multiple C&nbsp;declarations for types or external symbols (named
104 variables or functions). <tt>def</tt> must be a Lua string. It's
105 recommended to use the syntactic sugar for string arguments as
106 follows:
107 </p>
108 <pre class="code">
109 ffi.cdef[[
110 <span style="color:#00a000;">typedef struct foo { int a, b; } foo_t; // Declare a struct and typedef.
111 int dofoo(foo_t *f, int n); /* Declare an external C function. */</span>
113 </pre>
115 The contents of the string (the part in green above) must be a
116 sequence of
117 <a href="ext_ffi_semantics.html#clang">C&nbsp;declarations</a>,
118 separated by semicolons. The trailing semicolon for a single
119 declaration may be omitted.
120 </p>
122 Please note that external symbols are only <em>declared</em>, but they
123 are <em>not bound</em> to any specific address, yet. Binding is
124 achieved with C&nbsp;library namespaces (see below).
125 </p>
126 <p style="color: #c00000;">
127 C&nbsp;declarations are not passed through a C&nbsp;pre-processor,
128 yet. No pre-processor tokens are allowed, except for
129 <tt>#pragma&nbsp;pack</tt>. Replace <tt>#define</tt> in existing
130 C&nbsp;header files with <tt>enum</tt>, <tt>static&nbsp;const</tt>
131 or <tt>typedef</tt> and/or pass the files through an external
132 C&nbsp;pre-processor (once). Be careful not to include unneeded or
133 redundant declarations from unrelated header files.
134 </p>
136 <h3 id="ffi_C"><tt>ffi.C</tt></h3>
138 This is the default C&nbsp;library namespace &mdash; note the
139 uppercase <tt>'C'</tt>. It binds to the default set of symbols or
140 libraries on the target system. These are more or less the same as a
141 C&nbsp;compiler would offer by default, without specifying extra link
142 libraries.
143 </p>
145 On POSIX systems, this binds to symbols in the default or global
146 namespace. This includes all exported symbols from the executable and
147 any libraries loaded into the global namespace. This includes at least
148 <tt>libc</tt>, <tt>libm</tt>, <tt>libdl</tt> (on Linux),
149 <tt>libgcc</tt> (if compiled with GCC), as well as any exported
150 symbols from the Lua/C&nbsp;API provided by LuaJIT itself.
151 </p>
153 On Windows systems, this binds to symbols exported from the
154 <tt>*.exe</tt>, the <tt>lua51.dll</tt> (i.e. the Lua/C&nbsp;API
155 provided by LuaJIT itself), the C&nbsp;runtime library LuaJIT was linked
156 with (<tt>msvcrt*.dll</tt>), <tt>kernel32.dll</tt>,
157 <tt>user32.dll</tt> and <tt>gdi32.dll</tt>.
158 </p>
160 <h3 id="ffi_load"><tt>clib = ffi.load(name [,global])</tt></h3>
162 This loads the dynamic library given by <tt>name</tt> and returns
163 a new C&nbsp;library namespace which binds to its symbols. On POSIX
164 systems, if <tt>global</tt> is <tt>true</tt>, the library symbols are
165 loaded into the global namespace, too.
166 </p>
168 If <tt>name</tt> is a path, the library is loaded from this path.
169 Otherwise <tt>name</tt> is canonicalized in a system-dependent way and
170 searched in the default search path for dynamic libraries:
171 </p>
173 On POSIX systems, if the name contains no dot, the extension
174 <tt>.so</tt> is appended. Also, the <tt>lib</tt> prefix is prepended
175 if necessary. So <tt>ffi.load("z")</tt> looks for <tt>"libz.so"</tt>
176 in the default shared library search path.
177 </p>
179 On Windows systems, if the name contains no dot, the extension
180 <tt>.dll</tt> is appended. So <tt>ffi.load("ws2_32")</tt> looks for
181 <tt>"ws2_32.dll"</tt> in the default DLL search path.
182 </p>
184 <h2 id="create">Creating cdata Objects</h2>
186 The following API functions create cdata objects (<tt>type()</tt>
187 returns <tt>"cdata"</tt>). All created cdata objects are
188 <a href="ext_ffi_semantics.html#gc">garbage collected</a>.
189 </p>
191 <h3 id="ffi_new"><tt>cdata = ffi.new(ct [,nelem] [,init...])<br>
192 cdata = <em>ctype</em>([nelem,] [init...])</tt></h3>
194 Creates a cdata object for the given <tt>ct</tt>. VLA/VLS types
195 require the <tt>nelem</tt> argument. The second syntax uses a ctype as
196 a constructor and is otherwise fully equivalent.
197 </p>
199 The cdata object is initialized according to the
200 <a href="ext_ffi_semantics.html#init">rules for initializers</a>,
201 using the optional <tt>init</tt> arguments. Excess initializers cause
202 an error.
203 </p>
205 Performance notice: if you want to create many objects of one kind,
206 parse the cdecl only once and get its ctype with
207 <tt>ffi.typeof()</tt>. Then use the ctype as a constructor repeatedly.
208 </p>
209 <p style="font-size: 8pt;">
210 Please note that an anonymous <tt>struct</tt> declaration implicitly
211 creates a new and distinguished ctype every time you use it for
212 <tt>ffi.new()</tt>. This is probably <b>not</b> what you want,
213 especially if you create more than one cdata object. Different anonymous
214 <tt>structs</tt> are not considered assignment-compatible by the
215 C&nbsp;standard, even though they may have the same fields! Also, they
216 are considered different types by the JIT-compiler, which may cause an
217 excessive number of traces. It's strongly suggested to either declare
218 a named <tt>struct</tt> or <tt>typedef</tt> with <tt>ffi.cdef()</tt>
219 or to create a single ctype object for an anonymous <tt>struct</tt>
220 with <tt>ffi.typeof()</tt>.
221 </p>
223 <h3 id="ffi_typeof"><tt>ctype = ffi.typeof(ct)</tt></h3>
225 Creates a ctype object for the given <tt>ct</tt>.
226 </p>
228 This function is especially useful to parse a cdecl only once and then
229 use the resulting ctype object as a <a href="#ffi_new">constructor</a>.
230 </p>
232 <h3 id="ffi_cast"><tt>cdata = ffi.cast(ct, init)</tt></h3>
234 Creates a scalar cdata object for the given <tt>ct</tt>. The cdata
235 object is initialized with <tt>init</tt> using the "cast" variant of
236 the <a href="ext_ffi_semantics.html#convert">C&nbsp;type conversion
237 rules</a>.
238 </p>
240 This functions is mainly useful to override the pointer compatibility
241 checks or to convert pointers to addresses or vice versa.
242 </p>
244 <h3 id="ffi_metatype"><tt>ctype = ffi.metatype(ct, metatable)</tt></h3>
246 Creates a ctype object for the given <tt>ct</tt> and associates it with
247 a metatable. Only <tt>struct</tt>/<tt>union</tt> types, complex numbers
248 and vectors are allowed. Other types may be wrapped in a
249 <tt>struct</tt>, if needed.
250 </p>
252 The association with a metatable is permanent and cannot be changed
253 afterwards. Neither the contents of the <tt>metatable</tt> nor the
254 contents of an <tt>__index</tt> table (if any) may be modified
255 afterwards. The associated metatable automatically applies to all uses
256 of this type, no matter how the objects are created or where they
257 originate from. Note that pre-defined operations on types have
258 precedence (e.g. declared field names cannot be overriden).
259 </p>
261 All standard Lua metamethods are implemented. These are called directly,
262 without shortcuts and on any mix of types. For binary operations, the
263 left operand is checked first for a valid ctype metamethod. The
264 <tt>__gc</tt> metamethod only applies to <tt>struct</tt>/<tt>union</tt>
265 types and performs an implicit <a href="#ffi_gc"><tt>ffi.gc()</tt></a>
266 call during creation of an instance.
267 </p>
269 <h3 id="ffi_gc"><tt>cdata = ffi.gc(cdata, finalizer)</tt></h3>
271 Associates a finalizer with a pointer or aggregate cdata object. The
272 cdata object is returned unchanged.
273 </p>
275 This function allows safe integration of unmanaged resources into the
276 automatic memory management of the LuaJIT garbage collector. Typical
277 usage:
278 </p>
279 <pre class="code">
280 local p = ffi.gc(ffi.C.malloc(n), ffi.C.free)
282 p = nil -- Last reference to p is gone.
283 -- GC will eventually run finalizer: ffi.C.free(p)
284 </pre>
286 A cdata finalizer works like the <tt>__gc</tt> metamethod for userdata
287 objects: when the last reference to a cdata object is gone, the
288 associated finalizer is called with the cdata object as an argument. The
289 finalizer can be a Lua function or a cdata function or cdata function
290 pointer. An existing finalizer can be removed by setting a <tt>nil</tt>
291 finalizer, e.g. right before explicitly deleting a resource:
292 </p>
293 <pre class="code">
294 ffi.C.free(ffi.gc(p, nil)) -- Manually free the memory.
295 </pre>
297 <h2 id="info">C&nbsp;Type Information</h2>
299 The following API functions return information about C&nbsp;types.
300 They are most useful for inspecting cdata objects.
301 </p>
303 <h3 id="ffi_sizeof"><tt>size = ffi.sizeof(ct [,nelem])</tt></h3>
305 Returns the size of <tt>ct</tt> in bytes. Returns <tt>nil</tt> if
306 the size is not known (e.g. for <tt>"void"</tt> or function types).
307 Requires <tt>nelem</tt> for VLA/VLS types, except for cdata objects.
308 </p>
310 <h3 id="ffi_alignof"><tt>align = ffi.alignof(ct)</tt></h3>
312 Returns the minimum required alignment for <tt>ct</tt> in bytes.
313 </p>
315 <h3 id="ffi_offsetof"><tt>ofs [,bpos,bsize] = ffi.offsetof(ct, field)</tt></h3>
317 Returns the offset (in bytes) of <tt>field</tt> relative to the start
318 of <tt>ct</tt>, which must be a <tt>struct</tt>. Additionally returns
319 the position and the field size (in bits) for bit fields.
320 </p>
322 <h3 id="ffi_istype"><tt>status = ffi.istype(ct, obj)</tt></h3>
324 Returns <tt>true</tt> if <tt>obj</tt> has the C&nbsp;type given by
325 <tt>ct</tt>. Returns <tt>false</tt> otherwise.
326 </p>
328 C&nbsp;type qualifiers (<tt>const</tt> etc.) are ignored. Pointers are
329 checked with the standard pointer compatibility rules, but without any
330 special treatment for <tt>void&nbsp;*</tt>. If <tt>ct</tt> specifies a
331 <tt>struct</tt>/<tt>union</tt>, then a pointer to this type is accepted,
332 too. Otherwise the types must match exactly.
333 </p>
335 Note: this function accepts all kinds of Lua objects for the
336 <tt>obj</tt> argument, but always returns <tt>false</tt> for non-cdata
337 objects.
338 </p>
340 <h2 id="util">Utility Functions</h2>
342 <h3 id="ffi_errno"><tt>err = ffi.errno([newerr])</tt></h3>
344 Returns the error number set by the last C&nbsp;function call which
345 indicated an error condition. If the optional <tt>newerr</tt> argument
346 is present, the error number is set to the new value and the previous
347 value is returned.
348 </p>
350 This function offers a portable and OS-independent way to get and set the
351 error number. Note that only <em>some</em> C&nbsp;functions set the error
352 number. And it's only significant if the function actually indicated an
353 error condition (e.g. with a return value of <tt>-1</tt> or
354 <tt>NULL</tt>). Otherwise, it may or may not contain any previously set
355 value.
356 </p>
358 You're advised to call this function only when needed and as close as
359 possible after the return of the related C&nbsp;function. The
360 <tt>errno</tt> value is preserved across hooks, memory allocations,
361 invocations of the JIT compiler and other internal VM activity. The same
362 applies to the value returned by <tt>GetLastError()</tt> on Windows, but
363 you need to declare and call it yourself.
364 </p>
366 <h3 id="ffi_string"><tt>str = ffi.string(ptr [,len])</tt></h3>
368 Creates an interned Lua string from the data pointed to by
369 <tt>ptr</tt>.
370 </p>
372 If the optional argument <tt>len</tt> is missing, <tt>ptr</tt> is
373 converted to a <tt>"char&nbsp;*"</tt> and the data is assumed to be
374 zero-terminated. The length of the string is computed with
375 <tt>strlen()</tt>.
376 </p>
378 Otherwise <tt>ptr</tt> is converted to a <tt>"void&nbsp;*"</tt> and
379 <tt>len</tt> gives the length of the data. The data may contain
380 embedded zeros and need not be byte-oriented (though this may cause
381 endianess issues).
382 </p>
384 This function is mainly useful to convert (temporary)
385 <tt>"const&nbsp;char&nbsp;*"</tt> pointers returned by
386 C&nbsp;functions to Lua strings and store them or pass them to other
387 functions expecting a Lua string. The Lua string is an (interned) copy
388 of the data and bears no relation to the original data area anymore.
389 Lua strings are 8&nbsp;bit clean and may be used to hold arbitrary,
390 non-character data.
391 </p>
393 Performance notice: it's faster to pass the length of the string, if
394 it's known. E.g. when the length is returned by a C&nbsp;call like
395 <tt>sprintf()</tt>.
396 </p>
398 <h3 id="ffi_copy"><tt>ffi.copy(dst, src, len)<br>
399 ffi.copy(dst, str)</tt></h3>
401 Copies the data pointed to by <tt>src</tt> to <tt>dst</tt>.
402 <tt>dst</tt> is converted to a <tt>"void&nbsp;*"</tt> and <tt>src</tt>
403 is converted to a <tt>"const void&nbsp;*"</tt>.
404 </p>
406 In the first syntax, <tt>len</tt> gives the number of bytes to copy.
407 Caveat: if <tt>src</tt> is a Lua string, then <tt>len</tt> must not
408 exceed <tt>#src+1</tt>.
409 </p>
411 In the second syntax, the source of the copy must be a Lua string. All
412 bytes of the string <em>plus a zero-terminator</em> are copied to
413 <tt>dst</tt> (i.e. <tt>#src+1</tt> bytes).
414 </p>
416 Performance notice: <tt>ffi.copy()</tt> may be used as a faster
417 (inlinable) replacement for the C&nbsp;library functions
418 <tt>memcpy()</tt>, <tt>strcpy()</tt> and <tt>strncpy()</tt>.
419 </p>
421 <h3 id="ffi_fill"><tt>ffi.fill(dst, len [,c])</tt></h3>
423 Fills the data pointed to by <tt>dst</tt> with <tt>len</tt> constant
424 bytes, given by <tt>c</tt>. If <tt>c</tt> is omitted, the data is
425 zero-filled.
426 </p>
428 Performance notice: <tt>ffi.fill()</tt> may be used as a faster
429 (inlinable) replacement for the C&nbsp;library function
430 <tt>memset(dst,&nbsp;c,&nbsp;len)</tt>. Please note the different
431 order of arguments!
432 </p>
434 <h2 id="target">Target-specific Information</h2>
436 <h3 id="ffi_abi"><tt>status = ffi.abi(param)</tt></h3>
438 Returns <tt>true</tt> if <tt>param</tt> (a Lua string) applies for the
439 target ABI (Application Binary Interface). Returns <tt>false</tt>
440 otherwise. The following parameters are currently defined:
441 </p>
442 <table class="abitable">
443 <tr class="abihead">
444 <td class="abiparam">Parameter</td>
445 <td class="abidesc">Description</td>
446 </tr>
447 <tr class="odd separate">
448 <td class="abiparam">32bit</td><td class="abidesc">32 bit architecture</td></tr>
449 <tr class="even">
450 <td class="abiparam">64bit</td><td class="abidesc">64 bit architecture</td></tr>
451 <tr class="odd separate">
452 <td class="abiparam">le</td><td class="abidesc">Little-endian architecture</td></tr>
453 <tr class="even">
454 <td class="abiparam">be</td><td class="abidesc">Big-endian architecture</td></tr>
455 <tr class="odd separate">
456 <td class="abiparam">fpu</td><td class="abidesc">Target has a hardware FPU</td></tr>
457 <tr class="even">
458 <td class="abiparam">softfp</td><td class="abidesc">softfp calling conventions</td></tr>
459 <tr class="odd">
460 <td class="abiparam">hardfp</td><td class="abidesc">hardfp calling conventions</td></tr>
461 <tr class="even separate">
462 <td class="abiparam">eabi</td><td class="abidesc">EABI variant of the standard ABI</td></tr>
463 <tr class="odd">
464 <td class="abiparam">win</td><td class="abidesc">Windows variant of the standard ABI</td></tr>
465 </table>
467 <h3 id="ffi_os"><tt>ffi.os</tt></h3>
469 Contains the target OS name. Same contents as
470 <a href="ext_jit.html#jit_os"><tt>jit.os</tt></a>.
471 </p>
473 <h3 id="ffi_arch"><tt>ffi.arch</tt></h3>
475 Contains the target architecture name. Same contents as
476 <a href="ext_jit.html#jit_arch"><tt>jit.arch</tt></a>.
477 </p>
479 <h2 id="callback">Methods for Callbacks</h2>
481 The C&nbsp;types for <a href="ext_ffi_semantics.html#callback">callbacks</a>
482 have some extra methods:
483 </p>
485 <h3 id="callback_free"><tt>cb:free()</tt></h3>
487 Free the resources associated with a callback. The associated Lua
488 function is unanchored and may be garbage collected. The callback
489 function pointer is no longer valid and must not be called anymore
490 (it may be reused by a subsequently created callback).
491 </p>
493 <h3 id="callback_set"><tt>cb:set(func)</tt></h3>
495 Associate a new Lua function with a callback. The C&nbsp;type of the
496 callback and the callback function pointer are unchanged.
497 </p>
499 This method is useful to dynamically switch the receiver of callbacks
500 without creating a new callback each time and registering it again (e.g.
501 with a GUI library).
502 </p>
504 <h2 id="extended">Extended Standard Library Functions</h2>
506 The following standard library functions have been extended to work
507 with cdata objects:
508 </p>
510 <h3 id="tonumber"><tt>n = tonumber(cdata)</tt></h3>
512 Converts a number cdata object to a <tt>double</tt> and returns it as
513 a Lua number. This is particularly useful for boxed 64&nbsp;bit
514 integer values. Caveat: this conversion may incur a precision loss.
515 </p>
517 <h3 id="tostring"><tt>s = tostring(cdata)</tt></h3>
519 Returns a string representation of the value of 64&nbsp;bit integers
520 (<tt><b>"</b>nnn<b>LL"</b></tt> or <tt><b>"</b>nnn<b>ULL"</b></tt>) or
521 complex numbers (<tt><b>"</b>re&plusmn;im<b>i"</b></tt>). Otherwise
522 returns a string representation of the C&nbsp;type of a ctype object
523 (<tt><b>"ctype&lt;</b>type<b>&gt;"</b></tt>) or a cdata object
524 (<tt><b>"cdata&lt;</b>type<b>&gt;:&nbsp;</b>address"</tt>).
525 </p>
527 <h2 id="literals">Extensions to the Lua Parser</h2>
529 The parser for Lua source code treats numeric literals with the
530 suffixes <tt>LL</tt> or <tt>ULL</tt> as signed or unsigned 64&nbsp;bit
531 integers. Case doesn't matter, but uppercase is recommended for
532 readability. It handles both decimal (<tt>42LL</tt>) and hexadecimal
533 (<tt>0x2aLL</tt>) literals.
534 </p>
536 The imaginary part of complex numbers can be specified by suffixing
537 number literals with <tt>i</tt> or <tt>I</tt>, e.g. <tt>12.5i</tt>.
538 Caveat: you'll need to use <tt>1i</tt> to get an imaginary part with
539 the value one, since <tt>i</tt> itself still refers to a variable
540 named <tt>i</tt>.
541 </p>
542 <br class="flush">
543 </div>
544 <div id="foot">
545 <hr class="hide">
546 Copyright &copy; 2005-2012 Mike Pall
547 <span class="noprint">
548 &middot;
549 <a href="contact.html">Contact</a>
550 </span>
551 </div>
552 </body>
553 </html>