Search code examples
iphoneios7objective-c-blocksjavascriptcore

Variable argument list to JavascriptCore block


I'd like to define a function in the JavascriptCore context that takes a variable amount of arguments.

Something like this:

JSVirtualMachine* virtualMachine = [[JSVirtualMachine alloc] init];
JSContext* ctx = [[JSContext alloc] initWithVirtualMachine:virtualMachine];

ctx[@"func"] = ^(JSValue* value, ...){
    va_list args;
    va_start(args, value);
    for (JSValue *arg = value; arg != nil; arg = va_arg(args, JSValue*)) {
        NSLog( @"%@", arg);
    }
    va_end(args);
};

[ctx evaluateScript:@"func('arg1', 'arg2');"];

I believe that the JSC wrapper doesn't pass the second argument to the block, because iterating on va_list crashes after logging the first argument.

I also tried with the NSArray* convention, it doesn't work.

Is this possible in any way?


Solution

  • From JSContext.h:

    // This method may be called from within an Objective-C block or method invoked
    // as a callback from JavaScript to retrieve the callback's arguments, objects
    // in the returned array are instances of JSValue. Outside of a callback from
    // JavaScript this method will return nil.
    + (NSArray *)currentArguments;
    

    Leading to the following:

    ctx[@"func"] = ^{
        NSArray *args = [JSContext currentArguments];
        for (JSValue *arg in args) {
            NSLog( @"%@", arg);
        }
    };
    
    [ctx evaluateScript:@"func('arg1', 'arg2');"];