📄 wsasm.c
字号:
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);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -