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; use Peertube::DL::Javascript;
my $a = Peertube::DL::Javascript::_duk_create_heap_default(); my $a = Peertube::DL::Javascript::_duk_create_heap_default();
eval { Peertube::DL::Javascript::_duk_push_lstring( $a, "\"hola mundo\"" ); };
if ($@) {
warn $@;
$@ = "";
}
if ( defined $a ) { if ( defined $a ) {
Peertube::DL::Javascript::_duk_peval($a); eval {
say Peertube::DL::Javascript::_duk_get_lstring($a, -1); my $return = Peertube::DL::Javascript::_duk_eval_wrapper(
Peertube::DL::Javascript::_duk_destroy_heap($a); $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 RETVAL
SV * SV *
_duk_push_lstring(SV *, SV *) _duk_eval_wrapper(SV *, SV *)
CODE: CODE:
if (!ST(0)) {
croak("Javascript context undefined.", 0);
}
duk_context *context = (duk_context *) SvUV(ST(0)); duk_context *context = (duk_context *) SvUV(ST(0));
if(!context) { if (!context) {
croak("Javascript context undef.", 0); croak("Javascript context null on function call.");
} }
STRLEN len; duk_idx_t top_index;
char * lstring = SvPV(ST(1), len); if ( (top_index = duk_get_top_index(context)) != DUK_INVALID_INDEX) {
if(!len) { duk_pop_n(context, top_index + 1);
croak("Empty string on lstring push.");
} }
duk_push_lstring(context, lstring, strlen(lstring)); duk_require_stack(context, 2);
// if (!ST(1)) {
// * Example subroutine call croak("Code to eval is undef.");
// dSP; }
// ENTER; STRLEN code_len;
// SAVETMPS; char *code = SvPV(ST(1), code_len);
// PUSHMARK(SP); duk_push_lstring(context, code, strlen(code));
// EXTEND(SP, 1); if ( duk_peval(context) != 0 ) {
// PUSHs(sv_2mortal(newSVpv("Javascript context invalid.", 0))); croak("Eval failed:\n%s\n", duk_get_string(context, -1));
// PUTBACK; }
// duk_size_t *lstring_len;
// call_sv(sv_2mortal(newSVpv("::die", 0)), G_DISCARD); const char * lstring = duk_get_lstring(context, -1, lstring_len);
// RETVAL = newSVpv(lstring, (size_t) lstring_len);
// FREETMPS; top_index = duk_get_top_index(context);
// LEAVE; duk_pop_n(context, top_index+1);
//
//
OUTPUT: OUTPUT:
RETVAL RETVAL
void SV *
_duk_peval(SV *) _duk_call_function(SV *, SV *, ...)
CODE: CODE:
if (!ST(0)) {
croak("Context is undef.");
}
duk_context *context = (duk_context *) SvUV(ST(0)); duk_context *context = (duk_context *) SvUV(ST(0));
if(!context) { if (!context) {
croak("Javascript context undef.", 0); croak("Javascript context null on function call.");
} }
STRLEN function_name_len;
if(duk_peval(context) != 0) { if (!ST(1)) {
croak("Eval failed:\n%s\n", duk_safe_to_string(context, -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 void
_duk_destroy_heap(SV *) _duk_destroy_heap(SV *)
@ -75,24 +107,3 @@ _duk_destroy_heap(SV *)
croak("Cannot destroy something that is not a context."); croak("Cannot destroy something that is not a context.");
} }
duk_destroy_heap(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