Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2916377
property.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
property.h
View Options
#ifndef SV_PROPERTY_H
#define SV_PROPERTY_H
#include
"silver/engine.h"
#include
"utf8.h"
#include
<math.h>
#include
<stdlib.h>
static
inline
jsval_t
sv_getprop_fallback_len
(
ant_t
*
js
,
jsval_t
obj
,
const
char
*
key
,
jsoff_t
key_len
)
{
char
small
[
64
];
char
*
tmp
=
small
;
if
(
key_len
+
1
>
(
jsoff_t
)
sizeof
(
small
))
{
tmp
=
malloc
((
size_t
)
key_len
+
1
);
if
(
!
tmp
)
return
js_mkerr
(
js
,
"out of memory"
);
}
memcpy
(
tmp
,
key
,
(
size_t
)
key_len
);
tmp
[
key_len
]
=
'\0'
;
jsval_t
out
=
js_getprop_fallback
(
js
,
obj
,
tmp
);
if
(
tmp
!=
small
)
free
(
tmp
);
return
out
;
}
static
inline
jsval_t
sv_key_to_propstr
(
ant_t
*
js
,
jsval_t
key
)
{
return
coerce_to_str
(
js
,
key
);
}
static
inline
jsval_t
sv_getprop_by_key
(
ant_t
*
js
,
jsval_t
obj
,
jsval_t
key
)
{
if
(
vtype
(
key
)
==
T_SYMBOL
)
return
js_get_sym
(
js
,
obj
,
key
);
jsval_t
key_str
=
sv_key_to_propstr
(
js
,
key
);
if
(
is_err
(
key_str
)
||
vtype
(
key_str
)
!=
T_STR
)
return
js_mkundef
();
jsoff_t
klen
=
0
;
jsoff_t
koff
=
vstr
(
js
,
key_str
,
&
klen
);
const
char
*
kptr
=
(
const
char
*
)
&
js
->
mem
[
koff
];
return
sv_getprop_fallback_len
(
js
,
obj
,
kptr
,
klen
);
}
static
inline
jsval_t
sv_prop_get_at
(
ant_t
*
js
,
jsval_t
obj
,
const
char
*
str
,
uint32_t
len
,
sv_func_t
*
func
,
uint8_t
*
ip
)
{
uint8_t
t
=
vtype
(
obj
);
if
(
t
==
T_NULL
||
t
==
T_UNDEF
)
{
if
(
func
&&
ip
)
js_set_error_site_from_bc
(
js
,
func
,
(
int
)(
ip
-
func
->
code
),
func
->
filename
);
return
js_mkerr_typed
(
js
,
JS_ERR_TYPE
,
"Cannot read properties of %s (reading '%.*s')"
,
t
==
T_NULL
?
"null"
:
"undefined"
,
(
int
)
len
,
str
);
}
jsval_t
str_prim
=
js_mkundef
();
jsval_t
sym_prim
=
js_mkundef
();
if
(
t
==
T_STR
)
{
str_prim
=
obj
;
}
else
if
(
t
==
T_SYMBOL
)
{
sym_prim
=
obj
;
}
else
if
(
t
==
T_OBJ
)
{
jsval_t
prim
=
js_get_slot
(
js
,
obj
,
SLOT_PRIMITIVE
);
if
(
vtype
(
prim
)
==
T_STR
)
str_prim
=
prim
;
else
if
(
vtype
(
prim
)
==
T_SYMBOL
)
sym_prim
=
prim
;
}
if
(
vtype
(
str_prim
)
==
T_STR
&&
len
==
6
&&
memcmp
(
str
,
"length"
,
6
)
==
0
)
{
jsoff_t
byte_len
=
0
;
jsoff_t
str_off
=
vstr
(
js
,
str_prim
,
&
byte_len
);
const
char
*
str_data
=
(
const
char
*
)
&
js
->
mem
[
str_off
];
return
tov
((
double
)
utf16_strlen
(
str_data
,
byte_len
));
}
if
(
vtype
(
sym_prim
)
==
T_SYMBOL
&&
len
==
11
&&
memcmp
(
str
,
"description"
,
11
)
==
0
)
{
const
char
*
desc
=
js_sym_desc
(
js
,
sym_prim
);
if
(
desc
)
return
js_mkstr
(
js
,
desc
,
strlen
(
desc
));
return
js_mkundef
();
}
return
sv_getprop_fallback_len
(
js
,
obj
,
str
,
(
jsoff_t
)
len
);
}
static
inline
jsval_t
sv_prop_get
(
ant_t
*
js
,
jsval_t
obj
,
const
char
*
str
,
uint32_t
len
)
{
return
sv_prop_get_at
(
js
,
obj
,
str
,
len
,
NULL
,
NULL
);
}
static
inline
bool
sv_parse_string_index_key
(
ant_t
*
js
,
jsval_t
key
,
size_t
*
out_idx
)
{
if
(
vtype
(
key
)
==
T_NUM
)
{
double
d
=
tod
(
key
);
if
(
!
isfinite
(
d
)
||
d
<
0.0
)
return
false
;
double
di
=
floor
(
d
);
if
(
di
!=
d
||
di
>
(
double
)
SIZE_MAX
)
return
false
;
*
out_idx
=
(
size_t
)
di
;
return
true
;
}
if
(
vtype
(
key
)
!=
T_STR
)
return
false
;
jsoff_t
klen
=
0
;
jsoff_t
koff
=
vstr
(
js
,
key
,
&
klen
);
const
char
*
k
=
(
const
char
*
)
&
js
->
mem
[
koff
];
if
(
klen
==
0
)
return
false
;
if
(
klen
>
1
&&
k
[
0
]
==
'0'
)
return
false
;
size_t
idx
=
0
;
for
(
jsoff_t
i
=
0
;
i
<
klen
;
i
++
)
{
if
(
k
[
i
]
<
'0'
||
k
[
i
]
>
'9'
)
return
false
;
size_t
digit
=
(
size_t
)(
k
[
i
]
-
'0'
);
if
(
idx
>
(
SIZE_MAX
-
digit
)
/
10
)
return
false
;
idx
=
idx
*
10
+
digit
;
}
*
out_idx
=
idx
;
return
true
;
}
static
inline
bool
sv_try_string_index_get
(
ant_t
*
js
,
jsval_t
obj
,
jsval_t
key
,
jsval_t
*
out
)
{
jsval_t
str
=
obj
;
if
(
vtype
(
obj
)
==
T_OBJ
)
{
jsval_t
prim
=
js_get_slot
(
js
,
obj
,
SLOT_PRIMITIVE
);
if
(
vtype
(
prim
)
==
T_STR
)
str
=
prim
;
}
if
(
vtype
(
str
)
!=
T_STR
)
return
false
;
size_t
idx
=
0
;
if
(
!
sv_parse_string_index_key
(
js
,
key
,
&
idx
))
return
false
;
jsoff_t
byte_len
=
0
;
jsoff_t
str_off
=
vstr
(
js
,
str
,
&
byte_len
);
const
char
*
str_data
=
(
const
char
*
)
&
js
->
mem
[
str_off
];
size_t
char_bytes
=
0
;
int
byte_offset
=
utf16_index_to_byte_offset
(
str_data
,
byte_len
,
idx
,
&
char_bytes
);
if
(
byte_offset
<
0
||
char_bytes
==
0
)
{
*
out
=
js_mkundef
();
return
true
;
}
*
out
=
js_mkstr
(
js
,
str_data
+
byte_offset
,
char_bytes
);
return
true
;
}
static
inline
jsval_t
sv_op_get_field
(
sv_vm_t
*
vm
,
ant_t
*
js
,
sv_func_t
*
func
,
uint8_t
*
ip
)
{
uint32_t
idx
=
sv_get_u32
(
ip
+
1
);
sv_atom_t
*
a
=
&
func
->
atoms
[
idx
];
jsval_t
obj
=
vm
->
stack
[
--
vm
->
sp
];
jsval_t
res
=
sv_prop_get_at
(
js
,
obj
,
a
->
str
,
a
->
len
,
func
,
ip
);
if
(
is_err
(
res
))
return
res
;
vm
->
stack
[
vm
->
sp
++
]
=
res
;
return
js_mkundef
();
}
static
inline
jsval_t
sv_op_get_field2
(
sv_vm_t
*
vm
,
ant_t
*
js
,
sv_func_t
*
func
,
uint8_t
*
ip
)
{
uint32_t
idx
=
sv_get_u32
(
ip
+
1
);
sv_atom_t
*
a
=
&
func
->
atoms
[
idx
];
jsval_t
obj
=
vm
->
stack
[
vm
->
sp
-
1
];
jsval_t
res
=
sv_prop_get_at
(
js
,
obj
,
a
->
str
,
a
->
len
,
func
,
ip
);
if
(
is_err
(
res
))
return
res
;
vm
->
stack
[
vm
->
sp
++
]
=
res
;
return
js_mkundef
();
}
static
inline
jsval_t
sv_op_put_field
(
sv_vm_t
*
vm
,
ant_t
*
js
,
sv_func_t
*
func
,
uint8_t
*
ip
)
{
uint32_t
idx
=
sv_get_u32
(
ip
+
1
);
sv_atom_t
*
a
=
&
func
->
atoms
[
idx
];
jsval_t
val
=
vm
->
stack
[
--
vm
->
sp
];
jsval_t
obj
=
vm
->
stack
[
--
vm
->
sp
];
jsval_t
key
=
js_mkstr
(
js
,
a
->
str
,
a
->
len
);
return
js_setprop
(
js
,
obj
,
key
,
val
);
}
static
inline
jsval_t
sv_op_get_elem
(
sv_vm_t
*
vm
,
ant_t
*
js
,
sv_func_t
*
func
,
uint8_t
*
ip
)
{
jsval_t
key
=
vm
->
stack
[
--
vm
->
sp
];
jsval_t
obj
=
vm
->
stack
[
--
vm
->
sp
];
uint8_t
ot
=
vtype
(
obj
);
if
(
ot
==
T_NULL
||
ot
==
T_UNDEF
)
{
if
(
func
&&
ip
)
js_set_error_site_from_bc
(
js
,
func
,
(
int
)(
ip
-
func
->
code
),
func
->
filename
);
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
)
{
vm
->
stack
[
vm
->
sp
++
]
=
js_arr_get
(
js
,
obj
,
(
uint32_t
)
d
);
return
js_mkundef
();
}
}
jsval_t
str_elem
=
js_mkundef
();
if
(
sv_try_string_index_get
(
js
,
obj
,
key
,
&
str_elem
))
{
vm
->
stack
[
vm
->
sp
++
]
=
str_elem
;
return
js_mkundef
();
}
jsval_t
res
=
sv_getprop_by_key
(
js
,
obj
,
key
);
if
(
is_err
(
res
))
return
res
;
vm
->
stack
[
vm
->
sp
++
]
=
res
;
return
js_mkundef
();
}
static
inline
jsval_t
sv_op_get_elem2
(
sv_vm_t
*
vm
,
ant_t
*
js
,
sv_func_t
*
func
,
uint8_t
*
ip
)
{
jsval_t
key
=
vm
->
stack
[
--
vm
->
sp
];
jsval_t
obj
=
vm
->
stack
[
vm
->
sp
-
1
];
uint8_t
ot
=
vtype
(
obj
);
if
(
ot
==
T_NULL
||
ot
==
T_UNDEF
)
{
if
(
func
&&
ip
)
js_set_error_site_from_bc
(
js
,
func
,
(
int
)(
ip
-
func
->
code
),
func
->
filename
);
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
)
{
vm
->
stack
[
vm
->
sp
++
]
=
js_arr_get
(
js
,
obj
,
(
uint32_t
)
d
);
return
js_mkundef
();
}
}
jsval_t
str_elem
=
js_mkundef
();
if
(
sv_try_string_index_get
(
js
,
obj
,
key
,
&
str_elem
))
{
vm
->
stack
[
vm
->
sp
++
]
=
str_elem
;
return
js_mkundef
();
}
jsval_t
res
=
sv_getprop_by_key
(
js
,
obj
,
key
);
if
(
is_err
(
res
))
return
res
;
vm
->
stack
[
vm
->
sp
++
]
=
res
;
return
js_mkundef
();
}
static
inline
jsval_t
sv_op_put_elem
(
sv_vm_t
*
vm
,
ant_t
*
js
)
{
jsval_t
val
=
vm
->
stack
[
--
vm
->
sp
];
jsval_t
key
=
vm
->
stack
[
--
vm
->
sp
];
jsval_t
obj
=
vm
->
stack
[
--
vm
->
sp
];
if
(
vtype
(
key
)
==
T_SYMBOL
)
return
js_setprop
(
js
,
obj
,
key
,
val
);
jsval_t
key_jv
=
sv_key_to_propstr
(
js
,
key
);
return
js_setprop
(
js
,
obj
,
key_jv
,
val
);
}
static
inline
void
sv_op_define_field
(
sv_vm_t
*
vm
,
ant_t
*
js
,
sv_func_t
*
func
,
uint8_t
*
ip
)
{
uint32_t
idx
=
sv_get_u32
(
ip
+
1
);
sv_atom_t
*
a
=
&
func
->
atoms
[
idx
];
jsval_t
val
=
vm
->
stack
[
--
vm
->
sp
];
jsval_t
obj
=
vm
->
stack
[
vm
->
sp
-
1
];
js_define_own_prop
(
js
,
obj
,
a
->
str
,
a
->
len
,
val
);
}
static
inline
jsval_t
sv_op_get_length
(
sv_vm_t
*
vm
,
ant_t
*
js
)
{
jsval_t
obj
=
vm
->
stack
[
--
vm
->
sp
];
if
(
vtype
(
obj
)
==
T_ARR
)
{
vm
->
stack
[
vm
->
sp
++
]
=
tov
((
double
)(
uint32_t
)
js_arr_len
(
js
,
obj
));
return
js_mkundef
();
}
if
(
vtype
(
obj
)
==
T_STR
)
{
jsoff_t
byte_len
=
0
;
jsoff_t
off
=
vstr
(
js
,
obj
,
&
byte_len
);
const
char
*
str_data
=
(
const
char
*
)
&
js
->
mem
[
off
];
vm
->
stack
[
vm
->
sp
++
]
=
tov
((
double
)(
uint32_t
)
utf16_strlen
(
str_data
,
byte_len
));
return
js_mkundef
();
}
jsval_t
res
=
js_getprop_fallback
(
js
,
obj
,
"length"
);
if
(
is_err
(
res
))
return
res
;
vm
->
stack
[
vm
->
sp
++
]
=
res
;
return
js_mkundef
();
}
#endif
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Thu, Mar 26, 4:48 PM (1 d, 18 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
512017
Default Alt Text
property.h (8 KB)
Attached To
Mode
rANT Ant
Attached
Detach File
Event Timeline
Log In to Comment