⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wsasm.c

📁 mms client
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * * wsasm.c * * Author: Markku Rossi <mtr@iki.fi> * * Copyright (c) 1999-2000 WAPIT OY LTD. *		 All rights reserved. * * Byte-code assembler. * */#include "wsint.h"#include "wsasm.h"#include "wsstdlib.h"/********************* Macros to fetch items from BC operands ***********/#define WS_OPNAME(op) (operands[(op)].name)#define WS_OPSIZE(op) (operands[(op)].size)/********************* Byte-code operands *******************************/static struct{    char *name;    int size;} operands[256] = {#include "wsopcodes.h"};/********************* Symbolic assembler instructions ******************//* General helpers. */void ws_asm_link(WsCompiler *compiler, WsAsmIns *ins){    if (compiler->asm_tail) {        compiler->asm_tail->next = ins;        ins->prev = compiler->asm_tail;        compiler->asm_tail = ins;    } else        compiler->asm_tail = compiler->asm_head = ins;}void ws_asm_print(WsCompiler *compiler){    WsAsmIns *ins;    for (ins = compiler->asm_head; ins; ins = ins->next) {        if (ins->type > 0xff) {            /* A symbolic operand. */            switch (ins->type) {            case WS_ASM_P_LABEL:                ws_fprintf(WS_STDOUT, ".L%d:\t\t\t\t/* refcount=%d */\n",                           ins->ws_label_idx, ins->ws_label_refcount);                break;            case WS_ASM_P_JUMP:                ws_fprintf(WS_STDOUT, "\tjump*\t\tL%d\n",                           ins->ws_label->ws_label_idx);                break;            case WS_ASM_P_TJUMP:                ws_fprintf(WS_STDOUT, "\ttjump*\t\tL%d\n",                           ins->ws_label->ws_label_idx);                break;            case WS_ASM_P_CALL:                ws_fprintf(WS_STDOUT, "\tcall*\t\t%s\n",                           compiler->functions[ins->ws_findex].name);                break;            case WS_ASM_P_CALL_LIB:                {                    const char *lib;                    const char *func;                    ws_stdlib_function_name(ins->ws_lindex,                                            ins->ws_findex,                                            &lib, &func);                    ws_fprintf(WS_STDOUT, "\tcall_lib*\t%s.%s\n",                               lib ? lib : "???",                               func ? func : "???");                }                break;            case WS_ASM_P_CALL_URL:                ws_fprintf(WS_STDOUT, "\tcall_url*\t%u %u %u\n",                           ins->ws_lindex, ins->ws_findex, ins->ws_args);                break;            case WS_ASM_P_LOAD_VAR:                ws_fprintf(WS_STDOUT, "\tload_var*\t%u\n", ins->ws_vindex);                break;            case WS_ASM_P_STORE_VAR:                ws_fprintf(WS_STDOUT, "\tstore_var*\t%u\n", ins->ws_vindex);                break;            case WS_ASM_P_INCR_VAR:                ws_fprintf(WS_STDOUT, "\tincr_var*\t%u\n", ins->ws_vindex);                break;            case WS_ASM_P_LOAD_CONST:                ws_fprintf(WS_STDOUT, "\tload_const*\t%u\n", ins->ws_cindex);                break;            }        } else {            WsUInt8 op = WS_ASM_OP(ins->type);            if (operands[op].name) {                /* Operands add_asg and sub_asg are special. */                if (op == WS_ASM_ADD_ASG || op == WS_ASM_SUB_ASG)                    ws_fprintf(WS_STDOUT, "\t%s\t\t%u\n", operands[ins->type].name,                               ins->ws_vindex);                else                    ws_fprintf(WS_STDOUT, "\t%s\n", operands[ins->type].name);            } else                ws_fatal("ws_asm_print(): unknown operand 0x%x", op);        }    }}void ws_asm_dasm(WsCompilerPtr compiler, const unsigned char *code, size_t len){    size_t i = 0;    while (i < len) {        WsUInt8 byt = code[i];        WsUInt8 op;        WsUInt8 arg;        WsUInt8 i8, j8, k8;        WsUInt16 i16, j16;        op = WS_ASM_OP(byt);        arg = WS_ASM_ARG(byt);        ws_fprintf(WS_STDOUT, "%4x:\t%-16s", i, WS_OPNAME(op));        switch (op) {            /* The `short jumps'. */        case WS_ASM_JUMP_FW_S:        case WS_ASM_TJUMP_FW_S:            ws_fprintf(WS_STDOUT, "%x\n", i + WS_OPSIZE(op) + arg);            break;        case WS_ASM_JUMP_BW_S:            ws_fprintf(WS_STDOUT, "%x\n", i - arg);            break;            /* Jumps with WsUInt8 argument. */        case WS_ASM_JUMP_FW:        case WS_ASM_TJUMP_FW:            WS_GET_UINT8(code + i + 1, i8);            ws_fprintf(WS_STDOUT, "%x\n", i + WS_OPSIZE(op) + i8);            break;        case WS_ASM_JUMP_BW:        case WS_ASM_TJUMP_BW:            WS_GET_UINT8(code + i + 1, i8);            ws_fprintf(WS_STDOUT, "%x\n", i - i8);            break;            /* Jumps with wide argument. */        case WS_ASM_JUMP_FW_W:        case WS_ASM_TJUMP_FW_W:            WS_GET_UINT16(code + i + 1, i16);            ws_fprintf(WS_STDOUT, "%x\n", i + WS_OPSIZE(op) + i16);            break;        case WS_ASM_JUMP_BW_W:        case WS_ASM_TJUMP_BW_W:            WS_GET_UINT16(code + i + 1, i16);            ws_fprintf(WS_STDOUT, "%x\n", i - i16);            break;            /* The `short' opcodes. */        case WS_ASM_LOAD_VAR_S:        case WS_ASM_STORE_VAR_S:        case WS_ASM_INCR_VAR_S:            ws_fprintf(WS_STDOUT, "%d\n", arg);            break;            /* Local script function calls. */        case WS_ASM_CALL_S:            ws_fprintf(WS_STDOUT, "%d\n", arg);            break;        case WS_ASM_CALL:            WS_GET_UINT8(code + i + 1, i8);            ws_fprintf(WS_STDOUT, "%d\n", i8);            break;            /* Library calls. */        case WS_ASM_CALL_LIB_S:        case WS_ASM_CALL_LIB:        case WS_ASM_CALL_LIB_W:            {                WsUInt8 findex;                WsUInt16 lindex;                char lnamebuf[64];                char fnamebuf[64];                const char *lname;                const char *fname;                if (op == WS_ASM_CALL_LIB_S) {                    WS_GET_UINT8(code + i + 1, lindex);                    findex = arg;                } else if (op == WS_ASM_CALL_LIB) {                    WS_GET_UINT8(code + i + 1, findex);                    WS_GET_UINT8(code + i + 2, lindex);                } else {                    WS_GET_UINT8(code + i + 1, findex);                    WS_GET_UINT16(code + i + 2, lindex);                }                if (!ws_stdlib_function_name(lindex, findex, &lname, &fname)) {                    snprintf(lnamebuf, sizeof(lnamebuf), "%d", lindex);                    snprintf(fnamebuf, sizeof(lnamebuf), "%d", findex);                    lname = lnamebuf;                    fname = fnamebuf;                }                ws_fprintf(WS_STDOUT, "%s.%s\n", lname, fname);            }            break;            /* URL calls. */        case WS_ASM_CALL_URL:            WS_GET_UINT8(code + i + 1, i8);            WS_GET_UINT8(code + i + 2, j8);            WS_GET_UINT8(code + i + 3, k8);            ws_fprintf(WS_STDOUT, "%d.%d %d\n", i8, j8, k8);            break;        case WS_ASM_CALL_URL_W:            WS_GET_UINT16(code + i + 1, i16);            WS_GET_UINT16(code + i + 3, j16);            WS_GET_UINT8(code + i + 5, i8);            ws_fprintf(WS_STDOUT, "%d.%d %d\n", i16, j16, i8);            break;            /* Constant access. */        case WS_ASM_LOAD_CONST_S:        case WS_ASM_LOAD_CONST:        case WS_ASM_LOAD_CONST_W:            if (op == WS_ASM_LOAD_CONST_S)                i16 = arg;            else if (op == WS_ASM_LOAD_CONST) {                WS_GET_UINT8(code + i + 1, i8);                i16 = i8;            } else                WS_GET_UINT16(code + i + 1, i16);            ws_fprintf(WS_STDOUT, "%d\n", i16);            break;            /* Operands with WsUInt8 argument. */        case WS_ASM_LOAD_VAR:        case WS_ASM_STORE_VAR:        case WS_ASM_INCR_VAR:        case WS_ASM_DECR_VAR:        case WS_ASM_ADD_ASG:        case WS_ASM_SUB_ASG:            WS_GET_UINT8(code + i + 1, i8);            ws_fprintf(WS_STDOUT, "%d\n", i8);            break;            /* The trivial cases. */        default:            ws_fprintf(WS_STDOUT, "\n");            break;        }        i += WS_OPSIZE(op);    }}voidws_asm_linearize(WsCompiler *compiler){    WsAsmIns *ins;    WsBool process_again = WS_TRUE;    /* Calculate all offsets and select real assembler instructions for       our internal pseudo instructions.  This is continued as long as       the code changes. */    while (process_again) {        WsUInt32 offset = 1;        process_again = WS_FALSE;        for (ins = compiler->asm_head; ins; ins = ins->next) {            ins->offset = offset;            switch (ins->type) {            case WS_ASM_JUMP_FW_S:                ins->ws_offset = (ins->ws_label->offset                                  - (offset + WS_OPSIZE(ins->type)));                break;            case WS_ASM_JUMP_FW:                ins->ws_offset = (ins->ws_label->offset                                  - (offset + WS_OPSIZE(ins->type)));                if (ins->ws_offset <= 31) {                    ins->type = WS_ASM_JUMP_FW_S;                    process_again = WS_TRUE;                }                break;            case WS_ASM_JUMP_FW_W:                ins->ws_offset = (ins->ws_label->offset                                  - (offset + WS_OPSIZE(ins->type)));                if (ins->ws_offset <= 31) {                    ins->type = WS_ASM_JUMP_FW_S;                    process_again = WS_TRUE;                } else if (ins->ws_offset <= 255) {                    ins->type = WS_ASM_JUMP_FW;                    process_again = WS_TRUE;                }                break;            case WS_ASM_JUMP_BW_S:                ins->ws_offset = offset - ins->ws_label->offset;                break;            case WS_ASM_JUMP_BW:                ins->ws_offset = offset - ins->ws_label->offset;                if (ins->ws_offset <= 31) {                    ins->type = WS_ASM_JUMP_BW_S;                    process_again = WS_TRUE;                }                break;            case WS_ASM_JUMP_BW_W:                ins->ws_offset = offset - ins->ws_label->offset;                if (ins->ws_offset <= 31) {                    ins->type = WS_ASM_JUMP_BW_S;                    process_again = WS_TRUE;                } else if (ins->ws_offset <= 255) {                    ins->type = WS_ASM_JUMP_BW;                    process_again = WS_TRUE;                }                break;            case WS_ASM_TJUMP_FW_S:                ins->ws_offset = (ins->ws_label->offset                                  - (offset + WS_OPSIZE(ins->type)));                break;            case WS_ASM_TJUMP_FW:                ins->ws_offset = (ins->ws_label->offset                                  - (offset + WS_OPSIZE(ins->type)));                if (ins->ws_offset <= 31) {                    ins->type = WS_ASM_TJUMP_FW_S;                    process_again = WS_TRUE;                }                break;            case WS_ASM_TJUMP_FW_W:                ins->ws_offset = (ins->ws_label->offset                                  - (offset + WS_OPSIZE(ins->type)));                if (ins->ws_offset <= 31) {                    ins->type = WS_ASM_TJUMP_FW_S;                    process_again = WS_TRUE;                } else if (ins->ws_offset <= 255) {                    ins->type = WS_ASM_TJUMP_FW;                    process_again = WS_TRUE;                }                break;            case WS_ASM_TJUMP_BW:                 ins->ws_offset = offset - ins->ws_label->offset;                 break;            case WS_ASM_TJUMP_BW_W:                ins->ws_offset = offset - ins->ws_label->offset;                if (ins->ws_offset <= 255) {                    ins->type = WS_ASM_TJUMP_BW;                    process_again = WS_TRUE;                }                break;                /*                 * The pseudo instructions.                 */            case WS_ASM_P_LABEL:                /* Nothing here. */                break;            case WS_ASM_P_JUMP:                if (ins->ws_label->offset == 0) {                    /* A forward jump.  Let's assume the widest form. */                    ins->type = WS_ASM_JUMP_FW_W;                } else {                    ins->ws_offset = offset - ins->ws_label->offset;                    /* Jump backwards. */                    if (ins->ws_offset <= 31) {                        ins->type = WS_ASM_JUMP_BW_S;                    } else if (ins->ws_offset <= 255) {                        ins->type = WS_ASM_JUMP_BW;                    } else {                        ins->type = WS_ASM_JUMP_BW_W;                    }                }                break;            case WS_ASM_P_TJUMP:                if (ins->ws_label->offset == 0) {                    /* A forward jump.  Let's assume the widest form. */                    ins->type = WS_ASM_TJUMP_FW_W;                    process_again = WS_TRUE;                } else {                    ins->ws_offset = offset - ins->ws_label->offset;                    /* Jump backwards. */                    if (ins->ws_offset <= 255) {                        ins->type = WS_ASM_TJUMP_BW;                    } else {                        ins->type = WS_ASM_TJUMP_BW_W;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -