From d8a4f3ec91db3d4ef4cd519074e51cbafc118c15 Mon Sep 17 00:00:00 2001 From: Andrew Binstock <920630+platypusguy@users.noreply.github.com> Date: Sat, 2 Sep 2023 19:31:43 -0700 Subject: [PATCH] JACOBIN-345 Replaced several routines with native methods. --- src/classloader/javaLangString.go | 21 ++++++++++++++--- src/classloader/javaLangSystem.go | 39 +++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/classloader/javaLangString.go b/src/classloader/javaLangString.go index d2775d8c..633f1dd3 100644 --- a/src/classloader/javaLangString.go +++ b/src/classloader/javaLangString.go @@ -6,9 +6,14 @@ package classloader +import ( + "jacobin/log" + "jacobin/types" +) + /* -We don't run String's static initializer block because the initialization -is already handled in new String creation + We don't run String's static initializer block because the initialization + is already handled in String creation */ func Load_Lang_String() map[string]GMeth { @@ -16,8 +21,18 @@ func Load_Lang_String() map[string]GMeth { MethodSignatures["java/lang/String.()V"] = GMeth{ ParamSlots: 0, - GFunction: justReturn, + GFunction: stringClinit, } return MethodSignatures } + +func stringClinit([]interface{}) interface{} { + klass := MethAreaFetch("java/lang/String") + if klass == nil { + errMsg := "In , expected java/lang/String to be in the MethodArea, but it was not" + _ = log.Log(errMsg, log.SEVERE) + } + klass.Data.ClInit = types.ClInitRun // just mark that String.() has been run + return nil +} diff --git a/src/classloader/javaLangSystem.go b/src/classloader/javaLangSystem.go index ea526ded..687769bc 100644 --- a/src/classloader/javaLangSystem.go +++ b/src/classloader/javaLangSystem.go @@ -9,8 +9,10 @@ package classloader import ( "fmt" "jacobin/globals" + "jacobin/log" "jacobin/object" "jacobin/shutdown" + "jacobin/types" "os" "os/user" "runtime" @@ -66,16 +68,49 @@ func Load_Lang_System() map[string]GMeth { GFunction: getProperty, } - // need to replace eventually by enbling the Java intializer to run - MethodSignatures["java/lang/System.()V"] = + MethodSignatures["java/lang/System.registerNatives()V"] = GMeth{ ParamSlots: 0, GFunction: justReturn, } + MethodSignatures["java/lang/System.()V"] = + GMeth{ + ParamSlots: 0, + GFunction: clinit, + } + return MethodSignatures } +/* + check whether this clinit() has been previously run. If not, have it duplicate the + following bytecodes from JDK 17 java/lang/System: + static {}; + 0: invokestatic #637 // Method registerNatives:()V + 3: aconst_null + 4: putstatic #640 // Field in:Ljava/io/InputStream; + 7: aconst_null + 8: putstatic #387 // Field out:Ljava/io/PrintStream; + 11: aconst_null + 12: putstatic #384 // Field err:Ljava/io/PrintStream; + 15: return +*/ +func clinit([]interface{}) interface{} { + klass := MethAreaFetch("java/lang/System") + if klass == nil { + errMsg := "In , expected java/lang/System to be in the MethodArea, but it was not" + _ = log.Log(errMsg, log.SEVERE) + } + if klass.Data.ClInit != types.ClInitRun { + _ = AddStatic("java/lang/System.in", Static{Type: "L", Value: object.Null}) + _ = AddStatic("java/lang/System.err", Static{Type: "L", Value: object.Null}) + _ = AddStatic("java/lang/System.out", Static{Type: "L", Value: object.Null}) + klass.Data.ClInit = types.ClInitRun + } + return nil +} + // Return time in milliseconds, measured since midnight of Jan 1, 1970 func currentTimeMillis([]interface{}) interface{} { return time.Now().UnixMilli() // is int64