Skip to content

Commit 51da045

Browse files
committed
add transform functions for integer in jerryx/arg
JerryScript-DCO-1.0-Signed-off-by: Zidong Jiang [email protected]
1 parent add6086 commit 51da045

File tree

4 files changed

+244
-46
lines changed

4 files changed

+244
-46
lines changed

jerry-ext/arg/arg-transform-functions.c

Lines changed: 105 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,15 @@ jerryx_arg_transform_optional (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< ava
3939
} /* jerryx_arg_transform_optional */
4040

4141
/**
42-
* Tranform a JS argument to a double. Type coercion is not allowed.
42+
* The common part in transforming a JS argument to a number (double or certain int) type.
43+
* Type coercion is not allowed.
4344
*
4445
* @return jerry undefined: the transformer passes,
4546
* jerry error: the transformer fails.
4647
*/
47-
jerry_value_t
48-
jerryx_arg_transform_number_strict (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
49-
const jerryx_arg_t *c_arg_p) /**< the native arg */
48+
static jerry_value_t
49+
jerryx_arg_transform_number_strict_common (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
50+
double *number_p) /**< OUT: the number in JS arg */
5051
{
5152
jerry_value_t js_arg = jerryx_arg_js_iterator_pop (js_arg_iter_p);
5253

@@ -56,21 +57,21 @@ jerryx_arg_transform_number_strict (jerryx_arg_js_iterator_t *js_arg_iter_p, /**
5657
(jerry_char_t *) "It is not a number.");
5758
}
5859

59-
double *dest = c_arg_p->dest;
60-
*dest = jerry_get_number_value (js_arg);
60+
*number_p = jerry_get_number_value (js_arg);
6161

6262
return jerry_create_undefined ();
63-
} /* jerryx_arg_transform_number_strict */
63+
} /* jerryx_arg_transform_number_strict_common */
6464

6565
/**
66-
* Tranform a JS argument to a double. Type coercion is allowed.
66+
* The common part in transforming a JS argument to a number (double or certain int) type.
67+
* Type coercion is allowed.
6768
*
6869
* @return jerry undefined: the transformer passes,
6970
* jerry error: the transformer fails.
7071
*/
71-
jerry_value_t
72-
jerryx_arg_transform_number (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
73-
const jerryx_arg_t *c_arg_p) /**< the native arg */
72+
static jerry_value_t
73+
jerryx_arg_transform_number_common (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
74+
double *number_p) /**< OUT: the number in JS arg */
7475
{
7576
jerry_value_t js_arg = jerryx_arg_js_iterator_pop (js_arg_iter_p);
7677

@@ -84,13 +85,90 @@ jerryx_arg_transform_number (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< avail
8485
(jerry_char_t *) "It can not be converted to a number.");
8586
}
8687

87-
double *dest = c_arg_p->dest;
88-
*dest = jerry_get_number_value (to_number);
88+
*number_p = jerry_get_number_value (to_number);
8989
jerry_release_value (to_number);
9090

9191
return jerry_create_undefined ();
92+
} /* jerryx_arg_transform_number_common */
93+
94+
/**
95+
* clamp a double by given min and max value
96+
* @return clamped double value
97+
*/
98+
static double
99+
jerryx_arg_clamp_double (double d, /**< the double value */
100+
double min, /**< min value */
101+
double max) /**< max value */
102+
{
103+
const double t = d < min ? min : d;
104+
return t > max ? max : t;
105+
} /* jerryx_arg_clamp_double */
106+
107+
/**
108+
* Tranform a JS argument to a double. Type coercion is not allowed.
109+
*
110+
* @return jerry undefined: the transformer passes,
111+
* jerry error: the transformer fails.
112+
*/
113+
jerry_value_t
114+
jerryx_arg_transform_number_strict (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
115+
const jerryx_arg_t *c_arg_p) /**< the native arg */
116+
{
117+
return jerryx_arg_transform_number_strict_common (js_arg_iter_p,
118+
c_arg_p->dest);
119+
} /* jerryx_arg_transform_number_strict */
120+
121+
/**
122+
* Tranform a JS argument to a double. Type coercion is allowed.
123+
*
124+
* @return jerry undefined: the transformer passes,
125+
* jerry error: the transformer fails.
126+
*/
127+
jerry_value_t
128+
jerryx_arg_transform_number (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
129+
const jerryx_arg_t *c_arg_p) /**< the native arg */
130+
{
131+
return jerryx_arg_transform_number_common (js_arg_iter_p,
132+
c_arg_p->dest);
92133
} /* jerryx_arg_transform_number */
93134

