Commit b1e64585 authored by Rob Pike's avatar Rob Pike

move dereference code out of the ops and into the interpreter loops.

R=rsc
DELTA=574  (40 added, 149 deleted, 385 changed)
OCL=31017
CL=31019
parent c701af8c
...@@ -122,6 +122,11 @@ func newEncState(b *bytes.Buffer) *EncState { ...@@ -122,6 +122,11 @@ func newEncState(b *bytes.Buffer) *EncState {
return state; return state;
} }
func encAddrOf(state *EncState, instr *encInstr) unsafe.Pointer {
p := unsafe.Pointer(state.base+instr.offset);
return encIndirect(p, instr.indir);
}
// Test instruction execution for encoding. // Test instruction execution for encoding.
// Do not run the machine yet; instead do individual instructions crafted by hand. // Do not run the machine yet; instead do individual instructions crafted by hand.
func TestScalarEncInstructions(t *testing.T) { func TestScalarEncInstructions(t *testing.T) {
...@@ -136,17 +141,17 @@ func TestScalarEncInstructions(t *testing.T) { ...@@ -136,17 +141,17 @@ func TestScalarEncInstructions(t *testing.T) {
instr := &encInstr{ encBool, 0, 0, 0 }; instr := &encInstr{ encBool, 0, 0, 0 };
state := newEncState(b); state := newEncState(b);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 0; state.fieldnum = 0;
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 1; state.fieldnum = 1;
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
if !bytes.Equal(boolResult, b.Data()) { if !bytes.Equal(boolResult, b.Data()) {
t.Errorf("bool enc instructions: expected % x got % x", boolResult, b.Data()) t.Errorf("bool enc instructions: expected % x got % x", boolResult, b.Data())
} }
...@@ -162,17 +167,17 @@ func TestScalarEncInstructions(t *testing.T) { ...@@ -162,17 +167,17 @@ func TestScalarEncInstructions(t *testing.T) {
instr := &encInstr{ encInt, 0, 0, 0 }; instr := &encInstr{ encInt, 0, 0, 0 };
state := newEncState(b); state := newEncState(b);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 0; state.fieldnum = 0;
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 1; state.fieldnum = 1;
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
if !bytes.Equal(signedResult, b.Data()) { if !bytes.Equal(signedResult, b.Data()) {
t.Errorf("int enc instructions: expected % x got % x", signedResult, b.Data()) t.Errorf("int enc instructions: expected % x got % x", signedResult, b.Data())
} }
...@@ -188,17 +193,17 @@ func TestScalarEncInstructions(t *testing.T) { ...@@ -188,17 +193,17 @@ func TestScalarEncInstructions(t *testing.T) {
instr := &encInstr{ encUint, 0, 0, 0 }; instr := &encInstr{ encUint, 0, 0, 0 };
state := newEncState(b); state := newEncState(b);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 0; state.fieldnum = 0;
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 1; state.fieldnum = 1;
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
if !bytes.Equal(unsignedResult, b.Data()) { if !bytes.Equal(unsignedResult, b.Data()) {
t.Errorf("uint enc instructions: expected % x got % x", unsignedResult, b.Data()) t.Errorf("uint enc instructions: expected % x got % x", unsignedResult, b.Data())
} }
...@@ -214,17 +219,17 @@ func TestScalarEncInstructions(t *testing.T) { ...@@ -214,17 +219,17 @@ func TestScalarEncInstructions(t *testing.T) {
instr := &encInstr{ encInt, 0, 0, 0 }; instr := &encInstr{ encInt, 0, 0, 0 };
state := newEncState(b); state := newEncState(b);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 0; state.fieldnum = 0;
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 1; state.fieldnum = 1;
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
if !bytes.Equal(signedResult, b.Data()) { if !bytes.Equal(signedResult, b.Data()) {
t.Errorf("int8 enc instructions: expected % x got % x", signedResult, b.Data()) t.Errorf("int8 enc instructions: expected % x got % x", signedResult, b.Data())
} }
...@@ -240,17 +245,17 @@ func TestScalarEncInstructions(t *testing.T) { ...@@ -240,17 +245,17 @@ func TestScalarEncInstructions(t *testing.T) {
instr := &encInstr{ encUint, 0, 0, 0 }; instr := &encInstr{ encUint, 0, 0, 0 };
state := newEncState(b); state := newEncState(b);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 0; state.fieldnum = 0;
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 1; state.fieldnum = 1;
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
if !bytes.Equal(unsignedResult, b.Data()) { if !bytes.Equal(unsignedResult, b.Data()) {
t.Errorf("uint8 enc instructions: expected % x got % x", unsignedResult, b.Data()) t.Errorf("uint8 enc instructions: expected % x got % x", unsignedResult, b.Data())
} }
...@@ -266,17 +271,17 @@ func TestScalarEncInstructions(t *testing.T) { ...@@ -266,17 +271,17 @@ func TestScalarEncInstructions(t *testing.T) {
instr := &encInstr{ encInt16, 0, 0, 0 }; instr := &encInstr{ encInt16, 0, 0, 0 };
state := newEncState(b); state := newEncState(b);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 0; state.fieldnum = 0;
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 1; state.fieldnum = 1;
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
if !bytes.Equal(signedResult, b.Data()) { if !bytes.Equal(signedResult, b.Data()) {
t.Errorf("int16 enc instructions: expected % x got % x", signedResult, b.Data()) t.Errorf("int16 enc instructions: expected % x got % x", signedResult, b.Data())
} }
...@@ -292,17 +297,17 @@ func TestScalarEncInstructions(t *testing.T) { ...@@ -292,17 +297,17 @@ func TestScalarEncInstructions(t *testing.T) {
instr := &encInstr{ encUint16, 0, 0, 0 }; instr := &encInstr{ encUint16, 0, 0, 0 };
state := newEncState(b); state := newEncState(b);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 0; state.fieldnum = 0;
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 1; state.fieldnum = 1;
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
if !bytes.Equal(unsignedResult, b.Data()) { if !bytes.Equal(unsignedResult, b.Data()) {
t.Errorf("uint16 enc instructions: expected % x got % x", unsignedResult, b.Data()) t.Errorf("uint16 enc instructions: expected % x got % x", unsignedResult, b.Data())
} }
...@@ -318,17 +323,17 @@ func TestScalarEncInstructions(t *testing.T) { ...@@ -318,17 +323,17 @@ func TestScalarEncInstructions(t *testing.T) {
instr := &encInstr{ encInt32, 0, 0, 0 }; instr := &encInstr{ encInt32, 0, 0, 0 };
state := newEncState(b); state := newEncState(b);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 0; state.fieldnum = 0;
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 1; state.fieldnum = 1;
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
if !bytes.Equal(signedResult, b.Data()) { if !bytes.Equal(signedResult, b.Data()) {
t.Errorf("int32 enc instructions: expected % x got % x", signedResult, b.Data()) t.Errorf("int32 enc instructions: expected % x got % x", signedResult, b.Data())
} }
...@@ -344,17 +349,17 @@ func TestScalarEncInstructions(t *testing.T) { ...@@ -344,17 +349,17 @@ func TestScalarEncInstructions(t *testing.T) {
instr := &encInstr{ encUint32, 0, 0, 0 }; instr := &encInstr{ encUint32, 0, 0, 0 };
state := newEncState(b); state := newEncState(b);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 0; state.fieldnum = 0;
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 1; state.fieldnum = 1;
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
if !bytes.Equal(unsignedResult, b.Data()) { if !bytes.Equal(unsignedResult, b.Data()) {
t.Errorf("uint32 enc instructions: expected % x got % x", unsignedResult, b.Data()) t.Errorf("uint32 enc instructions: expected % x got % x", unsignedResult, b.Data())
} }
...@@ -370,17 +375,17 @@ func TestScalarEncInstructions(t *testing.T) { ...@@ -370,17 +375,17 @@ func TestScalarEncInstructions(t *testing.T) {
instr := &encInstr{ encInt64, 0, 0, 0 }; instr := &encInstr{ encInt64, 0, 0, 0 };
state := newEncState(b); state := newEncState(b);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 0; state.fieldnum = 0;
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 1; state.fieldnum = 1;
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
if !bytes.Equal(signedResult, b.Data()) { if !bytes.Equal(signedResult, b.Data()) {
t.Errorf("int64 enc instructions: expected % x got % x", signedResult, b.Data()) t.Errorf("int64 enc instructions: expected % x got % x", signedResult, b.Data())
} }
...@@ -396,17 +401,17 @@ func TestScalarEncInstructions(t *testing.T) { ...@@ -396,17 +401,17 @@ func TestScalarEncInstructions(t *testing.T) {
instr := &encInstr{ encUint, 0, 0, 0 }; instr := &encInstr{ encUint, 0, 0, 0 };
state := newEncState(b); state := newEncState(b);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 0; state.fieldnum = 0;
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 1; state.fieldnum = 1;
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
if !bytes.Equal(unsignedResult, b.Data()) { if !bytes.Equal(unsignedResult, b.Data()) {
t.Errorf("uint64 enc instructions: expected % x got % x", unsignedResult, b.Data()) t.Errorf("uint64 enc instructions: expected % x got % x", unsignedResult, b.Data())
} }
...@@ -422,17 +427,17 @@ func TestScalarEncInstructions(t *testing.T) { ...@@ -422,17 +427,17 @@ func TestScalarEncInstructions(t *testing.T) {
instr := &encInstr{ encFloat, 0, 0, 0 }; instr := &encInstr{ encFloat, 0, 0, 0 };
state := newEncState(b); state := newEncState(b);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 0; state.fieldnum = 0;
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 1; state.fieldnum = 1;
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
if !bytes.Equal(floatResult, b.Data()) { if !bytes.Equal(floatResult, b.Data()) {
t.Errorf("float enc instructions: expected % x got % x", floatResult, b.Data()) t.Errorf("float enc instructions: expected % x got % x", floatResult, b.Data())
} }
...@@ -448,17 +453,17 @@ func TestScalarEncInstructions(t *testing.T) { ...@@ -448,17 +453,17 @@ func TestScalarEncInstructions(t *testing.T) {
instr := &encInstr{ encFloat32, 0, 0, 0 }; instr := &encInstr{ encFloat32, 0, 0, 0 };
state := newEncState(b); state := newEncState(b);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 0; state.fieldnum = 0;
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 1; state.fieldnum = 1;
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
if !bytes.Equal(floatResult, b.Data()) { if !bytes.Equal(floatResult, b.Data()) {
t.Errorf("float32 enc instructions: expected % x got % x", floatResult, b.Data()) t.Errorf("float32 enc instructions: expected % x got % x", floatResult, b.Data())
} }
...@@ -474,17 +479,17 @@ func TestScalarEncInstructions(t *testing.T) { ...@@ -474,17 +479,17 @@ func TestScalarEncInstructions(t *testing.T) {
instr := &encInstr{ encFloat64, 0, 0, 0 }; instr := &encInstr{ encFloat64, 0, 0, 0 };
state := newEncState(b); state := newEncState(b);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 0; state.fieldnum = 0;
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
state.fieldnum = 1; state.fieldnum = 1;
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
instr.op(instr, state); instr.op(instr, state, encAddrOf(state, instr));
if !bytes.Equal(floatResult, b.Data()) { if !bytes.Equal(floatResult, b.Data()) {
t.Errorf("float64 enc instructions: expected % x got % x", floatResult, b.Data()) t.Errorf("float64 enc instructions: expected % x got % x", floatResult, b.Data())
} }
...@@ -509,6 +514,12 @@ func newDecState(data []byte) *DecState { ...@@ -509,6 +514,12 @@ func newDecState(data []byte) *DecState {
return state; return state;
} }
// derive the address of a field, after indirecting indir times.
func decAddrOf(state *DecState, instr *decInstr) unsafe.Pointer {
p := unsafe.Pointer(state.base+instr.offset);
return decIndirect(p, instr.indir);
}
// Test instruction execution for decoding. // Test instruction execution for decoding.
// Do not run the machine yet; instead do individual instructions crafted by hand. // Do not run the machine yet; instead do individual instructions crafted by hand.
func TestScalarDecInstructions(t *testing.T) { func TestScalarDecInstructions(t *testing.T) {
...@@ -520,17 +531,17 @@ func TestScalarDecInstructions(t *testing.T) { ...@@ -520,17 +531,17 @@ func TestScalarDecInstructions(t *testing.T) {
state := newDecState(boolResult); state := newDecState(boolResult);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
expectField(0, state, t); expectField(0, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
expectField(1, state, t); expectField(1, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
expectField(2, state, t); expectField(2, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
if data.a != true { if data.a != true {
t.Errorf("int a = %v not true", data.a) t.Errorf("int a = %v not true", data.a)
} }
...@@ -549,17 +560,17 @@ func TestScalarDecInstructions(t *testing.T) { ...@@ -549,17 +560,17 @@ func TestScalarDecInstructions(t *testing.T) {
state := newDecState(signedResult); state := newDecState(signedResult);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
expectField(0, state, t); expectField(0, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
expectField(1, state, t); expectField(1, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
expectField(2, state, t); expectField(2, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
if data.a != 17 { if data.a != 17 {
t.Errorf("int a = %v not 17", data.a) t.Errorf("int a = %v not 17", data.a)
} }
...@@ -578,17 +589,17 @@ func TestScalarDecInstructions(t *testing.T) { ...@@ -578,17 +589,17 @@ func TestScalarDecInstructions(t *testing.T) {
state := newDecState(unsignedResult); state := newDecState(unsignedResult);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
expectField(0, state, t); expectField(0, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
expectField(1, state, t); expectField(1, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
expectField(2, state, t); expectField(2, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
if data.a != 17 { if data.a != 17 {
t.Errorf("int a = %v not 17", data.a) t.Errorf("int a = %v not 17", data.a)
} }
...@@ -607,17 +618,17 @@ func TestScalarDecInstructions(t *testing.T) { ...@@ -607,17 +618,17 @@ func TestScalarDecInstructions(t *testing.T) {
state := newDecState(signedResult); state := newDecState(signedResult);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
expectField(0, state, t); expectField(0, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
expectField(1, state, t); expectField(1, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
expectField(2, state, t); expectField(2, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
if data.a != 17 { if data.a != 17 {
t.Errorf("int a = %v not 17", data.a) t.Errorf("int a = %v not 17", data.a)
} }
...@@ -636,17 +647,17 @@ func TestScalarDecInstructions(t *testing.T) { ...@@ -636,17 +647,17 @@ func TestScalarDecInstructions(t *testing.T) {
state := newDecState(unsignedResult); state := newDecState(unsignedResult);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
expectField(0, state, t); expectField(0, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
expectField(1, state, t); expectField(1, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
expectField(2, state, t); expectField(2, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
if data.a != 17 { if data.a != 17 {
t.Errorf("int a = %v not 17", data.a) t.Errorf("int a = %v not 17", data.a)
} }
...@@ -665,17 +676,17 @@ func TestScalarDecInstructions(t *testing.T) { ...@@ -665,17 +676,17 @@ func TestScalarDecInstructions(t *testing.T) {
state := newDecState(signedResult); state := newDecState(signedResult);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
expectField(0, state, t); expectField(0, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
expectField(1, state, t); expectField(1, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
expectField(2, state, t); expectField(2, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
if data.a != 17 { if data.a != 17 {
t.Errorf("int a = %v not 17", data.a) t.Errorf("int a = %v not 17", data.a)
} }
...@@ -694,17 +705,17 @@ func TestScalarDecInstructions(t *testing.T) { ...@@ -694,17 +705,17 @@ func TestScalarDecInstructions(t *testing.T) {
state := newDecState(unsignedResult); state := newDecState(unsignedResult);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
expectField(0, state, t); expectField(0, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
expectField(1, state, t); expectField(1, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
expectField(2, state, t); expectField(2, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
if data.a != 17 { if data.a != 17 {
t.Errorf("int a = %v not 17", data.a) t.Errorf("int a = %v not 17", data.a)
} }
...@@ -723,17 +734,17 @@ func TestScalarDecInstructions(t *testing.T) { ...@@ -723,17 +734,17 @@ func TestScalarDecInstructions(t *testing.T) {
state := newDecState(signedResult); state := newDecState(signedResult);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
expectField(0, state, t); expectField(0, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
expectField(1, state, t); expectField(1, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
expectField(2, state, t); expectField(2, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
if data.a != 17 { if data.a != 17 {
t.Errorf("int a = %v not 17", data.a) t.Errorf("int a = %v not 17", data.a)
} }
...@@ -752,17 +763,17 @@ func TestScalarDecInstructions(t *testing.T) { ...@@ -752,17 +763,17 @@ func TestScalarDecInstructions(t *testing.T) {
state := newDecState(unsignedResult); state := newDecState(unsignedResult);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
expectField(0, state, t); expectField(0, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
expectField(1, state, t); expectField(1, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
expectField(2, state, t); expectField(2, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
if data.a != 17 { if data.a != 17 {
t.Errorf("int a = %v not 17", data.a) t.Errorf("int a = %v not 17", data.a)
} }
...@@ -781,17 +792,17 @@ func TestScalarDecInstructions(t *testing.T) { ...@@ -781,17 +792,17 @@ func TestScalarDecInstructions(t *testing.T) {
state := newDecState(signedResult); state := newDecState(signedResult);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
expectField(0, state, t); expectField(0, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
expectField(1, state, t); expectField(1, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
expectField(2, state, t); expectField(2, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
if data.a != 17 { if data.a != 17 {
t.Errorf("int a = %v not 17", data.a) t.Errorf("int a = %v not 17", data.a)
} }
...@@ -810,17 +821,17 @@ func TestScalarDecInstructions(t *testing.T) { ...@@ -810,17 +821,17 @@ func TestScalarDecInstructions(t *testing.T) {
state := newDecState(unsignedResult); state := newDecState(unsignedResult);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
expectField(0, state, t); expectField(0, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
expectField(1, state, t); expectField(1, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
expectField(2, state, t); expectField(2, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
if data.a != 17 { if data.a != 17 {
t.Errorf("int a = %v not 17", data.a) t.Errorf("int a = %v not 17", data.a)
} }
...@@ -839,17 +850,17 @@ func TestScalarDecInstructions(t *testing.T) { ...@@ -839,17 +850,17 @@ func TestScalarDecInstructions(t *testing.T) {
state := newDecState(floatResult); state := newDecState(floatResult);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
expectField(0, state, t); expectField(0, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
expectField(1, state, t); expectField(1, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
expectField(2, state, t); expectField(2, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
if data.a != 17 { if data.a != 17 {
t.Errorf("int a = %v not 17", data.a) t.Errorf("int a = %v not 17", data.a)
} }
...@@ -868,17 +879,17 @@ func TestScalarDecInstructions(t *testing.T) { ...@@ -868,17 +879,17 @@ func TestScalarDecInstructions(t *testing.T) {
state := newDecState(floatResult); state := newDecState(floatResult);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
expectField(0, state, t); expectField(0, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
expectField(1, state, t); expectField(1, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
expectField(2, state, t); expectField(2, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
if data.a != 17 { if data.a != 17 {
t.Errorf("int a = %v not 17", data.a) t.Errorf("int a = %v not 17", data.a)
} }
...@@ -897,17 +908,17 @@ func TestScalarDecInstructions(t *testing.T) { ...@@ -897,17 +908,17 @@ func TestScalarDecInstructions(t *testing.T) {
state := newDecState(floatResult); state := newDecState(floatResult);
state.base = uintptr(unsafe.Pointer(&data)); state.base = uintptr(unsafe.Pointer(&data));
expectField(0, state, t); expectField(0, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 1; instr.field = 1;
instr.indir = 1; instr.indir = 1;
instr.offset = uintptr(unsafe.Offsetof(data.b)); instr.offset = uintptr(unsafe.Offsetof(data.b));
expectField(1, state, t); expectField(1, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
instr.field = 2; instr.field = 2;
instr.indir = 2; instr.indir = 2;
instr.offset = uintptr(unsafe.Offsetof(data.c)); instr.offset = uintptr(unsafe.Offsetof(data.c));
expectField(2, state, t); expectField(2, state, t);
instr.op(instr, state); instr.op(instr, state, decAddrOf(state, instr));
if data.a != 17 { if data.a != 17 {
t.Errorf("int a = %v not 17", data.a) t.Errorf("int a = %v not 17", data.a)
} }
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
package gob package gob
// TODO(rsc): When garbage collector changes, revisit
// the allocations in this file that use unsafe.Pointer.
import ( import (
"gob"; "gob";
"io"; "io";
...@@ -57,9 +60,12 @@ func DecodeInt(state *DecState) int64 { ...@@ -57,9 +60,12 @@ func DecodeInt(state *DecState) int64 {
return int64(x >> 1) return int64(x >> 1)
} }
type decInstr struct
type decOp func(i *decInstr, state *DecState, p unsafe.Pointer);
// The 'instructions' of the decoding machine // The 'instructions' of the decoding machine
type decInstr struct { type decInstr struct {
op func(i *decInstr, state *DecState); op decOp;
field int; // field number field int; // field number
indir int; // how many pointer indirections to reach the value in the struct indir int; // how many pointer indirections to reach the value in the struct
offset uintptr; // offset in the structure of the field to encode offset uintptr; // offset in the structure of the field to encode
...@@ -84,14 +90,10 @@ func decIndirect(p unsafe.Pointer, indir int) unsafe.Pointer { ...@@ -84,14 +90,10 @@ func decIndirect(p unsafe.Pointer, indir int) unsafe.Pointer {
return p return p
} }
func decBool(i *decInstr, state *DecState) { func decBool(i *decInstr, state *DecState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 { if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil { if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int)); *(*unsafe.Pointer)(p) = unsafe.Pointer(new(bool));
p = *(*unsafe.Pointer)(p); p = *(*unsafe.Pointer)(p);
} }
} }
...@@ -101,12 +103,8 @@ func decBool(i *decInstr, state *DecState) { ...@@ -101,12 +103,8 @@ func decBool(i *decInstr, state *DecState) {
} }
} }
func decInt(i *decInstr, state *DecState) { func decInt(i *decInstr, state *DecState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 { if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil { if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int)); *(*unsafe.Pointer)(p) = unsafe.Pointer(new(int));
p = *(*unsafe.Pointer)(p); p = *(*unsafe.Pointer)(p);
...@@ -118,14 +116,10 @@ func decInt(i *decInstr, state *DecState) { ...@@ -118,14 +116,10 @@ func decInt(i *decInstr, state *DecState) {
} }
} }
func decUint(i *decInstr, state *DecState) { func decUint(i *decInstr, state *DecState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 { if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil { if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int)); *(*unsafe.Pointer)(p) = unsafe.Pointer(new(uint));
p = *(*unsafe.Pointer)(p); p = *(*unsafe.Pointer)(p);
} }
} }
...@@ -135,14 +129,10 @@ func decUint(i *decInstr, state *DecState) { ...@@ -135,14 +129,10 @@ func decUint(i *decInstr, state *DecState) {
} }
} }
func decInt8(i *decInstr, state *DecState) { func decInt8(i *decInstr, state *DecState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 { if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil { if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int)); *(*unsafe.Pointer)(p) = unsafe.Pointer(new(int8));
p = *(*unsafe.Pointer)(p); p = *(*unsafe.Pointer)(p);
} }
} }
...@@ -152,14 +142,10 @@ func decInt8(i *decInstr, state *DecState) { ...@@ -152,14 +142,10 @@ func decInt8(i *decInstr, state *DecState) {
} }
} }
func decUint8(i *decInstr, state *DecState) { func decUint8(i *decInstr, state *DecState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 { if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil { if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int)); *(*unsafe.Pointer)(p) = unsafe.Pointer(new(uint8));
p = *(*unsafe.Pointer)(p); p = *(*unsafe.Pointer)(p);
} }
} }
...@@ -169,14 +155,10 @@ func decUint8(i *decInstr, state *DecState) { ...@@ -169,14 +155,10 @@ func decUint8(i *decInstr, state *DecState) {
} }
} }
func decInt16(i *decInstr, state *DecState) { func decInt16(i *decInstr, state *DecState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 { if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil { if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int)); *(*unsafe.Pointer)(p) = unsafe.Pointer(new(int16));
p = *(*unsafe.Pointer)(p); p = *(*unsafe.Pointer)(p);
} }
} }
...@@ -186,14 +168,10 @@ func decInt16(i *decInstr, state *DecState) { ...@@ -186,14 +168,10 @@ func decInt16(i *decInstr, state *DecState) {
} }
} }
func decUint16(i *decInstr, state *DecState) { func decUint16(i *decInstr, state *DecState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 { if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil { if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int)); *(*unsafe.Pointer)(p) = unsafe.Pointer(new(uint16));
p = *(*unsafe.Pointer)(p); p = *(*unsafe.Pointer)(p);
} }
} }
...@@ -203,14 +181,10 @@ func decUint16(i *decInstr, state *DecState) { ...@@ -203,14 +181,10 @@ func decUint16(i *decInstr, state *DecState) {
} }
} }
func decInt32(i *decInstr, state *DecState) { func decInt32(i *decInstr, state *DecState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 { if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil { if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int)); *(*unsafe.Pointer)(p) = unsafe.Pointer(new(int32));
p = *(*unsafe.Pointer)(p); p = *(*unsafe.Pointer)(p);
} }
} }
...@@ -220,14 +194,10 @@ func decInt32(i *decInstr, state *DecState) { ...@@ -220,14 +194,10 @@ func decInt32(i *decInstr, state *DecState) {
} }
} }
func decUint32(i *decInstr, state *DecState) { func decUint32(i *decInstr, state *DecState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 { if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil { if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int)); *(*unsafe.Pointer)(p) = unsafe.Pointer(new(uint32));
p = *(*unsafe.Pointer)(p); p = *(*unsafe.Pointer)(p);
} }
} }
...@@ -237,14 +207,10 @@ func decUint32(i *decInstr, state *DecState) { ...@@ -237,14 +207,10 @@ func decUint32(i *decInstr, state *DecState) {
} }
} }
func decInt64(i *decInstr, state *DecState) { func decInt64(i *decInstr, state *DecState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 { if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil { if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int)); *(*unsafe.Pointer)(p) = unsafe.Pointer(new(int64));
p = *(*unsafe.Pointer)(p); p = *(*unsafe.Pointer)(p);
} }
} }
...@@ -254,14 +220,10 @@ func decInt64(i *decInstr, state *DecState) { ...@@ -254,14 +220,10 @@ func decInt64(i *decInstr, state *DecState) {
} }
} }
func decUint64(i *decInstr, state *DecState) { func decUint64(i *decInstr, state *DecState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 { if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil { if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int)); *(*unsafe.Pointer)(p) = unsafe.Pointer(new(uint64));
p = *(*unsafe.Pointer)(p); p = *(*unsafe.Pointer)(p);
} }
} }
...@@ -286,14 +248,10 @@ func floatFromBits(u uint64) float64 { ...@@ -286,14 +248,10 @@ func floatFromBits(u uint64) float64 {
return math.Float64frombits(v); return math.Float64frombits(v);
} }
func decFloat(i *decInstr, state *DecState) { func decFloat(i *decInstr, state *DecState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 { if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil { if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int)); *(*unsafe.Pointer)(p) = unsafe.Pointer(new(float));
p = *(*unsafe.Pointer)(p); p = *(*unsafe.Pointer)(p);
} }
} }
...@@ -303,14 +261,10 @@ func decFloat(i *decInstr, state *DecState) { ...@@ -303,14 +261,10 @@ func decFloat(i *decInstr, state *DecState) {
} }
} }
func decFloat32(i *decInstr, state *DecState) { func decFloat32(i *decInstr, state *DecState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 { if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil { if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int)); *(*unsafe.Pointer)(p) = unsafe.Pointer(new(float32));
p = *(*unsafe.Pointer)(p); p = *(*unsafe.Pointer)(p);
} }
} }
...@@ -320,14 +274,10 @@ func decFloat32(i *decInstr, state *DecState) { ...@@ -320,14 +274,10 @@ func decFloat32(i *decInstr, state *DecState) {
} }
} }
func decFloat64(i *decInstr, state *DecState) { func decFloat64(i *decInstr, state *DecState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 { if i.indir > 0 {
if i.indir > 1 {
p = decIndirect(p, i.indir);
}
if *(*unsafe.Pointer)(p) == nil { if *(*unsafe.Pointer)(p) == nil {
*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int)); *(*unsafe.Pointer)(p) = unsafe.Pointer(new(float64));
p = *(*unsafe.Pointer)(p); p = *(*unsafe.Pointer)(p);
} }
} }
...@@ -346,7 +296,7 @@ type decEngine struct { ...@@ -346,7 +296,7 @@ type decEngine struct {
} }
var decEngineMap = make(map[reflect.Type] *decEngine) var decEngineMap = make(map[reflect.Type] *decEngine)
var decOp = map[int] func(*decInstr, *DecState) { var decOpMap = map[int] decOp {
reflect.BoolKind: decBool, reflect.BoolKind: decBool,
reflect.IntKind: decInt, reflect.IntKind: decInt,
reflect.Int8Kind: decInt8, reflect.Int8Kind: decInt8,
...@@ -386,7 +336,7 @@ func compileDec(rt reflect.Type, typ Type) *decEngine { ...@@ -386,7 +336,7 @@ func compileDec(rt reflect.Type, typ Type) *decEngine {
ftyp = pt.Sub(); ftyp = pt.Sub();
indir++; indir++;
} }
op, ok := decOp[ftyp.Kind()]; op, ok := decOpMap[ftyp.Kind()];
if !ok { if !ok {
panicln("can't handle decode for type", ftyp.String()); panicln("can't handle decode for type", ftyp.String());
} }
...@@ -424,7 +374,11 @@ func (engine *decEngine) decode(r io.Reader, v reflect.Value) os.Error { ...@@ -424,7 +374,11 @@ func (engine *decEngine) decode(r io.Reader, v reflect.Value) os.Error {
panicln("TODO(r): need to handle unknown data"); panicln("TODO(r): need to handle unknown data");
} }
instr := &engine.instr[fieldnum]; instr := &engine.instr[fieldnum];
instr.op(instr, state); p := unsafe.Pointer(state.base+instr.offset);
if instr.indir > 1 {
p = decIndirect(p, instr.indir);
}
instr.op(instr, state, p);
state.fieldnum = fieldnum; state.fieldnum = fieldnum;
} }
return state.err return state.err
......
...@@ -60,9 +60,12 @@ func EncodeInt(state *EncState, i int64){ ...@@ -60,9 +60,12 @@ func EncodeInt(state *EncState, i int64){
EncodeUint(state, uint64(x)) EncodeUint(state, uint64(x))
} }
type encInstr struct
type encOp func(i *encInstr, state *EncState, p unsafe.Pointer)
// The 'instructions' of the encoding machine // The 'instructions' of the encoding machine
type encInstr struct { type encInstr struct {
op func(i *encInstr, state *EncState); op encOp;
field int; // field number field int; // field number
indir int; // how many pointer indirections to reach the value in the struct indir int; // how many pointer indirections to reach the value in the struct
offset uintptr; // offset in the structure of the field to encode offset uintptr; // offset in the structure of the field to encode
...@@ -84,13 +87,7 @@ func encIndirect(p unsafe.Pointer, indir int) unsafe.Pointer { ...@@ -84,13 +87,7 @@ func encIndirect(p unsafe.Pointer, indir int) unsafe.Pointer {
return p return p
} }
func encBool(i *encInstr, state *EncState) { func encBool(i *encInstr, state *EncState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
b := *(*bool)(p); b := *(*bool)(p);
if b { if b {
EncodeUint(state, uint64(i.field - state.fieldnum)); EncodeUint(state, uint64(i.field - state.fieldnum));
...@@ -98,13 +95,7 @@ func encBool(i *encInstr, state *EncState) { ...@@ -98,13 +95,7 @@ func encBool(i *encInstr, state *EncState) {
} }
} }
func encInt(i *encInstr, state *EncState) { func encInt(i *encInstr, state *EncState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
v := int64(*(*int)(p)); v := int64(*(*int)(p));
if v != 0 { if v != 0 {
EncodeUint(state, uint64(i.field - state.fieldnum)); EncodeUint(state, uint64(i.field - state.fieldnum));
...@@ -112,13 +103,7 @@ func encInt(i *encInstr, state *EncState) { ...@@ -112,13 +103,7 @@ func encInt(i *encInstr, state *EncState) {
} }
} }
func encUint(i *encInstr, state *EncState) { func encUint(i *encInstr, state *EncState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
v := uint64(*(*uint)(p)); v := uint64(*(*uint)(p));
if v != 0 { if v != 0 {
EncodeUint(state, uint64(i.field - state.fieldnum)); EncodeUint(state, uint64(i.field - state.fieldnum));
...@@ -126,13 +111,7 @@ func encUint(i *encInstr, state *EncState) { ...@@ -126,13 +111,7 @@ func encUint(i *encInstr, state *EncState) {
} }
} }
func encInt8(i *encInstr, state *EncState) { func encInt8(i *encInstr, state *EncState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
v := int64(*(*int8)(p)); v := int64(*(*int8)(p));
if v != 0 { if v != 0 {
EncodeUint(state, uint64(i.field - state.fieldnum)); EncodeUint(state, uint64(i.field - state.fieldnum));
...@@ -140,13 +119,7 @@ func encInt8(i *encInstr, state *EncState) { ...@@ -140,13 +119,7 @@ func encInt8(i *encInstr, state *EncState) {
} }
} }
func encUint8(i *encInstr, state *EncState) { func encUint8(i *encInstr, state *EncState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
v := uint64(*(*uint8)(p)); v := uint64(*(*uint8)(p));
if v != 0 { if v != 0 {
EncodeUint(state, uint64(i.field - state.fieldnum)); EncodeUint(state, uint64(i.field - state.fieldnum));
...@@ -154,13 +127,7 @@ func encUint8(i *encInstr, state *EncState) { ...@@ -154,13 +127,7 @@ func encUint8(i *encInstr, state *EncState) {
} }
} }
func encInt16(i *encInstr, state *EncState) { func encInt16(i *encInstr, state *EncState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
v := int64(*(*int16)(p)); v := int64(*(*int16)(p));
if v != 0 { if v != 0 {
EncodeUint(state, uint64(i.field - state.fieldnum)); EncodeUint(state, uint64(i.field - state.fieldnum));
...@@ -168,13 +135,7 @@ func encInt16(i *encInstr, state *EncState) { ...@@ -168,13 +135,7 @@ func encInt16(i *encInstr, state *EncState) {
} }
} }
func encUint16(i *encInstr, state *EncState) { func encUint16(i *encInstr, state *EncState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
v := uint64(*(*uint16)(p)); v := uint64(*(*uint16)(p));
if v != 0 { if v != 0 {
EncodeUint(state, uint64(i.field - state.fieldnum)); EncodeUint(state, uint64(i.field - state.fieldnum));
...@@ -182,13 +143,7 @@ func encUint16(i *encInstr, state *EncState) { ...@@ -182,13 +143,7 @@ func encUint16(i *encInstr, state *EncState) {
} }
} }
func encInt32(i *encInstr, state *EncState) { func encInt32(i *encInstr, state *EncState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
v := int64(*(*int32)(p)); v := int64(*(*int32)(p));
if v != 0 { if v != 0 {
EncodeUint(state, uint64(i.field - state.fieldnum)); EncodeUint(state, uint64(i.field - state.fieldnum));
...@@ -196,13 +151,7 @@ func encInt32(i *encInstr, state *EncState) { ...@@ -196,13 +151,7 @@ func encInt32(i *encInstr, state *EncState) {
} }
} }
func encUint32(i *encInstr, state *EncState) { func encUint32(i *encInstr, state *EncState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
v := uint64(*(*uint32)(p)); v := uint64(*(*uint32)(p));
if v != 0 { if v != 0 {
EncodeUint(state, uint64(i.field - state.fieldnum)); EncodeUint(state, uint64(i.field - state.fieldnum));
...@@ -210,13 +159,7 @@ func encUint32(i *encInstr, state *EncState) { ...@@ -210,13 +159,7 @@ func encUint32(i *encInstr, state *EncState) {
} }
} }
func encInt64(i *encInstr, state *EncState) { func encInt64(i *encInstr, state *EncState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
v := *(*int64)(p); v := *(*int64)(p);
if v != 0 { if v != 0 {
EncodeUint(state, uint64(i.field - state.fieldnum)); EncodeUint(state, uint64(i.field - state.fieldnum));
...@@ -224,13 +167,7 @@ func encInt64(i *encInstr, state *EncState) { ...@@ -224,13 +167,7 @@ func encInt64(i *encInstr, state *EncState) {
} }
} }
func encUint64(i *encInstr, state *EncState) { func encUint64(i *encInstr, state *EncState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
v := *(*uint64)(p); v := *(*uint64)(p);
if v != 0 { if v != 0 {
EncodeUint(state, uint64(i.field - state.fieldnum)); EncodeUint(state, uint64(i.field - state.fieldnum));
...@@ -254,13 +191,7 @@ func floatBits(f float64) uint64 { ...@@ -254,13 +191,7 @@ func floatBits(f float64) uint64 {
return v; return v;
} }
func encFloat(i *encInstr, state *EncState) { func encFloat(i *encInstr, state *EncState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
f := float(*(*float)(p)); f := float(*(*float)(p));
if f != 0 { if f != 0 {
v := floatBits(float64(f)); v := floatBits(float64(f));
...@@ -269,13 +200,7 @@ func encFloat(i *encInstr, state *EncState) { ...@@ -269,13 +200,7 @@ func encFloat(i *encInstr, state *EncState) {
} }
} }
func encFloat32(i *encInstr, state *EncState) { func encFloat32(i *encInstr, state *EncState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
f := float32(*(*float32)(p)); f := float32(*(*float32)(p));
if f != 0 { if f != 0 {
v := floatBits(float64(f)); v := floatBits(float64(f));
...@@ -284,13 +209,7 @@ func encFloat32(i *encInstr, state *EncState) { ...@@ -284,13 +209,7 @@ func encFloat32(i *encInstr, state *EncState) {
} }
} }
func encFloat64(i *encInstr, state *EncState) { func encFloat64(i *encInstr, state *EncState, p unsafe.Pointer) {
p := unsafe.Pointer(state.base+i.offset);
if i.indir > 0 {
if p = encIndirect(p, i.indir); p == nil {
return
}
}
f := *(*float64)(p); f := *(*float64)(p);
if f != 0 { if f != 0 {
v := floatBits(f); v := floatBits(f);
...@@ -300,7 +219,7 @@ func encFloat64(i *encInstr, state *EncState) { ...@@ -300,7 +219,7 @@ func encFloat64(i *encInstr, state *EncState) {
} }
// The end of a struct is marked by a delta field number of 0. // The end of a struct is marked by a delta field number of 0.
func encStructTerminator(i *encInstr, state *EncState) { func encStructTerminator(i *encInstr, state *EncState, p unsafe.Pointer) {
EncodeUint(state, 0); EncodeUint(state, 0);
} }
...@@ -313,7 +232,7 @@ type encEngine struct { ...@@ -313,7 +232,7 @@ type encEngine struct {
} }
var encEngineMap = make(map[reflect.Type] *encEngine) var encEngineMap = make(map[reflect.Type] *encEngine)
var encOp = map[int] func(*encInstr, *EncState) { var encOpMap = map[int] encOp {
reflect.BoolKind: encBool, reflect.BoolKind: encBool,
reflect.IntKind: encInt, reflect.IntKind: encInt,
reflect.Int8Kind: encInt8, reflect.Int8Kind: encInt8,
...@@ -352,7 +271,7 @@ func compileEnc(rt reflect.Type, typ Type) *encEngine { ...@@ -352,7 +271,7 @@ func compileEnc(rt reflect.Type, typ Type) *encEngine {
ftyp = pt.Sub(); ftyp = pt.Sub();
indir++; indir++;
} }
op, ok := encOp[ftyp.Kind()]; op, ok := encOpMap[ftyp.Kind()];
if !ok { if !ok {
panicln("encode can't handle type", ftyp.String()); panicln("encode can't handle type", ftyp.String());
} }
...@@ -383,7 +302,14 @@ func (engine *encEngine) encode(w io.Writer, v reflect.Value) os.Error { ...@@ -383,7 +302,14 @@ func (engine *encEngine) encode(w io.Writer, v reflect.Value) os.Error {
state.fieldnum = -1; state.fieldnum = -1;
for i := 0; i < len(engine.instr); i++ { for i := 0; i < len(engine.instr); i++ {
instr := &engine.instr[i]; instr := &engine.instr[i];
instr.op(instr, state); p := unsafe.Pointer(state.base+instr.offset);
if instr.indir > 0 {
if p = encIndirect(p, instr.indir); p == nil {
state.fieldnum = i;
continue
}
}
instr.op(instr, state, p);
if state.err != nil { if state.err != nil {
break break
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment