Skip to content

Commit

Permalink
change every object method to inline, change type to use bitmath to h…
Browse files Browse the repository at this point in the history
…ave faster operations, remove object virtuals
  • Loading branch information
meepen committed Jul 19, 2021
1 parent aa76437 commit 056ab3a
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 108 deletions.
2 changes: 1 addition & 1 deletion src/vm/bytecode/bcexpressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class binopsimplifier {
bool free_right = false;
gen.runexpressionhandler(expr.lhs, target, 1);

if (free_right = !get(expr.rhs, &rhs_stack, false)) {
if ((free_right = !get(expr.rhs, &rhs_stack, false))) {
rhs_stack = gen.funcptr->getslots(1);
gen.runexpressionhandler(expr.rhs, rhs_stack, 1);
}
Expand Down
168 changes: 69 additions & 99 deletions src/vm/software/object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include <memory>
#include <unordered_map>

#define LORELAI_SOFTWARE_DEFAULT_FUNCTION(name, ...) name (__VA_ARGS__) { except(#name); }
#define LORELAI_SOFTWARE_DEFAULT_FUNCTION(name, ...) name (__VA_ARGS__) { throw exception(string("cannot " #name " a ") + typenames[_typeid()]); }


namespace lorelai {
Expand All @@ -23,9 +23,6 @@ namespace lorelai {
class object;

class referenceobject {
protected:
void except(string str) const { throw exception(string("cannot ") + str + " a " + typenames[_typeid()]); }

public:
virtual ~referenceobject() { }
virtual _type _typeid() const = 0;
Expand All @@ -42,20 +39,19 @@ namespace lorelai {
throw exception(string("cannot convert ") + typenames[_typeid()] + " to number");
}

virtual bool LORELAI_SOFTWARE_DEFAULT_FUNCTION(rawget, softwarestate &state, object &out, const object &index)
virtual void LORELAI_SOFTWARE_DEFAULT_FUNCTION(rawset, softwarestate &state, const object &index, const object &data)
virtual state::_retdata LORELAI_SOFTWARE_DEFAULT_FUNCTION(call, softwarestate &state, int nargs)
virtual void LORELAI_SOFTWARE_DEFAULT_FUNCTION(setindex, softwarestate &state, object &key, object &value)

void LORELAI_SOFTWARE_DEFAULT_FUNCTION(length, softwarestate &state, object &out)
bool LORELAI_SOFTWARE_DEFAULT_FUNCTION(lessthan, softwarestate &state, object &rhs);
bool LORELAI_SOFTWARE_DEFAULT_FUNCTION(greaterthan, softwarestate &state, object &rhs);
void LORELAI_SOFTWARE_DEFAULT_FUNCTION(add, softwarestate &state, object &out, object &rhs);
void LORELAI_SOFTWARE_DEFAULT_FUNCTION(subtract, softwarestate &state, object &out, object &rhs);
void LORELAI_SOFTWARE_DEFAULT_FUNCTION(divide, softwarestate &state, object &out, object &rhs);
void LORELAI_SOFTWARE_DEFAULT_FUNCTION(multiply, softwarestate &state, object &out, object &rhs);
void LORELAI_SOFTWARE_DEFAULT_FUNCTION(power, softwarestate &state, object &out, object &rhs);
void LORELAI_SOFTWARE_DEFAULT_FUNCTION(modulo, softwarestate &state, object &out, object &rhs);
[[noreturn]] virtual bool LORELAI_SOFTWARE_DEFAULT_FUNCTION(rawget, softwarestate &state, object &out, const object &index)
[[noreturn]] virtual void LORELAI_SOFTWARE_DEFAULT_FUNCTION(rawset, softwarestate &state, const object &index, const object &data)
[[noreturn]] virtual state::_retdata LORELAI_SOFTWARE_DEFAULT_FUNCTION(call, softwarestate &state, int nargs)
[[noreturn]] virtual void LORELAI_SOFTWARE_DEFAULT_FUNCTION(setindex, softwarestate &state, object &key, object &value)
[[noreturn]] virtual void LORELAI_SOFTWARE_DEFAULT_FUNCTION(length, softwarestate &state, object &out)
[[noreturn]] virtual bool LORELAI_SOFTWARE_DEFAULT_FUNCTION(lessthan, softwarestate &state, object &rhs);
[[noreturn]] virtual bool LORELAI_SOFTWARE_DEFAULT_FUNCTION(greaterthan, softwarestate &state, object &rhs);
[[noreturn]] virtual void LORELAI_SOFTWARE_DEFAULT_FUNCTION(add, softwarestate &state, object &out, object &rhs);
[[noreturn]] virtual void LORELAI_SOFTWARE_DEFAULT_FUNCTION(subtract, softwarestate &state, object &out, object &rhs);
[[noreturn]] virtual void LORELAI_SOFTWARE_DEFAULT_FUNCTION(divide, softwarestate &state, object &out, object &rhs);
[[noreturn]] virtual void LORELAI_SOFTWARE_DEFAULT_FUNCTION(multiply, softwarestate &state, object &out, object &rhs);
[[noreturn]] virtual void LORELAI_SOFTWARE_DEFAULT_FUNCTION(power, softwarestate &state, object &out, object &rhs);
[[noreturn]] virtual void LORELAI_SOFTWARE_DEFAULT_FUNCTION(modulo, softwarestate &state, object &out, object &rhs);

inline bool equals(softwarestate &state, object &other);

Expand Down Expand Up @@ -83,26 +79,26 @@ namespace lorelai {
};

public:
object(const object &obj) {
LORELAI_INLINE object(const object &obj) {
type = obj.type;
raw = obj.raw;
}
object(referenceobject &ref) {
LORELAI_INLINE object(referenceobject &ref) {
set(ref);
}
object(const number num) {
LORELAI_INLINE object(const number num) {
set(num);
}
object(const bool b) {
LORELAI_INLINE object(const bool b) {
set(b);
}
object() {
LORELAI_INLINE object() {
set();
}

public:
LORELAI_INLINE void set(referenceobject &ref) {
type = TABLE;
type = STRING;
raw.ref = &ref;
}

Expand Down Expand Up @@ -150,14 +146,11 @@ namespace lorelai {

public:
// called in lua vm
inline bool equals (softwarestate &state, object &other) {
LORELAI_INLINE bool equals (softwarestate &state, object &other) {
// if either can potentially have a custom metamethod be ran, pass through to the reference object to check
if (type >= TABLE) {
if (LORELAI_ISREFERENCETYPE(type | other.type)) {
return raw.ref->equals(state, other);
}
else if (other.type >= TABLE) {
return other.raw.ref->equals(state, *this);
}

// otherwise, check types
// regular object can only be equal to the same type
Expand All @@ -177,105 +170,82 @@ namespace lorelai {
}
}

inline bool lessthan (softwarestate &state, object &other) {
LORELAI_INLINE bool lessthan (softwarestate &state, object &other) {
return tonumber(state) < other.tonumber(state);
}
inline bool greaterthan (softwarestate &state, object &other) {
LORELAI_INLINE bool greaterthan (softwarestate &state, object &other) {
return tonumber(state) > other.tonumber(state);
}

void concat (softwarestate &state, object &out, object &other);

inline void add (softwarestate &state, object &out, object &other) {
// if either can potentially have a custom metamethod be ran, pass through to the reference object to check
if (type == NUMBER && other.type == NUMBER) {
LORELAI_INLINE void add(softwarestate &state, object &out, object &other) {
if ((type | other.type) == NUMBER) {
out.set(raw.num + other.raw.num);
}
else if (type >= TABLE) {
return raw.ref->add(state, out, other);
}
else if (other.type >= TABLE) {
return other.raw.ref->add(state, out, *this);
else if (LORELAI_ISREFERENCETYPE(type | other.type)) {
throw;
}
else {
out.set(tonumber(state) + other.tonumber(state));
}
}

inline void subtract (softwarestate &state, object &out, object &other) {
// if either can potentially have a custom metamethod be ran, pass through to the reference object to check
if (type == NUMBER && other.type == NUMBER) {
LORELAI_INLINE void subtract(softwarestate &state, object &out, object &other) {
if ((type | other.type) == NUMBER) {
out.set(raw.num - other.raw.num);
}
else if (type >= TABLE) {
return raw.ref->subtract(state, out, other);
}
else if (other.type >= TABLE) {
return other.raw.ref->subtract(state, out, *this);
else if (LORELAI_ISREFERENCETYPE(type | other.type)) {
throw;
}
else {
out.set(tonumber(state) - other.tonumber(state));
}
}

inline void divide (softwarestate &state, object &out, object &other) {
LORELAI_INLINE void divide(softwarestate &state, object &out, object &other) {
// if either can potentially have a custom metamethod be ran, pass through to the reference object to check
if (type == NUMBER && other.type == NUMBER) {
out.set(raw.num / other.raw.num);
}
else if (type >= TABLE) {
return raw.ref->divide(state, out, other);
}
else if (other.type >= TABLE) {
return other.raw.ref->divide(state, out, *this);
else if (LORELAI_ISREFERENCETYPE(type | other.type)) {
throw;
}
else {
out.set(tonumber(state) / other.tonumber(state));
}
}

inline void multiply (softwarestate &state, object &out, object &other) {
// if either can potentially have a custom metamethod be ran, pass through to the reference object to check
if (type == NUMBER && other.type == NUMBER) {
LORELAI_INLINE void multiply(softwarestate &state, object &out, object &other) {
if ((type | other.type) == NUMBER) {
out.set(raw.num * other.raw.num);
}
else if (type >= TABLE) {
return raw.ref->multiply(state, out, other);
}
else if (other.type >= TABLE) {
return other.raw.ref->multiply(state, out, *this);
else if (LORELAI_ISREFERENCETYPE(type | other.type)) {
throw;
}
else {
out.set(tonumber(state) * other.tonumber(state));
}
}

inline void power (softwarestate &state, object &out, object &other) {
// if either can potentially have a custom metamethod be ran, pass through to the reference object to check
if (type == NUMBER && other.type == NUMBER) {
LORELAI_INLINE void power(softwarestate &state, object &out, object &other) {
if ((type | other.type) == NUMBER) {
out.set(std::pow(raw.num, other.raw.num));
}
else if (type >= TABLE) {
return raw.ref->power(state, out, other);
}
else if (other.type >= TABLE) {
return other.raw.ref->power(state, out, *this);
else if (LORELAI_ISREFERENCETYPE(type | other.type)) {
throw;
}
else {
out.set(std::pow(tonumber(state), other.tonumber(state)));
}
}

inline void modulo (softwarestate &state, object &out, object &other) {
// if either can potentially have a custom metamethod be ran, pass through to the reference object to check
if (type == NUMBER && other.type == NUMBER) {
out.set(raw.num - other.raw.num * std::floor(raw.num / other.raw.num));
}
else if (type >= TABLE) {
return raw.ref->modulo(state, out, other);
LORELAI_INLINE void modulo(softwarestate &state, object &out, object &other) {
if ((type | other.type) == NUMBER) {
auto a = raw.num, b = other.raw.num;

out.set(a - b * std::floor(a / b));
}
else if (other.type >= TABLE) {
return other.raw.ref->modulo(state, out, *this);
else if (LORELAI_ISREFERENCETYPE(type | other.type)) {
throw;
}
else {
auto a = tonumber(state), b = other.tonumber(state);
Expand All @@ -284,60 +254,60 @@ namespace lorelai {
}
}

virtual bool rawget(softwarestate &state, object &out, const object &index) {
if (type < TABLE) {
LORELAI_INLINE bool rawget(softwarestate &state, object &out, const object &index) {
if (!LORELAI_ISREFERENCETYPE(type)) {
throw exception(string("NYI: cannot index ") + gettypename());
}

return raw.ref->rawget(state, out, index);
}
virtual void rawset(softwarestate &state, const object &index, const object &value) {
if (type < TABLE) {
LORELAI_INLINE void rawset(softwarestate &state, const object &index, const object &value) {
if (!LORELAI_ISREFERENCETYPE(type)) {
throw exception(string("NYI: cannot set index on ") + gettypename());
}

return raw.ref->rawset(state, index, value);
}

bool index (softwarestate &state, object &out, object &index) {
if (type < TABLE) {
LORELAI_INLINE bool index (softwarestate &state, object &out, object &index) {
if (!LORELAI_ISREFERENCETYPE(type)) {
throw exception(string("NYI: cannot index ") + gettypename());
}

return raw.ref->index(state, out, index);
}

void setindex (softwarestate &state, object &key, object &value) {
if (type < TABLE) {
LORELAI_INLINE void setindex (softwarestate &state, object &key, object &value) {
if (!LORELAI_ISREFERENCETYPE(type)) {
throw exception(string("NYI: cannot setindex ") + gettypename());
}

return raw.ref->setindex(state, key, value);
}

state::_retdata call (softwarestate &state, int nargs) {
if (type < TABLE) {
LORELAI_INLINE state::_retdata call (softwarestate &state, int nargs) {
if (!LORELAI_ISREFERENCETYPE(type)) {
throw exception(string("NYI: cannot call ") + gettypename());
}

return raw.ref->call(state, nargs);
}

void convertexception(const char *what) {
[[noreturn]] LORELAI_INLINE void convertexception(const char *what) {
throw exception(string("cannot convert ") + gettypename() + " to " + what);
}

LORELAI_INLINE number tonumber (softwarestate &state) {
LORELAI_INLINE number tonumber(softwarestate &state) {
if (type == NUMBER) {
return raw.num;
}
else if (type >= TABLE) {
else if (LORELAI_ISREFERENCETYPE(type)) {
return raw.ref->tonumber(state);
}
convertexception("number");
}

inline string tostring (softwarestate &state) const {
LORELAI_INLINE string tostring(softwarestate &state) const {
switch (type) {
case NIL:
return "nil";
Expand All @@ -355,7 +325,7 @@ namespace lorelai {
}
}

inline bool tobool (softwarestate &state) {
LORELAI_INLINE bool tobool(softwarestate &state) {
switch (type) {
case NIL:
return false;
Expand All @@ -366,17 +336,17 @@ namespace lorelai {
}
}

object metatable(softwarestate &state) {
if (type >= TABLE) {
LORELAI_INLINE object metatable(softwarestate &state) {
if (LORELAI_ISREFERENCETYPE(type)) {
return raw.ref->metatable(state);
}

return object();
}

public:
const char *gettypename() {
if (type >= TABLE) {
LORELAI_INLINE const char *gettypename() {
if (LORELAI_ISREFERENCETYPE(type)) {
return typenames[raw.ref->_typeid()];
}
return typenames[type];
Expand Down
2 changes: 1 addition & 1 deletion src/vm/software/types/luafunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ state::_retdata luafunctionobject::call(softwarestate &state, int nargs) {
state[instr->b].modulo(state, state[instr->a], state[instr->c]);
vmbreak;
vmcase (CONCAT)
state[instr->b].concat(state, state[instr->a], state[instr->c]);
state[instr->b].set(stringobject::create(state, state[instr->a].tostring(state) + state[instr->c].tostring(state)));
vmbreak;
vmcase (MULTIPLY)
state[instr->b].multiply(state, state[instr->a], state[instr->c]);
Expand Down
4 changes: 0 additions & 4 deletions src/vm/software/types/string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@
using namespace lorelai;
using namespace lorelai::vm;

void object::concat(softwarestate &state, object &out, object &other) {
out.set(stringobject::create(state, tostring(state) + other.tostring(state)));
}

object stringobject::create(softwarestate &state, string str) {
auto found = state.stringmap.find(str);
if (found != state.stringmap.end()) {
Expand Down
Loading

0 comments on commit 056ab3a

Please sign in to comment.