wsasm.c
资源名称:gateway-1.2.1 [点击查看]
上传用户:gzpyjq
上传日期:2013-01-31
资源大小:1852k
文件大小:27k
源码类别:
手机WAP编程
开发平台:
WINDOWS
- /*
- *
- * 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:tttt/* refcount=%d */n",
- ins->ws_label_idx, ins->ws_label_refcount);
- break;
- case WS_ASM_P_JUMP:
- ws_fprintf(WS_STDOUT, "tjump*ttL%dn",
- ins->ws_label->ws_label_idx);
- break;
- case WS_ASM_P_TJUMP:
- ws_fprintf(WS_STDOUT, "ttjump*ttL%dn",
- ins->ws_label->ws_label_idx);
- break;
- case WS_ASM_P_CALL:
- ws_fprintf(WS_STDOUT, "tcall*tt%sn",
- 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.%sn",
- lib ? lib : "???",
- func ? func : "???");
- }
- break;
- case WS_ASM_P_CALL_URL:
- ws_fprintf(WS_STDOUT, "tcall_url*t%u %u %un",
- ins->ws_lindex, ins->ws_findex, ins->ws_args);
- break;
- case WS_ASM_P_LOAD_VAR:
- ws_fprintf(WS_STDOUT, "tload_var*t%un", ins->ws_vindex);
- break;
- case WS_ASM_P_STORE_VAR:
- ws_fprintf(WS_STDOUT, "tstore_var*t%un", ins->ws_vindex);
- break;
- case WS_ASM_P_INCR_VAR:
- ws_fprintf(WS_STDOUT, "tincr_var*t%un", ins->ws_vindex);
- break;
- case WS_ASM_P_LOAD_CONST:
- ws_fprintf(WS_STDOUT, "tload_const*t%un", 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%stt%un", operands[ins->type].name,
- ins->ws_vindex);
- else
- ws_fprintf(WS_STDOUT, "t%sn", 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, "%xn", i + WS_OPSIZE(op) + arg);
- break;
- case WS_ASM_JUMP_BW_S:
- ws_fprintf(WS_STDOUT, "%xn", 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, "%xn", 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, "%xn", 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, "%xn", 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, "%xn", 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, "%dn", arg);
- break;
- /* Local script function calls. */
- case WS_ASM_CALL_S:
- ws_fprintf(WS_STDOUT, "%dn", arg);
- break;
- case WS_ASM_CALL:
- WS_GET_UINT8(code + i + 1, i8);
- ws_fprintf(WS_STDOUT, "%dn", 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.%sn", 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 %dn", 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 %dn", 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, "%dn", 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, "%dn", i8);
- break;
- /* The trivial cases. */
- default:
- ws_fprintf(WS_STDOUT, "n");
- break;
- }
- i += WS_OPSIZE(op);
- }
- }
- void
- ws_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;
- }
- }
- break;
- case WS_ASM_P_CALL:
- if (ins->ws_findex <= 7) {
- /* The most compact form. */
- ins->type = WS_ASM_CALL_S;
- } else {
- /* The wider form. */
- ins->type = WS_ASM_CALL;
- }
- break;
- case WS_ASM_P_CALL_LIB:
- if (ins->ws_findex <= 7 && ins->ws_lindex <= 255) {
- /* The most compact form. */
- ins->type = WS_ASM_CALL_LIB_S;
- } else if (ins->ws_findex <= 255 && ins->ws_lindex <= 255) {
- /* The quite compact form. */
- ins->type = WS_ASM_CALL_LIB;
- } else {
- /* The most liberal form. */
- ins->type = WS_ASM_CALL_LIB_W;
- }
- break;
- case WS_ASM_P_CALL_URL:
- if (ins->ws_findex <= 255 && ins->ws_lindex <= 255)
- /* The compact form. */
- ins->type = WS_ASM_CALL_URL;
- else
- ins->type = WS_ASM_CALL_URL_W;
- break;
- case WS_ASM_P_LOAD_VAR:
- if (ins->ws_vindex <= 31)
- /* The compact form. */
- ins->type = WS_ASM_LOAD_VAR_S;
- else
- ins->type = WS_ASM_LOAD_VAR;
- break;
- case WS_ASM_P_STORE_VAR:
- if (ins->ws_vindex <= 15)
- ins->type = WS_ASM_STORE_VAR_S;
- else
- ins->type = WS_ASM_STORE_VAR;
- break;
- case WS_ASM_P_INCR_VAR:
- if (ins->ws_vindex <= 7)
- ins->type = WS_ASM_INCR_VAR_S;
- else
- ins->type = WS_ASM_INCR_VAR;
- break;
- case WS_ASM_P_LOAD_CONST:
- if (ins->ws_cindex <= 15)
- ins->type = WS_ASM_LOAD_CONST_S;
- else if (ins->ws_cindex <= 255)
- ins->type = WS_ASM_LOAD_CONST;
- else
- ins->type = WS_ASM_LOAD_CONST_W;
- break;
- }
- gw_assert(ins->type == WS_ASM_P_LABEL || ins->type < 0x100);
- if (ins->type != WS_ASM_P_LABEL) {
- gw_assert(operands[ins->type].name != NULL);
- offset += operands[ins->type].size;
- }
- }
- }
- /* Ok, ready to linearize the byte-code. */
- for (ins = compiler->asm_head; ins; ins = ins->next) {
- if (ins->type == WS_ASM_P_LABEL)
- continue;
- gw_assert(ins->type <= 0xff);
- switch (ins->type) {
- case WS_ASM_JUMP_FW_S:
- case WS_ASM_JUMP_BW_S:
- case WS_ASM_TJUMP_FW_S:
- if (!ws_encode_buffer(&compiler->byte_code,
- WS_ENC_BYTE,
- WS_ASM_GLUE(ins->type, ins->ws_offset),
- WS_ENC_END))
- goto error;
- break;
- case WS_ASM_JUMP_FW:
- case WS_ASM_JUMP_BW:
- case WS_ASM_TJUMP_FW:
- case WS_ASM_TJUMP_BW:
- if (!ws_encode_buffer(&compiler->byte_code,
- WS_ENC_BYTE, ins->type,
- WS_ENC_UINT8, (WsUInt8) ins->ws_offset,
- WS_ENC_END))
- goto error;
- break;
- case WS_ASM_JUMP_FW_W:
- case WS_ASM_JUMP_BW_W:
- case WS_ASM_TJUMP_FW_W:
- case WS_ASM_TJUMP_BW_W:
- if (!ws_encode_buffer(&compiler->byte_code,
- WS_ENC_BYTE, ins->type,
- WS_ENC_UINT16, (WsUInt16) ins->ws_offset,
- WS_ENC_END))
- goto error;
- break;
- case WS_ASM_CALL_S:
- if (!ws_encode_buffer(&compiler->byte_code,
- WS_ENC_BYTE,
- WS_ASM_GLUE(ins->type, ins->ws_findex),
- WS_ENC_END))
- goto error;
- break;
- case WS_ASM_CALL:
- if (!ws_encode_buffer(&compiler->byte_code,
- WS_ENC_BYTE, (WsByte) ins->type,
- WS_ENC_UINT8, (WsUInt8) ins->ws_findex,
- WS_ENC_END))
- goto error;
- break;
- case WS_ASM_CALL_LIB_S:
- if (!ws_encode_buffer(&compiler->byte_code,
- WS_ENC_BYTE,
- WS_ASM_GLUE(ins->type, ins->ws_findex),
- WS_ENC_UINT8, (WsUInt8) ins->ws_lindex,
- WS_ENC_END))
- goto error;
- break;
- case WS_ASM_CALL_LIB:
- if (!ws_encode_buffer(&compiler->byte_code,
- WS_ENC_BYTE, (WsByte) ins->type,
- WS_ENC_UINT8, (WsUInt8) ins->ws_findex,
- WS_ENC_UINT8, (WsUInt8) ins->ws_lindex,
- WS_ENC_END))
- goto error;
- break;
- case WS_ASM_CALL_LIB_W:
- if (!ws_encode_buffer(&compiler->byte_code,
- WS_ENC_BYTE, (WsByte) ins->type,
- WS_ENC_UINT8, (WsUInt8) ins->ws_findex,
- WS_ENC_UINT16, (WsUInt16) ins->ws_lindex,
- WS_ENC_END))
- goto error;
- break;
- case WS_ASM_CALL_URL:
- if (!ws_encode_buffer(&compiler->byte_code,
- WS_ENC_BYTE, (WsByte) ins->type,
- WS_ENC_UINT8, (WsUInt8) ins->ws_lindex,
- WS_ENC_UINT8, (WsUInt8) ins->ws_findex,
- WS_ENC_UINT8, (WsUInt8) ins->ws_args,
- WS_ENC_END))
- goto error;
- break;
- case WS_ASM_CALL_URL_W:
- if (!ws_encode_buffer(&compiler->byte_code,
- WS_ENC_BYTE, (WsByte) ins->type,
- WS_ENC_UINT16, (WsUInt16) ins->ws_lindex,
- WS_ENC_UINT16, (WsUInt16) ins->ws_findex,
- WS_ENC_UINT8, (WsUInt8) ins->ws_args,
- WS_ENC_END))
- goto error;
- break;
- case WS_ASM_LOAD_VAR_S:
- case WS_ASM_STORE_VAR_S:
- if (!ws_encode_buffer(&compiler->byte_code,
- WS_ENC_BYTE,
- WS_ASM_GLUE(ins->type, ins->ws_vindex),
- WS_ENC_END))
- goto error;
- break;
- case WS_ASM_LOAD_VAR:
- case WS_ASM_STORE_VAR:
- if (!ws_encode_buffer(&compiler->byte_code,
- WS_ENC_BYTE, (WsByte) ins->type,
- WS_ENC_UINT8, (WsUInt8) ins->ws_vindex,
- WS_ENC_END))
- goto error;
- break;
- case WS_ASM_INCR_VAR_S:
- if (!ws_encode_buffer(&compiler->byte_code,
- WS_ENC_BYTE,
- WS_ASM_GLUE(ins->type, ins->ws_vindex),
- WS_ENC_END))
- goto error;
- break;
- case WS_ASM_INCR_VAR:
- case WS_ASM_DECR_VAR:
- if (!ws_encode_buffer(&compiler->byte_code,
- WS_ENC_BYTE, (WsByte) ins->type,
- WS_ENC_UINT8, (WsUInt8) ins->ws_vindex,
- WS_ENC_END))
- goto error;
- break;
- case WS_ASM_LOAD_CONST_S:
- if (!ws_encode_buffer(&compiler->byte_code,
- WS_ENC_BYTE,
- WS_ASM_GLUE(ins->type, ins->ws_cindex),
- WS_ENC_END))
- goto error;
- break;
- case WS_ASM_LOAD_CONST:
- if (!ws_encode_buffer(&compiler->byte_code,
- WS_ENC_BYTE, (WsByte) ins->type,
- WS_ENC_UINT8, (WsUInt8) ins->ws_cindex,
- WS_ENC_END))
- goto error;
- break;
- case WS_ASM_LOAD_CONST_W:
- if (!ws_encode_buffer(&compiler->byte_code,
- WS_ENC_BYTE, (WsByte) ins->type,
- WS_ENC_UINT16, (WsUInt16) ins->ws_cindex,
- WS_ENC_END))
- goto error;
- break;
- case WS_ASM_ADD_ASG:
- case WS_ASM_SUB_ASG:
- if (!ws_encode_buffer(&compiler->byte_code,
- WS_ENC_BYTE, (WsByte) ins->type,
- WS_ENC_UINT8, (WsUInt8) ins->ws_vindex,
- WS_ENC_END))
- goto error;
- break;
- case WS_ASM_CONST_0:
- case WS_ASM_CONST_1:
- case WS_ASM_CONST_M1:
- case WS_ASM_CONST_ES:
- case WS_ASM_CONST_INVALID:
- case WS_ASM_CONST_TRUE:
- case WS_ASM_CONST_FALSE:
- case WS_ASM_INCR:
- case WS_ASM_DECR:
- case WS_ASM_UMINUS:
- case WS_ASM_ADD:
- case WS_ASM_SUB:
- case WS_ASM_MUL:
- case WS_ASM_DIV:
- case WS_ASM_IDIV:
- case WS_ASM_REM:
- case WS_ASM_B_AND:
- case WS_ASM_B_OR:
- case WS_ASM_B_XOR:
- case WS_ASM_B_NOT:
- case WS_ASM_B_LSHIFT:
- case WS_ASM_B_RSSHIFT:
- case WS_ASM_B_RSZSHIFT:
- case WS_ASM_EQ:
- case WS_ASM_LE:
- case WS_ASM_LT:
- case WS_ASM_GE:
- case WS_ASM_GT:
- case WS_ASM_NE:
- case WS_ASM_NOT:
- case WS_ASM_SCAND:
- case WS_ASM_SCOR:
- case WS_ASM_TOBOOL:
- case WS_ASM_POP:
- case WS_ASM_TYPEOF:
- case WS_ASM_ISVALID:
- case WS_ASM_RETURN:
- case WS_ASM_RETURN_ES:
- case WS_ASM_DEBUG:
- if (!ws_encode_buffer(&compiler->byte_code,
- WS_ENC_BYTE, (WsByte) ins->type,
- WS_ENC_END))
- goto error;
- break;
- default:
- ws_fatal("ws_asm_linearize(): unknown instruction 0x%02x",
- ins->type);
- break;
- }
- }
- /*
- * Avoid generating 0-length functions, because not all clients
- * handle them correctly.
- */
- if (ws_buffer_len(&compiler->byte_code) == 0) {
- if (!ws_encode_buffer(&compiler->byte_code,
- WS_ENC_BYTE, (WsByte) WS_ASM_RETURN_ES,
- WS_ENC_END))
- goto error;
- }
- return;
- /*
- * Error handling.
- */
- error:
- ws_error_memory(compiler);
- return;
- }
- /* Contructors for assembler instructions. */
- static WsAsmIns *asm_alloc(WsCompiler *compiler, WsUInt16 type, WsUInt32 line)
- {
- WsAsmIns *ins = ws_f_calloc(compiler->pool_asm, 1, sizeof(*ins));
- if (ins == NULL)
- ws_error_memory(compiler);
- else {
- ins->type = type;
- ins->line = line;
- }
- return ins;
- }
- WsAsmIns *ws_asm_label(WsCompiler *compiler, WsUInt32 line)
- {
- WsAsmIns *ins = asm_alloc(compiler, WS_ASM_P_LABEL, line);
- if (ins)
- ins->ws_label_idx = compiler->next_label++;
- return ins;
- }
- WsAsmIns *ws_asm_branch(WsCompiler *compiler, WsUInt32 line, WsUInt16 inst,
- WsAsmIns *label)
- {
- WsAsmIns *ins = asm_alloc(compiler, inst, line);
- if (ins) {
- ins->ws_label = label;
- label->ws_label_refcount++;
- }
- return ins;
- }
- WsAsmIns *ws_asm_call(WsCompiler *compiler, WsUInt32 line, WsUInt8 findex)
- {
- WsAsmIns *ins = asm_alloc(compiler, WS_ASM_P_CALL, line);
- if (ins)
- ins->ws_findex = findex;
- return ins;
- }
- WsAsmIns *ws_asm_call_lib(WsCompiler *compiler, WsUInt32 line, WsUInt8 findex,
- WsUInt16 lindex)
- {
- WsAsmIns *ins = asm_alloc(compiler, WS_ASM_P_CALL_LIB, line);
- if (ins) {
- ins->ws_findex = findex;
- ins->ws_lindex = lindex;
- }
- return ins;
- }
- WsAsmIns *ws_asm_call_url(WsCompiler *compiler, WsUInt32 line, WsUInt16 findex,
- WsUInt16 urlindex, WsUInt8 args)
- {
- WsAsmIns *ins = asm_alloc(compiler, WS_ASM_P_CALL_URL, line);
- if (ins) {
- ins->ws_findex = findex;
- ins->ws_lindex = urlindex;
- ins->ws_args = args;
- }
- return ins;
- }
- WsAsmIns *ws_asm_variable(WsCompiler *compiler, WsUInt32 line, WsUInt16 inst,
- WsUInt8 vindex)
- {
- WsAsmIns *ins = asm_alloc(compiler, inst, line);
- if (ins)
- ins->ws_vindex = vindex;
- return ins;
- }
- WsAsmIns *ws_asm_load_const(WsCompiler *compiler, WsUInt32 line,
- WsUInt16 cindex)
- {
- WsAsmIns *ins = asm_alloc(compiler, WS_ASM_P_LOAD_CONST, line);
- if (ins)
- ins->ws_cindex = cindex;
- return ins;
- }
- WsAsmIns *ws_asm_ins(WsCompiler *compiler, WsUInt32 line, WsUInt8 opcode)
- {
- return asm_alloc(compiler, opcode, line);
- }