1 #include "yobaperl/perl.hpp" 2 #include "yobaperl/perl_stack.hpp" 3 #include "yobaperl/callbacks.hpp" 9 int Perl::_last_id = -1;
10 std::vector<Perl *> Perl::_perls;
17 #ifndef YOBAPERL_MULTIPLICITY 19 throw PerlException(0,
"Only one Perl instance allowed without -DYOBAPERL_MULTIPLICITY");
23 _perls.push_back(
this);
30 : _interpreter(to_move._interpreter),
32 _is_exceptions_enabled(to_move.isExceptionsEnabled()),
33 _is_warnings_enabled(to_move.isWarningsEnabled()),
34 _callbacks(
std::move(to_move._callbacks))
36 to_move._interpreter =
nullptr;
44 perl_destruct(_interpreter);
45 perl_free(_interpreter);
53 return Scalar(*
this, _createSV(),
false);
58 return Scalar(*
this, _getOrCreateNamedSV(name),
true);
63 return Array(*
this, _createAV(),
false);
68 YOBAPERL_ASSERT(end > begin);
72 for(IV i = begin; i <= end; i++)
73 result.
push(newScalar<IV>(i));
80 return Array(*
this, _getOrCreateNamedAV(name),
true);
85 return Hash(*
this, _createHV(),
false);
90 return Hash(*
this, _getOrCreateNamedHV(name),
true);
95 return callMethod<Scalar>(class_name +
"::new",
newScalar(class_name));
100 return callMethod<Scalar>(class_name +
"::new",
newScalar(class_name), param);
105 return callMethod<Scalar>(class_name +
"::new",
newScalar(class_name), params);
112 return Scalar(*
this, _getNamedSV(name),
true);
117 return Array(*
this, _getNamedAV(name),
true);
122 return Hash(*
this, _getNamedHV(name),
true);
127 return Code(*
this, _getNamedCV(name),
true);
132 return Code(*
this, MUTABLE_CV(
newScalar(name).detachSV()),
true);
147 return HashPtr(
new Hash(*
this, _getNamedHV(name),
true));
152 return CodePtr(
new Code(*
this, _getNamedCV(name),
true));
159 static const char * argv[] = {
"",
"-f",
"-e",
"0" };
160 static const int argc = 4;
165 PERL_SYS_INIT((
int *)&argc, (
char ***)&argv);
166 std::atexit(Perl_sys_term);
169 _interpreter = perl_alloc();
170 PERL_SET_CONTEXT(_interpreter);
172 perl_construct(_interpreter);
174 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
175 PL_perl_destruct_level = 2;
177 if(0 != perl_parse(_interpreter, xs_init, argc, (
char **)argv, (
char **)NULL))
180 #ifdef YOBAPERL_MULTIPLICITY 201 if(isExceptionsEnabled())
204 if(isWarningsEnabled())
205 warn(
"%s", getError().c_str());
214 load_module(PERL_LOADMOD_DENY, newSVpv(name.c_str(),name.length()), NULL, NULL);
221 eval(std::string(
"require ") + name);
225 if(isExceptionsEnabled())
228 if(isWarningsEnabled())
229 warn(
"%s", getError().c_str());
237 _is_exceptions_enabled = state;
243 _is_warnings_enabled = state;
249 return SvTRUE_NN(ERRSV);
252 std::string Perl::getError()
const 254 return SvPVx_nolen_const(ERRSV);
259 Perl & Perl::registerVoidToVoid(
const std::string & name, priv::Callbacks::VoidToVoidCB
function)
261 _callbacks.setVoidToVoid(name,
function);
265 Perl & Perl::registerVoidToScalar(
const std::string & name, priv::Callbacks::VoidToScalarCB
function)
267 _callbacks.setVoidToScalar(name,
function);
271 Perl & Perl::registerScalarToVoid(
const std::string & name, priv::Callbacks::ScalarToVoidCB
function)
273 _callbacks.setScalarToVoid(name,
function);
277 Perl & Perl::registerScalarToScalar(
const std::string & name, priv::Callbacks::ScalarToScalarCB
function)
279 _callbacks.setScalarToScalar(name,
function);
283 CV * Perl::registerStatic(
const std::string & sub_name,
void(*
function)(PerlInterpreter *, CV *))
285 CV * sub = Perl_newXS_len_flags(
getInterpreter(), sub_name.c_str(), sub_name.length(),
function,
286 NULL, NULL, NULL, 0);
287 YOBAPERL_ASSERT(sub);
291 priv::Callbacks & Perl::getCallbacks()
310 return _getNamedSV(name);
315 return _getNamedAV(name);
320 return _getNamedHV(name);
325 return _getNamedCV(name);
328 bool Perl::isExceptionsEnabled()
const 330 return _is_exceptions_enabled;
333 bool Perl::isWarningsEnabled()
const 335 return _is_warnings_enabled;
348 return callMethod<Scalar>(
"coderef2text", *_code_deparser, code.
makeRef()).toString();
353 PERL_SET_CONTEXT(_interpreter);
359 return *_perls.at(
id);
364 #ifdef YOBAPERL_MULTIPLICITY 365 static const std::string name =
"YobaPerl::id";
367 SV ** elements = hv_fetch(PL_modglobal, name.c_str(), name.length(), NULL);
368 YOBAPERL_ASSERT(elements);
370 SV * element = *elements;
371 YOBAPERL_ASSERT(element);
386 char prefix = query[0];
402 SV * Perl::_createSV(STRLEN size)
404 SV * result = newSV(size);
405 YOBAPERL_ASSERT(result);
409 AV * Perl::_createAV(SSize_t size, SV ** elements)
411 AV * result =
nullptr;
413 result = av_make(size, elements);
417 YOBAPERL_ASSERT(result);
421 HV * Perl::_createHV()
423 HV * result = newHV();
424 YOBAPERL_ASSERT(result);
428 SV * Perl::_getOrCreateNamedSV(
const std::string & name)
const 430 GV * gv = gv_fetchpvn_flags(name.c_str(), name.length(), GV_ADD, SVt_PV);
435 AV * Perl::_getOrCreateNamedAV(
const std::string & name)
const 437 GV * gv = gv_fetchpvn_flags(name.c_str(), name.length(), GV_ADD, SVt_PVAV);
442 HV * Perl::_getOrCreateNamedHV(
const std::string & name)
const 444 GV * gv = gv_fetchpvn_flags(name.c_str(), name.length(), GV_ADD, SVt_PVHV);
449 SV * Perl::_getNamedSV(
const std::string & name)
const 451 if(isExceptionsEnabled() || isWarningsEnabled())
453 GV * gv = gv_fetchpvn_flags(name.c_str(), name.length(), 0, SVt_PV);
456 std::string error =
"Undefined symbol: $" + name;
458 if(isExceptionsEnabled())
461 if(isWarningsEnabled())
462 warn(
"%s", error.c_str());
466 return _getOrCreateNamedSV(name);
469 AV * Perl::_getNamedAV(
const std::string & name)
const 471 if(isExceptionsEnabled() || isWarningsEnabled())
473 GV * gv = gv_fetchpvn_flags(name.c_str(), name.length(), 0, SVt_PVAV);
477 std::string error =
"Undefined symbol: @" + name;
479 if(isExceptionsEnabled())
482 if(isWarningsEnabled())
483 warn(
"%s", error.c_str());
489 return _getOrCreateNamedAV(name);
492 HV * Perl::_getNamedHV(
const std::string & name)
const 494 if(isExceptionsEnabled() || isWarningsEnabled())
496 GV * gv = gv_fetchpvn_flags(name.c_str(), name.length(), 0, SVt_PVHV);
500 std::string error =
"Undefined symbol: %" + name;
502 if(isExceptionsEnabled())
505 if(isWarningsEnabled())
506 warn(
"%s", error.c_str());
512 return _getOrCreateNamedHV(name);
515 CV * Perl::_getNamedCV(
const std::string & name)
const 517 GV * gv = gv_fetchpvn_flags(name.c_str(), name.length(), 0, SVt_PVCV);
522 std::string error =
"Undefined symbol: &" + name;
bool hasError() const
Check Perl error.
CodePtr getSubroutinePtr(const std::string &name)
Place subroutine reference in heap.
std::string deparse(const Code &code)
Convert subroutine to string using B::Deparse.
AV * getNamedAV(const std::string &name) const
Get raw array by name.
Hash getHash(const std::string &name)
Get hash by name.
Perl & init()
Initialize the Perl interpreter.
Array getArray(const std::string &name)
Get array by name.
Array & reserve(SSize_t size)
Reserve space.
ArrayPtr getArrayPtr(const std::string &name)
Place array reference in heap.
Array & push(const Scalar &scalar)
Add element to end.
HashPtr getHashPtr(const std::string &name)
Place hash reference in heap.
Perl & setExceptionsEnabled(bool state)
Enable/disable all exceptions. Default: enabled.
Perl & no(const std::string &name)
Unload a module.
HV * getNamedHV(const std::string &name) const
Get raw hash by name.
static Perl & getInstanceById(int perl_id)
Get Perl instance by object id.
Array newNamedArray(const std::string &name)
Create empty array as @name.
Scalar getScalar(const std::string &name)
Get scalar by name.
Perl & setWarningsEnabled(bool state)
Enable/disable all warnings. Default: disabled.
Code getSubroutine(const std::string &name)
Get subroutine by name.
Perl & use(const std::string &name)
Import a module.
Hash & insert(const std::string &key, const Scalar &value)
Add element.
SV * getNamedSV(const std::string &name) const
Get raw scalar by name.
VariablePtr operator[](std::string query)
Universal operator.
ReturnT eval(const std::string &code)
Evaluate string in generic context.
Array newArray()
Create anonymous empty array.
Scalar newNamedScalar(const std::string &name)
Create empty scalar as $name.
PerlInterpreter * getInterpreter() const
Raw interpreter.
Scalar newScalar()
Create anonymous empty scalar.
Perl & require(const std::string &name)
Load external file.
Code getMethod(const std::string &name)
Get class method by name.
Hash newNamedHash(const std::string &name)
Create empty hash as %name.
Scalar newObject(const std::string &class_name)
Create new object.
static Perl & getInstance(PerlInterpreter *_interpreter)
Get Perl instance by associated interpreter.
int getId() const
Perl object id.
Perl(bool do_init=true)
Default constructor.
Array & unshift(const Scalar &scalar)
Add element to begin.
Perl & lib(const std::string &path)
Add folder to module search path.
CV * getNamedCV(const std::string &name) const
Get raw subroutine by name.
Perl & setContext()
Set interpreter context.
ScalarPtr getScalarPtr(const std::string &name)
Place scalar reference in heap.
Hash newHash()
Create anonymous empty hash.
Scalar makeRef() const
Take reference.