// run

// Copyright 2010 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.

// Test of basic recover functionality.

package main

import (
	"os"
	"reflect"
	"runtime"
)

func main() {
	// go.tools/ssa/interp still has:
	// - some lesser bugs in recover()
	// - incomplete support for reflection
	interp := os.Getenv("GOSSAINTERP") != ""

	test1()
	test1WithClosures()
	test2()
	test3()
	if !interp {
		test4()
	}
	test5()
	test6()
	test6WithClosures()
	test7()
	test8()
	test9()
	if !interp {
		test9reflect1()
		test9reflect2()
	}
	test10()
	if !interp {
		test10reflect1()
		test10reflect2()
	}
	test11()
	if !interp {
		test11reflect1()
		test11reflect2()
	}
	test111()
	test12()
	if !interp {
		test12reflect1()
		test12reflect2()
	}
	test13()
	if !interp {
		test13reflect1()
		test13reflect2()
	}
	test14()
	if !interp {
		test14reflect1()
		test14reflect2()
		test15()
		test16()
	}
}

func die() {
	runtime.Breakpoint() // can't depend on panic
}

func mustRecoverBody(v1, v2, v3, x interface{}) {
	v := v1
	if v != nil {
		println("spurious recover", v)
		die()
	}
	v = v2
	if v == nil {
		println("missing recover", x.(int))
		die() // panic is useless here
	}
	if v != x {
		println("wrong value", v, x)
		die()
	}

	// the value should be gone now regardless
	v = v3
	if v != nil {
		println("recover didn't recover")
		die()
	}
}

func doubleRecover() interface{} {
	return recover()
}

func mustRecover(x interface{}) {
	mustRecoverBody(doubleRecover(), recover(), recover(), x)
}

func mustNotRecover() {
	v := recover()
	if v != nil {
		println("spurious recover", v)
		die()
	}
}

func withoutRecover() {
	mustNotRecover() // because it's a sub-call
}

func withoutRecoverRecursive(n int) {
	if n == 0 {
		withoutRecoverRecursive(1)
	} else {
		v := recover()
		if v != nil {
			println("spurious recover (recursive)", v)
			die()
		}
	}
}

func test1() {
	defer mustNotRecover()           // because mustRecover will squelch it
	defer mustRecover(1)             // because of panic below
	defer withoutRecover()           // should be no-op, leaving for mustRecover to find
	defer withoutRecoverRecursive(0) // ditto
	panic(1)
}

// Repeat test1 with closures instead of standard function.
// Interesting because recover bases its decision
// on the frame pointer of its caller, and a closure's
// frame pointer is in the middle of its actual arguments
// (after the hidden ones for the closed-over variables).
func test1WithClosures() {
	defer func() {
		v := recover()
		if v != nil {
			println("spurious recover in closure")
			die()
		}
	}()
	defer func(x interface{}) {
		mustNotRecover()
		v := recover()
		if v == nil {
			println("missing recover", x.(int))
			die()
		}
		if v != x {
			println("wrong value", v, x)
			die()
		}
	}(1)
	defer func() {
		mustNotRecover()
	}()
	panic(1)
}

func test2() {
	// Recover only sees the panic argument
	// if it is called from a deferred call.
	// It does not see the panic when called from a call within a deferred call (too late)
	// nor does it see the panic when it *is* the deferred call (too early).
	defer mustRecover(2)
	defer recover() // should be no-op
	panic(2)
}

func test3() {
	defer mustNotRecover()
	defer func() {
		recover() // should squelch
	}()
	panic(3)
}

func test4() {
	// Equivalent to test3 but using defer to make the call.
	defer mustNotRecover()
	defer func() {
		defer recover() // should squelch
	}()
	panic(4)
}

// Check that closures can set output arguments.
// Run g().  If it panics, return x; else return deflt.
func try(g func(), deflt interface{}) (x interface{}) {
	defer func() {
		if v := recover(); v != nil {
			x = v
		}
	}()
	defer g()
	return deflt
}

// Check that closures can set output arguments.
// Run g().  If it panics, return x; else return deflt.
func try1(g func(), deflt interface{}) (x interface{}) {
	defer func() {
		if v := recover(); v != nil {
			x = v
		}
	}()
	defer g()
	x = deflt
	return
}

