Skip to content

Commit 9017696

Browse files
committed
Make the assert a built-in method.
Remove the assert intrinsic from the parser and instead make it a real built-in method. This allows us to redefine the method if needed during runtime from JS. JerryScript-DCO-1.0-Signed-off-by: Peter Gal pgal.u-szeged@partner.samsung.com
1 parent f6b875c commit 9017696

File tree

6 files changed

+90
-39
lines changed

6 files changed

+90
-39
lines changed

jerry-core/ecma/base/ecma-magic-strings.inc.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,19 @@
1313
* limitations under the License.
1414
*/
1515

16+
/*
17+
* Naming convention for the magic strings.
18+
*
19+
* If the magic string has a format of:
20+
* - ECMA_MAGIC_STRING_[identifier][^_CHAR|_U|_UL] then the value is a lower-cased "identifier".
21+
* - ECMA_MAGIC_STRING_[identifier]_U then the value is an upper-cased "identifier".
22+
* - ECMA_MAGIC_STRING_[identifier]_UL then the value is an "identifier" with
23+
mixed upper-case and lower-case characters.
24+
* - ECMA_MAGIC_STRING_[identifier]_CHAR then the value is a character.
25+
* - ECMA_MAGIC_STRING__[identifier] then the value is a string described by identifier,
26+
* but could not be described using other cases.
27+
*/
28+
1629
/*
1730
* List of ECMA magic strings
1831
*/
@@ -212,4 +225,6 @@ ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING__EMPTY, "")
212225
/*
213226
* Implementation-defined magic strings
214227
*/
228+
ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING_ASSERT, "assert")
229+
ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING__ASSERTION_FAILED, "Assertion failed")
215230
ECMA_MAGIC_STRING_DEF (ECMA_MAGIC_STRING_JERRY_UL, "Jerry")

jerry-core/ecma/builtin-objects/ecma-builtin-global.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "ecma-alloc.h"
1717
#include "ecma-builtins.h"
1818
#include "ecma-conversion.h"
19+
#include "ecma-exceptions.h"
1920
#include "ecma-gc.h"
2021
#include "ecma-globals.h"
2122
#include "ecma-helpers.h"
@@ -208,6 +209,69 @@ ecma_builtin_global_object_encode_uri_component (ecma_value_t this_arg, /**< thi
208209
ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, uri_component);
209210
} /* ecma_builtin_global_object_encode_uri_component */
210211

212+
/**
213+
* Engine internal method to raise an Error for asserts.
214+
*
215+
* @return completion value
216+
* Returned value must be freed with ecma_free_completion_value.
217+
*/
218+
static ecma_completion_value_t
219+
ecma_builtin_global_object_assert (ecma_value_t this_arg __attr_unused___, /**< this argument */
220+
ecma_value_t condition, /**< assert condition */
221+
ecma_value_t message) /** < optional assert message*/
222+
{
223+
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
224+
225+
ECMA_TRY_CATCH (boolean_value,
226+
ecma_op_to_boolean (condition),
227+
ret_value);
228+
229+
if (ecma_is_value_true (boolean_value))
230+
{
231+
ret_value = ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_UNDEFINED);
232+
}
233+
else
234+
{
235+
ecma_string_t *assert_failed_str_p = NULL;
236+
237+
if (ecma_is_value_undefined (message) || ecma_is_value_object (message))
238+
{
239+
/*
240+
* In case of object we just ignore it and use our default string.
241+
* This is to avoid side effects caused by objects:
242+
* If we call the ecma_op_to_string on an object then it will try to invoke
243+
* the toString property which could lead to strange results.
244+
*/
245+
assert_failed_str_p = ecma_get_magic_string (ECMA_MAGIC_STRING__ASSERTION_FAILED);
246+
}
247+
else
248+
{
249+
ECMA_TRY_CATCH (message_value,
250+
ecma_op_to_string (message),
251+
ret_value);
252+
253+
assert_failed_str_p = ecma_copy_or_ref_ecma_string (ecma_get_string_from_value (message_value));
254+
255+
ECMA_FINALIZE (message_value);
256+
257+
/*
258+
* In this case the ecma_op_to_string should only be called on primitive types (not on object).
259+
* This there `ret_value` will be always empty, but just to be sure we'll do an assert on it.
260+
*/
261+
JERRY_ASSERT (ecma_is_completion_value_empty (ret_value));
262+
}
263+
264+
ecma_object_t *error = ecma_new_standard_error_with_message (ECMA_ERROR_COMMON, assert_failed_str_p);
265+
ret_value = ecma_make_throw_obj_completion_value (error);
266+
267+
ecma_deref_ecma_string (assert_failed_str_p);
268+
}
269+
270+
ECMA_FINALIZE (boolean_value);
271+
272+
return ret_value;
273+
} /* ecma_builtin_global_object_assert */
274+
211275
/**
212276
* @}
213277
* @}

jerry-core/ecma/builtin-objects/ecma-builtin-global.inc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,9 @@ ROUTINE (ECMA_MAGIC_STRING_ENCODE_URI, ecma_builtin_global_object_encode_uri, 1,
232232
ROUTINE (ECMA_MAGIC_STRING_ENCODE_URI_COMPONENT, ecma_builtin_global_object_encode_uri_component, 1, 1)
233233
ROUTINE (ECMA_MAGIC_STRING_PARSE_INT, ecma_builtin_global_object_parse_int, 2, 2)
234234

235+
/* Not part of ECMA 262 but used for testing */
236+
ROUTINE (ECMA_MAGIC_STRING_ASSERT, ecma_builtin_global_object_assert, 2, 2)
237+
235238
#undef OBJECT_ID
236239
#undef SIMPLE_VALUE
237240
#undef NUMBER_VALUE

