Coder Social home page Coder Social logo

dukeify / fake-jni Goto Github PK

View Code? Open in Web Editor NEW
26.0 5.0 10.0 494 KB

An implementation of the JNI and JVMTI with support for direct interaction between natively registered classes and JVM objects.

License: Other

CMake 0.64% C++ 58.40% C 40.58% Objective-C 0.38%
java jvm native jni cpp17 jvmti

fake-jni's People

Contributors

matthewacon avatar meme avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

fake-jni's Issues

Move all non-essential templates to matthewacon/CX

The code base is pretty polluted with generalized templates that are not necessarily specific to fake-jni. We should move all non-essential templates to the CX template library, to declutter the project and for code reuse in the future.

Transition away from the header-only library model

fake-jni has grown too large to be a header-only library; compile times are taking much longer than a standard shared library, the header include dependency ordering is too complex to easily make changes to, and the user API is suffering from unclear multiple definition compile-time errors when incorrectly including fake-jni, due to the inline functions and members as part of the library. Furthermore, the startup time and memory complexity of fake-jni, as a header-only library, grows linearly with every translation unit that it is included in, once again, due to the statically allocated inline members and inline functions.

Transitioning to a standard shared library model will solve all of these issues as all statically allocated memory and inline functions will only be defined in a single translation unit, regardless of the include count.

Clean up the native class registration process

FakeJni::_CX::RegistrationHookGenerator is an unnecessary template that can be replaced with capturing lambdas at each constructor for FakeJni::_CX::ClassDescriptorElement. This issue is waiting on #22.

Make FakeJni::JString keep track of string length

Since the type width of char does not equal that of JChar, JCharArray::length does not represent the actual length of the string, but rather the length of the string / sizeof(JChar), excluding the null-terminator. Just add a field and API function to JString for the actual string size.

Feature Targets

JNI:

  • Member Variable Retrieval
  • Static Variable Retrieval
  • Member Variable Assignment
  • Static Variable Assignment
  • Static Function Invocation
  • Member Function Invocation

Internal API:

  • Automated Memory Management
    • Background Allocation
    • Hooked JNI Freeing
  • Class Instance Differentiation
  • Classloader Differentiation (optional)
  • Compile Time Native Class Registration
    • Compile Time Static Member and Function Linking
  • Compile Time Method Signature Generation
  • Compile Time Field Signature Generation
  • Multi-dimensional Array Support

Support inner classes

When defining an inner class, the first parameter for each constructor must be an instance pointer to the encapsulating class:

using namespace FakeJni;

class Outer : public JObject {
public:
 DEFINE_CLASS_NAME("com/example/Outer")

 class Inner : public JObject {
 public:
  DEFINE_CLASS_NAME("com/example/Outer$Inner")
  const Outer& outer;

  explicit Inner(Outer * const inst) :
    outer(*inst)
  {}
 };
};

BEGIN_NATIVE_DESCRIPTOR(Outer)
 {Constructor<Outer> {}}
END_NATIVE_DESCRIPTOR

BEGIN_NATIVE_DESCRIPTOR(Outer::Inner)
 {Constructor<Outer::Inner, Outer *> {}}
END_NATIVE_DESCRIPTOR

For the purposes of JVM functionality compliance, all Outer::Inner instances will be constrained to an encapsulating instance of Outer.

Optionally link libffi dynamically

  • Factor the libffi build script into its own .cmake file
  • Check for a system libffi, use that if it exists, otherwise compile libffi and link it statically (additionally allow the ability to override this to force static compilation)

Fix CircleCI building

fake-jni requires clang, c++17 and CMake 3.8. One or more of these requirements is breaking the CircleCI builds

c varargs type promotions

Use sfinae templates to automatically promote any integral types smaller than int to int, and likewise for double, to generate template class encapsulated functions for _CX::getVArg.

unregisterClass seems to unregister the descriptor for JClass

FakeJni::JClass and the rest of the internal pre-defined fake-jni native types aren't currently added to any FakeJni::DefaultJvm instances automatically, thus they should never be removed. Also, the FakeJni::JClass descriptor seems to be removed no matter what template parameter is passed to FakeJni::JvmImpl::unregisterClass<T>(). See #18

