1 // Copyright (c) 1996 James Clark
2 // See the file copying.txt for copying permission.
5 #define Insn_INCLUDED 1
13 #ifdef DSSSL_NAMESPACE
14 namespace DSSSL_NAMESPACE {
21 class Insn : public Resource {
24 virtual const Insn *execute(VM &) const = 0;
25 virtual bool isReturn(int &nArgs) const;
26 virtual bool isPopBindings(int &n, ConstPtr<Insn> &) const;
29 typedef ConstPtr<Insn> InsnPtr;
31 class ErrorInsn : public Insn {
33 const Insn *execute(VM &) const;
36 class CondFailInsn : public ErrorInsn {
38 CondFailInsn(const Location &loc);
39 const Insn *execute(VM &) const;
44 class CaseFailInsn : public ErrorInsn {
46 CaseFailInsn(const Location &loc);
47 const Insn *execute(VM &) const;
52 class ConstantInsn : public Insn {
54 ConstantInsn(ELObj *, InsnPtr);
55 const Insn *execute(VM &) const;
61 class ResolveQuantitiesInsn : public Insn {
63 ResolveQuantitiesInsn(const Location &, InsnPtr);
64 const Insn *execute(VM &) const;
70 class TestInsn : public Insn {
72 TestInsn(InsnPtr, InsnPtr);
73 const Insn *execute(VM &) const;
79 class OrInsn : public Insn {
81 OrInsn(InsnPtr nextTest, InsnPtr next);
82 const Insn *execute(VM &) const;
88 class AndInsn : public Insn {
90 AndInsn(InsnPtr nextTest, InsnPtr next);
91 const Insn *execute(VM &) const;
97 class CaseInsn : public Insn {
99 CaseInsn(ELObj *, InsnPtr match, InsnPtr fail);
100 const Insn *execute(VM &) const;
107 class PopInsn : public Insn {
109 PopInsn(InsnPtr next);
110 const Insn *execute(VM &) const;
115 class ConsInsn : public Insn {
117 ConsInsn(InsnPtr next);
118 const Insn *execute(VM &) const;
123 class AppendInsn : public Insn {
125 AppendInsn(const Location &, InsnPtr next);
126 const Insn *execute(VM &) const;
132 class ApplyBaseInsn : public Insn {
134 ApplyBaseInsn(int nArgs, const Location &);
136 FunctionObj *decodeArgs(VM &) const;
141 class ApplyInsn : public ApplyBaseInsn {
143 ApplyInsn(int nArgs, const Location &, InsnPtr);
144 const Insn *execute(VM &) const;
149 class TailApplyInsn : public ApplyBaseInsn {
151 TailApplyInsn(int nCallerArgs, int nArgs, const Location &);
152 const Insn *execute(VM &) const;
157 class FrameRefInsn : public Insn {
159 FrameRefInsn(int index, InsnPtr next);
160 const Insn *execute(VM &vm) const;
166 class StackRefInsn : public Insn {
168 StackRefInsn(int index, int frameIndex, InsnPtr next);
169 const Insn *execute(VM &vm) const;
171 int index_; // always negative
176 class ClosureRefInsn : public Insn {
178 ClosureRefInsn(int index, InsnPtr next);
179 const Insn *execute(VM &vm) const;
185 class StackSetBoxInsn : public Insn {
187 StackSetBoxInsn(int index, int frameIndex, const Location &loc, InsnPtr next);
188 const Insn *execute(VM &vm) const;
190 int index_; // always negative
196 class StackSetInsn : public Insn {
198 StackSetInsn(int index, int frameIndex, InsnPtr next);
199 const Insn *execute(VM &vm) const;
201 int index_; // always negative
206 class ClosureSetBoxInsn : public Insn {
208 ClosureSetBoxInsn(int index, const Location &loc, InsnPtr next);
209 const Insn *execute(VM &vm) const;
216 class TopRefInsn : public Insn {
218 TopRefInsn(const Identifier *var, InsnPtr next);
219 const Insn *execute(VM &vm) const;
221 const Identifier *var_;
226 class PopBindingsInsn : public Insn {
228 const Insn *execute(VM &vm) const;
229 bool isPopBindings(int &n, InsnPtr &) const;
230 static InsnPtr make(int n, InsnPtr next);
232 PopBindingsInsn(int n, InsnPtr next);
239 class PrimitiveCallInsn : public Insn {
241 PrimitiveCallInsn(int nArgs, PrimitiveObj *, const Location &, InsnPtr);
242 const Insn *execute(VM &) const;
255 const Identifier *const *keys;
258 // This Insn constructs a ClosureObj.
260 class ClosureInsn : public Insn {
262 ClosureInsn(const Signature *, InsnPtr code, int displayLength, InsnPtr next);
263 const Insn *execute(VM &) const;
265 const Signature *sig_;
273 class FunctionCallInsn : public Insn {
275 FunctionCallInsn(int nArgs, FunctionObj *, const Location &, InsnPtr);
276 const Insn *execute(VM &) const;
279 FunctionObj *function_; // must be permanent
284 class FunctionTailCallInsn : public Insn {
286 FunctionTailCallInsn(int nArgs, FunctionObj *, const Location &,
288 const Insn *execute(VM &) const;
291 FunctionObj *function_; // must be permanent
296 class VarargsInsn : public Insn {
298 VarargsInsn(const Signature &, Vector<InsnPtr> &entryPoints,
300 const Insn *execute(VM &) const;
302 const Signature *sig_;
303 Vector<InsnPtr> entryPoints_;
307 class SetKeyArgInsn : public Insn {
309 SetKeyArgInsn(int offset, InsnPtr);
310 const Insn *execute(VM &) const;
316 class TestNullInsn : public Insn {
318 TestNullInsn(int offset, InsnPtr ifNull, InsnPtr ifNotNull);
319 const Insn *execute(VM &) const;
327 class ReturnInsn : public Insn {
329 ReturnInsn(int totalArgs);
330 const Insn *execute(VM &) const;
331 bool isReturn(int &nArgs) const;
336 class FunctionObj : public ELObj {
338 FunctionObj(const Signature *sig) : sig_(sig) { }
344 virtual const Insn *call(VM &vm, const Location &, const Insn *next) = 0;
345 virtual const Insn *tailCall(VM &vm, const Location &, int nCallerArgs) = 0;
346 virtual InsnPtr makeCallInsn(int nArgs, Interpreter &, const Location &,
348 virtual InsnPtr makeTailCallInsn(int nArgs, Interpreter &,
349 const Location &, int nCallerArgs);
350 const Signature &signature() const { return *sig_; }
351 FunctionObj *asFunction();
352 virtual void setArgToCC(VM &);
354 const Signature *sig_;
357 class PrimitiveObj : public FunctionObj {
359 PrimitiveObj(const Signature *sig) : FunctionObj(sig) { }
360 const Insn *call(VM &vm, const Location &, const Insn *next);
361 const Insn *tailCall(VM &vm, const Location &, int nCallerArgs);
362 InsnPtr makeCallInsn(int nArgs, Interpreter &, const Location &, InsnPtr next);
363 virtual ELObj *primitiveCall(int nArgs, ELObj **args, EvalContext &, Interpreter &,
364 const Location &) = 0;
365 void setIdentifier(const Identifier *ident);
367 ELObj *argError(Interpreter &, const Location &,
368 const MessageType3 &, unsigned, ELObj *) const;
369 ELObj *noCurrentNodeError(Interpreter &, const Location &) const;
371 const Identifier *ident_;
374 class ApplyPrimitiveObj : public FunctionObj {
377 const Insn *call(VM &vm, const Location &, const Insn *next);
378 const Insn *tailCall(VM &vm, const Location &, int nCallerArgs);
380 bool shuffle(VM &vm, const Location &loc);
381 static const Signature signature_;
384 class CallWithCurrentContinuationPrimitiveObj : public FunctionObj {
386 CallWithCurrentContinuationPrimitiveObj();
387 const Insn *call(VM &vm, const Location &, const Insn *next);
388 const Insn *tailCall(VM &vm, const Location &, int nCallerArgs);
390 static const Signature signature_;
393 class ClosureObj : public FunctionObj {
395 void *operator new(size_t, Collector &c) {
396 return c.allocateObject(1);
398 ClosureObj(const Signature *, InsnPtr, ELObj **display);
399 ~ClosureObj() { delete [] display_; }
401 const Insn *call(VM &, const Location &, const Insn *);
402 const Insn *tailCall(VM &, const Location &, int nCallerArgs);
403 void traceSubObjects(Collector &) const;
404 ELObj *display(int) const;
405 void setArgToCC(VM &);
408 // terminated by null pointer.
413 class ContinuationObj : public FunctionObj {
416 const Insn *call(VM &, const Location &, const Insn *);
417 const Insn *tailCall(VM &, const Location &, int nCallerArgs);
418 void set(size_t stackSize, size_t controlStackSize) {
419 stackSize_ = stackSize;
420 controlStackSize_ = controlStackSize;
422 void kill() { controlStackSize_ = 0; }
423 bool live() const { return controlStackSize_ > 0; }
426 size_t controlStackSize_;
427 static const Signature signature_;
430 class BoxObj : public ELObj {
435 void traceSubObjects(Collector &) const;
439 class SetBoxInsn : public Insn {
441 SetBoxInsn(int n, InsnPtr next);
442 const Insn *execute(VM &vm) const;
448 class SetImmediateInsn : public Insn {
450 SetImmediateInsn(int n, InsnPtr next);
451 const Insn *execute(VM &vm) const;
457 class UnboxInsn : public Insn {
459 UnboxInsn(InsnPtr next);
460 const Insn *execute(VM &vm) const;
465 class CheckInitInsn : public Insn {
467 CheckInitInsn(const Identifier *ident, const Location &, InsnPtr next);
468 const Insn *execute(VM &vm) const;
470 const Identifier *ident_;
475 class BoxInsn : public Insn {
477 BoxInsn(InsnPtr next);
478 const Insn *execute(VM &vm) const;
483 class BoxArgInsn : public Insn {
485 BoxArgInsn(int n, InsnPtr next);
486 const Insn *execute(VM &vm) const;
492 class BoxStackInsn : public Insn {
494 BoxStackInsn(int n, InsnPtr next);
495 const Insn *execute(VM &vm) const;
501 class VectorInsn : public Insn {
503 VectorInsn(size_t n, InsnPtr next);
504 const Insn *execute(VM &vm) const;
510 class ListToVectorInsn : public Insn {
512 ListToVectorInsn(InsnPtr next);
513 const Insn *execute(VM &vm) const;
519 int FunctionObj::nRequiredArgs()
521 return signature().nRequiredArgs;
525 int FunctionObj::nOptionalArgs()
527 return signature().nOptionalArgs;
531 bool FunctionObj::restArg()
533 return signature().restArg;
537 int FunctionObj::nKeyArgs()
539 return signature().nKeyArgs;
543 int FunctionObj::totalArgs()
545 const Signature &sig = signature();
546 return sig.nRequiredArgs + sig.nOptionalArgs + sig.nKeyArgs + sig.restArg;
550 void PrimitiveObj::setIdentifier(const Identifier *ident)
556 ELObj *ClosureObj::display(int i) const
561 #ifdef DSSSL_NAMESPACE
565 #endif /* not Insn_INCLUDED */