Kannel: Open Source WAP and SMS gateway  svn-r5335
wsasm.c File Reference
#include "wsint.h"
#include "wsasm.h"
#include "wsstdlib.h"
#include "wsopcodes.h"

Go to the source code of this file.

Macros

#define WS_OPNAME(op)   (operands[(op)].name)
 
#define WS_OPSIZE(op)   (operands[(op)].size)
 

Functions

void ws_asm_link (WsCompiler *compiler, WsAsmIns *ins)
 
void ws_asm_print (WsCompiler *compiler)
 
void ws_asm_dasm (WsCompilerPtr compiler, const unsigned char *code, size_t len)
 
void ws_asm_linearize (WsCompiler *compiler)
 
static WsAsmInsasm_alloc (WsCompiler *compiler, WsUInt16 type, WsUInt32 line)
 
WsAsmInsws_asm_label (WsCompiler *compiler, WsUInt32 line)
 
WsAsmInsws_asm_branch (WsCompiler *compiler, WsUInt32 line, WsUInt16 inst, WsAsmIns *label)
 
WsAsmInsws_asm_call (WsCompiler *compiler, WsUInt32 line, WsUInt8 findex)
 
WsAsmInsws_asm_call_lib (WsCompiler *compiler, WsUInt32 line, WsUInt8 findex, WsUInt16 lindex)
 
WsAsmInsws_asm_call_url (WsCompiler *compiler, WsUInt32 line, WsUInt16 findex, WsUInt16 urlindex, WsUInt8 args)
 
WsAsmInsws_asm_variable (WsCompiler *compiler, WsUInt32 line, WsUInt16 inst, WsUInt8 vindex)
 
WsAsmInsws_asm_load_const (WsCompiler *compiler, WsUInt32 line, WsUInt16 cindex)
 
WsAsmInsws_asm_ins (WsCompiler *compiler, WsUInt32 line, WsUInt8 opcode)
 

Variables

struct {
   char *   name
 
