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