Skip to content

Instantly share code, notes, and snippets.

@brn
Created December 24, 2017 14:14
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 brn/817f60791a0c7213d9e985729f35b00d to your computer and use it in GitHub Desktop.
Save brn/817f60791a0c7213d9e985729f35b00d to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
const int kHeapObjectTag = 1;
const int kHeapObjectTagSize = 2;
const intptr_t kHeapObjectTagMask = (1 << kHeapObjectTagSize) - 1;
inline static bool HasHeapObjectTag(const char* value) {
return ((reinterpret_cast<intptr_t>(value) & kHeapObjectTagMask) ==
kHeapObjectTag);
}
class Map {
public:
enum InstanceType {
JS_OBJECT,
JS_ARRAY,
JS_STRING
};
void set_instance_type(InstanceType instance_type) {
instance_type_ = instance_type;
}
InstanceType instance_type() {
return instance_type_;
}
private:
InstanceType instance_type_;
};
const int kHeaderSize = sizeof(Map);
typedef char byte;
typedef char* Address;
class HeapObject {
public:
char value() {return reinterpret_cast<Address>(this)[0];}
Map::InstanceType instance_type() {
return reinterpret_cast<Map*>(
reinterpret_cast<Address>(this) - kHeaderSize)->instance_type();
}
void Free() {
auto top = reinterpret_cast<Address>(this) - kHeaderSize - kHeapObjectTag;
free(top);
}
protected:
static Address NewType(Map::InstanceType instance_type, size_t size) {
auto allocated = reinterpret_cast<Address>(
malloc(sizeof(byte) * (size + kHeaderSize + kHeapObjectTag)));
auto map = reinterpret_cast<Map*>(allocated);
map->set_instance_type(instance_type);
return allocated + kHeaderSize + kHeapObjectTag;
}
};
class JSObject: public HeapObject {
public:
static JSObject* New() {
auto a = NewType(Map::JS_OBJECT, 1);
a[0] = 'o';
return reinterpret_cast<JSObject*>(a);
}
};
class JSArray: public JSObject {
public:
static JSArray* New() {
auto a = NewType(Map::JS_ARRAY, 1);
a[0] = 'a';
return reinterpret_cast<JSArray*>(a);
}
};
class JSString: public JSObject {
public:
static JSString* New() {
auto a = NewType(Map::JS_STRING, 1);
a[0] = 's';
return reinterpret_cast<JSString*>(a);
}
};
int main() {
JSObject* objects[] = {
JSObject::New(),
JSArray::New(),
JSString::New()
};
for (int i = 0; i < 3; i++) {
auto o = objects[i];
switch (o->instance_type()) {
case Map::JS_OBJECT:
printf("%c\n", o->value());
break;
case Map::JS_ARRAY:
printf("%c\n", o->value());
break;
case Map::JS_STRING:
printf("%c\n", o->value());
break;
}
}
for (int i = 0; i < 3; i++) {
objects[i]->Free();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment