Added support for calling javascript functions from perl.

This commit is contained in:
sergiotarxz 2021-01-07 16:02:34 +01:00
parent ff2f583c24
commit 41d1dfaa66
Signed by: sergiotarxz
GPG Key ID: E5903508B6510AC2
2 changed files with 75 additions and 60 deletions

View File

@ -8,13 +8,17 @@ use feature 'say';
use Peertube::DL::Javascript;
my $a = Peertube::DL::Javascript::_duk_create_heap_default();
eval { Peertube::DL::Javascript::_duk_push_lstring( $a, "\"hola mundo\"" ); };
if ($@) {
warn $@;
$@ = "";
}
if ( defined $a ) {
Peertube::DL::Javascript::_duk_peval($a);
say Peertube::DL::Javascript::_duk_get_lstring($a, -1);
Peertube::DL::Javascript::_duk_destroy_heap($a);
eval {
my $return = Peertube::DL::Javascript::_duk_eval_wrapper(
$a,
"function a(nombre) { return 'Hello ' + nombre; }; a('sergio');"
);
say $return;
};
if ($@) {
warn $@;
}
say Peertube::DL::Javascript::_duk_call_function( $a, "a", "sergio" );
Peertube::DL::Javascript::_duk_destroy_heap($a);
}

View File

@ -24,48 +24,80 @@ _duk_create_heap_default()
RETVAL
SV *
_duk_push_lstring(SV *, SV *)
_duk_eval_wrapper(SV *, SV *)
CODE:
if (!ST(0)) {
croak("Javascript context undefined.", 0);
}
duk_context *context = (duk_context *) SvUV(ST(0));
if(!context) {
croak("Javascript context undef.", 0);
if (!context) {
croak("Javascript context null on function call.");
}
STRLEN len;
char * lstring = SvPV(ST(1), len);
if(!len) {
croak("Empty string on lstring push.");
duk_idx_t top_index;
if ( (top_index = duk_get_top_index(context)) != DUK_INVALID_INDEX) {
duk_pop_n(context, top_index + 1);
}
duk_push_lstring(context, lstring, strlen(lstring));
//
// * Example subroutine call
// dSP;
// ENTER;
// SAVETMPS;
// PUSHMARK(SP);
// EXTEND(SP, 1);
// PUSHs(sv_2mortal(newSVpv("Javascript context invalid.", 0)));
// PUTBACK;
//
// call_sv(sv_2mortal(newSVpv("::die", 0)), G_DISCARD);
//
// FREETMPS;
// LEAVE;
//
//
duk_require_stack(context, 2);
if (!ST(1)) {
croak("Code to eval is undef.");
}
STRLEN code_len;
char *code = SvPV(ST(1), code_len);
duk_push_lstring(context, code, strlen(code));
if ( duk_peval(context) != 0 ) {
croak("Eval failed:\n%s\n", duk_get_string(context, -1));
}
duk_size_t *lstring_len;
const char * lstring = duk_get_lstring(context, -1, lstring_len);
RETVAL = newSVpv(lstring, (size_t) lstring_len);
top_index = duk_get_top_index(context);
duk_pop_n(context, top_index+1);
OUTPUT:
RETVAL
void
_duk_peval(SV *)
SV *
_duk_call_function(SV *, SV *, ...)
CODE:
if (!ST(0)) {
croak("Context is undef.");
}
duk_context *context = (duk_context *) SvUV(ST(0));
if(!context) {
croak("Javascript context undef.", 0);
if (!context) {
croak("Javascript context null on function call.");
}
if(duk_peval(context) != 0) {
croak("Eval failed:\n%s\n", duk_safe_to_string(context, -1));
STRLEN function_name_len;
if (!ST(1)) {
croak("Function name must be defined.");
}
char * function_name = SvPV(ST(1), function_name_len);
if ( function_name_len == 0 ) {
croak("Function name cannot be empty.");
}
duk_idx_t top_index;
if ( (top_index = duk_get_top_index(context)) != DUK_INVALID_INDEX ) {
duk_pop_n(context, top_index+1);
}
duk_require_stack(context, items+1);
(void) duk_get_global_lstring(context, function_name, strlen(function_name));
if (items > 2) {
for ( int i = 2; i < items; i++) {
SV *argument_SV = ST(i);
if (!argument_SV) {
croak("Argument %d undefined.", i);
}
STRLEN argument_len;
char *argument = SvPV(argument_SV, argument_len);
duk_push_lstring(context, argument, strlen(argument));
}
}
duk_size_t *lstring_len;
duk_call(context, 1);
char * return_value = duk_get_lstring(context, -1, lstring_len);
top_index = duk_get_top_index(context);
duk_pop_n(context, top_index+1);
RETVAL = newSVpv(return_value, (size_t) lstring_len);
OUTPUT:
RETVAL
void
_duk_destroy_heap(SV *)
@ -75,24 +107,3 @@ _duk_destroy_heap(SV *)
croak("Cannot destroy something that is not a context.");
}
duk_destroy_heap(context);
SV *
_duk_get_lstring(SV *, SV *)
CODE:
duk_context *context = (duk_context *) SvUV(ST(0));
if (!context) {
croak("Unable to get lstring from no existing context.");
}
duk_idx_t idx = SvIV(ST(1));
if (!duk_is_string(context, idx)) {
croak("Idx is not a string.");
}
if (duk_is_symbol(context, idx)) {
croak("This is a symbol, not a string.");
}
duk_size_t *lstring_len;
const char * lstring = duk_get_lstring(context, idx, lstring_len);
RETVAL = newSVpv(lstring, (size_t) lstring_len);
OUTPUT:
RETVAL