GithubHelp home page GithubHelp logo

Comments (13)

TooTallNate avatar TooTallNate commented on July 28, 2024

So yes, I'm still maintaining the project, and will happily review any pull requests.

I'm really glad that you have been working on getting some of these issues fixed, as they've all been on my radar for a long time now, it's just been hard to find the time. Let's get some of these patches landed!

from nodobjc.

trevorlinton avatar trevorlinton commented on July 28, 2024

Great! We'll clean it up and get it over to you.

from nodobjc.

trevorlinton avatar trevorlinton commented on July 28, 2024

Hi Nate,

I've finished my own unit tests and have fixed the items below. Can you open a new branch 0.1.0 that I can push up to? There's some issues below that we'd need to address before any sort of merge into a main/master.

Here's the branch: https://github.com/trevorlinton/NodObjC/tree/0.1.0

Changes:

  1. Decoupled many of the various prototypical inheritances between class/id/etc, the issue was a combination of both garbage collection not properly cleaning up extended classes and there were odd namespacing issues (discussed below) causing corner cases (such as created classes loosing their proto for the class when unwrapping).
  2. Put all the modules into a tighter closure (except for exception, i can update that though)
  3. Fixed some garbage collection issues when new function/selector were created, the pointer for the function/selector wasn't held onto, and if the user didn't hold it (but held its container) the GC would gobble it and an Unwrap error occurred.
  4. Imports now have an optional "recurse" level as a second param to $.Import, cycling recursively through all the imports dependencies can cause a simple nodobjc script to take sometimes 200~300MB. You can now specify a recursion level (0 for just that framework) as a second arg, if none is specified it will default to recursively including all dependences (as before).
  5. There were circular dependencies that have been fixed (i'm still trying to decouple a handful), these no longer cause GC issues but it may as code increases. Many of the SEL/imp/etc modules were merged together as they took up less memory (~1.2MB) by sitting in core rather than separate modules. The issue was core -> sel -> core -> imp -> core and multiple copies of core and several other modules were being made. Class/ID were converted to using a harder class/prototype schema and seems to have reduced the memory use as well.
  6. Running a dependency graph there was a lot of proxy/alias function and dead functions in the code (not used by unit tests or examples or I could find in the docs). These were removed, some were commented out and placed at the bottom of the .js files for review. Less code surface, less bugs :)
  7. The unit tests are not passing, i'm still trying to see what the intent of some of these were as i'm unsure what exactly was trying to be expressed, for example one unit tests creates and instance of a class then does a strict comparison of that class to the instance, failing if they are not equal. Is this supposed to be the case? An instances class definition should be equal to the original class, perhaps an "id instanceof Class" should be, but should a strict equality between instances and classes be true? I'm hoping maybe you can guide me through the failing unit tests and help see what can be done to correct them.
  8. I added uv.js as a test to see about integrating the CFEventLoop, I have a obj-c .mm file that links with node.js and successfully integrates the app loop with node but the uv.js version (which is pretty damn close) fails.
  9. I'm also currently working on yanking out libxmljs, the original bridgesupport leaked memory through libxmljs' node object, this has been fixed and drastically reduced memory footprint. There are some quick parsing "hacks" that can be done for parsing xml without having to use libxml. These hacks are fairly fool proof so long as the schema is straight forward, i'm hoping a 0.1.0 version can remove the libxmljs version and hopefully fix up the uv.js CFEventLoop issues.
  10. Added support for obj-c messages returning structures (specifically struts size >= 16 bytes). This required adding support for objcSendMsgStret (and its super equiv.).
  11. Changed import/loading system so that it uses the object returned by require for nodobjc to place definitions "onto" rather than using global's. This I thought would be just good practice :/ let me know if it may have screwed something up I didn't realize.
  12. I don't believe I've integrated the regex types support in index.js. This should also be finished soon.
  13. Fixed code to support node-ffi 1.2.x
  14. ref-struct vs. struct and types vs. types collisions, there were instances where Struct was actually ref-struct and not struct.js, i've resolved these as well. I'm unsure if the collisions were causing bugs as most of it was in dead code that was removed.

from nodobjc.

TooTallNate avatar TooTallNate commented on July 28, 2024

Hey @trevorlinton Nice looking branch, and list! So I've added you as a committer to this main repo. You can push to a new branch if you want and we can take a closer look and get things merged to the master branch asap.

I really appreciate you diving in and doing what's been on my TODO list for quite a while! Cheers!

from nodobjc.

trevorlinton avatar trevorlinton commented on July 28, 2024

@TooTallNate Hi Nate, after talking with some Apple engineers the general consensus was that ID's are a nomenclature and that Class and ID effectively mean the same thing since Classes are just Objects in obj-c (but only have significant differences in compiler validations and when integrating with C/C++ bridges). This may actually be good news but brings up a design ramification I wanted to clear through you before I do anything.

Should the ID and Class be merged together? If so, should the following assertions be true:

var someInstance = $.NSString('alloc');
assert(someInstance !== $.NSString);
assert(someInstance instanceof $.NSString);
assert(someInstance instanceof $.NSObject); // maintain heirarchy in obj-c
assert(someInstance.class() === $.NSString);
assert(someInstance.class().super() === $.NSObject);

assert(someInstance.super() == someInstance); // ???????  
// what happens here? and instance has a super of what? The NSObject "instance" i suppose?

