forked from YaoApp/v8go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathobject.go
124 lines (106 loc) · 3.62 KB
/
object.go
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
// Copyright 2021 Roger Chapman and the v8go contributors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package v8go
// #include <stdlib.h>
// #include "v8go.h"
import "C"
import (
"errors"
"fmt"
"math/big"
"unsafe"
)
// Object is a JavaScript object (ECMA-262, 4.3.3)
type Object struct {
*Value
}
func (o *Object) MethodCall(methodName string, args ...Valuer) (*Value, error) {
ckey := C.CString(methodName)
defer C.free(unsafe.Pointer(ckey))
getRtn := C.ObjectGet(o.ptr, ckey)
prop, err := valueResult(o.ctx, getRtn)
if err != nil {
return nil, err
}
fn, err := prop.AsFunction()
if err != nil {
return nil, err
}
return fn.Call(o, args...)
}
func coerceValue(iso *Isolate, val interface{}) (*Value, error) {
switch v := val.(type) {
case string, int32, uint32, int64, uint64, float64, bool, *big.Int:
// ignoring error as code cannot reach the error state as we are already
// validating the new value types in this case statement
value, _ := NewValue(iso, v)
return value, nil
case Valuer:
return v.value(), nil
default:
return nil, fmt.Errorf("v8go: unsupported object property type `%T`", v)
}
}
// Set will set a property on the Object to a given value.
// Supports all value types, eg: Object, Array, Date, Set, Map etc
// If the value passed is a Go supported primitive (string, int32, uint32, int64, uint64, float64, big.Int)
// then a *Value will be created and set as the value property.
func (o *Object) Set(key string, val interface{}) error {
if len(key) == 0 {
return errors.New("v8go: You must provide a valid property key")
}
value, err := coerceValue(o.ctx.iso, val)
if err != nil {
return err
}
ckey := C.CString(key)
defer C.free(unsafe.Pointer(ckey))
C.ObjectSet(o.ptr, ckey, value.ptr)
return nil
}
// Set will set a given index on the Object to a given value.
// Supports all value types, eg: Object, Array, Date, Set, Map etc
// If the value passed is a Go supported primitive (string, int32, uint32, int64, uint64, float64, big.Int)
// then a *Value will be created and set as the value property.
func (o *Object) SetIdx(idx uint32, val interface{}) error {
value, err := coerceValue(o.ctx.iso, val)
if err != nil {
return err
}
C.ObjectSetIdx(o.ptr, C.uint32_t(idx), value.ptr)
return nil
}
// Get tries to get a Value for a given Object property key.
func (o *Object) Get(key string) (*Value, error) {
ckey := C.CString(key)
defer C.free(unsafe.Pointer(ckey))
rtn := C.ObjectGet(o.ptr, ckey)
return valueResult(o.ctx, rtn)
}
// GetIdx tries to get a Value at a give Object index.
func (o *Object) GetIdx(idx uint32) (*Value, error) {
rtn := C.ObjectGetIdx(o.ptr, C.uint32_t(idx))
return valueResult(o.ctx, rtn)
}
// Has calls the abstract operation HasProperty(O, P) described in ECMA-262, 7.3.10.
// Returns true, if the object has the property, either own or on the prototype chain.
func (o *Object) Has(key string) bool {
ckey := C.CString(key)
defer C.free(unsafe.Pointer(ckey))
return C.ObjectHas(o.ptr, ckey) != 0
}
// HasIdx returns true if the object has a value at the given index.
func (o *Object) HasIdx(idx uint32) bool {
return C.ObjectHasIdx(o.ptr, C.uint32_t(idx)) != 0
}
// Delete returns true if successful in deleting a named property on the object.
func (o *Object) Delete(key string) bool {
ckey := C.CString(key)
defer C.free(unsafe.Pointer(ckey))
return C.ObjectDelete(o.ptr, ckey) != 0
}
// DeleteIdx returns true if successful in deleting a value at a given index of the object.
func (o *Object) DeleteIdx(idx uint32) bool {
return C.ObjectDeleteIdx(o.ptr, C.uint32_t(idx)) != 0
}