Created
December 24, 2017 14:14
-
-
Save brn/817f60791a0c7213d9e985729f35b00d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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