/[eiffelstudio]/branches/eth/eve/Src/Eiffel/eiffel/byte_code/visitor/melted_generator.e
ViewVC logotype

Contents of /branches/eth/eve/Src/Eiffel/eiffel/byte_code/visitor/melted_generator.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 94983 - (show annotations)
Fri May 2 11:05:28 2014 UTC (5 years, 5 months ago) by jasonw
File size: 69150 byte(s)
<<Merged from trunk#94978.>>
1 note
2 description: "Visitor for BYTE_NODE objects which generates the Eiffel melted code."
3 legal: "See notice at end of class."
4 status: "See notice at end of class."
5 date: "$Date$"
6 revision: "$Revision$"
7
8 class
9 MELTED_GENERATOR
10
11 inherit
12 BYTE_NODE_VISITOR
13
14 BYTE_CONST
15 export
16 {NONE} all
17 end
18
19 SHARED_BYTE_CONTEXT
20 export
21 {NONE} all
22 end
23
24 REFACTORING_HELPER
25 export
26 {NONE} all
27 end
28
29 SHARED_WORKBENCH
30 export
31 {NONE} all
32 end
33
34 SHARED_TYPES
35 export
36 {NONE} all
37 end
38
39 INTEGER_TYPE_MASKS
40
41 SHARED_BN_STATELESS_VISITOR
42 export
43 {NONE} all
44 end
45
46 COMPILER_EXPORTER
47
48 INTERNAL_COMPILER_STRING_EXPORTER
49
50 feature -- Initialize
51
52 generate (a_ba: BYTE_ARRAY; a_node: BYTE_NODE)
53 -- Generate `a_node''s code into `a_ba'.
54 require
55 a_ba_not_void: a_ba /= Void
56 a_node_not_void: a_node /= Void
57 do
58 ba := a_ba
59 a_node.process (Current)
60 ba := Void
61 end
62
63 generate_old_expression_initialization (a_ba: BYTE_ARRAY; a_node: UN_OLD_B)
64 -- Generate `a_node''s code into `a_ba'.
65 require
66 a_ba_not_void: a_ba /= Void
67 a_node_not_void: a_node /= Void
68 do
69 ba := a_ba
70 a_node.expr.process (Current)
71 -- Write the end of last old expression evaluation.
72 ba.write_forward
73 ba.append (bc_old)
74 ba.append_short_integer (a_node.position)
75 ba.append_short_integer (a_node.exception_position)
76 -- Mark start of next old expression evaluation.
77 ba.mark_forward
78 ba := Void
79 end
80
81 feature -- Access
82
83 ba: BYTE_ARRAY
84 -- Byte array where melted code is stored.
85
86 is_in_creation_call: BOOLEAN
87 -- Is current call a creation instruction?
88
89 feature {NONE} -- Status report
90
91 is_initialization: BOOLEAN
92 -- Is initialization code being processed?
93
94 feature -- Routine visitor
95
96 process_std_byte_code (a_node: STD_BYTE_CODE)
97 -- Process current element.
98 do
99 end
100
101 feature {NONE} -- Implementation visitors
102
103 process_hidden_if_b (a_node: HIDDEN_IF_B)
104 -- Process `a_node'.
105 do
106 process_if_b (a_node)
107 end
108
109 process_hidden_b (a_node: HIDDEN_B)
110 -- Process `a_node'.
111 do
112 context.enter_hidden_code
113 process_byte_list (a_node)
114 context.exit_hidden_code
115 end
116
117 process_do_rescue_b (a_node: DO_RESCUE_B)
118 -- Process `a_node'
119 do
120 ba.mark_retry
121 if attached a_node.compound as l_compound then
122 ba.append (bc_do_rescue)
123 if a_node.rescue_clause /= Void then
124 ba.append_boolean (True)
125 ba.mark_forward3
126 else
127 ba.append_boolean (False)
128 end
129
130 -- Compound byte code
131 l_compound.process (Current)
132 ba.append (Bc_do_rescue_end)
133 if attached a_node.rescue_clause as l_rescue_clause then
134 ba.append (bc_jmp)
135 ba.mark_forward4
136 -- Mark the start of the rescue clause
137 ba.write_forward3
138 ba.append (Bc_rescue)
139 l_rescue_clause.process (Current)
140 --| No Bc_end_rescue, since we do not want to exit the routine
141 ba.append (Bc_end_rescue)
142 -- Mark the end of the rescue clause.
143 ba.write_forward4
144 end
145 end
146 end
147
148 process_try_b (a_node: TRY_B)
149 -- Process `a_node'
150 local
151 l_except_part: detachable BYTE_LIST [BYTE_NODE]
152 do
153 if attached a_node.compound as l_compound then
154 ba.append (bc_try)
155 l_except_part := a_node.except_part
156 if l_except_part /= Void then
157 ba.append_boolean (True)
158 ba.mark_forward2
159 else
160 ba.append_boolean (False)
161 end
162
163 -- Compound byte code
164 l_compound.process (Current)
165 ba.append (bc_try_end)
166
167 if l_except_part /= Void then
168 ba.append (bc_jmp)
169 ba.mark_forward3
170 -- Mark the start of the except part
171 ba.write_forward2
172 l_except_part.process (Current)
173 ba.append (Bc_try_end_except)
174 -- Mark the end of the try/except clause.
175 ba.write_forward3
176 end
177 end
178 end
179
180 feature {NONE} -- Visitors
181
182 process_access_expr_b (a_node: ACCESS_EXPR_B)
183 -- Process `a_node'.
184 do
185 a_node.expr.process (Current)
186 end
187
188 process_address_b (a_node: ADDRESS_B)
189 -- Process `a_node'.
190 do
191 ba.append (Bc_addr)
192 ba.append_integer (
193 system.address_table.id_of_dollar_feature (a_node.feature_class_id, a_node.feature_id, context.class_type))
194 end
195
196 process_argument_b (a_node: ARGUMENT_B)
197 -- Process `a_node'.
198 do
199 ba.append (Bc_arg)
200 ba.append_short_integer (a_node.position)
201 end
202
203 process_array_const_b (a_node: ARRAY_CONST_B)
204 -- Process `a_node'.
205 local
206 l_real_ty: GEN_TYPE_A
207 l_feat_i: FEATURE_I
208 l_expr: EXPR_B
209 l_target_type: TYPE_A
210 l_base_class: CLASS_C
211 l_special_info: CREATE_TYPE
212 l_special_type: TYPE_A
213 l_special_class_type: SPECIAL_CLASS_TYPE
214 i: INTEGER
215 do
216 l_real_ty ?= context.real_type (a_node.type)
217 l_target_type := l_real_ty.generics.first
218
219 -- We first create a SPECIAL in which we will store the information above before
220 -- creating the ARRAY using `make_from_special'.
221 -- First push the number of elements in the SPECIAL
222 ba.append (Bc_int32)
223 ba.append_integer (a_node.expressions.count)
224 -- Then create an instance of the SPECIAL.
225 ba.append (bc_spcreate)
226 if system.is_using_new_special then
227 -- We are going to use `make_empty'
228 ba.append_boolean (False)
229 ba.append_boolean (True)
230 else
231 -- We are going to use `make'
232 ba.append_boolean (False)
233 ba.append_boolean (False)
234 end
235 l_special_info := a_node.special_info.updated_info
236 l_special_info.make_byte_code (ba)
237 l_special_type := l_special_info.type
238 check
239 is_special_type: l_special_type /= Void and then l_special_type.base_class.lace_class = System.special_class
240 end
241 l_special_class_type ?= l_special_type.associated_class_type (context.context_class_type.type)
242 check
243 l_class_type_not_void: l_special_class_type /= Void
244 end
245 l_special_class_type.make_creation_byte_code (ba)
246
247 -- We compute the expressions and store them into the special
248 from
249 a_node.expressions.start
250 i := 0
251 until
252 a_node.expressions.after
253 loop
254 l_expr ?= a_node.expressions.item
255 check
256 l_expr_not_void: l_expr /= Void
257 end
258 make_expression_byte_code_for_type (l_expr, l_target_type)
259 ba.append (bc_special_extend)
260 ba.append_integer (i)
261 i := i + 1
262 a_node.expressions.forth
263 end
264
265 -- Now we create the ARRAY instance vi the call to `to_array' from SPECIAL
266 l_base_class := l_special_class_type.associated_class
267 l_feat_i := l_base_class.feature_table.item_id ({PREDEFINED_NAMES}.to_array_name_id)
268 ba.append (Bc_array)
269 ba.append_integer (l_feat_i.rout_id_set.first)
270 end
271
272 process_assert_b (a_node: ASSERT_B)
273 -- Process `a_node'.
274 do
275 make_assert_b (a_node)
276 end
277
278 process_assign_b (a_node: ASSIGN_B)
279 -- Process `a_node'.
280 local
281 l_target_type: TYPE_A
282 l_target_node: ACCESS_B
283 l_mark_count: NATURAL
284 do
285 l_target_node := a_node.target
286 l_target_type := Context.real_type (l_target_node.type)
287 generate_melted_debugger_hook
288
289 -- Generate expression byte code
290 if a_node.is_creation_instruction then
291 -- Avoid object cloning.
292 a_node.source.process (Current)
293 else
294 -- Clone source object depending on its type and type of target.
295 make_expression_byte_code_for_type (a_node.source, l_target_type)
296 end
297
298 if a_node.source.is_hector then
299 if attached {HECTOR_B} a_node.source as l_hector_b then
300 make_protected_byte_code (l_hector_b, 0)
301 else
302 -- Address expressions are disallowed for attachement
303 check False end
304 end
305 end
306
307 -- Generate assignment header depending of the type
308 -- of the target (local, attribute or result).
309 if l_target_type.is_true_expanded then
310 -- Target is expanded: copy with possible exception
311 ba.append (l_target_node.expanded_assign_code)
312 else
313 -- Target is basic or reference: simple attachment
314 ba.append (l_target_node.assign_code)
315 end
316 melted_assignment_generator.generate_assignment (ba, l_target_node)
317 -- Write marks if required.
318 from
319 until
320 l_mark_count = 0
321 loop
322 ba.write_forward
323 l_mark_count := l_mark_count - 1
324 variant
325 l_mark_count.as_integer_32
326 end
327 end
328
329 process_attribute_b (a_node: ATTRIBUTE_B)
330 -- Process `a_node'.
331 local
332 f: FEATURE_B
333 do
334 f := a_node.wrapper
335 if f /= Void then
336 process_feature_b (f)
337 else
338 if a_node.context_type.is_basic then
339 -- Access to `item' from basic types.
340 -- Nothing to be done since the right value is already on the stack.
341 else
342 if a_node.is_first then
343 ba.append (bc_current)
344 ba.append (bc_attribute)
345 else
346 ba.append (bc_attribute_inv)
347 ba.append_raw_string (a_node.attribute_name)
348 end
349 ba.append_integer (a_node.routine_id)
350 ba.append_natural_32 (context.real_type (a_node.type).sk_value (context.context_class_type.type))
351 end
352 end
353 end
354
355 process_bin_and_b (a_node: BIN_AND_B)
356 -- Process `a_node'.
357 do
358 process_bin_and_then_b (a_node)
359 end
360
361 process_bin_and_then_b (a_node: B_AND_THEN_B)
362 -- Process `a_node'.
363 do
364 if a_node.is_built_in then
365 a_node.left.process (Current)
366 ba.append (bc_and_then)
367 ba.mark_forward
368 a_node.right.process (Current)
369 ba.append (bc_and)
370 ba.write_forward
371 else
372 a_node.nested_b.process (Current)
373 end
374 end
375
376 process_bin_div_b (a_node: BIN_DIV_B)
377 -- Process `a_node'.
378 do
379 make_binary_b (a_node, bc_div)
380 end
381
382 process_bin_eq_b (a_node: BIN_EQ_B)
383 -- Process `a_node'.
384 do
385 make_binary_equal_b (a_node, bc_eq, bc_false_compar)
386 end
387
388 process_bin_free_b (a_node: BIN_FREE_B)
389 -- Process `a_node'.
390 do
391 a_node.nested_b.process (Current)
392 end
393
394 process_bin_ge_b (a_node: BIN_GE_B)
395 -- Process `a_node'.
396 do
397 make_binary_b (a_node, bc_ge)
398 end
399
400 process_bin_gt_b (a_node: BIN_GT_B)
401 -- Process `a_node'.
402 do
403 make_binary_b (a_node, bc_gt)
404 end
405
406 process_bin_implies_b (a_node: B_IMPLIES_B)
407 -- Process `a_node'.
408 do
409 if a_node.is_built_in then
410 a_node.left.process (Current)
411 ba.append (bc_not)
412 ba.append (bc_or_else)
413 ba.mark_forward
414 a_node.right.process (Current)
415 ba.append (bc_or)
416 ba.write_forward
417 else
418 a_node.nested_b.process (Current)
419 end
420 end
421
422 process_bin_le_b (a_node: BIN_LE_B)
423 -- Process `a_node'.
424 do
425 make_binary_b (a_node, bc_le)
426 end
427
428 process_bin_lt_b (a_node: BIN_LT_B)
429 -- Process `a_node'.
430 do
431 make_binary_b (a_node, bc_lt)
432 end
433
434 process_bin_minus_b (a_node: BIN_MINUS_B)
435 -- Process `a_node'.
436 do
437 make_binary_b (a_node, bc_minus)
438 end
439
440 process_bin_mod_b (a_node: BIN_MOD_B)
441 -- Process `a_node'.
442 do
443 make_binary_b (a_node, bc_mod)
444 end
445
446 process_bin_ne_b (a_node: BIN_NE_B)
447 -- Process `a_node'.
448 do
449 make_binary_equal_b (a_node, bc_ne, bc_true_compar)
450 end
451
452 process_bin_not_tilde_b (a_node: BIN_NOT_TILDE_B)
453 -- Process `a_node'.
454 do
455 process_bin_tilde_b (a_node)
456 ba.append (bc_not)
457 end
458
459 process_bin_or_b (a_node: BIN_OR_B)
460 -- Process `a_node'.
461 do
462 process_bin_or_else_b (a_node)
463 end
464
465 process_bin_or_else_b (a_node: B_OR_ELSE_B)
466 -- Process `a_node'.
467 do
468 if a_node.is_built_in then
469 a_node.left.process (Current)
470 ba.append (Bc_or_else)
471 ba.mark_forward
472 a_node.right.process (Current)
473 ba.append (bc_or)
474 ba.write_forward
475 else
476 a_node.nested_b.process (Current)
477 end
478 end
479
480 process_bin_plus_b (a_node: BIN_PLUS_B)
481 -- Process `a_node'.
482 do
483 make_binary_b (a_node, bc_plus)
484 end
485
486 process_bin_power_b (a_node: BIN_POWER_B)
487 -- Process `a_node'.
488 do
489 make_binary_b (a_node, bc_power)
490 end
491
492 process_bin_slash_b (a_node: BIN_SLASH_B)
493 -- Process `a_node'.
494 do
495 make_binary_b (a_node, bc_slash)
496 end
497
498 process_bin_star_b (a_node: BIN_STAR_B)
499 -- Process `a_node'.
500 do
501 make_binary_b (a_node, bc_star)
502 end
503
504 process_bin_tilde_b (a_node: BIN_TILDE_B)
505 -- Process `a_node'.
506 local
507 l_lt, l_rt: TYPE_A
508 l_flag: BOOLEAN
509 do
510 l_lt := context.real_type (a_node.left.type)
511 l_rt := context.real_type (a_node.right.type)
512
513 -- For values of the same basic type the equality test is generated.
514 if l_lt.is_basic and then l_rt.is_basic and then l_lt.same_as (l_rt) then
515 a_node.left.process (Current)
516 a_node.right.process (Current)
517 ba.append (bc_eq)
518 elseif
519 (l_lt.is_expanded and then l_rt.is_none) or else
520 (l_lt.is_none and then l_rt.is_expanded) or else
521 (l_lt.is_expanded and then l_rt.is_expanded and then
522 l_lt.has_associated_class and then l_rt.has_associated_class and then
523 l_lt.base_class.class_id /= l_rt.base_class.class_id)
524 then
525 -- A value of an expanded type is not Void.
526 -- Two values of different expanded types are not equal.
527 -- In both cases we simply evaluate the expressions and
528 -- then remove them from the stack to insert the expected value.
529 a_node.left.process (Current)
530 a_node.right.process (Current)
531 ba.append (bc_pop)
532 ba.append_uint32_integer (2)
533 ba.append (bc_bool)
534 ba.append_boolean (False)
535 else
536 a_node.left.process (Current)
537 if (l_lt.is_basic and then l_rt.is_reference) then
538 ba.append (Bc_metamorphose)
539 l_flag := True
540 end
541 a_node.right.process (Current)
542 if (l_lt.is_reference and then l_rt.is_basic) then
543 ba.append (Bc_metamorphose)
544 l_flag := True
545 end
546 -- FIXME: This call assumes that `is_equal' from ANY always takes
547 -- `like Current' as argument, but actually it could be different.
548 ba.append (bc_standard_equal)
549 end
550 end
551
552 process_bin_xor_b (a_node: BIN_XOR_B)
553 -- Process `a_node'.
554 do
555 make_binary_b (a_node, bc_xor)
556 end
557
558 process_bool_const_b (a_node: BOOL_CONST_B)
559 -- Process `a_node'.
560 do
561 ba.append (bc_bool)
562 ba.append_boolean (a_node.value)
563 end
564
565 process_byte_list (a_node: BYTE_LIST [BYTE_NODE])
566 -- Process `a_node'.
567 local
568 l_area: SPECIAL [BYTE_NODE]
569 i, nb: INTEGER
570 do
571 from
572 l_area := a_node.area
573 nb := a_node.count
574 until
575 i = nb
576 loop
577 l_area.item (i).process (Current)
578 i := i + 1
579 end
580 end
581
582 process_case_b (a_node: CASE_B)
583 -- Process `a_node'.
584 local
585 i: INTEGER
586 do
587 from
588 i := a_node.interval.count
589 until
590 i < 1
591 loop
592 ba.write_forward2
593 i := i - 1
594 end
595 if attached a_node.compound as c then
596 c.process (Current)
597 end
598 -- To end of inspect
599 ba.append (Bc_jmp)
600 ba.mark_forward
601 end
602
603 process_char_const_b (a_node: CHAR_CONST_B)
604 -- Process `a_node'.
605 do
606 if a_node.is_character_32 then
607 ba.append (Bc_wchar)
608 ba.append_character_32 (a_node.value)
609 else
610 ba.append (Bc_char)
611 ba.append (a_node.value.to_character_8)
612 end
613 end
614
615 process_char_val_b (a_node: CHAR_VAL_B)
616 -- Process `a_node'.
617 do
618 ba.append (Bc_wchar)
619 ba.append_character_32 (a_node.value)
620 end
621
622 process_check_b (a_node: CHECK_B)
623 -- Process `a_node'.
624 do
625 if a_node.check_list /= Void then
626 -- Set assertion type
627 context.set_assertion_type ({ASSERT_TYPE}.In_check)
628
629 ba.append (Bc_check)
630 -- In case, the check assertions won't be checked, we
631 -- have to put a jump offset
632 ba.mark_forward
633 -- Assertion byte code
634 a_node.check_list.process (Current)
635 -- Jump offset evaluation
636 ba.write_forward
637
638 context.set_assertion_type (0)
639 end
640 end
641
642 process_constant_b (a_node: CONSTANT_B)
643 -- Process `a_node'.
644 do
645 a_node.access.process (Current)
646 end
647
648 process_creation_expr_b (a_node: CREATION_EXPR_B)
649 -- Process `a_node'.
650 local
651 l_basic_type: BASIC_A
652 l_special_type: TYPE_A
653 l_class_type: SPECIAL_CLASS_TYPE
654 l_call: CALL_ACCESS_B
655 l_nested: NESTED_B
656 l_is_make_filled: BOOLEAN
657 do
658 l_basic_type ?= context.real_type (a_node.type)
659 if l_basic_type /= Void then
660 -- Special cases for basic types where nothing needs to be created, we
661 -- simply need to push a default value as their creation procedure
662 -- is `default_create' and it does nothing.
663 l_basic_type.c_type.make_default_byte_code (ba)
664 else
665 l_call := a_node.call
666 if a_node.is_special_creation then
667 l_is_make_filled := a_node.is_special_make_filled
668 l_special_type := context.real_type (a_node.type)
669 check
670 is_special_call_valid: a_node.is_special_call_valid
671 is_special_type: l_special_type /= Void and then
672 l_special_type.base_class.lace_class = system.special_class
673 end
674 l_class_type ?= l_special_type.associated_class_type (context.context_class_type.type)
675 check
676 l_class_type_not_void: l_class_type /= Void
677 end
678 l_call.parameters.first.process (Current)
679 if l_is_make_filled then
680 l_call.parameters.i_th (2).process (Current)
681 end
682 ba.append (Bc_spcreate)
683 -- Say whether or not we should fill the SPECIAL.
684 ba.append_boolean (l_is_make_filled)
685 ba.append_boolean (a_node.is_special_make_empty)
686 a_node.info.updated_info.make_byte_code (ba)
687 l_class_type.make_creation_byte_code (ba)
688 if l_is_make_filled then
689 create l_nested
690 l_nested.set_target (a_node)
691 l_nested.set_message (l_call)
692 l_call.set_parent (l_nested)
693 make_call_access_b (l_call, bc_feature, bc_feature_inv, True)
694 l_call.set_parent (Void)
695 end
696 else
697 ba.append (Bc_create)
698 -- If there is a call, we need to duplicate newly created object
699 -- after its creation. This information is used by the runtime
700 -- to do this duplication.
701 ba.append_boolean (l_call /= Void)
702
703 -- Create associated object.
704 a_node.info.updated_info.make_byte_code (ba)
705
706 -- Call creation procedure if any.
707 if l_call /= Void then
708 create l_nested
709 l_nested.set_target (a_node)
710 l_nested.set_message (l_call)
711 l_call.set_parent (l_nested)
712 is_in_creation_call := True
713 l_call.process (Current)
714 is_in_creation_call := False
715 l_call.set_parent (Void)
716 end
717 end
718 end
719 end
720
721 process_current_b (a_node: CURRENT_B)
722 -- Process `a_node'.
723 do
724 ba.append (bc_current)
725 end
726
727 process_custom_attribute_b (a_node: CUSTOM_ATTRIBUTE_B)
728 -- Process `a_node'.
729 do
730 check
731 not_applicable: False
732 end
733 end
734
735 process_debug_b (a_node: DEBUG_B)
736 -- Process `a_node'.
737 do
738 if a_node.compound /= Void then
739 ba.append (Bc_debug)
740 if a_node.keys = Void then
741 ba.append_integer (0)
742 else
743 ba.append_integer (a_node.keys.count)
744 from
745 a_node.keys.start
746 until
747 a_node.keys.after
748 loop
749 ba.append_integer (a_node.keys.item.count)
750 ba.append_raw_string (a_node.keys.item)
751 a_node.keys.forth
752 end
753 end
754 ba.mark_forward
755 a_node.compound.process (Current)
756 ba.write_forward
757 end
758 end
759
760 process_elsif_b (a_node: ELSIF_B)
761 -- Process `a_node'.
762 do
763 -- Generate hook for the condition test
764 generate_melted_debugger_hook
765
766 -- Generate byte code for expression
767 a_node.expr.process (Current)
768
769 -- Test if False
770 ba.append (Bc_jmp_f)
771 ba.mark_forward
772
773 if a_node.compound /= Void then
774 -- Generate alternative compound byte code
775 a_node.compound.process (Current)
776 end
777 ba.append (Bc_jmp)
778 ba.mark_forward2
779 ba.write_forward
780 end
781
782 process_elsif_expression_b (a_node: ELSIF_EXPRESSION_B)
783 -- <Precursor>
784 do
785 -- Generate hook for the condition test.
786 generate_melted_debugger_hook
787
788 -- Generate byte code for condition.
789 a_node.condition.process (Current)
790
791 -- Test if False.
792 ba.append (Bc_jmp_f)
793 ba.mark_forward
794
795 -- Generate alternative expression byte code.
796 a_node.expression.process (Current)
797 ba.append (Bc_jmp)
798 ba.mark_forward2
799 ba.write_forward
800 end
801
802 process_expr_address_b (a_node: EXPR_ADDRESS_B)
803 -- Process `a_node'.
804 --| Generation is exactly the same as in `process_hector_b'.
805 local
806 l_type: TYPE_A
807 do
808 l_type := Context.real_type (a_node.expr.type)
809 if l_type.is_basic then
810 -- Getting the address of a basic type can be done
811 -- only once all the expressions have been evaluated
812 ba.append (Bc_reserve)
813 else
814 a_node.expr.process (Current)
815 if l_type.is_reference then
816 ba.append (Bc_ref_to_ptr)
817 end
818 end
819 end
820
821 process_external_b (a_node: EXTERNAL_B)
822 -- Process `a_node'.
823 local
824 i: INTEGER
825 l_has_hector: BOOLEAN
826 l_parameter_b: PARAMETER_B
827 l_hector_b: HECTOR_B
828 l_expr_address_b: EXPR_ADDRESS_B
829 l_nb_expr_address: INTEGER
830 l_pos: INTEGER
831 l_is_in_creation_call: like is_in_creation_call
832 do
833 l_is_in_creation_call := is_in_creation_call
834 is_in_creation_call := False
835 if a_node.parameters /= Void then
836 -- Generate the expression address byte code
837 from
838 a_node.parameters.start
839 until
840 a_node.parameters.after
841 loop
842 l_parameter_b ?= a_node.parameters.item
843 if l_parameter_b /= Void and then l_parameter_b.is_hector then
844 l_has_hector := True
845 l_expr_address_b ?= l_parameter_b.expression
846 if l_expr_address_b /= Void and then l_expr_address_b.is_protected then
847 l_expr_address_b.expr.process (Current)
848 l_nb_expr_address := l_nb_expr_address + 1
849 end
850 end
851 a_node.parameters.forth
852 end
853
854 from
855 a_node.parameters.start
856 until
857 a_node.parameters.after
858 loop
859 a_node.parameters.item.process (Current)
860 a_node.parameters.forth
861 end
862 end
863
864 if l_has_hector then
865 from
866 a_node.parameters.start
867 until
868 a_node.parameters.after
869 loop
870 l_pos := l_pos + 1
871 l_parameter_b ?= a_node.parameters.item
872 if l_parameter_b /= Void and then l_parameter_b.is_hector then
873 l_hector_b ?= l_parameter_b.expression
874 if l_hector_b /= Void then
875 make_protected_byte_code (l_hector_b, a_node.parameters.count - l_pos)
876 else
877 -- Cannot be Void
878 l_expr_address_b ?= l_parameter_b.expression
879 if l_expr_address_b.is_protected then
880 i := i + 1
881 l_expr_address_b.make_protected_byte_code (ba,
882 a_node.parameters.count - l_pos,
883 a_node.parameters.count + l_nb_expr_address - i)
884 end
885 end
886 end
887 a_node.parameters.forth
888 end
889 end
890
891 if a_node.is_static_call then
892 ba.append (bc_current)
893 ba.append (bc_extern)
894 ba.append_integer (a_node.routine_id)
895 make_precursor_byte_code (a_node)
896 else
897 make_call_access_b (a_node, bc_extern, bc_extern_inv, l_is_in_creation_call)
898 end
899
900 if l_nb_expr_address > 0 then
901 ba.append (Bc_pop)
902 ba.append_uint32_integer (l_nb_expr_address)
903 end
904
905 if context.real_type (a_node.type).is_reference then
906 -- Box return value if required.
907 ba.append (bc_metamorphose)
908 end
909 end
910
911 process_feature_b (a_node: FEATURE_B)
912 -- Process `a_node'.
913 local
914 i, l_pos, l_nb_expr_address: INTEGER
915 l_has_hector: BOOLEAN
916 l_parameter_b: PARAMETER_B
917 l_hector_b: HECTOR_B
918 l_expr_address_b: EXPR_ADDRESS_B
919 l_access_expression_b: ACCESS_EXPR_B
920 l_is_in_creation_call: like is_in_creation_call
921 do
922 l_is_in_creation_call := is_in_creation_call
923 is_in_creation_call := False
924 if a_node.parameters /= Void then
925 -- Generate the expression address byte code
926 from
927 a_node.parameters.start
928 until
929 a_node.parameters.after
930 loop
931 l_parameter_b ?= a_node.parameters.item
932 if l_parameter_b /= Void and then l_parameter_b.is_hector then
933 l_has_hector := True
934 l_expr_address_b ?= l_parameter_b.expression
935 if l_expr_address_b /= Void and then l_expr_address_b.is_protected then
936 l_expr_address_b.expr.process (Current)
937 l_nb_expr_address := l_nb_expr_address + 1
938 end
939 end
940 a_node.parameters.forth
941 end
942
943 l_has_hector := l_has_hector or else (a_node.parent /= Void and then a_node.parent.target.is_hector)
944
945 -- Generate byte code for parameters
946 from
947 a_node.parameters.start
948 until
949 a_node.parameters.after
950 loop
951 a_node.parameters.item.process (Current)
952 a_node.parameters.forth
953 end
954 end
955
956 if l_has_hector then
957 if (a_node.parent /= Void and then a_node.parent.target.is_hector) then
958 -- We are in the case of a nested calls which have
959 -- a target using the `$' operator. It can only be the case
960 -- of `($a).f (..)'. where `($a)' represents an
961 -- ACCESS_EXPR_B object which contains an HECTOR_B
962 -- or an EXPR_ADDESS_B object.
963 l_access_expression_b ?= a_node.parent.target
964 check
965 has_access_expression: l_access_expression_b /= Void
966 end
967 l_hector_b ?= l_access_expression_b.expr
968 if l_hector_b /= Void then
969 make_protected_byte_code (l_hector_b, a_node.parameters.count)
970 else
971 l_expr_address_b ?= l_parameter_b.expression
972 check
973 expr_address_b_not_void: l_expr_address_b /= Void
974 end
975 if l_expr_address_b.is_protected then
976 i := i + 1
977 l_expr_address_b.make_protected_byte_code (ba,
978 a_node.parameters.count,
979 a_node.parameters.count + l_nb_expr_address - i)
980 end
981 end
982 end
983 from
984 a_node.parameters.start
985 until
986 a_node.parameters.after
987 loop
988 l_pos := l_pos + 1
989 l_parameter_b ?= a_node.parameters.item
990 if l_parameter_b /= Void and then l_parameter_b.is_hector then
991 l_hector_b ?= l_parameter_b.expression
992 if l_hector_b /= Void then
993 make_protected_byte_code (l_hector_b, a_node.parameters.count - l_pos)
994 else
995 -- Cannot be Void
996 l_expr_address_b ?= l_parameter_b.expression
997 if l_expr_address_b.is_protected then
998 i := i + 1
999 l_expr_address_b.make_protected_byte_code (ba,
1000 a_node.parameters.count - l_pos,
1001 a_node.parameters.count + l_nb_expr_address - i)
1002 end
1003 end
1004 end
1005 a_node.parameters.forth
1006 end
1007 end
1008
1009 make_call_access_b (a_node, bc_feature, bc_feature_inv, l_is_in_creation_call)
1010
1011 if l_nb_expr_address > 0 then
1012 ba.append (Bc_pop)
1013 ba.append_uint32_integer (l_nb_expr_address)
1014 end
1015
1016 if context.real_type (a_node.type).is_reference then
1017 -- Box return value if required.
1018 ba.append (bc_metamorphose)
1019 end
1020 end
1021
1022 process_agent_call_b (a_node: AGENT_CALL_B)
1023 -- Process `a_node'.
1024 do
1025 process_feature_b (a_node)
1026 end
1027
1028 process_formal_conversion_b (a_node: FORMAL_CONVERSION_B)
1029 -- Process `a_node'.
1030 local
1031 l_type, l_expr_type: TYPE_A
1032 do
1033 a_node.expr.process (Current)
1034
1035 l_type := context.real_type (a_node.type)
1036 l_expr_type := context.real_type (a_node.expr.type)
1037 if a_node.is_conversion_needed (l_expr_type, l_type) then
1038 if l_expr_type.is_basic then
1039 ba.append (bc_metamorphose)
1040 else
1041 ba.append (bc_clone)
1042 end
1043 end
1044 end
1045
1046 process_guard_b (a_node: GUARD_B)
1047 -- <Precursor>
1048 do
1049 -- Generate hook for the condition test.
1050 if attached a_node.check_list as c then
1051 -- Generated byte code for assertions.
1052 context.set_assertion_type ({ASSERT_TYPE}.In_guard)
1053 c.process (Current)
1054 context.set_assertion_type (0)
1055 end
1056 if attached a_node.compound as c then
1057 -- Generated byte code for compound.
1058 c.process (Current)
1059 end
1060 end
1061
1062 process_hector_b (a_node: HECTOR_B)
1063 -- Process `a_node'.
1064 local
1065 l_type: TYPE_A
1066 do
1067 l_type := context.real_type (a_node.expr.type)
1068 if l_type.is_basic then
1069 -- Getting the address of a basic type can be done
1070 -- only once all the expressions have been evaluated
1071 ba.append (Bc_reserve)
1072 else
1073 a_node.expr.process (Current)
1074 if l_type.is_reference then
1075 ba.append (Bc_ref_to_ptr)
1076 end
1077 end
1078 end
1079
1080 process_if_b (a_node: IF_B)
1081 -- Process `a_node'.
1082 local
1083 l_elsif_clause: ELSIF_B
1084 i, nb_jumps: INTEGER
1085 do
1086 if attached {HIDDEN_IF_B} a_node then
1087 context.enter_hidden_code
1088 a_node.condition.process (Current)
1089 context.exit_hidden_code
1090 else
1091 -- Generate hook for the condition test
1092 generate_melted_debugger_hook
1093
1094 -- Generated byte code for condition
1095 a_node.condition.process (Current)
1096 end
1097
1098 -- Generated a test
1099 ba.append (Bc_jmp_f)
1100
1101 -- Deferred writing of the jump value
1102 ba.mark_forward
1103
1104 if a_node.compound /= Void then
1105 -- Generated byte code for first compound (if any).
1106 a_node.compound.process (Current)
1107 end
1108 ba.append (Bc_jmp)
1109 ba.mark_forward2
1110 nb_jumps := nb_jumps + 1
1111
1112 -- Writes the relative jump value.
1113 ba.write_forward
1114
1115 if a_node.elsif_list /= Void then
1116 -- Generates byte code for alternatives
1117 from
1118 a_node.elsif_list.start
1119 until
1120 a_node.elsif_list.after
1121 loop
1122 l_elsif_clause ?= a_node.elsif_list.item
1123 check l_elsif_clause_not_void: l_elsif_clause /= Void end
1124 l_elsif_clause.process (Current)
1125 nb_jumps := nb_jumps + 1
1126 a_node.elsif_list.forth
1127 end
1128 end
1129
1130 if a_node.else_part /= Void then
1131 -- Generates byte code for default compound.
1132 a_node.else_part.process (Current)
1133 end
1134
1135 from
1136 -- Generate jump values for unconditional jumps
1137 -- after the `nb_jumps' compounds encountered in the
1138 -- entire instruction.
1139 i := 1
1140 until
1141 i > nb_jumps
1142 loop
1143 ba.write_forward2
1144 i := i + 1
1145 end
1146 end
1147
1148 process_if_expression_b (a_node: IF_EXPRESSION_B)
1149 -- <Precursor>
1150 local
1151 nb_jumps: INTEGER
1152 do
1153 -- Generate hook for the condition test.
1154 generate_melted_debugger_hook
1155
1156 -- Generate byte code for condition.
1157 a_node.condition.process (Current)
1158
1159 -- Generate a test.
1160 ba.append (Bc_jmp_f)
1161
1162 -- Deferred writing of the jump value.
1163 ba.mark_forward
1164
1165 -- Generate expression for Then_part.
1166 a_node.then_expression.process (Current)
1167
1168 ba.append (Bc_jmp)
1169 ba.mark_forward2
1170 nb_jumps := 1
1171
1172 -- Write relative jump value.
1173 ba.write_forward
1174
1175 if attached a_node.elsif_list as l then
1176 -- Generate byte code for alternatives.
1177 across
1178 l as c
1179 loop
1180 c.item.process (Current)
1181 end
1182 nb_jumps := nb_jumps + l.count
1183 end
1184
1185 -- Generate expression for Else_part.
1186 a_node.else_expression.process (Current)
1187
1188 from
1189 -- Generate jump values for unconditional jumps
1190 -- after the `nb_jumps' expressions encountered in the
1191 -- entire conditional expression.
1192 until
1193 nb_jumps <= 0
1194 loop
1195 ba.write_forward2
1196 nb_jumps := nb_jumps - 1
1197 end
1198 end
1199
1200 process_inspect_b (a_node: INSPECT_B)
1201 -- Process `a_node'.
1202 local
1203 i, l_nb_jump: INTEGER
1204 l_case: CASE_B
1205 do
1206 generate_melted_debugger_hook
1207
1208 -- Generate switch expression byte code
1209 a_node.switch.process (Current)
1210 if a_node.case_list /= Void then
1211 from
1212 i := a_node.case_list.count
1213 l_nb_jump := i
1214 until
1215 i < 1
1216 loop
1217 l_case ?= a_node.case_list.i_th (i)
1218 check
1219 l_case_not_void: l_case /= Void
1220 end
1221 make_case_range (l_case)
1222 i := i - 1
1223 end
1224 -- Go to else part
1225 ba.append (Bc_jmp)
1226 ba.mark_forward3
1227
1228 -- Generate code for the various inspect matches
1229 a_node.case_list.process (Current)
1230 ba.write_forward3
1231 end
1232 if a_node.else_part /= Void then
1233 -- We need to pop the value of the expression since we do not need it anymore.
1234 ba.append (bc_pop)
1235 ba.append_natural_32 (1)
1236 a_node.else_part.process (Current)
1237 else
1238 ba.append (Bc_inspect_excep)
1239 end
1240
1241 -- Jumps for cases compounds
1242 from
1243 i := l_nb_jump
1244 until
1245 i < 1
1246 loop
1247 ba.write_forward
1248 i := i - 1
1249 end
1250 end
1251
1252 process_instr_call_b (a_node: INSTR_CALL_B)
1253 -- Process `a_node'.
1254 do
1255 generate_melted_debugger_hook
1256 a_node.call.process (Current)
1257 end
1258
1259 process_instr_list_b (a_node: INSTR_LIST_B)
1260 -- Process `a_node'.
1261 do
1262 a_node.compound.process (Current)
1263 end
1264
1265 process_int64_val_b (a_node: INT64_VAL_B)
1266 -- Process `a_node'.
1267 do
1268 ba.append (bc_int64)
1269 ba.append_integer_64 (a_node.value)
1270 end
1271
1272 process_int_val_b (a_node: INT_VAL_B)
1273 -- Process `a_node'.
1274 do
1275 ba.append (bc_int32)
1276 ba.append_integer (a_node.value)
1277 end
1278
1279 process_integer_constant (a_node: INTEGER_CONSTANT)
1280 -- Process `a_node'.
1281 do
1282 a_node.make_byte_code (ba)
1283 end
1284
1285 process_inv_assert_b (a_node: INV_ASSERT_B)
1286 -- Process `a_node'.
1287 do
1288 make_assert_b (a_node)
1289 end
1290
1291 process_invariant_b (a_node: INVARIANT_B)
1292 -- Process `a_node'.
1293 local
1294 l_local_list: ARRAYED_LIST [TYPE_A]
1295 l_tmp_ba: BYTE_ARRAY
1296 l_context: like context
1297 do
1298 l_context := context
1299 l_local_list := l_context.local_list
1300 l_local_list.wipe_out
1301 l_context.add_locals (a_node.object_test_locals)
1302
1303 create l_tmp_ba.make
1304 l_tmp_ba.clear
1305
1306 -- Default precond- and postcondition offsets
1307 --l_tmp_ba.append_integer (0)
1308 --l_tmp_ba.append_integer (0)
1309
1310 -- This is not once routine.
1311 l_tmp_ba.append ('%U')
1312
1313 l_tmp_ba.append (Bc_start)
1314
1315 -- no Routine id
1316 l_tmp_ba.append_integer (0)
1317 -- no Real body id ( -1 because it's an invariant. We can't set a breakpoint )
1318 l_tmp_ba.append_integer (-1)
1319
1320 -- Void result type
1321 l_tmp_ba.append_natural_32 (Void_type.c_type.sk_value)
1322 -- No arguments
1323 l_tmp_ba.append_short_integer (0)
1324
1325
1326 ba.append_raw_string ("_invariant")
1327 ba.append_short_integer (context.class_type.static_type_id - 1)
1328
1329 -- No rescue
1330 ba.append ('%U')
1331 l_context.set_assertion_type ({ASSERT_TYPE}.in_invariant)
1332
1333 l_context.set_original_body_index (a_node.associated_class.invariant_feature.body_index)
1334
1335 -- Allocate memory for once manifest strings if required
1336 l_context.make_once_string_allocation_byte_code (ba, a_node.once_manifest_string_count)
1337
1338 a_node.byte_list.process (Current)
1339 ba.append (Bc_inv_null)
1340
1341 -- Generate information about types of locals.
1342 generate_local_types (l_local_list, l_tmp_ba)
1343
1344 l_context.byte_prepend (ba, l_tmp_ba)
1345
1346 -- Reset assertion type
1347 l_context.set_assertion_type (0)
1348 end
1349
1350 process_local_b (a_node: LOCAL_B)
1351 -- Process `a_node'.
1352 do
1353 ba.append (bc_local)
1354 ba.append_short_integer (a_node.position)
1355 end
1356
1357 process_loop_b (a_node: LOOP_B)
1358 -- Process `a_node'.
1359 local
1360 local_list: ARRAYED_LIST [TYPE_A]
1361 variant_local_number: INTEGER
1362 invariant_breakpoint_slot: INTEGER
1363 body_breakpoint_slot: INTEGER
1364 l_context: like context
1365 exit_count: NATURAL
1366 l_old_hidden_code_level: INTEGER
1367 do
1368 l_context := context
1369 l_old_hidden_code_level := l_context.hidden_code_level
1370 l_context.set_hidden_code_level (0)
1371
1372 if attached a_node.iteration_initialization as i then
1373 -- Generate byte code for iteration initialization.
1374 generate_melted_debugger_hook
1375 l_context.enter_hidden_code
1376 i.process (Current)
1377 l_context.exit_hidden_code
1378 end
1379 if a_node.from_part /= Void then
1380 -- Generate byte code for the from part
1381 a_node.from_part.process (Current)
1382 end
1383
1384 if a_node.variant_part /= Void then
1385 -- Initialization of the variant control variable
1386 local_list := l_context.local_list
1387 l_context.add_local (integer_32_type)
1388 variant_local_number := local_list.count
1389 ba.append (Bc_init_variant)
1390 ba.append_short_integer (variant_local_number)
1391 end
1392
1393 -- Record context.
1394 invariant_breakpoint_slot := l_context.get_breakpoint_slot
1395
1396 if not (a_node.invariant_part = Void and then a_node.variant_part = Void) then
1397 ba.append (Bc_loop)
1398 -- In case the loop assertion are not checked, we
1399 -- have to put a jump value.
1400 ba.mark_forward
1401
1402 -- Invariant loop byte code
1403 if a_node.invariant_part /= Void then
1404 l_context.set_assertion_type ({ASSERT_TYPE}.in_loop_invariant)
1405 a_node.invariant_part.process (Current)
1406 end
1407 -- Variant loop byte code
1408 if a_node.variant_part /= Void then
1409 l_context.set_assertion_type ({ASSERT_TYPE}.in_loop_variant)
1410 a_node.variant_part.process (Current)
1411 ba.append_short_integer (variant_local_number)
1412 end
1413
1414 -- Evaluation of the jump value
1415 ba.write_forward
1416 l_context.set_assertion_type (0)
1417 end
1418
1419 -- Generate byte code for exit expression
1420 ba.mark_backward
1421
1422 if attached a_node.iteration_exit_condition as e then
1423 -- Generate a test for iteration exit condition.
1424 e.process (Current)
1425 ba.append (Bc_jmp_t)
1426 -- Deferred writing of the jump relative value
1427 ba.mark_forward
1428 exit_count := 1
1429 end
1430 if attached a_node.stop as s then
1431 -- Generate breakpoint slot.
1432 generate_melted_debugger_hook
1433 -- Generate a test for loop exit condition.
1434 s.process (Current)
1435 ba.append (Bc_jmp_t)
1436 -- Deferred writing of the jump relative value
1437 ba.mark_forward
1438 exit_count := exit_count + 1
1439 end
1440
1441 if a_node.compound /= Void then
1442 a_node.compound.process (Current)
1443 end
1444 if attached a_node.advance_code as a then
1445 a.process (Current)
1446 end
1447
1448 -- Save hook context & restore recorded context.
1449 body_breakpoint_slot := l_context.get_breakpoint_slot
1450 l_context.set_breakpoint_slot (invariant_breakpoint_slot)
1451
1452 if not (a_node.invariant_part = Void and then a_node.variant_part = Void) then
1453 ba.append (Bc_loop)
1454 -- In case the loop assertion are not checked, we
1455 -- have to put a jump value.
1456 ba.mark_forward
1457
1458 -- Invariant loop byte code
1459 if a_node.invariant_part /= Void then
1460 l_context.set_assertion_type ({ASSERT_TYPE}.in_loop_invariant)
1461 a_node.invariant_part.process (Current)
1462 end
1463 -- Variant loop byte code
1464 if a_node.variant_part /= Void then
1465 l_context.set_assertion_type ({ASSERT_TYPE}.in_loop_variant)
1466 a_node.variant_part.process (Current)
1467 ba.append_short_integer (variant_local_number)
1468 end
1469
1470 -- Evaluation of the jump value
1471 ba.write_forward
1472 l_context.set_assertion_type (0)
1473 end
1474
1475 -- Restore hook context
1476 l_context.set_breakpoint_slot (body_breakpoint_slot)
1477
1478 -- Generate an unconditional jump
1479 ba.append (Bc_jmp)
1480 -- Write offset value for unconditinal jump
1481 ba.write_backward
1482
1483 -- Write jump value for the conditional exit(s).
1484 from
1485 until
1486 exit_count = 0
1487 loop
1488 ba.write_forward
1489 exit_count := exit_count - 1
1490 end
1491
1492 l_context.set_hidden_code_level (l_old_hidden_code_level)
1493 end
1494
1495 process_loop_expr_b (a_node: LOOP_EXPR_B)
1496 -- <Precursor>
1497 local
1498 local_list: ARRAYED_LIST [TYPE_A]
1499 variant_local_number: INTEGER
1500 result_local_number: INTEGER
1501 invariant_breakpoint_slot: INTEGER
1502 body_breakpoint_slot: INTEGER
1503 l_context: like context
1504 v: detachable VARIANT_B
1505 i: detachable BYTE_LIST [BYTE_NODE]
1506 exit_count: NATURAL
1507 l_old_hidden_code_level: INTEGER
1508 do
1509 l_context := context
1510 l_old_hidden_code_level := l_context.hidden_code_level
1511 l_context.set_hidden_code_level (0)
1512
1513 -- Generate loop iteration part.
1514 generate_melted_debugger_hook
1515 l_context.enter_hidden_code
1516 a_node.iteration_code.process (Current)
1517 l_context.exit_hidden_code
1518
1519 local_list := l_context.local_list
1520
1521 -- Add a local to keep the loop expression result.
1522 l_context.add_local (boolean_type)
1523 result_local_number := local_list.count
1524 ba.append (bc_bool)
1525 ba.append_boolean (a_node.is_all)
1526 ba.append (bc_lassign)
1527 ba.append_short_integer (result_local_number)
1528
1529 v := a_node.variant_code
1530 if v /= Void then
1531 -- Initialization of the variant control variable
1532 l_context.add_local (integer_32_type)
1533 variant_local_number := local_list.count
1534 ba.append (Bc_init_variant)
1535 ba.append_short_integer (variant_local_number)
1536 end
1537
1538 -- Record context.
1539 invariant_breakpoint_slot := l_context.get_breakpoint_slot
1540
1541 i := a_node.invariant_code
1542 if i /= Void or else v /= Void then
1543 ba.append (Bc_loop)
1544 -- In case the loop assertion are not checked, we
1545 -- have to put a jump value.
1546 ba.mark_forward
1547 -- Invariant loop byte code
1548 if i /= Void then
1549 l_context.set_assertion_type ({ASSERT_TYPE}.in_loop_invariant)
1550 i.process (Current)
1551 end
1552 -- Variant loop byte code
1553 if v /= Void then
1554 l_context.set_assertion_type ({ASSERT_TYPE}.in_loop_variant)
1555 v.process (Current)
1556 ba.append_short_integer (variant_local_number)
1557 end
1558 -- Evaluation of the jump value
1559 ba.write_forward
1560 l_context.set_assertion_type (0)
1561 end
1562
1563 ba.mark_backward
1564
1565 -- Generate byte code for result of loop expression.
1566 ba.append (bc_local)
1567 ba.append_short_integer (result_local_number)
1568 if a_node.is_all then
1569 ba.append (bc_jmp_f)
1570 else
1571 ba.append (bc_jmp_t)
1572 end
1573 -- Deferred writing of the jump relative value
1574 ba.mark_forward
1575
1576 -- Generate byte code for iteration exit condition.
1577 a_node.iteration_exit_condition_code.process (Current)
1578 ba.append (Bc_jmp_t)
1579 -- Deferred writing of the jump relative value.
1580 ba.mark_forward
1581 exit_count := 2 -- One exit condition is controlled by the loop expression variable.
1582
1583 if attached a_node.exit_condition_code as e then
1584 -- Generate byte code for optional exit condition.
1585 generate_melted_debugger_hook
1586 e.process (Current)
1587 ba.append (Bc_jmp_t)
1588 -- Deferred writing of the jump relative value.
1589 ba.mark_forward
1590 exit_count := 3
1591 end
1592
1593 generate_melted_debugger_hook
1594 a_node.expression_code.process (Current)
1595 ba.append (bc_lassign)
1596 ba.append_short_integer (result_local_number)
1597
1598 -- Advance the loop cursor.
1599 a_node.advance_code.process (Current)
1600
1601 -- Save hook context & restore recorded context.
1602 body_breakpoint_slot := l_context.get_breakpoint_slot
1603 l_context.set_breakpoint_slot (invariant_breakpoint_slot)
1604
1605 if i /= Void or else v /= Void then
1606 ba.append (Bc_loop)
1607 -- In case the loop assertion are not checked, we
1608 -- have to put a jump value.
1609 ba.mark_forward
1610
1611 -- Invariant loop byte code
1612 if i /= Void then
1613 l_context.set_assertion_type ({ASSERT_TYPE}.in_loop_invariant)
1614 i.process (Current)
1615 end
1616 -- Variant loop byte code
1617 if v /= Void then
1618 l_context.set_assertion_type ({ASSERT_TYPE}.in_loop_variant)
1619 v.process (Current)
1620 ba.append_short_integer (variant_local_number)
1621 end
1622
1623 -- Evaluation of the jump value
1624 ba.write_forward
1625 l_context.set_assertion_type (0)
1626 end
1627
1628 -- Restore hook context
1629 l_context.set_breakpoint_slot (body_breakpoint_slot)
1630
1631 -- Generate an unconditional jump
1632 ba.append (Bc_jmp)
1633 -- Write offset value for unconditinal jump
1634 ba.write_backward
1635
1636 -- Write jump value for the conditional exits.
1637 from
1638 until
1639 exit_count = 0
1640 loop
1641 ba.write_forward
1642 exit_count := exit_count - 1
1643 end
1644
1645 ba.append (bc_local)
1646 ba.append_short_integer (result_local_number)
1647 l_context.set_hidden_code_level (l_old_hidden_code_level)
1648 end
1649
1650 process_nat64_val_b (a_node: NAT64_VAL_B)
1651 -- Process `a_node'.
1652 do
1653 ba.append (bc_uint64)
1654 ba.append_natural_64 (a_node.value)
1655 end
1656
1657 process_nat_val_b (a_node: NAT_VAL_B)
1658 -- Process `a_node'.
1659 do
1660 ba.append (Bc_uint32)
1661 ba.append_natural_32 (a_node.value)
1662 end
1663
1664 process_nested_b (a_node: NESTED_B)
1665 -- Process `a_node'.
1666 do
1667 a_node.target.process (Current)
1668 if a_node.target.is_feature then
1669 generate_melted_debugger_hook_nested
1670 end
1671 a_node.message.process (Current)
1672 end
1673
1674 process_object_test_b (a_node: OBJECT_TEST_B)
1675 -- Process `a_node'.
1676 local
1677 l_source_type: TYPE_A
1678 l_target_type: TYPE_A
1679 l_source_class_type: CL_TYPE_A
1680 l_target_class_type: CL_TYPE_A
1681 do
1682 -- Generate expression byte code
1683 l_source_type := context.real_type (a_node.expression.type)
1684 l_target_type := context.real_type (a_node.target.type)
1685
1686 make_expression_byte_code_for_type (a_node.expression, l_target_type)
1687
1688 if l_target_type.is_none then
1689 -- Remove expression value because it is not used.
1690 ba.append (bc_pop)
1691 ba.append_uint32_integer (1)
1692 -- Types do not conform or expression is not attached.
1693 ba.append (bc_bool)
1694 ba.append_boolean (False)
1695 elseif l_target_type.is_expanded and then l_source_type.is_expanded then
1696 -- NOOP if classes are different or normal assignment otherwise.
1697 l_source_class_type ?= l_source_type
1698 l_target_class_type ?= l_target_type
1699 if
1700 l_target_class_type /= Void and then l_source_class_type /= Void and then
1701 l_target_class_type.class_id = l_source_class_type.class_id
1702 then
1703 -- Do normal assignment.
1704 if l_target_type.is_basic then
1705 ba.append (a_node.target.assign_code)
1706 else
1707 ba.append (a_node.target.expanded_assign_code)
1708 end
1709 melted_assignment_generator.generate_assignment (ba, a_node.target)
1710 -- Types conform.
1711 ba.append (bc_bool)
1712 ba.append_boolean (True)
1713 else
1714 -- Remove expression value because it is not used.
1715 ba.append (bc_pop)
1716 ba.append_uint32_integer (1)
1717 -- Types do not conform.
1718 ba.append (bc_bool)
1719 ba.append_boolean (False)
1720 end
1721 else
1722 -- Target is a reference, source is a reference, or both
1723 if not l_target_type.is_separate and then l_source_type.is_separate then
1724 -- Check if expression object belongs to the current processor.
1725 ba.append (bc_separate)
1726 -- Placeholders not used in this instruction sequence.
1727 ba.append_argument_count (0)
1728 ba.append_boolean (True)
1729 end
1730 ba.append (bc_object_test)
1731 ba.append_short_integer (context.object_test_local_position (a_node.target))
1732 -- Generate type of target
1733 a_node.info.updated_info.make_byte_code (ba)
1734 end
1735 end
1736
1737 process_object_test_local_b (a_node: OBJECT_TEST_LOCAL_B)
1738 do
1739 ba.append (bc_local)
1740 ba.append_short_integer (context.object_test_local_position (a_node))
1741 end
1742
1743 process_once_string_b (a_node: ONCE_STRING_B)
1744 -- Process `a_node'.
1745 local
1746 l_is_str32: BOOLEAN
1747 l_value: STRING
1748 l_value_32: STRING_32
1749 do
1750 l_is_str32 := a_node.is_string_32
1751 if l_is_str32 then
1752 ba.append (bc_once_string32)
1753 else
1754 ba.append (bc_once_string)
1755 end
1756 ba.append_integer (a_node.body_index - 1)
1757 ba.append_integer (a_node.number - 1)
1758 if l_is_str32 then
1759 l_value_32 := a_node.value_32
1760 -- Bytes to read.
1761 ba.append_integer (l_value_32.count * 4)
1762 ba.append_raw_string_32 (l_value_32)
1763 else
1764 l_value := a_node.value
1765 -- Bytes to read
1766 ba.append_integer (l_value.count)
1767 ba.append_raw_string (l_value)
1768 end
1769 end
1770
1771 process_operand_b (a_node: OPERAND_B)
1772 -- Process `a_node'.
1773 do
1774 -- Nothing to be done.
1775 end
1776
1777 process_parameter_b (a_node: PARAMETER_B)
1778 -- Process `a_node'.
1779 local
1780 l_target_type, l_source_type: TYPE_A
1781 do
1782 l_target_type := context.real_type (a_node.attachment_type)
1783 l_source_type := context.real_type (a_node.expression.type)
1784 make_expression_byte_code_for_type (a_node.expression, l_target_type)
1785 if l_target_type.is_expanded and then l_source_type.is_none then
1786 ba.append (Bc_exp_excep)
1787 end
1788 end
1789
1790 process_paran_b (a_node: PARAN_B)
1791 -- Process `a_node'.
1792 do
1793 a_node.expr.process (Current)
1794 end
1795
1796 process_real_const_b (a_node: REAL_CONST_B)
1797 -- Process `a_node'.
1798 do
1799 if a_node.real_size = 64 then
1800 ba.append (bc_real64)
1801 else
1802 ba.append (bc_real32)
1803 end
1804 ba.append_double (a_node.value.to_double)
1805 end
1806
1807 process_require_b (a_node: REQUIRE_B)
1808 do
1809 make_assert_b (a_node)
1810 end
1811
1812 process_result_b (a_node: RESULT_B)
1813 -- Process `a_node'.
1814 do
1815 ba.append (bc_result)
1816 end
1817
1818 process_retry_b (a_node: RETRY_B)
1819 -- Process `a_node'.
1820 do
1821 generate_melted_debugger_hook
1822 ba.append (bc_retry)
1823 ba.write_retry
1824 end
1825
1826 process_reverse_b (a_node: REVERSE_B)
1827 -- Process `a_node'.
1828 local
1829 l_source_type: TYPE_A
1830 l_target_type: TYPE_A
1831 l_source_class_type: CL_TYPE_A
1832 l_target_class_type: CL_TYPE_A
1833 do
1834 generate_melted_debugger_hook
1835
1836 -- Generate expression byte code
1837 l_source_type := context.real_type (a_node.source.type)
1838 l_target_type := context.real_type (a_node.target.type)
1839
1840 make_expression_byte_code_for_type (a_node.source, l_target_type)
1841
1842 if l_target_type.is_none then
1843 ba.append (Bc_none_assign)
1844 elseif l_target_type.is_expanded and then l_source_type.is_expanded then
1845 -- NOOP if classes are different or normal assignment otherwise.
1846 l_source_class_type ?= l_source_type
1847 l_target_class_type ?= l_target_type
1848 if
1849 l_target_class_type /= Void and then l_source_class_type /= Void and then
1850 l_target_class_type.class_id = l_source_class_type.class_id
1851 then
1852 -- Do normal assignment.
1853 if l_target_type.is_basic then
1854 ba.append (a_node.target.assign_code)
1855 else
1856 ba.append (a_node.target.expanded_assign_code)
1857 end
1858 melted_assignment_generator.generate_assignment (ba, a_node.target)
1859 else
1860 -- Remove expression value because it is not used.
1861 ba.append (bc_pop)
1862 ba.append_uint32_integer (1)
1863 end
1864 else
1865 -- Target is a reference
1866 ba.append (a_node.target.reverse_code)
1867 melted_assignment_generator.generate_assignment (ba, a_node.target)
1868 -- Generate type of target
1869 a_node.info.updated_info.make_byte_code (ba)
1870 end
1871 end
1872
1873 process_routine_creation_b (a_node: ROUTINE_CREATION_B)
1874 -- Process `a_node'.
1875 local
1876 l_type: TYPE_A
1877 do
1878 -- Closed operands
1879 if a_node.arguments /= Void then
1880 a_node.arguments.process (Current)
1881 end
1882
1883 -- Open map
1884 if a_node.open_positions /= Void then
1885 a_node.open_positions.process (Current)
1886 end
1887
1888 -- Now create routine object
1889 ba.append (Bc_rcreate)
1890
1891 -- Do we have arguments (a TUPLE) on the stack?
1892 ba.append_boolean (a_node.arguments /= Void)
1893
1894 -- Generate byte code for `a_node.type'.
1895 l_type := context.real_type (a_node.type)
1896 l_type.make_full_type_byte_code (ba, context.context_class_type.type)
1897
1898 -- Routine ID of the routine
1899 ba.append_integer_32 (a_node.rout_id)
1900 -- is_basic
1901 ba.append_boolean (a_node.is_basic)
1902 -- is_target_closed
1903 ba.append_boolean (a_node.is_target_closed)
1904 -- is_inline_agent
1905 if a_node.is_inline_agent then
1906 ba.append_integer_32 (a_node.class_type.static_type_id (context.current_type) - 1)
1907 else
1908 ba.append_integer_32 (-1)
1909 end
1910 -- open_count
1911 if a_node.omap /= Void then
1912 ba.append_integer (a_node.omap.count)
1913 else
1914 ba.append_integer (0)
1915 end
1916 end
1917
1918 process_string_b (a_node: STRING_B)
1919 -- Process `a_node'.
1920 local
1921 l_value: STRING_8
1922 l_value_32: STRING_32
1923 do
1924 if a_node.is_string_32 then
1925 l_value_32 := a_node.value_32
1926 ba.append (Bc_string32)
1927 -- Bytes to read
1928 ba.append_integer (l_value_32.count * 4)
1929 ba.append_raw_string_32 (l_value_32)
1930 else
1931 l_value := a_node.value_8
1932 ba.append (Bc_string)
1933 -- Bytes to read
1934 ba.append_integer (l_value.count)
1935 ba.append_raw_string (l_value)
1936 end
1937 end
1938
1939 process_strip_b (a_node: STRIP_B)
1940 -- Process `a_node'.
1941 local
1942 l_attr_names: LINKED_LIST [STRING]
1943 do
1944 l_attr_names := a_node.attribute_names
1945 from
1946 l_attr_names.start
1947 until
1948 l_attr_names.after
1949 loop
1950 ba.append (Bc_add_strip)
1951 ba.append_raw_string (l_attr_names.item)
1952 l_attr_names.forth
1953 end
1954 ba.append (Bc_end_strip)
1955 ba.append_short_integer (context.class_type.type_id - 1)
1956 ba.append_integer (l_attr_names.count)
1957 end
1958
1959 process_tuple_access_b (a_node: TUPLE_ACCESS_B)
1960 -- Process `a_node'.
1961 local
1962 l_tuple_type: TYPE_A
1963 do
1964 l_tuple_type := context.real_type (a_node.tuple_element_type)
1965 -- It is guaranteed that the TUPLE object is on the stack because
1966 -- TUPLE_ACCESS_B is always the message of a NESTED_B node.
1967 if a_node.source /= Void then
1968 -- Assignment to a tuple entry.
1969 generate_melted_debugger_hook
1970 a_node.source.process (Current)
1971 if a_node.source.is_hector then
1972 if attached {HECTOR_B} a_node.source.expression as l_hector_b then
1973 make_protected_byte_code (l_hector_b, 0)
1974 else
1975 -- Address expressions are disallowed.
1976 check False end
1977 end
1978 end
1979 if l_tuple_type.c_type.is_reference then
1980 context.make_tuple_catcall_check (ba, a_node.position)
1981 end
1982 ba.append (bc_tuple_assign)
1983 else
1984 -- Access to tuple entry.
1985 ba.append (bc_tuple_access)
1986 end
1987 ba.append_integer_32 (a_node.position)
1988 ba.append_natural_32 (l_tuple_type.sk_value (context.context_class_type.type))
1989 end
1990
1991 process_tuple_const_b (a_node: TUPLE_CONST_B)
1992 -- Process `a_node'.
1993 local
1994 l_real_ty: TUPLE_TYPE_A
1995 l_expr: EXPR_B
1996 do
1997 l_real_ty ?= context.real_type (a_node.type)
1998 -- Need to insert expression into
1999 -- the stack back to front in order
2000 -- to be inserted into the area correctly
2001 from
2002 a_node.expressions.finish
2003 until
2004 a_node.expressions.before
2005 loop
2006 l_expr ?= a_node.expressions.item
2007 check l_expr_not_void: l_expr /= Void end
2008 l_expr.process (Current)
2009 if l_expr.is_hector then
2010 if attached {HECTOR_B} l_expr as l_hector_b then
2011 make_protected_byte_code (l_hector_b, 0)
2012 else
2013 -- Address expressions are disallowed for tuple
2014 -- initialization.
2015 check False end
2016 end
2017 end
2018 a_node.expressions.back
2019 end
2020 ba.append (Bc_tuple)
2021 l_real_ty.make_type_byte_code (ba, True, context.context_class_type.type)
2022 ba.append_short_integer (-1)
2023 ba.append_integer (a_node.expressions.count + 1)
2024 if l_real_ty.is_basic_uniform then
2025 ba.append_integer (1)
2026 else
2027 ba.append_integer (0)
2028 end
2029 end
2030
2031
2032 process_type_expr_b (a_node: TYPE_EXPR_B)
2033 -- Process `a_node'.
2034 local
2035 l_type_creator: CREATE_INFO
2036 l_type_type: TYPE_A
2037 do
2038 ba.append (Bc_create_type)
2039 -- There is no feature call:
2040 ba.append_boolean (False)
2041
2042 l_type_type := context.descendant_type (a_node.type_type)
2043 l_type_creator := l_type_type.create_info
2044 l_type_creator.make_byte_code (ba)
2045
2046 -- Because `l_type_creator' discards the attachment mark if any, we need
2047 -- to take it into account to create the proper type.
2048 -- First boolean is to figure out if there is an action to be taken, the
2049 -- second which action.
2050 if l_type_type.is_attached then
2051 ba.append_boolean (True)
2052 ba.append_boolean (True)
2053 elseif l_type_type.has_detachable_mark then
2054 ba.append_boolean (True)
2055 ba.append_boolean (False)
2056 else
2057 ba.append_boolean (False)
2058 end
2059 end
2060
2061 process_typed_interval_b (a_node: TYPED_INTERVAL_B [INTERVAL_VAL_B])
2062 -- Process `a_node'.
2063 do
2064 -- Nothing to be done.
2065 end
2066
2067 process_un_free_b (a_node: UN_FREE_B)
2068 -- Process `a_node'.
2069 do
2070 a_node.nested_b.process (Current)
2071 end
2072
2073 process_un_minus_b (a_node: UN_MINUS_B)
2074 -- Process `a_node'.
2075 do
2076 make_unary_b (a_node, bc_uminus)
2077 end
2078
2079 process_un_not_b (a_node: UN_NOT_B)
2080 -- Process `a_node'.
2081 do
2082 make_unary_b (a_node, bc_not)
2083 end
2084
2085 process_un_old_b (a_node: UN_OLD_B)
2086 -- Process `a_node'.
2087 do
2088 ba.append (Bc_retrieve_old)
2089 ba.append_short_integer (a_node.position)
2090 ba.append_short_integer (a_node.exception_position)
2091 end
2092
2093 process_un_plus_b (a_node: UN_PLUS_B)
2094 -- Process `a_node'.
2095 do
2096 make_unary_b (a_node, bc_uplus)
2097 end
2098
2099 process_variant_b (a_node: VARIANT_B)
2100 -- Process `a_node'.
2101 do
2102 make_assert_b (a_node)
2103 end
2104
2105 process_void_b (a_node: VOID_B)
2106 -- Process `a_node'.
2107 do
2108 ba.append (bc_void)
2109 end
2110
2111 feature {NONE} -- Implementation
2112
2113 make_expression_byte_code_for_type (an_expr: EXPR_B; a_target_type: TYPE_A)
2114 -- Generate byte code for the expression which is about
2115 -- to be assigned or compared to the type `a_target_type'.
2116 require
2117 expr_not_void: an_expr /= Void
2118 target_type_not_void: a_target_type /= Void
2119 local
2120 l_expression_type: TYPE_A
2121 do
2122 an_expr.process (Current)
2123 l_expression_type := context.real_type (an_expr.type)
2124
2125 if a_target_type.is_reference then
2126 if l_expression_type.is_basic then
2127 -- Source is basic and target is a reference:
2128 -- metamorphose
2129 ba.append (Bc_metamorphose)
2130 elseif l_expression_type.is_expanded then
2131 -- Source is expanded and target is a reference:
2132 -- clone
2133 ba.append (Bc_clone)
2134 else
2135 -- Source can be a boxed expanded object.
2136 generate_dynamic_clone (an_expr, l_expression_type)
2137 end
2138 elseif l_expression_type.is_none then
2139 -- Reattachment of void to expanded.
2140 ba.append (Bc_exp_excep)
2141 elseif not a_target_type.is_basic then
2142 if l_expression_type.is_true_expanded then
2143 -- Source and target are expanded:
2144 -- clone
2145 ba.append (Bc_clone)
2146 elseif not l_expression_type.is_basic then
2147 -- Source can be a boxed expanded object.
2148 generate_dynamic_clone (an_expr, l_expression_type)
2149 end
2150 end
2151 end
2152
2153 generate_dynamic_clone (expression: EXPR_B; type: TYPE_A)
2154 -- Generate code that clones result of an `expression' depending on
2155 -- dynamic type of object of static type `type'.
2156 require
2157 expression_not_void: expression /= Void
2158 type_not_void: type /= Void
2159 type_is_reference: type.is_reference
2160 do
2161 if expression.is_dynamic_clone_required (type) then
2162 ba.append (bc_cclone)
2163 end
2164 end
2165
2166 make_assert_b (a_node: ASSERT_B)
2167 -- Generate code for `ASSERT_B' node.
2168 require
2169 a_node_not_void: a_node /= Void
2170 do
2171 -- Assertion mark
2172 if context.assertion_type = {ASSERT_TYPE}.in_precondition then
2173 make_precondition_byte_code (a_node)
2174 else
2175 if context.assertion_type /= {ASSERT_TYPE}.in_invariant then
2176 -- No hooks when it is an invariant
2177 generate_melted_debugger_hook
2178 end
2179 ba.append (Bc_assert)
2180 inspect
2181 context.assertion_type
2182 when {ASSERT_TYPE}.in_postcondition then
2183 ba.append (Bc_pst)
2184 when {ASSERT_TYPE}.in_check then
2185 ba.append (Bc_chk)
2186 when {ASSERT_TYPE}.in_guard then
2187 ba.append (Bc_guard)
2188 when {ASSERT_TYPE}.in_loop_invariant then
2189 ba.append (Bc_linv)
2190 when {ASSERT_TYPE}.in_loop_variant then
2191 ba.append (Bc_lvar)
2192 when {ASSERT_TYPE}.in_invariant then
2193 ba.append (Bc_inv)
2194 end
2195
2196 -- Generate the tag name if any.
2197 if a_node.tag = Void then
2198 ba.append (Bc_notag)
2199 else
2200 ba.append (Bc_tag)
2201 ba.append_raw_string (a_node.tag)
2202 end
2203
2204 -- Assertion byte code
2205 a_node.expr.process (Current)
2206
2207 -- End assertion mark
2208 if context.assertion_type = {ASSERT_TYPE}.in_loop_variant then
2209 ba.append (bc_end_variant)
2210 else
2211 -- For guards, we do not want the `in_assertion' to be affected,
2212 -- so we generate an extra boolean computation to let the interpreter
2213 -- do the right thing.
2214 ba.append (bc_end_assert)
2215 ba.append_boolean (context.assertion_type /= {ASSERT_TYPE}.in_guard)
2216 end
2217 end
2218 end
2219
2220 make_precondition_byte_code (a_node: ASSERT_B)
2221 -- Generate byte code for a precondition.
2222 local
2223 l_context: like context
2224 l_ba: like ba
2225 s: TRAVERSABLE_SUBSET [INTEGER_32]
2226 do
2227 l_context := context
2228 l_ba := ba
2229 if l_context.is_new_precondition_block then
2230 l_context.set_new_precondition_block (False)
2231 if l_context.is_first_precondition_block_generated then
2232 from
2233 until
2234 l_ba.forward_marks4.count = 0
2235 loop
2236 l_ba.write_forward4
2237 end
2238 l_ba.append (Bc_goto_body)
2239 ba.mark_forward
2240 else
2241 l_context.set_first_precondition_block_generated (True)
2242 end
2243 end
2244
2245 -- generate a debugger hook
2246 generate_melted_debugger_hook
2247
2248 l_ba.append (Bc_assert)
2249 l_ba.append (Bc_pre)
2250 if a_node.tag = Void then
2251 l_ba.append (Bc_notag)
2252 else
2253 l_ba.append (Bc_tag)
2254 l_ba.append_raw_string (a_node.tag)
2255 end
2256 -- It's possible that there is a wait condition.
2257 -- Whether this is true or not is detected at run-time
2258 -- by inspecting if the argument used in the precondition
2259 -- as a separate target is controlled or not.
2260 separate_target_collector.clean
2261 a_node.expr.process (separate_target_collector)
2262 if separate_target_collector.has_separate_target then
2263 -- Enumerate all separate arguments used as a target of a call.
2264 s := separate_target_collector.target
2265 from
2266 s.start
2267 until
2268 s.after
2269 loop
2270 l_ba.append (bc_wait_arg)
2271 l_ba.append_short_integer (s.item)
2272 s.forth
2273 end
2274 end
2275 -- Assertion byte code
2276 a_node.expr.process (Current)
2277 l_ba.append (Bc_end_pre)
2278 l_ba.mark_forward4
2279 end
2280
2281 make_protected_byte_code (a_node: HECTOR_B; a_pos: INTEGER)
2282 -- Generate byte code for an unprotected external call argument
2283 require
2284 a_node_not_void: a_node /= Void
2285 local
2286 l_type: TYPE_A
2287 do
2288 l_type := context.real_type (a_node.expr.type)
2289 if l_type.is_basic then
2290 ba.append (Bc_object_addr)
2291 ba.append_uint32_integer (a_pos)
2292 a_node.expr.process (Current)
2293 end
2294 end
2295
2296 make_binary_b (a_node: BINARY_B; a_node_opcode: CHARACTER)
2297 -- Generate code for `a_node'
2298 require
2299 a_node_not_void: a_node /= Void
2300 do
2301 if a_node.is_built_in then
2302 a_node.left.process (Current)
2303 a_node.right.process (Current)
2304 -- Write binary operator.
2305 ba.append (a_node_opcode)
2306 else
2307 a_node.nested_b.process (Current)
2308 end
2309 end
2310
2311 make_binary_equal_b (a_node: BIN_EQUAL_B; a_node_opcode, a_node_obvious_opcode: CHARACTER)
2312 -- Generate code for `a_node'
2313 require
2314 a_node_not_void: a_node /= Void
2315 a_node_opcode_valid: a_node_opcode = bc_eq or a_node_opcode = bc_ne
2316 a_node_obvious_opcode_valid: a_node_obvious_opcode = bc_true_compar or
2317 a_node_obvious_opcode = bc_false_compar
2318 local
2319 l_lt, l_rt: TYPE_A
2320 l_flag: BOOLEAN
2321 do
2322 l_lt := context.real_type (a_node.left.type)
2323 l_rt := context.real_type (a_node.right.type)
2324
2325 a_node.left.process (Current)
2326 if (l_lt.is_basic and then l_rt.is_reference) then
2327 ba.append (Bc_metamorphose)
2328 l_flag := True
2329 end
2330
2331 a_node.right.process (Current)
2332 if (l_lt.is_reference and then l_rt.is_basic) then
2333 ba.append (Bc_metamorphose)
2334 l_flag := True
2335 end
2336
2337 if l_lt.is_true_expanded or else l_rt.is_true_expanded or else l_flag then
2338 -- Standard equality
2339 ba.append (bc_standard_equal)
2340 if a_node_opcode = bc_ne then
2341 ba.append (bc_not)
2342 end
2343 elseif (l_lt.is_basic and then l_rt.is_none) or else (l_lt.is_none and then l_rt.is_basic) then
2344 -- A basic type is neither Void
2345 ba.append (a_node_obvious_opcode)
2346 elseif
2347 l_lt.is_reference and then
2348 l_rt.is_reference and then
2349 a_node.left.is_dynamic_clone_required (l_lt) and then
2350 a_node.right.is_dynamic_clone_required (l_rt)
2351 then
2352 -- Reference type equality.
2353 -- Check if one of the operands is of expanded type
2354 -- and use object comparison. Use reference comparison
2355 -- otherwise.
2356 ba.append (Bc_cequal)
2357 if a_node_opcode = bc_ne then
2358 ba.append (bc_not)
2359 end
2360 else
2361 -- Pure reference or basic type equality.
2362 ba.append (a_node_opcode)
2363 end
2364 end
2365
2366 make_unary_b (a_node: UNARY_B; a_node_opcode: CHARACTER)
2367 -- Generate code for unary operator
2368 require
2369 a_node_not_void: a_node /= Void
2370 do
2371 if a_node.is_built_in then
2372 a_node.expr.process (Current)
2373 -- Write unary operator
2374 ba.append (a_node_opcode)
2375 else
2376 a_node.nested_b.process (Current)
2377 end
2378 end
2379
2380 make_case_range (a_node: CASE_B)
2381 -- Generate range byte code
2382 require
2383 a_node_not_void: a_node /= Void
2384 local
2385 i: INTEGER
2386 l_inter: INTERVAL_B
2387 do
2388 from
2389 i := a_node.interval.count
2390 until
2391 i < 1
2392 loop
2393 l_inter := a_node.interval.i_th (i)
2394 l_inter.lower.process (Current)
2395 l_inter.upper.process (Current)
2396 ba.append (bc_range)
2397 ba.mark_forward2
2398 i := i - 1
2399 end
2400 end
2401
2402 make_call_access_b (a_node: CALL_ACCESS_B; code_first, code_next: CHARACTER; is_creation: BOOLEAN)
2403 -- Generate call to EXTERNAL_B/FEATURE_B.
2404 -- Generate byte code for a feature call.
2405 -- `is_creation' indicates if this is a call to a creation procedure.
2406 -- if `meta', metamorphose the feature call.
2407 -- Doesn't process the parameters
2408 require
2409 a_node_not_void: a_node /= Void
2410 local
2411 l_basic_type: BASIC_A
2412 l_inst_cont_type: TYPE_A
2413 l_finish_byte_code: BOOLEAN
2414 do
2415 l_inst_cont_type := a_node.context_type
2416 if l_inst_cont_type.is_separate then
2417 -- The call may be separate.
2418 ba.append (bc_separate)
2419 -- Arguments need to be passed together with feature information.
2420 if attached a_node.parameters as p then
2421 ba.append_argument_count (p.count)
2422 else
2423 ba.append_argument_count (0)
2424 end
2425 -- Indicate if this is a query or procedure call:
2426 -- True is used for a query, False - for a procedure.
2427 ba.append_boolean (not a_node.type.is_void)
2428 end
2429 -- Note: Manu 08/08/2002: if `a_node.precursor_type' is not Void, it can only means
2430 -- that we are currently performing a static access call on a feature
2431 -- from a basic class. Assuming otherwise is not correct as you
2432 -- cannot seriously inherit from a basic class.
2433 if l_inst_cont_type.is_basic and a_node.precursor_type = Void then
2434 l_basic_type ?= l_inst_cont_type
2435 if a_node.is_feature_special (False, l_basic_type) then
2436 a_node.make_special_byte_code (ba, l_basic_type)
2437 else
2438 -- Process the call via the `feature_name' in the
2439 -- associated reference type
2440 if a_node.parameters /= Void then
2441 ba.append (Bc_rotate)
2442 ba.append_short_integer (a_node.parameters.count + 1)
2443 end
2444 ba.append (Bc_metamorphose)
2445 l_finish_byte_code := True
2446 end
2447 else
2448 if a_node.is_first then
2449 --! Cannot melt basic calls hence is_first
2450 --! is not used in the above if meta statement.
2451 ba.append (Bc_current)
2452 else
2453 if a_node.parameters /= Void then
2454 ba.append (Bc_rotate)
2455 ba.append_short_integer (a_node.parameters.count + 1)
2456 end
2457 end
2458 l_finish_byte_code := True
2459 end
2460 if l_finish_byte_code then
2461 if is_creation then
2462 ba.append (bc_creation)
2463 elseif a_node.is_first then
2464 ba.append (code_first)
2465 else
2466 ba.append (code_next)
2467 ba.append_raw_string (a_node.feature_name)
2468 end
2469 ba.append_integer (a_node.routine_id)
2470 make_precursor_byte_code (a_node)
2471 end
2472 end
2473
2474 make_precursor_byte_code (a_node: CALL_ACCESS_B)
2475 -- Generate precursor byte code if needed.
2476 local
2477 l_type: TYPE_A
2478 do
2479 if a_node.precursor_type /= Void then
2480 l_type := context.real_type (a_node.precursor_type)
2481 if l_type.is_multi_constrained then
2482 check
2483 has_multi_constraint_static: a_node.has_multi_constraint_static
2484 end
2485 l_type := context.real_type (a_node.multi_constraint_static)
2486 end
2487 ba.append_short_integer (l_type.static_type_id (context.context_class_type.type) - 1)
2488 else
2489 ba.append_short_integer (-1)
2490 end
2491 end
2492
2493 generate_melted_debugger_hook
2494 -- Record breakable point (standard)
2495 local
2496 lnr: INTEGER
2497 ctx: like context
2498 do
2499 ctx := context
2500 if not ctx.is_inside_hidden_code then
2501 if attached ctx.current_feature as cf and then cf.supports_step_in then
2502 lnr := ctx.get_next_breakpoint_slot
2503 check
2504 valid_line: lnr > 0
2505 end
2506 ba.generate_melted_debugger_hook (lnr)
2507 end
2508 end
2509 end
2510
2511 generate_melted_debugger_hook_nested
2512 -- Record breakable point for nested call
2513 local
2514 l_line, l_nested: INTEGER
2515 ctx: like context
2516 do
2517 ctx := context
2518 if not ctx.is_inside_hidden_code then
2519 if attached ctx.current_feature as cf and then cf.supports_step_in then
2520 l_line := ctx.get_breakpoint_slot
2521 if l_line > 0 then
2522 -- Generate a hook when there is really need for one.
2523 -- (E.g. we do not need a hook for the code generation
2524 -- of an invariant).
2525 l_nested := ctx.get_next_breakpoint_nested_slot
2526 ba.generate_melted_debugger_hook_nested (l_line, l_nested)
2527 end
2528 end
2529 end
2530 end
2531
2532 feature -- Type information
2533
2534 generate_local_types (l: ARRAYED_LIST [TYPE_A]; b: BYTE_ARRAY)
2535 -- Generate types of locals `l' into byte array `b'.
2536 require
2537 l_attached: attached l
2538 b_attached: attached b
2539 do
2540 b.append_short_integer (l.count)
2541 l.do_all (agent generate_local_type (?, b))
2542 end
2543
2544 generate_local_type (t: TYPE_A; b: BYTE_ARRAY)
2545 -- Generate type information for a local of type `t' into byte array `b'.
2546 local
2547 r: TYPE_A
2548 do
2549 r := context.real_type (t)
2550 b.append_natural_32 (r.sk_value (context.context_class_type.type))
2551 if r.is_true_expanded then
2552 -- Generate full type info.
2553 t.make_full_type_byte_code (b, context.context_class_type.type)
2554 end
2555 end
2556
2557 feature {NONE} -- SCOOP
2558
2559 separate_target_collector: SEPARATE_TARGET_COLLECTOR
2560 -- Visitor to detect wait conditions.
2561 once
2562 create Result
2563 end
2564
2565 note
2566 copyright: "Copyright (c) 1984-2014, Eiffel Software"
2567 license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
2568 licensing_options: "http://www.eiffel.com/licensing"
2569 copying: "[
2570 This file is part of Eiffel Software's Eiffel Development Environment.
2571
2572 Eiffel Software's Eiffel Development Environment is free
2573 software; you can redistribute it and/or modify it under
2574 the terms of the GNU General Public License as published
2575 by the Free Software Foundation, version 2 of the License
2576 (available at the URL listed under "license" above).
2577
2578 Eiffel Software's Eiffel Development Environment is
2579 distributed in the hope that it will be useful, but
2580 WITHOUT ANY WARRANTY; without even the implied warranty
2581 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
2582 See the GNU General Public License for more details.
2583
2584 You should have received a copy of the GNU General Public
2585 License along with Eiffel Software's Eiffel Development
2586 Environment; if not, write to the Free Software Foundation,
2587 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2588 ]"
2589 source: "[
2590 Eiffel Software
2591 5949 Hollister Ave., Goleta, CA 93117 USA
2592 Telephone 805-685-1006, Fax 805-685-6869
2593 Website http://www.eiffel.com
2594 Customer support http://support.eiffel.com
2595 ]"
2596
2597 end

Properties

Name Value
svn:eol-style native
svn:keywords Author Date ID Revision

  ViewVC Help
Powered by ViewVC 1.1.23