forked from sergiotarxz/Peertube-dl
Added support for calling javascript functions from perl.
This commit is contained in:
parent
ff2f583c24
commit
41d1dfaa66
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user