NAME

JavaScript::Duktape - Perl interface to Duktape embeddable javascript engine

SYNOPSIS

use JavaScript::Duktape;

##create new js context
my $js = JavaScript::Duktape->new();

#set function to be used from javascript land
$js->set('write' => sub {
    my $duk = shift;
    print $_[0], "\n";
});

$js->eval(qq~
    (function(){
        for (var i = 0; i < 100; i++){
            write(i);
        }
    })();
~);

DESCRIPTION

JavaScript::Duktape implements almost all duktape javascript engine api, the c code is just a thin layer that maps duktape api to perl, and all other functions implemented in perl it self, so maintaing and contributing to the base code should be easy.

methods

set('name', data);

Creates properity 'name' and sets it's value to the given perl data

get('name');

Gets properity 'name' value from javascript and return it as perl data

eval('javascript');

Evaluates javascript string and return the results or croak if error

VM API

vm api corresponds to Duktape Engine API see http://duktape.org/api.html To access vm create new context then call vm

my $js = JavaScript::Duktape->new();
my $duk = $js->vm;

#now you can call Duktape API from perl 

$duk->push_string('print');
$duk->eval();
$duk->push_string('hi');
$duk->call(1);
$duk->pop();

Also you may find it useful to use dump function regularly to get a better idea where you're in the stack, the following code is the same example above but with using dump function to get a glance of stack top

my $js = JavaScript::Duktape->new();
my $duk = $js->duk;

#push "print" string
$duk->push_string('print');
$duk->dump(); #-> [ Duktape (top=1): print ]

#since print is a native function we need to evaluate it
$duk->eval();
$duk->dump(); #-> [ Duktape (top=1): function print() {/* native */} ]

#push one argument to print function
$duk->push_string('hi');
$duk->dump(); #-> [ Duktape (top=2): function print() {/* native */} hi ]

#now call print function and pass "hi" as one argument
$duk->call(1);

#since print function doesn't return any value, it will push undefined to the stack
$duk->dump(); #-> [ Duktape (top=1): undefined ]

#pop to remove undefined from stack top
$duk->pop();

#Bingo
$duk->dump(); #-> [ Duktape (top=0): ]

VM methods

As a general rule all duktape api supported, but I haven't had the chance to test them all, so please report any missing or failure api call and I'll try to fix

For the list of duktape engine API please see http://duktape.org/api.html, and here is how you can translate duktape api to perl

my $js = JavaScript::Duktape->new();
my $duk = $js->duk;

# -- C example
# duk_push_c_function(func, 2);
# duk_push_int(ctx, 2);
# duk_push_int(ctx, 3);
# duk_call(ctx, 2);  /* [ ... func 2 3 ] -> [ 5 ] */
# printf("2+3=%ld\n", (long) duk_get_int(ctx, -1));
# duk_pop(ctx);

#and here is how we can implement it in JavaScript::Duktape

$duk->push_c_function(sub { 
    my $duk = shift;
    my $num1 = shift;
    my $num2 = shift;

    my $total = $num1+$num2;
    $duk->push_number($total);
    return 1;
}, 2);

$duk->push_int(2);
$duk->push_int(3);
$duk->call(2);  # [ ... func 2 3 ] -> [ 5 ]
printf("2+3=%ld\n", $duk->get_int(-1));
$duk->pop();

As you can see all you need to do is replacing duk_ with $duk-> and remove ctx from the function call, this may sounds crazy but api tests have been generated by copying duktape tests and using search and replace tool :)

Besides duktape api, JavaScript::Duktape::Vm implements the following methods

push_function ( code_ref, num_of_args );

an alias to push_c_function

push_perl( ... );

Push given perl data into the duktape stack.

to_perl(index);

Get the value at index and return it as perl data

reset_top

resets duktape stack top

AUTHOR

Mamod Mehyar <mamod.mehyar@gmail.com>

LICENSE

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.