#!/usr/bin/env ruby

# Copyright (C) 2011, 2016 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.

$: << File.dirname(__FILE__)

require "config"
require "backends"
require "digest/sha1"
require "offsets"
require 'optparse'
require "parser"
require "self_hash"
require "settings"
require "transform"

class Assembler
    def initialize(outp)
        @outp = outp
        @state = :cpp
        resetAsm
    end

    def resetAsm
        @commentState = :none
        @comment = nil
        @internalComment = nil
        @annotation = nil
        @codeOrigin = nil
        @numLocalLabels = 0
        @numGlobalLabels = 0
        @deferredActions = []
        @deferredNextLabelActions = []
        @count = 0

        @newlineSpacerState = :none
        @lastlabel = ""
    end

    def enterAsm
        @outp.puts "OFFLINE_ASM_BEGIN" if !$emitWinAsm

        if !$emitWinAsm
            @outp.puts "OFFLINE_ASM_GLOBAL_LABEL(llintPCRangeStart)"
        else
            putsProc("llintPCRangeStart", "")
            putsProcEndIfNeeded
        end
        @state = :asm
        SourceFile.outputDotFileList(@outp) if $enableDebugAnnotations
    end
    
    def leaveAsm
        putsProcEndIfNeeded if $emitWinAsm
        if !$emitWinAsm
            @outp.puts "OFFLINE_ASM_GLOBAL_LABEL(llintPCRangeEnd)"
        else
            putsProc("llintPCRangeEnd", "")
            putsProcEndIfNeeded
        end
        putsLastComment
        (@deferredNextLabelActions + @deferredActions).each {
            | action |
            action.call()
        }
        @outp.puts "OFFLINE_ASM_END" if !$emitWinAsm
        @state = :cpp
    end
    
    def deferAction(&proc)
        @deferredActions << proc
    end

    def deferNextLabelAction(&proc)
        @deferredNextLabelActions << proc
    end
    
    def newUID
        @count += 1
        @count
    end
    
    def inAsm
        resetAsm
        enterAsm
        yield
        leaveAsm
    end
    
    # Concatenates all the various components of the comment to dump.
    def lastComment
        separator = " "
        result = ""
        result = "#{@comment}" if @comment
        if @annotation and $enableInstrAnnotations
            result += separator if result != ""
            result += "#{@annotation}"
        end
        if @internalComment
            result += separator if result != ""
            result += "#{@internalComment}"
        end
        if @codeOrigin and $enableCodeOriginComments
            result += separator if result != ""
            result += "#{@codeOrigin}"
        end
        if result != ""
            result = $commentPrefix + " " + result
        end

        # Reset all the components that we've just sent to be dumped.
        @commentState = :none
        @comment = nil
        @annotation = nil
        @codeOrigin = nil
        @internalComment = nil
        result
    end
    
    # Puts a C Statement in the output stream.
    def putc(*line)
        raise unless @state == :asm
        @outp.puts(formatDump("    " + line.join(''), lastComment))
    end
    
    def formatDump(dumpStr, comment, commentColumns=$preferredCommentStartColumn)
        if comment.length > 0
            "%-#{commentColumns}s %s" % [dumpStr, comment]
        else
            dumpStr
        end
    end

    # private method for internal use only.
    def putAnnotation(text)
        raise unless @state == :asm
        if $enableInstrAnnotations
            @outp.puts text
            @annotation = nil
        end
    end

    def putLocalAnnotation()
        putAnnotation "    // #{@annotation}" if @annotation
    end

    def putGlobalAnnotation()
        putsNewlineSpacerIfAppropriate(:annotation)
        putAnnotation "// #{@annotation}" if @annotation
    end

    def putsLastComment
        comment = lastComment
        unless comment.empty?
            @outp.puts comment
        end
    end
    
    def puts(*line)
        raise unless @state == :asm
        if !$emitWinAsm
            @outp.puts(formatDump("    \"\\t" + line.join('') + "\\n\"", lastComment))
        else
            @outp.puts(formatDump("    " + line.join(''), lastComment))
        end
    end
    
    def print(line)
        raise unless @state == :asm
        @outp.print("\"" + line + "\"")
    end
    
    def putsNewlineSpacerIfAppropriate(state)
        if @newlineSpacerState != state
            @outp.puts("\n")
            @newlineSpacerState = state
        end
    end

    def putsProc(label, comment)
        raise unless $emitWinAsm
        @outp.puts(formatDump("#{label} PROC PUBLIC", comment))
        @lastlabel = label
    end

    def putsProcEndIfNeeded
        raise unless $emitWinAsm
        if @lastlabel != ""
            @outp.puts("#{@lastlabel} ENDP")
        end
        @lastlabel = ""
    end

    def putsLabel(labelName, isGlobal)
        raise unless @state == :asm
        @deferredNextLabelActions.each {
            | action |
            action.call()
        }
        @deferredNextLabelActions = []
        @numGlobalLabels += 1
        putsProcEndIfNeeded if $emitWinAsm and isGlobal
        putsNewlineSpacerIfAppropriate(:global)
        @internalComment = $enableLabelCountComments ? "Global Label #{@numGlobalLabels}" : nil
        if isGlobal
            if !$emitWinAsm
                @outp.puts(formatDump("OFFLINE_ASM_GLOBAL_LABEL(#{labelName})", lastComment))
            else
                putsProc(labelName, lastComment)
            end            
        elsif /\Allint_op_/.match(labelName)
            if !$emitWinAsm
                @outp.puts(formatDump("OFFLINE_ASM_OPCODE_LABEL(op_#{$~.post_match})", lastComment))
            else
                label = "llint_" + "op_#{$~.post_match}"
                @outp.puts(formatDump("  _#{label}:", lastComment))
            end            
        else
            if !$emitWinAsm
                @outp.puts(formatDump("OFFLINE_ASM_GLUE_LABEL(#{labelName})", lastComment))
            else
                @outp.puts(formatDump("  _#{labelName}:", lastComment))
            end
        end
        @newlineSpacerState = :none # After a global label, we can use another spacer.
    end
    
    def putsLocalLabel(labelName)
        raise unless @state == :asm
        @numLocalLabels += 1
        @outp.puts("\n")
        @internalComment = $enableLabelCountComments ? "Local Label #{@numLocalLabels}" : nil
        if !$emitWinAsm
            @outp.puts(formatDump("  OFFLINE_ASM_LOCAL_LABEL(#{labelName})", lastComment))
        else
            @outp.puts(formatDump("  #{labelName}:", lastComment))
        end
    end

    def self.externLabelReference(labelName)
        if !$emitWinAsm
            "\" LOCAL_REFERENCE(#{labelName}) \""
        else
            "#{labelName}"
        end
    end

    def self.labelReference(labelName)
        if !$emitWinAsm
            "\" LOCAL_LABEL_STRING(#{labelName}) \""
        else
            "_#{labelName}"
        end
    end
    
    def self.localLabelReference(labelName)
        if !$emitWinAsm
            "\" LOCAL_LABEL_STRING(#{labelName}) \""
        else
            "#{labelName}"
        end
    end
    
    def self.cLabelReference(labelName)
        if /\Allint_op_/.match(labelName)
            "op_#{$~.post_match}"  # strip opcodes of their llint_ prefix.
        else
            "#{labelName}"
        end
    end
    
    def self.cLocalLabelReference(labelName)
        "#{labelName}"
    end
    
    def codeOrigin(text)
        case @commentState
        when :none
            @codeOrigin = text
            @commentState = :one
        when :one
            if $enableCodeOriginComments
                @outp.puts "    " + $commentPrefix + " #{@codeOrigin}"
                @outp.puts "    " + $commentPrefix + " #{text}"
            end
            @codeOrigin = nil
            @commentState = :many
        when :many
            @outp.puts $commentPrefix + " #{text}" if $enableCodeOriginComments
        else
            raise
        end
    end

    def comment(text)
        @comment = text
    end

    def annotation(text)
        @annotation = text
    end

    def debugAnnotation(text)
        @outp.puts text
    end
