aboutsummaryrefslogtreecommitdiff
path: root/interpreter/ElymasAsm.pm
blob: 3a13f53820635bf0a6a78f4a319bac9b8bd30a27 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package ElymasAsm;

use strict;
use warnings;

use Elymas;
use ACME::Bare::Metal;

sub constructBlock {
  my ($block, $size) = @_;

  my $scope; $scope = \{
    'base' => [$block, 'int', 'passive'],
    'size' => [$size, 'int', 'passive'],
    'free' => [sub {
      my ($data) = @_;

      ACME::Bare::Metal::deallocate($$scope->{'base'}->[0], $$scope->{'size'}->[0]);
    }, ['func', 'sys .asm .free'], 'active'],
  };

  return $$scope;
}

our $asm = {
  'alloc' => [sub {
    my ($data) = @_;

    my $size = popInt($data);
    my $block = ACME::Bare::Metal::allocate($size);

    push @$data, [constructBlock($block, $size), ['struct']];
  }, ['func', 'sys .asm .alloc'], 'active'],
  'allocAt' => [sub {
    my ($data) = @_;

    my $addr = popInt($data);
    my $size = popInt($data);
    my $block = ACME::Bare::Metal::allocateAt($size, $addr);

    push @$data, [constructBlock($block, $size), ['struct']];
  }, ['func', 'sys .asm .alloc'], 'active'],
  'poke' => [sub {
    my ($data, $scope) = @_;

    my $addr = popInt($data);
    my $value = popInt($data);

    ACME::Bare::Metal::poke($addr, $value);
  }, ['func', 'sys .asm .poke', ['int', 'int'], []], 'active'],
  'peek' => [sub {
    my ($data, $scope) = @_;

    my $addr = popInt($data);
    my $value = ACME::Bare::Metal::peek($addr);

    push @$data, [$value, 'int'];
  }, ['func', 'sys .asm .peek', ['int'], ['int']], 'active'],
  'execute' => [sub {
    my ($data, $scope) = @_;

    my $addr = popInt($data);

    ACME::Bare::Metal::execute($addr);
  }, ['func', 'sys .asm .execute'], 'active'],
};