Skip to content

Commit 525c35f

Browse files
rerobikadbatyai
authored andcommitted
Introduce jerry_get_resource_name API function (#3236)
This new API function adds possibility to query the resource name of the currently executed script (including modules) or a function object. This patch closes #2170. JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
1 parent 55423ab commit 525c35f

File tree

16 files changed

+415
-82
lines changed

16 files changed

+415
-82
lines changed

docs/02.API-REFERENCE.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7556,6 +7556,105 @@ main (void)
75567556
- [jerry_create_external_function](#jerry_create_external_function)
75577557

75587558

7559+
## jerry_get_resurce_name
7560+
7561+
**Summary**
7562+
7563+
Get the resource name (usually a file name) of the currently executed script or the given function object.
7564+
7565+
This function is typically called from native callbacks.
7566+
7567+
*Notes*:
7568+
- Returned value must be freed with [jerry_release_value](#jerry_release_value) when it
7569+
is no longer needed.
7570+
- This feature depends on build option (`JERRY_LINE_INFO`) and can be checked
7571+
in runtime with the `JERRY_FEATURE_LINE_INFO` feature enum value,
7572+
see: [jerry_is_feature_enabled](#jerry_is_feature_enabled).
7573+
7574+
**Prototype**
7575+
7576+
```c
7577+
jerry_value_t
7578+
jerry_get_resurce_name (void);
7579+
```
7580+
7581+
- return string value constructed from
7582+
- the currently executed function object's resource name, if the given value is undefined
7583+
- resource name of the function object, if the given value is a function object
7584+
- "<anonymous>", otherwise
7585+
7586+
**Example**
7587+
7588+
[doctest]: # (name="02.API-REFERENCE-jsresourcename.c")
7589+
7590+
```c
7591+
#include <stdio.h>
7592+
#include <string.h>
7593+
#include "jerryscript.h"
7594+
7595+
static jerry_value_t
7596+
resource_name_handler (const jerry_value_t function_obj,
7597+
const jerry_value_t this_val,
7598+
const jerry_value_t args_p[],
7599+
const jerry_length_t args_count)
7600+
{
7601+
jerry_value_t undefined_value = jerry_create_undefined ();
7602+
jerry_value_t resource_name = jerry_get_resource_name (args_count > 0 ? args_p[0] : undefined_value);
7603+
jerry_release_value (undefined_value);
7604+
7605+
return resource_name;
7606+
} /* resource_name_handler */
7607+
7608+
int
7609+
main (void)
7610+
{
7611+
jerry_init (JERRY_INIT_EMPTY);
7612+
7613+
jerry_value_t global = jerry_get_global_object ();
7614+
7615+
/* Register the "resourceName" method. */
7616+
{
7617+
jerry_value_t func = jerry_create_external_function (resource_name_handler);
7618+
jerry_value_t name = jerry_create_string ((const jerry_char_t *) "resourceName");
7619+
jerry_value_t result = jerry_set_property (global, name, func);
7620+
jerry_release_value (result);
7621+
jerry_release_value (name);
7622+
jerry_release_value (func);
7623+
}
7624+
7625+
jerry_release_value (global);
7626+
7627+
const jerry_char_t source[] = "function myFunction() { return resourceName() }; myFunction()";
7628+
const jerry_char_t resource[] = "demo.js";
7629+
7630+
jerry_value_t program = jerry_parse (resource,
7631+
sizeof (resource) - 1,
7632+
source,
7633+
sizeof (source) - 1,
7634+
JERRY_PARSE_NO_OPTS);
7635+
7636+
if (!jerry_value_is_error (program))
7637+
{
7638+
/* `run_result` contains "demo.js" */
7639+
jerry_value_t run_result = jerry_run (program);
7640+
7641+
/* usage of `run_result` */
7642+
7643+
jerry_release_value (run_result);
7644+
}
7645+
7646+
jerry_release_value (program);
7647+
jerry_cleanup ();
7648+
7649+
return 0;
7650+
}
7651+
```
7652+
7653+
**See also**
7654+
7655+
- [jerry_create_external_function](#jerry_create_external_function)
7656+
7657+
75597658
# ArrayBuffer and TypedArray functions
75607659

75617660
These APIs all depend on the ES2015-subset profile.

jerry-core/api/jerry.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3354,6 +3354,49 @@ jerry_get_backtrace (uint32_t max_depth) /**< depth limit of the backtrace */
33543354
return vm_get_backtrace (max_depth);
33553355
} /* jerry_get_backtrace */
33563356

3357+
/**
3358+
* Get the resource name (usually a file name) of the currently executed script or the given function object
3359+
*
3360+
* Note: returned value must be freed with jerry_release_value, when it is no longer needed
3361+
*
3362+
* @return JS string constructed from
3363+
* - the currently executed function object's resource name, if the given value is undefined
3364+
* - resource name of the function object, if the given value is a function object
3365+
* - "<anonymous>", otherwise
3366+
*/
3367+
jerry_value_t
3368+
jerry_get_resource_name (const jerry_value_t value) /**< jerry api value */
3369+
{
3370+
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
3371+
if (ecma_is_value_undefined (value))
3372+
{
3373+
if (JERRY_CONTEXT (vm_top_context_p) != NULL)
3374+
{
3375+
return ecma_copy_value (JERRY_CONTEXT (vm_top_context_p)->resource_name);
3376+
}
3377+
}
3378+
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
3379+
#if ENABLED (JERRY_LINE_INFO)
3380+
else if (ecma_is_value_object (value))
3381+
{
3382+
ecma_object_t *obj_p = ecma_get_object_from_value (value);
3383+
3384+
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION
3385+
&& !ecma_get_object_is_builtin (obj_p))
3386+
{
3387+
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) obj_p;
3388+
3389+
const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
3390+
3391+
return ecma_copy_value (ecma_op_resource_name (bytecode_data_p));
3392+
}
3393+
}
3394+
#endif /* ENABLED (JERRY_LINE_INFO) */
3395+
3396+
JERRY_UNUSED (value);
3397+
return ecma_make_magic_string_value (LIT_MAGIC_STRING_RESOURCE_ANON);
3398+
} /* jerry_get_resource_name */
3399+
33573400
/**
33583401
* Check if the given value is an ArrayBuffer object.
33593402
*

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,45 @@
3434
* @{
3535
*/
3636

37+
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
38+
/**
39+
* Get the resource name from the compiled code header
40+
*
41+
* @return resource name as ecma-string
42+
*/
43+
ecma_value_t
44+
ecma_op_resource_name (const ecma_compiled_code_t *bytecode_header_p)
45+
{
46+
JERRY_ASSERT (bytecode_header_p != NULL);
47+
48+
ecma_length_t formal_params_number = 0;
49+
50+
if (CBC_NON_STRICT_ARGUMENTS_NEEDED (bytecode_header_p))
51+
{
52+
if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
53+
{
54+
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_header_p;
55+
56+
formal_params_number = args_p->argument_end;
57+
}
58+
else
59+
{
60+
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_header_p;
61+
62+
formal_params_number = args_p->argument_end;
63+
}
64+
}
65+
66+
uint8_t *byte_p = (uint8_t *) bytecode_header_p;
67+
byte_p += ((size_t) bytecode_header_p->size) << JMEM_ALIGNMENT_LOG;
68+
69+
ecma_value_t *resource_name_p = (ecma_value_t *) byte_p;
70+
resource_name_p -= formal_params_number;
71+
72+
return resource_name_p[-1];
73+
} /* ecma_op_resource_name */
74+
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
75+
3776
/**
3877
* Checks whether the type is a normal or arrow function.
3978
*

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828

2929
bool ecma_is_normal_or_arrow_function (ecma_object_type_t type);
3030

31+
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
32+
ecma_value_t ecma_op_resource_name (const ecma_compiled_code_t *bytecode_header_p);
33+
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
34+
3135
bool ecma_op_is_callable (ecma_value_t value);
3236
bool ecma_op_object_is_callable (ecma_object_t *obj_p);
3337
bool ecma_is_constructor (ecma_value_t value);

jerry-core/include/jerryscript-core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,7 @@ jerry_context_t *jerry_create_context (uint32_t heap_size, jerry_context_alloc_t
605605
*/
606606
void jerry_set_vm_exec_stop_callback (jerry_vm_exec_stop_callback_t stop_cb, void *user_p, uint32_t frequency);
607607
jerry_value_t jerry_get_backtrace (uint32_t max_depth);
608+
jerry_value_t jerry_get_resource_name (const jerry_value_t value);
608609

609610
/**
610611
* Array buffer components.

jerry-core/lit/lit-magic-strings.inc.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -602,9 +602,7 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SET_UTC_DATE_UL, "setUTCDate")
602602
#if ENABLED (JERRY_BUILTIN_STRING) && ENABLED (JERRY_ES2015_BUILTIN)
603603
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_STARTS_WITH, "startsWith")
604604
#endif
605-
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
606605
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_RESOURCE_ANON, "<anonymous>")
607-
#endif
608606
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) \
609607
|| ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
610608
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ARRAY_BUFFER_UL, "ArrayBuffer")
@@ -837,18 +835,7 @@ LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (10, LIT_MAGIC_STRING_COPY_WITHIN)
837835
#else
838836
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (10, LIT_MAGIC_STRING_ENUMERABLE)
839837
#endif
840-
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
841838
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (11, LIT_MAGIC_STRING_RESOURCE_ANON)
842-
#elif ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) \
843-
|| ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
844-
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (11, LIT_MAGIC_STRING_ARRAY_BUFFER_UL)
845-
#elif ENABLED (JERRY_BUILTIN_ERRORS)
846-
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (11, LIT_MAGIC_STRING_SYNTAX_ERROR_UL)
847-
#elif ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
848-
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (11, LIT_MAGIC_STRING_UINT16_ARRAY_UL)
849-
#else
850-
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (11, LIT_MAGIC_STRING_CONSTRUCTOR)
851-
#endif
852839
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
853840
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (12, LIT_MAGIC_STRING_FLOAT32_ARRAY_UL)
854841
#elif ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) && ENABLED (JERRY_NUMBER_TYPE_FLOAT64)

jerry-core/parser/js/js-parser-statm.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2312,12 +2312,14 @@ parser_parse_statements (parser_context_t *context_p) /**< context */
23122312
}
23132313
#endif /* ENABLED (JERRY_DEBUGGER) */
23142314

2315-
#if ENABLED (JERRY_LINE_INFO)
2315+
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
23162316
if (JERRY_CONTEXT (resource_name) != ECMA_VALUE_UNDEFINED)
23172317
{
23182318
parser_emit_cbc_ext (context_p, CBC_EXT_RESOURCE_NAME);
23192319
parser_flush_cbc (context_p);
23202320
}
2321+
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
2322+
#if ENABLED (JERRY_LINE_INFO)
23212323
context_p->last_line_info_line = 0;
23222324
#endif /* ENABLED (JERRY_LINE_INFO) */
23232325

jerry-core/parser/js/js-parser.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,12 +1160,12 @@ parser_post_processing (parser_context_t *context_p) /**< context */
11601160
total_size += context_p->argument_count * sizeof (ecma_value_t);
11611161
}
11621162

