| 181 | static void fxSpreadNodeCode(void* it, void* param, txInteger counter); |
| 182 | |
| 183 | txScript* fxParserCode(txParser* parser) |
| 184 | { |
| 185 | txCoder coder; |
| 186 | txByteCode* code; |
| 187 | txScript* script; |
| 188 | txSize size, delta, offset; |
| 189 | txSymbol* symbol; |
| 190 | txSymbol** address; |
| 191 | txSize c, i; |
| 192 | txID id, count; |
| 193 | txSize total; |
| 194 | txByte* p; |
| 195 | txHostNode* node; |
| 196 | #ifdef mxMetering |
| 197 | txUnsigned meterIndex = 0; |
| 198 | #endif |
| 199 | |
| 200 | c_memset(&coder, 0, sizeof(txCoder)); |
| 201 | coder.parser = parser; |
| 202 | if (parser->errorCount == 0) { |
| 203 | mxTryParser(parser) { |
| 204 | txNode* self = parser->root; |
| 205 | (*self->description->dispatch->code)(parser->root, &coder); |
| 206 | } |
| 207 | mxCatchParser(parser) { |
| 208 | } |
| 209 | } |
| 210 | if (parser->errorCount) { |
| 211 | if (parser->console) { |
| 212 | coder.firstCode = NULL; |
| 213 | coder.lastCode = NULL; |
| 214 | fxCoderAddByte(&coder, 1, XS_CODE_GLOBAL); |
| 215 | fxCoderAddSymbol(&coder, 0, XS_CODE_GET_VARIABLE, parser->errorSymbol); |
| 216 | fxCoderAddByte(&coder, 2, XS_CODE_NEW); |
| 217 | fxCoderAddString(&coder, 1, XS_CODE_STRING_1, mxStringLength(parser->errorMessage), parser->errorMessage); |
| 218 | fxCoderAddInteger(&coder, -3, XS_CODE_RUN_1, 1); |
| 219 | fxCoderAddByte(&coder, -1, XS_CODE_THROW); |
| 220 | } |
| 221 | else |
| 222 | return C_NULL; |
| 223 | } |
| 224 | |
| 225 | fxCoderOptimize(&coder); |
| 226 | |
| 227 | script = c_malloc(sizeof(txScript)); |
| 228 | if (!script) goto bail; |
| 229 | c_memset(script, 0, sizeof(txScript)); |
| 230 | |
| 231 | code = coder.firstCode; |
| 232 | size = 0; |
| 233 | delta = 0; |
| 234 | while (code) { |
| 235 | txInteger value; |
| 236 | switch (code->id) { |
| 237 | case XS_NO_CODE: |
| 238 | ((txTargetCode*)code)->offset = size; |
| 239 | break; |
| 240 | case XS_CODE_BRANCH_1: |
no test coverage detected