Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F9899510
symbol.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
symbol.c
View Options
#include
<stdlib.h>
#include
<string.h>
#include
<stdio.h>
#include
"ant.h"
#include
"utf8.h"
#include
"errors.h"
#include
"runtime.h"
#include
"internal.h"
#include
"silver/engine.h"
#include
"modules/symbol.h"
#include
"descriptors.h"
#include
"gc/roots.h"
#include
"gc/modules.h"
#define DECL_SYM(name, _desc) static ant_value_t g_##name = {0};
WELLKNOWN_SYMBOLS
(
DECL_SYM
)
#undef DECL_SYM
#define DEF_GET_SYM(name, _desc) ant_value_t get_##name##_sym(void) { return g_##name; }
WELLKNOWN_SYMBOLS
(
DEF_GET_SYM
)
#undef DEF_GET_SYM
static
ant_value_t
builtin_Symbol
(
ant_t
*
js
,
ant_value_t
*
args
,
int
nargs
)
{
if
(
vtype
(
js
->
new_target
)
!=
T_UNDEF
)
return
js_mkerr_typed
(
js
,
JS_ERR_TYPE
,
"Symbol is not a constructor"
);
const
char
*
desc
=
NULL
;
if
(
nargs
>
0
&&
vtype
(
args
[
0
])
==
T_STR
)
{
desc
=
js_getstr
(
js
,
args
[
0
],
NULL
);
}
return
js_mksym
(
js
,
desc
);
}
static
ant_value_t
builtin_Symbol_for
(
ant_t
*
js
,
ant_value_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
||
vtype
(
args
[
0
])
!=
T_STR
)
{
return
js_mkerr
(
js
,
"Symbol.for requires a string argument"
);
}
char
*
key
=
js_getstr
(
js
,
args
[
0
],
NULL
);
if
(
!
key
)
return
js_mkerr
(
js
,
"Invalid key"
);
return
js_mksym_for
(
js
,
key
);
}
static
ant_value_t
builtin_Symbol_keyFor
(
ant_t
*
js
,
ant_value_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
||
vtype
(
args
[
0
])
!=
T_SYMBOL
)
{
return
js_mkundef
();
}
const
char
*
key
=
js_sym_key
(
args
[
0
]);
if
(
!
key
)
return
js_mkundef
();
return
js_mkstr
(
js
,
key
,
strlen
(
key
));
}
static
ant_value_t
builtin_Symbol_toString
(
ant_t
*
js
,
ant_value_t
*
args
,
int
nargs
)
{
ant_value_t
this_val
=
js_getthis
(
js
);
if
(
vtype
(
this_val
)
!=
T_SYMBOL
)
{
return
js_mkerr
(
js
,
"Symbol.prototype.toString requires a symbol"
);
}
return
js_symbol_to_string
(
js
,
this_val
);
}
static
ant_value_t
get_iterator_prototype
(
ant_t
*
js
)
{
if
(
vtype
(
js
->
sym
.
iterator_proto
)
==
T_OBJ
)
return
js
->
sym
.
iterator_proto
;
js
->
sym
.
iterator_proto
=
js_mkobj
(
js
);
js_set_proto_init
(
js
->
sym
.
iterator_proto
,
js
->
object
);
js_set_sym
(
js
,
js
->
sym
.
iterator_proto
,
g_iterator
,
js_mkfun
(
sym_this_cb
));
return
js
->
sym
.
iterator_proto
;
}
static
ant_value_t
arr_iter_next
(
ant_t
*
js
,
ant_value_t
*
args
,
int
nargs
)
{
ant_value_t
iter
=
js
->
this_val
;
ant_value_t
array
=
js_get_slot
(
iter
,
SLOT_DATA
);
ant_value_t
state_v
=
js_get_slot
(
iter
,
SLOT_ITER_STATE
);
uint32_t
state
=
(
vtype
(
state_v
)
==
T_NUM
)
?
(
uint32_t
)
js_getnum
(
state_v
)
:
0
;
uint32_t
kind
=
ARR_ITER_KIND
(
state
);
uint32_t
idx
=
ARR_ITER_INDEX
(
state
);
ant_value_t
result
=
js_mkobj
(
js
);
ant_offset_t
len
=
js_arr_len
(
js
,
array
);
if
(
idx
>=
(
uint32_t
)
len
)
{
js_set
(
js
,
result
,
"done"
,
js_true
);
js_set
(
js
,
result
,
"value"
,
js_mkundef
());
return
result
;
}
ant_value_t
value
;
switch
(
kind
)
{
case
ARR_ITER_KEYS
:
value
=
js_mknum
((
double
)
idx
);
break
;
case
ARR_ITER_ENTRIES
:
{
ant_value_t
pair
=
js_mkarr
(
js
);
js_arr_push
(
js
,
pair
,
js_mknum
((
double
)
idx
));
js_arr_push
(
js
,
pair
,
js_arr_get
(
js
,
array
,
(
ant_offset_t
)
idx
));
value
=
pair
;
break
;
}
default
:
value
=
js_arr_get
(
js
,
array
,
(
ant_offset_t
)
idx
);
break
;
}
js_set_slot
(
iter
,
SLOT_ITER_STATE
,
js_mknum
((
double
)
ARR_ITER_PACK
(
kind
,
idx
+
1
)));
js_set
(
js
,
result
,
"done"
,
js_false
);
js_set
(
js
,
result
,
"value"
,
value
);
return
result
;
}
static
ant_value_t
get_array_iterator_prototype
(
ant_t
*
js
)
{
if
(
vtype
(
js
->
sym
.
array_iterator_proto
)
==
T_OBJ
)
return
js
->
sym
.
array_iterator_proto
;
ant_value_t
iterator_proto
=
get_iterator_prototype
(
js
);
js
->
sym
.
array_iterator_proto
=
js_mkobj
(
js
);
js_set
(
js
,
js
->
sym
.
array_iterator_proto
,
"next"
,
js_mkfun
(
arr_iter_next
));
js_set_proto_init
(
js
->
sym
.
array_iterator_proto
,
iterator_proto
);
return
js
->
sym
.
array_iterator_proto
;
}
ant_value_t
make_array_iterator
(
ant_t
*
js
,
ant_value_t
array
,
int
kind
)
{
ant_value_t
iter
=
js_mkobj
(
js
);
js_set_slot_wb
(
js
,
iter
,
SLOT_DATA
,
array
);
js_set_slot
(
iter
,
SLOT_ITER_STATE
,
js_mknum
((
double
)
ARR_ITER_PACK
(
kind
,
0
)));
js_set_proto_init
(
iter
,
get_array_iterator_prototype
(
js
));
return
iter
;
}
static
ant_value_t
str_iter_next
(
ant_t
*
js
,
ant_value_t
*
args
,
int
nargs
)
{
ant_value_t
iter
=
js
->
this_val
;
ant_value_t
str
=
js_get_slot
(
iter
,
SLOT_DATA
);
ant_value_t
idx_v
=
js_get_slot
(
iter
,
SLOT_ITER_STATE
);
int
idx
=
(
vtype
(
idx_v
)
==
T_NUM
)
?
(
int
)
js_getnum
(
idx_v
)
:
0
;
size_t
slen
;
char
*
s
=
js_getstr
(
js
,
str
,
&
slen
);
ant_value_t
result
=
js_mkobj
(
js
);
if
(
idx
>=
(
int
)
slen
)
{
js_set
(
js
,
result
,
"done"
,
js_true
);
js_set
(
js
,
result
,
"value"
,
js_mkundef
());
return
result
;
}
unsigned
char
c
=
(
unsigned
char
)
s
[
idx
];
int
char_bytes
=
utf8_sequence_length
(
c
);
if
(
char_bytes
<
1
)
char_bytes
=
1
;
if
(
idx
+
char_bytes
>
(
int
)
slen
)
char_bytes
=
(
int
)
slen
-
idx
;
js_set
(
js
,
result
,
"value"
,
js_mkstr
(
js
,
s
+
idx
,
(
ant_offset_t
)
char_bytes
));
js_set
(
js
,
result
,
"done"
,
js_false
);
js_set_slot
(
iter
,
SLOT_ITER_STATE
,
js_mknum
(
idx
+
char_bytes
));
return
result
;
}
static
ant_value_t
get_string_iterator_prototype
(
ant_t
*
js
)
{
if
(
vtype
(
js
->
sym
.
string_iterator_proto
)
==
T_OBJ
)
return
js
->
sym
.
string_iterator_proto
;
ant_value_t
iterator_proto
=
get_iterator_prototype
(
js
);
js
->
sym
.
string_iterator_proto
=
js_mkobj
(
js
);
js_set
(
js
,
js
->
sym
.
string_iterator_proto
,
"next"
,
js_mkfun
(
str_iter_next
));
js_set_proto_init
(
js
->
sym
.
string_iterator_proto
,
iterator_proto
);
return
js
->
sym
.
string_iterator_proto
;
}
static
ant_value_t
string_iterator
(
ant_t
*
js
,
ant_value_t
*
args
,
int
nargs
)
{
ant_value_t
iter
=
js_mkobj
(
js
);
js_set_slot_wb
(
js
,
iter
,
SLOT_DATA
,
js
->
this_val
);
js_set_slot
(
iter
,
SLOT_ITER_STATE
,
js_mknum
(
0
));
js_set_proto_init
(
iter
,
get_string_iterator_prototype
(
js
));
return
iter
;
}
ant_value_t
maybe_call_symbol_method
(
ant_t
*
js
,
ant_value_t
target
,
ant_value_t
sym
,
ant_value_t
this_arg
,
ant_value_t
*
args
,
int
nargs
,
bool
*
called
)
{
*
called
=
false
;
if
(
vtype
(
sym
)
!=
T_SYMBOL
||
!
is_object_type
(
target
))
return
js_mkundef
();
ant_value_t
method
=
js_get_sym
(
js
,
target
,
sym
);
if
(
is_err
(
method
))
return
method
;
uint8_t
mt
=
vtype
(
method
);
if
(
mt
==
T_UNDEF
||
mt
==
T_NULL
)
return
js_mkundef
();
if
(
mt
!=
T_FUNC
&&
mt
!=
T_CFUNC
)
{
return
js_mkerr_typed
(
js
,
JS_ERR_TYPE
,
"Symbol method is not callable"
);
}
*
called
=
true
;
return
sv_vm_call
(
js
->
vm
,
js
,
method
,
this_arg
,
args
,
nargs
,
NULL
,
false
);
}
void
js_define_species_getter
(
ant_t
*
js
,
ant_value_t
ctor
)
{
if
(
!
is_object_type
(
ctor
)
||
vtype
(
g_species
)
!=
T_SYMBOL
)
return
;
ctor
=
js_as_obj
(
ctor
);
js_set_sym_getter_desc
(
js
,
ctor
,
g_species
,
js_mkfun
(
sym_this_cb
),
JS_DESC_C
);
}
void
init_symbol_module
(
void
)
{
ant_t
*
js
=
rt
->
js
;
js
->
sym
.
iterator_proto
=
js_mkundef
();
js
->
sym
.
array_iterator_proto
=
js_mkundef
();
js
->
sym
.
string_iterator_proto
=
js_mkundef
();
gc_register_root
(
&
js
->
sym
.
iterator_proto
);
gc_register_root
(
&
js
->
sym
.
array_iterator_proto
);
gc_register_root
(
&
js
->
sym
.
string_iterator_proto
);
#define INIT_SYM(name, desc) g_##name = js_mksym_well_known(js, desc);
WELLKNOWN_SYMBOLS
(
INIT_SYM
)
#undef INIT_SYM
ant_value_t
symbol_proto
=
js_mkobj
(
js
);
js_set
(
js
,
symbol_proto
,
"toString"
,
js_mkfun
(
builtin_Symbol_toString
));
ant_value_t
symbol_ctor
=
js_mkobj
(
js
);
js_set_slot
(
symbol_ctor
,
SLOT_CFUNC
,
js_mkfun
(
builtin_Symbol
));
js_setprop
(
js
,
symbol_ctor
,
js_mkstr
(
js
,
"for"
,
3
),
js_mkfun
(
builtin_Symbol_for
));
js_set
(
js
,
symbol_ctor
,
"keyFor"
,
js_mkfun
(
builtin_Symbol_keyFor
));
js_set
(
js
,
symbol_ctor
,
"prototype"
,
symbol_proto
);
#define SET_CTOR_SYM(name, _desc) js_set(js, symbol_ctor, #name, g_##name);
WELLKNOWN_SYMBOLS
(
SET_CTOR_SYM
)
#undef SET_CTOR_SYM
ant_value_t
func_symbol
=
js_obj_to_func
(
symbol_ctor
);
js_set
(
js
,
js_glob
(
js
),
"Symbol"
,
func_symbol
);
// set internal types before ant module snapshot
ant_value_t
array_ctor
=
js_get
(
js
,
js_glob
(
js
),
"Array"
);
ant_value_t
array_proto
=
js_get
(
js
,
array_ctor
,
"prototype"
);
(
void
)
get_array_iterator_prototype
(
js
);
(
void
)
get_string_iterator_prototype
(
js
);
js_set_sym
(
js
,
rt
->
ant_obj
,
g_toStringTag
,
js_mkstr
(
js
,
"Ant"
,
3
));
js_set_sym
(
js
,
array_proto
,
g_iterator
,
js_get
(
js
,
array_proto
,
"values"
));
ant_value_t
array_unscopables
=
js_mkobj
(
js
);
js_set
(
js
,
array_unscopables
,
"find"
,
js_true
);
js_set
(
js
,
array_unscopables
,
"findIndex"
,
js_true
);
js_set
(
js
,
array_unscopables
,
"fill"
,
js_true
);
js_set
(
js
,
array_unscopables
,
"copyWithin"
,
js_true
);
js_set
(
js
,
array_unscopables
,
"entries"
,
js_true
);
js_set
(
js
,
array_unscopables
,
"keys"
,
js_true
);
js_set
(
js
,
array_unscopables
,
"values"
,
js_true
);
js_set
(
js
,
array_unscopables
,
"flat"
,
js_true
);
js_set
(
js
,
array_unscopables
,
"flatMap"
,
js_true
);
js_set_sym
(
js
,
array_proto
,
g_unscopables
,
array_unscopables
);
ant_value_t
string_ctor
=
js_get
(
js
,
js_glob
(
js
),
"String"
);
ant_value_t
string_proto
=
js_get
(
js
,
string_ctor
,
"prototype"
);
js_set_sym
(
js
,
string_proto
,
g_iterator
,
js_mkfun
(
string_iterator
));
ant_value_t
promise_ctor
=
js_get
(
js
,
js_glob
(
js
),
"Promise"
);
ant_value_t
promise_proto
=
js_get
(
js
,
promise_ctor
,
"prototype"
);
js_set_sym
(
js
,
promise_proto
,
g_toStringTag
,
js_mkstr
(
js
,
"Promise"
,
7
));
js_define_species_getter
(
js
,
promise_ctor
);
js_define_species_getter
(
js
,
array_ctor
);
}
void
gc_mark_symbols
(
ant_t
*
js
,
gc_mark_fn
mark
)
{
mark
(
js
,
js
->
sym
.
iterator_proto
);
mark
(
js
,
js
->
sym
.
array_iterator_proto
);
mark
(
js
,
js
->
sym
.
string_iterator_proto
);
#define GC_SYM(name, _desc) mark(js, g_##name);
WELLKNOWN_SYMBOLS
(
GC_SYM
)
#undef GC_SYM
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sat, Aug 1, 2:09 PM (1 d, 1 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
603517
Default Alt Text
symbol.c (9 KB)
Attached To
Mode
rANT Ant
Attached
Detach File
Event Timeline
Log In to Comment