someInstance.toString(); // Format: '[ '+ClassName+' '+pointerAddress+' ]'  [NSString 0x00000003 *]
// note that the * just tries to differentiate between a instance (id) and a class.
someInstance.class().toString(); // [NSString 0x00000001]
someInstance.class().super().toString(); // [NSObject 0x00000000]
someInstance.super().toString(); // [NSObject 0x00000000 *] ????
// what happens here? once again do we infer an "instance" of NSObject as the super? or?

assert(someInstance.isInstance() == true)
assert(someInstance.isClass() == false)
assert($.NSObject.isClass() == true)
assert($.NSObject.class() === Object.prototype) // ???

In addition static or '+' methods are only accessible by Class "definitions" and '-' or instance methods are only available by ID "definitions" (if you will, I say definitions as both Class/ID would come out of the same object in node).

Finally, extending a class simply extends its '+' methods and applies a new inheritance chain? In addition should extending a class into a new one immediately register it within the NodObjc main object for consistency?

from nodobjc.

TooTallNate avatar TooTallNate commented on July 28, 2024

after talking with some Apple engineers the general consensus was that ID's are a nomenclature and that Class and ID effectively mean the same thing since Classes are just Objects in obj-c.

I mean I wouldn't call them the same thing... Class instances are a type of Object, but vice-versa isn't true. Just look at the Obj-C runtime reference. You can see that there's functions (prefixed class_) that only work on Class objects, and not instances (which the objc_ prefix is used for). That said... it does still make sense to me to keep them separate. Your ??? assertions below support this (more on that in a sec).

but only have significant differences in compiler validations and when integrating with C/C++ bridges

Well NodObjC is a bridge right? 😉

assertions...

So... all of those assertions seem fine to me in theory, however I'm not sure if we'll be able to get instanceof working reliably. Setting up an full JS prototype chain of Class objects seems costly to me when all you're really interested in is the base NSString.

assert(someInstance.super() == someInstance); // ???????  
assert(someInstance.super().toString(); // [NSObject 0x00000000 *] ????
// what happens here? once again do we infer an "instance" of NSObject as the super? or?

Both of those bases seem kind of weird to me. A super() function should probably only be available on Class objects, not instances.

assert($.NSObject.class() === Object.prototype) // ???

I would think null actually. Trying to merge over to the JS world once we reach the top of the Obj-C inheritance chain seems unnecessary to me.

extending a class simply extends its '+' methods and applies a new inheritance chain?

Well if we could get instanceof working like that, then ya, possibly. But we'd still need to do the objc_allocateClassPair() and friends dance as well, so that the Obj-C runtime registers the subclass as well (what the Class#extend() function does right now).

In addition should extending a class into a new one immediately register it within the NodObjc main object for consistency?

It already does that in the Class#register() function. Do you want it to be bound earlier? It's not quite usable/fully subclassed until the register() function is called (objc_registerClassPair() C function).

Let me know if that helps!

from nodobjc.

trevorlinton avatar trevorlinton commented on July 28, 2024

@TooTallNate All of your points were fairly spot on. I tried to do some more refactoring but realized I was walking down a rabbit hole and have since stopped.

I have found one issue which is perplexing, using core.objc_getAssociatedObject and core.objc_setAssociatedObject to hold onto a pointer within ID.wrap seems to sometimes cause assertion violations (as the incoming/return pointers are not equal), I believe this is due to the objects original memory pointer being recycled by obj-c's runtime. In addition, it seems it prevents v8 from gobbling up anything passed through ID.wrap, which is obviously an issue. I was wondering if this was done for speed or if it served another purpose? I've also added a test-case memtest.js that tries to cause memory leaks. So far (there's still a ways to go) but it seems most of the memory issues are resolved.

You can see the updates here: trevorlinton@0184e91

Thoughts?

from nodobjc.

TooTallNate avatar TooTallNate commented on July 28, 2024

IIRC, the core.objc_getAssociatedObject() and core.objc_setAssociatedObject() dance was required in order to ensure that a JavaScript wrapper would be the same wrapper instance throughout the Objective-C object's lifetime. See this test case for an example:

assert.ok(nsarray === $.NSArray, 'fails strict equality test')

As for your patch, I'll try reviewing that a bit later today. Cheers!

from nodobjc.

trevorlinton avatar trevorlinton commented on July 28, 2024

@TooTallNate Ahh, that makes more sense, I was shoring up the code to pass all the unit tests and the array-references was one of the outliers I was struggling with. That helps, thanks. I'll soon have a finished patch with all the unit tests passing.

And the latest mem-tests i've ran allocate 2GB of structs, to delegates and function pointers without a single bit of memory leaks! (well, atleast on the javascript/v8 side of things).

from nodobjc.

trevorlinton avatar trevorlinton commented on July 28, 2024

@TooTallNate All unit tests are passing, memory references seem clear and i've successfully decoupled Class from ID. Note there were minor changes to some unit tests, most were simply changing the "require" file/module; all of the code of the unit tests were kept.

from nodobjc.

trevorlinton avatar trevorlinton commented on July 28, 2024

@TooTallNate I pushed up branch 0.1.0, docs need to be revised, maybe some more testing and your thumbs up and we can set it in motion!

from nodobjc.

TooTallNate avatar TooTallNate commented on July 28, 2024

@trevorlinton Hey Trev, so I'm checking out your branch now. First issue is that the dependencies in the package.json aren't quite right/complete. node-ffi package has been renamed to ffi package (c0aaa30), and there's some additional missing deps.

from nodobjc.

TooTallNate avatar TooTallNate commented on July 28, 2024

Let's continue this in #39.

from nodobjc.

Related Issues (20)

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.