#include "wsint.h"#include "wsasm.h"#include "wsstdlib.h"#include "wsopcodes.h"Include dependency graph for wsasm.c:

Go to the source code of this file.
|
|
|
|
|
|
|
||||||||||||||||
|
|
|
||||||||||||||||||||
|
|
|
||||||||||||||||
|
|
|
||||||||||||||||||||
|
|
|
||||||||||||||||||||||||
|
|
|
||||||||||||||||
|
Definition at line 498 of file wsasm.c. Referenced by compile_stream(), and main(). 00499 {
00500 /* The wider form. */
00501 ins->type = WS_ASM_CALL;
00502 }
00503 break;
00504
00505 case WS_ASM_P_CALL_LIB:
00506 if (ins->ws_findex <= 7 && ins->ws_lindex <= 255) {
00507 /* The most compact form. */
00508 ins->type = WS_ASM_CALL_LIB_S;
00509 } else if (ins->ws_findex <= 255 && ins->ws_lindex <= 255) {
00510 /* The quite compact form. */
00511 ins->type = WS_ASM_CALL_LIB;
00512 } else {
00513 /* The most liberal form. */
00514 ins->type = WS_ASM_CALL_LIB_W;
00515 }
00516 break;
00517
00518 case WS_ASM_P_CALL_URL:
00519 if (ins->ws_findex <= 255 && ins->ws_lindex <= 255)
00520 /* The compact form. */
00521 ins->type = WS_ASM_CALL_URL;
00522 else
00523 ins->type = WS_ASM_CALL_URL_W;
00524 break;
00525
00526 case WS_ASM_P_LOAD_VAR:
00527 if (ins->ws_vindex <= 31)
00528 /* The compact form. */
00529 ins->type = WS_ASM_LOAD_VAR_S;
00530 else
00531 ins->type = WS_ASM_LOAD_VAR;
00532 break;
00533
00534 case WS_ASM_P_STORE_VAR:
00535 if (ins->ws_vindex <= 15)
00536 ins->type = WS_ASM_STORE_VAR_S;
00537 else
00538 ins->type = WS_ASM_STORE_VAR;
00539 break;
00540
00541 case WS_ASM_P_INCR_VAR:
00542 if (ins->ws_vindex <= 7)
00543 ins->type = WS_ASM_INCR_VAR_S;
00544 else
00545 ins->type = WS_ASM_INCR_VAR;
00546 break;
00547
00548 case WS_ASM_P_LOAD_CONST:
00549 if (ins->ws_cindex <= 15)
00550 ins->type = WS_ASM_LOAD_CONST_S;
00551 else if (ins->ws_cindex <= 255)
00552 ins->type = WS_ASM_LOAD_CONST;
00553 else
00554 ins->type = WS_ASM_LOAD_CONST_W;
00555 break;
00556 }
00557
00558 gw_assert(ins->type == WS_ASM_P_LABEL || ins->type < 0x100);
00559
00560 if (ins->type != WS_ASM_P_LABEL) {
00561 gw_assert(operands[ins->type].name != NULL);
00562 offset += operands[ins->type].size;
00563 }
00564 }
00565 }
00566
00567 /* Ok, ready to linearize the byte-code. */
00568 for (ins = compiler->asm_head; ins; ins = ins->next) {
00569 if (ins->type == WS_ASM_P_LABEL)
00570 continue;
00571
00572 gw_assert(ins->type <= 0xff);
00573
00574 switch (ins->type) {
00575 case WS_ASM_JUMP_FW_S:
00576 case WS_ASM_JUMP_BW_S:
00577 case WS_ASM_TJUMP_FW_S:
00578 if (!ws_encode_buffer(&compiler->byte_code,
00579 WS_ENC_BYTE,
00580 WS_ASM_GLUE(ins->type, ins->ws_offset),
00581 WS_ENC_END))
00582 goto error;
00583 break;
00584
00585 case WS_ASM_JUMP_FW:
00586 case WS_ASM_JUMP_BW:
00587 case WS_ASM_TJUMP_FW:
00588 case WS_ASM_TJUMP_BW:
00589 if (!ws_encode_buffer(&compiler->byte_code,
00590 WS_ENC_BYTE, ins->type,
00591 WS_ENC_UINT8, (WsUInt8) ins->ws_offset,
00592 WS_ENC_END))
00593 goto error;
00594 break;
00595
00596 case WS_ASM_JUMP_FW_W:
00597 case WS_ASM_JUMP_BW_W:
00598 case WS_ASM_TJUMP_FW_W:
00599 case WS_ASM_TJUMP_BW_W:
00600 if (!ws_encode_buffer(&compiler->byte_code,
00601 WS_ENC_BYTE, ins->type,
00602 WS_ENC_UINT16, (WsUInt16) ins->ws_offset,
00603 WS_ENC_END))
00604 goto error;
00605 break;
00606
00607 case WS_ASM_CALL_S:
00608 if (!ws_encode_buffer(&compiler->byte_code,
00609 WS_ENC_BYTE,
00610 WS_ASM_GLUE(ins->type, ins->ws_findex),
00611 WS_ENC_END))
00612 goto error;
00613 break;
00614
00615 case WS_ASM_CALL:
00616 if (!ws_encode_buffer(&compiler->byte_code,
00617 WS_ENC_BYTE, (WsByte) ins->type,
00618 WS_ENC_UINT8, (WsUInt8) ins->ws_findex,
00619 WS_ENC_END))
00620 goto error;
00621 break;
00622
00623 case WS_ASM_CALL_LIB_S:
00624 if (!ws_encode_buffer(&compiler->byte_code,
00625 WS_ENC_BYTE,
00626 WS_ASM_GLUE(ins->type, ins->ws_findex),
00627 WS_ENC_UINT8, (WsUInt8) ins->ws_lindex,
00628 WS_ENC_END))
00629 goto error;
00630 break;
00631
00632 case WS_ASM_CALL_LIB:
00633 if (!ws_encode_buffer(&compiler->byte_code,
00634 WS_ENC_BYTE, (WsByte) ins->type,
00635 WS_ENC_UINT8, (WsUInt8) ins->ws_findex,
00636 WS_ENC_UINT8, (WsUInt8) ins->ws_lindex,
00637 WS_ENC_END))
00638 goto error;
00639 break;
00640
00641 case WS_ASM_CALL_LIB_W:
00642 if (!ws_encode_buffer(&compiler->byte_code,
00643 WS_ENC_BYTE, (WsByte) ins->type,
00644 WS_ENC_UINT8, (WsUInt8) ins->ws_findex,
00645 WS_ENC_UINT16, (WsUInt16) ins->ws_lindex,
00646 WS_ENC_END))
00647 goto error;
00648 break;
00649
00650 case WS_ASM_CALL_URL:
|
|
||||||||||||||||
|
|
|
||||||||||||
|
|
|
|
Definition at line 654 of file wsasm.c. References WS_ASM_ADD, WS_ASM_ADD_ASG, WS_ASM_B_AND, WS_ASM_B_LSHIFT, WS_ASM_B_NOT, WS_ASM_B_OR, WS_ASM_B_RSSHIFT, WS_ASM_B_RSZSHIFT, WS_ASM_B_XOR, WS_ASM_CALL_URL_W, WS_ASM_CONST_0, WS_ASM_CONST_1, WS_ASM_CONST_ES, WS_ASM_CONST_FALSE, WS_ASM_CONST_INVALID, WS_ASM_CONST_M1, WS_ASM_CONST_TRUE, WS_ASM_DEBUG, WS_ASM_DECR, WS_ASM_DECR_VAR, WS_ASM_DIV, WS_ASM_EQ, WS_ASM_GE, WS_ASM_GLUE, WS_ASM_GT, WS_ASM_IDIV, WS_ASM_INCR, WS_ASM_INCR_VAR, WS_ASM_INCR_VAR_S, WS_ASM_ISVALID, WS_ASM_LE, WS_ASM_LOAD_CONST, WS_ASM_LOAD_CONST_S, WS_ASM_LOAD_CONST_W, WS_ASM_LOAD_VAR, WS_ASM_LOAD_VAR_S, WS_ASM_LT, WS_ASM_MUL, WS_ASM_NE, WS_ASM_NOT, WS_ASM_POP, WS_ASM_REM, WS_ASM_RETURN, WS_ASM_RETURN_ES, WS_ASM_SCAND, WS_ASM_SCOR, WS_ASM_STORE_VAR, WS_ASM_STORE_VAR_S, WS_ASM_SUB, WS_ASM_SUB_ASG, WS_ASM_TOBOOL, WS_ASM_TYPEOF, and WS_ASM_UMINUS. 00660 : 00661 if (!ws_encode_buffer(&compiler->byte_code, 00662 WS_ENC_BYTE, (WsByte) ins->type, 00663 WS_ENC_UINT16, (WsUInt16) ins->ws_lindex, 00664 WS_ENC_UINT16, (WsUInt16) ins->ws_findex, 00665 WS_ENC_UINT8, (WsUInt8) ins->ws_args, 00666 WS_ENC_END)) 00667 goto error; 00668 break; 00669 00670 case WS_ASM_LOAD_VAR_S: 00671 case WS_ASM_STORE_VAR_S: 00672 if (!ws_encode_buffer(&compiler->byte_code, 00673 WS_ENC_BYTE, 00674 WS_ASM_GLUE(ins->type, ins->ws_vindex), 00675 WS_ENC_END)) 00676 goto error; 00677 break; 00678 00679 case WS_ASM_LOAD_VAR: 00680 case WS_ASM_STORE_VAR: 00681 if (!ws_encode_buffer(&compiler->byte_code, 00682 WS_ENC_BYTE, (WsByte) ins->type, 00683 WS_ENC_UINT8, (WsUInt8) ins->ws_vindex, 00684 WS_ENC_END)) 00685 goto error; 00686 break; 00687 00688 case WS_ASM_INCR_VAR_S: 00689 if (!ws_encode_buffer(&compiler->byte_code, 00690 WS_ENC_BYTE, 00691 WS_ASM_GLUE(ins->type, ins->ws_vindex), 00692 WS_ENC_END)) 00693 goto error; 00694 break; 00695 00696 case WS_ASM_INCR_VAR: 00697 case WS_ASM_DECR_VAR: 00698 if (!ws_encode_buffer(&compiler->byte_code, 00699 WS_ENC_BYTE, (WsByte) ins->type, 00700 WS_ENC_UINT8, (WsUInt8) ins->ws_vindex, 00701 WS_ENC_END)) 00702 goto error; 00703 break; 00704 00705 case WS_ASM_LOAD_CONST_S: 00706 if (!ws_encode_buffer(&compiler->byte_code, 00707 WS_ENC_BYTE, 00708 WS_ASM_GLUE(ins->type, ins->ws_cindex), 00709 WS_ENC_END)) 00710 goto error; 00711 break; 00712 00713 case WS_ASM_LOAD_CONST: 00714 if (!ws_encode_buffer(&compiler->byte_code, 00715 WS_ENC_BYTE, (WsByte) ins->type, 00716 WS_ENC_UINT8, (WsUInt8) ins->ws_cindex, 00717 WS_ENC_END)) 00718 goto error; 00719 break; 00720 00721 case WS_ASM_LOAD_CONST_W: 00722 if (!ws_encode_buffer(&compiler->byte_code, 00723 WS_ENC_BYTE, (WsByte) ins->type, 00724 WS_ENC_UINT16, (WsUInt16) ins->ws_cindex, 00725 WS_ENC_END)) 00726 goto error; 00727 break; 00728 00729 case WS_ASM_ADD_ASG: 00730 case WS_ASM_SUB_ASG: 00731 if (!ws_encode_buffer(&compiler->byte_code, 00732 WS_ENC_BYTE, (WsByte) ins->type, 00733 WS_ENC_UINT8, (WsUInt8) ins->ws_vindex, 00734 WS_ENC_END)) 00735 goto error; 00736 break; 00737 00738 case WS_ASM_CONST_0: 00739 case WS_ASM_CONST_1: 00740 case WS_ASM_CONST_M1: 00741 case WS_ASM_CONST_ES: 00742 case WS_ASM_CONST_INVALID: 00743 case WS_ASM_CONST_TRUE: 00744 case WS_ASM_CONST_FALSE: 00745 case WS_ASM_INCR: 00746 case WS_ASM_DECR: 00747 case WS_ASM_UMINUS: 00748 case WS_ASM_ADD: 00749 case WS_ASM_SUB: 00750 case WS_ASM_MUL: 00751 case WS_ASM_DIV: 00752 case WS_ASM_IDIV: 00753 case WS_ASM_REM: 00754 case WS_ASM_B_AND: 00755 case WS_ASM_B_OR: 00756 case WS_ASM_B_XOR: 00757 case WS_ASM_B_NOT: 00758 case WS_ASM_B_LSHIFT: 00759 case WS_ASM_B_RSSHIFT: 00760 case WS_ASM_B_RSZSHIFT: 00761 case WS_ASM_EQ: 00762 case WS_ASM_LE: 00763 case WS_ASM_LT: 00764 case WS_ASM_GE: 00765 case WS_ASM_GT: 00766 case WS_ASM_NE: 00767 case WS_ASM_NOT: 00768 case WS_ASM_SCAND: 00769 case WS_ASM_SCOR: 00770 case WS_ASM_TOBOOL: 00771 case WS_ASM_POP: 00772 case WS_ASM_TYPEOF: 00773 case WS_ASM_ISVALID: 00774 case WS_ASM_RETURN: 00775 case WS_ASM_RETURN_ES: 00776 case WS_ASM_DEBUG: 00777 if (!ws_encode_buffer(&compiler->byte_code, 00778 WS_ENC_BYTE, (WsByte) ins->type, 00779 WS_ENC_END)) 00780 goto error; 00781 break; 00782 00783 default: 00784 ws_fatal("ws_asm_linearize(): unknown instruction 0x%02x", 00785 ins->type); 00786 break; 00787 } 00788 } 00789 00790 /* 00791 * Avoid generating 0-length functions, because not all clients 00792 * handle them correctly. 00793 */ 00794 if (ws_buffer_len(&compiler->byte_code) == 0) { 00795 if (!ws_encode_buffer(&compiler->byte_code, 00796 WS_ENC_BYTE, (WsByte) WS_ASM_RETURN_ES, 00797 WS_ENC_END)) 00798 goto error; 00799 } 00800 00801 return; 00802 00803 /* 00804 * Error handling. 00805 */ 00806 00807 error: 00808 00809 ws_error_memory(compiler); 00810 return; 00811 } 00812 00813 00814 /* Contructors for assembler instructions. */ 00815 00816 static WsAsmIns *asm_alloc(WsCompiler *compiler, WsUInt16 type, WsUInt32 line) 00817 { 00818 WsAsmIns *ins = ws_f_calloc(compiler->pool_asm, 1, sizeof(*ins)); 00819 00820 if (ins == NULL) 00821 ws_error_memory(compiler); 00822 else { 00823 ins->type = type; 00824 ins->line = line; 00825 } 00826 00827 return ins; 00828 } 00829 00830 00831 WsAsmIns *ws_asm_label(WsCompiler *compiler, WsUInt32 line) 00832 { 00833 WsAsmIns *ins = asm_alloc(compiler, WS_ASM_P_LABEL, line); 00834 00835 if (ins) 00836 ins->ws_label_idx = compiler->next_label++; 00837 00838 return ins; 00839 } 00840 00841 00842 WsAsmIns *ws_asm_branch(WsCompiler *compiler, WsUInt32 line, WsUInt16 inst, 00843 WsAsmIns *label) 00844 { 00845 WsAsmIns *ins = asm_alloc(compiler, inst, line); 00846 00847 if (ins) { 00848 ins->ws_label = label; 00849 label->ws_label_refcount++; 00850 } 00851 00852 return ins; 00853 } 00854 00855 00856 WsAsmIns *ws_asm_call(WsCompiler *compiler, WsUInt32 line, WsUInt8 findex) 00857 { 00858 WsAsmIns *ins = asm_alloc(compiler, WS_ASM_P_CALL, line); 00859 00860 if (ins) 00861 ins->ws_findex = findex; 00862 00863 return ins; 00864 } 00865 00866 00867 WsAsmIns *ws_asm_call_lib(WsCompiler *compiler, WsUInt32 line, WsUInt8 findex, 00868 WsUInt16 lindex) 00869 { 00870 WsAsmIns *ins = asm_alloc(compiler, WS_ASM_P_CALL_LIB, line); 00871 00872 if (ins) { 00873 ins->ws_findex = findex; 00874 ins->ws_lindex = lindex; 00875 } 00876 00877 return ins; 00878 } 00879 00880 00881 WsAsmIns *ws_asm_call_url(WsCompiler *compiler, WsUInt32 line, WsUInt16 findex, 00882 WsUInt16 urlindex, WsUInt8 args) 00883 { 00884 WsAsmIns *ins = asm_alloc(compiler, WS_ASM_P_CALL_URL, line); 00885 00886 if (ins) { 00887 ins->ws_findex = findex; 00888 ins->ws_lindex = urlindex; 00889 ins->ws_args = args; 00890 } 00891 00892 return ins; 00893 } 00894 00895 00896 WsAsmIns *ws_asm_variable(WsCompiler *compiler, WsUInt32 line, WsUInt16 inst, 00897 WsUInt8 vindex) 00898 { 00899 WsAsmIns *ins = asm_alloc(compiler, inst, line); 00900 00901 if (ins) 00902 ins->ws_vindex = vindex; 00903 00904 return ins; 00905 } 00906 00907 00908 WsAsmIns *ws_asm_load_const(WsCompiler *compiler, WsUInt32 line, 00909 WsUInt16 cindex) 00910 { 00911 WsAsmIns *ins = asm_alloc(compiler, WS_ASM_P_LOAD_CONST, line); 00912 00913 if (ins) 00914 ins->ws_cindex = cindex; 00915 00916 return ins; 00917 } 00918 00919 00920 WsAsmIns *ws_asm_ins(WsCompiler *compiler, WsUInt32 line, WsUInt8 opcode) 00921 { 00922 return asm_alloc(compiler, opcode, line); 00923 } }
|
|
||||||||||||
|
Definition at line 406 of file wsasm.c. 00411 : 00412 ins->ws_offset = (ins->ws_label->offset 00413 - (offset + WS_OPSIZE(ins->type))); 00414 break; 00415 case WS_ASM_TJUMP_FW:
|
|
||||||||||||||||
|
|
|
|
Definition at line 418 of file wsasm.c. References WsAsmInsRec::type. 00420 {
00421 ins->type = WS_ASM_TJUMP_FW_S;
00422 process_again = WS_TRUE;
00423 }
00424 break;
00425
00426 case WS_ASM_TJUMP_FW_W:
00427 ins->ws_offset = (ins->ws_label->offset
00428 - (offset + WS_OPSIZE(ins->type)));
00429
00430 if (ins->ws_offset <= 31) {
00431 ins->type = WS_ASM_TJUMP_FW_S;
00432 process_again = WS_TRUE;
00433 } else if (ins->ws_offset <= 255) {
00434 ins->type = WS_ASM_TJUMP_FW;
00435 process_again = WS_TRUE;
00436 }
00437 break;
00438
00439 case WS_ASM_TJUMP_BW:
00440 ins->ws_offset = offset - ins->ws_label->offset;
00441 break;
00442
00443 case WS_ASM_TJUMP_BW_W:
00444 ins->ws_offset = offset - ins->ws_label->offset;
00445
00446 if (ins->ws_offset <= 255) {
00447 ins->type = WS_ASM_TJUMP_BW;
00448 process_again = WS_TRUE;
00449 }
00450 break;
00451
00452 /*
00453 * The pseudo instructions.
00454 */
00455
00456 case WS_ASM_P_LABEL:
00457 /* Nothing here. */
00458 break;
00459
00460 case WS_ASM_P_JUMP:
00461 if (ins->ws_label->offset == 0) {
00462 /* A forward jump. Let's assume the widest form. */
00463 ins->type = WS_ASM_JUMP_FW_W;
00464 } else {
00465 ins->ws_offset = offset - ins->ws_label->offset;
00466
00467 /* Jump backwards. */
00468 if (ins->ws_offset <= 31) {
00469 ins->type = WS_ASM_JUMP_BW_S;
00470 } else if (ins->ws_offset <= 255) {
00471 ins->type = WS_ASM_JUMP_BW;
00472 } else {
00473 ins->type = WS_ASM_JUMP_BW_W;
00474 }
00475 }
00476 break;
00477
00478 case WS_ASM_P_TJUMP:
00479 if (ins->ws_label->offset == 0) {
00480 /* A forward jump. Let's assume the widest form. */
00481 ins->type = WS_ASM_TJUMP_FW_W;
00482 process_again = WS_TRUE;
00483 } else {
00484 ins->ws_offset = offset - ins->ws_label->offset;
00485
00486 /* Jump backwards. */
00487 if (ins->ws_offset <= 255) {
00488 ins->type = WS_ASM_TJUMP_BW;
00489 } else {
00490 ins->type = WS_ASM_TJUMP_BW_W;
00491 }
00492 }
00493 break;
00494
00495 case WS_ASM_P_CALL:
|
|
||||||||||||||||||||
|
|
|
|
|
|
|
|
|