@@ -400,8 +400,107 @@ scanner_seek (parser_context_t *context_p) /**< context */
400400 context_p -> next_scanner_info_p = prev_p -> next_p ;
401401} /* scanner_seek */
402402
403+ /**
404+ * Checks whether a literal is equal to "arguments".
405+ */
406+ static inline bool JERRY_ATTR_ALWAYS_INLINE
407+ scanner_literal_is_arguments (lexer_lit_location_t * literal_p ) /**< literal */
408+ {
409+ return lexer_compare_identifier_to_string (literal_p , (const uint8_t * ) "arguments" , 9 );
410+ } /* scanner_literal_is_arguments */
411+
403412#if JERRY_ESNEXT
404413
414+ /**
415+ * Find if there is a duplicated argument in the given context
416+ *
417+ * @return true - if there are duplicates, false - otherwise
418+ */
419+ static bool
420+ scanner_find_duplicated_arg (parser_context_t * context_p , lexer_lit_location_t * lit_loc_p )
421+ {
422+ if (!(context_p -> status_flags & PARSER_FUNCTION_IS_PARSING_ARGS ))
423+ {
424+ return false;
425+ }
426+
427+ if (scanner_literal_is_arguments (lit_loc_p ))
428+ {
429+ return true;
430+ }
431+
432+ uint16_t register_end , encoding_limit , encoding_delta ;
433+ ecma_value_t * literal_p ;
434+ ecma_value_t * literal_start_p ;
435+
436+ const ecma_compiled_code_t * bytecode_header_p = JERRY_CONTEXT (vm_top_context_p )-> shared_p -> bytecode_header_p ;
437+
438+ if (bytecode_header_p -> status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS )
439+ {
440+ cbc_uint16_arguments_t * args_p = (cbc_uint16_arguments_t * ) bytecode_header_p ;
441+
442+ register_end = args_p -> register_end ;
443+
444+ literal_p = (ecma_value_t * ) (args_p + 1 );
445+ literal_p -= register_end ;
446+ literal_start_p = literal_p ;
447+ literal_p += args_p -> literal_end ;
448+ }
449+ else
450+ {
451+ cbc_uint8_arguments_t * args_p = (cbc_uint8_arguments_t * ) bytecode_header_p ;
452+
453+ register_end = args_p -> register_end ;
454+
455+ literal_p = (ecma_value_t * ) (args_p + 1 );
456+ literal_p -= register_end ;
457+ literal_start_p = literal_p ;
458+ literal_p += args_p -> literal_end ;
459+ }
460+
461+ if (!(bytecode_header_p -> status_flags & CBC_CODE_FLAGS_FULL_LITERAL_ENCODING ))
462+ {
463+ encoding_limit = CBC_SMALL_LITERAL_ENCODING_LIMIT ;
464+ encoding_delta = CBC_SMALL_LITERAL_ENCODING_DELTA ;
465+ }
466+ else
467+ {
468+ encoding_limit = CBC_FULL_LITERAL_ENCODING_LIMIT ;
469+ encoding_delta = CBC_FULL_LITERAL_ENCODING_DELTA ;
470+ }
471+
472+ uint8_t * byte_code_p = (uint8_t * ) literal_p ;
473+
474+ bool found_duplicate = false;
475+
476+ while (* byte_code_p == CBC_CREATE_LOCAL )
477+ {
478+ byte_code_p ++ ;
479+ uint16_t literal_index = * byte_code_p ++ ;
480+
481+ if (literal_index >= encoding_limit )
482+ {
483+ literal_index = (uint16_t ) (((literal_index << 8 ) | * byte_code_p ++ ) - encoding_delta );
484+ }
485+
486+ ecma_string_t * arg_string = ecma_get_string_from_value (literal_start_p [literal_index ]);
487+ uint8_t * destination_p = (uint8_t * ) parser_malloc (context_p , lit_loc_p -> length );
488+ lexer_convert_ident_to_cesu8 (destination_p , lit_loc_p -> char_p , lit_loc_p -> length );
489+ ecma_string_t * search_key_p = ecma_new_ecma_string_from_utf8 (destination_p , lit_loc_p -> length );
490+ scanner_free (destination_p , lit_loc_p -> length );
491+
492+ found_duplicate = ecma_compare_ecma_strings (arg_string , search_key_p );
493+ ecma_deref_ecma_string (search_key_p );
494+
495+ if (found_duplicate )
496+ {
497+ break ;
498+ }
499+ }
500+
501+ return found_duplicate ;
502+ } /* scanner_find_duplicated_arg */
503+
405504/**
406505 * Find any let/const declaration of a given literal.
407506 *
@@ -466,7 +565,8 @@ scanner_scope_find_lexical_declaration (parser_context_t *context_p, /**< contex
466565 {
467566 ecma_property_t * property_p = ecma_find_named_property (lex_env_p , name_p );
468567
469- if (property_p != NULL && ecma_is_property_enumerable (* property_p ))
568+ if (property_p != NULL
569+ && (ecma_is_property_enumerable (* property_p ) || scanner_find_duplicated_arg (context_p , literal_p )))
470570 {
471571 ecma_deref_ecma_string (name_p );
472572 return true;
@@ -549,15 +649,6 @@ scanner_push_literal_pool (parser_context_t *context_p, /**< context */
549649
550650JERRY_STATIC_ASSERT (PARSER_MAXIMUM_IDENT_LENGTH <= UINT8_MAX , maximum_ident_length_must_fit_in_a_byte );
551651
552- /**
553- * Checks whether a literal is equal to "arguments".
554- */
555- static inline bool JERRY_ATTR_ALWAYS_INLINE
556- scanner_literal_is_arguments (lexer_lit_location_t * literal_p ) /**< literal */
557- {
558- return lexer_compare_identifier_to_string (literal_p , (const uint8_t * ) "arguments" , 9 );
559- } /* scanner_literal_is_arguments */
560-
561652/**
562653 * Current status of arguments.
563654 */
0 commit comments