11import { Compiler , Target , ConversionKind , typeToNativeType , typeToNativeOne , typeToNativeZero } from "./compiler" ;
22import { DiagnosticCode } from "./diagnostics" ;
3- import { Node , Expression } from "./ast" ;
3+ import { Node , Expression , IdentifierExpression } from "./ast" ;
44import { Type } from "./types" ;
55import { Module , ExpressionRef , UnaryOp , BinaryOp , HostOp , NativeType , FunctionTypeRef } from "./module" ;
66import { Program , ElementFlags , Element , Global , FunctionPrototype , Local } from "./program" ;
@@ -9,6 +9,9 @@ import { Program, ElementFlags, Element, Global, FunctionPrototype, Local } from
99export function initialize ( program : Program ) : void {
1010
1111 // math
12+ addConstant ( program , "NaN" , Type . f64 ) ;
13+ addConstant ( program , "Infinity" , Type . f64 ) ;
14+
1215 addFunction ( program , "isNaN" , true ) ;
1316 addFunction ( program , "isFinite" , true ) ;
1417 addFunction ( program , "clz" , true ) ;
@@ -96,12 +99,24 @@ export function initialize(program: Program): void {
9699 if ( program . target == Target . WASM64 ) {
97100 program . elements . set ( "isize" , < Element > program . elements . get ( "i64" ) ) ;
98101 program . elements . set ( "usize" , < Element > program . elements . get ( "u64" ) ) ;
102+ addConstant ( program , "HEAP_START" , Type . usize64 ) ;
99103 } else {
100104 program . elements . set ( "isize" , < Element > program . elements . get ( "i32" ) ) ;
101105 program . elements . set ( "usize" , < Element > program . elements . get ( "u32" ) ) ;
106+ addConstant ( program , "HEAP_START" , Type . usize32 ) ;
102107 }
103108}
104109
110+ /** Adds a built-in global to the specified program. */
111+ function addConstant ( program : Program , name : string , type : Type ) : Global {
112+ const global : Global = new Global ( program , name , null , null ) ;
113+ global . isBuiltIn = true ;
114+ global . isConstant = true ;
115+ global . type = type ;
116+ program . elements . set ( name , global ) ;
117+ return global ;
118+ }
119+
105120/** Adds a built-in function to the specified program. */
106121function addFunction ( program : Program , name : string , isGeneric : bool = false ) : FunctionPrototype {
107122 let prototype : FunctionPrototype = new FunctionPrototype ( program , name , name , null , null ) ;
@@ -111,6 +126,29 @@ function addFunction(program: Program, name: string, isGeneric: bool = false): F
111126 return prototype ;
112127}
113128
129+ export function compileGetGlobal ( compiler : Compiler , global : Global ) : ExpressionRef {
130+ switch ( global . internalName ) {
131+
132+ case "NaN" :
133+ if ( compiler . currentType == Type . f32 )
134+ return compiler . module . createF32 ( NaN ) ;
135+ compiler . currentType = Type . f64 ;
136+ return compiler . module . createF64 ( NaN ) ;
137+
138+ case "Infinity" :
139+ if ( compiler . currentType == Type . f32 )
140+ return compiler . module . createF32 ( Infinity ) ;
141+ compiler . currentType = Type . f64 ;
142+ return compiler . module . createF64 ( Infinity ) ;
143+
144+ case "HEAP_START" : // never inlined
145+ return compiler . module . createGetGlobal ( "HEAP_START" , typeToNativeType ( < Type > global . type ) ) ;
146+
147+ default :
148+ throw new Error ( "not implemented: " + global . internalName ) ;
149+ }
150+ }
151+
114152/** Compiles a call to a built-in function. */
115153export function compileCall ( compiler : Compiler , prototype : FunctionPrototype , typeArguments : Type [ ] , operands : Expression [ ] , reportNode : Node ) : ExpressionRef {
116154 const module : Module = compiler . module ;
0 commit comments