func walkScanTree()

in x86/x86map/map.go [797:902]


func walkScanTree(p *Prog, is64 int) {
	keys := p.keys()
	for _, key := range keys {
		if p.Action == "is64" {
			switch key {
			case "0":
				is64 = 0
			case "1":
				is64 = 1
			}
		}
		walkScanTree(p.Child[key], is64)
	}

	switch p.Action {
	case "read", "match":
		// keep
		return
	case "decode":
		if len(keys) >= 8 && keys[0] == "/0" && keys[7] == "/7" && allSame(p, keys) {
			p.Action = "read"
			p.Child = map[string]*Prog{"/r": p.Child[keys[0]]}
			return
		}
	case "op", "arg":
		// drop
		*p = *p.Child[keys[0]]
		return
	case "prefix":
		if len(keys) >= 1 && keys[0] == "0" && allSame(p, keys) {
			*p = *p.Child[keys[0]]
			return
		}
	case "is64", "addrsize", "datasize", "ismem":
		if len(keys) == 1 && keys[0] == "any" {
			*p = *p.Child[keys[0]]
			return
		}
		nkey := len(allKeys[p.Action])
		if p.Action == "addrsize" {
			nkey = 2
		}
		if p.Action == "datasize" && is64 == 0 {
			nkey = 2
		}
		if len(keys) == nkey && allSame(p, keys) {
			*p = *p.Child[keys[0]]
			return
		}
	}

	switch p.Action {
	case "datasize":
		if len(keys) == 2 && is64 == 0 || len(keys) == 3 {
			if treeText(p.Child["16"]) == "read iw match ! \n" && treeText(p.Child["32"]) == "read id match ! \n" && (len(keys) == 2 || treeText(p.Child["64"]) == "read id match ! \n") {
				p.Action = "read"
				p.Child = map[string]*Prog{"iwd/d": p.Child["16"].Child["iw"]}
				return
			}
			if len(keys) == 3 && treeText(p.Child["16"]) == "read iw match ! \n" && treeText(p.Child["32"]) == "read id match ! \n" && treeText(p.Child["64"]) == "read io match ! \n" {
				p.Action = "read"
				p.Child = map[string]*Prog{"iwdo/d": p.Child["16"].Child["iw"]}
				return
			}
			if treeText(p.Child["16"]) == "read /r read iw match ! \n" && treeText(p.Child["32"]) == "read /r read id match ! \n" && (len(keys) == 2 || treeText(p.Child["64"]) == "read /r read id match ! \n") {
				p.Action = "read"
				p.Child = map[string]*Prog{"/r": {Action: "read", Child: map[string]*Prog{"iwd/d": p.Child["16"].Child["/r"].Child["iw"]}}}
				return
			}
			if treeText(p.Child["16"]) == "read cw match ! \n" && treeText(p.Child["32"]) == "read cd match ! \n" && (len(keys) == 2 || treeText(p.Child["64"]) == "read cd match ! \n") {
				p.Action = "read"
				p.Child = map[string]*Prog{"cwd/d": p.Child["16"].Child["cw"]}
				return
			}
			if treeText(p.Child["16"]) == "read cd match ! \n" && treeText(p.Child["32"]) == "read cp match ! \n" && (len(keys) == 2 || treeText(p.Child["64"]) == "read cp match ! \n") {
				p.Action = "read"
				p.Child = map[string]*Prog{"cdp/d": p.Child["16"].Child["cd"]}
				return
			}
			fmt.Printf("!! %q\n", treeText(p.Child["16"]))
		}

	case "is64":
		if len(keys) == 2 && treeText(p.Child["0"]) == "read cwd/d match ! \n" && treeText(p.Child["1"]) == "read cd match ! \n" {
			*p = *p.Child["0"]
			return
		}
		if len(keys) == 2 && treeText(p.Child["0"]) == "read iwd/d match ! \n" && treeText(p.Child["1"]) == "read iwdo/d match ! \n" {
			*p = *p.Child["1"]
			return
		}
	}

	/*
		match := make(map[string][]string)
		for _, key := range keys {
			text := treeText(p.Child[key])
			match[text] = append(match[text], key)
		}
		child := make(map[string]*Prog)
		for _, keys := range match {
			child[strings.Join(keys, ",")] = p.Child[keys[0]]
		}
		p.Child = child
	*/
}