superinstance-flux-runtime 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flux
4
+ # Binary loader for FLUX bytecode files
5
+ class Loader
6
+ FLUX_MAGIC = 'FLUX'.b
7
+
8
+ # Load a FLUX bytecode file
9
+ # Returns raw bytecode, stripping the FLUX header if present
10
+ def load_file(path)
11
+ data = File.binread(path)
12
+
13
+ if data.start_with?(FLUX_MAGIC)
14
+ strip_header(data)
15
+ else
16
+ data
17
+ end
18
+ end
19
+
20
+ # Check if file has FLUX header
21
+ def has_header?(path)
22
+ data = File.binread(path, 4)
23
+ data == FLUX_MAGIC
24
+ end
25
+
26
+ # Parse header information
27
+ def parse_header(path)
28
+ data = File.binread(path)
29
+
30
+ unless data.start_with?(FLUX_MAGIC)
31
+ return nil
32
+ end
33
+
34
+ {
35
+ magic: data[0..3],
36
+ version_major: data.getbyte(4) | (data.getbyte(5) << 8),
37
+ version_minor: data.getbyte(6) | (data.getbyte(7) << 8),
38
+ flags: data.getbyte(8) | (data.getbyte(9) << 8),
39
+ entry_point: data.getbyte(10) | (data.getbyte(11) << 8) |
40
+ (data.getbyte(12) << 16) | (data.getbyte(13) << 24),
41
+ reserved: data[14..17]
42
+ }
43
+ end
44
+
45
+ private
46
+
47
+ def strip_header(data)
48
+ # FLUX header is 16 bytes
49
+ # Magic (4) + Version (2) + Flags (2) + Entry point (4) + Reserved (4)
50
+ return data[16..] if data.bytesize > 16
51
+
52
+ data
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'exceptions'
4
+
5
+ module Flux
6
+ # Opcode registry mapping opcode byte values to method names
7
+ # and providing all core opcode implementations
8
+ module OpcodeRegistry
9
+ OPCODE_CLASSES = {
10
+ # Control Flow (0x00-0x0F)
11
+ 0x00 => :Halt,
12
+ 0x01 => :Nop,
13
+ 0x02 => :Ret,
14
+ 0x03 => :Jump,
15
+ 0x04 => :JumpIf,
16
+ 0x05 => :JumpIfNot,
17
+ 0x06 => :Call,
18
+ 0x07 => :CallIndirect,
19
+ 0x08 => :Yield,
20
+ 0x09 => :Panic,
21
+ 0x0A => :Unreachable,
22
+
23
+ # Stack Operations (0x10-0x1F)
24
+ 0x10 => :Push,
25
+ 0x11 => :Pop,
26
+ 0x12 => :Dup,
27
+ 0x13 => :Swap,
28
+
29
+ # Integer Arithmetic (0x20-0x3F)
30
+ 0x20 => :IMov,
31
+ 0x21 => :IAdd,
32
+ 0x22 => :ISub,
33
+ 0x23 => :IMul,
34
+ 0x24 => :IDiv,
35
+ 0x25 => :IMod,
36
+ 0x26 => :INeg,
37
+ 0x27 => :IAbs,
38
+ 0x28 => :IInc,
39
+ 0x29 => :IDec,
40
+ 0x2A => :IMin,
41
+ 0x2B => :IMax,
42
+ 0x2C => :IAnd,
43
+ 0x2D => :IOr,
44
+ 0x2E => :IXor,
45
+ 0x2F => :IShl,
46
+ 0x30 => :IShr,
47
+ 0x31 => :INot,
48
+ 0x32 => :ICmpEq,
49
+ 0x33 => :ICmpNe,
50
+ 0x34 => :ICmpLt,
51
+ 0x35 => :ICmpLe,
52
+ 0x36 => :ICmpGt,
53
+ 0x37 => :ICmpGe,
54
+
55
+ # Float Arithmetic (0x40-0x5F)
56
+ 0x40 => :FMov,
57
+ 0x41 => :FAdd,
58
+ 0x42 => :FSub,
59
+ 0x43 => :FMul,
60
+ 0x44 => :FDiv,
61
+ 0x45 => :FMod,
62
+ 0x46 => :FNeg,
63
+ 0x47 => :FAbs,
64
+ 0x48 => :FSqrt,
65
+ 0x49 => :FFloor,
66
+ 0x4A => :FCeil,
67
+ 0x4B => :FRound,
68
+ 0x4C => :FMin,
69
+ 0x4D => :FMax,
70
+ 0x4E => :FSin,
71
+ 0x4F => :FCos,
72
+ 0x50 => :FExp,
73
+ 0x51 => :FLog,
74
+ 0x52 => :FClamp,
75
+ 0x53 => :FLerp,
76
+ 0x54 => :FCmpEq,
77
+ 0x55 => :FCmpNe,
78
+ 0x56 => :FCmpLt,
79
+ 0x57 => :FCmpLe,
80
+ 0x58 => :FCmpGt,
81
+ 0x59 => :FCmpGe,
82
+
83
+ # Conversions (0x60-0x6F)
84
+ 0x60 => :IToF,
85
+ 0x61 => :FToI,
86
+ 0x62 => :BToI,
87
+ 0x63 => :IToB,
88
+
89
+ # Memory Operations (0x70-0x7F)
90
+ 0x70 => :Load8,
91
+ 0x71 => :Load16,
92
+ 0x72 => :Load32,
93
+ 0x73 => :Load64,
94
+ 0x74 => :Store8,
95
+ 0x75 => :Store16,
96
+ 0x76 => :Store32,
97
+ 0x77 => :Store64,
98
+ 0x78 => :LoadAddr,
99
+ 0x79 => :StackAlloc,
100
+
101
+ # Agent-to-Agent Communication (0x80-0x8F)
102
+ 0x80 => :ASend,
103
+ 0x81 => :ARecv,
104
+ 0x82 => :AAsk,
105
+ 0x83 => :ATell,
106
+ 0x84 => :ADelegate,
107
+ 0x85 => :ABroadcast,
108
+ 0x86 => :ASubscribe,
109
+ 0x87 => :AWait,
110
+ 0x88 => :ATrust,
111
+ 0x89 => :AVerify,
112
+
113
+ # Type/Meta Operations (0x90-0x9F)
114
+ 0x90 => :Cast,
115
+ 0x91 => :SizeOf,
116
+ 0x92 => :TypeOf,
117
+
118
+ # Bitwise Operations (0xA0-0xAF)
119
+ 0xA0 => :BAnd,
120
+ 0xA1 => :BOr,
121
+ 0xA2 => :BXor,
122
+ 0xA3 => :BShl,
123
+ 0xA4 => :BShr,
124
+ 0xA5 => :BNot,
125
+
126
+ # Vector/SIMD Operations (0xB0-0xBF)
127
+ 0xB0 => :VLoad,
128
+ 0xB1 => :VStore,
129
+ 0xB2 => :VAdd,
130
+ 0xB3 => :VMul,
131
+ 0xB4 => :VDot
132
+ }.freeze
133
+
134
+ OPCODE_NAMES = OPCODE_CLASSES.transform_values(&:to_s).freeze
135
+
136
+ # Get opcode name from byte
137
+ def self.opcode_name(opcode_byte)
138
+ OPCODE_NAMES[opcode_byte] || "Unknown_0x#{opcode_byte.to_s(16).upcase}"
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../flux_vm'
4
+
5
+ module Flux
6
+ module Runtime
7
+ # Agent shell that wraps a FluxVM and provides method_missing
8
+ # for PLATO-based capability lookup
9
+ #
10
+ # @example
11
+ # agent = Flux::Runtime::Agent.new
12
+ # agent.load(bytecode)
13
+ # agent.run
14
+ #
15
+ # @example with PLATO
16
+ # client = PLATO::Client.new
17
+ # agent = Flux::Runtime::Agent.new(plato_client: client, vessel_id: 'my-agent')
18
+ #
19
+ # # Unknown method triggers PLATO lookup
20
+ # result = agent.learned_capability(arg1, arg2)
21
+ #
22
+ class Agent
23
+ attr_reader :vm, :vessel_id
24
+
25
+ def initialize(plato_client: nil, vessel_id: nil)
26
+ @vm = FluxVM.new
27
+ @plato = plato_client
28
+ @vessel_id = vessel_id
29
+ @capabilities = {}
30
+ end
31
+
32
+ # Load bytecode into the VM
33
+ def load(bytecode)
34
+ @vm.load(bytecode)
35
+ self
36
+ end
37
+
38
+ # Run the VM
39
+ def run(max_cycles: nil)
40
+ @vm.run(max_cycles: max_cycles)
41
+ self
42
+ end
43
+
44
+ # Step one instruction
45
+ def step
46
+ @vm.step
47
+ self
48
+ end
49
+
50
+ # Reset the VM
51
+ def reset
52
+ @vm.reset
53
+ self
54
+ end
55
+
56
+ # Get current state
57
+ def state
58
+ @vm.state
59
+ end
60
+
61
+ # Get register values
62
+ def regs
63
+ @vm.regs
64
+ end
65
+
66
+ # Get execution stats
67
+ def stats
68
+ @vm.stats
69
+ end
70
+
71
+ # Delegate unknown methods to VM if they exist there
72
+ # Otherwise, look up in PLATO
73
+ def method_missing(method_name, *args, &block)
74
+ # Check if it's a VM method
75
+ if @vm.respond_to?(method_name)
76
+ @vm.send(method_name, *args, &block)
77
+ else
78
+ # Look up capability in PLATO
79
+ capability = lookup_capability(method_name)
80
+
81
+ if capability
82
+ execute_capability(capability, *args, &block)
83
+ else
84
+ super
85
+ end
86
+ end
87
+ end
88
+
89
+ # Proper introspection support
90
+ def respond_to_missing?(method_name, include_private = false)
91
+ @vm.respond_to?(method_name, include_private) ||
92
+ lookup_capability(method_name) ||
93
+ super
94
+ end
95
+
96
+ private
97
+
98
+ # Look up a capability by name in PLATO
99
+ def lookup_capability(capability_name)
100
+ return nil unless @plato && @vessel_id
101
+
102
+ @capabilities[capability_name] ||= @plato.query_tiles(
103
+ "capabilities:#{@vessel_id}",
104
+ capability_name.to_s
105
+ ).first
106
+ end
107
+
108
+ # Execute a capability from PLATO
109
+ def execute_capability(capability, *args, &block)
110
+ # Capability is a PLATO tile containing:
111
+ # - opcode: the FLUX opcode to execute
112
+ # - handler: Ruby code to run
113
+ if capability.is_a?(Hash)
114
+ if capability[:handler]
115
+ instance_exec(*args, capability[:handler], &capability[:handler])
116
+ elsif capability[:opcode]
117
+ @vm.send("op#{capability[:opcode]}", *args)
118
+ else
119
+ raise ArgumentError, 'Capability must have :handler or :opcode'
120
+ end
121
+ else
122
+ # Assume it's executable
123
+ capability.call(*args)
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../flux_vm'
4
+
5
+ module Flux
6
+ module Runtime
7
+ # Runtime opcode registration module
8
+ # Allows Ruby code to add custom FLUX opcodes dynamically
9
+ class Opcode
10
+ class << self
11
+ attr_accessor :opcode_id, :format, :execute_block
12
+
13
+ # Define a new opcode at runtime
14
+ # @param opcode_id [Integer] 0-255 opcode number
15
+ # @param format [Symbol] :A, :B, :C, :D, :E, or :G
16
+ # @param block [Proc] execution block receiving vm and operands
17
+ #
18
+ # @example
19
+ # Flux::Runtime::Opcode.define(0xF0, format: :C) do |vm, rd, ra, rb|
20
+ # vm.gp[rd] = vm.gp[ra] + vm.gp[rb] * 2
21
+ # end
22
+ def define(opcode_id, format: :C, &block)
23
+ @opcode_id = opcode_id
24
+ @format = format
25
+ @execute_block = block
26
+
27
+ # Register with VM
28
+ FluxVM.register_opcode(self)
29
+ end
30
+
31
+ # Execute this opcode on a VM
32
+ def execute(vm, *operands)
33
+ @execute_block.call(vm, *operands)
34
+ end
35
+
36
+ # Create and register in one call
37
+ def create(opcode_id, format: :C, &block)
38
+ Class.new(self) do
39
+ define(opcode_id, format: format, &block)
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ # DSL for defining opcodes
46
+ module OpcodeDSL
47
+ def define_opcode(opcode_id, format: :C, &block)
48
+ Opcode.define(opcode_id, format: format, &block)
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ # Convenience: include in any class to get define_opcode method
55
+ module FluxRuntimeOpcodeDSL
56
+ include Flux::Runtime::OpcodeDSL
57
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Superinstance
4
+ module Flux
5
+ module Runtime # Intentionally empty - version defined in version.rb
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Flux
4
+ VERSION = '1.0.0'
5
+ end
6
+
7
+ require_relative 'superinstance/flux-runtime/version'
8
+ require_relative 'superinstance/flux-runtime/flux_vm'
9
+ require_relative 'superinstance/flux-runtime/opcode'
10
+ require_relative 'superinstance/flux-runtime/assembler'
11
+ require_relative 'superinstance/flux-runtime/disassembler'
12
+ require_relative 'superinstance/flux-runtime/loader'
13
+ require_relative 'superinstance/flux-runtime/exceptions'
14
+ require_relative 'superinstance/flux-runtime/runtime/opcode'
15
+ require_relative 'superinstance/flux-runtime/runtime/agent'
16
+ require_relative 'superinstance/flux-runtime/cli'
17
+
18
+ module Superinstance
19
+ module Flux
20
+ Runtime = Flux
21
+ end
22
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: superinstance-flux-runtime
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - SuperInstance
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-05-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.12'
27
+ description: |
28
+ A pure Ruby implementation of the FLUX ISA v3.0 virtual machine.
29
+ Supports register-based execution, bytecode loading, assembly/disassembly,
30
+ and runtime metaprogramming for agent capabilities.
31
+ email: engineering@superinstance.dev
32
+ executables: []
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - lib/superinstance-flux-runtime.rb
37
+ - lib/superinstance/flux-runtime/assembler.rb
38
+ - lib/superinstance/flux-runtime/cli.rb
39
+ - lib/superinstance/flux-runtime/disassembler.rb
40
+ - lib/superinstance/flux-runtime/exceptions.rb
41
+ - lib/superinstance/flux-runtime/flux_vm.rb
42
+ - lib/superinstance/flux-runtime/loader.rb
43
+ - lib/superinstance/flux-runtime/opcode.rb
44
+ - lib/superinstance/flux-runtime/runtime/agent.rb
45
+ - lib/superinstance/flux-runtime/runtime/opcode.rb
46
+ - lib/superinstance/flux-runtime/version.rb
47
+ homepage: https://github.com/SuperInstance/superinstance-flux-runtime
48
+ licenses:
49
+ - MIT
50
+ metadata: {}
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '3.0'
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubygems_version: 3.3.5
67
+ signing_key:
68
+ specification_version: 4
69
+ summary: Pure Ruby FLUX ISA v3.0 virtual machine with runtime metaprogramming
70
+ test_files: []