Check-in [7e48f725c8]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merge wip-midlevel into trunk, yay!
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 7e48f725c8aba2dc5b267a6925bbc47521542606
User & Date: stephanie.gawroriski 2020-06-30 22:23:47
Context
2020-07-01
07:02
Backup developer notes. check-in: 134c2ad82a user: squirreljme tags: trunk, x-date-202007
2020-06-30
22:28
Create new branch named "wip-midlcdui" check-in: 5ddea90a4e user: stephanie.gawroriski tags: wip-midlcdui
22:23
Merge wip-midlevel into trunk, yay! check-in: 7e48f725c8 user: stephanie.gawroriski tags: trunk
22:14
Removal of ObjectAccess. Closed-Leaf check-in: 84d1b6e583 user: stephanie.gawroriski tags: wip-midlevel
07:02
Backup developer notes. check-in: 174e69a68a user: squirreljme tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to .circleci/config.yml.

89
90
91
92
93
94
95






















96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
...
121
122
123
124
125
126
127
































128
129
130
131
132
133
134
135
136
137
138
139

140




            mkdir -p ~/test-results/junit/
            find . -type f -regex '.*/build/test-results/.*xml' -exec cp {} ~/test-results/junit/ \;
          when: always
      - store_test_results:
          path: ~/test-results
      - store_artifacts:
          path: ~/test-results/junit






















  test_springcoat:
    executor: buildenv
    steps:
      - checkout
      - attach_workspace:
          at: .
      - run:
          name: SpringCoat Tests
          command: |
            if ! ./gradlew testSpringCoat --continue --parallel
            then
              echo "SpringCoat testing failed, ignoring..." 1>&2
            fi
          no_output_timeout: 2m
      - run:
          name: Save test results
          command: |
            mkdir -p ~/test-results/junit/
            find . -type f -regex '.*/springcoat/junit-reports/.*xml' -exec cp {} ~/test-results/junit/ \;
          when: always
      - run:
................................................................................
          when: always
      - store_test_results:
          path: ~/test-results
      - store_artifacts:
          path: ~/test-results/junit
      - store_artifacts:
          path: ~/test-results/nps

































workflows:
  version: 2
  tests:
    jobs:
      - build_windows
      - build_linux
      - build_macosx
      - test_springcoat:
          requires:
            - build_windows
            - build_linux

            - build_macosx











>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








<
|
<
<
<
|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|

<

>
|
>
>
>
>
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

126



127
128
129
130
131
132
133
134
...
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187

188
189
190
191
192
193
194
            mkdir -p ~/test-results/junit/
            find . -type f -regex '.*/build/test-results/.*xml' -exec cp {} ~/test-results/junit/ \;
          when: always
      - store_test_results:
          path: ~/test-results
      - store_artifacts:
          path: ~/test-results/junit
  construct_testjars:
    executor: buildenv
    steps:
      - checkout
      - attach_workspace:
          at: .
      - run:
          name: Constuct Test JARs
          command: ./gradlew testJar --continue --parallel
      - persist_to_workspace:
          root: .
          paths:
            - '.gradle/*'
            - 'build/*'
            - 'buildSrc/.gradle/*'
            - 'buildSrc/build/*'
            - 'emulators/build/*'
            - 'emulators/*/build/*'
            - 'modules/build/*'
            - 'modules/*/build/*'
            - 'tools/build/*'
            - 'tools/*/build/*'
  test_springcoat:
    executor: buildenv
    steps:
      - checkout
      - attach_workspace:
          at: .
      - run:
          name: SpringCoat Tests

          command: timeout --foreground 15m ./gradlew testSpringCoat --console plain --continue --parallel



          no_output_timeout: 15m
      - run:
          name: Save test results
          command: |
            mkdir -p ~/test-results/junit/
            find . -type f -regex '.*/springcoat/junit-reports/.*xml' -exec cp {} ~/test-results/junit/ \;
          when: always
      - run:
................................................................................
          when: always
      - store_test_results:
          path: ~/test-results
      - store_artifacts:
          path: ~/test-results/junit
      - store_artifacts:
          path: ~/test-results/nps
  test_summercoat:
    executor: buildenv
    steps:
      - checkout
      - attach_workspace:
          at: .
      - run:
          name: SummerCoat Tests
          command: |
            if ! timeout --foreground 1s ./gradlew testSummerCoat --console plain --continue --parallel
            then
              echo "SummerCoat testing failed, ignoring..." 1>&2
            fi
          no_output_timeout: 1m
      - run:
          name: Save test results
          command: |
            mkdir -p ~/test-results/junit/
            find . -type f -regex '.*/summercoat/junit-reports/.*xml' -exec cp {} ~/test-results/junit/ \;
          when: always
      - run:
          name: Save snapshots
          command: |
            mkdir -p ~/test-results/nps/
            find . -type f -regex '.*/summercoat/nps/.*nps' -exec cp {} ~/test-results/nps/ \;
          when: always
      - store_test_results:
          path: ~/test-results
      - store_artifacts:
          path: ~/test-results/junit
      - store_artifacts:
          path: ~/test-results/nps

workflows:
  version: 2
  tests:
    jobs:
      - build_windows
      - build_linux
      - build_macosx
      - construct_testjars:
          requires:

            - build_linux
      - test_springcoat:
          requires:
            - construct_testjars
      - test_summercoat:
          requires:
            - construct_testjars

Changes to .gitignore.

24
25
26
27
28
29
30


*.diff
*.gdiff
*.patch
*.rej
*.bun
*.bundle










>
>
24
25
26
27
28
29
30
31
32
*.diff
*.gdiff
*.patch
*.rej
*.bun
*.bundle

# Crash logs
*.log

Changes to .idea/codeStyles/Project.xml.

3
4
5
6
7
8
9

10
11
12
13
14
15
16
    <option name="OTHER_INDENT_OPTIONS">
      <value>
        <option name="USE_TAB_CHARACTER" value="true" />
      </value>
    </option>
    <option name="LINE_SEPARATOR" value="&#10;" />
    <option name="RIGHT_MARGIN" value="79" />

    <DBN-PSQL>
      <case-options enabled="true">
        <option name="KEYWORD_CASE" value="lower" />
        <option name="FUNCTION_CASE" value="lower" />
        <option name="PARAMETER_CASE" value="lower" />
        <option name="DATATYPE_CASE" value="lower" />
        <option name="OBJECT_CASE" value="preserve" />







>







3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    <option name="OTHER_INDENT_OPTIONS">
      <value>
        <option name="USE_TAB_CHARACTER" value="true" />
      </value>
    </option>
    <option name="LINE_SEPARATOR" value="&#10;" />
    <option name="RIGHT_MARGIN" value="79" />
    <option name="SOFT_MARGINS" value="79" />
    <DBN-PSQL>
      <case-options enabled="true">
        <option name="KEYWORD_CASE" value="lower" />
        <option name="FUNCTION_CASE" value="lower" />
        <option name="PARAMETER_CASE" value="lower" />
        <option name="DATATYPE_CASE" value="lower" />
        <option name="OBJECT_CASE" value="preserve" />

Changes to .idea/dictionaries/xer.xml.

1
2
3
4
5

6
7






8
9
10
11
12
13
14
..
25
26
27
28
29
30
31


32
33


34

35
36
37
38
39
40

41
42

43

44
45
46
47
<component name="ProjectDictionaryState">
  <dictionary name="xer">
    <words>
      <w>accel</w>
      <w>backlight</w>

      <w>bootram</w>
      <w>cldc</w>






      <w>endianess</w>
      <w>fprintf</w>
      <w>gawroriski</w>
      <w>ioob</w>
      <w>jarray</w>
      <w>jboolean</w>
      <w>jbyte</w>
................................................................................
      <w>jniexport</w>
      <w>jobject</w>
      <w>jshort</w>
      <w>jstring</w>
      <w>jthrowable</w>
      <w>jvalue</w>
      <w>jweak</w>


      <w>multiphasicapps</w>
      <w>narg</w>


      <w>phasic</w>

      <w>siii</w>
      <w>siiii</w>
      <w>siiiii</w>
      <w>siiiiii</w>
      <w>siiiiiii</w>
      <w>siiiiiiii</w>

      <w>squirreljme</w>
      <w>stdint</w>

      <w>targetting</w>

      <w>vtable</w>
    </words>
  </dictionary>
</component>





>


>
>
>
>
>
>







 







>
>


>
>

>






>


>

>




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<component name="ProjectDictionaryState">
  <dictionary name="xer">
    <words>
      <w>accel</w>
      <w>backlight</w>
      <w>baos</w>
      <w>bootram</w>
      <w>cldc</w>
      <w>compactified</w>
      <w>cpibm</w>
      <w>csascii</w>
      <w>csibm</w>
      <w>csisolatin</w>
      <w>ebcdic</w>
      <w>endianess</w>
      <w>fprintf</w>
      <w>gawroriski</w>
      <w>ioob</w>
      <w>jarray</w>
      <w>jboolean</w>
      <w>jbyte</w>
................................................................................
      <w>jniexport</w>
      <w>jobject</w>
      <w>jshort</w>
      <w>jstring</w>
      <w>jthrowable</w>
      <w>jvalue</w>
      <w>jweak</w>
      <w>ljava</w>
      <w>microedition</w>
      <w>multiphasicapps</w>
      <w>narg</w>
      <w>noassert</w>
      <w>nsee</w>
      <w>phasic</w>
      <w>roro</w>
      <w>siii</w>
      <w>siiii</w>
      <w>siiiii</w>
      <w>siiiiii</w>
      <w>siiiiiii</w>
      <w>siiiiiiii</w>
      <w>springcoat</w>
      <w>squirreljme</w>
      <w>stdint</w>
      <w>summercoat</w>
      <w>targetting</w>
      <w>vmtypes</w>
      <w>vtable</w>
    </words>
  </dictionary>
</component>

Changes to .idea/fileTemplates/H File.h.

1
2
3
4
5
6
#parse("CPP Header.h")

#ifndef __HEADER_H__
#define __HEADER_H__

#endif /*__HEADER_H__ */



|

|
1
2
3
4
5
6
#parse("CPP Header.h")

#ifndef __HEADER_H__
\#define __HEADER_H__

#endif /* __HEADER_H__ */

Changes to .idea/gradle.xml.

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<project version="4">
  <component name="GradleMigrationSettings" migrationVersion="1" />
  <component name="GradleSettings">
    <option name="linkedExternalProjectsSettings">
      <GradleProjectSettings>
        <option name="delegatedBuild" value="true" />
        <option name="testRunner" value="GRADLE" />
        <option name="disableWrapperSourceDistributionNotification" value="true" />
        <option name="distributionType" value="DEFAULT_WRAPPED" />
        <option name="externalProjectPath" value="$PROJECT_DIR$" />
        <option name="gradleJvm" value="1.8" />
        <option name="modules">
          <set>
            <option value="$PROJECT_DIR$" />
            <option value="$PROJECT_DIR$/buildSrc" />







<







2
3
4
5
6
7
8

9
10
11
12
13
14
15
<project version="4">
  <component name="GradleMigrationSettings" migrationVersion="1" />
  <component name="GradleSettings">
    <option name="linkedExternalProjectsSettings">
      <GradleProjectSettings>
        <option name="delegatedBuild" value="true" />
        <option name="testRunner" value="GRADLE" />

        <option name="distributionType" value="DEFAULT_WRAPPED" />
        <option name="externalProjectPath" value="$PROJECT_DIR$" />
        <option name="gradleJvm" value="1.8" />
        <option name="modules">
          <set>
            <option value="$PROJECT_DIR$" />
            <option value="$PROJECT_DIR$/buildSrc" />

Changes to .idea/inspectionProfiles/Project_Default.xml.

13
14
15
16
17
18
19
20


21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
..
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
..
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
...
182
183
184
185
186
187
188
189
190

191
192
193
194
195
196
197
...
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
      <option name="m_limit" value="1" />
    </inspection_tool>
    <inspection_tool class="AnonymousHasLambdaAlternative" enabled="false" level="WARNING" enabled_by_default="false" />
    <inspection_tool class="AnonymousInnerClass" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="ArrayLengthInLoopCondition" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AssertEqualsBetweenInconvertibleTypes" enabled="false" level="WARNING" enabled_by_default="false" />
    <inspection_tool class="AssignmentUsedAsCondition" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AutoCloseableResource" enabled="true" level="WARNING" enabled_by_default="true" />


    <inspection_tool class="BeforeClassOrAfterClassIsPublicStaticVoidNoArg" enabled="false" level="WARNING" enabled_by_default="false" />
    <inspection_tool class="BeforeOrAfterIsPublicVoidNoArg" enabled="false" level="WARNING" enabled_by_default="false" />
    <inspection_tool class="BooleanMethodNameMustStartWithQuestion" enabled="false" level="WEAK WARNING" enabled_by_default="false">
      <option name="ignoreBooleanMethods" value="false" />
      <option name="ignoreInAnnotationInterface" value="true" />
      <option name="onlyWarnOnBaseMethods" value="true" />
      <option name="questionString" value="add,are,can,check,contains,could,endsWith,equals,has,is,matches,must,put,remove,shall,should,startsWith,was,were,will,would" />
    </inspection_tool>

    <inspection_tool class="CheckForOutOfMemoryOnLargeArrayAllocation" enabled="true" level="WARNING" enabled_by_default="true">
      <option name="m_limit" value="64" />
    </inspection_tool>
    <inspection_tool class="ClassComplexity" enabled="true" level="WARNING" enabled_by_default="true">
      <option name="m_limit" value="80" />
    </inspection_tool>
    <inspection_tool class="ClassCoupling" enabled="true" level="WARNING" enabled_by_default="true">
................................................................................
      <option name="commentsAreContent" value="true" />
    </inspection_tool>
    <inspection_tool class="EnhancedSwitchBackwardMigration" enabled="false" level="INFORMATION" enabled_by_default="false" />
    <inspection_tool class="EnhancedSwitchMigration" enabled="false" level="WARNING" enabled_by_default="false" />
    <inspection_tool class="ExceptionNameDoesntEndWithException" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
    <inspection_tool class="ExplicitArgumentCanBeLambda" enabled="false" level="INFORMATION" enabled_by_default="false" />
    <inspection_tool class="ExtendsUtilityClass" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="FeatureEnvy" enabled="true" level="WARNING" enabled_by_default="true">
      <option name="ignoreTestCases" value="false" />
    </inspection_tool>
    <inspection_tool class="FieldNamingConvention" enabled="true" level="WEAK WARNING" enabled_by_default="true">
      <extension name="ConstantNamingConvention" enabled="true">
        <option name="m_regex" value="_?[a-zA-Z][A-Z_\d]*" />
        <option name="m_minLength" value="2" />
        <option name="m_maxLength" value="32" />
      </extension>
      <extension name="ConstantWithMutableFieldTypeNamingConvention" enabled="true">
        <option name="m_regex" value="_?[a-z][a-zA-z_]*" />
        <option name="m_minLength" value="2" />
        <option name="m_maxLength" value="32" />
      </extension>
      <extension name="EnumeratedConstantNamingConvention" enabled="true">
        <option name="m_regex" value="[A-Z][A-Z_\d]*" />
        <option name="m_minLength" value="2" />
        <option name="m_maxLength" value="40" />
................................................................................
      </extension>
      <extension name="InstanceVariableNamingConvention" enabled="true">
        <option name="m_regex" value="_?[a-z][a-zA-z_]*" />
        <option name="m_minLength" value="2" />
        <option name="m_maxLength" value="32" />
      </extension>
      <extension name="StaticVariableNamingConvention" enabled="true">
        <option name="m_regex" value="_?[A-Z][A-Z_\d]*" />
        <option name="m_minLength" value="2" />
        <option name="m_maxLength" value="32" />
      </extension>
    </inspection_tool>
    <inspection_tool class="Finalize" enabled="true" level="ERROR" enabled_by_default="true">
      <option name="ignoreTrivialFinalizers" value="false" />
    </inspection_tool>
................................................................................
      <option name="m_ignoreForLoopParameters" value="true" />
      <option name="m_ignoreCatchParameters" value="true" />
      <option name="m_regex" value="(__)?[a-z][A-Za-z\d]*" />
      <option name="m_minLength" value="1" />
      <option name="m_maxLength" value="20" />
    </inspection_tool>
    <inspection_tool class="LongLine" enabled="true" level="TYPO" enabled_by_default="true" />
    <inspection_tool class="MagicNumber" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
    <inspection_tool class="MethodCallInLoopCondition" enabled="true" level="WARNING" enabled_by_default="true" />

    <inspection_tool class="MethodNameSameAsClassName" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
    <inspection_tool class="MethodNameSameAsParentName" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
    <inspection_tool class="MethodRefCanBeReplacedWithLambda" enabled="false" level="INFORMATION" enabled_by_default="false" />
    <inspection_tool class="MissingOverrideAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
      <option name="ignoreObjectMethods" value="false" />
      <option name="ignoreAnonymousClassMethods" value="false" />
    </inspection_tool>
................................................................................
      <option name="ignoreInconvertibleTypes" value="true" />
    </inspection_tool>
    <inspection_tool class="OverloadedVarargsMethod" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
    <inspection_tool class="OverlyLargePrimitiveArrayInitializer" enabled="true" level="WARNING" enabled_by_default="true">
      <option name="m_limit" value="64" />
    </inspection_tool>
    <inspection_tool class="PackageInfoWithoutPackage" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="PackageNamingConvention" enabled="true" level="WEAK WARNING" enabled_by_default="true">
      <option name="m_regex" value="[a-z]*" />
      <option name="m_minLength" value="2" />
      <option name="m_maxLength" value="16" />
    </inspection_tool>
    <inspection_tool class="ParameterNameDiffersFromOverriddenParameter" enabled="false" level="WEAK WARNING" enabled_by_default="false">
      <option name="m_ignoreSingleCharacterNames" value="false" />
      <option name="m_ignoreOverridesOfLibraryMethods" value="false" />







|
>
>








>







 







<
<
<


|




|







 







|







 







|
|
>







 







|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
..
74
75
76
77
78
79
80



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
..
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
...
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
...
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
      <option name="m_limit" value="1" />
    </inspection_tool>
    <inspection_tool class="AnonymousHasLambdaAlternative" enabled="false" level="WARNING" enabled_by_default="false" />
    <inspection_tool class="AnonymousInnerClass" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="ArrayLengthInLoopCondition" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AssertEqualsBetweenInconvertibleTypes" enabled="false" level="WARNING" enabled_by_default="false" />
    <inspection_tool class="AssignmentUsedAsCondition" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AutoCloseableResource" enabled="true" level="WARNING" enabled_by_default="true">
      <option name="METHOD_MATCHER_CONFIG" value="java.util.Formatter,format,java.io.Writer,append,com.google.common.base.Preconditions,checkNotNull,org.hibernate.Session,close,java.io.PrintWriter,printf,cc.squirreljme.vm.springcoat.NativeHLEHandler,__fdOutput" />
    </inspection_tool>
    <inspection_tool class="BeforeClassOrAfterClassIsPublicStaticVoidNoArg" enabled="false" level="WARNING" enabled_by_default="false" />
    <inspection_tool class="BeforeOrAfterIsPublicVoidNoArg" enabled="false" level="WARNING" enabled_by_default="false" />
    <inspection_tool class="BooleanMethodNameMustStartWithQuestion" enabled="false" level="WEAK WARNING" enabled_by_default="false">
      <option name="ignoreBooleanMethods" value="false" />
      <option name="ignoreInAnnotationInterface" value="true" />
      <option name="onlyWarnOnBaseMethods" value="true" />
      <option name="questionString" value="add,are,can,check,contains,could,endsWith,equals,has,is,matches,must,put,remove,shall,should,startsWith,was,were,will,would" />
    </inspection_tool>
    <inspection_tool class="CharsetObjectCanBeUsed" enabled="false" level="WARNING" enabled_by_default="false" />
    <inspection_tool class="CheckForOutOfMemoryOnLargeArrayAllocation" enabled="true" level="WARNING" enabled_by_default="true">
      <option name="m_limit" value="64" />
    </inspection_tool>
    <inspection_tool class="ClassComplexity" enabled="true" level="WARNING" enabled_by_default="true">
      <option name="m_limit" value="80" />
    </inspection_tool>
    <inspection_tool class="ClassCoupling" enabled="true" level="WARNING" enabled_by_default="true">
................................................................................
      <option name="commentsAreContent" value="true" />
    </inspection_tool>
    <inspection_tool class="EnhancedSwitchBackwardMigration" enabled="false" level="INFORMATION" enabled_by_default="false" />
    <inspection_tool class="EnhancedSwitchMigration" enabled="false" level="WARNING" enabled_by_default="false" />
    <inspection_tool class="ExceptionNameDoesntEndWithException" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
    <inspection_tool class="ExplicitArgumentCanBeLambda" enabled="false" level="INFORMATION" enabled_by_default="false" />
    <inspection_tool class="ExtendsUtilityClass" enabled="true" level="WARNING" enabled_by_default="true" />



    <inspection_tool class="FieldNamingConvention" enabled="true" level="WEAK WARNING" enabled_by_default="true">
      <extension name="ConstantNamingConvention" enabled="true">
        <option name="m_regex" value="_?[a-zA-Z][A-Za-z_\d]*" />
        <option name="m_minLength" value="2" />
        <option name="m_maxLength" value="32" />
      </extension>
      <extension name="ConstantWithMutableFieldTypeNamingConvention" enabled="true">
        <option name="m_regex" value="_?[a-zA-Z][A-Za-z_\d]*" />
        <option name="m_minLength" value="2" />
        <option name="m_maxLength" value="32" />
      </extension>
      <extension name="EnumeratedConstantNamingConvention" enabled="true">
        <option name="m_regex" value="[A-Z][A-Z_\d]*" />
        <option name="m_minLength" value="2" />
        <option name="m_maxLength" value="40" />
................................................................................
      </extension>
      <extension name="InstanceVariableNamingConvention" enabled="true">
        <option name="m_regex" value="_?[a-z][a-zA-z_]*" />
        <option name="m_minLength" value="2" />
        <option name="m_maxLength" value="32" />
      </extension>
      <extension name="StaticVariableNamingConvention" enabled="true">
        <option name="m_regex" value="_?[a-zA-Z][A-Za-z_\d]*" />
        <option name="m_minLength" value="2" />
        <option name="m_maxLength" value="32" />
      </extension>
    </inspection_tool>
    <inspection_tool class="Finalize" enabled="true" level="ERROR" enabled_by_default="true">
      <option name="ignoreTrivialFinalizers" value="false" />
    </inspection_tool>
................................................................................
      <option name="m_ignoreForLoopParameters" value="true" />
      <option name="m_ignoreCatchParameters" value="true" />
      <option name="m_regex" value="(__)?[a-z][A-Za-z\d]*" />
      <option name="m_minLength" value="1" />
      <option name="m_maxLength" value="20" />
    </inspection_tool>
    <inspection_tool class="LongLine" enabled="true" level="TYPO" enabled_by_default="true" />
    <inspection_tool class="MagicNumber" enabled="true" level="WEAK WARNING" enabled_by_default="true">
      <scope name="Tests" level="WEAK WARNING" enabled="false" />
    </inspection_tool>
    <inspection_tool class="MethodNameSameAsClassName" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
    <inspection_tool class="MethodNameSameAsParentName" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
    <inspection_tool class="MethodRefCanBeReplacedWithLambda" enabled="false" level="INFORMATION" enabled_by_default="false" />
    <inspection_tool class="MissingOverrideAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
      <option name="ignoreObjectMethods" value="false" />
      <option name="ignoreAnonymousClassMethods" value="false" />
    </inspection_tool>
................................................................................
      <option name="ignoreInconvertibleTypes" value="true" />
    </inspection_tool>
    <inspection_tool class="OverloadedVarargsMethod" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
    <inspection_tool class="OverlyLargePrimitiveArrayInitializer" enabled="true" level="WARNING" enabled_by_default="true">
      <option name="m_limit" value="64" />
    </inspection_tool>
    <inspection_tool class="PackageInfoWithoutPackage" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="PackageNamingConvention" enabled="false" level="WEAK WARNING" enabled_by_default="false">
      <option name="m_regex" value="[a-z]*" />
      <option name="m_minLength" value="2" />
      <option name="m_maxLength" value="16" />
    </inspection_tool>
    <inspection_tool class="ParameterNameDiffersFromOverriddenParameter" enabled="false" level="WEAK WARNING" enabled_by_default="false">
      <option name="m_ignoreSingleCharacterNames" value="false" />
      <option name="m_ignoreOverridesOfLibraryMethods" value="false" />

Changes to .idea/misc.xml.

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ExternalStorageConfigurationManager" enabled="true" />
  <component name="JavaScriptSettings">
    <option name="languageLevel" value="ES6" />
  </component>
  <component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="false" project-jdk-name="1.8" project-jdk-type="JavaSDK" />
</project>






|

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ExternalStorageConfigurationManager" enabled="true" />
  <component name="JavaScriptSettings">
    <option name="languageLevel" value="ES6" />
  </component>
  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="false" project-jdk-name="1.8" project-jdk-type="JavaSDK" />
</project>

Changes to buildSrc/src/main/java/cc/squirreljme/plugin/ErrorListManager.java.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
 * This is used to get the error lists from a project.
 *
 * @since 2020/02/22
 */
public final class ErrorListManager
{
	
	/** The project to manage the list for. */
	protected final Project project;
	
	/** The listed errors. */
	private final Map<Integer, SourceError> _errors =
		new TreeMap<>();
	







<







18
19
20
21
22
23
24

25
26
27
28
29
30
31
/**
 * This is used to get the error lists from a project.
 *
 * @since 2020/02/22
 */
public final class ErrorListManager
{

	/** The project to manage the list for. */
	protected final Project project;
	
	/** The listed errors. */
	private final Map<Integer, SourceError> _errors =
		new TreeMap<>();
	

Changes to buildSrc/src/main/java/cc/squirreljme/plugin/SourceError.java.

88
89
90
91
92
93
94



95
96
97
98
99
100
101
...
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
		// Store body in
		this.body = body.toString();
		
		// Parameter list?
		List<String> parameters = new ArrayList<String>();
		if ("(".equals(queue.peekFirst()))
		{



			// Process queue
			StringBuilder buffer = new StringBuilder();
			while (!queue.isEmpty())
			{
				String item = queue.peekFirst();
				
				// End parameter or next?
................................................................................
	 * @return The translated string to index.
	 * @since 2020/02/22
	 */
	public static String indexToString(int __index)
	{
		StringBuilder sb = new StringBuilder();
		
		sb.append(Character.toUpperCase(Character.forDigit(
			__index / Character.MAX_RADIX, Character.MAX_RADIX)));
		sb.append(Character.toUpperCase(Character.forDigit(
			__index % Character.MAX_RADIX, Character.MAX_RADIX)));
		
		return sb.toString();
	}
	
	/**
	 * Returns the index for the given string.







>
>
>







 







|

|







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
...
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
		// Store body in
		this.body = body.toString();
		
		// Parameter list?
		List<String> parameters = new ArrayList<String>();
		if ("(".equals(queue.peekFirst()))
		{
			// Remove the starting parenthesis so it is not added
			queue.removeFirst();
			
			// Process queue
			StringBuilder buffer = new StringBuilder();
			while (!queue.isEmpty())
			{
				String item = queue.peekFirst();
				
				// End parameter or next?
................................................................................
	 * @return The translated string to index.
	 * @since 2020/02/22
	 */
	public static String indexToString(int __index)
	{
		StringBuilder sb = new StringBuilder();
		
		sb.append(Character.toLowerCase(Character.forDigit(
			__index / Character.MAX_RADIX, Character.MAX_RADIX)));
		sb.append(Character.toLowerCase(Character.forDigit(
			__index % Character.MAX_RADIX, Character.MAX_RADIX)));
		
		return sb.toString();
	}
	
	/**
	 * Returns the index for the given string.

Changes to buildSrc/src/main/java/cc/squirreljme/plugin/SquirrelJMEPlugin.java.

37
38
39
40
41
42
43

44
45
46
47
48
49
50
51
	 * {@inheritDoc}
	 * @since 2020/02/15
	 */
	@Override
	public void apply(Project __project)
	{
		// Add configuration for SquirrelJME

		__project.getExtensions().<SquirrelJMEPluginConfiguration>create(
			"squirreljme", SquirrelJMEPluginConfiguration.class,
			this, __project);
		
		// Build task
		__project.getTasks().getByName("build");
		
		// Class generation







>
|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
	 * {@inheritDoc}
	 * @since 2020/02/15
	 */
	@Override
	public void apply(Project __project)
	{
		// Add configuration for SquirrelJME
		SquirrelJMEPluginConfiguration config = __project
			.getExtensions().<SquirrelJMEPluginConfiguration>create(
			"squirreljme", SquirrelJMEPluginConfiguration.class,
			this, __project);
		
		// Build task
		__project.getTasks().getByName("build");
		
		// Class generation

Added buildSrc/src/main/java/cc/squirreljme/plugin/package-info.java.

































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

/**
 * This contains the base plugin code to support SquirrelJME.
 *
 * @since 2020/06/13
 */

package cc.squirreljme.plugin;

Changes to buildSrc/src/main/java/cc/squirreljme/plugin/tasks/AbstractEmulatedTask.java.

12
13
14
15
16
17
18

19
20
21
22
23

24
25
26
27
28
29
30
...
160
161
162
163
164
165
166
167
168
169
170



171
172
173
174
175
176
177
...
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
import cc.squirreljme.plugin.SquirrelJMEPluginConfiguration;
import cc.squirreljme.plugin.swm.JavaMEMidlet;
import cc.squirreljme.plugin.swm.JavaMEMidletType;
import cc.squirreljme.plugin.tasks.test.EmulatedTestUtilities;
import java.io.File;
import java.nio.file.Path;
import java.util.Collection;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Objects;
import java.util.Set;

import java.util.concurrent.Callable;
import org.gradle.api.Action;
import org.gradle.api.DefaultTask;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.Dependency;
................................................................................
	
	/**
	 * Returns the run class path.
	 *
	 * @return The run class path.
	 * @since 2020/02/29
	 */
	@Deprecated
	Iterable<Path> __runClassPath()
	{
		Collection<Path> result = new LinkedHashSet<>();



		
		this.__recursiveDependencies(result, this.getProject());
		
		return result;
	}
	
	/**
................................................................................
	 * Recursively scans and obtains dependencies.
	 *
	 * @param __out The output collection.
	 * @param __at The current project currently at.
	 * @since 2020/02/29
	 */
	@Deprecated
	final void __recursiveDependencies(Collection<Path> __out, Project __at)
	{
		this.__recursiveDependencies(__out, __at, new HashSet<>());
	}
	
	/**
	 * Recursively scans and obtains dependencies.
	 *







>





>







 







<



>
>
>







 







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176
177
178
179
180
181
...
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
import cc.squirreljme.plugin.SquirrelJMEPluginConfiguration;
import cc.squirreljme.plugin.swm.JavaMEMidlet;
import cc.squirreljme.plugin.swm.JavaMEMidletType;
import cc.squirreljme.plugin.tasks.test.EmulatedTestUtilities;
import java.io.File;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Deque;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.Callable;
import org.gradle.api.Action;
import org.gradle.api.DefaultTask;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.Dependency;
................................................................................
	
	/**
	 * Returns the run class path.
	 *
	 * @return The run class path.
	 * @since 2020/02/29
	 */

	Iterable<Path> __runClassPath()
	{
		Collection<Path> result = new LinkedHashSet<>();
		
		Deque<Project> projects = new LinkedList<>();
		Set<Project> didProjects = new TreeSet<>();
		
		this.__recursiveDependencies(result, this.getProject());
		
		return result;
	}
	
	/**
................................................................................
	 * Recursively scans and obtains dependencies.
	 *
	 * @param __out The output collection.
	 * @param __at The current project currently at.
	 * @since 2020/02/29
	 */
	@Deprecated
	private void __recursiveDependencies(Collection<Path> __out, Project __at)
	{
		this.__recursiveDependencies(__out, __at, new HashSet<>());
	}
	
	/**
	 * Recursively scans and obtains dependencies.
	 *

Changes to buildSrc/src/main/java/cc/squirreljme/plugin/tasks/TestInVMTask.java.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
..
31
32
33
34
35
36
37

38
39
40
41
42
43
44
..
52
53
54
55
56
57
58

59
60
61
62
63
64
65
..
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
...
103
104
105
106
107
108
109







110
111
112
113
114
115
116

117
118
119
120
121
122
123
124
125
126

127
128
129
130













131
132
133
134
135
136
137

138
139
140
141
142
143
144
145
146
147
148
149
150

151
152
153
154
155
156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

package cc.squirreljme.plugin.tasks;

import cc.squirreljme.plugin.tasks.test.EmulatedTestExecutionSpec;
import cc.squirreljme.plugin.tasks.test.EmulatedTestExecutor;
import java.io.File;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.Callable;
import javax.inject.Inject;
import org.gradle.api.internal.provider.AbstractMinimalProvider;
import org.gradle.api.tasks.testing.AbstractTestTask;
import org.gradle.api.tasks.testing.Test;
import org.gradle.jvm.tasks.Jar;

/**
 * Tests in virtual machine, this uses an abstract test tasks which implement
 * all of the needed classes for test.
................................................................................
 *  - reports.enabledReports.html.outputLocation
 *  - reports.enabledReports.junitXml.outputLocation
 *
 * Gradle Test task {@link Test}.
 *
 * @since 2020/03/06
 */

public class TestInVMTask
	extends AbstractTestTask
{
	/** The binary results directory. */
	private static final String _BINARY_RESULTS_DIRECTORY =
		"binaryResultsDirectory";
	
................................................................................
	 * Initializes the task.
	 *
	 * @param __jar The JAR sources.
	 * @param __vm The virtual machine to run.
	 * @since 2020/03/06
	 */
	@Inject

	public TestInVMTask(Jar __jar, String __vm)
	{
		// We need these for tasks and such
		this.emulator = __vm;
		this.jar = __jar;
		
		// Set description
................................................................................
		// The input file for our tests is the JAR we want to look at!
		this.getInputs().file(__jar.getArchiveFile());
		
		// Where binary results are going to be stored, these both have to
		// be set otherwise the test build will fail
		this.setProperty(TestInVMTask._BINARY_RESULTS_DIRECTORY,
			this.getProject().getObjects().directoryProperty()
			.dir(new __BinaryResultsDirectoryProvider__()));
		this.setBinResultsDir(
			new File(new __BinaryResultsDirectoryProvider__().get()));
		
		// Generate HTML reports because they are useful
		this.getReports().getHtml().setDestination(
			this.__tempRoot().resolve("html-reports").toFile());
		
		// Generate JUnit XML, these will be uploaded to CICD
		this.getReports().getJunitXml().setDestination(
................................................................................
		// have when running the VMs especially when not fully stable
		this.testLogging(__settings ->
			{
				__settings.setShowCauses(true);
				__settings.setShowStandardStreams(true);
				__settings.setShowStackTraces(true);
			});







	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/03/06
	 */
	@Override

	protected EmulatedTestExecutor createTestExecuter()
	{
		return new EmulatedTestExecutor(this);
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/03/06
	 */
	@Override

	protected EmulatedTestExecutionSpec createTestExecutionSpec()
	{
		return new EmulatedTestExecutionSpec(this.emulator, this.jar);
	}













	
	/**
	 * Finds the emulator JAR task.
	 *
	 * @return The emulator JAR task.
	 * @since 2020/02/29
	 */

	Jar __findEmulatorBaseJarTask()
	{
		return (Jar)Objects.requireNonNull(this.getProject().getRootProject().
			findProject(":emulators:emulator-base"),
			"No emulator base?").getTasks().getByName("jar");
	}
	
	/**
	 * Locates the emulator package to base on.
	 *
	 * @return The emulator base.
	 * @since 2020/02/29
	 */

	Jar __findEmulatorJarTask()
	{
		return (Jar)Objects.requireNonNull(this.getProject().getRootProject().
			findProject(":emulators:" + this.emulator + "-vm"),
			"No emulator?").getTasks().getByName("jar");
	}
	
	/**
	 * Returns the temporary file root base.
	 *
	 * @return The temporary root.
	 * @since 2020/03/06
	 */

	public final Path __tempRoot()
	{
		return this.getProject().getBuildDir().toPath().resolve("vm-test").
			resolve(this.emulator);
	}
	
	/**
	 * Provider for directory.
	 *
	 * @since 2020/03/06
	 */
	class __BinaryResultsDirectoryProvider__
		extends AbstractMinimalProvider<String>
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/03/06
		 */
		@Override
		public String get()
			throws IllegalStateException
		{
			String rv = this.getOrNull();
			if (rv == null)
				throw new IllegalStateException("No directory!");
			return rv;
		}
		
		/**
		 * {@inheritDoc}
		 * @since 2020/03/06
		 */
		@Override
		public String getOrNull()
		{
			return TestInVMTask.this.__tempRoot().resolve("bin-results")
				.toAbsolutePath().toString();
		}
		
		/**
		 * {@inheritDoc}
		 * @since 2020/03/06
		 */
		@Override
		public Class<String> getType()
		{
			return String.class;
		}
	}
}







<



|







 







>







 







>







 







|
|
<







 







>
>
>
>
>
>
>







>










>




>
>
>
>
>
>
>
>
>
>
>
>
>







>













>













>





|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25
26
..
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
..
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
..
73
74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
...
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194













































package cc.squirreljme.plugin.tasks;

import cc.squirreljme.plugin.tasks.test.EmulatedTestExecutionSpec;
import cc.squirreljme.plugin.tasks.test.EmulatedTestExecutor;
import java.io.File;
import java.nio.file.Path;

import java.util.Objects;
import java.util.concurrent.Callable;
import javax.inject.Inject;
import org.gradle.api.internal.provider.DefaultProvider;
import org.gradle.api.tasks.testing.AbstractTestTask;
import org.gradle.api.tasks.testing.Test;
import org.gradle.jvm.tasks.Jar;

/**
 * Tests in virtual machine, this uses an abstract test tasks which implement
 * all of the needed classes for test.
................................................................................
 *  - reports.enabledReports.html.outputLocation
 *  - reports.enabledReports.junitXml.outputLocation
 *
 * Gradle Test task {@link Test}.
 *
 * @since 2020/03/06
 */
@Deprecated
public class TestInVMTask
	extends AbstractTestTask
{
	/** The binary results directory. */
	private static final String _BINARY_RESULTS_DIRECTORY =
		"binaryResultsDirectory";
	
................................................................................
	 * Initializes the task.
	 *
	 * @param __jar The JAR sources.
	 * @param __vm The virtual machine to run.
	 * @since 2020/03/06
	 */
	@Inject
	@Deprecated
	public TestInVMTask(Jar __jar, String __vm)
	{
		// We need these for tasks and such
		this.emulator = __vm;
		this.jar = __jar;
		
		// Set description
................................................................................
		// The input file for our tests is the JAR we want to look at!
		this.getInputs().file(__jar.getArchiveFile());
		
		// Where binary results are going to be stored, these both have to
		// be set otherwise the test build will fail
		this.setProperty(TestInVMTask._BINARY_RESULTS_DIRECTORY,
			this.getProject().getObjects().directoryProperty()
			.dir(new DefaultProvider<>(this::__binResultPath)));
		this.setBinResultsDir(new File(this.__binResultPath().toString()));

		
		// Generate HTML reports because they are useful
		this.getReports().getHtml().setDestination(
			this.__tempRoot().resolve("html-reports").toFile());
		
		// Generate JUnit XML, these will be uploaded to CICD
		this.getReports().getJunitXml().setDestination(
................................................................................
		// have when running the VMs especially when not fully stable
		this.testLogging(__settings ->
			{
				__settings.setShowCauses(true);
				__settings.setShowStandardStreams(true);
				__settings.setShowStackTraces(true);
			});
		
		// Make sure that both report types are enabled!
		this.reports(__reports ->
			{
				__reports.getJunitXml().setEnabled(true);
				__reports.getHtml().setEnabled(true);
			});
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/03/06
	 */
	@Override
	@Deprecated
	protected EmulatedTestExecutor createTestExecuter()
	{
		return new EmulatedTestExecutor(this);
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/03/06
	 */
	@Override
	@Deprecated
	protected EmulatedTestExecutionSpec createTestExecutionSpec()
	{
		return new EmulatedTestExecutionSpec(this.emulator, this.jar);
	}
	
	/**
	 * Returns the binary results path.
	 * 
	 * @return The binary results path.
	 * @since 2020/06/22
	 */
	@Deprecated
	CharSequence __binResultPath()
	{
		return this.__tempRoot().resolve("bin-results")
			.toAbsolutePath().toString();
	}
	
	/**
	 * Finds the emulator JAR task.
	 *
	 * @return The emulator JAR task.
	 * @since 2020/02/29
	 */
	@Deprecated
	Jar __findEmulatorBaseJarTask()
	{
		return (Jar)Objects.requireNonNull(this.getProject().getRootProject().
			findProject(":emulators:emulator-base"),
			"No emulator base?").getTasks().getByName("jar");
	}
	
	/**
	 * Locates the emulator package to base on.
	 *
	 * @return The emulator base.
	 * @since 2020/02/29
	 */
	@Deprecated
	Jar __findEmulatorJarTask()
	{
		return (Jar)Objects.requireNonNull(this.getProject().getRootProject().
			findProject(":emulators:" + this.emulator + "-vm"),
			"No emulator?").getTasks().getByName("jar");
	}
	
	/**
	 * Returns the temporary file root base.
	 *
	 * @return The temporary root.
	 * @since 2020/03/06
	 */
	@Deprecated
	public final Path __tempRoot()
	{
		return this.getProject().getBuildDir().toPath().resolve("vm-test").
			resolve(this.emulator);
	}
}












































Added buildSrc/src/main/java/cc/squirreljme/plugin/tasks/test/ConsoleLine.java.



















































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.plugin.tasks.test;

import org.gradle.api.internal.tasks.testing.TestResultProcessor;
import org.gradle.api.tasks.testing.TestOutputEvent;

/**
 * This indicates a line that happened on the consoles.
 *
 * @since 2020/06/22
 */
public final class ConsoleLine
{
	/** Is this to standard error?. */
	public final boolean stdErr;
	
	/** When did this happen? */
	public final long timeMillis;
	
	/** The text that was printed to the console. */
	public final String text;
	
	/**
	 * Initializes the console line.
	 * 
	 * @param __stdErr Is this standard error?
	 * @param __timeMillis When this message appeared.
	 * @param __text The text for the message.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/22
	 */
	public ConsoleLine(boolean __stdErr, long __timeMillis, String __text)
		throws NullPointerException
	{
		if (__text == null)
			throw new NullPointerException("NARG");
		
		this.stdErr = __stdErr;
		this.timeMillis = __timeMillis;
		this.text = __text;
	}
	
	/**
	 * Reports the line.
	 * 
	 * @param __results The test results output.
	 * @param __method The method to report to.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/22
	 */
	public void report(TestResultProcessor __results,
		EmulatedTestMethodDescriptor __method)
		throws NullPointerException
	{
		// Where is this going?
		TestOutputEvent.Destination destination = (this.stdErr ?
				TestOutputEvent.Destination.StdErr :
				TestOutputEvent.Destination.StdOut);
		
		// Print output
		__results.output(__method.getId(),
			EmulatedTestUtilities.output(destination,
				this.text + System.getProperty("line.separator")));
	}
}

Changes to buildSrc/src/main/java/cc/squirreljme/plugin/tasks/test/EmulatedTestExecutor.java.

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51




52
53
54
55
56
57
58
..
72
73
74
75
76
77
78





79
80
81
82
83
84
85
86
87
88
89











90
91

92
93
94
95
96


97
98
99
100
101
102


103
104
105
106
107
108
109
110
111
112
113
114
115
116











































117
118
119
120
121
122
123
124

125
126

127
128




129
130
131
132
133
134
135
136







137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
...
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190








































191
192
193
194
195
196
197

198
199

200
201
202
203
204

205
206
207
208
209
210
211
212
213
214
215

216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

232
233
234
235
236
237
238

239
240
241
242
243
244
245
246
247


248
249
250
251
252
253
254
255
256
257
258
259


260
261
262
263


264
265
266
267
268



269
270
271


272
273
274
275
276
277
278
279
280


281
282
283
284
285


286
287
288
289
290



291
292
293
294
295
296
297
...
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.plugin.tasks.test;

import cc.squirreljme.plugin.tasks.TestInVMTask;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.channels.ClosedByInterruptException;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Objects;
import java.util.TreeSet;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.gradle.api.Project;
import org.gradle.api.internal.tasks.testing.TestExecuter;
import org.gradle.api.internal.tasks.testing.TestResultProcessor;
import org.gradle.api.tasks.testing.TestOutputEvent;
import org.gradle.process.ExecResult;

/**
 * This is the executer for tests.
 *
 * @since 2020/03/06
 */
public final class EmulatedTestExecutor
	implements TestExecuter<EmulatedTestExecutionSpec>
{
	/** The number of permitted interrupts before failure. */
	private static final int _MAX_INTERRUPTS =
		8;
	
	/** The service resource file. */
	public static final String SERVICE_RESOURCE =
		"META-INF/services/net.multiphasicapps.tac.TestInterface";
	
	/** The test task. */
	private final TestInVMTask _testInVMTask;
	




	/** Should this test be stopped? */
	private volatile boolean _stopRunning =
		false;
	
	/**
	 * Initializes the task executor.
	 *
................................................................................
	@Override
	public void execute(EmulatedTestExecutionSpec __spec,
		TestResultProcessor __results)
	{
		// We need the project to access details
		Project project = this._testInVMTask.getProject();
		





		// Run for this suite/project
		EmulatedTestSuiteDescriptor suite =
			new EmulatedTestSuiteDescriptor(project);
		
		// Indicate that the suite has started execution
		__results.started(suite, EmulatedTestUtilities.startNow());
		
		// Perform testing logic
		boolean allPassed = true;
		try
		{











			// Execute test classes (find them and run them)
			allPassed = this.executeClasses(__spec, __results, suite);

			
			// Did all tests pass?
			__results.completed(suite.getId(),
				EmulatedTestUtilities.passOrFailNow(allPassed));
		}


		catch (Throwable t)
		{
			// Report the thrown exception
			__results.failure(suite.getId(), t);
			__results.completed(suite.getId(),
				EmulatedTestUtilities.failNow());


		}
		
		// Did not pass, so cause the task to fail
		if (!allPassed)
		{
			// Throw a blank failure exception
			RuntimeException toss = new RuntimeException("Failed tests.");
			toss.setStackTrace(new StackTraceElement[0]);
			
			throw toss;
		}
	}
	
	/**











































	 * Goes through and executes the single test class.
	 *
	 * @param __spec The specification.
	 * @param __results The output results.
	 * @param __method The method to run.
	 * @return The exit value of the test.
	 * @since 2020/03/06
	 */

	private int executeClass(EmulatedTestExecutionSpec __spec,
		TestResultProcessor __results, EmulatedTestMethodDescriptor __method)

	{
		Project project = this._testInVMTask.getProject();




		
		// For some reason test reports do not run if there is no output for
		// them, so this for the most part forces console output to happen
		// which makes tests happen
		__results.output(__method.getId(),
			EmulatedTestUtilities.outputErr(String.format(
			"Running test %s...", __method.getDisplayName())));
		







		// Execute the test Java program
		System.err.printf("Executing Java Program...%n");
		ExecResult result = project.javaexec(__javaExecSpec ->
			{
				Collection<String> args = new LinkedList<>();
				
				// The class we are executing in
				String withinClass = Objects.requireNonNull(
					__method.getParent(),
					"No test class?").getClassName();
				
				// Add emulator
				args.add("-Xemulator:" + __spec.emulator);
				
				// Add snapshot path
				args.add("-Xsnapshot:" + EmulatedTestExecutor.this
					._testInVMTask.__tempRoot().resolve("nps")
					.resolve(withinClass + ".nps").toAbsolutePath());
................................................................................
				// Only run a single test
				args.add("net.multiphasicapps.tac.MainSingleRunner");
				
				// Target this single test
				args.add(withinClass);
				
				// Configure the VM for execution
				__javaExecSpec.classpath(EmulatedTestUtilities
					.emulatorClassPath(project, __spec.emulator));
				__javaExecSpec.setMain("cc.squirreljme.emulator.vm.VMFactory");
				__javaExecSpec.setArgs(args);
				
				// Pipe outputs to the specified areas so the console can be
				// read properly!
				__javaExecSpec.setStandardOutput(new PipeOutputStream(
					__method.getId(), __results,
					TestOutputEvent.Destination.StdOut));
				__javaExecSpec.setErrorOutput(new PipeOutputStream(
					__method.getId(), __results,
					TestOutputEvent.Destination.StdErr));
				
				// Do not throw an exception on a non-zero exit value since
				// it is important to us
				__javaExecSpec.setIgnoreExitValue(true);
			});
		
		// Return the exit value here
		System.err.printf("Exited with value: %d%n", result.getExitValue());
		return result.getExitValue();
	}








































	
	/**
	 * Goes through and executes the test classes.
	 *
	 * @param __spec The specification.
	 * @param __results The output results.
	 * @param __suite The suite to run.

	 * @return Did all tests pass?
	 * @throws IOException On read errors.

	 * @since 2020/03/06
	 */
	@SuppressWarnings("FeatureEnvy")
	private boolean executeClasses(EmulatedTestExecutionSpec __spec,
		TestResultProcessor __results, EmulatedTestSuiteDescriptor __suite)

		throws IOException
	{
		// Extract all of the test classes to be executed
		Collection<String> testClasses = new TreeSet<>();
		for (int iCount = 0;;)
			try (ZipInputStream zip = new ZipInputStream(Files.newInputStream(
				__spec.jar.getArchiveFile().get().getAsFile().toPath(),
				StandardOpenOption.READ)))
			{
				EmulatedTestExecutor.__findTestClasses(zip, testClasses);
				

				break;
			}
			catch (ClosedByInterruptException e)
			{
				// Prevent dead-locking if interrupting just keeps happening
				if (++iCount >= EmulatedTestExecutor._MAX_INTERRUPTS)
					throw new RuntimeException(
						"Could not read JAR due to too many interrupts.", e);
				
				System.err.printf("Interrupt during JAR read, retrying...%n");
				
				// Clear interrupt flag
				Thread.interrupted();
			}
		
		// Used to flag if every test passed

		boolean allPassed = true;
		
		// Now go through the tests we discovered and execute them
		for (String testClass : testClasses)
		{
			// Stop executing? Note that if this is stopped in the middle of
			// a test we cannot make the tests pass

			if (this._stopRunning)
				return false;
			
			// In SquirrelJME all tests only have a single run method, so the
			// run is the actual class of execution
			EmulatedTestClassDescriptor classy =
				new EmulatedTestClassDescriptor(__suite, testClass);
			EmulatedTestMethodDescriptor method =
				new EmulatedTestMethodDescriptor(classy);


			
			// Start execution
			__results.started(classy,
				EmulatedTestUtilities.startNow(__suite));
			__results.started(method,
				EmulatedTestUtilities.startNow(classy));
			
			// Execute each class alone
			try
			{
				// Execute individual test
				int result = this.executeClass(__spec, __results, method);


				
				// Test did not pass
				if (result != ExitValueConstants.SUCCESS &&
					result != ExitValueConstants.SKIPPED)


				{
					// Clear out the stack trace because they are really
					// annoying
					Throwable empty = new Throwable("Test failed");
					empty.setStackTrace(new StackTraceElement[0]);



					
					// Use this thrown exception
					__results.failure(method.getId(), empty);


				}
				
				// End execution
				__results.completed(method.getId(),
					EmulatedTestUtilities.passSkipOrFailNow(result));
				__results.completed(classy.getId(),
					EmulatedTestUtilities.passSkipOrFailNow(result));
			}
			catch (Throwable t)


			{
				// Report the thrown exception
				__results.failure(method.getId(), t);
				__results.completed(method.getId(),
					EmulatedTestUtilities.failNow());


				
				// Fail the class as well
				__results.completed(classy.getId(),
					EmulatedTestUtilities.failNow());
			}



		}
		
		// Return how all the tests ran
		return allPassed;
	}
	
	/**
................................................................................
	 */
	@Override
	public void stopNow()
	{
		// Stop running and prevent the next test from stopping
		this._stopRunning = true;
	}
	
	/**
	 * Attempts to find the test classes.
	 *
	 * @param __zip The ZIP to read.
	 * @param __testClasses The target classes.
	 * @throws IOException On read failures.
	 * @since 2020/05/25
	 */
	private static void __findTestClasses(ZipInputStream __zip,
		Collection<String> __testClasses)
		throws IOException
	{
		for (;;)
		{
			// Stop at the end of the ZIP
			ZipEntry entry = __zip.getNextEntry();
			if (entry == null)
				break;
			
			// Only consider the services file
			if (!EmulatedTestExecutor.SERVICE_RESOURCE
				.equals(entry.getName()))
				continue;
			
			// We cannot close a stream, so we need to copy the data over
			// first
			ByteArrayOutputStream baos = new ByteArrayOutputStream(
				(int)Math.max(0, entry.getSize()));
			for (byte[] buf = new byte[4096];;)
			{
				int rc = __zip.read(buf);
				if (rc < 0)
					break;
				
				baos.write(buf, 0, rc);
			}
			
			// Read in all the test classes
			try (BufferedReader br = new BufferedReader(
				new InputStreamReader(new ByteArrayInputStream(
				baos.toByteArray()), "utf-8")))
			{
				for (;;)
				{
					// End of file?
					String ln = br.readLine();
					if (ln == null)
						break;
					
					// Add test class to possible tests to run
					if (!ln.isEmpty())
						__testClasses.add(ln.trim());
				}
			}
		}
	}
}







|
|
|
|
|
<
|
<
|
|
|
|
|
|



<



|






<
<
<
<







>
>
>
>







 







>
>
>
>
>




<
<
<

|


>
>
>
>
>
>
>
>
>
>
>

|
>





>
>


<
<
|
<
>
>














>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|
<



>
|
<
>


>
>
>
>




|
|
<
|
>
>
>
>
>
>
>

<




<
<
<
<
<







 







|
|





|
<
<
|
<
<






|
<


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







>


>


|
|
|
>
|

<
<
<
|
|
|
|
|
<
>
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
>

<
<
|

<
<
>

<
|
<
<
<
<
<
<
>
>
|
<
<
<
<
<

<
<
<
|
<
>
>
|
<
<
<
>
>
|
<
<
<
<
>
>
>
|
<
<
>
>
|
|
<
<
<
<
<
<
<
>
>
|
<
<
<
<
>
>
|
<
<
<
<
>
>
>







 







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
6
7
8
9
10
11
12
13
14
15
16
17

18

19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36
37




38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
..
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111


112

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175

176
177
178
179
180

181
182
183
184
185
186
187
188
189
190
191
192
193

194
195
196
197
198
199
200
201
202

203
204
205
206





207
208
209
210
211
212
213
...
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234


235


236
237
238
239
240
241
242

243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303



304
305
306
307
308

309
310
311
312













313
314


315
316


317
318

319






320
321
322





323



324

325
326
327



328
329
330




331
332
333
334


335
336
337
338







339
340
341




342
343
344




345
346
347
348
349
350
351
352
353
354
...
357
358
359
360
361
362
363
364

























































// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.plugin.tasks.test;

import cc.squirreljme.plugin.tasks.TestInVMTask;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import java.util.LinkedList;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicInteger;
import org.gradle.api.Project;
import org.gradle.api.internal.tasks.testing.TestExecuter;
import org.gradle.api.internal.tasks.testing.TestResultProcessor;

import org.gradle.process.ExecResult;

/**
 * This is the executor for tests.
 *
 * @since 2020/03/06
 */
public final class EmulatedTestExecutor
	implements TestExecuter<EmulatedTestExecutionSpec>
{




	/** The service resource file. */
	public static final String SERVICE_RESOURCE =
		"META-INF/services/net.multiphasicapps.tac.TestInterface";
	
	/** The test task. */
	private final TestInVMTask _testInVMTask;
	
	/** Emulator classpath. */
	private final Map<String, Iterable<Object>> _emuClassPathCache =
		new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
	
	/** Should this test be stopped? */
	private volatile boolean _stopRunning =
		false;
	
	/**
	 * Initializes the task executor.
	 *
................................................................................
	@Override
	public void execute(EmulatedTestExecutionSpec __spec,
		TestResultProcessor __results)
	{
		// We need the project to access details
		Project project = this._testInVMTask.getProject();
		
		// Initialize the classpath for our emulator!
		// Otherwise the Gradle build will fail since it tries to get the
		// classpath outside of this
		this.emulatorClassPath(project, __spec.emulator);
		
		// Run for this suite/project
		EmulatedTestSuiteDescriptor suite =
			new EmulatedTestSuiteDescriptor(project);
		



		// Perform testing logic
		boolean allPassed;
		try
		{
			// Load tests to run
			Collection<String> classes = EmulatedTestUtilities.readJarServices(
				__spec.jar.getArchiveFile().get().getAsFile().toPath());
			
			// Report on the found test size (debugging)
			project.getLogger().lifecycle(String.format(
				"Found %d tests...%n", classes.size()));
			
			// Indicate that the suite has started execution
			__results.started(suite, EmulatedTestUtilities.startNow());
			
			// Execute test classes (find them and run them)
			allPassed = this.__executeClasses(__spec, __results, suite,
				classes);
			
			// Did all tests pass?
			__results.completed(suite.getId(),
				EmulatedTestUtilities.passOrFailNow(allPassed));
		}
		
		// Something went wrong it seems
		catch (Throwable t)
		{


			project.getLogger().error("Throwable caught during testing.", t);

			
			throw new RuntimeException("Caught throwable during testing.", t);
		}
		
		// Did not pass, so cause the task to fail
		if (!allPassed)
		{
			// Throw a blank failure exception
			RuntimeException toss = new RuntimeException("Failed tests.");
			toss.setStackTrace(new StackTraceElement[0]);
			
			throw toss;
		}
	}
	
	/**
	 * Executes the test class.
	 * 
	 * @param __spec The specification.
	 * @param __suite The suite to run.
	 * @param __testClass The test class.
	 * @return If this test passed.
	 * @since 2020/06/21
	 */
	private EmulatedTestResult __executeClass(EmulatedTestExecutionSpec __spec,
		EmulatedTestSuiteDescriptor __suite, String __testClass)
	{
		// Setup result
		EmulatedTestResult result = new EmulatedTestResult(
			__suite, __testClass);
		
		// Signal as started
		result.testStart();
		
		// Execute each class alone
		try
		{
			// Execute individual test
			int exitCode = this.__executeClassVm(__spec, result);
			
			// Finish the test with the result code
			result.testFinish(exitCode, null);
		}
		catch (Throwable t)
		{
			// Just mark failure
			result.testFinish(ExitValueConstants.FAILURE, t);
			
			// Print the trace since this was outside of the VM
			synchronized (System.err)
			{
				t.printStackTrace(System.err);
			}
		}
		
		return result;
	}
	
	/**
	 * Goes through and executes the single test class.
	 *
	 * @param __spec The specification.
	 * @param __result The output result.

	 * @return The exit value of the test.
	 * @since 2020/03/06
	 */
	@SuppressWarnings("resource")
	private int __executeClassVm(EmulatedTestExecutionSpec __spec,

		EmulatedTestResult __result)
	{
		Project project = this._testInVMTask.getProject();
		
		// Setup test standard output and error streams
		OutputStream stdOut = __result.stdOut();
		OutputStream stdErr = __result.stdErr();
		
		// For some reason test reports do not run if there is no output for
		// them, so this for the most part forces console output to happen
		// which makes tests happen
		String withinClass = __result.className;
		try

		{
			stdErr.write(String.format("Starting VM for %s...", withinClass)
				.getBytes());
		}
		catch (IOException ignored)
		{
		}
		
		// Execute the test Java program

		ExecResult result = project.javaexec(__javaExecSpec ->
			{
				Collection<String> args = new LinkedList<>();
				





				// Add emulator
				args.add("-Xemulator:" + __spec.emulator);
				
				// Add snapshot path
				args.add("-Xsnapshot:" + EmulatedTestExecutor.this
					._testInVMTask.__tempRoot().resolve("nps")
					.resolve(withinClass + ".nps").toAbsolutePath());
................................................................................
				// Only run a single test
				args.add("net.multiphasicapps.tac.MainSingleRunner");
				
				// Target this single test
				args.add(withinClass);
				
				// Configure the VM for execution
				__javaExecSpec.classpath(EmulatedTestExecutor.this
					.emulatorClassPath(null, __spec.emulator));
				__javaExecSpec.setMain("cc.squirreljme.emulator.vm.VMFactory");
				__javaExecSpec.setArgs(args);
				
				// Pipe outputs to the specified areas so the console can be
				// read properly!
				__javaExecSpec.setStandardOutput(stdOut);


				__javaExecSpec.setErrorOutput(stdErr);


				
				// Do not throw an exception on a non-zero exit value since
				// it is important to us
				__javaExecSpec.setIgnoreExitValue(true);
			});
		
		// The exit value is the test result

		return result.getExitValue();
	}
	
	/**
	 * Returns the classpath for the emulator.
	 * 
	 * @param __project The project to use.
	 * @param __emulator The emulator to use.
	 * @return The classpath for the emulator.
	 * @throws NullPointerException On null arguments, or if {@code __project}
	 * is null and this is not already cached.
	 * @since 2020/06/22
	 */
	private Iterable<Object> emulatorClassPath(Project __project,
		String __emulator)
		throws NullPointerException
	{
		if (__emulator == null)
			throw new NullPointerException("NARG");
		
		// Use already cached value
		Map<String, Iterable<Object>> cache = this._emuClassPathCache;
		Iterable<Object> rv = cache.get(__emulator);
		if (rv != null)
			return rv; 
		
		// Get new result
		Iterable<Object> now = EmulatedTestUtilities.emulatorClassPath(
			__project, __emulator);
		
		// Add to the cache
		List<Object> toCache = new ArrayList<>();
		for (Object item : now)
			toCache.add(item);
		
		// Store unreadable form
		cache.put(__emulator,
			(rv = Collections.unmodifiableCollection(toCache)));
		
		// Ensure it stays unreadable
		return rv;
	}
	
	/**
	 * Goes through and executes the test classes.
	 *
	 * @param __spec The specification.
	 * @param __results The output results.
	 * @param __suite The suite to run.
	 * @param __classes The classes to run.
	 * @return Did all tests pass?
	 * @throws IOException On read errors.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/03/06
	 */
	@SuppressWarnings({"FeatureEnvy", "MagicNumber"})
	private boolean __executeClasses(EmulatedTestExecutionSpec __spec,
		TestResultProcessor __results, EmulatedTestSuiteDescriptor __suite,
		Iterable<String> __classes)
		throws IOException, NullPointerException
	{



		if (__spec == null || __results == null || __suite == null ||
			__classes == null)
			throw new NullPointerException("NARG");
		
		// And any results of the runs will be placed in this pool along

		// with the number of added and finished tests
		AtomicInteger finishedTests = new AtomicInteger();
		
		// Create jobs for the tests













		Set<String> failedTests = new TreeSet<>();
		boolean allPassed = true;


		for (String testClass : __classes)
		{


			// If stopping running, discontinue and fail the tests
			if (this._stopRunning)

			{






				allPassed = false;
				break;
			}





			



			// Execute the test

			EmulatedTestResult result = this.__executeClass(
				__spec, __suite, testClass);
			



			// Report the test
			result.report(__results);
			




			// Did this fail?
			if (result.isFailure())
				failedTests.add(result.className);
			


			// Increase the test counter, as this was grabbed
			finishedTests.incrementAndGet();
		}
		







		// There were test failures?
		if (!failedTests.isEmpty())
		{




			// Not every test passed
			allPassed = false;
			




			// Print all the failed tests out
			for (String testClass : failedTests)
				System.err.printf("Failed Test: %s%n", testClass);
		}
		
		// Return how all the tests ran
		return allPassed;
	}
	
	/**
................................................................................
	 */
	@Override
	public void stopNow()
	{
		// Stop running and prevent the next test from stopping
		this._stopRunning = true;
	}
}

























































Added buildSrc/src/main/java/cc/squirreljme/plugin/tasks/test/EmulatedTestResult.java.





































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.plugin.tasks.test;

import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import org.gradle.api.internal.tasks.testing.TestResultProcessor;

/**
 * The contains the result for emulated tests.
 *
 * @since 2020/06/22
 */
public final class EmulatedTestResult
{
	/** Which test is this for? */
	protected final String className;
	
	/** The suite. */
	protected final EmulatedTestSuiteDescriptor suite;
	
	/** The console lines. */
	private final Collection<ConsoleLine> _lines =
		new ArrayList<>(128);
	
	/** The exit code of the test. */
	private int _exitCode =
		Integer.MIN_VALUE;
	
	/** The start time. */
	private long _timeStart =
		Long.MIN_VALUE;
	
	/** The end time. */
	private long _timeEnd =
		Long.MIN_VALUE;
	
	/** The tossed exception, if any. */
	private Throwable _tossed;
	
	/**
	 * Initializes the base for the test result.
	 * 
	 * @param __suite The test suite.
	 * @param __className The name of the class.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/22
	 */
	public EmulatedTestResult(EmulatedTestSuiteDescriptor __suite,
		String __className)
		throws NullPointerException
	{
		if (__suite == null || __className == null)
			throw new NullPointerException("NARG");
		
		this.suite = __suite;
		this.className = __className;
	}
	
	/**
	 * Adds a line to the output.
	 * 
	 * @param __line The line to add.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/22
	 */
	public void addLine(ConsoleLine __line)
		throws NullPointerException
	{
		if (__line == null)
			throw new NullPointerException("NARG");
		
		synchronized (this)
		{
			this._lines.add(__line);
		}
	}
	
	/**
	 * Is this a test failure?
	 * 
	 * @return If this is a test failure.
	 * @since 2020/06/22
	 */
	public final boolean isFailure()
	{
		synchronized (this)
		{
			int exitCode = this._exitCode;
			return exitCode != ExitValueConstants.SUCCESS &&
				exitCode != ExitValueConstants.SKIPPED;
		}
	}
	
	/**
	 * Sends in the test report.
	 * 
	 * @param __results The output results.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/22
	 */
	public final void report(TestResultProcessor __results)
		throws NullPointerException
	{
		if (__results == null)
			throw new NullPointerException("NARG");
		
		EmulatedTestSuiteDescriptor suite = this.suite;
		String testClass = this.className;
		
		// In SquirrelJME all tests only have a single run method, so the
		// run is the actual class of execution
		EmulatedTestClassDescriptor classy =
			new EmulatedTestClassDescriptor(suite, testClass);
		EmulatedTestMethodDescriptor method =
			new EmulatedTestMethodDescriptor(classy);
		
		synchronized (this)
		{
			// Execution times
			long timeStart = this._timeStart;
			long timeEnd = this._timeEnd;
			
			// Signal start
			__results.started(classy,
				EmulatedTestUtilities.startAt(timeStart, suite));
			__results.started(method,
				EmulatedTestUtilities.startAt(timeStart, classy));
			
			// Print all the output text
			for (ConsoleLine line : this._lines)
				line.report(__results, method);
			
			// Was the test in error?
			int exitCode = this._exitCode;
			if (exitCode != ExitValueConstants.SUCCESS &&
				exitCode != ExitValueConstants.SKIPPED)
			{
				// Was an exception thrown? If not, make a generic one
				Throwable tossed = this._tossed;
				if (tossed == null)
				{
					tossed = new Throwable("Test Failed");
					
					// Make the trace empty as it has no meaning
					tossed.setStackTrace(new StackTraceElement[0]);
				}
				
				// Toss it now
				__results.failure(method.getId(), tossed);
			}
			
			// End execution
			__results.completed(method.getId(),
				EmulatedTestUtilities.passSkipOrFailAt(timeEnd, exitCode));
			__results.completed(classy.getId(),
				EmulatedTestUtilities.passSkipOrFailAt(timeEnd, exitCode));
		}
	}
	
	/**
	 * Returns standard error.
	 * 
	 * @return Standard error.
	 * @since 2020/06/22
	 */
	public OutputStream stdErr()
	{
		return new PipeOutputStream(this, true);
	}
	
	/**
	 * Returns standard output.
	 * 
	 * @return Standard output.
	 * @since 2020/06/22
	 */
	public OutputStream stdOut()
	{
		return new PipeOutputStream(this, false);
	}
	
	/**
	 * Finishes the test with the given exit code.
	 * 
	 * @param __exitCode The exit code.
	 * @param _toss The tossed exception, if any.
	 * @since 2020/06/22
	 */
	public void testFinish(int __exitCode, Throwable _toss)
	{
		synchronized (this)
		{
			if (this._timeEnd != Long.MIN_VALUE)
				throw new IllegalStateException("Test already finished.");
			
			this._timeEnd = System.currentTimeMillis();
			this._exitCode = __exitCode;
			this._tossed = _toss;
		}
	}
	
	/**
	 * Starts the test.
	 * 
	 * @since 2020/06/22
	 */
	public final void testStart()
	{
		synchronized (this)
		{
			if (this._timeStart != Long.MIN_VALUE)
				throw new IllegalStateException("Test already started.");
			
			this._timeStart = System.currentTimeMillis();
		}
	}
}

Changes to buildSrc/src/main/java/cc/squirreljme/plugin/tasks/test/EmulatedTestUtilities.java.

6
7
8
9
10
11
12



13





14

15
16

17

18
19


20
21
22
23
24
25
26
...
209
210
211
212
213
214
215













216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
...
261
262
263
264
265
266
267













268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
...
290
291
292
293
294
295
296

297
298
299
300
301
302
303
304
305
306
307
308
309

310
311
312
313
314

315
316
317
318
319
320
321
322
323




















































































































324
325
326
327
328
329
330
331
332


























333
334
335
336
337
338
339
...
348
349
350
351
352
353
354

355
356
357
358
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.plugin.tasks.test;

import cc.squirreljme.plugin.SquirrelJMEPluginConfiguration;



import java.io.File;





import java.nio.file.Path;

import java.util.Collection;
import java.util.Deque;

import java.util.LinkedList;

import java.util.Set;
import java.util.TreeSet;


import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.artifacts.ProjectDependency;
import org.gradle.api.internal.tasks.testing.DefaultTestOutputEvent;
import org.gradle.api.internal.tasks.testing.TestCompleteEvent;
import org.gradle.api.internal.tasks.testing.TestDescriptorInternal;
................................................................................
		rv.add(emuProject.getConfigurations().getByName("runtimeClasspath")
			.getFiles());
		rv.add(((Jar)emuProject.getTasks().getByName("jar")).getOutputs()
			.getFiles());
		
		return rv;
	}













	
	/**
	 * Returns a failing completion.
	 *
	 * @return An event.
	 * @since 2020/03/06
	 */
	public static TestCompleteEvent failNow()
	{
		return new TestCompleteEvent(System.currentTimeMillis(),
			TestResult.ResultType.FAILURE);
	}
	
	/**
	 * Outputs a message.
	 *
	 * @param __dest The destination.
	 * @param __msg The message.
................................................................................
	 * @since 2020/03/06
	 */
	public static TestOutputEvent outputErr(String __msg)
	{
		return EmulatedTestUtilities.output(
			TestOutputEvent.Destination.StdErr, __msg);
	}













	
	/**
	 * Returns a passing completion.
	 *
	 * @return An event.
	 * @since 2020/03/06
	 */
	public static TestCompleteEvent passNow()
	{
		return new TestCompleteEvent(System.currentTimeMillis(),
			TestResult.ResultType.SUCCESS);
	}
	
	/**
	 * Either passes or fails.
	 *
	 * @param __pass Does the test pass?
	 * @return The event.
................................................................................
		return (__pass ? EmulatedTestUtilities.passNow() :
			EmulatedTestUtilities.failNow());
	}
	
	/**
	 * Either passes or skips.
	 *

	 * @param __pass Does the test pass?
	 * @return The event.
	 * @since 2020/03/06
	 */
	public static TestCompleteEvent passOrSkipNow(boolean __pass)
	{
		return (__pass ? EmulatedTestUtilities.passNow() :
			EmulatedTestUtilities.skipNow());
	}
	
	/**
	 * Depending on the exit code, this will pass, fail, or skip a test.
	 *

	 * @param __exitCode The exit code.
	 * @return The completion event.
	 * @since 2020/03/07
	 */
	public static TestCompleteEvent passSkipOrFailNow(int __exitCode)

	{
		if (__exitCode == ExitValueConstants.SUCCESS)
			return EmulatedTestUtilities.passNow();
		else if (__exitCode == ExitValueConstants.SKIPPED)
			return EmulatedTestUtilities.skipNow();
		return EmulatedTestUtilities.failNow();
	}
	
	/**




















































































































	 * Returns a skipping completion.
	 *
	 * @return An event.
	 * @since 2020/03/06
	 */
	public static TestCompleteEvent skipNow()
	{
		return new TestCompleteEvent(System.currentTimeMillis(),
			TestResult.ResultType.SKIPPED);


























	}
	
	/**
	 * Returns a test starting now.
	 *
	 * @return An event
	 * @since 2020/03/06
................................................................................
	 *
	 * @param __test The test information.
	 * @return An event
	 * @since 2020/03/06
	 */
	public static TestStartEvent startNow(TestDescriptorInternal __test)
	{

		return new TestStartEvent(System.currentTimeMillis(),
			(__test == null ? null : __test.getId()));
	}
}







>
>
>

>
>
>
>
>

>


>

>


>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>









|
<







 







>
>
>
>
>
>
>
>
>
>
>
>
>









|
<







 







>




|

|
|



|
|
>
|

|

|
>


|

|
|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
|
<


6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
...
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251

252
253
254
255
256
257
258
...
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
...
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487

488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
...
529
530
531
532
533
534
535
536
537

538
539
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.plugin.tasks.test;

import cc.squirreljme.plugin.SquirrelJMEPluginConfiguration;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Collection;
import java.util.Deque;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.artifacts.ProjectDependency;
import org.gradle.api.internal.tasks.testing.DefaultTestOutputEvent;
import org.gradle.api.internal.tasks.testing.TestCompleteEvent;
import org.gradle.api.internal.tasks.testing.TestDescriptorInternal;
................................................................................
		rv.add(emuProject.getConfigurations().getByName("runtimeClasspath")
			.getFiles());
		rv.add(((Jar)emuProject.getTasks().getByName("jar")).getOutputs()
			.getFiles());
		
		return rv;
	}
	
	/**
	 * Fails at the specified time.
	 * 
	 * @param __millis The time to fail at.
	 * @return The completion event.
	 * @since 2020/06/22
	 */
	private static TestCompleteEvent failAt(long __millis)
	{
		return new TestCompleteEvent(__millis,
			TestResult.ResultType.FAILURE);
	}
	
	/**
	 * Returns a failing completion.
	 *
	 * @return An event.
	 * @since 2020/03/06
	 */
	public static TestCompleteEvent failNow()
	{
		return EmulatedTestUtilities.failAt(System.currentTimeMillis());

	}
	
	/**
	 * Outputs a message.
	 *
	 * @param __dest The destination.
	 * @param __msg The message.
................................................................................
	 * @since 2020/03/06
	 */
	public static TestOutputEvent outputErr(String __msg)
	{
		return EmulatedTestUtilities.output(
			TestOutputEvent.Destination.StdErr, __msg);
	}
	
	/**
	 * Passes at the given time.
	 * 
	 * @param __millis The time to pass at.
	 * @return The completion event.
	 * @since 2020/06/22
	 */
	private static TestCompleteEvent passAt(long __millis)
	{
		return new TestCompleteEvent(__millis,
			TestResult.ResultType.SUCCESS);
	}
	
	/**
	 * Returns a passing completion.
	 *
	 * @return An event.
	 * @since 2020/03/06
	 */
	public static TestCompleteEvent passNow()
	{
		return EmulatedTestUtilities.passAt(System.currentTimeMillis());

	}
	
	/**
	 * Either passes or fails.
	 *
	 * @param __pass Does the test pass?
	 * @return The event.
................................................................................
		return (__pass ? EmulatedTestUtilities.passNow() :
			EmulatedTestUtilities.failNow());
	}
	
	/**
	 * Either passes or skips.
	 *
	 * @param __millis The time to finish.
	 * @param __pass Does the test pass?
	 * @return The event.
	 * @since 2020/03/06
	 */
	public static TestCompleteEvent passOrSkipAt(long __millis, boolean __pass)
	{
		return (__pass ? EmulatedTestUtilities.passAt(__millis) :
			EmulatedTestUtilities.skipAt(__millis));
	}
	
	/**
	 * Passes, skips, or fails at the given time.
	 * 
	 * @param __millis The time to finish.
	 * @param __exitCode The status code.
	 * @return The completion event.
	 * @since 2020/06/22
	 */
	public static TestCompleteEvent passSkipOrFailAt(long __millis,
		int __exitCode)
	{
		if (__exitCode == ExitValueConstants.SUCCESS)
			return EmulatedTestUtilities.passAt(__millis);
		else if (__exitCode == ExitValueConstants.SKIPPED)
			return EmulatedTestUtilities.skipAt(__millis);
		return EmulatedTestUtilities.failAt(__millis);
	}
	
	/**
	 * Depending on the exit code, this will pass, fail, or skip a test.
	 *
	 * @param __exitCode The exit code.
	 * @return The completion event.
	 * @since 2020/03/07
	 */
	public static TestCompleteEvent passSkipOrFailNow(int __exitCode)
	{
		return EmulatedTestUtilities.passSkipOrFailAt(
			System.currentTimeMillis(), __exitCode);
	}
	
	/**
	 * Reads test services from the JAR. 
	 *
	 * @param __path The path to read from.
	 * @throws IOException On read failures.
	 * @since 2020/06/22
	 */
	public static Collection<String> readJarServices(Path __path)
		throws IOException, NullPointerException
	{
		if (__path == null)
			throw new NullPointerException("NARG");
		
		try (InputStream in = Files.newInputStream(
			__path, StandardOpenOption.READ);
			ZipInputStream zip = new ZipInputStream(in))
		{
			return EmulatedTestUtilities.readJarServices(zip);
		}
	}
	
	/**
	 * Reads test services from the JAR. 
	 *
	 * @param __zip The ZIP to read.
	 * @throws IOException On read failures.
	 * @since 2020/05/25
	 */
	public static Collection<String> readJarServices(ZipInputStream __zip)
		throws IOException
	{
		// Resultant collection
		Collection<String> result = new LinkedHashSet<>();
		
		// Potential resource file data
		byte[] resourceData = null;
		
		// Go through entries within the ZIP
		ZipEntry entry;
		while (null != (entry = __zip.getNextEntry()))
		{
			// Only consider the services file
			if (!Objects.equals(EmulatedTestExecutor.SERVICE_RESOURCE,
				entry.getName()))
				continue;
			
			// Copy file data
			try (ByteArrayOutputStream baos = new ByteArrayOutputStream())
			{
				// Copy bytes
				byte[] buf = new byte[4096];
				for (;;)
				{
					int rc = __zip.read(buf);
					
					if (rc < 0)
						break;
					
					baos.write(buf, 0, rc);
				}
				
				// Set resource data and stop finding entries
				resourceData = baos.toByteArray();
				break;
			}
		}
		
		// Read in service list
		if (resourceData != null)
			try (BufferedReader br = new BufferedReader(new InputStreamReader(
				new ByteArrayInputStream(resourceData),
					StandardCharsets.UTF_8)))
			{
				for (;;)
				{
					// End of file?
					String ln = br.readLine();
					if (ln == null)
						break;
					
					// Only consider lines with content
					ln = ln.trim();
					if (!ln.isEmpty())
						result.add(ln);
				}
			}
		
		return result;
	}
	
	/**
	 * Skips at the given time.
	 * 
	 * @param __millis The time to skip at.
	 * @return The completion event.
	 * @since 2020/06/22
	 */
	private static TestCompleteEvent skipAt(long __millis)
	{
		return new TestCompleteEvent(__millis,
			TestResult.ResultType.SKIPPED);
	}
	
	/**
	 * Returns a skipping completion.
	 *
	 * @return An event.
	 * @since 2020/03/06
	 */
	public static TestCompleteEvent skipNow()
	{
		return EmulatedTestUtilities.skipAt(System.currentTimeMillis());

	}
	
	/**
	 * Returns a test starting now.
	 *
	 * @param __millis The starting time.
	 * @return An event
	 * @since 2020/06/22
	 */
	public static TestStartEvent startAt(long __millis)
	{
		return EmulatedTestUtilities.startAt(__millis, null);
	}
	
	/**
	 * Returns a test starting now.
	 *
	 * @param __test The test information.
	 * @return An event
	 * @since 2020/06/22
	 */
	public static TestStartEvent startAt(long __millis,
		TestDescriptorInternal __test)
	{
		return new TestStartEvent(__millis,
			(__test == null ? null : __test.getId()));
	}
	
	/**
	 * Returns a test starting now.
	 *
	 * @return An event
	 * @since 2020/03/06
................................................................................
	 *
	 * @param __test The test information.
	 * @return An event
	 * @since 2020/03/06
	 */
	public static TestStartEvent startNow(TestDescriptorInternal __test)
	{
		return EmulatedTestUtilities.startAt(
			System.currentTimeMillis(), __test);

	}
}

Changes to buildSrc/src/main/java/cc/squirreljme/plugin/tasks/test/PipeOutputStream.java.

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

54
55
56
57
58

59
60
61
62
63
64
65
..
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
...
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
...
150
151
152
153
154
155
156

157
158
159
160
161
162
163
164
165
166
167
168
169
170
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.plugin.tasks.test;

import java.io.OutputStream;
import org.gradle.api.internal.tasks.testing.TestResultProcessor;
import org.gradle.api.tasks.testing.TestOutputEvent;

/**
 * Pipes output stream to the results output accordingly.
 *
 * @since 2020/03/07
 */
public class PipeOutputStream
	extends OutputStream
{
	/** The output buffer. */
	protected final StringBuilder buffer =
		new StringBuilder();
	
	/** The test ID. */
	protected final Object testId;
	
	/** The destination. */
	protected final TestOutputEvent.Destination destination;
	
	/** Results for execution. */
	private final TestResultProcessor results;
	
	/** Do we have a carriage return? */
	private boolean haveCR;
	
	/**
	 * Initializes the pipe output.
	 *
	 * @param __id The test ID.
	 * @param __r The result processor.
	 * @param __d The destination.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/03/07
	 */
	public PipeOutputStream(Object __id, TestResultProcessor __r,
		TestOutputEvent.Destination __d)
		throws NullPointerException
	{
		if (__id == null || __r == null || __d == null)

			throw new NullPointerException();
		
		this.testId = __id;
		this.results = __r;
		this.destination = __d;

	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/03/07
	 */
	@SuppressWarnings("DuplicatedCode")
................................................................................
	{
		StringBuilder buffer = this.buffer;
		
		// Flush the buffer on newlines
		if (__b == '\r' || __b == '\n')
		{
			if (__b == '\r')
				this.haveCR = true;
			else
			{
				this.__flush();
				this.haveCR = false;
			}
		}
		else
		{
			// Flush if we just gave a CR
			if (this.haveCR)
				this.__flush();
			
			if (__b < 0)
				buffer.append('?');
			else
				buffer.append((char)__b);
		}
................................................................................
		{
			byte b = __b[__o++];
			
			// Flush the buffer on newlines
			if (b == '\r' || b == '\n')
			{
				if (b == '\r')
					this.haveCR = true;
				else
				{
					this.__flush();
					this.haveCR = false;
				}
			}
			else
			{
				// Flush if we just gave a CR
				if (this.haveCR)
					this.__flush();
				
				if (b < 0)
					buffer.append('?');
				else
					buffer.append((char)b);
			}
................................................................................
	/**
	 * Flushes the buffer.
	 *
	 * @since 2020/03/07
	 */
	private void __flush()
	{

		StringBuilder buffer = this.buffer;
		
		// Send to output
		buffer.append('\n');
		this.results.output(this.testId, EmulatedTestUtilities.output(
			this.destination, buffer.toString()));
		
		// Clear the buffer
		buffer.setLength(0);
		
		// Always clear CR state
		this.haveCR = false;
	}
}







<
<













|
|

|
|

<
<
<

|



|
|
|
<

|

|
<


<
>
|

<
|
<
>







 







|



|





|







 







|



|





|







 







>

<
|
<
<
|





|


6
7
8
9
10
11
12


13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31



32
33
34
35
36
37
38
39

40
41
42
43

44
45

46
47
48

49

50
51
52
53
54
55
56
57
..
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
...
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
...
142
143
144
145
146
147
148
149
150

151


152
153
154
155
156
157
158
159
160
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.plugin.tasks.test;

import java.io.OutputStream;



/**
 * Pipes output stream to the results output accordingly.
 *
 * @since 2020/03/07
 */
public class PipeOutputStream
	extends OutputStream
{
	/** The output buffer. */
	protected final StringBuilder buffer =
		new StringBuilder();
	
	/** The test result. */
	protected final EmulatedTestResult result;
	
	/** Is this standard error. */
	protected final boolean stdErr;
	



	/** Do we have a carriage return? */
	private boolean _haveCr;
	
	/**
	 * Initializes the pipe output.
	 * 
	 * @param __result The result to send to.
	 * @param __stdErr Is this standard error?

	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/22
	 */
	public PipeOutputStream(EmulatedTestResult __result, boolean __stdErr)

		throws NullPointerException
	{

		if (__result == null)
			throw new NullPointerException("NARG");
		

		this.result = __result;

		this.stdErr = __stdErr;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/03/07
	 */
	@SuppressWarnings("DuplicatedCode")
................................................................................
	{
		StringBuilder buffer = this.buffer;
		
		// Flush the buffer on newlines
		if (__b == '\r' || __b == '\n')
		{
			if (__b == '\r')
				this._haveCr = true;
			else
			{
				this.__flush();
				this._haveCr = false;
			}
		}
		else
		{
			// Flush if we just gave a CR
			if (this._haveCr)
				this.__flush();
			
			if (__b < 0)
				buffer.append('?');
			else
				buffer.append((char)__b);
		}
................................................................................
		{
			byte b = __b[__o++];
			
			// Flush the buffer on newlines
			if (b == '\r' || b == '\n')
			{
				if (b == '\r')
					this._haveCr = true;
				else
				{
					this.__flush();
					this._haveCr = false;
				}
			}
			else
			{
				// Flush if we just gave a CR
				if (this._haveCr)
					this.__flush();
				
				if (b < 0)
					buffer.append('?');
				else
					buffer.append((char)b);
			}
................................................................................
	/**
	 * Flushes the buffer.
	 *
	 * @since 2020/03/07
	 */
	private void __flush()
	{
		// Send buffer to the output
		StringBuilder buffer = this.buffer;

		this.result.addLine(new ConsoleLine(this.stdErr,


			System.currentTimeMillis(), buffer.toString()));
		
		// Clear the buffer
		buffer.setLength(0);
		
		// Always clear CR state
		this._haveCr = false;
	}
}

Changes to changelog.mkd.

25
26
27
28
29
30
31

32
33
34
35
36
37
38
..
48
49
50
51
52
53
54

55
56
57
58
59
60
61
...
152
153
154
155
156
157
158

159
160
161
162
163
164
165
 * Programs and Libraries
   * `cldc-compact`
     * Added a rehash indicator for the internal `__BucketMap__` so that
       `java.util.Hashtable` knows when a reorder was performed.
     * Added `java.util.Vector`, it was missing.
     * Added support for ISO-8859-15, this is the newer encoding with the
       Euro symbol.

     * Corrected bug in `__CanSetPrintStream__` where if it were set to itself
       then it could lead to infinite recursion, instead if this kind of
       stream is attempted to be set it will use the target.
     * Corrected `java.lang.Object.clone()` to return the new copy of the array
       when cloning and not the original.
     * Corrected `java.util.Objects.equals()` not correctly checking equality
       on two objects.
................................................................................
     * Implemented `java.io.PrintStream`.
     * Implemented `java.util.EventObject`.
     * Implemented `java.util.Hashtable`.
     * Implemented `java.util.LinkedHashMap`.
     * Implemented `java.util.LinkedList`.
     * Made the stack trace printed by `Throwable` much cleaner so that it
       takes up less screen space and is formatted a bit better.

     * Return values for `line.separator`, `microedition.encoding`,
       `microedition.configuration`, and `microedition.locale`.
   * `demo-hello`
     * Made the system properties array `final`.
   * `jblend-api`
     * Added API Stubs.
   * `launcher`
................................................................................
   * SpringCoat
     * Add limit to stack frame depth.
     * Add support for system properties being based to virtual machine
       instances.
     * Allow inheritance of static methods in classes.
     * Profiler thread lists are easier to read because the main suite is
       listed instead of the VM identifier.

   * SummerCoat
     * New Virtual Machine, register based.
     * Vast improvements over SpringCoat, faster and slimmer.
   * RatufaCoat
     * New Virtual Machine, based off SummerCoat.
     * Fast and slim, written in C.
 * Cleanup







>







 







>







 







>







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
..
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
...
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
 * Programs and Libraries
   * `cldc-compact`
     * Added a rehash indicator for the internal `__BucketMap__` so that
       `java.util.Hashtable` knows when a reorder was performed.
     * Added `java.util.Vector`, it was missing.
     * Added support for ISO-8859-15, this is the newer encoding with the
       Euro symbol.
     * Added support for `os.arch`, `os.name`, and `os.version`.
     * Corrected bug in `__CanSetPrintStream__` where if it were set to itself
       then it could lead to infinite recursion, instead if this kind of
       stream is attempted to be set it will use the target.
     * Corrected `java.lang.Object.clone()` to return the new copy of the array
       when cloning and not the original.
     * Corrected `java.util.Objects.equals()` not correctly checking equality
       on two objects.
................................................................................
     * Implemented `java.io.PrintStream`.
     * Implemented `java.util.EventObject`.
     * Implemented `java.util.Hashtable`.
     * Implemented `java.util.LinkedHashMap`.
     * Implemented `java.util.LinkedList`.
     * Made the stack trace printed by `Throwable` much cleaner so that it
       takes up less screen space and is formatted a bit better.
     * Removed `GuestDepth`, it is no longer a concept.
     * Return values for `line.separator`, `microedition.encoding`,
       `microedition.configuration`, and `microedition.locale`.
   * `demo-hello`
     * Made the system properties array `final`.
   * `jblend-api`
     * Added API Stubs.
   * `launcher`
................................................................................
   * SpringCoat
     * Add limit to stack frame depth.
     * Add support for system properties being based to virtual machine
       instances.
     * Allow inheritance of static methods in classes.
     * Profiler thread lists are easier to read because the main suite is
       listed instead of the VM identifier.
     * Refactored greatly to be much leaner and simplified.
   * SummerCoat
     * New Virtual Machine, register based.
     * Vast improvements over SpringCoat, faster and slimmer.
   * RatufaCoat
     * New Virtual Machine, based off SummerCoat.
     * Fast and slim, written in C.
 * Cleanup

Changes to emulators/emulator-base/build.gradle.

5
6
7
8
9
10
11








12
13
14
15
16
17
18
..
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
	id "java-library"
	id "java-test-fixtures"
}

description = "This library provides the base support for testing and " +
	"running SquirrelJME on a Java SE host, which is normally not " +
	"capable of doing as such."









// Due to the combination of C++ and Java these dependencies have to be very
// specific in that they only refer to the Java or C++ portion. So
// "implementation" and "compile" cannot be used because the C++ library will
// try to use them during compilation.
dependencies
{
................................................................................
	// on the target device). Due to the flexibility it allows easier switching
	// from Java SE, SpringCoat, and SummerCoat
	compileClasspath "org.testng:testng:7.1.0"
	runtimeClasspath "org.testng:testng:7.1.0"

	// We need these two modules to obtain the SquirrelJME specific classes
	compileClasspath project(":modules:cldc-compact")
	compileClasspath project(":modules:cldc")
	compileClasspath project(":modules:common-vm")
	compileClasspath project(":modules:io")
	compileClasspath project(":modules:meep-swm")
	compileClasspath project(":modules:tac")
	compileClasspath project(":modules:tool-manifest-reader")
	compileClasspath project(":modules:zip")

	// And for run-time to be able to be ran
	runtimeClasspath project(":modules:cldc-compact")
	runtimeClasspath project(":modules:cldc")
	runtimeClasspath project(":modules:common-vm")
	runtimeClasspath project(":modules:io")
	runtimeClasspath project(":modules:meep-swm")
	runtimeClasspath project(":modules:tac")
	runtimeClasspath project(":modules:tool-manifest-reader")
	runtimeClasspath project(":modules:zip")
}

// We need the native library in the JAR before we can properly use it
// But we can compile the Java code just fine without it
jar {
	dependsOn "assembleRelease"

	from buildDir.toPath().resolve("lib").resolve("main").
		resolve("release").toFile()
	into "/"
}







>
>
>
>
>
>
>
>







 







<


<

<




<


<

<












5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
..
29
30
31
32
33
34
35

36
37

38

39
40
41
42

43
44

45

46
47
48
49
50
51
52
53
54
55
56
57
	id "java-library"
	id "java-test-fixtures"
}

description = "This library provides the base support for testing and " +
	"running SquirrelJME on a Java SE host, which is normally not " +
	"capable of doing as such."

// Although it would be useful to use Java 8, we have to stay on Java 7
// because SquirrelJME is a Java 7 VM.
compileJava
{
	sourceCompatibility = JavaVersion.VERSION_1_7
	targetCompatibility = JavaVersion.VERSION_1_7
}

// Due to the combination of C++ and Java these dependencies have to be very
// specific in that they only refer to the Java or C++ portion. So
// "implementation" and "compile" cannot be used because the C++ library will
// try to use them during compilation.
dependencies
{
................................................................................
	// on the target device). Due to the flexibility it allows easier switching
	// from Java SE, SpringCoat, and SummerCoat
	compileClasspath "org.testng:testng:7.1.0"
	runtimeClasspath "org.testng:testng:7.1.0"

	// We need these two modules to obtain the SquirrelJME specific classes
	compileClasspath project(":modules:cldc-compact")

	compileClasspath project(":modules:common-vm")
	compileClasspath project(":modules:io")

	compileClasspath project(":modules:tac")

	compileClasspath project(":modules:zip")

	// And for run-time to be able to be ran
	runtimeClasspath project(":modules:cldc-compact")

	runtimeClasspath project(":modules:common-vm")
	runtimeClasspath project(":modules:io")

	runtimeClasspath project(":modules:tac")

	runtimeClasspath project(":modules:zip")
}

// We need the native library in the JAR before we can properly use it
// But we can compile the Java code just fine without it
jar {
	dependsOn "assembleRelease"

	from buildDir.toPath().resolve("lib").resolve("main").
		resolve("release").toFile()
	into "/"
}

Added emulators/emulator-base/src/main/cpp/mle_object.cpp.

























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/* -*- Mode: C++; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// -------------------------------------------------------------------------*/

#include "squirreljme.h"
#include "cc_squirreljme_jvm_mle_ObjectShelf.h"

JNIEXPORT jint JNICALL Impl_mle_ObjectShelf_arrayLength(JNIEnv* env,
	jclass classy, jarray array)
{
	jclass classClass;
	jmethodID classIsArrayId;

	if (array == NULL)
		return -1;

	// Determine if this is an array or not
	classClass = env->FindClass("java/lang/Class");
	classIsArrayId = env->GetMethodID(classClass, "isArray", "()Z");
	if (JNI_FALSE == env->CallBooleanMethod(env->GetObjectClass(array),
		classIsArrayId))
		return -1;

	return env->GetArrayLength(array);
}

static const JNINativeMethod mleObjectMethods[] =
{
	{"arrayLength", "(Ljava/lang/Object;)I",
		(void*)Impl_mle_ObjectShelf_arrayLength},
};

jint JNICALL mleObjectInit(JNIEnv* env, jclass classy)
{
	return env->RegisterNatives(
		env->FindClass("cc/squirreljme/jvm/mle/ObjectShelf"),
		mleObjectMethods, sizeof(mleObjectMethods) /
			sizeof(JNINativeMethod));
}

Added emulators/emulator-base/src/main/cpp/mle_runtime.cpp.

















































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/* -*- Mode: C++; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// -------------------------------------------------------------------------*/

#include "squirreljme.h"
#include "cc_squirreljme_jvm_mle_RuntimeShelf.h"

JNIEXPORT jint JNICALL Impl_mle_RuntimeShelf_lineEnding(JNIEnv*, jclass)
{
#if defined(_WIN32)
	return 3;
#else
	return 1;
#endif
}

JNIEXPORT jint JNICALL Impl_mle_RuntimeShelf_vmType(JNIEnv*, jclass)
{
	// The value 1 is Java SE type
	return 1;
}

static const JNINativeMethod mleRuntimeMethods[] =
{
	{"lineEnding", "()I", (void*)Impl_mle_RuntimeShelf_lineEnding},
	{"vmType", "()I", (void*)Impl_mle_RuntimeShelf_vmType},
};

jint JNICALL mleRuntimeInit(JNIEnv* env, jclass classy)
{
	return env->RegisterNatives(
		env->FindClass("cc/squirreljme/jvm/mle/RuntimeShelf"),
		mleRuntimeMethods, sizeof(mleRuntimeMethods) /
			sizeof(JNINativeMethod));
}

Added emulators/emulator-base/src/main/cpp/mle_terminal.cpp.





























































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/* -*- Mode: C++; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// -------------------------------------------------------------------------*/

#include <stdio.h>

#include "squirreljme.h"
#include "cc_squirreljme_jvm_mle_TerminalShelf.h"

static FILE* getPipeForFd(jint fd)
{
	if (fd == 1)
		return stdout;
	else if (fd == 2)
		return stderr;
	return NULL;
}

JNIEXPORT jint JNICALL Impl_mle_TerminalShelf_flush(JNIEnv* env,
	jclass classy, jint fd)
{
	FILE* pipe = getPipeForFd(fd);

	if (pipe == NULL)
		return -1;

	if (fflush(pipe) == 0)
		return 1;
	return -1;
}

JNIEXPORT jint JNICALL Impl_mle_TerminalShelf_writeII(JNIEnv* env,
	jclass classy, jint fd, jint code)
{
	FILE* pipe = getPipeForFd(fd);

	if (pipe == NULL)
		return -1;

	if (fputc(code, pipe) >= 0)
		return 1;
	return -1;
}

static const JNINativeMethod mleTerminalMethods[] =
{
	{"flush", "(I)I", (void*)Impl_mle_TerminalShelf_flush},
	{"write", "(II)I", (void*)Impl_mle_TerminalShelf_writeII},
};

jint JNICALL mleTerminalInit(JNIEnv* env, jclass classy)
{
	return env->RegisterNatives(
		env->FindClass("cc/squirreljme/jvm/mle/TerminalShelf"),
		mleTerminalMethods, sizeof(mleTerminalMethods) /
			sizeof(JNINativeMethod));
}

Changes to emulators/emulator-base/src/main/cpp/nativebinding.cpp.

9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
..
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
..
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
...
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
...
266
267
268
269
270
271
272


273
274
275






#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#include "jni.h"
#include "cc_squirreljme_emulator_NativeBinding.h"
#include "cc_squirreljme_jvm_Assembly.h"


// Method handler for special functions
JNIEXPORT void JNICALL doNothing(JNIEnv* env, jclass classy);
JNIEXPORT jint JNICALL doNothingZeroI(JNIEnv* env, jclass classy);
JNIEXPORT void JNICALL notImplemented(JNIEnv* env, jclass classy);
JNIEXPORT void JNICALL restrictedFunction(JNIEnv* env, jclass classy);

// Glue for putting names together
#define GLUE_NAME(name) Java_cc_squirreljme_jvm_Assembly_sysCall##name

// Assembly method mappings
static const JNINativeMethod assemblyMethods[] =
{
	{"arrayLength", "(J)I", (void*)Java_cc_squirreljme_jvm_Assembly_arrayLength__J},
	{"arrayLength", "(Ljava/lang/Object;)I", (void*)Java_cc_squirreljme_jvm_Assembly_arrayLength__Ljava_lang_Object_2},
	{"arrayLengthSet", "(JI)V", (void*)restrictedFunction},
	{"arrayLengthSet", "(Ljava/lang/Object;I)V", (void*)restrictedFunction},
	{"atomicCompareGetAndSet", "(IIJ)I", (void*)notImplemented},
	{"atomicDecrementAndGet", "(J)I", (void*)notImplemented},
	{"atomicIncrement", "(J)V", (void*)notImplemented},
	{"breakpoint", "()V", (void*)doNothing},
	{"classInfoOfBoolean", "()Lcc/squirreljme/jvm/ClassInfo;", (void*)restrictedFunction},
	{"classInfoOfBooleanPointer", "()J", (void*)restrictedFunction},
	{"classInfoOfByte", "()Lcc/squirreljme/jvm/ClassInfo;", (void*)restrictedFunction},
	{"classInfoOfBytePointer", "()J", (void*)restrictedFunction},
	{"classInfoOfCharacter", "()Lcc/squirreljme/jvm/ClassInfo;", (void*)restrictedFunction},
	{"classInfoOfCharacterPointer", "()J", (void*)restrictedFunction},
	{"classInfoOfDouble", "()Lcc/squirreljme/jvm/ClassInfo;", (void*)restrictedFunction},
................................................................................
	{"classInfoOfFloatPointer", "()J", (void*)restrictedFunction},
	{"classInfoOfInteger", "()Lcc/squirreljme/jvm/ClassInfo;", (void*)restrictedFunction},
	{"classInfoOfIntegerPointer", "()J", (void*)restrictedFunction},
	{"classInfoOfLong", "()Lcc/squirreljme/jvm/ClassInfo;", (void*)restrictedFunction},
	{"classInfoOfLongPointer", "()J", (void*)restrictedFunction},
	{"classInfoOfShort", "()Lcc/squirreljme/jvm/ClassInfo;", (void*)restrictedFunction},
	{"classInfoOfShortPointer", "()J", (void*)restrictedFunction},
	{"doublePack", "(II)D", (void*)notImplemented},
	{"doubleToRawLongBits", "(D)J", (void*)notImplemented},
	{"doubleUnpackHigh", "(D)I", (void*)notImplemented},
	{"doubleUnpackLow", "(D)I", (void*)notImplemented},
	{"exceptionHandle", "()V", (void*)doNothing},
	{"floatToRawIntBits", "(F)I", (void*)notImplemented},
	{"intBitsToFloat", "(I)F", (void*)notImplemented},
	{"invoke", "(JJ)V", (void*)restrictedFunction},
	{"invoke", "(JJI)V", (void*)restrictedFunction},
	{"invoke", "(JJII)V", (void*)restrictedFunction},
	{"invoke", "(JJIII)V", (void*)restrictedFunction},
	{"invoke", "(JJIIII)V", (void*)restrictedFunction},
	{"invoke", "(JJIIIII)V", (void*)restrictedFunction},
	{"invoke", "(JJIIIIII)V", (void*)restrictedFunction},
................................................................................
	{"invokeVL", "(JJII)J", (void*)restrictedFunction},
	{"invokeVL", "(JJIII)J", (void*)restrictedFunction},
	{"invokeVL", "(JJIIII)J", (void*)restrictedFunction},
	{"invokeVL", "(JJIIIII)J", (void*)restrictedFunction},
	{"invokeVL", "(JJIIIIII)J", (void*)restrictedFunction},
	{"invokeVL", "(JJIIIIIII)J", (void*)restrictedFunction},
	{"invokeVL", "(JJIIIIIIII)J", (void*)restrictedFunction},
	{"longBitsToDouble", "(J)D", (void*)notImplemented},
	{"longPack", "(II)J", (void*)Java_cc_squirreljme_jvm_Assembly_longPack},
	{"longUnpackHigh", "(J)I", (void*)Java_cc_squirreljme_jvm_Assembly_longUnpackHigh},
	{"longUnpackLow", "(J)I", (void*)Java_cc_squirreljme_jvm_Assembly_longUnpackLow},
	{"memReadByte", "(JI)I", (void*)notImplemented},
	{"memReadInt", "(JI)I", (void*)notImplemented},
	{"memReadJavaInt", "(JI)I", (void*)notImplemented},
	{"memReadJavaLong", "(JI)J", (void*)notImplemented},
	{"memReadJavaShort", "(JI)I", (void*)notImplemented},
	{"memReadPointer", "(JI)J", (void*)notImplemented},
	{"memReadShort", "(JI)I", (void*)notImplemented},
	{"memWriteByte", "(JII)V", (void*)notImplemented},
	{"memWriteInt", "(JII)V", (void*)notImplemented},
	{"memWriteJavaInt", "(JII)V", (void*)notImplemented},
	{"memWriteJavaLong", "(JIJ)V", (void*)notImplemented},
	{"memWriteJavaShort", "(JII)V", (void*)notImplemented},
	{"memWritePointer", "(JIJ)V", (void*)notImplemented},
	{"memWriteShort", "(JII)V", (void*)notImplemented},
	{"monitorCountDecrementAndGetAtomic", "(J)I", (void*)restrictedFunction},
	{"monitorCountDecrementAndGetAtomic", "(Ljava/lang/Object;)I", (void*)restrictedFunction},
	{"monitorCountIncrementAndGetAtomic", "(J)I", (void*)restrictedFunction},
	{"monitorCountIncrementAndGetAtomic", "(Ljava/lang/Object;)I", (void*)restrictedFunction},
	{"monitorCountGetAtomic", "(J)I", (void*)restrictedFunction},
	{"monitorCountGetAtomic", "(Ljava/lang/Object;)I", (void*)restrictedFunction},
	{"monitorCountSetAtomic", "(JI)V", (void*)restrictedFunction},
................................................................................
	{"objectGetClassInfo", "(Ljava/lang/Object;)Lcc/squirreljme/jvm/ClassInfo;", (void*)restrictedFunction},
	{"objectGetClassInfoPointer", "(J)J", (void*)restrictedFunction},
	{"objectGetClassInfoPointer", "(Ljava/lang/Object;)J", (void*)restrictedFunction},
	{"objectSetClassInfo", "(JJ)V", (void*)restrictedFunction},
	{"objectSetClassInfo", "(Ljava/lang/Object;J)V", (void*)restrictedFunction},
	{"objectSetClassInfo", "(JLcc/squirreljme/jvm/ClassInfo;)V", (void*)restrictedFunction},
	{"objectSetClassInfo", "(Ljava/lang/Object;Lcc/squirreljme/jvm/ClassInfo;)V", (void*)restrictedFunction},
	{"objectToPointer", "(Ljava/lang/Object;)J", (void*)Java_cc_squirreljme_jvm_Assembly_objectToPointer},
	{"objectToPointerRefQueue", "(Ljava/lang/Object;)J", (void*)Java_cc_squirreljme_jvm_Assembly_objectToPointer},
	{"pointerToObject", "(J)Ljava/lang/Object;", (void*)Java_cc_squirreljme_jvm_Assembly_pointerToObject},
	{"pointerToClassInfo", "(J)Lcc/squirreljme/jvm/ClassInfo;", (void*)Java_cc_squirreljme_jvm_Assembly_pointerToObject},
	{"poolLoad", "(JI)J", (void*)restrictedFunction},
	{"poolLoad", "(Ljava/lang/Object;I)J", (void*)restrictedFunction},
	{"poolStore", "(JIJ)V", (void*)restrictedFunction},
	{"poolStore", "(Ljava/lang/Object;IJ)V", (void*)restrictedFunction},
	{"refCount", "(J)V", (void*)doNothing},
	{"refCount", "(Ljava/lang/Object;)V", (void*)doNothing},
	{"refGetCount", "(J)I", (void*)restrictedFunction},
	{"refGetCount", "(Ljava/lang/Object;)I", (void*)restrictedFunction},
	{"refSetCount", "(JI)V", (void*)restrictedFunction},
	{"refSetCount", "(Ljava/lang/Object;I)V", (void*)restrictedFunction},
	{"refUncount", "(J)V", (void*)doNothing},
	{"refUncount", "(Ljava/lang/Object;)V", (void*)doNothing},
	{"returnFrame", "()V", (void*)notImplemented},
	{"returnFrame", "(I)V", (void*)notImplemented},
	{"returnFrame", "(II)V", (void*)notImplemented},
	{"returnFrameLong", "(J)V", (void*)notImplemented},
	{"sizeOfBaseArray", "()I", (void*)notImplemented},
	{"sizeOfBaseObject", "()I", (void*)notImplemented},
	{"sizeOfPointer", "()I", (void*)notImplemented},
	{"specialGetExceptionRegister", "()Ljava/lang/Object;", (void*)restrictedFunction},
	{"specialGetExceptionRegisterThrowable", "()Ljava/lang/Throwable;", (void*)restrictedFunction},
	{"specialGetExceptionRegisterPointer", "()J", (void*)restrictedFunction},
	{"specialGetPoolRegister", "()Ljava/lang/Object;", (void*)restrictedFunction},
	{"specialGetPoolRegisterPointer", "()J", (void*)restrictedFunction},
	{"specialGetReturnRegister", "()I", (void*)restrictedFunction},
	{"specialGetReturnRegisterLong", "()J", (void*)restrictedFunction},
................................................................................
	env->ThrowNew(env->FindClass("java/lang/Error"),
		__func__);
}

JNIEXPORT jint JNICALL Java_cc_squirreljme_emulator_NativeBinding__1_1bindMethods
	(JNIEnv* env, jclass classy)
{


	return env->RegisterNatives(env->FindClass("cc/squirreljme/jvm/Assembly"),
		assemblyMethods, sizeof(assemblyMethods) / sizeof(JNINativeMethod));
}













>













|
|


|
|
|
|







 







|
|
|
|
|
|
|







 







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







 







|
|
|
|




|
|




|
|
|
|
|
|
|
|
|







 







>
>
|

|
>
>
>
>
>
>
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
..
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
..
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
...
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
...
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#include "jni.h"
#include "cc_squirreljme_emulator_NativeBinding.h"
#include "cc_squirreljme_jvm_Assembly.h"
#include "squirreljme.h"

// Method handler for special functions
JNIEXPORT void JNICALL doNothing(JNIEnv* env, jclass classy);
JNIEXPORT jint JNICALL doNothingZeroI(JNIEnv* env, jclass classy);
JNIEXPORT void JNICALL notImplemented(JNIEnv* env, jclass classy);
JNIEXPORT void JNICALL restrictedFunction(JNIEnv* env, jclass classy);

// Glue for putting names together
#define GLUE_NAME(name) Java_cc_squirreljme_jvm_Assembly_sysCall##name

// Assembly method mappings
static const JNINativeMethod assemblyMethods[] =
{
	{"arrayLength", "(J)I", (void*)restrictedFunction},
	{"arrayLength", "(Ljava/lang/Object;)I", (void*)restrictedFunction},
	{"arrayLengthSet", "(JI)V", (void*)restrictedFunction},
	{"arrayLengthSet", "(Ljava/lang/Object;I)V", (void*)restrictedFunction},
	{"atomicCompareGetAndSet", "(IIJ)I", (void*)restrictedFunction},
	{"atomicDecrementAndGet", "(J)I", (void*)restrictedFunction},
	{"atomicIncrement", "(J)V", (void*)restrictedFunction},
	{"breakpoint", "()V", (void*)restrictedFunction},
	{"classInfoOfBoolean", "()Lcc/squirreljme/jvm/ClassInfo;", (void*)restrictedFunction},
	{"classInfoOfBooleanPointer", "()J", (void*)restrictedFunction},
	{"classInfoOfByte", "()Lcc/squirreljme/jvm/ClassInfo;", (void*)restrictedFunction},
	{"classInfoOfBytePointer", "()J", (void*)restrictedFunction},
	{"classInfoOfCharacter", "()Lcc/squirreljme/jvm/ClassInfo;", (void*)restrictedFunction},
	{"classInfoOfCharacterPointer", "()J", (void*)restrictedFunction},
	{"classInfoOfDouble", "()Lcc/squirreljme/jvm/ClassInfo;", (void*)restrictedFunction},
................................................................................
	{"classInfoOfFloatPointer", "()J", (void*)restrictedFunction},
	{"classInfoOfInteger", "()Lcc/squirreljme/jvm/ClassInfo;", (void*)restrictedFunction},
	{"classInfoOfIntegerPointer", "()J", (void*)restrictedFunction},
	{"classInfoOfLong", "()Lcc/squirreljme/jvm/ClassInfo;", (void*)restrictedFunction},
	{"classInfoOfLongPointer", "()J", (void*)restrictedFunction},
	{"classInfoOfShort", "()Lcc/squirreljme/jvm/ClassInfo;", (void*)restrictedFunction},
	{"classInfoOfShortPointer", "()J", (void*)restrictedFunction},
	{"doublePack", "(II)D", (void*)restrictedFunction},
	{"doubleToRawLongBits", "(D)J", (void*)restrictedFunction},
	{"doubleUnpackHigh", "(D)I", (void*)restrictedFunction},
	{"doubleUnpackLow", "(D)I", (void*)restrictedFunction},
	{"exceptionHandle", "()V", (void*)restrictedFunction},
	{"floatToRawIntBits", "(F)I", (void*)restrictedFunction},
	{"intBitsToFloat", "(I)F", (void*)restrictedFunction},
	{"invoke", "(JJ)V", (void*)restrictedFunction},
	{"invoke", "(JJI)V", (void*)restrictedFunction},
	{"invoke", "(JJII)V", (void*)restrictedFunction},
	{"invoke", "(JJIII)V", (void*)restrictedFunction},
	{"invoke", "(JJIIII)V", (void*)restrictedFunction},
	{"invoke", "(JJIIIII)V", (void*)restrictedFunction},
	{"invoke", "(JJIIIIII)V", (void*)restrictedFunction},
................................................................................
	{"invokeVL", "(JJII)J", (void*)restrictedFunction},
	{"invokeVL", "(JJIII)J", (void*)restrictedFunction},
	{"invokeVL", "(JJIIII)J", (void*)restrictedFunction},
	{"invokeVL", "(JJIIIII)J", (void*)restrictedFunction},
	{"invokeVL", "(JJIIIIII)J", (void*)restrictedFunction},
	{"invokeVL", "(JJIIIIIII)J", (void*)restrictedFunction},
	{"invokeVL", "(JJIIIIIIII)J", (void*)restrictedFunction},
	{"longBitsToDouble", "(J)D", (void*)restrictedFunction},
	{"longPack", "(II)J", (void*)restrictedFunction},
	{"longUnpackHigh", "(J)I", (void*)restrictedFunction},
	{"longUnpackLow", "(J)I", (void*)restrictedFunction},
	{"memReadByte", "(JI)I", (void*)restrictedFunction},
	{"memReadInt", "(JI)I", (void*)restrictedFunction},
	{"memReadJavaInt", "(JI)I", (void*)restrictedFunction},
	{"memReadJavaLong", "(JI)J", (void*)restrictedFunction},
	{"memReadJavaShort", "(JI)I", (void*)restrictedFunction},
	{"memReadPointer", "(JI)J", (void*)restrictedFunction},
	{"memReadShort", "(JI)I", (void*)restrictedFunction},
	{"memWriteByte", "(JII)V", (void*)restrictedFunction},
	{"memWriteInt", "(JII)V", (void*)restrictedFunction},
	{"memWriteJavaInt", "(JII)V", (void*)restrictedFunction},
	{"memWriteJavaLong", "(JIJ)V", (void*)restrictedFunction},
	{"memWriteJavaShort", "(JII)V", (void*)restrictedFunction},
	{"memWritePointer", "(JIJ)V", (void*)restrictedFunction},
	{"memWriteShort", "(JII)V", (void*)restrictedFunction},
	{"monitorCountDecrementAndGetAtomic", "(J)I", (void*)restrictedFunction},
	{"monitorCountDecrementAndGetAtomic", "(Ljava/lang/Object;)I", (void*)restrictedFunction},
	{"monitorCountIncrementAndGetAtomic", "(J)I", (void*)restrictedFunction},
	{"monitorCountIncrementAndGetAtomic", "(Ljava/lang/Object;)I", (void*)restrictedFunction},
	{"monitorCountGetAtomic", "(J)I", (void*)restrictedFunction},
	{"monitorCountGetAtomic", "(Ljava/lang/Object;)I", (void*)restrictedFunction},
	{"monitorCountSetAtomic", "(JI)V", (void*)restrictedFunction},
................................................................................
	{"objectGetClassInfo", "(Ljava/lang/Object;)Lcc/squirreljme/jvm/ClassInfo;", (void*)restrictedFunction},
	{"objectGetClassInfoPointer", "(J)J", (void*)restrictedFunction},
	{"objectGetClassInfoPointer", "(Ljava/lang/Object;)J", (void*)restrictedFunction},
	{"objectSetClassInfo", "(JJ)V", (void*)restrictedFunction},
	{"objectSetClassInfo", "(Ljava/lang/Object;J)V", (void*)restrictedFunction},
	{"objectSetClassInfo", "(JLcc/squirreljme/jvm/ClassInfo;)V", (void*)restrictedFunction},
	{"objectSetClassInfo", "(Ljava/lang/Object;Lcc/squirreljme/jvm/ClassInfo;)V", (void*)restrictedFunction},
	{"objectToPointer", "(Ljava/lang/Object;)J", (void*)restrictedFunction},
	{"objectToPointerRefQueue", "(Ljava/lang/Object;)J", (void*)restrictedFunction},
	{"pointerToObject", "(J)Ljava/lang/Object;", (void*)restrictedFunction},
	{"pointerToClassInfo", "(J)Lcc/squirreljme/jvm/ClassInfo;", (void*)restrictedFunction},
	{"poolLoad", "(JI)J", (void*)restrictedFunction},
	{"poolLoad", "(Ljava/lang/Object;I)J", (void*)restrictedFunction},
	{"poolStore", "(JIJ)V", (void*)restrictedFunction},
	{"poolStore", "(Ljava/lang/Object;IJ)V", (void*)restrictedFunction},
	{"refCount", "(J)V", (void*)restrictedFunction},
	{"refCount", "(Ljava/lang/Object;)V", (void*)restrictedFunction},
	{"refGetCount", "(J)I", (void*)restrictedFunction},
	{"refGetCount", "(Ljava/lang/Object;)I", (void*)restrictedFunction},
	{"refSetCount", "(JI)V", (void*)restrictedFunction},
	{"refSetCount", "(Ljava/lang/Object;I)V", (void*)restrictedFunction},
	{"refUncount", "(J)V", (void*)restrictedFunction},
	{"refUncount", "(Ljava/lang/Object;)V", (void*)restrictedFunction},
	{"returnFrame", "()V", (void*)restrictedFunction},
	{"returnFrame", "(I)V", (void*)restrictedFunction},
	{"returnFrame", "(II)V", (void*)restrictedFunction},
	{"returnFrameLong", "(J)V", (void*)restrictedFunction},
	{"sizeOfBaseArray", "()I", (void*)restrictedFunction},
	{"sizeOfBaseObject", "()I", (void*)restrictedFunction},
	{"sizeOfPointer", "()I", (void*)restrictedFunction},
	{"specialGetExceptionRegister", "()Ljava/lang/Object;", (void*)restrictedFunction},
	{"specialGetExceptionRegisterThrowable", "()Ljava/lang/Throwable;", (void*)restrictedFunction},
	{"specialGetExceptionRegisterPointer", "()J", (void*)restrictedFunction},
	{"specialGetPoolRegister", "()Ljava/lang/Object;", (void*)restrictedFunction},
	{"specialGetPoolRegisterPointer", "()J", (void*)restrictedFunction},
	{"specialGetReturnRegister", "()I", (void*)restrictedFunction},
	{"specialGetReturnRegisterLong", "()J", (void*)restrictedFunction},
................................................................................
	env->ThrowNew(env->FindClass("java/lang/Error"),
		__func__);
}

JNIEXPORT jint JNICALL Java_cc_squirreljme_emulator_NativeBinding__1_1bindMethods
	(JNIEnv* env, jclass classy)
{
	jint rv = 0;

	rv |= env->RegisterNatives(env->FindClass("cc/squirreljme/jvm/Assembly"),
		assemblyMethods, sizeof(assemblyMethods) / sizeof(JNINativeMethod));

	rv |= mleRuntimeInit(env, classy);
	rv |= mleObjectInit(env, classy);
	rv |= mleTerminalInit(env, classy);

	return rv;
}

Added emulators/emulator-base/src/main/headers/cc_squirreljme_jvm_mle_ObjectShelf.h.



























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class cc_squirreljme_jvm_mle_ObjectShelf */

#ifndef _Included_cc_squirreljme_jvm_mle_ObjectShelf
#define _Included_cc_squirreljme_jvm_mle_ObjectShelf
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     cc_squirreljme_jvm_mle_ObjectShelf
 * Method:    arrayLength
 * Signature: (Ljava/lang/Object;)I
 */
JNIEXPORT jint JNICALL Java_cc_squirreljme_jvm_mle_ObjectShelf_arrayLength
  (JNIEnv *, jclass, jobject);

/*
 * Class:     cc_squirreljme_jvm_mle_ObjectShelf
 * Method:    arrayNew
 * Signature: (Lcc/squirreljme/jvm/mle/brackets/TypeBracket;I)Ljava/lang/Object;
 */
JNIEXPORT jobject JNICALL Java_cc_squirreljme_jvm_mle_ObjectShelf_arrayNew
  (JNIEnv *, jclass, jobject, jint);

#ifdef __cplusplus
}
#endif
#endif

Added emulators/emulator-base/src/main/headers/cc_squirreljme_jvm_mle_RuntimeShelf.h.



























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class cc_squirreljme_jvm_mle_RuntimeShelf */

#ifndef _Included_cc_squirreljme_jvm_mle_RuntimeShelf
#define _Included_cc_squirreljme_jvm_mle_RuntimeShelf
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     cc_squirreljme_jvm_mle_RuntimeShelf
 * Method:    encoding
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_cc_squirreljme_jvm_mle_RuntimeShelf_encoding
  (JNIEnv *, jclass);

/*
 * Class:     cc_squirreljme_jvm_mle_RuntimeShelf
 * Method:    lineEnding
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_cc_squirreljme_jvm_mle_RuntimeShelf_lineEnding
  (JNIEnv *, jclass);

/*
 * Class:     cc_squirreljme_jvm_mle_RuntimeShelf
 * Method:    locale
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_cc_squirreljme_jvm_mle_RuntimeShelf_locale
  (JNIEnv *, jclass);

/*
 * Class:     cc_squirreljme_jvm_mle_RuntimeShelf
 * Method:    vmType
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_cc_squirreljme_jvm_mle_RuntimeShelf_vmType
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

Added emulators/emulator-base/src/main/headers/cc_squirreljme_jvm_mle_TerminalShelf.h.











































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class cc_squirreljme_jvm_mle_TerminalShelf */

#ifndef _Included_cc_squirreljme_jvm_mle_TerminalShelf
#define _Included_cc_squirreljme_jvm_mle_TerminalShelf
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     cc_squirreljme_jvm_mle_TerminalShelf
 * Method:    flush
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_cc_squirreljme_jvm_mle_TerminalShelf_flush
  (JNIEnv *, jclass, jint);

/*
 * Class:     cc_squirreljme_jvm_mle_TerminalShelf
 * Method:    write
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_cc_squirreljme_jvm_mle_TerminalShelf_write__II
  (JNIEnv *, jclass, jint, jint);

/*
 * Class:     cc_squirreljme_jvm_mle_TerminalShelf
 * Method:    write
 * Signature: (I[BII)I
 */
JNIEXPORT jint JNICALL Java_cc_squirreljme_jvm_mle_TerminalShelf_write__I_3BII
  (JNIEnv *, jclass, jint, jbyteArray, jint, jint);

#ifdef __cplusplus
}
#endif
#endif

Added emulators/emulator-base/src/main/headers/squirreljme.h.







































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* -*- Mode: C++; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// -------------------------------------------------------------------------*/

#ifndef __SQUIRRELJME_H__
#define __SQUIRRELJME_H__

#include "jni.h"

jint JNICALL mleRuntimeInit(JNIEnv* env, jclass classy);
jint JNICALL mleObjectInit(JNIEnv* env, jclass classy);
jint JNICALL mleTerminalInit(JNIEnv* env, jclass classy);

#endif /* __SQUIRRELJME_H__ */

Changes to emulators/emulator-base/src/main/java/cc/squirreljme/emulator/EmulatorAssembly.java.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
package cc.squirreljme.emulator;

import cc.squirreljme.emulator.fb.NativeFramebuffer;
import cc.squirreljme.jvm.SystemCallError;
import cc.squirreljme.jvm.SystemCallIndex;
import cc.squirreljme.jvm.config.ConfigRomKey;
import cc.squirreljme.jvm.config.ConfigRomType;
import cc.squirreljme.jvm.config.LineEndingType;
import java.io.IOException;
import java.io.OutputStream;

/**
 * This contains the implementation of some system calls in the event that the
 * JNI emulation layer does not have a C-based implementation of a method.
 *
................................................................................
	 * @param __h Argument.
	 * @return The result.
	 * @since 2020/02/26
	 */
	public static long systemCall(short __si, int __a, int __b,
		int __c, int __d, int __e, int __f, int __g, int __h)
	{
		// We need the context for thread based info
		EmulatorThreadContext context = EmulatorAssembly.threadContext();
		
		// Depends on the system call
		switch (__si)
		{
				// System calls that are supported?
			case SystemCallIndex.QUERY_INDEX:
				{
					// Always succeeds
					context.setError(__si, 0);
					
					// Depends on the system call requested
					switch (__a)
					{
							// Implemented here
						case SystemCallIndex.CONFIG_GET_TYPE:
						case SystemCallIndex.CONFIG_GET_VALUE:
						case SystemCallIndex.ERROR_GET:
						case SystemCallIndex.ERROR_SET:
						case SystemCallIndex.FRAMEBUFFER:
						case SystemCallIndex.QUERY_INDEX:
						case SystemCallIndex.PD_OF_STDERR:
						case SystemCallIndex.PD_OF_STDOUT:
						case SystemCallIndex.PD_WRITE_BYTE:
						case SystemCallIndex.TIME_MILLI_WALL:
						case SystemCallIndex.TIME_NANO_MONO:
							return 1;
						
							// Not-implemented
						default:
							return 0;
					}
				}
				
				// Get configuration type
			case SystemCallIndex.CONFIG_GET_TYPE:
				switch (__a)
				{
					case ConfigRomKey.LINE_ENDING:
						return ConfigRomType.INTEGER;
					
					default:
						context.setError(__si,
							SystemCallError.NO_SUCH_CONFIG_KEY);
						return 0;
				}
			
				// Get raw value
			case SystemCallIndex.CONFIG_GET_VALUE:
				switch (__a)
				{
					case ConfigRomKey.LINE_ENDING:
						switch (System.getProperty("line.separator"))
						{
							case "\r":		return LineEndingType.CR;
							case "\r\n":	return LineEndingType.CRLF;
							case "\n":		return LineEndingType.LF;
							default:		return LineEndingType.UNSPECIFIED;
						}
						
					default:
						context.setError(__si,
							SystemCallError.NO_SUCH_CONFIG_KEY);
						return 0;
				}
			
				// Get error
			case SystemCallIndex.ERROR_GET:
				{
					context.setError(__si, 0);
					
					return context.getError((short)__a);
				}
			
				// Set error
			case SystemCallIndex.ERROR_SET:
				{
					context.setError(__si, 0);
					
					int oldError = context.getError((short)__a);
					context.setError((short)__a, __b);
					return oldError;
				}
			
				// Access the framebuffer
			case SystemCallIndex.FRAMEBUFFER:
				return NativeFramebuffer.getInstance().systemCall(context,
					__a, __b, __c, __d, __e, __f, __g, __h);
				
				// Descriptor of standard error
			case SystemCallIndex.PD_OF_STDERR:
				context.setError(__si, 0);
				return 2;
				
				// Descriptor of standard output
			case SystemCallIndex.PD_OF_STDOUT:
				context.setError(__si, 0);
				return 1;
				
				// Write byte
			case SystemCallIndex.PD_WRITE_BYTE:
				{
					OutputStream pipe = (__a == 2 ? System.err :
						(__a == 1 ? System.out : null));
					
					if (pipe != null)
					{
						try
						{
							pipe.write(__b);
							context.setError(__si, 0);
							
							return 1;
						}
						catch (IOException e)
						{
							context.setError(__si,
								SystemCallError.PIPE_DESCRIPTOR_BAD_WRITE);
							
							return 0;
						}
					}
					else
					{
						context.setError(__si,
							SystemCallError.PIPE_DESCRIPTOR_INVALID);
						return 0;
					}
				}
				
				// Current wall clock
			case SystemCallIndex.TIME_MILLI_WALL:
				{
					context.setError(__si, 0);
					
					return System.currentTimeMillis();
				}
			
				// Current monotonic clock
			case SystemCallIndex.TIME_NANO_MONO:
				{
					context.setError(__si, 0);
					
					return System.nanoTime();
				}
			
				// Un-handled, set as not supported and return a default value
			default:
				// Debug
				System.err.printf(
					"SysCall?: %d(%d, %d, %d, %d, %d, %d, %d, %d)%n",
					__si, __a, __b, __c, __d, __e, __f, __g, __h);
				
				// Set error
				context.setError(__si,
					SystemCallError.UNSUPPORTED_SYSTEM_CALL);
				return 0;
		}
	}
	
	/**
	 * Returns the current thread context.
	 *
	 * @return The thread context.
	 * @since 2020/02/26







|







 







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
53
54
55
56
57
58
59
60






























































































































































61
62
63
64
65
66
67
package cc.squirreljme.emulator;

import cc.squirreljme.emulator.fb.NativeFramebuffer;
import cc.squirreljme.jvm.SystemCallError;
import cc.squirreljme.jvm.SystemCallIndex;
import cc.squirreljme.jvm.config.ConfigRomKey;
import cc.squirreljme.jvm.config.ConfigRomType;
import cc.squirreljme.jvm.mle.constants.LineEndingType;
import java.io.IOException;
import java.io.OutputStream;

/**
 * This contains the implementation of some system calls in the event that the
 * JNI emulation layer does not have a C-based implementation of a method.
 *
................................................................................
	 * @param __h Argument.
	 * @return The result.
	 * @since 2020/02/26
	 */
	public static long systemCall(short __si, int __a, int __b,
		int __c, int __d, int __e, int __f, int __g, int __h)
	{
		throw new Error("Invalid Emulator System Call");






























































































































































	}
	
	/**
	 * Returns the current thread context.
	 *
	 * @return The thread context.
	 * @since 2020/02/26

Changes to emulators/emulator-base/src/main/java/cc/squirreljme/emulator/NativeBinding.java.

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
				e.addSuppressed(f);
			}
			
			throw new RuntimeException("Could not copy native library.", e);
		}
		
		// Attempt cleanup at shutdown.
		final Path[] paths = new Path[]{libFile, tempDir};
		Runtime.getRuntime().addShutdownHook(new Thread(() ->
			{
				try
				{
					for (Path p : paths)
						Files.delete(p);
				}
				catch (IOException e)
				{
				}
			}, "SquirrelJME-LibraryCleanupThread"));

		
		// Try loading the library now
		System.load(libFile.toString());
		
		// Bind methods
		if (NativeBinding.__bindMethods() != 0)
			throw new RuntimeException("Could not bind methods!");







<
|
<
<
<
<
<
<
<
<
<
<
>







80
81
82
83
84
85
86

87










88
89
90
91
92
93
94
95
				e.addSuppressed(f);
			}
			
			throw new RuntimeException("Could not copy native library.", e);
		}
		
		// Attempt cleanup at shutdown.

		Runtime.getRuntime().addShutdownHook(










			new PathCleanup(libFile, tempDir));
		
		// Try loading the library now
		System.load(libFile.toString());
		
		// Bind methods
		if (NativeBinding.__bindMethods() != 0)
			throw new RuntimeException("Could not bind methods!");

Added emulators/emulator-base/src/main/java/cc/squirreljme/emulator/PathCleanup.java.













































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.emulator;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

/**
 * Cleanup for paths.
 *
 * @since 2020/06/22
 */
public final class PathCleanup
	extends Thread
{
	/** The paths to clear. */
	private final Path[] _paths;
	
	/**
	 * Cleans up the paths.
	 * 
	 * @param __paths The paths to clear.
	 * @since 2020/06/22
	 */
	public PathCleanup(Path... __paths)
	{
		this._paths = (__paths == null ? new Path[0] : __paths.clone());
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/06/22
	 */
	@Override
	public final void run()
	{
		for (Path p : this._paths)
			try
			{
				Files.delete(p);
			}
			catch (IOException ignored)
			{
			}
	}
}

Changes to emulators/emulator-base/src/main/java/cc/squirreljme/emulator/profiler/ProfiledFrame.java.

57
58
59
60
61
62
63



64
65
66
67
68
69
70
..
97
98
99
100
101
102
103



104
105
106
107
108
109
110
...
139
140
141
142
143
144
145




146
147
148
149











150
151
152
153
154
155
156
	private long _currentstart =
		Long.MIN_VALUE;
	
	/** Current time sub-frame started execution, to remove self time. */
	private long _currentsubstart =
		Long.MIN_VALUE;
	



	/**
	 * Initializes this frame.
	 *
	 * @param __l The frame location.
	 * @param __d The depth of this frame.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/11
................................................................................
			
		// {@squirreljme.error AH02 Cannot enter frame that is in an invoke.}
		if (this._currentsubstart != Long.MIN_VALUE)
			throw new IllegalStateException("AH02");
		
		// Mark time
		this._currentstart = __ns;



	}
	
	/**
	 * Indicates that the frame has been exited.
	 *
	 * @param __ns The time of the exit.
	 * @return The time spent in this frame, in total, self time, and CPU
................................................................................
		// And only this frame time
		this._frameruntime += self;
		this._framecputime += self;
		
		// Clear these for next time
		this._currentstart = Long.MIN_VALUE;
		this._subtractself = 0;




		
		// Return both times since they may be useful
		return new long[]{total, self, total};
	}











	
	/**
	 * Indicates that this frame is no longer invoking some other method.
	 *
	 * @param __ns The ending nanoseconds.
	 * @return The time which has passed.
	 * @throws IllegalStateException If the frame is not in an invoke.







>
>
>







 







>
>
>







 







>
>
>
>




>
>
>
>
>
>
>
>
>
>
>







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
...
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
...
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
	private long _currentstart =
		Long.MIN_VALUE;
	
	/** Current time sub-frame started execution, to remove self time. */
	private long _currentsubstart =
		Long.MIN_VALUE;
	
	/** The current in-call count for this frame. */
	private int _inCallCount;
	
	/**
	 * Initializes this frame.
	 *
	 * @param __l The frame location.
	 * @param __d The depth of this frame.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/11
................................................................................
			
		// {@squirreljme.error AH02 Cannot enter frame that is in an invoke.}
		if (this._currentsubstart != Long.MIN_VALUE)
			throw new IllegalStateException("AH02");
		
		// Mark time
		this._currentstart = __ns;
		
		// Increase call count
		this._inCallCount++;
	}
	
	/**
	 * Indicates that the frame has been exited.
	 *
	 * @param __ns The time of the exit.
	 * @return The time spent in this frame, in total, self time, and CPU
................................................................................
		// And only this frame time
		this._frameruntime += self;
		this._framecputime += self;
		
		// Clear these for next time
		this._currentstart = Long.MIN_VALUE;
		this._subtractself = 0;
		
		// Lower the in-call count, make sure it never goes below zero
		if ((--this._inCallCount) < 0)
			this._inCallCount = 0;
		
		// Return both times since they may be useful
		return new long[]{total, self, total};
	}
	
	/**
	 * Returns the number of times this frame is currently in a call.
	 *
	 * @return The number of times this frame is considered in a call.
	 * @since 2020/06/17
	 */
	public final int inCallCount()
	{
		return this._inCallCount;
	}
	
	/**
	 * Indicates that this frame is no longer invoking some other method.
	 *
	 * @param __ns The ending nanoseconds.
	 * @return The time which has passed.
	 * @throws IllegalStateException If the frame is not in an invoke.

Changes to emulators/emulator-base/src/main/java/cc/squirreljme/emulator/vm/VMFactory.java.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
...
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
...
411
412
413
414
415
416
417
418
419
420
421


422
423
424
425
426
427
428
429
430
431
432
433
434
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.emulator.vm;

import cc.squirreljme.emulator.profiler.ProfilerSnapshot;
import cc.squirreljme.runtime.cldc.Poking;
import cc.squirreljme.runtime.swm.EntryPoints;
import cc.squirreljme.vm.JarClassLibrary;
import cc.squirreljme.vm.NameOverrideClassLibrary;
import cc.squirreljme.vm.VMClassLibrary;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.FileVisitOption;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Collection;
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Objects;
import java.util.ServiceLoader;
import java.util.stream.Stream;
import net.multiphasicapps.tool.manifest.JavaManifest;

/**
 * This class is used to initialize virtual machines based on a set of factory
 * classes.
 *
 * This was added because there were many cases where tons of code was
 * duplicated to initialize the virtual machine, which were effectively
................................................................................
		// -Xemulator:(vm)
		// -Xsnapshot:(path-to-nps)
		// -Xlibraries:(class:path:...)
		// -Dsysprop=value
		// -classpath (class:path:...)
		// Main-class
		// Arguments...
		Deque<String> queue = new ArrayDeque<>(Arrays.<String>asList(__args));
		while (!queue.isEmpty())
		{
			// End of our items?
			String item = queue.peekFirst();
			if (item == null || item.isEmpty() || item.charAt(0) != '-')
				break;
			
................................................................................
		if (!__path.endsWith("*"))
		{
			__files.add(__path);
			return;
		}
		
		// Try searching for JAR files in a directory
		try (Stream<Path> stream = Files.walk(
			Paths.get(__path.substring(0, __path.length() - 1)), 1,
			FileVisitOption.FOLLOW_LINKS))
		{


			stream.forEach(__scan ->
				{
					String fn = __scan.getFileName().toString();
					if (fn.endsWith(".jar") || fn.endsWith(".JAR"))
						__files.add(__scan.toString());
				});
		}
		catch (IOException e)
		{
			throw new RuntimeException(String.format(
				"Could not load wildcard JARs: %s", __path), e);
		}
	}







<





<






<










<







 







|







 







|
<
<

>
>
|
<
<
<
<
<







8
9
10
11
12
13
14

15
16
17
18
19

20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
...
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
...
407
408
409
410
411
412
413
414


415
416
417
418





419
420
421
422
423
424
425
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.emulator.vm;

import cc.squirreljme.emulator.profiler.ProfilerSnapshot;
import cc.squirreljme.runtime.cldc.Poking;

import cc.squirreljme.vm.JarClassLibrary;
import cc.squirreljme.vm.NameOverrideClassLibrary;
import cc.squirreljme.vm.VMClassLibrary;
import java.io.File;
import java.io.IOException;

import java.io.OutputStream;
import java.nio.file.FileVisitOption;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

import java.util.Arrays;
import java.util.Collection;
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Objects;
import java.util.ServiceLoader;
import java.util.stream.Stream;


/**
 * This class is used to initialize virtual machines based on a set of factory
 * classes.
 *
 * This was added because there were many cases where tons of code was
 * duplicated to initialize the virtual machine, which were effectively
................................................................................
		// -Xemulator:(vm)
		// -Xsnapshot:(path-to-nps)
		// -Xlibraries:(class:path:...)
		// -Dsysprop=value
		// -classpath (class:path:...)
		// Main-class
		// Arguments...
		Deque<String> queue = new LinkedList<>(Arrays.<String>asList(__args));
		while (!queue.isEmpty())
		{
			// End of our items?
			String item = queue.peekFirst();
			if (item == null || item.isEmpty() || item.charAt(0) != '-')
				break;
			
................................................................................
		if (!__path.endsWith("*"))
		{
			__files.add(__path);
			return;
		}
		
		// Try searching for JAR files in a directory
		try


		{
			Path startPath = Paths.get(
				__path.substring(0, __path.length() - 1));
			Files.walkFileTree(startPath, new __JarWalker__(__files));





		}
		catch (IOException e)
		{
			throw new RuntimeException(String.format(
				"Could not load wildcard JARs: %s", __path), e);
		}
	}

Added emulators/emulator-base/src/main/java/cc/squirreljme/emulator/vm/__JarWalker__.java.

































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.emulator.vm;

import cc.squirreljme.runtime.cldc.debug.Debugging;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Collection;

/**
 * Walks the file tree for wildcard JARs.
 *
 * @since 2020/06/22
 */
public final class __JarWalker__
	extends SimpleFileVisitor<Path>
{
	/** Where to place found files. */
	private final Collection<String> _files;
	
	/**
	 * Initializes the Jar walker.
	 * 
	 * @param __files The files to write to.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/22
	 */
	public __JarWalker__(Collection<String> __files)
		throws NullPointerException
	{
		if (__files == null)
			throw new NullPointerException("NARG");
		
		this._files = __files;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/06/22
	 */
	@Override
	public FileVisitResult visitFile(Path __path, BasicFileAttributes __attrib)
		throws IOException
	{
		// If this is a JAR, we will grab it
		String fn = __path.getFileName().toString();
		if (fn.endsWith(".jar") || fn.endsWith(".JAR"))
			this._files.add(__path.toString());
		
		// The default way is to just handle it
		return super.visitFile(__path, __attrib);
	}
}

Changes to emulators/springcoat-vm/build.gradle.

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
description = "This is a SpringCoat virtual machine which " +
	"is an unoptimized pure interpreter aimed for the purpose of being an " +
	"educational stepping stone to other future virtual machines."

dependencies
{
	api project(":emulators:emulator-base")

	api project(":modules:cldc-compact")
	api project(":modules:tool-classfile")
	api project(":modules:tool-manifest-reader")
	api project(":modules:meep-swm")
	api project(":modules:meep-midlet")
	api project(":modules:common-vm")
	api project(":modules:collections")
}







|

|
<

|
|
<

6
7
8
9
10
11
12
13
14
15

16
17
18

19
description = "This is a SpringCoat virtual machine which " +
	"is an unoptimized pure interpreter aimed for the purpose of being an " +
	"educational stepping stone to other future virtual machines."

dependencies
{
	api project(":emulators:emulator-base")
	
	api project(":modules:cldc-compact")
	api project(":modules:common-vm")

	api project(":modules:meep-swm")
	api project(":modules:tool-classfile")
	api project(":modules:tool-manifest-reader")

}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/AbstractGhostObject.java.

















































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.vm.springcoat.brackets.RefLinkHolder;
import cc.squirreljme.vm.springcoat.exceptions.SpringVirtualMachineException;

/**
 * This is the base for ghost objects which do not have a defined class type
 * or anything associated with a class object.
 *
 * @since 2020/05/30
 */
public abstract class AbstractGhostObject
	implements SpringObject
{
	/**
	 * {@inheritDoc}
	 * @since 2020/05/30
	 */
	@Override
	public final SpringMonitor monitor()
	{
		throw new SpringVirtualMachineException(
			"Ghost objects cannot have monitors: " + this.toString());
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/05/31
	 */
	@Override
	public RefLinkHolder refLink()
	{
		throw new SpringVirtualMachineException(
			"Ghost objects cannot have refLinks: " + this.toString());
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/05/30
	 */
	@Override
	public final SpringClass type()
	{
		throw new SpringVirtualMachineException(
			"Ghost objects cannot have types: " + this.toString());
	}
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/GlobalState.java.

























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * Contains virtual machine global state.
 *
 * @since 2020/05/30
 */
public final class GlobalState
{
	/** Ticker for atomic values. */
	public static final AtomicInteger TICKER =
		new AtomicInteger();
	
	/** The GC lock. */
	public static final AtomicInteger GC_LOCK =
		new AtomicInteger();
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/MLEAtomic.java.















































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.mle.AtomicShelf;
import cc.squirreljme.vm.springcoat.exceptions.SpringMLECallError;

/**
 * Functions for {@link AtomicShelf}.
 *
 * @since 2020/06/18
 */
public enum MLEAtomic
	implements MLEFunction
{
	/** {@link AtomicShelf#gcLock()}. */
	GC_LOCK("gcLock:()I")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			// Generate a key which will be returned in the lock
			int key = (int)MLEAtomic.TICK.handle(__thread);
			
			// When unlocked the lock will have zero, so we can set it to the
			// key we generated... otherwise we fail here
			if (GlobalState.GC_LOCK.compareAndSet(0, key))
				return key;
			return 0;
		}
	},
	
	/** {@link AtomicShelf#gcUnlock(int)}. */
	GC_UNLOCK("gcUnlock:(I)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			// Unlocking is simple and only works if we have the key used to
			// lock the garbage collector
			if (!GlobalState.GC_LOCK.compareAndSet((int)__args[0], 0))
				throw new SpringMLECallError("Wrong lock code.");
			
			return null;
		}
	},
	
	/** {@link AtomicShelf#spinLock(int)}. */
	SPIN_LOCK("spinLock:(I)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			int count = (int)__args[0];
			
			if (count < 0)
				throw new SpringMLECallError("Negative spin count.");
			
			// If we spin for too long, instead give up our cycles
			if (count > MLEAtomic._SPIN_LIMIT)
				Thread.yield();
			
			return null;
		}
	},
	
	/** {@link AtomicShelf#tick()}. */
	TICK("tick:()I")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return GlobalState.TICKER.decrementAndGet();
		}
	},
	
	/* End. */
	;
	
	/** How many times to spin before yielding. */
	private static final int _SPIN_LIMIT =
		8;
	
	/** The dispatch key. */
	protected final String key;
	
	/**
	 * Initializes the dispatcher info.
	 *
	 * @param __key The key.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/18
	 */
	MLEAtomic(String __key)
		throws NullPointerException
	{
		if (__key == null)
			throw new NullPointerException("NARG");
		
		this.key = __key;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/06/18
	 */
	@Override
	public String key()
	{
		return this.key;
	}
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/MLEDebug.java.





















































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.mle.DebugShelf;
import cc.squirreljme.jvm.mle.brackets.TracePointBracket;
import cc.squirreljme.runtime.cldc.debug.CallTraceElement;
import cc.squirreljme.vm.springcoat.brackets.TracePointObject;
import cc.squirreljme.vm.springcoat.exceptions.SpringMLECallError;

/**
 * Functions for {@link DebugShelf}.
 *
 * @since 2020/06/18
 */
public enum MLEDebug
	implements MLEFunction
{
	/** {@link DebugShelf#getThrowableTrace(Throwable)}. */
	GET_THROWABLE_TRACE("getThrowableTrace:(Ljava/lang/Throwable;)" +
		"[Lcc/squirreljme/jvm/mle/brackets/TracePointBracket;")
	{
		/**
		 * {@inheritDoc
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringObject object = (SpringObject)__args[0];
			
			// Must be throwable type
			if (!(object instanceof SpringSimpleObject) ||
				object.type().isAssignableFrom(
				__thread.resolveClass("java/lang/Throwable")))
				throw new SpringMLECallError("Not a Throwable.");
			
			return ((SpringSimpleObject)object).fieldByNameAndType(
				false, "_stack",
				"[Lcc/squirreljme/jvm/mle/brackets/TracePointBracket;")
				.get();
		}
	},
	
	/** {@link DebugShelf#pointAddress(TracePointBracket)}. */
	POINT_ADDRESS("pointAddress:(Lcc/squirreljme/jvm/mle/brackets/" +
		"TracePointBracket;)J")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return MLEDebug.__trace(__args[0]).getTrace().address();
		}
	},
	
	/** {@link DebugShelf#pointClass(TracePointBracket)} .*/
	POINT_CLASS("pointClass:(Lcc/squirreljme/jvm/mle/brackets/" +
		"TracePointBracket;)Ljava/lang/String;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return __thread.asVMObject(MLEDebug.__trace(__args[0])
				.getTrace().className());
		}
	},
	
	/** {@link DebugShelf#pointFile(TracePointBracket)}. */
	POINT_FILE("pointFile:(Lcc/squirreljme/jvm/mle/brackets/" +
		"TracePointBracket;)Ljava/lang/String;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return __thread.asVMObject(MLEDebug.__trace(__args[0])
				.getTrace().file());
		}
	},
	
	/** {@link DebugShelf#pointJavaAddress(TracePointBracket)}. */
	POINT_JAVA_ADDRESS("pointJavaAddress:(Lcc/squirreljme/jvm/mle/" +
		"brackets/TracePointBracket;)I")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return MLEDebug.__trace(__args[0]).getTrace().byteCodeAddress();
		}
	},
	
	/** {@link DebugShelf#pointJavaOperation(TracePointBracket)}. */
	POINT_JAVA_OPERATION("pointJavaOperation:(Lcc/squirreljme/jvm/mle/" +
		"brackets/TracePointBracket;)I")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return MLEDebug.__trace(__args[0]).getTrace()
				.byteCodeInstruction();
		}
	},
	
	/** {@link DebugShelf#pointLine(TracePointBracket)}. */
	POINT_LINE("pointLine:(Lcc/squirreljme/jvm/mle/brackets/" +
		"TracePointBracket;)I")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return MLEDebug.__trace(__args[0]).getTrace().line();
		}
	},
	
	/** {@link DebugShelf#pointMethodName(TracePointBracket)}. */
	POINT_METHOD_NAME("pointMethodName:(Lcc/squirreljme/jvm/mle/" +
		"brackets/TracePointBracket;)Ljava/lang/String;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return __thread.asVMObject(MLEDebug.__trace(__args[0])
				.getTrace().methodName());
		}
	},
	
	/** {@link DebugShelf#pointMethodType(TracePointBracket)}. */
	POINT_METHOD_TYPE( "pointMethodType:(Lcc/squirreljme/jvm/mle/" +
		"brackets/TracePointBracket;)Ljava/lang/String;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return __thread.asVMObject(MLEDebug.__trace(__args[0])
				.getTrace().methodDescriptor());
		}
	},
	
	/** {@link DebugShelf#traceStack()}. */
	TRACE_STACK("traceStack:()" +
		"[Lcc/squirreljme/jvm/mle/brackets/TracePointBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			CallTraceElement[] trace = __thread.thread.getStackTrace();
			
			int n = trace.length;
			TracePointObject[] rv = new TracePointObject[n];
			
			for (int i = 0; i < n; i++)
				rv[i] = new TracePointObject(trace[i]);
			
			return __thread.asVMObjectArray(__thread.loadClass(
				"[Lcc/squirreljme/jvm/mle/brackets/TracePointBracket;"),
				rv);
		}
	}
	
	/* End. */
	;
	
	/** The dispatch key. */
	protected final String key;
	
	/**
	 * Initializes the dispatcher info.
	 *
	 * @param __key The key.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/18
	 */
	MLEDebug(String __key)
		throws NullPointerException
	{
		if (__key == null)
			throw new NullPointerException("NARG");
		
		this.key = __key;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/06/18
	 */
	@Override
	public String key()
	{
		return this.key;
	}
	
	/**
	 * Checks if this is a trace point object.
	 * 
	 * @param __object The object to check.
	 * @return As a trace point if this is one.
	 * @throws SpringMLECallError If this is not a trace point object.
	 * @since 2020/06/22
	 */
	static TracePointObject __trace(Object __object)
		throws SpringMLECallError
	{
		if (!(__object instanceof TracePointObject))
			throw new SpringMLECallError("Not a trace point.");
		
		return (TracePointObject)__object; 
	}
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/MLEDispatcher.java.



















































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.mle.AtomicShelf;
import cc.squirreljme.jvm.mle.DebugShelf;
import cc.squirreljme.jvm.mle.JarPackageShelf;
import cc.squirreljme.jvm.mle.MathShelf;
import cc.squirreljme.jvm.mle.ObjectShelf;
import cc.squirreljme.jvm.mle.ReferenceShelf;
import cc.squirreljme.jvm.mle.RuntimeShelf;
import cc.squirreljme.jvm.mle.TerminalShelf;
import cc.squirreljme.jvm.mle.ThreadShelf;
import cc.squirreljme.jvm.mle.TypeShelf;
import cc.squirreljme.vm.springcoat.exceptions.SpringVirtualMachineException;
import java.util.Map;
import java.util.TreeMap;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.MethodNameAndType;

/**
 * Not Described.
 *
 * @since 2020/06/18
 */
public enum MLEDispatcher
	implements MLEDispatcherKey
{
	/** {@link AtomicShelf}. */
	ATOMIC("cc/squirreljme/jvm/mle/AtomicShelf",
		MLEAtomic.values()),
	
	/** {@link DebugShelf}. */
	DEBUG("cc/squirreljme/jvm/mle/DebugShelf",
		MLEDebug.values()),
	
	/** {@link JarPackageShelf}. */
	JAR_PACKAGE("cc/squirreljme/jvm/mle/JarPackageShelf",
		MLEJarPackage.values()),
	
	/** {@link MathShelf}. */
	MATH("cc/squirreljme/jvm/mle/MathShelf",
		MLEMath.values()),
	
	/** {@link ObjectShelf}. */
	OBJECT("cc/squirreljme/jvm/mle/ObjectShelf",
		MLEObject.values()),
	
	/** {@link ReferenceShelf}. */
	REFERENCE("cc/squirreljme/jvm/mle/ReferenceShelf",
		MLEReference.values()),
	
	/** {@link RuntimeShelf}. */
	RUNTIME("cc/squirreljme/jvm/mle/RuntimeShelf",
		MLERuntime.values()),
	
	/** {@link TerminalShelf}. */
	TERMINAL("cc/squirreljme/jvm/mle/TerminalShelf",
		MLETerminal.values()),
	
	/** {@link ThreadShelf}. */
	THREAD("cc/squirreljme/jvm/mle/ThreadShelf",
		MLEThread.values()),
	
	/** {@link TypeShelf}. */
	TYPE("cc/squirreljme/jvm/mle/TypeShelf",
		MLEType.values()),
	
	/* End. */
	;
	
	/** The function tree. */
	private static Map<String, Map<String, MLEDispatcherTarget>> _fnTree;
	
	/** The dispatcher key. */
	protected final String key;
	
	/** The functions. */
	private final MLEFunction[] _functions;
	
	static
	{
		Map<String, Map<String, MLEDispatcherTarget>> functionTree =
			new TreeMap<>();
		
		// Build the function tree
		for (MLEDispatcher dispatch : MLEDispatcher.values())
		{
			Map<String, MLEDispatcherTarget> subTree = new TreeMap<>();
			
			for (MLEFunction function : dispatch._functions)
				subTree.put(function.key(), function);
			
			functionTree.put(dispatch.key(), subTree);
		}
		
		MLEDispatcher._fnTree = functionTree;
	}
	
	/**
	 * Initializes the dispatcher info.
	 *
	 * @param __key The key.
	 * @param __functions Functions for the dispatcher.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/18
	 */
	MLEDispatcher(String __key, MLEFunction[] __functions)
		throws NullPointerException
	{
		if (__key == null || __functions == null)
			throw new NullPointerException("NARG");
		
		this.key = __key;
		this._functions = __functions;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/06/18
	 */
	@Override
	public String key()
	{
		return this.key;
	}
	
	/**
	 * Handles the dispatching of the native method.
	 *
	 * @param __thread The current thread this is acting under.
	 * @param __class The native class being called.
	 * @param __func The method being called.
	 * @param __args The arguments to the call.
	 * @return The resulting object returned by the dispatcher.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/05/30
	 */
	public static Object dispatch(SpringThreadWorker __thread,
		ClassName __class, MethodNameAndType __func, Object... __args)
		throws NullPointerException
	{
		if (__thread == null || __class == null)
			throw new NullPointerException("NARG");
		
		// Find the sub-tree
		Map<String, MLEDispatcherTarget> subTree = MLEDispatcher._fnTree.get(
			__class.toString());
		if (subTree == null)
			throw new SpringVirtualMachineException(String.format(
				"Unknown MLE Shelf: %s", __class));
		
		// Find the target function
		MLEDispatcherTarget target = subTree.get(__func.toString());
		if (target == null)
			throw new SpringVirtualMachineException(String.format(
				"Unknown MLE Shelf Function: %s::%s", __class, __func));
		
		// Call it
		return target.handle(__thread, __args);
	}
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/MLEDispatcherKey.java.





















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

/**
 * This interface is used to represent keys for the dispatcher.
 *
 * @since 2020/06/18
 */
public interface MLEDispatcherKey
{
	/**
	 * Returns the key for the item.
	 *
	 * @return The key for the item.
	 * @since 2020/06/18
	 */
	String key();
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/MLEDispatcherTarget.java.

























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

/**
 * This represents a target for MLE dispatching.
 *
 * @since 2020/06/18
 */
public interface MLEDispatcherTarget
{
	/**
	 * Handles the MLE call.
	 *
	 * @param __thread The thread to dispatch.
	 * @param __args The arguments.
	 * @return The result of the call.
	 * @since 2020/06/18
	 */
	Object handle(SpringThreadWorker __thread, Object... __args);
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/MLEFunction.java.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

/**
 * This represents a function in the MLE.
 *
 * @since 2020/06/18
 */
public interface MLEFunction
	extends MLEDispatcherKey, MLEDispatcherTarget
{
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/MLEJarPackage.java.















































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.mle.JarPackageShelf;
import cc.squirreljme.jvm.mle.brackets.JarPackageBracket;
import cc.squirreljme.vm.VMClassLibrary;
import cc.squirreljme.vm.springcoat.brackets.JarPackageObject;
import cc.squirreljme.vm.springcoat.brackets.TracePointObject;
import cc.squirreljme.vm.springcoat.exceptions.SpringMLECallError;
import cc.squirreljme.vm.springcoat.exceptions.SpringVirtualMachineException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import net.multiphasicapps.classfile.MethodDescriptor;

/**
 * Functions for {@link JarPackageShelf}.
 *
 * @since 2020/06/18
 */
public enum MLEJarPackage
	implements MLEFunction
{
	/** {@link JarPackageShelf#classPath()}. */
	CLASS_PATH("classPath:()[Lcc/squirreljme/jvm/mle/brackets/" +
		"JarPackageBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			VMClassLibrary[] springPath = __thread.machine.classloader
				.classPath();
		
			// Wrap the classpath in package objects
			int n = springPath.length;
			SpringObject[] rv = new SpringObject[n];
			for (int i = 0; i < n; i++)
				rv[i] = new JarPackageObject(springPath[i]);
			
			// Wrap
			return __thread.asVMObjectArray(__thread.resolveClass(
				"[Lcc/squirreljme/jvm/mle/brackets/JarPackageBracket;"),
				rv);
		}
	},
	
	/** {@link JarPackageShelf#openResource(JarPackageBracket, String)}. */
	OPEN_RESOURCE("openResource:(Lcc/squirreljme/jvm/mle/brackets/" +
		"JarPackageBracket;Ljava/lang/String;)Ljava/io/InputStream;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			JarPackageObject jar = MLEJarPackage.__jarObject(__args[0]);
			
			String rcName = __thread.<String>asNativeObject(
				String.class, __args[1]);
			if (rcName == null)
				throw new SpringMLECallError("Null resource string.");
			
			// Locate the resource
			try (InputStream in = jar.library().resourceAsStream(rcName))
			{
				// Not found
				if (in == null)
					return SpringNullObject.NULL;
				
				// Copy everything to the a byte array, since it is easier to
				// handle resources without juggling special resource streams
				// and otherwise
				try (ByteArrayOutputStream baos = new ByteArrayOutputStream(
					Math.max(1024, in.available())))
				{
					// Copy all the data
					byte[] copy = new byte[4096];
					for (;;)
					{
						int rc = in.read(copy);
						
						if (rc < 0)
							break;
						
						baos.write(copy, 0, rc);
					}
					
					// Use this as the stream input
					return __thread.newInstance(__thread.loadClass(
						"java/io/ByteArrayInputStream"),
						new MethodDescriptor("([B)V"),
						__thread.asVMObject(baos.toByteArray()));
				}
			}
			
			// Could not read it
			catch (IOException e)
			{
				throw new SpringVirtualMachineException(
					"Failed to read resource", e);
			}
		}
	}
	
	/* End. */
	;
	
	/** The dispatch key. */
	protected final String key;
	
	/**
	 * Initializes the dispatcher info.
	 *
	 * @param __key The key.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/18
	 */
	MLEJarPackage(String __key)
		throws NullPointerException
	{
		if (__key == null)
			throw new NullPointerException("NARG");
		
		this.key = __key;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/06/18
	 */
	@Override
	public String key()
	{
		return this.key;
	}
	
	/**
	 * Checks if this is a {@link JarPackageObject}.
	 * 
	 * @param __object The object to check.
	 * @return As a jar if this is one.
	 * @throws SpringMLECallError If this is not a jar.
	 * @since 2020/06/22
	 */
	static JarPackageObject __jarObject(Object __object)
		throws SpringMLECallError
	{
		if (!(__object instanceof JarPackageObject))
			throw new SpringMLECallError("Not a JarPackageObject.");
		
		return (JarPackageObject)__object; 
	}
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/MLEMath.java.



























































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.mle.MathShelf;

/**
 * Functions for {@link MathShelf}.
 *
 * @since 2020/06/18
 */
public enum MLEMath
	implements MLEFunction
{
	/** {@link MathShelf#rawDoubleToLong(double)}. */
	RAW_DOUBLE_TO_LONG("rawDoubleToLong:(D)J")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return Double.doubleToRawLongBits((double)__args[0]);
		}
	},
	
	/** {@link MathShelf#rawFloatToInt(float)}. */
	RAW_FLOAT_TO_INT("rawFloatToInt:(F)I")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return Float.floatToRawIntBits((float)__args[0]);
		}
	},
	
	/** {@link MathShelf#rawIntToFloat(int)}. */
	RAW_INT_TO_FLOAT("rawIntToFloat:(I)F")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return Float.intBitsToFloat((int)__args[0]);
		}
	},
	
	/** {@link MathShelf#rawLongToDouble(long)}. */
	RAW_LONG_TO_DOUBLE("rawLongToDouble:(J)D")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return Double.longBitsToDouble((long)__args[0]);
		}
	},
	
	/* End. */
	;
	
	/** The dispatch key. */
	protected final String key;
	
	/**
	 * Initializes the dispatcher info.
	 *
	 * @param __key The key.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/18
	 */
	MLEMath(String __key)
		throws NullPointerException
	{
		if (__key == null)
			throw new NullPointerException("NARG");
		
		this.key = __key;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/06/18
	 */
	@Override
	public String key()
	{
		return this.key;
	}
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/MLEObject.java.





















































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.mle.ObjectShelf;
import cc.squirreljme.jvm.mle.brackets.TypeBracket;
import cc.squirreljme.vm.springcoat.exceptions.SpringMLECallError;
import net.multiphasicapps.classfile.MethodDescriptor;

/**
 * Functions for {@link MLEObject}.
 *
 * @since 2020/06/18
 */
public enum MLEObject
	implements MLEFunction
{
	/** {@link ObjectShelf#arrayCopy(boolean[], int, boolean[], int, int)}. */
	ARRAY_COPY_BOOLEAN("arrayCopy:([ZI[ZII)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/22
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			MLEObject.<SpringArrayObjectBoolean>__arrayCopy(
				SpringArrayObjectBoolean.class,
				__args[0], (int)__args[1],
				__args[2], (int)__args[3], (int)__args[4]);
			return null;
		}
	},
	
	/** {@link ObjectShelf#arrayCopy(byte[], int, byte[], int, int)}. */
	ARRAY_COPY_BYTE("arrayCopy:([BI[BII)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/22
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			MLEObject.<SpringArrayObjectByte>__arrayCopy(
				SpringArrayObjectByte.class,
				__args[0], (int)__args[1],
				__args[2], (int)__args[3], (int)__args[4]);
			return null;
		}
	},
	
	/** {@link ObjectShelf#arrayCopy(short[], int, short[], int, int)}. */
	ARRAY_COPY_SHORT("arrayCopy:([SI[SII)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/22
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			MLEObject.<SpringArrayObjectShort>__arrayCopy(
				SpringArrayObjectShort.class,
				__args[0], (int)__args[1],
				__args[2], (int)__args[3], (int)__args[4]);
			return null;
		}
	},
	
	/** {@link ObjectShelf#arrayCopy(char[], int, char[], int, int)}. */
	ARRAY_COPY_CHAR("arrayCopy:([CI[CII)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/22
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			MLEObject.<SpringArrayObjectChar>__arrayCopy(
				SpringArrayObjectChar.class,
				__args[0], (int)__args[1],
				__args[2], (int)__args[3], (int)__args[4]);
			return null;
		}
	},
	
	/** {@link ObjectShelf#arrayCopy(int[], int, int[], int, int)}. */
	ARRAY_COPY_INTEGER("arrayCopy:([II[III)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/22
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			MLEObject.<SpringArrayObjectInteger>__arrayCopy(
				SpringArrayObjectInteger.class,
				__args[0], (int)__args[1],
				__args[2], (int)__args[3], (int)__args[4]);
			return null;
		}
	},
	
	/** {@link ObjectShelf#arrayCopy(long[], int, long[], int, int)}. */
	ARRAY_COPY_LONG("arrayCopy:([JI[JII)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/22
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			MLEObject.<SpringArrayObjectLong>__arrayCopy(
				SpringArrayObjectLong.class,
				__args[0], (int)__args[1],
				__args[2], (int)__args[3], (int)__args[4]);
			return null;
		}
	},
	
	/** {@link ObjectShelf#arrayCopy(float[], int, float[], int, int)}. */
	ARRAY_COPY_FLOAT("arrayCopy:([FI[FII)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/22
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			MLEObject.<SpringArrayObjectFloat>__arrayCopy(
				SpringArrayObjectFloat.class,
				__args[0], (int)__args[1],
				__args[2], (int)__args[3], (int)__args[4]);
			return null;
		}
	},
	
	/** {@link ObjectShelf#arrayCopy(double[], int, double[], int, int)}. */
	ARRAY_COPY_DOUBLE("arrayCopy:([DI[DII)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/22
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			MLEObject.<SpringArrayObjectDouble>__arrayCopy(
				SpringArrayObjectDouble.class,
				__args[0], (int)__args[1],
				__args[2], (int)__args[3], (int)__args[4]);
			return null;
		}
	},
	
	/** {@link ObjectShelf#arrayLength(Object)}. */
	ARRAY_LENGTH("arrayLength:(Ljava/lang/Object;)I")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringObject object = MLEType.__notNullObject(__args[0]);
			
			if (object instanceof SpringArrayObject)
				return ((SpringArrayObject)object).length();
			
			return -1;
		}
	},
	
	/** {@link ObjectShelf#arrayNew(TypeBracket, int)}. */
	ARRAY_NEW( "arrayNew:(Lcc/squirreljme/jvm/mle/brackets/" +
		"TypeBracket;I)Ljava/lang/Object;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			int len = (int)__args[1];
			if (len < 0)
				throw new SpringMLECallError("Negative array size.");
			
			SpringClass type = MLEType.__type(__args[0]).getSpringClass();
			if (!type.isArray())
				throw new SpringMLECallError("Type not an array.");
			
			return __thread.allocateArray(type, len);
		}
	},
	
	/** {@link ObjectShelf#holdsLock(Thread, Object)}. */
	HOLDS_LOCK("holdsLock:(Ljava/lang/Thread;Ljava/lang/Object;)Z")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/27
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringThread vmThread = MLEThread.__vmThread(
				MLEThread.TO_VM_THREAD.handle(__thread, __args[0]))
				.getThread();
			SpringObject target = (SpringObject)__args[1];
			
			// Cannot be null
			if (target == null || target == SpringNullObject.NULL)
				throw new SpringMLECallError("Target object is null.");
			
			return target.monitor().isHeldBy(vmThread);
		}
	}, 
	
	/** {@link ObjectShelf#identityHashCode(Object)}. */
	IDENTITY_HASH_CODE("identityHashCode:(Ljava/lang/Object;)I")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringObject object = (SpringObject)__args[0];
			return System.identityHashCode(MLEType.__notNullObject(object));
		}
	},
	
	/** {@link ObjectShelf#newInstance(TypeBracket)}. */
	NEW_INSTANCE("newInstance:(Lcc/squirreljme/jvm/mle/brackets/" +
		"TypeBracket;)Ljava/lang/Object;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringClass type = MLEType.__type(__args[0]).getSpringClass();
			
			if (type.isArray())
				throw new SpringMLECallError("Cannot newInstance array");
			
			return __thread.newInstance(type, new MethodDescriptor("()V"));
		}
	},
	
	/** {@link ObjectShelf#notify(Object, boolean)}. */
	NOTIFY("notify:(Ljava/lang/Object;Z)I")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/22
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringObject target = MLEType.__notNullObject(__args[0]);
			boolean notifyAll = (int)__args[1] != 0; 
			
			// Signal the monitor
			return target.monitor().monitorNotify(__thread.thread, notifyAll);
		}
	},
	
	/** {@link ObjectShelf#wait(Object, long, int)}. */
	WAIT("wait:(Ljava/lang/Object;JI)I")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/22
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringObject target = MLEType.__notNullObject(__args[0]);
			long ms = (long)__args[1];
			int ns = (int)__args[2];
			
			return target.monitor().monitorWait(__thread.thread, ms, ns);
		}
	}, 
	
	/* End. */
	;
	
	/** The dispatch key. */
	protected final String key;
	
	/**
	 * Initializes the dispatcher info.
	 *
	 * @param __key The key.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/18
	 */
	MLEObject(String __key)
		throws NullPointerException
	{
		if (__key == null)
			throw new NullPointerException("NARG");
		
		this.key = __key;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/06/18
	 */
	@Override
	public String key()
	{
		return this.key;
	}
	
	/**
	 * Copies the given array.
	 * 
	 * @param <A> The SpringCoat array type.
	 * @param __classy The class type.
	 * @param __src The source array.
	 * @param __srcOff The source offset.
	 * @param __dest The destination array.
	 * @param __destOff The destination offset.
	 * @param __len The length.
	 * @throws SpringMLECallError If the input is not valid.
	 * @since 2020/06/22
	 */
	@SuppressWarnings("SuspiciousSystemArraycopy")
	static <A extends SpringArrayObject> void __arrayCopy(
		Class<A> __classy, Object __src, int __srcOff,
		Object __dest, int __destOff, int __len)
		throws SpringMLECallError
	{
		// Wrong array type
		if (!__classy.isInstance(__src) ||
			!__classy.isInstance(__dest))
			throw new SpringMLECallError("Null array.");
		
		if (__srcOff < 0 || __destOff < 0 || __len < 0)
			throw new SpringMLECallError("Negative offset or length.");
		
		// Try to copy
		try
		{
			System.arraycopy(((SpringArrayObject)__src).array(), __srcOff,
				((SpringArrayObject)__dest).array(), __destOff, __len);
		}
		
		// Not a valid copy
		catch (ArrayStoreException|IndexOutOfBoundsException|
			NullPointerException e)
		{
			throw new SpringMLECallError("Invalid copy.", e);
		}
	}
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/MLEReference.java.



































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.mle.ReferenceShelf;
import cc.squirreljme.jvm.mle.brackets.RefLinkBracket;
import cc.squirreljme.vm.springcoat.brackets.RefLinkObject;
import cc.squirreljme.vm.springcoat.exceptions.SpringMLECallError;

/**
 * Functions for {@link ReferenceShelf}.
 *
 * @since 2020/06/18
 */
public enum MLEReference
	implements MLEFunction
{
	/** {@link ReferenceShelf#deleteLink(RefLinkBracket)}. */
	DELETE_LINK("deleteLink:(Lcc/squirreljme/jvm/mle/brackets/" +
		"RefLinkBracket;)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/29
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			// Check it, but otherwise do nothing
			MLEReference.__refLink(__args[0]);
			
			return null;
		}
	},
	
	/** {@link ReferenceShelf#linkGetNext(RefLinkBracket)}. */
	LINK_GET_NEXT("linkGetNext:(Lcc/squirreljme/jvm/mle/brackets/" +
		"RefLinkBracket;)Lcc/squirreljme/jvm/mle/brackets/RefLinkBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/29
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return MLEReference.__refLink(__args[0]).getNext();
		}
	},
	
	/** {@link ReferenceShelf#linkGetObject(RefLinkBracket)}. */
	LINK_GET_OBJECT("linkGetObject:(Lcc/squirreljme/jvm/mle/brackets/" +
		"RefLinkBracket;)Ljava/lang/Object;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return MLEReference.__refLink(__args[0]).getObject();
		}
	},
	
	/** {@link ReferenceShelf#linkGetPrev(RefLinkBracket)}. */
	LINK_GET_PREV("linkGetPrev:(Lcc/squirreljme/jvm/mle/brackets/" +
		"RefLinkBracket;)Lcc/squirreljme/jvm/mle/brackets/RefLinkBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/29
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return MLEReference.__refLink(__args[0]).getPrev();
		}
	},
	
	/** {@link ReferenceShelf#linkSetNext(RefLinkBracket, RefLinkBracket)}. */
	LINK_SET_NEXT("linkSetNext:(Lcc/squirreljme/jvm/mle/brackets/" +
		"RefLinkBracket;Lcc/squirreljme/jvm/mle/brackets/RefLinkBracket;)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/29
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			MLEReference.__refLink(__args[0]).setNext(
				MLEReference.__refLink(__args[1]));
			return null;
		}
	},
	
	/** {@link ReferenceShelf#linkSetObject(RefLinkBracket, Object)}. */
	LINK_SET_OBJECT("linkSetObject:(Lcc/squirreljme/jvm/mle/brackets/" +
		"RefLinkBracket;Ljava/lang/Object;)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			MLEReference.__refLink(__args[0])
				.setObject((SpringObject)__args[1]);
			return null;
		}
	},
	
	/** {@link ReferenceShelf#linkSetPrev(RefLinkBracket, RefLinkBracket)}. */
	LINK_SET_PREV("linkSetPrev:(Lcc/squirreljme/jvm/mle/brackets/" +
		"RefLinkBracket;Lcc/squirreljme/jvm/mle/brackets/RefLinkBracket;)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/29
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			MLEReference.__refLink(__args[0]).setPrev(
				MLEReference.__refLink(__args[1]));
			return null;
		}
	},
	
	/** {@link ReferenceShelf#newLink()}. */
	NEW_LINK("newLink:()Lcc/squirreljme/jvm/mle/brackets/" +
		"RefLinkBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return new RefLinkObject();
		}
	},
	
	/** {@link ReferenceShelf#objectGet(Object)}. */
	OBJECT_GET("objectGet:(Ljava/lang/Object;)" +
		"Lcc/squirreljme/jvm/mle/brackets/RefLinkBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringObject object = (SpringObject)__args[0];
			if (!(object instanceof SpringSimpleObject))
				throw new SpringMLECallError("Invalid object"); 
			
			return object.refLink().get();
		}
	},
	
	/** {@link ReferenceShelf#objectSet(Object, RefLinkBracket)}. */
	OBJECT_SET("objectSet:(Ljava/lang/Object;" +
		"Lcc/squirreljme/jvm/mle/brackets/RefLinkBracket;)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringObject object = (SpringObject)__args[0];
			if (!(object instanceof SpringSimpleObject))
				throw new SpringMLECallError("Invalid object"); 
			
			object.refLink().set(MLEReference.__refLink(__args[1]));
			return null;
		}
	}
	
	/* End. */
	;
	
	/** The dispatch key. */
	protected final String key;
	
	/**
	 * Initializes the dispatcher info.
	 *
	 * @param __key The key.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/18
	 */
	MLEReference(String __key)
		throws NullPointerException
	{
		if (__key == null)
			throw new NullPointerException("NARG");
		
		this.key = __key;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/06/18
	 */
	@Override
	public String key()
	{
		return this.key;
	}
	
	/**
	 * Checks if this is a {@link RefLinkObject}.
	 * 
	 * @param __object The object to check.
	 * @return As a {@link RefLinkObject} if this is one.
	 * @throws SpringMLECallError If this is not a {@link RefLinkObject}.
	 * @since 2020/06/28
	 */
	static RefLinkObject __refLink(Object __object)
		throws SpringMLECallError
	{
		if (!(__object instanceof RefLinkObject))
			throw new SpringMLECallError("Not a RefLinkObject.");
		
		return (RefLinkObject)__object; 
	}
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/MLERuntime.java.









































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.mle.RuntimeShelf;
import cc.squirreljme.jvm.mle.constants.BuiltInEncodingType;
import cc.squirreljme.jvm.mle.constants.BuiltInLocaleType;
import cc.squirreljme.jvm.mle.constants.VMDescriptionType;
import cc.squirreljme.jvm.mle.constants.VMStatisticType;
import cc.squirreljme.jvm.mle.constants.VMType;
import cc.squirreljme.runtime.cldc.SquirrelJME;
import cc.squirreljme.runtime.cldc.debug.Debugging;
import cc.squirreljme.runtime.cldc.lang.LineEndingUtils;
import cc.squirreljme.vm.springcoat.exceptions.SpringMLECallError;

/**
 * Functions for {@link MLERuntime}.
 *
 * @since 2020/06/18
 */
public enum MLERuntime
	implements MLEFunction
{
	/** {@link RuntimeShelf#currentTimeMillis()}. */
	CURRENT_TIME_MILLIS("currentTimeMillis:()J")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return System.currentTimeMillis();
		}
	},
	
	/** {@link RuntimeShelf#encoding()}. */
	ENCODING("encoding:()I")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return BuiltInEncodingType.UTF8;
		}
	},
	
	/** {@link RuntimeShelf#exit(int)}. */
	EXIT("exit:(I)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			__thread.machine.exit((int)__args[0]);
			return null;
		}
	},
	
	/** {@link RuntimeShelf#lineEnding()}. */
	LINE_ENDING("lineEnding:()I")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return LineEndingUtils.toType(
				System.getProperty("line.separator"));
		}
	},
	
	/** {@link RuntimeShelf#locale()}. */
	LOCALE("locale:()I")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@SuppressWarnings("SwitchStatementWithTooFewBranches")
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			switch (System.getProperty("user.country"))
			{
				case "US":
					switch (System.getProperty("user.language"))
					{
						case "en":
							return BuiltInLocaleType.ENGLISH_US;
					}
					return BuiltInLocaleType.UNSPECIFIED;
				
				default:
					return BuiltInLocaleType.UNSPECIFIED;
			}
		}
	},
	
	/** {@link RuntimeShelf#nanoTime()}. */
	NANO_TIME("nanoTime:()J")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return System.nanoTime();
		}
	},
	
	/** {@link RuntimeShelf#systemProperty(String)}. */
	SYSTEM_PROPERTY("systemProperty:(Ljava/lang/String;)" +
		"Ljava/lang/String;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			String key = __thread
				.<String>asNativeObject(String.class, __args[0]);
			
			if (key == null)
				throw new SpringMLECallError("Null key.");
			
			return __thread.machine._sysproperties.get(key);
		}
	},
	
	/** {@link RuntimeShelf#vmDescription(int)}. */
	VM_DESCRIPTION("vmDescription:(I)Ljava/lang/String;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			int index = (int)__args[0];
			if (index < 0 || index >= VMDescriptionType.NUM_TYPES)
				throw new SpringMLECallError(
					"Index out of range: " + index);
			
			switch (index)
			{
				case VMDescriptionType.EXECUTABLE_PATH:
					return null;
				
				case VMDescriptionType.OS_ARCH:
					return "springcoat/" + System.getProperty("os.arch");
					
				case VMDescriptionType.OS_NAME:
					return System.getProperty("os.name");
				
				case VMDescriptionType.OS_VERSION:
					return System.getProperty("os.version");
				
				case VMDescriptionType.VM_EMAIL:
					return "xer@multiphasicapps.net";
					
				case VMDescriptionType.VM_NAME:
					return "SquirrelJME SpringCoat";
				
				case VMDescriptionType.VM_URL:
					return "https://squirreljme.cc/";
					
				case VMDescriptionType.VM_VENDOR:
					return "Stephanie Gawroriski";
				
				case VMDescriptionType.VM_VERSION:
					return SquirrelJME.RUNTIME_VERSION;
			}
			
			return null;
		}
	},
	
	/** {@link RuntimeShelf#vmStatistic(int)}. */
	VM_STATISTIC("vmStatistic:(I)J")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			int index = (int)__args[0];
			if (index < 0 || index >= VMStatisticType.NUM_STATISTICS)
				throw new SpringMLECallError(
					"Index out of range: " + index);
			
			switch (index)
			{
				case VMStatisticType.MEM_FREE:
					return Runtime.getRuntime().freeMemory();
					
				case VMStatisticType.MEM_MAX:
					return Runtime.getRuntime().maxMemory();
				
				case VMStatisticType.MEM_USED:
					return Runtime.getRuntime().totalMemory();
			}
			
			return 0L;
		}
	},
	
	/** {@link RuntimeShelf#vmType()}. */
	VM_TYPE("vmType:()I")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return VMType.SPRINGCOAT;
		}
	},
	
	/* End. */
	;
	
	/** The dispatch key. */
	protected final String key;
	
	/**
	 * Initializes the dispatcher info.
	 *
	 * @param __key The key.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/18
	 */
	MLERuntime(String __key)
		throws NullPointerException
	{
		if (__key == null)
			throw new NullPointerException("NARG");
		
		this.key = __key;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/06/18
	 */
	@Override
	public String key()
	{
		return this.key;
	}
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/MLETerminal.java.































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.mle.TerminalShelf;
import cc.squirreljme.jvm.mle.constants.StandardPipeType;
import cc.squirreljme.vm.springcoat.exceptions.SpringMLECallError;
import java.io.IOException;
import java.io.OutputStream;

/**
 * Functions for {@link MLETerminal}.
 *
 * @since 2020/06/18
 */
public enum MLETerminal
	implements MLEFunction
{
	/** {@link TerminalShelf#flush(int)}. */
	FLUSH("flush:(I)I")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@SuppressWarnings("resource")
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			try
			{
				MLETerminal.__fdOutput((int)__args[0]).flush();
				return 1;
			}
			catch (IllegalArgumentException|IOException e)
			{
				return -1;
			}
		}
	},
	
	/** {@link TerminalShelf#write(int, int)}. */
	WRITE_BYTE("write:(II)I")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@SuppressWarnings("resource")
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			try
			{
				MLETerminal.__fdOutput((int)__args[0]).write((int)__args[1]);
				return 1;
			}
			catch (IllegalArgumentException|IOException e)
			{
				return -1;
			}
		}
	},
	
	/** {@link TerminalShelf#write(int, byte[], int, int)}. */
	WRITE_BYTES("write:(I[BII)I")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@SuppressWarnings("resource")
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			if (!(__args[1] instanceof SpringArrayObjectByte))
				throw new SpringMLECallError("Not a byte array.");
			
			SpringArrayObjectByte buf = (SpringArrayObjectByte)__args[1];
			int off = (int)__args[2];
			int len = (int)__args[3];
			
			// Perform basic bounds checking here
			if (off < 0 || len < 0 || (off + len) > buf.length)
				throw new SpringMLECallError("Index out of bounds.");
			
			try
			{
				MLETerminal.__fdOutput((int)__args[0])
					.write(buf.array(), off, len);
				return len;
			}
			catch (IllegalArgumentException|IOException e)
			{
				return -1;
			}
		}
	},
	
	/* End. */
	;
	
	/** The dispatch key. */
	protected final String key;
	
	/**
	 * Initializes the dispatcher info.
	 *
	 * @param __key The key.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/18
	 */
	MLETerminal(String __key)
		throws NullPointerException
	{
		if (__key == null)
			throw new NullPointerException("NARG");
		
		this.key = __key;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/06/18
	 */
	@Override
	public String key()
	{
		return this.key;
	}
	
	/**
	 * Returns the output stream for the given descriptor.
	 *
	 * @param __fd The file descriptor.
	 * @return The output stream for it.
	 * @throws SpringMLECallError If the descriptor is not valid.
	 * @since 2020/06/13
	 */
	static OutputStream __fdOutput(int __fd)
		throws SpringMLECallError
	{
		switch (__fd)
		{
			case StandardPipeType.STDOUT:	return System.out;
			case StandardPipeType.STDERR:	return System.err;
			
			default:
				throw new SpringMLECallError("Unknown FD: " + __fd);
		}
	}
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/MLEThread.java.



































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.mle.ThreadShelf;
import cc.squirreljme.jvm.mle.brackets.VMThreadBracket;
import cc.squirreljme.vm.springcoat.brackets.VMThreadObject;
import cc.squirreljme.vm.springcoat.exceptions.SpringMLECallError;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.MethodNameAndType;

/**
 * Functions for {@link ThreadShelf}.
 *
 * @since 2020/06/18
 */
public enum MLEThread
	implements MLEFunction
{
	/** {@link ThreadShelf#aliveThreadCount(boolean, boolean)}. */
	ALIVE_THREAD_COUNT("aliveThreadCount:(ZZ)I")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			boolean includeMain = ((int)__args[0] != 0);
			boolean includeDaemon = ((int)__args[1] != 0);
			
			// Count every thread
			int count = 0;
			SpringMachine machine = __thread.machine;
			synchronized (machine)
			{
				for (SpringThread thread : machine.getThreads())
				{
					boolean isMain = thread.isMain();
					boolean isDaemon = thread.isDaemon();
					
					if ((includeMain && isMain) ||
						(includeDaemon && isDaemon) ||
						(!isMain && !isDaemon))
						count++;
				}
			}
			
			return count;
		}
	},
	
	/** {@link ThreadShelf#createVMThread(Thread)}. */
	CREATE_VM_THREAD( "createVMThread:(Ljava/lang/Thread;)Lcc/" +
		"squirreljme/jvm/mle/brackets/VMThreadBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringSimpleObject javaThread = MLEThread.__javaThread(__thread,
				__args[0]);
			
			// Find the thread which the given passed object is bound to, this
			// is the target thread
			SpringThread target = null;
			SpringMachine machine = __thread.machine;
			synchronized (machine)
			{
				// Search through every thread
				SpringThread[] threads = machine.getThreads();
				for (SpringThread thread : threads)
				{
					SpringObject instance;
					try
					{
						instance = thread.threadInstance();
					}
					catch (IllegalStateException ignored)
					{
						continue;
					}
					
					// If this is the thread for this, then use that!
					if (javaThread == instance)
					{
						target = thread;
						break;
					}
				}
				
				// If there is exactly one thread, we can rather get into a bit
				// of a loop where our main thread is created outside of normal
				// means by the VM and not by any other thread.. but only if
				// this initial thread has no actual instance
				if (threads.length == 1 && !threads[0].hasThreadInstance())
					target = threads[0];
				
				// No actual thread exists that the object is bound to, so
				// oops! We need to actually create one here and bind it
				// accordingly!
				if (target == null)
					target = machine.createThread(null, false);
			}
			
			// Create object with this attached thread
			VMThreadObject vmThread = new VMThreadObject(target);
			
			// The thread gets these as well
			target.setThreadInstance(javaThread);
			target.setVMThread(vmThread);
			
			return vmThread;
		}
	},
	
	/** {@link ThreadShelf#currentExitCode()}. */
	CURRENT_EXIT_CODE("currentExitCode:()I")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return __thread.machine._exitcode;
		}
	},
	
	/** {@link ThreadShelf#currentJavaThread()}. */
	CURRENT_JAVA_THREAD("currentJavaThread:()Ljava/lang/Thread;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return __thread.thread.threadInstance();
		}
	},
	
	/** {@link ThreadShelf#javaThreadClearInterrupt(Thread)}. */
	JAVA_THREAD_CLEAR_INTERRUPT("javaThreadClearInterrupt:" +
		"(Ljava/lang/Thread;)Z")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/28
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringFieldStorage field = MLEThread.__javaThread(__thread,
				__args[0]).fieldByNameAndType(false, 
				"_interrupted", "Z");
			
			// Get and clear the field value
			Object old = field.get();
			field.set(false);
			return old;
		}
	}, 
	
	/** {@link ThreadShelf#javaThreadFlagStarted(Thread)}. */
	JAVA_THREAD_FLAG_STARTED("javaThreadFlagStarted:(Ljava/lang/" +
		"Thread;)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			// Just set the started field to true
			MLEThread.__javaThread(__thread, __args[0]).fieldByNameAndType(
				false, "_started", "Z").set(true);
			return null;
		}
	},
	
	/** {@link ThreadShelf#javaThreadIsStarted(Thread)}. */
	JAVA_THREAD_IS_STARTED("javaThreadIsStarted:(Ljava/lang/Thread;)Z")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			// Just get the state of the given field
			return MLEThread.__javaThread(__thread, __args[0])
				.fieldByNameAndType(false, 
					"_started", "Z").get();
		}
	},
	
	/** {@link ThreadShelf#javaThreadRunnable(Thread)}. */
	JAVA_THREAD_RUNNABLE("javaThreadRunnable:(Ljava/lang/Thread;)" +
		"Ljava/lang/Runnable;")
	{
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			// Just get the state of the given field
			return MLEThread.__javaThread(__thread, __args[0])
				.fieldByNameAndType(
				false, "_runnable",
				"Ljava/lang/Runnable;").get();
		}
	},
	
	/** {@link ThreadShelf#javaThreadSetAlive(Thread, boolean)}. */
	JAVA_THREAD_SET_ALIVE("javaThreadSetAlive:(Ljava/lang/Thread;Z)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			// Just set the started field to true
			MLEThread.__javaThread(__thread, __args[0]).fieldByNameAndType(
				false, "_isAlive", "Z")
				.set((int)__args[1] != 0);
			return null;
		}
	},
	
	/** {@link ThreadShelf#runProcessMain()}. */
	RUN_PROCESS_MAIN("runProcessMain:()V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			__thread.runProcessMain();
			return null;
		}
	},
	
	/** {@link ThreadShelf#setCurrentExitCode(int)}. */
	SET_CURRENT_EXIT_CODE("setCurrentExitCode:(I)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/27
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			int exitCode = (int)__args[0];
			
			__thread.machine.setExitCode(exitCode);
			
			return null;
		}
	}, 
	
	/** {@link ThreadShelf#sleep(int, int)}. */
	SLEEP("sleep:(II)Z")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			int ms = (int)__args[0];
			int ns = (int)__args[1];
			
			if (ms < 0 || ns < 0 || ns > 1000000000)
				throw new SpringMLECallError("Out of range time.");
			
			if (ms == 0 && ns == 0)
				Thread.yield();
			else
				try
				{
					Thread.sleep(ms, ns);
				}
				catch (InterruptedException ignored)
				{
					return true;
				}
			
			return false;
		}
	},
	
	/** {@link ThreadShelf#toJavaThread(VMThreadBracket)}. */
	TO_JAVA_THREAD("toJavaThread:(Lcc/squirreljme/jvm/mle/" +
		"brackets/VMThreadBracket;)Ljava/lang/Thread;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/29
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			VMThreadObject vmThread = MLEThread.__vmThread(__args[0]);
			
			return vmThread.getThread().threadInstance();
		}
	}, 
	
	/** {@link ThreadShelf#toVMThread(Thread)}. */
	TO_VM_THREAD("toVMThread:(Ljava/lang/Thread;)Lcc/squirreljme/" +
		"jvm/mle/brackets/VMThreadBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return MLEThread.__javaThread(__thread, __args[0]).fieldByField(
				__thread.resolveClass("java/lang/Thread")
				.lookupField(false, "_vmThread",
				"Lcc/squirreljme/jvm/mle/brackets/VMThreadBracket;"))
				.get();
		}
	},
	
	/** {@link ThreadShelf#vmThreadId(VMThreadBracket)}. */
	VM_THREAD_ID("vmThreadId:(Lcc/squirreljme/jvm/mle/brackets/" +
		"VMThreadBracket;)I")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return MLEThread.__vmThread(__args[0]).getThread().id;
		}
	},
	
	/** {@link ThreadShelf#vmThreadInterrupt(VMThreadBracket)}. */ 
	VM_THREAD_INTERRUPT("vmThreadInterrupt:(Lcc/squirreljme/jvm/mle/" +
		"brackets/VMThreadBracket;)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/22
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			VMThreadObject vmThread = MLEThread.__vmThread(__args[0]);
			
			// Send an interrupt to the thread
			vmThread.getThread().hardInterrupt();
			
			return null;
		}
	},
	
	/** {@link ThreadShelf#vmThreadIsMain(VMThreadBracket)}. */
	VM_THREAD_IS_MAIN("vmThreadIsMain:(Lcc/squirreljme/jvm/mle/" +
		"brackets/VMThreadBracket;)Z")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return MLEThread.__vmThread(__args[0]).getThread().isMain();
		}
	},
	
	/** {@link ThreadShelf#vmThreadSetPriority(VMThreadBracket, int)}. */
	VM_THREAD_SET_PRIORITY("vmThreadSetPriority:(Lcc/squirreljme/" +
		"jvm/mle/brackets/VMThreadBracket;I)V")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/29
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringThread thread = MLEThread.__vmThread(__args[0]).getThread();
			int priority = (int)__args[1];
			
			if (priority < Thread.MIN_PRIORITY ||
				priority > Thread.MAX_PRIORITY)
				throw new SpringMLECallError(
					"Thread priority out of range.");
			
			// Try to set the priority
			try
			{
				thread._worker.setPriority(priority);
			}
			catch (IllegalArgumentException|SecurityException e)
			{
				throw new SpringMLECallError(
					"Could not set priority.", e);
			}
			
			return null;
		}
	}, 
	
	/** {@link ThreadShelf#vmThreadStart(VMThreadBracket)}. */
	VM_THREAD_START("vmThreadStart:(Lcc/squirreljme/jvm/mle/brackets/" +
		"VMThreadBracket;)Z")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringThread target = MLEThread.__vmThread(__args[0]).getThread();
			
			// Create worker for thread and start it
			SpringThreadWorker worker = new SpringThreadWorker(
				__thread.machine, target, false);
			
			// Enter the base setup frame
			target.enterFrame(worker.loadClass(MLEThread._START_CLASS)
				.lookupMethod(true, MLEThread._BASE_THREAD_METHOD));
			
			// Try to start it
			try
			{
				worker.start();
				return true;
			}
			catch (IllegalThreadStateException ignored)
			{
				return false;
			}
		}
	},
	
	/** {@link ThreadShelf#waitForUpdate(int)}. */
	WAIT_FOR_UPDATE("waitForUpdate:(I)Z")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/29
		 */
		@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			int ms = (int)__args[0];
			
			if (ms < 0)
				throw new SpringMLECallError("Negative milliseconds");
			
			// Waiting for nothing? just give up our slice
			if (ms == 0)
			{
				Thread.yield();
				return false;
			}
			
			// Wait until the monitor is hit
			SpringMachine machine = __thread.machine;
			synchronized (machine)
			{
				try
				{
					machine.wait(ms);
				}
				catch (InterruptedException e)
				{
					return true;
				}
			}
			
			// Assume not interrupted
			return false;
		}
	}, 
	
	/* End. */
	;
	
	/** The class which contains the thread starting point. */
	static final ClassName _START_CLASS =
		new ClassName("java/lang/__Start__");
	
	/** The method to enter for main threads. */
	static final MethodNameAndType _BASE_THREAD_METHOD =
		new MethodNameAndType("__base", "()V");
	
	/** The dispatch key. */
	protected final String key;
	
	/**
	 * Initializes the dispatcher info.
	 *
	 * @param __key The key.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/18
	 */
	MLEThread(String __key)
		throws NullPointerException
	{
		if (__key == null)
			throw new NullPointerException("NARG");
		
		this.key = __key;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/06/18
	 */
	@Override
	public String key()
	{
		return this.key;
	}
	
	/**
	 * Checks if this is a Java thread.
	 * 
	 * @param __thread The context thread.
	 * @param __object The object to check.
	 * @return The verified object.
	 * @throws SpringMLECallError If {@code __object} is {@code null} or is
	 * not an instance of {@link Throwable}.
	 * @since 2020/06/28
	 */
	static SpringSimpleObject __javaThread(SpringThreadWorker __thread,
		Object __object)
		throws SpringMLECallError
	{
		if (__thread == null)
			throw new NullPointerException("NARG");
		
		if (!(__object instanceof SpringSimpleObject))
			throw new SpringMLECallError("Not a Java Thread");
		
		SpringSimpleObject rv = (SpringSimpleObject)__object;
		if (!rv.type().isAssignableFrom(
			__thread.resolveClass("java/lang/Thread")))
			throw new SpringMLECallError("Not instance of Thread.");
		
		return rv;
	}
	
	/**
	 * Ensures that this is a {@link VMThreadObject}.
	 * 
	 * @param __object The object to check.
	 * @return As a {@link VMThreadObject}.
	 * @throws SpringMLECallError If this is not one.
	 * @since 2020/06/27
	 */
	static VMThreadObject __vmThread(Object __object)
		throws SpringMLECallError
	{
		if (!(__object instanceof VMThreadObject))
			throw new SpringMLECallError("Not a VMThreadObject.");
		
		return (VMThreadObject)__object; 
	}
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/MLEType.java.





























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.mle.TypeShelf;
import cc.squirreljme.jvm.mle.brackets.TypeBracket;
import cc.squirreljme.runtime.cldc.debug.Debugging;
import cc.squirreljme.vm.springcoat.brackets.JarPackageObject;
import cc.squirreljme.vm.springcoat.brackets.TypeObject;
import cc.squirreljme.vm.springcoat.exceptions.SpringClassNotFoundException;
import cc.squirreljme.vm.springcoat.exceptions.SpringMLECallError;
import java.util.Objects;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.MethodNameAndType;
import net.multiphasicapps.classfile.PrimitiveType;

/**
 * Functions for {@link TypeShelf}.
 *
 * @since 2020/06/18
 */
public enum MLEType
	implements MLEFunction
{
	/** {@link TypeShelf#binaryName(TypeBracket)}. */
	BINARY_NAME("binaryName:(Lcc/squirreljme/jvm/mle/brackets/" +
		"TypeBracket;)Ljava/lang/String;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/27
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return __thread.asVMObject(MLEType.__type(__args[0])
				.getSpringClass().name().binaryName().toString());
		}
	}, 
	
	/** {@link TypeShelf#binaryPackageName(TypeBracket)}. */
	BINARY_PACKAGE_NAME("binaryPackageName:(Lcc/squirreljme/jvm/" +
		"mle/brackets/TypeBracket;)Ljava/lang/String;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return __thread.asVMObject(MLEType.__type(__args[0])
				.getSpringClass().name().binaryName().inPackage()
				.toString());
		}
	},
	
	/** {@link TypeShelf#classToType(Class)}. */
	CLASS_TO_TYPE("classToType:(Ljava/lang/Class;)" +
		"Lcc/squirreljme/jvm/mle/brackets/TypeBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return MLEType.__simple(__args[0]).fieldByField(
				__thread.resolveClass(new ClassName("java/lang/Class"))
				.lookupField(false, "_type",
				"Lcc/squirreljme/jvm/mle/brackets/TypeBracket;")).get();
		}
	},
	
	/** {@link TypeShelf#component(TypeBracket)}. */
	COMPONENT("component:(Lcc/squirreljme/jvm/mle/brackets/" +
		"TypeBracket;)Lcc/squirreljme/jvm/mle/brackets/TypeBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/28
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringClass type = MLEType.__type(__args[0]).getSpringClass();
			
			if (!type.isArray())
				throw new SpringMLECallError("Not an array type.");
			
			return new TypeObject(type.componentType());
		}
	},
	
	/** {@link TypeShelf#componentRoot(TypeBracket)}. */
	COMPONENT_ROOT("componentRoot:(Lcc/squirreljme/jvm/mle/" +
		"brackets/TypeBracket;)Lcc/squirreljme/jvm/mle/brackets/TypeBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/28
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringClass type = MLEType.__type(__args[0]).getSpringClass();
			
			if (!type.isArray())
				throw new SpringMLECallError("Not an array type.");
			
			// Find the root component
			while (type.isArray())
				type = type.componentType();
			return new TypeObject(type);
		}
	},
	
	/** {@link TypeShelf#enumValues(TypeBracket)}. */
	ENUM_VALUES("enumValues:(Lcc/squirreljme/jvm/mle/" +
		"brackets/TypeBracket;)[Ljava/lang/Enum;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/28
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringClass type = MLEType.__type(__args[0]).getSpringClass();
			
			// Must be an enumeration
			if (!type.isEnum())
				throw new SpringMLECallError("Not an enumeration type");
			
			// Call the static values() method in the given class, it is
			// automatically generated by the Java compiler (it is synthetic)
			return __thread.invokeMethod(true, type.name(),
				new MethodNameAndType("values", 
					"()" + type.name().field().addDimensions(1)));
		}
	}, 
	
	/** {@link TypeShelf#equals(TypeBracket, TypeBracket)}. */
	EQUALS("equals:(Lcc/squirreljme/jvm/mle/brackets/TypeBracket;" +
		"Lcc/squirreljme/jvm/mle/brackets/TypeBracket;)Z")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return Objects.equals(
				MLEType.__type(__args[0]).getSpringClass(),
				MLEType.__type(__args[1]).getSpringClass());
		}
	},
	
	/** {@link TypeShelf#findType(String)}. */
	FIND_TYPE("findType:(Ljava/lang/String;)" +
		"Lcc/squirreljme/jvm/mle/brackets/TypeBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringObject name = MLEType.__notNullObject(__args[0]);
			
			try
			{
				return new TypeObject(__thread.loadClass(
					__thread.<String>asNativeObject(String.class, name)));
			}
			
			// Since the method returns null when not found, we want to return
			// this here
			catch (SpringClassNotFoundException e)
			{
				return null;
			}
		}
	},
	
	/** {@link TypeShelf#inJar(TypeBracket)}. */
	IN_JAR("inJar:(Lcc/squirreljme/jvm/mle/brackets/TypeBracket;)" +
		"Lcc/squirreljme/jvm/mle/brackets/JarPackageBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return new JarPackageObject(MLEType.__type(__args[0])
				.getSpringClass().inJar());
		}
	},
	
	/** {@link TypeShelf#interfaces(TypeBracket)}. */
	INTERFACES("interfaces:(Lcc/squirreljme/jvm/mle/brackets/" +
		"TypeBracket;)[Lcc/squirreljme/jvm/mle/brackets/TypeBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/29
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringClass type = MLEType.__type(__args[0]).getSpringClass();
			
			SpringClass[] interfaces = type.interfaceClasses();
			int n = interfaces.length;
			
			SpringObject[] rv = new SpringObject[n];
			for (int i = 0; i < n; i++)
				rv[i] = new TypeObject(interfaces[i]);
			
			return __thread.asVMObjectArray(__thread.resolveClass(
				"[Lcc/squirreljme/jvm/mle/brackets/TypeBracket;"), rv);
		}
	}, 
	
	/** {@link TypeShelf#isArray(TypeBracket)}. */
	IS_ARRAY("isArray:(Lcc/squirreljme/jvm/mle/brackets/TypeBracket;)Z")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return MLEType.__type(__args[0]).getSpringClass().isArray();
		}
	},
	
	/** {@link TypeShelf#isEnum(TypeBracket)}. */
	IS_ENUM("isEnum:(Lcc/squirreljme/jvm/mle/brackets/TypeBracket;)Z")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/28
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return MLEType.__type(__args[0]).getSpringClass().isEnum();
		}
	},
	
	/** {@link TypeShelf#isInterface(TypeBracket)}. */
	IS_INTERFACE("isInterface:(Lcc/squirreljme/jvm/mle/brackets/" +
		"TypeBracket;)Z")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return MLEType.__type(__args[0]).getSpringClass().flags()
				.isInterface();
		}
	},
	
	/** {@link TypeShelf#isPrimitive(TypeBracket)}. */
	IS_PRIMITIVE("isPrimitive:(Lcc/squirreljme/jvm/mle/brackets/" +
		"TypeBracket;)Z")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return MLEType.__type(__args[0]).getSpringClass().name()
				.isPrimitive();
		}
	},
	
	/** {@link TypeShelf#objectType(Object)}. */
	OBJECT_TYPE("objectType:(Ljava/lang/Object;)" +
		"Lcc/squirreljme/jvm/mle/brackets/TypeBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return new TypeObject(__thread.loadClass(
				MLEType.__notNullObject(__args[0]).type().name().toString()));
		}
	},
	
	/** {@link TypeShelf#runtimeName(TypeBracket)}. */
	RUNTIME_NAME("runtimeName:(Lcc/squirreljme/jvm/mle/brackets/" +
		"TypeBracket;)Ljava/lang/String;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return MLEType.__type(__args[0]).getSpringClass()
				.name().toRuntimeString();
		}
	},
	
	/** {@link TypeShelf#superClass(TypeBracket)}. */
	SUPER_CLASS("superClass:(Lcc/squirreljme/jvm/mle/brackets/" +
		"TypeBracket;)Lcc/squirreljme/jvm/mle/brackets/TypeBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			SpringClass superClass = MLEType.__type(__args[0]).getSpringClass()
				.superClass();
			
			if (superClass == null)
				return SpringNullObject.NULL;
			return new TypeObject(superClass);
		}
	},
	
	/** {@link TypeShelf#typeOfBoolean()}. */
	TYPE_OF_BOOLEAN("typeOfBoolean:()Lcc/squirreljme/jvm/mle/brackets/" +
		"TypeBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return new TypeObject(__thread.loadClass(
				ClassName.fromPrimitiveType(PrimitiveType.BOOLEAN)));
		}
	},
	
	/** {@link TypeShelf#typeOfByte()}. */
	TYPE_OF_BYTE("typeOfByte:()Lcc/squirreljme/jvm/mle/brackets/" +
		"TypeBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return new TypeObject(__thread.loadClass(
				ClassName.fromPrimitiveType(PrimitiveType.BYTE)));
		}
	},
	
	/** {@link TypeShelf#typeOfCharacter()}. */
	TYPE_OF_CHARACTER("typeOfCharacter:()Lcc/squirreljme/jvm/mle/" +
		"brackets/TypeBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return new TypeObject(__thread.loadClass(
				ClassName.fromPrimitiveType(PrimitiveType.CHARACTER)));
		}
	},
	
	/** {@link TypeShelf#typeOfDouble()}. */
	TYPE_OF_DOUBLE("typeOfDouble:()Lcc/squirreljme/jvm/mle/brackets/" +
		"TypeBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return new TypeObject(__thread.loadClass(
				ClassName.fromPrimitiveType(PrimitiveType.DOUBLE)));
		}
	},
	
	/** {@link TypeShelf#typeOfFloat()}. */
	TYPE_OF_FLOAT("typeOfFloat:()Lcc/squirreljme/jvm/mle/brackets/" +
		"TypeBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return new TypeObject(__thread.loadClass(
				ClassName.fromPrimitiveType(PrimitiveType.FLOAT)));
		}
	},
	
	/** {@link TypeShelf#typeOfInteger()}. */
	TYPE_OF_INTEGER("typeOfInteger:()Lcc/squirreljme/jvm/mle/brackets/" +
		"TypeBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return new TypeObject(__thread.loadClass(
				ClassName.fromPrimitiveType(PrimitiveType.INTEGER)));
		}
	},
	
	/** {@link TypeShelf#typeOfLong()}. */
	TYPE_OF_LONG("typeOfLong:()Lcc/squirreljme/jvm/mle/brackets/" +
		"TypeBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return new TypeObject(__thread.loadClass(
				ClassName.fromPrimitiveType(PrimitiveType.LONG)));
		}
	},
	
	/** {@link TypeShelf#typeOfShort()}. */
	TYPE_OF_SHORT("typeOfShort:()Lcc/squirreljme/jvm/mle/brackets/" +
		"TypeBracket;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return new TypeObject(__thread.loadClass(
				ClassName.fromPrimitiveType(PrimitiveType.SHORT)));
		}
	},
	
	/** {@link TypeShelf#typeToClass(TypeBracket)}. */
	TYPE_TO_CLASS("typeToClass:(Lcc/squirreljme/jvm/mle/brackets/" +
		"TypeBracket;)Ljava/lang/Class;")
	{
		/**
		 * {@inheritDoc}
		 * @since 2020/06/18
		 */
		@Override
		public Object handle(SpringThreadWorker __thread, Object... __args)
		{
			return __thread.asVMObject(MLEType.__type(__args[0])
				.getSpringClass());
		}
	},
	
	/* End. */
	;
	
	/** The dispatch key. */
	protected final String key;
	
	/**
	 * Initializes the dispatcher info.
	 *
	 * @param __key The key.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/18
	 */
	MLEType(String __key)
		throws NullPointerException
	{
		if (__key == null)
			throw new NullPointerException("NARG");
		
		this.key = __key;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/06/18
	 */
	@Override
	public String key()
	{
		return this.key;
	}
	
	/**
	 * Checks if the object is {@code null}.
	 * 
	 * @param __object The object to check.
	 * @return The object.
	 * @throws SpringMLECallError If is null.
	 * @since 2020/06/22
	 */
	static SpringObject __notNullObject(Object __object)
		throws SpringMLECallError
	{
		if (__object == null || SpringNullObject.NULL == __object)
			throw new SpringMLECallError("Null object.");
		
		return (SpringObject)__object;
	}
	
	/**
	 * Checks if this is a simple object.
	 * 
	 * @param __object The object to check.
	 * @return The simple object.
	 * @throws SpringMLECallError If not a simple object.
	 * @since 2020/06/22
	 */
	static SpringSimpleObject __simple(Object __object)
	{
		if (!(__object instanceof SpringSimpleObject))
			throw new SpringMLECallError("Not a SpringSimpleObject.");
		
		return (SpringSimpleObject)__object; 
	}
	
	/**
	 * Checks if this is a {@link TypeObject}.
	 * 
	 * @param __object The object to check.
	 * @return As a {@link TypeObject} if this is one.
	 * @throws SpringMLECallError If this is not a {@link TypeObject}.
	 * @since 2020/06/22
	 */
	static TypeObject __type(Object __object)
		throws SpringMLECallError
	{
		if (!(__object instanceof TypeObject))
			throw new SpringMLECallError("Not a TypeObject.");
		
		return (TypeObject)__object; 
	}
}

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringArrayObject.java.

6
7
8
9
10
11
12




13
14
15
16
17
18
19
..
20
21
22
23
24
25
26




27
28
29
30
31
32
33
..
37
38
39
40
41
42
43
44
45

46
47
48
49
50
51

52
53
54
55




56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
..
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134










135
136
137
138
139
140
141
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;





import java.lang.ref.Reference;
import java.lang.ref.WeakReference;

/**
 * This is an object which acts as an array, which stores some kind of data.
 *
 * @since 2018/09/15
................................................................................
 */
public abstract class SpringArrayObject
	implements SpringObject
{
	/** The monitor for this array. */
	protected final SpringMonitor monitor =
		new SpringMonitor();




	
	/** The type of this object itself. */
	protected final SpringClass selftype;
	
	/** The component type. */
	protected final SpringClass component;
	
................................................................................
	/** String representation. */
	private Reference<String> _string;
	
	/**
	 * Initializes the array.
	 *
	 * @param __self The self type.
	 * @param __cl The component type.
	 * @param __l The array length.

	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/09/15
	 */
	public SpringArrayObject(SpringClass __self, SpringClass __cl, int __l)
		throws NullPointerException

	{
		if (__self == null || __cl == null)
			throw new NullPointerException("NARG");
		




		// {@squirreljme.error BK01 Attempt to allocate an array of a
		// negative size. (The length requested)}
		if (__l < 0)
			throw new SpringNegativeArraySizeException(
				String.format("BK01 %d", __l));
		
		this.selftype = __self;
		this.component = __cl;
		this.length = __l;
	}
	
	/**
	 * Returns the raw backing array.
	 *
	 * @return The array.
................................................................................
	 * @throws SpringArrayIndexOutOfBoundsException If the index is not within
	 * bounds.
	 * @since 2018/09/16
	 */
	public abstract void set(int __dx, Object __v)
		throws SpringArrayStoreException, SpringArrayIndexOutOfBoundsException;
	
	/**
	 * {@inheritDoc}
	 * @since 2018/09/15
	 */
	@Override
	public final SpringMonitor monitor()
	{
		return this.monitor;
	}
	
	/**
	 * Returns the length of this array.
	 *
	 * @return The array length.
	 * @since 2018/09/16
	 */
	public final int length()
	{
		return this.length;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2019/12/21
	 */
	@Override
	public final SpringPointerArea pointerArea()
	{
		throw new todo.TODO();










	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/09/15
	 */
	@Override







>
>
>
>







 







>
>
>
>







 







<

>




|
|
>

|


>
>
>
>







|







 







<
<
<
<
<
<
<
<
<
<













|


|

|
>
>
>
>
>
>
>
>
>
>







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
..
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
...
112
113
114
115
116
117
118










119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.vm.springcoat.brackets.RefLinkHolder;
import cc.squirreljme.vm.springcoat.exceptions.SpringArrayIndexOutOfBoundsException;
import cc.squirreljme.vm.springcoat.exceptions.SpringArrayStoreException;
import cc.squirreljme.vm.springcoat.exceptions.SpringNegativeArraySizeException;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;

/**
 * This is an object which acts as an array, which stores some kind of data.
 *
 * @since 2018/09/15
................................................................................
 */
public abstract class SpringArrayObject
	implements SpringObject
{
	/** The monitor for this array. */
	protected final SpringMonitor monitor =
		new SpringMonitor();
	
	/** The reference link holder. */
	protected final RefLinkHolder refLink =
		new RefLinkHolder();
	
	/** The type of this object itself. */
	protected final SpringClass selftype;
	
	/** The component type. */
	protected final SpringClass component;
	
................................................................................
	/** String representation. */
	private Reference<String> _string;
	
	/**
	 * Initializes the array.
	 *
	 * @param __self The self type.

	 * @param __l The array length.
	 * @throws IllegalArgumentException If the type is not an array.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/09/15
	 */
	public SpringArrayObject(SpringClass __self, int __l)
		throws IllegalArgumentException, NullPointerException,
			SpringNegativeArraySizeException
	{
		if (__self == null)
			throw new NullPointerException("NARG");
		
		// The passed type must always be an array
		if (!__self.isArray())
			throw new IllegalArgumentException("Type not an array: " + __self);
		
		// {@squirreljme.error BK01 Attempt to allocate an array of a
		// negative size. (The length requested)}
		if (__l < 0)
			throw new SpringNegativeArraySizeException(
				String.format("BK01 %d", __l));
		
		this.selftype = __self;
		this.component = __self.componentType();
		this.length = __l;
	}
	
	/**
	 * Returns the raw backing array.
	 *
	 * @return The array.
................................................................................
	 * @throws SpringArrayIndexOutOfBoundsException If the index is not within
	 * bounds.
	 * @since 2018/09/16
	 */
	public abstract void set(int __dx, Object __v)
		throws SpringArrayStoreException, SpringArrayIndexOutOfBoundsException;
	










	/**
	 * Returns the length of this array.
	 *
	 * @return The array length.
	 * @since 2018/09/16
	 */
	public final int length()
	{
		return this.length;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/09/15
	 */
	@Override
	public final SpringMonitor monitor()
	{
		return this.monitor;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/05/31
	 */
	@Override
	public final RefLinkHolder refLink()
	{
		return this.refLink;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/09/15
	 */
	@Override

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringArrayObjectBoolean.java.

6
7
8
9
10
11
12




13
14
15
16
17
18
19
..
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
..
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;





/**
 * Array backed by a boolean array.
 *
 * @since 2018/11/14
 */
public final class SpringArrayObjectBoolean
	extends SpringArrayObject
................................................................................
	/** Elements in the array. */
	private final boolean[] _elements;
	
	/**
	 * Initializes the array.
	 *
	 * @param __self The self type.
	 * @param __cl The component type.
	 * @param __l The array length.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/11/14
	 */
	public SpringArrayObjectBoolean(SpringClass __self, SpringClass __cl,
		int __l)
		throws NullPointerException
	{
		super(__self, __cl, __l);
		
		// Initialize elements
		this._elements = new boolean[__l];
	}
	
	/**
	 * Wraps the native array.
................................................................................
	 *
	 * @param __self The self type.
	 * @param __cl The component type.
	 * @param __a The array to wrap.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/18
	 */
	public SpringArrayObjectBoolean(SpringClass __self, SpringClass __cl,
		boolean[] __a)
		throws NullPointerException
	{
		super(__self, __cl, __a.length);
		
		this._elements = __a;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/19
	 */
	@Override
	public final Object array()
	{
		return this._elements;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/14







>
>
>
>







 







<





|
<


|







 







|
<


|









|







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
25
26
27
28
29
30
31

32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
..
48
49
50
51
52
53
54
55

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.vm.springcoat.exceptions.SpringArrayIndexOutOfBoundsException;
import cc.squirreljme.vm.springcoat.exceptions.SpringArrayStoreException;
import cc.squirreljme.vm.springcoat.exceptions.SpringNegativeArraySizeException;

/**
 * Array backed by a boolean array.
 *
 * @since 2018/11/14
 */
public final class SpringArrayObjectBoolean
	extends SpringArrayObject
................................................................................
	/** Elements in the array. */
	private final boolean[] _elements;
	
	/**
	 * Initializes the array.
	 *
	 * @param __self The self type.

	 * @param __l The array length.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/11/14
	 */
	public SpringArrayObjectBoolean(SpringClass __self, int __l)

		throws NullPointerException
	{
		super(__self, __l);
		
		// Initialize elements
		this._elements = new boolean[__l];
	}
	
	/**
	 * Wraps the native array.
................................................................................
	 *
	 * @param __self The self type.
	 * @param __cl The component type.
	 * @param __a The array to wrap.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/18
	 */
	public SpringArrayObjectBoolean(SpringClass __self, boolean[] __a)

		throws NullPointerException
	{
		super(__self, __a.length);
		
		this._elements = __a;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/19
	 */
	@Override
	public final boolean[] array()
	{
		return this._elements;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/14

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringArrayObjectByte.java.

6
7
8
9
10
11
12




13
14
15
16
17
18
19
..
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;





/**
 * Array backed by a byte array.
 *
 * @since 2018/11/04
 */
public final class SpringArrayObjectByte
	extends SpringArrayObject
................................................................................
	/** Elements in the array. */
	private final byte[] _elements;
	
	/**
	 * Initializes the array.
	 *
	 * @param __self The self type.
	 * @param __cl The component type.
	 * @param __l The array length.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/11/04
	 */
	public SpringArrayObjectByte(SpringClass __self, SpringClass __cl,
		int __l)
		throws NullPointerException
	{
		super(__self, __cl, __l);
		
		// Initialize elements
		this._elements = new byte[__l];
	}
	
	/**
	 * Wraps the native array.
	 *
	 * @param __self The self type.
	 * @param __cl The component type.
	 * @param __a The array to wrap.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/18
	 */
	public SpringArrayObjectByte(SpringClass __self, SpringClass __cl,
		byte[] __a)
		throws NullPointerException
	{
		super(__self, __cl, __a.length);
		
		this._elements = __a;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/19
	 */
	@Override
	public final Object array()
	{
		return this._elements;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/14







>
>
>
>







 







<





|
<


|









<




|
<


|









|







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
25
26
27
28
29
30
31

32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.vm.springcoat.exceptions.SpringArrayIndexOutOfBoundsException;
import cc.squirreljme.vm.springcoat.exceptions.SpringArrayStoreException;
import cc.squirreljme.vm.springcoat.exceptions.SpringNegativeArraySizeException;

/**
 * Array backed by a byte array.
 *
 * @since 2018/11/04
 */
public final class SpringArrayObjectByte
	extends SpringArrayObject
................................................................................
	/** Elements in the array. */
	private final byte[] _elements;
	
	/**
	 * Initializes the array.
	 *
	 * @param __self The self type.

	 * @param __l The array length.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/11/04
	 */
	public SpringArrayObjectByte(SpringClass __self, int __l)

		throws NullPointerException
	{
		super(__self, __l);
		
		// Initialize elements
		this._elements = new byte[__l];
	}
	
	/**
	 * Wraps the native array.
	 *
	 * @param __self The self type.

	 * @param __a The array to wrap.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/18
	 */
	public SpringArrayObjectByte(SpringClass __self, byte[] __a)

		throws NullPointerException
	{
		super(__self, __a.length);
		
		this._elements = __a;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/19
	 */
	@Override
	public final byte[] array()
	{
		return this._elements;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/14

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringArrayObjectChar.java.

6
7
8
9
10
11
12




13
14
15
16
17
18
19
..
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;





/**
 * Array backed by a char array.
 *
 * @since 2018/11/04
 */
public final class SpringArrayObjectChar
	extends SpringArrayObject
................................................................................
	/** Elements in the array. */
	private final char[] _elements;
	
	/**
	 * Initializes the array.
	 *
	 * @param __self The self type.
	 * @param __cl The component type.
	 * @param __l The array length.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/11/04
	 */
	public SpringArrayObjectChar(SpringClass __self, SpringClass __cl,
		int __l)
		throws NullPointerException
	{
		super(__self, __cl, __l);
		
		// Initialize elements
		this._elements = new char[__l];
	}
	
	/**
	 * Wraps the native array.
	 *
	 * @param __self The self type.
	 * @param __cl The component type.
	 * @param __a The array to wrap.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/18
	 */
	public SpringArrayObjectChar(SpringClass __self, SpringClass __cl,
		char[] __a)
		throws NullPointerException
	{
		super(__self, __cl, __a.length);
		
		this._elements = __a;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/19
	 */
	@Override
	public final Object array()
	{
		return this._elements;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/14







>
>
>
>







 







<





|
<


|









<




|
<


|









|







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
25
26
27
28
29
30
31

32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.vm.springcoat.exceptions.SpringArrayIndexOutOfBoundsException;
import cc.squirreljme.vm.springcoat.exceptions.SpringArrayStoreException;
import cc.squirreljme.vm.springcoat.exceptions.SpringNegativeArraySizeException;

/**
 * Array backed by a char array.
 *
 * @since 2018/11/04
 */
public final class SpringArrayObjectChar
	extends SpringArrayObject
................................................................................
	/** Elements in the array. */
	private final char[] _elements;
	
	/**
	 * Initializes the array.
	 *
	 * @param __self The self type.

	 * @param __l The array length.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/11/04
	 */
	public SpringArrayObjectChar(SpringClass __self, int __l)

		throws NullPointerException
	{
		super(__self, __l);
		
		// Initialize elements
		this._elements = new char[__l];
	}
	
	/**
	 * Wraps the native array.
	 *
	 * @param __self The self type.

	 * @param __a The array to wrap.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/18
	 */
	public SpringArrayObjectChar(SpringClass __self, char[] __a)

		throws NullPointerException
	{
		super(__self, __a.length);
		
		this._elements = __a;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/19
	 */
	@Override
	public final char[] array()
	{
		return this._elements;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/14

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringArrayObjectDouble.java.

6
7
8
9
10
11
12




13
14
15
16
17
18
19
..
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;





/**
 * Array backed by a double array.
 *
 * @since 2018/11/14
 */
public final class SpringArrayObjectDouble
	extends SpringArrayObject
................................................................................
	/** Elements in the array. */
	private final double[] _elements;
	
	/**
	 * Initializes the array.
	 *
	 * @param __self The self type.
	 * @param __cl The component type.
	 * @param __l The array length.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/11/14
	 */
	public SpringArrayObjectDouble(SpringClass __self, SpringClass __cl,
		int __l)
		throws NullPointerException
	{
		super(__self, __cl, __l);
		
		// Initialize elements
		this._elements = new double[__l];
	}
	
	/**
	 * Wraps the native array.
	 *
	 * @param __self The self type.
	 * @param __cl The component type.
	 * @param __a The array to wrap.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/18
	 */
	public SpringArrayObjectDouble(SpringClass __self, SpringClass __cl,
		double[] __a)
		throws NullPointerException
	{
		super(__self, __cl, __a.length);
		
		this._elements = __a;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/19
	 */
	@Override
	public final Object array()
	{
		return this._elements;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/14







>
>
>
>







 







<





|
<


|









<




|
<


|









|







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
25
26
27
28
29
30
31

32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.vm.springcoat.exceptions.SpringArrayIndexOutOfBoundsException;
import cc.squirreljme.vm.springcoat.exceptions.SpringArrayStoreException;
import cc.squirreljme.vm.springcoat.exceptions.SpringNegativeArraySizeException;

/**
 * Array backed by a double array.
 *
 * @since 2018/11/14
 */
public final class SpringArrayObjectDouble
	extends SpringArrayObject
................................................................................
	/** Elements in the array. */
	private final double[] _elements;
	
	/**
	 * Initializes the array.
	 *
	 * @param __self The self type.

	 * @param __l The array length.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/11/14
	 */
	public SpringArrayObjectDouble(SpringClass __self, int __l)

		throws NullPointerException
	{
		super(__self, __l);
		
		// Initialize elements
		this._elements = new double[__l];
	}
	
	/**
	 * Wraps the native array.
	 *
	 * @param __self The self type.

	 * @param __a The array to wrap.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/18
	 */
	public SpringArrayObjectDouble(SpringClass __self, double[] __a)

		throws NullPointerException
	{
		super(__self, __a.length);
		
		this._elements = __a;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/19
	 */
	@Override
	public final double[] array()
	{
		return this._elements;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/14

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringArrayObjectFloat.java.

6
7
8
9
10
11
12




13
14
15
16
17
18
19
..
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;





/**
 * Array backed by a float array.
 *
 * @since 2018/11/14
 */
public final class SpringArrayObjectFloat
	extends SpringArrayObject
................................................................................
	/** Elements in the array. */
	private final float[] _elements;
	
	/**
	 * Initializes the array.
	 *
	 * @param __self The self type.
	 * @param __cl The component type.
	 * @param __l The array length.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/11/14
	 */
	public SpringArrayObjectFloat(SpringClass __self, SpringClass __cl,
		int __l)
		throws NullPointerException
	{
		super(__self, __cl, __l);
		
		// Initialize elements
		this._elements = new float[__l];
	}
	
	/**
	 * Wraps the native array.
	 *
	 * @param __self The self type.
	 * @param __cl The component type.
	 * @param __a The array to wrap.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/18
	 */
	public SpringArrayObjectFloat(SpringClass __self, SpringClass __cl,
		float[] __a)
		throws NullPointerException
	{
		super(__self, __cl, __a.length);
		
		this._elements = __a;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/19
	 */
	@Override
	public final Object array()
	{
		return this._elements;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/14







>
>
>
>







 







<





|
<


|









<




|
<


|









|







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
25
26
27
28
29
30
31

32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.vm.springcoat.exceptions.SpringArrayIndexOutOfBoundsException;
import cc.squirreljme.vm.springcoat.exceptions.SpringArrayStoreException;
import cc.squirreljme.vm.springcoat.exceptions.SpringNegativeArraySizeException;

/**
 * Array backed by a float array.
 *
 * @since 2018/11/14
 */
public final class SpringArrayObjectFloat
	extends SpringArrayObject
................................................................................
	/** Elements in the array. */
	private final float[] _elements;
	
	/**
	 * Initializes the array.
	 *
	 * @param __self The self type.

	 * @param __l The array length.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/11/14
	 */
	public SpringArrayObjectFloat(SpringClass __self, int __l)

		throws NullPointerException
	{
		super(__self, __l);
		
		// Initialize elements
		this._elements = new float[__l];
	}
	
	/**
	 * Wraps the native array.
	 *
	 * @param __self The self type.

	 * @param __a The array to wrap.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/18
	 */
	public SpringArrayObjectFloat(SpringClass __self, float[] __a)

		throws NullPointerException
	{
		super(__self, __a.length);
		
		this._elements = __a;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/19
	 */
	@Override
	public final float[] array()
	{
		return this._elements;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/14

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringArrayObjectGeneric.java.

6
7
8
9
10
11
12
13


14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

35
36
37
38
39
40
41

42
43
44







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

















86
87
88
89
90
91
92
93
94
95
96
97
98
99
...
101
102
103
104
105
106
107






108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

















126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import net.multiphasicapps.classfile.PrimitiveType;



/**
 * Generic array that can store any type.
 *
 * @since 2018/11/04
 */
public final class SpringArrayObjectGeneric
	extends SpringArrayObject
{
	/** Elements in the array. */
	private final Object[] _elements;
	
	/** The last class which was checked for compatibility. */
	private SpringClass _lastvalid;
	
	/**
	 * Initializes the array.
	 *
	 * @param __self The self type.
	 * @param __cl The component type.
	 * @param __l The array length.

	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/09/15
	 */
	public SpringArrayObjectGeneric(SpringClass __self, SpringClass __cl,
		int __l)
		throws NullPointerException

	{
		super(__self, __cl, __l);
		







		// Initialize elements
		Object[] elements;
		this._elements = (elements = new Object[__l]);
		
		// Determine the initial value to use
		PrimitiveType type = __cl.name().primitiveType();
		Object v;
		if (type == null)
			v = SpringNullObject.NULL;
		else
			switch (type)
			{
				case BOOLEAN:
				case BYTE:
				case SHORT:
				case CHARACTER:
				case INTEGER:
					v = Integer.valueOf(0);
					break;
				
				case LONG:
					v = Long.valueOf(0);
					break;
				
				case FLOAT:
					v = Float.valueOf(0);
					break;
				
				case DOUBLE:
					v = Double.valueOf(0);
					break;
				
				default:
					throw new todo.OOPS();
			}
		
		// Set all elements to an initial value depending on the type
		// Set all 
		for (int i = 0; i < __l; i++)
			elements[i] = v;
	}

















	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/19
	 */
	@Override
	public final Object array()
	{
		return this._elements;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/14
................................................................................
	@Override
	public final <C> C get(Class<C> __cl, int __dx)
		throws NullPointerException, SpringArrayIndexOutOfBoundsException
	{
		// Faster to just have the host VM do bounds check
		try
		{






			return __cl.cast(this._elements[__dx]);
		}
		
		// {@squirreljme.error BK0h Out of bounds access to array.
		// (The index; The length of the array)}
		catch (IndexOutOfBoundsException e)
		{
			throw new SpringArrayIndexOutOfBoundsException(
				String.format("BK0h %d %d", __dx, this.length), e);
		}
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/14
	 */
	@Override
	public final void set(int __dx, Object __v)

















		throws SpringArrayStoreException, SpringArrayIndexOutOfBoundsException
	{
		try
		{
			// This is a cached type for setting because an array of one type
			// will usually in most cases set with objects which are compatible
			// so the rather involved instanceof check will take awhile and
			// compound for setting single elements.
			SpringClass lastvalid = this._lastvalid,
				wouldset = null;
			
			// If the input value is an object
			boolean docheck;
			if (__v instanceof SpringObject)
			{
				// If a check is done, then 
				wouldset = ((SpringObject)__v).type();
				
				// Only if the types differ would we actually check
				docheck = (wouldset != lastvalid);
			}
			
			// Otherwise always do a check since we do not really know the
			// class type here
			else
				docheck = true;
			
			// Performing the check for cache?
			if (docheck)

			{
				// {@squirreljme.error BK0i The specified type is not
				// compatible with the values this array stores. (The input
				// value; The component type)}
				SpringClass component = this.component;
				if (!component.isCompatible(__v))
					throw new SpringArrayStoreException(String.format(
						"BK0i %s %s", __v, component));
				
				// Next validity check would be set if done on an object
				// Ignore setting it back to null, if one was previously
				// valid
				if (wouldset != null)
					this._lastvalid = wouldset;
			}
			
			// Set
			this._elements[__dx] = __v;
		}
		
		// {@squirreljme.error BK0j Out of bounds access to array. (The index;
		// The length of the array)}
		catch (IndexOutOfBoundsException e)
		{
			throw new SpringArrayIndexOutOfBoundsException(
				String.format("BK0j %d %d", __dx, this.length), e);
		}
	}
}








|
>
>










|


|





<

>




|
<
|
>

|

>
>
>
>
>
>
>

|
|


<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|







 







>
>
>
>
>
>
|













|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
>












|
|



|












6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58



59


60
























61

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
..
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
















156

157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.vm.springcoat.exceptions.SpringArrayIndexOutOfBoundsException;
import cc.squirreljme.vm.springcoat.exceptions.SpringArrayStoreException;
import cc.squirreljme.vm.springcoat.exceptions.SpringNegativeArraySizeException;

/**
 * Generic array that can store any type.
 *
 * @since 2018/11/04
 */
public final class SpringArrayObjectGeneric
	extends SpringArrayObject
{
	/** Elements in the array. */
	private final SpringObject[] _elements;
	
	/** The last class which was checked for compatibility. */
	private SpringClass _lastValid;
	
	/**
	 * Initializes the array.
	 *
	 * @param __self The self type.

	 * @param __l The array length.
	 * @throws IllegalArgumentException If the given type is primitive.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/09/15
	 */
	public SpringArrayObjectGeneric(SpringClass __self, int __l)

		throws IllegalArgumentException, NullPointerException,
			SpringNegativeArraySizeException
	{
		super(__self, __l);
		
		// Previously this was permitted, however since there are other more
		// optimal forms for arrays this is no longer needed to have a generic
		// array to store these values
		if (__self.componentType().name().primitiveType() != null)
			throw new IllegalArgumentException("Cannot have a generic " +
				"array of primitive types: " + __self);
		
		// Initialize elements
		SpringObject[] elements;
		this._elements = (elements = new SpringObject[__l]);
		
		// Determine the initial value to use



		SpringObject v = SpringNullObject.NULL;


		
























		// Set all elements to an initial value depending on the type

		for (int i = 0; i < __l; i++)
			elements[i] = v;
	}
	
	/**
	 * Wraps the given array as a generic array.
	 *
	 * @param __self The self type.
	 * @param __elements The array elements.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/13
	 */
	public SpringArrayObjectGeneric(SpringClass __self,
		SpringObject[] __elements)
		throws NullPointerException
	{
		super(__self, __elements.length);
		
		this._elements = __elements;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/19
	 */
	@Override
	public final SpringObject[] array()
	{
		return this._elements;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/14
................................................................................
	@Override
	public final <C> C get(Class<C> __cl, int __dx)
		throws NullPointerException, SpringArrayIndexOutOfBoundsException
	{
		// Faster to just have the host VM do bounds check
		try
		{
			SpringObject rv = this._elements[__dx];
			
			// Always have the special null be used here
			if (rv == null)
				rv = SpringNullObject.NULL;
			
			return __cl.cast(rv);
		}
		
		// {@squirreljme.error BK0h Out of bounds access to array.
		// (The index; The length of the array)}
		catch (IndexOutOfBoundsException e)
		{
			throw new SpringArrayIndexOutOfBoundsException(
				String.format("BK0h %d %d", __dx, this.length), e);
		}
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/06/13
	 */
	@Override
	public final void set(int __dx, Object __v)
		throws ClassCastException, SpringArrayStoreException,
			SpringArrayIndexOutOfBoundsException
	{
		this.set(__dx, (SpringObject)__v);
	}
	
	/**
	 * Sets the value in the array.
	 *
	 * @param __dx The index.
	 * @param __v The value to set.
	 * @throws SpringArrayStoreException If the type is not valid.
	 * @throws SpringArrayIndexOutOfBoundsException If the index is out of
	 * bounds.
	 * @since 2018/11/14
	 */
	public final void set(int __dx, SpringObject __v)
		throws SpringArrayStoreException, SpringArrayIndexOutOfBoundsException
	{
		try
		{
			// This is a cached type for setting because an array of one type
			// will usually in most cases set with objects which are compatible
			// so the rather involved instanceof check will take awhile and
			// compound for setting single elements.
			SpringClass lastValid = this._lastValid;
			SpringClass wouldSet = (__v == null ? null : __v.type());
			
















			// Performing the check for cache?

			if (wouldSet != lastValid)
			{
				// {@squirreljme.error BK0i The specified type is not
				// compatible with the values this array stores. (The input
				// value; The component type)}
				SpringClass component = this.component;
				if (!component.isCompatible(__v))
					throw new SpringArrayStoreException(String.format(
						"BK0i %s %s", __v, component));
				
				// Next validity check would be set if done on an object
				// Ignore setting it back to null, if one was previously
				// valid
				if (wouldSet != null)
					this._lastValid = wouldSet;
			}
			
			// Set
			this._elements[__dx] = (__v == null ? SpringNullObject.NULL : __v);
		}
		
		// {@squirreljme.error BK0j Out of bounds access to array. (The index;
		// The length of the array)}
		catch (IndexOutOfBoundsException e)
		{
			throw new SpringArrayIndexOutOfBoundsException(
				String.format("BK0j %d %d", __dx, this.length), e);
		}
	}
}

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringArrayObjectInteger.java.

6
7
8
9
10
11
12




13
14
15
16
17
18
19
..
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;





/**
 * Array backed by an int array.
 *
 * @since 2018/11/04
 */
public final class SpringArrayObjectInteger
	extends SpringArrayObject
................................................................................
	/** Elements in the array. */
	private final int[] _elements;
	
	/**
	 * Initializes the array.
	 *
	 * @param __self The self type.
	 * @param __cl The component type.
	 * @param __l The array length.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/11/04
	 */
	public SpringArrayObjectInteger(SpringClass __self, SpringClass __cl,
		int __l)
		throws NullPointerException
	{
		super(__self, __cl, __l);
		
		// Initialize elements
		this._elements = new int[__l];
	}
	
	/**
	 * Wraps the native array.
	 *
	 * @param __self The self type.
	 * @param __cl The component type.
	 * @param __a The array to wrap.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/18
	 */
	public SpringArrayObjectInteger(SpringClass __self, SpringClass __cl,
		int[] __a)
		throws NullPointerException
	{
		super(__self, __cl, __a.length);
		
		this._elements = __a;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/19
	 */
	@Override
	public final Object array()
	{
		return this._elements;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/14







>
>
>
>







 







<





|
<


|









<




|
<


|









|







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
25
26
27
28
29
30
31

32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.vm.springcoat.exceptions.SpringArrayIndexOutOfBoundsException;
import cc.squirreljme.vm.springcoat.exceptions.SpringArrayStoreException;
import cc.squirreljme.vm.springcoat.exceptions.SpringNegativeArraySizeException;

/**
 * Array backed by an int array.
 *
 * @since 2018/11/04
 */
public final class SpringArrayObjectInteger
	extends SpringArrayObject
................................................................................
	/** Elements in the array. */
	private final int[] _elements;
	
	/**
	 * Initializes the array.
	 *
	 * @param __self The self type.

	 * @param __l The array length.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/11/04
	 */
	public SpringArrayObjectInteger(SpringClass __self, int __l)

		throws NullPointerException
	{
		super(__self, __l);
		
		// Initialize elements
		this._elements = new int[__l];
	}
	
	/**
	 * Wraps the native array.
	 *
	 * @param __self The self type.

	 * @param __a The array to wrap.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/18
	 */
	public SpringArrayObjectInteger(SpringClass __self, int[] __a)

		throws NullPointerException
	{
		super(__self, __a.length);
		
		this._elements = __a;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/19
	 */
	@Override
	public final int[] array()
	{
		return this._elements;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/14

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringArrayObjectLong.java.

6
7
8
9
10
11
12




13
14
15
16
17
18
19
..
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;





/**
 * Array backed by a long array.
 *
 * @since 2018/11/14
 */
public final class SpringArrayObjectLong
	extends SpringArrayObject
................................................................................
	/** Elements in the array. */
	private final long[] _elements;
	
	/**
	 * Initializes the array.
	 *
	 * @param __self The self type.
	 * @param __cl The component type.
	 * @param __l The array length.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/11/14
	 */
	public SpringArrayObjectLong(SpringClass __self, SpringClass __cl,
		int __l)
		throws NullPointerException
	{
		super(__self, __cl, __l);
		
		// Initialize elements
		this._elements = new long[__l];
	}
	
	/**
	 * Wraps the native array.
	 *
	 * @param __self The self type.
	 * @param __cl The component type.
	 * @param __a The array to wrap.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/18
	 */
	public SpringArrayObjectLong(SpringClass __self, SpringClass __cl,
		long[] __a)
		throws NullPointerException
	{
		super(__self, __cl, __a.length);
		
		this._elements = __a;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/19
	 */
	@Override
	public final Object array()
	{
		return this._elements;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/14







>
>
>
>







 







<





|
<


|









<




|
<


|









|







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
25
26
27
28
29
30
31

32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.vm.springcoat.exceptions.SpringArrayIndexOutOfBoundsException;
import cc.squirreljme.vm.springcoat.exceptions.SpringArrayStoreException;
import cc.squirreljme.vm.springcoat.exceptions.SpringNegativeArraySizeException;

/**
 * Array backed by a long array.
 *
 * @since 2018/11/14
 */
public final class SpringArrayObjectLong
	extends SpringArrayObject
................................................................................
	/** Elements in the array. */
	private final long[] _elements;
	
	/**
	 * Initializes the array.
	 *
	 * @param __self The self type.

	 * @param __l The array length.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/11/14
	 */
	public SpringArrayObjectLong(SpringClass __self, int __l)

		throws NullPointerException
	{
		super(__self, __l);
		
		// Initialize elements
		this._elements = new long[__l];
	}
	
	/**
	 * Wraps the native array.
	 *
	 * @param __self The self type.

	 * @param __a The array to wrap.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/18
	 */
	public SpringArrayObjectLong(SpringClass __self, long[] __a)

		throws NullPointerException
	{
		super(__self, __a.length);
		
		this._elements = __a;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/19
	 */
	@Override
	public final long[] array()
	{
		return this._elements;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/14

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringArrayObjectShort.java.

6
7
8
9
10
11
12




13
14
15
16
17
18
19
..
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;





/**
 * Array backed by a short array.
 *
 * @since 2018/11/14
 */
public final class SpringArrayObjectShort
	extends SpringArrayObject
................................................................................
	/** Elements in the array. */
	private final short[] _elements;
	
	/**
	 * Initializes the array.
	 *
	 * @param __self The self type.
	 * @param __cl The component type.
	 * @param __l The array length.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/11/14
	 */
	public SpringArrayObjectShort(SpringClass __self, SpringClass __cl,
		int __l)
		throws NullPointerException
	{
		super(__self, __cl, __l);
		
		// Initialize elements
		this._elements = new short[__l];
	}
	
	/**
	 * Wraps the native array.
	 *
	 * @param __self The self type.
	 * @param __cl The component type.
	 * @param __a The array to wrap.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/18
	 */
	public SpringArrayObjectShort(SpringClass __self, SpringClass __cl,
		short[] __a)
		throws NullPointerException
	{
		super(__self, __cl, __a.length);
		
		this._elements = __a;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/19
	 */
	@Override
	public final Object array()
	{
		return this._elements;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/14







>
>
>
>







 







<





|
<


|









<




|
<


|









|







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
25
26
27
28
29
30
31

32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.vm.springcoat.exceptions.SpringArrayIndexOutOfBoundsException;
import cc.squirreljme.vm.springcoat.exceptions.SpringArrayStoreException;
import cc.squirreljme.vm.springcoat.exceptions.SpringNegativeArraySizeException;

/**
 * Array backed by a short array.
 *
 * @since 2018/11/14
 */
public final class SpringArrayObjectShort
	extends SpringArrayObject
................................................................................
	/** Elements in the array. */
	private final short[] _elements;
	
	/**
	 * Initializes the array.
	 *
	 * @param __self The self type.

	 * @param __l The array length.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/11/14
	 */
	public SpringArrayObjectShort(SpringClass __self, int __l)

		throws NullPointerException
	{
		super(__self, __l);
		
		// Initialize elements
		this._elements = new short[__l];
	}
	
	/**
	 * Wraps the native array.
	 *
	 * @param __self The self type.

	 * @param __a The array to wrap.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/18
	 */
	public SpringArrayObjectShort(SpringClass __self, short[] __a)

		throws NullPointerException
	{
		super(__self, __a.length);
		
		this._elements = __a;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/19
	 */
	@Override
	public final short[] array()
	{
		return this._elements;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/14

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringClass.java.

7
8
9
10
11
12
13






14
15
16
17
18
19
20
..
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
..
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
...
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
...
443
444
445
446
447
448
449











450
451
452
453
454
455
456
...
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.Constants;






import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.multiphasicapps.classfile.ClassFile;
import net.multiphasicapps.classfile.ClassFlags;
import net.multiphasicapps.classfile.ClassName;
................................................................................
	
	/** The super class. */
	protected final SpringClass superclass;
	
	/** The number of instance fields that exist. */
	protected final int instancefieldcount;
	
	/** The special class index. */
	protected final int specialindex;
	
	/** The dimentions of this class. */
	protected final int dimensions;
	
	/** The component type. */
	protected final SpringClass component;
	
	/** The JAR this class is in. */
	protected final String injar;
	
	/** The virtualized size of instances for this class. */
	protected final int instancesize;
	
	/** Interface classes. */
	private final SpringClass[] _interfaceclasses;
	
................................................................................
	
	/**
	 * Initializes the spring class.
	 *
	 * @param __super The super class of this class.
	 * @param __interfaces The the interfaces this class implements.
	 * @param __cf The class file for this class.
	 * @param __si The special class index.
	 * @param __ct The component type.
	 * @param __injar The JAR this class is in.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/07/21
	 */
	SpringClass(SpringClass __super, SpringClass[] __interfaces,
		ClassFile __cf, int __si, SpringClass __ct, String __injar)
		throws NullPointerException
	{
		if (__interfaces == null || __cf == null)
			throw new NullPointerException("NARG");
		
		ClassName name = __cf.thisName();
		this.name = name;
		this.specialindex = __si;
		this.injar = __injar;
		this.file = __cf;
		this.superclass = __super;
		this.component = __ct;
		this.dimensions = name.dimensions();
		
		// Check
		this._interfaceclasses = (__interfaces = __interfaces.clone());
................................................................................
	
	/**
	 * Returns the JAR this class is in.
	 *
	 * @return The JAR this class is in.
	 * @since 2018/10/07
	 */
	public final String inJar()
	{
		return this.injar;
	}
	
	/**
	 * Returns the number of instance fields this class stores. This is for
	 * the most part the size of the given class.
	 *
	 * @return The number of instance fields this class stores.
................................................................................
		else if (__v instanceof SpringObject)
			return this.isAssignableFrom(((SpringObject)__v).type());
		
		// Unknown
		else
			throw new todo.OOPS();
	}











	
	/**
	 * Has this class been initialized?
	 *
	 * @return If the class has been initialized.
	 * @since 2018/09/08
	 */
................................................................................
		if (this._initialized)
			throw new SpringVirtualMachineException(String.format(
				"BK11 %s", this.name));
		
		this._initialized = true;
	}
	
	/**
	 * Returns the special class index.
	 *
	 * @return The special class index.
	 * @since 2018/09/20
	 */
	public final int specialIndex()
	{
		return this.specialindex;
	}
	
	/**
	 * Returns the super class of this class.
	 *
	 * @return The super class of this class.
	 * @since 2018/09/08
	 */
	public final SpringClass superClass()







>
>
>
>
>
>







 







<
<
<







|







 







<

|




|







<
|







 







|

|







 







>
>
>
>
>
>
>
>
>
>
>







 







<
<
<
<
<
<
<
<
<
<
<







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
..
52
53
54
55
56
57
58



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
..
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119
...
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
...
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
...
751
752
753
754
755
756
757











758
759
760
761
762
763
764
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.Constants;
import cc.squirreljme.vm.VMClassLibrary;
import cc.squirreljme.vm.springcoat.exceptions.SpringClassFormatException;
import cc.squirreljme.vm.springcoat.exceptions.SpringIncompatibleClassChangeException;
import cc.squirreljme.vm.springcoat.exceptions.SpringNoSuchFieldException;
import cc.squirreljme.vm.springcoat.exceptions.SpringNoSuchMethodException;
import cc.squirreljme.vm.springcoat.exceptions.SpringVirtualMachineException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.multiphasicapps.classfile.ClassFile;
import net.multiphasicapps.classfile.ClassFlags;
import net.multiphasicapps.classfile.ClassName;
................................................................................
	
	/** The super class. */
	protected final SpringClass superclass;
	
	/** The number of instance fields that exist. */
	protected final int instancefieldcount;
	



	/** The dimentions of this class. */
	protected final int dimensions;
	
	/** The component type. */
	protected final SpringClass component;
	
	/** The JAR this class is in. */
	protected final VMClassLibrary inJar;
	
	/** The virtualized size of instances for this class. */
	protected final int instancesize;
	
	/** Interface classes. */
	private final SpringClass[] _interfaceclasses;
	
................................................................................
	
	/**
	 * Initializes the spring class.
	 *
	 * @param __super The super class of this class.
	 * @param __interfaces The the interfaces this class implements.
	 * @param __cf The class file for this class.

	 * @param __ct The component type.
	 * @param __inJar The JAR this class is in.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/07/21
	 */
	SpringClass(SpringClass __super, SpringClass[] __interfaces,
		ClassFile __cf, SpringClass __ct, VMClassLibrary __inJar)
		throws NullPointerException
	{
		if (__interfaces == null || __cf == null)
			throw new NullPointerException("NARG");
		
		ClassName name = __cf.thisName();
		this.name = name;

		this.inJar = __inJar;
		this.file = __cf;
		this.superclass = __super;
		this.component = __ct;
		this.dimensions = name.dimensions();
		
		// Check
		this._interfaceclasses = (__interfaces = __interfaces.clone());
................................................................................
	
	/**
	 * Returns the JAR this class is in.
	 *
	 * @return The JAR this class is in.
	 * @since 2018/10/07
	 */
	public final VMClassLibrary inJar()
	{
		return this.inJar;
	}
	
	/**
	 * Returns the number of instance fields this class stores. This is for
	 * the most part the size of the given class.
	 *
	 * @return The number of instance fields this class stores.
................................................................................
		else if (__v instanceof SpringObject)
			return this.isAssignableFrom(((SpringObject)__v).type());
		
		// Unknown
		else
			throw new todo.OOPS();
	}
	
	/**
	 * Checks if this is an enumeration.
	 * 
	 * @return If this is an enumeration.
	 * @since 2020/06/28
	 */
	public final boolean isEnum()
	{
		return this.flags().isEnum();
	}
	
	/**
	 * Has this class been initialized?
	 *
	 * @return If the class has been initialized.
	 * @since 2018/09/08
	 */
................................................................................
		if (this._initialized)
			throw new SpringVirtualMachineException(String.format(
				"BK11 %s", this.name));
		
		this._initialized = true;
	}
	











	/**
	 * Returns the super class of this class.
	 *
	 * @return The super class of this class.
	 * @since 2018/09/08
	 */
	public final SpringClass superClass()

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringClassLoader.java.

7
8
9
10
11
12
13



14
15
16
17
18
19
20
...
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
...
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
...
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
...
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.vm.VMClassLibrary;



import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import net.multiphasicapps.classfile.ClassFile;
................................................................................
				return rv;
			
			// Debug
			/*todo.DEBUG.note("Loading class `%s`...", __cn);*/
			
			// Load class file for this class
			ClassFile cf;
			String[] injar = new String[1];
			try
			{
				cf = this.loadClassFile(__cn, injar);
			}
			catch (InvalidClassFormatException e)
			{
				// {@squirreljme.error BK12 Could not load class. (The class
				// to load)}
				throw new InvalidClassFormatException(
					String.format("BK12 %s", __cn), e);
................................................................................
			// Component?
			SpringClass component = null;
			if (__cn.isArray())
				component = this.loadClass(__cn.componentType());
			
			// Load class information
			rv = new SpringClass(superclass, interfaceclasses, cf,
				this._nexcsi++, component, injar[0]);
			
			// Store for later use
			classes.put(__cn, rv);
			
			return rv;
		}
	}
................................................................................
	 * @return The loaded class file data.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringClassFormatException If the class is not formatted
	 * properly.
	 * @throws SpringClassNotFoundException If the class was not found.
	 * @since 2018/09/01
	 */
	public final ClassFile loadClassFile(ClassName __cn, String[] __ij)
		throws NullPointerException, SpringClassFormatException,
			SpringClassNotFoundException
	{
		if (__cn == null)
			throw new NullPointerException("NARG");
		
		// Debug
................................................................................
						
						baos.write(buf, 0, rc);
					}
				}
				
				// Record the binary
				if (__ij != null && __ij.length > 0)
					__ij[0] = b.name();
				
				break;
			}
			catch (IOException e)
			{
				// {@squirreljme.error BK13 Failed to read from the class
				// path.}







>
>
>







 







|


|







 







|







 







|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
...
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
...
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
...
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.vm.VMClassLibrary;
import cc.squirreljme.vm.springcoat.exceptions.SpringClassFormatException;
import cc.squirreljme.vm.springcoat.exceptions.SpringClassNotFoundException;
import cc.squirreljme.vm.springcoat.exceptions.SpringVirtualMachineException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import net.multiphasicapps.classfile.ClassFile;
................................................................................
				return rv;
			
			// Debug
			/*todo.DEBUG.note("Loading class `%s`...", __cn);*/
			
			// Load class file for this class
			ClassFile cf;
			VMClassLibrary[] inJar = new VMClassLibrary[1];
			try
			{
				cf = this.loadClassFile(__cn, inJar);
			}
			catch (InvalidClassFormatException e)
			{
				// {@squirreljme.error BK12 Could not load class. (The class
				// to load)}
				throw new InvalidClassFormatException(
					String.format("BK12 %s", __cn), e);
................................................................................
			// Component?
			SpringClass component = null;
			if (__cn.isArray())
				component = this.loadClass(__cn.componentType());
			
			// Load class information
			rv = new SpringClass(superclass, interfaceclasses, cf,
				component, inJar[0]);
			
			// Store for later use
			classes.put(__cn, rv);
			
			return rv;
		}
	}
................................................................................
	 * @return The loaded class file data.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringClassFormatException If the class is not formatted
	 * properly.
	 * @throws SpringClassNotFoundException If the class was not found.
	 * @since 2018/09/01
	 */
	public final ClassFile loadClassFile(ClassName __cn, VMClassLibrary[] __ij)
		throws NullPointerException, SpringClassFormatException,
			SpringClassNotFoundException
	{
		if (__cn == null)
			throw new NullPointerException("NARG");
		
		// Debug
................................................................................
						
						baos.write(buf, 0, rc);
					}
				}
				
				// Record the binary
				if (__ij != null && __ij.length > 0)
					__ij[0] = b;
				
				break;
			}
			catch (IOException e)
			{
				// {@squirreljme.error BK13 Failed to read from the class
				// path.}

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringCoatFactory.java.

45
46
47
48
49
50
51
52
53
54
55
56
		VMSuiteManager __sm, VMClassLibrary[] __cp, String __maincl,
		Map<String, String> __sprops, String[] __args)
		throws IllegalArgumentException, NullPointerException, VMException
	{
		// Create a new instance of the VM
		SpringTaskManager tm = new SpringTaskManager(__sm, __ps, __sprops);
		return new SpringMachine(__sm, new SpringClassLoader(__cp),
			tm, __maincl, false, -1,
			1, __ps, __sprops, __args);
	}
}








<
|



45
46
47
48
49
50
51

52
53
54
55
		VMSuiteManager __sm, VMClassLibrary[] __cp, String __maincl,
		Map<String, String> __sprops, String[] __args)
		throws IllegalArgumentException, NullPointerException, VMException
	{
		// Create a new instance of the VM
		SpringTaskManager tm = new SpringTaskManager(__sm, __ps, __sprops);
		return new SpringMachine(__sm, new SpringClassLoader(__cp),

			tm, __maincl, __ps, __sprops, tm.globalState, __args);
	}
}

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringDisplayEventCallback.java.

7
8
9
10
11
12
13


14
15
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
..
48
49
50
51
52
53
54



55
56
57
58
59
60
61
62
63
64
65
66
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.runtime.cldc.asm.NativeDisplayEventCallback;


import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.MethodDescriptor;
import net.multiphasicapps.classfile.MethodNameAndType;

/**
 * This is the callback to use which calls the given spring object, this is
 * needed by the native display.
 *
 * @since 2018/12/03
 */

public final class SpringDisplayEventCallback
	implements NativeDisplayEventCallback
{
	/** The class used for callback. */
	private static final ClassName _CALLBACK_CLASS =
		new ClassName("cc/squirreljme/runtime/cldc/asm/" +
			"NativeDisplayEventCallback");
................................................................................
	 */
	public SpringDisplayEventCallback(SpringMachine __m, SpringObject __o)
		throws NullPointerException
	{
		if (__m == null || __o == null)
			throw new NullPointerException("NARG");
		



		// Set object to call
		this.object = __o;
		
		// Setup thread
		SpringThread thread = __m.createThread("SpringCoat-LCDUIThread");
		SpringThreadWorker worker = new SpringThreadWorker(__m, thread, false);
		
		// Need to initialize a thread object because this thread has to be
		// registered with the runtime in order for programs to operate
		// correctly on it, even though it is a weird thread
		// This is always registered until it is explicitely not registered
		SpringObject fakethread = worker.newInstance(







>
>










>







 







>
>
>




|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
..
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.runtime.cldc.asm.NativeDisplayEventCallback;
import cc.squirreljme.runtime.cldc.debug.Debugging;
import cc.squirreljme.vm.springcoat.exceptions.SpringMachineExitException;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.MethodDescriptor;
import net.multiphasicapps.classfile.MethodNameAndType;

/**
 * This is the callback to use which calls the given spring object, this is
 * needed by the native display.
 *
 * @since 2018/12/03
 */
@Deprecated
public final class SpringDisplayEventCallback
	implements NativeDisplayEventCallback
{
	/** The class used for callback. */
	private static final ClassName _CALLBACK_CLASS =
		new ClassName("cc/squirreljme/runtime/cldc/asm/" +
			"NativeDisplayEventCallback");
................................................................................
	 */
	public SpringDisplayEventCallback(SpringMachine __m, SpringObject __o)
		throws NullPointerException
	{
		if (__m == null || __o == null)
			throw new NullPointerException("NARG");
		
		if (true)
			throw Debugging.todo("SDEC again or something else?");
		
		// Set object to call
		this.object = __o;
		
		// Setup thread
		SpringThread thread = __m.createThread("SpringCoat-LCDUIThread", false);
		SpringThreadWorker worker = new SpringThreadWorker(__m, thread, false);
		
		// Need to initialize a thread object because this thread has to be
		// registered with the runtime in order for programs to operate
		// correctly on it, even though it is a weird thread
		// This is always registered until it is explicitely not registered
		SpringObject fakethread = worker.newInstance(

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringFieldStorage.java.

6
7
8
9
10
11
12


13
14
15
16
17
18
19
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;



import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.ConstantValue;
import net.multiphasicapps.classfile.FieldNameAndType;

/**
 * Contains storage and other information for fields.
 *







>
>







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.vm.springcoat.exceptions.SpringIllegalAccessException;
import cc.squirreljme.vm.springcoat.exceptions.SpringIncompatibleClassChangeException;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.ConstantValue;
import net.multiphasicapps.classfile.FieldNameAndType;

/**
 * Contains storage and other information for fields.
 *

Deleted emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringInstance.java.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

/**
 * This represents an instance of an object which has a class and defined
 * fields.
 *
 * @since 2018/07/22
 */
public final class SpringInstance
{
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringMachine.java.

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22


23
24
25

26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46




47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
..
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137

138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
...
175
176
177
178
179
180
181
182


183
184
185
186
187
188
189
190
191
192
193
194
195
196




197
198
199


200
201
202



203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
...
293
294
295
296
297
298
299











300
301
302
303
304
305


306
307
308

309
310
311
312
313
314
315
316
317
318







































319
320
321
322
323
324
325
...
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
...
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485



486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
...
612
613
614
615
616
617
618























619
620
621
622
623
624
625
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.runtime.cldc.asm.TaskAccess;
import cc.squirreljme.runtime.cldc.lang.GuestDepth;
import cc.squirreljme.runtime.swm.EntryPoint;
import cc.squirreljme.runtime.swm.EntryPoints;
import cc.squirreljme.vm.VMClassLibrary;
import cc.squirreljme.emulator.vm.VMResourceAccess;
import cc.squirreljme.emulator.vm.VMSuiteManager;
import cc.squirreljme.emulator.vm.VirtualMachine;
import java.io.IOException;
import java.io.InputStream;


import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;

import java.util.List;
import java.util.Map;

import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.ConstantValueString;
import net.multiphasicapps.classfile.MethodDescriptor;
import net.multiphasicapps.classfile.MethodNameAndType;
import cc.squirreljme.emulator.profiler.ProfilerSnapshot;
import net.multiphasicapps.tool.manifest.JavaManifest;

/**
 * This class contains the instance of the SpringCoat virtual machine and has
 * a classpath along with all the needed storage for variables and such.
 *
 * @since 2018/07/29
 */
public final class SpringMachine
	implements Runnable, VirtualMachine
{
	/** Lock. */
	public final Object strlock =
		new Object();




	
	/** The class loader. */
	protected final SpringClassLoader classloader;
	
	/** Resources accessor. */
	protected final VMResourceAccess resourceaccessor;
	
	/** The boot class. */
	protected final String bootcl;
	
	/** Is the boot a midlet? */
	protected final boolean bootmid;
	
	/** The boot index. */
	protected final int bootdx;
	
	/** The manager for suites. */
	protected final VMSuiteManager suites;
	
	/** Task manager. */
	protected final SpringTaskManager tasks;
	
	/** The depth of this machine. */
	protected final int guestdepth;
	
	/** The profiling information. */
	protected final ProfilerSnapshot profiler;
	
	/** Pointer manager. */
	protected final SpringPointerManager pointers =
		new SpringPointerManager();
	
	/** Threads which are available. */
	private final List<SpringThread> _threads =
		new ArrayList<>();
	
	/** Static fields which exist within the virtual machine. */
	private final Map<SpringField, SpringFieldStorage> _staticfields =
		new HashMap<>();
................................................................................
	/** Class names by their objects. */
	private final Map<SpringObject, ClassName> _namesbyclass =
		new HashMap<>();
	
	/** Main entry point arguments. */
	private final String[] _args;
	
	/** Long to string map. */
	private final Map<Long, String> _strlongtostring =
		new HashMap<>();
	
	/** String to long map. */
	private final Map<String, Long> _strstringtolong =
		new HashMap<>();
	
	/** System properties. */
	final Map<String, String> _sysproperties;
	
	/** The next thread ID to use. */
	private volatile int _nextthreadid;
	
	/** The next long to choose. */
	private long _strnextlong;
	
	/** Is the VM exiting? */
	private volatile boolean _exiting;
	
	/** Exit code of the VM. */
	volatile int _exitcode;
	
	/**
	 * Initializes the virtual machine.
	 *
	 * @param __sm The manager for suites.
	 * @param __cl The class loader.
	 * @param __tm Task manager.
	 * @param __bootcl The boot class.
	 * @param __bootmid The boot class a midlet.
	 * @param __bootdx The entry point which should be booted when the VM
	 * runs.
	 * @param __gd Guest depth.
	 * @param __profiler The profiler to use.
	 * @param __sprops System properties.

	 * @param __args Main entry point arguments.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/09/03
	 */
	public SpringMachine(VMSuiteManager __sm, SpringClassLoader __cl,
		SpringTaskManager __tm, String __bootcl, boolean __bootmid,
		int __bootdx, int __gd, ProfilerSnapshot __profiler,
		Map<String, String> __sprops, String... __args)
		throws NullPointerException
	{
		if (__cl == null || __sm == null)
			throw new NullPointerException("NARG");
		
		this.suites = __sm;
		this.classloader = __cl;
		this.tasks = __tm;
		this.bootcl = __bootcl;
		this.bootmid = __bootmid;
		this.bootdx = __bootdx;
		this.guestdepth = __gd;
		this._args = (__args == null ? new String[0] : __args.clone());
		this.profiler = (__profiler != null ? __profiler :
			new ProfilerSnapshot());
		this._sysproperties = (__sprops == null ?
			new HashMap<String, String>() : new HashMap<>(__sprops));
		
		// Setup resource accessor
................................................................................
	{
		return this.classloader;
	}
	
	/**
	 * Creates a new thread within the virtual machine.
	 *
	 * @param __n The name of the thread.


	 * @return The newly created thread.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/09/01
	 */
	public final SpringThread createThread(String __n)
		throws NullPointerException
	{
		if (__n == null)
			throw new NullPointerException("NARG");
		
		// Store thread
		List<SpringThread> threads = this._threads;
		synchronized (threads)
		{




			// Initialize new thread
			int v;
			SpringThread rv = new SpringThread((v = ++this._nextthreadid), __n,


				this.profiler.measureThread(String.format("%s-vm%08x-%d-%s",
				this.classloader.bootLibrary().name(),
				System.identityHashCode(this), v, __n)));



			
			// Store thread
			threads.add(rv);
			return rv;
		}
	}
	
	/**
	 * Resolves the given string pointer.
	 *
	 * @param __p The pointer.
	 * @return The string at the given pointer or {@code null} if it has no
	 * resolution.
	 * @since 2018/09/29
	 */
	public final String debugResolveString(long __p)
	{
		if (__p == -1L)
			return null;
		
		synchronized (this.strlock)
		{
			return this._strlongtostring.get(__p);
		}
	}
	
	/**
	 * Unresolves the given string.
	 *
	 * @param __s The string to unresolve.
	 * @return The pointer to the string.
	 * @since 2018/09/29
	 */
	public final long debugUnresolveString(String __s)
	{
		if (__s == null)
			return -1L;
		
		synchronized (this.strlock)
		{
			Long rv = this._strstringtolong.get(__s);
			if (rv != null)
				return rv.longValue();
			
			Long next = Long.valueOf(++this._strnextlong);
			this._strstringtolong.put(__s, next);
			this._strlongtostring.put(next, __s);
			
			return next;
		}
	}
	
	/**
	 * Exits the virtual machine.
	 *
	 * @param __code The exit code.
	 * @throws SpringMachineExitException To signal virtual machine exit.
	 * @since 2018/10/13
	 */
................................................................................
	public final void exitNoException(int __code)
		throws SpringMachineExitException
	{
		// Set as exiting
		this._exitcode = __code;
		this._exiting = true;
	}











	
	/**
	 * Gets the thread by the given ID.
	 *
	 * @param __id The ID of the thread.
	 * @return The thread by this ID or {@code null} if it was not found.


	 * @since 2018/11/21
	 */
	public final SpringThread getThread(int __id)

	{
		List<SpringThread> threads = this._threads;
		synchronized (threads)
		{
			for (SpringThread t : threads)
				if (t.id == __id)
					return t;
		}
		
		return null;







































	}
	
	/**
	 * Returns the static field for the given field.
	 *
	 * @param __f The field to get the static field for.
	 * @return The static field.
................................................................................
	 * @return The number of active and alive threads.
	 * @since 2018/09/03
	 */
	public final int numThreads()
	{
		// Store thread
		List<SpringThread> threads = this._threads;
		synchronized (threads)
		{
			return threads.size();
		}
	}
	
	/**
	 * Returns the access for resources.
................................................................................
	/**
	 * {@inheritDoc}
	 * @since 2018/09/13
	 */
	@Override
	public final void run()
	{
		// Obtain the boot library to read entry points from
		SpringClassLoader classloader = this.classloader;
		VMClassLibrary bootbin = classloader.bootLibrary();
		
		// May be specified or not
		String entryclass = this.bootcl;
		boolean ismidlet = this.bootmid;
		int launchid = this.bootdx;
		
		// Lookup the entry class via the manifest
		if (entryclass == null)
		{
			// Need to load the manifest where the entry points will be
			EntryPoints entries;
			try (InputStream in = bootbin.resourceAsStream(
				"META-INF/MANIFEST.MF"))
			{
				// {@squirreljme.error BK1a Entry point JAR has no manifest.
				// (The name of the boot binary)}
				if (in == null)
					throw new SpringVirtualMachineException("BK1a " +
						bootbin.name());
				
				entries = new EntryPoints(new JavaManifest(in));
			}
			
			// {@squirreljme.error BK1b Failed to read the manifest.}
			catch (IOException e)
			{
				throw new SpringVirtualMachineException("BK1b", e);
			}
			
			int n = entries.size();
			
			// Print entry points out out for debug, but only for the first
			// guest because this is annoying!
			if (GuestDepth.guestDepth() + 1 == this.guestdepth)
			{
				todo.DEBUG.note("Entry points:");
				for (int i = 0; i < n; i++)
					todo.DEBUG.note("    %d: %s", i, entries.get(i));
			}
			
			// Use the first program if the ID is not valid
			if (launchid < 0 || launchid >= n)
				launchid = 0;
			
			// Needed to enter the machine
			EntryPoint entry = entries.get(launchid);
			entryclass = entry.entryPoint().toString();
			ismidlet = entry.isMidlet();
		}
		
		// Thread that will be used as the main thread of execution, also used
		// to initialize classes when they are requested
		SpringThread mainthread = this.createThread("main");
		
		// We will be using the same logic in the thread worker if we need to
		// initialize any objects or arguments
		SpringThreadWorker worker = new SpringThreadWorker(this,
			mainthread, true);
		mainthread._worker = worker;
		
		// Load the entry point class
		SpringClass entrycl = worker.loadClass(new ClassName(
			entryclass.replace('.', '/')));
		
		// Find the method to be entered in
		SpringMethod mainmethod;
		if (ismidlet)
			mainmethod = entrycl.lookupMethod(false,
				new MethodNameAndType("startApp", "()V"));
		else
			mainmethod = entrycl.lookupMethod(true,
				new MethodNameAndType("main", "([Ljava/lang/String;)V"));
		
		// Setup object to initialize with for thread
		SpringVMStaticMethod vmsm = new SpringVMStaticMethod(mainmethod);
		
		// Determine the entry argument, midlets is just the class to run
		Object entryarg;
		if (ismidlet)
			entryarg = worker.asVMObject(entryclass.replace('.', '/'));
		else
		{
			String[] inargs = this._args;
			int inlen = inargs.length;
			
			// Setup array
			SpringArrayObject outargs = worker.allocateArray(
				worker.resolveClass(new ClassName("java/lang/String")), inlen);
			
			// Initialize the argument array
			for (int i = 0; i < inlen; i++)
				outargs.set(i, worker.asVMObject(inargs[i]));
			
			entryarg = outargs;
		}
		
		// Setup new thread object



		SpringObject threadobj = worker.newInstance(worker.loadClass(
			new ClassName("java/lang/Thread")), new MethodDescriptor(
			"(Ljava/lang/String;ILcc/squirreljme/runtime/cldc/asm/" +
			"StaticMethod;Ljava/lang/Object;)V"), worker.asVMObject("Main"),
			(ismidlet ? 3 : 4), vmsm, entryarg);
		
		// Enter the frame for that method using the arguments we passed (in
		// a static fashion)
		mainthread.enterFrame(worker.loadClass(
			new ClassName("java/lang/Thread")).lookupMethod(false,
			new MethodNameAndType("__start", "()V")), threadobj);
		
		// The main although it executes in this context will always have the
		// same exact logic as other threads running apart from this main
		// thread, so no code is needed to be duplicated at all.
		try
		{
			worker.run();
		}
		
		// Virtual machine exited, do not print fatal trace just exit here
		catch (SpringMachineExitException e)
		{
			throw e;
		}
		
		// Ooopsie!
		catch (RuntimeException e)
		{
			/*PrintStream err = System.err;
			
			err.println("****************************");
			
			// Print the real stack trace
			err.println("*** EXTERNAL STACK TRACE ***");
			e.printStackTrace(err);
			err.println();
			
			// Print the VM seen stack trace
			err.println("*** INTERNAL STACK TRACE ***");
			mainthread.printStackTrace(err);
			err.println();
			
			err.println("****************************");*/
			
			// Retoss
			throw e;
		}
		
		// Wait until all threads have terminated before actually leaving
		for (;;)
		{
			// Check if the VM is exiting, this would have happen if another
			// thread called exit
			// If we do not check, then the VM will never exit even after
			// another thread has exited
			this.exitCheck();
			
			// No more threads left?
			int okay = 0,
				notokay = 0;
			List<SpringThread> threads = this._threads;
			synchronized (threads)
			{
				for (SpringThread t : threads)
					if (t.isExitOkay())
						okay++;
					else
						notokay++;
			}
			
			// Okay to exit?
			if (notokay == 0)
				return;
			
			// Wait a short duration before checking again
			try
			{
				Thread.sleep(500);
			}
			catch (InterruptedException e)
			{
			}
		}
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/17
	 */
	@Override
................................................................................
			err.println();
			
			err.println("****************************");
			
			return TaskAccess.EXIT_CODE_FATAL_EXCEPTION;
		}
	}























	
	/**
	 * Returns the suite manager which is available.
	 *
	 * @return The suite manager that is available.
	 * @since 2018/10/26
	 */







<
<
<
<
|



|
|
>
>



>


>




<
<










|
|
|
>
>
>
>








|
<
<
<
<
<
<







|
|




<
<
<
<







 







<
<
<
<
<
<
<
<






<
<
<













<
<
<
<


>





|
|
|








|
|
<
<







 







|
>
>




|
<

<
<
<


|

>
>
>
>


|
>
>


|
>
>
>







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







>
>
>
>
>
>
>
>
>
>
>





|
>
>



>


|






|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|




|
|

|
|
<
<
<
<
<
<
<
<
|
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
>
>
|
|
|
|
<
<
<
<
<
<
<









|
<
<
<
<
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







6
7
8
9
10
11
12




13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57






58
59
60
61
62
63
64
65
66
67
68
69
70




71
72
73
74
75
76
77
..
87
88
89
90
91
92
93








94
95
96
97
98
99



100
101
102
103
104
105
106
107
108
109
110
111
112




113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133


134
135
136
137
138
139
140
...
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

166



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192













































193
194
195
196
197
198
199
...
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
...
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
...
370
371
372
373
374
375
376





















































377
378
379
380
381
382
383
384
385
386
387
388








389

390
























391
392
393
394
395
396
397







398
399
400
401
402
403
404
405
406
407






408
409

















410
411




































412
413
414
415
416
417
418
...
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;





import cc.squirreljme.emulator.profiler.ProfilerSnapshot;
import cc.squirreljme.emulator.vm.VMResourceAccess;
import cc.squirreljme.emulator.vm.VMSuiteManager;
import cc.squirreljme.emulator.vm.VirtualMachine;
import cc.squirreljme.runtime.cldc.asm.TaskAccess;
import cc.squirreljme.vm.springcoat.exceptions.SpringFatalException;
import cc.squirreljme.vm.springcoat.exceptions.SpringMachineExitException;
import cc.squirreljme.vm.springcoat.exceptions.SpringVirtualMachineException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.ConstantValueString;
import net.multiphasicapps.classfile.MethodDescriptor;
import net.multiphasicapps.classfile.MethodNameAndType;



/**
 * This class contains the instance of the SpringCoat virtual machine and has
 * a classpath along with all the needed storage for variables and such.
 *
 * @since 2018/07/29
 */
public final class SpringMachine
	implements Runnable, VirtualMachine
{
	/** The class which contains the thread starting point. */
	private static final ClassName _START_CLASS =
		new ClassName("java/lang/__Start__");
	
	/** The method to enter for main threads. */
	private static final MethodNameAndType _MAIN_THREAD_METHOD =
		new MethodNameAndType("__main", "()V");
	
	/** The class loader. */
	protected final SpringClassLoader classloader;
	
	/** Resources accessor. */
	protected final VMResourceAccess resourceaccessor;
	
	/** The boot class. */
	protected final String bootClass;






	
	/** The manager for suites. */
	protected final VMSuiteManager suites;
	
	/** Task manager. */
	protected final SpringTaskManager tasks;
	
	/** The global VM state. */
	protected final GlobalState globalState;
	
	/** The profiling information. */
	protected final ProfilerSnapshot profiler;
	




	/** Threads which are available. */
	private final List<SpringThread> _threads =
		new ArrayList<>();
	
	/** Static fields which exist within the virtual machine. */
	private final Map<SpringField, SpringFieldStorage> _staticfields =
		new HashMap<>();
................................................................................
	/** Class names by their objects. */
	private final Map<SpringObject, ClassName> _namesbyclass =
		new HashMap<>();
	
	/** Main entry point arguments. */
	private final String[] _args;
	








	/** System properties. */
	final Map<String, String> _sysproperties;
	
	/** The next thread ID to use. */
	private volatile int _nextthreadid;
	



	/** Is the VM exiting? */
	private volatile boolean _exiting;
	
	/** Exit code of the VM. */
	volatile int _exitcode;
	
	/**
	 * Initializes the virtual machine.
	 *
	 * @param __sm The manager for suites.
	 * @param __cl The class loader.
	 * @param __tm Task manager.
	 * @param __bootcl The boot class.




	 * @param __profiler The profiler to use.
	 * @param __sprops System properties.
	 * @param __gs Global system state.
	 * @param __args Main entry point arguments.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/09/03
	 */
	public SpringMachine(VMSuiteManager __sm, SpringClassLoader __cl,
		SpringTaskManager __tm, String __bootcl,
		ProfilerSnapshot __profiler, Map<String, String> __sprops,
		GlobalState __gs, String... __args)
		throws NullPointerException
	{
		if (__cl == null || __sm == null)
			throw new NullPointerException("NARG");
		
		this.suites = __sm;
		this.classloader = __cl;
		this.tasks = __tm;
		this.bootClass = __bootcl;
		this.globalState = __gs;


		this._args = (__args == null ? new String[0] : __args.clone());
		this.profiler = (__profiler != null ? __profiler :
			new ProfilerSnapshot());
		this._sysproperties = (__sprops == null ?
			new HashMap<String, String>() : new HashMap<>(__sprops));
		
		// Setup resource accessor
................................................................................
	{
		return this.classloader;
	}
	
	/**
	 * Creates a new thread within the virtual machine.
	 *
	 * @param __n The name of the thread, may be {@code null} in which case
	 * the thread will just get an ID number.
	 * @param __main Is this a main thread?
	 * @return The newly created thread.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/09/01
	 */
	public final SpringThread createThread(String __n, boolean __main)

	{



		// Store thread
		List<SpringThread> threads = this._threads;
		synchronized (this)
		{
			// The name of the thread to use
			String usedName = (__n != null ? __n :
				"hwThread-" + this.numThreads());
			
			// Initialize new thread
			int v;
			SpringThread rv = new SpringThread(
				(v = ++this._nextthreadid), __main,
				usedName,
				this.profiler.measureThread(String.format("%s-vm%08x-%d-%s",
				this.classloader.bootLibrary().name(),
				System.identityHashCode(this), v, usedName)));
			
			// Signal that a major state has changed
			this.notifyAll();
			
			// Store thread
			threads.add(rv);
			return rv;
		}
	}
	













































	/**
	 * Exits the virtual machine.
	 *
	 * @param __code The exit code.
	 * @throws SpringMachineExitException To signal virtual machine exit.
	 * @since 2018/10/13
	 */
................................................................................
	public final void exitNoException(int __code)
		throws SpringMachineExitException
	{
		// Set as exiting
		this._exitcode = __code;
		this._exiting = true;
	}
	
	/**
	 * Returns the main arguments.
	 *
	 * @return The main arguments.
	 * @since 2020/06/17
	 */
	public final String[] getMainArguments()
	{
		return this._args.clone();
	}
	
	/**
	 * Gets the thread by the given ID.
	 *
	 * @param __id The ID of the thread.
	 * @return The thread by this ID.
	 * @throws NoSuchElementException If there is no thread that exists by
	 * that ID.
	 * @since 2018/11/21
	 */
	public final SpringThread getThread(int __id)
		throws NoSuchElementException
	{
		List<SpringThread> threads = this._threads;
		synchronized (this)
		{
			for (SpringThread t : threads)
				if (t.id == __id)
					return t;
		}
		
		throw new NoSuchElementException("No such thread ID: " + __id);
	}
	
	/**
	 * Returns all of the process threads.
	 *
	 * @return All of the current process threads.
	 * @since 2020/06/17
	 */
	@SuppressWarnings("UnnecessaryLocalVariable")
	public final SpringThread[] getThreads()
	{
		List<SpringThread> rv = new ArrayList<>();
		
		// Go through threads but also cleanup any that have ended
		List<SpringThread> threads = this._threads;
		synchronized (this)
		{
			for (Iterator<SpringThread> it = threads.iterator(); it.hasNext();)
			{
				SpringThread thread = it.next();
				
				// If the thread is terminating, clean it up
				if (thread.isTerminated())
				{
					// Remove it
					it.remove();
					
					// Signal that a state of a thread has changed
					this.notifyAll();
				}
				
				// Otherwise add it
				else
					rv.add(thread);
			}
		}
		
		// Use whatever was found
		return rv.<SpringThread>toArray(new SpringThread[rv.size()]);
	}
	
	/**
	 * Returns the static field for the given field.
	 *
	 * @param __f The field to get the static field for.
	 * @return The static field.
................................................................................
	 * @return The number of active and alive threads.
	 * @since 2018/09/03
	 */
	public final int numThreads()
	{
		// Store thread
		List<SpringThread> threads = this._threads;
		synchronized (this)
		{
			return threads.size();
		}
	}
	
	/**
	 * Returns the access for resources.
................................................................................
	/**
	 * {@inheritDoc}
	 * @since 2018/09/13
	 */
	@Override
	public final void run()
	{





















































		// Thread that will be used as the main thread of execution, also used
		// to initialize classes when they are requested
		SpringThread mainThread = this.createThread("main", true);
		
		// We will be using the same logic in the thread worker if we need to
		// initialize any objects or arguments
		SpringThreadWorker worker = new SpringThreadWorker(this,
			mainThread, true);
		mainThread._worker = worker;
		
		// Enter the main entry point which handles the thread logic
		mainThread.enterFrame(worker.loadClass(SpringMachine._START_CLASS)








			.lookupMethod(true, SpringMachine._MAIN_THREAD_METHOD));

		
























		// Initialize an instance of Thread for this thread, as this is
		// very important, the call to create VM threads will bind the instance
		// object and the vm thread together.
		worker.newInstance(
			new ClassName("java/lang/Thread"),
			new MethodDescriptor("(Ljava/lang/String;)V"),
			worker.asVMObject("main"));







		
		// The main although it executes in this context will always have the
		// same exact logic as other threads running apart from this main
		// thread, so no code is needed to be duplicated at all.
		try
		{
			worker.run();
		}
		
		// Either failed or threw exit exception






		catch (RuntimeException e)
		{

















			throw e;
		}




































	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/17
	 */
	@Override
................................................................................
			err.println();
			
			err.println("****************************");
			
			return TaskAccess.EXIT_CODE_FATAL_EXCEPTION;
		}
	}
	
	/**
	 * Sets the current exit code.
	 * 
	 * @param __exitCode The exit code to set.
	 * @since 2020/06/27
	 */
	public final void setExitCode(int __exitCode)
	{
		this._exitcode = __exitCode;
	}
	
	/**
	 * Signals that the given thread terminated.
	 * 
	 * @param __thread The thread that was terminated.
	 * @since 2020/06/29
	 */
	public void signalThreadTerminate(SpringThread __thread)
	{
		// The act of getting all threads will clear out terminated threads
		this.getThreads();
	}
	
	/**
	 * Returns the suite manager which is available.
	 *
	 * @return The suite manager that is available.
	 * @since 2018/10/26
	 */

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringMonitor.java.

6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
..
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
..
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
..
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
...
122
123
124
125
126
127
128
129
130
131
132




















133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
...
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
...
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.runtime.cldc.asm.ObjectAccess;


/**
 * This is a monitor which is associated with an object.
 *
 * @since 2018/09/15
 */
public final class SpringMonitor
{
	/** The monitor lock. */
	protected final Object lock =
		new Object();
	
	/** The thread which owns this monitor. */
	volatile SpringThread _owner;
	
	/** Number of threads which are waiting on this monitor. */
	volatile int _waitcount;
	
	/** The number of notifications happening. */
................................................................................
	public final void enter(SpringThread __t)
		throws NullPointerException
	{
		if (__t == null)
			throw new NullPointerException("NARG");
		
		// Lock on the monitor lock
		Object lock = this.lock;
		for (;;)
			synchronized (lock)
			{
				// We take possession of this monitor
				SpringThread owner = this._owner;
				if (owner == null)
				{
					this._owner = __t;
					this._count = 1;
................................................................................
				
				// Need to wait for it to be cleared
				else
				{
					// Wait for lock to be freed
					try
					{
						lock.wait();
					}
					catch (InterruptedException e)
					{
						// Ignore
					}
				}
			}
................................................................................
	public final void exit(SpringThread __t, boolean __notify)
		throws NullPointerException, SpringIllegalMonitorStateException
	{
		if (__t == null)
			throw new NullPointerException("NARG");
		
		// Lock on the monitor lock
		Object lock = this.lock;
		synchronized (lock)
		{
			// {@squirreljme.error BK1c This thread does not own the
			// monitor.}
			if (this._owner != __t)
				throw new SpringIllegalMonitorStateException("BK1c");	
			
			// {@squirreljme.error BK1d No previous entry call was made.
................................................................................
			if (count <= 0)
			{
				this._owner = null;
				
				// Wake up all threads so that they try and lock on the lock
				// so whoever gets that chance
				if (__notify)
					lock.notifyAll();
			}
		}
	}




















	
	/**
	 * Notifies on this monitor and returns the status.
	 *
	 * @param __by The thread that is doing the notify.
	 * @param __all Notify all threads?
	 * @return The notification status.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/20
	 */
	public final int monitorNotify(SpringThread __by, boolean __all)
		throws NullPointerException
	{
		if (__by == null)
			throw new NullPointerException("NARG");
		
		// Lock on the monitor lock
		Object lock = this.lock;
		synchronized (lock)
		{
			// Wrong thread?
			if (this._owner != __by)
				return ObjectAccess.MONITOR_NOT_OWNED;
			
			// Nothing is waiting, do not bother at all!
			int waitcount = this._waitcount;
			if (waitcount == 0)
				return 0;
			
			// Notify all threads or just one?
			// Never let the notify count exceed the wait count as well
			int notifycount = this._notifycount;
			this._notifycount = Math.min(waitcount,
				(__all ? waitcount : notifycount + 1));
			
			// Notify all threads that something happened with the lock
			lock.notifyAll();
			
			return 0;
		}
	}
	
	/**
	 * Waits on the monitor.
	 *
	 * @param __by The thread doing the wait.
	 * @param __ms The milliseconds to wait.
	 * @param __ns The nanoseconds to wait.
	 * @return The wait result.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/21
	 */
	public final int monitorWait(SpringThread __by, long __ms, int __ns)
		throws NullPointerException
	{
		if (__by == null)
			throw new NullPointerException("NARG");
		
		// Lock on the monitor lock
		Object lock = this.lock;
		synchronized (lock)
		{
			// Wrong thread?
			if (this._owner != __by)
				return ObjectAccess.MONITOR_NOT_OWNED;
			
			// Increase our wait count
			this._waitcount++;
			
			// Relinquish control of this monitor, so that way when we actually
			// internally do the wait we check notify counts and such.
			this.exit(__by, true);
................................................................................
						this._notifycount = waitcount;
					
					// Re-enter the monitor
					this.enter(__by);
					
					// Whatever state we ended up in
					if (interrupted)
						return ObjectAccess.MONITOR_INTERRUPTED;
					return ObjectAccess.MONITOR_NOT_INTERRUPTED;
				}
				
				// Otherwise wait for notification to happen
				else
				{
					// Could be interrupted
					try
................................................................................
							if (rem <= 0)
							{
								expired = true;
								continue;
							}
							
							// Wait for this time
							lock.wait(rem / 1_000_000L,
								(int)(rem % 1_000_000L));
						}
						
						// Wait forever
						else
						{
							lock.wait();
						}
					}
					
					// Was interrupted
					catch (InterruptedException e)
					{
						interrupted = true;
					}
				}
			}
		}
	}
	
	/**
	 * Waiting information on this monitor.
	 *
	 * @since 2018/11/20
	 */
	private static final class __Waiting__
	{
	}
}








|
>








<
<
<
<







 







<

|







 







|







 







<
|







 







|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|










<
|



|













|











|










<
|



|







 







|
|







 







|






|











<
<
<
<
<
<
<
<
<



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22




23
24
25
26
27
28
29
..
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56
57
..
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
..
94
95
96
97
98
99
100

101
102
103
104
105
106
107
108
...
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205

206
207
208
209
210
211
212
213
214
215
216
217
...
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
...
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292









293
294
295
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.mle.constants.MonitorResultType;
import cc.squirreljme.vm.springcoat.exceptions.SpringIllegalMonitorStateException;

/**
 * This is a monitor which is associated with an object.
 *
 * @since 2018/09/15
 */
public final class SpringMonitor
{




	/** The thread which owns this monitor. */
	volatile SpringThread _owner;
	
	/** Number of threads which are waiting on this monitor. */
	volatile int _waitcount;
	
	/** The number of notifications happening. */
................................................................................
	public final void enter(SpringThread __t)
		throws NullPointerException
	{
		if (__t == null)
			throw new NullPointerException("NARG");
		
		// Lock on the monitor lock

		for (;;)
			synchronized (this)
			{
				// We take possession of this monitor
				SpringThread owner = this._owner;
				if (owner == null)
				{
					this._owner = __t;
					this._count = 1;
................................................................................
				
				// Need to wait for it to be cleared
				else
				{
					// Wait for lock to be freed
					try
					{
						this.wait();
					}
					catch (InterruptedException e)
					{
						// Ignore
					}
				}
			}
................................................................................
	public final void exit(SpringThread __t, boolean __notify)
		throws NullPointerException, SpringIllegalMonitorStateException
	{
		if (__t == null)
			throw new NullPointerException("NARG");
		
		// Lock on the monitor lock

		synchronized (this)
		{
			// {@squirreljme.error BK1c This thread does not own the
			// monitor.}
			if (this._owner != __t)
				throw new SpringIllegalMonitorStateException("BK1c");	
			
			// {@squirreljme.error BK1d No previous entry call was made.
................................................................................
			if (count <= 0)
			{
				this._owner = null;
				
				// Wake up all threads so that they try and lock on the lock
				// so whoever gets that chance
				if (__notify)
					this.notifyAll();
			}
		}
	}
	
	/**
	 * Checks if this monitor is held by the given thread.
	 * 
	 * @param __vmThread The virtual machine thread.
	 * @return If this is held by the given thread.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/27
	 */
	public boolean isHeldBy(SpringThread __vmThread)
		throws NullPointerException
	{
		if (__vmThread == null)
			throw new NullPointerException("NARG");
		
		synchronized (this)
		{
			return this._owner == __vmThread;
		}
	}
	
	/**
	 * Notifies on this monitor and returns the status.
	 *
	 * @param __by The thread that is doing the notify.
	 * @param __all Notify all threads?
	 * @return The {@link MonitorResultType}.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/20
	 */
	public final int monitorNotify(SpringThread __by, boolean __all)
		throws NullPointerException
	{
		if (__by == null)
			throw new NullPointerException("NARG");
		
		// Lock on the monitor lock

		synchronized (this)
		{
			// Wrong thread?
			if (this._owner != __by)
				return MonitorResultType.NOT_OWNED;
			
			// Nothing is waiting, do not bother at all!
			int waitcount = this._waitcount;
			if (waitcount == 0)
				return 0;
			
			// Notify all threads or just one?
			// Never let the notify count exceed the wait count as well
			int notifycount = this._notifycount;
			this._notifycount = Math.min(waitcount,
				(__all ? waitcount : notifycount + 1));
			
			// Notify all threads that something happened with the lock
			this.notifyAll();
			
			return 0;
		}
	}
	
	/**
	 * Waits on the monitor.
	 *
	 * @param __by The thread doing the wait.
	 * @param __ms The milliseconds to wait.
	 * @param __ns The nanoseconds to wait.
	 * @return The {@link MonitorResultType}.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/21
	 */
	public final int monitorWait(SpringThread __by, long __ms, int __ns)
		throws NullPointerException
	{
		if (__by == null)
			throw new NullPointerException("NARG");
		
		// Lock on the monitor lock

		synchronized (this)
		{
			// Wrong thread?
			if (this._owner != __by)
				return MonitorResultType.NOT_OWNED;
			
			// Increase our wait count
			this._waitcount++;
			
			// Relinquish control of this monitor, so that way when we actually
			// internally do the wait we check notify counts and such.
			this.exit(__by, true);
................................................................................
						this._notifycount = waitcount;
					
					// Re-enter the monitor
					this.enter(__by);
					
					// Whatever state we ended up in
					if (interrupted)
						return MonitorResultType.INTERRUPTED;
					return MonitorResultType.NOT_INTERRUPTED;
				}
				
				// Otherwise wait for notification to happen
				else
				{
					// Could be interrupted
					try
................................................................................
							if (rem <= 0)
							{
								expired = true;
								continue;
							}
							
							// Wait for this time
							this.wait(rem / 1_000_000L,
								(int)(rem % 1_000_000L));
						}
						
						// Wait forever
						else
						{
							this.wait();
						}
					}
					
					// Was interrupted
					catch (InterruptedException e)
					{
						interrupted = true;
					}
				}
			}
		}









	}
}

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringNullObject.java.

6
7
8
9
10
11
12



13
14
15
16
17
18
19
..
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;




/**
 * Represents the null object.
 *
 * @since 2018/09/08
 */
public final class SpringNullObject
	implements SpringObject
................................................................................
	 * @since 2018/09/15
	 */
	@Override
	public final SpringMonitor monitor()
	{
		// {@squirreljme.error BK1e Cannot obtain the monitor of an object
		// that is null.}
		throw new SpringNullPointerException("BK1e");
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2019/12/21
	 */
	@Override
	public final SpringPointerArea pointerArea()
	{
		return SpringPointerArea.NULL;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/09/09
	 */
	@Override
	public final SpringClass type()
	{
		return null;
	}
}








>
>
>







 







|



|
|


|

|













6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.vm.springcoat.brackets.RefLinkHolder;
import cc.squirreljme.vm.springcoat.exceptions.SpringVirtualMachineException;

/**
 * Represents the null object.
 *
 * @since 2018/09/08
 */
public final class SpringNullObject
	implements SpringObject
................................................................................
	 * @since 2018/09/15
	 */
	@Override
	public final SpringMonitor monitor()
	{
		// {@squirreljme.error BK1e Cannot obtain the monitor of an object
		// that is null.}
		throw new SpringVirtualMachineException("BK1e");
	}
	
	/**
	 * {@inheritDoc
	 * @since 2020/05/31
	 */
	@Override
	public RefLinkHolder refLink()
	{
		throw new SpringVirtualMachineException("NULL has no refLink.");
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/09/09
	 */
	@Override
	public final SpringClass type()
	{
		return null;
	}
}

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringObject.java.

6
7
8
9
10
11
12


13
14
15
16
17
18
19
..
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;



/**
 * This represents anything that is treated by the virtual machine as a kind
 * of object reference. This is needed for SquirrelJME since it exposes a
 * pointer logic which is magically handled by the virtual machine.
 *
 * @since 2018/09/08
 */
................................................................................
	 *
	 * @return This object's monitor.
	 * @since 2018/09/15
	 */
	SpringMonitor monitor();
	
	/**
	 * Returns the pointer area for this object.
	 *
	 * @return The pointer area for this object.
	 * @since 2019/12/21
	 */
	SpringPointerArea pointerArea();
	
	/**
	 * Returns the object type.
	 *
	 * @return The object type.
	 * @since 2018/09/09
	 */
	SpringClass type();
}








>
>







 







|

|
|

|










6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.vm.springcoat.brackets.RefLinkHolder;

/**
 * This represents anything that is treated by the virtual machine as a kind
 * of object reference. This is needed for SquirrelJME since it exposes a
 * pointer logic which is magically handled by the virtual machine.
 *
 * @since 2018/09/08
 */
................................................................................
	 *
	 * @return This object's monitor.
	 * @since 2018/09/15
	 */
	SpringMonitor monitor();
	
	/**
	 * Returns the reference link holder for this object.
	 *
	 * @return The reference link for the object.
	 * @since 2020/05/31
	 */
	RefLinkHolder refLink();
	
	/**
	 * Returns the object type.
	 *
	 * @return The object type.
	 * @since 2018/09/09
	 */
	SpringClass type();
}

Deleted emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringPointerArea.java.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

/**
 * This represents a new area where pointers can go.
 *
 * @since 2019/12/21
 */
public final class SpringPointerArea
	implements Comparable<SpringPointerArea>
{
	/** Null pointer. */
	public static final SpringPointerArea NULL =
		new SpringPointerArea(0, 0);
	
	/** The base address. */
	public final int base;
	
	/** The length of the area. */
	public final int length;
	
	/**
	 * Initializes the pointer area.
	 *
	 * @param __b The basee.
	 * @param __l The length.
	 * @throws IllegalArgumentException If the length is negative.
	 * @since 2019/12/21
	 */
	public SpringPointerArea(int __b, int __l)
		throws IllegalArgumentException
	{
		// {@squirreljme.error BK3f Cannot have a negative length pointer
		// area.}
		if (__l < 0)
			throw new IllegalArgumentException("BK3f");
		
		this.base = __b;
		this.length = __l;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2019/12/21
	 */
	@Override
	public final int compareTo(SpringPointerArea __o)
	{
		throw new todo.TODO();
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2019/12/21
	 */
	@Override
	public final boolean equals(Object __o)
	{
		throw new todo.TODO();
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2019/12/21
	 */
	@Override
	public final int hashCode()
	{
		throw new todo.TODO();
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2019/12/21
	 */
	@Override
	public final String toString()
	{
		throw new todo.TODO();
	}
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































Deleted emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringPointerManager.java.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;

/**
 * This is used to manage pointers within SpringCoat.
 *
 * @since 2019/12/21
 */
public final class SpringPointerManager
{
	/** Queue for cleared references. */
	private final ReferenceQueue<SpringObject> _queue =
		new ReferenceQueue<>();
	
	/** Reference to integer. */
	private final Map<Reference<SpringObject>, Integer> _rtoi =
		new HashMap<>();
	
	/** Integer to reference. */
	private final Map<Integer, Reference<SpringObject>> _itor =
		new HashMap<>();
	
	/** The next allocation address. */
	private int _next =
		4;
	
	/**
	 * Allocates and returns a new pointer area.
	 *
	 * @param __l The length to allocate.
	 * @return The resulting pointer.
	 * @throws IllegalArgumentException If the length is negative.
	 * @since 2019/12/21
	 */
	public final SpringPointerArea allocate(int __l)
		throws IllegalArgumentException
	{
		// {@squirreljme.error BK3g Cannot allocate negative pointer space.}
		if (__l < 0)
			throw new IllegalArgumentException("BK3g");
		
		// Determine base pointer
		int base = this._next;
		
		// {@squirreljme.error BK3h Ran out of address space allocating
		// object. (The requested length)}
		if (base < 0)
			throw new SpringVirtualMachineException("BK3h " + __l);
		
		// Set next position
		this._next = base + ((__l + 3) & ~3);
		
		// Build pointer here
		return new SpringPointerArea(base, __l);
	}
	
	/**
	 * Allocates a pointer of the given length and binds the specified object
	 * to that pointer.
	 *
	 * @param __l The length to allocate.
	 * @param __o The object to bind.
	 * @return The resulting pointer.
	 * @throws IllegalArgumentException If the length is negative.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/12/22
	 */
	public final SpringPointerArea allocateAndBind(int __l, SpringObject __o)
		throws IllegalArgumentException, NullPointerException
	{
		if (__o == null)
			throw new NullPointerException("NARG");
		
		// Allocate pointer
		SpringPointerArea rv = this.allocate(__l);
		
		// Setup reference
		Reference<SpringObject> ref = new WeakReference(__o, this._queue);
		
		// Bind it
		synchronized (this)
		{
			Integer ibase = rv.base;
			
			// Store into both referencing maps
			this._rtoi.put(ref, ibase);
			this._itor.put(ibase, ref);
		}
		
		// Return the result
		return rv;
	}
	
	/**
	 * Locates the object at the given address.
	 *
	 * @param __p The object to find.
	 * @return The object which was found.
	 * @since 2019/12/22
	 */
	public final SpringObject findObject(int __p)
	{
		// Zero address always returns null pointers!
		if (__p == 0)
			return SpringNullObject.NULL;
		
		// Need to use both maps
		Map<Reference<SpringObject>, Integer> rtoi = this._rtoi;
		Map<Integer, Reference<SpringObject>> itor = this._itor;
		
		// Lock on self
		synchronized (this)
		{
			// First try to cleanup anything that was cleared reference
			// wise
			ReferenceQueue<SpringObject> queue = this._queue;
			for (;;)
			{
				// Any new ones appeared?
				Reference<? extends SpringObject> polled = queue.poll();
				if (polled == null)
					break;
				
				// Read integer base
				Integer ibase = rtoi.get(polled);
				
				// Clear from both maps
				rtoi.remove(polled);
				itor.remove(ibase);
			}
			
			// Try to find object reference
			Reference<SpringObject> ref = itor.get(__p);
			
			// {@squirreljme.error BK3i Could not find object referenced at
			// the given pointer. (The requested address)}
			SpringObject rv = (ref != null ? ref.get() : null);
			if (rv == null)
				throw new SpringVirtualMachineException(
					String.format("BK3i @%08x", __p));
			
			return rv;
		}
	}
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































Deleted emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringPrimitiveReference.java.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

/**
 * This interface represents a base reference.
 *
 * @since 2018/09/23
 */
public abstract class SpringPrimitiveReference
	implements SpringObject
{
	/**
	 * Gets the object from this reference.
	 *
	 * @return The value of the reference.
	 * @since 2018/09/23
	 */
	public abstract SpringObject get();
	
	/**
	 * Sets the reference to the given object.
	 *
	 * @param __o The object to set.
	 * @since 2018/09/23
	 */
	public abstract void set(SpringObject __o);
	
	/**
	 * {@inheritDoc}
	 * @since 2018/09/23
	 */
	@Override
	public final SpringMonitor monitor()
	{
		// {@squirreljme.error BK1f Reference types are special and have no
		// monitor.}
		throw new SpringVirtualMachineException("BK1f");
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2019/12/21
	 */
	@Override
	public final SpringPointerArea pointerArea()
	{
		throw new todo.TODO();
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/09/23
	 */
	@Override
	public final SpringClass type()
	{
		// {@squirreljme.error BK1g Reference types are special and have no
		// class.}
		throw new SpringVirtualMachineException("BK1g");
	}
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































Deleted emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringPrimitiveWeakReference.java.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import java.lang.ref.Reference;
import java.lang.ref.WeakReference;

/**
 * This class stores information for weak references.
 *
 * @since 2018/09/23
 */
public final class SpringPrimitiveWeakReference
	extends SpringPrimitiveReference
{
	/** The reference used. */
	private Reference<SpringObject> _ref;
	
	/**
	 * {@inheritDoc}
	 * @since 2018/09/23
	 */
	@Override
	public final SpringObject get()
	{
		Reference<SpringObject> ref = this._ref;
		if (ref != null)
			return ref.get();
		return null;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/09/23
	 */
	@Override
	public final void set(SpringObject __o)
	{
		this._ref = new WeakReference<>(__o);
	}
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringSimpleObject.java.

6
7
8
9
10
11
12

13
14
15
16
17
18
19
..
24
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
..
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
..
92
93
94
95
96
97
98
















99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;


import java.lang.ref.Reference;
import java.lang.ref.WeakReference;

/**
 * This is a representation of an object within the virtual machine.
 *
 * @since 2018/09/08
................................................................................
	/** The type of object this is. */
	protected final SpringClass type;
	
	/** The monitor for this object, every object has one. */
	protected final SpringMonitor monitor =
		new SpringMonitor();
	
	/** The pointer for this object. */
	protected final SpringPointerArea pointer;

	
	/** Field storage in the class. */
	private final SpringFieldStorage[] _fields;
	
	/** String representation. */
	private Reference<String> _string;
	
	/**
	 * Initializes the object.
	 *
	 * @param __cl The class of the object.
	 * @param __spm The manager for pointers.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/09/08
	 */
	public SpringSimpleObject(SpringClass __cl, SpringPointerManager __spm)
		throws NullPointerException
	{
		if (__cl == null || __spm == null)
			throw new NullPointerException("NARG");
		
		this.type = __cl;
		
		// Setup field array
		int n;
		SpringFieldStorage[] fields;
................................................................................
		this._fields = (fields =
			new SpringFieldStorage[(n = __cl.instanceFieldCount())]);
		
		// Initialize variable for all fields
		int i = 0;
		for (SpringField f : __cl.fieldTable())
			fields[i++] = new SpringFieldStorage(f);
		
		// Allocate pointer
		this.pointer = __spm.allocateAndBind(__cl.instancesize, this);
	}
	
	/**
	 * Returns the field by the given field.
	 *
	 * @param __f The field to get.
	 * @return The storage for the field.
................................................................................
	 * @return The storage for the field by the specified index.
	 * @since 2018/09/16
	 */
	public final SpringFieldStorage fieldByIndex(int __dx)
	{
		return this._fields[__dx];
	}
















	
	/**
	 * {@inheritDoc}
	 * @since 2018/09/15
	 */
	@Override
	public final SpringMonitor monitor()
	{
		return this.monitor;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2019/12/21
	 */
	@Override
	public final SpringPointerArea pointerArea()
	{
		return this.pointer;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/09/15
	 */
	@Override







>







 







|
|
>











<



|


|







 







<
<
<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>













|


|

|







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
..
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53
54
55
56
57
58
59
..
60
61
62
63
64
65
66



67
68
69
70
71
72
73
..
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.vm.springcoat.brackets.RefLinkHolder;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;

/**
 * This is a representation of an object within the virtual machine.
 *
 * @since 2018/09/08
................................................................................
	/** The type of object this is. */
	protected final SpringClass type;
	
	/** The monitor for this object, every object has one. */
	protected final SpringMonitor monitor =
		new SpringMonitor();
	
	/** The reference link holder. */
	protected final RefLinkHolder refLink =
		new RefLinkHolder();
	
	/** Field storage in the class. */
	private final SpringFieldStorage[] _fields;
	
	/** String representation. */
	private Reference<String> _string;
	
	/**
	 * Initializes the object.
	 *
	 * @param __cl The class of the object.

	 * @throws NullPointerException On null arguments.
	 * @since 2018/09/08
	 */
	public SpringSimpleObject(SpringClass __cl)
		throws NullPointerException
	{
		if (__cl == null)
			throw new NullPointerException("NARG");
		
		this.type = __cl;
		
		// Setup field array
		int n;
		SpringFieldStorage[] fields;
................................................................................
		this._fields = (fields =
			new SpringFieldStorage[(n = __cl.instanceFieldCount())]);
		
		// Initialize variable for all fields
		int i = 0;
		for (SpringField f : __cl.fieldTable())
			fields[i++] = new SpringFieldStorage(f);



	}
	
	/**
	 * Returns the field by the given field.
	 *
	 * @param __f The field to get.
	 * @return The storage for the field.
................................................................................
	 * @return The storage for the field by the specified index.
	 * @since 2018/09/16
	 */
	public final SpringFieldStorage fieldByIndex(int __dx)
	{
		return this._fields[__dx];
	}
	
	/**
	 * Returns the field by the name and type.
	 *
	 * @param __static Is this field static?
	 * @param __name The name of the field.
	 * @param __type The type of the field.
	 * @return The storage for the field.
	 * @since 2020/06/17
	 */
	public final SpringFieldStorage fieldByNameAndType(boolean __static,
		String __name, String __type)
	{
		return this.fieldByField(
			this.type().lookupField(__static, __name, __type));
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/09/15
	 */
	@Override
	public final SpringMonitor monitor()
	{
		return this.monitor;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/05/31
	 */
	@Override
	public RefLinkHolder refLink()
	{
		return this.refLink;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/09/15
	 */
	@Override

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringTaskManager.java.

7
8
9
10
11
12
13

14
15
16

17
18
19
20
21
22
23
..
32
33
34
35
36
37
38



39
40
41
42
43
44
45
..
62
63
64
65
66
67
68

69
70
71
72
73
74
75
..
82
83
84
85
86
87
88



89
90
91
92
93
94
95
...
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.runtime.cldc.asm.TaskAccess;

import cc.squirreljme.runtime.swm.EntryPoints;
import cc.squirreljme.vm.VMClassLibrary;
import cc.squirreljme.emulator.vm.VMSuiteManager;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import javax.microedition.swm.TaskStatus;
import cc.squirreljme.emulator.profiler.ProfilerSnapshot;
import net.multiphasicapps.tool.manifest.JavaManifest;
................................................................................
{
	/** The manager for suites. */
	protected final VMSuiteManager suites;
	
	/** The profiling information. */
	protected final ProfilerSnapshot profiler;
	



	/** Tasks that are used. */
	private final Map<Integer, SpringTask> _tasks =
		new HashMap<>();
	
	/** System properties. */
	private final Map<String, String> _sysprops;
	
................................................................................
		if (__sm == null)
			throw new NullPointerException("NARG");
		
		this.suites = __sm;
		this.profiler = (__ps == null ? new ProfilerSnapshot() : __ps);
		this._sysprops = (__sp == null ? new HashMap<String, String>() :
			new HashMap<>(__sp));

	}
	
	/**
	 * Starts the specified task.
	 *
	 * @param __cp The class path to use.
	 * @param __entry The entry point.
................................................................................
	public final int startTask(String[] __cp, String __entry, String[] __args,
		int __gd)
		throws NullPointerException
	{
		if (__cp == null || __entry == null || __args == null)
			throw new NullPointerException("NARG");
		



		VMSuiteManager suites = this.suites;
		
		// Load classpath libraries
		int cpn = __cp.length;
		VMClassLibrary[] scl = new VMClassLibrary[cpn];
		for (int i = 0; i < cpn; i++)
		{
................................................................................
		// Could not find the boot point
		if (bootdx < 0)
			return TaskAccess.ERROR_INVALID_ENTRY;
		
		// Build machine for the task
		SpringMachine machine = new SpringMachine(suites,
			new SpringClassLoader(scl), this, null,
			false, bootdx, __gd + 1,
			this.profiler, this._sysprops, __args);
		
		// Lock on tasks
		Map<Integer, SpringTask> tasks = this._tasks;
		synchronized (tasks)
		{
			// Next task ID
			int tid = ++this._nextid;







>



>







 







>
>
>







 







>







 







>
>
>







 







<
|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
..
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
..
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
...
146
147
148
149
150
151
152

153
154
155
156
157
158
159
160
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.runtime.cldc.asm.TaskAccess;
import cc.squirreljme.runtime.cldc.debug.Debugging;
import cc.squirreljme.runtime.swm.EntryPoints;
import cc.squirreljme.vm.VMClassLibrary;
import cc.squirreljme.emulator.vm.VMSuiteManager;
import cc.squirreljme.vm.springcoat.exceptions.SpringVirtualMachineException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import javax.microedition.swm.TaskStatus;
import cc.squirreljme.emulator.profiler.ProfilerSnapshot;
import net.multiphasicapps.tool.manifest.JavaManifest;
................................................................................
{
	/** The manager for suites. */
	protected final VMSuiteManager suites;
	
	/** The profiling information. */
	protected final ProfilerSnapshot profiler;
	
	/** Global state. */
	protected final GlobalState globalState;
	
	/** Tasks that are used. */
	private final Map<Integer, SpringTask> _tasks =
		new HashMap<>();
	
	/** System properties. */
	private final Map<String, String> _sysprops;
	
................................................................................
		if (__sm == null)
			throw new NullPointerException("NARG");
		
		this.suites = __sm;
		this.profiler = (__ps == null ? new ProfilerSnapshot() : __ps);
		this._sysprops = (__sp == null ? new HashMap<String, String>() :
			new HashMap<>(__sp));
		this.globalState = new GlobalState();
	}
	
	/**
	 * Starts the specified task.
	 *
	 * @param __cp The class path to use.
	 * @param __entry The entry point.
................................................................................
	public final int startTask(String[] __cp, String __entry, String[] __args,
		int __gd)
		throws NullPointerException
	{
		if (__cp == null || __entry == null || __args == null)
			throw new NullPointerException("NARG");
		
		if (true)
			throw Debugging.todo("Tasks changed completely!!");
		
		VMSuiteManager suites = this.suites;
		
		// Load classpath libraries
		int cpn = __cp.length;
		VMClassLibrary[] scl = new VMClassLibrary[cpn];
		for (int i = 0; i < cpn; i++)
		{
................................................................................
		// Could not find the boot point
		if (bootdx < 0)
			return TaskAccess.ERROR_INVALID_ENTRY;
		
		// Build machine for the task
		SpringMachine machine = new SpringMachine(suites,
			new SpringClassLoader(scl), this, null,

			this.profiler, this._sysprops, this.globalState, __args);
		
		// Lock on tasks
		Map<Integer, SpringTask> tasks = this._tasks;
		synchronized (tasks)
		{
			// Next task ID
			int tid = ++this._nextid;

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringThread.java.

7
8
9
10
11
12
13





14
15
16
17
18
19
20
..
28
29
30
31
32
33
34



35
36
37
38
39
40
41
42
43
44
45
46
47
48






49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67



68
69
70
71

72
73
74
75
76

77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
...
106
107
108
109
110
111
112





113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
...
150
151
152
153
154
155
156





157
158
159
160
161
162
163
...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
...
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
...
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271





































































































272
273
274
275
276
277
278
279
280

























281
282
283
284
285
286
287
...
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
...
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
...
348
349
350
351
352
353
354
355

356


357
358
359















360
361
362
363



364
365

366
367
368

369
370
371













372

373
374
375


376
377
378
379
380
381
382
383
384

385
386









































387
388
389
390
391
392
393
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.SystemCallIndex;





import java.io.PrintStream;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import net.multiphasicapps.classfile.ByteCode;
import cc.squirreljme.emulator.profiler.ProfiledThread;
................................................................................
{
	/** Maximum depth of the stack. */
	public static final int MAX_STACK_DEPTH =
		64;
	
	/** The thread ID. */
	protected final int id;



	
	/** The name of this thread. */
	protected final String name;
	
	/** Profiler information. */
	protected final ProfiledThread profiler;
	
	/** System call errors. */
	final int[] _syscallerrors =
		new int[SystemCallIndex.NUM_SYSCALLS];
	
	/** The stack frames. */
	private final List<SpringThread.Frame> _frames =
		new ArrayList<>();






		
	/** String representation. */
	private Reference<String> _string;
	
	/** Ran at least one frame (was started)? */
	private volatile boolean _hadoneframe;
	
	/** Is this a daemon thread? */
	volatile boolean _daemon;
	
	/** Terminate the thread? */
	volatile boolean _terminate;
	
	/** Did we signal exit? */
	volatile boolean _signaledexit;
	
	/** The current worker for the thread. */
	volatile SpringThreadWorker _worker;
	



	/**
	 * Initializes the thread.
	 *
	 * @param __id The thread ID.

	 * @param __n The name of the thread.
	 * @param __profiler Profiled storage.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/09/01
	 */

	SpringThread(int __id, String __n, ProfiledThread __profiler)
		throws NullPointerException
	{
		if (__n == null)
			throw new NullPointerException("NARG");
		
		this.id = __id;

		this.name = __n;
		this.profiler = __profiler;
	}
	
	/**
	 * Returns the current frame of execution or {@code null} if there is none.
	 *
	 * @return The current frame of execution or {@code null} if there is none.
	 * @since 2018/09/03
	 */
	public final SpringThread.Frame currentFrame()
	{
		List<SpringThread.Frame> frames = this._frames;
		synchronized (frames)
		{
			if (frames.isEmpty())
				return null;
			return frames.get(frames.size() - 1);
		}
	}
	
................................................................................
	 * Enters a blank frame to store data.
	 *
	 * @return The
	 * @since 2018/09/20
	 */
	public final SpringThread.Frame enterBlankFrame()
	{





		// Setup blank frame
		SpringThread.Frame rv = new SpringThread.Frame();
		
		// {@squirreljme.error BK1j Stack overflow.}
		List<SpringThread.Frame> frames = this._frames;
		if (frames.size() >= SpringThread.MAX_STACK_DEPTH)
			throw new SpringVirtualMachineException("BK1j");
		
		// Lock on frames as a new one is added
		synchronized (frames)
		{
			frames.add(rv);
		}
		
		// Profile for this frame
		this.profiler.enterFrame("<blank>", "<blank>", "()V",
			System.nanoTime());
		
		// Had one frame (started)
		this._hadoneframe = true;
		
		// Undo termination
		this._terminate = false;
		
		return rv;
	}
	
	/**
	 * Enters the specified method and sets up a stack frame for it.
	 *
	 * @param __m The method to enter.
................................................................................
	public final SpringThread.Frame enterFrame(SpringMethod __m,
		Object... __args)
		throws NullPointerException, SpringVirtualMachineException
	{
		if (__m == null)
			throw new NullPointerException("NARG");
		





		if (__args == null)
			__args = new Object[0];
		
		// Debug
		/*todo.DEBUG.note("enterFrame(%s::%s, %s)", __m.inClass(),
			__m.nameAndType(), Arrays.<Object>asList(__args));*/
		
................................................................................
		// Profile for this frame
		this.profiler.enterFrame(__m.inClass().toString(),
			__m.nameAndType().name().toString(),
			__m.nameAndType().type().toString(), System.nanoTime());
		
		// Lock on frames as a new one is added
		List<SpringThread.Frame> frames = this._frames;
		synchronized (frames)
		{
			frames.add(rv);
		}
		
		// Had one frame (started)
		this._hadoneframe = true;
		
		// Undo termination
		this._terminate = false;
		
		// Handle synchronized method
		if (__m.flags().isSynchronized())
		{
			SpringObject monitor;
			
			// Monitor on the class object, needs the worker since we need to
			// load a class
................................................................................
	 *
	 * @since 2018/11/17
	 */
	public final void exitAllFrames()
	{
		// Lock on frames as a new one is added
		List<SpringThread.Frame> frames = this._frames;
		synchronized (frames)
		{
			frames.clear();
		}
	}
	
	/**
	 * Returns all of the frames which are available.
................................................................................
	 * @return All of the available stack frames.
	 * @since 2018/09/16
	 */
	public final SpringThread.Frame[] frames()
	{
		// Lock on frames
		List<SpringThread.Frame> frames = this._frames;
		synchronized (frames)
		{
			return frames.<SpringThread.Frame>toArray(
				new SpringThread.Frame[frames.size()]);
		}
	}
	
	/**





































































































	 * Is exiting the virtual machine okay?
	 *
	 * @return If it is okay to exit.
	 * @since 2018/11/17
	 */
	public final boolean isExitOkay()
	{
		return this._daemon || this._terminate;
	}

























	
	/**
	 * Returns the name of the thread.
	 *
	 * @return The name of the thread.
	 * @since 2018/09/03
	 */
................................................................................
	 *
	 * @return The number of available frames.
	 * @since 2018/09/03
	 */
	public final int numFrames()
	{
		List<SpringThread.Frame> frames = this._frames;
		synchronized (frames)
		{
			return frames.size();
		}
	}
	
	/**
	 * Pops a frame from the thread stack.
................................................................................
	{
		// Exit the frame
		this.profiler.exitFrame(System.nanoTime());
		
		// Pop from the stack
		SpringThread.Frame rv;
		List<SpringThread.Frame> frames = this._frames;
		synchronized (frames)
		{
			// {@squirreljme.error BK1o No frames to pop.}
			int n;
			if ((n = frames.size()) <= 0)
				throw new SpringVirtualMachineException("BK1o");	
			
			rv = frames.remove(n - 1);
................................................................................
	 */
	public final void printStackTrace(PrintStream __ps)
		throws NullPointerException
	{
		if (__ps == null)
			throw new NullPointerException("NARG");
		
		// Note the thread

		__ps.printf("Thread #%d: %s%n", this.id, this.name);


		
		// Lock since the frames may change!
		List<SpringThread.Frame> frames = this._frames;















		synchronized (frames)
		{
			// The frames at the end are at the top
			for (int n = frames.size(), i = n - 1; i >= 0; i--)



			{
				SpringThread.Frame frame = frames.get(i);

				
				// Do not print traces for blank frames
				if (frame.isBlank())

				{
					__ps.printf("    at <guard frame>%n");
					continue;













				}

				
				SpringMethod inmethod = frame.method();
				int pc = frame.lastExecutedPc();


				
				// Print information
				__ps.printf("    at %s.%s @ %d [%s] (%s:%d)%n",
					inmethod.inClass(),
					inmethod.nameAndType(),
					pc,
					inmethod.byteCode().getByAddress(pc).mnemonic(),
					inmethod.inFile(),
					inmethod.byteCode().lineOfAddress(pc));

			}
		}









































	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/09/15
	 */
	@Override







>
>
>
>
>







 







>
>
>







<
<
<
<



>
>
>
>
>
>










<
<
<






>
>
>




>





>
|






>













|







 







>
>
>
>
>









|











<
<
<







 







>
>
>
>
>







 







|







<
<
<







 







|







 







|







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







 







|







 







|
>
|
>
>
|
<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

<
<
>
>
>
|
<
>
|
<
<
>
|
<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
<
<
>
>
|
<
<
<
<
<
<
<
<
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49




50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
...
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151



152
153
154
155
156
157
158
...
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
...
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207



208
209
210
211
212
213
214
...
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
...
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
...
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
...
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
...
491
492
493
494
495
496
497
498
499
500
501
502
503


504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520


521
522
523
524

525
526


527
528


529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544


545
546
547








548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.SystemCallIndex;
import cc.squirreljme.runtime.cldc.debug.CallTraceElement;
import cc.squirreljme.runtime.cldc.debug.CallTraceUtils;
import cc.squirreljme.vm.springcoat.brackets.VMThreadObject;
import cc.squirreljme.vm.springcoat.exceptions.SpringNullPointerException;
import cc.squirreljme.vm.springcoat.exceptions.SpringVirtualMachineException;
import java.io.PrintStream;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import net.multiphasicapps.classfile.ByteCode;
import cc.squirreljme.emulator.profiler.ProfiledThread;
................................................................................
{
	/** Maximum depth of the stack. */
	public static final int MAX_STACK_DEPTH =
		64;
	
	/** The thread ID. */
	protected final int id;
	
	/** Is this a main thread? */
	protected final boolean main;
	
	/** The name of this thread. */
	protected final String name;
	
	/** Profiler information. */
	protected final ProfiledThread profiler;
	




	/** The stack frames. */
	private final List<SpringThread.Frame> _frames =
		new ArrayList<>();
	
	/** The thread's {@link Thread} instance. */
	private SpringObject _threadInstance;
	
	/** The thread's VM Thread instance. */
	private VMThreadObject _vmThread;
		
	/** String representation. */
	private Reference<String> _string;
	
	/** Ran at least one frame (was started)? */
	private volatile boolean _hadoneframe;
	
	/** Is this a daemon thread? */
	volatile boolean _daemon;
	



	/** Did we signal exit? */
	volatile boolean _signaledexit;
	
	/** The current worker for the thread. */
	volatile SpringThreadWorker _worker;
	
	/** Terminate the thread? */
	private volatile boolean _terminate;
	
	/**
	 * Initializes the thread.
	 *
	 * @param __id The thread ID.
	 * @param __main Is this a main thread.
	 * @param __n The name of the thread.
	 * @param __profiler Profiled storage.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/09/01
	 */
	SpringThread(int __id, boolean __main, String __n,
		ProfiledThread __profiler)
		throws NullPointerException
	{
		if (__n == null)
			throw new NullPointerException("NARG");
		
		this.id = __id;
		this.main = __main;
		this.name = __n;
		this.profiler = __profiler;
	}
	
	/**
	 * Returns the current frame of execution or {@code null} if there is none.
	 *
	 * @return The current frame of execution or {@code null} if there is none.
	 * @since 2018/09/03
	 */
	public final SpringThread.Frame currentFrame()
	{
		List<SpringThread.Frame> frames = this._frames;
		synchronized (this)
		{
			if (frames.isEmpty())
				return null;
			return frames.get(frames.size() - 1);
		}
	}
	
................................................................................
	 * Enters a blank frame to store data.
	 *
	 * @return The
	 * @since 2018/09/20
	 */
	public final SpringThread.Frame enterBlankFrame()
	{
		// Cannot enter frames when terminated
		if (this.isTerminated())
			throw new SpringVirtualMachineException(
				"Cannot enter frame on terminated thread.");
		
		// Setup blank frame
		SpringThread.Frame rv = new SpringThread.Frame();
		
		// {@squirreljme.error BK1j Stack overflow.}
		List<SpringThread.Frame> frames = this._frames;
		if (frames.size() >= SpringThread.MAX_STACK_DEPTH)
			throw new SpringVirtualMachineException("BK1j");
		
		// Lock on frames as a new one is added
		synchronized (this)
		{
			frames.add(rv);
		}
		
		// Profile for this frame
		this.profiler.enterFrame("<blank>", "<blank>", "()V",
			System.nanoTime());
		
		// Had one frame (started)
		this._hadoneframe = true;
		



		return rv;
	}
	
	/**
	 * Enters the specified method and sets up a stack frame for it.
	 *
	 * @param __m The method to enter.
................................................................................
	public final SpringThread.Frame enterFrame(SpringMethod __m,
		Object... __args)
		throws NullPointerException, SpringVirtualMachineException
	{
		if (__m == null)
			throw new NullPointerException("NARG");
		
		// Cannot enter frames when terminated
		if (this.isTerminated())
			throw new SpringVirtualMachineException(
				"Cannot enter frame on terminated thread.");
		
		if (__args == null)
			__args = new Object[0];
		
		// Debug
		/*todo.DEBUG.note("enterFrame(%s::%s, %s)", __m.inClass(),
			__m.nameAndType(), Arrays.<Object>asList(__args));*/
		
................................................................................
		// Profile for this frame
		this.profiler.enterFrame(__m.inClass().toString(),
			__m.nameAndType().name().toString(),
			__m.nameAndType().type().toString(), System.nanoTime());
		
		// Lock on frames as a new one is added
		List<SpringThread.Frame> frames = this._frames;
		synchronized (this)
		{
			frames.add(rv);
		}
		
		// Had one frame (started)
		this._hadoneframe = true;
		



		// Handle synchronized method
		if (__m.flags().isSynchronized())
		{
			SpringObject monitor;
			
			// Monitor on the class object, needs the worker since we need to
			// load a class
................................................................................
	 *
	 * @since 2018/11/17
	 */
	public final void exitAllFrames()
	{
		// Lock on frames as a new one is added
		List<SpringThread.Frame> frames = this._frames;
		synchronized (this)
		{
			frames.clear();
		}
	}
	
	/**
	 * Returns all of the frames which are available.
................................................................................
	 * @return All of the available stack frames.
	 * @since 2018/09/16
	 */
	public final SpringThread.Frame[] frames()
	{
		// Lock on frames
		List<SpringThread.Frame> frames = this._frames;
		synchronized (this)
		{
			return frames.<SpringThread.Frame>toArray(
				new SpringThread.Frame[frames.size()]);
		}
	}
	
	/**
	 * Returns the stack trace for this thread.
	 * 
	 * @return The stack trace for this thread.
	 * @since 2020/06/13
	 */
	public final CallTraceElement[] getStackTrace()
	{
		// Lock since the frames may change!
		List<SpringThread.Frame> frames = this._frames;
		synchronized (this)
		{
			// Setup target array
			int n = frames.size();
			CallTraceElement[] rv = new CallTraceElement[n];
			
			// The frames at the end are at the top
			for (int i = n - 1, write = 0; i >= 0; i--, write++)
			{
				SpringThread.Frame frame = frames.get(i);
				CallTraceElement trace;
				
				// Blanks are purely virtual standing points so they are
				// regarded as such
				if (frame.isBlank())
				{
					trace = new CallTraceElement(
						"<guard>", "<guard>", null,
						0L, null, -1);
				}
				
				// Print other parts
				else
				{
					SpringMethod inMethod = frame.method();
					int pc = frame.lastExecutedPc();
					
					trace = new CallTraceElement(
						inMethod.inClass().toString(),
						inMethod.name().toString(),
						inMethod.nameAndType().type().toString(),
						0,
						inMethod.infile,
						inMethod.byteCode().lineOfAddress(pc),
						inMethod.byteCode().getByAddress(pc).operation(),
						pc);
				}
				
				// Store trace in top-most order
				rv[write] = trace;
			}
			
			return rv;
		}
	}
	
	/**
	 * Interrupts this thread.
	 * 
	 * @since 2020/06/22
	 */
	public final void hardInterrupt()
	{
		SpringThreadWorker worker = this._worker;
		if (worker == null)
			throw new RuntimeException(
				"Cannot interrupt thread with no worker.");
		
		// Signal the other thread or something else?
		Thread signal = this._worker.signalinstead;
		if (signal != null)
			signal.interrupt();
		else
			worker.interrupt();
	}
	
	/**
	 * Returns whether or not this thread has an instance.
	 *
	 * @return If this thread has an instance.
	 * @since 2020/06/18
	 */
	public final boolean hasThreadInstance()
	{
		synchronized (this)
		{
			return this._threadInstance != null;
		}
	}
	
	/**
	 * Is this a daemon thread?
	 *
	 * @return If this is a daemon thread.
	 * @since 2020/06/17
	 */
	public final boolean isDaemon()
	{
		return this._daemon;
	}
	
	/**
	 * Is exiting the virtual machine okay?
	 *
	 * @return If it is okay to exit.
	 * @since 2018/11/17
	 */
	public final boolean isExitOkay()
	{
		return this._daemon || this._terminate;
	}
	
	/**
	 * If this is a main thread or not.
	 *
	 * @return If this is a main thread.
	 * @since 2020/06/17
	 */
	public final boolean isMain()
	{
		return this.main;
	}
	
	/**
	 * Returns if this thread has terminated.
	 * 
	 * @return If this thread has terminated.
	 * @since 2020/06/29
	 */
	public final boolean isTerminated()
	{
		synchronized (this)
		{
			return this._terminate;
		}
	}
	
	/**
	 * Returns the name of the thread.
	 *
	 * @return The name of the thread.
	 * @since 2018/09/03
	 */
................................................................................
	 *
	 * @return The number of available frames.
	 * @since 2018/09/03
	 */
	public final int numFrames()
	{
		List<SpringThread.Frame> frames = this._frames;
		synchronized (this)
		{
			return frames.size();
		}
	}
	
	/**
	 * Pops a frame from the thread stack.
................................................................................
	{
		// Exit the frame
		this.profiler.exitFrame(System.nanoTime());
		
		// Pop from the stack
		SpringThread.Frame rv;
		List<SpringThread.Frame> frames = this._frames;
		synchronized (this)
		{
			// {@squirreljme.error BK1o No frames to pop.}
			int n;
			if ((n = frames.size()) <= 0)
				throw new SpringVirtualMachineException("BK1o");	
			
			rv = frames.remove(n - 1);
................................................................................
	 */
	public final void printStackTrace(PrintStream __ps)
		throws NullPointerException
	{
		if (__ps == null)
			throw new NullPointerException("NARG");
		
		// Use standard SquirrelJME trace printing here
		CallTraceUtils.printStackTrace(__ps,
			String.format("Thread #%d: %s", this.id, this.name),
			this.getStackTrace(), null, null,
			0);
	}


	
	/**
	 * Sets the {@link Thread} instance.
	 *
	 * @param __object The object to set the instance to.
	 * @throws IllegalStateException If this thread already has an instance.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/17
	 */
	public final void setThreadInstance(SpringObject __object)
		throws IllegalStateException, NullPointerException
	{
		if (__object == null)
			throw new NullPointerException("NARG");
		
		synchronized (this)
		{


			// Only a single instance is permitted
			if (this._threadInstance != null)
				throw new IllegalStateException("Thread has an instance.");
			

			this._threadInstance = __object;
		}


	}
	


	/**
	 * Sets the virtual machine thread of this thread.
	 *
	 * @param __vmThread The thread to set.
	 * @throws IllegalStateException If this thread already has one.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/17
	 */
	public final void setVMThread(VMThreadObject __vmThread)
		throws IllegalStateException, NullPointerException
	{
		if (__vmThread == null)
			throw new NullPointerException("NARG");
		
		synchronized (this)
		{


			if (this._vmThread != null)
				throw new IllegalStateException("Thread has VM Thread.");
			








			this._vmThread = __vmThread;
		}
	}
	
	/**
	 * Terminates this thread.
	 * 
	 * @since 2020/06/29
	 */
	public final void terminate()
	{
		// Terminates this thread
		synchronized (this)
		{
			// Set as terminated
			this._terminate = true;
		}
		
		// Signal to the machine that this thread terminated
		SpringThreadWorker worker = this._worker;
		if (worker != null)
			worker.machine.signalThreadTerminate(this);
	}
	
	/**
	 * Returns the instance of the {@link Thread} object for this thread.
	 *
	 * @return The instance of {@link Thread}.
	 * @throws IllegalStateException If the thread has no instance.
	 * @since 2020/06/17
	 */
	public final SpringObject threadInstance()
		throws IllegalStateException
	{
		SpringObject rv;
		synchronized (this)
		{
			rv = this._threadInstance;
		}
		
		if (rv == null)
			throw new IllegalStateException("Thread has no state.");
		
		return rv;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/09/15
	 */
	@Override

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringThreadWorker.java.

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23




24
25
26
27
28
29
30
..
97
98
99
100
101
102
103
104
105
106

107
108
109
110
111

112
113
114
115
116
117



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
...
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
...
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
...
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
...
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372

373
374

375
376
377
378

379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402

403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
...
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595


596
597
598
599
600
601
602
...
605
606
607
608
609
610
611
612
613
614

615



616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640

641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657

658
659
660
661
662
663
664
665
666
667
668




669
670
671
672

673
674
675
676
677
678
679
...
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
...
988
989
990
991
992
993
994






















995
996
997
998

999
1000
1001
1002
1003
1004
1005
....
1101
1102
1103
1104
1105
1106
1107
1108

1109
1110
1111
1112
1113
1114

1115
1116
1117

1118
1119
1120
1121
1122
1123
1124
1125
1126

1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426


1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658


1659
1660
1661



1662
1663
1664
1665





1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710


1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780

1781
1782
1783
1784
1785
1786
1787
....
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
....
1845
1846
1847
1848
1849
1850
1851















1852
1853
1854
1855
1856
1857
1858
....
1916
1917
1918
1919
1920
1921
1922
1923



1924
1925
1926
1927
1928
1929
1930
1931
1932
....
1937
1938
1939
1940
1941
1942
1943



1944
1945
1946
1947
1948
1949
1950
....
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
....
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980





































1981
1982
1983
1984
1985
1986
1987
....
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
....
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
....
2306
2307
2308
2309
2310
2311
2312
2313

2314
2315
2316
2317
2318
2319
2320
....
2372
2373
2374
2375
2376
2377
2378

2379
2380
2381
2382
2383
2384
2385
....
3759
3760
3761
3762
3763
3764
3765
3766

3767
3768
3769
3770
3771
3772
3773
....
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
....
4563
4564
4565
4566
4567
4568
4569









4570
4571
4572
4573
4574
4575
4576
4577








4578
4579
4580
4581
4582
4583
4584
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.jvm.CallStackItem;
import cc.squirreljme.jvm.SystemCallError;
import cc.squirreljme.jvm.SystemCallIndex;
import cc.squirreljme.runtime.cldc.asm.ConsoleOutput;
import cc.squirreljme.runtime.cldc.asm.SystemAccess;
import cc.squirreljme.runtime.cldc.asm.SystemProperties;
import cc.squirreljme.runtime.cldc.lang.ApiLevel;
import cc.squirreljme.runtime.cldc.lang.OperatingSystemType;
import cc.squirreljme.vm.VMClassLibrary;
import java.io.IOException;
import java.io.OutputStream;




import java.io.PrintStream;
import java.util.Arrays;
import java.util.Map;
import net.multiphasicapps.classfile.ByteCode;
import net.multiphasicapps.classfile.ClassFlags;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.ConstantValue;
................................................................................
			throw new SpringVirtualMachineException("BK1x");
	}
	
	/**
	 * Allocates the memory needed to store an array of the given class and
	 * of the given length.
	 *
	 * @param __cl The component type.
	 * @param __l The length of the array.
	 * @return The allocated array.

	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/09/15
	 */
	public final SpringArrayObject allocateArray(SpringClass __cl, int __l)

		throws NullPointerException, SpringNegativeArraySizeException
	{
		if (__cl == null)
			throw new NullPointerException("NARG");
		
		SpringClass dim = this.resolveClass(__cl.name().addDimensions(1));



		switch (__cl.name().toString())
		{
				// Boolean
			case "boolean":
				return new SpringArrayObjectBoolean(dim, __cl, __l);
			
				// Byte
			case "byte":
				return new SpringArrayObjectByte(dim, __cl, __l);
				
				// Short
			case "short":
				return new SpringArrayObjectShort(dim, __cl, __l);
				
				// Char
			case "char":
				return new SpringArrayObjectChar(dim, __cl, __l);
				
				// Int
			case "int":
				return new SpringArrayObjectInteger(dim, __cl, __l);
				
				// Long
			case "long":
				return new SpringArrayObjectLong(dim, __cl, __l);
				
				// Float
			case "float":
				return new SpringArrayObjectFloat(dim, __cl, __l);
				
				// Float
			case "double":
				return new SpringArrayObjectDouble(dim, __cl, __l);
			
				// Generic array
			default:
				return new SpringArrayObjectGeneric(dim, __cl, __l);
		}
		
	}
	
	/**
	 * Allocates the memory needed to store an object of the given class.
	 *
................................................................................
		throws NullPointerException
	{
		if (__cl == null)
			throw new NullPointerException("NARG");
		
		// The called constructor will allocate the space needed to store
		// this object
		return new SpringSimpleObject(__cl, this.machine.pointers);
	}
	
	/**
	 * Converts the specified virtual machine object to a native object.
	 *
	 * @param __in The input object.
	 * @return The resulting native object.
................................................................................
	 */
	public final Object asNativeObject(Object __in)
		throws NullPointerException, SpringFatalException
	{
		if (__in == null)
			throw new NullPointerException("NARG");
		
		// Is null refernece
		else if (__in == SpringNullObject.NULL)
			return null;
		
		// Boxed types remain the same
		else if (__in instanceof Integer || __in instanceof Long ||
			__in instanceof Float || __in instanceof Double)
			return __in;
		
		// Array type
		else if (__in instanceof SpringArrayObject)
		{
			SpringArrayObject sao = (SpringArrayObject)__in;
			
			int len = sao.length();
			
			// Depends on the array type
			SpringClass sscl = sao.type();
			ClassName type = sscl.name();
			switch (type.toString())
			{
					// Char array
				case "[C":
					{
						char[] rv = new char[len];
						
						for (int i = 0; i < len; i++)
							rv[i] = (char)(sao.<Integer>get(Integer.class, i).
								intValue());
						
						return rv;
					}
					
					// String
				case "[Ljava/lang/String;":
					{
						String[] rv = new String[len];
						
						for (int i = 0; i < len; i++)
							rv[i] = this.<String>asNativeObject(String.class,
								sao.<SpringObject>get(SpringObject.class, i));
						
						return rv;
					}
				
					// {@squirreljme.error BK1y Do not know how to convert the
					// given virtual machine array to a native machine array.
					// (The input class)}
				default:
					throw new RuntimeException(
						String.format("BK1y %s", type));
			}
		}
		
		// Class type
		else if (__in instanceof SpringSimpleObject)
		{
			SpringSimpleObject sso = (SpringSimpleObject)__in;
			
			// Depends on the class type
................................................................................
		// {@squirreljme.error BK20 Do not know how to convert the given class
		// to a native machine object. (The input class)}
		else
			throw new SpringFatalException(
				String.format("BK20 %s", __in.getClass()));
	}
	
	/**
	 * Converts the specified object to a native object or unwraps an array
	 * for direct access.
	 *
	 * @param <C> The resulting class type.
	 * @param __cl The class to cast to.
	 * @param __in The input object.
	 * @return The resulting object.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/11/19
	 */
	public final <C> C asNativeObjectUnwrapArray(Class<C> __cl, Object __in)
		throws NullPointerException
	{
		if (__cl == null)
			throw new NullPointerException();
		
		if (__in instanceof SpringArrayObject)
			return __cl.cast(((SpringArrayObject)__in).array());
		return this.<C>asNativeObject(__cl, __in);
	}
	
	/**
	 * Converts the specified virtual machine object to a native object.
	 *
	 * @param <C> The class type.
	 * @param __cl The class type.
	 * @param __in The input object.
	 * @return The resulting native object.
................................................................................
		else if (__in instanceof Integer || __in instanceof Long ||
			__in instanceof Float || __in instanceof Double ||
			__in instanceof SpringObject)
			return __in;
		
		// Boolean to integer
		else if (__in instanceof Boolean)
			return Integer.valueOf((Boolean.TRUE.equals(__in) ? 1 : 0));
		
		// Character to Integer
		else if (__in instanceof Character)
			return Integer.valueOf(((Character)__in).charValue());
		
		// Promoted to integer
		else if (__in instanceof Byte || __in instanceof Short)
			return Integer.valueOf(((Number)__in).intValue());
		
		// Character array
		else if (__in instanceof char[])
		{

			char[] in = (char[])__in;
			

			// Setup return array
			int n = in.length;
			SpringArrayObject rv = this.allocateArray(
				this.loadClass(new ClassName("char")), n);

			
			// Copy array values
			for (int i = 0; i < n; i++)
				rv.set(i, (int)in[i]);
			
			return rv;
		}
		
		// Integer array
		else if (__in instanceof int[])
		{
			int[] in = (int[])__in;
			
			// Setup return array
			int n = in.length;
			SpringArrayObject rv = this.allocateArray(
				this.loadClass(new ClassName("int")), n);
			
			// Copy array values
			for (int i = 0; i < n; i++)
				rv.set(i, (int)in[i]);
			
			return rv;
		}

		
		// String array
		else if (__in instanceof String[])
		{
			String[] in = (String[])__in;
			
			// Setup return array
			int n = in.length;
			SpringArrayObject rv = this.allocateArray(
				this.loadClass(new ClassName("java/lang/String")), n);
			
			// Copy array values
			for (int i = 0; i < n; i++)
				rv.set(i, this.asVMObject(in[i]));
			
			return rv;
		}
		
		// Convertable exception
		else if (__in instanceof SpringConvertableThrowable)
		{
			SpringConvertableThrowable e = (SpringConvertableThrowable)__in;
			
			// Initialize new instance with this type, use the input message
			return this.newInstance(new ClassName(e.targetClass()),
				new MethodDescriptor("(Ljava/lang/String;)V"),
................................................................................
			{
				// Pre-cached object already exists?
				SpringObject rv = com.get(name);
				if (rv != null)
					return rv;
				
				// Resolve the input class, so it is initialized
				SpringClass resclass = (__noclassres ? this.loadClass(name) :
					this.resolveClass(name));
				
				// Resolve the class object
				SpringClass classobj = this.resolveClass(
					new ClassName("java/lang/Class"));
				
				// Copy interfaces into a class array
				SpringClass[] interfaces = resclass.interfaceClasses();
				int ni = interfaces.length;
				SpringArrayObject ints = this.allocateArray(classobj, ni);
				for (int i = 0; i < ni; i++)
					ints.set(i, this.asVMObject(interfaces[i]));
				
				// See if there is a default constructor
				SpringMethod defconmeth = resclass.lookupDefaultConstructor();
				
				// Get static method for this constructor
				int defconflags;
				SpringObject defconsm;
				if (defconmeth != null)
				{
					defconflags = defconmeth.flags().toJavaBits();
					defconsm = new SpringVMStaticMethod(defconmeth);
				}
				
				// There is none
				else
				{
					defconflags = 0;
					defconsm = SpringNullObject.NULL;
				}
				
				// Get the static method for enumeration values
				ClassFlags classflags = resclass.flags();
				SpringObject enumsm;
				if (classflags.isEnum())
					try
					{
						enumsm = new SpringVMStaticMethod(
							resclass.lookupMethod(true,
							new MethodName("values"),
							new MethodDescriptor(name.addDimensions(1).
							field())));
					}
					catch (SpringIncompatibleClassChangeException e)
					{
						enumsm = SpringNullObject.NULL;
					}
				else
					enumsm = SpringNullObject.NULL;
				
				// Initialize V1 class data which is initialized with class
				// data
				SpringObject cdata = this.newInstance(new ClassName(
					"cc/squirreljme/runtime/cldc/lang/ClassDataV1"),
					new MethodDescriptor("(ILjava/lang/String;" +
						"Ljava/lang/Class;[Ljava/lang/Class;" +
						"Ljava/lang/Class;Ljava/lang/String;II" +
						"Lcc/squirreljme/runtime/cldc/asm/StaticMethod;" +
						"Lcc/squirreljme/runtime/cldc/asm/StaticMethod;)V"),
					resclass.specialIndex(),
					this.asVMObject(name.toString(), true),
					this.asVMObject(resclass.superClass(), true),
					ints,
					(!resclass.isArray() ? SpringNullObject.NULL :
						this.asVMObject(resclass.componentType(), true)),
					this.asVMObject(resclass.inJar()),
					classflags.toJavaBits(),
					defconflags, defconsm, enumsm);
				
				// Initialize class with special class index and some class
				// information
				rv = this.newInstance(classobj.name(),
					new MethodDescriptor(
					"(Lcc/squirreljme/runtime/cldc/lang/ClassData;)V"), cdata);


				
				// Cache and use it
				com.put(name, rv);
				ocm.put(rv, name);
				return rv;
			}
		}
................................................................................
		// to a virtual machine object. (The input class)}
		else
			throw new RuntimeException(
				String.format("BK21 %s", __in.getClass()));
	}
	
	/**
	 * As VM object, but boxed if a primitive.
	 *
	 * @param __in The object to convert.

	 * @return The converted object.



	 * @since 2018/11/19
	 */
	public final Object asVMObjectBoxed(Object __in)
	{
		// Null is converted to null
		if (__in == null)
			return SpringNullObject.NULL;
		
		// Box these
		else if (__in instanceof Integer)
			return this.newInstance(new ClassName("java/lang/Integer"),
				new MethodDescriptor("(I)V"), __in);
		else if (__in instanceof Long)
			return this.newInstance(new ClassName("java/lang/Long"),
				new MethodDescriptor("(J)V"), __in);
		else if (__in instanceof Float)
			return this.newInstance(new ClassName("java/lang/Float"),
				new MethodDescriptor("(F)V"), __in);
		else if (__in instanceof Double)
			return this.newInstance(new ClassName("java/lang/Double"),
				new MethodDescriptor("(D)V"), __in);
		
		// As-is
		else if (__in instanceof SpringObject)
			return __in;

		
		else
			return this.asVMObject(__in);
	}
	
	/**
	 * As VM object, if it is an array it is wrapped otherwise if the object is
	 * a primitive type it becomes boxed.
	 *
	 * @param __in The object to convert.
	 * @return The converted object.
	 * @since 2018/12/03
	 */
	public final Object asVMObjectBoxedOrWrappedArray(Object __in)
	{
		if (__in == null)
			return SpringNullObject.NULL;

		
		// Array types
		else if (__in instanceof boolean[] ||
			__in instanceof byte[] ||
			__in instanceof short[] ||
			__in instanceof char[] ||
			__in instanceof int[] ||
			__in instanceof long[] ||
			__in instanceof float[] ||
			__in instanceof double[])
			return this.asWrappedArray(__in);




		
		// As boxed type instead
		else
			return this.asVMObjectBoxed(__in);

	}
	
	/**
	 * Wraps the native array so that it is directly read and written in
	 * the VM code.
	 *
	 * @param __a The object to convert.
................................................................................
		if (__a == null)
			return SpringNullObject.NULL;
		
		// Boolean
		else if (__a instanceof boolean[])
			return new SpringArrayObjectBoolean(
				this.loadClass(new ClassName("[Z")),
				this.loadClass(new ClassName("boolean")),
				(boolean[])__a);
		
		// Byte
		else if (__a instanceof byte[])
			return new SpringArrayObjectByte(
				this.loadClass(new ClassName("[B")),
				this.loadClass(new ClassName("byte")),
				(byte[])__a);
		
		// Short
		else if (__a instanceof short[])
			return new SpringArrayObjectShort(
				this.loadClass(new ClassName("[S")),
				this.loadClass(new ClassName("short")),
				(short[])__a);
		
		// Character
		else if (__a instanceof char[])
			return new SpringArrayObjectChar(
				this.loadClass(new ClassName("[C")),
				this.loadClass(new ClassName("char")),
				(char[])__a);
		
		// Integer
		else if (__a instanceof int[])
			return new SpringArrayObjectInteger(
				this.loadClass(new ClassName("[I")),
				this.loadClass(new ClassName("int")),
				(int[])__a);
		
		// Long
		else if (__a instanceof long[])
			return new SpringArrayObjectLong(
				this.loadClass(new ClassName("[J")),
				this.loadClass(new ClassName("long")),
				(long[])__a);
		
		// Float
		else if (__a instanceof float[])
			return new SpringArrayObjectFloat(
				this.loadClass(new ClassName("[F")),
				this.loadClass(new ClassName("float")),
				(float[])__a);
		
		// Double
		else if (__a instanceof double[])
			return new SpringArrayObjectDouble(
				this.loadClass(new ClassName("[D")),
				this.loadClass(new ClassName("double")),
				(double[])__a);
		
		// {@squirreljme.error BK22 Cannot wrap this as a native array.
		// (The input class type)}
		else
			throw new RuntimeException("BK22 " + __a.getClass());
	}
................................................................................
	/**
	 * Loads the specified class, potentially performing initialization on it
	 * if it has not been initialized.
	 *
	 * @param __cn The class to load.
	 * @return The loaded class.
	 * @throws NullPointerException On null arguments.






















	 * @since 2018/09/08
	 */
	public final SpringClass loadClass(ClassName __cn)
		throws NullPointerException

	{
		if (__cn == null)
			throw new NullPointerException("NARG");
		
		// Use the class loading lock to prevent other threads from loading or
		// initializing classes while this thread does such things
		SpringClassLoader classloader = this.machine.classLoader();
................................................................................
	
	/**
	 * Handles a native action within the VM.
	 *
	 * Note that the return value should be a native type, it is translated
	 * as needed.
	 *
	 * @param __func The function to call.

	 * @param __args The arguments to the function.
	 * @return The result from the call.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/09/16
	 */
	public final Object nativeMethod(String __func, Object... __args)

		throws NullPointerException
	{
		if (__func == null || __args == null)

			throw new NullPointerException("NARG");
		
		// Debug
		/*todo.DEBUG.note("Call native %s", __func);*/
		
		// Depends on the function
		switch (__func)
		{
				// Return the length of the array

			case "cc/squirreljme/jvm/Assembly::" +
				"arrayLength:(Ljava/lang/Object;)I":
				return ((SpringArrayObject)__args[0]).length();
				
				// Pack double together
			case "cc/squirreljme/jvm/Assembly::" +
				"doublePack:(II)D":
				return Double.longBitsToDouble(
					((((Integer)__args[0]).longValue() << 32L) |
					((((Integer)__args[1]).longValue()) & 0xFFFFFFFFL)));
				
				// Gets the raw bits for the given double value
			case "cc/squirreljme/jvm/Assembly::" +
				"doubleToRawLongBits:(D)J":
				return Double.doubleToRawLongBits((Double)__args[0]);
				
				// Float to raw int bits
			case "cc/squirreljme/jvm/Assembly::" +
				"floatToRawIntBits:(F)I":
				return Float.floatToRawIntBits((Float)__args[0]);
				
				// Int bits to float
			case "cc/squirreljme/jvm/Assembly::" +
				"intBitsToFloat:(I)F":
				return Float.intBitsToFloat((Integer)__args[0]);
				
				// Convert long bits to double
			case "cc/squirreljme/jvm/Assembly::" +
				"longBitsToDouble:(J)D":
				return Double.longBitsToDouble((Long)__args[0]);
				
				// Pack long together
			case "cc/squirreljme/jvm/Assembly::" +
				"longPack:(II)J":
				return ((((Integer)__args[0]).longValue() << 32L) |
					((((Integer)__args[1]).longValue()) & 0xFFFFFFFFL));
				
				// Unpack high long
			case "cc/squirreljme/jvm/Assembly::" +
				"longUnpackHigh:(L)I":
				return (int)((((Long)__args[0]).longValue()) >>> 32L);
				
				// Unpack low long
			case "cc/squirreljme/jvm/Assembly::" +
				"longUnpackLow:(L)I":
				return (int)(((Long)__args[0]).longValue());
				
				// Object to pointer
			case "cc/squirreljme/jvm/Assembly::" +
				"objectToPointer:(Ljava/lang/Object;)I":
			case "cc/squirreljme/jvm/Assembly::" +
				"objectToPointerRefQueue:(Ljava/lang/Object;)I":
				return this.uniqueObjectToPointer((SpringObject)__args[0]);
				
				// Pointer to object
			case "cc/squirreljme/jvm/Assembly::" +
				"pointerToObject:(I)Ljava/lang/Object;":
				return this.uniquePointerToObject((Integer)__args[0]);
				
				// System calls (no return value)
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCall:(S)V":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCall:(SI)V":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCall:(SII)V":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCall:(SIII)V":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCall:(SIIII)V":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCall:(SIIIII)V":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCall:(SIIIIII)V":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCall:(SIIIIIII)V":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCall:(SIIIIIIII)V":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallP:(S)V":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallP:(SI)V":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallP:(SII)V":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallP:(SIII)V":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallP:(SIIII)V":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallP:(SIIIII)V":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallP:(SIIIIII)V":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallP:(SIIIIIII)V":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallP:(SIIIIIIII)V":
				{
					// System call index and number of arguments used
					int si = (Integer)__args[0],
						na = __args.length - 1;
					
					// Copy argument values to integers
					int[] ta = new int[na];
					for (int i = 1, o = 0; o < na; i++, o++)
						ta[o] = (Integer)__args[i];
					
					// Do system call handler
					this.systemCall((short)si, ta);
					return null;
				}
				
				// System calls (returns value)
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallV:(S)I":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallV:(SI)I":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallV:(SII)I":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallV:(SIII)I":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallV:(SIIII)I":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallV:(SIIIII)I":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallV:(SIIIIII)I":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallV:(SIIIIIII)I":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallV:(SIIIIIIII)I":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallPV:(S)I":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallPV:(SI)I":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallPV:(SII)I":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallPV:(SIII)I":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallPV:(SIIII)I":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallPV:(SIIIII)I":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallPV:(SIIIIII)I":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallPV:(SIIIIIII)I":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallPV:(SIIIIIIII)I":
				{
					// System call index and number of arguments used
					int si = (Integer)__args[0],
						na = __args.length - 1;
					
					// Copy argument values to integers
					int[] ta = new int[na];
					for (int i = 1, o = 0; o < na; i++, o++)
						ta[o] = (Integer)__args[i];
					
					// Do system call handler
					return (int)this.systemCall((short)si, ta);
				}
				
				// System calls (returns long value)
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallVL:(S)J":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallVL:(SI)J":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallVL:(SII)J":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallVL:(SIII)J":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallVL:(SIIII)J":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallVL:(SIIIII)J":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallVL:(SIIIIII)J":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallVL:(SIIIIIII)J":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallVL:(SIIIIIIII)J":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallPVL:(S)J":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallPVL:(SI)J":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallPVL:(SII)J":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallPVL:(SIII)J":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallPVL:(SIIII)J":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallPVL:(SIIIII)J":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallPVL:(SIIIIII)J":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallPVL:(SIIIIIII)J":
			case "cc/squirreljme/jvm/Assembly::" +
				"sysCallPVL:(SIIIIIIII)J":
				{
					// System call index and number of arguments used
					int si = (Integer)__args[0],
						na = __args.length - 1;
					
					// Copy argument values to integers
					int[] ta = new int[na];
					for (int i = 1, o = 0; o < na; i++, o++)
						ta[o] = (Integer)__args[i];
					
					// Do system call handler
					return (long)this.systemCall((short)si, ta);
				}
			
				// Read console buffer
			case "cc/squirreljme/runtime/cldc/asm/ConsoleOutput::" +
				"displayRead:([I[BII)I":
				return 0;
				
				// Flush the console
			case "cc/squirreljme/runtime/cldc/asm/ConsoleOutput::" +
				"flush:(I)I":
				{
					int fd = (Integer)__args[0];
					PrintStream to = (fd == ConsoleOutput.OUTPUT ?
						System.out : (fd == ConsoleOutput.ERROR ?
						System.err : null));
					
					// Flush if valid
					if (to != null)
					{
						to.flush();
						return 0;
					}
					else
						return ConsoleOutput.ERROR_INVALIDFD;
				}
			
				// Write to the console
			case "cc/squirreljme/runtime/cldc/asm/ConsoleOutput::" +
				"write:(II)I":
				{
					int fd = (Integer)__args[0];
					PrintStream to = (fd == ConsoleOutput.OUTPUT ?
						System.out : (fd == ConsoleOutput.ERROR ?
						System.err : null));
					
					// Write if it exists
					if (to != null)
					{
						to.write((Integer)__args[1]);
						return 0;
					}
					else
						return ConsoleOutput.ERROR_INVALIDFD;
				}
				
				// Write to the console (bulk)
			case "cc/squirreljme/runtime/cldc/asm/ConsoleOutput::" +
				"write:(I[BII)I":
				{
					int fd = (Integer)__args[0];
					PrintStream to = (fd == ConsoleOutput.OUTPUT ?
						System.out : (fd == ConsoleOutput.ERROR ?
						System.err : null));
					
					// Write if it exists
					if (to != null)
					{
						to.write(
							(byte[])((SpringArrayObjectByte)__args[1]).array(),
							(Integer)__args[2],
							(Integer)__args[3]);
						return 0;
					}
					else
						return ConsoleOutput.ERROR_INVALIDFD;
				}
				
				// Allocate object but do not construct it
			case "cc/squirreljme/runtime/cldc/asm/ObjectAccess::" +
				"allocateObject:(Ljava/lang/String;)Ljava/lang/Object;":
				return this.allocateObject(this.loadClass(
					new ClassName(this.<String>asNativeObject(
					String.class, ((SpringObject)__args[0])))));
			
				// Allocate array of a given class
			case "cc/squirreljme/runtime/cldc/asm/ObjectAccess::" +
				"arrayNew:(Ljava/lang/Class;I)Ljava/lang/Object;":
				{
					// Cannot do a reverse lookup
					SpringMachine machine = this.machine;
					Map<SpringObject, ClassName> ocm = machine.
						__classObjectToNameMap();
					synchronized (machine.classLoader().classLoadingLock())
					{
						// {@squirreljme.error BK24 Could not reverse class
						// object to class name.}
						ClassName cn = ocm.get((SpringObject)__args[0]);
						if (cn == null)
							throw new SpringVirtualMachineException("BK24");


						
						// Lookup class for the component type, we need it
						SpringClass cl = this.loadClass(cn.componentType());
						
						// Allocate array for the component type
						return this.allocateArray(cl,
							(Integer)__args[1]);
					}
				}
			
				// Get the class by the name of whatever is input
			case "cc/squirreljme/runtime/cldc/asm/ObjectAccess::" +
				"classByName:(Ljava/lang/String;)Ljava/lang/Class;":
				try
				{
					return this.asVMObject(new ClassName(
						this.<String>asNativeObject(String.class,
						(SpringObject)__args[0])), true);
				}
				catch (SpringClassNotFoundException e)
				{
					return this.asVMObject(null);
				}
				
				// Returns the class data for a class object
			case "cc/squirreljme/runtime/cldc/asm/ObjectAccess::" +
				"classData:(Ljava/lang/Class;)Lcc/squirreljme/" +
				"runtime/cldc/lang/ClassData;":
				return this.invokeMethod(false,
					new ClassName("java/lang/Class"),
					new MethodNameAndType("__classData",
					"()Lcc/squirreljme/runtime/cldc/lang/ClassData;"),
					(SpringObject)__args[0]);
				
				// Get the class object for an object
			case "cc/squirreljme/runtime/cldc/asm/ObjectAccess::" +
				"classOf:(Ljava/lang/Object;)Ljava/lang/Class;":
				{
					// Just use the input class of the type
					SpringObject so = (SpringObject)__args[0];
					return so.type();
				}
				
				// Check if thread holds the given lock
			case "cc/squirreljme/runtime/cldc/asm/ObjectAccess::" +
				"holdsLock:(ILjava/lang/Object;)Z":
				{
					SpringThread owner =
						((SpringObject)__args[1]).monitor()._owner;
					return (owner == null ? false :
						((Integer)__args[0]).intValue() == owner.id);
				}
				
				// Identity hash code
			case "cc/squirreljme/runtime/cldc/asm/ObjectAccess::" +
				"identityHashCode:(Ljava/lang/Object;)I":
				return System.identityHashCode(((SpringObject)__args[0]));
				
				// Invoke static method
			case "cc/squirreljme/runtime/cldc/asm/ObjectAccess::" +
				"invokeStatic:(Lcc/squirreljme/runtime/cldc/asm/" +
				"StaticMethod;[Ljava/lang/Object;)Ljava/lang/Object;":
				{
					// We will need this to pass object arguments
					SpringArrayObject vargs = (SpringArrayObject)__args[1];
					
					// Copy object values
					int n = vargs.length();
					Object[] xargs = new Object[n];
					for (int i = 0; i < n; i++)
						xargs[i] = vargs.get(Object.class, i);
					
					// The method to execute
					SpringMethod m = ((SpringVMStaticMethod)__args[0]).method;
					
					// Enter the frame for this method
					this.thread.enterFrame(m, xargs);
					
					// If the method has no return value, just push a null to
					// the stack
					if (!m.nameAndType().type().hasReturnValue())
						return SpringNullObject.NULL;
					
					// No return value, sort of
					return null;
				}
				
				// Monitor notify
			case "cc/squirreljme/runtime/cldc/asm/ObjectAccess::" +
				"monitorNotify:(Ljava/lang/Object;Z)I":
				return ((SpringObject)__args[0]).monitor().
					monitorNotify(this.thread,
					((Integer)__args[1]).intValue() != 0);
			
				// Monitor notify
			case "cc/squirreljme/runtime/cldc/asm/ObjectAccess::" +
				"monitorWait:(Ljava/lang/Object;JI)I":
				return ((SpringObject)__args[0]).monitor().
					monitorWait(this.thread, (Long)__args[1],
						(Integer)__args[2]);
				
				// Create new primitive weak reference
			case "cc/squirreljme/runtime/cldc/asm/ObjectAccess::" +
				"newWeakReference:" +
				"()Lcc/squirreljme/runtime/cldc/ref/PrimitiveReference;":
				{
					return new SpringPrimitiveWeakReference();
				}
				
				// Get reference
			case "cc/squirreljme/runtime/cldc/asm/ObjectAccess::" +
				"referenceGet:(Lcc/squirreljme/runtime/cldc/ref/" +
				"PrimitiveReference;)Ljava/lang/Object;":
				return ((SpringPrimitiveReference)__args[0]).get();
				
				// Set reference
			case "cc/squirreljme/runtime/cldc/asm/ObjectAccess::" +
				"referenceSet:(Lcc/squirreljme/runtime/cldc/ref/" +
				"PrimitiveReference;Ljava/lang/Object;)V":
				((SpringPrimitiveReference)__args[0]).set(
					(SpringObject)__args[1]);
				return null;
				
				// Returns the number of bytes available in the resource.
			case "cc/squirreljme/runtime/cldc/asm/ResourceAccess::" +
				"available:(I)I":
				return this.machine.resourceAccess().available(
					(Integer)__args[0]);
				
				// Close resource in JAR
			case "cc/squirreljme/runtime/cldc/asm/ResourceAccess::" +
				"close:(I)I":
				return this.machine.resourceAccess().close(
					(Integer)__args[0]);
				
				// Open resource in JAR
			case "cc/squirreljme/runtime/cldc/asm/ResourceAccess::" +
				"open:(Ljava/lang/String;Ljava/lang/String;)I":
				return this.machine.resourceAccess().open(
					this.<String>asNativeObject(String.class, __args[0]),
					this.<String>asNativeObject(String.class, __args[1]));
				
				// Read resource in JAR
			case "cc/squirreljme/runtime/cldc/asm/ResourceAccess::" +
				"read:(I[BII)I":
				return this.machine.resourceAccess().read(
					(Integer)__args[0],
					(byte[])((SpringArrayObjectByte)__args[1]).array(),
					(Integer)__args[2],
					(Integer)__args[3]);
			
				// List suites that are available
			case "cc/squirreljme/runtime/cldc/asm/SuiteAccess::" +
				"availableSuites:()[Ljava/lang/String;":
				return this.machine.suiteManager().listLibraryNames();
			
				// List current class path
			case "cc/squirreljme/runtime/cldc/asm/SuiteAccess::" +
				"currentClassPath:()[Ljava/lang/String;":
				{
					VMClassLibrary[] vp = this.machine.classloader.classPath();
					int n = vp.length;
					String[] rv = new String[n];
					for (int i = 0; i < n; i++)
						rv[i] = vp[i].name();
					return this.asVMObject(rv);
				}
				
				// Get environment variable
			case "cc/squirreljme/runtime/cldc/asm/SystemAccess::" +
				"getEnv:(Ljava/lang/String;)Ljava/lang/String;":
				return this.asVMObject(SystemAccess.getEnv(
					this.<String>asNativeObject(String.class, __args[0])));
			
				// Approximated executable path
			case "cc/squirreljme/runtime/cldc/asm/SystemProperties::" +
				"executablePath:()Ljava/lang/String;":
				// Just use the one of the host VM, if it is known anyway
				return this.asVMObject(SystemProperties.executablePath());
				
				// The guest depth of this virtual machine
			case "cc/squirreljme/runtime/cldc/asm/SystemProperties::" +
				"guestDepth:()I":
				return this.machine.guestdepth;
				
				// The class to use for an implementation of something, by
				// default
			case "cc/squirreljme/runtime/cldc/asm/SystemProperties::" +
				"implementationClass:(Ljava/lang/String;)Ljava/lang/String;":
				return SpringNullObject.NULL;
				
				// VM e-mail
			case "cc/squirreljme/runtime/cldc/asm/SystemProperties::" +
				"javaVMEmail:()Ljava/lang/String;":
				return "xerthesquirrel@gmail.com";
				
				// VM name
			case "cc/squirreljme/runtime/cldc/asm/SystemProperties::" +
				"javaVMName:()Ljava/lang/String;":
				return "SquirrelJME SpringCoat";
				
				// VM URL
			case "cc/squirreljme/runtime/cldc/asm/SystemProperties::" +
				"javaVMURL:()Ljava/lang/String;":
				return "http://squirreljme.cc/";
				
				// VM vendor
			case "cc/squirreljme/runtime/cldc/asm/SystemProperties::" +
				"javaVMVendor:()Ljava/lang/String;":
				return "Stephanie Gawroriski";
				
				// VM Version
			case "cc/squirreljme/runtime/cldc/asm/SystemProperties::" +
				"javaVMVersion:()Ljava/lang/String;":
				return "0.2.0";
				
				// Get the operating system type
			case "cc/squirreljme/runtime/cldc/asm/SystemProperties::" +
				"operatingSystemType:()I":
				return OperatingSystemType.UNKNOWN;
				
				// Get system property
			case "cc/squirreljme/runtime/cldc/asm/SystemProperties::" +
				"systemProperty:(Ljava/lang/String;)Ljava/lang/String;":
				String pk = this.<String>asNativeObject(String.class,
					__args[0]),
					pv = this.machine._sysproperties.get(pk);
				if (pv != null)
					return pv;
				return System.getProperty(pk);
				
				// Current thread ID


			case "cc/squirreljme/runtime/cldc/asm/TaskAccess::" +
				"currentThread:()I":
				return this.thread.id;



				
				// Set thread priority
			case "cc/squirreljme/runtime/cldc/asm/TaskAccess::" +
				"setThreadPriority:(II)V":





				{
					SpringThread st = this.machine.getThread(
						(Integer)__args[0]);
					if (st != null)
					{
						SpringThreadWorker stw = st._worker;
						if (stw != null)
						{
							Thread signal = stw.signalinstead;
							if (signal != null)
								signal.setPriority((Integer)__args[1]);
							else
								stw.setPriority((Integer)__args[1]);
						}
					}
					
					return null;
				}
				
				// Interrupt the given thread
			case "cc/squirreljme/runtime/cldc/asm/TaskAccess::" +
				"signalInterrupt:(I)V":
				{
					SpringThread st = this.machine.getThread(
						(Integer)__args[0]);
					if (st != null)
					{
						SpringThreadWorker stw = st._worker;
						if (stw != null)
						{
							Thread signal = stw.signalinstead;
							if (signal != null)
								signal.interrupt();
							else
								stw.interrupt();
						}
					}
					
					return null;
				}
				
				// Sleep
			case "cc/squirreljme/runtime/cldc/asm/TaskAccess::" +
				"sleep:(JI)Z":
				try


				{
					long ms = (Long)__args[0];
					int ns = (Integer)__args[1];
					
					// Zero time is a yield
					if (ms == 0 && ns == 0)
						Thread.yield();
					
					// Otherwise sleep for given time
					else
						Thread.sleep(ms, ns);
					return 0;
				}
				catch (InterruptedException e)
				{
					return 1;
				}
				
				// Start Task
			case "cc/squirreljme/runtime/cldc/asm/TaskAccess::" +
				"startTask:([Ljava/lang/String;Ljava/lang/String;" +
				"[Ljava/lang/String;)I":
			case "cc/squirreljme/runtime/cldc/asm/TaskAccess::" +
				"startTask:([Ljava/lang/String;Ljava/lang/String;" +
				"[Ljava/lang/String;[Ljava/lang/String;" +
				"Lcc/squirreljme/runtime/cldc/asm/ConsoleCallback;" +
				"Lcc/squirreljme/runtime/cldc/asm/ConsoleCallback;)I":
				return this.machine.taskManager().startTask(
					this.<String[]>asNativeObject(String[].class, __args[0]),
					this.<String>asNativeObject(String.class, __args[1]),
					this.<String[]>asNativeObject(String[].class, __args[2]),
					this.machine.guestdepth);
				
				// Start Thread
			case "cc/squirreljme/runtime/cldc/asm/TaskAccess::" +
				"startThread:(Ljava/lang/Thread;Ljava/lang/String;)I":
				{
					// Create thread
					String name;
					SpringThread thread = this.machine.createThread(
						(name = this.<String>asNativeObject(String.class,
							__args[1])));
					
					// Enter Thread's `__start()`
					SpringObject throbj = (SpringObject)__args[0];
					thread.enterFrame(this.resolveClass(
						new ClassName("java/lang/Thread")).lookupMethod(false,
						new MethodNameAndType("__start", "()V")), throbj);
					
					// Create worker for this thread
					SpringThreadWorker worker = new SpringThreadWorker(
						this.machine, thread, false);
					worker.start();
					
					// Return this thread ID
					return thread.id;
				}
				
				// Task status
			case "cc/squirreljme/runtime/cldc/asm/TaskAccess::" +
				"taskStatus:(I)I":
				return this.machine.taskManager().taskStatus(
					(Integer)__args[0]);
				
				// {@squirreljme.error BK25 Unknown native function. (The
				// native function)}
			default:
				throw new SpringVirtualMachineException(
					String.format("BK25 %s", __func));
		}

	}
	
	/**
	 * Creates a new instance of the given class and initializes it using the
	 * given arguments. Access checks are ignored.
	 *
	 * @param __cl The class to initialize.
................................................................................
		if (__cl == null || __desc == null || __args == null)
			throw new NullPointerException("NARG");
		
		// Make sure this class is loaded
		__cl = this.loadClass(__cl);
		
		// Lookup constructor to this method
		SpringMethod cons = __cl.lookupMethod(false, new MethodName("<init>"),
			__desc);
		
		// Allocate the object
		SpringObject rv = this.allocateObject(__cl);
			
		// Stop execution when the constructor exits
		SpringThread thread = this.thread;
		int framelimit = thread.numFrames();
................................................................................
		
		// Execute until it finishes
		this.run(framelimit);
		
		// Return the resulting object
		return rv;
	}















	
	/**
	 * Resolves the given class, checking access.
	 *
	 * @param __cl The class to resolve.
	 * @return The resolved class.
	 * @throws NullPointerException On null arguments.
................................................................................
				this.__singleStep();
			}
		}
		
		// If the VM is exiting then clear the execution stack before we go
		// away
		catch (SpringMachineExitException e)
		{



			// Thread is okay to exit!
			thread._terminate = true;
			thread._signaledexit = true;
			
			// Exit all frames
			thread.exitAllFrames();
			
			// Exit profiler stack
			thread.profiler.exitAll(System.nanoTime());
................................................................................
		
		// Caught exception
		catch (RuntimeException e)
		{
			// Frame limit is zero, so kill the thread
			if (__framelimit == 0)
			{



				PrintStream err = System.err;
				
				err.println("****************************");
				
				// Print the real stack trace
				err.println("*** EXTERNAL STACK TRACE ***");
				e.printStackTrace(err);
................................................................................
				// Print the VM seen stack trace
				err.println("*** INTERNAL STACK TRACE ***");
				thread.printStackTrace(err);
				err.println();
				
				err.println("****************************");
				
				// Terminate the thread
				thread._terminate = true;
				
				// Exit all frames
				thread.exitAllFrames();
				
				// Exit from all profiler threads
				thread.profiler.exitAll(System.nanoTime());
			}
			
................................................................................
			throw e;
		}
		
		// Terminate if the last frame
		finally
		{
			if (__framelimit == 0)
				thread._terminate = true;
		}
	}





































	
	/**
	 * Checks if an exception is being thrown and sets up the state from it.
	 *
	 * @return True if an exception was detected.
	 * @since 2018/12/06
	 */
................................................................................
			// Pop our current frame from the call stack
			thread.popFrame();
			
			// Did we run out of stack frames?
			SpringThread.Frame cf = thread.currentFrame();
			if (cf == null)
			{
				// Send our throwable to a special handler
				this.invokeMethod(true, new ClassName("cc/squirreljme/" +
					"runtime/cldc/lang/UncaughtExceptionHandler"),
					new MethodNameAndType("handle",
					"(Ljava/lang/Throwable;)V"), __o);
				
				// Just stop execution here
				return -1;
			}
			
			// Toss onto the new current frame
			cf.tossException(__o);
			
................................................................................
		}
		
		// If the VM is exiting then clear the execution stack before we go
		// away
		catch (SpringMachineExitException e)
		{
			// Thread is okay to exit!
			thread._terminate = true;
			
			// Exit profiler stack
			thread.profiler.exitAll(System.nanoTime());
			
			throw e;
		}
		
................................................................................
					frame.loadToStack(SpringObject.class,
						opid - InstructionIndex.ALOAD_0);
					break;
				
					// Allocate new array
				case InstructionIndex.ANEWARRAY:
					frame.pushToStack(this.allocateArray(this.resolveClass(
						inst.<ClassName>argument(0, ClassName.class)),

						frame.<Integer>popFromStack(Integer.class)));
					break;
					
					// Return reference
				case InstructionIndex.ARETURN:
					this.__vmReturn(thread,
						frame.<SpringObject>popFromStack(SpringObject.class));
................................................................................
						SpringObject pop = frame.<SpringObject>popFromStack(
							SpringObject.class);
						
						// {@squirreljme.error BK2d Cannot cast object to the
						// target type. (The type to cast to; The type of the
						// object)}
						if (pop != SpringNullObject.NULL &&

							!as.isAssignableFrom(pop.type()))
							throw new SpringClassCastException(String.format(
								"BK2d %s %s", as, pop.type()));
						
						// Return the popped value
						else
							frame.pushToStack(pop);
................................................................................
					this.__vmNew(inst, frame);
					break;
				
					// Allocate new primitive array
				case InstructionIndex.NEWARRAY:
					frame.pushToStack(this.allocateArray(this.resolveClass(
						ClassName.fromPrimitiveType(
						inst.<PrimitiveType>argument(0, PrimitiveType.class))),

						frame.<Integer>popFromStack(Integer.class)));
					break;
					
					// Return from method with no return value
				case InstructionIndex.RETURN:
					thread.popFrame();
					break;
................................................................................
		// because it is of the wrong type. (The reference class; The class
		// of the target object; The first argument)}
		SpringClass objclass = onthis.type();
		if (objclass == null || !refclass.isAssignableFrom(objclass))
			throw new SpringClassCastException(
				String.format("BK32 %s %s %s", refclass, objclass, args[0]));
		
		// Relookup the method since we need to the right one! Then invoke it
		__t.enterFrame(objclass.lookupMethod(false, ref.memberNameAndType()),
			args);
	}
	
	/**
	 * Internal system call handling.
	 *
	 * @param __si System call index.
	 * @param __args Arguments.
	 * @return The result.
	 * @since 2019/05/23
	 */
	public final long systemCall(short __si, int... __args)
	{
		// Make at least 8!
		if (__args == null)
			__args = new int[8];
		if (__args.length < 8)
			__args = Arrays.copyOf(__args, 8);
		
		// Error state for the last call of this type
		int[] errors = this.thread._syscallerrors;
		
		// Return value with error value, to set if any
		long rv;
		int err;
		
		// Depends on the system call type
		switch (__si)
		{
				// Check if system call is supported
			case SystemCallIndex.QUERY_INDEX:
				{
					err = 0;
					switch (__args[0])
					{
						case SystemCallIndex.API_LEVEL:
						case SystemCallIndex.CALL_STACK_HEIGHT:
						case SystemCallIndex.CALL_STACK_ITEM:
						case SystemCallIndex.ERROR_GET:
						case SystemCallIndex.ERROR_SET:
						case SystemCallIndex.EXIT:
						case SystemCallIndex.FATAL_TODO:
						case SystemCallIndex.GARBAGE_COLLECT:
						case SystemCallIndex.LOAD_STRING:
						case SystemCallIndex.PD_OF_STDERR:
						case SystemCallIndex.PD_OF_STDIN:
						case SystemCallIndex.PD_OF_STDOUT:
						case SystemCallIndex.PD_WRITE_BYTE:
						case SystemCallIndex.SLEEP:
						case SystemCallIndex.TIME_MILLI_WALL:
						case SystemCallIndex.TIME_NANO_MONO:
						case SystemCallIndex.VMI_MEM_FREE:
						case SystemCallIndex.VMI_MEM_MAX:
						case SystemCallIndex.VMI_MEM_USED:
							rv = 1;
							break;
						
						default:
							rv = 0;
							break;
					}
				}
				break;
				
				// Returns the height of the call stack
			case SystemCallIndex.CALL_STACK_HEIGHT:
				{
					rv = this.thread.frames().length;
					err = 0;
				}
				break;
				
				// Returns the given call stack item
			case SystemCallIndex.CALL_STACK_ITEM:
				{
					// Need to get all the stack frames first
					SpringThread.Frame[] frames = this.thread.frames();
					int numframes = frames.length;
					int curf = (numframes - __args[0]) - 1;
					
					// Out of range item
					if (curf < 0 || curf >= numframes)
					{
						rv = -1;
						err = SystemCallError.VALUE_OUT_OF_RANGE;
					}
					
					// Depends on the item
					else
					{
						// Reset
						rv = err = 0;
						
						// Get method we are in
						SpringMethod inmethod = frames[curf].method();
						
						// Depends on the item
						switch (__args[1])
						{
								// Class name
							case CallStackItem.CLASS_NAME:
								if (inmethod == null)
									err = SystemCallError.VALUE_OUT_OF_RANGE;
								else
									rv = this.uniqueStringId(
										inmethod.inClass().toString());
								break;

								// The method name.
							case CallStackItem.METHOD_NAME:
								if (inmethod == null)
									err = SystemCallError.VALUE_OUT_OF_RANGE;
								else
									rv = this.uniqueStringId(inmethod.
										nameAndType().name().toString());
								break;

								// The method type.
							case CallStackItem.METHOD_TYPE:
								if (inmethod == null)
									err = SystemCallError.VALUE_OUT_OF_RANGE;
								else
									rv = this.uniqueStringId(inmethod.
										nameAndType().type().toString());
								break;

								// The current file.
							case CallStackItem.SOURCE_FILE:
								if (inmethod == null)
									err = SystemCallError.VALUE_OUT_OF_RANGE;
								else
									rv = this.uniqueStringId(
										inmethod.inFile());
								break;

								// Source line.
							case CallStackItem.SOURCE_LINE:
								rv = frames[curf].lastExecutedPcSourceLine();
								break;

								// The PC address.
							case CallStackItem.PC_ADDRESS:
							case CallStackItem.JAVA_PC_ADDRESS:
								rv = frames[curf].lastExecutedPc();
								break;

							default:
								err = SystemCallError.VALUE_OUT_OF_RANGE;
								break;
						}
					}
				}
				break;
				
				// Get error
			case SystemCallIndex.ERROR_GET:
				{
					// If the ID is valid then a bad array access will be used
					int dx = __args[0];
					if (dx < 0 || dx >= SystemCallIndex.NUM_SYSCALLS)
						dx = SystemCallIndex.QUERY_INDEX;
					
					// Return the stored error code
					synchronized (errors)
					{
						rv = errors[dx];
					}
					
					// Always succeeds
					err = 0;
				}
				break;
				
				// Set error
			case SystemCallIndex.ERROR_SET:
				{
					// If the ID is valid then a bad array access will be used
					int dx = __args[0];
					if (dx < 0 || dx >= SystemCallIndex.NUM_SYSCALLS)
						dx = SystemCallIndex.QUERY_INDEX;
					
					// Return last error code, and set new one
					synchronized (errors)
					{
						rv = errors[dx];
						errors[dx] = __args[0];
					}
					
					// Always succeeds
					err = 0;
				}
				break;
				
				// Exit the VM
			case SystemCallIndex.EXIT:
				{
					// Tell everything to cleanup and exit
					this.thread.profiler.exitAll(System.nanoTime());
					this.machine.exit((Integer)__args[0]);
					
					rv = 0;
					err = 0;
				}
				break;
				
				// Fatal ToDo
			case SystemCallIndex.FATAL_TODO:
				// {@squirreljme.error BK33 Virtual machine code executed
				// a fatal Todo. (The To Do code)}
				rv = err = 0;
				throw new SpringVirtualMachineException("BK33 " + __args[1]);
				
				// Invoke the garbage collector
			case SystemCallIndex.GARBAGE_COLLECT:
				{
					Runtime.getRuntime().gc();
					
					rv = 0;
					err = 0;
				}
				break;
				
				// Loads a string
			case SystemCallIndex.LOAD_STRING:
				{
					rv = (__args[0] == 0 ? 0 :
						this.uniqueObjectToPointer((SpringObject)
						this.asVMObject(new ConstantValueString(
						this.uniqueString(__args[0])))));
					err = 0;
				}
				break;
			
				// Current wall clock milliseconds (low).
			case SystemCallIndex.TIME_MILLI_WALL:
				{
					rv = System.currentTimeMillis();
					err = 0;
				}
				break;

				// Current monotonic clock nanoseconds (low).
			case SystemCallIndex.TIME_NANO_MONO:
				{
					rv = System.nanoTime();
					err = 0;
				}
				break;
			
				// VM information: Memory free bytes
			case SystemCallIndex.VMI_MEM_FREE:
				{
					rv = (int)Math.min(Integer.MAX_VALUE,
						Runtime.getRuntime().freeMemory());
					err = 0;
				}
				break;
			
				// VM information: Memory used bytes
			case SystemCallIndex.VMI_MEM_USED:
				{
					rv = (int)Math.min(Integer.MAX_VALUE,
						Runtime.getRuntime().totalMemory());
					err = 0;
				}
				break;
			
				// VM information: Memory max bytes
			case SystemCallIndex.VMI_MEM_MAX:
				{
					rv = (int)Math.min(Integer.MAX_VALUE,
						Runtime.getRuntime().maxMemory());
					err = 0;
				}
				break;
				
				// API level
			case SystemCallIndex.API_LEVEL:
				{
					rv = ApiLevel.LEVEL_SQUIRRELJME_0_3_0_DEV;
					err = 0;
				}
				break;
				
				// Pipe descriptor of standard input
			case SystemCallIndex.PD_OF_STDIN:
				{
					rv = 0;
					err = 0;
				}
				break;
				
				// Pipe descriptor of standard output
			case SystemCallIndex.PD_OF_STDOUT:
				{
					rv = 1;
					err = 0;
				}
				break;
				
				// Pipe descriptor of standard error
			case SystemCallIndex.PD_OF_STDERR:
				{
					rv = 1;
					err = 0;
				}
				break;
				
				// Write single byte to PD
			case SystemCallIndex.PD_WRITE_BYTE:
				{
					// Depends on the stream
					int pd = __args[0];
					OutputStream os = (pd == 1 ? System.out :
						(pd == 2 ? System.err : null));
					
					// Write
					if (os != null)
					{
						try
						{
							os.write(__args[1]);
							
							// Okay
							rv = 1;
							err = 0;
						}
						
						// Failed
						catch (IOException e)
						{
							rv = -1;
							err = SystemCallError.PIPE_DESCRIPTOR_BAD_WRITE;
						}
					}
					
					// Failed
					else
					{
						rv = -1;
						err = SystemCallError.PIPE_DESCRIPTOR_INVALID;
					}
				}
				break;
				
				// Sleep
			case SystemCallIndex.SLEEP:
				try
				{
					Thread.sleep(__args[0], __args[1]);
					
					rv = 0;
					err = SystemCallError.NO_ERROR;
				}
				catch (InterruptedException e)
				{
					rv = 1;
					err = SystemCallError.INTERRUPTED;
				}
				break;
			
			default:
				// Returns no value but sets an error
				rv = -1;
				err = SystemCallError.UNSUPPORTED_SYSTEM_CALL;
				
				// If the ID is valid then a bad array access will be used
				if (__si < 0 || __si >= SystemCallIndex.NUM_SYSCALLS)
					__si = SystemCallIndex.QUERY_INDEX;
				break;
		}
		
		// Set error state as needed
		synchronized (errors)
		{
			errors[__si] = err;
		}
		
		// Use returning value
		return rv;
	}
	
	/**
	 * Converts an object to a unique pointer.
	 *
	 * @param __p The object to convert.
	 * @return The resulting pointer.
	 * @since 2019/06/16
	 */
	public final int uniqueObjectToPointer(SpringObject __p)
	{
		// Null reference?
		if (__p == SpringNullObject.NULL)
			return 0;
		
		// Return the base of the pointer area
		return __p.pointerArea().base;
	}
	
	/**
	 * Converts an object to a unique pointer.
	 *
	 * @param __p The object to convert.
	 * @return The resulting pointer.
	 * @since 2019/06/16
	 */
	public final SpringObject uniquePointerToObject(int __p)
	{
		// Null reference?
		if (__p == 0)
			return SpringNullObject.NULL;
		
		return this.machine.pointers.findObject(__p);
	}
	
	/**
	 * Returns the string of the given ID.
	 *
	 * @param __id The ID to get.
	 * @return The resulting string.
	 * @since 2019/06/16
	 */
	public final String uniqueString(int __id)
	{
		if (__id == 0)
			return null;
		return this.machine.debugResolveString((int)__id);
	}
	
	/**
	 * Returns a unique ID for the given string.
	 *
	 * @param __s The String to get the ID of.
	 * @return The unique string ID.
	 * @throws NullPointerException On null arguments.
	 * @since 2019/06/16
	 */
	public final int uniqueStringId(String __s)
		throws NullPointerException
	{
		if (__s == null)
			return 0;
		
		return (int)this.machine.debugUnresolveString(__s);
	}
	
	/**
	 * Performs a special invoke.
	 *
	 * @param __i The instruction.
	 * @param __t The current thread.
................................................................................
		Object[] args = new Object[nargs];
		for (int i = nargs - 1; i >= 0; i--)
			args[i] = __f.popFromStack();
		
		// Virtualized native call, depends on what it is
		if (refmethod.flags().isNative())
		{









			// Calculate result of method
			MethodDescriptor type = ref.memberType();
			Object rv = this.nativeMethod(ref.className() + "::" +
				ref.memberName() + ":" + type, args);
			
			// Push native object to the stack
			if (type.hasReturnValue())
				__f.pushToStack(this.asVMObject(rv, true));








		}
		
		// Real code that exists in class file format
		else
			__t.enterFrame(refmethod, args);
	}
	







|
|
|
|
|
|
|
|
|
|
|
>
>
>
>







 







|


>





>
|




|
>
>
>
|



|



|



|



|



|



|



|



|



|







 







|







 







|









|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|



|



|

|
|
<
>
|
<
>
|
|
|
|
>
|
<
|
<
<
<
<
<
<
|
<
<
<
<
<
|
|
<
<
<
<
<
<
<
>









|








|







 







|



|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|
<
<
>
>







 







|

|
>
|
>
>
>
|

<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
>

<
<
<
<
<
<
<
<
<
<
>
>
>
>

<
<
<
>







 







<






<






<






<






<






<






<






<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|
>







 







|
>





|
>


<
>


<
|
<
<
<
<
<
>
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
>
|
<
<
>
>
>
|
<
<
<
>
>
>
>
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
>
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>







 







|
|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
>
>
>

<







 







>
>
>







 







<
<
<







 







|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







<
<
<
<
<
<







 







|







 







|
>







 







>







 







|
>







 







|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
...
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
...
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212

213








































214
215
216
217
218
219
220
...
246
247
248
249
250
251
252






















253
254
255
256
257
258
259
...
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317

318
319

320
321
322
323
324
325
326

327






328





329
330







331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
...
442
443
444
445
446
447
448
449
450
451
452
453
454
455
































































456
457
458


459
460
461
462
463
464
465
466
467
...
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486




487
















488

489
490














491

492
493










494
495
496
497
498



499
500
501
502
503
504
505
506
...
514
515
516
517
518
519
520

521
522
523
524
525
526

527
528
529
530
531
532

533
534
535
536
537
538

539
540
541
542
543
544

545
546
547
548
549
550

551
552
553
554
555
556

557
558
559
560
561
562

563
564
565
566
567
568
569
...
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
...
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960

961
962
963

964





965
966




967





































































































































































































































































































968
969
970
971







































































































































































































































972
973
974


975
976
977
978



979
980
981
982
983
984








































985



986
987
988





































































989
990
991
992
993
994
995
996
....
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
....
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
....
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151

1152
1153
1154
1155
1156
1157
1158
....
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
....
1182
1183
1184
1185
1186
1187
1188



1189
1190
1191
1192
1193
1194
1195
....
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
....
1329
1330
1331
1332
1333
1334
1335






1336
1337
1338
1339
1340
1341
1342
....
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
....
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
....
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
....
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
....
3266
3267
3268
3269
3270
3271
3272
3273
3274


















































































































3275









































































































































































































































































































































3276
3277
3278
3279
3280
3281
3282
....
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;

import cc.squirreljme.emulator.profiler.ProfiledFrame;
import cc.squirreljme.vm.springcoat.brackets.TypeObject;
import cc.squirreljme.vm.springcoat.exceptions.SpringArithmeticException;
import cc.squirreljme.vm.springcoat.exceptions.SpringClassCastException;
import cc.squirreljme.vm.springcoat.exceptions.SpringClassFormatException;
import cc.squirreljme.vm.springcoat.exceptions.SpringClassNotFoundException;
import cc.squirreljme.vm.springcoat.exceptions.SpringFatalException;
import cc.squirreljme.vm.springcoat.exceptions.SpringIllegalAccessException;
import cc.squirreljme.vm.springcoat.exceptions.SpringIncompatibleClassChangeException;
import cc.squirreljme.vm.springcoat.exceptions.SpringMachineExitException;
import cc.squirreljme.vm.springcoat.exceptions.SpringNegativeArraySizeException;
import cc.squirreljme.vm.springcoat.exceptions.SpringNoSuchFieldException;
import cc.squirreljme.vm.springcoat.exceptions.SpringNoSuchMethodException;
import cc.squirreljme.vm.springcoat.exceptions.SpringNullPointerException;
import cc.squirreljme.vm.springcoat.exceptions.SpringVirtualMachineException;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Map;
import net.multiphasicapps.classfile.ByteCode;
import net.multiphasicapps.classfile.ClassFlags;
import net.multiphasicapps.classfile.ClassName;
import net.multiphasicapps.classfile.ConstantValue;
................................................................................
			throw new SpringVirtualMachineException("BK1x");
	}
	
	/**
	 * Allocates the memory needed to store an array of the given class and
	 * of the given length.
	 *
	 * @param __cl The array type.
	 * @param __l The length of the array.
	 * @return The allocated array.
	 * @throws IllegalArgumentException If the type is not an array.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringNegativeArraySizeException If the array size is negative.
	 * @since 2018/09/15
	 */
	public final SpringArrayObject allocateArray(SpringClass __cl, int __l)
		throws IllegalArgumentException, NullPointerException,
			SpringNegativeArraySizeException
	{
		if (__cl == null)
			throw new NullPointerException("NARG");
		
		// This must be an array type
		if (!__cl.isArray())
			throw new IllegalArgumentException("Not an array: " + __cl);
		
		switch (__cl.componentType().name().toString())
		{
				// Boolean
			case "boolean":
				return new SpringArrayObjectBoolean(__cl, __l);
			
				// Byte
			case "byte":
				return new SpringArrayObjectByte(__cl, __l);
				
				// Short
			case "short":
				return new SpringArrayObjectShort(__cl, __l);
				
				// Char
			case "char":
				return new SpringArrayObjectChar(__cl, __l);
				
				// Int
			case "int":
				return new SpringArrayObjectInteger(__cl, __l);
				
				// Long
			case "long":
				return new SpringArrayObjectLong(__cl, __l);
				
				// Float
			case "float":
				return new SpringArrayObjectFloat(__cl, __l);
				
				// Float
			case "double":
				return new SpringArrayObjectDouble(__cl, __l);
			
				// Generic array
			default:
				return new SpringArrayObjectGeneric(__cl, __l);
		}
		
	}
	
	/**
	 * Allocates the memory needed to store an object of the given class.
	 *
................................................................................
		throws NullPointerException
	{
		if (__cl == null)
			throw new NullPointerException("NARG");
		
		// The called constructor will allocate the space needed to store
		// this object
		return new SpringSimpleObject(__cl);
	}
	
	/**
	 * Converts the specified virtual machine object to a native object.
	 *
	 * @param __in The input object.
	 * @return The resulting native object.
................................................................................
	 */
	public final Object asNativeObject(Object __in)
		throws NullPointerException, SpringFatalException
	{
		if (__in == null)
			throw new NullPointerException("NARG");
		
		// Is null reference
		else if (__in == SpringNullObject.NULL)
			return null;
		
		// Boxed types remain the same
		else if (__in instanceof Integer || __in instanceof Long ||
			__in instanceof Float || __in instanceof Double)
			return __in;
		
		// Array type
		if (__in instanceof SpringArrayObject)

			return ((SpringArrayObject)__in).array();








































		
		// Class type
		else if (__in instanceof SpringSimpleObject)
		{
			SpringSimpleObject sso = (SpringSimpleObject)__in;
			
			// Depends on the class type
................................................................................
		// {@squirreljme.error BK20 Do not know how to convert the given class
		// to a native machine object. (The input class)}
		else
			throw new SpringFatalException(
				String.format("BK20 %s", __in.getClass()));
	}
	






















	/**
	 * Converts the specified virtual machine object to a native object.
	 *
	 * @param <C> The class type.
	 * @param __cl The class type.
	 * @param __in The input object.
	 * @return The resulting native object.
................................................................................
		else if (__in instanceof Integer || __in instanceof Long ||
			__in instanceof Float || __in instanceof Double ||
			__in instanceof SpringObject)
			return __in;
		
		// Boolean to integer
		else if (__in instanceof Boolean)
			return (Boolean.TRUE.equals(__in) ? 1 : 0);
		
		// Character to Integer
		else if (__in instanceof Character)
			return (int)(Character)__in;
		
		// Promoted to integer
		else if (__in instanceof Byte || __in instanceof Short)
			return ((Number)__in).intValue();
		
		// An array type (not copied)
		else if (__in instanceof boolean[] ||

			__in instanceof byte[] ||
			__in instanceof short[] ||

			__in instanceof char[] ||
			__in instanceof int[] ||
			__in instanceof long[] ||
			__in instanceof float[] ||
			__in instanceof double[])
			return this.asWrappedArray(__in);
		

		// Object array type






		else if (__in instanceof SpringObject[])





			return new SpringArrayObjectGeneric(
				this.loadClass(new ClassName("java/lang/Object")),







				(SpringObject[])__in);
		
		// String array
		else if (__in instanceof String[])
		{
			String[] in = (String[])__in;
			
			// Setup return array
			int n = in.length;
			SpringArrayObject rv = this.allocateArray(
				this.loadClass(new ClassName("[Ljava/lang/String;")), n);
			
			// Copy array values
			for (int i = 0; i < n; i++)
				rv.set(i, this.asVMObject(in[i]));
			
			return rv;
		}
		
		// Convertible exception
		else if (__in instanceof SpringConvertableThrowable)
		{
			SpringConvertableThrowable e = (SpringConvertableThrowable)__in;
			
			// Initialize new instance with this type, use the input message
			return this.newInstance(new ClassName(e.targetClass()),
				new MethodDescriptor("(Ljava/lang/String;)V"),
................................................................................
			{
				// Pre-cached object already exists?
				SpringObject rv = com.get(name);
				if (rv != null)
					return rv;
				
				// Resolve the input class, so it is initialized
				SpringClass resClass = (__noclassres ? this.loadClass(name) :
					this.resolveClass(name));
				
				// Resolve the class object
				SpringClass classClass = this.resolveClass(
					new ClassName("java/lang/Class"));
				
































































				// Initialize class with special class index and some class
				// information
				rv = this.newInstance(classClass.name(), new MethodDescriptor(


					"(Lcc/squirreljme/jvm/mle/brackets/TypeBracket;)V"),
					new TypeObject(resClass));
				
				// Cache and use it
				com.put(name, rv);
				ocm.put(rv, name);
				return rv;
			}
		}
................................................................................
		// to a virtual machine object. (The input class)}
		else
			throw new RuntimeException(
				String.format("BK21 %s", __in.getClass()));
	}
	
	/**
	 * Creates an array from the given elements.
	 *
	 * @param __type The array type.
	 * @param __elements The elements to be in the array.
	 * @return The array.
	 * @throws IllegalArgumentException If the type is not an array that is
	 * compatible with objects.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/12
	 */




	public final SpringArrayObjectGeneric asVMObjectArray(SpringClass __type,
















		SpringObject... __elements)

		throws IllegalArgumentException, NullPointerException
	{














		if (__type == null)

			throw new NullPointerException("NARG");
		










		// Prevent invalid arrays from being wrapped
		if (!__type.isArray() || __type.componentType().name().isPrimitive())
			throw new IllegalArgumentException("Cannot have object array " +
				"that is not an array or primitive type: " + __type);
		



		return new SpringArrayObjectGeneric(__type, __elements);
	}
	
	/**
	 * Wraps the native array so that it is directly read and written in
	 * the VM code.
	 *
	 * @param __a The object to convert.
................................................................................
		if (__a == null)
			return SpringNullObject.NULL;
		
		// Boolean
		else if (__a instanceof boolean[])
			return new SpringArrayObjectBoolean(
				this.loadClass(new ClassName("[Z")),

				(boolean[])__a);
		
		// Byte
		else if (__a instanceof byte[])
			return new SpringArrayObjectByte(
				this.loadClass(new ClassName("[B")),

				(byte[])__a);
		
		// Short
		else if (__a instanceof short[])
			return new SpringArrayObjectShort(
				this.loadClass(new ClassName("[S")),

				(short[])__a);
		
		// Character
		else if (__a instanceof char[])
			return new SpringArrayObjectChar(
				this.loadClass(new ClassName("[C")),

				(char[])__a);
		
		// Integer
		else if (__a instanceof int[])
			return new SpringArrayObjectInteger(
				this.loadClass(new ClassName("[I")),

				(int[])__a);
		
		// Long
		else if (__a instanceof long[])
			return new SpringArrayObjectLong(
				this.loadClass(new ClassName("[J")),

				(long[])__a);
		
		// Float
		else if (__a instanceof float[])
			return new SpringArrayObjectFloat(
				this.loadClass(new ClassName("[F")),

				(float[])__a);
		
		// Double
		else if (__a instanceof double[])
			return new SpringArrayObjectDouble(
				this.loadClass(new ClassName("[D")),

				(double[])__a);
		
		// {@squirreljme.error BK22 Cannot wrap this as a native array.
		// (The input class type)}
		else
			throw new RuntimeException("BK22 " + __a.getClass());
	}
................................................................................
	/**
	 * Loads the specified class, potentially performing initialization on it
	 * if it has not been initialized.
	 *
	 * @param __cn The class to load.
	 * @return The loaded class.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringClassFormatException If the class is not formatted
	 * properly.
	 * @throws SpringClassNotFoundException If the class was not found.
	 * @since 2020/06/17
	 */
	public final SpringClass loadClass(String __cn)
		throws NullPointerException, SpringClassFormatException,
			SpringClassNotFoundException
	{
		return this.loadClass(new ClassName(__cn));
	}
	
	/**
	 * Loads the specified class, potentially performing initialization on it
	 * if it has not been initialized.
	 *
	 * @param __cn The class to load.
	 * @return The loaded class.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringClassFormatException If the class is not formatted
	 * properly.
	 * @throws SpringClassNotFoundException If the class was not found.
	 * @since 2018/09/08
	 */
	public final SpringClass loadClass(ClassName __cn)
		throws NullPointerException, SpringClassFormatException,
			SpringClassNotFoundException
	{
		if (__cn == null)
			throw new NullPointerException("NARG");
		
		// Use the class loading lock to prevent other threads from loading or
		// initializing classes while this thread does such things
		SpringClassLoader classloader = this.machine.classLoader();
................................................................................
	
	/**
	 * Handles a native action within the VM.
	 *
	 * Note that the return value should be a native type, it is translated
	 * as needed.
	 *
	 * @param __class The class the function is in.
	 * @param __method The method being called.
	 * @param __args The arguments to the function.
	 * @return The result from the call.
	 * @throws NullPointerException On null arguments.
	 * @since 2018/09/16
	 */
	public final Object nativeMethod(ClassName __class,
		MethodNameAndType __method, Object... __args)
		throws NullPointerException
	{

		if (__class == null || __method == null || __args == null)
			throw new NullPointerException("NARG");
		

		// All low-level calls are considered invalid in SpringCoat because





		// it does not have the given functionality.
		if (__class.toString().startsWith("cc/squirreljme/jvm/Assembly") ||




			__class.toString().startsWith("cc/squirreljme/jvm/mle/lle/"))





































































































































































































































































































			throw new SpringVirtualMachineException(String.format(
				"Invalid LLE native call: %s %s", __class,
				Arrays.asList(__args)));
		







































































































































































































































		// Do not allow the older SpringCoat "asm" classes to be called as
		// the interfaces are very different with the MLE layer.
		if (__class.toString().startsWith("cc/squirreljme/runtime/cldc/asm/"))


			throw new SpringVirtualMachineException(String.format(
				"Old-SpringCoat native call: %s %s", __class,
				Arrays.asList(__args)));
		



		// Only allow mid-level native calls
		if (!__class.toString().startsWith("cc/squirreljme/jvm/mle/"))
			throw new SpringVirtualMachineException(String.format(
				"Non-MLE native call: %s %s", __class,
				Arrays.asList(__args)));
		








































		// Debug



		/*Debugging.debugNote("Call native %s::%s %s", __class, __method,
			Arrays.asList(__args));*/
		





































































		return MLEDispatcher.dispatch(this, __class, __method, __args);
	}
	
	/**
	 * Creates a new instance of the given class and initializes it using the
	 * given arguments. Access checks are ignored.
	 *
	 * @param __cl The class to initialize.
................................................................................
		if (__cl == null || __desc == null || __args == null)
			throw new NullPointerException("NARG");
		
		// Make sure this class is loaded
		__cl = this.loadClass(__cl);
		
		// Lookup constructor to this method
		SpringMethod cons = __cl.lookupMethod(false,
			new MethodName("<init>"), __desc);
		
		// Allocate the object
		SpringObject rv = this.allocateObject(__cl);
			
		// Stop execution when the constructor exits
		SpringThread thread = this.thread;
		int framelimit = thread.numFrames();
................................................................................
		
		// Execute until it finishes
		this.run(framelimit);
		
		// Return the resulting object
		return rv;
	}
	
	/**
	 * Resolves the given class, checking access.
	 *
	 * @param __cl The class to resolve.
	 * @return The resolved class.
	 * @throws NullPointerException On null arguments.
	 * @throws SpringIllegalAccessException If the class cannot be accessed.
	 * @since 2020/06/17
	 */
	public final SpringClass resolveClass(String __cl)
		throws NullPointerException, SpringIllegalAccessException
	{
		return this.resolveClass(new ClassName(__cl));
	}
	
	/**
	 * Resolves the given class, checking access.
	 *
	 * @param __cl The class to resolve.
	 * @return The resolved class.
	 * @throws NullPointerException On null arguments.
................................................................................
				this.__singleStep();
			}
		}
		
		// If the VM is exiting then clear the execution stack before we go
		// away
		catch (SpringMachineExitException e)
		{	
			// Terminate the thread
			thread.terminate();
			
			// Thread is okay to exit!

			thread._signaledexit = true;
			
			// Exit all frames
			thread.exitAllFrames();
			
			// Exit profiler stack
			thread.profiler.exitAll(System.nanoTime());
................................................................................
		
		// Caught exception
		catch (RuntimeException e)
		{
			// Frame limit is zero, so kill the thread
			if (__framelimit == 0)
			{
				// Terminate the thread
				thread.terminate();
				
				PrintStream err = System.err;
				
				err.println("****************************");
				
				// Print the real stack trace
				err.println("*** EXTERNAL STACK TRACE ***");
				e.printStackTrace(err);
................................................................................
				// Print the VM seen stack trace
				err.println("*** INTERNAL STACK TRACE ***");
				thread.printStackTrace(err);
				err.println();
				
				err.println("****************************");
				



				// Exit all frames
				thread.exitAllFrames();
				
				// Exit from all profiler threads
				thread.profiler.exitAll(System.nanoTime());
			}
			
................................................................................
			throw e;
		}
		
		// Terminate if the last frame
		finally
		{
			if (__framelimit == 0)
				thread.terminate();
		}
	}
	
	/**
	 * Run the main process for this thread.
	 *
	 * @since 2020/06/17
	 */
	public final void runProcessMain()
	{
		SpringMachine machine = this.machine;
		
		// Locate the main class
		SpringClass bootClass = this.loadClass(
			machine.bootClass.replace('.', '/'));
		
		// Lookup the main method
		SpringMethod main = bootClass.lookupMethod(true,
			new MethodNameAndType("main", "([Ljava/lang/String;)V"));
		
		// Setup main arguments
		String[] args = machine.getMainArguments();
		int argsLen = args.length;
		
		// Allocate in VM
		SpringArrayObject vmArgs = this.allocateArray(
			this.resolveClass("[Ljava/lang/String;"), argsLen);
		
		// Copy everything over
		for (int i = 0; i < argsLen; i++)
			vmArgs.set(i, this.asVMObject(args[i]));
		
		// Enter the main method with all the passed arguments
		int deepness = this.thread.numFrames();
		this.thread.enterFrame(main, vmArgs);
		
		// Run until it finishes execution
		this.run(deepness);
	}
	
	/**
	 * Checks if an exception is being thrown and sets up the state from it.
	 *
	 * @return True if an exception was detected.
	 * @since 2018/12/06
	 */
................................................................................
			// Pop our current frame from the call stack
			thread.popFrame();
			
			// Did we run out of stack frames?
			SpringThread.Frame cf = thread.currentFrame();
			if (cf == null)
			{






				// Just stop execution here
				return -1;
			}
			
			// Toss onto the new current frame
			cf.tossException(__o);
			
................................................................................
		}
		
		// If the VM is exiting then clear the execution stack before we go
		// away
		catch (SpringMachineExitException e)
		{
			// Thread is okay to exit!
			thread.terminate();
			
			// Exit profiler stack
			thread.profiler.exitAll(System.nanoTime());
			
			throw e;
		}
		
................................................................................
					frame.loadToStack(SpringObject.class,
						opid - InstructionIndex.ALOAD_0);
					break;
				
					// Allocate new array
				case InstructionIndex.ANEWARRAY:
					frame.pushToStack(this.allocateArray(this.resolveClass(
						inst.<ClassName>argument(0, ClassName.class)
						.addDimensions(1)),
						frame.<Integer>popFromStack(Integer.class)));
					break;
					
					// Return reference
				case InstructionIndex.ARETURN:
					this.__vmReturn(thread,
						frame.<SpringObject>popFromStack(SpringObject.class));
................................................................................
						SpringObject pop = frame.<SpringObject>popFromStack(
							SpringObject.class);
						
						// {@squirreljme.error BK2d Cannot cast object to the
						// target type. (The type to cast to; The type of the
						// object)}
						if (pop != SpringNullObject.NULL &&
							!(pop instanceof AbstractGhostObject) &&
							!as.isAssignableFrom(pop.type()))
							throw new SpringClassCastException(String.format(
								"BK2d %s %s", as, pop.type()));
						
						// Return the popped value
						else
							frame.pushToStack(pop);
................................................................................
					this.__vmNew(inst, frame);
					break;
				
					// Allocate new primitive array
				case InstructionIndex.NEWARRAY:
					frame.pushToStack(this.allocateArray(this.resolveClass(
						ClassName.fromPrimitiveType(
						inst.<PrimitiveType>argument(0,
							PrimitiveType.class)).addDimensions(1)),
						frame.<Integer>popFromStack(Integer.class)));
					break;
					
					// Return from method with no return value
				case InstructionIndex.RETURN:
					thread.popFrame();
					break;
................................................................................
		// because it is of the wrong type. (The reference class; The class
		// of the target object; The first argument)}
		SpringClass objclass = onthis.type();
		if (objclass == null || !refclass.isAssignableFrom(objclass))
			throw new SpringClassCastException(
				String.format("BK32 %s %s %s", refclass, objclass, args[0]));
		
		// Re-lookup the method since we need to the right one! Then invoke it
		__t.enterFrame(objclass.lookupMethod(false,


















































































































			ref.memberNameAndType()), args);









































































































































































































































































































































	}
	
	/**
	 * Performs a special invoke.
	 *
	 * @param __i The instruction.
	 * @param __t The current thread.
................................................................................
		Object[] args = new Object[nargs];
		for (int i = nargs - 1; i >= 0; i--)
			args[i] = __f.popFromStack();
		
		// Virtualized native call, depends on what it is
		if (refmethod.flags().isNative())
		{
			// Add profiler point for native calls to track them there along
			// with being able to handle that
			ProfiledFrame pFrame = this.thread.profiler.enterFrame(
				ref.className().toString(),
				ref.memberName().toString(), ref.memberType().toString());
			
			// Now perform the actual call
			try
			{
				// Calculate result of method
				MethodDescriptor type = ref.memberType();
				Object rv = this.nativeMethod(ref.className(),
					ref.memberNameAndType(), args);
				
				// Push native object to the stack
				if (type.hasReturnValue())
					__f.pushToStack(this.asVMObject(rv, true));
			}
			
			// Exit the profiler frame to it is no longer tracked
			finally
			{
				if (pFrame.inCallCount() > 0)
					this.thread.profiler.exitFrame();
			}
		}
		
		// Real code that exists in class file format
		else
			__t.enterFrame(refmethod, args);
	}
	

Changes to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringVMStaticMethod.java.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
..
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/**
 * This is a virtual machine representation of a static method.
 *
 * @since 2018/11/20
 */
@Deprecated
public final class SpringVMStaticMethod
	implements SpringObject
{
	/** The method to execute. */
	protected final SpringMethod method;
	
	/**
	 * Initializes the static method.
	 *
................................................................................
		throws NullPointerException
	{
		if (__m == null)
			throw new NullPointerException("NARG");
		
		this.method = __m;
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/20
	 */
	@Override
	public final SpringMonitor monitor()
	{
		// {@squirreljme.error BK3b StaticMethod does not have a monitor.}
		throw new SpringFatalException("BK3b");
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2019/12/21
	 */
	@Override
	public final SpringPointerArea pointerArea()
	{
		throw new todo.TODO();
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2018/11/20
	 */
	@Override
	public final SpringClass type()
	{
		// {@squirreljme.error BK3c StaticMethod does not have a type.}
		throw new SpringFatalException("BK3c");
	}
}








|







 







|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
..
33
34
35
36
37
38
39
40






41


























/**
 * This is a virtual machine representation of a static method.
 *
 * @since 2018/11/20
 */
@Deprecated
public final class SpringVMStaticMethod
	extends AbstractGhostObject
{
	/** The method to execute. */
	protected final SpringMethod method;
	
	/**
	 * Initializes the static method.
	 *
................................................................................
		throws NullPointerException
	{
		if (__m == null)
			throw new NullPointerException("NARG");
		
		this.method = __m;
	}
}

































Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/brackets/JarPackageObject.java.









































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.brackets;

import cc.squirreljme.vm.VMClassLibrary;
import cc.squirreljme.vm.springcoat.AbstractGhostObject;

/**
 * Not Described.
 *
 * @since 2020/06/17
 */
public class JarPackageObject
	extends AbstractGhostObject
{
	/** The class library. */
	private final VMClassLibrary library;
	
	/**
	 * Initializes the package object.
	 *
	 * @param __lib The library.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/17
	 */
	public JarPackageObject(VMClassLibrary __lib)
		throws NullPointerException
	{
		if (__lib == null)
			throw new NullPointerException("NARG");
		
		this.library = __lib;
	}
	
	/**
	 * Returns the library.
	 *
	 * @return The library.
	 * @since 2020/06/17
	 */
	public VMClassLibrary library()
	{
		return this.library;
	}
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/brackets/RefLinkHolder.java.























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.brackets;

/**
 * Contains the holder for reference links.
 *
 * @since 2020/05/31
 */
public final class RefLinkHolder
{
	/** The associated link. */
	RefLinkObject _link;
	
	/**
	 * Returns the ref link.
	 *
	 * @return The link.
	 * @since 2020/05/31
	 */
	public RefLinkObject get()
	{
		return this._link;
	}
	
	/**
	 * Sets the ref link.
	 *
	 * @param __link The link.
	 * @since 2020/05/31
	 */
	public void set(RefLinkObject __link)
	{
		this._link = __link;
	}
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/brackets/RefLinkObject.java.







































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.brackets;

import cc.squirreljme.jvm.mle.brackets.RefLinkBracket;
import cc.squirreljme.vm.springcoat.AbstractGhostObject;
import cc.squirreljme.vm.springcoat.SpringObject;

/**
 * This contains the storage for reference links, these chain to each other.
 *
 * @see RefLinkBracket
 * @since 2020/05/30
 */
public final class RefLinkObject
	extends AbstractGhostObject
{
	/** The object this links. */
	volatile SpringObject _object;
	
	/** The next link in the chain. */
	volatile RefLinkObject _next;
	
	/** The previous link in the chain. */
	volatile RefLinkObject _prev;
	
	/**
	 * Gets the next link.
	 * 
	 * @return The link.
	 * @since 2020/06/29
	 */
	public RefLinkObject getNext()
	{
		return this._next;
	}
	
	/**
	 * Returns the object that this points to.
	 *
	 * @return The object.
	 * @since 2020/06/13
	 */
	public final SpringObject getObject()
	{
		return this._object;
	}
	
	/**
	 * Gets the previous link.
	 * 
	 * @return The link.
	 * @since 2020/06/29
	 */
	public RefLinkObject getPrev()
	{
		return this._prev;
	}
	
	/**
	 * Sets the next link.
	 * 
	 * @param __next The new link.
	 * @since 2020/06/29
	 */
	public void setNext(RefLinkObject __next)
	{
		this._next = __next;
	}
	
	/**
	 * Sets the object of this holder.
	 *
	 * @param __o The object to set.
	 * @since 2020/06/13
	 */
	public void setObject(SpringObject __o)
	{
		this._object = __o;
	}
	
	/**
	 * Sets the previous link.
	 * 
	 * @param __prev The new link.
	 * @since 2020/06/29
	 */
	public void setPrev(RefLinkObject __prev)
	{
		this._prev = __prev;
	}
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/brackets/TracePointObject.java.









































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.brackets;

import cc.squirreljme.runtime.cldc.debug.CallTraceElement;
import cc.squirreljme.vm.springcoat.AbstractGhostObject;

/**
 * This class stores anything that is within trace points and such.
 *
 * @since 2020/06/12
 */
public final class TracePointObject
	extends AbstractGhostObject
{
	/** The trace for the call. */
	protected final CallTraceElement trace;
	
	/**
	 * Initializes the trace point.
	 *
	 * @param __trace The trace to wrap.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/14
	 */
	public TracePointObject(CallTraceElement __trace)
		throws NullPointerException
	{
		if (__trace == null)
			throw new NullPointerException("NARG");
		
		this.trace = __trace;
	}
	
	/**
	 * Returns the trace.
	 *
	 * @return The trace.
	 * @since 2020/06/16
	 */
	public final CallTraceElement getTrace()
	{
		return this.trace;
	}
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/brackets/TypeObject.java.









































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.brackets;

import cc.squirreljme.vm.springcoat.AbstractGhostObject;
import cc.squirreljme.vm.springcoat.SpringClass;

/**
 * Represents a type from within the VM.
 *
 * @since 2020/06/02
 */
public class TypeObject
	extends AbstractGhostObject
{
	/** The class this provides. */
	protected final SpringClass classy;
	
	/**
	 * Initializes the type object.
	 *
	 * @param __cl The class to use.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/04
	 */
	public TypeObject(SpringClass __cl)
		throws NullPointerException
	{
		if (__cl == null)
			throw new NullPointerException("NARG");
		
		this.classy = __cl;
	}
	
	/**
	 * Returns the class this refers to.
	 *
	 * @return The class this refers to.
	 * @since 2020/06/13
	 */
	public final SpringClass getSpringClass()
	{
		return this.classy;
	}
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/brackets/VMThreadObject.java.









































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.brackets;

import cc.squirreljme.vm.springcoat.AbstractGhostObject;
import cc.squirreljme.vm.springcoat.SpringThread;

/**
 * This represents the "thread" object.
 *
 * @since 2020/06/17
 */
public final class VMThreadObject
	extends AbstractGhostObject
{
	/** The thread to target. */
	protected final SpringThread thread;
	
	/**
	 * Initializes the thread.
	 *
	 * @param __thread The thread to target.
	 * @throws NullPointerException On null arguments.
	 * @since 2020/06/17
	 */
	public VMThreadObject(SpringThread __thread)
		throws NullPointerException
	{
		if (__thread == null)
			throw new NullPointerException("NARG");
		
		this.thread = __thread;
	}
	
	/**
	 * Returns the thread this is bound to.
	 *
	 * @return The thread this is bound to.
	 * @since 2020/06/17
	 */
	public SpringThread getThread()
	{
		return this.thread;
	}
}

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/brackets/package-info.java.

































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

/**
 * The package contains the brackets used for SpringCoat.
 *
 * @since 2020/06/12
 */

package cc.squirreljme.vm.springcoat.brackets;

Name change from emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringArithmeticException.java to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/exceptions/SpringArithmeticException.java.

4
5
6
7
8
9
10
11



12
13
14
15
16
17
18
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;




/**
 * This is thrown when a divide by zero occurs.
 *
 * @since 2018/12/04
 */
public class SpringArithmeticException







|
>
>
>







4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.exceptions;

import cc.squirreljme.vm.springcoat.SpringConvertableThrowable;
import cc.squirreljme.vm.springcoat.SpringException;

/**
 * This is thrown when a divide by zero occurs.
 *
 * @since 2018/12/04
 */
public class SpringArithmeticException

Name change from emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringArrayIndexOutOfBoundsException.java to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/exceptions/SpringArrayIndexOutOfBoundsException.java.

4
5
6
7
8
9
10
11



12
13
14
15
16
17
18
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;




/**
 * This is thrown when an invalid out of bounds index was accessed in an
 * array.
 *
 * @since 2018/09/16
 */







|
>
>
>







4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.exceptions;

import cc.squirreljme.vm.springcoat.SpringConvertableThrowable;
import cc.squirreljme.vm.springcoat.SpringException;

/**
 * This is thrown when an invalid out of bounds index was accessed in an
 * array.
 *
 * @since 2018/09/16
 */

Name change from emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringArrayStoreException.java to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/exceptions/SpringArrayStoreException.java.

4
5
6
7
8
9
10
11



12
13
14
15
16
17
18
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;




/**
 * This is thrown when an invalid value was attempted to be stored into an
 * array.
 *
 * @since 2018/09/16
 */







|
>
>
>







4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.exceptions;

import cc.squirreljme.vm.springcoat.SpringConvertableThrowable;
import cc.squirreljme.vm.springcoat.SpringException;

/**
 * This is thrown when an invalid value was attempted to be stored into an
 * array.
 *
 * @since 2018/09/16
 */

Name change from emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringClassCastException.java to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/exceptions/SpringClassCastException.java.

4
5
6
7
8
9
10
11



12
13
14
15
16
17
18
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;




/**
 * This is thrown when an attempt is made to cast from one class type to
 * another.
 *
 * @since 2018/09/15
 */







|
>
>
>







4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.exceptions;

import cc.squirreljme.vm.springcoat.SpringConvertableThrowable;
import cc.squirreljme.vm.springcoat.SpringException;

/**
 * This is thrown when an attempt is made to cast from one class type to
 * another.
 *
 * @since 2018/09/15
 */

Name change from emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringClassFormatException.java to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/exceptions/SpringClassFormatException.java.

4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;


import net.multiphasicapps.classfile.ClassName;

/**
 * This is thrown when the format of a class is not correct, it is invalid.
 *
 * @since 2018/08/05
 */







|

>







4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.exceptions;

import cc.squirreljme.vm.springcoat.SpringException;
import net.multiphasicapps.classfile.ClassName;

/**
 * This is thrown when the format of a class is not correct, it is invalid.
 *
 * @since 2018/08/05
 */

Name change from emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringClassNotFoundException.java to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/exceptions/SpringClassNotFoundException.java.

4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;


import net.multiphasicapps.classfile.ClassName;

/**
 * This is thrown when the specified class could not be found.
 *
 * @since 2018/08/05
 */







|

>







4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.exceptions;

import cc.squirreljme.vm.springcoat.SpringException;
import net.multiphasicapps.classfile.ClassName;

/**
 * This is thrown when the specified class could not be found.
 *
 * @since 2018/08/05
 */

Name change from emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringFatalException.java to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/exceptions/SpringFatalException.java.

4
5
6
7
8
9
10
11


12
13
14
15
16
17
18
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;



/**
 * This is an exception which describes something that is very fatal within
 * the virtual machine.
 *
 * @since 2018/09/20
 */







|
>
>







4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.exceptions;

import cc.squirreljme.vm.springcoat.SpringException;

/**
 * This is an exception which describes something that is very fatal within
 * the virtual machine.
 *
 * @since 2018/09/20
 */

Name change from emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringIllegalAccessException.java to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/exceptions/SpringIllegalAccessException.java.

4
5
6
7
8
9
10
11


12
13
14
15
16
17
18
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;



/**
 * This is thrown when a class or member of a class cannot be accessed.
 *
 * @since 2018/09/15
 */
public class SpringIllegalAccessException







|
>
>







4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.exceptions;

import cc.squirreljme.vm.springcoat.SpringException;

/**
 * This is thrown when a class or member of a class cannot be accessed.
 *
 * @since 2018/09/15
 */
public class SpringIllegalAccessException

Name change from emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringIllegalMonitorStateException.java to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/exceptions/SpringIllegalMonitorStateException.java.

4
5
6
7
8
9
10
11



12
13
14
15
16
17
18
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;




/**
 * This is thrown when the state of a monitor is not valid.
 *
 * @since 2018/09/15
 */
public class SpringIllegalMonitorStateException







|
>
>
>







4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.exceptions;

import cc.squirreljme.vm.springcoat.SpringConvertableThrowable;
import cc.squirreljme.vm.springcoat.SpringException;

/**
 * This is thrown when the state of a monitor is not valid.
 *
 * @since 2018/09/15
 */
public class SpringIllegalMonitorStateException

Name change from emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringIncompatibleClassChangeException.java to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/exceptions/SpringIncompatibleClassChangeException.java.

4
5
6
7
8
9
10
11


12
13
14
15
16
17
18
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;



/**
 * This is thrown when a class refers to another reference and it differs
 * than what was expected at run-time.
 *
 * @since 2018/09/09
 */







|
>
>







4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.exceptions;

import cc.squirreljme.vm.springcoat.SpringException;

/**
 * This is thrown when a class refers to another reference and it differs
 * than what was expected at run-time.
 *
 * @since 2018/09/09
 */

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/exceptions/SpringMLECallError.java.



























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.exceptions;

import cc.squirreljme.jvm.mle.exceptions.MLECallError;
import cc.squirreljme.vm.springcoat.SpringConvertableThrowable;
import cc.squirreljme.vm.springcoat.SpringException;

/**
 * This is SpringCoat's variant of {@link MLECallError}.
 *
 * @since 2020/06/22
 */
public class SpringMLECallError
	extends SpringException
	implements SpringConvertableThrowable
{
	/**
	 * Initialize the exception with no message or cause.
	 *
	 * @since 2020/06/22
	 */
	public SpringMLECallError()
	{
	}
	
	/**
	 * Initialize the exception with a message and no cause.
	 *
	 * @param __m The message.
	 * @since 2020/06/22
	 */
	public SpringMLECallError(String __m)
	{
		super(__m);
	}
	
	/**
	 * Initialize the exception with a message and cause.
	 *
	 * @param __m The message.
	 * @param __c The cause.
	 * @since 2020/06/22
	 */
	public SpringMLECallError(String __m, Throwable __c)
	{
		super(__m, __c);
	}
	
	/**
	 * Initialize the exception with no message and with a cause.
	 *
	 * @param __c The cause.
	 * @since 2020/06/22
	 */
	public SpringMLECallError(Throwable __c)
	{
		super(__c);
	}
	
	/**
	 * {@inheritDoc}
	 * @since 2020/06/22
	 */
	@Override
	public String targetClass()
	{
		return "cc/squirreljme/jvm/mle/exceptions/MLECallError";
	}
}

Name change from emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringMachineExitException.java to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/exceptions/SpringMachineExitException.java.

4
5
6
7
8
9
10
11


12
13
14
15
16
17
18
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;



/**
 * This is thrown when the virtual machine is exiting.
 *
 * @since 2018/10/13
 */
public class SpringMachineExitException







|
>
>







4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.exceptions;

import cc.squirreljme.vm.springcoat.SpringException;

/**
 * This is thrown when the virtual machine is exiting.
 *
 * @since 2018/10/13
 */
public class SpringMachineExitException

Name change from emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringNegativeArraySizeException.java to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/exceptions/SpringNegativeArraySizeException.java.

4
5
6
7
8
9
10
11



12
13
14
15
16
17
18
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;




/**
 * This is thrown when an attempt was made to allocate an array of a negative
 * size.
 *
 * @since 2018/09/15
 */







|
>
>
>







4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.exceptions;

import cc.squirreljme.vm.springcoat.SpringConvertableThrowable;
import cc.squirreljme.vm.springcoat.SpringException;

/**
 * This is thrown when an attempt was made to allocate an array of a negative
 * size.
 *
 * @since 2018/09/15
 */

Name change from emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringNoSuchFieldException.java to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/exceptions/SpringNoSuchFieldException.java.

4
5
6
7
8
9
10
11


12
13
14
15
16
17
18
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;



/**
 * This is thrown when a field in a class does not exist.
 *
 * @since 2018/09/09
 */
public class SpringNoSuchFieldException







|
>
>







4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.exceptions;

import cc.squirreljme.vm.springcoat.exceptions.SpringIncompatibleClassChangeException;

/**
 * This is thrown when a field in a class does not exist.
 *
 * @since 2018/09/09
 */
public class SpringNoSuchFieldException

Name change from emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringNoSuchMethodException.java to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/exceptions/SpringNoSuchMethodException.java.

4
5
6
7
8
9
10
11


12
13
14
15
16
17
18
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;



/**
 * This is thrown when a method in a class does not exist.
 *
 * @since 2018/09/03
 */
public class SpringNoSuchMethodException







|
>
>







4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.exceptions;

import cc.squirreljme.vm.springcoat.exceptions.SpringIncompatibleClassChangeException;

/**
 * This is thrown when a method in a class does not exist.
 *
 * @since 2018/09/03
 */
public class SpringNoSuchMethodException

Name change from emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringNullPointerException.java to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/exceptions/SpringNullPointerException.java.

4
5
6
7
8
9
10
11



12
13
14
15
16
17
18
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;




/**
 * This is thrown when a null reference has been detected.
 *
 * @since 2018/09/09
 */
public class SpringNullPointerException







|
>
>
>







4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.exceptions;

import cc.squirreljme.vm.springcoat.SpringConvertableThrowable;
import cc.squirreljme.vm.springcoat.SpringException;

/**
 * This is thrown when a null reference has been detected.
 *
 * @since 2018/09/09
 */
public class SpringNullPointerException

Name change from emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/SpringVirtualMachineException.java to emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/exceptions/SpringVirtualMachineException.java.

4
5
6
7
8
9
10
11


12
13
14
15
16
17
18
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat;



/**
 * This is thrown when the virtual machine has been detected to not be
 * operating properly, this is an error.
 *
 * @since 2018/09/01
 */







|
>
>







4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
//     Copyright (C) Multi-Phasic Applications <multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.vm.springcoat.exceptions;

import cc.squirreljme.vm.springcoat.SpringException;

/**
 * This is thrown when the virtual machine has been detected to not be
 * operating properly, this is an error.
 *
 * @since 2018/09/01
 */

Added emulators/springcoat-vm/src/main/java/cc/squirreljme/vm/springcoat/exceptions/package-info.java.

































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

/**
 * This package contains all of the exception types used within SpringCoat.
 *
 * @since 2020/06/12
 */

package cc.squirreljme.vm.springcoat.exceptions;

Changes to emulators/summercoat-vm/build.gradle.

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
description = "This is the SummerCoat VM which is a more " +
	"optimized register based virtual machine which should result in faster" +
	"code execution."

dependencies
{
	api project(":emulators:emulator-base")

	api project(":modules:cldc-compact")
	api project(":modules:collections")
	api project(":modules:common-vm")
	api project(":modules:io")
	api project(":modules:meep-midlet")
	api project(":modules:meep-swm")
	api project(":modules:tool-classfile")
	api project(":modules:tool-jarfile")
	api project(":modules:tool-manifest-reader")
	api project(":modules:tool-packfile")
}







|

<

<
<
<


<

|
6
7
8
9
10
11
12
13
14

15



16
17

18
19
description = "This is the SummerCoat VM which is a more " +
	"optimized register based virtual machine which should result in faster" +
	"code execution."

dependencies
{
	api project(":emulators:emulator-base")
	
	api project(":modules:cldc-compact")

	api project(":modules:common-vm")



	api project(":modules:tool-classfile")
	api project(":modules:tool-jarfile")

	api project(":modules:tool-packfile")
}

Changes to gradle/wrapper/gradle-wrapper.properties.

1
2
3
4
5
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists


|


1
2
3
4
5
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

Added language.mkd.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Language Information

# Pronunciation

 * IPA
   * `[ˈskwərəl] [ʤeɪ] [ɛm] [i]`
 * Phonetics
   * `skwUHR-ruhl jAY-Em-EE`

# Translation/Transliterations

The _Squirrel_ in _SquirrelJME_ may be translated or not, if it is translated
and not transliterated then **Both** with be specified, otherwise it will
be **Transliteration**.

 * Bosnian
   * Both: `VjevericaDŽMI`, `ВјеверицаЏМЕ`
   * Transliteration: `SkvrlDŽMI`, `СкврлЏМI`
 * Japanese
   * Transliteration: `スクアルジェエムイ`, `sukuaru je'emui`

Changes to license.mkd.

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 * Assets which are not fonts, includes the mascot, logo, and icons:
   * **Creative Commons CC-BY-SA 4.0**
 * Fonts:
   * **SIL Open Font License Version 1.1**

[Commercial licenses are available under the commercial terms](commercial.mkd).

Contributors must agree to the [contributor license](contibuting.mkd) before
their code may be accepted.

Additionally, if the **GNU GPLv3** and **CC-BY-SA 4.0** are not desirable a
proprietary license may be purchased for a negotiable fee. The terms of the
contract are to be negotiated.

Note that there is no linking exception to the **GNU GPLv3**, this is because:







|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 * Assets which are not fonts, includes the mascot, logo, and icons:
   * **Creative Commons CC-BY-SA 4.0**
 * Fonts:
   * **SIL Open Font License Version 1.1**

[Commercial licenses are available under the commercial terms](commercial.mkd).

Contributors must agree to the [contributor license](contributing.mkd) before
their code may be accepted.

Additionally, if the **GNU GPLv3** and **CC-BY-SA 4.0** are not desirable a
proprietary license may be purchased for a negotiable fee. The terms of the
contract are to be negotiated.

Note that there is no linking exception to the **GNU GPLv3**, this is because:

Changes to modules/cldc-compact/src/main/java/cc/squirreljme/jvm/ClassInfo.java.

11
12
13
14
15
16
17

18
19
20
21
22
23
24

/**
 * This contains class information which is used to define the information
 * that is needed to parse it properly.
 *
 * @since 2019/05/25
 */

public final class ClassInfo
{
	/** The magic number which should be used. */
	public static final int MAGIC_NUMBER =
		0x4C6F7665;
	
	/** Self pointer. */







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

/**
 * This contains class information which is used to define the information
 * that is needed to parse it properly.
 *
 * @since 2019/05/25
 */
@Deprecated
public final class ClassInfo
{
	/** The magic number which should be used. */
	public static final int MAGIC_NUMBER =
		0x4C6F7665;
	
	/** Self pointer. */

Changes to modules/cldc-compact/src/main/java/cc/squirreljme/jvm/config/BuiltInLocale.java.

10
11
12
13
14
15
16

17
18
19
20
21
22
23
package cc.squirreljme.jvm.config;

/**
 * This represents a built-in locale.
 *
 * @since 2020/05/12
 */

public interface BuiltInLocale
{
	/** Unknown, will be treated as US English. */
	byte UNKNOWN =
		0;
	
	/** English: United States of America. */







>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package cc.squirreljme.jvm.config;

/**
 * This represents a built-in locale.
 *
 * @since 2020/05/12
 */
@Deprecated
public interface BuiltInLocale
{
	/** Unknown, will be treated as US English. */
	byte UNKNOWN =
		0;
	
	/** English: United States of America. */

Changes to modules/cldc-compact/src/main/java/cc/squirreljme/jvm/config/ConfigRomKey.java.

5
6
7
8
9
10
11



12
13
14
15
16
17
18
...
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.jvm.config;




/**
 * This represents an option in the configuration ROM.
 *
 * @since 2019/06/14
 */
public interface ConfigRomKey
{
................................................................................
	 * @squirreljme.configtype {@link ConfigRomType#LONG}
	 * @since 2019/06/14
	 */
	byte SYSCALL_POOL_POINTER =
		14;
	
	/**
	 * The built-in encoding to use, see {@link BuiltInEncoding}.
	 *
	 * @squirreljme.configtype {@link ConfigRomType#INTEGER}
	 * @since 2019/06/14
	 */
	byte BUILT_IN_ENCODING =
		15;
	







>
>
>







 







|







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.jvm.config;

import cc.squirreljme.jvm.mle.constants.BuiltInEncodingType;
import cc.squirreljme.jvm.mle.constants.LineEndingType;

/**
 * This represents an option in the configuration ROM.
 *
 * @since 2019/06/14
 */
public interface ConfigRomKey
{
................................................................................
	 * @squirreljme.configtype {@link ConfigRomType#LONG}
	 * @since 2019/06/14
	 */
	byte SYSCALL_POOL_POINTER =
		14;
	
	/**
	 * The built-in encoding to use, see {@link BuiltInEncodingType}.
	 *
	 * @squirreljme.configtype {@link ConfigRomType#INTEGER}
	 * @since 2019/06/14
	 */
	byte BUILT_IN_ENCODING =
		15;
	

Deleted modules/cldc-compact/src/main/java/cc/squirreljme/jvm/config/LineEndingType.java.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.jvm.config;

/**
 * The type of line ending used.
 *
 * @since 2020/04/09
 */
public interface LineEndingType
{
	/** Unspecified. */
	byte UNSPECIFIED =
		0;
	
	/** LF. */
	byte LF =
		1;
	
	/** CR. */
	byte CR =
		2;
	
	/** CRLF. */
	byte CRLF =
		3;
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































Added modules/cldc-compact/src/main/java/cc/squirreljme/jvm/mle/AtomicShelf.java.









































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.jvm.mle;

/**
 * This shelf provides helpers for atomic operations.
 *
 * @since 2020/05/30
 */
public final class AtomicShelf
{
	/**
	 * Not used.
	 *
	 * @since 2020/05/30
	 */
	private AtomicShelf()
	{
	}
	
	/**
	 * Lock for garbage collection operations.
	 *
	 * @return The locking key if locked, otherwise {@code 0} when busy.
	 * @since 2020/05/30
	 */
	public static native int gcLock();
	
	/**
	 * Unlocks the garbage collector provided that the previous locking key
	 * matches.
	 *
	 * @param __key The key that was previously used to lock the garbage
	 * collector.
	 * @since 2020/05/30
	 */
	public static native void gcUnlock(int __key);
	
	/**
	 * For constant lock spins, this provides a consistent means of counting
	 * and then potentially fire-spinning or resting depending on the
	 * situation. This may cause a thread to preempt.
	 *
	 * On cooperatively tasked systems, this may switch to another thread.
	 *
	 * @param __count The number of times the lock has spun.
	 * @since 2020/05/30
	 */
	public static native void spinLock(int __count);
	
	/**
	 * Returns a "unique" atomic tick value. The value returned should be
	 * unique enough but the actual value that is returned should not be used
	 * in any way for comparisons other than equality.
	 *
	 * @return The tick value, note that it should not be used for comparisons
	 * other than equality.
	 * @since 2020/05/03
	 */
	public static native int tick();
}

Added modules/cldc-compact/src/main/java/cc/squirreljme/jvm/mle/DebugShelf.java.

















































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.jvm.mle;

import cc.squirreljme.jvm.mle.brackets.TracePointBracket;

/**
 * This is the shelf used for accessing the debugging features of SquirrelJME
 * along with miscellaneous debugging utilities.
 *
 * @since 2020/06/11
 */
public final class DebugShelf
{
	/**
	 * Not used.
	 *
	 * @since 2020/06/11
	 */
	private DebugShelf()
	{
	}
	
	/**
	 * Returns the trace that is part of the given throwable.
	 *
	 * @param __t The throwable to gets it's trace of.
	 * @return The trace that was within the given throwable.
	 * @since 2020/06/11
	 */
	public static native TracePointBracket[] getThrowableTrace(Throwable __t);
	
	/**
	 * Resolves the address from the given point.
	 *
	 * @param __point The point to resolve.
	 * @return The address.
	 * @since 2020/06/16
	 */
	public static native long pointAddress(TracePointBracket __point);
	
	/**
	 * Resolves the class from the given point.
	 *
	 * @param __point The point to resolve.
	 * @return The class.
	 * @since 2020/06/16
	 */
	public static native String pointClass(TracePointBracket __point);
	
	/**
	 * Resolves the file from the given point.
	 *
	 * @param __point The point to resolve.
	 * @return The file.
	 * @since 2020/06/16
	 */
	public static native String pointFile(TracePointBracket __point);
	
	/**
	 * Resolves the Java address from the given point.
	 *
	 * @param __point The point to resolve.
	 * @return The Java address.
	 * @since 2020/06/16
	 */
	public static native int pointJavaAddress(TracePointBracket __point);
	
	/**
	 * Resolves the Java operation from the given point.
	 *
	 * @param __point The point to resolve.
	 * @return The Java operation.
	 * @since 2020/06/16
	 */
	public static native int pointJavaOperation(TracePointBracket __point);
	
	/**
	 * Resolves the line from the given point.
	 *
	 * @param __point The point to resolve.
	 * @return The line.
	 * @since 2020/06/16
	 */
	public static native int pointLine(TracePointBracket __point);
	
	/**
	 * Resolves the method name from the given point.
	 *
	 * @param __point The point to resolve.
	 * @return The method name.
	 * @since 2020/06/16
	 */
	public static native String pointMethodName(TracePointBracket __point);
	
	/**
	 * Resolves the method type from the given point.
	 *
	 * @param __point The point to resolve.
	 * @return The method type.
	 * @since 2020/06/16
	 */
	public static native String pointMethodType(TracePointBracket __point);
	
	/**
	 * Traces the entire stack, the top-most trace point in the stack is always
	 * first.
	 *
	 * @return The stack trace.
	 * @since 2020/06/11
	 */
	public static native TracePointBracket[] traceStack();
}

Added modules/cldc-compact/src/main/java/cc/squirreljme/jvm/mle/JarPackageShelf.java.

















































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.jvm.mle;

import cc.squirreljme.jvm.mle.brackets.JarPackageBracket;
import java.io.InputStream;

/**
 * This allows access to the library class path and resources.
 *
 * @since 2020/06/07
 */
public final class JarPackageShelf
{
	/**
	 * Returns the classpath of the current program.
	 *
	 * @return The classpath of the current program.
	 * @since 2020/06/07
	 */
	public static native JarPackageBracket[] classPath();
	
	/**
	 * Opens the resource from the input stream.
	 *
	 * @param __jar The JAR to open.
	 * @param __rc The resource to load from the given JAR.
	 * @return Input stream to the resource.
	 * @since 2020/06/07
	 */
	public static native InputStream openResource(JarPackageBracket __jar,
		String __rc);
}

Added modules/cldc-compact/src/main/java/cc/squirreljme/jvm/mle/MathShelf.java.































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.jvm.mle;

/**
 * This contains various math functions.
 *
 * @since 2020/06/18
 */
public final class MathShelf
{
	/**
	 * Not used.
	 *
	 * @since 2020/06/18
	 */
	private MathShelf()
	{
	}
	
	/**
	 * Extracts the raw bits of the given value.
	 *
	 * @param __v The value to extract.
	 * @return The raw bits.
	 * @since 2020/06/18
	 */
	public static native long rawDoubleToLong(double __v);
	
	/**
	 * Extracts the raw bits of the given value.
	 *
	 * @param __v The value to extract.
	 * @return The raw bits.
	 * @since 2020/06/18
	 */
	public static native int rawFloatToInt(float __v);
	
	/**
	 * Composes the value from the given bits
	 *
	 * @param __b The raw bits.
	 * @return The value.
	 * @since 2020/06/18
	 */
	public static native float rawIntToFloat(int __b);
	
	/**
	 * Composes the value from the given bits
	 *
	 * @param __b The raw bits.
	 * @return The value.
	 * @since 2020/06/18
	 */
	public static native double rawLongToDouble(long __b);
}

Added modules/cldc-compact/src/main/java/cc/squirreljme/jvm/mle/ObjectShelf.java.



























































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.jvm.mle;

import cc.squirreljme.jvm.mle.brackets.TypeBracket;
import cc.squirreljme.jvm.mle.constants.MonitorResultType;

/**
 * This shelf supports object anything that has to do with objects.
 *
 * @since 2020/06/09
 */
public final class ObjectShelf
{
	/**
	 * Not used.
	 *
	 * @since 2020/06/09
	 */
	private ObjectShelf()
	{
	}
	
	/**
	 * Copies the given arrays.
	 * 
	 * @param __src The source array.
	 * @param __srcOff The source offset.
	 * @param __dest The destination array.
	 * @param __destOff The destination offset.
	 * @param __len The elements to copy.
	 * @since 2020/06/22
	 */
	public static native void arrayCopy(boolean[] __src, int __srcOff,
		boolean[] __dest, int __destOff, int __len);
	
	/**
	 * Copies the given arrays.
	 * 
	 * @param __src The source array.
	 * @param __srcOff The source offset.
	 * @param __dest The destination array.
	 * @param __destOff The destination offset.
	 * @param __len The elements to copy.
	 * @since 2020/06/22
	 */
	public static native void arrayCopy(byte[] __src, int __srcOff,
		byte[] __dest, int __destOff, int __len);
	
	/**
	 * Copies the given arrays.
	 * 
	 * @param __src The source array.
	 * @param __srcOff The source offset.
	 * @param __dest The destination array.
	 * @param __destOff The destination offset.
	 * @param __len The elements to copy.
	 * @since 2020/06/22
	 */
	public static native void arrayCopy(short[] __src, int __srcOff,
		short[] __dest, int __destOff, int __len);
	
	/**
	 * Copies the given arrays.
	 * 
	 * @param __src The source array.
	 * @param __srcOff The source offset.
	 * @param __dest The destination array.
	 * @param __destOff The destination offset.
	 * @param __len The elements to copy.
	 * @since 2020/06/22
	 */
	public static native void arrayCopy(char[] __src, int __srcOff,
		char[] __dest, int __destOff, int __len);
	
	/**
	 * Copies the given arrays.
	 * 
	 * @param __src The source array.
	 * @param __srcOff The source offset.
	 * @param __dest The destination array.
	 * @param __destOff The destination offset.
	 * @param __len The elements to copy.
	 * @since 2020/06/22
	 */
	public static native void arrayCopy(int[] __src, int __srcOff,
		int[] __dest, int __destOff, int __len);
	
	/**
	 * Copies the given arrays.
	 * 
	 * @param __src The source array.
	 * @param __srcOff The source offset.
	 * @param __dest The destination array.
	 * @param __destOff The destination offset.
	 * @param __len The elements to copy.
	 * @since 2020/06/22
	 */
	public static native void arrayCopy(long[] __src, int __srcOff,
		long[] __dest, int __destOff, int __len);
	
	/**
	 * Copies the given arrays.
	 * 
	 * @param __src The source array.
	 * @param __srcOff The source offset.
	 * @param __dest The destination array.
	 * @param __destOff The destination offset.
	 * @param __len The elements to copy.
	 * @since 2020/06/22
	 */
	public static native void arrayCopy(float[] __src, int __srcOff,
		float[] __dest, int __destOff, int __len);
	
	/**
	 * Copies the given arrays.
	 * 
	 * @param __src The source array.
	 * @param __srcOff The source offset.
	 * @param __dest The destination array.
	 * @param __destOff The destination offset.
	 * @param __len The elements to copy.
	 * @since 2020/06/22
	 */
	public static native void arrayCopy(double[] __src, int __srcOff,
		double[] __dest, int __destOff, int __len);
	
	/**
	 * Returns the length of the array if this object is an array.
	 *
	 * @param __object The object to get the length of.
	 * @return The length of the array or a negative value if this is not an
	 * array.
	 * @since 2020/06/09
	 */
	public static native int arrayLength(Object __object);
	
	/**
	 * Allocates a new array.
	 *
	 * @param <T> The resultant type of the array.
	 * @param __type The type to allocate the array for.
	 * @param __len The length of the array.
	 * @return The newly allocated array as the given object.
	 * @since 2020/06/09
	 */
	public static native <T> T arrayNew(TypeBracket __type, int __len);
	
	/**
	 * Checks if the given thread holds the lock on the given method.
	 *
	 * @param __javaThread The Java thread to check if it holds the lock.
	 * @param __o The object to check.
	 * @return If the given thread holds the lock.
	 * @since 2020/06/17
	 */
	public static native boolean holdsLock(Thread __javaThread, Object __o);
	
	/**
	 * Returns the identity hashcode of the object.
	 *
	 * @param __o The object to get the hashcode of.
	 * @return The identity hashcode of the object.
	 * @since 2020/06/18
	 */
	public static native int identityHashCode(Object __o);
	
	/**
	 * Creates a new instance of the given type.
	 *
	 * @param __type The type to instantiate.
	 * @return The newly created object or {@code null} if there was no
	 * memory left.
	 * @since 2020/06/17
	 */
	public static native Object newInstance(TypeBracket __type);
	
	/**
	 * Notifies the monitors holding onto this object.
	 * 
	 * @param __object The object to signal.
	 * @param __all Notify all threads?
	 * @return The {@link MonitorResultType}.
	 * @since 2020/06/22
	 */
	public static native int notify(Object __object, boolean __all);
	
	/**
	 * Waits on the given monitor.
	 * 
	 * @param __object The object to wait on.
	 * @param __ms The milliseconds to wait.
	 * @param __ns The nanoseconds to wait.
	 * @return The {@link MonitorResultType}.
	 * @since 2020/06/22
	 */
	public static native int wait(Object __object, long __ms, int __ns);
}

Added modules/cldc-compact/src/main/java/cc/squirreljme/jvm/mle/ReferenceShelf.java.





















































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.jvm.mle;

import cc.squirreljme.jvm.mle.brackets.RefLinkBracket;

/**
 * This provides the interface for references which are used to weakly refer
 * to them, so that they may be collected or act as a cache.
 *
 * @see RefLinkBracket
 * @since 2020/05/30
 */
public final class ReferenceShelf
{
	/**
	 * Not used.
	 *
	 * @since 2020/05/30
	 */
	private ReferenceShelf()
	{
	}
	
	/**
	 * Deletes the reference link, freeing any associated memory.
	 *
	 * @param __link The link to delete.
	 * @since 2020/05/30
	 */
	public static native void deleteLink(RefLinkBracket __link);
	
	/**
	 * Returns the link after the specified one.
	 *
	 * @param __link The link.
	 * @return The next link or {@code null} if there is none.
	 * @since 2020/05/30
	 */
	public static native RefLinkBracket linkGetNext(RefLinkBracket __link);
	
	/**
	 * Gets the object this points to.
	 *
	 * @param __link The link to get the object of.
	 * @return The object that this points to, or {@code null} if there
	 * is no pointed object.
	 * @since 2020/05/30
	 */
	public static native Object linkGetObject(RefLinkBracket __link);
	
	/**
	 * Returns the link before the specified one.
	 *
	 * @param __link The link.
	 * @return The previous link or {@code null} if there is none.
	 * @since 2020/05/30
	 */
	public static native RefLinkBracket linkGetPrev(RefLinkBracket __link);
	
	/**
	 * Sets the link that is after this one
	 *
	 * @param __link The link.
	 * @param __next The new link to set, may be {@code null} to clear.
	 * @since 2020/05/30
	 */
	public static native void linkSetNext(RefLinkBracket __link,
		RefLinkBracket __next);
	
	/**
	 * Sets the object that this points to.
	 *
	 * @param __link The link to be given the object.
	 * @param __v The object to set to, may be {@code null}.
	 * @since 2020/05/30
	 */
	public static native void linkSetObject(RefLinkBracket __link, Object __v);
	
	/**
	 * Sets the link that is before this one.
	 *
	 * @param __link The link.
	 * @param __prev The new link to set, may be {@code null} to clear.
	 * @since 2020/05/30
	 */
	public static native void linkSetPrev(RefLinkBracket __link,
		RefLinkBracket __prev);
	
	/**
	 * Creates a new reference link.
	 *
	 * @return The newly created reference link.
	 * @since 2020/05/30
	 */
	public static native RefLinkBracket newLink();
	
	/**
	 * Gets the link of an object.
	 *
	 * @param __o The object to get the link of.
	 * @return The link of the object or {@code null} if there is none.
	 * @since 2020/05/30
	 */
	public static native RefLinkBracket objectGet(Object __o);
	
	/**
	 * Sets the link of the object.
	 *
	 * @param __o The object to set the link of.
	 * @param __link The link to set to it.
	 * @since 2020/05/30
	 */
	public static native void objectSet(Object __o, RefLinkBracket __link);
}

Added modules/cldc-compact/src/main/java/cc/squirreljme/jvm/mle/RuntimeShelf.java.

































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.jvm.mle;

import cc.squirreljme.jvm.mle.constants.LineEndingType;
import cc.squirreljme.jvm.mle.constants.BuiltInEncodingType;
import cc.squirreljme.jvm.mle.constants.BuiltInLocaleType;
import cc.squirreljme.jvm.mle.constants.VMDescriptionType;
import cc.squirreljme.jvm.mle.constants.VMStatisticType;
import cc.squirreljme.jvm.mle.constants.VMType;
import cc.squirreljme.jvm.mle.exceptions.MLECallError;

/**
 * Run-time shelf which contains system information.
 *
 * @since 2020/06/09
 */
public final class RuntimeShelf
{
	/**
	 * Not used.
	 *
	 * @since 2020/06/09
	 */
	private RuntimeShelf()
	{
	}
	
	/**
	 * Returns the current time in milliseconds since UTC.
	 *
	 * @return The current time in milliseconds since UTC.
	 * @since 2020/06/18
	 */
	public static native long currentTimeMillis();
	
	/**
	 * Returns the encoding of the system.
	 *
	 * @return The encoding of the system, see {@link BuiltInEncodingType}.
	 * @see BuiltInEncodingType
	 * @since 2020/06/11
	 */
	public static native int encoding();
	
	/**
	 * Exits the virtual machine.
	 *
	 * @param __code The exit code.
	 * @since 2020/06/16
	 */
	public static native void exit(int __code);
	
	/**
	 * Returns the line ending type of the system.
	 *
	 * @return The line ending type of the system, see {@link LineEndingType}.
	 * @see LineEndingType
	 * @since 2020/06/09
	 */
	public static native int lineEnding();
	
	/**
	 * The built-in locate to use.
	 *
	 * @return The built-in locale, see {@link BuiltInLocaleType}.
	 * @see BuiltInLocaleType
	 * @since 2020/06/11
	 */
	public static native int locale();
	
	/**
	 * Returns the number of monotonic nanoseconds that have elapsed.
	 *
	 * @return The monotonic nanosecond clock.
	 * @since 2020/06/18
	 */
	public static native long nanoTime();
	
	/**
	 * Returns the system property for the given key, if there is one.
	 *
	 * @param __key The property key.
	 * @return The value of the system property or {@code null}.
	 * @throws MLECallError If {@code __key} is {@code null}.
	 * @since 2020/06/17
	 */
	public static native String systemProperty(String __key)
		throws MLECallError;
	
	/**
	 * Returns a special virtual machine description.
	 *
	 * @param __type The {@link VMDescriptionType}.
	 * @return The string for the given description or {@code null} if not
	 * set.
	 * @throws MLECallError If {@code __type} is not valid.
	 * @since 2020/06/17
	 */
	public static native String vmDescription(int __type)
		throws MLECallError;
	
	/**
	 * Returns a statistic of the virtual machine.
	 *
	 * @param __type The {@link VMStatisticType}.
	 * @return The value of the statistic, or {@code 0L} if not set.
	 * @throws MLECallError If {@code __type} is not valid.
	 * @since 2020/06/17
	 */
	public static native long vmStatistic(int __type)
		throws MLECallError;
	
	/**
	 * Returns the current {@link VMType}.
	 *
	 * @return The current {@link VMType}.
	 * @since 2020/06/16
	 */
	public static native int vmType();
}

Added modules/cldc-compact/src/main/java/cc/squirreljme/jvm/mle/TerminalShelf.java.





























































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.jvm.mle;

import cc.squirreljme.jvm.mle.constants.StandardPipeType;
import cc.squirreljme.runtime.cldc.annotation.Api;
import cc.squirreljme.runtime.cldc.lang.ApiLevel;

/**
 * This contains the shell for printing to the console and otherwise.
 *
 * @since 2020/06/14
 */
public final class TerminalShelf
{
	/**
	 * Not used.
	 *
	 * @since 2002/06/14
	 */
	private TerminalShelf()
	{
	}
	
	/**
	 * Flushes the stream.
	 *
	 * @param __fd The {@link StandardPipeType} to flush.
	 * @return Zero on success, negative values for failure.
	 * @since 2018/12/08
	 */
	public static native int flush(int __fd);
	
	/**
	 * Writes the character to the console output.
	 *
	 * @param __fd The {@link StandardPipeType} to write to.
	 * @param __c The byte to write, only the lowest 8-bits are used.
	 * @return Zero on success, negative values for failure.
	 * @since 2018/09/21
	 */
	public static native int write(int __fd, int __c);
	
	/**
	 * Writes the given bytes to the console output.
	 *
	 * @param __fd The {@link StandardPipeType} to write to.
	 * @param __b The bytes to write.
	 * @param __o The offset.
	 * @param __l The length.
	 * @return Zero on success, negative values for failure.
	 * @since 2018/12/05
	 */
	public static native int write(int __fd, byte[] __b, int __o, int __l);
}

Added modules/cldc-compact/src/main/java/cc/squirreljme/jvm/mle/ThreadShelf.java.













































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// Multi-Phasic Applications: SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the GNU General Public License v3+, or later.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.jvm.mle;

import cc.squirreljme.jvm.mle.brackets.VMThreadBracket;
import cc.squirreljme.jvm.mle.exceptions.MLECallError;

/**
 * This shelf handles everything regarding threading and otherwise.
 *
 * @see VMThreadBracket
 * @since 2020/06/17
 */
public final class ThreadShelf
{
	/**
	 * Returns the number of alive threads.
	 *
	 * @param __includeMain Include main threads?
	 * @param __includeDaemon Include daemon threads?
	 * @return The number of alive threads.
	 * @since 2020/06/17
	 */
	public static native int aliveThreadCount(boolean __includeMain,
		boolean __includeDaemon);
	
	/**
	 * Creates a virtual machine thread for the given Java thread.
	 *
	 * @param __javaThread The Java thread to create under.
	 * @return The virtual machine thread.
	 * @throws MLECallError If {@code __javaThread} is null.
	 * @since 2020/06/17
	 */
	public static native VMThreadBracket createVMThread(Thread __javaThread)
		throws MLECallError;
	
	/**
	 * Returns the current Java thread.
	 *
	 * @return The current {@link Thread}.
	 * @since 2020/06/17
	 */
	public static native Thread currentJavaThread();
	
	/**
	 * Returns the exit code for the current process.
	 *
	 * @return The exit code for the current process.
	 * @since 2020/06/17
	 */
	public static native int currentExitCode();
	
	/**
	 * Returns whether the interrupt flag was raised and clears it.
	 *
	 * @param __javaThread The Java thread.
	 * @return If the thread was interrupted.
	 * @throws MLECallError If {@code __javaThread} is null.
	 * @since 2020/06/17
	 */
	public static native boolean javaThreadClearInterrupt(Thread __javaThread)
		throws MLECallError;
	
	/**
	 * Marks the thread as being started.
	 *
	 * @param __javaThread The thread to mark started.
	 * @throws MLECallError If {@code __javaThread} is null.
	 * @since 2020/06/17
	 */
	public static native void javaThreadFlagStarted(Thread __javaThread)
		throws MLECallError;
	
	/**
	 * Has this Java thread been started?
	 *
	 * @param __javaThread The Java thread.
	 * @return If this thread has been started.
	 * @throws MLECallError If {@code __javaThread} is null.
	 * @since 2020/06/17
	 */
	public static native boolean javaThreadIsStarted(Thread __javaThread)
		throws MLECallError;
	
	/**
	 * Returns the runnable for the given Java thread.
	 *
	 * @param __javaThread The Java thread.
	 * @return The {@link Runnable} for the given thread.
	 * @throws MLECallError If {@code __javaThread} is null.
	 * @since 2020/06/17
	 */
	public static native Runnable javaThreadRunnable(Thread __javaThread)
		throws MLECallError;
	
	/**
	 * Sets if the thread is alive or not.
	 *
	 * @param __javaThread The Java thread.
	 * @param __set If this is to be alive or not. If this is {@code true}
	 * then the active count goes up, otherwise it shall go down.
	 * @throws MLECallError If {@code __javaThread} is null.
	 * @since 2020/06/17
	 */
	public static native void javaThreadSetAlive(Thread __javaThread,
		boolean __set)
		throws MLECallError;
	
	/**
	 * Runs the main entry point for the current process and gives it all of
	 * the arguments that were specified on program initialization.
	 *
	 * @since 2020/06/17
	 */
	public static native void runProcessMain();
	
	/**
	 * Sets the current process exit code.
	 *
	 * @param __code The exit code to use.
	 * @since 2020/06/17
	 */
	public static native void setCurrentExitCode(int __code);
	
	/**
	 * Sleeps the current thread for the given amount of time.
	 *
	 * If both times are zero, this means to yield the thread (give up its
	 * current execution context).
	 *
	 * @param __ms The number of milliseconds.
	 * @param __ns The number of nanoseconds.
	 * @return {@code true} if the thread was interrupted.
	 * @throws MLECallError If either value is negative or the nanoseconds is
	 * out of range.
	 * @since 2020/06/17
	 */
	public static native boolean sleep(int __ms, int __ns)
		throws MLECallError;
	
	/**
	 * Returns the Java thread for the VM thread.
	 *
	 * @param __vmThread The VM thread.
	 * @return The Java thread which belongs to this thread.
	 * @throws MLECallError If {@code __thread} is null.
	 * @since 2020/06/17
	 */
	public static native Thread toJavaThread(VMThreadBracket __vmThread)
		throws MLECallError;
	
	/**
	 * Returns the virtual machine thread from the given Java thread.
	 *
	 * @param __thread The Java thread.
	 * @return The VM thread for this thread.
	 * @throws MLECallError If {@code __thread} is null.
	 * @since 2020/06/17
	 */
	public static native VMThreadBracket toVMThread(Thread __thread)
		throws MLECallError;
	
	/**
	 * Returns the thread ID for the given thread.
	 *
	 * @param __vmThread The virtual machine thread.
	 * @return The thread ID.
	 * @throws MLECallError If {@code __vmThread} is null.
	 * @since 2020/06/17
	 */
	public static native int vmThreadId(VMThreadBracket __vmThread)
		throws MLECallError;
	
	/**
	 * Performs a hardware interrupt on the thread.
	 *
	 * @param __vmThread The virtual machine thread.
	 * @throws MLECallError If {@code __vmThread} is null.
	 * @since 2020/06/17
	 */
	public static native void vmThreadInterrupt(VMThreadBracket __vmThread)
		throws MLECallError;
	
	/**
	 * Checks if the given thread is a main thread.
	 *
	 * @param __vmThread The thread to check.
	 * @return {@code true} if the given thread is a main thread.
	 * @throws MLECallError If {@code __vmThread} is null.
	 * @since 2020/06/17
	 */
	public static native boolean vmThreadIsMain(VMThreadBracket __vmThread)
		throws MLECallError;
	
	/**
	 * Sets the thread priority in the same manner as
	 * {@link Thread#setPriority(int)} if this is supported by the hardware.
	 * 
	 * This may or may not be supported and should only be used as a hint and
	 * not a guarantee.
	 *
	 * @param __vmThread The virtual machine thread.
	 * @param __p The priority to set, this will be the same as
	 * {@link Thread#setPriority(int)}.
	 * @throws MLECallError If {@code __vmThread} is null or {@code __p} is
	 * not within {@link Thread#MIN_PRIORITY} and {@link Thread#MAX_PRIORITY}
	 * inclusive.
	 * @since 2020/06/17
	 */
	public static native void vmThreadSetPriority(VMThreadBracket __vmThread,
		int __p)
		throws MLECallError;
	
	/**
	 * Performs the actual start of the given thread.
	 *
	 * @param __vmThread The thread to start.
	 * @return If the start of the thread succeeded.
	 * @throws MLECallError If {@code __vmThread} is null.
	 * @since 2020/06/17
	 */
	public static native boolean vmThreadStart(VMThreadBracket __vmThread)
		throws MLECallError;
	
	/**
	 * Waits for the state of threads to be updated, or just times out.
	 *
	 * A thread update is when another thread becomes alive, becomes dead,
	 * or is started.
	 *
	 * @param __ms The amount of time to wait for.
	 * @return If the thread was interrupted while waiting.
	 * @throws MLECallError If {@code __ms} is negative.
	 * @since 2020/06/17
	 */
	public static native boolean waitForUpdate(int __ms)
		throws MLECallError;
}

Added modules/cldc-compact/src/main/java/cc/squirreljme/jvm/mle/TypeShelf.java.





































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173