summaryrefslogtreecommitdiff
path: root/src/pkg/exp/ogle/rvalue.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/exp/ogle/rvalue.go')
-rw-r--r--src/pkg/exp/ogle/rvalue.go515
1 files changed, 0 insertions, 515 deletions
diff --git a/src/pkg/exp/ogle/rvalue.go b/src/pkg/exp/ogle/rvalue.go
deleted file mode 100644
index 3d630f936..000000000
--- a/src/pkg/exp/ogle/rvalue.go
+++ /dev/null
@@ -1,515 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ogle
-
-import (
- "debug/proc"
- "exp/eval"
- "fmt"
-)
-
-// A RemoteMismatchError occurs when an operation that requires two
-// identical remote processes is given different process. For
-// example, this occurs when trying to set a pointer in one process to
-// point to something in another process.
-type RemoteMismatchError string
-
-func (e RemoteMismatchError) String() string { return string(e) }
-
-// A ReadOnlyError occurs when attempting to set or assign to a
-// read-only value.
-type ReadOnlyError string
-
-func (e ReadOnlyError) String() string { return string(e) }
-
-// A maker is a function that converts a remote address into an
-// interpreter Value.
-type maker func(remote) eval.Value
-
-type remoteValue interface {
- addr() remote
-}
-
-// remote represents an address in a remote process.
-type remote struct {
- base proc.Word
- p *Process
-}
-
-func (v remote) Get(a aborter, size int) uint64 {
- // TODO(austin) This variable might temporarily be in a
- // register. We could trace the assembly back from the
- // current PC, looking for the beginning of the function or a
- // call (both of which guarantee that the variable is in
- // memory), or an instruction that loads the variable into a
- // register.
- //
- // TODO(austin) If this is a local variable, it might not be
- // live at this PC. In fact, because the compiler reuses
- // slots, there might even be a different local variable at
- // this location right now. A simple solution to both
- // problems is to include the range of PC's over which a local
- // variable is live in the symbol table.
- //
- // TODO(austin) We need to prevent the remote garbage
- // collector from collecting objects out from under us.
- var arr [8]byte
- buf := arr[0:size]
- _, err := v.p.Peek(v.base, buf)
- if err != nil {
- a.Abort(err)
- }
- return uint64(v.p.ToWord(buf))
-}
-
-func (v remote) Set(a aborter, size int, x uint64) {
- var arr [8]byte
- buf := arr[0:size]
- v.p.FromWord(proc.Word(x), buf)
- _, err := v.p.Poke(v.base, buf)
- if err != nil {
- a.Abort(err)
- }
-}
-
-func (v remote) plus(x proc.Word) remote { return remote{v.base + x, v.p} }
-
-func tryRVString(f func(a aborter) string) string {
- var s string
- err := try(func(a aborter) { s = f(a) })
- if err != nil {
- return fmt.Sprintf("<error: %v>", err)
- }
- return s
-}
-
-/*
- * Bool
- */
-
-type remoteBool struct {
- r remote
-}
-
-func (v remoteBool) String() string {
- return tryRVString(func(a aborter) string { return fmt.Sprintf("%v", v.aGet(a)) })
-}
-
-func (v remoteBool) Assign(t *eval.Thread, o eval.Value) {
- v.Set(t, o.(eval.BoolValue).Get(t))
-}
-
-func (v remoteBool) Get(t *eval.Thread) bool { return v.aGet(t) }
-
-func (v remoteBool) aGet(a aborter) bool { return v.r.Get(a, 1) != 0 }
-
-func (v remoteBool) Set(t *eval.Thread, x bool) {
- v.aSet(t, x)
-}
-
-func (v remoteBool) aSet(a aborter, x bool) {
- if x {
- v.r.Set(a, 1, 1)
- } else {
- v.r.Set(a, 1, 0)
- }
-}
-
-func (v remoteBool) addr() remote { return v.r }
-
-func mkBool(r remote) eval.Value { return remoteBool{r} }
-
-/*
- * Uint
- */
-
-type remoteUint struct {
- r remote
- size int
-}
-
-func (v remoteUint) String() string {
- return tryRVString(func(a aborter) string { return fmt.Sprintf("%v", v.aGet(a)) })
-}
-
-func (v remoteUint) Assign(t *eval.Thread, o eval.Value) {
- v.Set(t, o.(eval.UintValue).Get(t))
-}
-
-func (v remoteUint) Get(t *eval.Thread) uint64 {
- return v.aGet(t)
-}
-
-func (v remoteUint) aGet(a aborter) uint64 { return v.r.Get(a, v.size) }
-
-func (v remoteUint) Set(t *eval.Thread, x uint64) {
- v.aSet(t, x)
-}
-
-func (v remoteUint) aSet(a aborter, x uint64) { v.r.Set(a, v.size, x) }
-
-func (v remoteUint) addr() remote { return v.r }
-
-func mkUint8(r remote) eval.Value { return remoteUint{r, 1} }
-
-func mkUint16(r remote) eval.Value { return remoteUint{r, 2} }
-
-func mkUint32(r remote) eval.Value { return remoteUint{r, 4} }
-
-func mkUint64(r remote) eval.Value { return remoteUint{r, 8} }
-
-func mkUint(r remote) eval.Value { return remoteUint{r, r.p.IntSize()} }
-
-func mkUintptr(r remote) eval.Value { return remoteUint{r, r.p.PtrSize()} }
-
-/*
- * Int
- */
-
-type remoteInt struct {
- r remote
- size int
-}
-
-func (v remoteInt) String() string {
- return tryRVString(func(a aborter) string { return fmt.Sprintf("%v", v.aGet(a)) })
-}
-
-func (v remoteInt) Assign(t *eval.Thread, o eval.Value) {
- v.Set(t, o.(eval.IntValue).Get(t))
-}
-
-func (v remoteInt) Get(t *eval.Thread) int64 { return v.aGet(t) }
-
-func (v remoteInt) aGet(a aborter) int64 { return int64(v.r.Get(a, v.size)) }
-
-func (v remoteInt) Set(t *eval.Thread, x int64) {
- v.aSet(t, x)
-}
-
-func (v remoteInt) aSet(a aborter, x int64) { v.r.Set(a, v.size, uint64(x)) }
-
-func (v remoteInt) addr() remote { return v.r }
-
-func mkInt8(r remote) eval.Value { return remoteInt{r, 1} }
-
-func mkInt16(r remote) eval.Value { return remoteInt{r, 2} }
-
-func mkInt32(r remote) eval.Value { return remoteInt{r, 4} }
-
-func mkInt64(r remote) eval.Value { return remoteInt{r, 8} }
-
-func mkInt(r remote) eval.Value { return remoteInt{r, r.p.IntSize()} }
-
-/*
- * Float
- */
-
-type remoteFloat struct {
- r remote
- size int
-}
-
-func (v remoteFloat) String() string {
- return tryRVString(func(a aborter) string { return fmt.Sprintf("%v", v.aGet(a)) })
-}
-
-func (v remoteFloat) Assign(t *eval.Thread, o eval.Value) {
- v.Set(t, o.(eval.FloatValue).Get(t))
-}
-
-func (v remoteFloat) Get(t *eval.Thread) float64 {
- return v.aGet(t)
-}
-
-func (v remoteFloat) aGet(a aborter) float64 {
- bits := v.r.Get(a, v.size)
- switch v.size {
- case 4:
- return float64(v.r.p.ToFloat32(uint32(bits)))
- case 8:
- return v.r.p.ToFloat64(bits)
- }
- panic("Unexpected float size")
-}
-
-func (v remoteFloat) Set(t *eval.Thread, x float64) {
- v.aSet(t, x)
-}
-
-func (v remoteFloat) aSet(a aborter, x float64) {
- var bits uint64
- switch v.size {
- case 4:
- bits = uint64(v.r.p.FromFloat32(float32(x)))
- case 8:
- bits = v.r.p.FromFloat64(x)
- default:
- panic("Unexpected float size")
- }
- v.r.Set(a, v.size, bits)
-}
-
-func (v remoteFloat) addr() remote { return v.r }
-
-func mkFloat32(r remote) eval.Value { return remoteFloat{r, 4} }
-
-func mkFloat64(r remote) eval.Value { return remoteFloat{r, 8} }
-
-func mkFloat(r remote) eval.Value { return remoteFloat{r, r.p.FloatSize()} }
-
-/*
- * String
- */
-
-type remoteString struct {
- r remote
-}
-
-func (v remoteString) String() string {
- return tryRVString(func(a aborter) string { return v.aGet(a) })
-}
-
-func (v remoteString) Assign(t *eval.Thread, o eval.Value) {
- v.Set(t, o.(eval.StringValue).Get(t))
-}
-
-func (v remoteString) Get(t *eval.Thread) string {
- return v.aGet(t)
-}
-
-func (v remoteString) aGet(a aborter) string {
- rs := v.r.p.runtime.String.mk(v.r).(remoteStruct)
- str := proc.Word(rs.field(v.r.p.f.String.Str).(remoteUint).aGet(a))
- len := rs.field(v.r.p.f.String.Len).(remoteInt).aGet(a)
-
- bytes := make([]uint8, len)
- _, err := v.r.p.Peek(str, bytes)
- if err != nil {
- a.Abort(err)
- }
- return string(bytes)
-}
-
-func (v remoteString) Set(t *eval.Thread, x string) {
- v.aSet(t, x)
-}
-
-func (v remoteString) aSet(a aborter, x string) {
- // TODO(austin) This isn't generally possible without the
- // ability to allocate remote memory.
- a.Abort(ReadOnlyError("remote strings cannot be assigned to"))
-}
-
-func mkString(r remote) eval.Value { return remoteString{r} }
-
-/*
- * Array
- */
-
-type remoteArray struct {
- r remote
- len int64
- elemType *remoteType
-}
-
-func (v remoteArray) String() string {
- res := "{"
- for i := int64(0); i < v.len; i++ {
- if i > 0 {
- res += ", "
- }
- res += v.elem(i).String()
- }
- return res + "}"
-}
-
-func (v remoteArray) Assign(t *eval.Thread, o eval.Value) {
- // TODO(austin) Could do a bigger memcpy if o is a
- // remoteArray in the same Process.
- oa := o.(eval.ArrayValue)
- for i := int64(0); i < v.len; i++ {
- v.Elem(t, i).Assign(t, oa.Elem(t, i))
- }
-}
-
-func (v remoteArray) Get(t *eval.Thread) eval.ArrayValue {
- return v
-}
-
-func (v remoteArray) Elem(t *eval.Thread, i int64) eval.Value {
- return v.elem(i)
-}
-
-func (v remoteArray) elem(i int64) eval.Value {
- return v.elemType.mk(v.r.plus(proc.Word(int64(v.elemType.size) * i)))
-}
-
-func (v remoteArray) Sub(i int64, len int64) eval.ArrayValue {
- return remoteArray{v.r.plus(proc.Word(int64(v.elemType.size) * i)), len, v.elemType}
-}
-
-/*
- * Struct
- */
-
-type remoteStruct struct {
- r remote
- layout []remoteStructField
-}
-
-type remoteStructField struct {
- offset int
- fieldType *remoteType
-}
-
-func (v remoteStruct) String() string {
- res := "{"
- for i := range v.layout {
- if i > 0 {
- res += ", "
- }
- res += v.field(i).String()
- }
- return res + "}"
-}
-
-func (v remoteStruct) Assign(t *eval.Thread, o eval.Value) {
- // TODO(austin) Could do a bigger memcpy.
- oa := o.(eval.StructValue)
- l := len(v.layout)
- for i := 0; i < l; i++ {
- v.Field(t, i).Assign(t, oa.Field(t, i))
- }
-}
-
-func (v remoteStruct) Get(t *eval.Thread) eval.StructValue {
- return v
-}
-
-func (v remoteStruct) Field(t *eval.Thread, i int) eval.Value {
- return v.field(i)
-}
-
-func (v remoteStruct) field(i int) eval.Value {
- f := &v.layout[i]
- return f.fieldType.mk(v.r.plus(proc.Word(f.offset)))
-}
-
-func (v remoteStruct) addr() remote { return v.r }
-
-/*
- * Pointer
- */
-
-// TODO(austin) Comparing two remote pointers for equality in the
-// interpreter will crash it because the Value's returned from
-// remotePtr.Get() will be structs.
-
-type remotePtr struct {
- r remote
- elemType *remoteType
-}
-
-func (v remotePtr) String() string {
- return tryRVString(func(a aborter) string {
- e := v.aGet(a)
- if e == nil {
- return "<nil>"
- }
- return "&" + e.String()
- })
-}
-
-func (v remotePtr) Assign(t *eval.Thread, o eval.Value) {
- v.Set(t, o.(eval.PtrValue).Get(t))
-}
-
-func (v remotePtr) Get(t *eval.Thread) eval.Value {
- return v.aGet(t)
-}
-
-func (v remotePtr) aGet(a aborter) eval.Value {
- addr := proc.Word(v.r.Get(a, v.r.p.PtrSize()))
- if addr == 0 {
- return nil
- }
- return v.elemType.mk(remote{addr, v.r.p})
-}
-
-func (v remotePtr) Set(t *eval.Thread, x eval.Value) {
- v.aSet(t, x)
-}
-
-func (v remotePtr) aSet(a aborter, x eval.Value) {
- if x == nil {
- v.r.Set(a, v.r.p.PtrSize(), 0)
- return
- }
- xr, ok := x.(remoteValue)
- if !ok || v.r.p != xr.addr().p {
- a.Abort(RemoteMismatchError("remote pointer must point within the same process"))
- }
- v.r.Set(a, v.r.p.PtrSize(), uint64(xr.addr().base))
-}
-
-func (v remotePtr) addr() remote { return v.r }
-
-/*
- * Slice
- */
-
-type remoteSlice struct {
- r remote
- elemType *remoteType
-}
-
-func (v remoteSlice) String() string {
- return tryRVString(func(a aborter) string {
- b := v.aGet(a).Base
- if b == nil {
- return "<nil>"
- }
- return b.String()
- })
-}
-
-func (v remoteSlice) Assign(t *eval.Thread, o eval.Value) {
- v.Set(t, o.(eval.SliceValue).Get(t))
-}
-
-func (v remoteSlice) Get(t *eval.Thread) eval.Slice {
- return v.aGet(t)
-}
-
-func (v remoteSlice) aGet(a aborter) eval.Slice {
- rs := v.r.p.runtime.Slice.mk(v.r).(remoteStruct)
- base := proc.Word(rs.field(v.r.p.f.Slice.Array).(remoteUint).aGet(a))
- nel := rs.field(v.r.p.f.Slice.Len).(remoteInt).aGet(a)
- cap := rs.field(v.r.p.f.Slice.Cap).(remoteInt).aGet(a)
- if base == 0 {
- return eval.Slice{nil, nel, cap}
- }
- return eval.Slice{remoteArray{remote{base, v.r.p}, nel, v.elemType}, nel, cap}
-}
-
-func (v remoteSlice) Set(t *eval.Thread, x eval.Slice) {
- v.aSet(t, x)
-}
-
-func (v remoteSlice) aSet(a aborter, x eval.Slice) {
- rs := v.r.p.runtime.Slice.mk(v.r).(remoteStruct)
- if x.Base == nil {
- rs.field(v.r.p.f.Slice.Array).(remoteUint).aSet(a, 0)
- } else {
- ar, ok := x.Base.(remoteArray)
- if !ok || v.r.p != ar.r.p {
- a.Abort(RemoteMismatchError("remote slice must point within the same process"))
- }
- rs.field(v.r.p.f.Slice.Array).(remoteUint).aSet(a, uint64(ar.r.base))
- }
- rs.field(v.r.p.f.Slice.Len).(remoteInt).aSet(a, x.Len)
- rs.field(v.r.p.f.Slice.Cap).(remoteInt).aSet(a, x.Cap)
-}