func test5() {
	v := try(func() { panic(5) }, 55).(int)
	if v != 5 {
		println("wrong value", v, 5)
		die()
	}

	s := try(func() {}, "hi").(string)
	if s != "hi" {
		println("wrong value", s, "hi")
		die()
	}

	v = try1(func() { panic(5) }, 55).(int)
	if v != 5 {
		println("try1 wrong value", v, 5)
		die()
	}

	s = try1(func() {}, "hi").(string)
	if s != "hi" {
		println("try1 wrong value", s, "hi")
		die()
	}
}

// When a deferred big call starts, it must first
// create yet another stack segment to hold the
// giant frame for x.  Make sure that doesn't
// confuse recover.
func big(mustRecover bool) {
	var x [100000]int
	x[0] = 1
	x[99999] = 1
	_ = x

	v := recover()
	if mustRecover {
		if v == nil {
			println("missing big recover")
			die()
		}
	} else {
		if v != nil {
			println("spurious big recover")
			die()
		}
	}
}

func test6() {
	defer big(false)
	defer big(true)
	panic(6)
}

func test6WithClosures() {
	defer func() {
		var x [100000]int
		x[0] = 1
		x[99999] = 1
		_ = x
		if recover() != nil {
			println("spurious big closure recover")
			die()
		}
	}()
	defer func() {
		var x [100000]int
		x[0] = 1
		x[99999] = 1
		_ = x
		if recover() == nil {
			println("missing big closure recover")
			die()
		}
	}()
	panic("6WithClosures")
}

func test7() {
	ok := false
	func() {
		// should panic, then call mustRecover 7, which stops the panic.
		// then should keep processing ordinary defers earlier than that one
		// before returning.
		// this test checks that the defer func on the next line actually runs.
		defer func() { ok = true }()
		defer mustRecover(7)
		panic(7)
	}()
	if !ok {
		println("did not run ok func")
		die()
	}
}

func varargs(s *int, a ...int) {
	*s = 0
	for _, v := range a {
		*s += v
	}
	if recover() != nil {
		*s += 100
	}
}

func test8a() (r int) {
	defer varargs(&r, 1, 2, 3)
	panic(0)
}

func test8b() (r int) {
	defer varargs(&r, 4, 5, 6)
	return
}

func test8() {
	if test8a() != 106 || test8b() != 15 {
		println("wrong value")
		die()
	}
}

type I interface {
	M()
}

// pointer receiver, so no wrapper in i.M()
type T1 struct{}

func (*T1) M() {
	mustRecoverBody(doubleRecover(), recover(), recover(), 9)
}

func test9() {
	var i I = &T1{}
	defer i.M()
	panic(9)
}

func test9reflect1() {
	f := reflect.ValueOf(&T1{}).Method(0).Interface().(func())
	defer f()
	panic(9)
}

func test9reflect2() {
	f := reflect.TypeOf(&T1{}).Method(0).Func.Interface().(func(*T1))
	defer f(&T1{})
	panic(9)
}

// word-sized value receiver, so no wrapper in i.M()
type T2 uintptr

func (T2) M() {
	mustRecoverBody(doubleRecover(), recover(), recover(), 10)
}

func test10() {
	var i I = T2(0)
	defer i.M()
	panic(10)
}

func test10reflect1() {
	f := reflect.ValueOf(T2(0)).Method(0).Interface().(func())
	defer f()
	panic(10)
}

func test10reflect2() {
	f := reflect.TypeOf(T2(0)).Method(0).Func.Interface().(func(T2))
	defer f(T2(0))
	panic(10)
}

// tiny receiver, so basic wrapper in i.M()
type T3 struct{}

func (T3) M() {
	mustRecoverBody(doubleRecover(), recover(), recover(), 11)
}

func test11() {
	var i I = T3{}
	defer i.M()
	panic(11)
}

func test11reflect1() {
	f := reflect.ValueOf(T3{}).Method(0).Interface().(func())
	defer f()
	panic(11)
}

func test11reflect2() {
	f := reflect.TypeOf(T3{}).Method(0).Func.Interface().(func(T3))
	defer f(T3{})
	panic(11)
}