   int   size
 
operands [256]
 

Macro Definition Documentation

◆ WS_OPNAME

#define WS_OPNAME (   op)    (operands[(op)].name)

Definition at line 76 of file wsasm.c.

Referenced by ws_asm_dasm().

◆ WS_OPSIZE

#define WS_OPSIZE (   op)    (operands[(op)].size)

Definition at line 77 of file wsasm.c.

Referenced by ws_asm_dasm(), and ws_asm_linearize().

Function Documentation

◆ asm_alloc()

static WsAsmIns* asm_alloc ( WsCompiler compiler,
WsUInt16  type,
WsUInt32  line 
)
static

Definition at line 816 of file wsasm.c.

References WsAsmInsRec::line, WsCompilerRec::pool_asm, type, WsAsmInsRec::type, ws_error_memory(), and ws_f_calloc().

Referenced by ws_asm_branch(), ws_asm_call(), ws_asm_call_lib(), ws_asm_call_url(), ws_asm_ins(), ws_asm_label(), ws_asm_load_const(), and ws_asm_variable().

817 {
818  WsAsmIns *ins = ws_f_calloc(compiler->pool_asm, 1, sizeof(*ins));
819 
820  if (ins == NULL)
821  ws_error_memory(compiler);
822  else {
823  ins->type = type;
824  ins->line = line;
825  }
826 
827  return ins;
828 }
int type
Definition: smsc_cimd2.c:215
WsUInt16 type
Definition: wsasm.h:257
WsUInt32 line
Definition: wsasm.h:260
void * ws_f_calloc(WsFastMalloc *pool, size_t num, size_t size)
Definition: wsfalloc.c:150
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
WsFastMalloc * pool_asm
Definition: wsint.h:207

◆ ws_asm_branch()

WsAsmIns* ws_asm_branch ( WsCompiler compiler,
WsUInt32  line,
WsUInt16  inst,
WsAsmIns label 
)

Definition at line 842 of file wsasm.c.

References asm_alloc().

Referenced by ws_expr_linearize(), and ws_stmt_linearize().

844 {
845  WsAsmIns *ins = asm_alloc(compiler, inst, line);
846 
847  if (ins) {
848  ins->ws_label = label;
849  label->ws_label_refcount++;
850  }
851 
852  return ins;
853 }
static WsAsmIns * asm_alloc(WsCompiler *compiler, WsUInt16 type, WsUInt32 line)
Definition: wsasm.c:816

◆ ws_asm_call()

WsAsmIns* ws_asm_call ( WsCompiler compiler,
WsUInt32  line,
WsUInt8  findex 
)

Definition at line 856 of file wsasm.c.

References asm_alloc(), and WS_ASM_P_CALL.

Referenced by ws_expr_linearize().

857 {
858  WsAsmIns *ins = asm_alloc(compiler, WS_ASM_P_CALL, line);
859 
860  if (ins)
861  ins->ws_findex = findex;
862 
863  return ins;
864 }
static WsAsmIns * asm_alloc(WsCompiler *compiler, WsUInt16 type, WsUInt32 line)
Definition: wsasm.c:816
#define WS_ASM_P_CALL
Definition: wsasm.h:228

◆ ws_asm_call_lib()

WsAsmIns* ws_asm_call_lib ( WsCompiler compiler,
WsUInt32  line,
WsUInt8  findex,
WsUInt16  lindex 
)

Definition at line 867 of file wsasm.c.

References asm_alloc(), and WS_ASM_P_CALL_LIB.

Referenced by ws_expr_linearize().

869 {
870  WsAsmIns *ins = asm_alloc(compiler, WS_ASM_P_CALL_LIB, line);
871 
872  if (ins) {
873  ins->ws_findex = findex;
874  ins->ws_lindex = lindex;
875  }
876 
877  return ins;
878 }
#define WS_ASM_P_CALL_LIB
Definition: wsasm.h:229
static WsAsmIns * asm_alloc(WsCompiler *compiler, WsUInt16 type, WsUInt32 line)
Definition: wsasm.c:816

◆ ws_asm_call_url()

WsAsmIns* ws_asm_call_url ( WsCompiler compiler,
WsUInt32  line,
WsUInt16  findex,
WsUInt16  urlindex,
WsUInt8  args 
)

Definition at line 881 of file wsasm.c.

References asm_alloc(), and WS_ASM_P_CALL_URL.

Referenced by ws_expr_linearize().

883 {
884  WsAsmIns *ins = asm_alloc(compiler, WS_ASM_P_CALL_URL, line);
885 
886  if (ins) {
887  ins->ws_findex = findex;
888  ins->ws_lindex = urlindex;
889  ins->ws_args = args;
890  }
891 
892  return ins;
893 }
static WsAsmIns * asm_alloc(WsCompiler *compiler, WsUInt16 type, WsUInt32 line)
Definition: wsasm.c:816
#define WS_ASM_P_CALL_URL
Definition: wsasm.h:230

◆ ws_asm_dasm()

void ws_asm_dasm ( WsCompilerPtr  compiler,
const unsigned char *  code,
size_t  len 
)

Definition at line 185 of file wsasm.c.

References code, WS_ASM_ADD_ASG, WS_ASM_ARG, WS_ASM_CALL, WS_ASM_CALL_LIB, WS_ASM_CALL_LIB_S, WS_ASM_CALL_LIB_W, WS_ASM_CALL_S, WS_ASM_CALL_URL, WS_ASM_CALL_URL_W, WS_ASM_DECR_VAR, WS_ASM_INCR_VAR, WS_ASM_INCR_VAR_S, WS_ASM_JUMP_BW, WS_ASM_JUMP_BW_S, WS_ASM_JUMP_BW_W, WS_ASM_JUMP_FW, WS_ASM_JUMP_FW_S, WS_ASM_JUMP_FW_W, WS_ASM_LOAD_CONST, WS_ASM_LOAD_CONST_S, WS_ASM_LOAD_CONST_W, WS_ASM_LOAD_VAR, WS_ASM_LOAD_VAR_S, WS_ASM_OP, WS_ASM_STORE_VAR, WS_ASM_STORE_VAR_S, WS_ASM_SUB_ASG, WS_ASM_TJUMP_BW, WS_ASM_TJUMP_BW_W, WS_ASM_TJUMP_FW, WS_ASM_TJUMP_FW_S, WS_ASM_TJUMP_FW_W, ws_fprintf(), WS_GET_UINT16, WS_GET_UINT8, WS_OPNAME, WS_OPSIZE, ws_stdlib_function_name(), and WS_STDOUT.

Referenced by compile_stream(), and main().

186 {
187  size_t i = 0;
188 
189  while (i < len) {
190  WsUInt8 byt = code[i];
191  WsUInt8 op;
192  WsUInt8 arg;
193  WsUInt8 i8, j8, k8;
194  WsUInt16 i16, j16;
195 
196  op = WS_ASM_OP(byt);
197  arg = WS_ASM_ARG(byt);
198 
199  ws_fprintf(WS_STDOUT, "%4x:\t%-16s", i, WS_OPNAME(op));
200 
201  switch (op) {
202  /* The `short jumps'. */
203  case WS_ASM_JUMP_FW_S:
204  case WS_ASM_TJUMP_FW_S:
205  ws_fprintf(WS_STDOUT, "%x\n", i + WS_OPSIZE(op) + arg);
206  break;
207 
208  case WS_ASM_JUMP_BW_S:
209  ws_fprintf(WS_STDOUT, "%x\n", i - arg);
210  break;
211 
212  /* Jumps with WsUInt8 argument. */
213  case WS_ASM_JUMP_FW:
214  case WS_ASM_TJUMP_FW:
215  WS_GET_UINT8(code + i + 1, i8);
216  ws_fprintf(WS_STDOUT, "%x\n", i + WS_OPSIZE(op) + i8);
217  break;
218 
219  case WS_ASM_JUMP_BW:
220  case WS_ASM_TJUMP_BW:
221  WS_GET_UINT8(code + i + 1, i8);
222  ws_fprintf(WS_STDOUT, "%x\n", i - i8);
223  break;
224 
225  /* Jumps with wide argument. */
226  case WS_ASM_JUMP_FW_W:
227  case WS_ASM_TJUMP_FW_W:
228  WS_GET_UINT16(code + i + 1, i16);
229  ws_fprintf(WS_STDOUT, "%x\n", i + WS_OPSIZE(op) + i16);
230  break;
231 
232  case WS_ASM_JUMP_BW_W:
233  case WS_ASM_TJUMP_BW_W:
234  WS_GET_UINT16(code + i + 1, i16);
235  ws_fprintf(WS_STDOUT, "%x\n", i - i16);
236  break;
237 
238  /* The `short' opcodes. */
239  case WS_ASM_LOAD_VAR_S:
240  case WS_ASM_STORE_VAR_S:
241  case WS_ASM_INCR_VAR_S:
242  ws_fprintf(WS_STDOUT, "%d\n", arg);
243  break;
244 
245  /* Local script function calls. */
246  case WS_ASM_CALL_S:
247  ws_fprintf(WS_STDOUT, "%d\n", arg);
248  break;
249 
250  case WS_ASM_CALL:
251  WS_GET_UINT8(code + i + 1, i8);
252  ws_fprintf(WS_STDOUT, "%d\n", i8);
253  break;
254 
255  /* Library calls. */
256  case WS_ASM_CALL_LIB_S:
257  case WS_ASM_CALL_LIB:
258  case WS_ASM_CALL_LIB_W:
259  {
260  WsUInt8 findex;
261  WsUInt16 lindex;
262  char lnamebuf[64];
263  char fnamebuf[64];
264  const char *lname;
265  const char *fname;
266 
267  if (op == WS_ASM_CALL_LIB_S) {
268  WS_GET_UINT8(code + i + 1, lindex);
269  findex = arg;
270  } else if (op == WS_ASM_CALL_LIB) {
271  WS_GET_UINT8(code + i + 1, findex);
272  WS_GET_UINT8(code + i + 2, lindex);
273  } else {
274  WS_GET_UINT8(code + i + 1, findex);
275  WS_GET_UINT16(code + i + 2, lindex);
276  }
277 
278  if (!ws_stdlib_function_name(lindex, findex, &lname, &fname)) {
279  snprintf(lnamebuf, sizeof(lnamebuf), "%d", lindex);
280  snprintf(fnamebuf, sizeof(lnamebuf), "%d", findex);
281  lname = lnamebuf;
282  fname = fnamebuf;
283  }
284  ws_fprintf(WS_STDOUT, "%s.%s\n", lname, fname);
285  }
286  break;
287 
288  /* URL calls. */
289  case WS_ASM_CALL_URL:
290  WS_GET_UINT8(code + i + 1, i8);
291  WS_GET_UINT8(code + i + 2, j8);
292  WS_GET_UINT8(code + i + 3, k8);
293  ws_fprintf(WS_STDOUT, "%d.%d %d\n", i8, j8, k8);
294  break;
295 
296  case WS_ASM_CALL_URL_W:
297  WS_GET_UINT16(code + i + 1, i16);
298  WS_GET_UINT16(code + i + 3, j16);
299  WS_GET_UINT8(code + i + 5, i8);
300  ws_fprintf(WS_STDOUT, "%d.%d %d\n", i16, j16, i8);
301  break;
302 
303  /* Constant access. */
304  case WS_ASM_LOAD_CONST_S:
305  case WS_ASM_LOAD_CONST:
306  case WS_ASM_LOAD_CONST_W:
307  if (op == WS_ASM_LOAD_CONST_S)
308  i16 = arg;
309  else if (op == WS_ASM_LOAD_CONST) {
310  WS_GET_UINT8(code + i + 1, i8);
311  i16 = i8;
312  } else
313  WS_GET_UINT16(code + i + 1, i16);
314 
315  ws_fprintf(WS_STDOUT, "%d\n", i16);
316  break;
317 
318  /* Operands with WsUInt8 argument. */
319  case WS_ASM_LOAD_VAR:
320  case WS_ASM_STORE_VAR:
321  case WS_ASM_INCR_VAR:
322  case WS_ASM_DECR_VAR:
323  case WS_ASM_ADD_ASG:
324  case WS_ASM_SUB_ASG:
325  WS_GET_UINT8(code + i + 1, i8);
326  ws_fprintf(WS_STDOUT, "%d\n", i8);
327  break;
328 
329  /* The trivial cases. */
330  default:
331  ws_fprintf(WS_STDOUT, "\n");
332  break;
333  }
334 
335  i += WS_OPSIZE(op);
336  }
337 }
#define WS_ASM_JUMP_FW_S
Definition: wsasm.h:130
#define WS_GET_UINT16(buf, var)
Definition: wsencode.h:107
#define WS_ASM_JUMP_FW_W
Definition: wsasm.h:132
#define WS_ASM_LOAD_CONST
Definition: wsasm.h:167
#define WS_ASM_ADD_ASG
Definition: wsasm.h:180
int code
Definition: smsc_cimd2.c:346
#define WS_ASM_CALL_LIB
Definition: wsasm.h:149
#define WS_ASM_JUMP_BW
Definition: wsasm.h:135
#define WS_GET_UINT8(buf, var)
Definition: wsencode.h:101
#define WS_ASM_ARG(op)
Definition: wsasm.h:114
#define WS_ASM_CALL_URL
Definition: wsasm.h:152
unsigned char WsUInt8
Definition: wsint.h:116
#define WS_ASM_JUMP_BW_W
Definition: wsasm.h:136
#define WS_OPNAME(op)
Definition: wsasm.c:76
#define WS_ASM_TJUMP_BW_W
Definition: wsasm.h:143
void ws_fprintf(WsIOProc io, void *context, const char *fmt,...)
Definition: wserror.c:190
unsigned short WsUInt16
Definition: wsint.h:119
#define WS_ASM_CALL
Definition: wsasm.h:146
#define WS_ASM_JUMP_BW_S
Definition: wsasm.h:134
#define WS_ASM_INCR_VAR_S
Definition: wsasm.h:161
#define WS_OPSIZE(op)
Definition: wsasm.c:77
#define WS_ASM_LOAD_VAR
Definition: wsasm.h:156
#define WS_ASM_LOAD_CONST_W
Definition: wsasm.h:168
#define WS_ASM_CALL_LIB_S
Definition: wsasm.h:148
#define WS_ASM_LOAD_VAR_S
Definition: wsasm.h:155
#define WS_ASM_TJUMP_BW
Definition: wsasm.h:142
#define WS_ASM_TJUMP_FW_S
Definition: wsasm.h:138
#define WS_ASM_STORE_VAR
Definition: wsasm.h:159
#define WS_ASM_DECR_VAR
Definition: wsasm.h:164
#define WS_ASM_CALL_URL_W
Definition: wsasm.h:153
#define WS_ASM_CALL_LIB_W
Definition: wsasm.h:150
#define WS_ASM_TJUMP_FW
Definition: wsasm.h:139
#define WS_ASM_INCR_VAR
Definition: wsasm.h:162
#define WS_ASM_STORE_VAR_S
Definition: wsasm.h:158
WsBool ws_stdlib_function_name(WsUInt16 lindex, WsUInt8 findex, const char **library_return, const char **function_return)
Definition: wsstdlib.c:375
#define WS_ASM_SUB_ASG
Definition: wsasm.h:181
#define WS_ASM_TJUMP_FW_W
Definition: wsasm.h:140
#define WS_ASM_LOAD_CONST_S
Definition: wsasm.h:166
#define WS_ASM_CALL_S
Definition: wsasm.h:145
#define WS_ASM_JUMP_FW
Definition: wsasm.h:131
#define WS_STDOUT
Definition: wserror.h:113
#define WS_ASM_OP(op)
Definition: wsasm.h:102

◆ ws_asm_ins()

WsAsmIns* ws_asm_ins ( WsCompiler compiler,
WsUInt32  line,
WsUInt8  opcode 
)

Definition at line 920 of file wsasm.c.

References asm_alloc(), and opcode.

Referenced by opt_peephole(), ws_expr_linearize(), and ws_stmt_linearize().

921 {
922  return asm_alloc(compiler, opcode, line);
923 }
static WsAsmIns * asm_alloc(WsCompiler *compiler, WsUInt16 type, WsUInt32 line)
Definition: wsasm.c:816
int opcode
Definition: test_cimd2.c:769

◆ ws_asm_label()

WsAsmIns* ws_asm_label ( WsCompiler compiler,
WsUInt32  line 
)

Definition at line 831 of file wsasm.c.

References asm_alloc(), WsCompilerRec::next_label, and WS_ASM_P_LABEL.

Referenced by ws_expr_linearize(), and ws_stmt_linearize().

832 {
833  WsAsmIns *ins = asm_alloc(compiler, WS_ASM_P_LABEL, line);
834 
835  if (ins)
836  ins->ws_label_idx = compiler->next_label++;
837 
838  return ins;
839 }
#define WS_ASM_P_LABEL
Definition: wsasm.h:225
static WsAsmIns * asm_alloc(WsCompiler *compiler, WsUInt16 type, WsUInt32 line)
Definition: wsasm.c:816
WsUInt32 next_label
Definition: wsint.h:221

◆ ws_asm_linearize()

void ws_asm_linearize ( WsCompiler compiler)

Definition at line 341 of file wsasm.c.

References WsCompilerRec::asm_head, WsCompilerRec::byte_code, error(), gw_assert(), WsAsmInsRec::next, WsAsmInsRec::offset, operands, WsAsmInsRec::type, WS_ASM_ADD, WS_ASM_ADD_ASG, WS_ASM_B_AND, WS_ASM_B_LSHIFT, WS_ASM_B_NOT, WS_ASM_B_OR, WS_ASM_B_RSSHIFT, WS_ASM_B_RSZSHIFT, WS_ASM_B_XOR, WS_ASM_CALL, WS_ASM_CALL_LIB, WS_ASM_CALL_LIB_S, WS_ASM_CALL_LIB_W, WS_ASM_CALL_S, WS_ASM_CALL_URL, WS_ASM_CALL_URL_W, WS_ASM_CONST_0, WS_ASM_CONST_1, WS_ASM_CONST_ES, WS_ASM_CONST_FALSE, WS_ASM_CONST_INVALID, WS_ASM_CONST_M1, WS_ASM_CONST_TRUE, WS_ASM_DEBUG, WS_ASM_DECR, WS_ASM_DECR_VAR, WS_ASM_DIV, WS_ASM_EQ, WS_ASM_GE, WS_ASM_GLUE, WS_ASM_GT, WS_ASM_IDIV, WS_ASM_INCR, WS_ASM_INCR_VAR, WS_ASM_INCR_VAR_S, WS_ASM_ISVALID, WS_ASM_JUMP_BW, WS_ASM_JUMP_BW_S, WS_ASM_JUMP_BW_W, WS_ASM_JUMP_FW, WS_ASM_JUMP_FW_S, WS_ASM_JUMP_FW_W, WS_ASM_LE, WS_ASM_LOAD_CONST, WS_ASM_LOAD_CONST_S, WS_ASM_LOAD_CONST_W, WS_ASM_LOAD_VAR, WS_ASM_LOAD_VAR_S, WS_ASM_LT, WS_ASM_MUL, WS_ASM_NE, WS_ASM_NOT, WS_ASM_P_CALL, WS_ASM_P_CALL_LIB, WS_ASM_P_CALL_URL, WS_ASM_P_INCR_VAR, WS_ASM_P_JUMP, WS_ASM_P_LABEL, WS_ASM_P_LOAD_CONST, WS_ASM_P_LOAD_VAR, WS_ASM_P_STORE_VAR, WS_ASM_P_TJUMP, WS_ASM_POP, WS_ASM_REM, WS_ASM_RETURN, WS_ASM_RETURN_ES, WS_ASM_SCAND, WS_ASM_SCOR, WS_ASM_STORE_VAR, WS_ASM_STORE_VAR_S, WS_ASM_SUB, WS_ASM_SUB_ASG, WS_ASM_TJUMP_BW, WS_ASM_TJUMP_BW_W, WS_ASM_TJUMP_FW, WS_ASM_TJUMP_FW_S, WS_ASM_TJUMP_FW_W, WS_ASM_TOBOOL, WS_ASM_TYPEOF, WS_ASM_UMINUS, ws_buffer_len(), WS_ENC_BYTE, WS_ENC_END, WS_ENC_UINT16, WS_ENC_UINT8, ws_encode_buffer(), ws_error_memory(), WS_FALSE, ws_fatal(), WS_OPSIZE, and WS_TRUE.

Referenced by compile_stream().

342 {
343  WsAsmIns *ins;
344  WsBool process_again = WS_TRUE;
345 
346  /* Calculate all offsets and select real assembler instructions for
347  our internal pseudo instructions. This is continued as long as
348  the code changes. */
349  while (process_again) {
350  WsUInt32 offset = 1;
351 
352  process_again = WS_FALSE;
353 
354  for (ins = compiler->asm_head; ins; ins = ins->next) {
355  ins->offset = offset;
356 
357  switch (ins->type) {
358  case WS_ASM_JUMP_FW_S:
359  ins->ws_offset = (ins->ws_label->offset
360  - (offset + WS_OPSIZE(ins->type)));
361  break;
362 
363  case WS_ASM_JUMP_FW:
364  ins->ws_offset = (ins->ws_label->offset
365  - (offset + WS_OPSIZE(ins->type)));
366 
367  if (ins->ws_offset <= 31) {
368  ins->type = WS_ASM_JUMP_FW_S;
369  process_again = WS_TRUE;
370  }
371  break;
372 
373  case WS_ASM_JUMP_FW_W:
374  ins->ws_offset = (ins->ws_label->offset
375  - (offset + WS_OPSIZE(ins->type)));
376 
377  if (ins->ws_offset <= 31) {
378  ins->type = WS_ASM_JUMP_FW_S;
379  process_again = WS_TRUE;
380  } else if (ins->ws_offset <= 255) {
381  ins->type = WS_ASM_JUMP_FW;
382  process_again = WS_TRUE;
383  }
384  break;
385 
386  case WS_ASM_JUMP_BW_S:
387  ins->ws_offset = offset - ins->ws_label->offset;
388  break;
389 
390  case WS_ASM_JUMP_BW:
391  ins->ws_offset = offset - ins->ws_label->offset;
392 
393  if (ins->ws_offset <= 31) {
394  ins->type = WS_ASM_JUMP_BW_S;
395  process_again = WS_TRUE;
396  }
397  break;
398 
399  case WS_ASM_JUMP_BW_W:
400  ins->ws_offset = offset - ins->ws_label->offset;
401 
402  if (ins->ws_offset <= 31) {
403  ins->type = WS_ASM_JUMP_BW_S;
404  process_again = WS_TRUE;
405  } else if (ins->ws_offset <= 255) {
406  ins->type = WS_ASM_JUMP_BW;
407  process_again = WS_TRUE;
408  }
409  break;
410 
411  case WS_ASM_TJUMP_FW_S:
412  ins->ws_offset = (ins->ws_label->offset
413  - (offset + WS_OPSIZE(ins->type)));
414  break;
415 
416  case WS_ASM_TJUMP_FW:
417  ins->ws_offset = (ins->ws_label->offset
418  - (offset + WS_OPSIZE(ins->type)));
419 
420  if (ins->ws_offset <= 31) {
421  ins->type = WS_ASM_TJUMP_FW_S;
422  process_again = WS_TRUE;
423  }
424  break;
425 
426  case WS_ASM_TJUMP_FW_W:
427  ins->ws_offset = (ins->ws_label->offset
428  - (offset + WS_OPSIZE(ins->type)));
429 
430  if (ins->ws_offset <= 31) {
431  ins->type = WS_ASM_TJUMP_FW_S;
432  process_again = WS_TRUE;
433  } else if (ins->ws_offset <= 255) {
434  ins->type = WS_ASM_TJUMP_FW;
435  process_again = WS_TRUE;
436  }
437  break;
438 
439  case WS_ASM_TJUMP_BW:
440  ins->ws_offset = offset - ins->ws_label->offset;
441  break;
442 
443  case WS_ASM_TJUMP_BW_W:
444  ins->ws_offset = offset - ins->ws_label->offset;
445 
446  if (ins->ws_offset <= 255) {
447  ins->type = WS_ASM_TJUMP_BW;
448  process_again = WS_TRUE;
449  }
450  break;
451 
452  /*
453  * The pseudo instructions.
454  */
455 
456  case WS_ASM_P_LABEL:
457  /* Nothing here. */
458  break;
459 
460  case WS_ASM_P_JUMP:
461  if (ins->ws_label->offset == 0) {
462  /* A forward jump. Let's assume the widest form. */
463  ins->type = WS_ASM_JUMP_FW_W;
464  } else {
465  ins->ws_offset = offset - ins->ws_label->offset;
466 
467  /* Jump backwards. */
468  if (ins->ws_offset <= 31) {
469  ins->type = WS_ASM_JUMP_BW_S;
470  } else if (ins->ws_offset <= 255) {
471  ins->type = WS_ASM_JUMP_BW;
472  } else {
473  ins->type = WS_ASM_JUMP_BW_W;
474  }
475  }
476  break;
477 
478  case WS_ASM_P_TJUMP:
479  if (ins->ws_label->offset == 0) {
480  /* A forward jump. Let's assume the widest form. */
481  ins->type = WS_ASM_TJUMP_FW_W;
482  process_again = WS_TRUE;
483  } else {
484  ins->ws_offset = offset - ins->ws_label->offset;
485 
486  /* Jump backwards. */
487  if (ins->ws_offset <= 255) {
488  ins->type = WS_ASM_TJUMP_BW;
489  } else {
490  ins->type = WS_ASM_TJUMP_BW_W;
491  }
492  }
493  break;
494 
495  case WS_ASM_P_CALL:
496  if (ins->ws_findex <= 7) {
497  /* The most compact form. */
498  ins->type = WS_ASM_CALL_S;
499  } else {
500  /* The wider form. */
501  ins->type = WS_ASM_CALL;
502  }
503  break;
504 
505  case WS_ASM_P_CALL_LIB:
506  if (ins->ws_findex <= 7 && ins->ws_lindex <= 255) {
507  /* The most compact form. */
508  ins->type = WS_ASM_CALL_LIB_S;
509  } else if (ins->ws_findex <= 255 && ins->ws_lindex <= 255) {
510  /* The quite compact form. */
511  ins->type = WS_ASM_CALL_LIB;
512  } else {
513  /* The most liberal form. */
514  ins->type = WS_ASM_CALL_LIB_W;
515  }
516  break;
517 
518  case WS_ASM_P_CALL_URL:
519  if (ins->ws_findex <= 255 && ins->ws_lindex <= 255)
520  /* The compact form. */
521  ins->type = WS_ASM_CALL_URL;
522  else
523  ins->type = WS_ASM_CALL_URL_W;
524  break;
525 
526  case WS_ASM_P_LOAD_VAR:
527  if (ins->ws_vindex <= 31)
528  /* The compact form. */
529  ins->type = WS_ASM_LOAD_VAR_S;
530  else
531  ins->type = WS_ASM_LOAD_VAR;
532  break;
533 
534  case WS_ASM_P_STORE_VAR:
535  if (ins->ws_vindex <= 15)
536  ins->type = WS_ASM_STORE_VAR_S;
537  else
538  ins->type = WS_ASM_STORE_VAR;
539  break;
540 
541  case WS_ASM_P_INCR_VAR:
542  if (ins->ws_vindex <= 7)
543  ins->type = WS_ASM_INCR_VAR_S;
544  else
545  ins->type = WS_ASM_INCR_VAR;
546  break;
547 
548  case WS_ASM_P_LOAD_CONST:
549  if (ins->ws_cindex <= 15)
550  ins->type = WS_ASM_LOAD_CONST_S;
551  else if (ins->ws_cindex <= 255)
552  ins->type = WS_ASM_LOAD_CONST;
553  else
554  ins->type = WS_ASM_LOAD_CONST_W;
555  break;
556  }
557 
558  gw_assert(ins->type == WS_ASM_P_LABEL || ins->type < 0x100);
559 
560  if (ins->type != WS_ASM_P_LABEL) {
561  gw_assert(operands[ins->type].name != NULL);
562  offset += operands[ins->type].size;
563  }
564  }
565  }
566 
567  /* Ok, ready to linearize the byte-code. */
568  for (ins = compiler->asm_head; ins; ins = ins->next) {
569  if (ins->type == WS_ASM_P_LABEL)
570  continue;
571 
572  gw_assert(ins->type <= 0xff);
573 
574  switch (ins->type) {
575  case WS_ASM_JUMP_FW_S:
576  case WS_ASM_JUMP_BW_S:
577  case WS_ASM_TJUMP_FW_S:
578  if (!ws_encode_buffer(&compiler->byte_code,
579  WS_ENC_BYTE,
580  WS_ASM_GLUE(ins->type, ins->ws_offset),
581  WS_ENC_END))
582  goto error;
583  break;
584 
585  case WS_ASM_JUMP_FW:
586  case WS_ASM_JUMP_BW:
587  case WS_ASM_TJUMP_FW:
588  case WS_ASM_TJUMP_BW:
589  if (!ws_encode_buffer(&compiler->byte_code,
590  WS_ENC_BYTE, ins->type,
591  WS_ENC_UINT8, (WsUInt8) ins->ws_offset,
592  WS_ENC_END))
593  goto error;
594  break;
595 
596  case WS_ASM_JUMP_FW_W:
597  case WS_ASM_JUMP_BW_W:
598  case WS_ASM_TJUMP_FW_W:
599  case WS_ASM_TJUMP_BW_W:
600  if (!ws_encode_buffer(&compiler->byte_code,
601  WS_ENC_BYTE, ins->type,
602  WS_ENC_UINT16, (WsUInt16) ins->ws_offset,
603  WS_ENC_END))
604  goto error;
605  break;
606 
607  case WS_ASM_CALL_S:
608  if (!ws_encode_buffer(&compiler->byte_code,
609  WS_ENC_BYTE,
610  WS_ASM_GLUE(ins->type, ins->ws_findex),
611  WS_ENC_END))
612  goto error;
613  break;
614 
615  case WS_ASM_CALL:
616  if (!ws_encode_buffer(&compiler->byte_code,
617  WS_ENC_BYTE, (WsByte) ins->type,
618  WS_ENC_UINT8, (WsUInt8) ins->ws_findex,
619  WS_ENC_END))
620  goto error;
621  break;
622 
623  case WS_ASM_CALL_LIB_S:
624  if (!ws_encode_buffer(&compiler->byte_code,
625  WS_ENC_BYTE,
626  WS_ASM_GLUE(ins->type, ins->ws_findex),
627  WS_ENC_UINT8, (WsUInt8) ins->ws_lindex,
628  WS_ENC_END))
629  goto error;
630  break;
631 
632  case WS_ASM_CALL_LIB:
633  if (!ws_encode_buffer(&compiler->byte_code,
634  WS_ENC_BYTE, (WsByte) ins->type,
635  WS_ENC_UINT8, (WsUInt8) ins->ws_findex,
636  WS_ENC_UINT8, (WsUInt8) ins->ws_lindex,
637  WS_ENC_END))
638  goto error;
639  break;
640 
641  case WS_ASM_CALL_LIB_W:
642  if (!ws_encode_buffer(&compiler->byte_code,
643  WS_ENC_BYTE, (WsByte) ins->type,
644  WS_ENC_UINT8, (WsUInt8) ins->ws_findex,
645  WS_ENC_UINT16, (WsUInt16) ins->ws_lindex,
646  WS_ENC_END))
647  goto error;
648  break;
649 
650  case WS_ASM_CALL_URL:
651  if (!ws_encode_buffer(&compiler->byte_code,
652  WS_ENC_BYTE, (WsByte) ins->type,
653  WS_ENC_UINT8, (WsUInt8) ins->ws_lindex,
654  WS_ENC_UINT8, (WsUInt8) ins->ws_findex,
655  WS_ENC_UINT8, (WsUInt8) ins->ws_args,
656  WS_ENC_END))
657  goto error;
658  break;
659 
660  case WS_ASM_CALL_URL_W:
661  if (!ws_encode_buffer(&compiler->byte_code,
662  WS_ENC_BYTE, (WsByte) ins->type,
663  WS_ENC_UINT16, (WsUInt16) ins->ws_lindex,
664  WS_ENC_UINT16, (WsUInt16) ins->ws_findex,
665  WS_ENC_UINT8, (WsUInt8) ins->ws_args,
666  WS_ENC_END))
667  goto error;
668  break;
669 
670  case WS_ASM_LOAD_VAR_S:
671  case WS_ASM_STORE_VAR_S:
672  if (!ws_encode_buffer(&compiler->byte_code,
673  WS_ENC_BYTE,
674  WS_ASM_GLUE(ins->type, ins->ws_vindex),
675  WS_ENC_END))
676  goto error;
677  break;
678 
679  case WS_ASM_LOAD_VAR:
680  case WS_ASM_STORE_VAR:
681  if (!ws_encode_buffer(&compiler->byte_code,
682  WS_ENC_BYTE, (WsByte) ins->type,
683  WS_ENC_UINT8, (WsUInt8) ins->ws_vindex,
684  WS_ENC_END))
685  goto error;
686  break;
687 
688  case WS_ASM_INCR_VAR_S:
689  if (!ws_encode_buffer(&compiler->byte_code,
690  WS_ENC_BYTE,
691  WS_ASM_GLUE(ins->type, ins->ws_vindex),
692  WS_ENC_END))
693  goto error;
694  break;
695 
696  case WS_ASM_INCR_VAR:
697  case WS_ASM_DECR_VAR:
698  if (!ws_encode_buffer(&compiler->byte_code,
699  WS_ENC_BYTE, (WsByte) ins->type,
700  WS_ENC_UINT8, (WsUInt8) ins->ws_vindex,
701  WS_ENC_END))
702  goto error;
703  break;
704 
705  case WS_ASM_LOAD_CONST_S:
706  if (!ws_encode_buffer(&compiler->byte_code,
707  WS_ENC_BYTE,
708  WS_ASM_GLUE(ins->type, ins->ws_cindex),
709  WS_ENC_END))
710  goto error;
711  break;
712 
713  case WS_ASM_LOAD_CONST:
714  if (!ws_encode_buffer(&compiler->byte_code,
715  WS_ENC_BYTE, (WsByte) ins->type,
716  WS_ENC_UINT8, (WsUInt8) ins->ws_cindex,
717  WS_ENC_END))
718  goto error;
719  break;
720 
721  case WS_ASM_LOAD_CONST_W:
722  if (!ws_encode_buffer(&compiler->byte_code,
723  WS_ENC_BYTE, (WsByte) ins->type,
724  WS_ENC_UINT16, (WsUInt16) ins->ws_cindex,
725  WS_ENC_END))
726  goto error;
727  break;
728 
729  case WS_ASM_ADD_ASG:
730  case WS_ASM_SUB_ASG:
731  if (!ws_encode_buffer(&compiler->byte_code,
732  WS_ENC_BYTE, (WsByte) ins->type,
733  WS_ENC_UINT8, (WsUInt8) ins->ws_vindex,
734  WS_ENC_END))
735  goto error;
736  break;
737 
738  case WS_ASM_CONST_0:
739  case WS_ASM_CONST_1:
740  case WS_ASM_CONST_M1:
741  case WS_ASM_CONST_ES:
743  case WS_ASM_CONST_TRUE:
744  case WS_ASM_CONST_FALSE:
745  case WS_ASM_INCR:
746  case WS_ASM_DECR:
747  case WS_ASM_UMINUS:
748  case WS_ASM_ADD:
749  case WS_ASM_SUB:
750  case WS_ASM_MUL:
751  case WS_ASM_DIV:
752  case WS_ASM_IDIV:
753  case WS_ASM_REM:
754  case WS_ASM_B_AND:
755  case WS_ASM_B_OR:
756  case WS_ASM_B_XOR:
757  case WS_ASM_B_NOT:
758  case WS_ASM_B_LSHIFT:
759  case WS_ASM_B_RSSHIFT:
760  case WS_ASM_B_RSZSHIFT:
761  case WS_ASM_EQ:
762  case WS_ASM_LE:
763  case WS_ASM_LT:
764  case WS_ASM_GE:
765  case WS_ASM_GT:
766  case WS_ASM_NE:
767  case WS_ASM_NOT:
768  case WS_ASM_SCAND:
769  case WS_ASM_SCOR:
770  case WS_ASM_TOBOOL:
771  case WS_ASM_POP:
772  case WS_ASM_TYPEOF:
773  case WS_ASM_ISVALID:
774  case WS_ASM_RETURN:
775  case WS_ASM_RETURN_ES:
776  case WS_ASM_DEBUG:
777  if (!ws_encode_buffer(&compiler->byte_code,
778  WS_ENC_BYTE, (WsByte) ins->type,
779  WS_ENC_END))
780  goto error;
781  break;
782 
783  default:
784  ws_fatal("ws_asm_linearize(): unknown instruction 0x%02x",
785  ins->type);
786  break;
787  }
788  }
789 
790  /*
791  * Avoid generating 0-length functions, because not all clients
792  * handle them correctly.
793  */
794  if (ws_buffer_len(&compiler->byte_code) == 0) {
795  if (!ws_encode_buffer(&compiler->byte_code,
797  WS_ENC_END))
798  goto error;
799  }
800 
801  return;
802 
803  /*
804  * Error handling.
805  */
806 
807 error:
808 
809  ws_error_memory(compiler);
810  return;
811 }
void error(int err, const char *fmt,...)
Definition: log.c:648
void ws_fatal(char *fmt,...)
Definition: wserror.c:91
#define WS_ASM_JUMP_FW_S
Definition: wsasm.h:130
#define WS_ASM_CONST_TRUE
Definition: wsasm.h:175
#define WS_ASM_SCOR
Definition: wsasm.h:207
#define WS_ASM_B_RSSHIFT
Definition: wsasm.h:195
#define WS_ASM_P_CALL_LIB
Definition: wsasm.h:229
#define WS_ASM_JUMP_FW_W
Definition: wsasm.h:132
Definition: wsint.h:131
#define WS_ASM_P_LABEL
Definition: wsasm.h:225
gw_assert(wtls_machine->packet_to_send !=NULL)
#define WS_ASM_GLUE(op, arg)
Definition: wsasm.h:125
#define WS_ASM_LOAD_CONST
Definition: wsasm.h:167
unsigned long WsUInt32
Definition: wsint.h:122
#define WS_ASM_ADD_ASG
Definition: wsasm.h:180
#define WS_ASM_TYPEOF
Definition: wsasm.h:212
#define WS_ASM_NOT
Definition: wsasm.h:205
#define WS_ASM_CALL_LIB
Definition: wsasm.h:149
#define WS_ASM_JUMP_BW
Definition: wsasm.h:135
WsUInt32 offset
Definition: wsasm.h:263
#define WS_ASM_RETURN
Definition: wsasm.h:215
size_t ws_buffer_len(WsBuffer *buffer)
Definition: wsbuffer.c:139
WsAsmIns * asm_head
Definition: wsint.h:224
static struct @112 operands[256]
#define WS_ASM_CONST_INVALID
Definition: wsasm.h:174
#define WS_ASM_P_CALL_URL
Definition: wsasm.h:230
#define WS_ASM_DIV
Definition: wsasm.h:186
#define WS_ASM_CALL_URL
Definition: wsasm.h:152
#define WS_ASM_CONST_M1
Definition: wsasm.h:172
#define WS_ASM_CONST_FALSE
Definition: wsasm.h:176
#define WS_ASM_P_JUMP
Definition: wsasm.h:226
unsigned char WsUInt8
Definition: wsint.h:116
#define WS_ASM_B_LSHIFT
Definition: wsasm.h:194
#define WS_ASM_JUMP_BW_W
Definition: wsasm.h:136
#define WS_ASM_ISVALID
Definition: wsasm.h:213
#define WS_ASM_TJUMP_BW_W
Definition: wsasm.h:143
#define WS_ASM_P_TJUMP
Definition: wsasm.h:227
WsUInt16 type
Definition: wsasm.h:257
#define WS_ASM_B_NOT
Definition: wsasm.h:193
#define WS_ASM_LE
Definition: wsasm.h:199
#define WS_ASM_REM
Definition: wsasm.h:188
unsigned short WsUInt16
Definition: wsint.h:119
#define WS_ASM_CALL
Definition: wsasm.h:146
#define WS_ASM_JUMP_BW_S
Definition: wsasm.h:134
struct WsAsmInsRec * next
Definition: wsasm.h:255
#define WS_ASM_DECR
Definition: wsasm.h:179
#define WS_ASM_INCR_VAR_S
Definition: wsasm.h:161
#define WS_OPSIZE(op)
Definition: wsasm.c:77
#define WS_ASM_LOAD_VAR
Definition: wsasm.h:156
#define WS_ASM_GT
Definition: wsasm.h:202
#define WS_ASM_P_LOAD_VAR
Definition: wsasm.h:231
#define WS_ASM_NE
Definition: wsasm.h:203
#define WS_ASM_LOAD_CONST_W
Definition: wsasm.h:168
#define WS_ASM_CALL_LIB_S
Definition: wsasm.h:148
WsBool ws_encode_buffer(WsBuffer *buffer,...)
Definition: wsencode.c:123
#define WS_ASM_LOAD_VAR_S
Definition: wsasm.h:155
#define WS_ASM_TOBOOL
Definition: wsasm.h:208
#define WS_ASM_B_OR
Definition: wsasm.h:191
#define WS_ASM_POP
Definition: wsasm.h:210
#define WS_ASM_TJUMP_BW
Definition: wsasm.h:142
#define WS_ASM_TJUMP_FW_S
Definition: wsasm.h:138
#define WS_ASM_B_XOR
Definition: wsasm.h:192
WsBool
Definition: wsint.h:128
#define WS_ASM_CONST_1
Definition: wsasm.h:171
#define WS_ASM_EQ
Definition: wsasm.h:198
#define WS_ASM_STORE_VAR
Definition: wsasm.h:159
#define WS_ASM_DECR_VAR
Definition: wsasm.h:164
#define WS_ASM_P_STORE_VAR
Definition: wsasm.h:232
#define WS_ASM_CALL_URL_W
Definition: wsasm.h:153
#define WS_ASM_CALL_LIB_W
Definition: wsasm.h:150
#define WS_ASM_TJUMP_FW
Definition: wsasm.h:139
#define WS_ASM_INCR
Definition: wsasm.h:178
#define WS_ASM_INCR_VAR
Definition: wsasm.h:162
#define WS_ASM_STORE_VAR_S
Definition: wsasm.h:158
#define WS_ASM_B_RSZSHIFT
Definition: wsasm.h:196
#define WS_ASM_P_LOAD_CONST
Definition: wsasm.h:234
#define WS_ASM_SUB_ASG
Definition: wsasm.h:181
#define WS_ASM_DEBUG
Definition: wsasm.h:218
#define WS_ASM_TJUMP_FW_W
Definition: wsasm.h:140
#define WS_ASM_UMINUS
Definition: wsasm.h:182
#define WS_ASM_LOAD_CONST_S
Definition: wsasm.h:166
#define WS_ASM_GE
Definition: wsasm.h:201
#define WS_ASM_P_INCR_VAR
Definition: wsasm.h:233
#define WS_ASM_CALL_S
Definition: wsasm.h:145
unsigned char WsByte
Definition: wsint.h:113
#define WS_ASM_B_AND
Definition: wsasm.h:190
#define WS_ASM_IDIV
Definition: wsasm.h:187
#define WS_ASM_JUMP_FW
Definition: wsasm.h:131
#define WS_ASM_CONST_0
Definition: wsasm.h:170
#define WS_ASM_MUL
Definition: wsasm.h:185
#define WS_ASM_ADD
Definition: wsasm.h:183
void ws_error_memory(WsCompilerPtr compiler)
Definition: wserror.c:107
#define WS_ASM_CONST_ES
Definition: wsasm.h:173
WsBuffer byte_code
Definition: wsint.h:229
#define WS_ASM_P_CALL
Definition: wsasm.h:228
#define WS_ASM_RETURN_ES
Definition: wsasm.h:216
#define WS_ASM_SCAND
Definition: wsasm.h:206
#define WS_ASM_LT
Definition: wsasm.h:200
#define WS_ASM_SUB
Definition: wsasm.h:184

◆ ws_asm_link()

void ws_asm_link ( WsCompiler compiler,
WsAsmIns ins 
)

Definition at line 93 of file wsasm.c.

References WsCompilerRec::asm_head, WsCompilerRec::asm_tail, WsAsmInsRec::next, and WsAsmInsRec::prev.

Referenced by linearize_variable_init(), ws_expr_linearize(), and ws_stmt_linearize().

94 {
95  if (compiler->asm_tail) {
96  compiler->asm_tail->next = ins;
97  ins->prev = compiler->asm_tail;
98 
99  compiler->asm_tail = ins;
100  } else
101  compiler->asm_tail = compiler->asm_head = ins;
102 }
WsAsmIns * asm_head
Definition: wsint.h:224
WsAsmIns * asm_tail
Definition: wsint.h:225
struct WsAsmInsRec * next
Definition: wsasm.h:255
struct WsAsmInsRec * prev
Definition: wsasm.h:256

◆ ws_asm_load_const()

WsAsmIns* ws_asm_load_const ( WsCompiler compiler,
WsUInt32  line,
WsUInt16  cindex 
)

Definition at line 908 of file wsasm.c.

References asm_alloc(), and WS_ASM_P_LOAD_CONST.

Referenced by ws_expr_linearize().

910 {
911  WsAsmIns *ins = asm_alloc(compiler, WS_ASM_P_LOAD_CONST, line);
912 
913  if (ins)
914  ins->ws_cindex = cindex;
915 
916  return ins;
917 }
static WsAsmIns * asm_alloc(WsCompiler *compiler, WsUInt16 type, WsUInt32 line)
Definition: wsasm.c:816
#define WS_ASM_P_LOAD_CONST
Definition: wsasm.h:234

◆ ws_asm_print()

void ws_asm_print ( WsCompiler compiler)

Definition at line 105 of file wsasm.c.

References WsCompilerRec::asm_head, WsCompilerRec::functions, name, WsFunctionRec::name, WsAsmInsRec::next, operands, WsAsmInsRec::type, WS_ASM_ADD_ASG, WS_ASM_OP, WS_ASM_P_CALL, WS_ASM_P_CALL_LIB, WS_ASM_P_CALL_URL, WS_ASM_P_INCR_VAR, WS_ASM_P_JUMP, WS_ASM_P_LABEL, WS_ASM_P_LOAD_CONST, WS_ASM_P_LOAD_VAR, WS_ASM_P_STORE_VAR, WS_ASM_P_TJUMP, WS_ASM_SUB_ASG, ws_fatal(), ws_fprintf(), ws_stdlib_function_name(), and WS_STDOUT.

Referenced by compile_stream().

106 {
107  WsAsmIns *ins;
108 
109  for (ins = compiler->asm_head; ins; ins = ins->next) {
110  if (ins->type > 0xff) {
111  /* A symbolic operand. */
112  switch (ins->type) {
113  case WS_ASM_P_LABEL:
114  ws_fprintf(WS_STDOUT, ".L%d:\t\t\t\t/* refcount=%d */\n",
115  ins->ws_label_idx, ins->ws_label_refcount);
116  break;
117 
118  case WS_ASM_P_JUMP:
119  ws_fprintf(WS_STDOUT, "\tjump*\t\tL%d\n",
120  ins->ws_label->ws_label_idx);
121  break;
122 
123  case WS_ASM_P_TJUMP:
124  ws_fprintf(WS_STDOUT, "\ttjump*\t\tL%d\n",
125  ins->ws_label->ws_label_idx);
126  break;
127 
128  case WS_ASM_P_CALL:
129  ws_fprintf(WS_STDOUT, "\tcall*\t\t%s\n",
130  compiler->functions[ins->ws_findex].name);
131  break;
132 
133  case WS_ASM_P_CALL_LIB:
134  {
135  const char *lib;
136  const char *func;
137 
138  ws_stdlib_function_name(ins->ws_lindex,
139  ins->ws_findex,
140  &lib, &func);
141  ws_fprintf(WS_STDOUT, "\tcall_lib*\t%s.%s\n",
142  lib ? lib : "???",
143  func ? func : "???");
144  }
145  break;
146 
147  case WS_ASM_P_CALL_URL:
148  ws_fprintf(WS_STDOUT, "\tcall_url*\t%u %u %u\n",
149  ins->ws_lindex, ins->ws_findex, ins->ws_args);
150  break;
151 
152  case WS_ASM_P_LOAD_VAR:
153  ws_fprintf(WS_STDOUT, "\tload_var*\t%u\n", ins->ws_vindex);
154  break;
155 
156  case WS_ASM_P_STORE_VAR:
157  ws_fprintf(WS_STDOUT, "\tstore_var*\t%u\n", ins->ws_vindex);
158  break;
159 
160  case WS_ASM_P_INCR_VAR:
161  ws_fprintf(WS_STDOUT, "\tincr_var*\t%u\n", ins->ws_vindex);
162  break;
163 
164  case WS_ASM_P_LOAD_CONST:
165  ws_fprintf(WS_STDOUT, "\tload_const*\t%u\n", ins->ws_cindex);
166  break;
167  }
168  } else {
169  WsUInt8 op = WS_ASM_OP(ins->type);
170 
171  if (operands[op].name) {
172  /* Operands add_asg and sub_asg are special. */
173  if (op == WS_ASM_ADD_ASG || op == WS_ASM_SUB_ASG)
174  ws_fprintf(WS_STDOUT, "\t%s\t\t%u\n", operands[ins->type].name,
175  ins->ws_vindex);
176  else
177  ws_fprintf(WS_STDOUT, "\t%s\n", operands[ins->type].name);
178  } else
179  ws_fatal("ws_asm_print(): unknown operand 0x%x", op);
180  }
181  }
182 }
void ws_fatal(char *fmt,...)
Definition: wserror.c:91
#define WS_ASM_P_CALL_LIB
Definition: wsasm.h:229
#define WS_ASM_P_LABEL
Definition: wsasm.h:225
char * name
Definition: wsasm.c:83
#define WS_ASM_ADD_ASG
Definition: wsasm.h:180
WsAsmIns * asm_head
Definition: wsint.h:224
static struct @112 operands[256]
#define WS_ASM_P_CALL_URL
Definition: wsasm.h:230
#define WS_ASM_P_JUMP
Definition: wsasm.h:226
unsigned char WsUInt8
Definition: wsint.h:116
#define WS_ASM_P_TJUMP
Definition: wsasm.h:227
WsUInt16 type
Definition: wsasm.h:257
void ws_fprintf(WsIOProc io, void *context, const char *fmt,...)
Definition: wserror.c:190
struct WsAsmInsRec * next
Definition: wsasm.h:255
#define WS_ASM_P_LOAD_VAR
Definition: wsasm.h:231
WsFunction * functions
Definition: wsint.h:238
#define WS_ASM_P_STORE_VAR
Definition: wsasm.h:232
#define WS_ASM_P_LOAD_CONST
Definition: wsasm.h:234
WsBool ws_stdlib_function_name(WsUInt16 lindex, WsUInt8 findex, const char **library_return, const char **function_return)
Definition: wsstdlib.c:375
#define WS_ASM_SUB_ASG
Definition: wsasm.h:181
#define WS_ASM_P_INCR_VAR
Definition: wsasm.h:233
char * name
Definition: wsstree.h:199
#define WS_STDOUT
Definition: wserror.h:113
#define WS_ASM_OP(op)
Definition: wsasm.h:102
#define WS_ASM_P_CALL
Definition: wsasm.h:228

◆ ws_asm_variable()

WsAsmIns* ws_asm_variable ( WsCompiler compiler,
WsUInt32  line,
WsUInt16  inst,
WsUInt8  vindex 
)

Definition at line 896 of file wsasm.c.

References asm_alloc().

Referenced by linearize_variable_init(), and ws_expr_linearize().

898 {
899  WsAsmIns *ins = asm_alloc(compiler, inst, line);
900 
901  if (ins)
902  ins->ws_vindex = vindex;
903 
904  return ins;
905 }
static WsAsmIns * asm_alloc(WsCompiler *compiler, WsUInt16 type, WsUInt32 line)
Definition: wsasm.c:816

Variable Documentation

◆ name

char* name

Definition at line 83 of file wsasm.c.

Referenced by ws_asm_print().

◆ operands

struct { ... } operands[256]

Referenced by ws_asm_linearize(), and ws_asm_print().

◆ size

See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.