1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation 2425bb815Sopenharmony_ci * 3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License. 5425bb815Sopenharmony_ci * You may obtain a copy of the License at 6425bb815Sopenharmony_ci * 7425bb815Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8425bb815Sopenharmony_ci * 9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS 11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and 13425bb815Sopenharmony_ci * limitations under the License. 14425bb815Sopenharmony_ci */ 15425bb815Sopenharmony_ci 16425bb815Sopenharmony_ci#include "ecma-alloc.h" 17425bb815Sopenharmony_ci#include "ecma-gc.h" 18425bb815Sopenharmony_ci#include "ecma-helpers.h" 19425bb815Sopenharmony_ci#include "vm-defines.h" 20425bb815Sopenharmony_ci#include "vm-stack.h" 21425bb815Sopenharmony_ci#include "ecma-iterator-object.h" 22425bb815Sopenharmony_ci 23425bb815Sopenharmony_ci/** \addtogroup vm Virtual machine 24425bb815Sopenharmony_ci * @{ 25425bb815Sopenharmony_ci * 26425bb815Sopenharmony_ci * \addtogroup stack VM stack 27425bb815Sopenharmony_ci * @{ 28425bb815Sopenharmony_ci */ 29425bb815Sopenharmony_ci 30425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (PARSER_WITH_CONTEXT_STACK_ALLOCATION == PARSER_BLOCK_CONTEXT_STACK_ALLOCATION, 31425bb815Sopenharmony_ci parser_with_context_stack_allocation_must_be_equal_to_parser_block_context_stack_allocation); 32425bb815Sopenharmony_ci 33425bb815Sopenharmony_ci/** 34425bb815Sopenharmony_ci * Abort (finalize) the current stack context, and remove it. 35425bb815Sopenharmony_ci * 36425bb815Sopenharmony_ci * @return new stack top 37425bb815Sopenharmony_ci */ 38425bb815Sopenharmony_ciecma_value_t * 39425bb815Sopenharmony_civm_stack_context_abort (vm_frame_ctx_t *frame_ctx_p, /**< frame context */ 40425bb815Sopenharmony_ci ecma_value_t *vm_stack_top_p) /**< current stack top */ 41425bb815Sopenharmony_ci{ 42425bb815Sopenharmony_ci ecma_value_t context_info = vm_stack_top_p[-1]; 43425bb815Sopenharmony_ci 44425bb815Sopenharmony_ci if (context_info & VM_CONTEXT_HAS_LEX_ENV) 45425bb815Sopenharmony_ci { 46425bb815Sopenharmony_ci ecma_object_t *lex_env_p = frame_ctx_p->lex_env_p; 47425bb815Sopenharmony_ci JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL); 48425bb815Sopenharmony_ci frame_ctx_p->lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); 49425bb815Sopenharmony_ci ecma_deref_object (lex_env_p); 50425bb815Sopenharmony_ci } 51425bb815Sopenharmony_ci 52425bb815Sopenharmony_ci switch (VM_GET_CONTEXT_TYPE (context_info)) 53425bb815Sopenharmony_ci { 54425bb815Sopenharmony_ci case VM_CONTEXT_FINALLY_THROW: 55425bb815Sopenharmony_ci case VM_CONTEXT_FINALLY_RETURN: 56425bb815Sopenharmony_ci { 57425bb815Sopenharmony_ci ecma_free_value (vm_stack_top_p[-2]); 58425bb815Sopenharmony_ci /* FALLTHRU */ 59425bb815Sopenharmony_ci } 60425bb815Sopenharmony_ci case VM_CONTEXT_FINALLY_JUMP: 61425bb815Sopenharmony_ci case VM_CONTEXT_TRY: 62425bb815Sopenharmony_ci case VM_CONTEXT_CATCH: 63425bb815Sopenharmony_ci { 64425bb815Sopenharmony_ci VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION); 65425bb815Sopenharmony_ci vm_stack_top_p -= PARSER_TRY_CONTEXT_STACK_ALLOCATION; 66425bb815Sopenharmony_ci break; 67425bb815Sopenharmony_ci } 68425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 69425bb815Sopenharmony_ci case VM_CONTEXT_BLOCK: 70425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 71425bb815Sopenharmony_ci case VM_CONTEXT_WITH: 72425bb815Sopenharmony_ci { 73425bb815Sopenharmony_ci VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_WITH_CONTEXT_STACK_ALLOCATION); 74425bb815Sopenharmony_ci vm_stack_top_p -= PARSER_WITH_CONTEXT_STACK_ALLOCATION; 75425bb815Sopenharmony_ci break; 76425bb815Sopenharmony_ci } 77425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 78425bb815Sopenharmony_ci case VM_CONTEXT_FOR_OF: 79425bb815Sopenharmony_ci { 80425bb815Sopenharmony_ci ecma_value_t iterator = vm_stack_top_p[-3]; 81425bb815Sopenharmony_ci 82425bb815Sopenharmony_ci if (context_info & VM_CONTEXT_CLOSE_ITERATOR) 83425bb815Sopenharmony_ci { 84425bb815Sopenharmony_ci ecma_op_iterator_close (iterator); 85425bb815Sopenharmony_ci } 86425bb815Sopenharmony_ci ecma_free_value (iterator); 87425bb815Sopenharmony_ci 88425bb815Sopenharmony_ci ecma_free_value (vm_stack_top_p[-2]); 89425bb815Sopenharmony_ci VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION); 90425bb815Sopenharmony_ci vm_stack_top_p -= PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION; 91425bb815Sopenharmony_ci break; 92425bb815Sopenharmony_ci } 93425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 94425bb815Sopenharmony_ci default: 95425bb815Sopenharmony_ci { 96425bb815Sopenharmony_ci JERRY_ASSERT (VM_GET_CONTEXT_TYPE (vm_stack_top_p[-1]) == VM_CONTEXT_FOR_IN); 97425bb815Sopenharmony_ci 98425bb815Sopenharmony_ci ecma_collection_t *collection_p; 99425bb815Sopenharmony_ci collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, vm_stack_top_p[-2]); 100425bb815Sopenharmony_ci 101425bb815Sopenharmony_ci ecma_value_t *buffer_p = collection_p->buffer_p; 102425bb815Sopenharmony_ci 103425bb815Sopenharmony_ci for (uint32_t index = vm_stack_top_p[-3]; index < collection_p->item_count; index++) 104425bb815Sopenharmony_ci { 105425bb815Sopenharmony_ci ecma_free_value (buffer_p[index]); 106425bb815Sopenharmony_ci } 107425bb815Sopenharmony_ci 108425bb815Sopenharmony_ci ecma_collection_destroy (collection_p); 109425bb815Sopenharmony_ci 110425bb815Sopenharmony_ci ecma_free_value (vm_stack_top_p[-4]); 111425bb815Sopenharmony_ci 112425bb815Sopenharmony_ci VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION); 113425bb815Sopenharmony_ci vm_stack_top_p -= PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION; 114425bb815Sopenharmony_ci break; 115425bb815Sopenharmony_ci } 116425bb815Sopenharmony_ci } 117425bb815Sopenharmony_ci 118425bb815Sopenharmony_ci return vm_stack_top_p; 119425bb815Sopenharmony_ci} /* vm_stack_context_abort */ 120425bb815Sopenharmony_ci 121425bb815Sopenharmony_ci/** 122425bb815Sopenharmony_ci * Decode branch offset. 123425bb815Sopenharmony_ci * 124425bb815Sopenharmony_ci * @return branch offset 125425bb815Sopenharmony_ci */ 126425bb815Sopenharmony_cistatic uint32_t 127425bb815Sopenharmony_civm_decode_branch_offset (const uint8_t *branch_offset_p, /**< start offset of byte code */ 128425bb815Sopenharmony_ci uint32_t length) /**< length of the branch */ 129425bb815Sopenharmony_ci{ 130425bb815Sopenharmony_ci uint32_t branch_offset = *branch_offset_p; 131425bb815Sopenharmony_ci 132425bb815Sopenharmony_ci JERRY_ASSERT (length >= 1 && length <= 3); 133425bb815Sopenharmony_ci 134425bb815Sopenharmony_ci switch (length) 135425bb815Sopenharmony_ci { 136425bb815Sopenharmony_ci case 3: 137425bb815Sopenharmony_ci { 138425bb815Sopenharmony_ci branch_offset <<= 8; 139425bb815Sopenharmony_ci branch_offset |= *(++branch_offset_p); 140425bb815Sopenharmony_ci /* FALLTHRU */ 141425bb815Sopenharmony_ci } 142425bb815Sopenharmony_ci case 2: 143425bb815Sopenharmony_ci { 144425bb815Sopenharmony_ci branch_offset <<= 8; 145425bb815Sopenharmony_ci branch_offset |= *(++branch_offset_p); 146425bb815Sopenharmony_ci break; 147425bb815Sopenharmony_ci } 148425bb815Sopenharmony_ci } 149425bb815Sopenharmony_ci 150425bb815Sopenharmony_ci return branch_offset; 151425bb815Sopenharmony_ci} /* vm_decode_branch_offset */ 152425bb815Sopenharmony_ci 153425bb815Sopenharmony_ci/** 154425bb815Sopenharmony_ci * Find a finally up to the end position. 155425bb815Sopenharmony_ci * 156425bb815Sopenharmony_ci * @return true - if 'finally' found, 157425bb815Sopenharmony_ci * false - otherwise 158425bb815Sopenharmony_ci */ 159425bb815Sopenharmony_cibool 160425bb815Sopenharmony_civm_stack_find_finally (vm_frame_ctx_t *frame_ctx_p, /**< frame context */ 161425bb815Sopenharmony_ci ecma_value_t **vm_stack_top_ref_p, /**< current stack top */ 162425bb815Sopenharmony_ci vm_stack_context_type_t finally_type, /**< searching this finally */ 163425bb815Sopenharmony_ci uint32_t search_limit) /**< search up-to this byte code */ 164425bb815Sopenharmony_ci{ 165425bb815Sopenharmony_ci ecma_value_t *vm_stack_top_p = *vm_stack_top_ref_p; 166425bb815Sopenharmony_ci 167425bb815Sopenharmony_ci JERRY_ASSERT (finally_type <= VM_CONTEXT_FINALLY_RETURN); 168425bb815Sopenharmony_ci 169425bb815Sopenharmony_ci if (finally_type != VM_CONTEXT_FINALLY_JUMP) 170425bb815Sopenharmony_ci { 171425bb815Sopenharmony_ci search_limit = 0xffffffffu; 172425bb815Sopenharmony_ci } 173425bb815Sopenharmony_ci 174425bb815Sopenharmony_ci while (frame_ctx_p->context_depth > 0) 175425bb815Sopenharmony_ci { 176425bb815Sopenharmony_ci vm_stack_context_type_t context_type; 177425bb815Sopenharmony_ci uint32_t context_end = VM_GET_CONTEXT_END (vm_stack_top_p[-1]); 178425bb815Sopenharmony_ci 179425bb815Sopenharmony_ci if (search_limit < context_end) 180425bb815Sopenharmony_ci { 181425bb815Sopenharmony_ci *vm_stack_top_ref_p = vm_stack_top_p; 182425bb815Sopenharmony_ci return false; 183425bb815Sopenharmony_ci } 184425bb815Sopenharmony_ci 185425bb815Sopenharmony_ci context_type = VM_GET_CONTEXT_TYPE (vm_stack_top_p[-1]); 186425bb815Sopenharmony_ci if (context_type == VM_CONTEXT_TRY || context_type == VM_CONTEXT_CATCH) 187425bb815Sopenharmony_ci { 188425bb815Sopenharmony_ci const uint8_t *byte_code_p; 189425bb815Sopenharmony_ci uint32_t branch_offset_length; 190425bb815Sopenharmony_ci uint32_t branch_offset; 191425bb815Sopenharmony_ci 192425bb815Sopenharmony_ci if (search_limit == context_end) 193425bb815Sopenharmony_ci { 194425bb815Sopenharmony_ci *vm_stack_top_ref_p = vm_stack_top_p; 195425bb815Sopenharmony_ci return false; 196425bb815Sopenharmony_ci } 197425bb815Sopenharmony_ci 198425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 199425bb815Sopenharmony_ci if (vm_stack_top_p[-1] & VM_CONTEXT_HAS_LEX_ENV) 200425bb815Sopenharmony_ci { 201425bb815Sopenharmony_ci ecma_object_t *lex_env_p = frame_ctx_p->lex_env_p; 202425bb815Sopenharmony_ci JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL); 203425bb815Sopenharmony_ci frame_ctx_p->lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); 204425bb815Sopenharmony_ci ecma_deref_object (lex_env_p); 205425bb815Sopenharmony_ci } 206425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 207425bb815Sopenharmony_ci 208425bb815Sopenharmony_ci byte_code_p = frame_ctx_p->byte_code_start_p + context_end; 209425bb815Sopenharmony_ci 210425bb815Sopenharmony_ci if (context_type == VM_CONTEXT_TRY) 211425bb815Sopenharmony_ci { 212425bb815Sopenharmony_ci JERRY_ASSERT (byte_code_p[0] == CBC_EXT_OPCODE); 213425bb815Sopenharmony_ci 214425bb815Sopenharmony_ci if (byte_code_p[1] >= CBC_EXT_CATCH 215425bb815Sopenharmony_ci && byte_code_p[1] <= CBC_EXT_CATCH_3) 216425bb815Sopenharmony_ci { 217425bb815Sopenharmony_ci branch_offset_length = CBC_BRANCH_OFFSET_LENGTH (byte_code_p[1]); 218425bb815Sopenharmony_ci branch_offset = vm_decode_branch_offset (byte_code_p + 2, 219425bb815Sopenharmony_ci branch_offset_length); 220425bb815Sopenharmony_ci 221425bb815Sopenharmony_ci if (finally_type == VM_CONTEXT_FINALLY_THROW) 222425bb815Sopenharmony_ci { 223425bb815Sopenharmony_ci branch_offset += (uint32_t) (byte_code_p - frame_ctx_p->byte_code_start_p); 224425bb815Sopenharmony_ci 225425bb815Sopenharmony_ci vm_stack_top_p[-1] = VM_CREATE_CONTEXT (VM_CONTEXT_CATCH, branch_offset); 226425bb815Sopenharmony_ci 227425bb815Sopenharmony_ci byte_code_p += 2 + branch_offset_length; 228425bb815Sopenharmony_ci frame_ctx_p->byte_code_p = byte_code_p; 229425bb815Sopenharmony_ci 230425bb815Sopenharmony_ci *vm_stack_top_ref_p = vm_stack_top_p; 231425bb815Sopenharmony_ci return true; 232425bb815Sopenharmony_ci } 233425bb815Sopenharmony_ci 234425bb815Sopenharmony_ci byte_code_p += branch_offset; 235425bb815Sopenharmony_ci 236425bb815Sopenharmony_ci if (*byte_code_p == CBC_CONTEXT_END) 237425bb815Sopenharmony_ci { 238425bb815Sopenharmony_ci VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION); 239425bb815Sopenharmony_ci vm_stack_top_p -= PARSER_TRY_CONTEXT_STACK_ALLOCATION; 240425bb815Sopenharmony_ci continue; 241425bb815Sopenharmony_ci } 242425bb815Sopenharmony_ci } 243425bb815Sopenharmony_ci } 244425bb815Sopenharmony_ci else 245425bb815Sopenharmony_ci { 246425bb815Sopenharmony_ci#if !ENABLED (JERRY_ES2015) 247425bb815Sopenharmony_ci if (vm_stack_top_p[-1] & VM_CONTEXT_HAS_LEX_ENV) 248425bb815Sopenharmony_ci { 249425bb815Sopenharmony_ci ecma_object_t *lex_env_p = frame_ctx_p->lex_env_p; 250425bb815Sopenharmony_ci JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL); 251425bb815Sopenharmony_ci frame_ctx_p->lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); 252425bb815Sopenharmony_ci ecma_deref_object (lex_env_p); 253425bb815Sopenharmony_ci } 254425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */ 255425bb815Sopenharmony_ci 256425bb815Sopenharmony_ci if (byte_code_p[0] == CBC_CONTEXT_END) 257425bb815Sopenharmony_ci { 258425bb815Sopenharmony_ci VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION); 259425bb815Sopenharmony_ci vm_stack_top_p -= PARSER_TRY_CONTEXT_STACK_ALLOCATION; 260425bb815Sopenharmony_ci continue; 261425bb815Sopenharmony_ci } 262425bb815Sopenharmony_ci } 263425bb815Sopenharmony_ci 264425bb815Sopenharmony_ci JERRY_ASSERT (byte_code_p[0] == CBC_EXT_OPCODE); 265425bb815Sopenharmony_ci JERRY_ASSERT (byte_code_p[1] >= CBC_EXT_FINALLY 266425bb815Sopenharmony_ci && byte_code_p[1] <= CBC_EXT_FINALLY_3); 267425bb815Sopenharmony_ci 268425bb815Sopenharmony_ci branch_offset_length = CBC_BRANCH_OFFSET_LENGTH (byte_code_p[1]); 269425bb815Sopenharmony_ci branch_offset = vm_decode_branch_offset (byte_code_p + 2, 270425bb815Sopenharmony_ci branch_offset_length); 271425bb815Sopenharmony_ci 272425bb815Sopenharmony_ci branch_offset += (uint32_t) (byte_code_p - frame_ctx_p->byte_code_start_p); 273425bb815Sopenharmony_ci 274425bb815Sopenharmony_ci vm_stack_top_p[-1] = VM_CREATE_CONTEXT ((uint32_t) finally_type, branch_offset); 275425bb815Sopenharmony_ci 276425bb815Sopenharmony_ci byte_code_p += 2 + branch_offset_length; 277425bb815Sopenharmony_ci frame_ctx_p->byte_code_p = byte_code_p; 278425bb815Sopenharmony_ci 279425bb815Sopenharmony_ci *vm_stack_top_ref_p = vm_stack_top_p; 280425bb815Sopenharmony_ci return true; 281425bb815Sopenharmony_ci } 282425bb815Sopenharmony_ci 283425bb815Sopenharmony_ci vm_stack_top_p = vm_stack_context_abort (frame_ctx_p, vm_stack_top_p); 284425bb815Sopenharmony_ci } 285425bb815Sopenharmony_ci 286425bb815Sopenharmony_ci *vm_stack_top_ref_p = vm_stack_top_p; 287425bb815Sopenharmony_ci return false; 288425bb815Sopenharmony_ci} /* vm_stack_find_finally */ 289425bb815Sopenharmony_ci 290425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 291425bb815Sopenharmony_ci 292425bb815Sopenharmony_ci/** 293425bb815Sopenharmony_ci * Get the offsets of ecma values from the specified item of a context. 294425bb815Sopenharmony_ci * 295425bb815Sopenharmony_ci * @return array of offsets, last item represents the size of the context item 296425bb815Sopenharmony_ci */ 297425bb815Sopenharmony_ciuint32_t 298425bb815Sopenharmony_civm_get_context_value_offsets (ecma_value_t *context_item_p) /**< any item of a context */ 299425bb815Sopenharmony_ci{ 300425bb815Sopenharmony_ci switch (VM_GET_CONTEXT_TYPE (context_item_p[-1])) 301425bb815Sopenharmony_ci { 302425bb815Sopenharmony_ci case VM_CONTEXT_FINALLY_THROW: 303425bb815Sopenharmony_ci case VM_CONTEXT_FINALLY_RETURN: 304425bb815Sopenharmony_ci { 305425bb815Sopenharmony_ci return (2 << (VM_CONTEXT_OFFSET_SHIFT)) | PARSER_TRY_CONTEXT_STACK_ALLOCATION; 306425bb815Sopenharmony_ci } 307425bb815Sopenharmony_ci case VM_CONTEXT_FINALLY_JUMP: 308425bb815Sopenharmony_ci case VM_CONTEXT_TRY: 309425bb815Sopenharmony_ci case VM_CONTEXT_CATCH: 310425bb815Sopenharmony_ci { 311425bb815Sopenharmony_ci return PARSER_TRY_CONTEXT_STACK_ALLOCATION; 312425bb815Sopenharmony_ci } 313425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 314425bb815Sopenharmony_ci case VM_CONTEXT_BLOCK: 315425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 316425bb815Sopenharmony_ci case VM_CONTEXT_WITH: 317425bb815Sopenharmony_ci { 318425bb815Sopenharmony_ci return PARSER_WITH_CONTEXT_STACK_ALLOCATION; 319425bb815Sopenharmony_ci } 320425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 321425bb815Sopenharmony_ci case VM_CONTEXT_FOR_OF: 322425bb815Sopenharmony_ci { 323425bb815Sopenharmony_ci return ((3 << (VM_CONTEXT_OFFSET_SHIFT * 2)) 324425bb815Sopenharmony_ci | (2 << (VM_CONTEXT_OFFSET_SHIFT)) 325425bb815Sopenharmony_ci | PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION); 326425bb815Sopenharmony_ci } 327425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 328425bb815Sopenharmony_ci default: 329425bb815Sopenharmony_ci { 330425bb815Sopenharmony_ci return (4 << (VM_CONTEXT_OFFSET_SHIFT)) | PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION; 331425bb815Sopenharmony_ci } 332425bb815Sopenharmony_ci } 333425bb815Sopenharmony_ci} /* vm_get_context_value_offsets */ 334425bb815Sopenharmony_ci 335425bb815Sopenharmony_ci/** 336425bb815Sopenharmony_ci * Ref / deref lexical environments in the chain using the current context. 337425bb815Sopenharmony_ci */ 338425bb815Sopenharmony_civoid 339425bb815Sopenharmony_civm_ref_lex_env_chain (ecma_object_t *lex_env_p, /**< top of lexical environment */ 340425bb815Sopenharmony_ci uint16_t context_depth, /**< depth of function context */ 341425bb815Sopenharmony_ci ecma_value_t *context_end_p, /**< end of function context */ 342425bb815Sopenharmony_ci bool do_ref) /**< ref or deref lexical environments */ 343425bb815Sopenharmony_ci{ 344425bb815Sopenharmony_ci ecma_value_t *context_top_p = context_end_p + context_depth; 345425bb815Sopenharmony_ci JERRY_ASSERT (context_top_p > context_end_p); 346425bb815Sopenharmony_ci 347425bb815Sopenharmony_ci do 348425bb815Sopenharmony_ci { 349425bb815Sopenharmony_ci if (context_top_p[-1] & VM_CONTEXT_HAS_LEX_ENV) 350425bb815Sopenharmony_ci { 351425bb815Sopenharmony_ci JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL); 352425bb815Sopenharmony_ci ecma_object_t *next_lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); 353425bb815Sopenharmony_ci 354425bb815Sopenharmony_ci if (do_ref) 355425bb815Sopenharmony_ci { 356425bb815Sopenharmony_ci ecma_ref_object (lex_env_p); 357425bb815Sopenharmony_ci } 358425bb815Sopenharmony_ci else 359425bb815Sopenharmony_ci { 360425bb815Sopenharmony_ci ecma_deref_object (lex_env_p); 361425bb815Sopenharmony_ci } 362425bb815Sopenharmony_ci 363425bb815Sopenharmony_ci lex_env_p = next_lex_env_p; 364425bb815Sopenharmony_ci } 365425bb815Sopenharmony_ci 366425bb815Sopenharmony_ci uint32_t offsets = vm_get_context_value_offsets (context_top_p); 367425bb815Sopenharmony_ci 368425bb815Sopenharmony_ci while (VM_CONTEXT_HAS_NEXT_OFFSET (offsets)) 369425bb815Sopenharmony_ci { 370425bb815Sopenharmony_ci int32_t offset = VM_CONTEXT_GET_NEXT_OFFSET (offsets); 371425bb815Sopenharmony_ci 372425bb815Sopenharmony_ci if (do_ref) 373425bb815Sopenharmony_ci { 374425bb815Sopenharmony_ci ecma_ref_if_object (context_top_p[offset]); 375425bb815Sopenharmony_ci } 376425bb815Sopenharmony_ci else 377425bb815Sopenharmony_ci { 378425bb815Sopenharmony_ci ecma_deref_if_object (context_top_p[offset]); 379425bb815Sopenharmony_ci } 380425bb815Sopenharmony_ci 381425bb815Sopenharmony_ci offsets >>= VM_CONTEXT_OFFSET_SHIFT; 382425bb815Sopenharmony_ci } 383425bb815Sopenharmony_ci 384425bb815Sopenharmony_ci JERRY_ASSERT (context_top_p >= context_end_p + offsets); 385425bb815Sopenharmony_ci context_top_p -= offsets; 386425bb815Sopenharmony_ci } 387425bb815Sopenharmony_ci while (context_top_p > context_end_p); 388425bb815Sopenharmony_ci} /* vm_ref_lex_env_chain */ 389425bb815Sopenharmony_ci 390425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 391425bb815Sopenharmony_ci 392425bb815Sopenharmony_ci/** 393425bb815Sopenharmony_ci * @} 394425bb815Sopenharmony_ci * @} 395425bb815Sopenharmony_ci */ 396