about summary refs log tree commit diff
path: root/pkg/lang/vm/value/data.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/value/data.go
parent83d1dc87f3336d70ccda476627c70c282b7b6e11 (diff)
downloadjinx-0a7700112f82e634a957685bee0cbaa3458f4945.tar.zst
jinx-0a7700112f82e634a957685bee0cbaa3458f4945.zip
Harden VM Mem
Diffstat (limited to 'pkg/lang/vm/value/data.go')
-rw-r--r--pkg/lang/vm/value/data.go80
1 files changed, 52 insertions, 28 deletions
diff --git a/pkg/lang/vm/value/data.go b/pkg/lang/vm/value/data.go
index a49753e..2e3b3e6 100644
--- a/pkg/lang/vm/value/data.go
+++ b/pkg/lang/vm/value/data.go
@@ -8,7 +8,7 @@ import (
 )
 
 type Data interface {
-	String(*mem.Mem) string
+	String(*mem.Mem) (string, error)
 }
 
 type IntData int64
@@ -17,8 +17,8 @@ func (i IntData) Get() int64 {
 	return int64(i)
 }
 
-func (i IntData) String(_ *mem.Mem) string {
-	return strconv.FormatInt(int64(i), 10)
+func (i IntData) String(_ *mem.Mem) (string, error) {
+	return strconv.FormatInt(int64(i), 10), nil
 }
 
 type FloatData float64
@@ -27,17 +27,20 @@ func (f FloatData) Get() float64 {
 	return float64(f)
 }
 
-func (f FloatData) String(_ *mem.Mem) string {
-	return strconv.FormatFloat(float64(f), 'f', -1, 64)
+func (f FloatData) String(_ *mem.Mem) (string, error) {
+	return strconv.FormatFloat(float64(f), 'f', -1, 64), nil
 }
 
 type StringData struct {
 	data mem.Ptr
 }
 
-func (s StringData) String(m *mem.Mem) string {
-	data := m.Get(s.data)
-	return "\"" + data.(string) + "\""
+func (s StringData) String(m *mem.Mem) (string, error) {
+	if data, err := m.Get(s.data); err == nil {
+		return "\"" + data.(StringCell).Get() + "\"", nil
+	} else {
+		return "", err
+	}
 }
 
 type BoolData bool
@@ -46,16 +49,21 @@ func (b BoolData) Get() bool {
 	return bool(b)
 }
 
-func (b BoolData) String(_ *mem.Mem) string {
-	return strconv.FormatBool(bool(b))
+func (b BoolData) String(_ *mem.Mem) (string, error) {
+	return strconv.FormatBool(bool(b)), nil
 }
 
 type ArrayData struct {
 	data mem.Ptr
 }
 
-func (a ArrayData) String(m *mem.Mem) string {
-	arr := m.Get(a.data).([]Value)
+func (a ArrayData) String(m *mem.Mem) (string, error) {
+	val, err := m.Get(a.data)
+	if err != nil {
+		return "", err
+	}
+
+	arr := val.(ArrayCell).Get()
 
 	builder := strings.Builder{}
 	builder.WriteString("[")
@@ -63,29 +71,45 @@ func (a ArrayData) String(m *mem.Mem) string {
 		if i > 0 {
 			builder.WriteString(", ")
 		}
-		builder.WriteString(v.Data().String(m))
+		if s, err := v.Data().String(m); err == nil {
+			builder.WriteString(s)
+		} else {
+			return "", err
+		}
 	}
 	builder.WriteString("]")
-	return builder.String()
+	return builder.String(), nil
 }
 
-func (a ArrayData) Len(m *mem.Mem) int {
-	data := m.Get(a.data)
-	arr := data.([]Value)
-	return len(arr)
+func (a ArrayData) Len(m *mem.Mem) (int, error) {
+	data, err := m.Get(a.data)
+	if err != nil {
+		return 0, err
+	}
+	arr := data.(ArrayCell).Get()
+	return len(arr), nil
 }
 
-func (a ArrayData) At(m *mem.Mem, i int) Value {
-	data := m.Get(a.data)
-	arr := data.([]Value)
-	return arr[i]
+func (a ArrayData) At(m *mem.Mem, i int) (Value, error) {
+	data, err := m.Get(a.data)
+	if err != nil {
+		return Value{}, err
+	}
+	arr := data.(ArrayCell).Get()
+	return arr[i], nil
 }
 
-func (a ArrayData) Push(m *mem.Mem, v Value) {
-	data := m.Get(a.data)
-	arr := data.([]Value)
+func (a ArrayData) Push(m *mem.Mem, v Value) error {
+	data, err := m.Get(a.data)
+	if err != nil {
+		return err
+	}
+
+	arr := data.(ArrayCell).Get()
 	arr = append(arr, v)
-	m.Set(a.data, arr)
+	m.Set(a.data, ArrayCell(arr))
+
+	return nil
 }
 
 type NullData struct{}
@@ -107,8 +131,8 @@ func (f FunctionData) WithEnv(env mem.Ptr) FunctionData {
 	return FunctionData{pc: f.pc, env: env}
 }
 
-func (f FunctionData) String(_ *mem.Mem) string {
-	return fmt.Sprintf("<fn %d>", f.pc)
+func (f FunctionData) String(_ *mem.Mem) (string, error) {
+	return fmt.Sprintf("<fn %d>", f.pc), nil
 }
 
 type ObjectData struct{} // TODO