135+
/**
136+
* Use the macro to define two transform functions for int type.
137+
* One is non-strict version and the other is the strict version.
138+
*/
139+
#define GENERATE_JERRYX_ARG_TRANSFORM_FUNC_FOR_INT(type, min, max) \
140+
jerry_value_t jerryx_arg_transform_ ## type ## _strict (jerryx_arg_js_iterator_t *js_arg_iter_p, \
141+
const jerryx_arg_t *c_arg_p) \
142+
{ \
143+
double tmp; \
144+
jerry_value_t rv = jerryx_arg_transform_number_strict_common (js_arg_iter_p, &tmp);\
145+
if (!jerry_value_has_error_flag (rv)) \
146+
{ \
147+
tmp = jerryx_arg_clamp_double (tmp, min, max); \
148+
*(type ## _t *) c_arg_p->dest = (type ## _t) tmp; \
149+
} \
150+
return rv; \
151+
} \
152+
jerry_value_t jerryx_arg_transform_ ## type (jerryx_arg_js_iterator_t *js_arg_iter_p, \
153+
const jerryx_arg_t *c_arg_p) \
154+
{ \
155+
double tmp; \
156+
jerry_value_t rv = jerryx_arg_transform_number_common (js_arg_iter_p, &tmp); \
157+
if (!jerry_value_has_error_flag (rv)) \
158+
{ \
159+
tmp = jerryx_arg_clamp_double (tmp, min, max); \
160+
*(type ## _t *) c_arg_p->dest = (type ## _t) tmp; \
161+
} \
162+
return rv; \
163+
}
164+
165+
GENERATE_JERRYX_ARG_TRANSFORM_FUNC_FOR_INT (uint8, 0, 255)
166+
GENERATE_JERRYX_ARG_TRANSFORM_FUNC_FOR_INT (int8, -128, 127)
167+
GENERATE_JERRYX_ARG_TRANSFORM_FUNC_FOR_INT (uint16, 0, 65535)
168+
GENERATE_JERRYX_ARG_TRANSFORM_FUNC_FOR_INT (int16, -32767, 32767)
169+
GENERATE_JERRYX_ARG_TRANSFORM_FUNC_FOR_INT (uint32, 0, 4294967295)
170+
GENERATE_JERRYX_ARG_TRANSFORM_FUNC_FOR_INT (int32, -2147483648 , 2147483647)
171+
94172
/**
95173
* Tranform a JS argument to a boolean. Type coercion is not allowed.
96174
*
@@ -251,7 +329,7 @@ jerryx_arg_transform_native_pointer (jerryx_arg_js_iterator_t *js_arg_iter_p, /*
251329
if (!jerry_value_is_object (js_arg))
252330
{
253331
return jerry_create_error (JERRY_ERROR_TYPE,
254-
(jerry_char_t *) "It is not a object.");
332+
(jerry_char_t *) "It is not an object.");
255333
}
256334

257335
const jerry_object_native_info_t *expected_info_p;
@@ -289,6 +367,19 @@ JERRYX_ARG_TRANSFORM_OPTIONAL (string_strict)
289367
JERRYX_ARG_TRANSFORM_OPTIONAL (function)
290368
JERRYX_ARG_TRANSFORM_OPTIONAL (native_pointer)
291369

370+
JERRYX_ARG_TRANSFORM_OPTIONAL (uint8)
371+
JERRYX_ARG_TRANSFORM_OPTIONAL (uint16)
372+
JERRYX_ARG_TRANSFORM_OPTIONAL (uint32)
373+
JERRYX_ARG_TRANSFORM_OPTIONAL (int8)
374+
JERRYX_ARG_TRANSFORM_OPTIONAL (int16)
375+
JERRYX_ARG_TRANSFORM_OPTIONAL (int32)
376+
JERRYX_ARG_TRANSFORM_OPTIONAL (int8_strict)
377+
JERRYX_ARG_TRANSFORM_OPTIONAL (int16_strict)
378+
JERRYX_ARG_TRANSFORM_OPTIONAL (int32_strict)
379+
JERRYX_ARG_TRANSFORM_OPTIONAL (uint8_strict)
380+
JERRYX_ARG_TRANSFORM_OPTIONAL (uint16_strict)
381+
JERRYX_ARG_TRANSFORM_OPTIONAL (uint32_strict)
382+
292383
/**
293384
* Ignore the JS argument.
294385
*

jerry-ext/include/jerryscript-ext/arg.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,18 @@ typedef enum
9494
static inline jerryx_arg_t
9595
jerryx_arg_number (double *dest, jerryx_arg_coerce_t conv_flag, jerryx_arg_optional_t opt_flag);
9696
static inline jerryx_arg_t
97+
jerryx_arg_uint8 (uint8_t *dest, jerryx_arg_coerce_t conv_flag, jerryx_arg_optional_t opt_flag);
98+
static inline jerryx_arg_t
99+
jerryx_arg_int8 (int8_t *dest, jerryx_arg_coerce_t conv_flag, jerryx_arg_optional_t opt_flag);
100+
static inline jerryx_arg_t
101+
jerryx_arg_uint16 (uint16_t *dest, jerryx_arg_coerce_t conv_flag, jerryx_arg_optional_t opt_flag);
102+
static inline jerryx_arg_t
103+
jerryx_arg_int16 (int16_t *dest, jerryx_arg_coerce_t conv_flag, jerryx_arg_optional_t opt_flag);
104+
static inline jerryx_arg_t
105+
jerryx_arg_uint32 (uint32_t *dest, jerryx_arg_coerce_t conv_flag, jerryx_arg_optional_t opt_flag);
106+
static inline jerryx_arg_t
107+
jerryx_arg_int32 (int32_t *dest, jerryx_arg_coerce_t conv_flag, jerryx_arg_optional_t opt_flag);
108+
static inline jerryx_arg_t
97109
jerryx_arg_boolean (bool *dest, jerryx_arg_coerce_t conv_flag, jerryx_arg_optional_t opt_flag);
98110
static inline jerryx_arg_t
99111
jerryx_arg_string (char *dest, uint32_t size, jerryx_arg_coerce_t conv_flag, jerryx_arg_optional_t opt_flag);

jerry-ext/include/jerryscript-ext/arg.impl.h

Lines changed: 66 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,41 +17,75 @@
1717
#define JERRYX_ARG_IMPL_H
1818

1919
/* transform functions for each type. */
20-
jerry_value_t jerryx_arg_transform_number_strict (jerryx_arg_js_iterator_t *js_arg_iter_p,
21-
const jerryx_arg_t *c_arg_p);
22-
jerry_value_t jerryx_arg_transform_number_strict_optional (jerryx_arg_js_iterator_t *js_arg_iter_p,
23-
const jerryx_arg_t *c_arg_p);
24-
jerry_value_t jerryx_arg_transform_number_optional (jerryx_arg_js_iterator_t *js_arg_iter_p,
25-
const jerryx_arg_t *c_arg_p);
26-
jerry_value_t jerryx_arg_transform_number (jerryx_arg_js_iterator_t *js_arg_iter_p,
27-
const jerryx_arg_t *c_arg_p);
28-
jerry_value_t jerryx_arg_transform_boolean_strict (jerryx_arg_js_iterator_t *js_arg_iter_p,
29-
const jerryx_arg_t *c_arg_p);
30-
jerry_value_t jerryx_arg_transform_boolean_strict_optional (jerryx_arg_js_iterator_t *js_arg_iter_p,
31-
const jerryx_arg_t *c_arg_p);
32-
jerry_value_t jerryx_arg_transform_boolean_optional (jerryx_arg_js_iterator_t *js_arg_iter_p,
33-
const jerryx_arg_t *c_arg_p);
34-
jerry_value_t jerryx_arg_transform_boolean (jerryx_arg_js_iterator_t *js_arg_iter_p,
35-
const jerryx_arg_t *c_arg_p);
36-
jerry_value_t jerryx_arg_transform_string_strict (jerryx_arg_js_iterator_t *js_arg_iter_p,
37-
const jerryx_arg_t *c_arg_p);
38-
jerry_value_t jerryx_arg_transform_string_strict_optional (jerryx_arg_js_iterator_t *js_arg_iter_p,
39-
const jerryx_arg_t *c_arg_p);
40-
jerry_value_t jerryx_arg_transform_string_optional (jerryx_arg_js_iterator_t *js_arg_iter_p,
41-
const jerryx_arg_t *c_arg_p);
42-
jerry_value_t jerryx_arg_transform_string (jerryx_arg_js_iterator_t *js_arg_iter_p,
43-
const jerryx_arg_t *c_arg_p);
44-
jerry_value_t jerryx_arg_transform_function (jerryx_arg_js_iterator_t *js_arg_iter_p,
45-
const jerryx_arg_t *c_arg_p);
46-
jerry_value_t jerryx_arg_transform_function_optional (jerryx_arg_js_iterator_t *js_arg_iter_p,
47-
const jerryx_arg_t *c_arg_p);
48-
jerry_value_t jerryx_arg_transform_native_pointer (jerryx_arg_js_iterator_t *js_arg_iter_p,
49-
const jerryx_arg_t *c_arg_p);
50-
jerry_value_t jerryx_arg_transform_native_pointer_optional (jerryx_arg_js_iterator_t *js_arg_iter_p,
51-
const jerryx_arg_t *c_arg_p);
20+
21+
#define DECLARE_JERRYX_ARG_TRANSFORM_FUNC_WITH_OPTIONAL(type) \
22+
jerry_value_t jerryx_arg_transform_ ## type (jerryx_arg_js_iterator_t *js_arg_iter_p, \
23+
const jerryx_arg_t *c_arg_p); \
24+
jerry_value_t jerryx_arg_transform_ ## type ## _optional (jerryx_arg_js_iterator_t *js_arg_iter_p, \
25+
const jerryx_arg_t *c_arg_p);
26+
27+
#define DECLARE_JERRYX_ARG_TRANSFORM_FUNC_WITH_OPTIONAL_AND_STRICT(type) \
28+
DECLARE_JERRYX_ARG_TRANSFORM_FUNC_WITH_OPTIONAL(type) \
29+
DECLARE_JERRYX_ARG_TRANSFORM_FUNC_WITH_OPTIONAL(type ## _strict)
30+
31+
DECLARE_JERRYX_ARG_TRANSFORM_FUNC_WITH_OPTIONAL_AND_STRICT (uint8)
32+
DECLARE_JERRYX_ARG_TRANSFORM_FUNC_WITH_OPTIONAL_AND_STRICT (int8)
33+
DECLARE_JERRYX_ARG_TRANSFORM_FUNC_WITH_OPTIONAL_AND_STRICT (uint16)
34+
DECLARE_JERRYX_ARG_TRANSFORM_FUNC_WITH_OPTIONAL_AND_STRICT (int16)
35+
DECLARE_JERRYX_ARG_TRANSFORM_FUNC_WITH_OPTIONAL_AND_STRICT (uint32)
36+
DECLARE_JERRYX_ARG_TRANSFORM_FUNC_WITH_OPTIONAL_AND_STRICT (int32)
37+
DECLARE_JERRYX_ARG_TRANSFORM_FUNC_WITH_OPTIONAL_AND_STRICT (number)
38+
DECLARE_JERRYX_ARG_TRANSFORM_FUNC_WITH_OPTIONAL_AND_STRICT (string)
39+
DECLARE_JERRYX_ARG_TRANSFORM_FUNC_WITH_OPTIONAL_AND_STRICT (boolean)
40+
DECLARE_JERRYX_ARG_TRANSFORM_FUNC_WITH_OPTIONAL (function)
41+
DECLARE_JERRYX_ARG_TRANSFORM_FUNC_WITH_OPTIONAL (native_pointer)
5242
jerry_value_t jerryx_arg_transform_ignore (jerryx_arg_js_iterator_t *js_arg_iter_p,
5343
const jerryx_arg_t *c_arg_p);
5444

45+
/**
46+
* The macro used to generate jerryx_arg_xxx for int type.
47+
*/
48+
#define GENERATE_JERRYX_ARG_INT(type) \
49+
static inline jerryx_arg_t \
50+
jerryx_arg_ ## type (type ## _t *dest, jerryx_arg_coerce_t coerce_flag, jerryx_arg_optional_t opt_flag) \
51+
{ \
52+
jerryx_arg_transform_func_t func; \
53+
if (coerce_flag == JERRYX_ARG_NO_COERCE) \
54+
{ \
55+
if (opt_flag == JERRYX_ARG_OPTIONAL) \
56+
{ \
57+
func = jerryx_arg_transform_ ## type ## _strict_optional; \
58+
} \
59+
else \
60+
{ \
61+
func = jerryx_arg_transform_ ## type ## _strict; \
62+
} \
63+
} \
64+
else \
65+
{ \
66+
if (opt_flag == JERRYX_ARG_OPTIONAL) \
67+
{ \
68+
func = jerryx_arg_transform_ ## type ## _optional; \
69+
} \
70+
else \
71+
{ \
72+
func = jerryx_arg_transform_ ## type; \
73+
} \
74+
} \
75+
return (jerryx_arg_t) \
76+
{ \
77+
.func = func, \
78+
.dest = (void *) dest \
79+
}; \
80+
}
81+
82+
GENERATE_JERRYX_ARG_INT (uint8)
83+
GENERATE_JERRYX_ARG_INT (int8)
84+
GENERATE_JERRYX_ARG_INT (uint16)
85+
GENERATE_JERRYX_ARG_INT (int16)
86+
GENERATE_JERRYX_ARG_INT (uint32)
87+
GENERATE_JERRYX_ARG_INT (int32)
88+
5589
/**
5690
* Create a validation/transformation step (`jerryx_arg_t`) that expects to
5791
* consume one `number` JS argument and stores it into a C `double`.

tests/unit-ext/test-ext-arg.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ const char *test_source = (
4040
"test_validator2.call(obj_a, 5);"
4141
"test_validator2.call(obj_b, 5);"
4242
"test_validator2.call(obj_a, 1);"
43+
"test_validator_int(-1000, 1000, 128, -1000, 1000, -127,"
44+
" -1000, 4294967297, 65536, -2200000000, 4294967297, -2147483647);"
4345
);
4446

4547
static const jerry_object_native_info_t thing_a_info =
@@ -67,6 +69,7 @@ static my_type_b_t my_thing_b;
6769

6870
static int validator1_count = 0;
6971
static int validator2_count = 0;
72+
static int validator_int_count = 0;
7073

7174
/**
7275
* The handler should have following arguments:
@@ -211,6 +214,62 @@ test_validator2_handler (const jerry_value_t func_obj_val __attribute__((unused)
211214
return jerry_create_undefined ();
212215
} /* test_validator2_handler */
213216

217+
218+
/**
219+
* args_p[0-2] are uint8, args_p[3-5] are int8, args_p[6-8] are uint32, args_p[9-11] are int32.
220+
*/
221+
static jerry_value_t
222+
test_validator_int_handler (const jerry_value_t func_obj_val __attribute__((unused)), /**< function object */
223+
const jerry_value_t this_val __attribute__((unused)), /**< this value */
224+
const jerry_value_t args_p[], /**< arguments list */
225+
const jerry_length_t args_cnt) /**< arguments length */
226+
{
227+
uint8_t num0, num1, num2;
228+
int8_t num3, num4, num5;
229+
uint32_t num6, num7, num8;
230+
int32_t num9, num10, num11;
231+
232+
jerryx_arg_t mapping[] =
233+
{
234+
jerryx_arg_uint8 (&num0, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
235+
jerryx_arg_uint8 (&num1, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
236+
jerryx_arg_uint8 (&num2, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
237+
jerryx_arg_int8 (&num3, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
238+
jerryx_arg_int8 (&num4, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
239+
jerryx_arg_int8 (&num5, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
240+
jerryx_arg_uint32 (&num6, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
241+
jerryx_arg_uint32 (&num7, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
242+
jerryx_arg_uint32 (&num8, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
243+
jerryx_arg_int32 (&num9, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
244+
jerryx_arg_int32 (&num10, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
245+
jerryx_arg_int32 (&num11, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED)
246+
};
247+
248+
jerry_value_t is_ok = jerryx_arg_transform_args (args_p,
249+
args_cnt,
250+
mapping,
251+
12);
252+
253+
TEST_ASSERT (!jerry_value_has_error_flag (is_ok));
254+
TEST_ASSERT (num0 == 0);
255+
TEST_ASSERT (num1 == 255);
256+
TEST_ASSERT (num2 == 128);
257+
TEST_ASSERT (num3 == -128);
258+
TEST_ASSERT (num4 == 127);
259+
TEST_ASSERT (num5 == -127);
260+
TEST_ASSERT (num6 == 0);
261+
TEST_ASSERT (num7 == 4294967295);
262+
TEST_ASSERT (num8 == 65536);
263+
TEST_ASSERT (num9 == -2147483648);
264+
TEST_ASSERT (num10 == 2147483647);
265+
TEST_ASSERT (num11 == -2147483647);
266+
267+
jerry_release_value (is_ok);
268+
validator_int_count ++;
269+
270+
return jerry_create_undefined ();
271+
} /* test_validator_int_handler */
272+
214273
static jerry_value_t
215274
create_object_a_handler (const jerry_value_t func_obj_val __attribute__((unused)), /**< function object */
216275
const jerry_value_t this_val, /**< this value */
@@ -270,6 +329,7 @@ main (void)
270329

271330
register_js_function ("test_validator1", test_validator1_handler);
272331
register_js_function ("test_validator2", test_validator2_handler);
332+
register_js_function ("test_validator_int", test_validator_int_handler);
273333
register_js_function ("MyObjectA", create_object_a_handler);
274334
register_js_function ("MyObjectB", create_object_b_handler);
275335

@@ -280,6 +340,7 @@ main (void)
280340
TEST_ASSERT (!jerry_value_has_error_flag (res));
281341
TEST_ASSERT (validator1_count == 4);
282342
TEST_ASSERT (validator2_count == 3);
343+
TEST_ASSERT (validator_int_count == 1);
283344

284345
jerry_release_value (res);
285346
jerry_release_value (parsed_code_val);

0 commit comments

Comments
 (0)