Builtin functions for memory.grow and memory.size
This commit is contained in:
parent
6890c78743
commit
0c23c326ac
@ -385,7 +385,45 @@ func (c *Compiler) compileExpressionWAT(expr Expression) (string, error) {
|
||||
}
|
||||
}
|
||||
|
||||
return wat + "call $" + fc.Function + "\n", nil
|
||||
switch fc.Function {
|
||||
case BUILTIN_MEMORY_GROW:
|
||||
if !c.Wasm64 {
|
||||
cast, err := castPrimitiveWAT(Primitive_U64, Primitive_U32)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
wat += cast
|
||||
}
|
||||
|
||||
wat += "memory.grow\n"
|
||||
|
||||
if !c.Wasm64 {
|
||||
cast, err := castPrimitiveWAT(Primitive_I32, Primitive_I64)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
wat += cast
|
||||
}
|
||||
|
||||
return wat, nil
|
||||
case BUILTIN_MEMORY_SIZE:
|
||||
wat += "memory.size\n"
|
||||
|
||||
if !c.Wasm64 {
|
||||
cast, err := castPrimitiveWAT(Primitive_U32, Primitive_U64)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
wat += cast
|
||||
}
|
||||
|
||||
return wat, nil
|
||||
default:
|
||||
return wat + "call $" + fc.Function + "\n", nil
|
||||
}
|
||||
case Expression_Unary:
|
||||
unary := expr.Value.(UnaryExpression)
|
||||
exprType := expr.ValueType.Value.(PrimitiveType)
|
||||
|
4
lexer.go
4
lexer.go
@ -113,6 +113,10 @@ type Lexer struct {
|
||||
Position uint64
|
||||
}
|
||||
|
||||
func unknownPosition() TokenPosition {
|
||||
return TokenPosition{SourceFile: "", Position: 0}
|
||||
}
|
||||
|
||||
func (l *Lexer) error(message string) error {
|
||||
return CompilerError{Position: TokenPosition{SourceFile: l.SourceFile, Position: l.LastTokenPosition}, Message: message}
|
||||
}
|
||||
|
@ -9,5 +9,14 @@ void free(u64 address) {
|
||||
}
|
||||
|
||||
u64 growMemory(u64 numPages) {
|
||||
return 0u64;
|
||||
i64 value = __builtin_memory_grow(numPages);
|
||||
if(value == -1) {
|
||||
return 0u64;
|
||||
}
|
||||
|
||||
return __builtin_memory_size();
|
||||
}
|
||||
|
||||
u64 memorySize() {
|
||||
return __builtin_memory_size();
|
||||
}
|
||||
|
70
validator.go
70
validator.go
@ -14,6 +14,26 @@ type Validator struct {
|
||||
CurrentFunction *ParsedFunction
|
||||
}
|
||||
|
||||
const (
|
||||
BUILTIN_MEMORY_GROW = "__builtin_memory_grow"
|
||||
BUILTIN_MEMORY_SIZE = "__builtin_memory_size"
|
||||
)
|
||||
|
||||
var builtinFunctions map[string]*ParsedFunction = map[string]*ParsedFunction{
|
||||
BUILTIN_MEMORY_GROW: {
|
||||
Name: BUILTIN_MEMORY_GROW,
|
||||
FullName: "builtin." + BUILTIN_MEMORY_GROW,
|
||||
Parameters: []ParsedParameter{{Name: "memory", Type: Type{Type: Type_Primitive, Value: Primitive_U64, Position: unknownPosition()}}},
|
||||
ReturnType: &Type{Type: Type_Primitive, Value: Primitive_I64, Position: unknownPosition()},
|
||||
},
|
||||
BUILTIN_MEMORY_SIZE: {
|
||||
Name: BUILTIN_MEMORY_SIZE,
|
||||
FullName: "builtin." + BUILTIN_MEMORY_SIZE,
|
||||
Parameters: []ParsedParameter{},
|
||||
ReturnType: &Type{Type: Type_Primitive, Value: Primitive_U64, Position: unknownPosition()},
|
||||
},
|
||||
}
|
||||
|
||||
func isSameType(a Type, b Type) bool {
|
||||
if a.Type != b.Type {
|
||||
return false
|
||||
@ -294,10 +314,13 @@ func (v *Validator) validatePotentiallyVoidExpression(expr *Expression) []error
|
||||
case Expression_FunctionCall:
|
||||
fc := expr.Value.(FunctionCallExpression)
|
||||
|
||||
calledFunc, ok := v.AllFunctions[fc.Function]
|
||||
calledFunc, ok := builtinFunctions[fc.Function]
|
||||
if !ok {
|
||||
errors = append(errors, v.createError("call to undefined function '"+fc.Function+"'", expr.Position))
|
||||
return errors
|
||||
calledFunc, ok = v.AllFunctions[fc.Function]
|
||||
if !ok {
|
||||
errors = append(errors, v.createError("call to undefined function '"+fc.Function+"'", expr.Position))
|
||||
return errors
|
||||
}
|
||||
}
|
||||
|
||||
if fc.Parameters != nil {
|
||||
@ -306,27 +329,32 @@ func (v *Validator) validatePotentiallyVoidExpression(expr *Expression) []error
|
||||
errors = append(errors, paramsErrors...)
|
||||
return errors
|
||||
}
|
||||
}
|
||||
|
||||
params := []*Expression{fc.Parameters}
|
||||
if fc.Parameters.Type == Expression_Tuple {
|
||||
for i := 0; i < len(fc.Parameters.Value.(TupleExpression).Members); i++ {
|
||||
params[i] = &fc.Parameters.Value.(TupleExpression).Members[i]
|
||||
}
|
||||
var params []*Expression
|
||||
if fc.Parameters == nil {
|
||||
params = []*Expression{}
|
||||
} else if fc.Parameters.Type == Expression_Tuple {
|
||||
params = make([]*Expression, len(fc.Parameters.Value.(TupleExpression).Members))
|
||||
for i := 0; i < len(fc.Parameters.Value.(TupleExpression).Members); i++ {
|
||||
params[i] = &fc.Parameters.Value.(TupleExpression).Members[i]
|
||||
}
|
||||
} else {
|
||||
params = []*Expression{fc.Parameters}
|
||||
}
|
||||
|
||||
if len(params) != len(calledFunc.Parameters) {
|
||||
errors = append(errors, v.createError("wrong number of arguments in function call: expected "+strconv.Itoa(len(calledFunc.Parameters))+", got "+strconv.Itoa(len(params)), expr.Position))
|
||||
}
|
||||
|
||||
for i := 0; i < min(len(params), len(calledFunc.Parameters)); i++ {
|
||||
typeGiven := params[i]
|
||||
typeExpected := calledFunc.Parameters[i]
|
||||
if !isTypeExpandableTo(*typeGiven.ValueType, typeExpected.Type) {
|
||||
errors = append(errors, v.createError("invalid type for parameter "+strconv.Itoa(i)+": expected "+typeExpected.Type.String()+", got "+typeGiven.ValueType.String(), expr.Position))
|
||||
}
|
||||
|
||||
if len(params) != len(calledFunc.Parameters) {
|
||||
errors = append(errors, v.createError("wrong number of arguments in function call: expected "+strconv.Itoa(len(calledFunc.Parameters))+", got "+strconv.Itoa(len(params)), expr.Position))
|
||||
}
|
||||
|
||||
for i := 0; i < min(len(params), len(calledFunc.Parameters)); i++ {
|
||||
typeGiven := params[i]
|
||||
typeExpected := calledFunc.Parameters[i]
|
||||
if !isTypeExpandableTo(*typeGiven.ValueType, typeExpected.Type) {
|
||||
errors = append(errors, v.createError("invalid type for parameter "+strconv.Itoa(i), expr.Position))
|
||||
}
|
||||
|
||||
expandExpressionToType(typeGiven, typeExpected.Type)
|
||||
}
|
||||
expandExpressionToType(typeGiven, typeExpected.Type)
|
||||
}
|
||||
|
||||
expr.ValueType = calledFunc.ReturnType
|
||||
|
Loading…
Reference in New Issue
Block a user