From f7abe7190d80075baf94350361afb05781ff1f17 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Thu, 17 Jul 2014 22:02:07 +0400 Subject: [PATCH] Implementing var_decl opcode. --- src/libcoreint/interpreter.h | 4 +-- src/libcoreint/opcode-structures.h | 2 +- src/libcoreint/opcodes.c | 42 +++++++++++++++++++++++-- src/libecmaobjects/ecma-helpers-value.c | 24 ++++++++++---- src/libecmaobjects/ecma-helpers.h | 1 + src/libecmaoperations/ecma-operations.h | 7 +++-- 6 files changed, 65 insertions(+), 15 deletions(-) diff --git a/src/libcoreint/interpreter.h b/src/libcoreint/interpreter.h index 3368045e5..7bf733f69 100644 --- a/src/libcoreint/interpreter.h +++ b/src/libcoreint/interpreter.h @@ -27,8 +27,8 @@ opfunc __opfuncs[LAST_OP]; struct __int_data { int pos; /**< current opcode to execute */ - ecma_Object_t *pThisBinding; /**< this binding for current context */ - ecma_Object_t *pLexEnv; /**< current lexical environment */ + ecma_Object_t *this_binding_p; /**< this binding for current context */ + ecma_Object_t *lex_env_p; /**< current lexical environment */ int *root_op_addr; /**< pointer to first opcode saved */ }; diff --git a/src/libcoreint/opcode-structures.h b/src/libcoreint/opcode-structures.h index 2c291729b..7d57a764b 100644 --- a/src/libcoreint/opcode-structures.h +++ b/src/libcoreint/opcode-structures.h @@ -383,7 +383,7 @@ OP_CODE_DECL (loop_postcond, T_IDX_IDX, // Variable declaration OP_CODE_DECL (var_decl, T_IDX, - variable) + variable_name) // TODO New constructor diff --git a/src/libcoreint/opcodes.c b/src/libcoreint/opcodes.c index 06fba08c5..16dc54619 100644 --- a/src/libcoreint/opcodes.c +++ b/src/libcoreint/opcodes.c @@ -131,8 +131,7 @@ free_string_literal_copy(string_literal_copy *str_lit_descr_p) /**< string liter op(remainder) \ op(jmp_up) \ op(jmp_down) \ - op(nop) \ - op(var_decl) + op(nop) #define DEFINE_UNIMPLEMENTED_OP(op) \ ecma_CompletionValue_t opfunc_ ## op(OPCODE opdata, struct __int_data *int_data) { \ @@ -191,6 +190,43 @@ opfunc_jmp (OPCODE opdata, struct __int_data *int_data) ECMA_TARGET_ID_RESERVED); } +/** + * Variable declaration. + * + * See also: ECMA-262 v5, 10.5 - Declaration binding instantiation (block 8). + */ +ecma_CompletionValue_t +opfunc_var_decl(OPCODE opdata, /**< operation data */ + struct __int_data *int_data __unused) /**< interpreter context */ +{ + string_literal_copy variable_name; + init_string_literal_copy( opdata.data.var_decl.variable_name, &variable_name); + + if ( ecma_IsCompletionValueNormalFalse( ecma_OpHasBinding( int_data->lex_env_p, + variable_name.str_p)) ) + { + ecma_OpCreateMutableBinding( int_data->lex_env_p, + variable_name.str_p, + false); // FIXME: Pass configurableBindings + + /* Skipping SetMutableBinding as we have already checked that there were not + * any binding with specified name in current lexical environment + * and CreateMutableBinding sets the created binding's value to undefined */ + JERRY_ASSERT( ecma_is_completion_value_normal_simple_value( ecma_OpGetBindingValue( int_data->lex_env_p, + variable_name.str_p, + true), + ECMA_SIMPLE_VALUE_UNDEFINED) ); + } + + free_string_literal_copy( &variable_name); + + int_data->pos++; + + return ecma_MakeCompletionValue( ECMA_COMPLETION_TYPE_NORMAL, + ecma_MakeSimpleValue( ECMA_SIMPLE_VALUE_EMPTY), + ECMA_TARGET_ID_RESERVED); +} /* opfunc_var_decl */ + /** * Exit from script with specified status code: * 0 - for successful completion @@ -264,5 +300,5 @@ GETOP_IMPL_3 (loop_init_num, start, stop, step) GETOP_IMPL_2 (loop_precond_begin_num, condition, after_loop_op) GETOP_IMPL_3 (loop_precond_end_num, iterator, step, precond_begin) GETOP_IMPL_2 (loop_postcond, condition, body_root) -GETOP_IMPL_1 (var_decl, variable) +GETOP_IMPL_1 (var_decl, variable_name) diff --git a/src/libecmaobjects/ecma-helpers-value.c b/src/libecmaobjects/ecma-helpers-value.c index 170aa40d1..acf6fe358 100644 --- a/src/libecmaobjects/ecma-helpers-value.c +++ b/src/libecmaobjects/ecma-helpers-value.c @@ -242,6 +242,22 @@ ecma_MakeThrowValue( ecma_Object_t *exception_p) /**< an object */ ECMA_TARGET_ID_RESERVED); } /* ecma_MakeThrowValue */ +/** + * Check if the completion value is specified normal simple value. + * + * @return true - if the completion type is normal and + * value contains specified simple ecma-value, + * false - otherwise. + */ +bool +ecma_is_completion_value_normal_simple_value(ecma_CompletionValue_t value, /**< completion value */ + ecma_SimpleValue_t simple_value) /**< simple value to check for equality with */ +{ + return ( value.type == ECMA_COMPLETION_TYPE_NORMAL + && value.value.m_ValueType == ECMA_TYPE_SIMPLE + && value.value.m_Value == simple_value ); +} /* ecma_is_completion_value_normal_simple_value */ + /** * Check if the completion value is normal true. * @@ -252,9 +268,7 @@ ecma_MakeThrowValue( ecma_Object_t *exception_p) /**< an object */ bool ecma_IsCompletionValueNormalTrue( ecma_CompletionValue_t value) /**< completion value */ { - return ( value.type == ECMA_COMPLETION_TYPE_NORMAL - && value.value.m_ValueType == ECMA_TYPE_SIMPLE - && value.value.m_Value == ECMA_SIMPLE_VALUE_TRUE ); + return ecma_is_completion_value_normal_simple_value( value, ECMA_SIMPLE_VALUE_TRUE); } /* ecma_IsCompletionValueNormalTrue */ /** @@ -267,9 +281,7 @@ ecma_IsCompletionValueNormalTrue( ecma_CompletionValue_t value) /**< completion bool ecma_IsCompletionValueNormalFalse( ecma_CompletionValue_t value) /**< completion value */ { - return ( value.type == ECMA_COMPLETION_TYPE_NORMAL - && value.value.m_ValueType == ECMA_TYPE_SIMPLE - && value.value.m_Value == ECMA_SIMPLE_VALUE_FALSE ); + return ecma_is_completion_value_normal_simple_value( value, ECMA_SIMPLE_VALUE_FALSE); } /* ecma_IsCompletionValueNormalFalse */ /** diff --git a/src/libecmaobjects/ecma-helpers.h b/src/libecmaobjects/ecma-helpers.h index 8f87ddaf2..c5273b830 100644 --- a/src/libecmaobjects/ecma-helpers.h +++ b/src/libecmaobjects/ecma-helpers.h @@ -55,6 +55,7 @@ extern void ecma_FreeValue( const ecma_Value_t value); extern ecma_CompletionValue_t ecma_MakeCompletionValue( ecma_CompletionType_t type, ecma_Value_t value, uint8_t target); extern ecma_CompletionValue_t ecma_MakeThrowValue( ecma_Object_t *exception_p); +extern bool ecma_is_completion_value_normal_simple_value( ecma_CompletionValue_t value, ecma_SimpleValue_t simple_value); extern bool ecma_IsCompletionValueNormalFalse( ecma_CompletionValue_t value); extern bool ecma_IsCompletionValueNormalTrue( ecma_CompletionValue_t value); diff --git a/src/libecmaoperations/ecma-operations.h b/src/libecmaoperations/ecma-operations.h index 56b7c7c27..9f4fe9aee 100644 --- a/src/libecmaoperations/ecma-operations.h +++ b/src/libecmaoperations/ecma-operations.h @@ -16,6 +16,10 @@ #ifndef JERRY_ECMA_OPERATIONS_H #define JERRY_ECMA_OPERATIONS_H +#include "ecma-globals.h" +#include "ecma-lex-env.h" +#include "ecma-reference.h" + /** \addtogroup ecma ---TODO--- * @{ * @@ -23,9 +27,6 @@ * @{ */ -#include "ecma-globals.h" -#include "ecma-reference.h" - extern ecma_Reference_t ecma_OpGetIdentifierReference( ecma_Object_t *lex_env_p, ecma_Char_t *name_p, bool is_strict); extern ecma_CompletionValue_t ecma_OpGetValue( ecma_Reference_t *ref_p);