Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2916337
reflect.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
reflect.c
View Options
#include
<stdlib.h>
#include
<string.h>
#include
"ant.h"
#include
"errors.h"
#include
"runtime.h"
#include
"internal.h"
#include
"silver/engine.h"
#include
"modules/reflect.h"
#include
"modules/symbol.h"
static
jsval_t
reflect_get
(
ant_t
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
2
)
return
js_mkundef
();
jsval_t
target
=
args
[
0
];
jsval_t
key
=
args
[
1
];
int
t
=
vtype
(
target
);
if
(
t
!=
T_OBJ
&&
t
!=
T_FUNC
)
return
js_mkundef
();
if
(
vtype
(
key
)
!=
T_STR
)
return
js_mkundef
();
char
*
key_str
=
js_getstr
(
js
,
key
,
NULL
);
if
(
!
key_str
)
return
js_mkundef
();
return
js_get
(
js
,
target
,
key_str
);
}
static
jsval_t
reflect_set
(
ant_t
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
3
)
return
js_false
;
jsval_t
target
=
args
[
0
];
jsval_t
key
=
args
[
1
];
jsval_t
value
=
args
[
2
];
int
t
=
vtype
(
target
);
if
(
t
!=
T_OBJ
&&
t
!=
T_FUNC
)
return
js_false
;
if
(
vtype
(
key
)
!=
T_STR
)
return
js_false
;
char
*
key_str
=
js_getstr
(
js
,
key
,
NULL
);
if
(
!
key_str
)
return
js_false
;
js_set
(
js
,
target
,
key_str
,
value
);
return
js_true
;
}
static
jsval_t
reflect_has
(
ant_t
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
2
)
return
js_false
;
jsval_t
target
=
args
[
0
];
jsval_t
key
=
args
[
1
];
int
t
=
vtype
(
target
);
if
(
t
!=
T_OBJ
&&
t
!=
T_FUNC
)
return
js_false
;
if
(
vtype
(
key
)
!=
T_STR
)
return
js_false
;
size_t
key_len
;
char
*
key_str
=
js_getstr
(
js
,
key
,
&
key_len
);
if
(
!
key_str
)
return
js_false
;
jsoff_t
off
=
lkp_proto
(
js
,
target
,
key_str
,
key_len
);
return
js_bool
(
off
>
0
);
}
static
jsval_t
reflect_delete_property
(
ant_t
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
2
)
return
js_false
;
jsval_t
target
=
args
[
0
];
jsval_t
key
=
args
[
1
];
int
t
=
vtype
(
target
);
if
(
t
!=
T_OBJ
&&
t
!=
T_FUNC
)
return
js_false
;
if
(
vtype
(
key
)
!=
T_STR
)
return
js_false
;
char
*
key_str
=
js_getstr
(
js
,
key
,
NULL
);
if
(
!
key_str
)
return
js_false
;
bool
deleted
=
js_del
(
js
,
target
,
key_str
);
return
js_bool
(
deleted
);
}
static
jsval_t
reflect_own_keys
(
ant_t
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
)
return
js_mkarr
(
js
);
jsval_t
target
=
args
[
0
];
int
t
=
vtype
(
target
);
if
(
t
!=
T_OBJ
&&
t
!=
T_FUNC
)
{
return
js_mkerr
(
js
,
"Reflect.ownKeys called on non-object"
);
}
jsval_t
keys_arr
=
js_mkarr
(
js
);
ant_iter_t
iter
=
js_prop_iter_begin
(
js
,
target
);
const
char
*
key
;
size_t
key_len
;
jsval_t
value
;
while
(
js_prop_iter_next
(
&
iter
,
&
key
,
&
key_len
,
&
value
))
{
if
(
key_len
>=
9
&&
memcmp
(
key
,
STR_PROTO
,
STR_PROTO_LEN
)
==
0
)
continue
;
if
(
key_len
>=
2
&&
key
[
0
]
==
'_'
&&
key
[
1
]
==
'_'
)
continue
;
js_arr_push
(
js
,
keys_arr
,
js_mkstr
(
js
,
key
,
key_len
));
}
js_prop_iter_end
(
&
iter
);
return
keys_arr
;
}
static
jsval_t
reflect_construct
(
ant_t
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
2
)
{
return
js_mkerr
(
js
,
"Reflect.construct requires at least 2 arguments"
);
}
jsval_t
target
=
args
[
0
];
jsval_t
args_arr
=
args
[
1
];
jsval_t
new_target
=
(
nargs
>=
3
)
?
args
[
2
]
:
target
;
if
(
vtype
(
target
)
!=
T_FUNC
&&
vtype
(
target
)
!=
T_CFUNC
)
{
return
js_mkerr
(
js
,
"Reflect.construct: first argument must be a constructor"
);
}
if
(
vtype
(
new_target
)
!=
T_FUNC
&&
vtype
(
new_target
)
!=
T_CFUNC
)
{
return
js_mkerr
(
js
,
"Reflect.construct: third argument must be a constructor"
);
}
jsval_t
length_val
=
js_get
(
js
,
args_arr
,
"length"
);
int
arg_count
=
0
;
if
(
vtype
(
length_val
)
==
T_NUM
)
{
arg_count
=
(
int
)
js_getnum
(
length_val
);
}
jsval_t
*
call_args
=
NULL
;
if
(
arg_count
>
0
)
{
call_args
=
malloc
(
arg_count
*
sizeof
(
jsval_t
));
if
(
!
call_args
)
return
js_mkerr
(
js
,
"Out of memory"
);
for
(
int
i
=
0
;
i
<
arg_count
;
i
++
)
{
char
idx
[
16
];
snprintf
(
idx
,
sizeof
(
idx
),
"%d"
,
i
);
call_args
[
i
]
=
js_get
(
js
,
args_arr
,
idx
);
}
}
jsval_t
new_obj
=
js_mkobj
(
js
);
jsval_t
proto
=
js_get
(
js
,
new_target
,
"prototype"
);
if
(
vtype
(
proto
)
==
T_OBJ
)
js_set_proto
(
js
,
new_obj
,
proto
);
jsval_t
saved_new_target
=
js
->
new_target
;
js
->
new_target
=
new_target
;
jsval_t
result
=
sv_vm_call
(
js
->
vm
,
js
,
target
,
new_obj
,
call_args
,
arg_count
,
NULL
,
true
);
js
->
new_target
=
saved_new_target
;
if
(
call_args
)
free
(
call_args
);
if
(
is_object_type
(
result
))
return
result
;
return
new_obj
;
}
static
jsval_t
reflect_apply
(
ant_t
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
3
)
{
return
js_mkerr
(
js
,
"Reflect.apply requires 3 arguments"
);
}
jsval_t
target
=
args
[
0
];
jsval_t
this_arg
=
args
[
1
];
jsval_t
args_arr
=
args
[
2
];
if
(
vtype
(
target
)
!=
T_FUNC
&&
vtype
(
target
)
!=
T_CFUNC
)
{
return
js_mkerr
(
js
,
"Reflect.apply: first argument must be a function"
);
}
jsval_t
length_val
=
js_get
(
js
,
args_arr
,
"length"
);
int
arg_count
=
0
;
if
(
vtype
(
length_val
)
==
T_NUM
)
{
arg_count
=
(
int
)
js_getnum
(
length_val
);
}
jsval_t
*
call_args
=
NULL
;
if
(
arg_count
>
0
)
{
call_args
=
malloc
(
arg_count
*
sizeof
(
jsval_t
));
if
(
!
call_args
)
return
js_mkerr
(
js
,
"Out of memory"
);
for
(
int
i
=
0
;
i
<
arg_count
;
i
++
)
{
char
idx
[
16
];
snprintf
(
idx
,
sizeof
(
idx
),
"%d"
,
i
);
call_args
[
i
]
=
js_get
(
js
,
args_arr
,
idx
);
}
}
jsval_t
result
=
sv_vm_call
(
js
->
vm
,
js
,
target
,
this_arg
,
call_args
,
arg_count
,
NULL
,
false
);
if
(
call_args
)
free
(
call_args
);
return
result
;
}
static
jsval_t
reflect_get_own_property_descriptor
(
ant_t
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
2
)
return
js_mkundef
();
jsval_t
target
=
args
[
0
];
jsval_t
key
=
args
[
1
];
int
t
=
vtype
(
target
);
if
(
t
!=
T_OBJ
&&
t
!=
T_FUNC
)
return
js_mkundef
();
if
(
vtype
(
key
)
!=
T_STR
)
return
js_mkundef
();
size_t
key_len
;
char
*
key_str
=
js_getstr
(
js
,
key
,
&
key_len
);
if
(
!
key_str
)
return
js_mkundef
();
jsoff_t
off
=
lkp
(
js
,
target
,
key_str
,
key_len
);
if
(
off
<=
0
)
return
js_mkundef
();
jsval_t
value
=
js_get
(
js
,
target
,
key_str
);
jsval_t
desc
=
js_mkobj
(
js
);
js_set
(
js
,
desc
,
"value"
,
value
);
js_set
(
js
,
desc
,
"writable"
,
js_true
);
js_set
(
js
,
desc
,
"enumerable"
,
js_true
);
js_set
(
js
,
desc
,
"configurable"
,
js_true
);
return
desc
;
}
static
jsval_t
reflect_define_property
(
ant_t
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
3
)
return
js_false
;
jsval_t
target
=
args
[
0
];
jsval_t
key
=
args
[
1
];
jsval_t
descriptor
=
args
[
2
];
int
t
=
vtype
(
target
);
if
(
t
!=
T_OBJ
&&
t
!=
T_FUNC
)
return
js_false
;
if
(
vtype
(
key
)
!=
T_STR
)
return
js_false
;
if
(
!
is_special_object
(
descriptor
))
return
js_false
;
char
*
key_str
=
js_getstr
(
js
,
key
,
NULL
);
if
(
!
key_str
)
return
js_false
;
jsval_t
value
=
js_get
(
js
,
descriptor
,
"value"
);
js_set
(
js
,
target
,
key_str
,
value
);
return
js_true
;
}
static
jsval_t
reflect_get_prototype_of
(
ant_t
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
)
{
return
js_mkerr
(
js
,
"Reflect.getPrototypeOf requires an argument"
);
}
jsval_t
target
=
args
[
0
];
if
(
!
is_object_type
(
target
))
{
return
js_mkerr
(
js
,
"Reflect.getPrototypeOf: argument must be an object"
);
}
return
js_get_proto
(
js
,
target
);
}
static
jsval_t
reflect_set_prototype_of
(
ant_t
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
2
)
return
js_false
;
jsval_t
target
=
args
[
0
];
jsval_t
proto
=
args
[
1
];
int
t
=
vtype
(
target
);
if
(
t
!=
T_OBJ
&&
t
!=
T_FUNC
)
return
js_false
;
int
pt
=
vtype
(
proto
);
if
(
pt
!=
T_OBJ
&&
pt
!=
T_FUNC
&&
pt
!=
T_NULL
)
return
js_false
;
js_set_proto
(
js
,
target
,
proto
);
return
js_true
;
}
static
jsval_t
reflect_is_extensible
(
ant_t
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
)
return
js_false
;
jsval_t
target
=
args
[
0
];
int
t
=
vtype
(
target
);
if
(
t
!=
T_OBJ
&&
t
!=
T_FUNC
)
return
js_false
;
if
(
js_get_slot
(
js
,
target
,
SLOT_EXTENSIBLE
)
==
js_false
)
return
js_false
;
if
(
js_get_slot
(
js
,
target
,
SLOT_FROZEN
)
==
js_true
)
return
js_false
;
if
(
js_get_slot
(
js
,
target
,
SLOT_SEALED
)
==
js_true
)
return
js_false
;
return
js_true
;
}
static
jsval_t
reflect_prevent_extensions
(
ant_t
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
)
return
js_false
;
jsval_t
target
=
args
[
0
];
int
t
=
vtype
(
target
);
if
(
t
!=
T_OBJ
&&
t
!=
T_FUNC
)
return
js_false
;
js_set_slot
(
js
,
target
,
SLOT_EXTENSIBLE
,
js_false
);
return
js_true
;
}
void
init_reflect_module
(
void
)
{
ant_t
*
js
=
rt
->
js
;
jsval_t
reflect_obj
=
js_mkobj
(
js
);
js_set
(
js
,
reflect_obj
,
"get"
,
js_mkfun
(
reflect_get
));
js_set
(
js
,
reflect_obj
,
"set"
,
js_mkfun
(
reflect_set
));
js_set
(
js
,
reflect_obj
,
"has"
,
js_mkfun
(
reflect_has
));
js_set
(
js
,
reflect_obj
,
"deleteProperty"
,
js_mkfun
(
reflect_delete_property
));
js_set
(
js
,
reflect_obj
,
"ownKeys"
,
js_mkfun
(
reflect_own_keys
));
js_set
(
js
,
reflect_obj
,
"construct"
,
js_mkfun
(
reflect_construct
));
js_set
(
js
,
reflect_obj
,
"apply"
,
js_mkfun
(
reflect_apply
));
js_set
(
js
,
reflect_obj
,
"getOwnPropertyDescriptor"
,
js_mkfun
(
reflect_get_own_property_descriptor
));
js_set
(
js
,
reflect_obj
,
"defineProperty"
,
js_mkfun
(
reflect_define_property
));
js_set
(
js
,
reflect_obj
,
"getPrototypeOf"
,
js_mkfun
(
reflect_get_prototype_of
));
js_set
(
js
,
reflect_obj
,
"setPrototypeOf"
,
js_mkfun
(
reflect_set_prototype_of
));
js_set
(
js
,
reflect_obj
,
"isExtensible"
,
js_mkfun
(
reflect_is_extensible
));
js_set
(
js
,
reflect_obj
,
"preventExtensions"
,
js_mkfun
(
reflect_prevent_extensions
));
js_set_sym
(
js
,
reflect_obj
,
get_toStringTag_sym
(),
js_mkstr
(
js
,
"Reflect"
,
7
));
js_set
(
js
,
js_glob
(
js
),
"Reflect"
,
reflect_obj
);
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Thu, Mar 26, 4:46 PM (1 d, 18 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
511735
Default Alt Text
reflect.c (9 KB)
Attached To
Mode
rANT Ant
Attached
Detach File
Event Timeline
Log In to Comment