Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2920939
symbol.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
symbol.c
View Options
#include
<stdlib.h>
#include
<string.h>
#include
<stdio.h>
#include
"ant.h"
#include
"errors.h"
#include
"runtime.h"
#include
"internal.h"
#include
"modules/symbol.h"
typedef
struct
{
jsval_t
sym
;
char
key
[
32
];
}
wellknown_sym_t
;
static
wellknown_sym_t
g_iterator
=
{
0
};
static
wellknown_sym_t
g_asyncIterator
=
{
0
};
static
wellknown_sym_t
g_toStringTag
=
{
0
};
static
wellknown_sym_t
g_hasInstance
=
{
0
};
static
wellknown_sym_t
g_observable
=
{
0
};
static
wellknown_sym_t
g_toPrimitive
=
{
0
};
static
wellknown_sym_t
g_species
=
{
0
};
const
char
*
get_iterator_sym_key
(
void
)
{
return
g_iterator
.
key
;
}
const
char
*
get_asyncIterator_sym_key
(
void
)
{
return
g_asyncIterator
.
key
;
}
const
char
*
get_toStringTag_sym_key
(
void
)
{
return
g_toStringTag
.
key
;
}
const
char
*
get_observable_sym_key
(
void
)
{
return
g_observable
.
key
;
}
const
char
*
get_toPrimitive_sym_key
(
void
)
{
return
g_toPrimitive
.
key
;
}
const
char
*
get_hasInstance_sym_key
(
void
)
{
return
g_hasInstance
.
key
;
}
static
const
struct
{
jsval_t
*
sym
;
const
char
*
name
;
}
sym_table
[]
=
{
{
&
g_iterator
.
sym
,
"Symbol.iterator"
},
{
&
g_asyncIterator
.
sym
,
"Symbol.asyncIterator"
},
{
&
g_toStringTag
.
sym
,
"Symbol.toStringTag"
},
{
&
g_hasInstance
.
sym
,
"Symbol.hasInstance"
},
{
&
g_observable
.
sym
,
"Symbol.observable"
},
{
&
g_toPrimitive
.
sym
,
"Symbol.toPrimitive"
},
{
&
g_species
.
sym
,
"Symbol.species"
},
};
const
char
*
get_symbol_description_from_key
(
const
char
*
sym_key
,
size_t
key_len
)
{
if
(
key_len
<
9
||
memcmp
(
sym_key
,
"__sym_"
,
6
)
!=
0
)
return
NULL
;
uint64_t
id
=
0
;
for
(
const
char
*
p
=
sym_key
+
6
;
*
p
>=
'0'
&&
*
p
<=
'9'
;
p
++
)
id
=
id
*
10
+
(
*
p
-
'0'
);
for
(
size_t
i
=
0
;
i
<
sizeof
(
sym_table
)
/
sizeof
(
sym_table
[
0
]);
i
++
)
{
if
(
js_sym_id
(
*
sym_table
[
i
].
sym
)
==
id
)
return
sym_table
[
i
].
name
;
}
return
"Symbol()"
;
}
static
inline
void
init_symbol
(
struct
js
*
js
,
wellknown_sym_t
*
sym_var
,
const
char
*
name
)
{
sym_var
->
sym
=
js_mksym
(
js
,
name
);
snprintf
(
sym_var
->
key
,
sizeof
(
sym_var
->
key
),
"__sym_%llu__"
,
(
unsigned
long
long
)
js_sym_id
(
sym_var
->
sym
));
}
static
jsval_t
builtin_Symbol
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
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
jsval_t
builtin_Symbol_for
(
struct
js
*
js
,
jsval_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
jsval_t
builtin_Symbol_keyFor
(
struct
js
*
js
,
jsval_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
jsval_t
builtin_Symbol_toString
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
jsval_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
jsval_t
iterator_next
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
jsval_t
this_val
=
js_getthis
(
js
);
jsval_t
arr
=
js_get
(
js
,
this_val
,
"__arr"
);
jsval_t
idx_val
=
js_get
(
js
,
this_val
,
"__idx"
);
jsval_t
len_val
=
js_get
(
js
,
this_val
,
"__len"
);
int
idx
=
(
int
)
js_getnum
(
idx_val
);
int
len
=
(
int
)
js_getnum
(
len_val
);
jsval_t
result
=
js_mkobj
(
js
);
if
(
idx
>=
len
)
{
js_set
(
js
,
result
,
"done"
,
js_true
);
js_set
(
js
,
result
,
"value"
,
js_mkundef
());
}
else
{
char
idxstr
[
16
];
snprintf
(
idxstr
,
sizeof
(
idxstr
),
"%d"
,
idx
);
jsval_t
value
=
js_get
(
js
,
arr
,
idxstr
);
js_set
(
js
,
result
,
"value"
,
value
);
js_set
(
js
,
result
,
"done"
,
js_false
);
js_set
(
js
,
this_val
,
"__idx"
,
js_mknum
(
idx
+
1
));
}
return
result
;
}
static
jsval_t
array_iterator
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
jsval_t
arr
=
js_getthis
(
js
);
jsval_t
len_val
=
js_get
(
js
,
arr
,
"length"
);
int
len
=
vtype
(
len_val
)
==
T_NUM
?
(
int
)
js_getnum
(
len_val
)
:
0
;
jsval_t
iter
=
js_mkobj
(
js
);
js_set
(
js
,
iter
,
"__arr"
,
arr
);
js_set
(
js
,
iter
,
"__idx"
,
js_mknum
(
0
));
js_set
(
js
,
iter
,
"__len"
,
js_mknum
(
len
));
js_set
(
js
,
iter
,
"next"
,
js_mkfun
(
iterator_next
));
return
iter
;
}
static
jsval_t
string_iterator_next
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
jsval_t
this_val
=
js_getthis
(
js
);
jsval_t
str
=
js_get
(
js
,
this_val
,
"__str"
);
jsval_t
idx_val
=
js_get
(
js
,
this_val
,
"__idx"
);
jsval_t
len_val
=
js_get
(
js
,
this_val
,
"__len"
);
int
idx
=
(
int
)
js_getnum
(
idx_val
);
int
len
=
(
int
)
js_getnum
(
len_val
);
jsval_t
result
=
js_mkobj
(
js
);
if
(
idx
>=
len
)
{
js_set
(
js
,
result
,
"done"
,
js_true
);
js_set
(
js
,
result
,
"value"
,
js_mkundef
());
}
else
{
char
*
s
=
js_getstr
(
js
,
str
,
NULL
);
char
ch
[
2
]
=
{
s
[
idx
],
0
};
js_set
(
js
,
result
,
"value"
,
js_mkstr
(
js
,
ch
,
1
));
js_set
(
js
,
result
,
"done"
,
js_false
);
js_set
(
js
,
this_val
,
"__idx"
,
js_mknum
(
idx
+
1
));
}
return
result
;
}
static
jsval_t
string_iterator
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
(
void
)
args
;
(
void
)
nargs
;
jsval_t
str
=
js_getthis
(
js
);
size_t
len
;
js_getstr
(
js
,
str
,
&
len
);
jsval_t
iter
=
js_mkobj
(
js
);
js_set
(
js
,
iter
,
"__str"
,
str
);
js_set
(
js
,
iter
,
"__idx"
,
js_mknum
(
0
));
js_set
(
js
,
iter
,
"__len"
,
js_mknum
((
double
)
len
));
js_set
(
js
,
iter
,
"next"
,
js_mkfun
(
string_iterator_next
));
return
iter
;
}
static
jsval_t
species_getter
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
(
void
)
args
;
(
void
)
nargs
;
return
js_getthis
(
js
);
}
static
jsval_t
date_toPrimitive
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
jsval_t
this_val
=
js_getthis
(
js
);
const
char
*
hint
=
"default"
;
if
(
nargs
>
0
&&
vtype
(
args
[
0
])
==
T_STR
)
{
hint
=
js_getstr
(
js
,
args
[
0
],
NULL
);
}
bool
prefer_string
=
(
hint
==
NULL
||
strcmp
(
hint
,
"number"
)
!=
0
);
const
char
*
methods
[
2
]
=
{
prefer_string
?
"toString"
:
"valueOf"
,
prefer_string
?
"valueOf"
:
"toString"
};
for
(
int
i
=
0
;
i
<
2
;
i
++
)
{
jsval_t
method
=
js_getprop_fallback
(
js
,
this_val
,
methods
[
i
]);
if
(
vtype
(
method
)
==
T_FUNC
||
vtype
(
method
)
==
T_CFUNC
)
{
jsval_t
result
=
js_call_with_this
(
js
,
method
,
this_val
,
NULL
,
0
);
if
(
is_err
(
result
)
||
!
is_object_type
(
result
))
return
result
;
}
}
return
js_mkerr
(
js
,
"Cannot convert object to primitive value"
);
}
void
init_symbol_module
(
void
)
{
struct
js
*
js
=
rt
->
js
;
init_symbol
(
js
,
&
g_iterator
,
"Symbol.iterator"
);
init_symbol
(
js
,
&
g_asyncIterator
,
"Symbol.asyncIterator"
);
init_symbol
(
js
,
&
g_toStringTag
,
"Symbol.toStringTag"
);
init_symbol
(
js
,
&
g_observable
,
"Symbol.observable"
);
init_symbol
(
js
,
&
g_toPrimitive
,
"Symbol.toPrimitive"
);
init_symbol
(
js
,
&
g_hasInstance
,
"Symbol.hasInstance"
);
init_symbol
(
js
,
&
g_species
,
"Symbol.species"
);
jsval_t
symbol_proto
=
js_mkobj
(
js
);
js_set
(
js
,
symbol_proto
,
"toString"
,
js_mkfun
(
builtin_Symbol_toString
));
jsval_t
symbol_ctor
=
js_mkobj
(
js
);
js_set_slot
(
js
,
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
);
js_set
(
js
,
symbol_ctor
,
"iterator"
,
g_iterator
.
sym
);
js_set
(
js
,
symbol_ctor
,
"asyncIterator"
,
g_asyncIterator
.
sym
);
js_set
(
js
,
symbol_ctor
,
"toStringTag"
,
g_toStringTag
.
sym
);
js_set
(
js
,
symbol_ctor
,
"hasInstance"
,
g_hasInstance
.
sym
);
js_set
(
js
,
symbol_ctor
,
"observable"
,
g_observable
.
sym
);
js_set
(
js
,
symbol_ctor
,
"toPrimitive"
,
g_toPrimitive
.
sym
);
js_set
(
js
,
symbol_ctor
,
"species"
,
g_species
.
sym
);
jsval_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
js_set
(
js
,
rt
->
ant_obj
,
get_toStringTag_sym_key
(),
js_mkstr
(
js
,
"Ant"
,
3
));
jsval_t
array_ctor
=
js_get
(
js
,
js_glob
(
js
),
"Array"
);
jsval_t
array_proto
=
js_get
(
js
,
array_ctor
,
"prototype"
);
js_set
(
js
,
array_proto
,
g_iterator
.
key
,
js_mkfun
(
array_iterator
));
jsval_t
string_ctor
=
js_get
(
js
,
js_glob
(
js
),
"String"
);
jsval_t
string_proto
=
js_get
(
js
,
string_ctor
,
"prototype"
);
js_set
(
js
,
string_proto
,
g_iterator
.
key
,
js_mkfun
(
string_iterator
));
jsval_t
date_ctor
=
js_get
(
js
,
js_glob
(
js
),
"Date"
);
jsval_t
date_proto
=
js_get
(
js
,
date_ctor
,
"prototype"
);
js_set
(
js
,
date_proto
,
g_toPrimitive
.
key
,
js_mkfun
(
date_toPrimitive
));
jsval_t
promise_ctor
=
js_get
(
js
,
js_glob
(
js
),
"Promise"
);
jsval_t
promise_proto
=
js_get
(
js
,
promise_ctor
,
"prototype"
);
js_set
(
js
,
promise_proto
,
g_toStringTag
.
key
,
js_mkstr
(
js
,
"Promise"
,
7
));
jsval_t
species_fn
=
js_mkfun
(
species_getter
);
js_set_getter_desc
(
js
,
promise_ctor
,
g_species
.
key
,
strlen
(
g_species
.
key
),
species_fn
,
JS_DESC_C
);
js_set_getter_desc
(
js
,
array_ctor
,
g_species
.
key
,
strlen
(
g_species
.
key
),
species_fn
,
JS_DESC_C
);
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Fri, Mar 27, 7:38 AM (2 d)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
512715
Default Alt Text
symbol.c (8 KB)
Attached To
Mode
rANT Ant
Attached
Detach File
Event Timeline
Log In to Comment