#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