Skip to content

Commit 35485a8

Browse files
committed
Implement global realm and support realms for built-in objects
JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg [email protected]
1 parent d845ac9 commit 35485a8

File tree

18 files changed

+667
-146
lines changed

18 files changed

+667
-146
lines changed

docs/02.API-REFERENCE.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ Possible compile time enabled feature types:
141141
- JERRY_FEATURE_SET - Set support
142142
- JERRY_FEATURE_WEAKMAP - WeakMap support
143143
- JERRY_FEATURE_WEAKSET - WeakSet support
144+
- JERRY_FEATURE_BIGINT - BigInt support
145+
- JERRY_FEATURE_REALM - realm support
144146

145147
*New in version 2.0*.
146148

@@ -5969,6 +5971,38 @@ jerry_create_undefined (void);
59695971
- [jerry_release_value](#jerry_release_value)
59705972

59715973

5974+
## jerry_create_realm
5975+
5976+
**Summary**
5977+
5978+
Creates a `jerry_value_t` representing a new global object.
5979+
5980+
**Prototype**
5981+
5982+
```c
5983+
jerry_value_t
5984+
jerry_create_realm (void);
5985+
```
5986+
5987+
- return value - realm object value
5988+
5989+
**Example**
5990+
5991+
```c
5992+
{
5993+
jerry_value_t realm_value = jerry_create_realm ();
5994+
5995+
... // usage of the value
5996+
5997+
jerry_release_value (realm_value);
5998+
}
5999+
```
6000+
6001+
**See also**
6002+
6003+
- [jerry_release_value](#jerry_release_value)
6004+
6005+
59726006
# General API functions of JS objects
59736007

59746008
## jerry_has_property

jerry-core/api/jerry.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,6 +1341,9 @@ jerry_is_feature_enabled (const jerry_feature_t feature) /**< feature to check *
13411341
#if ENABLED (JERRY_BUILTIN_BIGINT)
13421342
|| feature == JERRY_FEATURE_BIGINT
13431343
#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */
1344+
#if ENABLED (JERRY_BUILTIN_REALMS)
1345+
|| feature == JERRY_FEATURE_REALM
1346+
#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
13441347
);
13451348
} /* jerry_is_feature_enabled */
13461349

@@ -2299,6 +2302,24 @@ jerry_create_regexp_sz (const jerry_char_t *pattern_p, /**< zero-terminated UTF-
22992302
#endif /* ENABLED (JERRY_BUILTIN_REGEXP) */
23002303
} /* jerry_create_regexp_sz */
23012304

2305+
/**
2306+
* Creates a new realm (global object).
2307+
*
2308+
* @return new realm object
2309+
*/
2310+
jerry_value_t
2311+
jerry_create_realm (void)
2312+
{
2313+
jerry_assert_api_available ();
2314+
2315+
#if ENABLED (JERRY_BUILTIN_REALMS)
2316+
ecma_global_object_t *global_object_p = ecma_builtin_create_global_object ();
2317+
return ecma_make_object_value ((ecma_object_t *) global_object_p);
2318+
#else /* !ENABLED (JERRY_BUILTIN_REALMS) */
2319+
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Realms are disabled.")));
2320+
#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
2321+
} /* jerry_create_realm */
2322+
23022323
/**
23032324
* Get length of an array object
23042325
*

jerry-core/config.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@
7979
# define JERRY_ESNEXT 1
8080
#endif /* !defined (JERRY_ESNEXT) */
8181

82+
#ifndef JERRY_BUILTIN_REALMS
83+
# define JERRY_BUILTIN_REALMS JERRY_ESNEXT
84+
#endif /* !defined (JERRY_BUILTIN_REALMS) */
85+
8286
#ifndef JERRY_BUILTIN_DATAVIEW
8387
# define JERRY_BUILTIN_DATAVIEW JERRY_ESNEXT
8488
#endif /* !defined (JERRY_BUILTIN_DATAVIEW) */
@@ -523,6 +527,10 @@
523527
|| ((JERRY_ESNEXT != 0) && (JERRY_ESNEXT != 1))
524528
# error "Invalid value for JERRY_ESNEXT macro."
525529
#endif
530+
#if !defined (JERRY_BUILTIN_REALMS) \
531+
|| ((JERRY_BUILTIN_REALMS != 0) && (JERRY_BUILTIN_REALMS != 1))
532+
# error "Invalid value for JERRY_BUILTIN_REALMS macro."
533+
#endif
526534
#if !defined (JERRY_BUILTIN_DATAVIEW) \
527535
|| ((JERRY_BUILTIN_DATAVIEW != 0) && (JERRY_BUILTIN_DATAVIEW != 1))
528536
# error "Invalid value for JERRY_BUILTIN_DATAVIEW macro."

