Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Thiago Henrique Hüpner committed Jun 29, 2024
1 parent d3e0bcf commit e6f2c92
Show file tree
Hide file tree
Showing 6 changed files with 1,891 additions and 56 deletions.
64 changes: 64 additions & 0 deletions src/classloader/classloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,65 @@ func LoadFromLoaderChannel(LoaderChannel <-chan string) {
globals.LoaderWg.Done()
}

// Load a class from name in java/lang/Class format
func LoadClassFromNameOnlyToClassLoader(classloader *Classloader, className string) error {
var err error

if className == "" {
errMsg := "LoadClassFromNameOnly(): null class name is invalid"
_ = log.Log(errMsg, log.SEVERE)
debug.PrintStack()
return errors.New(errMsg)
}

// get the jmod file name for this class. We'll use the jmod file to
// get the .class file for this class.
jmodFileName := JmodMapFetch(className)

if strings.HasSuffix(className, ";") {
msg := fmt.Sprintf("LoadClassFromNameOnly: invalid class name: %s", className)
_ = log.Log(msg, log.SEVERE)
debug.PrintStack()
return errors.New(msg)
}

// Load class from a jmod?
if jmodFileName != "" {
_ = log.Log("LoadClassFromNameOnly: Load "+className+" from jmod "+jmodFileName, log.CLASS)
classBytes, err := GetClassBytes(jmodFileName, className)
if err != nil {
_ = log.Log("LoadClassFromNameOnly: GetClassBytes className="+className+" from jmodFileName="+jmodFileName+" failed", log.SEVERE)
_ = log.Log(err.Error(), log.SEVERE)
}
_, err = loadClassFromBytes(*classloader, className, classBytes)
return err
}

// Load class from a jar file?
if len(globals.GetGlobalRef().StartingJar) > 0 {
validName := util.ConvertToPlatformPathSeparators(className)
_ = log.Log("LoadClassFromNameOnly: LoadClassFromJar "+validName, log.CLASS)
_, err = LoadClassFromJar(*classloader, validName, globals.GetGlobalRef().StartingJar)
if err != nil {
_ = log.Log("LoadClassFromNameOnly: LoadClassFromJar "+validName+" failed", log.SEVERE)
_ = log.Log(err.Error(), log.SEVERE)
}
return err
}

// Loading from a local file system class
// TODO: classpath
validName := util.ConvertToPlatformPathSeparators(className)
_ = log.Log("LoadClassFromNameOnly: Loaded class from file "+validName, log.CLASS)
_, err = LoadClassFromFile(*classloader, validName)
if err != nil {
errMsg := fmt.Sprintf("LoadClassFromNameOnly for %s failed", className)
globals.GetGlobalRef().FuncThrowException(excNames.ClassNotFoundException, errMsg)
return errors.New(errMsg) // return for tests only
}
return err
}

// Load a class from name in java/lang/Class format
func LoadClassFromNameOnly(className string) error {
var err error
Expand Down Expand Up @@ -451,8 +510,13 @@ func ParseAndPostClass(cl *Classloader, filename string, rawBytes []byte) (uint3
Loader: cl.Name,
Data: &classToPost,
}

MethAreaInsert(fullyParsedClass.className, &eKF)

if VerifyClass(&eKF, cl) != nil {
return types.InvalidStringIndex, fmt.Errorf("class did not verify")
}

// record the class in the classloader
ClassesLock.Lock()
cl.ClassCount += 1
Expand Down
110 changes: 54 additions & 56 deletions src/classloader/jmodBase.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ package classloader

import (
"archive/zip"
"bytes"
"io"
"jacobin/globals"
"jacobin/log"
"strings"
)
Expand All @@ -19,60 +17,60 @@ import (
// Only called in one place: LoadBaseClasses.
func WalkBaseJmod() error {

// Skip over the JMOD header so that it is recognized as a ZIP file
global := globals.GetGlobalRef()
ioReader := bytes.NewReader(global.JmodBaseBytes[4:])
zipReader, err := zip.NewReader(ioReader, int64(len(global.JmodBaseBytes)-4))
if err != nil {
_ = log.Log(err.Error(), log.WARNING)
return err
}

// Get the lib/classlist (bootstrap set of classes) if it exists
bootstrapSet := getClasslist(*zipReader)
useBootstrapSet := len(bootstrapSet) > 0

// For each class file in the base jmod,
// if it is in the classlist
for _, classFile := range zipReader.File {

// If not prefixed by "classes" or suffixed by ".class", skip this file
if !strings.HasPrefix(classFile.Name, "classes") {
continue
}
if !strings.HasSuffix(classFile.Name, ".class") {
continue
}

// Remove prefix for bootstrap list check
strapFileName := strings.Replace(classFile.Name, "classes/", "", 1)

// Is there a bootstrap list?
if useBootstrapSet {
// Yes, make sure that this class is on the list
_, onList := bootstrapSet[strapFileName]
if !onList {
continue
}
}

// Open the class file
rc, err := classFile.Open()
if err != nil {
return err
}

// Read all of the bytes
classBytes, err := io.ReadAll(rc)
if err != nil {
return err
}
_ = rc.Close()

// Parse and post class into MethArea
ParseAndPostClass(&BootstrapCL, classFile.Name, classBytes)

}
//// Skip over the JMOD header so that it is recognized as a ZIP file
//global := globals.GetGlobalRef()
//ioReader := bytes.NewReader(global.JmodBaseBytes[4:])
//zipReader, err := zip.NewReader(ioReader, int64(len(global.JmodBaseBytes)-4))
//if err != nil {
// _ = log.Log(err.Error(), log.WARNING)
// return err
//}
//
//// Get the lib/classlist (bootstrap set of classes) if it exists
//bootstrapSet := getClasslist(*zipReader)
//useBootstrapSet := len(bootstrapSet) > 0
//
//// For each class file in the base jmod,
//// if it is in the classlist
//for _, classFile := range zipReader.File {
//
// // If not prefixed by "classes" or suffixed by ".class", skip this file
// if !strings.HasPrefix(classFile.Name, "classes") {
// continue
// }
// if !strings.HasSuffix(classFile.Name, ".class") {
// continue
// }
//
// // Remove prefix for bootstrap list check
// strapFileName := strings.Replace(classFile.Name, "classes/", "", 1)
//
// // Is there a bootstrap list?
// if useBootstrapSet {
// // Yes, make sure that this class is on the list
// _, onList := bootstrapSet[strapFileName]
// if !onList {
// continue
// }
// }
//
// // Open the class file
// rc, err := classFile.Open()
// if err != nil {
// return err
// }
//
// // Read all of the bytes
// classBytes, err := io.ReadAll(rc)
// if err != nil {
// return err
// }
// _ = rc.Close()
//
// // Parse and post class into MethArea
// //ParseAndPostClass(&BootstrapCL, classFile.Name, classBytes)
//
//}

return nil
}
Expand Down
Loading

0 comments on commit e6f2c92

Please sign in to comment.