00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 #include "wsint.h"
00071 #include "wsasm.h"
00072 #include "wsstdlib.h"
00073
00074
00075
00076 #define WS_OPNAME(op) (operands[(op)].name)
00077 #define WS_OPSIZE(op) (operands[(op)].size)
00078
00079
00080
00081 static struct
00082 {
00083 char *name;
00084 int size;
00085 } operands[256] = {
00086 #include "wsopcodes.h"
00087 };
00088
00089
00090
00091
00092
00093 void ws_asm_link(WsCompiler *compiler, WsAsmIns *ins)
00094 {
00095 if (compiler->asm_tail) {
00096 compiler->asm_tail->next = ins;
00097 ins->prev = compiler->asm_tail;
00098
00099 compiler->asm_tail = ins;
00100 } else
00101 compiler->asm_tail = compiler->asm_head = ins;
00102 }
00103
00104
00105 void ws_asm_print(WsCompiler *compiler)
00106 {
00107 WsAsmIns *ins;
00108
00109 for (ins = compiler->asm_head; ins; ins = ins->next) {
00110 if (ins->type > 0xff) {
00111
00112 switch (ins->type) {
00113 case WS_ASM_P_LABEL:
00114 ws_fprintf(WS_STDOUT, ".L%d:\t\t\t\t/* refcount=%d */\n",
00115 ins->ws_label_idx, ins->ws_label_refcount);
00116 break;
00117
00118 case WS_ASM_P_JUMP:
00119 ws_fprintf(WS_STDOUT, "\tjump*\t\tL%d\n",
00120 ins->ws_label->ws_label_idx);
00121 break;
00122
00123 case WS_ASM_P_TJUMP:
00124 ws_fprintf(WS_STDOUT, "\ttjump*\t\tL%d\n",
00125 ins->ws_label->ws_label_idx);
00126 break;
00127
00128 case WS_ASM_P_CALL:
00129 ws_fprintf(WS_STDOUT, "\tcall*\t\t%s\n",
00130 compiler->functions[ins->ws_findex].name);
00131 break;
00132
00133 case WS_ASM_P_CALL_LIB:
00134 {
00135 const char *lib;
00136 const char *func;
00137
00138 ws_stdlib_function_name(ins->ws_lindex,
00139 ins->ws_findex,
00140 &lib, &func);
00141 ws_fprintf(WS_STDOUT, "\tcall_lib*\t%s.%s\n",
00142 lib ? lib : "???",
00143 func ? func : "???");
00144 }
00145 break;
00146
00147 case WS_ASM_P_CALL_URL:
00148 ws_fprintf(WS_STDOUT, "\tcall_url*\t%u %u %u\n",
00149 ins->ws_lindex, ins->ws_findex, ins->ws_args);
00150 break;
00151
00152 case WS_ASM_P_LOAD_VAR:
00153 ws_fprintf(WS_STDOUT, "\tload_var*\t%u\n", ins->ws_vindex);
00154 break;
00155
00156 case WS_ASM_P_STORE_VAR:
00157 ws_fprintf(WS_STDOUT, "\tstore_var*\t%u\n", ins->ws_vindex);
00158 break;
00159
00160 case WS_ASM_P_INCR_VAR:
00161 ws_fprintf(WS_STDOUT, "\tincr_var*\t%u\n", ins->ws_vindex);
00162 break;
00163
00164 case WS_ASM_P_LOAD_CONST:
00165 ws_fprintf(WS_STDOUT, "\tload_const*\t%u\n", ins->ws_cindex);
00166 break;
00167 }
00168 } else {
00169 WsUInt8 op = WS_ASM_OP(ins->type);
00170
00171 if (operands[op].name) {
00172
00173 if (op == WS_ASM_ADD_ASG || op == WS_ASM_SUB_ASG)
00174 ws_fprintf(WS_STDOUT, "\t%s\t\t%u\n", operands[ins->type].name,
00175 ins->ws_vindex);
00176 else
00177 ws_fprintf(WS_STDOUT, "\t%s\n", operands[ins->type].name);
00178 } else
00179 ws_fatal("ws_asm_print(): unknown operand 0x%x", op);
00180 }
00181 }
00182 }
00183
00184
00185 void ws_asm_dasm(WsCompilerPtr compiler, const unsigned char *code, size_t len)
00186 {
00187 size_t i = 0;
00188
00189 while (i < len) {
00190 WsUInt8 byt = code[i];
00191 WsUInt8 op;
00192 WsUInt8 arg;
00193 WsUInt8 i8, j8, k8;
00194 WsUInt16 i16, j16;
00195
00196 op = WS_ASM_OP(byt);
00197 arg = WS_ASM_ARG(byt);
00198
00199 ws_fprintf(WS_STDOUT, "%4x:\t%-16s", i, WS_OPNAME(op));
00200
00201 switch (op) {
00202
00203 case WS_ASM_JUMP_FW_S:
00204 case WS_ASM_TJUMP_FW_S:
00205 ws_fprintf(WS_STDOUT, "%x\n", i + WS_OPSIZE(op) + arg);
00206 break;
00207
00208 case WS_ASM_JUMP_BW_S:
00209 ws_fprintf(WS_STDOUT, "%x\n", i - arg);
00210 break;
00211
00212
00213 case WS_ASM_JUMP_FW:
00214 case WS_ASM_TJUMP_FW:
00215 WS_GET_UINT8(code + i + 1, i8);
00216 ws_fprintf(WS_STDOUT, "%x\n", i + WS_OPSIZE(op) + i8);
00217 break;
00218
00219 case WS_ASM_JUMP_BW:
00220 case WS_ASM_TJUMP_BW:
00221 WS_GET_UINT8(code + i + 1, i8);
00222 ws_fprintf(WS_STDOUT, "%x\n", i - i8);
00223 break;
00224
00225
00226 case WS_ASM_JUMP_FW_W:
00227 case WS_ASM_TJUMP_FW_W:
00228 WS_GET_UINT16(code + i + 1, i16);
00229 ws_fprintf(WS_STDOUT, "%x\n", i + WS_OPSIZE(op) + i16);
00230 break;
00231
00232 case WS_ASM_JUMP_BW_W:
00233 case WS_ASM_TJUMP_BW_W:
00234 WS_GET_UINT16(code + i + 1, i16);
00235 ws_fprintf(WS_STDOUT, "%x\n", i - i16);
00236 break;
00237
00238
00239 case WS_ASM_LOAD_VAR_S:
00240 case WS_ASM_STORE_VAR_S:
00241 case WS_ASM_INCR_VAR_S:
00242 ws_fprintf(WS_STDOUT, "%d\n", arg);
00243 break;
00244
00245
00246 case WS_ASM_CALL_S:
00247 ws_fprintf(WS_STDOUT, "%d\n", arg);
00248 break;
00249
00250 case WS_ASM_CALL:
00251 WS_GET_UINT8(code + i + 1, i8);
00252 ws_fprintf(WS_STDOUT, "%d\n", i8);
00253 break;
00254
00255
00256 case WS_ASM_CALL_LIB_S:
00257 case WS_ASM_CALL_LIB:
00258 case WS_ASM_CALL_LIB_W:
00259 {
00260 WsUInt8 findex;
00261 WsUInt16 lindex;
00262 char lnamebuf[64];
00263 char fnamebuf[64];
00264 const char *lname;
00265 const char *fname;
00266
00267 if (op == WS_ASM_CALL_LIB_S) {
00268 WS_GET_UINT8(code + i + 1, lindex);
00269 findex = arg;
00270 } else if (op == WS_ASM_CALL_LIB) {
00271 WS_GET_UINT8(code + i + 1, findex);
00272 WS_GET_UINT8(code + i + 2, lindex);
00273 } else {
00274 WS_GET_UINT8(code + i + 1, findex);
00275 WS_GET_UINT16(code + i + 2, lindex);
00276 }
00277
00278 if (!ws_stdlib_function_name(lindex, findex, &lname, &fname)) {
00279 snprintf(lnamebuf, sizeof(lnamebuf), "%d", lindex);
00280 snprintf(fnamebuf, sizeof(lnamebuf), "%d", findex);
00281 lname = lnamebuf;
00282 fname = fnamebuf;
00283 }
00284 ws_fprintf(WS_STDOUT, "%s.%s\n", lname, fname);
00285 }
00286 break;
00287
00288
00289 case WS_ASM_CALL_URL:
00290 WS_GET_UINT8(code + i + 1, i8);
00291 WS_GET_UINT8(code + i + 2, j8);
00292 WS_GET_UINT8(code + i + 3, k8);
00293 ws_fprintf(WS_STDOUT, "%d.%d %d\n", i8, j8, k8);
00294 break;
00295
00296 case WS_ASM_CALL_URL_W:
00297 WS_GET_UINT16(code + i + 1, i16);
00298 WS_GET_UINT16(code + i + 3, j16);
00299 WS_GET_UINT8(code + i + 5, i8);
00300 ws_fprintf(WS_STDOUT, "%d.%d %d\n", i16, j16, i8);
00301 break;
00302
00303
00304 case WS_ASM_LOAD_CONST_S:
00305 case WS_ASM_LOAD_CONST:
00306 case WS_ASM_LOAD_CONST_W:
00307 if (op == WS_ASM_LOAD_CONST_S)
00308 i16 = arg;
00309 else if (op == WS_ASM_LOAD_CONST) {
00310 WS_GET_UINT8(code + i + 1, i8);
00311 i16 = i8;
00312 } else
00313 WS_GET_UINT16(code + i + 1, i16);
00314
00315 ws_fprintf(WS_STDOUT, "%d\n", i16);
00316 break;
00317
00318
00319 case WS_ASM_LOAD_VAR:
00320 case WS_ASM_STORE_VAR:
00321 case WS_ASM_INCR_VAR:
00322 case WS_ASM_DECR_VAR:
00323 case WS_ASM_ADD_ASG:
00324 case WS_ASM_SUB_ASG:
00325 WS_GET_UINT8(code + i + 1, i8);
00326 ws_fprintf(WS_STDOUT, "%d\n", i8);
00327 break;
00328
00329
00330 default:
00331 ws_fprintf(WS_STDOUT, "\n");
00332 break;
00333 }
00334
00335 i += WS_OPSIZE(op);
00336 }
00337 }
00338
00339
00340 void
00341 ws_asm_linearize(WsCompiler *compiler)
00342 {
00343 WsAsmIns *ins;
00344 WsBool process_again = WS_TRUE;
00345
00346
00347
00348
00349 while (process_again) {
00350 WsUInt32 offset = 1;
00351
00352 process_again = WS_FALSE;
00353
00354 for (ins = compiler->asm_head; ins; ins = ins->next) {
00355 ins->offset = offset;
00356
00357 switch (ins->type) {
00358 case WS_ASM_JUMP_FW_S:
00359 ins->ws_offset = (ins->ws_label->offset
00360 - (offset + WS_OPSIZE(ins->type)));
00361 break;
00362
00363 case WS_ASM_JUMP_FW:
00364 ins->ws_offset = (ins->ws_label->offset
00365 - (offset + WS_OPSIZE(ins->type)));
00366
00367 if (ins->ws_offset <= 31) {
00368 ins->type = WS_ASM_JUMP_FW_S;
00369 process_again = WS_TRUE;
00370 }
00371 break;
00372
00373 case WS_ASM_JUMP_FW_W:
00374 ins->ws_offset = (ins->ws_label->offset
00375 - (offset + WS_OPSIZE(ins->type)));
00376
00377 if (ins->ws_offset <= 31) {
00378 ins->type = WS_ASM_JUMP_FW_S;
00379 process_again = WS_TRUE;
00380 } else if (ins->ws_offset <= 255) {
00381 ins->type = WS_ASM_JUMP_FW;
00382 process_again = WS_TRUE;
00383 }
00384 break;
00385
00386 case WS_ASM_JUMP_BW_S:
00387 ins->ws_offset = offset - ins->ws_label->offset;
00388 break;
00389
00390 case WS_ASM_JUMP_BW:
00391 ins->ws_offset = offset - ins->ws_label->offset;
00392
00393 if (ins->ws_offset <= 31) {
00394 ins->type = WS_ASM_JUMP_BW_S;
00395 process_again = WS_TRUE;
00396 }
00397 break;
00398
00399 case WS_ASM_JUMP_BW_W:
00400 ins->ws_offset = offset - ins->ws_label->offset;
00401
00402 if (ins->ws_offset <= 31) {
00403 ins->type = WS_ASM_JUMP_BW_S;
00404 process_again = WS_TRUE;
00405 } else if (ins->ws_offset <= 255) {
00406 ins->type = WS_ASM_JUMP_BW;
00407 process_again = WS_TRUE;
00408 }
00409 break;
00410
00411 case WS_ASM_TJUMP_FW_S:
00412 ins->ws_offset = (ins->ws_label->offset
00413 - (offset + WS_OPSIZE(ins->type)));
00414 break;
00415
00416 case WS_ASM_TJUMP_FW:
00417 ins->ws_offset = (ins->ws_label->offset
00418 - (offset + WS_OPSIZE(ins->type)));
00419
00420 if (ins->ws_offset <= 31) {
00421 ins->type = WS_ASM_TJUMP_FW_S;
00422 process_again = WS_TRUE;
00423 }
00424 break;
00425
00426 case WS_ASM_TJUMP_FW_W:
00427 ins->ws_offset = (ins->ws_label->offset
00428 - (offset + WS_OPSIZE(ins->type)));
00429
00430 if (ins->ws_offset <= 31) {
00431 ins->type = WS_ASM_TJUMP_FW_S;
00432 process_again = WS_TRUE;
00433 } else if (ins->ws_offset <= 255) {
00434 ins->type = WS_ASM_TJUMP_FW;
00435 process_again = WS_TRUE;
00436 }
00437 break;
00438
00439 case WS_ASM_TJUMP_BW:
00440 ins->ws_offset = offset - ins->ws_label->offset;
00441 break;
00442
00443 case WS_ASM_TJUMP_BW_W:
00444 ins->ws_offset = offset - ins->ws_label->offset;
00445
00446 if (ins->ws_offset <= 255) {
00447 ins->type = WS_ASM_TJUMP_BW;
00448 process_again = WS_TRUE;
00449 }
00450 break;
00451
00452
00453
00454
00455
00456 case WS_ASM_P_LABEL:
00457
00458 break;
00459
00460 case WS_ASM_P_JUMP:
00461 if (ins->ws_label->offset == 0) {
00462
00463 ins->type = WS_ASM_JUMP_FW_W;
00464 } else {
00465 ins->ws_offset = offset - ins->ws_label->offset;
00466
00467
00468 if (ins->ws_offset <= 31) {
00469 ins->type = WS_ASM_JUMP_BW_S;
00470 } else if (ins->ws_offset <= 255) {
00471 ins->type = WS_ASM_JUMP_BW;
00472 } else {
00473 ins->type = WS_ASM_JUMP_BW_W;
00474 }
00475 }
00476 break;
00477
00478 case WS_ASM_P_TJUMP:
00479 if (ins->ws_label->offset == 0) {
00480
00481 ins->type = WS_ASM_TJUMP_FW_W;
00482 process_again = WS_TRUE;
00483 } else {
00484 ins->ws_offset = offset - ins->ws_label->offset;
00485
00486
00487 if (ins->ws_offset <= 255) {
00488 ins->type = WS_ASM_TJUMP_BW;
00489 } else {
00490 ins->type = WS_ASM_TJUMP_BW_W;
00491 }
00492 }
00493 break;
00494
00495 case WS_ASM_P_CALL:
00496 if (ins->ws_findex <= 7) {
00497
00498 ins->type = WS_ASM_CALL_S;
00499 } else {
00500
00501 ins->type = WS_ASM_CALL;
00502 }
00503 break;
00504
00505 case WS_ASM_P_CALL_LIB:
00506 if (ins->ws_findex <= 7 && ins->ws_lindex <= 255) {
00507
00508 ins->type = WS_ASM_CALL_LIB_S;
00509 } else if (ins->ws_findex <= 255 && ins->ws_lindex <= 255) {
00510
00511 ins->type = WS_ASM_CALL_LIB;
00512 } else {
00513
00514 ins->type = WS_ASM_CALL_LIB_W;
00515 }
00516 break;
00517
00518 case WS_ASM_P_CALL_URL:
00519 if (ins->ws_findex <= 255 && ins->ws_lindex <= 255)
00520
00521 ins->type = WS_ASM_CALL_URL;
00522 else
00523 ins->type = WS_ASM_CALL_URL_W;
00524 break;
00525
00526 case WS_ASM_P_LOAD_VAR:
00527 if (ins->ws_vindex <= 31)
00528
00529 ins->type = WS_ASM_LOAD_VAR_S;
00530 else
00531 ins->type = WS_ASM_LOAD_VAR;
00532 break;
00533
00534 case WS_ASM_P_STORE_VAR:
00535 if (ins->ws_vindex <= 15)
00536 ins->type = WS_ASM_STORE_VAR_S;
00537 else
00538 ins->type = WS_ASM_STORE_VAR;
00539 break;
00540
00541 case WS_ASM_P_INCR_VAR:
00542 if (ins->ws_vindex <= 7)
00543 ins->type = WS_ASM_INCR_VAR_S;
00544 else
00545 ins->type = WS_ASM_INCR_VAR;
00546 break;
00547
00548 case WS_ASM_P_LOAD_CONST:
00549 if (ins->ws_cindex <= 15)
00550 ins->type = WS_ASM_LOAD_CONST_S;
00551 else if (ins->ws_cindex <= 255)
00552 ins->type = WS_ASM_LOAD_CONST;
00553 else
00554 ins->type = WS_ASM_LOAD_CONST_W;
00555 break;
00556 }
00557
00558 gw_assert(ins->type == WS_ASM_P_LABEL || ins->type < 0x100);
00559
00560 if (ins->type != WS_ASM_P_LABEL) {
00561 gw_assert(operands[ins->type].name != NULL);
00562 offset += operands[ins->type].size;
00563 }
00564 }
00565 }
00566
00567
00568 for (ins = compiler->asm_head; ins; ins = ins->next) {
00569 if (ins->type == WS_ASM_P_LABEL)
00570 continue;
00571
00572 gw_assert(ins->type <= 0xff);
00573
00574 switch (ins->type) {
00575 case WS_ASM_JUMP_FW_S:
00576 case WS_ASM_JUMP_BW_S:
00577 case WS_ASM_TJUMP_FW_S:
00578 if (!ws_encode_buffer(&compiler->byte_code,
00579 WS_ENC_BYTE,
00580 WS_ASM_GLUE(ins->type, ins->ws_offset),
00581 WS_ENC_END))
00582 goto error;
00583 break;
00584
00585 case WS_ASM_JUMP_FW:
00586 case WS_ASM_JUMP_BW:
00587 case WS_ASM_TJUMP_FW:
00588 case WS_ASM_TJUMP_BW:
00589 if (!ws_encode_buffer(&compiler->byte_code,
00590 WS_ENC_BYTE, ins->type,
00591 WS_ENC_UINT8, (WsUInt8) ins->ws_offset,
00592 WS_ENC_END))
00593 goto error;
00594 break;
00595
00596 case WS_ASM_JUMP_FW_W:
00597 case WS_ASM_JUMP_BW_W:
00598 case WS_ASM_TJUMP_FW_W:
00599 case WS_ASM_TJUMP_BW_W:
00600 if (!ws_encode_buffer(&compiler->byte_code,
00601 WS_ENC_BYTE, ins->type,
00602 WS_ENC_UINT16, (WsUInt16) ins->ws_offset,
00603 WS_ENC_END))
00604 goto error;
00605 break;
00606
00607 case WS_ASM_CALL_S:
00608 if (!ws_encode_buffer(&compiler->byte_code,
00609 WS_ENC_BYTE,
00610 WS_ASM_GLUE(ins->type, ins->ws_findex),
00611 WS_ENC_END))
00612 goto error;
00613 break;
00614
00615 case WS_ASM_CALL:
00616 if (!ws_encode_buffer(&compiler->byte_code,
00617 WS_ENC_BYTE, (WsByte) ins->type,
00618 WS_ENC_UINT8, (WsUInt8) ins->ws_findex,
00619 WS_ENC_END))
00620 goto error;
00621 break;
00622
00623 case WS_ASM_CALL_LIB_S:
00624 if (!ws_encode_buffer(&compiler->byte_code,
00625 WS_ENC_BYTE,
00626 WS_ASM_GLUE(ins->type, ins->ws_findex),
00627 WS_ENC_UINT8, (WsUInt8) ins->ws_lindex,
00628 WS_ENC_END))
00629 goto error;
00630 break;
00631
00632 case WS_ASM_CALL_LIB:
00633 if (!ws_encode_buffer(&compiler->byte_code,
00634 WS_ENC_BYTE, (WsByte) ins->type,
00635 WS_ENC_UINT8, (WsUInt8) ins->ws_findex,
00636 WS_ENC_UINT8, (WsUInt8) ins->ws_lindex,
00637 WS_ENC_END))
00638 goto error;
00639 break;
00640
00641 case WS_ASM_CALL_LIB_W:
00642 if (!ws_encode_buffer(&compiler->byte_code,
00643 WS_ENC_BYTE, (WsByte) ins->type,
00644 WS_ENC_UINT8, (WsUInt8) ins->ws_findex,
00645 WS_ENC_UINT16, (WsUInt16) ins->ws_lindex,
00646 WS_ENC_END))
00647 goto error;
00648 break;
00649
00650 case WS_ASM_CALL_URL:
00651 if (!ws_encode_buffer(&compiler->byte_code,
00652 WS_ENC_BYTE, (WsByte) ins->type,
00653 WS_ENC_UINT8, (WsUInt8) ins->ws_lindex,
00654 WS_ENC_UINT8, (WsUInt8) ins->ws_findex,
00655 WS_ENC_UINT8, (WsUInt8) ins->ws_args,
00656 WS_ENC_END))
00657 goto error;
00658 break;
00659
00660 case WS_ASM_CALL_URL_W:
00661 if (!ws_encode_buffer(&compiler->byte_code,
00662 WS_ENC_BYTE, (WsByte) ins->type,
00663 WS_ENC_UINT16, (WsUInt16) ins->ws_lindex,
00664 WS_ENC_UINT16, (WsUInt16) ins->ws_findex,
00665 WS_ENC_UINT8, (WsUInt8) ins->ws_args,
00666 WS_ENC_END))
00667 goto error;
00668 break;
00669
00670 case WS_ASM_LOAD_VAR_S:
00671 case WS_ASM_STORE_VAR_S:
00672 if (!ws_encode_buffer(&compiler->byte_code,
00673 WS_ENC_BYTE,
00674 WS_ASM_GLUE(ins->type, ins->ws_vindex),
00675 WS_ENC_END))
00676 goto error;
00677 break;
00678
00679 case WS_ASM_LOAD_VAR:
00680 case WS_ASM_STORE_VAR:
00681 if (!ws_encode_buffer(&compiler->byte_code,
00682 WS_ENC_BYTE, (WsByte) ins->type,
00683 WS_ENC_UINT8, (WsUInt8) ins->ws_vindex,
00684 WS_ENC_END))
00685 goto error;
00686 break;
00687
00688 case WS_ASM_INCR_VAR_S:
00689 if (!ws_encode_buffer(&compiler->byte_code,
00690 WS_ENC_BYTE,
00691 WS_ASM_GLUE(ins->type, ins->ws_vindex),
00692 WS_ENC_END))
00693 goto error;
00694 break;
00695
00696 case WS_ASM_INCR_VAR:
00697 case WS_ASM_DECR_VAR:
00698 if (!ws_encode_buffer(&compiler->byte_code,
00699 WS_ENC_BYTE, (WsByte) ins->type,
00700 WS_ENC_UINT8, (WsUInt8) ins->ws_vindex,
00701 WS_ENC_END))
00702 goto error;
00703 break;
00704
00705 case WS_ASM_LOAD_CONST_S:
00706 if (!ws_encode_buffer(&compiler->byte_code,
00707 WS_ENC_BYTE,
00708 WS_ASM_GLUE(ins->type, ins->ws_cindex),
00709 WS_ENC_END))
00710 goto error;
00711 break;
00712
00713 case WS_ASM_LOAD_CONST:
00714 if (!ws_encode_buffer(&compiler->byte_code,
00715 WS_ENC_BYTE, (WsByte) ins->type,
00716 WS_ENC_UINT8, (WsUInt8) ins->ws_cindex,
00717 WS_ENC_END))
00718 goto error;
00719 break;
00720
00721 case WS_ASM_LOAD_CONST_W:
00722 if (!ws_encode_buffer(&compiler->byte_code,
00723 WS_ENC_BYTE, (WsByte) ins->type,
00724 WS_ENC_UINT16, (WsUInt16) ins->ws_cindex,
00725 WS_ENC_END))
00726 goto error;
00727 break;
00728
00729 case WS_ASM_ADD_ASG:
00730 case WS_ASM_SUB_ASG:
00731 if (!ws_encode_buffer(&compiler->byte_code,
00732 WS_ENC_BYTE, (WsByte) ins->type,
00733 WS_ENC_UINT8, (WsUInt8) ins->ws_vindex,
00734 WS_ENC_END))
00735 goto error;
00736 break;
00737
00738 case WS_ASM_CONST_0:
00739 case WS_ASM_CONST_1:
00740 case WS_ASM_CONST_M1:
00741 case WS_ASM_CONST_ES:
00742 case WS_ASM_CONST_INVALID:
00743 case WS_ASM_CONST_TRUE:
00744 case WS_ASM_CONST_FALSE:
00745 case WS_ASM_INCR:
00746 case WS_ASM_DECR:
00747 case WS_ASM_UMINUS:
00748 case WS_ASM_ADD:
00749 case WS_ASM_SUB:
00750 case WS_ASM_MUL:
00751 case WS_ASM_DIV:
00752 case WS_ASM_IDIV:
00753 case WS_ASM_REM:
00754 case WS_ASM_B_AND:
00755 case WS_ASM_B_OR:
00756 case WS_ASM_B_XOR:
00757 case WS_ASM_B_NOT:
00758 case WS_ASM_B_LSHIFT:
00759 case WS_ASM_B_RSSHIFT:
00760 case WS_ASM_B_RSZSHIFT:
00761 case WS_ASM_EQ:
00762 case WS_ASM_LE:
00763 case WS_ASM_LT:
00764 case WS_ASM_GE:
00765 case WS_ASM_GT:
00766 case WS_ASM_NE:
00767 case WS_ASM_NOT:
00768 case WS_ASM_SCAND:
00769 case WS_ASM_SCOR:
00770 case WS_ASM_TOBOOL:
00771 case WS_ASM_POP:
00772 case WS_ASM_TYPEOF:
00773 case WS_ASM_ISVALID:
00774 case WS_ASM_RETURN:
00775 case WS_ASM_RETURN_ES:
00776 case WS_ASM_DEBUG:
00777 if (!ws_encode_buffer(&compiler->byte_code,
00778 WS_ENC_BYTE, (WsByte) ins->type,
00779 WS_ENC_END))
00780 goto error;
00781 break;
00782
00783 default:
00784 ws_fatal("ws_asm_linearize(): unknown instruction 0x%02x",
00785 ins->type);
00786 break;
00787 }
00788 }
00789
00790
00791
00792
00793
00794 if (ws_buffer_len(&compiler->byte_code) == 0) {
00795 if (!ws_encode_buffer(&compiler->byte_code,
00796 WS_ENC_BYTE, (WsByte) WS_ASM_RETURN_ES,
00797 WS_ENC_END))
00798 goto error;
00799 }
00800
00801 return;
00802
00803
00804
00805
00806
00807 error:
00808
00809 ws_error_memory(compiler);
00810 return;
00811 }
00812
00813
00814
00815
00816 static WsAsmIns *asm_alloc(WsCompiler *compiler, WsUInt16 type, WsUInt32 line)
00817 {
00818 WsAsmIns *ins = ws_f_calloc(compiler->pool_asm, 1, sizeof(*ins));
00819
00820 if (ins == NULL)
00821 ws_error_memory(compiler);
00822 else {
00823 ins->type = type;
00824 ins->line = line;
00825 }
00826
00827 return ins;
00828 }
00829
00830
00831 WsAsmIns *ws_asm_label(WsCompiler *compiler, WsUInt32 line)
00832 {
00833 WsAsmIns *ins = asm_alloc(compiler, WS_ASM_P_LABEL, line);
00834
00835 if (ins)
00836 ins->ws_label_idx = compiler->next_label++;
00837
00838 return ins;
00839 }
00840
00841
00842 WsAsmIns *ws_asm_branch(WsCompiler *compiler, WsUInt32 line, WsUInt16 inst,
00843 WsAsmIns *label)
00844 {
00845 WsAsmIns *ins = asm_alloc(compiler, inst, line);
00846
00847 if (ins) {
00848 ins->ws_label = label;
00849 label->ws_label_refcount++;
00850 }
00851
00852 return ins;
00853 }
00854
00855
00856 WsAsmIns *ws_asm_call(WsCompiler *compiler, WsUInt32 line, WsUInt8 findex)
00857 {
00858 WsAsmIns *ins = asm_alloc(compiler, WS_ASM_P_CALL, line);
00859
00860 if (ins)
00861 ins->ws_findex = findex;
00862
00863 return ins;
00864 }
00865
00866
00867 WsAsmIns *ws_asm_call_lib(WsCompiler *compiler, WsUInt32 line, WsUInt8 findex,
00868 WsUInt16 lindex)
00869 {
00870 WsAsmIns *ins = asm_alloc(compiler, WS_ASM_P_CALL_LIB, line);
00871
00872 if (ins) {
00873 ins->ws_findex = findex;
00874 ins->ws_lindex = lindex;
00875 }
00876
00877 return ins;
00878 }
00879
00880
00881 WsAsmIns *ws_asm_call_url(WsCompiler *compiler, WsUInt32 line, WsUInt16 findex,
00882 WsUInt16 urlindex, WsUInt8 args)
00883 {
00884 WsAsmIns *ins = asm_alloc(compiler, WS_ASM_P_CALL_URL, line);
00885
00886 if (ins) {
00887 ins->ws_findex = findex;
00888 ins->ws_lindex = urlindex;
00889 ins->ws_args = args;
00890 }
00891
00892 return ins;
00893 }
00894
00895
00896 WsAsmIns *ws_asm_variable(WsCompiler *compiler, WsUInt32 line, WsUInt16 inst,
00897 WsUInt8 vindex)
00898 {
00899 WsAsmIns *ins = asm_alloc(compiler, inst, line);
00900
00901 if (ins)
00902 ins->ws_vindex = vindex;
00903
00904 return ins;
00905 }
00906
00907
00908 WsAsmIns *ws_asm_load_const(WsCompiler *compiler, WsUInt32 line,
00909 WsUInt16 cindex)
00910 {
00911 WsAsmIns *ins = asm_alloc(compiler, WS_ASM_P_LOAD_CONST, line);
00912
00913 if (ins)
00914 ins->ws_cindex = cindex;
00915
00916 return ins;
00917 }
00918
00919
00920 WsAsmIns *ws_asm_ins(WsCompiler *compiler, WsUInt32 line, WsUInt8 opcode)
00921 {
00922 return asm_alloc(compiler, opcode, line);
00923 }
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.