jerry-core/ecma/operations/ecma-function-object.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -942,7 +942,8 @@ ecma_op_function_declaration (ecma_object_t *lex_env_p, /**< lexical environment
942942
}
943943
else
944944
{
945-
JERRY_ASSERT (ecma_is_completion_value_empty (completion));
945+
JERRY_ASSERT (ecma_is_completion_value_empty (completion)
946+
|| ecma_is_completion_value_normal_simple_value (completion, ECMA_SIMPLE_VALUE_TRUE));
946947

947948
// f.
948949
ret_value = ecma_op_set_mutable_binding (lex_env_p,

jerry-core/parser/js/opcodes-dumper.cpp

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -386,28 +386,6 @@ create_op_meta_for_vlt (varg_list_type vlt, operand *res, operand *obj)
386386
return ret;
387387
}
388388

389-
static void
390-
dump_assert (operand op)
391-
{
392-
switch (op.type)
393-
{
394-
case OPERAND_LITERAL:
395-
{
396-
const opcode_t opcode = getop_is_true_jmp_down (LITERAL_TO_REWRITE, 0, 2);
397-
serializer_dump_op_meta (create_op_meta_100 (opcode, op.data.lit_id));
398-
break;
399-
}
400-
case OPERAND_TMP:
401-
{
402-
const opcode_t opcode = getop_is_true_jmp_down (op.data.uid, 0, 2);
403-
serializer_dump_op_meta (create_op_meta_000 (opcode));
404-
break;
405-
}
406-
}
407-
const opcode_t opcode = getop_exitval (1);
408-
serializer_dump_op_meta (create_op_meta_000 (opcode));
409-
}
410-
411389
static void
412390
split_opcode_counter (opcode_counter_t oc, idx_t *id1, idx_t *id2)
413391
{
@@ -729,25 +707,15 @@ dumper_finish_scope (void)
729707
}
730708

731709
bool
732-
dumper_is_intrinsic (operand obj)
710+
dumper_is_intrinsic (operand /* obj */)
733711
{
734-
if (obj.type == OPERAND_LITERAL)
735-
{
736-
if (literal_equal_type_s (lexer_get_literal_by_id (obj.data.lit_id), "assert"))
737-
{
738-
return true;
739-
}
740-
}
741712
return false;
742713
}
743714

744715
operand
745-
dump_intrinsic (operand obj, operand arg)
716+
dump_intrinsic (operand /* obj */, operand /* arg */)
746717
{
747-
JERRY_ASSERT (obj.type == OPERAND_LITERAL);
748-
TODO (/* Rewrite when there will be more intrinsics. */)
749-
JERRY_ASSERT (literal_equal_type_s (lexer_get_literal_by_id (obj.data.lit_id), "assert"));
750-
dump_assert (arg);
718+
JERRY_UNREACHABLE ();
751719
return dump_undefined_assignment_res ();
752720
}
753721

main-linux.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ main (int argc,
132132
jerry_flag_t flags = JERRY_FLAG_EMPTY;
133133

134134
#ifdef JERRY_ENABLE_LOG
135-
const char *log_file_name = nullptr;
135+
const char *log_file_name = NULL;
136136
#endif /* JERRY_ENABLE_LOG */
137137
for (i = 1; i < argc; i++)
138138
{
@@ -222,7 +222,7 @@ main (int argc,
222222
if (log_file_name)
223223
{
224224
jerry_log_file = fopen (log_file_name, "w");
225-
if (jerry_log_file == nullptr)
225+
if (jerry_log_file == NULL)
226226
{
227227
JERRY_ERROR_MSG ("Failed to open log file: %s\n", log_file_name);
228228
return JERRY_STANDALONE_EXIT_CODE_FAIL;
@@ -259,7 +259,7 @@ main (int argc,
259259
if (jerry_log_file && jerry_log_file != stdout)
260260
{
261261
fclose (jerry_log_file);
262-
jerry_log_file = nullptr;
262+
jerry_log_file = NULL;
263263
}
264264
#endif /* JERRY_ENABLE_LOG */
265265

0 commit comments

Comments
 (0)