| JavaScript documentation | Contained in the JavaScript distribution. |
JavaScript::Runtime - Runs contexts
Creates a new runtime object. The optional argument $maxbytes specifies the number of bytes that can be allocated before garbage collection is runned. If ommited it defaults to 1MB.
Creates a new JavaScript::Context-object in the runtime.
Attaches an interrupt handler (a function that is called before each op is executed ) to the runtime. The argument $handler must be either a code-reference or the name of a subroutine in the calling package.
To remove the handler call this method with an undef as argument.
Note that attaching an interrupt handler to the runtime causes a slowdown in execution speed since we must execute some Perl code between each op.
In order to abort execution your handler should a false value (such as 0). All true values will continue execution. Any exceptions thrown by the handler are ignored and $@ is cleared.
| JavaScript documentation | Contained in the JavaScript distribution. |
package JavaScript::Runtime; use strict; use warnings; use Carp qw(croak); use JavaScript; sub new { my ($pkg, @args) = @_; $pkg = ref $pkg || $pkg; my $maxbytes = $JavaScript::MAXBYTES; $maxbytes = shift @args if (@args && $args[0] =~ /^\d+$/); my @does; for (@args) { if (my ($type) = $_ =~ /^-(\w+)$/) { my $does = "JavaScript::Runtime::" . $type; if (!exists $JavaScript::Runtime::{$type . '::'}) { eval "require $does;"; croak $@ if $@; } push @does, $does; } } my $runtime = jsr_create($maxbytes); my $self = bless { _impl => $runtime, _does => \@does }, $pkg; for (@does) { my $init = $_->can('_init'); $init->($self) if $init; } return $self; } sub _destroy { my $self = shift; for (@{$self->{_does}}) { my $destroy = $_->can('_destroy'); $destroy->($self); } if ($self->{_perl_interrupt_handler}) { # Remove the current one $self->set_interrupt_handler(); } return unless $self->{'_impl'}; jsr_destroy($self->{'_impl'}); delete $self->{'_impl'}; return 1; } sub DESTROY { my ($self) = @_; $self->_destroy(); } sub create_context { my $self = shift; warn "Requesting a custom stacksize is not longer supported" if @_ && $_[0]; my $context = JavaScript::Context->new($self); return $context; } sub _add_interrupt_handler { my ($self, $handler) = @_; jsr_add_interrupt_handler($self->{_impl}, $handler); } sub _remove_interrupt_handler { my ($self, $handler) = @_; jsr_remove_interrupt_handler($self->{_impl}, $handler); } sub set_interrupt_handler { my ($self, $handler) = @_; if ($handler && ref $handler eq '') { my $caller_pkg = caller; $handler = $caller_pkg->can($handler); } if ($handler) { $self->{_perl_interrupt_handler} = jsr_init_perl_interrupt_handler($handler); $self->_add_interrupt_handler($self->{_perl_interrupt_handler}); } elsif ($self->{_perl_interrupt_handler}) { $self->_remove_interrupt_handler($self->{_perl_interrupt_handler}); jsr_destroy_perl_interrupt_handler($self->{_perl_interrupt_handler}); delete $self->{_perl_interrupt_handler}; } 1; } our $AUTOLOAD; sub AUTOLOAD { my $self = shift; my ($method_name) = $AUTOLOAD =~ /::([A-Za-z0-9_]+)$/; for my $does (@{$self->{_does}}) { if (defined (my $method = $does->can($method_name))) { return $method->($self, @_); } } my $isa = join(", ", @{$self->{_does}}); croak "Can't call method '$method_name' because it's not defined in $isa"; } 1; __END__