Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F4468536
coercion.h
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
coercion.h
View Options
#ifndef SV_COERCION_H
#define SV_COERCION_H
#include
"silver/engine.h"
#include
"esm/loader.h"
#include
<string.h>
#include
"globals.h"
#include
"property.h"
static
inline
ant_value_t
sv_module_export_cstr
(
ant_t
*
js
,
const
char
*
name
,
size_t
len
,
ant_value_t
value
)
{
ant_value_t
module_ns
=
js_module_eval_active_ns
(
js
);
if
(
vtype
(
module_ns
)
!=
T_OBJ
)
return
js_mkerr_typed
(
js
,
JS_ERR_SYNTAX
,
"export used outside module"
);
ant_value_t
set_res
=
setprop_cstr
(
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_wb
(
js
,
module_ns
,
SLOT_DEFAULT
,
value
);
return
tov
(
0
);
}
static
inline
ant_value_t
sv_op_to_object
(
sv_vm_t
*
vm
,
ant_t
*
js
)
{
ant_value_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"
);
ant_value_t
obj
=
mkobj
(
js
,
0
);
ant_value_t
obj_as_obj
=
js_as_obj
(
obj
);
js_set_slot
(
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
)
{
ant_value_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
)
{
ant_value_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
)
{
ant_value_t
v
=
vm
->
stack
[
vm
->
sp
-
1
];
vm
->
stack
[
vm
->
sp
-
1
]
=
mkval
(
T_BOOL
,
vtype
(
v
)
==
T_NULL
);
}
static
inline
ant_value_t
sv_op_import
(
sv_vm_t
*
vm
,
ant_t
*
js
)
{
ant_value_t
specifier
=
vm
->
stack
[
--
vm
->
sp
];
ant_value_t
import_fn
=
js_get_module_import_binding
(
js
);
if
(
vtype
(
import_fn
)
!=
T_FUNC
&&
vtype
(
import_fn
)
!=
T_CFUNC
)
import_fn
=
js_getprop_fallback
(
js
,
js
->
global
,
"import"
);
if
(
vtype
(
import_fn
)
==
T_FUNC
||
vtype
(
import_fn
)
==
T_CFUNC
)
{
ant_value_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
ant_value_t
sv_op_import_sync
(
sv_vm_t
*
vm
,
ant_t
*
js
)
{
ant_value_t
specifier
=
vm
->
stack
[
--
vm
->
sp
];
ant_value_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
)
{
ant_value_t
ns
=
vm
->
stack
[
vm
->
sp
-
1
];
if
(
vtype
(
ns
)
==
T_OBJ
)
{
ant_value_t
slot_val
=
js_get_slot
(
ns
,
SLOT_DEFAULT
);
if
(
vtype
(
slot_val
)
!=
T_UNDEF
)
{
vm
->
stack
[
vm
->
sp
-
1
]
=
slot_val
;
return
;
}
}
}
static
inline
bool
sv_module_namespace_has_export
(
ant_t
*
js
,
ant_value_t
ns
,
const
char
*
name
,
size_t
len
)
{
if
(
!
is_object_type
(
ns
))
return
false
;
ant_value_t
as_obj
=
js_as_obj
(
ns
);
if
(
is_proxy
(
as_obj
))
return
false
;
if
(
lkp
(
js
,
as_obj
,
name
,
len
)
!=
0
)
return
true
;
prop_meta_t
meta
;
return
lookup_string_prop_meta
(
js
,
as_obj
,
name
,
len
,
&
meta
);
}
static
inline
const
char
*
sv_module_namespace_display_name
(
ant_t
*
js
,
ant_value_t
ns
)
{
if
(
!
is_object_type
(
ns
))
return
NULL
;
ant_value_t
module_ctx
=
js_get_slot
(
ns
,
SLOT_MODULE_CTX
);
if
(
!
is_object_type
(
module_ctx
))
return
NULL
;
ant_value_t
display_name
=
js_get
(
js
,
module_ctx
,
"displayName"
);
if
(
vtype
(
display_name
)
==
T_STR
)
return
js_getstr
(
js
,
display_name
,
NULL
);
ant_value_t
filename
=
js_get
(
js
,
module_ctx
,
"filename"
);
if
(
vtype
(
filename
)
!=
T_STR
)
return
NULL
;
return
js_getstr
(
js
,
filename
,
NULL
);
}
static
inline
ant_value_t
sv_missing_named_export_error
(
ant_t
*
js
,
ant_value_t
ns
,
const
char
*
name
,
size_t
len
)
{
const
char
*
display_name
=
sv_module_namespace_display_name
(
js
,
ns
);
if
(
!
display_name
)
display_name
=
"<unknown>"
;
return
js_mkerr_typed
(
js
,
JS_ERR_SYNTAX
,
"The requested module '%s' does not provide an export named '%.*s'"
,
display_name
,
(
int
)
len
,
name
);
}
static
inline
ant_value_t
sv_op_import_named
(
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 import atom index"
);
ant_value_t
ns
=
vm
->
stack
[
vm
->
sp
-
1
];
sv_atom_t
*
a
=
&
func
->
atoms
[
atom_idx
];
if
(
!
sv_module_namespace_has_export
(
js
,
ns
,
a
->
str
,
a
->
len
)
&&
js_get_slot
(
ns
,
SLOT_MODULE_LOADING
)
!=
js_true
)
return
sv_missing_named_export_error
(
js
,
ns
,
a
->
str
,
a
->
len
);
ant_value_t
value
=
js_get
(
js
,
ns
,
a
->
str
);
if
(
is_err
(
value
))
return
value
;
vm
->
stack
[
vm
->
sp
-
1
]
=
value
;
return
tov
(
0
);
}
static
inline
ant_value_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"
);
ant_value_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
ant_value_t
sv_op_export_all
(
sv_vm_t
*
vm
,
ant_t
*
js
)
{
ant_value_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
;
ant_value_t
value
=
js_mkundef
();
while
(
js_prop_iter_next
(
&
iter
,
&
key
,
&
key_len
,
&
value
))
{
ant_value_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
ant_value_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
ant_value_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
,
ant_value_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
(
js
,
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
bool
sv_try_get_with_bound_value
(
ant_t
*
js
,
ant_value_t
with_obj
,
const
sv_atom_t
*
a
,
ant_value_t
*
out
)
{
ant_object_t
*
ptr
=
is_object_type
(
with_obj
)
?
js_obj_ptr
(
js_as_obj
(
with_obj
))
:
NULL
;
const
char
*
interned
=
intern_string
(
a
->
str
,
a
->
len
);
if
(
ptr
&&
interned
)
{
bool
should_fallback
=
false
;
if
(
sv_try_get_shape_data_prop
(
js
,
ptr
,
interned
,
out
,
&
should_fallback
))
return
true
;
if
(
!
should_fallback
)
return
false
;
}
if
(
lkp
(
js
,
with_obj
,
a
->
str
,
a
->
len
)
==
0
)
return
false
;
*
out
=
sv_getprop_fallback_len
(
js
,
with_obj
,
a
->
str
,
(
ant_offset_t
)
a
->
len
);
return
true
;
}
static
inline
ant_value_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
)
{
ant_value_t
val
=
js_mkundef
();
if
(
sv_try_get_with_bound_value
(
js
,
frame
->
with_obj
,
a
,
&
val
))
{
if
(
is_err
(
val
))
return
val
;
vm
->
stack
[
vm
->
sp
++
]
=
val
;
return
js_mkundef
();
}}
if
(
fb_kind
==
WITH_FB_GLOBAL
)
{
ant_value_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
];
ant_value_t
val
=
vm
->
stack
[
--
vm
->
sp
];
if
(
vtype
(
frame
->
with_obj
)
!=
T_UNDEF
)
{
if
(
lkp
(
js
,
frame
->
with_obj
,
a
->
str
,
a
->
len
)
!=
0
)
{
ant_value_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
)
{
ant_value_t
result
=
js_delete_prop
(
js
,
frame
->
with_obj
,
a
->
str
,
a
->
len
);
vm
->
stack
[
vm
->
sp
++
]
=
result
;
return
;
}
}
ant_value_t
result
=
js_delete_prop
(
js
,
js
->
global
,
a
->
str
,
a
->
len
);
bool
ok
=
!
is_err
(
result
)
&&
js_truthy
(
js
,
result
);
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
==
3
)
{
vm
->
stack
[
vm
->
sp
++
]
=
js_get_module_import_binding
(
js
);
return
;
}
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
;
}
if
(
vtype
(
frame
->
arguments_obj
)
==
T_UNDEF
)
{
int
mapped_count
=
sv_frame_is_strict
(
frame
)
||
!
frame
->
func
?
0
:
frame
->
func
->
param_count
;
if
(
mapped_count
>
frame
->
argc
)
mapped_count
=
frame
->
argc
;
frame
->
arguments_obj
=
js_create_arguments_object
(
js
,
frame
->
callee
,
frame
,
frame
->
argc
,
mapped_count
,
sv_frame_is_strict
(
frame
)
);
}
vm
->
stack
[
vm
->
sp
++
]
=
frame
->
arguments_obj
;
}
#endif
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sat, May 2, 7:42 PM (2 d)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
541499
Default Alt Text
coercion.h (10 KB)
Attached To
Mode
rANT Ant
Attached
Detach File
Event Timeline
Log In to Comment