Byte code related symbolic constants and macros in vm.h get better names
and comments. Space consumed by opcode triplets are reduced to 16 bits down from 32 bits. This reduces the opcode triplet tables by 220 bytes. New symbolic constants and defines were also added to describe common operations. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
+31
-29
@@ -153,7 +153,7 @@ vm_init (ecma_compiled_code_t *program_p) /**< pointer to byte-code data */
|
||||
/**
|
||||
* Decode table for opcodes.
|
||||
*/
|
||||
static const uint32_t vm_decode_table[] =
|
||||
static const uint16_t vm_decode_table[] =
|
||||
{
|
||||
CBC_OPCODE_LIST
|
||||
};
|
||||
@@ -161,7 +161,7 @@ static const uint32_t vm_decode_table[] =
|
||||
/**
|
||||
* Decode table for extended opcodes.
|
||||
*/
|
||||
static const uint32_t vm_ext_decode_table[] =
|
||||
static const uint16_t vm_ext_decode_table[] =
|
||||
{
|
||||
CBC_EXT_OPCODE_LIST
|
||||
};
|
||||
@@ -801,11 +801,11 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
|
||||
free_flags = 0;
|
||||
if (opcode_data & (VM_OC_GET_DATA_MASK << VM_OC_GET_DATA_SHIFT))
|
||||
if (VM_OC_HAS_GET_ARGS (opcode_data))
|
||||
{
|
||||
uint32_t operands = VM_OC_GET_DATA_GET_ID (opcode_data);
|
||||
uint32_t operands = VM_OC_GET_ARGS_GET_INDEX (opcode_data);
|
||||
|
||||
if (operands >= VM_OC_GET_DATA_GET_ID (VM_OC_GET_LITERAL))
|
||||
if (operands >= VM_OC_GET_ARGS_GET_INDEX (VM_OC_GET_LITERAL))
|
||||
{
|
||||
uint16_t literal_index;
|
||||
READ_LITERAL_INDEX (literal_index);
|
||||
@@ -815,7 +815,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
|
||||
switch (operands)
|
||||
{
|
||||
case VM_OC_GET_DATA_GET_ID (VM_OC_GET_STACK_LITERAL):
|
||||
case VM_OC_GET_ARGS_GET_INDEX (VM_OC_GET_STACK_LITERAL):
|
||||
{
|
||||
JERRY_ASSERT (stack_top_p > frame_ctx_p->registers_p + register_end);
|
||||
right_value = left_value;
|
||||
@@ -823,12 +823,12 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
free_flags = (uint8_t) ((free_flags << 1) | VM_FREE_LEFT_VALUE);
|
||||
break;
|
||||
}
|
||||
case VM_OC_GET_DATA_GET_ID (VM_OC_GET_LITERAL_BYTE):
|
||||
case VM_OC_GET_ARGS_GET_INDEX (VM_OC_GET_LITERAL_BYTE):
|
||||
{
|
||||
right_value = *(byte_code_p++);
|
||||
break;
|
||||
}
|
||||
case VM_OC_GET_DATA_GET_ID (VM_OC_GET_LITERAL_LITERAL):
|
||||
case VM_OC_GET_ARGS_GET_INDEX (VM_OC_GET_LITERAL_LITERAL):
|
||||
{
|
||||
uint16_t literal_index;
|
||||
READ_LITERAL_INDEX (literal_index);
|
||||
@@ -837,7 +837,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
free_flags |= VM_FREE_RIGHT_VALUE);
|
||||
break;
|
||||
}
|
||||
case VM_OC_GET_DATA_GET_ID (VM_OC_GET_THIS_LITERAL):
|
||||
case VM_OC_GET_ARGS_GET_INDEX (VM_OC_GET_THIS_LITERAL):
|
||||
{
|
||||
right_value = left_value;
|
||||
left_value = ecma_copy_value (frame_ctx_p->this_binding);
|
||||
@@ -846,7 +846,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
default:
|
||||
{
|
||||
JERRY_ASSERT (operands == VM_OC_GET_DATA_GET_ID (VM_OC_GET_LITERAL));
|
||||
JERRY_ASSERT (operands == VM_OC_GET_ARGS_GET_INDEX (VM_OC_GET_LITERAL));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -855,14 +855,14 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
{
|
||||
switch (operands)
|
||||
{
|
||||
case VM_OC_GET_DATA_GET_ID (VM_OC_GET_STACK):
|
||||
case VM_OC_GET_ARGS_GET_INDEX (VM_OC_GET_STACK):
|
||||
{
|
||||
JERRY_ASSERT (stack_top_p > frame_ctx_p->registers_p + register_end);
|
||||
left_value = *(--stack_top_p);
|
||||
free_flags = VM_FREE_LEFT_VALUE;
|
||||
break;
|
||||
}
|
||||
case VM_OC_GET_DATA_GET_ID (VM_OC_GET_STACK_STACK):
|
||||
case VM_OC_GET_ARGS_GET_INDEX (VM_OC_GET_STACK_STACK):
|
||||
{
|
||||
JERRY_ASSERT (stack_top_p > frame_ctx_p->registers_p + register_end + 1);
|
||||
right_value = *(--stack_top_p);
|
||||
@@ -870,7 +870,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
free_flags = VM_FREE_LEFT_VALUE | VM_FREE_RIGHT_VALUE;
|
||||
break;
|
||||
}
|
||||
case VM_OC_GET_DATA_GET_ID (VM_OC_GET_BYTE):
|
||||
case VM_OC_GET_ARGS_GET_INDEX (VM_OC_GET_BYTE):
|
||||
{
|
||||
right_value = *(byte_code_p++);
|
||||
break;
|
||||
@@ -1227,7 +1227,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
case VM_OC_POST_INCR:
|
||||
case VM_OC_POST_DECR:
|
||||
{
|
||||
uint32_t base = VM_OC_GROUP_GET_INDEX (opcode_data) - VM_OC_PROP_PRE_INCR;
|
||||
uint32_t opcode_flags = VM_OC_GROUP_GET_INDEX (opcode_data) - VM_OC_PROP_PRE_INCR;
|
||||
|
||||
last_completion_value = ecma_op_to_number (left_value);
|
||||
|
||||
@@ -1244,9 +1244,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
ecma_integer_value_t int_value = (ecma_integer_value_t) result;
|
||||
ecma_integer_value_t int_increase;
|
||||
|
||||
if (base & 0x2)
|
||||
if (opcode_flags & VM_OC_DECREMENT_OPERATOR_FLAG)
|
||||
{
|
||||
/* For decrement operators */
|
||||
if (int_value <= (ECMA_INTEGER_NUMBER_MIN << ECMA_DIRECT_SHIFT))
|
||||
{
|
||||
int_increase = 0;
|
||||
@@ -1270,12 +1269,12 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
|
||||
if (int_increase != 0)
|
||||
{
|
||||
/* Post operators require the unmodifed number value. */
|
||||
if (base & 0x4)
|
||||
/* Postfix operators require the unmodifed number value. */
|
||||
if (opcode_flags & VM_OC_POST_INCR_DECR_OPERATOR_FLAG)
|
||||
{
|
||||
if (opcode_data & VM_OC_PUT_STACK)
|
||||
{
|
||||
if (base & 0x1)
|
||||
if (opcode_flags & VM_OC_IDENT_INCR_DECR_OPERATOR_FLAG)
|
||||
{
|
||||
JERRY_ASSERT (opcode == CBC_POST_INCR_IDENT_PUSH_RESULT
|
||||
|| opcode == CBC_POST_DECR_IDENT_PUSH_RESULT);
|
||||
@@ -1313,18 +1312,18 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
ecma_number_t increase = ECMA_NUMBER_ONE;
|
||||
ecma_number_t result_number = ecma_get_number_from_value (result);
|
||||
|
||||
if (base & 0x2)
|
||||
if (opcode_flags & VM_OC_DECREMENT_OPERATOR_FLAG)
|
||||
{
|
||||
/* For decrement operators */
|
||||
increase = ECMA_NUMBER_MINUS_ONE;
|
||||
}
|
||||
|
||||
/* Post operators require the unmodifed number value. */
|
||||
if (base & 0x4)
|
||||
if (opcode_flags & VM_OC_POST_INCR_DECR_OPERATOR_FLAG)
|
||||
{
|
||||
if (opcode_data & VM_OC_PUT_STACK)
|
||||
{
|
||||
if (base & 0x1)
|
||||
if (opcode_flags & VM_OC_IDENT_INCR_DECR_OPERATOR_FLAG)
|
||||
{
|
||||
JERRY_ASSERT (opcode == CBC_POST_INCR_IDENT_PUSH_RESULT
|
||||
|| opcode == CBC_POST_DECR_IDENT_PUSH_RESULT);
|
||||
@@ -1433,7 +1432,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (opcode_data & (VM_OC_PUT_DATA_MASK << VM_OC_PUT_DATA_SHIFT))
|
||||
if (VM_OC_HAS_PUT_RESULT (opcode_data))
|
||||
{
|
||||
result = last_completion_value;
|
||||
}
|
||||
@@ -1465,7 +1464,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
goto error;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (opcode_data & (VM_OC_PUT_DATA_MASK << VM_OC_PUT_DATA_SHIFT));
|
||||
JERRY_ASSERT (VM_OC_HAS_PUT_RESULT (opcode_data));
|
||||
result = last_completion_value;
|
||||
break;
|
||||
}
|
||||
@@ -1536,7 +1535,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
case VM_OC_BRANCH_IF_LOGICAL_TRUE:
|
||||
case VM_OC_BRANCH_IF_LOGICAL_FALSE:
|
||||
{
|
||||
uint32_t base = VM_OC_GROUP_GET_INDEX (opcode_data) - VM_OC_BRANCH_IF_TRUE;
|
||||
uint32_t opcode_flags = VM_OC_GROUP_GET_INDEX (opcode_data) - VM_OC_BRANCH_IF_TRUE;
|
||||
|
||||
last_completion_value = ecma_op_to_boolean (left_value);
|
||||
|
||||
@@ -1546,11 +1545,14 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
|
||||
JERRY_ASSERT (free_flags & VM_FREE_LEFT_VALUE);
|
||||
if (last_completion_value == ecma_make_simple_value ((base & 0x1) ? ECMA_SIMPLE_VALUE_FALSE
|
||||
: ECMA_SIMPLE_VALUE_TRUE))
|
||||
|
||||
bool branch_if_false = (opcode_flags & VM_OC_BRANCH_IF_FALSE_FLAG);
|
||||
|
||||
if (last_completion_value == ecma_make_simple_value (branch_if_false ? ECMA_SIMPLE_VALUE_FALSE
|
||||
: ECMA_SIMPLE_VALUE_TRUE))
|
||||
{
|
||||
byte_code_p = byte_code_start_p + branch_offset;
|
||||
if (base & 0x2)
|
||||
if (opcode_flags & VM_OC_LOGICAL_BRANCH_FLAG)
|
||||
{
|
||||
free_flags = 0;
|
||||
++stack_top_p;
|
||||
@@ -2170,7 +2172,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
}
|
||||
|
||||
if (opcode_data & (VM_OC_PUT_DATA_MASK << VM_OC_PUT_DATA_SHIFT))
|
||||
if (VM_OC_HAS_PUT_RESULT (opcode_data))
|
||||
{
|
||||
if (opcode_data & VM_OC_PUT_IDENT)
|
||||
{
|
||||
|
||||
+108
-30
@@ -29,33 +29,71 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define VM_OC_GET_DATA_SHIFT 24
|
||||
#define VM_OC_GET_DATA_MASK 0x1f
|
||||
#define VM_OC_GET_DATA_CREATE_ID(V) \
|
||||
(((V) & VM_OC_GET_DATA_MASK) << VM_OC_GET_DATA_SHIFT)
|
||||
#define VM_OC_GET_DATA_GET_ID(O) \
|
||||
(((O) >> VM_OC_GET_DATA_SHIFT) & VM_OC_GET_DATA_MASK)
|
||||
/**
|
||||
* Each CBC opcode is transformed to three vm opcodes:
|
||||
*
|
||||
* - first opcode is a "get arguments" opcode which specifies
|
||||
* the type (register, literal, stack, etc.) and number
|
||||
* (from 0 to 2) of input arguments
|
||||
* - second opcode is a "group" opcode which specifies
|
||||
* the actual operation (add, increment, call, etc.)
|
||||
* - third opcode is a "put result" opcode which specifies
|
||||
* the destination where the result is stored (register,
|
||||
* stack, etc.)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Position of "get arguments" opcode.
|
||||
*/
|
||||
#define VM_OC_GET_ARGS_SHIFT 7
|
||||
|
||||
/**
|
||||
* Mask of "get arguments" opcode.
|
||||
*/
|
||||
#define VM_OC_GET_ARGS_MASK 0x1f
|
||||
|
||||
/**
|
||||
* Generate the binary representation of a "get arguments" opcode.
|
||||
*/
|
||||
#define VM_OC_GET_ARGS_CREATE_INDEX(V) (((V) & VM_OC_GET_ARGS_MASK) << VM_OC_GET_ARGS_SHIFT)
|
||||
|
||||
/**
|
||||
* Extract the "get arguments" opcode.
|
||||
*/
|
||||
#define VM_OC_GET_ARGS_GET_INDEX(O) (((O) >> VM_OC_GET_ARGS_SHIFT) & VM_OC_GET_ARGS_MASK)
|
||||
|
||||
/**
|
||||
* Checks whether the result is stored somewhere.
|
||||
*/
|
||||
#define VM_OC_HAS_GET_ARGS(V) ((V) & (VM_OC_GET_ARGS_MASK << VM_OC_GET_ARGS_SHIFT))
|
||||
|
||||
/**
|
||||
* Argument getters that are part of the opcodes.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
VM_OC_GET_NONE = VM_OC_GET_DATA_CREATE_ID (0), /**< do nothing */
|
||||
VM_OC_GET_STACK = VM_OC_GET_DATA_CREATE_ID (1), /**< pop one elemnet from the stack */
|
||||
VM_OC_GET_STACK_STACK = VM_OC_GET_DATA_CREATE_ID (2), /**< pop two elemnets from the stack */
|
||||
VM_OC_GET_BYTE = VM_OC_GET_DATA_CREATE_ID (3), /**< read a byte */
|
||||
VM_OC_GET_NONE = VM_OC_GET_ARGS_CREATE_INDEX (0), /**< do nothing */
|
||||
VM_OC_GET_STACK = VM_OC_GET_ARGS_CREATE_INDEX (1), /**< pop one elemnet from the stack */
|
||||
VM_OC_GET_STACK_STACK = VM_OC_GET_ARGS_CREATE_INDEX (2), /**< pop two elemnets from the stack */
|
||||
VM_OC_GET_BYTE = VM_OC_GET_ARGS_CREATE_INDEX (3), /**< read a byte */
|
||||
|
||||
VM_OC_GET_LITERAL = VM_OC_GET_DATA_CREATE_ID (4), /**< resolve literal */
|
||||
VM_OC_GET_STACK_LITERAL = VM_OC_GET_DATA_CREATE_ID (5), /**< pop one elemnet from the stack and resolve a literal*/
|
||||
VM_OC_GET_LITERAL_BYTE = VM_OC_GET_DATA_CREATE_ID (6), /**< pop one elemnet from stack and read a byte */
|
||||
VM_OC_GET_LITERAL_LITERAL = VM_OC_GET_DATA_CREATE_ID (7), /**< resolve two literals */
|
||||
VM_OC_GET_THIS_LITERAL = VM_OC_GET_DATA_CREATE_ID (8), /**< get this and resolve a literal */
|
||||
VM_OC_GET_LITERAL = VM_OC_GET_ARGS_CREATE_INDEX (4), /**< resolve literal */
|
||||
VM_OC_GET_STACK_LITERAL = VM_OC_GET_ARGS_CREATE_INDEX (5), /**< pop one elemnet from the stack
|
||||
* and resolve a literal */
|
||||
VM_OC_GET_LITERAL_BYTE = VM_OC_GET_ARGS_CREATE_INDEX (6), /**< pop one elemnet from stack and read a byte */
|
||||
VM_OC_GET_LITERAL_LITERAL = VM_OC_GET_ARGS_CREATE_INDEX (7), /**< resolve two literals */
|
||||
VM_OC_GET_THIS_LITERAL = VM_OC_GET_ARGS_CREATE_INDEX (8), /**< get this and resolve a literal */
|
||||
} vm_oc_get_types;
|
||||
|
||||
#define VM_OC_GROUP_MASK 0xff
|
||||
#define VM_OC_GROUP_GET_INDEX(O) \
|
||||
((O) & VM_OC_GROUP_MASK)
|
||||
/**
|
||||
* Mask of "group" opcode.
|
||||
*/
|
||||
#define VM_OC_GROUP_MASK 0x7f
|
||||
|
||||
/**
|
||||
* Extract the "group" opcode.
|
||||
*/
|
||||
#define VM_OC_GROUP_GET_INDEX(O) ((O) & VM_OC_GROUP_MASK)
|
||||
|
||||
/**
|
||||
* Opcodes.
|
||||
@@ -88,12 +126,12 @@ typedef enum
|
||||
|
||||
/* These eight opcodes must be in this order. */
|
||||
VM_OC_PROP_PRE_INCR, /**< prefix increment of a property */
|
||||
VM_OC_PRE_INCR, /**< prefix increment */
|
||||
VM_OC_PROP_PRE_DECR, /**< prop prefix decrement of a property */
|
||||
VM_OC_PRE_DECR, /**< prefix decrement */
|
||||
VM_OC_PROP_POST_INCR, /**< prop postfix increment of a property */
|
||||
VM_OC_POST_INCR, /**< postfix increment */
|
||||
VM_OC_PROP_POST_DECR, /**< prop postfix decrement of a property */
|
||||
VM_OC_PRE_INCR, /**< prefix increment */
|
||||
VM_OC_PRE_DECR, /**< prefix decrement */
|
||||
VM_OC_POST_INCR, /**< postfix increment */
|
||||
VM_OC_POST_DECR, /**< postfix decrement */
|
||||
|
||||
VM_OC_PROP_DELETE, /**< delete property */
|
||||
@@ -163,20 +201,60 @@ typedef enum
|
||||
VM_OC_JUMP_AND_EXIT_CONTEXT, /**< jump and exit context */
|
||||
} vm_oc_types;
|
||||
|
||||
#define VM_OC_PUT_DATA_SHIFT 12
|
||||
#define VM_OC_PUT_DATA_MASK 0xf
|
||||
#define VM_OC_PUT_DATA_CREATE_FLAG(V) \
|
||||
(((V) & VM_OC_PUT_DATA_MASK) << VM_OC_PUT_DATA_SHIFT)
|
||||
/**
|
||||
* Decrement operator.
|
||||
*/
|
||||
#define VM_OC_DECREMENT_OPERATOR_FLAG 0x1
|
||||
|
||||
/**
|
||||
* Result writers that are part of the opcodes.
|
||||
* Postfix increment/decrement operator.
|
||||
*/
|
||||
#define VM_OC_POST_INCR_DECR_OPERATOR_FLAG 0x2
|
||||
|
||||
/**
|
||||
* An named variable is updated by the increment/decrement operator.
|
||||
*/
|
||||
#define VM_OC_IDENT_INCR_DECR_OPERATOR_FLAG 0x4
|
||||
|
||||
/**
|
||||
* Jump to target offset if input value is logical false.
|
||||
*/
|
||||
#define VM_OC_BRANCH_IF_FALSE_FLAG 0x1
|
||||
|
||||
/**
|
||||
* Branch optimized for logical and/or opcodes.
|
||||
*/
|
||||
#define VM_OC_LOGICAL_BRANCH_FLAG 0x2
|
||||
|
||||
/**
|
||||
* Position of "put result" opcode.
|
||||
*/
|
||||
#define VM_OC_PUT_RESULT_SHIFT 12
|
||||
|
||||
/**
|
||||
* Mask of "put result" opcode.
|
||||
*/
|
||||
#define VM_OC_PUT_RESULT_MASK 0xf
|
||||
|
||||
/**
|
||||
* Generate a "put result" opcode flag bit.
|
||||
*/
|
||||
#define VM_OC_PUT_RESULT_CREATE_FLAG(V) (((V) & VM_OC_PUT_RESULT_MASK) << VM_OC_PUT_RESULT_SHIFT)
|
||||
|
||||
/**
|
||||
* Checks whether the result is stored somewhere.
|
||||
*/
|
||||
#define VM_OC_HAS_PUT_RESULT(V) ((V) & (VM_OC_PUT_RESULT_MASK << VM_OC_PUT_RESULT_SHIFT))
|
||||
|
||||
/**
|
||||
* Specify where the result is stored
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
VM_OC_PUT_IDENT = VM_OC_PUT_DATA_CREATE_FLAG (0x1),
|
||||
VM_OC_PUT_REFERENCE = VM_OC_PUT_DATA_CREATE_FLAG (0x2),
|
||||
VM_OC_PUT_STACK = VM_OC_PUT_DATA_CREATE_FLAG (0x4),
|
||||
VM_OC_PUT_BLOCK = VM_OC_PUT_DATA_CREATE_FLAG (0x8),
|
||||
VM_OC_PUT_IDENT = VM_OC_PUT_RESULT_CREATE_FLAG (0x1),
|
||||
VM_OC_PUT_REFERENCE = VM_OC_PUT_RESULT_CREATE_FLAG (0x2),
|
||||
VM_OC_PUT_STACK = VM_OC_PUT_RESULT_CREATE_FLAG (0x4),
|
||||
VM_OC_PUT_BLOCK = VM_OC_PUT_RESULT_CREATE_FLAG (0x8),
|
||||
} vm_oc_put_types;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user