GithubHelp home page GithubHelp logo

fmjs's Introduction

FMJS

An incomplete and experimental JavaScript to C/Cocoa bridge

Code borrowed liberally from the Mocha project: https://github.com/logancollins/Mocha

Planned Conversions (not all implemented yet)

Bridging from C to JavaScript:

  • To JS String: NSString + subclasses, selectors, char pointers (_C_CHARPTR)
  • To JS Boolean: BOOL, bool
  • To JS Number: char, short, int, long, long long, float, double
  • To JS Object: NSObject, Class,
  • To JS Undefined: returning void from functions.
  • To JS Functions: Blocks

Not handled (yet?): out pointers

JavaScript to C:

If runtime information is available, we'll try and do the right conversions. If no runtime info is available, this is what will happen:

  • From JS String: NSString
  • From JS Boolean: BOOL
  • From JS Number: long (NSInteger)
  • From JS Objects NSDictionary?
  • From JS Null: nil
  • From JS Function: Not handled
  • From JS Undefined: Not handled

Pass blocks to the JavaScript runtime and call them as JavaScript functions:

FJSRuntime *runtime = [FJSRuntime new];

runtime[@"funkItUp"] = ^(NSString *what) {
    // Do whatever here
};

[runtime evaluateScript:@"funkItUp('funky');"];

Custom Conversions

If you have a method on an object where you'd like to have a little bit more control with the values being handed to you, you have two options:

You can implement the following function:

- (BOOL)doFJSFunction:(FJSValue*)function inRuntime:(FJSRuntime*)runtime withValues:(NSArray<FJSValue*>*)values returning:(FJSValue*_Nullable __autoreleasing*_Nullable)returnValue

And if you return true from this, the original method being called on your object will be skipped in favor of this (obviously, you'd handle the method call in here). Check out FJSSimpleTests.m for an example.

Also, let's say you've got a method named - (int)fooWithBar:(float)f on an object, but you'd like to get your hands on the FJSValue or JSValueRefs which are being used for the arguments. You can implement the following method in your object and it will be called instead: -(FJSValue*)fooWithBar:(FJSValue*)f inFJSRuntime:(FJSRuntime*)runtime. FMJS will look for a method selector with an additional inFJSRuntime: tacked on the end to it (or fooWithBarInFJSRuntime: if there were no aguments previously) and call this instead of the original function.

Thread Safety

FJSRuntime uses an internal queue when evaluating scripts, and when calling functions. The JavaScriptCore API is thread safe but there are parts of FMJS that aren't without evaluating things on the queue. Because of this, FJSRuntime exposes a method which allows you to interact with it on the same queue it uses internally: - (void)dispatchOnQueue:(DISPATCH_NOESCAPE dispatch_block_t)block;

If using FMJS in a multithreaded environment, use this method to help coordinate safe execution across threads.

Notes

Q: Why is the framework called FMJS, but the class prefixes FJS?
A: I hate four letter prefixes, and having it "FJS" always makes me think it stands for "F'n JavaScript".

Random Todos:

  • Stop using NSString for the encodings in the symbols. Try c strings, will ya?
  • Bridge to Swift some day using Mirror, especially now that it has a stable ABI ( https://swift.org/blog/how-mirror-works/ )
  • What should we do about converting js native strings to ints via -[FJSValue toInt]?
  • Should we auto-manage CFTypes? CGImageRef, etc? Probably!

Other Random Notes:

If /usr/bin/gen_bridge_metadata isn't working because it can't find @rpath/libclang.dylib, you can symlink it to /usr/local/lib/: sudo mkdir /usr/local/lib cd /usr/local/lib/ sudo ln -s /Library/Developer/CommandLineTools/usr/lib/libclang.dylib

gen_bridge_metadata -c '-lffi' ~/Projects/fmjs/fmjsTests/FJSSimpleTests.h

Code Usage

FMJS utilizes code and ideas from the following projects:

Files are marked appropriately when code it utilized in complete or near-complete duplicate from these awesome projects.

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.