Skip to content

Implemented jerry_api_create_error() #76

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 20, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions jerry-core/jerry-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,20 @@ typedef enum
JERRY_API_DATA_TYPE_OBJECT /**< object */
} jerry_api_data_type_t;

/**
* Jerry API Error object types
*/
typedef enum
{
JERRY_API_ERROR_COMMON, /**< Error */
JERRY_API_ERROR_EVAL, /**< EvalError */
JERRY_API_ERROR_RANGE, /**< RangeError */
JERRY_API_ERROR_REFERENCE, /**< ReferenceError */
JERRY_API_ERROR_SYNTAX, /**< SyntaxError */
JERRY_API_ERROR_TYPE, /**< TypeError */
JERRY_API_ERROR_URI /**< URIError */
} jerry_api_error_t;

/**
* Jerry's string value
*/
Expand Down Expand Up @@ -127,6 +141,8 @@ jerry_api_string_t* jerry_api_create_string (const char *v);
extern EXTERN_C
jerry_api_object_t* jerry_api_create_object (void);
extern EXTERN_C
jerry_api_object_t* jerry_api_create_error (jerry_api_error_t error_type, const char *message_p);
extern EXTERN_C
jerry_api_object_t* jerry_api_create_external_function (jerry_external_handler_t handler_p);

extern EXTERN_C
Expand Down
75 changes: 75 additions & 0 deletions jerry-core/jerry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "ecma-alloc.h"
#include "ecma-builtins.h"
#include "ecma-exceptions.h"
#include "ecma-extension.h"
#include "ecma-eval.h"
#include "ecma-function-object.h"
Expand Down Expand Up @@ -415,6 +416,80 @@ jerry_api_create_object (void)
return ecma_op_create_object_object_noarg ();
} /* jerry_api_create_object */

/**
* Create an error object
*
* Note:
* caller should release the object with jerry_api_release_object, just when the value becomes unnecessary.
*
* @return pointer to created error object
*/
jerry_api_object_t*
jerry_api_create_error (jerry_api_error_t error_type, const char *message_p)
{
jerry_assert_api_available ();

ecma_standard_error_t standard_error_type = ECMA_ERROR_COMMON;

switch (error_type)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need additional level of abstraction for that? Why don't we simply use ECMA_ERROR_COMMON, ECMA_ERROR_EVAL etc? As for me, its better to extend ecma_standard_error_t enum if needed and use it across the API.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was questionable for me too, Then let's make it use only ecma_standart_error_t.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about naming? should we change the name of enum entry like ECMA_ERROR_COMMON to JERRY_ERROR_COMMON ?

{
case JERRY_API_ERROR_COMMON:
{
standard_error_type = ECMA_ERROR_COMMON;
break;
}
case JERRY_API_ERROR_EVAL:
{
standard_error_type = ECMA_ERROR_EVAL;
break;
}
case JERRY_API_ERROR_RANGE:
{
standard_error_type = ECMA_ERROR_RANGE;
break;
}
case JERRY_API_ERROR_REFERENCE:
{
standard_error_type = ECMA_ERROR_REFERENCE;
break;
}
case JERRY_API_ERROR_SYNTAX:
{
standard_error_type = ECMA_ERROR_SYNTAX;
break;
}
case JERRY_API_ERROR_TYPE:
{
standard_error_type = ECMA_ERROR_TYPE;
break;
}
case JERRY_API_ERROR_URI:
{
standard_error_type = ECMA_ERROR_URI;
break;
}
default:
{
JERRY_UNREACHABLE ();
}
}

if (message_p == NULL)
{
return ecma_new_standard_error (standard_error_type);
}
else
{
ecma_string_t* message_string_p = ecma_new_ecma_string ((const ecma_char_t*) message_p);

ecma_object_t* error_object_p = ecma_new_standard_error_with_message (standard_error_type, message_string_p);

ecma_deref_ecma_string (message_string_p);

return error_object_p;
}
}

/**
* Create an external function object
*
Expand Down
70 changes: 64 additions & 6 deletions tests/unit/test_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,21 @@ const char *test_source = (
"this.t = 12; "
"} "
"this.A = A; "
"this.a = new A ();"
"function call_external () {"
" return this.external ('1', true);"
"}"
"this.a = new A (); "
"function call_external () { "
" return this.external ('1', true); "
"} "
"function call_throw_test() { "
" bool catched = false "
" try { "
" this.throw_test(); "
" } catch (e) { "
" catched = true; "
" assert(e.name == 'TypeError'); "
" assert(e.message == 'error'); "
" } "
" assert(catched); "
"} "
);

bool test_api_is_free_callback_was_called = false;
Expand Down Expand Up @@ -117,6 +128,24 @@ handler (const jerry_api_object_t *function_obj_p,
return true;
} /* handler */

static bool
handler_throw_test (const jerry_api_object_t *function_obj_p,
const jerry_api_value_t *this_p,
jerry_api_value_t *ret_val_p,
const jerry_api_value_t args_p[],
const uint16_t args_cnt)
{
printf ("ok %p %p %p %d %p\n", function_obj_p, this_p, args_p, args_cnt, ret_val_p);

jerry_api_object_t* error_p = jerry_api_create_error (JERRY_API_ERROR_TYPE, "error");

test_api_init_api_value_object (ret_val_p, error_p);

jerry_api_release_object (error_p);

return false;
}

static void
handler_construct_freecb (uintptr_t native_p)
{
Expand Down Expand Up @@ -162,6 +191,7 @@ main (void)
jerry_api_value_t val_external, val_external_construct, val_call_external;
jerry_api_object_t* global_obj_p;
jerry_api_object_t* external_func_p, *external_construct_p;
jerry_api_object_t* throw_test_handler_p;
jerry_api_value_t res, args[2];
char buffer[32];

Expand Down Expand Up @@ -308,8 +338,6 @@ main (void)
jerry_api_release_value (&res);
assert (!strcmp (buffer, "string from handler"));

jerry_api_release_object (global_obj_p);

// Create native handler bound function object and set it to 'external_construct' variable
external_construct_p = jerry_api_create_external_function (handler_construct);
assert (external_construct_p != NULL
Expand Down Expand Up @@ -346,6 +374,36 @@ main (void)

jerry_api_release_value (&res);


// Test: Throwing exception from native handler.
throw_test_handler_p = jerry_api_create_external_function (handler_throw_test);
assert (throw_test_handler_p != NULL
&& jerry_api_is_function (throw_test_handler_p));

test_api_init_api_value_object (&val_t, throw_test_handler_p);
is_ok = jerry_api_set_object_field_value (global_obj_p,
"throw_test",
&val_t);
assert (is_ok);
jerry_api_release_value (&val_t);
jerry_api_release_object (throw_test_handler_p);

is_ok = jerry_api_get_object_field_value (global_obj_p, "call_throw_test", &val_t);
assert (is_ok
&& val_t.type == JERRY_API_DATA_TYPE_OBJECT);

is_ok = jerry_api_call_function (val_t.v_object,
global_obj_p,
&res,
NULL, 0);
assert (is_ok);
jerry_api_release_value (&val_t);
jerry_api_release_value (&res);


// cleanup.
jerry_api_release_object (global_obj_p);

jerry_cleanup ();

assert (test_api_is_free_callback_was_called);
Expand Down