/src/tools/compiler/asm/marshall/liberty_asm_writer.e

http://github.com/tybor/Liberty · Specman e · 214 lines · 173 code · 27 blank · 14 comment · 5 complexity · ffcb8d63883521e21c9ff78a2be2fa00 MD5 · raw file

  1. -- This file is part of Liberty Eiffel.
  2. --
  3. -- Liberty Eiffel is free software: you can redistribute it and/or modify
  4. -- it under the terms of the GNU General Public License as published by
  5. -- the Free Software Foundation, version 3 of the License.
  6. --
  7. -- Liberty Eiffel is distributed in the hope that it will be useful,
  8. -- but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. -- GNU General Public License for more details.
  11. --
  12. -- You should have received a copy of the GNU General Public License
  13. -- along with Liberty Eiffel. If not, see <http://www.gnu.org/licenses/>.
  14. --
  15. class LIBERTY_ASM_WRITER
  16. inherit
  17. LIBERTY_ASM_INSTRUCTION_VISITOR
  18. insert
  19. LIBERTY_ASM_CODES
  20. create {LIBERTY_ASM_MARSHALLER}
  21. write
  22. feature {}
  23. write (a_stream: OUTPUT_STREAM; a_system: LIBERTY_ASM_SYSTEM) is
  24. require
  25. a_stream /= Void
  26. a_system /= Void
  27. do
  28. positions.set_positions(a_system.types)
  29. stream := a_stream
  30. put_data(system_marker)
  31. put_data(a_system.main.id)
  32. put_data(a_system.main.type.id)
  33. a_system.types.do_all(agent visit_type)
  34. end
  35. stream: OUTPUT_STREAM
  36. put_string (string: ABSTRACT_STRING) is
  37. require
  38. string /= Void
  39. do
  40. put_data(string.count)
  41. string.do_all(agent (c: CHARACTER) is
  42. do
  43. put_code(c.to_integer_8)
  44. end
  45. )
  46. end
  47. put_native (native: LIBERTY_ASM_NATIVE_VALUE) is
  48. do
  49. if native = Void then
  50. put_code(native_void)
  51. elseif native.is_integer then
  52. put_code(native_integer)
  53. elseif native.is_pointer then
  54. put_code(native_pointer)
  55. else
  56. check False end
  57. end
  58. end
  59. put_code (code: INTEGER_8) is
  60. do
  61. stream.put_character(code.to_character)
  62. end
  63. put_data (int: INTEGER) is
  64. do
  65. stream.put_character(( int & 0xff).to_character)
  66. stream.put_character(((int |>> 8) & 0xff).to_character)
  67. stream.put_character(((int |>> 16) & 0xff).to_character)
  68. stream.put_character(((int |>> 24) & 0xff).to_character)
  69. end
  70. visit_type (a_type: LIBERTY_ASM_TYPE) is
  71. require
  72. a_type /= Void
  73. do
  74. put_data(type_marker)
  75. put_data(a_type.id)
  76. put_data(a_type.attributes_count)
  77. put_data(a_type.methods_count)
  78. a_type.do_all_methods(agent visit_method)
  79. end
  80. visit_method (a_method: LIBERTY_ASM_METHOD) is
  81. local
  82. flags: INTEGER_8
  83. do
  84. put_data(method_marker)
  85. put_data(a_method.id)
  86. put_data(a_method.parameters.count)
  87. if a_method.retry_code /= Void then
  88. flags := flags | flag_retry
  89. end
  90. if a_method.precondition /= Void then
  91. flags := flags | flag_precondition
  92. end
  93. if a_method.postcondition /= Void then
  94. flags := flags | flag_postcondition
  95. end
  96. put_code(flags)
  97. visit_code(a_method.code, a_method.code_size)
  98. visit_code(a_method.retry_code, a_method.retry_size)
  99. visit_code(a_method.precondition, a_method.precondition_size)
  100. visit_code(a_method.postcondition, a_method.postcondition_size)
  101. end
  102. visit_code (a_instruction: LIBERTY_ASM_INSTRUCTION; size: INTEGER) is
  103. require
  104. size > 0 implies a_instruction /= Void
  105. size >= 0
  106. local
  107. code: LIBERTY_ASM_INSTRUCTION
  108. do
  109. if size > 0 then
  110. put_data(size)
  111. from
  112. code := a_instruction
  113. until
  114. code = Void
  115. loop
  116. code.accept(Current)
  117. code := code.next
  118. end
  119. end
  120. end
  121. feature {LIBERTY_ASM_INSTRUCTION}
  122. visit_and (a_instruction: LIBERTY_ASM_AND) is
  123. do
  124. put_code(asm_and)
  125. end
  126. visit_invoke (a_instruction: LIBERTY_ASM_INVOKE) is
  127. do
  128. put_code(asm_invoke)
  129. put_data(a_instruction.method.type.id)
  130. put_data(a_instruction.method.id)
  131. end
  132. visit_jump (a_instruction: LIBERTY_ASM_JUMP) is
  133. do
  134. put_code(asm_jump)
  135. put_data(a_instruction.target.position)
  136. end
  137. visit_new (a_instruction: LIBERTY_ASM_NEW) is
  138. do
  139. put_code(asm_new)
  140. put_data(a_instruction.type.id)
  141. end
  142. visit_not (a_instruction: LIBERTY_ASM_NOT) is
  143. do
  144. put_code(asm_not)
  145. end
  146. visit_or (a_instruction: LIBERTY_ASM_OR) is
  147. do
  148. put_code(asm_or)
  149. end
  150. visit_return (a_instruction: LIBERTY_ASM_RETURN) is
  151. do
  152. put_code(asm_return)
  153. end
  154. visit_load_int (a_instruction: LIBERTY_ASM_LOAD_INT) is
  155. do
  156. put_code(asm_load_int)
  157. put_data(a_instruction.value)
  158. end
  159. visit_add_int (a_instruction: LIBERTY_ASM_ADD_INT) is
  160. do
  161. put_code(asm_add_int)
  162. end
  163. visit_sub_int (a_instruction: LIBERTY_ASM_SUB_INT) is
  164. do
  165. put_code(asm_sub_int)
  166. end
  167. visit_mul_int (a_instruction: LIBERTY_ASM_MUL_INT) is
  168. do
  169. put_code(asm_mul_int)
  170. end
  171. visit_div_int (a_instruction: LIBERTY_ASM_DIV_INT) is
  172. do
  173. put_code(asm_div_int)
  174. end
  175. visit_rem_int (a_instruction: LIBERTY_ASM_REM_INT) is
  176. do
  177. put_code(asm_rem_int)
  178. end
  179. visit_call_native (a_instruction: LIBERTY_ASM_CALL_NATIVE) is
  180. do
  181. put_code(asm_call_native)
  182. put_string(a_instruction.symbol)
  183. put_native(a_instruction.return)
  184. put_data(a_instruction.arguments.count)
  185. a_instruction.arguments.do_all(agent put_native)
  186. end
  187. end -- class LIBERTY_ASM_WRITER