blob: 56041fb2ba3619c3fa752237b3ecdcb290c75bad [file] [log] [blame]
/*
* Copyright (C) 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.
*/
#include "config.h"
#include "WHLSLNameContext.h"
#if ENABLE(WEBGPU)
#include "WHLSLEnumerationDefinition.h"
#include "WHLSLFunctionDefinition.h"
#include "WHLSLNativeFunctionDeclaration.h"
#include "WHLSLNativeTypeDeclaration.h"
#include "WHLSLStructureDefinition.h"
#include "WHLSLTypeDefinition.h"
#include "WHLSLVariableDeclaration.h"
namespace WebCore {
namespace WHLSL {
NameContext::NameContext(NameContext* parent)
: m_parent(parent)
{
}
Expected<void, Error> NameContext::add(AST::TypeDefinition& typeDefinition)
{
if (auto existing = topLevelExists(typeDefinition.name()))
return makeUnexpected(Error("Duplicate name in program", *existing));
typeDefinition.setNameSpace(m_currentNameSpace);
auto index = static_cast<unsigned>(m_currentNameSpace);
auto result = m_types[index].add(typeDefinition.name(), Vector<std::reference_wrapper<AST::NamedType>, 1>());
ASSERT(result.isNewEntry);
result.iterator->value.append(typeDefinition);
return { };
}
Expected<void, Error> NameContext::add(AST::StructureDefinition& structureDefinition)
{
if (auto existing = topLevelExists(structureDefinition.name()))
return makeUnexpected(Error("Duplicate name in program.", *existing));
structureDefinition.setNameSpace(m_currentNameSpace);
auto index = static_cast<unsigned>(m_currentNameSpace);
auto result = m_types[index].add(structureDefinition.name(), Vector<std::reference_wrapper<AST::NamedType>, 1>());
ASSERT(result.isNewEntry);
result.iterator->value.append(structureDefinition);
return { };
}
Expected<void, Error> NameContext::add(AST::EnumerationDefinition& enumerationDefinition)
{
if (auto existing = topLevelExists(enumerationDefinition.name()))
return makeUnexpected(Error("Duplicate name in program.", *existing));
enumerationDefinition.setNameSpace(m_currentNameSpace);
auto index = static_cast<unsigned>(m_currentNameSpace);
auto result = m_types[index].add(enumerationDefinition.name(), Vector<std::reference_wrapper<AST::NamedType>, 1>());
ASSERT(result.isNewEntry);
result.iterator->value.append(enumerationDefinition);
return { };
}
Expected<void, Error> NameContext::add(AST::FunctionDefinition& functionDefinition)
{
auto index = static_cast<unsigned>(m_currentNameSpace);
if (auto* type = searchTypes(functionDefinition.name()))
return makeUnexpected(Error("Duplicate name in program.", type->codeLocation()));
functionDefinition.setNameSpace(m_currentNameSpace);
auto result = m_functions[index].add(functionDefinition.name(), Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>());
result.iterator->value.append(functionDefinition);
return { };
}
Expected<void, Error> NameContext::add(AST::NativeFunctionDeclaration& nativeFunctionDeclaration)
{
auto index = static_cast<unsigned>(m_currentNameSpace);
if (auto* type = searchTypes(nativeFunctionDeclaration.name()))
return makeUnexpected(Error("Duplicate name in program.", type->codeLocation()));
nativeFunctionDeclaration.setNameSpace(m_currentNameSpace);
auto result = m_functions[index].add(nativeFunctionDeclaration.name(), Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>());
result.iterator->value.append(nativeFunctionDeclaration);
return { };
}
Expected<void, Error> NameContext::add(AST::NativeTypeDeclaration& nativeTypeDeclaration)
{
auto index = static_cast<unsigned>(m_currentNameSpace);
if (auto* function = searchFunctions(nativeTypeDeclaration.name()))
return makeUnexpected(Error("Duplicate name in program.", function->codeLocation()));
nativeTypeDeclaration.setNameSpace(m_currentNameSpace);
auto result = m_types[index].add(nativeTypeDeclaration.name(), Vector<std::reference_wrapper<AST::NamedType>, 1>());
result.iterator->value.append(nativeTypeDeclaration);
return { };
}
Expected<void, Error> NameContext::add(AST::VariableDeclaration& variableDeclaration)
{
if (variableDeclaration.name().isNull())
return { };
if (auto* declaration = localExists(variableDeclaration.name()))
return makeUnexpected(Error("Duplicate name in program.", declaration->codeLocation()));
auto result = m_variables.add(String(variableDeclaration.name()), &variableDeclaration);
ASSERT_UNUSED(result, result.isNewEntry);
return { };
}
Vector<std::reference_wrapper<AST::NamedType>, 1> NameContext::getTypes(const String& name, AST::NameSpace fromNamespace)
{
// Named types can only be declared in the global name context.
if (m_parent)
return m_parent->getTypes(name, fromNamespace);
Vector<std::reference_wrapper<AST::NamedType>, 1> result;
unsigned index = static_cast<unsigned>(fromNamespace);
auto iterator = m_types[index].find(name);
if (iterator != m_types[index].end()) {
for (auto type : iterator->value)
result.append(type);
}
if (fromNamespace != AST::NameSpace::StandardLibrary) {
index = static_cast<unsigned>(AST::NameSpace::StandardLibrary);
iterator = m_types[index].find(name);
if (iterator != m_types[index].end()) {
for (auto type : iterator->value)
result.append(type);
}
}
return result;
}
Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1> NameContext::getFunctions(const String& name, AST::NameSpace fromNamespace)
{
// Functions can only be declared in the global name context.
if (m_parent)
return m_parent->getFunctions(name, fromNamespace);
Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1> result;
unsigned index = static_cast<unsigned>(fromNamespace);
auto iterator = m_functions[index].find(name);
if (iterator != m_functions[index].end()) {
for (auto type : iterator->value)
result.append(type);
}
if (fromNamespace != AST::NameSpace::StandardLibrary) {
index = static_cast<unsigned>(AST::NameSpace::StandardLibrary);
iterator = m_functions[index].find(name);
if (iterator != m_functions[index].end()) {
for (auto type : iterator->value)
result.append(type);
}
}
return result;
}
AST::VariableDeclaration* NameContext::getVariable(const String& name)
{
auto iterator = m_variables.find(name);
if (iterator == m_variables.end()) {
if (m_parent)
return m_parent->getVariable(name);
return nullptr;
}
return iterator->value;
}
AST::NamedType* NameContext::searchTypes(String& name) const
{
ASSERT(!m_parent);
if (m_currentNameSpace == AST::NameSpace::StandardLibrary) {
for (auto& types : m_types) {
auto iter = types.find(name);
if (iter != types.end())
return &iter->value[0].get();
}
return nullptr;
}
auto index = static_cast<unsigned>(m_currentNameSpace);
auto iter = m_types[index].find(name);
if (iter != m_types[index].end())
return &iter->value[0].get();
index = static_cast<unsigned>(AST::NameSpace::StandardLibrary);
iter = m_types[index].find(name);
if (iter != m_types[index].end())
return &iter->value[0].get();
return nullptr;
}
AST::FunctionDeclaration* NameContext::searchFunctions(String& name) const
{
ASSERT(!m_parent);
if (m_currentNameSpace == AST::NameSpace::StandardLibrary) {
for (auto& functions : m_functions) {
auto iter = functions.find(name);
if (iter != functions.end())
return &iter->value[0].get();
}
return nullptr;
}
auto index = static_cast<unsigned>(m_currentNameSpace);
auto iter = m_functions[index].find(name);
if (iter != m_functions[index].end())
return &iter->value[0].get();
index = static_cast<unsigned>(AST::NameSpace::StandardLibrary);
iter = m_functions[index].find(name);
if (iter != m_functions[index].end())
return &iter->value[0].get();
return nullptr;
}
Optional<CodeLocation> NameContext::topLevelExists(String& name) const
{
if (auto* type = searchTypes(name))
return type->codeLocation();
if (auto* function = searchFunctions(name))
return function->codeLocation();
return WTF::nullopt;
}
AST::VariableDeclaration* NameContext::localExists(String& name) const
{
ASSERT(m_parent);
auto iter = m_variables.find(name);
if (iter != m_variables.end())
return iter->value;
return nullptr;
}
} // namespace WHLSL
} // namespace WebCore
#endif // ENABLE(WEBGPU)