1 /* -*- Mode: C; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // -------------------------------------------------------------------------*/
12 #include "sjme/nvm/nvm.h"
13 #include "sjme/debug.h"
14 #include "sjme/nvm/tread.h"
17 * Pops a generic value from the stack into a local variable.
19 * @param frame The frame to pop from.
20 * @param localIndex The local index to store to.
21 * @param accessor The accessor used.
22 * @param outOldLocalValue Optional output old local value.
23 * @param outStackValue Optional output stack value.
24 * @return Returns @c SJME_JNI_TRUE on success.
27 static sjme_errorCode
sjme_nvm_localPopGeneric(
28 sjme_attrInNotNull sjme_nvm_frame frame
,
29 sjme_attrInPositive
volatile sjme_jint localIndex
,
30 sjme_attrInNotNull
const sjme_nvm_frameTreadAccessor
* accessor
,
31 sjme_attrOutNullable sjme_pointer outOldLocalValue
,
32 sjme_attrOutNullable sjme_pointer outStackValue
)
34 sjme_todo("Implement");
35 return SJME_ERROR_NOT_IMPLEMENTED
;
38 sjme_javaTypeId topType
;
39 sjme_nvm_frameStack
* stack
;
40 sjme_nvm_frameTread
* tread
;
41 const sjme_nvm_frameLocalMap
* localMap
;
42 sjme_jbyte indexMapTo
;
43 sjme_pointer valueAddr
;
45 SJME_EXCEPT_WITH_FRAME
:
46 if (frame
== NULL
|| accessor
== NULL
)
47 SJME_EXCEPT_TOSS(SJME_ERROR_NULL_ARGUMENTS
);
49 /* Obtain the tread to access. */
51 if (!accessor
->getTread(frame
, accessor
, &tread
) || tread
== NULL
)
52 SJME_EXCEPT_TOSS(SJME_ERROR_FRAME_MISSING_STACK_TREADS
);
54 /* Check to make sure they exist. */
56 localMap
= frame
->localMap
;
57 if (stack
== NULL
|| tread
== NULL
|| localMap
== NULL
)
58 SJME_EXCEPT_TOSS(SJME_ERROR_FRAME_MISSING_STACK_TREADS
);
60 if (localIndex
< 0 || localIndex
>= localMap
->max
)
61 SJME_EXCEPT_TOSS(SJME_ERROR_LOCAL_INDEX_INVALID
);
63 if (stack
->count
<= 0 || tread
->count
<= tread
->stackBaseIndex
)
64 SJME_EXCEPT_TOSS(SJME_ERROR_STACK_UNDERFLOW
);
66 /* Get the type at the top to check if it is valid. */
67 topType
= stack
->order
[stack
->count
- 1];
68 if (topType
!= accessor
->typeId
)
69 SJME_EXCEPT_TOSS(accessor
->errorInvalidTop
);
71 /* Copy the stack value to the local. */
72 indexMapTo
= localMap
->maps
[localIndex
].to
[accessor
->typeId
];
74 if (!accessor
->address(frame
, accessor
, tread
, tread
->count
- 1,
75 &valueAddr
) || valueAddr
== NULL
)
76 SJME_EXCEPT_TOSS(SJME_ERROR_STACK_INVALID_READ
);
78 /* Store the old value in the local variable. */
79 if (outOldLocalValue
!= NULL
)
80 if (!accessor
->read(frame
, accessor
, tread
, indexMapTo
,
82 SJME_EXCEPT_TOSS(SJME_ERROR_LOCAL_INVALID_READ
);
84 /* Store the output stack value, if requested. */
85 if (outStackValue
!= NULL
)
86 memmove(outStackValue
, valueAddr
, accessor
->size
);
88 /* Write value directly from stack source address. */
89 if (sjme_error_is(accessor
->write(frame
, accessor
, tread
,
90 indexMapTo
, valueAddr
)))
91 SJME_EXCEPT_TOSS(SJME_ERROR_LOCAL_INVALID_WRITE
);
93 /* Clear old stack value with zero value. */
94 valueAddr
= sjme_alloca(accessor
->size
);
95 memset(valueAddr
, 0, accessor
->size
);
96 if (sjme_error_is(accessor
->write(frame
, accessor
, tread
,
97 tread
->count
- 1, valueAddr
)))
98 SJME_EXCEPT_TOSS(SJME_ERROR_STACK_INVALID_WRITE
);
100 /* Clear and reduce stack counts. */
101 stack
->order
[stack
->count
] = 0;
106 SJME_EXCEPT_DONE(SJME_ERROR_NONE
);
109 return sjme_except_gracefulDeath(
110 "Invalid %s pop into %d within l:[0, %d] s:[0, %d].",
113 (frame
== NULL
|| frame
->localMap
== NULL
? -1 :
114 frame
->localMap
->max
),
115 (frame
== NULL
|| frame
->stack
== NULL
? -1 :
116 frame
->stack
->count
));
120 sjme_errorCode
sjme_nvm_arrayLength(sjme_nvm_frame frame
,
121 sjme_jobject arrayInstance
, sjme_jint
* outLen
)
123 sjme_todo("Implement");
127 sjme_tempIndex
sjme_nvm_arrayLoadIntoTemp(sjme_nvm_frame frame
,
128 sjme_basicTypeId primitiveType
,
129 sjme_jobject arrayInstance
,
132 sjme_todo("Implement");
136 sjme_errorCode
sjme_nvm_arrayStore(sjme_nvm_frame frame
,
137 sjme_basicTypeId primitiveType
,
138 sjme_jobject arrayInstance
,
142 sjme_todo("Implement");
143 return SJME_ERROR_NOT_IMPLEMENTED
;
146 sjme_errorCode
sjme_nvm_checkCast(sjme_nvm_frame frame
,
147 sjme_jobject instance
,
148 sjme_dynamic_linkage_data_classObject
* type
)
150 sjme_todo("Implement");
151 return SJME_ERROR_NOT_IMPLEMENTED
;
154 sjme_errorCode
sjme_nvm_countReferenceDown(sjme_nvm_frame frame
,
155 sjme_jobject instance
)
157 sjme_todo("Implement");
158 return SJME_ERROR_NOT_IMPLEMENTED
;
161 sjme_tempIndex
sjme_nvm_fieldGetToTemp(sjme_nvm_frame frame
,
162 sjme_jobject instance
,
163 sjme_dynamic_linkage_data_fieldAccess
* field
)
165 sjme_todo("Implement");
169 sjme_errorCode
sjme_nvm_fieldPut(sjme_nvm_frame frame
,
170 sjme_jobject instance
,
171 sjme_dynamic_linkage_data_fieldAccess
* field
,
174 sjme_todo("Implement");
175 return SJME_ERROR_NOT_IMPLEMENTED
;
178 sjme_errorCode
sjme_nvm_gcObject(
179 sjme_attrInNotNull sjme_nvm_frame frame
,
180 sjme_attrInNullable sjme_jobject instance
)
182 sjme_todo("Implement");
183 return SJME_ERROR_NOT_IMPLEMENTED
;
188 SJME_EXCEPT_WITH_FRAME
:
189 if (frame
== NULL
|| instance
== NULL
)
190 SJME_EXCEPT_TOSS(SJME_ERROR_NULL_ARGUMENTS
);
193 if (instance
->refCount
!= 0)
194 SJME_EXCEPT_TOSS(SJME_ERROR_OBJECT_REFCOUNT_NOT_ZERO
);
196 /* Call GC hook, if any. */
197 state
= frame
->inThread
->inState
;
198 if (state
->hooks
!= NULL
&& state
->hooks
->gc
!= NULL
)
199 if (!state
->hooks
->gc(frame
, instance
))
200 SJME_EXCEPT_TOSS(SJME_ERROR_OBJECT_GC_CANCELLED
);
202 /* TODO: Implement actual GC... */
203 sjme_message("Actually implement object GC of %p...", instance
);
206 return SJME_JNI_TRUE
;
209 return sjme_except_gracefulDeath("Could not GC %p.",
214 sjme_errorCode
sjme_nvm_invoke(sjme_nvm_frame frame
,
215 sjme_dynamic_linkage_data_invokeNormal
* method
)
217 sjme_todo("Implement");
218 return SJME_ERROR_NOT_IMPLEMENTED
;
221 sjme_errorCode
sjme_nvm_localPopDouble(sjme_nvm_frame frame
,
222 sjme_jint localIndex
)
224 return sjme_nvm_localPopGeneric(frame
, localIndex
,
225 sjme_nvm_frameTreadAccessorByType(
226 SJME_JAVA_TYPE_ID_DOUBLE
),
230 sjme_errorCode
sjme_nvm_localPopFloat(sjme_nvm_frame frame
,
231 sjme_jint localIndex
)
233 return sjme_nvm_localPopGeneric(frame
, localIndex
,
234 sjme_nvm_frameTreadAccessorByType(
235 SJME_JAVA_TYPE_ID_FLOAT
),
239 sjme_errorCode
sjme_nvm_localPopInteger(sjme_nvm_frame frame
,
240 volatile sjme_jint localIndex
)
242 return sjme_nvm_localPopGeneric(frame
, localIndex
,
243 sjme_nvm_frameTreadAccessorByType(
244 SJME_JAVA_TYPE_ID_INTEGER
),
248 sjme_errorCode
sjme_nvm_localPopLong(sjme_nvm_frame frame
,
249 sjme_jint localIndex
)
251 return sjme_nvm_localPopGeneric(frame
, localIndex
,
252 sjme_nvm_frameTreadAccessorByType(
253 SJME_JAVA_TYPE_ID_LONG
),
257 sjme_errorCode
sjme_nvm_localPopReference(sjme_nvm_frame frame
,
258 sjme_jint localIndex
)
260 sjme_todo("Implement");
261 return SJME_ERROR_NOT_IMPLEMENTED
;
264 sjme_jobject oldLocalValue
, stackValue
;
266 SJME_EXCEPT_WITH_FRAME
:
267 /* Read in the stack values. */
268 oldLocalValue
= NULL
;
270 if (sjme_error_is(sjme_nvm_localPopGeneric(frame
, localIndex
,
271 sjme_nvm_frameTreadAccessorByType(
272 SJME_JAVA_TYPE_ID_OBJECT
),
273 &oldLocalValue
, &stackValue
)))
274 SJME_EXCEPT_TOSS(SJME_ERROR_INVALID_REFERENCE_POP
);
276 /* Need to refcount the old stack value? */
277 /* Always happens, even if they are the same reference because now there */
279 if (oldLocalValue
!= NULL
)
280 if (--oldLocalValue
->refCount
<= 0)
281 if (sjme_error_is(sjme_nvm_gcObject(frame
, oldLocalValue
)))
282 SJME_EXCEPT_TOSS(SJME_ERROR_COULD_NOT_GC_OBJECT
);
285 return SJME_ERROR_NONE
;
288 return sjme_except_gracefulDeath("Could not refcount objects.");
292 sjme_errorCode
sjme_nvm_localPushDouble(sjme_nvm_frame frame
,
295 sjme_todo("Implement");
296 return SJME_ERROR_NOT_IMPLEMENTED
;
299 sjme_errorCode
sjme_nvm_localPushFloat(sjme_nvm_frame frame
,
302 sjme_todo("Implement");
303 return SJME_ERROR_NOT_IMPLEMENTED
;
306 sjme_errorCode
sjme_nvm_localPushInteger(sjme_nvm_frame frame
,
309 sjme_todo("Implement");
310 return SJME_ERROR_NOT_IMPLEMENTED
;
313 sjme_errorCode
sjme_nvm_localPushLong(sjme_nvm_frame frame
,
316 sjme_todo("Implement");
317 return SJME_ERROR_NOT_IMPLEMENTED
;
320 sjme_errorCode
sjme_nvm_localPushReference(sjme_nvm_frame frame
,
323 sjme_todo("Implement");
324 return SJME_ERROR_NOT_IMPLEMENTED
;
327 sjme_errorCode
sjme_nvm_localReadInteger(
328 sjme_attrInNotNull sjme_nvm_frame frame
,
329 sjme_attrInValue sjme_attrInPositive sjme_jint index
,
330 sjme_attrOutNotNull sjme_jint
* outValue
)
332 sjme_todo("Implement");
333 return SJME_ERROR_NOT_IMPLEMENTED
;
336 sjme_errorCode
sjme_nvm_localStoreInteger(sjme_nvm_frame frame
,
340 sjme_todo("Implement");
341 return SJME_ERROR_NOT_IMPLEMENTED
;
344 sjme_tempIndex
sjme_nvm_lookupClassObjectIntoTemp(sjme_nvm_frame frame
,
345 sjme_dynamic_linkage_data_classObject
* classObjectLinkage
)
347 sjme_todo("Implement");
351 sjme_tempIndex
sjme_nvm_lookupStringIntoTemp(sjme_nvm_frame frame
,
352 sjme_dynamic_linkage_data_stringObject
* stringObjectLinkage
)
354 sjme_todo("Implement");
358 sjme_errorCode
sjme_nvm_monitor(sjme_nvm_frame frame
,
359 sjme_jobject instance
,
360 sjme_jboolean isEnter
)
362 sjme_todo("Implement");
363 return SJME_ERROR_NOT_IMPLEMENTED
;
366 sjme_tempIndex
sjme_nvm_newArrayIntoTemp(sjme_nvm_frame frame
,
367 sjme_dynamic_linkage_data_classObject
* componentType
,
370 sjme_todo("Implement");
374 sjme_tempIndex
sjme_nvm_newInstanceIntoTemp(sjme_nvm_frame frame
,
375 sjme_dynamic_linkage_data_classObject
* linkage
)
377 sjme_todo("Implement");
381 sjme_errorCode
sjme_nvm_returnFromMethod(sjme_nvm_frame frame
,
384 sjme_todo("Implement");
385 return SJME_ERROR_NOT_IMPLEMENTED
;
388 sjme_errorCode
sjme_nvm_stackPopAny(sjme_nvm_frame frame
,
391 sjme_todo("Implement");
392 return SJME_ERROR_NOT_IMPLEMENTED
;
395 sjme_tempIndex
sjme_nvm_stackPopAnyToTemp(sjme_nvm_frame frame
)
397 sjme_todo("Implement");
401 sjme_jint
sjme_nvm_stackPopInteger(sjme_nvm_frame frame
)
403 sjme_todo("Implement");
407 sjme_jobject
sjme_nvm_stackPopReference(sjme_nvm_frame frame
)
409 sjme_todo("Implement");
413 sjme_errorCode
sjme_nvm_stackPopReferenceThenThrow(sjme_nvm_frame frame
)
415 sjme_todo("Implement");
416 return SJME_ERROR_NOT_IMPLEMENTED
;
419 sjme_tempIndex
sjme_nvm_stackPopReferenceToTemp(sjme_nvm_frame frame
)
421 sjme_todo("Implement");
425 sjme_errorCode
sjme_nvm_stackPushAny(sjme_nvm_frame frame
,
428 sjme_todo("Implement");
429 return SJME_ERROR_NOT_IMPLEMENTED
;
432 sjme_errorCode
sjme_nvm_stackPushAnyFromTemp(sjme_nvm_frame frame
,
433 sjme_tempIndex input
)
435 sjme_todo("Implement");
436 return SJME_ERROR_NOT_IMPLEMENTED
;
439 sjme_errorCode
sjme_nvm_stackPushDoubleParts(sjme_nvm_frame frame
,
443 sjme_todo("Implement");
444 return SJME_ERROR_NOT_IMPLEMENTED
;
447 sjme_errorCode
sjme_nvm_stackPushFloatRaw(sjme_nvm_frame frame
,
450 sjme_todo("Implement");
451 return SJME_ERROR_NOT_IMPLEMENTED
;
454 sjme_errorCode
sjme_nvm_stackPushInteger(sjme_nvm_frame frame
,
457 sjme_todo("Implement");
458 return SJME_ERROR_NOT_IMPLEMENTED
;
461 sjme_errorCode
sjme_nvm_stackPushIntegerIsInstanceOf(sjme_nvm_frame frame
,
462 sjme_jobject instance
,
463 sjme_dynamic_linkage_data_classObject
* type
)
465 sjme_todo("Implement");
466 return SJME_ERROR_NOT_IMPLEMENTED
;
469 sjme_errorCode
sjme_nvm_stackPushLongParts(sjme_nvm_frame frame
,
473 sjme_todo("Implement");
474 return SJME_ERROR_NOT_IMPLEMENTED
;
477 sjme_errorCode
sjme_nvm_stackPushReference(sjme_nvm_frame frame
,
478 sjme_jobject instance
)
480 sjme_todo("Implement");
481 return SJME_ERROR_NOT_IMPLEMENTED
;
484 sjme_errorCode
sjme_nvm_stackPushReferenceFromTemp(sjme_nvm_frame frame
,
485 sjme_tempIndex tempIndex
)
487 sjme_todo("Implement");
488 return SJME_ERROR_NOT_IMPLEMENTED
;
491 sjme_errorCode
sjme_nvm_tempDiscard(sjme_nvm_frame frame
)
493 sjme_todo("Implement");
494 return SJME_ERROR_NOT_IMPLEMENTED
;
497 sjme_errorCode
sjme_nvm_throwExecute(sjme_nvm_frame frame
)
499 sjme_todo("Implement");
500 return SJME_ERROR_NOT_IMPLEMENTED
;
503 sjme_errorCode
sjme_nvm_topFrame(
504 sjme_attrInNotNull sjme_nvm_thread inThread
,
505 sjme_attrOutNotNull sjme_nvm_frame outFrame
)
507 sjme_todo("Implement");
508 return SJME_ERROR_NOT_IMPLEMENTED
;