#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include <JavaScript.h> #define PJS_ERROR_OPCODELILMIT_EXCEEDED "JavaScript::Error::OpcodeLimitExceeded" struct PJS_Runtime_OpcodeCounting { U32 count; U32 limit; }; typedef struct PJS_Runtime_OpcodeCounting PJS_Runtime_OpcodeCounting; static JSTrapStatus opcodecounting_interrupt_handler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, void *data) { PJS_Runtime_OpcodeCounting *opcount = (PJS_Runtime_OpcodeCounting *) data; opcount->count++; if (opcount->limit > 0 && opcount->count > opcount->limit) { sv_setsv(ERRSV, newRV_inc(newSViv(opcount->limit))); sv_bless(ERRSV, gv_stashpvn(PJS_ERROR_OPCODELILMIT_EXCEEDED, strlen(PJS_ERROR_OPCODELILMIT_EXCEEDED), TRUE)); return JSTRAP_ERROR; } return JSTRAP_CONTINUE; } MODULE = JavaScript::Runtime::OpcodeCounting PACKAGE = JavaScript::Runtime::OpcodeCounting PJS_TrapHandler * jsr_init() PREINIT: PJS_TrapHandler *handler; PJS_Runtime_OpcodeCounting *opcount; CODE: Newz(1, opcount, 1, PJS_Runtime_OpcodeCounting); if (opcount == NULL) { croak("Failed to allocate memory for PJS_Runtime_OpcodeCounting"); } opcount->count = 0; opcount->limit = 0; Newz(1, handler, 1, PJS_TrapHandler); if (handler == NULL) { Safefree(opcount); croak("Failed to allocate memory for PJS_TrapHandler"); } handler->handler = opcodecounting_interrupt_handler; handler->data = (void *) opcount; RETVAL = handler; OUTPUT: RETVAL void jsr_destroy(handler) PJS_TrapHandler *handler; CODE: Safefree(handler->data); Safefree(handler); I32 jsr_get_opcount(handler) PJS_TrapHandler *handler; PREINIT: PJS_Runtime_OpcodeCounting *opcount; CODE: opcount = (PJS_Runtime_OpcodeCounting *) handler->data; RETVAL = opcount->count; OUTPUT: RETVAL void jsr_set_opcount(handler,count) PJS_TrapHandler *handler; I32 count; PREINIT: PJS_Runtime_OpcodeCounting *opcount; CODE: opcount = (PJS_Runtime_OpcodeCounting *) handler->data; opcount->count = count; I32 jsr_get_opcount_limit(handler) PJS_TrapHandler *handler; PREINIT: PJS_Runtime_OpcodeCounting *opcount; CODE: opcount = (PJS_Runtime_OpcodeCounting *) handler->data; RETVAL = opcount->limit; OUTPUT: RETVAL void jsr_set_opcount_limit(handler,limit) PJS_TrapHandler *handler; I32 limit; PREINIT: PJS_Runtime_OpcodeCounting *opcount; CODE: opcount = (PJS_Runtime_OpcodeCounting *) handler->data; opcount->limit = limit;