Skip to content

Commit

Permalink
make class.name a lua string
Browse files Browse the repository at this point in the history
prefer obj.field over obj.method
fix constructor calls
return [ as objects
update java bridge tests
  • Loading branch information
jbalint committed Apr 25, 2013
1 parent ba28f9a commit fcaa0af
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 26 deletions.
5 changes: 5 additions & 0 deletions Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ public int polyMorphic4(int x, Test y) {
}
public int polyMorphic5(int x, Object y) {
return 5;
}
private int x = 0;
public Test() {
System.out.println("WELL the constructor was called!");
x = 150;
}
public static void main(String args[]) {
System.out.println("Jess");
Expand Down
33 changes: 20 additions & 13 deletions java_bridge.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ local function find_methods(class, name)
for idx, method_id in pairs(lj_get_class_methods(class)) do
-- match literal method names or "new" for constructors
if method_id.name == name or (method_id.name == "<init>" and name == "new") then
methods[#methods+1] = method_id
table.insert(methods, method_id)
end
end
class = lj_call_method(class, superclass_method_id, "L", 0)
Expand Down Expand Up @@ -81,6 +81,11 @@ end
-- perform the actual method call. this will match the `args'
-- to one of the `possible_methods'
local function call_java_method(object, possible_methods, args)
-- local old_lj = lj_call_method
-- local function lj_call_method(a, b, c, d)
-- print("Calling: ", b.class, b.name)
-- return old_lj(a, b, c, d)
-- end
local argc = #args
-- filter out non-matching methods
local possible2 = {}
Expand Down Expand Up @@ -154,7 +159,7 @@ debug.getregistry()["jmethod_id_mt"] = jmethod_id_mt
jmethod_id_mt.__tostring = function(method_id)
return string.format("jmethod_id@%s %s.%s%s",
lj_pointer_to_string(method_id),
method_id.class.name.toString(),
method_id.class.name,
method_id.name,
method_id.sig)
end
Expand Down Expand Up @@ -208,7 +213,7 @@ debug.getregistry()["jfield_id_mt"] = jfield_id_mt
jfield_id_mt.__tostring = function(field_id)
return string.format("jfield_id@%s %s.%s type=%s",
lj_pointer_to_string(field_id),
field_id.class.name.toString(),
field_id.class.name,
field_id.name,
field_id.sig)
end
Expand Down Expand Up @@ -270,7 +275,11 @@ jobject_mt.__index = function(object, key)
elseif key == "name" then
-- name is a transient and cached property in java.lang.Class, don't access it directly
-- c.f. Class.java source
return object.getName()
return lj_call_method(object,
lj_get_method_id("java/lang/Class",
"getName",
"", "Ljava/lang/String;"),
"STR", 0)
elseif key == "isAssignableFrom" then
-- handled manually to prevent recursion in generic method calling
local isAssignableFromMethod = function(c2)
Expand All @@ -282,21 +291,19 @@ jobject_mt.__index = function(object, key)
end
return isAssignableFromMethod
end
-- NOTE: following this, object == class
class = object
end

local field_id = find_field(class, key)
if field_id then
return lj_get_field(object, field_id, field_id.modifiers.static)
end

local methods = find_methods(class, key)
if #methods > 0 then
return new_jcallable_method(object, methods)
end

local field_id = find_field(class, key)
if field_id then
if field_id.modifiers.static then
return lj_get_field(object.class, field_id, true)
else
return lj_get_field(object, field_id, false)
end
end
end

print("java_bridge.lua - loaded with " .. _VERSION)
20 changes: 16 additions & 4 deletions lua_java.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ static int lj_call_method(lua_State *L)
int param_num;
int result_count = 1;

jvalue *jargs;
jvalue *jargs = NULL;

const char *argtype;
char *method_name;
Expand All @@ -544,7 +544,11 @@ static int lj_call_method(lua_State *L)
(*lj_jvmti)->GetMethodName(lj_jvmti, method_id, &method_name, NULL, NULL);
lj_check_jvmti_error(L);

jargs = malloc(sizeof(jvalue) * argcount);
if (argcount > 0)
{
jargs = malloc(sizeof(jvalue) * argcount);
memset(jargs, 0, sizeof(jvalue) * argcount);
}

param_num = 5;
/* get arguments */
Expand Down Expand Up @@ -589,6 +593,7 @@ static int lj_call_method(lua_State *L)

lua_pop(L, (2 * argcount) + 4);

memset(&val, 0, sizeof(val));
/* call method - in order shown in JNI docs*/
if (!strcmp("V", ret))
{
Expand All @@ -598,7 +603,7 @@ static int lj_call_method(lua_State *L)
}
else if (!strcmp("L", ret) || !strcmp("STR", ret))
{
if (!strcmp("<init>", method_name))
if (!strcmp("<init>", method_name))
val.l = (*lj_jni)->NewObjectA(lj_jni, object, method_id, jargs);
else
val.l = (*lj_jni)->CallObjectMethodA(lj_jni, object, method_id, jargs);
Expand Down Expand Up @@ -661,6 +666,8 @@ static int lj_call_method(lua_State *L)
luaL_error(L, "Unknown return type '%s", ret);
}

if (argcount > 0)
free(jargs);
free_jvmti_refs(lj_jvmti, method_name, (void *)-1);

return result_count;
Expand Down Expand Up @@ -922,7 +929,7 @@ static int lj_get_field(lua_State *L)
NULL, &sig, NULL);
lj_check_jvmti_error(L);

if (*sig == 'L')
if (*sig == 'L' || *sig == '[')
{
if (is_static)
val.l = (*lj_jni)->GetStaticObjectField(lj_jni, object, field_id->field_id);
Expand Down Expand Up @@ -1003,6 +1010,11 @@ static int lj_get_field(lua_State *L)
EXCEPTION_CHECK(lj_jni);
lua_pushnumber(L, val.d);
}
else
{
lj_print_message("Unknown return type '%s' for field\n", sig);
lua_pushnil(L);
}

return 1;
}
Expand Down
22 changes: 22 additions & 0 deletions test/lunit/BasicTestClass.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
public class BasicTestClass {
public static String someStaticMethod(String smth) {
return "You passed: " + smth;
}

private String myVal;
public BasicTestClass(String val) {
myVal = val;
}

public String getMyVal() {
return myVal;
}

public static void main(String args[]) throws Exception {
char [] s = new char[0];
System.out.println("String length: " + s);
System.out.println("String length: " + s.length);
/* Allow tests to run */
Thread.sleep(5000);
}
}
28 changes: 27 additions & 1 deletion test/lunit/test_java_bridge_class.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,31 @@
require("lunit")
module("test_java_bridge_class", lunit.testcase, package.seeall)

function test_1()
function test_basic_class_access()
local string_class = java.lang.String
assert_equal(lj_find_class("java/lang/String"), string_class, "Class objects should be equal when accessed differently")
assert_equal("java.lang.String", string_class.name)
assert_string(string_class.name)
assert_equal("String.java", string_class.sourcefile)
end

function test_basic_instantiation()
local empty_string = java.lang.String.new()
assert_equal(0, empty_string.length())
assert_equal(java.lang.String, empty_string.class)
local num_string = java.lang.String.new(4000)
assert_equal("4000", num_string.toString())
local bool_string = java.lang.String.new(false)
assert_equal("false", bool_string.toString())
local str_string = java.lang.String.new("Hello")
assert_equal("Hello", str_string.toString())
local copy_string = java.lang.String.new(str_string)
assert_equal("Hello", copy_string.toString())
-- TODO set this up
--assert_equal(str_string, copy_string)

local success, error = pcall(function () print(java.lang.String.new(1,2,3,4,5)) end)
if success then
fail("Constructor call should fail if it doesn't exist")
end
end
8 changes: 0 additions & 8 deletions test/test_basic.lua

This file was deleted.

0 comments on commit fcaa0af

Please sign in to comment.