// tiny receiver, so basic wrapper in i.M()
type T3deeper struct{}

func (T3deeper) M() {
	badstate() // difference from T3
	mustRecoverBody(doubleRecover(), recover(), recover(), 111)
}

func test111() {
	var i I = T3deeper{}
	defer i.M()
	panic(111)
}

type Tiny struct{}

func (Tiny) M() {
	panic(112)
}

// i.M is a wrapper, and i.M panics.
//
// This is a torture test for an old implementation of recover that
// tried to deal with wrapper functions by doing some argument
// positioning math on both entry and exit. Doing anything on exit
// is a problem because sometimes functions exit via panic instead
// of an ordinary return, so panic would have to know to do the
// same math when unwinding the stack. It gets complicated fast.
// This particular test never worked with the old scheme, because
// panic never did the right unwinding math.
//
// The new scheme adjusts Panic.argp on entry to a wrapper.
// It has no exit work, so if a wrapper is interrupted by a panic,
// there's no cleanup that panic itself must do.
// This test just works now.
func badstate() {
	defer func() {
		recover()
	}()
	var i I = Tiny{}
	i.M()
}

// large receiver, so basic wrapper in i.M()
type T4 [2]string

func (T4) M() {
	mustRecoverBody(doubleRecover(), recover(), recover(), 12)
}

func test12() {
	var i I = T4{}
	defer i.M()
	panic(12)
}

func test12reflect1() {
	f := reflect.ValueOf(T4{}).Method(0).Interface().(func())
	defer f()
	panic(12)
}

func test12reflect2() {
	f := reflect.TypeOf(T4{}).Method(0).Func.Interface().(func(T4))
	defer f(T4{})
	panic(12)
}

// enormous receiver, so wrapper splits stack to call M
type T5 [8192]byte

func (T5) M() {
	mustRecoverBody(doubleRecover(), recover(), recover(), 13)
}

func test13() {
	var i I = T5{}
	defer i.M()
	panic(13)
}

func test13reflect1() {
	f := reflect.ValueOf(T5{}).Method(0).Interface().(func())
	defer f()
	panic(13)
}

func test13reflect2() {
	f := reflect.TypeOf(T5{}).Method(0).Func.Interface().(func(T5))
	defer f(T5{})
	panic(13)
}

// enormous receiver + enormous method frame, so wrapper splits stack to call M,
// and then M splits stack to allocate its frame.
// recover must look back two frames to find the panic.
type T6 [8192]byte

var global byte

func (T6) M() {
	var x [8192]byte
	x[0] = 1
	x[1] = 2
	for i := range x {
		global += x[i]
	}
	mustRecoverBody(doubleRecover(), recover(), recover(), 14)
}

func test14() {
	var i I = T6{}
	defer i.M()
	panic(14)
}

func test14reflect1() {
	f := reflect.ValueOf(T6{}).Method(0).Interface().(func())
	defer f()
	panic(14)
}

func test14reflect2() {
	f := reflect.TypeOf(T6{}).Method(0).Func.Interface().(func(T6))
	defer f(T6{})
	panic(14)
}

// function created by reflect.MakeFunc

func reflectFunc(args []reflect.Value) (results []reflect.Value) {
	mustRecoverBody(doubleRecover(), recover(), recover(), 15)
	return nil
}

func test15() {
	f := reflect.MakeFunc(reflect.TypeOf((func())(nil)), reflectFunc).Interface().(func())
	defer f()
	panic(15)
}

func reflectFunc2(args []reflect.Value) (results []reflect.Value) {
	// This will call reflectFunc3
	args[0].Interface().(func())()
	return nil
}

func reflectFunc3(args []reflect.Value) (results []reflect.Value) {
	if v := recover(); v != nil {
		println("spurious recover", v)
		die()
	}
	return nil
}

func test16() {
	defer mustRecover(16)

	f2 := reflect.MakeFunc(reflect.TypeOf((func(func()))(nil)), reflectFunc2).Interface().(func(func()))
	f3 := reflect.MakeFunc(reflect.TypeOf((func())(nil)), reflectFunc3).Interface().(func())
	defer f2(f3)

	panic(16)
}
