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 }