1163-
#if ENABLED (JERRY_LINE_INFO)
1163+
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
11641164
if (JERRY_CONTEXT (resource_name) != ECMA_VALUE_UNDEFINED)
11651165
{
11661166
total_size += sizeof (ecma_value_t);
11671167
}
1168-
#endif /* ENABLED (JERRY_LINE_INFO) */
1168+
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
11691169

11701170
#if ENABLED (JERRY_SNAPSHOT_SAVE)
11711171
total_size_used = total_size;
@@ -1558,7 +1558,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */
15581558
}
15591559
}
15601560

1561-
#if ENABLED (JERRY_LINE_INFO)
1561+
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
15621562
if (JERRY_CONTEXT (resource_name) != ECMA_VALUE_UNDEFINED)
15631563
{
15641564
ecma_value_t *resource_name_p = (ecma_value_t *) (((uint8_t *) compiled_code_p) + total_size);
@@ -1571,7 +1571,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */
15711571

15721572
resource_name_p[-1] = JERRY_CONTEXT (resource_name);
15731573
}
1574-
#endif /* ENABLED (JERRY_LINE_INFO) */
1574+
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
15751575

15761576
#if ENABLED (JERRY_DEBUGGER)
15771577
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)

jerry-core/vm/vm-defines.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,10 @@ typedef struct vm_frame_ctx_t
5252
#endif /* defined (JERRY_DEBUGGER) || ENABLED (JERRY_LINE_INFO) */
5353
ecma_value_t this_binding; /**< this binding */
5454
ecma_value_t block_result; /**< block result */
55-
#if ENABLED (JERRY_LINE_INFO)
55+
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
5656
ecma_value_t resource_name; /**< current resource name (usually a file name) */
57+
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
58+
#if ENABLED (JERRY_LINE_INFO)
5759
uint32_t current_line; /**< currently executed line */
5860
#endif /* ENABLED (JERRY_LINE_INFO) */
5961
uint16_t context_depth; /**< current context depth */

