Skip to content

Commit

Permalink
jit: throw ClassCastException from check_cast()
Browse files Browse the repository at this point in the history
Signed-off-by: Tomek Grabiec <tgrabiec@gmail.com>
Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
  • Loading branch information
tgrabiec authored and Pekka Enberg committed Jun 8, 2009
1 parent cbb3e34 commit 864b493
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 5 deletions.
1 change: 0 additions & 1 deletion arch/x86/insn-selector_32.brg
Expand Up @@ -1247,7 +1247,6 @@ stmt: STMT_CHECKCAST(reg)
select_insn(s, tree, rel_insn(INSN_CALL_REL, (unsigned long)check_cast));

method_args_cleanup(s, tree, 2);
select_exception_test(s, tree);
}

%%
Expand Down
32 changes: 31 additions & 1 deletion regression/jvm/ExceptionsTest.java
Expand Up @@ -44,6 +44,9 @@ public static void takeInt(int val) {
public static void takeLong(long val) {
}

public static void takeObject(Object obj) {
}

public static void testTryBlockDoesNotThrowAnything() {
boolean caught;
try {
Expand Down Expand Up @@ -309,6 +312,32 @@ public static void testLrem() {
assertTrue(caught);
}

public static void testCheckcast() {
boolean caught = false;
Object o = null;
String s = null;

try {
s = (String)o;
} catch (ClassCastException e) {
caught = true;
}

assertFalse(caught);

o = new Object();

try {
s = (String)o;
} catch (ClassCastException e) {
caught = true;
}

assertTrue(caught);

takeObject(s);
}

public static void main(String args[]) {
testTryBlockDoesNotThrowAnything();
testThrowAndCatchInTheSameMethod();
Expand All @@ -326,11 +355,12 @@ public static void main(String args[]) {
testGetfield();
testPutfield();
testMonitorenter();
/* TODO: testMonitorexit() */
/* TODO: testMonitorexit() */
testIdiv();
testIrem();
testLdiv();
testLrem();
testCheckcast();

exit();
}
Expand Down
45 changes: 42 additions & 3 deletions vm/class.c
Expand Up @@ -24,10 +24,13 @@
* Please refer to the file LICENSE for details.
*/

#include <jit/exception.h>
#include <jit/compiler.h>
#include <vm/string.h>
#include <vm/die.h>
#include <vm/vm.h>
#include <stdlib.h>
#include <errno.h>

typedef void (*exception_init_fn)(struct object *, struct object *);

Expand Down Expand Up @@ -84,9 +87,45 @@ void check_array(struct object *obj, unsigned int index)

void check_cast(struct object *obj, struct object *type)
{
if (!obj)
struct string *str;
int err;

if (!obj || isInstanceOf(type, obj->class))
return;

if (!isInstanceOf(type, obj->class))
abort();
if (exception_occurred())
goto throw;

str = alloc_str();
if (str == NULL) {
err = -ENOMEM;
goto error;
}

err = str_append(str, slash2dots(CLASS_CB(obj->class)->name));
if (err)
goto error;

err = str_append(str, " cannot be cast to ");
if (err)
goto error;

err = str_append(str, slash2dots(CLASS_CB(type)->name));
if (err)
goto error;

signal_new_exception("java/lang/ClassCastException", str->value);
free_str(str);
throw:
throw_from_native(2 * sizeof(struct object *));
return;

error:
if (str)
free_str(str);

if (err == -ENOMEM) /* TODO: throw OutOfMemoryError */
die("%s: out of memory", __func__);

die("%s: error %d", __func__, err);
}

0 comments on commit 864b493

Please sign in to comment.