46 friend class IndexContextGuard;
49 explicit Compiler(
Engine &engine);
52 std::shared_ptr<const std::string> sourceCode =
nullptr);
56 std::shared_ptr<const std::string> sourceCode =
nullptr);
63 void registerFunction(
const ASTNode *funcDef);
70 void registerFunctionAs(
const std::string &qualifiedName,
84 const std::unordered_map<std::string, BytecodeChunk> &compiledFuncs()
const
86 return compiledFuncs_;
88 void clearCompiledFuncs() { compiledFuncs_.clear(); }
91 void eraseCompiledFunc(
const std::string &name) { compiledFuncs_.erase(name); }
96 void eraseCompiledFuncsForClass(
const std::string &className);
103 const std::unordered_map<std::string, BytecodeChunk> &scriptLocalCompiledFuncs()
const
105 return scriptLocalCompiledFuncs_;
111 const BytecodeChunk *findCompiled(
const std::string &name)
const;
118 void beginScriptScope();
119 void endScriptScope();
120 bool inScriptScope()
const {
return scriptDepth_ > 0; }
125 void promoteScriptLocalsToWorkspace();
137 std::unordered_map<std::string, uint8_t> varRegisters_;
154 int anonCounter_ = 0;
155 bool isTopLevel_ =
false;
158 bool inFusionFallback_ =
false;
159 uint8_t nargoutContext_ = 1;
162 uint8_t indexContextArr_ = 0;
163 uint8_t indexContextDim_ = 0;
164 uint8_t indexContextNdims_ = 1;
171 std::unordered_map<std::string, BytecodeChunk> compiledFuncs_;
176 std::unordered_set<std::string> uncompilableClassMethods_;
183 std::unordered_map<std::string, BytecodeChunk> scriptLocalCompiledFuncs_;
184 std::vector<std::unordered_map<std::string, BytecodeChunk>> savedScriptLocalCompiledFuncs_;
185 int scriptDepth_ = 0;
209 uint8_t varRegWrite(
const std::string &name);
210 uint8_t varRegRead(
const std::string &name);
217 uint8_t varRegLookup(
const std::string &name,
bool preloadReserved =
true);
218 void markAssigned(
const std::string &name) { chunk_.assignedVars.insert(name); }
220 void preImportGlobals(
const ASTNode *ast);
221 void collectAllIdentifiers(
const ASTNode *node, std::unordered_set<std::string> &out);
225 void collectAssignedNames(
const ASTNode *node, std::vector<std::string> &out);
234 void preallocateAssignedVars(
const ASTNode *body);
240 void emitABC(OpCode op, uint8_t a, uint8_t b, uint8_t c);
241 void emitAB(OpCode op, uint8_t a, uint8_t b);
242 void emitAD(OpCode op, uint8_t a, int16_t d);
243 void emitA(OpCode op, uint8_t a);
244 void emitD(OpCode op, int16_t d);
245 void emitNone(OpCode op);
248 size_t currentPos()
const;
251 void patchJump(
size_t instrPos, int32_t offset);
254 int16_t addConstant(
double value);
255 int16_t addStringConstant(
const std::string &s);
258 int16_t appendConstant(
Value v);
259 int16_t appendString(
const std::string &s);
264 uint8_t reserveRegs(
size_t n);
273 uint8_t compileNode(
const ASTNode *node);
274 uint8_t compileNodeExpand(
const ASTNode *node);
275 uint8_t compileBlock(
const ASTNode *node);
276 uint8_t compileNumber(
const ASTNode *node);
277 uint8_t compileString(
const ASTNode *node);
278 uint8_t compileBool(
const ASTNode *node);
279 uint8_t compileIdentifier(
const ASTNode *node);
280 uint8_t compileAssign(
const ASTNode *node);
281 uint8_t compileMultiAssign(
const ASTNode *node);
282 uint8_t compileBinaryOp(
const ASTNode *node);
283 uint8_t compileUnaryOp(
const ASTNode *node);
284 uint8_t compileExprStmt(
const ASTNode *node);
287 uint8_t compileIf(
const ASTNode *node);
288 uint8_t compileSwitch(
const ASTNode *node);
289 uint8_t compileTryCatch(
const ASTNode *node);
290 uint8_t compileGlobalPersistent(
const ASTNode *node);
291 uint8_t compileFieldAccess(
const ASTNode *node);
292 uint8_t compileFieldAssign(
const ASTNode *node);
293 uint8_t compileCellLiteral(
const ASTNode *node);
294 uint8_t compileCellIndex(
const ASTNode *node);
295 uint8_t compileCellAssign(
const ASTNode *node);
301 uint8_t compileFieldStore(
const ASTNode *lhs,
const ASTNode *rhsNode,
302 int inValReg,
bool suppress);
303 uint8_t compileCellStore(
const ASTNode *lhs,
const ASTNode *rhsNode,
304 int inValReg,
bool suppress);
305 uint8_t compileIndexStore(
const ASTNode *lhs,
const ASTNode *rhsNode,
306 int inValReg,
bool suppress);
308 void compileStoreLValue(
const ASTNode *target, uint8_t valReg,
bool suppress);
314 bool needsGeneralLValuePath(
const ASTNode *lhs)
const;
319 uint8_t compileLValueStore(
const ASTNode *lhs,
const ASTNode *rhsNode,
320 int inValReg,
bool suppress);
327 uint8_t compileSuperCall(
const ASTNode *callNode,
const ASTNode *superRef,
328 int explicitOutBase, uint8_t nout);
329 uint8_t compileAnonFunc(
const ASTNode *node);
330 void collectFreeVars(
const ASTNode *node,
331 const std::vector<std::string> ¶ms,
332 std::vector<std::string> &freeVars);
333 uint8_t compileWhile(
const ASTNode *node);
334 uint8_t compileBreak(
const ASTNode *node);
335 uint8_t compileContinue(
const ASTNode *node);
338 uint8_t compileFor(
const ASTNode *node);
339 uint8_t compileColonExpr(
const ASTNode *node);
340 uint8_t compileMatrixLiteral(
const ASTNode *node);
341 uint8_t compileIndexExpr(
const ASTNode *node);
342 uint8_t compileIndexAssign(
const ASTNode *node);
345 uint8_t compileCall(
const ASTNode *node);
352 int tryCompileFused(
const ASTNode *node);
356 uint8_t compileFused(
const ASTNode *node,
size_t ruleIdx,
357 const std::vector<const ASTNode *> &operands);
358 uint8_t compileCommandCall(
const ASTNode *node);
361 void recordCallArgNames(
const ASTNode *callNode,
size_t callInstrIdx);
362 uint8_t compileFunctionDef(
const ASTNode *node);
363 uint8_t compileReturn(
const ASTNode *node);
366 void emitVarargoutReturn();
367 uint8_t compileDeleteAssign(
const ASTNode *node);
368 static int8_t resolveBuiltinId(
const std::string &name,
size_t nargs);
372 std::unordered_map<int16_t, uint8_t> constRegCache_;
376 std::bitset<256> scalarRegs_;
379 void peepholeOptimize();
384 std::vector<size_t> breakPatches;
385 std::vector<size_t> continuePatches;
386 bool isForLoop =
false;
388 std::vector<LoopContext> loopStack_;