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