# Copyright (C) 2018-2019 Apple Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF # THE POSSIBILITY OF SUCH DAMAGE. require_relative 'Fits' class Argument attr_reader :name attr_reader :index def initialize(name, type, index) @optional = name[-1] == "?" @name = @optional ? name[0...-1] : name @type = type @index = index end def field "#{@type.to_s} #{field_name};" end def create_param "#{@type.to_s} #{@name}" end def create_reference_param "#{@type.to_s}& #{@name}" end def field_name "m_#{@name}" end def fits_check(size) Fits::check size, @name, @type end def fits_write(size) Fits::write size, @name, @type end def assert_fits(size) "ASSERT((#{fits_check size}));" end def load_from_stream(index, size) "#{field_name}(#{Fits::convert(size, "stream[#{index}]", @type)})" end def setter(traits) <<-EOF template<typename Functor> void set#{capitalized_name}(#{@type.to_s} value, Functor func) { if (isWide32<#{traits}>()) set#{capitalized_name}<OpcodeSize::Wide32>(value, func); else if (isWide16<#{traits}>()) set#{capitalized_name}<OpcodeSize::Wide16>(value, func); else set#{capitalized_name}<OpcodeSize::Narrow>(value, func); } template <OpcodeSize size, typename Functor> void set#{capitalized_name}(#{@type.to_s} value, Functor func) { if (!#{Fits::check "size", "value", @type}) value = func(); auto* stream = bitwise_cast<typename TypeBySize<size>::unsignedType*>(reinterpret_cast<uint8_t*>(this) + #{@index} * size + PaddingBySize<size>::value + /* Opcode size */ 1); *stream = #{Fits::convert "size", "value", @type}; } EOF end def capitalized_name @capitalized_name ||= @name.to_s.split('_').map do |word| letters = word.split('') letters.first.upcase! letters.join end.join end end