-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathatom.v
133 lines (120 loc) · 2.63 KB
/
atom.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
module vjs
@[typedef]
struct C.JSAtom {}
@[typedef]
struct C.JSPropertyEnum {
is_enumerable bool
atom C.JSAtom
}
// Atom structure based on `JSAtom` in qjs
// and implemented into `ref`.
pub struct Atom {
ref C.JSAtom
ctx Context
}
// PropertyEnum structure based on `JSPropertyEnum` in qjs.
pub struct PropertyEnum {
pub:
atom Atom
is_enumerable bool
}
pub type AtomValue = int | string
fn C.JS_AtomToCString(&C.JSContext, C.JSAtom) &char
fn C.JS_AtomToValue(&C.JSContext, C.JSAtom) C.JSValue
fn C.JS_NewAtom(&C.JSContext, &char) C.JSAtom
fn C.JS_GetModuleName(&C.JSContext, &C.JSModuleDef) C.JSAtom
fn C.JS_FreeAtom(&C.JSContext, C.JSAtom)
fn C.JS_NewAtomUInt32(&C.JSContext, u32) C.JSAtom
fn C.JS_GetOwnPropertyNames(&C.JSContext, &&C.JSPropertyEnum, &u32, JSValueConst, int) int
pub fn (ctx &Context) c_atom(atom C.JSAtom) Atom {
return Atom{
ctx: ctx
ref: atom
}
}
// Create new Atom support `int` | `string`.
// Example:
// ```v
// atom := ctx.new_atom('my_atom')
// ```
@[manualfree]
pub fn (ctx &Context) new_atom(val AtomValue) Atom {
if val is string {
ptr := val.str
atom := Atom{
ctx: ctx
ref: C.JS_NewAtom(ctx.ref, ptr)
}
unsafe {
free(ptr)
}
return atom
}
return Atom{
ctx: ctx
ref: C.JS_NewAtomUInt32(ctx.ref, u32(val as int))
}
}
// Convert Atom to string.
@[manualfree]
pub fn (a Atom) to_string() string {
ptr := C.JS_AtomToCString(a.ctx.ref, a.ref)
ret := v_str(ptr)
C.JS_FreeCString(a.ctx.ref, ptr)
return ret
}
// Convert Atom to string.
pub fn (a Atom) str() string {
return a.to_string()
}
// Convert Atom to Value.
// Example:
// ```v
// val := atom.to_value()
// println(val)
// ```
pub fn (a Atom) to_value() Value {
return a.ctx.c_val(C.JS_AtomToValue(a.ctx.ref, a.ref))
}
// arrays property_names `[]PropertyEnum`.
// Example:
// ```v
// props := val.property_names() or { panic(err) }
// println(props)
//
// for prop in props {
// println(prop.atom)
// println(prop.is_enumerable)
// }
// ```
@[manualfree]
pub fn (v Value) property_names() ![]PropertyEnum {
mut ref := &C.JSPropertyEnum{}
mut size := u32(0)
flag := 1 << 0 | 1 << 1 | 1 << 2
res := C.JS_GetOwnPropertyNames(v.ctx.ref, &ref, &size, v.ref, flag)
if res < 0 {
return v.ctx.js_error(message: 'value does not contain properties').to_error()
}
defer {
C.js_free(v.ctx.ref, ref)
}
len := int(size)
mut props := []PropertyEnum{cap: len}
for i in 0 .. len {
prop := unsafe { ref[i] }
atom := Atom{
ctx: v.ctx
ref: prop.atom
}
props << PropertyEnum{
atom: atom
is_enumerable: prop.is_enumerable
}
}
return props
}
// Free Atom
pub fn (a &Atom) free() {
C.JS_FreeAtom(a.ctx.ref, a.ref)
}