Skip to content

Instantly share code, notes, and snippets.

@evanw
Created July 30, 2017 00:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save evanw/57e2c3f40bc8789951b4926fcce8e1e8 to your computer and use it in GitHub Desktop.
Save evanw/57e2c3f40bc8789951b4926fcce8e1e8 to your computer and use it in GitHub Desktop.
An optimizer bug with emscripten's WebAssembly backend
<script src="asmjs.js"></script>
#include "FGNode.h"
#include <stdio.h>
bool Node::supportsFillPaintData() const {
return usesGeometryCache(_fields._type);
}
const PaintData& Node::fillPaintData() const {
const auto* value = _fields._fillPaintData.get();
if (!supportsFillPaintData() || !value) {
static PaintData emptyPaintData;
return emptyPaintData;
}
return *value;
}
bool Node::hasPaintedFill() const {
if (_fields._type == NodeType::B) return false;
if (!fillPaintData().containsEnabledVisiblePaint()) return false;
return true;
}
int main() {
SceneGraph scene;
auto rect = scene.findOrCreateNode(1, 0);
rect->_fields._type = NodeType::C;
rect->_fields._fillPaintData.reset(new PaintData);
rect->_fields._fillPaintData->paints.emplace_back(new Paint);
bool value = rect->hasPaintedFill();
printf("hasPaintedFill is %d\n", value);
return 0;
}
Node* SceneGraph::findOrCreateNode(int guid, int sessionID) {
std::unique_ptr<Node> owned(new Node(this, guid));
auto node = owned.get();
_nodes.emplace_back(std::move(owned));
return node;
}
#pragma once
#include "FGPaint.h"
struct SceneGraph;
enum class NodeType : uint8_t {
A,
B,
C,
D,
};
inline bool usesGeometryCache(NodeType type) {
return type >= NodeType::B && type <= NodeType::D;
}
struct DenseFieldToAny {
NodeType _type = {};
std::unique_ptr<PaintData> _fillPaintData;
};
struct Node {
Node(SceneGraph* scene_, int uniqueID) : scene(scene_), _uniqueID(uniqueID) {}
const PaintData& fillPaintData() const;
bool hasPaintedFill() const;
bool supportsFillPaintData() const;
SceneGraph* const scene;
int _uniqueID = 0;
DenseFieldToAny _fields;
};
struct SceneGraph {
Node* findOrCreateNode(int guid, int sessionID);
std::vector<std::unique_ptr<Node>> _nodes;
};
#include "FGPaint.h"
bool PaintData::containsEnabledVisiblePaint() const {
for (const auto &paint : paints) {
if (paint->isVisible()) {
return true;
}
}
return false;
}
#pragma once
#include <vector>
#include <memory>
struct Paint {
bool isVisible() const { return _enabled && _opacity > 0; }
private:
bool _enabled = true;
float _opacity = 1.0f;
};
struct PaintData {
bool containsEnabledVisiblePaint() const;
std::vector<std::unique_ptr<Paint>> paints;
};
build:
c++ *.cpp -std=c++11 -O3
./a.out
emcc *.cpp -std=c++11 -O3 -o asmjs.js
emcc *.cpp -std=c++11 -O3 -s WASM=1 -o wasm.js
<script src="wasm.js"></script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment