// Generates code that can be placed inline in generated code. // This is not the cleanest way to write this kind of code - it is // optimized for generating fast inline code. RuntimeGenerator = { alloc: function(target, size, type) { var ret = target + ' = ' + type + 'TOP; ' + type + 'TOP += ' + size + ';'; if (QUANTUM_SIZE > 1) { ret += RuntimeGenerator.alignMemory(type + 'TOP'); } return ret; }, // An allocation that lives as long as the current function call stackAlloc: function(target, size) { var ret = RuntimeGenerator.alloc(target, size, 'STACK'); if (GUARD_STACK) { ret += ' assert(STACKTOP < STACK_ROOT + STACK_MAX);'; } return ret; }, stackEnter: function() { return 'STACK_STACK.push(STACKTOP);'; }, stackExit: function() { return 'STACKTOP = STACK_STACK.pop();'; }, // An allocation that cannot be free'd staticAlloc: function(target, size) { return RuntimeGenerator.alloc(target, size, 'STATIC'); }, alignMemory: function(target) { return target + ' = Math.ceil(' + target + '/QUANTUM_SIZE)*QUANTUM_SIZE;'; }, }; function unInline(name_, params) { var src = '(function ' + name_ + '(' + params + ') { var ret; ' + RuntimeGenerator[name_].apply(null, ['ret'].concat(params)) + ' return ret; })'; print('src: ' + src); return eval(src); } // Uses the RuntimeGenerator during compilation, in order to // 1. Let the compiler access and run those functions during compilation // 2. We expose the entire Runtime object to generated code, so it can // use that functionality in a non-inline manner. Runtime = { stackAlloc: unInline('stackAlloc', ['size']), staticAlloc: unInline('staticAlloc', ['size']), }; function getRuntime() { var ret = ''; for (i in Runtime) { ret += Runtime[i].toString() + '\n'; } return ret; }