end

IncludeFile.processIncludeOptions()

asmFile = ARGV.shift
offsetsFile = ARGV.shift
outputFlnm = ARGV.shift
variants = ARGV.shift.split(/[,\s]+/)

$options = {}
OptionParser.new do |opts|
    opts.banner = "Usage: asm.rb asmFile offsetsFile outputFileName [--assembler=<ASM>]"
    # This option is currently only used to specify the masm assembler
    opts.on("--assembler=[ASM]", "Specify an assembler to use.") do |assembler|
        $options[:assembler] = assembler
    end
end.parse!

begin
    configurationList = offsetsAndConfigurationIndexForVariants(offsetsFile, variants)
rescue MissingMagicValuesException
    $stderr.puts "offlineasm: No magic values found. Skipping assembly file generation."
    exit 1
end

# The MS compiler doesn't accept DWARF2 debug annotations.
if isMSVC
    $enableDebugAnnotations = false
end

$emitWinAsm = isMSVC ? outputFlnm.index(".asm") != nil : false
$commentPrefix = $emitWinAsm ? ";" : "//"

inputHash =
    $commentPrefix + " offlineasm input hash: " + parseHash(asmFile) +
    " " + Digest::SHA1.hexdigest(configurationList.map{|v| (v[0] + [v[1]]).join(' ')}.join(' ')) +
    " " + selfHash +
    " " + Digest::SHA1.hexdigest($options.has_key?(:assembler) ? $options[:assembler] : "")

if FileTest.exist? outputFlnm
    lastLine = nil
    File.open(outputFlnm, "r") {
        | file |
        file.each_line {
            | line |
            line = line.chomp
            unless line.empty?
                lastLine = line
            end
        }
    }
    if lastLine and lastLine == inputHash
        # Nothing changed.
        exit 0
    end
end

File.open(outputFlnm, "w") {
    | outp |
    $output = outp

    $asm = Assembler.new($output)
    
    ast = parse(asmFile)
    settingsCombinations = computeSettingsCombinations(ast)

    configurationList.each {
        | configuration |
        offsetsList = configuration[0]
        configIndex = configuration[1]
        forSettings(settingsCombinations[configIndex], ast) {
            | concreteSettings, lowLevelAST, backend |

            # There could be multiple backends we are generating for, but the C_LOOP is
            # always by itself so this check to turn off $enableDebugAnnotations won't
            # affect the generation for any other backend.
            if backend == "C_LOOP" || backend == "C_LOOP_WIN"
                $enableDebugAnnotations = false
            end

            lowLevelAST = lowLevelAST.demacroify({})
            lowLevelAST = lowLevelAST.resolve(buildOffsetsMap(lowLevelAST, offsetsList))
            lowLevelAST.validate
            emitCodeInConfiguration(concreteSettings, lowLevelAST, backend) {
                $currentSettings = concreteSettings
                $asm.inAsm {
                    lowLevelAST.lower(backend)
                }
            }
        }
    }

    $output.fsync
    $output.puts inputHash
}
