diff options
| author | Mike Pall <mike> | 2021-03-25 02:21:31 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2021-03-25 02:21:31 +0100 |
| commit | 4c6b669c419f313306b9e6ee43be4ad5f6d73ec6 (patch) | |
| tree | 4547f52836e186e94b68b331ea73d6b0086cb415 | |
| parent | 836fb5bbd3a0d48cf3e4de70535925a85aea835f (diff) | |
| download | luajit-4c6b669c419f313306b9e6ee43be4ad5f6d73ec6.tar.gz luajit-4c6b669c419f313306b9e6ee43be4ad5f6d73ec6.tar.bz2 luajit-4c6b669c419f313306b9e6ee43be4ad5f6d73ec6.zip | |
String buffers, part 1: object serialization.
Sponsored by fmad.io.
| -rw-r--r-- | doc/contact.html | 2 | ||||
| -rw-r--r-- | doc/ext_buffer.html | 275 | ||||
| -rw-r--r-- | doc/ext_c_api.html | 2 | ||||
| -rw-r--r-- | doc/ext_ffi.html | 2 | ||||
| -rw-r--r-- | doc/ext_ffi_api.html | 2 | ||||
| -rw-r--r-- | doc/ext_ffi_semantics.html | 2 | ||||
| -rw-r--r-- | doc/ext_ffi_tutorial.html | 2 | ||||
| -rw-r--r-- | doc/ext_jit.html | 2 | ||||
| -rw-r--r-- | doc/ext_profiler.html | 2 | ||||
| -rw-r--r-- | doc/extensions.html | 2 | ||||
| -rw-r--r-- | doc/faq.html | 2 | ||||
| -rw-r--r-- | doc/install.html | 2 | ||||
| -rw-r--r-- | doc/luajit.html | 2 | ||||
| -rw-r--r-- | doc/running.html | 2 | ||||
| -rw-r--r-- | doc/status.html | 2 | ||||
| -rw-r--r-- | src/Makefile | 6 | ||||
| -rw-r--r-- | src/Makefile.dep | 36 | ||||
| -rw-r--r-- | src/lib_buffer.c | 66 | ||||
| -rw-r--r-- | src/lib_string.c | 3 | ||||
| -rw-r--r-- | src/lj_arch.h | 7 | ||||
| -rw-r--r-- | src/lj_buf.h | 9 | ||||
| -rw-r--r-- | src/lj_errmsg.h | 10 | ||||
| -rw-r--r-- | src/lj_serialize.c | 351 | ||||
| -rw-r--r-- | src/lj_serialize.h | 21 | ||||
| -rw-r--r-- | src/ljamalg.c | 2 | ||||
| -rw-r--r-- | src/lualib.h | 1 |
26 files changed, 797 insertions, 18 deletions
diff --git a/doc/contact.html b/doc/contact.html index b7980091..c253a08b 100644 --- a/doc/contact.html +++ b/doc/contact.html | |||
| @@ -37,6 +37,8 @@ | |||
| 37 | <a href="ext_ffi_semantics.html">FFI Semantics</a> | 37 | <a href="ext_ffi_semantics.html">FFI Semantics</a> |
| 38 | </li></ul> | 38 | </li></ul> |
| 39 | </li><li> | 39 | </li><li> |
| 40 | <a href="ext_buffer.html">String Buffers</a> | ||
| 41 | </li><li> | ||
| 40 | <a href="ext_jit.html">jit.* Library</a> | 42 | <a href="ext_jit.html">jit.* Library</a> |
| 41 | </li><li> | 43 | </li><li> |
| 42 | <a href="ext_c_api.html">Lua/C API</a> | 44 | <a href="ext_c_api.html">Lua/C API</a> |
diff --git a/doc/ext_buffer.html b/doc/ext_buffer.html new file mode 100644 index 00000000..455c298d --- /dev/null +++ b/doc/ext_buffer.html | |||
| @@ -0,0 +1,275 @@ | |||
| 1 | <!DOCTYPE html> | ||
| 2 | <html> | ||
| 3 | <head> | ||
| 4 | <title>String Buffers</title> | ||
| 5 | <meta charset="utf-8"> | ||
| 6 | <meta name="Copyright" content="Copyright (C) 2005-2021"> | ||
| 7 | <meta name="Language" content="en"> | ||
| 8 | <link rel="stylesheet" type="text/css" href="bluequad.css" media="screen"> | ||
| 9 | <link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print"> | ||
| 10 | </head> | ||
| 11 | <body> | ||
| 12 | <div id="site"> | ||
| 13 | <a href="https://luajit.org"><span>Lua<span id="logo">JIT</span></span></a> | ||
| 14 | </div> | ||
| 15 | <div id="head"> | ||
| 16 | <h1>String Buffers</h1> | ||
| 17 | </div> | ||
| 18 | <div id="nav"> | ||
| 19 | <ul><li> | ||
| 20 | <a href="luajit.html">LuaJIT</a> | ||
| 21 | <ul><li> | ||
| 22 | <a href="https://luajit.org/download.html">Download <span class="ext">»</span></a> | ||
| 23 | </li><li> | ||
| 24 | <a href="install.html">Installation</a> | ||
| 25 | </li><li> | ||
| 26 | <a href="running.html">Running</a> | ||
| 27 | </li></ul> | ||
| 28 | </li><li> | ||
| 29 | <a href="extensions.html">Extensions</a> | ||
| 30 | <ul><li> | ||
| 31 | <a href="ext_ffi.html">FFI Library</a> | ||
| 32 | <ul><li> | ||
| 33 | <a href="ext_ffi_tutorial.html">FFI Tutorial</a> | ||
| 34 | </li><li> | ||
| 35 | <a href="ext_ffi_api.html">ffi.* API</a> | ||
| 36 | </li><li> | ||
| 37 | <a href="ext_ffi_semantics.html">FFI Semantics</a> | ||
| 38 | </li></ul> | ||
| 39 | </li><li> | ||
| 40 | <a class="current" href="ext_buffer.html">String Buffers</a> | ||
| 41 | </li><li> | ||
| 42 | <a href="ext_jit.html">jit.* Library</a> | ||
| 43 | </li><li> | ||
| 44 | <a href="ext_c_api.html">Lua/C API</a> | ||
| 45 | </li><li> | ||
| 46 | <a href="ext_profiler.html">Profiler</a> | ||
| 47 | </li></ul> | ||
| 48 | </li><li> | ||
| 49 | <a href="status.html">Status</a> | ||
| 50 | </li><li> | ||
| 51 | <a href="faq.html">FAQ</a> | ||
| 52 | </li><li> | ||
| 53 | <a href="http://wiki.luajit.org/">Wiki <span class="ext">»</span></a> | ||
| 54 | </li><li> | ||
| 55 | <a href="https://luajit.org/list.html">Mailing List <span class="ext">»</span></a> | ||
| 56 | </li></ul> | ||
| 57 | </div> | ||
| 58 | <div id="main"> | ||
| 59 | <p> | ||
| 60 | |||
| 61 | The string buffer library allows <b>high-performance manipulation of | ||
| 62 | string-like data</b>. | ||
| 63 | |||
| 64 | </p> | ||
| 65 | <p> | ||
| 66 | |||
| 67 | Unlike Lua strings, which are constants, string buffers are | ||
| 68 | <b>mutable</b> sequences of 8-bit (binary-transparent) characters. Data | ||
| 69 | can be stored, formatted and encoded into a string buffer and later | ||
| 70 | converted, decoded or extracted. | ||
| 71 | |||
| 72 | </p> | ||
| 73 | <p> | ||
| 74 | |||
| 75 | The convenient string buffer API simplifies common string manipulation | ||
| 76 | tasks, that would otherwise require creating many intermediate strings. | ||
| 77 | String buffers improve performance by eliminating redundant memory | ||
| 78 | copies, object creation, string interning and garbage collection | ||
| 79 | overhead. In conjunction with the FFI library, they allow zero-copy | ||
| 80 | operations. | ||
| 81 | |||
| 82 | </p> | ||
| 83 | |||
| 84 | <h2 id="load">Using the String Buffer Library</h2> | ||
| 85 | <p> | ||
| 86 | The string buffer library is built into LuaJIT by default, but it's not | ||
| 87 | loaded by default. Add this to the start of every Lua file that needs | ||
| 88 | one of its functions: | ||
| 89 | </p> | ||
| 90 | <pre class="code"> | ||
| 91 | local buffer = require("string.buffer") | ||
| 92 | </pre> | ||
| 93 | |||
| 94 | <h2 id="wip" style="color:#ff0000">Work in Progress</h2> | ||
| 95 | |||
| 96 | <p> | ||
| 97 | |||
| 98 | <b style="color:#ff0000">This library is a work in progress. More | ||
| 99 | functions will be added soon.</b> | ||
| 100 | |||
| 101 | </p> | ||
| 102 | |||
| 103 | <h2 id="serialize">Serialization of Lua Objects</h2> | ||
| 104 | <p> | ||
| 105 | |||
| 106 | The following functions and methods allow <b>high-speed serialization</b> | ||
| 107 | (encoding) of a Lua object into a string and decoding it back to a Lua | ||
| 108 | object. This allows convenient storage and transport of <b>structured | ||
| 109 | data</b>. | ||
| 110 | |||
| 111 | </p> | ||
| 112 | <p> | ||
| 113 | |||
| 114 | The encoded data is in an <a href="#serialize_format">internal binary | ||
| 115 | format</a>. The data can be stored in files, binary-transparent | ||
| 116 | databases or transmitted to other LuaJIT instances across threads, | ||
| 117 | processes or networks. | ||
| 118 | |||
| 119 | </p> | ||
| 120 | <p> | ||
| 121 | |||
| 122 | Encoding speed can reach up to 1 Gigabyte/second on a modern desktop- or | ||
| 123 | server-class system, even when serializing many small objects. Decoding | ||
| 124 | speed is mostly constrained by object creation cost. | ||
| 125 | |||
| 126 | </p> | ||
| 127 | <p> | ||
| 128 | |||
| 129 | The serializer handles most Lua types, common FFI number types and | ||
| 130 | nested structures. Functions, thread objects, other FFI cdata, full | ||
| 131 | userdata and associated metatables cannot be serialized (yet). | ||
| 132 | |||
| 133 | </p> | ||
| 134 | <p> | ||
| 135 | |||
| 136 | The encoder serializes nested structures as trees. Multiple references | ||
| 137 | to a single object will be stored separately and create distinct objects | ||
| 138 | after decoding. Circular references cause an error. | ||
| 139 | |||
| 140 | |||
| 141 | </p> | ||
| 142 | |||
| 143 | <h3 id="buffer_encode"><tt>str = buffer.encode(obj)</tt></h3> | ||
| 144 | <p> | ||
| 145 | |||
| 146 | Serializes (encodes) the Lua object <tt>obj</tt> into the string | ||
| 147 | <tt>str</tt>. | ||
| 148 | |||
| 149 | </p> | ||
| 150 | <p> | ||
| 151 | |||
| 152 | <tt>obj</tt> can be any of the supported Lua types — it doesn't | ||
| 153 | need to be a Lua table. | ||
| 154 | |||
| 155 | </p> | ||
| 156 | <p> | ||
| 157 | |||
| 158 | This function may throw an error when attempting to serialize | ||
| 159 | unsupported object types, circular references or deeply nested tables. | ||
| 160 | |||
| 161 | </p> | ||
| 162 | |||
| 163 | <h3 id="buffer_decode"><tt>obj = buffer.decode(str)</tt></h3> | ||
| 164 | <p> | ||
| 165 | |||
| 166 | De-serializes (decodes) the string <tt>str</tt> into the Lua object | ||
| 167 | <tt>obj</tt>. | ||
| 168 | |||
| 169 | </p> | ||
| 170 | <p> | ||
| 171 | |||
| 172 | The returned object may be any of the supported Lua types — | ||
| 173 | even <tt>nil</tt>. | ||
| 174 | |||
| 175 | </p> | ||
| 176 | <p> | ||
| 177 | |||
| 178 | This function may throw an error when fed with malformed or incomplete | ||
| 179 | encoded data. The standalone function throws when there's left-over data | ||
| 180 | after decoding a single top-level object. | ||
| 181 | |||
| 182 | </p> | ||
| 183 | |||
| 184 | <h2 id="serialize_format">Serialization Format Specification</h2> | ||
| 185 | <p> | ||
| 186 | |||
| 187 | This serialization format is designed for <b>internal use</b> by LuaJIT | ||
| 188 | applications. Serialized data is upwards-compatible and portable across | ||
| 189 | all supported LuaJIT platforms. | ||
| 190 | |||
| 191 | </p> | ||
| 192 | <p> | ||
| 193 | |||
| 194 | It's an <b>8-bit binary format</b> and not human-readable. It uses e.g. | ||
| 195 | embedded zeroes and stores embedded Lua string objects unmodified, which | ||
| 196 | are 8-bit-clean, too. Encoded data can be safely concatenated for | ||
| 197 | streaming and later decoded one top-level object at a time. | ||
| 198 | |||
| 199 | </p> | ||
| 200 | <p> | ||
| 201 | |||
| 202 | The encoding is reasonably compact, but tuned for maximum performance, | ||
| 203 | not for minimum space usage. It compresses well with any of the common | ||
| 204 | byte-oriented data compression algorithms. | ||
| 205 | |||
| 206 | </p> | ||
| 207 | <p> | ||
| 208 | |||
| 209 | Although documented here for reference, this format is explicitly | ||
| 210 | <b>not</b> intended to be a 'public standard' for structured data | ||
| 211 | interchange across computer languages (like JSON or MessagePack). Please | ||
| 212 | do not use it as such. | ||
| 213 | |||
| 214 | </p> | ||
| 215 | <p> | ||
| 216 | |||
| 217 | The specification is given below as a context-free grammar with a | ||
| 218 | top-level <tt>object</tt> as the starting point. Alternatives are | ||
| 219 | separated by the <tt>|</tt> symbol and <tt>*</tt> indicates repeats. | ||
| 220 | Grouping is implicit or indicated by <tt>{…}</tt>. Terminals are | ||
| 221 | either plain hex numbers, encoded as bytes, or have a <tt>.format</tt> | ||
| 222 | suffix. | ||
| 223 | |||
| 224 | </p> | ||
| 225 | <pre> | ||
| 226 | object → nil | false | true | ||
| 227 | | null | lightud32 | lightud64 | ||
| 228 | | int | num | tab | ||
| 229 | | int64 | uint64 | complex | ||
| 230 | | string | ||
| 231 | |||
| 232 | nil → 0x00 | ||
| 233 | false → 0x01 | ||
| 234 | true → 0x02 | ||
| 235 | |||
| 236 | null → 0x03 // NULL lightuserdata | ||
| 237 | lightud32 → 0x04 data.I // 32 bit lightuserdata | ||
| 238 | lightud64 → 0x05 data.L // 64 bit lightuserdata | ||
| 239 | |||
| 240 | int → 0x06 int.I // int32_t | ||
| 241 | num → 0x07 double.L | ||
| 242 | |||
| 243 | tab → 0x08 // Empty table | ||
| 244 | | 0x09 h.U h*{object object} // Key/value hash | ||
| 245 | | 0x0a a.U a*object // 0-based array | ||
| 246 | | 0x0b a.U a*object h.U h*{object object} // Mixed | ||
| 247 | | 0x0c a.U (a-1)*object // 1-based array | ||
| 248 | | 0x0d a.U (a-1)*object h.U h*{object object} // Mixed | ||
| 249 | |||
| 250 | int64 → 0x10 int.L // FFI int64_t | ||
| 251 | uint64 → 0x11 uint.L // FFI uint64_t | ||
| 252 | complex → 0x12 re.L im.L // FFI complex | ||
| 253 | |||
| 254 | string → (0x20+len).U len*char.B | ||
| 255 | |||
| 256 | .B = 8 bit | ||
| 257 | .I = 32 bit little-endian | ||
| 258 | .L = 64 bit little-endian | ||
| 259 | .U = prefix-encoded 32 bit unsigned number n: | ||
| 260 | 0x00..0xdf → n.B | ||
| 261 | 0xe0..0x1fdf → (0xe0|(((n-0xe0)>>8)&0x1f)).B ((n-0xe0)&0xff).B | ||
| 262 | 0x1fe0.. → 0xff n.I | ||
| 263 | </pre> | ||
| 264 | <br class="flush"> | ||
| 265 | </div> | ||
| 266 | <div id="foot"> | ||
| 267 | <hr class="hide"> | ||
| 268 | Copyright © 2005-2021 | ||
| 269 | <span class="noprint"> | ||
| 270 | · | ||
| 271 | <a href="contact.html">Contact</a> | ||
| 272 | </span> | ||
| 273 | </div> | ||
| 274 | </body> | ||
| 275 | </html> | ||
diff --git a/doc/ext_c_api.html b/doc/ext_c_api.html index 6079e5ac..9f1ad212 100644 --- a/doc/ext_c_api.html +++ b/doc/ext_c_api.html | |||
| @@ -37,6 +37,8 @@ | |||
| 37 | <a href="ext_ffi_semantics.html">FFI Semantics</a> | 37 | <a href="ext_ffi_semantics.html">FFI Semantics</a> |
| 38 | </li></ul> | 38 | </li></ul> |
| 39 | </li><li> | 39 | </li><li> |
| 40 | <a href="ext_buffer.html">String Buffers</a> | ||
| 41 | </li><li> | ||
| 40 | <a href="ext_jit.html">jit.* Library</a> | 42 | <a href="ext_jit.html">jit.* Library</a> |
| 41 | </li><li> | 43 | </li><li> |
| 42 | <a class="current" href="ext_c_api.html">Lua/C API</a> | 44 | <a class="current" href="ext_c_api.html">Lua/C API</a> |
diff --git a/doc/ext_ffi.html b/doc/ext_ffi.html index 13b75bda..b934dc78 100644 --- a/doc/ext_ffi.html +++ b/doc/ext_ffi.html | |||
| @@ -37,6 +37,8 @@ | |||
| 37 | <a href="ext_ffi_semantics.html">FFI Semantics</a> | 37 | <a href="ext_ffi_semantics.html">FFI Semantics</a> |
| 38 | </li></ul> | 38 | </li></ul> |
| 39 | </li><li> | 39 | </li><li> |
| 40 | <a href="ext_buffer.html">String Buffers</a> | ||
| 41 | </li><li> | ||
| 40 | <a href="ext_jit.html">jit.* Library</a> | 42 | <a href="ext_jit.html">jit.* Library</a> |
| 41 | </li><li> | 43 | </li><li> |
| 42 | <a href="ext_c_api.html">Lua/C API</a> | 44 | <a href="ext_c_api.html">Lua/C API</a> |
diff --git a/doc/ext_ffi_api.html b/doc/ext_ffi_api.html index b7ace808..061cc42a 100644 --- a/doc/ext_ffi_api.html +++ b/doc/ext_ffi_api.html | |||
| @@ -42,6 +42,8 @@ td.abiparam { font-weight: bold; width: 6em; } | |||
| 42 | <a href="ext_ffi_semantics.html">FFI Semantics</a> | 42 | <a href="ext_ffi_semantics.html">FFI Semantics</a> |
| 43 | </li></ul> | 43 | </li></ul> |
| 44 | </li><li> | 44 | </li><li> |
| 45 | <a href="ext_buffer.html">String Buffers</a> | ||
| 46 | </li><li> | ||
| 45 | <a href="ext_jit.html">jit.* Library</a> | 47 | <a href="ext_jit.html">jit.* Library</a> |
| 46 | </li><li> | 48 | </li><li> |
| 47 | <a href="ext_c_api.html">Lua/C API</a> | 49 | <a href="ext_c_api.html">Lua/C API</a> |
diff --git a/doc/ext_ffi_semantics.html b/doc/ext_ffi_semantics.html index 904ee51d..fef39c32 100644 --- a/doc/ext_ffi_semantics.html +++ b/doc/ext_ffi_semantics.html | |||
| @@ -42,6 +42,8 @@ td.convop { font-style: italic; width: 40%; } | |||
| 42 | <a class="current" href="ext_ffi_semantics.html">FFI Semantics</a> | 42 | <a class="current" href="ext_ffi_semantics.html">FFI Semantics</a> |
| 43 | </li></ul> | 43 | </li></ul> |
| 44 | </li><li> | 44 | </li><li> |
| 45 | <a href="ext_buffer.html">String Buffers</a> | ||
| 46 | </li><li> | ||
| 45 | <a href="ext_jit.html">jit.* Library</a> | 47 | <a href="ext_jit.html">jit.* Library</a> |
| 46 | </li><li> | 48 | </li><li> |
| 47 | <a href="ext_c_api.html">Lua/C API</a> | 49 | <a href="ext_c_api.html">Lua/C API</a> |
diff --git a/doc/ext_ffi_tutorial.html b/doc/ext_ffi_tutorial.html index 8ed61364..ca71be4d 100644 --- a/doc/ext_ffi_tutorial.html +++ b/doc/ext_ffi_tutorial.html | |||
| @@ -44,6 +44,8 @@ td.idiomlua b { font-weight: normal; color: #2142bf; } | |||
| 44 | <a href="ext_ffi_semantics.html">FFI Semantics</a> | 44 | <a href="ext_ffi_semantics.html">FFI Semantics</a> |
| 45 | </li></ul> | 45 | </li></ul> |
| 46 | </li><li> | 46 | </li><li> |
| 47 | <a href="ext_buffer.html">String Buffers</a> | ||
| 48 | </li><li> | ||
| 47 | <a href="ext_jit.html">jit.* Library</a> | 49 | <a href="ext_jit.html">jit.* Library</a> |
| 48 | </li><li> | 50 | </li><li> |
| 49 | <a href="ext_c_api.html">Lua/C API</a> | 51 | <a href="ext_c_api.html">Lua/C API</a> |
diff --git a/doc/ext_jit.html b/doc/ext_jit.html index 84302fa0..6dd54c70 100644 --- a/doc/ext_jit.html +++ b/doc/ext_jit.html | |||
| @@ -37,6 +37,8 @@ | |||
| 37 | <a href="ext_ffi_semantics.html">FFI Semantics</a> | 37 | <a href="ext_ffi_semantics.html">FFI Semantics</a> |
| 38 | </li></ul> | 38 | </li></ul> |
| 39 | </li><li> | 39 | </li><li> |
| 40 | <a href="ext_buffer.html">String Buffers</a> | ||
| 41 | </li><li> | ||
| 40 | <a class="current" href="ext_jit.html">jit.* Library</a> | 42 | <a class="current" href="ext_jit.html">jit.* Library</a> |
| 41 | </li><li> | 43 | </li><li> |
| 42 | <a href="ext_c_api.html">Lua/C API</a> | 44 | <a href="ext_c_api.html">Lua/C API</a> |
diff --git a/doc/ext_profiler.html b/doc/ext_profiler.html index 0e8d3691..2783abdb 100644 --- a/doc/ext_profiler.html +++ b/doc/ext_profiler.html | |||
| @@ -37,6 +37,8 @@ | |||
| 37 | <a href="ext_ffi_semantics.html">FFI Semantics</a> | 37 | <a href="ext_ffi_semantics.html">FFI Semantics</a> |
| 38 | </li></ul> | 38 | </li></ul> |
| 39 | </li><li> | 39 | </li><li> |
| 40 | <a href="ext_buffer.html">String Buffers</a> | ||
| 41 | </li><li> | ||
| 40 | <a href="ext_jit.html">jit.* Library</a> | 42 | <a href="ext_jit.html">jit.* Library</a> |
| 41 | </li><li> | 43 | </li><li> |
| 42 | <a href="ext_c_api.html">Lua/C API</a> | 44 | <a href="ext_c_api.html">Lua/C API</a> |
diff --git a/doc/extensions.html b/doc/extensions.html index 77cf444c..799679a3 100644 --- a/doc/extensions.html +++ b/doc/extensions.html | |||
| @@ -54,6 +54,8 @@ td.excinterop { | |||
| 54 | <a href="ext_ffi_semantics.html">FFI Semantics</a> | 54 | <a href="ext_ffi_semantics.html">FFI Semantics</a> |
| 55 | </li></ul> | 55 | </li></ul> |
| 56 | </li><li> | 56 | </li><li> |
| 57 | <a href="ext_buffer.html">String Buffers</a> | ||
| 58 | </li><li> | ||
| 57 | <a href="ext_jit.html">jit.* Library</a> | 59 | <a href="ext_jit.html">jit.* Library</a> |
| 58 | </li><li> | 60 | </li><li> |
| 59 | <a href="ext_c_api.html">Lua/C API</a> | 61 | <a href="ext_c_api.html">Lua/C API</a> |
diff --git a/doc/faq.html b/doc/faq.html index b71e6e7c..a5d744d2 100644 --- a/doc/faq.html +++ b/doc/faq.html | |||
| @@ -40,6 +40,8 @@ dd { margin-left: 1.5em; } | |||
| 40 | <a href="ext_ffi_semantics.html">FFI Semantics</a> | 40 | <a href="ext_ffi_semantics.html">FFI Semantics</a> |
| 41 | </li></ul> | 41 | </li></ul> |
| 42 | </li><li> | 42 | </li><li> |
| 43 | <a href="ext_buffer.html">String Buffers</a> | ||
| 44 | </li><li> | ||
| 43 | <a href="ext_jit.html">jit.* Library</a> | 45 | <a href="ext_jit.html">jit.* Library</a> |
| 44 | </li><li> | 46 | </li><li> |
| 45 | <a href="ext_c_api.html">Lua/C API</a> | 47 | <a href="ext_c_api.html">Lua/C API</a> |
diff --git a/doc/install.html b/doc/install.html index fab0b2ca..e4af9dde 100644 --- a/doc/install.html +++ b/doc/install.html | |||
| @@ -65,6 +65,8 @@ td.compatno { | |||
| 65 | <a href="ext_ffi_semantics.html">FFI Semantics</a> | 65 | <a href="ext_ffi_semantics.html">FFI Semantics</a> |
| 66 | </li></ul> | 66 | </li></ul> |
| 67 | </li><li> | 67 | </li><li> |
| 68 | <a href="ext_buffer.html">String Buffers</a> | ||
| 69 | </li><li> | ||
| 68 | <a href="ext_jit.html">jit.* Library</a> | 70 | <a href="ext_jit.html">jit.* Library</a> |
| 69 | </li><li> | 71 | </li><li> |
| 70 | <a href="ext_c_api.html">Lua/C API</a> | 72 | <a href="ext_c_api.html">Lua/C API</a> |
diff --git a/doc/luajit.html b/doc/luajit.html index 42c0ac83..a25267a6 100644 --- a/doc/luajit.html +++ b/doc/luajit.html | |||
| @@ -122,6 +122,8 @@ table.feature small { | |||
| 122 | <a href="ext_ffi_semantics.html">FFI Semantics</a> | 122 | <a href="ext_ffi_semantics.html">FFI Semantics</a> |
| 123 | </li></ul> | 123 | </li></ul> |
| 124 | </li><li> | 124 | </li><li> |
| 125 | <a href="ext_buffer.html">String Buffers</a> | ||
| 126 | </li><li> | ||
| 125 | <a href="ext_jit.html">jit.* Library</a> | 127 | <a href="ext_jit.html">jit.* Library</a> |
| 126 | </li><li> | 128 | </li><li> |
| 127 | <a href="ext_c_api.html">Lua/C API</a> | 129 | <a href="ext_c_api.html">Lua/C API</a> |
diff --git a/doc/running.html b/doc/running.html index ae4911d5..b55b8439 100644 --- a/doc/running.html +++ b/doc/running.html | |||
| @@ -59,6 +59,8 @@ td.param_default { | |||
| 59 | <a href="ext_ffi_semantics.html">FFI Semantics</a> | 59 | <a href="ext_ffi_semantics.html">FFI Semantics</a> |
| 60 | </li></ul> | 60 | </li></ul> |
| 61 | </li><li> | 61 | </li><li> |
| 62 | <a href="ext_buffer.html">String Buffers</a> | ||
| 63 | </li><li> | ||
| 62 | <a href="ext_jit.html">jit.* Library</a> | 64 | <a href="ext_jit.html">jit.* Library</a> |
| 63 | </li><li> | 65 | </li><li> |
| 64 | <a href="ext_c_api.html">Lua/C API</a> | 66 | <a href="ext_c_api.html">Lua/C API</a> |
diff --git a/doc/status.html b/doc/status.html index e1f024bf..1d3ba984 100644 --- a/doc/status.html +++ b/doc/status.html | |||
| @@ -40,6 +40,8 @@ ul li { padding-bottom: 0.3em; } | |||
| 40 | <a href="ext_ffi_semantics.html">FFI Semantics</a> | 40 | <a href="ext_ffi_semantics.html">FFI Semantics</a> |
| 41 | </li></ul> | 41 | </li></ul> |
| 42 | </li><li> | 42 | </li><li> |
| 43 | <a href="ext_buffer.html">String Buffers</a> | ||
| 44 | </li><li> | ||
| 43 | <a href="ext_jit.html">jit.* Library</a> | 45 | <a href="ext_jit.html">jit.* Library</a> |
| 44 | </li><li> | 46 | </li><li> |
| 45 | <a href="ext_c_api.html">Lua/C API</a> | 47 | <a href="ext_c_api.html">Lua/C API</a> |
diff --git a/src/Makefile b/src/Makefile index 6f17bafd..a6e25ba1 100644 --- a/src/Makefile +++ b/src/Makefile | |||
| @@ -482,13 +482,15 @@ LJVM_BOUT= $(LJVM_S) | |||
| 482 | LJVM_MODE= elfasm | 482 | LJVM_MODE= elfasm |
| 483 | 483 | ||
| 484 | LJLIB_O= lib_base.o lib_math.o lib_bit.o lib_string.o lib_table.o \ | 484 | LJLIB_O= lib_base.o lib_math.o lib_bit.o lib_string.o lib_table.o \ |
| 485 | lib_io.o lib_os.o lib_package.o lib_debug.o lib_jit.o lib_ffi.o | 485 | lib_io.o lib_os.o lib_package.o lib_debug.o lib_jit.o lib_ffi.o \ |
| 486 | lib_buffer.o | ||
| 486 | LJLIB_C= $(LJLIB_O:.o=.c) | 487 | LJLIB_C= $(LJLIB_O:.o=.c) |
| 487 | 488 | ||
| 488 | LJCORE_O= lj_assert.o lj_gc.o lj_err.o lj_char.o lj_bc.o lj_obj.o lj_buf.o \ | 489 | LJCORE_O= lj_assert.o lj_gc.o lj_err.o lj_char.o lj_bc.o lj_obj.o lj_buf.o \ |
| 489 | lj_str.o lj_tab.o lj_func.o lj_udata.o lj_meta.o lj_debug.o \ | 490 | lj_str.o lj_tab.o lj_func.o lj_udata.o lj_meta.o lj_debug.o \ |
| 490 | lj_prng.o lj_state.o lj_dispatch.o lj_vmevent.o lj_vmmath.o \ | 491 | lj_prng.o lj_state.o lj_dispatch.o lj_vmevent.o lj_vmmath.o \ |
| 491 | lj_strscan.o lj_strfmt.o lj_strfmt_num.o lj_api.o lj_profile.o \ | 492 | lj_strscan.o lj_strfmt.o lj_strfmt_num.o lj_serialize.o \ |
| 493 | lj_api.o lj_profile.o \ | ||
| 492 | lj_lex.o lj_parse.o lj_bcread.o lj_bcwrite.o lj_load.o \ | 494 | lj_lex.o lj_parse.o lj_bcread.o lj_bcwrite.o lj_load.o \ |
| 493 | lj_ir.o lj_opt_mem.o lj_opt_fold.o lj_opt_narrow.o \ | 495 | lj_ir.o lj_opt_mem.o lj_opt_fold.o lj_opt_narrow.o \ |
| 494 | lj_opt_dce.o lj_opt_loop.o lj_opt_split.o lj_opt_sink.o \ | 496 | lj_opt_dce.o lj_opt_loop.o lj_opt_split.o lj_opt_sink.o \ |
diff --git a/src/Makefile.dep b/src/Makefile.dep index 3f26599e..315bf632 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep | |||
| @@ -10,6 +10,9 @@ lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ | |||
| 10 | lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_strscan.h \ | 10 | lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_strscan.h \ |
| 11 | lj_strfmt.h lj_ctype.h lj_cdata.h lj_cconv.h lj_carith.h lj_ff.h \ | 11 | lj_strfmt.h lj_ctype.h lj_cdata.h lj_cconv.h lj_carith.h lj_ff.h \ |
| 12 | lj_ffdef.h lj_lib.h lj_libdef.h | 12 | lj_ffdef.h lj_lib.h lj_libdef.h |
| 13 | lib_buffer.o: lib_buffer.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ | ||
| 14 | lj_def.h lj_arch.h lj_gc.h lj_buf.h lj_str.h lj_serialize.h lj_lib.h \ | ||
| 15 | lj_libdef.h | ||
| 13 | lib_debug.o: lib_debug.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ | 16 | lib_debug.o: lib_debug.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ |
| 14 | lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_lib.h \ | 17 | lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_lib.h \ |
| 15 | lj_libdef.h | 18 | lj_libdef.h |
| @@ -170,15 +173,18 @@ lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | |||
| 170 | lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_str.h lj_tab.h \ | 173 | lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_str.h lj_tab.h \ |
| 171 | lj_func.h lj_state.h lj_bc.h lj_ctype.h lj_strfmt.h lj_lex.h lj_parse.h \ | 174 | lj_func.h lj_state.h lj_bc.h lj_ctype.h lj_strfmt.h lj_lex.h lj_parse.h \ |
| 172 | lj_vm.h lj_vmevent.h | 175 | lj_vm.h lj_vmevent.h |
| 176 | lj_prng.o: lj_prng.c lj_def.h lua.h luaconf.h lj_arch.h lj_prng.h | ||
| 173 | lj_profile.o: lj_profile.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 177 | lj_profile.o: lj_profile.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 174 | lj_buf.h lj_gc.h lj_str.h lj_frame.h lj_bc.h lj_debug.h lj_dispatch.h \ | 178 | lj_buf.h lj_gc.h lj_str.h lj_frame.h lj_bc.h lj_debug.h lj_dispatch.h \ |
| 175 | lj_jit.h lj_ir.h lj_trace.h lj_traceerr.h lj_profile.h luajit.h | 179 | lj_jit.h lj_ir.h lj_trace.h lj_traceerr.h lj_profile.h luajit.h |
| 176 | lj_prng.o: lj_prng.c lj_def.h lua.h luaconf.h lj_arch.h lj_prng.h | ||
| 177 | lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 180 | lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 178 | lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \ | 181 | lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \ |
| 179 | lj_ctype.h lj_gc.h lj_ff.h lj_ffdef.h lj_debug.h lj_ir.h lj_jit.h \ | 182 | lj_ctype.h lj_gc.h lj_ff.h lj_ffdef.h lj_debug.h lj_ir.h lj_jit.h \ |
| 180 | lj_ircall.h lj_iropt.h lj_trace.h lj_dispatch.h lj_traceerr.h \ | 183 | lj_ircall.h lj_iropt.h lj_trace.h lj_dispatch.h lj_traceerr.h \ |
| 181 | lj_record.h lj_ffrecord.h lj_snap.h lj_vm.h lj_prng.h | 184 | lj_record.h lj_ffrecord.h lj_snap.h lj_vm.h lj_prng.h |
| 185 | lj_serialize.o: lj_serialize.c lj_obj.h lua.h luaconf.h lj_def.h \ | ||
| 186 | lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_tab.h \ | ||
| 187 | lj_udata.h lj_ctype.h lj_cdata.h lj_serialize.h | ||
| 182 | lj_snap.o: lj_snap.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ | 188 | lj_snap.o: lj_snap.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ |
| 183 | lj_tab.h lj_state.h lj_frame.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h \ | 189 | lj_tab.h lj_state.h lj_frame.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h \ |
| 184 | lj_trace.h lj_dispatch.h lj_traceerr.h lj_snap.h lj_target.h \ | 190 | lj_trace.h lj_dispatch.h lj_traceerr.h lj_snap.h lj_target.h \ |
| @@ -189,7 +195,7 @@ lj_state.o: lj_state.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | |||
| 189 | lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h lj_prng.h lj_lex.h \ | 195 | lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h lj_prng.h lj_lex.h \ |
| 190 | lj_alloc.h luajit.h | 196 | lj_alloc.h luajit.h |
| 191 | lj_str.o: lj_str.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ | 197 | lj_str.o: lj_str.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ |
| 192 | lj_err.h lj_errmsg.h lj_str.h lj_char.h | 198 | lj_err.h lj_errmsg.h lj_str.h lj_char.h lj_prng.h |
| 193 | lj_strfmt.o: lj_strfmt.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 199 | lj_strfmt.o: lj_strfmt.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 194 | lj_buf.h lj_gc.h lj_str.h lj_state.h lj_char.h lj_strfmt.h | 200 | lj_buf.h lj_gc.h lj_str.h lj_state.h lj_char.h lj_strfmt.h |
| 195 | lj_strfmt_num.o: lj_strfmt_num.c lj_obj.h lua.h luaconf.h lj_def.h \ | 201 | lj_strfmt_num.o: lj_strfmt_num.c lj_obj.h lua.h luaconf.h lj_def.h \ |
| @@ -204,7 +210,7 @@ lj_trace.o: lj_trace.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | |||
| 204 | lj_dispatch.h lj_traceerr.h lj_snap.h lj_gdbjit.h lj_record.h lj_asm.h \ | 210 | lj_dispatch.h lj_traceerr.h lj_snap.h lj_gdbjit.h lj_record.h lj_asm.h \ |
| 205 | lj_vm.h lj_vmevent.h lj_target.h lj_target_*.h lj_prng.h | 211 | lj_vm.h lj_vmevent.h lj_target.h lj_target_*.h lj_prng.h |
| 206 | lj_udata.o: lj_udata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 212 | lj_udata.o: lj_udata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 207 | lj_gc.h lj_udata.h | 213 | lj_gc.h lj_err.h lj_errmsg.h lj_udata.h |
| 208 | lj_vmevent.o: lj_vmevent.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 214 | lj_vmevent.o: lj_vmevent.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 209 | lj_str.h lj_tab.h lj_state.h lj_dispatch.h lj_bc.h lj_jit.h lj_ir.h \ | 215 | lj_str.h lj_tab.h lj_state.h lj_dispatch.h lj_bc.h lj_jit.h lj_ir.h \ |
| 210 | lj_vm.h lj_vmevent.h | 216 | lj_vm.h lj_vmevent.h |
| @@ -216,23 +222,23 @@ ljamalg.o: ljamalg.c lua.h luaconf.h lauxlib.h lj_assert.c lj_obj.h \ | |||
| 216 | lj_bc.h lj_ctype.h lj_cdata.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \ | 222 | lj_bc.h lj_ctype.h lj_cdata.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \ |
| 217 | lj_traceerr.h lj_vm.h lj_err.c lj_debug.h lj_ff.h lj_ffdef.h lj_strfmt.h \ | 223 | lj_traceerr.h lj_vm.h lj_err.c lj_debug.h lj_ff.h lj_ffdef.h lj_strfmt.h \ |
| 218 | lj_char.c lj_char.h lj_bc.c lj_bcdef.h lj_obj.c lj_buf.c lj_str.c \ | 224 | lj_char.c lj_char.h lj_bc.c lj_bcdef.h lj_obj.c lj_buf.c lj_str.c \ |
| 219 | lj_tab.c lj_func.c lj_udata.c lj_meta.c lj_strscan.h lj_lib.h lj_debug.c \ | 225 | lj_prng.h lj_tab.c lj_func.c lj_udata.c lj_meta.c lj_strscan.h lj_lib.h \ |
| 220 | lj_prng.c lj_prng.h lj_state.c lj_lex.h lj_alloc.h luajit.h \ | 226 | lj_debug.c lj_prng.c lj_state.c lj_lex.h lj_alloc.h luajit.h \ |
| 221 | lj_dispatch.c lj_ccallback.h lj_profile.h lj_vmevent.c lj_vmevent.h \ | 227 | lj_dispatch.c lj_ccallback.h lj_profile.h lj_vmevent.c lj_vmevent.h \ |
| 222 | lj_vmmath.c lj_strscan.c lj_strfmt.c lj_strfmt_num.c lj_api.c \ | 228 | lj_vmmath.c lj_strscan.c lj_strfmt.c lj_strfmt_num.c lj_serialize.c \ |
| 223 | lj_profile.c lj_lex.c lualib.h lj_parse.h lj_parse.c lj_bcread.c \ | 229 | lj_serialize.h lj_api.c lj_profile.c lj_lex.c lualib.h lj_parse.h \ |
| 224 | lj_bcdump.h lj_bcwrite.c lj_load.c lj_ctype.c lj_cdata.c lj_cconv.h \ | 230 | lj_parse.c lj_bcread.c lj_bcdump.h lj_bcwrite.c lj_load.c lj_ctype.c \ |
| 225 | lj_cconv.c lj_ccall.c lj_ccall.h lj_ccallback.c lj_target.h \ | 231 | lj_cdata.c lj_cconv.h lj_cconv.c lj_ccall.c lj_ccall.h lj_ccallback.c \ |
| 226 | lj_target_*.h lj_mcode.h lj_carith.c lj_carith.h lj_clib.c lj_clib.h \ | 232 | lj_target.h lj_target_*.h lj_mcode.h lj_carith.c lj_carith.h lj_clib.c \ |
| 227 | lj_cparse.c lj_cparse.h lj_lib.c lj_ir.c lj_ircall.h lj_iropt.h \ | 233 | lj_clib.h lj_cparse.c lj_cparse.h lj_lib.c lj_ir.c lj_ircall.h \ |
| 228 | lj_opt_mem.c lj_opt_fold.c lj_folddef.h lj_opt_narrow.c lj_opt_dce.c \ | 234 | lj_iropt.h lj_opt_mem.c lj_opt_fold.c lj_folddef.h lj_opt_narrow.c \ |
| 229 | lj_opt_loop.c lj_snap.h lj_opt_split.c lj_opt_sink.c lj_mcode.c \ | 235 | lj_opt_dce.c lj_opt_loop.c lj_snap.h lj_opt_split.c lj_opt_sink.c \ |
| 230 | lj_snap.c lj_record.c lj_record.h lj_ffrecord.h lj_crecord.c \ | 236 | lj_mcode.c lj_snap.c lj_record.c lj_record.h lj_ffrecord.h lj_crecord.c \ |
| 231 | lj_crecord.h lj_ffrecord.c lj_recdef.h lj_asm.c lj_asm.h lj_emit_*.h \ | 237 | lj_crecord.h lj_ffrecord.c lj_recdef.h lj_asm.c lj_asm.h lj_emit_*.h \ |
| 232 | lj_asm_*.h lj_trace.c lj_gdbjit.h lj_gdbjit.c lj_alloc.c lib_aux.c \ | 238 | lj_asm_*.h lj_trace.c lj_gdbjit.h lj_gdbjit.c lj_alloc.c lib_aux.c \ |
| 233 | lib_base.c lj_libdef.h lib_math.c lib_string.c lib_table.c lib_io.c \ | 239 | lib_base.c lj_libdef.h lib_math.c lib_string.c lib_table.c lib_io.c \ |
| 234 | lib_os.c lib_package.c lib_debug.c lib_bit.c lib_jit.c lib_ffi.c \ | 240 | lib_os.c lib_package.c lib_debug.c lib_bit.c lib_jit.c lib_ffi.c \ |
| 235 | lib_init.c | 241 | lib_buffer.c lib_init.c |
| 236 | luajit.o: luajit.c lua.h luaconf.h lauxlib.h lualib.h luajit.h lj_arch.h | 242 | luajit.o: luajit.c lua.h luaconf.h lauxlib.h lualib.h luajit.h lj_arch.h |
| 237 | host/buildvm.o: host/buildvm.c host/buildvm.h lj_def.h lua.h luaconf.h \ | 243 | host/buildvm.o: host/buildvm.c host/buildvm.h lj_def.h lua.h luaconf.h \ |
| 238 | lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_gc.h lj_obj.h lj_bc.h lj_ir.h \ | 244 | lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_gc.h lj_obj.h lj_bc.h lj_ir.h \ |
diff --git a/src/lib_buffer.c b/src/lib_buffer.c new file mode 100644 index 00000000..e4555596 --- /dev/null +++ b/src/lib_buffer.c | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | /* | ||
| 2 | ** Buffer library. | ||
| 3 | ** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h | ||
| 4 | */ | ||
| 5 | |||
| 6 | #define lib_buffer_c | ||
| 7 | #define LUA_LIB | ||
| 8 | |||
| 9 | #include "lua.h" | ||
| 10 | #include "lauxlib.h" | ||
| 11 | #include "lualib.h" | ||
| 12 | |||
| 13 | #include "lj_obj.h" | ||
| 14 | |||
| 15 | #if LJ_HASBUFFER | ||
| 16 | #include "lj_gc.h" | ||
| 17 | #include "lj_buf.h" | ||
| 18 | #include "lj_serialize.h" | ||
| 19 | #include "lj_lib.h" | ||
| 20 | |||
| 21 | /* ------------------------------------------------------------------------ */ | ||
| 22 | |||
| 23 | #define LJLIB_MODULE_buffer | ||
| 24 | |||
| 25 | /* Note: this uses interim structs until the SBuf reorg. */ | ||
| 26 | |||
| 27 | LJLIB_CF(buffer_encode) | ||
| 28 | { | ||
| 29 | cTValue *o = lj_lib_checkany(L, 1); | ||
| 30 | StrBuf sbuf; | ||
| 31 | sbuf.sb = lj_buf_tmp_(L); | ||
| 32 | lj_serialize_put(&sbuf, o); | ||
| 33 | setstrV(L, L->top++, lj_buf_str(L, sbuf.sb)); | ||
| 34 | lj_gc_check(L); | ||
| 35 | return 1; | ||
| 36 | } | ||
| 37 | |||
| 38 | LJLIB_CF(buffer_decode) | ||
| 39 | { | ||
| 40 | GCstr *str = lj_lib_checkstr(L, 1); | ||
| 41 | const char *p = strdata(str); | ||
| 42 | SBuf sb; | ||
| 43 | StrBuf sbuf; | ||
| 44 | setsbufL(&sb, L); | ||
| 45 | setmref(sb.b, p); | ||
| 46 | setmref(sb.p, p + str->len); | ||
| 47 | setmref(sb.e, p + str->len); | ||
| 48 | sbuf.sb = &sb; | ||
| 49 | sbuf.r = (char *)p; | ||
| 50 | setnilV(L->top++); | ||
| 51 | lj_serialize_get(&sbuf, L->top-1); | ||
| 52 | lj_gc_check(L); | ||
| 53 | return 1; | ||
| 54 | } | ||
| 55 | |||
| 56 | /* ------------------------------------------------------------------------ */ | ||
| 57 | |||
| 58 | #include "lj_libdef.h" | ||
| 59 | |||
| 60 | int luaopen_string_buffer(lua_State *L) | ||
| 61 | { | ||
| 62 | LJ_LIB_REG(L, NULL, buffer); | ||
| 63 | return 1; | ||
| 64 | } | ||
| 65 | |||
| 66 | #endif | ||
diff --git a/src/lib_string.c b/src/lib_string.c index 51d1c4b0..4a3ff372 100644 --- a/src/lib_string.c +++ b/src/lib_string.c | |||
| @@ -743,6 +743,9 @@ LUALIB_API int luaopen_string(lua_State *L) | |||
| 743 | setgcref(basemt_it(g, LJ_TSTR), obj2gco(mt)); | 743 | setgcref(basemt_it(g, LJ_TSTR), obj2gco(mt)); |
| 744 | settabV(L, lj_tab_setstr(L, mt, mmname_str(g, MM_index)), tabV(L->top-1)); | 744 | settabV(L, lj_tab_setstr(L, mt, mmname_str(g, MM_index)), tabV(L->top-1)); |
| 745 | mt->nomm = (uint8_t)(~(1u<<MM_index)); | 745 | mt->nomm = (uint8_t)(~(1u<<MM_index)); |
| 746 | #if LJ_HASBUFFER | ||
| 747 | lj_lib_prereg(L, LUA_STRLIBNAME ".buffer", luaopen_string_buffer, tabV(L->top-1)); | ||
| 748 | #endif | ||
| 746 | return 1; | 749 | return 1; |
| 747 | } | 750 | } |
| 748 | 751 | ||
diff --git a/src/lj_arch.h b/src/lj_arch.h index 0a6e1b9f..ae999467 100644 --- a/src/lj_arch.h +++ b/src/lj_arch.h | |||
| @@ -549,6 +549,13 @@ | |||
| 549 | #define LJ_HASFFI 1 | 549 | #define LJ_HASFFI 1 |
| 550 | #endif | 550 | #endif |
| 551 | 551 | ||
| 552 | /* Disable or enable the string buffer extension. */ | ||
| 553 | #if defined(LUAJIT_DISABLE_BUFFER) | ||
| 554 | #define LJ_HASBUFFER 0 | ||
| 555 | #else | ||
| 556 | #define LJ_HASBUFFER 1 | ||
| 557 | #endif | ||
| 558 | |||
| 552 | #if defined(LUAJIT_DISABLE_PROFILE) | 559 | #if defined(LUAJIT_DISABLE_PROFILE) |
| 553 | #define LJ_HASPROFILE 0 | 560 | #define LJ_HASPROFILE 0 |
| 554 | #elif LJ_TARGET_POSIX | 561 | #elif LJ_TARGET_POSIX |
diff --git a/src/lj_buf.h b/src/lj_buf.h index ae875298..a720f83b 100644 --- a/src/lj_buf.h +++ b/src/lj_buf.h | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | #include "lj_gc.h" | 10 | #include "lj_gc.h" |
| 11 | #include "lj_str.h" | 11 | #include "lj_str.h" |
| 12 | 12 | ||
| 13 | /* Resizable string buffers. Struct definition in lj_obj.h. */ | 13 | /* Resizable string buffers. SBuf struct definition in lj_obj.h. */ |
| 14 | #define sbufB(sb) (mref((sb)->b, char)) | 14 | #define sbufB(sb) (mref((sb)->b, char)) |
| 15 | #define sbufP(sb) (mref((sb)->p, char)) | 15 | #define sbufP(sb) (mref((sb)->p, char)) |
| 16 | #define sbufE(sb) (mref((sb)->e, char)) | 16 | #define sbufE(sb) (mref((sb)->e, char)) |
| @@ -100,4 +100,11 @@ static LJ_AINLINE GCstr *lj_buf_str(lua_State *L, SBuf *sb) | |||
| 100 | return lj_str_new(L, sbufB(sb), sbuflen(sb)); | 100 | return lj_str_new(L, sbufB(sb), sbuflen(sb)); |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | /* Interim user-accessible string buffer. */ | ||
| 104 | typedef struct StrBuf { | ||
| 105 | SBuf *sb; /* Pointer to system buffer. */ | ||
| 106 | char *r; /* String buffer read pointer. */ | ||
| 107 | int depth; /* Remaining recursion depth. */ | ||
| 108 | } StrBuf; | ||
| 109 | |||
| 103 | #endif | 110 | #endif |
diff --git a/src/lj_errmsg.h b/src/lj_errmsg.h index 9ff4553d..a6f638ce 100644 --- a/src/lj_errmsg.h +++ b/src/lj_errmsg.h | |||
| @@ -179,6 +179,16 @@ ERRDEF(FFI_NYIPACKBIT, "NYI: packed bit fields") | |||
| 179 | ERRDEF(FFI_NYICALL, "NYI: cannot call this C function (yet)") | 179 | ERRDEF(FFI_NYICALL, "NYI: cannot call this C function (yet)") |
| 180 | #endif | 180 | #endif |
| 181 | 181 | ||
| 182 | #if LJ_HASBUFFER | ||
| 183 | /* String buffer errors. */ | ||
| 184 | ERRDEF(BUFFER_BADENC, "cannot serialize " LUA_QS) | ||
| 185 | ERRDEF(BUFFER_BADDEC, "cannot deserialize tag 0x%02x") | ||
| 186 | ERRDEF(BUFFER_DEPTH, "too deep to serialize") | ||
| 187 | ERRDEF(BUFFER_DUPKEY, "duplicate table key") | ||
| 188 | ERRDEF(BUFFER_EOB, "unexpected end of buffer") | ||
| 189 | ERRDEF(BUFFER_LEFTOV, "left-over data in buffer") | ||
| 190 | #endif | ||
| 191 | |||
| 182 | #undef ERRDEF | 192 | #undef ERRDEF |
| 183 | 193 | ||
| 184 | /* Detecting unused error messages: | 194 | /* Detecting unused error messages: |
diff --git a/src/lj_serialize.c b/src/lj_serialize.c new file mode 100644 index 00000000..5d7b7721 --- /dev/null +++ b/src/lj_serialize.c | |||
| @@ -0,0 +1,351 @@ | |||
| 1 | /* | ||
| 2 | ** Object de/serialization. | ||
| 3 | ** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h | ||
| 4 | */ | ||
| 5 | |||
| 6 | #define lj_serialize_c | ||
| 7 | #define LUA_CORE | ||
| 8 | |||
| 9 | #include "lj_obj.h" | ||
| 10 | #include "lj_err.h" | ||
| 11 | #include "lj_buf.h" | ||
| 12 | #include "lj_str.h" | ||
| 13 | #include "lj_tab.h" | ||
| 14 | #include "lj_udata.h" | ||
| 15 | #if LJ_HASFFI | ||
| 16 | #include "lj_ctype.h" | ||
| 17 | #include "lj_cdata.h" | ||
| 18 | #endif | ||
| 19 | #include "lj_serialize.h" | ||
| 20 | |||
| 21 | /* Tags for internal serialization format. */ | ||
| 22 | enum { | ||
| 23 | SER_TAG_NIL, /* 0x00 */ | ||
| 24 | SER_TAG_FALSE, | ||
| 25 | SER_TAG_TRUE, | ||
| 26 | SER_TAG_NULL, | ||
| 27 | SER_TAG_LIGHTUD32, | ||
| 28 | SER_TAG_LIGHTUD64, | ||
| 29 | SER_TAG_INT, | ||
| 30 | SER_TAG_NUM, | ||
| 31 | SER_TAG_TAB, /* 0x08 */ | ||
| 32 | SER_TAG_0x0e = SER_TAG_TAB+6, | ||
| 33 | SER_TAG_0x0f, | ||
| 34 | SER_TAG_INT64, /* 0x10 */ | ||
| 35 | SER_TAG_UINT64, | ||
| 36 | SER_TAG_COMPLEX, | ||
| 37 | SER_TAG_0x13, | ||
| 38 | SER_TAG_0x14, | ||
| 39 | SER_TAG_0x15, | ||
| 40 | SER_TAG_0x16, | ||
| 41 | SER_TAG_0x17, | ||
| 42 | SER_TAG_0x18, /* 0x18 */ | ||
| 43 | SER_TAG_0x19, | ||
| 44 | SER_TAG_0x1a, | ||
| 45 | SER_TAG_0x1b, | ||
| 46 | SER_TAG_0x1c, | ||
| 47 | SER_TAG_0x1d, | ||
| 48 | SER_TAG_0x1e, | ||
| 49 | SER_TAG_0x1f, | ||
| 50 | SER_TAG_STR, /* 0x20 + str->len */ | ||
| 51 | }; | ||
| 52 | LJ_STATIC_ASSERT((SER_TAG_TAB & 7) == 0); | ||
| 53 | |||
| 54 | /* -- Helper functions ---------------------------------------------------- */ | ||
| 55 | |||
| 56 | static LJ_AINLINE char *serialize_more(char *w, StrBuf *sbuf, MSize sz) | ||
| 57 | { | ||
| 58 | if (LJ_UNLIKELY(sz > (MSize)(sbufE(sbuf->sb) - w))) { | ||
| 59 | setsbufP(sbuf->sb, w); | ||
| 60 | w = lj_buf_more2(sbuf->sb, sz); | ||
| 61 | } | ||
| 62 | return w; | ||
| 63 | } | ||
| 64 | |||
| 65 | /* Write U124 to buffer. */ | ||
| 66 | static LJ_NOINLINE char *serialize_wu124_(char *w, uint32_t v) | ||
| 67 | { | ||
| 68 | if (v < 0x1fe0) { | ||
| 69 | v -= 0xe0; | ||
| 70 | *w++ = (char)(0xe0 | (v >> 8)); *w++ = (char)v; | ||
| 71 | } else { | ||
| 72 | *w++ = (char)0xff; | ||
| 73 | #if LJ_BE | ||
| 74 | v = lj_bswap(v); | ||
| 75 | #endif | ||
| 76 | memcpy(w, &v, 4); w += 4; | ||
| 77 | } | ||
| 78 | return w; | ||
| 79 | } | ||
| 80 | |||
| 81 | static LJ_AINLINE char *serialize_wu124(char *w, uint32_t v) | ||
| 82 | { | ||
| 83 | if (LJ_LIKELY(v < 0xe0)) { | ||
| 84 | *w++ = (char)v; | ||
| 85 | return w; | ||
| 86 | } else { | ||
| 87 | return serialize_wu124_(w, v); | ||
| 88 | } | ||
| 89 | } | ||
| 90 | |||
| 91 | static LJ_NOINLINE char *serialize_ru124_(char *r, char *e, uint32_t *pv) | ||
| 92 | { | ||
| 93 | uint32_t v = *pv; | ||
| 94 | if (v != 0xff) { | ||
| 95 | if (r >= e) return NULL; | ||
| 96 | v = ((v & 0x1f) << 8) + *(uint8_t *)r + 0xe0; r++; | ||
| 97 | } else { | ||
| 98 | if (r + 4 > e) return NULL; | ||
| 99 | v = lj_getu32(r); r += 4; | ||
| 100 | #if LJ_BE | ||
| 101 | v = lj_bswap(v); | ||
| 102 | #endif | ||
| 103 | } | ||
| 104 | *pv = v; | ||
| 105 | return r; | ||
| 106 | } | ||
| 107 | |||
| 108 | static LJ_AINLINE char *serialize_ru124(char *r, char *e, uint32_t *pv) | ||
| 109 | { | ||
| 110 | if (LJ_LIKELY(r < e)) { | ||
| 111 | uint32_t v = *(uint8_t *)r; r++; | ||
| 112 | *pv = v; | ||
| 113 | if (LJ_UNLIKELY(v >= 0xe0)) { | ||
| 114 | r = serialize_ru124_(r, e, pv); | ||
| 115 | } | ||
| 116 | return r; | ||
| 117 | } | ||
| 118 | return NULL; | ||
| 119 | } | ||
| 120 | |||
| 121 | /* -- Internal serializer ------------------------------------------------- */ | ||
| 122 | |||
| 123 | /* Put serialized object into buffer. */ | ||
| 124 | static char *serialize_put(char *w, StrBuf *sbuf, cTValue *o) | ||
| 125 | { | ||
| 126 | if (LJ_LIKELY(tvisstr(o))) { | ||
| 127 | const GCstr *str = strV(o); | ||
| 128 | MSize len = str->len; | ||
| 129 | w = serialize_more(w, sbuf, 5+len); | ||
| 130 | w = serialize_wu124(w, SER_TAG_STR + len); | ||
| 131 | w = lj_buf_wmem(w, strdata(str), len); | ||
| 132 | } else if (tvisint(o)) { | ||
| 133 | uint32_t x = LJ_BE ? lj_bswap((uint32_t)intV(o)) : (uint32_t)intV(o); | ||
| 134 | w = serialize_more(w, sbuf, 1+4); | ||
| 135 | *w++ = SER_TAG_INT; memcpy(w, &x, 4); w += 4; | ||
| 136 | } else if (tvisnum(o)) { | ||
| 137 | uint64_t x = LJ_BE ? lj_bswap64(o->u64) : o->u64; | ||
| 138 | w = serialize_more(w, sbuf, 1+sizeof(lua_Number)); | ||
| 139 | *w++ = SER_TAG_NUM; memcpy(w, &x, 8); w += 8; | ||
| 140 | } else if (tvispri(o)) { | ||
| 141 | w = serialize_more(w, sbuf, 1); | ||
| 142 | *w++ = (char)(SER_TAG_NIL + ~itype(o)); | ||
| 143 | } else if (tvistab(o)) { | ||
| 144 | const GCtab *t = tabV(o); | ||
| 145 | uint32_t narray = 0, nhash = 0, one = 2; | ||
| 146 | if (sbuf->depth <= 0) lj_err_caller(sbufL(sbuf->sb), LJ_ERR_BUFFER_DEPTH); | ||
| 147 | sbuf->depth--; | ||
| 148 | if (t->asize > 0) { /* Determine max. length of array part. */ | ||
| 149 | ptrdiff_t i; | ||
| 150 | TValue *array = tvref(t->array); | ||
| 151 | for (i = (ptrdiff_t)t->asize-1; i >= 0; i--) | ||
| 152 | if (!tvisnil(&array[i])) | ||
| 153 | break; | ||
| 154 | narray = (uint32_t)(i+1); | ||
| 155 | if (narray && tvisnil(&array[0])) one = 4; | ||
| 156 | } | ||
| 157 | if (t->hmask > 0) { /* Count number of used hash slots. */ | ||
| 158 | uint32_t i, hmask = t->hmask; | ||
| 159 | Node *node = noderef(t->node); | ||
| 160 | for (i = 0; i <= hmask; i++) | ||
| 161 | nhash += !tvisnil(&node[i].val); | ||
| 162 | } | ||
| 163 | /* Write number of array slots and hash slots. */ | ||
| 164 | w = serialize_more(w, sbuf, 1+2*5); | ||
| 165 | *w++ = (char)(SER_TAG_TAB + (nhash ? 1 : 0) + (narray ? one : 0)); | ||
| 166 | if (narray) w = serialize_wu124(w, narray); | ||
| 167 | if (nhash) w = serialize_wu124(w, nhash); | ||
| 168 | if (narray) { /* Write array entries. */ | ||
| 169 | cTValue *oa = tvref(t->array) + (one >> 2); | ||
| 170 | cTValue *oe = tvref(t->array) + narray; | ||
| 171 | while (oa < oe) w = serialize_put(w, sbuf, oa++); | ||
| 172 | } | ||
| 173 | if (nhash) { /* Write hash entries. */ | ||
| 174 | const Node *node = noderef(t->node) + t->hmask; | ||
| 175 | for (;; node--) | ||
| 176 | if (!tvisnil(&node->val)) { | ||
| 177 | w = serialize_put(w, sbuf, &node->key); | ||
| 178 | w = serialize_put(w, sbuf, &node->val); | ||
| 179 | if (--nhash == 0) break; | ||
| 180 | } | ||
| 181 | } | ||
| 182 | sbuf->depth++; | ||
| 183 | #if LJ_HASFFI | ||
| 184 | } else if (tviscdata(o)) { | ||
| 185 | CTState *cts = ctype_cts(sbufL(sbuf->sb)); | ||
| 186 | CType *s = ctype_raw(cts, cdataV(o)->ctypeid); | ||
| 187 | uint8_t *sp = cdataptr(cdataV(o)); | ||
| 188 | if (ctype_isinteger(s->info) && s->size == 8) { | ||
| 189 | w = serialize_more(w, sbuf, 1+8); | ||
| 190 | *w++ = (s->info & CTF_UNSIGNED) ? SER_TAG_UINT64 : SER_TAG_INT64; | ||
| 191 | #if LJ_BE | ||
| 192 | { uint64_t u = lj_bswap64(*(uint64_t *)sp); memcpy(w, &u, 8); } | ||
| 193 | #else | ||
| 194 | memcpy(w, sp, 8); | ||
| 195 | #endif | ||
| 196 | w += 8; | ||
| 197 | } else if (ctype_iscomplex(s->info) && s->size == 16) { | ||
| 198 | w = serialize_more(w, sbuf, 1+16); | ||
| 199 | *w++ = SER_TAG_COMPLEX; | ||
| 200 | #if LJ_BE | ||
| 201 | { /* Only swap the doubles. The re/im order stays the same. */ | ||
| 202 | uint64_t u = lj_bswap64(((uint64_t *)sp)[0]); memcpy(w, &u, 8); | ||
| 203 | u = lj_bswap64(((uint64_t *)sp)[1]); memcpy(w+8, &u, 8); | ||
| 204 | } | ||
| 205 | #else | ||
| 206 | memcpy(w, sp, 16); | ||
| 207 | #endif | ||
| 208 | w += 16; | ||
| 209 | } else { | ||
| 210 | goto badenc; /* NYI other cdata */ | ||
| 211 | } | ||
| 212 | #endif | ||
| 213 | } else if (tvislightud(o)) { | ||
| 214 | uintptr_t ud = (uintptr_t)lightudV(G(sbufL(sbuf->sb)), o); | ||
| 215 | w = serialize_more(w, sbuf, 1+sizeof(ud)); | ||
| 216 | if (ud == 0) { | ||
| 217 | *w++ = SER_TAG_NULL; | ||
| 218 | } else if (LJ_32 || checku32(ud)) { | ||
| 219 | #if LJ_BE && LJ_64 | ||
| 220 | ud = lj_bswap64(ud); | ||
| 221 | #elif LJ_BE | ||
| 222 | ud = lj_bswap(ud); | ||
| 223 | #endif | ||
| 224 | *w++ = SER_TAG_LIGHTUD32; memcpy(w, &ud, 4); w += 4; | ||
| 225 | } else { | ||
| 226 | #if LJ_BE | ||
| 227 | ud = lj_bswap64(ud); | ||
| 228 | #endif | ||
| 229 | *w++ = SER_TAG_LIGHTUD64; memcpy(w, &ud, 8); w += 8; | ||
| 230 | } | ||
| 231 | } else { | ||
| 232 | /* NYI userdata */ | ||
| 233 | #if LJ_HASFFI | ||
| 234 | badenc: | ||
| 235 | #endif | ||
| 236 | lj_err_callerv(sbufL(sbuf->sb), LJ_ERR_BUFFER_BADENC, lj_typename(o)); | ||
| 237 | } | ||
| 238 | return w; | ||
| 239 | } | ||
| 240 | |||
| 241 | /* Get serialized object from buffer. */ | ||
| 242 | static char *serialize_get(char *r, StrBuf *sbuf, TValue *o) | ||
| 243 | { | ||
| 244 | char *e = sbufE(sbuf->sb); | ||
| 245 | uint32_t tp; | ||
| 246 | r = serialize_ru124(r, e, &tp); if (LJ_UNLIKELY(!r)) goto eob; | ||
| 247 | if (LJ_LIKELY(tp >= SER_TAG_STR)) { | ||
| 248 | uint32_t len = tp - SER_TAG_STR; | ||
| 249 | if (LJ_UNLIKELY(len > (uint32_t)(e - r))) goto eob; | ||
| 250 | setstrV(sbufL(sbuf->sb), o, lj_str_new(sbufL(sbuf->sb), r, len)); | ||
| 251 | r += len; | ||
| 252 | } else if (tp == SER_TAG_INT) { | ||
| 253 | if (LJ_UNLIKELY(r + 4 > e)) goto eob; | ||
| 254 | setintV(o, (int32_t)(LJ_BE ? lj_bswap(lj_getu32(r)) : lj_getu32(r))); | ||
| 255 | r += 4; | ||
| 256 | } else if (tp == SER_TAG_NUM) { | ||
| 257 | if (LJ_UNLIKELY(r + 8 > e)) goto eob; | ||
| 258 | memcpy(o, r, 8); r += 8; | ||
| 259 | #if LJ_BE | ||
| 260 | o->u64 = lj_bswap64(o->u64); | ||
| 261 | #endif | ||
| 262 | if (!tvisnum(o)) setnanV(o); | ||
| 263 | } else if (tp <= SER_TAG_TRUE) { | ||
| 264 | setpriV(o, ~tp); | ||
| 265 | } else if (tp >= SER_TAG_TAB && tp < SER_TAG_TAB+6) { | ||
| 266 | uint32_t narray = 0, nhash = 0; | ||
| 267 | GCtab *t; | ||
| 268 | if (tp >= SER_TAG_TAB+2) { | ||
| 269 | r = serialize_ru124(r, e, &narray); if (LJ_UNLIKELY(!r)) goto eob; | ||
| 270 | } | ||
| 271 | if ((tp & 1)) { | ||
| 272 | r = serialize_ru124(r, e, &nhash); if (LJ_UNLIKELY(!r)) goto eob; | ||
| 273 | } | ||
| 274 | t = lj_tab_new(sbufL(sbuf->sb), narray, hsize2hbits(nhash)); | ||
| 275 | settabV(sbufL(sbuf->sb), o, t); | ||
| 276 | if (narray) { | ||
| 277 | TValue *oa = tvref(t->array) + (tp >= SER_TAG_TAB+4); | ||
| 278 | TValue *oe = tvref(t->array) + narray; | ||
| 279 | while (oa < oe) r = serialize_get(r, sbuf, oa++); | ||
| 280 | } | ||
| 281 | if (nhash) { | ||
| 282 | do { | ||
| 283 | TValue k, *v; | ||
| 284 | r = serialize_get(r, sbuf, &k); | ||
| 285 | v = lj_tab_set(sbufL(sbuf->sb), t, &k); | ||
| 286 | if (LJ_UNLIKELY(!tvisnil(v))) | ||
| 287 | lj_err_caller(sbufL(sbuf->sb), LJ_ERR_BUFFER_DUPKEY); | ||
| 288 | r = serialize_get(r, sbuf, v); | ||
| 289 | } while (--nhash); | ||
| 290 | } | ||
| 291 | #if LJ_HASFFI | ||
| 292 | } else if (tp >= SER_TAG_INT64 && tp <= SER_TAG_COMPLEX) { | ||
| 293 | uint32_t sz = tp == SER_TAG_COMPLEX ? 16 : 8; | ||
| 294 | GCcdata *cd; | ||
| 295 | if (LJ_UNLIKELY(r + sz > e)) goto eob; | ||
| 296 | cd = lj_cdata_new_(sbufL(sbuf->sb), | ||
| 297 | tp == SER_TAG_INT64 ? CTID_INT64 : | ||
| 298 | tp == SER_TAG_UINT64 ? CTID_UINT64 : CTID_COMPLEX_DOUBLE, | ||
| 299 | sz); | ||
| 300 | memcpy(cdataptr(cd), r, sz); r += sz; | ||
| 301 | #if LJ_BE | ||
| 302 | *(uint64_t *)cdataptr(cd) = lj_bswap64(*(uint64_t *)cdataptr(cd)); | ||
| 303 | if (sz == 16) | ||
| 304 | ((uint64_t *)cdataptr(cd))[1] = lj_bswap64(((uint64_t *)cdataptr(cd))[1]); | ||
| 305 | #endif | ||
| 306 | setcdataV(sbufL(sbuf->sb), o, cd); | ||
| 307 | #endif | ||
| 308 | } else if (tp <= (LJ_64 ? SER_TAG_LIGHTUD64 : SER_TAG_LIGHTUD32)) { | ||
| 309 | uintptr_t ud = 0; | ||
| 310 | if (tp == SER_TAG_LIGHTUD32) { | ||
| 311 | if (LJ_UNLIKELY(r + 4 > e)) goto eob; | ||
| 312 | ud = (uintptr_t)(LJ_BE ? lj_bswap(lj_getu32(r)) : lj_getu32(r)); | ||
| 313 | r += 4; | ||
| 314 | } | ||
| 315 | #if LJ_64 | ||
| 316 | else if (tp == SER_TAG_LIGHTUD64) { | ||
| 317 | if (LJ_UNLIKELY(r + 8 > e)) goto eob; | ||
| 318 | memcpy(&ud, r, 8); r += 8; | ||
| 319 | #if LJ_BE | ||
| 320 | ud = lj_bswap64(ud); | ||
| 321 | #endif | ||
| 322 | } | ||
| 323 | setrawlightudV(o, lj_lightud_intern(sbufL(sbuf->sb), (void *)ud)); | ||
| 324 | #else | ||
| 325 | setrawlightudV(o, (void *)ud); | ||
| 326 | #endif | ||
| 327 | } else { | ||
| 328 | lj_err_callerv(sbufL(sbuf->sb), LJ_ERR_BUFFER_BADDEC, tp); | ||
| 329 | } | ||
| 330 | return r; | ||
| 331 | eob: | ||
| 332 | lj_err_caller(sbufL(sbuf->sb), LJ_ERR_BUFFER_EOB); | ||
| 333 | return NULL; | ||
| 334 | } | ||
| 335 | |||
| 336 | StrBuf * LJ_FASTCALL lj_serialize_put(StrBuf *sbuf, cTValue *o) | ||
| 337 | { | ||
| 338 | sbuf->depth = LJ_SERIALIZE_DEPTH; | ||
| 339 | setsbufP(sbuf->sb, serialize_put(sbufP(sbuf->sb), sbuf, o)); | ||
| 340 | return sbuf; | ||
| 341 | } | ||
| 342 | |||
| 343 | StrBuf * LJ_FASTCALL lj_serialize_get(StrBuf *sbuf, TValue *o) | ||
| 344 | { | ||
| 345 | char *r = serialize_get(sbuf->r, sbuf, o); | ||
| 346 | if (r != sbufP(sbuf->sb)) | ||
| 347 | lj_err_caller(sbufL(sbuf->sb), LJ_ERR_BUFFER_LEFTOV); | ||
| 348 | sbuf->r = r; | ||
| 349 | return sbuf; | ||
| 350 | } | ||
| 351 | |||
diff --git a/src/lj_serialize.h b/src/lj_serialize.h new file mode 100644 index 00000000..95d62f4e --- /dev/null +++ b/src/lj_serialize.h | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* | ||
| 2 | ** Object de/serialization. | ||
| 3 | ** Copyright (C) 2005-2021 Mike Pall. See Copyright Notice in luajit.h | ||
| 4 | */ | ||
| 5 | |||
| 6 | #ifndef _LJ_SERIALIZE_H | ||
| 7 | #define _LJ_SERIALIZE_H | ||
| 8 | |||
| 9 | #include "lj_obj.h" | ||
| 10 | #include "lj_buf.h" | ||
| 11 | |||
| 12 | #if LJ_HASBUFFER | ||
| 13 | |||
| 14 | #define LJ_SERIALIZE_DEPTH 100 /* Default depth. */ | ||
| 15 | |||
| 16 | LJ_FUNC StrBuf * LJ_FASTCALL lj_serialize_put(StrBuf *sb, cTValue *o); | ||
| 17 | LJ_FUNC StrBuf * LJ_FASTCALL lj_serialize_get(StrBuf *sb, TValue *o); | ||
| 18 | |||
| 19 | #endif | ||
| 20 | |||
| 21 | #endif | ||
diff --git a/src/ljamalg.c b/src/ljamalg.c index 8e2d4937..384b3cc1 100644 --- a/src/ljamalg.c +++ b/src/ljamalg.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include "lj_strscan.c" | 39 | #include "lj_strscan.c" |
| 40 | #include "lj_strfmt.c" | 40 | #include "lj_strfmt.c" |
| 41 | #include "lj_strfmt_num.c" | 41 | #include "lj_strfmt_num.c" |
| 42 | #include "lj_serialize.c" | ||
| 42 | #include "lj_api.c" | 43 | #include "lj_api.c" |
| 43 | #include "lj_profile.c" | 44 | #include "lj_profile.c" |
| 44 | #include "lj_lex.c" | 45 | #include "lj_lex.c" |
| @@ -85,5 +86,6 @@ | |||
| 85 | #include "lib_bit.c" | 86 | #include "lib_bit.c" |
| 86 | #include "lib_jit.c" | 87 | #include "lib_jit.c" |
| 87 | #include "lib_ffi.c" | 88 | #include "lib_ffi.c" |
| 89 | #include "lib_buffer.c" | ||
| 88 | #include "lib_init.c" | 90 | #include "lib_init.c" |
| 89 | 91 | ||
diff --git a/src/lualib.h b/src/lualib.h index 9cd39880..5c18e9ec 100644 --- a/src/lualib.h +++ b/src/lualib.h | |||
| @@ -33,6 +33,7 @@ LUALIB_API int luaopen_debug(lua_State *L); | |||
| 33 | LUALIB_API int luaopen_bit(lua_State *L); | 33 | LUALIB_API int luaopen_bit(lua_State *L); |
| 34 | LUALIB_API int luaopen_jit(lua_State *L); | 34 | LUALIB_API int luaopen_jit(lua_State *L); |
| 35 | LUALIB_API int luaopen_ffi(lua_State *L); | 35 | LUALIB_API int luaopen_ffi(lua_State *L); |
| 36 | LUALIB_API int luaopen_string_buffer(lua_State *L); | ||
| 36 | 37 | ||
| 37 | LUALIB_API void luaL_openlibs(lua_State *L); | 38 | LUALIB_API void luaL_openlibs(lua_State *L); |
| 38 | 39 | ||
