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

📄 wsasm.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ====================================================================  * The Kannel Software License, Version 1.0  *  * Copyright (c) 2001-2004 Kannel Group   * Copyright (c) 1998-2001 WapIT Ltd.    * All rights reserved.  *  * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  *  * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  *  * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in  *    the documentation and/or other materials provided with the  *    distribution.  *  * 3. The end-user documentation included with the redistribution,  *    if any, must include the following acknowledgment:  *       "This product includes software developed by the  *        Kannel Group (http://www.kannel.org/)."  *    Alternately, this acknowledgment may appear in the software itself,  *    if and wherever such third-party acknowledgments normally appear.  *  * 4. The names "Kannel" and "Kannel Group" must not be used to  *    endorse or promote products derived from this software without  *    prior written permission. For written permission, please   *    contact org@kannel.org.  *  * 5. Products derived from this software may not be called "Kannel",  *    nor may "Kannel" appear in their name, without prior written  *    permission of the Kannel Group.  *  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,   * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT   * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE   * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  * ====================================================================  *  * This software consists of voluntary contributions made by many  * individuals on behalf of the Kannel Group.  For more information on   * the Kannel Group, please see <http://www.kannel.org/>.  *  * Portions of this software are based upon software originally written at   * WapIT Ltd., Helsinki, Finland for the Kannel project.   */ /* * * 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. */

⌨️ 快捷键说明

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