-
Notifications
You must be signed in to change notification settings - Fork 0
chore: daily optimization patch for bridge/core and eventloop #158
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ package core | |
| import ( | ||
| "fmt" | ||
| "reflect" | ||
| "strconv" | ||
| "sync" | ||
|
|
||
| "github.com/grafana/sobek" | ||
|
|
@@ -337,6 +338,20 @@ func wrapJSCallback(vm *sobek.Runtime, callable sobek.Callable, goType reflect.T | |
| } | ||
|
|
||
| func bindSlice(vm *sobek.Runtime, v reflect.Value, visited map[uintptr]sobek.Value) (sobek.Value, error) { | ||
| // @optimized: Fast path for []byte using Uint8Array view | ||
| if v.Type().Elem() == reflect.TypeOf(byte(0)) { | ||
| var data []byte | ||
| if v.CanAddr() || v.Kind() == reflect.Slice { | ||
| data = v.Bytes() | ||
| } else { | ||
| // Unaddressable array, must copy to a slice first | ||
| data = make([]byte, v.Len()) | ||
| reflect.Copy(reflect.ValueOf(data), v) | ||
| } | ||
| // Data MUST be copied inside ToUint8Array to prevent shared memory mutation | ||
| return ToUint8Array(vm, data), nil | ||
| } | ||
|
Comment on lines
+341
to
+353
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The 🐛 Proposed fix to handle arrays correctly func bindSlice(vm *sobek.Runtime, v reflect.Value, visited map[uintptr]sobek.Value) (sobek.Value, error) {
// `@optimized`: Fast path for []byte using Uint8Array view
if v.Type().Elem() == reflect.TypeOf(byte(0)) {
var data []byte
- if v.CanAddr() || v.Kind() == reflect.Slice {
+ if v.Kind() == reflect.Slice {
data = v.Bytes()
} else {
// Unaddressable array, must copy to a slice first
data = make([]byte, v.Len())
reflect.Copy(reflect.ValueOf(data), v)
}
// Data MUST be copied inside ToUint8Array to prevent shared memory mutation
return ToUint8Array(vm, data), nil
}🤖 Prompt for AI Agents |
||
|
|
||
| // @optimized: Pre-allocate slice and use NewArray(vals...) to avoid repeated Set calls. | ||
| l := v.Len() | ||
| vals := make([]interface{}, l) | ||
|
|
@@ -352,16 +367,25 @@ func bindSlice(vm *sobek.Runtime, v reflect.Value, visited map[uintptr]sobek.Val | |
|
|
||
| func bindMap(vm *sobek.Runtime, v reflect.Value, visited map[uintptr]sobek.Value) (sobek.Value, error) { | ||
| obj := vm.NewObject() | ||
| for _, key := range v.MapKeys() { | ||
| // @optimized: Use MapRange to avoid allocating a slice of keys. | ||
| iter := v.MapRange() | ||
| for iter.Next() { | ||
| key := iter.Key() | ||
| var keyStr string | ||
| // @optimized: Avoid Sprintf if key is already a string. | ||
| if key.Kind() == reflect.String { | ||
|
|
||
| // @optimized: Use specific formatting functions to avoid interface boxing overhead. | ||
| switch key.Kind() { | ||
| case reflect.String: | ||
| keyStr = key.String() | ||
| } else { | ||
| case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||
| keyStr = strconv.FormatInt(key.Int(), 10) | ||
| case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: | ||
| keyStr = strconv.FormatUint(key.Uint(), 10) | ||
| default: | ||
| keyStr = fmt.Sprint(key.Interface()) | ||
| } | ||
|
|
||
| val, err := bindValue(vm, v.MapIndex(key), visited) | ||
| val, err := bindValue(vm, iter.Value(), visited) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing fallback when Uint8Array construction fails.
If the
Uint8Arrayconstructor exists butvm.New()fails (line 63), the function silently exits without setting anything on the global object. This breaks the function's documented contract to expose the buffer.The fallback path in
ToUint8Arraycorrectly returns the rawArrayBufferon failure;MapSharedBuffershould do the same.🐛 Proposed fix to add fallback on construction failure
view := ctor.ToObject(vm) typedArray, err := vm.New(view, vm.ToValue(buf)) if err == nil && typedArray != nil { _ = vm.GlobalObject().Set(name, typedArray) + } else { + _ = vm.GlobalObject().Set(name, buf) } }🤖 Prompt for AI Agents