forked from sergiotarxz/Peertube-dl
111 lines
3.6 KiB
Plaintext
111 lines
3.6 KiB
Plaintext
#define PERL_NO_GET_CONTEXT
|
|
#include "EXTERN.h"
|
|
#include "perl.h"
|
|
#include "XSUB.h"
|
|
#include "duktape.h"
|
|
#include "duk_config.h"
|
|
#include "javascript_builtins.h"
|
|
|
|
MODULE = Peertube::DL::Javascript PACKAGE = Peertube::DL::Javascript
|
|
PROTOTYPES: ENABLE
|
|
|
|
SV *
|
|
_duk_create_heap_default()
|
|
CODE:
|
|
duk_context *context = duk_create_heap_default();
|
|
if (context) {
|
|
duk_push_c_function(context, js_builtin_print, 1);
|
|
duk_put_global_string(context, "print");
|
|
RETVAL = newSVuv((size_t)context);
|
|
} else {
|
|
RETVAL = &PL_sv_undef;
|
|
}
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
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 null on function call.");
|
|
}
|
|
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, 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%s\n", duk_safe_to_string(context, -1), duk_to_stacktrace(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
|
|
|
|
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 null on function call.");
|
|
}
|
|
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);
|
|
const char * return_value = duk_get_lstring(context, -1, lstring_len);
|
|
if ( (top_index = duk_get_top_index(context)) != DUK_INVALID_INDEX ) {
|
|
duk_pop_n(context, top_index+1);
|
|
}
|
|
RETVAL = newSVpv(return_value, (size_t) lstring_len);
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
void
|
|
_duk_destroy_heap(SV *)
|
|
CODE:
|
|
duk_context *context = (duk_context *) SvUV(ST(0));
|
|
if (!context) {
|
|
croak("Cannot destroy something that is not a context.");
|
|
}
|
|
duk_destroy_heap(context);
|