about summary refs log tree commit diff
path: root/pkg/lang/vm/exec.go
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2022-05-28 01:22:17 +0000
committerGitHub <noreply@github.com>2022-05-28 01:22:17 +0000
commit0a7700112f82e634a957685bee0cbaa3458f4945 (patch)
tree847c397970d7d852bc988a7a01f4625eae443edb /pkg/lang/vm/exec.go
parent83d1dc87f3336d70ccda476627c70c282b7b6e11 (diff)
downloadjinx-0a7700112f82e634a957685bee0cbaa3458f4945.tar.zst
jinx-0a7700112f82e634a957685bee0cbaa3458f4945.zip
Harden VM Mem
Diffstat (limited to 'pkg/lang/vm/exec.go')
-rw-r--r--pkg/lang/vm/exec.go103
1 files changed, 77 insertions, 26 deletions
diff --git a/pkg/lang/vm/exec.go b/pkg/lang/vm/exec.go
index ee977b7..c9b8615 100644
--- a/pkg/lang/vm/exec.go
+++ b/pkg/lang/vm/exec.go
@@ -14,8 +14,14 @@ func (vm *VM) execPushFloat(x float64) {
 	vm.stack.Push(value.NewFloat(x))
 }
 
-func (vm *VM) execPushString(str string) {
-	vm.stack.Push(value.NewString(&vm.memory, str))
+func (vm *VM) execPushString(str string) error {
+	val, err := value.NewString(&vm.memory, str)
+	if err != nil {
+		return err
+	}
+
+	vm.stack.Push(val)
+	return nil
 }
 
 func (vm *VM) execPushBool(b bool) {
@@ -26,8 +32,14 @@ func (vm *VM) execPushNull() {
 	vm.stack.Push(value.NewNull())
 }
 
-func (vm *VM) execPushArray() {
-	vm.stack.Push(value.NewArray(&vm.memory, []value.Value{}))
+func (vm *VM) execPushArray() error {
+	val, err := value.NewArray(&vm.memory, []value.Value{})
+	if err != nil {
+		return err
+	}
+
+	vm.stack.Push(val)
+	return nil
 }
 
 func (vm *VM) execPushFunction(pc int) {
@@ -47,15 +59,23 @@ func (vm *VM) execGetLocal(offset int) error {
 }
 
 func (vm *VM) execGetEnv(envIndex int) error {
-	envPtr := vm.stack.CurrentCallEnv()
-	env := vm.memory.Get(envPtr).(value.Env)
+	envCell, err := vm.getMemCell(vm.stack.CurrentCallEnv(), mem.CellKindEnv, false)
+	if err != nil {
+		return err
+	}
+	env := envCell.(value.EnvCell).Get()
 
 	// First check outlet.
 	outletPtr := env.GetOutlet(envIndex)
-	outlet := vm.memory.Get(outletPtr)
-	if outlet != nil {
+	outletCell, err := vm.getMemCell(outletPtr, mem.CellKindOutlet, true)
+	if err != nil {
+		return err
+	}
+
+	if outletCell != nil {
 		// Outlet is not null, so value escaped.
-		val := outlet.(value.Value).Clone(&vm.memory)
+		outlet := outletCell.(value.OutletCell).Get()
+		val := outlet.Clone(&vm.memory)
 		vm.stack.Push(val)
 		return nil
 	}
@@ -79,14 +99,23 @@ func (vm *VM) execSetEnv(envIndex int) error {
 		return err
 	}
 
-	envPtr := vm.stack.CurrentCallEnv()
-	env := vm.memory.Get(envPtr).(value.Env)
+	envCell, err := vm.getMemCell(vm.stack.CurrentCallEnv(), mem.CellKindEnv, false)
+	if err != nil {
+		return err
+	}
+	env := envCell.(value.EnvCell).Get()
 
 	outletPtr := env.GetOutlet(envIndex)
-	outlet := vm.memory.Get(outletPtr)
-	if outlet != nil {
-		outlet.(value.Value).Drop(&vm.memory)
-		vm.memory.Set(outletPtr, new)
+	outletCell, err := vm.getMemCell(outletPtr, mem.CellKindOutlet, true)
+	if err != nil {
+		return err
+	}
+
+	if outletCell != nil {
+		// Outlet is not null, so value escaped.
+		outlet := outletCell.(value.OutletCell).Get()
+		outlet.Drop(&vm.memory)
+		vm.memory.Set(outletPtr, value.OutletCell(new))
 		return nil
 	}
 
@@ -119,8 +148,12 @@ func (vm *VM) execAddToEnv(localIndex int) error {
 	var envPtr mem.Ptr
 	if fn.Env().IsNull() {
 		// Allocate new Env.
-		envPtr = vm.memory.Allocate(mem.CellKindEnv)
-		vm.memory.Set(envPtr, value.NewEnv())
+		envPtr, err = vm.memory.Allocate(mem.CellKindEnv)
+		if err != nil {
+			return err
+		}
+
+		vm.memory.Set(envPtr, value.EnvCell(value.NewEnv()))
 		fn = fn.WithEnv(envPtr)
 	} else {
 		envPtr = fn.Env()
@@ -133,16 +166,24 @@ func (vm *VM) execAddToEnv(localIndex int) error {
 	}
 
 	if local.Outlet().IsNull() {
-		outlet := vm.memory.Allocate(mem.CellKindOutlet)
-		local = local.WithOutlet(outlet)
+		outletPtr, err := vm.memory.Allocate(mem.CellKindOutlet)
+		if err != nil {
+			return err
+		}
+		local = local.WithOutlet(outletPtr)
 	}
 
 	// Add local to env.
 	stackIndex := vm.stack.LocalToStackIndex(localIndex)
 
-	env := vm.memory.Get(envPtr).(value.Env)
+	envCell, err := vm.getMemCell(envPtr, mem.CellKindEnv, false)
+	if err != nil {
+		return err
+	}
+
+	env := envCell.(value.EnvCell).Get()
 	env.Add(stackIndex, local.Outlet())
-	vm.memory.Set(envPtr, env)
+	vm.memory.Set(envPtr, value.EnvCell(env))
 
 	// Push function back onto stack.
 	f = f.WithData(fn)
@@ -295,15 +336,22 @@ func (vm *VM) execIndex() error {
 		switch i.Type().Kind {
 		case value.IntType:
 			idx := i.Data().(value.IntData).Get()
-			len := int64(arr.Len(&vm.memory))
-			if idx < 0 || idx >= len {
+			len, err := arr.Len(&vm.memory)
+			if err != nil {
+				return err
+			}
+			if idx < 0 || idx >= int64(len) {
 				return ErrArrayIndexOutOfBounds{
 					Index: int(idx),
 					Len:   int(len),
 				}
 			}
 
-			val := arr.At(&vm.memory, int(idx)).Clone(&vm.memory)
+			val, err := arr.At(&vm.memory, int(idx))
+			if err != nil {
+				return err
+			}
+			val = val.Clone(&vm.memory)
 			vm.stack.Push(val)
 		default:
 			return ErrInvalidOperandTypes{
@@ -458,8 +506,11 @@ func (vm *VM) execTempArrLen() error {
 	switch a.Type().Kind {
 	case value.ArrayType:
 		arr := a.Data().(value.ArrayData)
-		len := int64(arr.Len(&vm.memory))
-		res := value.NewInt(len)
+		len, err := arr.Len(&vm.memory)
+		if err != nil {
+			return err
+		}
+		res := value.NewInt(int64(len))
 		vm.stack.Push(res)
 	default:
 		return ErrInvalidOperandTypes{