• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env ruby
2# Copyright (c) 2023 Huawei Device Co., Ltd.
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15require 'yaml'
16
17def llvm_type_getter(type, gc_space)
18  @llvm_type_map ||= {
19    'void' => 'Void',
20    'bool' => 'Int8',
21    'int8_t' => 'Int8',
22    'uint8_t' => 'Int8',
23    'int16_t' => 'Int16',
24    'uint16_t' => 'Int16',
25    'int32_t' => 'Int32',
26    'uint32_t' => 'Int32',
27    'int64_t' => 'Int64',
28    'uint64_t' => 'Int64',
29    'float' => 'Float',
30    'double' => 'Double',
31    'panda::FileEntityId' => 'Int32',
32  }
33  if ['size_t', 'ssize_t', 'uintptr_t', 'size_t pid'].include? type
34    # Predefined variable. Type of 'size_t' is implementation defined
35    return 'size_type'
36  elsif @llvm_type_map.key? type
37    return 'llvm::Type::get' + @llvm_type_map[type] + 'Ty(ctx)'
38  elsif type.include?('ObjectHeader**')
39    return 'llvm::PointerType::get(ctx, 0)'
40  elsif type.include?('*') && type.include?('coretypes') || type.include?('ObjectHeader*')
41    return 'llvm::PointerType::get(ctx, ' + gc_space + ')'
42  elsif type.include? '*'
43    return 'llvm::PointerType::get(ctx, 0)'
44  else
45    raise "Unexpected type required to lower into LLVM IR: #{type}"
46  end
47end
48
49class String
50  def snakecase
51    self.gsub(/::/, '/').
52    gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
53    gsub(/([a-z\d])([A-Z])/,'\1_\2').
54    tr("-", "_").
55    downcase
56  end
57end
58
59class Entrypoint
60  def initialize(dscr)
61    @dscr = dscr
62  end
63
64  def name
65    @dscr['name']
66  end
67
68  def llvm_internal_name
69    '__panda_entrypoint_' + name
70  end
71
72  def enum_name
73    @dscr['name'].snakecase.upcase
74  end
75
76  def entrypoint_name
77    @dscr.entrypoint.nil? ? "#{name}Entrypoint" : @dscr.entrypoint
78  end
79
80  def get_entry
81    "#{name}Entrypoint"
82  end
83
84  def signature
85    @dscr['signature']
86  end
87
88  def variadic?
89    signature.include? '...'
90  end
91
92  def has_property? prop
93    @dscr['properties']&.include? prop
94  end
95
96end
97
98module Compiler
99  module_function
100
101  def entrypoints
102    @entrypoints ||= @data['entrypoints'].map {|x| Entrypoint.new x }
103  end
104
105  def entrypoints_crc32
106    require "zlib"
107    Zlib.crc32(entrypoints.map(&:signature).join)
108  end
109
110  def wrap_data(data)
111    @data = data
112  end
113end
114
115def Gen.on_require(data)
116  Compiler.wrap_data(data)
117end
118