diff options
| author | Murilo Ijanc <[email protected]> | 2026-07-26 12:56:51 -0300 |
|---|---|---|
| committer | Murilo Ijanc <[email protected]> | 2026-07-26 12:56:59 -0300 |
| commit | b7b08a7d29d84de187dd8a55e0c94de66b07a572 (patch) | |
| tree | 7e55661d3eca3cf3b16aada6e87eabee68802fb9 /src/json.S | |
| download | asm-b7b08a7d29d84de187dd8a55e0c94de66b07a572.tar.gz | |
Initial importv0.1.0
Diffstat (limited to 'src/json.S')
| -rw-r--r-- | src/json.S | 482 |
1 files changed, 482 insertions, 0 deletions
diff --git a/src/json.S b/src/json.S new file mode 100644 index 0000000..58c5077 --- /dev/null +++ b/src/json.S @@ -0,0 +1,482 @@ +#include "abi.inc" +#include "defs.inc" + +#define JBUF -72 + + .text + +FUNC cepis__js_ws +.Lws_loop: + movzbl (%rdi), %eax + cmp $' ', %al + je .Lws_adv + cmp $9, %al + jb .Lws_end + cmp $13, %al + jbe .Lws_adv +.Lws_end: + mov %rdi, %rax + ret +.Lws_adv: + inc %rdi + jmp .Lws_loop +ENDFUNC cepis__js_ws + +FUNC cepis__js_hex4 + xor %ecx, %ecx + mov $4, %r8d +.Lhex_loop: + movzbl (%rdi), %eax + inc %rdi + cmp $'0', %al + jb .Lhex_bad + cmp $'9', %al + jbe .Lhex_digit + or $0x20, %al + cmp $'a', %al + jb .Lhex_bad + cmp $'f', %al + ja .Lhex_bad + sub $('a' - 10), %eax + jmp .Lhex_acc +.Lhex_digit: + sub $'0', %eax +.Lhex_acc: + shl $4, %ecx + or %eax, %ecx + dec %r8d + jnz .Lhex_loop + mov %ecx, %eax + ret +.Lhex_bad: + mov $-1, %eax + ret +ENDFUNC cepis__js_hex4 + +FUNC cepis__js_raw_string + cmpb $'"', (%rdi) + jne .Lraw_bad + inc %rdi +.Lraw_loop: + movzbl (%rdi), %eax + test %al, %al + jz .Lraw_bad + cmp $'\\', %al + je .Lraw_esc + cmp $'"', %al + je .Lraw_close + inc %rdi + jmp .Lraw_loop +.Lraw_esc: + cmpb $0, 1(%rdi) + je .Lraw_bad + add $2, %rdi + jmp .Lraw_loop +.Lraw_close: + lea 1(%rdi), %rax + ret +.Lraw_bad: + xor %eax, %eax + ret +ENDFUNC cepis__js_raw_string + +FUNC cepis__js_skip + PROLOGUE 8 + call cepis__js_ws + mov %rax, %rbx + movzbl (%rbx), %eax + test %al, %al + jz .Lskip_bad + cmp $'"', %al + je .Lskip_str + cmp $'{', %al + je .Lskip_nest + cmp $'[', %al + je .Lskip_nest + jmp .Lskip_token +.Lskip_str: + mov %rbx, %rdi + call cepis__js_raw_string + EPILOGUE + ret +.Lskip_token: + mov %rbx, %r12 +.Lskip_token_loop: + movzbl (%r12), %eax + cmp $'0', %al + jb .Lskip_token_sym + cmp $'9', %al + jbe .Lskip_token_adv + or $0x20, %al + cmp $'a', %al + jb .Lskip_token_end + cmp $'z', %al + jbe .Lskip_token_adv + jmp .Lskip_token_end +.Lskip_token_sym: + cmp $'+', %al + je .Lskip_token_adv + cmp $'-', %al + je .Lskip_token_adv + cmp $'.', %al + je .Lskip_token_adv + jmp .Lskip_token_end +.Lskip_token_adv: + inc %r12 + jmp .Lskip_token_loop +.Lskip_token_end: + cmp %rbx, %r12 + je .Lskip_bad + mov %r12, %rax + EPILOGUE + ret +.Lskip_nest: + xor %r13d, %r13d +.Lskip_nest_loop: + movzbl (%rbx), %eax + test %al, %al + jz .Lskip_bad + cmp $'"', %al + je .Lskip_nest_str + cmp $'{', %al + je .Lskip_nest_open + cmp $'[', %al + je .Lskip_nest_open + cmp $'}', %al + je .Lskip_nest_close + cmp $']', %al + je .Lskip_nest_close + inc %rbx + jmp .Lskip_nest_loop +.Lskip_nest_str: + mov %rbx, %rdi + call cepis__js_raw_string + test %rax, %rax + jz .Lskip_bad + mov %rax, %rbx + jmp .Lskip_nest_loop +.Lskip_nest_open: + inc %r13d + inc %rbx + jmp .Lskip_nest_loop +.Lskip_nest_close: + dec %r13d + inc %rbx + test %r13d, %r13d + jz .Lskip_nest_done + jmp .Lskip_nest_loop +.Lskip_nest_done: + mov %rbx, %rax + EPILOGUE + ret +.Lskip_bad: + xor %eax, %eax + EPILOGUE + ret +ENDFUNC cepis__js_skip + +FUNC cepis__js_string + PROLOGUE 40 + mov %rsi, %r14 + movq $0, JBUF(%rbp) + movq $0, JBUF+8(%rbp) + movq $0, JBUF+16(%rbp) + movq $0, (%r14) + cmpb $'"', (%rdi) + jne .Lstr_fail + lea 1(%rdi), %rbx +.Lstr_loop: + movzbl (%rbx), %eax + test %al, %al + jz .Lstr_fail + cmp $'"', %al + je .Lstr_done + cmp $'\\', %al + je .Lstr_esc + lea JBUF(%rbp), %rdi + movzbl (%rbx), %esi + call cepis__buf_appendc + test %eax, %eax + jnz .Lstr_fail + inc %rbx + jmp .Lstr_loop +.Lstr_esc: + movzbl 1(%rbx), %eax + test %al, %al + jz .Lstr_fail + cmp $'u', %al + je .Lstr_uesc + mov %eax, %r12d + cmp $'"', %al + je .Lstr_emit + cmp $'\\', %al + je .Lstr_emit + cmp $'/', %al + je .Lstr_emit + cmp $'b', %al + je .Lstr_bs + cmp $'f', %al + je .Lstr_ff + cmp $'n', %al + je .Lstr_nl + cmp $'r', %al + je .Lstr_cr + cmp $'t', %al + je .Lstr_tab + jmp .Lstr_fail +.Lstr_bs: + mov $8, %r12d + jmp .Lstr_emit +.Lstr_ff: + mov $12, %r12d + jmp .Lstr_emit +.Lstr_nl: + mov $10, %r12d + jmp .Lstr_emit +.Lstr_cr: + mov $13, %r12d + jmp .Lstr_emit +.Lstr_tab: + mov $9, %r12d +.Lstr_emit: + lea JBUF(%rbp), %rdi + mov %r12d, %esi + call cepis__buf_appendc + test %eax, %eax + jnz .Lstr_fail + add $2, %rbx + jmp .Lstr_loop +.Lstr_uesc: + lea 2(%rbx), %rdi + call cepis__js_hex4 + test %eax, %eax + js .Lstr_fail + mov %eax, %r12d + add $6, %rbx + cmp $0xD800, %r12d + jb .Lstr_encode + cmp $0xDBFF, %r12d + ja .Lstr_low + cmpb $'\\', (%rbx) + jne .Lstr_repl + cmpb $'u', 1(%rbx) + jne .Lstr_repl + lea 2(%rbx), %rdi + call cepis__js_hex4 + test %eax, %eax + js .Lstr_repl + mov %eax, %r13d + cmp $0xDC00, %r13d + jb .Lstr_repl + cmp $0xDFFF, %r13d + ja .Lstr_repl + add $6, %rbx + sub $0xD800, %r12d + shl $10, %r12d + sub $0xDC00, %r13d + add %r13d, %r12d + add $0x10000, %r12d + jmp .Lstr_encode +.Lstr_low: + cmp $0xDFFF, %r12d + ja .Lstr_encode +.Lstr_repl: + mov $0xFFFD, %r12d +.Lstr_encode: + cmp $0x80, %r12d + jb .Lstr_enc1 + cmp $0x800, %r12d + jb .Lstr_enc2 + cmp $0x10000, %r12d + jb .Lstr_enc3 + mov %r12d, %esi + shr $18, %esi + or $0xF0, %esi + lea JBUF(%rbp), %rdi + call cepis__buf_appendc + test %eax, %eax + jnz .Lstr_fail + mov %r12d, %esi + shr $12, %esi + and $0x3F, %esi + or $0x80, %esi + lea JBUF(%rbp), %rdi + call cepis__buf_appendc + test %eax, %eax + jnz .Lstr_fail + jmp .Lstr_enc_tail2 +.Lstr_enc3: + mov %r12d, %esi + shr $12, %esi + or $0xE0, %esi + lea JBUF(%rbp), %rdi + call cepis__buf_appendc + test %eax, %eax + jnz .Lstr_fail +.Lstr_enc_tail2: + mov %r12d, %esi + shr $6, %esi + and $0x3F, %esi + or $0x80, %esi + lea JBUF(%rbp), %rdi + call cepis__buf_appendc + test %eax, %eax + jnz .Lstr_fail + jmp .Lstr_enc_tail1 +.Lstr_enc2: + mov %r12d, %esi + shr $6, %esi + or $0xC0, %esi + lea JBUF(%rbp), %rdi + call cepis__buf_appendc + test %eax, %eax + jnz .Lstr_fail +.Lstr_enc_tail1: + mov %r12d, %esi + and $0x3F, %esi + or $0x80, %esi + lea JBUF(%rbp), %rdi + call cepis__buf_appendc + test %eax, %eax + jnz .Lstr_fail + jmp .Lstr_loop +.Lstr_enc1: + mov %r12d, %esi + lea JBUF(%rbp), %rdi + call cepis__buf_appendc + test %eax, %eax + jnz .Lstr_fail + jmp .Lstr_loop +.Lstr_done: + inc %rbx + cmpq $0, JBUF(%rbp) + jne .Lstr_take + call cepis__empty + test %rax, %rax + jz .Lstr_fail + mov %rax, (%r14) + mov %rbx, %rax + EPILOGUE + ret +.Lstr_take: + lea JBUF(%rbp), %rdi + call cepis__buf_take + mov %rax, (%r14) + mov %rbx, %rax + EPILOGUE + ret +.Lstr_fail: + lea JBUF(%rbp), %rdi + call cepis__buf_free + movq $0, (%r14) + xor %eax, %eax + EPILOGUE + ret +ENDFUNC cepis__js_string + +FUNC cepis__js_scalar_text + PROLOGUE 24 + mov %rsi, %r14 + movq $0, (%r14) + call cepis__js_ws + mov %rax, %rbx + movzbl (%rbx), %eax + cmp $'"', %al + je .Lsc_string + cmp $'{', %al + je .Lsc_fail + cmp $'[', %al + je .Lsc_fail + mov %rbx, %rdi + call cepis__js_skip + test %rax, %rax + jz .Lsc_fail + mov %rax, %r12 + mov %r12, %r13 + sub %rbx, %r13 + cmp $4, %r13 + jne .Lsc_copy + mov %rbx, %rdi + lea .Lsc_null(%rip), %rsi + mov $4, %rdx + call memcmp@PLT + test %eax, %eax + jnz .Lsc_copy + call cepis__empty + test %rax, %rax + jz .Lsc_fail + mov %rax, (%r14) + mov %r12, %rax + EPILOGUE + ret +.Lsc_copy: + mov %rbx, %rdi + mov %r13, %rsi + call cepis__strndup + test %rax, %rax + jz .Lsc_fail + mov %rax, (%r14) + mov %r12, %rax + EPILOGUE + ret +.Lsc_string: + mov %rbx, %rdi + mov %r14, %rsi + call cepis__js_string + EPILOGUE + ret +.Lsc_fail: + xor %eax, %eax + EPILOGUE + ret +ENDFUNC cepis__js_scalar_text + +FUNC cepis__js_number + PROLOGUE 40 + mov %rsi, %r14 + call cepis__js_ws + mov %rax, %rbx + cmpb $'"', (%rbx) + je .Lnum_quoted + mov %rbx, %rdi + lea LOCAL0(%rbp), %rsi + call strtod@PLT + mov LOCAL0(%rbp), %rax + cmp %rbx, %rax + je .Lnum_fail + movsd %xmm0, (%r14) + EPILOGUE + ret +.Lnum_quoted: + mov %rbx, %rdi + lea LOCAL1(%rbp), %rsi + call cepis__js_string + test %rax, %rax + jz .Lnum_fail + mov %rax, %r12 + mov LOCAL1(%rbp), %rdi + lea LOCAL0(%rbp), %rsi + call strtod@PLT + movsd %xmm0, LOCAL2(%rbp) + mov LOCAL1(%rbp), %rbx + mov LOCAL0(%rbp), %r13 + mov %rbx, %rdi + call free@PLT + cmp %rbx, %r13 + je .Lnum_fail + movsd LOCAL2(%rbp), %xmm0 + movsd %xmm0, (%r14) + mov %r12, %rax + EPILOGUE + ret +.Lnum_fail: + xor %eax, %eax + EPILOGUE + ret +ENDFUNC cepis__js_number + + .section .rodata +.Lsc_null: + .ascii "null" + + .section .note.GNU-stack,"",@progbits |