jerry-core/ecma/base/ecma-gc.c

Lines changed: 80 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,33 @@ ecma_deref_object (ecma_object_t *object_p) /**< object */
149149
object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs - ECMA_OBJECT_REF_ONE);
150150
} /* ecma_deref_object */
151151

152+
/**
153+
* Mark objects referenced by global object
154+
*/
155+
static void
156+
ecma_gc_mark_global_object (ecma_global_object_t *global_object_p) /**< global object */
157+
{
158+
JERRY_ASSERT (global_object_p->extended_object.u.built_in.routine_id == 0);
159+
160+
ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t, global_object_p->global_env_cp));
161+
162+
#if ENABLED (JERRY_ESNEXT)
163+
if (global_object_p->global_scope_cp != global_object_p->global_env_cp)
164+
{
165+
ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t, global_object_p->global_scope_cp));
166+
}
167+
#endif /* ENABLED (JERRY_ESNEXT) */
168+
169+
jmem_cpointer_t *builtin_objects_p = global_object_p->builtin_objects;
170+
for (int i = 0; i < ECMA_BUILTIN_OBJECTS_COUNT; i++)
171+
{
172+
if (builtin_objects_p[i] != JMEM_CP_NULL)
173+
{
174+
ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t, builtin_objects_p[i]));
175+
}
176+
}
177+
} /* ecma_gc_mark_global_object */
178+
152179
/**
153180
* Mark objects referenced by arguments object
154181
*/
@@ -620,14 +647,52 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
620647
{
621648
ecma_object_t *binding_object_p = ecma_get_lex_env_binding_object (object_p);
622649
ecma_gc_set_object_visited (binding_object_p);
623-
624650
return;
625651
}
626652
}
627653
else
628654
{
629-
switch (ecma_get_object_type (object_p))
655+
ecma_object_type_t object_type = ecma_get_object_type (object_p);
656+
657+
#if ENABLED (JERRY_BUILTIN_REALMS)
658+
if (JERRY_UNLIKELY (ecma_get_object_is_builtin (object_p)))
659+
{
660+
ecma_value_t realm_value;
661+
662+
if (ECMA_BUILTIN_IS_EXTENDED_BUILT_IN (object_type))
663+
{
664+
realm_value = ((ecma_extended_built_in_object_t *) object_p)->built_in.realm_value;
665+
}
666+
else
667+
{
668+
ecma_extended_object_t *extended_object_p = (ecma_extended_object_t *) object_p;
669+
670+
if (object_type == ECMA_OBJECT_TYPE_GENERAL
671+
&& extended_object_p->u.built_in.id == ECMA_BUILTIN_ID_GLOBAL)
672+
{
673+
ecma_gc_mark_global_object ((ecma_global_object_t *) object_p);
674+
}
675+
676+
realm_value = extended_object_p->u.built_in.realm_value;
677+
}
678+
679+
ecma_gc_set_object_visited (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, realm_value));
680+
}
681+
#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
682+
683+
switch (object_type)
630684
{
685+
#if !ENABLED (JERRY_BUILTIN_REALMS)
686+
case ECMA_OBJECT_TYPE_GENERAL:
687+
{
688+
if (JERRY_UNLIKELY (ecma_get_object_is_builtin (object_p))
689+
&& ((ecma_extended_object_t *) object_p)->u.built_in.id == ECMA_BUILTIN_ID_GLOBAL)
690+
{
691+
ecma_gc_mark_global_object ((ecma_global_object_t *) object_p);
692+
}
693+
break;
694+
}
695+
#endif /* !ENABLED (JERRY_BUILTIN_REALMS) */
631696
case ECMA_OBJECT_TYPE_CLASS:
632697
{
633698
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
@@ -1305,23 +1370,24 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
13051370
{
13061371
uint8_t length_and_bitset_size;
13071372

1308-
if (object_type == ECMA_OBJECT_TYPE_CLASS || object_type == ECMA_OBJECT_TYPE_ARRAY)
1373+
if (ECMA_BUILTIN_IS_EXTENDED_BUILT_IN (object_type))
13091374
{
13101375
ext_object_size = sizeof (ecma_extended_built_in_object_t);
13111376
length_and_bitset_size = ((ecma_extended_built_in_object_t *) object_p)->built_in.u.length_and_bitset_size;
13121377
ext_object_size += sizeof (uint64_t) * (length_and_bitset_size >> ECMA_BUILT_IN_BITSET_SHIFT);
13131378
}
13141379
else
13151380
{
1316-
if (object_type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION
1317-
&& ecma_builtin_function_is_routine (object_p))
1381+
ecma_extended_object_t *extended_object_p = (ecma_extended_object_t *) object_p;
1382+
1383+
if (extended_object_p->u.built_in.routine_id > 0)
13181384
{
1319-
#if ENABLED (JERRY_ESNEXT)
1320-
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
1385+
JERRY_ASSERT (object_type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION);
13211386

1322-
if (ext_obj_p->u.built_in.id == ECMA_BUILTIN_ID_HANDLER)
1387+
#if ENABLED (JERRY_ESNEXT)
1388+
if (extended_object_p->u.built_in.id == ECMA_BUILTIN_ID_HANDLER)
13231389
{
1324-
switch (ext_obj_p->u.built_in.routine_id)
1390+
switch (extended_object_p->u.built_in.routine_id)
13251391
{
13261392
case ECMA_NATIVE_HANDLER_PROMISE_RESOLVE:
13271393
case ECMA_NATIVE_HANDLER_PROMISE_REJECT:
@@ -1367,6 +1433,11 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
13671433
}
13681434
#endif /* ENABLED (JERRY_ESNEXT) */
13691435
}
1436+
else if (extended_object_p->u.built_in.id == ECMA_BUILTIN_ID_GLOBAL)
1437+
{
1438+
JERRY_ASSERT (object_type == ECMA_OBJECT_TYPE_GENERAL);
1439+
ext_object_size = sizeof (ecma_global_object_t);
1440+
}
13701441
else
13711442
{
13721443
length_and_bitset_size = ((ecma_extended_object_t *) object_p)->u.built_in.u.length_and_bitset_size;

jerry-core/ecma/base/ecma-globals.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,14 +864,30 @@ typedef struct
864864
uint8_t instantiated_bitset[1]; /**< instantiated property bit set for generic built-ins */
865865
uint8_t routine_flags; /**< flags for built-in routines */
866866
} u2;
867+
868+
#if ENABLED (JERRY_BUILTIN_REALMS)
869+
ecma_value_t realm_value; /**< realm value */
870+
#else /* !ENABLED (JERRY_BUILTIN_REALMS) */
867871
uint32_t continue_instantiated_bitset[1]; /**< bit set for instantiated properties */
872+
#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
868873
} ecma_built_in_props_t;
869874

875+
#if ENABLED (JERRY_BUILTIN_REALMS)
876+
877+
/**
878+
* Number of bits available in the instantiated bitset without allocation
879+
*/
880+
#define ECMA_BUILTIN_INSTANTIATED_BITSET_MIN_SIZE (8)
881+
882+
#else /* !ENABLED (JERRY_BUILTIN_REALMS) */
883+
870884
/**
871885
* Number of bits available in the instantiated bitset without allocation
872886
*/
873887
#define ECMA_BUILTIN_INSTANTIATED_BITSET_MIN_SIZE (8 + 32)
874888

889+
#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
890+
875891
/**
876892
* Builtin routine function object status flags
877893
*/
@@ -992,6 +1008,12 @@ typedef struct
9921008
ecma_built_in_props_t built_in; /**< built-in object part */
9931009
} ecma_extended_built_in_object_t;
9941010

1011+
/**
1012+
* Checks whether the built-in is an ecma_extended_built_in_object_t
1013+
*/
1014+
#define ECMA_BUILTIN_IS_EXTENDED_BUILT_IN(object_type) \
1015+
((object_type) == ECMA_OBJECT_TYPE_CLASS || (object_type) == ECMA_OBJECT_TYPE_ARRAY)
1016+
9951017
/**
9961018
* Flags for array.length_prop_and_hole_count
9971019
*/

jerry-core/ecma/base/ecma-helpers.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ ecma_get_object_builtin_id (ecma_object_t *object_p) /**< object */
250250
ecma_built_in_props_t *built_in_props_p;
251251
ecma_object_type_t object_type = ecma_get_object_type (object_p);
252252

253-
if (object_type == ECMA_OBJECT_TYPE_CLASS || object_type == ECMA_OBJECT_TYPE_ARRAY)
253+
if (ECMA_BUILTIN_IS_EXTENDED_BUILT_IN (object_type))
254254
{
255255
built_in_props_p = &((ecma_extended_built_in_object_t *) object_p)->built_in;
256256
}

jerry-core/ecma/base/ecma-init-finalize.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,17 @@ ecma_finalize (void)
7777

7878
ecma_finalize_global_environment ();
7979
uint8_t runs = 0;
80+
8081
do
8182
{
82-
ecma_finalize_builtins ();
8383
ecma_gc_run ();
8484
if (++runs >= JERRY_GC_LOOP_LIMIT)
8585
{
8686
jerry_fatal (ERR_UNTERMINATED_GC_LOOPS);
8787
}
8888
}
8989
while (JERRY_CONTEXT (ecma_gc_new_objects) != 0);
90+
9091
ecma_finalize_lit_storage ();
9192
} /* ecma_finalize */
9293

0 commit comments

Comments
 (0)