jerry-core/vm/vm.c

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3384,36 +3384,14 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
33843384
continue;
33853385
}
33863386
#endif /* ENABLED (JERRY_DEBUGGER) */
3387-
#if ENABLED (JERRY_LINE_INFO)
3387+
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
33883388
case VM_OC_RESOURCE_NAME:
33893389
{
3390-
ecma_length_t formal_params_number = 0;
3391-
3392-
if (CBC_NON_STRICT_ARGUMENTS_NEEDED (bytecode_header_p))
3393-
{
3394-
if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
3395-
{
3396-
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_header_p;
3397-
3398-
formal_params_number = args_p->argument_end;
3399-
}
3400-
else
3401-
{
3402-
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_header_p;
3403-
3404-
formal_params_number = args_p->argument_end;
3405-
}
3406-
}
3407-
3408-
uint8_t *byte_p = (uint8_t *) bytecode_header_p;
3409-
byte_p += ((size_t) bytecode_header_p->size) << JMEM_ALIGNMENT_LOG;
3410-
3411-
ecma_value_t *resource_name_p = (ecma_value_t *) byte_p;
3412-
resource_name_p -= formal_params_number;
3413-
3414-
frame_ctx_p->resource_name = resource_name_p[-1];
3390+
frame_ctx_p->resource_name = ecma_op_resource_name (bytecode_header_p);
34153391
continue;
34163392
}
3393+
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
3394+
#if ENABLED (JERRY_LINE_INFO)
34173395
case VM_OC_LINE:
34183396
{
34193397
uint32_t value = 0;
@@ -3840,8 +3818,10 @@ vm_run (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data heade
38403818
#endif /* defined (JERRY_DEBUGGER) || ENABLED (JERRY_LINE_INFO) */
38413819
frame_ctx.this_binding = this_binding_value;
38423820
frame_ctx.block_result = ECMA_VALUE_UNDEFINED;
3843-
#if ENABLED (JERRY_LINE_INFO)
3821+
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
38443822
frame_ctx.resource_name = ECMA_VALUE_UNDEFINED;
3823+
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
3824+
#if ENABLED (JERRY_LINE_INFO)
38453825
frame_ctx.current_line = 0;
38463826
#endif /* ENABLED (JERRY_LINE_INFO) */
38473827
frame_ctx.context_depth = 0;

0 commit comments

Comments
 (0)