mirror of
https://github.com/darlinghq/darling-JavaScriptCore.git
synced 2025-04-08 18:01:37 +00:00
205 lines
5.1 KiB
Ruby
205 lines
5.1 KiB
Ruby
# Copyright (C) 2011-2020 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 "config"
|
|
require "arm"
|
|
require "arm64"
|
|
require "ast"
|
|
require "x86"
|
|
require "mips"
|
|
require "cloop"
|
|
|
|
begin
|
|
require "arm64e"
|
|
rescue LoadError
|
|
end
|
|
|
|
BACKENDS =
|
|
[
|
|
"X86",
|
|
"X86_WIN",
|
|
"X86_64",
|
|
"X86_64_WIN",
|
|
"ARMv7",
|
|
"ARM64",
|
|
"ARM64E",
|
|
"MIPS",
|
|
"C_LOOP",
|
|
"C_LOOP_WIN"
|
|
]
|
|
|
|
# Keep the set of working backends separate from the set of backends that might be
|
|
# supported. This is great because the BACKENDS list is almost like a reserved
|
|
# words list, in that it causes settings resolution to treat those words specially.
|
|
# Hence this lets us set aside the name of a backend we might want to support in
|
|
# the future while not actually supporting the backend yet.
|
|
WORKING_BACKENDS =
|
|
[
|
|
"X86",
|
|
"X86_WIN",
|
|
"X86_64",
|
|
"X86_64_WIN",
|
|
"ARMv7",
|
|
"ARM64",
|
|
"ARM64E",
|
|
"MIPS",
|
|
"C_LOOP",
|
|
"C_LOOP_WIN"
|
|
]
|
|
|
|
BACKEND_PATTERN = Regexp.new('\\A(' + BACKENDS.join(')|(') + ')\\Z')
|
|
|
|
$allBackends = {}
|
|
$validBackends = {}
|
|
BACKENDS.each {
|
|
| backend |
|
|
$validBackends[backend] = true
|
|
$allBackends[backend] = true
|
|
}
|
|
|
|
def canonicalizeBackendNames(backendNames)
|
|
newBackendNames = []
|
|
backendNames.each {
|
|
| backendName |
|
|
backendName = backendName.upcase
|
|
if backendName =~ /ARM.*/
|
|
backendName.sub!(/ARMV7([KS]?)(.*)/) { | _ | 'ARMv7' + $1.downcase + $2 }
|
|
backendName = "ARM64" if backendName == "ARM64_32"
|
|
end
|
|
backendName = "X86" if backendName == "I386"
|
|
newBackendNames << backendName
|
|
newBackendNames << "ARMv7" if backendName.start_with?("ARMv7")
|
|
}
|
|
newBackendNames.uniq
|
|
end
|
|
|
|
def includeOnlyBackends(list)
|
|
newValidBackends = {}
|
|
list.each {
|
|
| backend |
|
|
if $validBackends[backend]
|
|
newValidBackends[backend] = true
|
|
end
|
|
}
|
|
$validBackends = newValidBackends
|
|
end
|
|
|
|
def isBackend?(backend)
|
|
$allBackends[backend]
|
|
end
|
|
|
|
def isValidBackend?(backend)
|
|
$validBackends[backend]
|
|
end
|
|
|
|
def validBackends
|
|
$validBackends.keys
|
|
end
|
|
|
|
class LoweringError < StandardError
|
|
attr_reader :originString
|
|
|
|
def initialize(e, originString)
|
|
super "#{e} (due to #{originString})"
|
|
@originString = originString
|
|
set_backtrace e.backtrace
|
|
end
|
|
end
|
|
|
|
class Node
|
|
def lower(name)
|
|
begin
|
|
$activeBackend = name
|
|
send("prepareToLower", name)
|
|
send("lower#{name}")
|
|
rescue => e
|
|
raise LoweringError.new(e, codeOriginString)
|
|
end
|
|
end
|
|
end
|
|
|
|
# Overrides for lower() for those nodes that are backend-agnostic
|
|
|
|
class Label
|
|
def lower(name)
|
|
$asm.debugAnnotation codeOrigin.debugDirective if $enableDebugAnnotations
|
|
$asm.putsLabel(self.name[1..-1], @global)
|
|
end
|
|
end
|
|
|
|
class LocalLabel
|
|
def lower(name)
|
|
$asm.putsLocalLabel "_offlineasm_#{self.name[1..-1]}"
|
|
end
|
|
end
|
|
|
|
class LabelReference
|
|
def asmLabel
|
|
if extern?
|
|
Assembler.externLabelReference(name[1..-1])
|
|
else
|
|
Assembler.labelReference(name[1..-1])
|
|
end
|
|
end
|
|
|
|
def cLabel
|
|
Assembler.cLabelReference(name[1..-1])
|
|
end
|
|
end
|
|
|
|
class LocalLabelReference
|
|
def asmLabel
|
|
Assembler.localLabelReference("_offlineasm_"+name[1..-1])
|
|
end
|
|
|
|
def cLabel
|
|
Assembler.cLocalLabelReference("_offlineasm_"+name[1..-1])
|
|
end
|
|
end
|
|
|
|
class Skip
|
|
def lower(name)
|
|
end
|
|
end
|
|
|
|
class Sequence
|
|
def lower(name)
|
|
$activeBackend = name
|
|
if respond_to? "getModifiedList#{name}"
|
|
newList = send("getModifiedList#{name}")
|
|
newList.each {
|
|
| node |
|
|
node.lower(name)
|
|
}
|
|
elsif respond_to? "lower#{name}"
|
|
send("lower#{name}")
|
|
else
|
|
@list.each {
|
|
| node |
|
|
node.lower(name)
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|