Refactoring of libcoreint part1

This commit is contained in:
e.gavrin 2014-08-22 21:13:35 +04:00
parent 6fbf3e4eed
commit d4a9d9430e
26 changed files with 1874 additions and 1959 deletions

View File

@ -119,7 +119,7 @@ run_int_from_pos (opcode_counter_t start_pos,
__memset (regs, 0, sizeof (regs));
JERRY_ASSERT (ecma_is_value_empty (regs[0]));
struct __int_data int_data;
__int_data int_data;
int_data.pos = (opcode_counter_t) (start_pos + 1);
int_data.this_binding = this_binding_value;
int_data.lex_env_p = lex_env_p;

View File

@ -20,21 +20,7 @@
#include "globals.h"
#include "opcodes.h"
typedef uint16_t opcode_counter_t;
struct __int_data
{
opcode_counter_t pos; /**< current opcode to execute */
ecma_value_t this_binding; /**< this binding for current context */
ecma_object_t *lex_env_p; /**< current lexical environment */
bool is_strict; /**< is current code execution mode strict? */
bool is_eval_code; /**< is current code executed with eval */
T_IDX min_reg_num; /**< minimum idx used for register identification */
T_IDX max_reg_num; /**< maximum idx used for register identification */
ecma_value_t *regs_p; /**< register variables */
};
void init_int (const OPCODE* program_p);
void init_int (const __opcode* program_p);
bool run_int (void);
ecma_completion_value_t run_int_from_pos (opcode_counter_t start_pos,
ecma_value_t this_binding_value,
@ -45,7 +31,7 @@ ecma_completion_value_t run_int_from_pos (opcode_counter_t start_pos,
ssize_t try_get_string_by_idx (T_IDX idx, ecma_char_t *buffer_p, ssize_t buffer_size);
ecma_number_t get_number_by_idx (T_IDX idx);
OPCODE read_opcode (opcode_counter_t counter);
__opcode read_opcode (opcode_counter_t counter);
#endif /* INTERPRETER_H */

View File

@ -1,434 +0,0 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OPCODE_STRUCTURES_H
#define OPCODE_STRUCTURES_H
#define OP_DEF(name, list) struct __op_##name { list ; } ;
#define OP_CODE_DECL_VOID(name) \
struct __op_##name { T_IDX __do_not_use; }; \
OPCODE getop_##name (void);
#define OP_CODE_DECL(name, type, ...) \
OP_DEF (name, type##_DECL(__VA_ARGS__)) \
OPCODE getop_##name (type);
#define T_IDX_IDX T_IDX, T_IDX
#define T_IDX_IDX_IDX T_IDX, T_IDX, T_IDX
#define T_IDX_DECL(name) T_IDX name
#define T_IDX_IDX_DECL(name1, name2) \
T_IDX_DECL (name1) ; \
T_IDX_DECL (name2)
#define T_IDX_IDX_IDX_DECL(name1, name2, name3) \
T_IDX_DECL (name1) ; \
T_IDX_DECL (name2); \
T_IDX_DECL (name3)
#define GETOP_IMPL_0(name) \
OPCODE getop_##name () \
{ \
OPCODE opdata; \
opdata.op_idx = __op__idx_##name; \
return opdata; \
}
#define GETOP_IMPL_1(name, field1) \
OPCODE getop_##name (T_IDX arg1) \
{ \
OPCODE opdata; \
opdata.op_idx = __op__idx_##name; \
opdata.data.name.field1 = arg1; \
return opdata; \
}
#define GETOP_IMPL_2(name, field1, field2) \
OPCODE getop_##name (T_IDX arg1, T_IDX arg2) \
{ \
OPCODE opdata; \
opdata.op_idx = __op__idx_##name; \
opdata.data.name.field1 = arg1; \
opdata.data.name.field2 = arg2; \
return opdata; \
}
#define GETOP_IMPL_3(name, field1, field2, field3) \
OPCODE getop_##name (T_IDX arg1, T_IDX arg2, T_IDX arg3) \
{ \
OPCODE opdata; \
opdata.op_idx = __op__idx_##name; \
opdata.data.name.field1 = arg1; \
opdata.data.name.field2 = arg2; \
opdata.data.name.field3 = arg3; \
return opdata; \
}
/** Instruction tests if BOOLEAN value is TRUE and JMP to DST */
OP_CODE_DECL (is_true_jmp, T_IDX_IDX,
value,
opcode)
/** Instruction tests if BOOLEAN value is FALSE and JMP to DST */
OP_CODE_DECL (is_false_jmp, T_IDX_IDX,
value,
opcode)
/** Unconditional JMP to the specified opcode index */
OP_CODE_DECL (jmp, T_IDX,
opcode_idx)
/** Unconditional JMP on opcode_count up */
OP_CODE_DECL (jmp_up, T_IDX,
opcode_count)
/** Unconditional JMP on opcode_count down */
OP_CODE_DECL (jmp_down, T_IDX,
opcode_count)
/** dst = L + R */
OP_CODE_DECL (addition, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = L - R */
OP_CODE_DECL (substraction, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = L / R */
OP_CODE_DECL (division, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = L * R */
OP_CODE_DECL (multiplication, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = L % R */
OP_CODE_DECL (remainder, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = L << R */
OP_CODE_DECL (b_shift_left, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = L >> R */
OP_CODE_DECL (b_shift_right, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = L >>> R */
OP_CODE_DECL (b_shift_uright, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
// Binary bitwise operators.
// Operands is a set of 32 bits
// Returns numerical.
/** dst = L & R */
OP_CODE_DECL (b_and, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = L | R */
OP_CODE_DECL (b_or, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = L ^ R */
OP_CODE_DECL (b_xor, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = ~ R */
OP_CODE_DECL (b_not, T_IDX_IDX,
dst,
var_right)
// Binary logical operators.
// Operands are booleans.
// Return boolean.
/** dst = L && R */
OP_CODE_DECL (logical_and, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = L || R */
OP_CODE_DECL (logical_or, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = ! R */
OP_CODE_DECL (logical_not, T_IDX_IDX,
dst,
var_right)
// Equality operations.
/** dst = L == R. */
OP_CODE_DECL (equal_value, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = L != R. */
OP_CODE_DECL (not_equal_value, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = L === R. */
OP_CODE_DECL (equal_value_type, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = L !== R. */
OP_CODE_DECL (not_equal_value_type, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
// Relational operations.
/** dst = L < R. */
OP_CODE_DECL (less_than, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = L > R. */
OP_CODE_DECL (greater_than, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = L <= R. */
OP_CODE_DECL (less_or_equal_than, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = L >= R. */
OP_CODE_DECL (greater_or_equal_than, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = L instanceof R. */
OP_CODE_DECL (instanceof, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = L in R. */
OP_CODE_DECL (in, T_IDX_IDX_IDX,
dst,
var_left,
var_right)
/** dst = var_right++. */
OP_CODE_DECL (post_incr, T_IDX_IDX,
dst,
var_right)
/** dst = var_right--. */
OP_CODE_DECL (post_decr, T_IDX_IDX,
dst,
var_right)
/** dst = ++var_right. */
OP_CODE_DECL (pre_incr, T_IDX_IDX,
dst,
var_right)
/** dst = --var_right. */
OP_CODE_DECL (pre_decr, T_IDX_IDX,
dst,
var_right)
// Assignment operators.
// Assign value to LEFT operand based on value of RIGHT operand.
/** L = R */
OP_CODE_DECL (assignment, T_IDX_IDX_IDX,
var_left,
type_value_right,
value_right)
// Functions calls, declarations and argument handling
/** a = name (); */
OP_CODE_DECL (call_0, T_IDX_IDX,
lhs,
name_lit_idx)
/** a = name (arg1); */
OP_CODE_DECL (call_1, T_IDX_IDX_IDX,
lhs,
name_lit_idx,
arg1_lit_idx)
/** a = name (arg1, ... */
OP_CODE_DECL (call_n, T_IDX_IDX_IDX,
lhs,
name_lit_idx,
arg1_lit_idx)
/** lhs = name (arg_list) */
OP_CODE_DECL (native_call, T_IDX_IDX_IDX,
lhs,
name,
arg_list)
/** a = new name (arg_list */
OP_CODE_DECL (construct_decl, T_IDX_IDX_IDX,
lhs,
name_lit_idx,
arg_list)
/** name (); */
OP_CODE_DECL (func_decl_0, T_IDX,
name_lit_idx)
/** name (arg1); */
OP_CODE_DECL (func_decl_1, T_IDX_IDX,
name_lit_idx,
arg1_lit_idx)
/** name (arg1, arg2); */
OP_CODE_DECL (func_decl_2, T_IDX_IDX_IDX,
name_lit_idx,
arg1_lit_idx,
arg2_lit_idx)
/** name (arg1, arg2, ... */
OP_CODE_DECL (func_decl_n, T_IDX_IDX_IDX,
name_lit_idx,
arg1_lit_idx,
arg2_lit_idx)
/** arg1, arg2, arg3 */
OP_CODE_DECL (varg_list, T_IDX_IDX_IDX,
arg1_lit_idx,
arg2_lit_idx,
arg3_lit_idx)
/** exit with status code; */
OP_CODE_DECL (exitval, T_IDX,
status_code)
/** return value; */
OP_CODE_DECL (retval, T_IDX,
ret_value)
OP_CODE_DECL_VOID (ret)
OP_CODE_DECL_VOID (nop)
/** a = [list] */
OP_CODE_DECL (array_decl, T_IDX_IDX,
lhs,
list)
/** a = b : c */
OP_CODE_DECL (prop, T_IDX_IDX_IDX,
lhs,
name,
value)
/** a = b.c OR a = b[c] */
OP_CODE_DECL (prop_getter, T_IDX_IDX_IDX,
lhs,
obj,
prop)
/** a.b = c OR a[b] = c */
OP_CODE_DECL (prop_setter, T_IDX_IDX_IDX,
obj,
prop,
rhs)
/** a = get prop () */
OP_CODE_DECL (prop_get_decl, T_IDX_IDX,
lhs,
prop)
/** a = set prop (arg) */
OP_CODE_DECL (prop_set_decl, T_IDX_IDX_IDX,
lhs,
prop,
arg)
/** a = { } */
OP_CODE_DECL (obj_decl, T_IDX_IDX,
lhs,
list)
/** a = this */
OP_CODE_DECL (this, T_IDX,
lhs)
/** a = delete b */
OP_CODE_DECL (delete, T_IDX_IDX,
lhs,
obj)
/** a = typeof b */
OP_CODE_DECL (typeof, T_IDX_IDX,
lhs,
obj)
/** with (b) { */
OP_CODE_DECL (with, T_IDX,
expr)
/** } */
OP_CODE_DECL_VOID (end_with)
// Variable declaration
OP_CODE_DECL (var_decl, T_IDX,
variable_name)
OP_CODE_DECL (reg_var_decl, T_IDX_IDX,
min,
max)
/** meta */
OP_CODE_DECL (meta, T_IDX_IDX_IDX,
type,
data_1,
data_2)
#endif /* OPCODE_STRUCTURES_H */

View File

@ -0,0 +1,140 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "opcodes.h"
#include "opcodes-ecma-support.h"
/**
* 'Jump if true' opcode handler.
*
* Note:
* the opcode changes current opcode position to specified opcode index
* if argument evaluates to true.
*/
ecma_completion_value_t
opfunc_is_true_jmp (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX cond_var_idx = opdata.data.is_true_jmp.value;
const T_IDX dst_opcode_idx = opdata.data.is_true_jmp.opcode;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (cond_value, get_variable_value (int_data, cond_var_idx, false), ret_value);
ecma_completion_value_t to_bool_completion = ecma_op_to_boolean (cond_value.value);
JERRY_ASSERT (ecma_is_completion_value_normal (to_bool_completion));
if (ecma_is_value_true (to_bool_completion.value))
{
int_data->pos = dst_opcode_idx;
}
else
{
int_data->pos++;
}
ret_value = ecma_make_empty_completion_value ();
ECMA_FINALIZE (cond_value);
return ret_value;
} /* opfunc_is_true_jmp */
/**
* 'Jump if false' opcode handler.
*
* Note:
* the opcode changes current opcode position to specified opcode index
* if argument evaluates to false.
*/
ecma_completion_value_t
opfunc_is_false_jmp (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX cond_var_idx = opdata.data.is_false_jmp.value;
const T_IDX dst_opcode_idx = opdata.data.is_false_jmp.opcode;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (cond_value, get_variable_value (int_data, cond_var_idx, false), ret_value);
ecma_completion_value_t to_bool_completion = ecma_op_to_boolean (cond_value.value);
JERRY_ASSERT (ecma_is_completion_value_normal (to_bool_completion));
if (!ecma_is_value_true (to_bool_completion.value))
{
int_data->pos = dst_opcode_idx;
}
else
{
int_data->pos++;
}
ret_value = ecma_make_empty_completion_value ();
ECMA_FINALIZE (cond_value);
return ret_value;
} /* opfunc_is_false_jmp */
/**
* 'Jump' opcode handler.
*
* Note:
* the opcode changes current opcode position to specified opcode index
*/
ecma_completion_value_t
opfunc_jmp (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
int_data->pos = opdata.data.jmp.opcode_idx;
return ecma_make_empty_completion_value ();
} /* opfunc_jmp */
/**
* 'Jump down' opcode handler.
*
* Note:
* the opcode changes adds specified value to current opcode position
*/
ecma_completion_value_t
opfunc_jmp_down (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
JERRY_ASSERT (int_data->pos <= int_data->pos + opdata.data.jmp_up.opcode_count);
int_data->pos = (opcode_counter_t) (int_data->pos + opdata.data.jmp_down.opcode_count);
return ecma_make_empty_completion_value ();
} /* opfunc_jmp_down */
/**
* 'Jump up' opcode handler.
*
* Note:
* the opcode changes substracts specified value from current opcode position
*/
ecma_completion_value_t
opfunc_jmp_up (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
JERRY_ASSERT (int_data->pos >= opdata.data.jmp_up.opcode_count);
int_data->pos = (opcode_counter_t) (int_data->pos - opdata.data.jmp_down.opcode_count);
return ecma_make_empty_completion_value ();
} /* opfunc_jmp_up */

View File

@ -0,0 +1,359 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "opcodes.h"
#include "opcodes-ecma-support.h"
/**
* Number bitwise logic operations.
*/
typedef enum
{
number_bitwise_logic_and, /**< bitwise AND calculation */
number_bitwise_logic_or, /**< bitwise OR calculation */
number_bitwise_logic_xor, /**< bitwise XOR calculation */
number_bitwise_shift_left, /**< bitwise LEFT SHIFT calculation */
number_bitwise_shift_right, /**< bitwise RIGHT_SHIFT calculation */
number_bitwise_shift_uright, /**< bitwise UNSIGNED RIGHT SHIFT calculation */
number_bitwise_not, /**< bitwise NOT calculation */
} number_bitwise_logic_op;
/**
* Perform ECMA number logic operation.
*
* The algorithm of the operation is following:
* leftNum = ToNumber (leftValue);
* rightNum = ToNumber (rightValue);
* result = leftNum BitwiseLogicOp rightNum;
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
static ecma_completion_value_t
do_number_bitwise_logic (__int_data *int_data, /**< interpreter context */
T_IDX dst_var_idx, /**< destination variable identifier */
number_bitwise_logic_op op, /**< number bitwise logic operation */
ecma_value_t left_value, /**< left value */
ecma_value_t right_value) /** right value */
{
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (num_left_value, ecma_op_to_number (left_value), ret_value);
ECMA_TRY_CATCH (num_right_value, ecma_op_to_number (right_value), ret_value);
ecma_number_t *left_p, *right_p;
left_p = (ecma_number_t*) ECMA_GET_POINTER (num_left_value.value.value);
right_p = (ecma_number_t*) ECMA_GET_POINTER (num_right_value.value.value);
ecma_number_t* res_p = ecma_alloc_number ();
int32_t left_int32 = ecma_number_to_int32 (*left_p);
int32_t right_int32 = ecma_number_to_int32 (*right_p);
uint32_t left_uint32 = ecma_number_to_uint32 (*left_p);
uint32_t right_uint32 = ecma_number_to_uint32 (*right_p);
switch (op)
{
case number_bitwise_logic_and:
{
*res_p = ecma_int32_to_number (left_int32 & right_int32);
break;
}
case number_bitwise_logic_or:
{
*res_p = ecma_int32_to_number (left_int32 | right_int32);
break;
}
case number_bitwise_logic_xor:
{
*res_p = ecma_int32_to_number (left_int32 ^ right_int32);
break;
}
case number_bitwise_shift_left:
{
*res_p = ecma_int32_to_number (left_int32 << (right_uint32 & 0x1F));
break;
}
case number_bitwise_shift_right:
{
*res_p = ecma_int32_to_number (left_int32 >> (right_uint32 & 0x1F));
break;
}
case number_bitwise_shift_uright:
{
*res_p = ecma_uint32_to_number (left_uint32 >> (right_uint32 & 0x1F));
break;
}
case number_bitwise_not:
{
*res_p = ecma_int32_to_number (~right_int32);
break;
}
}
ret_value = set_variable_value (int_data,
dst_var_idx,
ecma_make_number_value (res_p));
ecma_dealloc_number (res_p);
ECMA_FINALIZE (num_right_value);
ECMA_FINALIZE (num_left_value);
return ret_value;
} /* do_number_bitwise_logic */
/**
* 'Bitwise AND' opcode handler.
*
* See also: ECMA-262 v5, 11.10
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
opfunc_b_and (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX dst_var_idx = opdata.data.b_and.dst;
const T_IDX left_var_idx = opdata.data.b_and.var_left;
const T_IDX right_var_idx = opdata.data.b_and.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
ret_value = do_number_bitwise_logic (int_data,
dst_var_idx,
number_bitwise_logic_and,
left_value.value,
right_value.value);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_b_and */
/**
* 'Bitwise OR' opcode handler.
*
* See also: ECMA-262 v5, 11.10
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
opfunc_b_or (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX dst_var_idx = opdata.data.b_or.dst;
const T_IDX left_var_idx = opdata.data.b_or.var_left;
const T_IDX right_var_idx = opdata.data.b_or.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
ret_value = do_number_bitwise_logic (int_data,
dst_var_idx,
number_bitwise_logic_or,
left_value.value,
right_value.value);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_b_or */
/**
* 'Bitwise XOR' opcode handler.
*
* See also: ECMA-262 v5, 11.10
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
opfunc_b_xor (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX dst_var_idx = opdata.data.b_xor.dst;
const T_IDX left_var_idx = opdata.data.b_xor.var_left;
const T_IDX right_var_idx = opdata.data.b_xor.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
ret_value = do_number_bitwise_logic (int_data,
dst_var_idx,
number_bitwise_logic_xor,
left_value.value,
right_value.value);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_b_xor */
/**
* 'Left Shift Operator' opcode handler.
*
* See also: ECMA-262 v5, 11.7.1
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
opfunc_b_shift_left (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX dst_var_idx = opdata.data.b_shift_left.dst;
const T_IDX left_var_idx = opdata.data.b_shift_left.var_left;
const T_IDX right_var_idx = opdata.data.b_shift_left.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
ret_value = do_number_bitwise_logic (int_data,
dst_var_idx,
number_bitwise_shift_left,
left_value.value,
right_value.value);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_b_shift_left */
/**
* 'Right Shift Operator' opcode handler.
*
* See also: ECMA-262 v5, 11.7.2
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
opfunc_b_shift_right (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX dst_var_idx = opdata.data.b_shift_right.dst;
const T_IDX left_var_idx = opdata.data.b_shift_right.var_left;
const T_IDX right_var_idx = opdata.data.b_shift_right.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
ret_value = do_number_bitwise_logic (int_data,
dst_var_idx,
number_bitwise_shift_right,
left_value.value,
right_value.value);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_b_shift_right */
/**
* 'Unsigned Right Shift Operator' opcode handler.
*
* See also: ECMA-262 v5, 11.7.3
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
opfunc_b_shift_uright (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX dst_var_idx = opdata.data.b_shift_uright.dst;
const T_IDX left_var_idx = opdata.data.b_shift_uright.var_left;
const T_IDX right_var_idx = opdata.data.b_shift_uright.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
ret_value = do_number_bitwise_logic (int_data,
dst_var_idx,
number_bitwise_shift_uright,
left_value.value,
right_value.value);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_b_shift_uright */
/**
* 'Bitwise NOT Operator' opcode handler.
*
* See also: ECMA-262 v5, 10.4
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
opfunc_b_not (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX dst_var_idx = opdata.data.b_not.dst;
const T_IDX right_var_idx = opdata.data.b_not.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
ret_value = do_number_bitwise_logic (int_data,
dst_var_idx,
number_bitwise_not,
right_value.value,
right_value.value);
ECMA_FINALIZE (right_value);
return ret_value;
} /* opfunc_b_not */

View File

@ -0,0 +1,287 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "opcodes.h"
#include "opcodes-ecma-support.h"
#include "ecma-number-arithmetic.h"
/**
* Number arithmetic operations.
*/
typedef enum
{
number_arithmetic_addition, /**< addition */
number_arithmetic_substraction, /**< substraction */
number_arithmetic_multiplication, /**< multiplication */
number_arithmetic_division, /**< division */
number_arithmetic_remainder, /**< remainder calculation */
} number_arithmetic_op;
/**
* Perform ECMA number arithmetic operation.
*
* The algorithm of the operation is following:
* leftNum = ToNumber (leftValue);
* rightNum = ToNumber (rightValue);
* result = leftNum ArithmeticOp rightNum;
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
static ecma_completion_value_t
do_number_arithmetic (__int_data *int_data, /**< interpreter context */
T_IDX dst_var_idx, /**< destination variable identifier */
number_arithmetic_op op, /**< number arithmetic operation */
ecma_value_t left_value, /**< left value */
ecma_value_t right_value) /** right value */
{
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (num_left_value, ecma_op_to_number (left_value), ret_value);
ECMA_TRY_CATCH (num_right_value, ecma_op_to_number (right_value), ret_value);
ecma_number_t *left_p, *right_p, *res_p;
left_p = (ecma_number_t*) ECMA_GET_POINTER (num_left_value.value.value);
right_p = (ecma_number_t*) ECMA_GET_POINTER (num_right_value.value.value);
res_p = ecma_alloc_number ();
switch (op)
{
case number_arithmetic_addition:
{
*res_p = ecma_op_number_add (*left_p, *right_p);
break;
}
case number_arithmetic_substraction:
{
*res_p = ecma_op_number_substract (*left_p, *right_p);
break;
}
case number_arithmetic_multiplication:
{
*res_p = ecma_op_number_multiply (*left_p, *right_p);
break;
}
case number_arithmetic_division:
{
*res_p = ecma_op_number_divide (*left_p, *right_p);
break;
}
case number_arithmetic_remainder:
{
*res_p = ecma_op_number_remainder (*left_p, *right_p);
break;
}
}
ret_value = set_variable_value (int_data,
dst_var_idx,
ecma_make_number_value (res_p));
ecma_dealloc_number (res_p);
ECMA_FINALIZE (num_right_value);
ECMA_FINALIZE (num_left_value);
return ret_value;
} /* do_number_arithmetic */
/**
* 'Addition' opcode handler.
*
* See also: ECMA-262 v5, 11.6.1
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
opfunc_addition (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX dst_var_idx = opdata.data.addition.dst;
const T_IDX left_var_idx = opdata.data.addition.var_left;
const T_IDX right_var_idx = opdata.data.addition.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
ECMA_TRY_CATCH (prim_left_value, ecma_op_to_primitive (left_value.value, ECMA_PREFERRED_TYPE_NO), ret_value);
ECMA_TRY_CATCH (prim_right_value, ecma_op_to_primitive (right_value.value, ECMA_PREFERRED_TYPE_NO), ret_value);
if (prim_left_value.value.value_type == ECMA_TYPE_STRING
|| prim_right_value.value.value_type == ECMA_TYPE_STRING)
{
JERRY_UNIMPLEMENTED ();
}
else
{
ret_value = do_number_arithmetic (int_data,
dst_var_idx,
number_arithmetic_addition,
prim_left_value.value,
prim_right_value.value);
}
ECMA_FINALIZE (prim_right_value);
ECMA_FINALIZE (prim_left_value);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_addition */
/**
* 'Substraction' opcode handler.
*
* See also: ECMA-262 v5, 11.6.2
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
opfunc_substraction (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX dst_var_idx = opdata.data.substraction.dst;
const T_IDX left_var_idx = opdata.data.substraction.var_left;
const T_IDX right_var_idx = opdata.data.substraction.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
ret_value = do_number_arithmetic (int_data,
dst_var_idx,
number_arithmetic_substraction,
left_value.value,
right_value.value);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_substraction */
/**
* 'Multiplication' opcode handler.
*
* See also: ECMA-262 v5, 11.5, 11.5.1
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
opfunc_multiplication (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX dst_var_idx = opdata.data.multiplication.dst;
const T_IDX left_var_idx = opdata.data.multiplication.var_left;
const T_IDX right_var_idx = opdata.data.multiplication.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
ret_value = do_number_arithmetic (int_data,
dst_var_idx,
number_arithmetic_multiplication,
left_value.value,
right_value.value);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_multiplication */
/**
* 'Division' opcode handler.
*
* See also: ECMA-262 v5, 11.5, 11.5.2
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
opfunc_division (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX dst_var_idx = opdata.data.division.dst;
const T_IDX left_var_idx = opdata.data.division.var_left;
const T_IDX right_var_idx = opdata.data.division.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
ret_value = do_number_arithmetic (int_data,
dst_var_idx,
number_arithmetic_division,
left_value.value,
right_value.value);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_division */
/**
* 'Remainder calculation' opcode handler.
*
* See also: ECMA-262 v5, 11.5, 11.5.3
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
opfunc_remainder (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX dst_var_idx = opdata.data.remainder.dst;
const T_IDX left_var_idx = opdata.data.remainder.var_left;
const T_IDX right_var_idx = opdata.data.remainder.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
ret_value = do_number_arithmetic (int_data,
dst_var_idx,
number_arithmetic_remainder,
left_value.value,
right_value.value);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_remainder */

View File

@ -0,0 +1,182 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OPCODES_ECMA_SUPPORT_H
#define OPCODES_ECMA_SUPPORT_H
#include "ecma-alloc.h"
#include "ecma-comparison.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-function-object.h"
#include "ecma-gc.h"
#include "ecma-helpers.h"
#include "ecma-magic-strings.h"
#include "ecma-number-arithmetic.h"
#include "ecma-operations.h"
#include "ecma-try-catch-macro.h"
#include "ecma-objects.h"
#include "opcodes.h"
static bool do_strict_eval_arguments_check (ecma_reference_t) __unused;
static ecma_completion_value_t get_variable_value (__int_data *, T_IDX, bool) __unused;
static ecma_completion_value_t set_variable_value (__int_data *, T_IDX, ecma_value_t) __unused;
/**
* Perform so-called 'strict eval or arguments reference' check
* that is used in definition of several statement handling algorithms,
* but has no ECMA-defined name.
*
* @return true - if ref is strict reference
* and it's base is lexical environment
* and it's referenced name is 'eval' or 'arguments';
* false - otherwise.
*/
static bool
do_strict_eval_arguments_check (ecma_reference_t ref) /**< ECMA-reference */
{
bool ret;
if (ref.is_strict
&& (ref.base.value_type == ECMA_TYPE_OBJECT)
&& (ECMA_GET_POINTER (ref.base.value) != NULL)
&& (((ecma_object_t*) ECMA_GET_POINTER (ref.base.value))->is_lexical_environment))
{
ecma_string_t* magic_string_eval = ecma_get_magic_string (ECMA_MAGIC_STRING_EVAL);
ecma_string_t* magic_string_arguments = ecma_get_magic_string (ECMA_MAGIC_STRING_ARGUMENTS);
ret = (ecma_compare_ecma_string_to_ecma_string (ref.referenced_name_p,
magic_string_eval) == 0
|| ecma_compare_ecma_string_to_ecma_string (ref.referenced_name_p,
magic_string_arguments) == 0);
ecma_deref_ecma_string (magic_string_eval);
ecma_deref_ecma_string (magic_string_arguments);
}
else
{
ret = false;
}
return ret;
} /* do_strict_eval_arguments_check */
/**
* Get variable's value.
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
static ecma_completion_value_t
get_variable_value (__int_data *int_data, /**< interpreter context */
T_IDX var_idx, /**< variable identifier */
bool do_eval_or_arguments_check) /** run 'strict eval or arguments reference' check
See also: do_strict_eval_arguments_check */
{
ecma_completion_value_t ret_value;
if (var_idx >= int_data->min_reg_num
&& var_idx <= int_data->max_reg_num)
{
ecma_value_t reg_value = int_data->regs_p[ var_idx - int_data->min_reg_num ];
JERRY_ASSERT (!ecma_is_value_empty (reg_value));
ret_value = ecma_make_completion_value (ECMA_COMPLETION_TYPE_NORMAL,
ecma_copy_value (reg_value, true),
ECMA_TARGET_ID_RESERVED);
}
else
{
ecma_reference_t ref;
ecma_string_t *var_name_string_p = ecma_new_ecma_string_from_lit_index (var_idx);
ref = ecma_op_get_identifier_reference (int_data->lex_env_p,
var_name_string_p,
int_data->is_strict);
if (unlikely (do_eval_or_arguments_check
&& do_strict_eval_arguments_check (ref)))
{
ret_value = ecma_make_throw_value (ecma_new_standard_error (ECMA_ERROR_SYNTAX));
}
else
{
ret_value = ecma_op_get_value (ref);
}
ecma_deref_ecma_string (var_name_string_p);
ecma_free_reference (ref);
}
return ret_value;
} /* get_variable_value */
/**
* Set variable's value.
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
static ecma_completion_value_t
set_variable_value (__int_data *int_data, /**< interpreter context */
T_IDX var_idx, /**< variable identifier */
ecma_value_t value) /**< value to set */
{
ecma_completion_value_t ret_value;
if (var_idx >= int_data->min_reg_num
&& var_idx <= int_data->max_reg_num)
{
ecma_value_t reg_value = int_data->regs_p[ var_idx - int_data->min_reg_num ];
if (!ecma_is_value_empty (reg_value))
{
ecma_free_value (reg_value, true);
}
int_data->regs_p[ var_idx - int_data->min_reg_num ] = ecma_copy_value (value, true);
ret_value = ecma_make_empty_completion_value ();
}
else
{
ecma_reference_t ref;
ecma_string_t *var_name_string_p = ecma_new_ecma_string_from_lit_index (var_idx);
ref = ecma_op_get_identifier_reference (int_data->lex_env_p,
var_name_string_p,
int_data->is_strict);
if (unlikely (do_strict_eval_arguments_check (ref)))
{
ret_value = ecma_make_throw_value (ecma_new_standard_error (ECMA_ERROR_SYNTAX));
}
else
{
ret_value = ecma_op_put_value (ref, value);
}
ecma_deref_ecma_string (var_name_string_p);
ecma_free_reference (ref);
}
return ret_value;
} /* set_variable_value */
#endif /* OPCODES_ECMA_SUPPORT_H */

View File

@ -0,0 +1,155 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "opcodes.h"
#include "opcodes-ecma-support.h"
/**
* 'Equals' opcode handler.
*
* See also: ECMA-262 v5, 11.9.1
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
opfunc_equal_value (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX dst_var_idx = opdata.data.equal_value.dst;
const T_IDX left_var_idx = opdata.data.equal_value.var_left;
const T_IDX right_var_idx = opdata.data.equal_value.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
bool is_equal = ecma_op_abstract_equality_compare (left_value.value, right_value.value);
ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_TRUE
: ECMA_SIMPLE_VALUE_FALSE));
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_equal_value */
/**
* 'Does-not-equals' opcode handler.
*
* See also: ECMA-262 v5, 11.9.2
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
opfunc_not_equal_value (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX dst_var_idx = opdata.data.not_equal_value.dst;
const T_IDX left_var_idx = opdata.data.not_equal_value.var_left;
const T_IDX right_var_idx = opdata.data.not_equal_value.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
bool is_equal = ecma_op_abstract_equality_compare (left_value.value, right_value.value);
ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_FALSE
: ECMA_SIMPLE_VALUE_TRUE));
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_not_equal_value */
/**
* 'Strict Equals' opcode handler.
*
* See also: ECMA-262 v5, 11.9.4
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
opfunc_equal_value_type (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX dst_var_idx = opdata.data.equal_value_type.dst;
const T_IDX left_var_idx = opdata.data.equal_value_type.var_left;
const T_IDX right_var_idx = opdata.data.equal_value_type.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
bool is_equal = ecma_op_strict_equality_compare (left_value.value, right_value.value);
ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_TRUE
: ECMA_SIMPLE_VALUE_FALSE));
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_equal_value_type */
/**
* 'Strict Does-not-equals' opcode handler.
*
* See also: ECMA-262 v5, 11.9.5
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
opfunc_not_equal_value_type (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX dst_var_idx = opdata.data.not_equal_value_type.dst;
const T_IDX left_var_idx = opdata.data.not_equal_value_type.var_left;
const T_IDX right_var_idx = opdata.data.not_equal_value_type.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
bool is_equal = ecma_op_strict_equality_compare (left_value.value, right_value.value);
ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_FALSE
: ECMA_SIMPLE_VALUE_TRUE));
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_not_equal_value_type */

View File

@ -0,0 +1,331 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "opcodes.h"
#include "opcodes-ecma-support.h"
/**
* 'Less-than' opcode handler.
*
* See also: ECMA-262 v5, 11.8.1
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
opfunc_less_than (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX dst_var_idx = opdata.data.less_than.dst;
const T_IDX left_var_idx = opdata.data.less_than.var_left;
const T_IDX right_var_idx = opdata.data.less_than.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
ECMA_TRY_CATCH (compare_result,
ecma_op_abstract_relational_compare (left_value.value,
right_value.value,
true),
ret_value);
ecma_simple_value_t res;
if (ecma_is_value_undefined (compare_result.value))
{
res = ECMA_SIMPLE_VALUE_FALSE;
}
else
{
JERRY_ASSERT (ecma_is_value_boolean (compare_result.value));
res = compare_result.value.value;
}
ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (res));
ECMA_FINALIZE (compare_result);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_less_than */
/**
* 'Greater-than' opcode handler.
*
* See also: ECMA-262 v5, 11.8.2
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
opfunc_greater_than (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX dst_var_idx = opdata.data.greater_than.dst;
const T_IDX left_var_idx = opdata.data.greater_than.var_left;
const T_IDX right_var_idx = opdata.data.greater_than.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
ECMA_TRY_CATCH (compare_result,
ecma_op_abstract_relational_compare (right_value.value,
left_value.value,
false),
ret_value);
ecma_simple_value_t res;
if (ecma_is_value_undefined (compare_result.value))
{
res = ECMA_SIMPLE_VALUE_FALSE;
}
else
{
JERRY_ASSERT (ecma_is_value_boolean (compare_result.value));
res = compare_result.value.value;
}
ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (res));
ECMA_FINALIZE (compare_result);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_greater_than */
/**
* 'Less-than-or-equal' opcode handler.
*
* See also: ECMA-262 v5, 11.8.3
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
opfunc_less_or_equal_than (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX dst_var_idx = opdata.data.less_or_equal_than.dst;
const T_IDX left_var_idx = opdata.data.less_or_equal_than.var_left;
const T_IDX right_var_idx = opdata.data.less_or_equal_than.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
ECMA_TRY_CATCH (compare_result,
ecma_op_abstract_relational_compare (right_value.value,
left_value.value,
false),
ret_value);
ecma_simple_value_t res;
if (ecma_is_value_undefined (compare_result.value))
{
res = ECMA_SIMPLE_VALUE_FALSE;
}
else
{
JERRY_ASSERT (ecma_is_value_boolean (compare_result.value));
if (compare_result.value.value == ECMA_SIMPLE_VALUE_TRUE)
{
res = ECMA_SIMPLE_VALUE_FALSE;
}
else
{
res = ECMA_SIMPLE_VALUE_TRUE;
}
}
ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (res));
ECMA_FINALIZE (compare_result);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_less_or_equal_than */
/**
* 'Greater-than-or-equal' opcode handler.
*
* See also: ECMA-262 v5, 11.8.4
*
* @return completion value
* Returned value must be freed with ecma_free_completion_value
*/
ecma_completion_value_t
opfunc_greater_or_equal_than (OPCODE opdata, /**< operation data */
__int_data *int_data) /**< interpreter context */
{
const T_IDX dst_var_idx = opdata.data.greater_or_equal_than.dst;
const T_IDX left_var_idx = opdata.data.greater_or_equal_than.var_left;
const T_IDX right_var_idx = opdata.data.greater_or_equal_than.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
ECMA_TRY_CATCH (compare_result,
ecma_op_abstract_relational_compare (left_value.value,
right_value.value,
true),
ret_value);
ecma_simple_value_t res;
if (ecma_is_value_undefined (compare_result.value))
{
res = ECMA_SIMPLE_VALUE_FALSE;
}
else
{
JERRY_ASSERT (ecma_is_value_boolean (compare_result.value));
if (compare_result.value.value == ECMA_SIMPLE_VALUE_TRUE)
{
res = ECMA_SIMPLE_VALUE_FALSE;
}
else
{
res = ECMA_SIMPLE_VALUE_TRUE;
}
}
ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (res));
ECMA_FINALIZE (compare_result);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_greater_or_equal_than */
/**
* 'instanceof' opcode handler.
*
* See also: ECMA-262 v5, 11.8.6
*
* @return completion value
* returned value must be freed with ecma_free_completion_value.
*/
ecma_completion_value_t
opfunc_instanceof (OPCODE opdata __unused, /**< operation data */
__int_data *int_data __unused) /**< interpreter context */
{
const T_IDX dst_idx = opdata.data.instanceof.dst;
const T_IDX left_var_idx = opdata.data.instanceof.var_left;
const T_IDX right_var_idx = opdata.data.instanceof.var_right;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
if (right_value.value.value_type != ECMA_TYPE_OBJECT)
{
ret_value = ecma_make_throw_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
}
else
{
ecma_object_t *right_value_obj_p = ECMA_GET_POINTER (right_value.value.value);
ECMA_TRY_CATCH (is_instance_of,
ecma_op_object_has_instance (right_value_obj_p,
left_value.value),
ret_value);
ret_value = set_variable_value (int_data, dst_idx, is_instance_of.value);
ECMA_FINALIZE (is_instance_of);
}
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_instanceof */
/**
* 'in' opcode handler.
*
* See also: ECMA-262 v5, 11.8.7
*
* @return completion value
* returned value must be freed with ecma_free_completion_value.
*/
ecma_completion_value_t
opfunc_in (OPCODE opdata __unused, /**< operation data */
__int_data *int_data __unused) /**< interpreter context */
{
const T_IDX dst_idx = opdata.data.in.dst;
const T_IDX left_var_idx = opdata.data.in.var_left;
const T_IDX right_var_idx = opdata.data.in.var_right;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
if (right_value.value.value_type != ECMA_TYPE_OBJECT)
{
ret_value = ecma_make_throw_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
}
else
{
ECMA_TRY_CATCH (str_left_value, ecma_op_to_string (left_value.value), ret_value);
ecma_simple_value_t is_in = ECMA_SIMPLE_VALUE_UNDEFINED;
ecma_string_t *left_value_prop_name_p = ECMA_GET_POINTER (str_left_value.value.value);
ecma_object_t *right_value_obj_p = ECMA_GET_POINTER (right_value.value.value);
if (ecma_op_object_has_property (right_value_obj_p, left_value_prop_name_p))
{
is_in = ECMA_SIMPLE_VALUE_TRUE;
}
else
{
is_in = ECMA_SIMPLE_VALUE_FALSE;
}
ret_value = set_variable_value (int_data,
dst_idx,
ecma_make_simple_value (is_in));
ECMA_FINALIZE (str_left_value);
}
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
return ret_value;
} /* opfunc_in */

View File

@ -0,0 +1,119 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "opcodes-support.h"
#define GETOP_DEF_0(name) \
__opcode getop_##name (void) \
{ \
__opcode opdata; \
opdata.op_idx = __op__idx_##name; \
return opdata; \
}
#define GETOP_DEF_1(name, field1) \
__opcode getop_##name (T_IDX arg1) \
{ \
__opcode opdata; \
opdata.op_idx = __op__idx_##name; \
opdata.data.name.field1 = arg1; \
return opdata; \
}
#define GETOP_DEF_2(name, field1, field2) \
__opcode getop_##name (T_IDX arg1, T_IDX arg2) \
{ \
__opcode opdata; \
opdata.op_idx = __op__idx_##name; \
opdata.data.name.field1 = arg1; \
opdata.data.name.field2 = arg2; \
return opdata; \
}
#define GETOP_DEF_3(name, field1, field2, field3) \
__opcode getop_##name (T_IDX arg1, T_IDX arg2, T_IDX arg3) \
{ \
__opcode opdata; \
opdata.op_idx = __op__idx_##name; \
opdata.data.name.field1 = arg1; \
opdata.data.name.field2 = arg2; \
opdata.data.name.field3 = arg3; \
return opdata; \
}
GETOP_DEF_3 (construct_decl, lhs, name_lit_idx, arg_list)
GETOP_DEF_1 (func_decl_0, name_lit_idx)
GETOP_DEF_2 (array_decl, lhs, list)
GETOP_DEF_3 (prop, lhs, name, value)
GETOP_DEF_3 (prop_getter, lhs, obj, prop)
GETOP_DEF_3 (prop_setter, obj, prop, rhs)
GETOP_DEF_2 (prop_get_decl, lhs, prop)
GETOP_DEF_3 (prop_set_decl, lhs, prop, arg)
GETOP_DEF_2 (obj_decl, lhs, list)
GETOP_DEF_1 (this, lhs)
GETOP_DEF_2 (delete, lhs, obj)
GETOP_DEF_2 (typeof, lhs, obj)
GETOP_DEF_1 (with, expr)
GETOP_DEF_0 (end_with)
GETOP_DEF_1 (var_decl, variable_name)
GETOP_DEF_2 (reg_var_decl, min, max)
GETOP_DEF_3 (meta, type, data_1, data_2)
GETOP_DEF_2 (is_true_jmp, value, opcode)
GETOP_DEF_2 (is_false_jmp, value, opcode)
GETOP_DEF_1 (jmp, opcode_idx)
GETOP_DEF_1 (jmp_up, opcode_count)
GETOP_DEF_1 (jmp_down, opcode_count)
GETOP_DEF_3 (addition, dst, var_left, var_right)
GETOP_DEF_2 (post_incr, dst, var_right)
GETOP_DEF_2 (post_decr, dst, var_right)
GETOP_DEF_2 (pre_incr, dst, var_right)
GETOP_DEF_2 (pre_decr, dst, var_right)
GETOP_DEF_3 (substraction, dst, var_left, var_right)
GETOP_DEF_3 (division, dst, var_left, var_right)
GETOP_DEF_3 (multiplication, dst, var_left, var_right)
GETOP_DEF_3 (remainder, dst, var_left, var_right)
GETOP_DEF_3 (b_shift_left, dst, var_left, var_right)
GETOP_DEF_3 (b_shift_right, dst, var_left, var_right)
GETOP_DEF_3 (b_shift_uright, dst, var_left, var_right)
GETOP_DEF_3 (b_and, dst, var_left, var_right)
GETOP_DEF_3 (b_or, dst, var_left, var_right)
GETOP_DEF_3 (b_xor, dst, var_left, var_right)
GETOP_DEF_3 (logical_and, dst, var_left, var_right)
GETOP_DEF_3 (logical_or, dst, var_left, var_right)
GETOP_DEF_3 (equal_value, dst, var_left, var_right)
GETOP_DEF_3 (not_equal_value, dst, var_left, var_right)
GETOP_DEF_3 (equal_value_type, dst, var_left, var_right)
GETOP_DEF_3 (not_equal_value_type, dst, var_left, var_right)
GETOP_DEF_3 (less_than, dst, var_left, var_right)
GETOP_DEF_3 (greater_than, dst, var_left, var_right)
GETOP_DEF_3 (less_or_equal_than, dst, var_left, var_right)
GETOP_DEF_3 (greater_or_equal_than, dst, var_left, var_right)
GETOP_DEF_3 (assignment, var_left, type_value_right, value_right)
GETOP_DEF_2 (call_0, lhs, name_lit_idx)
GETOP_DEF_3 (call_1, lhs, name_lit_idx, arg1_lit_idx)
GETOP_DEF_3 (call_n, lhs, name_lit_idx, arg1_lit_idx)
GETOP_DEF_3 (native_call, lhs, name, arg_list)
GETOP_DEF_2 (func_decl_1, name_lit_idx, arg1_lit_idx)
GETOP_DEF_3 (func_decl_2, name_lit_idx, arg1_lit_idx, arg2_lit_idx)
GETOP_DEF_3 (func_decl_n, name_lit_idx, arg1_lit_idx, arg2_lit_idx)
GETOP_DEF_3 (varg_list, arg1_lit_idx, arg2_lit_idx, arg3_lit_idx)
GETOP_DEF_1 (exitval, status_code)
GETOP_DEF_1 (retval, ret_value)
GETOP_DEF_0 (ret)
GETOP_DEF_0 (nop)
GETOP_DEF_2 (b_not, dst, var_right)
GETOP_DEF_2 (logical_not, dst, var_right)
GETOP_DEF_3 (instanceof, dst, var_left, var_right)
GETOP_DEF_3 (in, dst, var_left, var_right)

View File

@ -0,0 +1,99 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OPCODES_SUPPORT_H
#define OPCODES_SUPPORT_H
#include "opcodes.h"
#define GETOP_DECL_0(name) \
__opcode getop_##name (void);
#define GETOP_DECL_1(name, field1) \
__opcode getop_##name (T_IDX);
#define GETOP_DECL_2(name, field1, field2) \
__opcode getop_##name (T_IDX, T_IDX);
#define GETOP_DECL_3(name, field1, field2, field3) \
__opcode getop_##name (T_IDX, T_IDX, T_IDX);
GETOP_DECL_3 (construct_decl, lhs, name_lit_idx, arg_list)
GETOP_DECL_1 (func_decl_0, name_lit_idx)
GETOP_DECL_2 (array_decl, lhs, list)
GETOP_DECL_3 (prop, lhs, name, value)
GETOP_DECL_3 (prop_getter, lhs, obj, prop)
GETOP_DECL_3 (prop_setter, obj, prop, rhs)
GETOP_DECL_2 (prop_get_decl, lhs, prop)
GETOP_DECL_3 (prop_set_decl, lhs, prop, arg)
GETOP_DECL_2 (obj_decl, lhs, list)
GETOP_DECL_1 (this, lhs)
GETOP_DECL_2 (delete, lhs, obj)
GETOP_DECL_2 (typeof, lhs, obj)
GETOP_DECL_1 (with, expr)
GETOP_DECL_0 (end_with)
GETOP_DECL_1 (var_decl, variable_name)
GETOP_DECL_2 (reg_var_decl, min, max)
GETOP_DECL_3 (meta, type, data_1, data_2)
GETOP_DECL_2 (is_true_jmp, value, opcode)
GETOP_DECL_2 (is_false_jmp, value, opcode)
GETOP_DECL_1 (jmp, opcode_idx)
GETOP_DECL_1 (jmp_up, opcode_count)
GETOP_DECL_1 (jmp_down, opcode_count)
GETOP_DECL_3 (addition, dst, var_left, var_right)
GETOP_DECL_2 (post_incr, dst, var_right)
GETOP_DECL_2 (post_decr, dst, var_right)
GETOP_DECL_2 (pre_incr, dst, var_right)
GETOP_DECL_2 (pre_decr, dst, var_right)
GETOP_DECL_3 (substraction, dst, var_left, var_right)
GETOP_DECL_3 (division, dst, var_left, var_right)
GETOP_DECL_3 (multiplication, dst, var_left, var_right)
GETOP_DECL_3 (remainder, dst, var_left, var_right)
GETOP_DECL_3 (b_shift_left, dst, var_left, var_right)
GETOP_DECL_3 (b_shift_right, dst, var_left, var_right)
GETOP_DECL_3 (b_shift_uright, dst, var_left, var_right)
GETOP_DECL_3 (b_and, dst, var_left, var_right)
GETOP_DECL_3 (b_or, dst, var_left, var_right)
GETOP_DECL_3 (b_xor, dst, var_left, var_right)
GETOP_DECL_3 (logical_and, dst, var_left, var_right)
GETOP_DECL_3 (logical_or, dst, var_left, var_right)
GETOP_DECL_3 (equal_value, dst, var_left, var_right)
GETOP_DECL_3 (not_equal_value, dst, var_left, var_right)
GETOP_DECL_3 (equal_value_type, dst, var_left, var_right)
GETOP_DECL_3 (not_equal_value_type, dst, var_left, var_right)
GETOP_DECL_3 (less_than, dst, var_left, var_right)
GETOP_DECL_3 (greater_than, dst, var_left, var_right)
GETOP_DECL_3 (less_or_equal_than, dst, var_left, var_right)
GETOP_DECL_3 (greater_or_equal_than, dst, var_left, var_right)
GETOP_DECL_3 (assignment, var_left, type_value_right, value_right)
GETOP_DECL_2 (call_0, lhs, name_lit_idx)
GETOP_DECL_3 (call_1, lhs, name_lit_idx, arg1_lit_idx)
GETOP_DECL_3 (call_n, lhs, name_lit_idx, arg1_lit_idx)
GETOP_DECL_3 (native_call, lhs, name, arg_list)
GETOP_DECL_2 (func_decl_1, name_lit_idx, arg1_lit_idx)
GETOP_DECL_3 (func_decl_2, name_lit_idx, arg1_lit_idx, arg2_lit_idx)
GETOP_DECL_3 (func_decl_n, name_lit_idx, arg1_lit_idx, arg2_lit_idx)
GETOP_DECL_3 (varg_list, arg1_lit_idx, arg2_lit_idx, arg3_lit_idx)
GETOP_DECL_1 (exitval, status_code)
GETOP_DECL_1 (retval, ret_value)
GETOP_DECL_0 (ret)
GETOP_DECL_0 (nop)
GETOP_DECL_2 (b_not, dst, var_right)
GETOP_DECL_2 (logical_not, dst, var_right)
GETOP_DECL_3 (instanceof, dst, var_left, var_right)
GETOP_DECL_3 (in, dst, var_left, var_right)
#endif /* OPCODES_SUPPORT_H */

File diff suppressed because it is too large Load Diff

View File

@ -19,22 +19,26 @@
#include "ecma-globals.h"
#include "globals.h"
#define OPCODE struct __opcode
struct __int_data;
#define OP_STRUCT_FIELD(name) struct __op_##name name;
#define OP_ENUM_FIELD(name) __op__idx_##name ,
#define OP_FUNC_DECL(name) ecma_completion_value_t opfunc_##name (OPCODE, struct __int_data *);
/** A single bytecode instruction is 32bit wide and has an 8bit opcode field
and several operand of 8 of 16 bit.*/
// OPCODE FIELD TYPES
#define T_IDX uint8_t /** index values */
#define OPCODE __opcode
OPCODE;
typedef
ecma_completion_value_t (*opfunc) (OPCODE, struct __int_data *);
#define OP_STRUCT_FIELD(name) __op_##name name;
#define OP_ENUM_FIELD(name) __op__idx_##name ,
#define OP_FUNC_DECL(name) ecma_completion_value_t opfunc_##name (__opcode, __int_data*);
typedef uint16_t opcode_counter_t;
typedef struct
{
opcode_counter_t pos; /**< current opcode to execute */
ecma_value_t this_binding; /**< this binding for current context */
ecma_object_t *lex_env_p; /**< current lexical environment */
bool is_strict; /**< is current code execution mode strict? */
bool is_eval_code; /**< is current code executed with eval */
T_IDX min_reg_num; /**< minimum idx used for register identification */
T_IDX max_reg_num; /**< maximum idx used for register identification */
ecma_value_t *regs_p; /**< register variables */
} __int_data;
#define OP_CALLS_AND_ARGS(op) \
op (call_0) \
@ -135,7 +139,108 @@ ecma_completion_value_t (*opfunc) (OPCODE, struct __int_data *);
op (reg_var_decl)\
op (meta)
#include "opcode-structures.h"
#define OP_DATA (name, list) typedef struct { list ; } __op_##name;
#define OP_DATA_0(name) \
typedef struct \
{ \
T_IDX __do_not_use; \
} __op_##name
#define OP_DATA_1(name, arg1) \
typedef struct \
{ \
T_IDX arg1; \
} __op_##name
#define OP_DATA_2(name, arg1, arg2) \
typedef struct \
{ \
T_IDX arg1; \
T_IDX arg2; \
} __op_##name
#define OP_DATA_3(name, arg1, arg2, arg3) \
typedef struct \
{ \
T_IDX arg1; \
T_IDX arg2; \
T_IDX arg3; \
} __op_##name
OP_DATA_2 (is_true_jmp, value, opcode);
OP_DATA_2 (is_false_jmp, value, opcode);
OP_DATA_1 (jmp, opcode_idx);
OP_DATA_1 (jmp_up, opcode_count);
OP_DATA_1 (jmp_down, opcode_count);
OP_DATA_3 (addition, dst, var_left, var_right);
OP_DATA_2 (post_incr, dst, var_right);
OP_DATA_2 (post_decr, dst, var_right);
OP_DATA_2 (pre_incr, dst, var_right);
OP_DATA_2 (pre_decr, dst, var_right);
OP_DATA_3 (substraction, dst, var_left, var_right);
OP_DATA_3 (division, dst, var_left, var_right);
OP_DATA_3 (multiplication, dst, var_left, var_right);
OP_DATA_3 (remainder, dst, var_left, var_right);
OP_DATA_3 (b_shift_left, dst, var_left, var_right);
OP_DATA_3 (b_shift_right, dst, var_left, var_right);
OP_DATA_3 (b_shift_uright, dst, var_left, var_right);
OP_DATA_3 (b_and, dst, var_left, var_right);
OP_DATA_3 (b_or, dst, var_left, var_right);
OP_DATA_3 (b_xor, dst, var_left, var_right);
OP_DATA_3 (logical_and, dst, var_left, var_right);
OP_DATA_3 (logical_or, dst, var_left, var_right);
OP_DATA_3 (equal_value, dst, var_left, var_right);
OP_DATA_3 (not_equal_value, dst, var_left, var_right);
OP_DATA_3 (equal_value_type, dst, var_left, var_right);
OP_DATA_3 (not_equal_value_type, dst, var_left, var_right);
OP_DATA_3 (less_than, dst, var_left, var_right);
OP_DATA_3 (greater_than, dst, var_left, var_right);
OP_DATA_3 (less_or_equal_than, dst, var_left, var_right);
OP_DATA_3 (greater_or_equal_than, dst, var_left, var_right);
OP_DATA_3 (assignment, var_left, type_value_right, value_right);
OP_DATA_2 (call_0, lhs, name_lit_idx);
OP_DATA_3 (call_1, lhs, name_lit_idx, arg1_lit_idx);
OP_DATA_3 (call_n, lhs, name_lit_idx, arg1_lit_idx);
OP_DATA_3 (native_call, lhs, name, arg_list);
OP_DATA_2 (func_decl_1, name_lit_idx, arg1_lit_idx);
OP_DATA_3 (func_decl_2, name_lit_idx, arg1_lit_idx, arg2_lit_idx);
OP_DATA_3 (func_decl_n, name_lit_idx, arg1_lit_idx, arg2_lit_idx);
OP_DATA_3 (varg_list, arg1_lit_idx, arg2_lit_idx, arg3_lit_idx);
OP_DATA_1 (exitval, status_code);
OP_DATA_1 (retval, ret_value);
OP_DATA_0 (ret);
OP_DATA_0 (nop);
OP_DATA_1 (var_decl, variable_name);
OP_DATA_2 (b_not, dst, var_right);
OP_DATA_2 (logical_not, dst, var_right);
OP_DATA_3 (instanceof, dst, var_left, var_right);
OP_DATA_3 (in, dst, var_left, var_right);
OP_DATA_3 (construct_decl, lhs, name_lit_idx, arg_list);
OP_DATA_1 (func_decl_0, name_lit_idx);
OP_DATA_2 (array_decl, lhs, list);
OP_DATA_3 (prop, lhs, name, value);
OP_DATA_3 (prop_getter, lhs, obj, prop);
OP_DATA_3 (prop_setter, obj, prop, rhs);
OP_DATA_2 (prop_get_decl, lhs, prop);
OP_DATA_3 (prop_set_decl, lhs, prop, arg);
OP_DATA_2 (obj_decl, lhs, list);
OP_DATA_1 (this, lhs);
OP_DATA_2 (delete, lhs, obj);
OP_DATA_2 (typeof, lhs, obj);
OP_DATA_1 (with, expr);
OP_DATA_0 (end_with);
OP_DATA_2 (reg_var_decl, min, max);
OP_DATA_3 (meta, type, data_1, data_2);
typedef struct
{
T_IDX op_idx;
union
{
OP_LIST (OP_STRUCT_FIELD)
} data;
} __opcode;
enum __opcode_idx
{
@ -143,19 +248,10 @@ enum __opcode_idx
LAST_OP
};
union __opdata
{
OP_LIST (OP_STRUCT_FIELD)
};
OP_LIST (OP_FUNC_DECL)
OPCODE
{
T_IDX op_idx;
union __opdata data;
}
__packed;
typedef ecma_completion_value_t (*opfunc) (__opcode, __int_data *);
/**
* Descriptor of assignment's second argument

View File

@ -17,7 +17,7 @@
#include "jerry-libc.h"
#include "lexer.h"
#include "parser.h"
#include "opcodes.h"
#include "opcodes-support.h"
#include "serializer.h"
#include "interpreter.h"

View File

@ -25,7 +25,7 @@
#op,
#define OPCODE_SIZE(op) \
sizeof (struct __op_##op) + 1,
sizeof (__op_##op) + 1,
static char* opcode_names[] =
{

View File

@ -19,7 +19,7 @@
#define NAME_TO_ID(op) (__op__idx_##op)
#define OPCODE_SIZE(op) \
sizeof (struct __op_##op) + 1,
sizeof (__op_##op) + 1,
static uint8_t opcode_sizes[] = {
OP_LIST (OPCODE_SIZE)
@ -28,7 +28,7 @@ static uint8_t opcode_sizes[] = {
static bool
opcodes_equal (const OPCODE *opcodes1, OPCODE *opcodes2, uint16_t size)
{
{
uint16_t i;
for (i = 0; i < size; i++)
{
@ -37,11 +37,11 @@ opcodes_equal (const OPCODE *opcodes1, OPCODE *opcodes2, uint16_t size)
if (opcode_num1 != opcode_num2)
return false;
if (opcode_num1 == NAME_TO_ID (nop) || opcode_num1 == NAME_TO_ID (ret)
|| opcode_num1 == NAME_TO_ID (end_with))
return true;
for (j = 1; j < opcode_sizes[opcode_num1]; j++)
if (((uint8_t*)&opcodes1[i])[j] != ((uint8_t*)&opcodes2[i])[j])
return false;

View File

@ -16,7 +16,7 @@
#include "globals.h"
#include "interpreter.h"
#include "mem-allocator.h"
#include "opcodes.h"
#include "opcodes-support.h"
#include "serializer.h"
/**

View File

@ -16,7 +16,7 @@
#include "globals.h"
#include "interpreter.h"
#include "mem-allocator.h"
#include "opcodes.h"
#include "opcodes-support.h"
#include "serializer.h"
/**

View File

@ -16,7 +16,7 @@
#include "globals.h"
#include "interpreter.h"
#include "mem-allocator.h"
#include "opcodes.h"
#include "opcodes-support.h"
#include "serializer.h"
/**

View File

@ -16,7 +16,7 @@
#include "globals.h"
#include "interpreter.h"
#include "mem-allocator.h"
#include "opcodes.h"
#include "opcodes-support.h"
#include "serializer.h"
/**

View File

@ -16,7 +16,7 @@
#include "globals.h"
#include "interpreter.h"
#include "mem-allocator.h"
#include "opcodes.h"
#include "opcodes-support.h"
#include "serializer.h"
#include "optimizer-passes.h"
#include "jerry-libc.h"
@ -91,4 +91,4 @@ main( int __unused argc,
return 1;
return 0;
}
}

View File

@ -22,6 +22,7 @@
#include "lexer.h"
#include "parser.h"
#include "mem-allocator.h"
#include "opcodes-support.h"
#define MAX_STRINGS 100
#define MAX_NUMS 25
@ -55,43 +56,43 @@ main( int __unused argc,
offset = serializer_dump_strings (strings, strings_num);
serializer_dump_nums (nums, nums_count, offset, strings_num);
parser_init ();
parser_parse_program ();
opcodes = deserialize_bytecode ();
serializer_print_opcodes ();
if (!opcodes_equal (opcodes, (OPCODE[]) {
[0] = getop_reg_var_decl (2, 5), // var tmp2 .. tmp5;
[1] = getop_var_decl (0), // var i;
[2] = getop_var_decl (1), // var j;
[3] = getop_assignment (2, 1, 0), // tmp2 = 0;
[4] = getop_assignment (0, 4, 2), // i = tmp2;
[5] = getop_assignment (4, 1, 10),// tmp4 = 10;
[6] = getop_less_than (3, 0, 4), // tmp3 = i < tmp4;
[7] = getop_is_false_jmp (3, 14), // if (!tmp3) goto 14;
[8] = getop_jmp_down (3), // goto 11;
[9] = getop_post_incr (5, 0), // tmp5 = i ++;
[10] = getop_jmp_up (5), // goto 5;
[11] = getop_assignment (2, 1, 10),// tmp2 = 10;
[12] = getop_assignment (1, 4, 2), // j = tmp2;
[13] = getop_jmp_up (5), // goto 8;
[14] = getop_nop (), // ;
[15] = getop_assignment (2, 1, 0), // tmp2 = 0;
[16] = getop_assignment (0, 4, 2), // i = tmp2;
[17] = getop_assignment (4, 1, 10),// tmp7 = 10;
[18] = getop_less_than (3, 0, 4), // tmp3 = i < tmp7;
[19] = getop_is_false_jmp (3, 27), // if (!tmp3) goto 27;
[20] = getop_jmp_down (3), // goto 23;
[21] = getop_post_incr (5, 0), // tmp5 = i ++;
[22] = getop_jmp_up (5), // goto 17;
[23] = getop_nop (), // ;
[24] = getop_assignment (2, 1, 10),// tmp2 = 10;
[25] = getop_assignment (1, 4, 5), // j = tmp2;
[26] = getop_jmp_up (5), // goto 21;
[27] = getop_exitval (0) // exit 0;
[0] = getop_reg_var_decl (2, 5), // var tmp2 .. tmp5;
[1] = getop_var_decl (0), // var i;
[2] = getop_var_decl (1), // var j;
[3] = getop_assignment (2, 1, 0), // tmp2 = 0;
[4] = getop_assignment (0, 4, 2), // i = tmp2;
[5] = getop_assignment (4, 1, 10),// tmp4 = 10;
[6] = getop_less_than (3, 0, 4), // tmp3 = i < tmp4;
[7] = getop_is_false_jmp (3, 14), // if (!tmp3) goto 14;
[8] = getop_jmp_down (3), // goto 11;
[9] = getop_post_incr (5, 0), // tmp5 = i ++;
[10] = getop_jmp_up (5), // goto 5;
[11] = getop_assignment (2, 1, 10),// tmp2 = 10;
[12] = getop_assignment (1, 4, 2), // j = tmp2;
[13] = getop_jmp_up (5), // goto 8;
[14] = getop_nop (), // ;
[15] = getop_assignment (2, 1, 0), // tmp2 = 0;
[16] = getop_assignment (0, 4, 2), // i = tmp2;
[17] = getop_assignment (4, 1, 10),// tmp7 = 10;
[18] = getop_less_than (3, 0, 4), // tmp3 = i < tmp7;
[19] = getop_is_false_jmp (3, 27), // if (!tmp3) goto 27;
[20] = getop_jmp_down (3), // goto 23;
[21] = getop_post_incr (5, 0), // tmp5 = i ++;
[22] = getop_jmp_up (5), // goto 17;
[23] = getop_nop (), // ;
[24] = getop_assignment (2, 1, 10),// tmp2 = 10;
[25] = getop_assignment (1, 4, 5), // j = tmp2;
[26] = getop_jmp_up (5), // goto 21;
[27] = getop_exitval (0) // exit 0;
}, 28))
return 1;
return 0;
}
}

View File

@ -16,7 +16,7 @@
#include "globals.h"
#include "interpreter.h"
#include "mem-allocator.h"
#include "opcodes.h"
#include "opcodes-support.h"
#include "serializer.h"
#include "optimizer-passes.h"
#include "jerry-libc.h"
@ -35,12 +35,12 @@ main( int __unused argc,
[0] = getop_reg_var_decl (5, 5), // tmp6
[1] = getop_assignment (0, OPCODE_ARG_TYPE_STRING, 1), // a = "b"
[2] = getop_var_decl (1), // var b
[3] = getop_func_decl_0 (2), // function c()
[3] = getop_func_decl_0 (2), // function c()
[4] = getop_jmp_down (3), // {
[5] = getop_var_decl (1), // var b
[6] = getop_retval (1), // return b; }
[7] = getop_assignment (5, OPCODE_ARG_TYPE_STRING, 3), // "use strict"
[8] = getop_exitval (0)
[8] = getop_exitval (0)
};
mem_init();
@ -60,16 +60,16 @@ main( int __unused argc,
if (!opcodes_equal (opcodes, (OPCODE[]) {
[0] = getop_reg_var_decl (5, 5), // tmp6
[1] = getop_assignment (5, OPCODE_ARG_TYPE_STRING, 3), // "use strict"
[2] = getop_func_decl_0 (2), // function c()
[2] = getop_func_decl_0 (2), // function c()
[3] = getop_jmp_down (3), // {
[4] = getop_var_decl (1), // var b
[5] = getop_retval (1), // return b; }
[6] = getop_var_decl (1), // var b
[7] = getop_assignment (0, OPCODE_ARG_TYPE_STRING, 1), // a = "b"
[8] = getop_exitval (0)
[8] = getop_exitval (0)
}, 9))
return 1;
return 0;
}
}

View File

@ -16,7 +16,7 @@
#include "globals.h"
#include "interpreter.h"
#include "mem-allocator.h"
#include "opcodes.h"
#include "opcodes-support.h"
#include "serializer.h"
/**

View File

@ -16,7 +16,7 @@
#include "globals.h"
#include "interpreter.h"
#include "mem-allocator.h"
#include "opcodes.h"
#include "opcodes-support.h"
#include "serializer.h"
/**

View File

@ -16,7 +16,7 @@
#include "globals.h"
#include "interpreter.h"
#include "mem-allocator.h"
#include "opcodes.h"
#include "opcodes-support.h"
#include "serializer.h"
/**