94 lines
1.9 KiB
Go
94 lines
1.9 KiB
Go
package state
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"fmt"
|
|
"sync"
|
|
|
|
luajit "git.sharkk.net/Sky/LuaJIT-to-Go"
|
|
)
|
|
|
|
// BytecodeEntry holds compiled bytecode with metadata
|
|
type BytecodeEntry struct {
|
|
Bytecode []byte
|
|
Name string
|
|
Hash [32]byte
|
|
}
|
|
|
|
// Global bytecode cache
|
|
var (
|
|
bytecodeCache = struct {
|
|
sync.RWMutex
|
|
entries map[string]*BytecodeEntry
|
|
}{
|
|
entries: make(map[string]*BytecodeEntry),
|
|
}
|
|
)
|
|
|
|
// CompileAndCache compiles code to bytecode and stores it globally
|
|
func CompileAndCache(state *luajit.State, code, name string) (*BytecodeEntry, error) {
|
|
hash := sha256.Sum256([]byte(code))
|
|
cacheKey := fmt.Sprintf("%x", hash)
|
|
|
|
// Check cache first
|
|
bytecodeCache.RLock()
|
|
if entry, exists := bytecodeCache.entries[cacheKey]; exists {
|
|
bytecodeCache.RUnlock()
|
|
return entry, nil
|
|
}
|
|
bytecodeCache.RUnlock()
|
|
|
|
// Compile bytecode
|
|
bytecode, err := state.CompileBytecode(code, name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Store in cache
|
|
entry := &BytecodeEntry{
|
|
Bytecode: bytecode,
|
|
Name: name,
|
|
Hash: hash,
|
|
}
|
|
|
|
bytecodeCache.Lock()
|
|
bytecodeCache.entries[cacheKey] = entry
|
|
bytecodeCache.Unlock()
|
|
|
|
return entry, nil
|
|
}
|
|
|
|
// GetCached retrieves bytecode from cache by code hash
|
|
func GetCached(code string) (*BytecodeEntry, bool) {
|
|
hash := sha256.Sum256([]byte(code))
|
|
cacheKey := fmt.Sprintf("%x", hash)
|
|
|
|
bytecodeCache.RLock()
|
|
defer bytecodeCache.RUnlock()
|
|
|
|
entry, exists := bytecodeCache.entries[cacheKey]
|
|
return entry, exists
|
|
}
|
|
|
|
// ClearCache removes all cached bytecode entries
|
|
func ClearCache() {
|
|
bytecodeCache.Lock()
|
|
defer bytecodeCache.Unlock()
|
|
|
|
bytecodeCache.entries = make(map[string]*BytecodeEntry)
|
|
}
|
|
|
|
// CacheStats returns cache statistics
|
|
func CacheStats() (int, int64) {
|
|
bytecodeCache.RLock()
|
|
defer bytecodeCache.RUnlock()
|
|
|
|
count := len(bytecodeCache.entries)
|
|
var totalSize int64
|
|
for _, entry := range bytecodeCache.entries {
|
|
totalSize += int64(len(entry.Bytecode))
|
|
}
|
|
|
|
return count, totalSize
|
|
}
|