~ubuntu-branches/ubuntu/precise/rakudo/precise

« back to all changes in this revision

Viewing changes to src/classes/Routine.pir

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghedini
  • Date: 2011-05-17 11:31:09 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20110517113109-rmfir654u1axbpt4
Tags: 0.1~2011.04-1
* New upstream release (Closes: #601862, #585762, #577502)
* New maintainer
* Switch to 3.0 (quilt) format
* Update dependencies (Closes: #584498)
* Update debian/copyright to lastest DEP5 revision
* Do not generate/install perl6 manpage (now done by the build system)
* Enable tests
* Bump Standards-Version to 3.9.2 (no changes needed)
* Do not install extra LICENSE files and duplicated docs
* Remove debian/clean (no more needed)
* Add Vcs-* fields in debian/control
* Rewrite (short) description
* Update upstream copyright years
* Upload to unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
## $Id$
2
 
 
3
 
=head1 TITLE
4
 
 
5
 
Code - Perl 6 Routine class
6
 
 
7
 
=head1 DESCRIPTION
8
 
 
9
 
This file sets up the Perl 6 C<Routine> class, the base class for all
10
 
wrappable executable objects.
11
 
 
12
 
=cut
13
 
 
14
 
.include 'interpinfo.pasm'
15
 
 
16
 
.namespace ['Routine']
17
 
 
18
 
.sub 'onload' :anon :load :init
19
 
    .local pmc p6meta
20
 
    p6meta = get_hll_global ['Perl6Object'], '$!P6META'
21
 
    p6meta.'new_class'('Routine', 'parent'=>'Block')
22
 
.end
23
 
 
24
 
 
25
 
=head1 METHODS
26
 
 
27
 
=over 4
28
 
 
29
 
=item wrap
30
 
 
31
 
=cut
32
 
 
33
 
.sub 'wrap' :method
34
 
    .param pmc wrapper
35
 
 
36
 
    # Did we already wrap?
37
 
    .local pmc cand_list, cur_sub
38
 
    cur_sub = getattribute self, ['Sub'], 'proxy'
39
 
    cand_list = getprop '@!candidates', cur_sub
40
 
    unless null cand_list goto have_cand_list
41
 
 
42
 
    # If not, need to create a new candidate list with the current sub,
43
 
    # and install the wrap helper that will start dispatching at the
44
 
    # start of the candidate list.
45
 
    .local pmc p6i, p6i_copy
46
 
    cand_list = root_new ['parrot';'ResizablePMCArray']
47
 
    unshift cand_list, cur_sub
48
 
    p6i = root_new ['parrot';'P6Invocation'], cand_list
49
 
    .lex '__CANDIDATE_LIST__', p6i
50
 
    .const 'Sub' $P0 = '!wrap_start_helper'
51
 
    $P0 = newclosure $P0
52
 
    setattribute self, ['Sub'], 'proxy', $P0
53
 
    setprop $P0, '@!candidates', cand_list
54
 
 
55
 
    # XXX Aww, fick. Some hrovno happens in what follows that puts
56
 
    # some merde value into the p6i register - even though we never
57
 
    # do anything to explicitly change the hora. So, we make a copy,
58
 
    # in another register, and then copy it back over at the end.
59
 
    # Something is srsly buggered up somewhere.
60
 
    p6i_copy = p6i
61
 
 
62
 
    # We need to clone the wrapper, then tweak it to have an outer of
63
 
    # !wrap_clholder_helper, which we use to hold the candidate list,
64
 
    # and set the helper's outer to the block's original outer to maintain
65
 
    # the static chain. This is so we have a lexical slot for the
66
 
    # candidate list to go in; beats giving every single block one.
67
 
  have_cand_list:
68
 
    .local pmc orig_wrapper, tmp, tmp2
69
 
    orig_wrapper = wrapper
70
 
    wrapper = clone orig_wrapper
71
 
    .fixup_cloned_sub(orig_wrapper, wrapper)
72
 
    .const 'Sub' $P1 = '!wrap_clholder_helper'
73
 
    $P1 = clone $P1
74
 
    setprop $P1, '$!wrapper_block', wrapper
75
 
    $P2 = wrapper.'get_outer'()
76
 
    $P1.'set_outer'($P2)
77
 
    wrapper.'set_outer'($P1)
78
 
 
79
 
    # Unshift this candidate onto the list; generate a wrap handle also, stick
80
 
    # it on the candidate and return it.
81
 
    .local pmc handle
82
 
    $I0 = 1
83
 
    $P2 = cand_list[0]
84
 
    $P2 = getprop '$!handle', $P2
85
 
    if null $P2 goto no_handle
86
 
    $I0 = $P2
87
 
  no_handle:
88
 
    inc $I0
89
 
    handle = box $I0
90
 
    setprop $P1, '$!handle', handle
91
 
    unshift cand_list, $P1
92
 
 
93
 
    if null p6i_copy goto done
94
 
    p6i = p6i_copy
95
 
  done:
96
 
    .return (handle)
97
 
.end
98
 
.sub '!wrap_start_helper' :anon :outer('wrap')
99
 
    .param pmc pos_args   :slurpy
100
 
    .param pmc named_args :slurpy :named
101
 
    $P0 = find_lex '__CANDIDATE_LIST__'
102
 
    $P1 = clone $P0
103
 
    .tailcall $P1(pos_args :flat, named_args :flat :named)
104
 
.end
105
 
.sub '!wrap_clholder_helper' :anon
106
 
    .param pmc pos_args   :slurpy
107
 
    .param pmc named_args :slurpy :named
108
 
 
109
 
    # Slot for candidate list.
110
 
    .lex '__CANDIDATE_LIST__', $P0
111
 
 
112
 
    # Set up return handler, so next[with|same] work.
113
 
    $P2 = root_new ['parrot';'ExceptionHandler']
114
 
    set_addr $P2, ret_handler
115
 
    $P2."handle_types"(58)
116
 
    push_eh $P2
117
 
 
118
 
    # Get the inner block and call it.
119
 
    $P1 = interpinfo .INTERPINFO_CURRENT_SUB
120
 
    $P1 = getprop '$!wrapper_block', $P1
121
 
    capture_lex $P1
122
 
    ($P3) = $P1(pos_args :flat, named_args :flat :named)
123
 
    .return ($P3)
124
 
 
125
 
  ret_handler:
126
 
    .local pmc exception, result
127
 
    .get_results (exception)
128
 
    result = getattribute exception, "payload"
129
 
    .return (result)
130
 
.end
131
 
 
132
 
 
133
 
=item unwrap
134
 
 
135
 
=cut
136
 
 
137
 
.sub 'unwrap' :method
138
 
    .param pmc handle
139
 
 
140
 
    # Check it's wrapped.
141
 
    .local pmc cand_list, cur_sub
142
 
    cur_sub = getattribute self, ['Sub'], 'proxy'
143
 
    cand_list = getprop '@!candidates', cur_sub
144
 
    if null cand_list goto error
145
 
 
146
 
    # Look by handle for what to remove and remove it.
147
 
    $I0 = elements cand_list
148
 
    $I1 = 0
149
 
  find_loop:
150
 
    if $I1 >= $I0 goto error
151
 
    $P0 = cand_list[$I1]
152
 
    $P0 = getprop '$!handle', $P0
153
 
    if null $P0 goto error
154
 
    if handle == $P0 goto remove
155
 
    inc $I1
156
 
    goto find_loop
157
 
  remove:
158
 
    delete cand_list[$I1]
159
 
 
160
 
    # If it's not the last wrapper we're done, otherwise  we'll remove the
161
 
    # wrapper completely and restore the sub.
162
 
    $I0 = elements cand_list
163
 
    if $I0 == 1 goto final
164
 
    .return (handle)
165
 
 
166
 
  final:
167
 
    $P0 = shift cand_list
168
 
    setattribute self, ['Sub'], 'proxy', $P0
169
 
    .return (handle)
170
 
 
171
 
  error:
172
 
    'die'('Could not unwrap; unrecognized wrap handle')
173
 
.end
174
 
 
175
 
=back
176
 
 
177
 
=cut
178
 
 
179
 
# Local Variables:
180
 
#   mode: pir
181
 
#   fill-column: 100
182
 
# End:
183
 
# vim: expandtab shiftwidth=4 ft=pir: