func (vm *VM) Run(code []byte) (err error) { vm.panic = nil // we can't trust the input, it maybe malicious or what ever // in the worst case, VM panic will not crash our program defer func() { if x := recover(); x != nil { vm.panic = debug.Stack() err = ErrorPanic } }() log.Debug("--------run-------") vm.code = code vm.pc = 0 for i := 0; i < 300; i++ { opcode := vm.code[vm.pc] log.Debug("opcode=", opcode) if opcode == 20 { break } instruct := instructions[opcode] err = instruct(vm) if err != nil { return err } } return nil }
func _FUNCTION_INVOKE(vm *VM) error { fun := vm.fun if clo, ok := fun.(*Procedure); ok { vm.stack.Push(vm.code) vm.stack.Push(vm.pc + 1) vm.code = clo.code vm.pc = clo.pos vm.env = clo.env } else if primitiveIdx, ok := fun.(byte); ok { switch primitiveIdx { case 10: case 13: // cons case 14: // car case 15: // cdr case 16: // pair? case 17: // symbol? case 18: // eq? case 19: default: break // TODO } } else { log.Debug(vm.fun) return errors.New("没有这个primitive额") } return nil }
func handleClient(conn net.Conn) { log.Debug("accept a connection...") agent := NewAgent(conn) go agent.Loop() }