/* ====================================================================
* The Kannel Software License, Version 1.0
*
* Copyright (c) 2001-2005 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 .
*
* Portions of this software are based upon software originally written at
* WapIT Ltd., Helsinki, Finland for the Kannel project.
*/
/*
*
* wsasm.h
*
* Author: Markku Rossi
*
* Copyright (c) 1999-2000 WAPIT OY LTD.
* All rights reserved.
*
* Byte-code assembler definitions.
*
*/
#ifndef WSASM_H
#define WSASM_H
/********************* Opcodes for the ASM instructions *****************/
/* The instruction classes. */
/* Class 1: 1xxPPPPP */
#define WS_ASM_CLASS1P(op) (((op) & 0x80) == 0x80)
#define WS_ASM_CLASS1_OP(op) ((op) & 0xe0)
#define WS_ASM_CLASS1_ARG(op) ((op) & 0x1f)
/* Class 2: 010xPPPP */
#define WS_ASM_CLASS2P(op) (((op) & 0xe0) == 0x40)
#define WS_ASM_CLASS2_OP(op) ((op) & 0xf0)
#define WS_ASM_CLASS2_ARG(op) ((op) & 0x0f)
/* Class 3: 011xxPPP */
#define WS_ASM_CLASS3P(op) (((op) & 0xe0) == 0x60)
#define WS_ASM_CLASS3_OP(op) ((op) & 0x78)
#define WS_ASM_CLASS3_ARG(op) ((op) & 0x07)
/* Class 4: 00xxxxxx */
#define WS_ASM_CLASS4P(op) (((op) & 0xc0) == 0x00)
#define WS_ASM_CLASS4_OP(op) (op)
/* Get the opcode of the operand `op'. The operand `op' can belong to
any of the classes 1-4. */
#define WS_ASM_OP(op) \
(WS_ASM_CLASS1P(op) \
? WS_ASM_CLASS1_OP(op) \
: (WS_ASM_CLASS2P(op) \
? WS_ASM_CLASS2_OP(op) \
: (WS_ASM_CLASS3P(op) \
? WS_ASM_CLASS3_OP(op) \
: WS_ASM_CLASS4_OP(op))))
/* Get the implicit argument of the operand `op'. The operand `op'
can belong to any of the classes 1-4. For the class 4 operands,
this returns 0. */
#define WS_ASM_ARG(op) \
(WS_ASM_CLASS1P(op) \
? WS_ASM_CLASS1_ARG(op) \
: (WS_ASM_CLASS2P(op) \
? WS_ASM_CLASS2_ARG(op) \
: (WS_ASM_CLASS3P(op) \
? WS_ASM_CLASS3_ARG(op) \
: 0)))
/* Create an operand with implicit argument from the operand `op' and
argument `arg'. */
#define WS_ASM_GLUE(op, arg) ((WsByte) (((WsByte) (op)) | ((WsByte) (arg))))
/* The instruction opcodes. Opcode Binary Size */
#define WS_ASM_JUMP_FW_S 0x80 /* 10000000 1 */
#define WS_ASM_JUMP_FW 0x01 /* 00000001 2 */
#define WS_ASM_JUMP_FW_W 0x02 /* 00000010 3 */
#define WS_ASM_JUMP_BW_S 0xa0 /* 10100000 1 */
#define WS_ASM_JUMP_BW 0x03 /* 00000011 2 */
#define WS_ASM_JUMP_BW_W 0x04 /* 00000100 3 */
#define WS_ASM_TJUMP_FW_S 0xc0 /* 11000000 1 */
#define WS_ASM_TJUMP_FW 0x05 /* 00000101 2 */
#define WS_ASM_TJUMP_FW_W 0x06 /* 00000110 3 */
#define WS_ASM_TJUMP_BW 0x07 /* 00000111 2 */
#define WS_ASM_TJUMP_BW_W 0x08 /* 00001000 3 */
#define WS_ASM_CALL_S 0x60 /* 01100000 1 */
#define WS_ASM_CALL 0x09 /* 00001001 2 */
#define WS_ASM_CALL_LIB_S 0x68 /* 01101000 2 */
#define WS_ASM_CALL_LIB 0x0a /* 00001010 3 */
#define WS_ASM_CALL_LIB_W 0x0b /* 00001011 4 */
#define WS_ASM_CALL_URL 0x0c /* 00001100 4 */
#define WS_ASM_CALL_URL_W 0x0d /* 00001101 6 */
#define WS_ASM_LOAD_VAR_S 0xe0 /* 11100000 1 */
#define WS_ASM_LOAD_VAR 0x0e /* 00001110 2 */
#define WS_ASM_STORE_VAR_S 0x40 /* 01000000 1 */
#define WS_ASM_STORE_VAR 0x0f /* 00001111 2 */
#define WS_ASM_INCR_VAR_S 0x70 /* 01110000 1 */
#define WS_ASM_INCR_VAR 0x10 /* 00010000 2 */
#define WS_ASM_DECR_VAR 0x11 /* 00010001 2 */
#define WS_ASM_LOAD_CONST_S 0x50 /* 01010000 1 */
#define WS_ASM_LOAD_CONST 0x12 /* 00010010 2 */
#define WS_ASM_LOAD_CONST_W 0x13 /* 00010011 3 */
#define WS_ASM_CONST_0 0x14 /* 00010100 1 */
#define WS_ASM_CONST_1 0x15 /* 00010101 1 */
#define WS_ASM_CONST_M1 0x16 /* 00010110 1 */
#define WS_ASM_CONST_ES 0x17 /* 00010111 1 */
#define WS_ASM_CONST_INVALID 0x18 /* 00011000 1 */
#define WS_ASM_CONST_TRUE 0x19 /* 00011001 1 */
#define WS_ASM_CONST_FALSE 0x1a /* 00011010 1 */
#define WS_ASM_INCR 0x1b /* 00011011 1 */
#define WS_ASM_DECR 0x1c /* 00011100 1 */
#define WS_ASM_ADD_ASG 0x1d /* 00011101 2 */
#define WS_ASM_SUB_ASG 0x1e /* 00011110 2 */
#define WS_ASM_UMINUS 0x1f /* 00011111 1 */
#define WS_ASM_ADD 0x20 /* 00100000 1 */
#define WS_ASM_SUB 0x21 /* 00100001 1 */
#define WS_ASM_MUL 0x22 /* 00100010 1 */
#define WS_ASM_DIV 0x23 /* 00100011 1 */
#define WS_ASM_IDIV 0x24 /* 00100100 1 */
#define WS_ASM_REM 0x25 /* 00100101 1 */
#define WS_ASM_B_AND 0x26 /* 00100110 1 */
#define WS_ASM_B_OR 0x27 /* 00100111 1 */
#define WS_ASM_B_XOR 0x28 /* 00101000 1 */
#define WS_ASM_B_NOT 0x29 /* 00101001 1 */
#define WS_ASM_B_LSHIFT 0x2a /* 00101010 1 */
#define WS_ASM_B_RSSHIFT 0x2b /* 00101011 1 */
#define WS_ASM_B_RSZSHIFT 0x2c /* 00101100 1 */
#define WS_ASM_EQ 0x2d /* 00101101 1 */
#define WS_ASM_LE 0x2e /* 00101110 1 */
#define WS_ASM_LT 0x2f /* 00101111 1 */
#define WS_ASM_GE 0x30 /* 00110000 1 */
#define WS_ASM_GT 0x31 /* 00110001 1 */
#define WS_ASM_NE 0x32 /* 00110010 1 */
#define WS_ASM_NOT 0x33 /* 00110011 1 */
#define WS_ASM_SCAND 0x34 /* 00110100 1 */
#define WS_ASM_SCOR 0x35 /* 00110101 1 */
#define WS_ASM_TOBOOL 0x36 /* 00110110 1 */
#define WS_ASM_POP 0x37 /* 00110111 1 */
#define WS_ASM_TYPEOF 0x38 /* 00111000 1 */
#define WS_ASM_ISVALID 0x39 /* 00111001 1 */
#define WS_ASM_RETURN 0x3a /* 00111010 1 */
#define WS_ASM_RETURN_ES 0x3b /* 00111011 1 */
#define WS_ASM_DEBUG 0x3c /* 00111100 1 */
/********************* Pseudo opcodes for assembler *********************/
/* These are pseudo opcodes grouping together several real byte-code
opcodes. These are used in the symbolic assembler. */
#define WS_ASM_P_LABEL 0x0100
#define WS_ASM_P_JUMP 0x0200
#define WS_ASM_P_TJUMP 0x0300
#define WS_ASM_P_CALL 0x0400
#define WS_ASM_P_CALL_LIB 0x0500
#define WS_ASM_P_CALL_URL 0x0600
#define WS_ASM_P_LOAD_VAR 0x0700
#define WS_ASM_P_STORE_VAR 0x0800
#define WS_ASM_P_INCR_VAR 0x0900
#define WS_ASM_P_LOAD_CONST 0x0a00
/* Check whether the instruction `ins' is a pseudo-branch
instruction. */
#define WS_ASM_P_BRANCH(ins) \
((ins)->type == WS_ASM_P_JUMP || (ins)->type == WS_ASM_P_TJUMP)
/********************* Symbolic assembler instructions ******************/
#define ws_label_idx u.ivalues.i1
#define ws_label_refcount u.ivalues.i2
#define ws_findex u.ivalues.i1
#define ws_lindex u.ivalues.i2
#define ws_args u.ivalues.i3
#define ws_vindex u.ivalues.i1
#define ws_cindex u.ivalues.i1
#define ws_label u.branch.label
#define ws_offset u.branch.offset
struct WsAsmInsRec
{
struct WsAsmInsRec *next;
struct WsAsmInsRec *prev;
WsUInt16 type;
/* The source stream line number. */
WsUInt32 line;
/* The operands offset in the linearized byte-code stream. */
WsUInt32 offset;
union
{
/* The target label for branch instructions. */
struct
{
struct WsAsmInsRec *label;
/* The offset argument of the branch operand. This is the
adjustment that must be performed for the pc after this
instruction. */
WsUInt32 offset;
}
branch;
struct
{
WsUInt32 i1;
WsUInt16 i2;
WsUInt16 i3;
}
ivalues;
} u;
};
typedef struct WsAsmInsRec WsAsmIns;
/* Link the instruction `ins' to the end of the symbolic assembler
chain, currently being constructed in `compiler'. */
void ws_asm_link(WsCompilerPtr compiler, WsAsmIns *ins);
/* Print the current assembler instructions of the compiler
`compiler'. */
void ws_asm_print(WsCompilerPtr compiler);
/* Disassemble the byte-code `code', `len' to the standard output. */
void ws_asm_dasm(WsCompilerPtr compiler, const unsigned char *code,
size_t len);
/* Linearize the assembler, currently being constructed in `compiler',
into `compiler->byte_code'. */
void ws_asm_linearize(WsCompilerPtr compiler);
/* Constructors for assembler instructions. */
/* Create a label instruction. */
WsAsmIns *ws_asm_label(WsCompilerPtr compiler, WsUInt32 line);
/* Create a branch instruction `ins' to label `label'. */
WsAsmIns *ws_asm_branch(WsCompilerPtr compiler, WsUInt32 line, WsUInt16 ins,
WsAsmIns *label);
/* Create a local call instruction to function `findex'. */
WsAsmIns *ws_asm_call(WsCompilerPtr compiler, WsUInt32 line, WsUInt8 findex);
/* Create a library call instruction to function `findex' from the
libary `lindex'. */
WsAsmIns *ws_asm_call_lib(WsCompilerPtr compiler, WsUInt32 line,
WsUInt8 findex, WsUInt16 lindex);
/* Create an URL call instruction for function `findex' from the URL
`urlindex' with `args' arguments. The arguments `urlindex' and
`findex' pont to the constant pool. */
WsAsmIns *ws_asm_call_url(WsCompilerPtr compiler, WsUInt32 line,
WsUInt16 findex, WsUInt16 urlindex, WsUInt8 args);
/* Create a variable modification instruction `ins' for the variable
`vindex'. */
WsAsmIns *ws_asm_variable(WsCompilerPtr compiler, WsUInt32 line, WsUInt16 ins,
WsUInt8 vindex);
/* Create a constant loading instruction for the constant `cindex'. */
WsAsmIns *ws_asm_load_const(WsCompilerPtr compiler, WsUInt32 line,
WsUInt16 cindex);
/* Create an instruction `ins'. */
WsAsmIns *ws_asm_ins(WsCompilerPtr compiler, WsUInt32 line, WsUInt8 opcode);
#endif /* not WSASM_H */