NodObjC

The NodeJS ⇆ Objective-C Bridge

blockbridgesupportclasscoreexceptionffi-extendglobalidimpimportindexivarmethodselstructtypes

Block

NOTE: C Block support in NodObjC is currently experimental!

NodObjC implements support for C Blocks!

References:

We have to simulate what the llvm compiler does when it encounters a Block literal expression (see Block-ABI-Apple.txt above). The "block literal" is the struct type for each Block instance.

var __block_literal_1 = ffi.Struct([
    ['pointer', 'isa']
  , ['int32', 'flags']
  , ['int32', 'reserved']
  , ['pointer', 'invoke']
  , ['pointer', 'descriptor']
])

The "block descriptor" is a static singleton struct. Probably used in more complex Block scenarios involving actual closure variables needing storage (in NodObjC, JavaScript closures are leveraged instead).

var __block_descriptor_1 = ffi.Struct([
    ['ulonglong', 'reserved']
  , ['ulonglong', 'Block_size']
])

var BD = new __block_descriptor_1()
BD.reserved = 0
BD.Block_size = ffi.sizeOf(__block_literal_1)


// The class of the block instances; lazy-loaded
var CGB

createBlockPointer()

This is a private function used internally by NodObjC. You should not need to use this function in your code.

Creates a C block instance from a JS function and returns it's pointer.

function createBlockPointer (func, type) {
  if (!func) return null
  var bl = new __block_literal_1
  // Set the class of the instance
  bl.isa = CGB || (CGB = core.process.get('_NSConcreteGlobalBlock'))
  // Global flags
  bl.flags = 1 << 29
  bl.reserved = 0
  bl.invoke = imp.createWrapperPointer(func, type)
  bl.descriptor = BD.ref()
  return bl.ref()
}

createBlock()

This is a private function used internally by NodObjC. You should not need to use this function in your code.

Creates a C block instance from a JS Function. Blocks are regular Objective-C objects in Obj-C, and can be sent messages; thus Block instances need are creted using the id.wrap() function.

function createBlock (func, type) {
  return id.wrap(createBlockPointer(func, type))
}

getPointer()

This is a private function used internally by NodObjC. You should not need to use this function in your code.

Gets an ffi pointer to a C block from an existing wrapped Block instance, or creates a new block with _createBlock(). The second case should be most common since it will be rare to create your own Block intstances and pass them around.

function getPointer (blockOrFunc, type) {
  if ('pointer' in blockOrFunc) {
    return blockOrFunc.pointer
  } else {
    return createBlockPointer(blockOrFunc, type)
  }
}
Fork me on GitHub