Create new macro for complex multiple inheritance fake-jni types

Something along the lines of DEFINE_COMPLEX_CLASS(name, bases...) that expands to:

class name: (public bases...), public virtual NativeObject<name>

and may be used like:

class MyBaseObject: public NativeObject<MyBaseObject> {
public:
 const JString someProperty;

 MyBaseObject(JString someProperty) :
  NativeObject<MyBaseObject>(),
  someProperty(someProperty) 
 {}

 JInt myExampleFunction() {
  return 31415926;
 }
};

//Constructor delegate for MyBaseObject
static MyBaseObject* myBaseObjectConstructorDelegate(JString *str) {
 return new MyBaseObject(*str);
}

//Register properties from MyBaseObject
DEFINE_NATIVE_TYPE(MyBaseObject) {
 {&MyBaseObject::someProperty, "myJavaPropertyName"},
 {&MyBaseObject::myExampleFunction, "myJavaFunctionName"},
 {myBaseObjectConstructorDelegate}
};

//Define complex class that inherits all registered properties from it's base classes,
//with the exception of constructors
DEFINE_COMPLEX_CLASS(MyDerivedObject, MyBaseObject) {
public:
 const JInt someOtherProperty;

 MyDerivedObject(JInt someOtherProperty) :
  NativeObject<MyDerivedObject>(),
  MyBaseObject({ "I'm a JString!" }),
  someOtherProperty(someOtherProperty)
 {}
};

//Constructor delegate for MyDerivedObject
static MyDerivedObject* myDerivedObjectConstructorDelegate(JInt i) {
 return new MyDerivedObject(i);
}

DEFINE_NATIVE_TYPE(MyDerivedObject) {
 {&MyDerivedObject::someOtherProperty, "someOtherProperty"},
 {myDerivedObjectConstructorDelegate}
};

Provide static assertions for overlapping fields from non-virtual bases

Related to #8

Support object construction with jvalue

Currently FakeJni::NativeObject<typename> only defines a JObject* newInstance(va_list) function for creating new instances of user-defined native classes, with c-varargs. We eventually need to add support for a JObject* newInstance(jvalue*) function that can create instances given jvalue[]s. FakeJni::JMethodID already defines an invoke function for jvalues so no new functionality is required to achieve this.

Link against loaded libraries before registerNatives

When registerNatives is invoked, preform a depth-first search for the corresponding function in all libraries registered with the JVM instance. The first symbol found will be registered in place of the function pointer provided by the JNINativeMethod struct.

Eliminate constructor delegate registration with CX

Constructor delegate functions can be removed in favour of direct instantiation through the supplied template parameter to FakeJni::NativeObject, however, we need to settle on a syntax for the registration. Since a delegate function wont be used for template parameter inference anymore, users must explicitly specify the template parameters for the prototype of the constructor somehow. This cannot be achieved with implicit conversions if no parameter is used to perform type inference on. Perhaps an empty template type could be used to minimize the impact on the end-user API bloat, something like:

template<typename... Args>
class Constructor {
public:
 const uint32_t modifiers;

 Constructor(const uint32_t modifiers): modifiers(modifiers) {}
};

with the resulting registration looking something like:

DEFINE_NATIVE_TYPE(MyNativeType) {
 {&MyNativeType::someProperty, "someProperty"},
 Constructor<JString*, JInt, JDoubleArray*>{},
 Constructor<>{ JMethodID::PRIVATE }
};

Change FakeJni::JString to use previously allocated strings when copy-constructing

The current implementation of FakeJni::JString::JString(const JString&) constructs a new FakeJni::JCharArray instance and copies the contents of the subject string into the current string. Instead, we should simply set the array pointer in FakeJni::JArray<JCharArray> to that of the allocated string.

To prevent undefined behaviour, should the underlying string be a stack-allocated reference, a constructor would need to be added to FakeJni::JArray<T> that ref counts so that the last instance deallocates the subject memory when destructed.

This issue is related to #29.

GTest with suite

  • Add GTest
  • Create JNI modules that are tested against BOTH Java's JNI and fake-jni
  • Test every commit using Circle CI (or custom CI [?])

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.