Skip to content

Commit

Permalink
Type32 => Type (cause 64 ;)
Browse files Browse the repository at this point in the history
prepared vector shim
  • Loading branch information
pannous committed Apr 26, 2024
1 parent 4ab1222 commit c4d59ac
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 37 deletions.
13 changes: 13 additions & 0 deletions source/Angle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ bool isGlobal(Node &node, Function &function) {
return false;
}


bool isPrimitive(Node &node) {
// should never be cloned so always compare by reference ok?
if (&node == &IntegerType)return true;
Expand Down Expand Up @@ -773,6 +774,18 @@ bool compatibleTypes(Type type1, Type type2) {
return false;
}

// todo ambiguous [2 x] [2,x] so only without space, BUT 2 km??
// do it in parser cause otherwise lists [2,x] would be interpreted as 2*x
Node &groupImplicitMultiplication(Node &node, Function &function) {
Node *left = &node;
Node *right = node.next;
Node *op = new Node("*");
op->setType(operators);
op->add(left);
op->add(right);
return *op;
}

Node &groupGlobal(Node &node, Function &function) {
// todo: turn wasp_main variables into global variables
if (node.length > 1) {
Expand Down
2 changes: 1 addition & 1 deletion source/Code.h
Original file line number Diff line number Diff line change
Expand Up @@ -1269,7 +1269,7 @@ struct Local { // todo: use
String name;
// Valtype type = unknown_type;
// Primitive grrr
Type type;// = unknown_type;
Type type = unknown_type;
Node *typeXX; // todo: REMOVE!
Node *ref;// why still needed?
int data_pointer = 0;// compile time handling of reference data, e.g. after emitData()
Expand Down
9 changes: 7 additions & 2 deletions source/DwarfEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -910,7 +910,7 @@ List<String> readLines(const char *string) {
return content.split("\n");
}

void testSourceMap() {
void testSourceMapHardCoded() {
List<String> names = {"ø" /* index zero = NO NAME, skip optional name index */, "j", "x", "tttt", "main"};
List<SourceMapping> mappings = {
{0x0, 0, 0, 0, 0},
Expand All @@ -932,11 +932,16 @@ void testSourceMap() {
}


void testSourceMap() {
// testSourceMapHardCoded();
assert_emit("int tttt(int j){x=j+1;x};tttt(3)", 4);
}


void testDwarf() {
#if WASM
return;
#endif
testSourceMap();
// DwarfReader reader("samples/test.wasm");
// reader.read();
// reader.print();
Expand Down
3 changes: 1 addition & 2 deletions source/Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1422,7 +1422,6 @@ extern "C" Node *smartNode(smart_pointer_64 smartPointer64) {
}

Node *reconstructArray(int *array_struct) {

// smart pointer to smart array
int kind = *array_struct++;
if (kind == array_header_32 or kind == node_header_32)// todo we know it's array but still. plz fix
Expand Down Expand Up @@ -1457,7 +1456,7 @@ Node *reconstructArray(int *array_struct) {
else if (value_kind == int16)chile = new Node(*(short *) val);
else if ((int) value_kind == longs)chile = new Node(*(int64 *) val);
else if ((int) value_kind == reals)chile = new Node(*(double *) val);
else todo("smartNode of array with element kind "s + typeName(value_kind));
else todo("smartNode of array with element kind "s + typeName((Kind)value_kind));
arr->add(chile);
}
return arr;
Expand Down
13 changes: 9 additions & 4 deletions source/NodeTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,9 @@ extern "C" chars kindName(::Kind t) {
chars typeName(Kind t, bool throws) {
switch (t) {
case 0:
return "ø"; // unknown ?
return "ø"; // undefined or void
case unknown:
return "unknown";
case objects:
return "object";
case groups:
Expand Down Expand Up @@ -316,8 +318,6 @@ chars typeName(Kind t, bool throws) {
return "bool";
case nils:
return "nil";
case unknown :
return "unknown";
case call:
return "call";// function
case declaration:
Expand Down Expand Up @@ -419,7 +419,12 @@ Valtype mapTypeToWasm(Type t) {
}
if (isArrayType(t))
return mapTypeToWasm(array); // wasm_pointer
Node *type_node = (Node *) t.value;
#if WASM
Node *type_node = (Node *) (long) t.value;
#else
Node *type_node = (Node *) (long) t.value;
error("Type32 can't hold pointer on 64bit systems");
#endif
warn("Insecure mapTypeToWasm %x %d as Node*"s % t.value % t.value);
if (type_node->node_header == node_header_32)
return mapTypeToWasm(*type_node);// might crash
Expand Down
43 changes: 24 additions & 19 deletions source/NodeTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ negative_mask_64 = 0xFF00000000000000L,
// 3 * sizeof(int32) header, kind, length before *DATA !
// sizeof(List) - sizeof(S*)

union Type32;
union Type;

const char *typeName(const Type32 *t);
const char *typeName(const Type *t);

// for Opcodes see Code.h

Expand Down Expand Up @@ -152,7 +152,7 @@ extern Node StringType;
// todo dangerous overlap with Valtype in Type!? OK only accessible via mapTypeToWasm
// needs to be stable: Kind is returned in multivalue and thus needs to be parsed by js!
// todo change naming scheme: remove false plural 's' where inappropiate: 'strings' groups … … …
enum Kind {// todo: merge Node.kind with Node.class(?)
enum Kind /* 32 bit*/ {// todo: merge Node.kind with Node.class(?)
// todo smartType4bit first 16 values!!
// plurals because of namespace clash
// TODO add subtypes of Class:Node Variable:Node etc ^^^
Expand Down Expand Up @@ -382,12 +382,14 @@ typedef int Address;
//enum Valtype;// c++ forbids forward references to enums
// todo generic types Array<Type> … via type & array_mask
// todo complicated types Array<struct{…}> … via mask and index into types map à la >>> ref(type_index) <<<
union Type32 {// 64 bit due to pointer! todo: i32 union, 4 bytes with special ranges:
// todo ⚠️ 64 bit due to pointer!
union Type {// 64 bit due to pointer! todo: Type32 i32 union, 4 bytes with special ranges:
/* this union is partitioned in the int space:
0x0000 - Ill defined
0x0001 - 0x1000 : Kinds of Node MUST NOT CLASH with Valtype!?
0x1000 - 0x10000: Classes (just the builtin ones) smarty32 " todo 150_000 classes should be enough for anyone ;)"
// todo memory offset ok? (data 0x1000 …)
// ⚠️ type.value >= 0x10000 means Generics! OR Pointer ??
0x10000 - … 2^60 : Addresses (including pointers to any Node including Node{type=clazz}
//todo endianness?
Expand All @@ -396,25 +398,26 @@ union Type32 {// 64 bit due to pointer! todo: i32 union, 4 bytes with special ra
*/

// todo: this union is BAD because we can not READ it safely, instead we need mapType / extractors for all combinations!
uint64 value = 0; // one of:
// SmartPointer64 smarty;
unsigned int value = 0;
// uint64 value = 0;
// one of:
// SmartPointer32 smarty;// when separating Types from values we don't need smart pointers
Kind kind; // Node of this type
Generics generics;
// Valtype valtype; // doesn't make sense here but try to avoid(guarantee?) overlap with type enum for future compatibility?
Primitive type;// c_string int_array long_array float_array etc, can also be type of value.data in boxed Node
// Node *clazz;// same as // 64 bit on normal systems!!!!
Address address;// pointer to Node
// Node *clazz;// same as Address // 64 bit on normal systems!!!!
// Valtype valtype; // doesn't make sense here but try to avoid(guarantee?) overlap with type enum for future compatibility?

Type32() {
Type() {
}


Type32(Type32 *o) {
Type(Type *o) {
value = o->value;
}

Type32(Node *o) {
Type(Node *o) {
if (!o) {
this->kind = Kind::nils;
return;
Expand All @@ -438,20 +441,20 @@ union Type32 {// 64 bit due to pointer! todo: i32 union, 4 bytes with special ra
// error("TODO Type32(const Node &o)");
// }

Type32(unsigned int value) {
Type(unsigned int value) {
this->value = value;
}

Type32(Generics generics) {
Type(Generics generics) {
this->generics = generics;
}

Type32(Primitive primitive) {
Type(Primitive primitive) {
type = primitive;
}


Type32(Kind kind) {
Type(Kind kind) {
this->kind = kind;
if ((int) kind > 0x1000)
error("erroneous or unsafe Type construction");
Expand Down Expand Up @@ -490,7 +493,7 @@ union Type32 {// 64 bit due to pointer! todo: i32 union, 4 bytes with special ra

explicit operator const char *() const { return typeName(this); }

bool operator==(Type32 other) {
bool operator==(Type other) {
return value == other.value;
}

Expand Down Expand Up @@ -519,15 +522,17 @@ union Type32 {// 64 bit due to pointer! todo: i32 union, 4 bytes with special ra
}
};

typedef Type32 Type;
//if (type.value >= 0x10000) means Generics!
//typedef Type32 Type;
//typedef Type64 Type;

Type valueType(Type type);

Type genericType(Type type, Type value_type);

union Generics64 {
Type32 kind;
Type32 value_type;
Type kind;
Type value_type;
};

// on 64bit systems pointers (to types)
Expand Down
2 changes: 1 addition & 1 deletion source/String.h
Original file line number Diff line number Diff line change
Expand Up @@ -1243,7 +1243,7 @@ void print(String);

void print(Type);

void print(Type32);
void print(Type);

void println(Node &s);

Expand Down
3 changes: 3 additions & 0 deletions source/Wasp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,9 @@ class Wasp {
// error("Bad number");
// } else {
if (base != 10) todo("base "s + base);
if(is_identifier(ch))
print("IMPLICIT MULTIPLICATION!?"); // now what?
// ch!=' ' and not is_operator(ch) and not isWhiteSpace(ch) and not is_bracket(ch) and not is_grouper(ch) and not and not is_operator(ch) and isDigit(ch)
return *new Node(number0); // {number0}; //wow cPP
// }
};
Expand Down
7 changes: 5 additions & 2 deletions source/test_wasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,13 @@ void testEmitter() {
#endif
}

void test_implicit_multiplication(){
assert_emit("x=3;2x", 6);
assert_emit("2π", 2 * pi);
}

void testGlobals() {
assert_emit("π", pi);
assert_emit("2π", 2 * pi);
assert_emit("2*π", 2*pi);
assert_emit("dub:=it*2;dub(π)", 2 * pi);
}

Expand Down
20 changes: 15 additions & 5 deletions source/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ void testVectorShim() {
assert_emit("v=[1 2 3];w=[2 3 4];v*w", 2 + 6 + 12);
}




void testHtmlWasp() {
eval("html{bold{Hello}}"); // => <html><body><bold>Hello</bold></body></html> via appendChild bold to body
// eval("html{bold($myid style=red){Hello}}"); // => <bold id=myid style=red>Hello</bold>
Expand Down Expand Up @@ -2429,7 +2432,6 @@ void testStringConcatenation() {
}

void testString() {

String *a = new String("abc");
String b = String("abc");
String c = *a;
Expand Down Expand Up @@ -2929,6 +2931,8 @@ void testBUG();

void testEmitBasics();

void testSourceMap();

void testNodeDataBinaryReconstruction() {
check_is(parse("y:{x:2 z:3}").serialize(), "y{x:2 z:3}");// todo y:{} vs y{}
assert_emit("y:{x:2 z:3}", parse("y:{x:2 z:3}"));// looks trivial but is epitome of binary (de)serialization!
Expand Down Expand Up @@ -3161,7 +3165,9 @@ void assurances() {
#if WASM
// check(sizeof(Type32) == 4) // todo:
#else
check(sizeof(Type) == 8) // otherwise all header structs fall apart
// check(sizeof(Type32) == 4) // otherwise all header structs fall apart
check(sizeof(Type64) == 8) // otherwise all header structs fall apart
// check(sizeof(Type) == 8) // otherwise all header structs fall apart
#endif
// check(sizeof(void*)==4) // otherwise all header structs fall apart TODO adjust in 64bit wasm / NORMAL arm64 !!
check(sizeof(int64) == 8)
Expand Down Expand Up @@ -3368,11 +3374,14 @@ void pleaseFix() {
// 2022-12-28 : 3 sec WITH runtime_emit, wasmedge on M1 WOW ALL TESTS PASSING
// ⚠️ CANNOT USE assert_emit in WASM! ONLY via void testRun();
void testCurrent() {
// assert_emit("dub:=it*2;dub(3)", 6);
assert_emit("dub:=it*2;dub(π)", 2 * pi);
// test_implicit_multiplication(); todo in parser how?
// testGlobals();
// testTypeConfusion();
return;
assert_is("1 2 3", Node(1, 2, 3, 0))

// testVectorShim();// use GPU even before wasm vector extension is available
// testSourceMap();
// return;

// testDwarf();
// testFibonacci();
Expand Down Expand Up @@ -3430,4 +3439,5 @@ void testCurrent() {
#endif
print("CURRENT TESTS PASSED");
}

// valgrind --track-origins=yes ./wasp
8 changes: 7 additions & 1 deletion source/wasm_emitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,8 @@ Code emitArray(Node &node, Function &context) {
short itemSize = arrayElementSize(node);
wasm_node_index typ_index = 0;
if (!node.type) /*node.type=*/addTypeFromSize(node, itemSize);
if (node.type) typ_index = emitNodeBinary(*node.type, context);// danger! Byte now lives inside wasm!
if (node.type) // save meta information about (generic) type!
typ_index = emitNodeBinary(*node.type, context);// danger! Byte now lives inside wasm!

let code = Code();
emitPaddingAlignment(8);
Expand Down Expand Up @@ -1628,6 +1629,8 @@ Code emitOperator(Node &node, Function &context) {
const Code &lhs_code = emitExpression(lhs, context);
Type lhs_type = last_type;
arg_type = last_type;// needs to be visible to array index [1,2,3]#1 gets FUCKED up in rhs operations!!
if(isGeneric(last_type))
arg_type = last_type.generics.value_type;
const Code &rhs_code = emitExpression(rhs, context);
Type rhs_type = last_type;
Type common_type = commonType(lhs_type, rhs_type);// 3.1 + 3 => 6.1 etc
Expand Down Expand Up @@ -1691,6 +1694,8 @@ Code emitOperator(Node &node, Function &context) {
code.addByte(i64_reinterpret_f64);// f32->i32 i32_trunc_f32_s would also work, but reinterpret is cheaper
code.addByte(i64_eqz);
last_type = i32t;// bool'ish
} else if (name == "*" and isArrayType(last_type)) {
code.add(emitCall(*new Node("matrix_multiply"), context)); // gpu / vector shim
} else if (name == "++" or name == "--") {
Node increased = Node(name[0]).setType(operators);
increased.add(first); // if not first emitted
Expand Down Expand Up @@ -2331,6 +2336,7 @@ Code cast(Type from, Type to) {
if (from == charp and to == i32t)return nop;// assume i32 is a pointer here. todo?
if (from == array and to == i32)return nop;// pray / assume i32 is a pointer here. todo!
if (from == charp and to == strings)return nop;
if(isGeneric(from) and isGeneric(to))return nop;
if (from == codepoint1 and to == i64t)
return Code(i64_extend_i32_s);
if (from == array and to == i64)return Code(i64_extend_i32_u);;// pray / assume i32 is a pointer here. todo!
Expand Down

0 comments on commit c4d59ac

Please sign in to comment.