Ejemplo n.º 1
0
// This function is an adjusted variant of gccgoimporter.GccgoInstallation.GetImporter.
func getNewImporter(searchpaths []string) types.Importer {
	return func(imports map[string]*types.Package, pkgpath string) (pkg *types.Package, err error) {
		if pkgpath == "unsafe" {
			return types.Unsafe, nil
		}

		fpath, err := findExportFile(searchpaths, pkgpath)
		if err != nil {
			return
		}

		reader, closer, err := openExportFile(fpath)
		if err != nil {
			return nil, err
		}
		defer closer.Close()

		// TODO(gri) At the moment we just read the entire file.
		// We should change importer.ImportData to take an io.Reader instead.
		data, err := ioutil.ReadAll(reader)
		if err != nil && err != io.EOF {
			return nil, err
		}

		return importer.ImportData(packages, data)
	}
}
Ejemplo n.º 2
0
func (imp *Importer) importPkg(imports map[string]*types.Package, path string) (*types.Package, error) {
	if path == "unsafe" {
		return types.Unsafe, nil
	}

	var (
		srcDir string
		err    error
	)

	if build.IsLocalImport(path) {
		srcDir, err = os.Getwd()
		if err != nil {
			return nil, err
		}
	}

	bp, err := buildCtx.Import(path, srcDir, build.AllowBinary)
	if err != nil {
		return nil, err
	}

	if pkg := imports[path]; pkg != nil && pkg.Complete() {
		return pkg, nil
	}

	buf, err := loadExports(bp)
	if err != nil {
		return nil, err
	}
	_, pkg, err := importer.ImportData(imports, buf)
	return pkg, err
}
Ejemplo n.º 3
0
func (imp *Importer) Import(imports map[string]*types.Package, path string) (pkg *types.Package, err error) {
	exportsPath := packageExportsFile(imp.context, path)
	data, err := ioutil.ReadFile(exportsPath)
	if err != nil {
		// Package has not been compiled yet, so
		// fall back to the standard GcImport.
		tracef("Falling back to gc import data for: %s", path)
		return gcimporter.Import(imports, path)
	}
	tracef("Loading import data for %q from %q", path, exportsPath)
	return importer.ImportData(imports, data)
}
Ejemplo n.º 4
0
func gccgoNewImporter(packages map[string]*types.Package, path string) (*types.Package, error) {
	reader, closer, err := openGccgoExportFile(path)
	if err != nil {
		return nil, err
	}
	defer closer.Close()

	// TODO(gri) importer.ImportData takes a []byte instead of an io.Reader;
	// hence the need to read some amount of data. At the same time we don't
	// want to read the entire, potentially very large object file. For now,
	// read 10K. Fix this!
	var data = make([]byte, 10<<10)
	n, err := reader.Read(data)
	if err != nil && err != io.EOF {
		return nil, err
	}

	return importer.ImportData(packages, data[:n])
}
Ejemplo n.º 5
0
func GetImporter(searchpaths []string, initmap map[*types.Package]InitData) types.Importer {
	return func(imports map[string]*types.Package, pkgpath string) (pkg *types.Package, err error) {
		if pkgpath == "unsafe" {
			return types.Unsafe, nil
		}

		fpath, err := findExportFile(searchpaths, pkgpath)
		if err != nil {
			return
		}

		reader, closer, err := openExportFile(fpath)
		if err != nil {
			return
		}
		if closer != nil {
			defer closer.Close()
		}

		var magic [4]byte
		_, err = reader.Read(magic[:])
		if err != nil {
			return
		}
		_, err = reader.Seek(0, 0)
		if err != nil {
			return
		}

		switch string(magic[:]) {
		case gccgov1Magic:
			var p parser
			p.init(fpath, reader, imports)
			pkg = p.parsePackage()
			if initmap != nil {
				initmap[pkg] = p.initdata
			}

		case goimporterMagic:
			var data []byte
			data, err = ioutil.ReadAll(reader)
			if err != nil {
				return
			}
			var n int
			n, pkg, err = importer.ImportData(imports, data)
			if err != nil {
				return
			}

			if initmap != nil {
				suffixreader := bytes.NewReader(data[n:])
				var p parser
				p.init(fpath, suffixreader, nil)
				p.parseInitData()
				initmap[pkg] = p.initdata
			}

		default:
			err = fmt.Errorf("unrecognized magic string: %q", string(magic[:]))
		}

		return
	}
}