Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for issue #178 #179

Merged
merged 5 commits into from
Dec 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 24 additions & 23 deletions backends/bmv2/jsonconverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1676,11 +1676,11 @@ void JsonConverter::addHeaderStacks(const IR::Type_Struct* headersStruct) {
void JsonConverter::addLocals() {
// We synthesize a "header_type" for each local which has a struct type
// and we pack all the scalar-typed locals into a scalarsStruct
auto scalarsStruct = new Util::JsonObject();
scalarsStruct = new Util::JsonObject();
scalarsName = refMap->newName("scalars");
scalarsStruct->emplace("name", scalarsName);
scalarsStruct->emplace("id", nextId("header_types"));
unsigned scalars_width = 0;
scalars_width = 0;
auto scalarFields = mkArrayField(scalarsStruct, "fields");

for (auto v : structure.variables) {
Expand Down Expand Up @@ -1738,28 +1738,28 @@ void JsonConverter::addLocals() {
}
}

if (scalars_width != 0) {
// pad the scalars
unsigned padding = scalars_width % 8;
if (padding != 0) {
cstring name = refMap->newName("_padding");
auto field = pushNewArray(scalarFields);
field->append(name);
field->append(8 - padding);
field->append(false);
}
// insert the scalars type
headerTypesCreated[scalarsName] = scalarsName;
headerTypes->append(scalarsStruct);

// insert the scalars type
headerTypesCreated[scalarsName] = scalarsName;
headerTypes->append(scalarsStruct);
// insert the scalars instance
auto json = new Util::JsonObject();
json->emplace("name", scalarsName);
json->emplace("id", nextId("headers"));
json->emplace("header_type", scalarsName);
json->emplace("metadata", true);
headerInstances->append(json);
}

// insert the scalars instance
auto json = new Util::JsonObject();
json->emplace("name", scalarsName);
json->emplace("id", nextId("headers"));
json->emplace("header_type", scalarsName);
json->emplace("metadata", true);
headerInstances->append(json);
void JsonConverter::padScalars() {
unsigned padding = scalars_width % 8;
auto scalarFields = (*scalarsStruct)["fields"]->to<Util::JsonArray>();
if (padding != 0) {
cstring name = refMap->newName("_padding");
auto field = pushNewArray(scalarFields);
field->append(name);
field->append(8 - padding);
field->append(false);
}
}

Expand Down Expand Up @@ -1822,8 +1822,9 @@ void JsonConverter::convert(P4::ReferenceMap* refMap, P4::TypeMap* typeMap,
::error("Expected metadata %1% to be a struct", mdType);
return;
}
addTypesAndInstances(mt, true);
addLocals();
addTypesAndInstances(mt, true);
padScalars();

auto prsrs = mkArrayField(&toplevel, "parsers");
auto parserJson = toJson(parser);
Expand Down
3 changes: 3 additions & 0 deletions backends/bmv2/jsonconverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ class JsonConverter final {
std::map<cstring, cstring> headerTypesCreated;
Util::JsonArray *headerInstances;
Util::JsonArray *headerStacks;
Util::JsonObject *scalarsStruct;
unsigned scalars_width = 0;
friend class ExpressionConverter;

protected:
Expand All @@ -84,6 +86,7 @@ class JsonConverter final {
unsigned nextId(cstring group);
void addHeaderStacks(const IR::Type_Struct* headersStruct);
void addLocals();
void padScalars();
void addTypesAndInstances(const IR::Type_StructLike* type, bool meta);
void convertActionBody(const IR::Vector<IR::StatOrDecl>* body,
Util::JsonArray* result, Util::JsonArray* fieldLists,
Expand Down
9 changes: 9 additions & 0 deletions frontends/p4/typeChecking/typeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ limitations under the License.
#include "typeConstraints.h"
#include "syntacticEquivalence.h"
#include "frontends/common/resolveReferences/resolveReferences.h"
#include "frontends/p4/methodInstance.h"

namespace P4 {

Expand Down Expand Up @@ -2260,6 +2261,14 @@ const IR::Node* TypeInference::postorder(IR::MethodCallExpression* expression) {
auto result = cts.convert(expression)->to<IR::MethodCallExpression>(); // cast arguments

setType(result, returnType);

auto mi = MethodInstance::resolve(expression, refMap, typeMap);
if (mi->isApply()) {
auto a = mi->to<ApplyMethod>();
if (a->isTableApply() && findContext<IR::P4Action>())
::error("%1%: tables cannot be invoked from actions", expression);
}

return result;
}
return expression;
Expand Down
6 changes: 3 additions & 3 deletions lib/json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ int JsonValue::getInt() const {
return val.get_si();
}

JsonArray* JsonArray::append(const IJson* value) {
JsonArray* JsonArray::append(IJson* value) {
push_back(value);
return this;
}
Expand All @@ -163,13 +163,13 @@ void JsonObject::serialize(std::ostream& out) const {
out << IndentCtl::unindent << IndentCtl::endl << "}";
}

JsonObject* JsonObject::emplace(cstring label, const IJson* value) {
JsonObject* JsonObject::emplace(cstring label, IJson* value) {
if (label.isNullOrEmpty())
throw std::logic_error("Empty label");
auto j = get(label);
if (j != nullptr)
throw std::logic_error(cstring("Duplicate label in json object ") + label.c_str());
ordered_map<cstring, const IJson*>::emplace(label, value);
ordered_map<cstring, IJson*>::emplace(label, value);
return this;
}

Expand Down
12 changes: 6 additions & 6 deletions lib/json.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,11 @@ class JsonValue final : public IJson {
const cstring str = nullptr;
};

class JsonArray final : public IJson, public std::vector<const IJson*> {
class JsonArray final : public IJson, public std::vector<IJson*> {
friend class Test::TestJson;
public:
void serialize(std::ostream& out) const;
JsonArray* append(const IJson* value);
JsonArray* append(IJson* value);
JsonArray* append(bool b) { append(new JsonValue(b)); return this; }
JsonArray* append(mpz_class v) { append(new JsonValue(v)); return this; }
JsonArray* append(int v) { append(new JsonValue(v)); return this; }
Expand All @@ -115,17 +115,17 @@ class JsonArray final : public IJson, public std::vector<const IJson*> {
JsonArray* append(cstring s) { append(new JsonValue(s)); return this; }
JsonArray* append(std::string s) { append(new JsonValue(s)); return this; }
JsonArray* append(const char* s) { append(new JsonValue(s)); return this; }
JsonArray(std::initializer_list<const IJson*> data) : std::vector<const IJson*>(data) {} // NOLINT
JsonArray(std::initializer_list<IJson*> data) : std::vector<IJson*>(data) {} // NOLINT
JsonArray() = default;
};

class JsonObject final : public IJson, public ordered_map<cstring, const IJson*> {
class JsonObject final : public IJson, public ordered_map<cstring, IJson*> {
friend class Test::TestJson;

public:
JsonObject() = default;
void serialize(std::ostream& out) const;
JsonObject* emplace(cstring label, const IJson* value);
JsonObject* emplace(cstring label, IJson* value);
JsonObject* emplace(cstring label, bool b)
{ emplace(label, new JsonValue(b)); return this; }
JsonObject* emplace(cstring label, mpz_class v)
Expand All @@ -148,7 +148,7 @@ class JsonObject final : public IJson, public ordered_map<cstring, const IJson*>
{ emplace(label, new JsonValue(s)); return this; }
JsonObject* emplace(cstring label, const char* s)
{ emplace(label, new JsonValue(s)); return this; }
const IJson* get(cstring label) const { return ::get(*this, label); }
IJson* get(cstring label) const { return ::get(*this, label); }
};

} // namespace Util
Expand Down
27 changes: 27 additions & 0 deletions testdata/p4_16_errors/call-table.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
Copyright 2016 VMware, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

control c() {
action a() {}
table t() {
actions = { a(); }
default_action = a();
}
action b() {
t.apply(); // cannot invoke table from action
}
apply {}
}
16 changes: 16 additions & 0 deletions testdata/p4_16_errors_outputs/call-table.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
control c() {
action a() {
}
table t() {
actions = {
a();
}
default_action = a();
}
action b() {
t.apply();
}
apply {
}
}

3 changes: 3 additions & 0 deletions testdata/p4_16_errors_outputs/call-table.p4-stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
../testdata/p4_16_errors/call-table.p4(24): error: t.apply: tables cannot be invoked from actions
t.apply();
^^^^^^^^^