Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F4497621
glue.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
17 KB
Referenced Files
None
Subscribers
None
glue.c
View Options
#ifdef ANT_JIT
#include
<math.h>
#include
"silver/glue.h"
#include
"utf8.h"
#include
"internal.h"
#include
"errors.h"
#include
"ops/globals.h"
#include
"ops/property.h"
#include
"ops/upvalues.h"
#include
"ops/comparison.h"
#include
"ops/calls.h"
bool
jit_helper_stack_overflow
(
ant_t
*
js
)
{
volatile
char
marker
;
uintptr_t
curr
=
(
uintptr_t
)
&
marker
;
if
(
js
->
cstk
.
limit
==
0
||
js
->
cstk
.
base
==
NULL
)
return
false
;
uintptr_t
base
=
(
uintptr_t
)
js
->
cstk
.
base
;
size_t
used
=
(
base
>
curr
)
?
(
base
-
curr
)
:
(
curr
-
base
);
return
used
>
js
->
cstk
.
limit
;
}
ant_value_t
jit_helper_stack_overflow_error
(
sv_vm_t
*
vm
,
ant_t
*
js
)
{
return
js_mkerr_typed
(
js
,
JS_ERR_RANGE
|
JS_ERR_NO_STACK
,
"Maximum JIT call stack size exceeded"
);
}
ant_value_t
jit_helper_add
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
)
{
if
(
vtype
(
l
)
==
T_NUM
&&
vtype
(
r
)
==
T_NUM
)
return
tov
(
tod
(
l
)
+
tod
(
r
));
return
SV_JIT_BAILOUT
;
}
ant_value_t
jit_helper_sub
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
)
{
if
(
vtype
(
l
)
==
T_NUM
&&
vtype
(
r
)
==
T_NUM
)
return
tov
(
tod
(
l
)
-
tod
(
r
));
return
SV_JIT_BAILOUT
;
}
ant_value_t
jit_helper_mul
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
)
{
if
(
vtype
(
l
)
==
T_NUM
&&
vtype
(
r
)
==
T_NUM
)
return
tov
(
tod
(
l
)
*
tod
(
r
));
return
SV_JIT_BAILOUT
;
}
ant_value_t
jit_helper_div
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
)
{
if
(
vtype
(
l
)
==
T_NUM
&&
vtype
(
r
)
==
T_NUM
)
return
tov
(
tod
(
l
)
/
tod
(
r
));
return
SV_JIT_BAILOUT
;
}
ant_value_t
jit_helper_mod
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
)
{
if
(
vtype
(
l
)
==
T_NUM
&&
vtype
(
r
)
==
T_NUM
)
return
tov
(
fmod
(
tod
(
l
),
tod
(
r
)));
return
SV_JIT_BAILOUT
;
}
ant_value_t
jit_helper_lt
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
)
{
if
(
vtype
(
l
)
==
T_NUM
&&
vtype
(
r
)
==
T_NUM
)
return
js_bool
(
tod
(
l
)
<
tod
(
r
));
return
SV_JIT_BAILOUT
;
}
ant_value_t
jit_helper_le
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
)
{
if
(
vtype
(
l
)
==
T_NUM
&&
vtype
(
r
)
==
T_NUM
)
return
js_bool
(
tod
(
l
)
<=
tod
(
r
));
return
SV_JIT_BAILOUT
;
}
ant_value_t
jit_helper_call
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
func
,
ant_value_t
this_val
,
ant_value_t
*
args
,
int
argc
)
{
return
sv_vm_call
(
vm
,
js
,
func
,
this_val
,
args
,
argc
,
NULL
,
false
);
}
ant_value_t
jit_helper_apply
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
func
,
ant_value_t
this_val
,
ant_value_t
*
args
,
int
argc
)
{
sv_call_args_t
call
;
sv_call_args_reset
(
&
call
,
args
,
argc
);
ant_value_t
norm
=
sv_apply_normalize_args
(
js
,
&
call
);
if
(
is_err
(
norm
))
return
norm
;
ant_value_t
result
=
sv_vm_call
(
vm
,
js
,
func
,
this_val
,
call
.
args
,
call
.
argc
,
NULL
,
false
);
sv_call_args_release
(
&
call
);
return
result
;
}
ant_value_t
jit_helper_rest
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
*
args
,
int
argc
,
int
start
)
{
ant_value_t
arr
=
js_mkarr
(
js
);
for
(
int
i
=
start
;
i
<
argc
;
i
++
)
js_arr_push
(
js
,
arr
,
args
[
i
]);
return
arr
;
}
ant_value_t
jit_helper_get_global
(
ant_t
*
js
,
const
char
*
str
,
sv_func_t
*
func
,
int32_t
bc_off
)
{
uint8_t
*
ip
=
NULL
;
if
(
func
&&
bc_off
>=
0
&&
bc_off
<
func
->
code_len
)
ip
=
func
->
code
+
bc_off
;
return
sv_global_get_interned_ic
(
js
,
str
,
func
,
ip
);
}
ant_value_t
jit_helper_seq
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
)
{
return
mkval
(
T_BOOL
,
strict_eq_values
(
js
,
l
,
r
));
}
ant_value_t
jit_helper_in
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
)
{
return
do_in
(
js
,
l
,
r
);
}
ant_value_t
jit_helper_eq
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
)
{
return
sv_abstract_eq
(
js
,
l
,
r
);
}
ant_value_t
jit_helper_throw
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
val
)
{
return
js_throw
(
js
,
val
);
}
ant_value_t
jit_helper_ne
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
)
{
ant_value_t
eq
=
sv_abstract_eq
(
js
,
l
,
r
);
return
mkval
(
T_BOOL
,
!
vdata
(
eq
));
}
ant_value_t
jit_helper_sne
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
)
{
return
mkval
(
T_BOOL
,
!
strict_eq_values
(
js
,
l
,
r
));
}
ant_value_t
jit_helper_not
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
v
)
{
return
mkval
(
T_BOOL
,
!
js_truthy
(
js
,
v
));
}
ant_value_t
jit_helper_instanceof
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
,
sv_func_t
*
func
,
int32_t
bc_off
)
{
(
void
)
vm
;
uint8_t
*
ip
=
NULL
;
if
(
func
&&
bc_off
>=
0
&&
bc_off
<
func
->
code_len
)
ip
=
func
->
code
+
bc_off
;
return
sv_instanceof_ic_eval
(
js
,
l
,
r
,
func
,
ip
);
}
ant_value_t
jit_helper_call_is_proto
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
call_this
,
ant_value_t
call_func
,
ant_value_t
arg
,
sv_func_t
*
func
,
int32_t
bc_off
)
{
uint8_t
*
ip
=
NULL
;
if
(
func
&&
bc_off
>=
0
&&
bc_off
<
func
->
code_len
)
ip
=
func
->
code
+
bc_off
;
if
(
vtype
(
call_func
)
==
T_CFUNC
&&
js_as_cfunc
(
call_func
)
==
builtin_object_isPrototypeOf
)
{
return
sv_isproto_ic_eval
(
js
,
call_this
,
arg
,
func
,
ip
);
}
ant_value_t
args
[
1
]
=
{
arg
};
return
sv_vm_call
(
vm
,
js
,
call_func
,
call_this
,
args
,
1
,
NULL
,
false
);
}
// TODO: dont bail out
ant_value_t
jit_helper_typeof
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
v
)
{
return
SV_JIT_BAILOUT
;
}
int64_t
jit_helper_is_truthy
(
ant_t
*
js
,
ant_value_t
v
)
{
return
(
int64_t
)
js_truthy
(
js
,
v
);
}
sv_closure_t
*
jit_helper_get_closure
(
ant_value_t
v
)
{
if
(
vtype
(
v
)
!=
T_FUNC
)
return
NULL
;
return
js_func_closure
(
v
);
}
static
inline
void
jit_set_error_site_from_func
(
ant_t
*
js
,
sv_func_t
*
func
,
int32_t
bc_off
)
{
if
(
!
func
)
return
;
js_set_error_site_from_bc
(
js
,
func
,
(
int
)
bc_off
,
func
->
filename
);
}
ant_value_t
jit_helper_get_field
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
obj
,
const
char
*
str
,
uint32_t
len
,
sv_func_t
*
func
,
int32_t
bc_off
)
{
(
void
)
vm
;
uint8_t
*
ip
=
NULL
;
if
(
func
&&
bc_off
>=
0
&&
bc_off
<
func
->
code_len
)
ip
=
func
->
code
+
bc_off
;
sv_atom_t
atom
=
{
.
str
=
str
,
.
len
=
len
};
ant_value_t
out
=
sv_prop_get_field_ic
(
js
,
obj
,
&
atom
,
func
,
ip
);
if
((
vtype
(
obj
)
==
T_NULL
||
vtype
(
obj
)
==
T_UNDEF
)
&&
is_err
(
out
))
jit_set_error_site_from_func
(
js
,
func
,
bc_off
);
return
out
;
}
ant_value_t
jit_helper_to_propkey
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
v
)
{
if
(
vtype
(
v
)
==
T_STR
||
vtype
(
v
)
==
T_SYMBOL
)
return
v
;
return
coerce_to_str
(
js
,
v
);
}
uint64_t
jit_helper_vtype
(
ant_value_t
v
)
{
return
vtype
(
v
);
}
double
jit_helper_tod
(
ant_value_t
v
)
{
return
tod
(
v
);
}
ant_value_t
jit_helper_tov
(
double
d
)
{
return
tov
(
d
);
}
ant_value_t
jit_helper_mkbool
(
int
b
)
{
return
js_bool
(
b
);
}
ant_value_t
jit_helper_closure
(
sv_vm_t
*
vm
,
ant_t
*
js
,
sv_closure_t
*
parent_closure
,
ant_value_t
this_val
,
ant_value_t
*
args
,
int
argc
,
uint32_t
const_idx
,
ant_value_t
*
locals
,
int
n_locals
)
{
sv_func_t
*
parent_func
=
parent_closure
->
func
;
sv_func_t
*
child
=
(
sv_func_t
*
)(
uintptr_t
)
vdata
(
parent_func
->
constants
[
const_idx
]);
sv_closure_t
*
closure
=
js_closure_alloc
(
js
);
if
(
!
closure
)
return
mkval
(
T_ERR
,
0
);
closure
->
func
=
child
;
closure
->
bound_this
=
child
->
is_arrow
?
this_val
:
js_mkundef
();
closure
->
bound_args
=
js_mkundef
();
closure
->
super_val
=
js_mkundef
();
closure
->
call_flags
=
child
->
is_arrow
?
SV_CALL_IS_ARROW
:
0
;
// TODO: reduce nesting
if
(
child
->
upvalue_count
>
0
)
{
closure
->
upvalues
=
calloc
((
size_t
)
child
->
upvalue_count
,
sizeof
(
sv_upvalue_t
*
));
for
(
int
i
=
0
;
i
<
child
->
upvalue_count
;
i
++
)
{
sv_upval_desc_t
*
desc
=
&
child
->
upval_descs
[
i
];
if
(
desc
->
is_local
)
{
int
idx
=
(
int
)
desc
->
index
;
if
(
idx
<
parent_func
->
param_count
)
{
sv_upvalue_t
*
uv
=
js_upvalue_alloc
();
uv
->
closed
=
(
idx
<
argc
&&
args
)
?
args
[
idx
]
:
js_mkundef
();
uv
->
location
=
&
uv
->
closed
;
closure
->
upvalues
[
i
]
=
uv
;
}
else
{
int
li
=
idx
-
parent_func
->
param_count
;
if
(
li
>=
0
&&
li
<
n_locals
&&
locals
)
{
closure
->
upvalues
[
i
]
=
sv_capture_upvalue
(
vm
,
&
locals
[
li
]);
}
else
{
sv_upvalue_t
*
uv
=
js_upvalue_alloc
();
uv
->
closed
=
js_mkundef
();
uv
->
location
=
&
uv
->
closed
;
closure
->
upvalues
[
i
]
=
uv
;
}
}
}
else
closure
->
upvalues
[
i
]
=
parent_closure
->
upvalues
[
desc
->
index
];
}
}
ant_value_t
func_obj
=
mkobj
(
js
,
0
);
closure
->
func_obj
=
func_obj
;
js_mark_constructor
(
func_obj
,
!
child
->
is_arrow
&&
!
child
->
is_method
);
js_setprop
(
js
,
func_obj
,
js
->
length_str
,
tov
((
double
)
child
->
param_count
));
js_set_descriptor
(
js
,
func_obj
,
"length"
,
6
,
JS_DESC_C
);
ant_value_t
func_val
=
mkval
(
T_FUNC
,
(
uintptr_t
)
closure
);
if
(
!
child
->
is_arrow
&&
!
child
->
is_method
)
sv_setup_function_prototype
(
js
,
func_obj
,
func_val
);
if
(
child
->
is_strict
)
js_set_slot
(
func_obj
,
SLOT_STRICT
,
js_true
);
if
(
child
->
is_async
)
{
js_set_slot
(
func_obj
,
SLOT_ASYNC
,
js_true
);
ant_value_t
async_proto
=
js_get_slot
(
js
->
global
,
SLOT_ASYNC_PROTO
);
if
(
vtype
(
async_proto
)
==
T_FUNC
)
js_set_proto_init
(
func_obj
,
async_proto
);
}
else
{
ant_value_t
func_proto
=
js_get_slot
(
js
->
global
,
SLOT_FUNC_PROTO
);
if
(
vtype
(
func_proto
)
==
T_FUNC
)
js_set_proto_init
(
func_obj
,
func_proto
);
}
return
func_val
;
}
void
jit_helper_close_upval
(
sv_vm_t
*
vm
,
uint16_t
slot_idx
,
ant_value_t
*
locals
,
int
n_locals
)
{
(
void
)
slot_idx
;
// TODO: use value
if
(
!
locals
||
n_locals
<=
0
)
return
;
ant_value_t
*
lo
=
locals
;
ant_value_t
*
hi
=
locals
+
n_locals
;
sv_upvalue_t
**
pp
=
&
vm
->
open_upvalues
;
while
(
*
pp
)
{
sv_upvalue_t
*
uv
=
*
pp
;
if
(
uv
->
location
>=
lo
&&
uv
->
location
<
hi
)
{
uv
->
closed
=
*
uv
->
location
;
uv
->
location
=
&
uv
->
closed
;
*
pp
=
uv
->
next
;
}
else
pp
=
&
uv
->
next
;
}
}
ant_value_t
jit_helper_bailout_resume
(
sv_vm_t
*
vm
,
sv_closure_t
*
closure
,
ant_value_t
this_val
,
ant_value_t
*
args
,
int
argc
,
ant_value_t
*
vstack
,
int64_t
vstack_sp
,
ant_value_t
*
locals
,
int64_t
n_locals
,
int64_t
bc_offset
)
{
if
(
!
closure
||
!
closure
->
func
)
return
mkval
(
T_ERR
,
0
);
sv_func_t
*
fn
=
closure
->
func
;
sv_jit_on_bailout
(
fn
);
vm
->
jit_resume
.
active
=
true
;
vm
->
jit_resume
.
ip_offset
=
(
int
)
bc_offset
;
vm
->
jit_resume
.
locals
=
locals
;
vm
->
jit_resume
.
n_locals
=
n_locals
;
vm
->
jit_resume
.
vstack
=
vstack
;
vm
->
jit_resume
.
vstack_sp
=
vstack_sp
;
return
sv_execute_closure_entry
(
vm
,
closure
,
closure
->
func_obj
,
js_mkundef
(),
this_val
,
args
,
argc
,
NULL
);
}
void
jit_helper_define_field
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
obj
,
ant_value_t
val
,
const
char
*
str
,
uint32_t
len
)
{
(
void
)
vm
;
if
(
!
sv_try_define_field_fast
(
js
,
obj
,
str
,
val
))
js_define_own_prop
(
js
,
obj
,
str
,
len
,
val
);
}
void
jit_helper_set_name
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
fn
,
const
char
*
str
,
uint32_t
len
)
{
ant_value_t
name
=
js_mkstr
(
js
,
str
,
len
);
setprop_cstr
(
js
,
fn
,
"name"
,
4
,
name
);
}
ant_value_t
jit_helper_get_length
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
obj
)
{
if
(
vtype
(
obj
)
==
T_ARR
)
return
tov
((
double
)(
uint32_t
)
js_arr_len
(
js
,
obj
));
if
(
vtype
(
obj
)
==
T_STR
)
{
ant_offset_t
byte_len
=
0
;
ant_offset_t
off
=
vstr
(
js
,
obj
,
&
byte_len
);
const
char
*
str_data
=
(
const
char
*
)(
uintptr_t
)(
off
);
return
tov
((
double
)(
uint32_t
)
utf16_strlen
(
str_data
,
byte_len
));
}
return
js_getprop_fallback
(
js
,
obj
,
"length"
);
}
ant_value_t
jit_helper_put_field
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
obj
,
ant_value_t
val
,
const
char
*
str
,
uint32_t
len
)
{
ant_value_t
key
=
js_mkstr
(
js
,
str
,
len
);
return
js_setprop
(
js
,
obj
,
key
,
val
);
}
ant_value_t
jit_helper_get_elem
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
obj
,
ant_value_t
key
,
sv_func_t
*
func
,
int32_t
bc_off
)
{
uint8_t
ot
=
vtype
(
obj
);
if
(
ot
==
T_NULL
||
ot
==
T_UNDEF
)
{
jit_set_error_site_from_func
(
js
,
func
,
bc_off
);
return
js_mkerr_typed
(
js
,
JS_ERR_TYPE
,
"Cannot read properties of %s"
,
ot
==
T_NULL
?
"null"
:
"undefined"
);
}
if
(
vtype
(
obj
)
==
T_ARR
&&
vtype
(
key
)
==
T_NUM
)
{
double
d
=
tod
(
key
);
if
(
d
>=
0
&&
d
==
(
uint32_t
)
d
)
return
js_arr_get
(
js
,
obj
,
(
uint32_t
)
d
);
}
ant_value_t
str_elem
=
js_mkundef
();
if
(
sv_try_string_index_get
(
js
,
obj
,
key
,
&
str_elem
))
return
str_elem
;
return
sv_getprop_by_key
(
js
,
obj
,
key
);
}
ant_value_t
jit_helper_put_elem
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
obj
,
ant_value_t
key
,
ant_value_t
val
)
{
if
(
vtype
(
key
)
==
T_SYMBOL
)
return
js_setprop
(
js
,
obj
,
key
,
val
);
ant_value_t
key_jv
=
sv_key_to_propstr
(
js
,
key
);
return
js_setprop
(
js
,
obj
,
key_jv
,
val
);
}
ant_value_t
jit_helper_put_global
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
val
,
const
char
*
str
,
uint32_t
len
,
int
is_strict
)
{
if
(
is_strict
&&
lkp
(
js
,
js
->
global
,
str
,
len
)
==
0
)
return
js_mkerr_typed
(
js
,
JS_ERR_REFERENCE
,
"'%.*s' is not defined"
,
(
int
)
len
,
str
);
ant_value_t
key
=
js_mkstr
(
js
,
str
,
len
);
return
js_setprop
(
js
,
js
->
global
,
key
,
val
);
}
ant_value_t
jit_helper_object
(
sv_vm_t
*
vm
,
ant_t
*
js
)
{
ant_value_t
obj
=
mkobj
(
js
,
0
);
ant_value_t
proto
=
js_get_ctor_proto
(
js
,
"Object"
,
6
);
if
(
vtype
(
proto
)
==
T_OBJ
)
js_set_proto_init
(
obj
,
proto
);
return
obj
;
}
ant_value_t
jit_helper_array
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
*
elements
,
int
count
)
{
ant_value_t
arr
=
js_mkarr
(
js
);
for
(
int
i
=
0
;
i
<
count
;
i
++
)
js_arr_push
(
js
,
arr
,
elements
[
i
]);
return
arr
;
}
ant_value_t
jit_helper_catch_value
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
err
)
{
if
(
vtype
(
err
)
==
T_ERR
&&
js
->
thrown_exists
&&
vtype
(
js
->
thrown_value
)
!=
T_UNDEF
)
{
ant_value_t
caught
=
js
->
thrown_value
;
js
->
thrown_value
=
js_mkundef
();
js
->
thrown_exists
=
false
;
return
caught
;
}
return
err
;
}
ant_value_t
jit_helper_throw_error
(
sv_vm_t
*
vm
,
ant_t
*
js
,
const
char
*
str
,
uint32_t
len
,
int
err_type
)
{
return
js_mkerr_typed
(
js
,
(
js_err_type_t
)
err_type
,
"%.*s"
,
(
int
)
len
,
str
);
}
ant_value_t
jit_helper_get_elem2
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
obj
,
ant_value_t
key
)
{
if
(
vtype
(
obj
)
==
T_ARR
&&
vtype
(
key
)
==
T_NUM
)
{
double
d
=
tod
(
key
);
if
(
d
>=
0
&&
d
==
(
uint32_t
)
d
)
return
js_arr_get
(
js
,
obj
,
(
uint32_t
)
d
);
}
ant_value_t
str_elem
=
js_mkundef
();
if
(
sv_try_string_index_get
(
js
,
obj
,
key
,
&
str_elem
))
return
str_elem
;
return
sv_getprop_by_key
(
js
,
obj
,
key
);
}
ant_value_t
jit_helper_set_proto
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
obj
,
ant_value_t
proto
)
{
uint8_t
pt
=
vtype
(
proto
);
if
(
pt
==
T_OBJ
||
pt
==
T_NULL
||
pt
==
T_FUNC
||
pt
==
T_ARR
)
js_set_proto_wb
(
js
,
obj
,
proto
);
return
js_mkundef
();
}
ant_value_t
jit_helper_band
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
)
{
if
(
vtype
(
l
)
!=
T_NUM
||
vtype
(
r
)
!=
T_NUM
)
return
SV_JIT_BAILOUT
;
int32_t
ai
=
js_to_int32
(
tod
(
l
));
int32_t
bi
=
js_to_int32
(
tod
(
r
));
return
tov
((
double
)(
ai
&
bi
));
}
ant_value_t
jit_helper_bor
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
)
{
if
(
vtype
(
l
)
!=
T_NUM
||
vtype
(
r
)
!=
T_NUM
)
return
SV_JIT_BAILOUT
;
int32_t
ai
=
js_to_int32
(
tod
(
l
));
int32_t
bi
=
js_to_int32
(
tod
(
r
));
return
tov
((
double
)(
ai
|
bi
));
}
ant_value_t
jit_helper_bxor
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
)
{
if
(
vtype
(
l
)
!=
T_NUM
||
vtype
(
r
)
!=
T_NUM
)
return
SV_JIT_BAILOUT
;
int32_t
ai
=
js_to_int32
(
tod
(
l
));
int32_t
bi
=
js_to_int32
(
tod
(
r
));
return
tov
((
double
)(
ai
^
bi
));
}
ant_value_t
jit_helper_bnot
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
v
)
{
if
(
vtype
(
v
)
!=
T_NUM
)
return
SV_JIT_BAILOUT
;
return
tov
((
double
)(
~
js_to_int32
(
tod
(
v
))));
}
ant_value_t
jit_helper_shl
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
)
{
if
(
vtype
(
l
)
!=
T_NUM
||
vtype
(
r
)
!=
T_NUM
)
return
SV_JIT_BAILOUT
;
int32_t
ai
=
js_to_int32
(
tod
(
l
));
uint32_t
bi
=
js_to_uint32
(
tod
(
r
));
return
tov
((
double
)(
ai
<<
(
bi
&
0x1f
)));
}
ant_value_t
jit_helper_shr
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
)
{
if
(
vtype
(
l
)
!=
T_NUM
||
vtype
(
r
)
!=
T_NUM
)
return
SV_JIT_BAILOUT
;
int32_t
ai
=
js_to_int32
(
tod
(
l
));
uint32_t
bi
=
js_to_uint32
(
tod
(
r
));
return
tov
((
double
)(
ai
>>
(
bi
&
0x1f
)));
}
ant_value_t
jit_helper_ushr
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
)
{
if
(
vtype
(
l
)
!=
T_NUM
||
vtype
(
r
)
!=
T_NUM
)
return
SV_JIT_BAILOUT
;
uint32_t
ai
=
js_to_uint32
(
tod
(
l
));
uint32_t
bi
=
js_to_uint32
(
tod
(
r
));
return
tov
((
double
)(
ai
>>
(
bi
&
0x1f
)));
}
ant_value_t
jit_helper_gt
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
)
{
if
(
vtype
(
l
)
==
T_NUM
&&
vtype
(
r
)
==
T_NUM
)
return
js_bool
(
tod
(
l
)
>
tod
(
r
));
return
SV_JIT_BAILOUT
;
}
ant_value_t
jit_helper_ge
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
l
,
ant_value_t
r
)
{
if
(
vtype
(
l
)
==
T_NUM
&&
vtype
(
r
)
==
T_NUM
)
return
js_bool
(
tod
(
l
)
>=
tod
(
r
));
return
SV_JIT_BAILOUT
;
}
ant_value_t
jit_helper_delete
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
obj
,
ant_value_t
key
)
{
ant_value_t
key_str
=
js_mkundef
();
if
(
vtype
(
key
)
==
T_SYMBOL
)
return
js_delete_sym_prop
(
js
,
obj
,
key
);
else
key_str
=
coerce_to_str
(
js
,
key
);
if
(
!
is_err
(
key_str
)
&&
vtype
(
key_str
)
==
T_STR
)
{
ant_offset_t
klen
=
0
;
ant_offset_t
koff
=
vstr
(
js
,
key_str
,
&
klen
);
const
char
*
kptr
=
(
const
char
*
)(
uintptr_t
)(
koff
);
return
js_delete_prop
(
js
,
obj
,
kptr
,
klen
);
}
return
mkval
(
T_BOOL
,
0
);
}
ant_value_t
jit_helper_new
(
sv_vm_t
*
vm
,
ant_t
*
js
,
ant_value_t
func
,
ant_value_t
new_target
,
ant_value_t
*
args
,
int
argc
)
{
ant_value_t
record_func
=
func
;
js
->
new_target
=
new_target
;
if
(
vtype
(
func
)
==
T_OBJ
&&
is_proxy
(
func
))
return
js_proxy_construct
(
js
,
func
,
args
,
argc
,
new_target
);
if
(
!
js_is_constructor
(
js
,
func
))
return
js_mkerr_typed
(
js
,
JS_ERR_TYPE
,
"not a constructor"
);
ant_value_t
proto
=
js_mkundef
();
if
(
vtype
(
func
)
==
T_FUNC
)
{
ant_value_t
proto_source
=
func
;
ant_value_t
func_obj
=
js_func_obj
(
func
);
ant_value_t
target_func
=
js_get_slot
(
func_obj
,
SLOT_TARGET_FUNC
);
if
(
vtype
(
target_func
)
==
T_FUNC
)
{
proto_source
=
target_func
;
record_func
=
target_func
;
}
proto
=
js_getprop_fallback
(
js
,
proto_source
,
"prototype"
);
}
ant_value_t
obj
=
js_mkobj_with_inobj_limit
(
js
,
sv_tfb_ctor_inobj_limit
(
record_func
));
if
(
is_object_type
(
proto
))
js_set_proto_init
(
obj
,
proto
);
ant_value_t
ctor_this
=
obj
;
ant_value_t
result
=
sv_vm_call
(
vm
,
js
,
func
,
obj
,
args
,
argc
,
&
ctor_this
,
true
);
if
(
is_err
(
result
))
return
result
;
ant_value_t
final_obj
=
is_object_type
(
result
)
?
result
:
(
is_object_type
(
ctor_this
)
?
ctor_this
:
obj
);
sv_tfb_record_ctor_prop_count
(
record_func
,
final_obj
);
return
final_obj
;
}
#endif
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sun, May 3, 7:20 AM (54 m, 29 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
535400
Default Alt Text
glue.c (17 KB)
Attached To
Mode
rANT Ant
Attached
Detach File
Event Timeline
Log In to Comment