blob: bf96bb0440bdbead9dc9176eaccd5a9944520750 [file] [log] [blame]
/*
* Copyright 2021 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/sksl/ir/SkSLConstructorArrayCast.h"
#include "src/sksl/SkSLConstantFolder.h"
#include "src/sksl/SkSLProgramSettings.h"
#include "src/sksl/ir/SkSLConstructorArray.h"
#include "src/sksl/ir/SkSLConstructorCompoundCast.h"
#include "src/sksl/ir/SkSLConstructorScalarCast.h"
namespace SkSL {
static std::unique_ptr<Expression> cast_constant_array(const Context& context,
const Type& destType,
std::unique_ptr<Expression> constCtor) {
const Type& scalarType = destType.componentType();
// Create a ConstructorArray(...) which typecasts each argument inside.
auto inputArgs = constCtor->as<ConstructorArray>().argumentSpan();
ExpressionArray typecastArgs;
typecastArgs.reserve_back(inputArgs.size());
for (std::unique_ptr<Expression>& arg : inputArgs) {
int line = arg->fLine;
if (arg->type().isScalar()) {
typecastArgs.push_back(ConstructorScalarCast::Make(context, line, scalarType,
std::move(arg)));
} else {
typecastArgs.push_back(ConstructorCompoundCast::Make(context, line, scalarType,
std::move(arg)));
}
}
return ConstructorArray::Make(context, constCtor->fLine, destType, std::move(typecastArgs));
}
std::unique_ptr<Expression> ConstructorArrayCast::Make(const Context& context,
int line,
const Type& type,
std::unique_ptr<Expression> arg) {
// Only arrays of the same size are allowed.
SkASSERT(type.isArray());
SkASSERT(type.isAllowedInES2(context));
SkASSERT(arg->type().isArray());
SkASSERT(type.columns() == arg->type().columns());
// If this is a no-op cast, return the expression as-is.
if (type.matches(arg->type())) {
return arg;
}
// Look up the value of constant variables. This allows constant-expressions like `myArray` to
// be replaced with the compile-time constant `int[2](0, 1)`.
arg = ConstantFolder::MakeConstantValueForVariable(std::move(arg));
// We can cast a vector of compile-time constants at compile-time.
if (arg->isCompileTimeConstant()) {
return cast_constant_array(context, type, std::move(arg));
}
return std::make_unique<ConstructorArrayCast>(line, type, std::move(arg));
}
} // namespace SkSL