mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Implement throwing const re-assignment error. (#3697)
JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
parent
9e6c44be4f
commit
4b780507e1
@ -257,6 +257,12 @@ ecma_op_put_value_lex_env_base (ecma_object_t *lex_env_p, /**< lexical environme
|
||||
|
||||
ecma_named_data_property_assign_value (lex_env_p, property_value_p, value);
|
||||
}
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
else if (ecma_is_property_enumerable (*property_p))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Constant bindings cannot be reassigned."));
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
else if (is_strict)
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Binding cannot be set."));
|
||||
|
||||
@ -239,6 +239,12 @@ ecma_op_set_mutable_binding (ecma_object_t *lex_env_p, /**< lexical environment
|
||||
{
|
||||
ecma_named_data_property_assign_value (lex_env_p, ECMA_PROPERTY_VALUE_PTR (property_p), value);
|
||||
}
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
else if (ecma_is_property_enumerable (*property_p))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Constant bindings cannot be reassigned."));
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
else if (is_strict)
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Binding cannot be set."));
|
||||
|
||||
@ -30,7 +30,7 @@ extern "C"
|
||||
/**
|
||||
* Jerry snapshot format version.
|
||||
*/
|
||||
#define JERRY_SNAPSHOT_VERSION (41u)
|
||||
#define JERRY_SNAPSHOT_VERSION (42u)
|
||||
|
||||
/**
|
||||
* Flags for jerry_generate_snapshot and jerry_generate_function_snapshot.
|
||||
|
||||
@ -578,6 +578,8 @@
|
||||
VM_OC_ERROR) \
|
||||
CBC_OPCODE (CBC_EXT_THROW_REFERENCE_ERROR, CBC_NO_FLAG, 1, \
|
||||
VM_OC_THROW_REFERENCE_ERROR) \
|
||||
CBC_OPCODE (CBC_EXT_THROW_ASSIGN_CONST_ERROR, CBC_NO_FLAG, 0, \
|
||||
VM_OC_THROW_CONST_ERROR) \
|
||||
CBC_OPCODE (CBC_EXT_REQUIRE_OBJECT_COERCIBLE, CBC_NO_FLAG, 0, \
|
||||
VM_OC_REQUIRE_OBJECT_COERCIBLE) \
|
||||
\
|
||||
|
||||
@ -173,10 +173,10 @@ typedef enum
|
||||
LEXER_PROPERTY_GETTER, /**< property getter function */
|
||||
LEXER_PROPERTY_SETTER, /**< property setter function */
|
||||
LEXER_COMMA_SEP_LIST, /**< comma separated bracketed expression list */
|
||||
LEXER_SCAN_SWITCH, /**< special value for switch pre-scan */
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
LEXER_ASSIGN_CONST, /**< a const binding is reassigned */
|
||||
LEXER_CLASS_CONSTRUCTOR, /**< special value for class constructor method */
|
||||
LEXER_INVALID_PATTERN, /**< special value for invalid destructuring pattern */
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
LEXER_ARROW_LEFT_PAREN, /**< start of arrow function argument list */
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
|
||||
@ -133,6 +133,7 @@ parser_check_invalid_assign (parser_context_t *context_p) /**< context */
|
||||
} /* parser_check_invalid_assign */
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
|
||||
/**
|
||||
* Check and throw an error if the "new.target" is invalid as a left-hand side expression.
|
||||
*/
|
||||
@ -153,6 +154,7 @@ parser_check_invalid_new_target (parser_context_t *context_p, /**< parser contex
|
||||
parser_raise_error (context_p, PARSER_ERR_NEW_TARGET_NOT_ALLOWED);
|
||||
}
|
||||
} /* parser_check_invalid_new_target */
|
||||
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
/**
|
||||
@ -220,6 +222,16 @@ parser_emit_unary_lvalue_opcode (parser_context_t *context_p, /**< context */
|
||||
}
|
||||
|
||||
parser_emit_ident_reference (context_p, unary_opcode);
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (unary_opcode != CBC_DELETE_IDENT_PUSH_RESULT
|
||||
&& scanner_literal_is_const_reg (context_p, context_p->last_cbc.literal_index))
|
||||
{
|
||||
/* The current value must be read, but it cannot be changed. */
|
||||
context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
|
||||
parser_emit_cbc_ext (context_p, CBC_EXT_THROW_ASSIGN_CONST_ERROR);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2228,10 +2240,9 @@ parser_process_unary_expression (parser_context_t *context_p, /**< context */
|
||||
*/
|
||||
static uint8_t
|
||||
parser_append_binary_single_assignment_token (parser_context_t *context_p, /**< context */
|
||||
uint8_t assign_ident_opcode) /**< assign ident opcode */
|
||||
bool is_lexical) /**< assign lexical declaration */
|
||||
{
|
||||
JERRY_ASSERT (assign_ident_opcode == CBC_ASSIGN_SET_IDENT
|
||||
|| assign_ident_opcode == CBC_ASSIGN_LET_CONST);
|
||||
JERRY_UNUSED (is_lexical);
|
||||
|
||||
/* Unlike other tokens, the whole byte code is saved for binary
|
||||
* assignment, since it has multiple forms depending on the
|
||||
@ -2242,8 +2253,6 @@ parser_append_binary_single_assignment_token (parser_context_t *context_p, /**<
|
||||
if (PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode)
|
||||
&& context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
|
||||
{
|
||||
JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_LITERAL, assign_ident_opcode));
|
||||
|
||||
parser_check_invalid_assign (context_p);
|
||||
|
||||
uint16_t literal_index;
|
||||
@ -2278,8 +2287,24 @@ parser_append_binary_single_assignment_token (parser_context_t *context_p, /**<
|
||||
}
|
||||
}
|
||||
|
||||
assign_opcode = CBC_ASSIGN_SET_IDENT;
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (!is_lexical)
|
||||
{
|
||||
if (scanner_literal_is_const_reg (context_p, literal_index))
|
||||
{
|
||||
parser_stack_push_uint8 (context_p, LEXER_ASSIGN_CONST);
|
||||
}
|
||||
}
|
||||
else if (literal_index < PARSER_REGISTER_START)
|
||||
{
|
||||
assign_opcode = CBC_ASSIGN_LET_CONST;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
parser_stack_push_uint16 (context_p, literal_index);
|
||||
assign_opcode = assign_ident_opcode;
|
||||
JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_LITERAL, assign_opcode));
|
||||
}
|
||||
else if (context_p->last_cbc_opcode == CBC_PUSH_PROP)
|
||||
{
|
||||
@ -2359,7 +2384,7 @@ parser_append_binary_token (parser_context_t *context_p) /**< context */
|
||||
|
||||
if (context_p->token.type == LEXER_ASSIGN)
|
||||
{
|
||||
parser_append_binary_single_assignment_token (context_p, CBC_ASSIGN_SET_IDENT);
|
||||
parser_append_binary_single_assignment_token (context_p, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2371,6 +2396,13 @@ parser_append_binary_token (parser_context_t *context_p) /**< context */
|
||||
parser_check_invalid_assign (context_p);
|
||||
|
||||
parser_emit_ident_reference (context_p, CBC_PUSH_IDENT_REFERENCE);
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (scanner_literal_is_const_reg (context_p, context_p->last_cbc.literal_index))
|
||||
{
|
||||
parser_stack_push_uint8 (context_p, LEXER_ASSIGN_CONST);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
}
|
||||
else if (PARSER_IS_PUSH_PROP (context_p->last_cbc_opcode))
|
||||
{
|
||||
@ -2437,20 +2469,39 @@ parser_process_binary_opcodes (parser_context_t *context_p, /**< context */
|
||||
opcode = (cbc_opcode_t) context_p->stack_top_uint8;
|
||||
parser_stack_pop_uint8 (context_p);
|
||||
|
||||
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL
|
||||
&& opcode == CBC_ASSIGN_SET_IDENT)
|
||||
{
|
||||
JERRY_ASSERT (CBC_ARGS_EQ (CBC_ASSIGN_LITERAL_SET_IDENT,
|
||||
CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2));
|
||||
context_p->last_cbc.value = parser_stack_pop_uint16 (context_p);
|
||||
context_p->last_cbc_opcode = CBC_ASSIGN_LITERAL_SET_IDENT;
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t index = -1;
|
||||
if (cbc_flags[opcode] & CBC_HAS_LITERAL_ARG)
|
||||
{
|
||||
uint16_t index = parser_stack_pop_uint16 (context_p);
|
||||
parser_emit_cbc_literal (context_p, (uint16_t) opcode, index);
|
||||
JERRY_ASSERT (opcode == CBC_ASSIGN_SET_IDENT
|
||||
|| opcode == CBC_ASSIGN_PROP_LITERAL
|
||||
|| opcode == CBC_ASSIGN_PROP_THIS_LITERAL
|
||||
|| opcode == CBC_ASSIGN_LET_CONST);
|
||||
|
||||
index = parser_stack_pop_uint16 (context_p);
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (JERRY_UNLIKELY (context_p->stack_top_uint8 == LEXER_ASSIGN_CONST))
|
||||
{
|
||||
parser_stack_pop_uint8 (context_p);
|
||||
parser_emit_cbc_ext (context_p, CBC_EXT_THROW_ASSIGN_CONST_ERROR);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL
|
||||
&& opcode == CBC_ASSIGN_SET_IDENT)
|
||||
{
|
||||
JERRY_ASSERT (CBC_ARGS_EQ (CBC_ASSIGN_LITERAL_SET_IDENT,
|
||||
CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2));
|
||||
|
||||
context_p->last_cbc.value = (uint16_t) index;
|
||||
context_p->last_cbc_opcode = CBC_ASSIGN_LITERAL_SET_IDENT;
|
||||
continue;
|
||||
}
|
||||
|
||||
parser_emit_cbc_literal (context_p, (uint16_t) opcode, (uint16_t) index);
|
||||
|
||||
if (opcode == CBC_ASSIGN_PROP_THIS_LITERAL
|
||||
&& (context_p->stack_depth >= context_p->stack_limit))
|
||||
@ -2644,16 +2695,9 @@ parser_pattern_form_assignment (parser_context_t *context_p, /**< context */
|
||||
{
|
||||
JERRY_UNUSED (ident_line_counter);
|
||||
|
||||
uint8_t assign_opcode = CBC_ASSIGN_SET_IDENT;
|
||||
|
||||
if (flags & (PARSER_PATTERN_LEXICAL | PARSER_PATTERN_LOCAL)
|
||||
&& context_p->lit_object.index < PARSER_REGISTER_START)
|
||||
{
|
||||
assign_opcode = CBC_ASSIGN_LET_CONST;
|
||||
}
|
||||
|
||||
parser_stack_push_uint8 (context_p, LEXER_EXPRESSION_START);
|
||||
assign_opcode = parser_append_binary_single_assignment_token (context_p, assign_opcode);
|
||||
bool is_lexical = (flags & (PARSER_PATTERN_LEXICAL | PARSER_PATTERN_LOCAL)) != 0;
|
||||
uint8_t assign_opcode = parser_append_binary_single_assignment_token (context_p, is_lexical);
|
||||
|
||||
if (flags & PARSER_PATTERN_ARRAY)
|
||||
{
|
||||
|
||||
@ -750,6 +750,9 @@ void scanner_create_variables (parser_context_t *context_p, uint32_t option_flag
|
||||
void scanner_get_location (scanner_location_t *location_p, parser_context_t *context_p);
|
||||
void scanner_set_location (parser_context_t *context_p, scanner_location_t *location_p);
|
||||
uint16_t scanner_decode_map_to (parser_scope_stack_t *stack_item_p);
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
bool scanner_literal_is_const_reg (parser_context_t *context_p, uint16_t literal_index);
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
void scanner_scan_all (parser_context_t *context_p, const uint8_t *arg_list_p, const uint8_t *arg_list_end_p,
|
||||
const uint8_t *source_p, const uint8_t *source_end_p);
|
||||
|
||||
@ -558,24 +558,22 @@ parser_parse_var_statement (parser_context_t *context_p) /**< context */
|
||||
}
|
||||
#endif /* ENABLED (JERRY_LINE_INFO) */
|
||||
|
||||
uint16_t index = context_p->lit_object.index;
|
||||
|
||||
lexer_next_token (context_p);
|
||||
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
|
||||
|
||||
cbc_opcode_t opcode = CBC_ASSIGN_SET_IDENT;
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (declaration_type != LEXER_KEYW_VAR
|
||||
&& context_p->lit_object.index < PARSER_REGISTER_START)
|
||||
&& (index < PARSER_REGISTER_START))
|
||||
{
|
||||
uint16_t index = context_p->lit_object.index;
|
||||
opcode = CBC_ASSIGN_LET_CONST;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
lexer_next_token (context_p);
|
||||
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
|
||||
parser_emit_cbc_literal (context_p, CBC_ASSIGN_LET_CONST, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
|
||||
parser_parse_expression_statement (context_p, PARSE_EXPR_NO_COMMA | PARSE_EXPR_HAS_LITERAL);
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
parser_emit_cbc_literal (context_p, opcode, index);
|
||||
}
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
else if (declaration_type == LEXER_KEYW_LET)
|
||||
|
||||
@ -2473,11 +2473,9 @@ parser_parse_arrow_function (parser_context_t *context_p, /**< context */
|
||||
JERRY_ASSERT (status_flags & PARSER_IS_ARROW_FUNCTION);
|
||||
parser_save_context (context_p, &saved_context);
|
||||
context_p->status_flags |= status_flags;
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
context_p->status_flags |= saved_context.status_flags & (PARSER_ALLOW_NEW_TARGET
|
||||
| PARSER_ALLOW_SUPER
|
||||
| PARSER_ALLOW_SUPER_CALL);
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
#if ENABLED (JERRY_PARSER_DUMP_BYTE_CODE)
|
||||
if (context_p->is_show_opcodes)
|
||||
@ -2529,14 +2527,12 @@ parser_parse_arrow_function (parser_context_t *context_p, /**< context */
|
||||
|
||||
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (context_p->status_flags & PARSER_IS_ASYNC_FUNCTION)
|
||||
{
|
||||
parser_emit_cbc_ext (context_p, CBC_EXT_RETURN_PROMISE);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
|
||||
{
|
||||
context_p->last_cbc_opcode = CBC_RETURN_WITH_LITERAL;
|
||||
@ -2545,9 +2541,7 @@ parser_parse_arrow_function (parser_context_t *context_p, /**< context */
|
||||
{
|
||||
parser_emit_cbc (context_p, CBC_RETURN);
|
||||
}
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
parser_flush_cbc (context_p);
|
||||
}
|
||||
|
||||
|
||||
@ -2291,6 +2291,40 @@ scanner_decode_map_to (parser_scope_stack_t *stack_item_p) /**< scope stack item
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
} /* scanner_decode_map_to */
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
|
||||
/**
|
||||
* Checks whether the literal is a const in the current scope.
|
||||
*
|
||||
* @return true if the literal is a const
|
||||
*/
|
||||
bool
|
||||
scanner_literal_is_const_reg (parser_context_t *context_p, /**< context */
|
||||
uint16_t literal_index) /**< literal index */
|
||||
{
|
||||
if (literal_index < PARSER_REGISTER_START)
|
||||
{
|
||||
/* Re-assignment of non-register const bindings are detected elsewhere. */
|
||||
return false;
|
||||
}
|
||||
|
||||
parser_scope_stack_t *scope_stack_p = context_p->scope_stack_p + context_p->scope_stack_top;
|
||||
|
||||
literal_index = (uint16_t) (literal_index - (PARSER_REGISTER_START - 1));
|
||||
|
||||
do
|
||||
{
|
||||
/* Registers must be found in the scope stack. */
|
||||
JERRY_ASSERT (scope_stack_p > context_p->scope_stack_p);
|
||||
scope_stack_p--;
|
||||
}
|
||||
while (literal_index != (scope_stack_p->map_to & PARSER_SCOPE_STACK_REGISTER_MASK));
|
||||
|
||||
return (scope_stack_p->map_to & PARSER_SCOPE_STACK_IS_CONST) != 0;
|
||||
} /* scanner_literal_is_const_reg */
|
||||
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
||||
@ -1506,6 +1506,11 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
continue;
|
||||
}
|
||||
case VM_OC_THROW_CONST_ERROR:
|
||||
{
|
||||
result = ecma_raise_type_error (ECMA_ERR_MSG ("Constant bindings cannot be reassigned."));
|
||||
goto error;
|
||||
}
|
||||
case VM_OC_COPY_TO_GLOBAL:
|
||||
{
|
||||
uint32_t literal_index;
|
||||
|
||||
@ -235,6 +235,7 @@ typedef enum
|
||||
VM_OC_CHECK_VAR, /**< check redeclared vars in the global scope */
|
||||
VM_OC_CHECK_LET, /**< check redeclared lets in the global scope */
|
||||
VM_OC_ASSIGN_LET_CONST, /**< assign values to let/const declarations */
|
||||
VM_OC_THROW_CONST_ERROR, /**< throw invalid assignment to const variable error */
|
||||
VM_OC_COPY_TO_GLOBAL, /**< copy value to global lex env */
|
||||
VM_OC_CLONE_CONTEXT, /**< clone lexical environment with let/const declarations */
|
||||
VM_OC_SET_COMPUTED_PROPERTY, /**< set computed property */
|
||||
@ -296,6 +297,7 @@ typedef enum
|
||||
VM_OC_CHECK_VAR = VM_OC_NONE, /**< check redeclared vars in the global scope */
|
||||
VM_OC_CHECK_LET = VM_OC_NONE, /**< check redeclared lets in the global scope */
|
||||
VM_OC_ASSIGN_LET_CONST = VM_OC_NONE, /**< assign values to let/const declarations */
|
||||
VM_OC_THROW_CONST_ERROR = VM_OC_NONE, /**< throw invalid assignment to const variable error */
|
||||
VM_OC_COPY_TO_GLOBAL = VM_OC_NONE, /**< copy value to global lex env */
|
||||
VM_OC_CLONE_CONTEXT = VM_OC_NONE, /**< clone lexical environment with let/const declarations */
|
||||
VM_OC_SET_COMPUTED_PROPERTY = VM_OC_NONE, /**< set computed property is unused */
|
||||
|
||||
74
tests/jerry/es2015/const1.js
Normal file
74
tests/jerry/es2015/const1.js
Normal file
@ -0,0 +1,74 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
const a = 6
|
||||
assert(!delete a)
|
||||
assert(a === 6)
|
||||
|
||||
try {
|
||||
eval("a = 7")
|
||||
assert(false)
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError)
|
||||
}
|
||||
|
||||
function check_type_error(code) {
|
||||
try {
|
||||
eval(code)
|
||||
assert(false)
|
||||
} catch (e) {
|
||||
assert(e instanceof TypeError)
|
||||
}
|
||||
}
|
||||
|
||||
// Register cases
|
||||
check_type_error("{ const a = 0; a = 1 }");
|
||||
check_type_error("{ const a = 0; a += 1 }");
|
||||
check_type_error("{ const a = 0; a -= 1 }");
|
||||
check_type_error("{ const a = 0; a *= 1 }");
|
||||
check_type_error("{ const a = 0; a %= 1 }");
|
||||
check_type_error("{ const a = 0; a /= 1 }");
|
||||
check_type_error("{ const a = 0; a <<= 1 }");
|
||||
check_type_error("{ const a = 0; a >>= 1 }");
|
||||
check_type_error("{ const a = 0; a >>>= 1 }");
|
||||
check_type_error("{ const a = 0; a &= 1 }");
|
||||
check_type_error("{ const a = 0; a |= 1 }");
|
||||
check_type_error("{ const a = 0; a ^= 1 }");
|
||||
check_type_error("{ const a = 0; a++ }");
|
||||
check_type_error("{ const a = 0; a-- }");
|
||||
check_type_error("{ const a = 0; ++a }");
|
||||
check_type_error("{ const a = 0; --a }");
|
||||
check_type_error("{ const a = 0; [a] = [1] }");
|
||||
check_type_error("{ const a = 0; ({a} = { a:1 }) }");
|
||||
|
||||
// Non-register cases
|
||||
check_type_error("{ const a = 0; (function (){ a = 1 })() }");
|
||||
check_type_error("{ const a = 0; (function (){ a += 1 })() }");
|
||||
check_type_error("{ const a = 0; (function (){ a -= 1 })() }");
|
||||
check_type_error("{ const a = 0; (function (){ a *= 1 })() }");
|
||||
check_type_error("{ const a = 0; (function (){ a %= 1 })() }");
|
||||
check_type_error("{ const a = 0; (function (){ a /= 1 })() }");
|
||||
check_type_error("{ const a = 0; (function (){ a <<= 1 })() }");
|
||||
check_type_error("{ const a = 0; (function (){ a >>= 1 })() }");
|
||||
check_type_error("{ const a = 0; (function (){ a >>>= 1 })() }");
|
||||
check_type_error("{ const a = 0; (function (){ a &= 1 })() }");
|
||||
check_type_error("{ const a = 0; (function (){ a |= 1 })() }");
|
||||
check_type_error("{ const a = 0; (function (){ a ^= 1 })() }");
|
||||
check_type_error("{ const a = 0; (function (){ a++ })() }");
|
||||
check_type_error("{ const a = 0; (function (){ a-- })() }");
|
||||
check_type_error("{ const a = 0; (function (){ ++a })() }");
|
||||
check_type_error("{ const a = 0; (function (){ --a })() }");
|
||||
check_type_error("{ const a = 0; (function (){ [a] = [1] })() }");
|
||||
check_type_error("{ const a = 0; (function (){ ({a} = { a:1 }) })() }");
|
||||
@ -223,7 +223,7 @@ main (void)
|
||||
/* Check the snapshot data. Unused bytes should be filled with zeroes */
|
||||
const uint8_t expected_data[] =
|
||||
{
|
||||
0x4A, 0x52, 0x52, 0x59, 0x29, 0x00, 0x00, 0x00,
|
||||
0x4A, 0x52, 0x52, 0x59, 0x2A, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x01, 0x00, 0x41, 0x00, 0x01, 0x00,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user