Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2916371
coercion.h
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
coercion.h
View Options
#ifndef SV_COERCION_H
#define SV_COERCION_H
#include
"silver/engine.h"
#include
"modules/symbol.h"
#include
"esm/loader.h"
#include
<string.h>
#include
"globals.h"
#include
"property.h"
static
inline
jsval_t
sv_module_export_cstr
(
ant_t
*
js
,
const
char
*
name
,
size_t
len
,
jsval_t
value
)
{
if
(
vtype
(
js
->
module_ns
)
!=
T_OBJ
)
return
js_mkerr_typed
(
js
,
JS_ERR_SYNTAX
,
"export used outside module"
);
jsval_t
set_res
=
setprop_cstr
(
js
,
js
->
module_ns
,
name
,
len
,
value
);
if
(
is_err
(
set_res
))
return
set_res
;
if
(
len
==
7
&&
memcmp
(
name
,
"default"
,
7
)
==
0
)
js_set_slot
(
js
,
js
->
module_ns
,
SLOT_DEFAULT
,
value
);
return
tov
(
0
);
}
static
inline
jsval_t
sv_op_to_object
(
sv_vm_t
*
vm
,
ant_t
*
js
)
{
jsval_t
v
=
vm
->
stack
[
vm
->
sp
-
1
];
uint8_t
t
=
vtype
(
v
);
if
(
t
==
T_OBJ
||
t
==
T_ARR
||
t
==
T_FUNC
)
return
tov
(
0
);
if
(
t
==
T_NULL
||
t
==
T_UNDEF
)
return
js_mkerr_typed
(
js
,
JS_ERR_TYPE
,
"Cannot convert undefined or null to object"
);
jsval_t
obj
=
mkobj
(
js
,
0
);
jsval_t
obj_as_obj
=
js_as_obj
(
obj
);
js_set_slot
(
js
,
obj_as_obj
,
SLOT_PRIMITIVE
,
v
);
vm
->
stack
[
vm
->
sp
-
1
]
=
obj
;
return
tov
(
0
);
}
static
inline
void
sv_op_to_propkey
(
sv_vm_t
*
vm
,
ant_t
*
js
)
{
jsval_t
v
=
vm
->
stack
[
vm
->
sp
-
1
];
if
(
vtype
(
v
)
!=
T_STR
&&
vtype
(
v
)
!=
T_SYMBOL
)
vm
->
stack
[
vm
->
sp
-
1
]
=
coerce_to_str
(
js
,
v
);
}
static
inline
void
sv_op_is_undef
(
sv_vm_t
*
vm
)
{
jsval_t
v
=
vm
->
stack
[
vm
->
sp
-
1
];
vm
->
stack
[
vm
->
sp
-
1
]
=
mkval
(
T_BOOL
,
vtype
(
v
)
==
T_UNDEF
);
}
static
inline
void
sv_op_is_null
(
sv_vm_t
*
vm
)
{
jsval_t
v
=
vm
->
stack
[
vm
->
sp
-
1
];
vm
->
stack
[
vm
->
sp
-
1
]
=
mkval
(
T_BOOL
,
vtype
(
v
)
==
T_NULL
);
}
static
inline
jsval_t
sv_op_import
(
sv_vm_t
*
vm
,
ant_t
*
js
)
{
jsval_t
specifier
=
vm
->
stack
[
--
vm
->
sp
];
jsval_t
import_fn
=
js_getprop_fallback
(
js
,
js
->
global
,
"import"
);
if
(
vtype
(
import_fn
)
==
T_FUNC
||
vtype
(
import_fn
)
==
T_CFUNC
)
{
jsval_t
result
=
sv_vm_call
(
vm
,
js
,
import_fn
,
js
->
global
,
&
specifier
,
1
,
NULL
,
false
);
if
(
!
is_err
(
result
))
vm
->
stack
[
vm
->
sp
++
]
=
result
;
return
result
;
}
vm
->
stack
[
vm
->
sp
++
]
=
mkval
(
T_UNDEF
,
0
);
return
tov
(
0
);
}
static
inline
jsval_t
sv_op_import_sync
(
sv_vm_t
*
vm
,
ant_t
*
js
)
{
jsval_t
specifier
=
vm
->
stack
[
--
vm
->
sp
];
jsval_t
result
=
js_esm_import_sync
(
js
,
specifier
);
if
(
!
is_err
(
result
))
vm
->
stack
[
vm
->
sp
++
]
=
result
;
return
result
;
}
static
inline
void
sv_op_import_default
(
sv_vm_t
*
vm
,
ant_t
*
js
)
{
jsval_t
ns
=
vm
->
stack
[
vm
->
sp
-
1
];
if
(
vtype
(
ns
)
==
T_OBJ
)
{
jsval_t
slot_val
=
js_get_slot
(
js
,
ns
,
SLOT_DEFAULT
);
if
(
vtype
(
slot_val
)
!=
T_UNDEF
)
{
vm
->
stack
[
vm
->
sp
-
1
]
=
slot_val
;
return
;
}
}
}
static
inline
jsval_t
sv_op_export
(
sv_vm_t
*
vm
,
ant_t
*
js
,
sv_func_t
*
func
,
uint8_t
*
ip
)
{
uint32_t
atom_idx
=
sv_get_u32
(
ip
+
1
);
if
(
atom_idx
>=
(
uint32_t
)
func
->
atom_count
)
return
js_mkerr
(
js
,
"invalid export atom index"
);
jsval_t
value
=
vm
->
stack
[
--
vm
->
sp
];
sv_atom_t
*
a
=
&
func
->
atoms
[
atom_idx
];
return
sv_module_export_cstr
(
js
,
a
->
str
,
a
->
len
,
value
);
}
static
inline
jsval_t
sv_op_export_all
(
sv_vm_t
*
vm
,
ant_t
*
js
)
{
jsval_t
ns
=
vm
->
stack
[
--
vm
->
sp
];
if
(
vtype
(
ns
)
!=
T_OBJ
)
return
js_mkerr_typed
(
js
,
JS_ERR_SYNTAX
,
"Cannot re-export from non-object module"
);
ant_iter_t
iter
=
js_prop_iter_begin
(
js
,
ns
);
const
char
*
key
=
NULL
;
size_t
key_len
=
0
;
jsval_t
value
=
js_mkundef
();
while
(
js_prop_iter_next
(
&
iter
,
&
key
,
&
key_len
,
&
value
))
{
jsval_t
export_res
=
sv_module_export_cstr
(
js
,
key
,
key_len
,
value
);
if
(
is_err
(
export_res
))
{
js_prop_iter_end
(
&
iter
);
return
export_res
;
}
}
js_prop_iter_end
(
&
iter
);
return
tov
(
0
);
}
static
inline
jsval_t
sv_op_enter_with
(
sv_vm_t
*
vm
,
ant_t
*
js
,
sv_frame_t
*
frame
)
{
if
(
sv_frame_is_strict
(
frame
))
return
js_mkerr_typed
(
js
,
JS_ERR_SYNTAX
,
"with statement not allowed in strict mode"
);
frame
->
with_obj
=
vm
->
stack
[
--
vm
->
sp
];
return
js_mkundef
();
}
static
inline
void
sv_op_exit_with
(
sv_vm_t
*
vm
,
sv_frame_t
*
frame
)
{
frame
->
with_obj
=
js_mkundef
();
}
enum
{
WITH_FB_GLOBAL
=
0
,
WITH_FB_LOCAL
=
1
,
WITH_FB_ARG
=
2
,
WITH_FB_UPVAL
=
3
};
static
inline
jsval_t
sv_with_fallback_get
(
sv_vm_t
*
vm
,
ant_t
*
js
,
sv_frame_t
*
frame
,
uint8_t
kind
,
uint16_t
idx
)
{
switch
(
kind
)
{
case
WITH_FB_LOCAL
:
return
frame
->
lp
?
frame
->
lp
[
idx
]
:
js_mkundef
();
case
WITH_FB_ARG
:
return
sv_frame_get_arg_value
(
frame
,
idx
);
case
WITH_FB_UPVAL
:
{
if
(
!
frame
->
upvalues
||
(
int
)
idx
>=
frame
->
upvalue_count
)
return
js_mkundef
();
sv_upvalue_t
*
uv
=
frame
->
upvalues
[
idx
];
return
uv
?
*
uv
->
location
:
js_mkundef
();
}
default
:
return
sv_global_get
(
js
,
NULL
,
0
);
}}
static
inline
void
sv_with_fallback_put
(
sv_vm_t
*
vm
,
ant_t
*
js
,
sv_frame_t
*
frame
,
uint8_t
kind
,
uint16_t
idx
,
jsval_t
val
)
{
switch
(
kind
)
{
case
WITH_FB_LOCAL
:
if
(
frame
->
lp
)
frame
->
lp
[
idx
]
=
val
;
break
;
case
WITH_FB_ARG
:
sv_frame_set_arg_value
(
frame
,
idx
,
val
);
break
;
case
WITH_FB_UPVAL
:
if
(
frame
->
upvalues
&&
(
int
)
idx
<
frame
->
upvalue_count
)
{
sv_upvalue_t
*
uv
=
frame
->
upvalues
[
idx
];
if
(
uv
)
*
uv
->
location
=
val
;
}
break
;
default
:
break
;
}
}
static
inline
jsval_t
sv_op_with_get_var
(
sv_vm_t
*
vm
,
ant_t
*
js
,
sv_frame_t
*
frame
,
sv_func_t
*
func
,
uint8_t
*
ip
)
{
uint32_t
atom_idx
=
sv_get_u32
(
ip
+
1
);
uint8_t
fb_kind
=
sv_get_u8
(
ip
+
5
);
uint16_t
fb_idx
=
sv_get_u16
(
ip
+
6
);
sv_atom_t
*
a
=
&
func
->
atoms
[
atom_idx
];
if
(
vtype
(
frame
->
with_obj
)
!=
T_UNDEF
)
{
if
(
lkp
(
js
,
frame
->
with_obj
,
a
->
str
,
a
->
len
)
!=
0
)
{
jsval_t
val
=
sv_getprop_fallback_len
(
js
,
frame
->
with_obj
,
a
->
str
,
(
jsoff_t
)
a
->
len
);
if
(
is_err
(
val
))
return
val
;
vm
->
stack
[
vm
->
sp
++
]
=
val
;
return
js_mkundef
();
}
}
if
(
fb_kind
==
WITH_FB_GLOBAL
)
{
jsval_t
val
=
sv_global_get
(
js
,
a
->
str
,
a
->
len
);
if
(
is_undefined
(
val
))
return
js_mkerr_typed
(
js
,
JS_ERR_REFERENCE
,
"'%.*s' is not defined"
,
(
int
)
a
->
len
,
a
->
str
);
vm
->
stack
[
vm
->
sp
++
]
=
val
;
}
else
vm
->
stack
[
vm
->
sp
++
]
=
sv_with_fallback_get
(
vm
,
js
,
frame
,
fb_kind
,
fb_idx
);
return
js_mkundef
();
}
static
inline
void
sv_op_with_put_var
(
sv_vm_t
*
vm
,
ant_t
*
js
,
sv_frame_t
*
frame
,
sv_func_t
*
func
,
uint8_t
*
ip
)
{
uint32_t
atom_idx
=
sv_get_u32
(
ip
+
1
);
uint8_t
fb_kind
=
sv_get_u8
(
ip
+
5
);
uint16_t
fb_idx
=
sv_get_u16
(
ip
+
6
);
sv_atom_t
*
a
=
&
func
->
atoms
[
atom_idx
];
jsval_t
val
=
vm
->
stack
[
--
vm
->
sp
];
if
(
vtype
(
frame
->
with_obj
)
!=
T_UNDEF
)
{
if
(
lkp
(
js
,
frame
->
with_obj
,
a
->
str
,
a
->
len
)
!=
0
)
{
jsval_t
key
=
js_mkstr
(
js
,
a
->
str
,
a
->
len
);
js_setprop
(
js
,
frame
->
with_obj
,
key
,
val
);
return
;
}
}
if
(
fb_kind
==
WITH_FB_GLOBAL
)
{
setprop_interned
(
js
,
js
->
global
,
a
->
str
,
a
->
len
,
val
);
}
else
sv_with_fallback_put
(
vm
,
js
,
frame
,
fb_kind
,
fb_idx
,
val
);
}
static
inline
void
sv_op_with_del_var
(
sv_vm_t
*
vm
,
ant_t
*
js
,
sv_frame_t
*
frame
,
sv_func_t
*
func
,
uint8_t
*
ip
)
{
uint32_t
atom_idx
=
sv_get_u32
(
ip
+
1
);
sv_atom_t
*
a
=
&
func
->
atoms
[
atom_idx
];
if
(
vtype
(
frame
->
with_obj
)
!=
T_UNDEF
)
{
if
(
lkp
(
js
,
frame
->
with_obj
,
a
->
str
,
a
->
len
)
!=
0
)
{
jsval_t
result
=
js_delete_prop
(
js
,
frame
->
with_obj
,
a
->
str
,
a
->
len
);
vm
->
stack
[
vm
->
sp
++
]
=
result
;
return
;
}
}
char
tmp
[
256
];
bool
ok
=
js_del
(
js
,
js
->
global
,
sv_atom_cstr
(
a
,
tmp
,
sizeof
(
tmp
)));
vm
->
stack
[
vm
->
sp
++
]
=
mkval
(
T_BOOL
,
ok
);
}
static
inline
void
sv_op_special_obj
(
sv_vm_t
*
vm
,
ant_t
*
js
,
sv_frame_t
*
frame
,
uint8_t
*
ip
)
{
uint8_t
which
=
sv_get_u8
(
ip
+
1
);
if
(
which
==
1
)
{
vm
->
stack
[
vm
->
sp
++
]
=
frame
?
frame
->
new_target
:
js_mkundef
();
return
;
}
if
(
which
==
2
)
{
vm
->
stack
[
vm
->
sp
++
]
=
frame
?
frame
->
super_val
:
js_mkundef
();
return
;
}
if
(
which
!=
0
||
!
frame
)
{
vm
->
stack
[
vm
->
sp
++
]
=
js_mkundef
();
return
;
}
jsval_t
arr
=
js_mkarr
(
js
);
jshdl_t
h
=
js_root
(
js
,
arr
);
if
(
frame
->
bp
&&
frame
->
argc
>
0
)
{
for
(
int
i
=
0
;
i
<
frame
->
argc
;
i
++
)
js_arr_push
(
js
,
js_deref
(
js
,
h
),
frame
->
bp
[
i
]);
}
if
(
sv_frame_is_strict
(
frame
))
js_set_slot
(
js
,
js_deref
(
js
,
h
),
SLOT_STRICT_ARGS
,
tov
(
1
));
else
if
(
vtype
(
frame
->
callee
)
==
T_FUNC
)
setprop_cstr
(
js
,
js_deref
(
js
,
h
),
"callee"
,
6
,
frame
->
callee
);
js_set_sym
(
js
,
js_deref
(
js
,
h
),
get_toStringTag_sym
(),
js_mkstr
(
js
,
"Arguments"
,
9
));
jsval_t
array_proto
=
js_get_ctor_proto
(
js
,
"Array"
,
5
);
if
(
is_object_type
(
array_proto
))
{
jsval_t
iter_fn
=
js_get_sym
(
js
,
array_proto
,
get_iterator_sym
());
if
(
vtype
(
iter_fn
)
==
T_FUNC
||
vtype
(
iter_fn
)
==
T_CFUNC
)
js_set_sym
(
js
,
js_deref
(
js
,
h
),
get_iterator_sym
(),
iter_fn
);
}
vm
->
stack
[
vm
->
sp
++
]
=
js_deref
(
js
,
h
);
js_unroot
(
js
,
h
);
}
#endif
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Thu, Mar 26, 4:48 PM (2 d)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
511907
Default Alt Text
coercion.h (8 KB)
Attached To
Mode
rANT Ant
Attached
Detach File
Event Timeline
Log In to Comment