1.1 --- a/src/compiler/HIR.h Mon Jun 10 00:46:29 2013 +0100
1.2 +++ b/src/compiler/HIR.h Mon Jun 10 01:04:43 2013 +0100
1.3 @@ -1,607 +1,607 @@
1.4 -/*
1.5 - * Copyright (C) 2012 David Anderson
1.6 - *
1.7 - * This file is part of SourcePawn.
1.8 - *
1.9 - * SourcePawn is free software: you can redistribute it and/or modify it under
1.10 - * the terms of the GNU General Public License as published by the Free
1.11 - * Software Foundation, either version 3 of the License, or (at your option)
1.12 - * any later version.
1.13 - *
1.14 - * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
1.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
1.17 - *
1.18 - * You should have received a copy of the GNU General Public License along with
1.19 - * SourcePawn. If not, see http://www.gnu.org/licenses/.
1.20 - */
1.21 -#ifndef _include_sp2_hir_h_
1.22 -#define _include_sp2_hir_h_
1.23 -
1.24 -#include "../Types.h"
1.25 -#include "../PoolAllocator.h"
1.26 -#include "../Opcodes.h"
1.27 -#include "Symbols.h"
1.28 -
1.29 -namespace ke {
1.30 -
1.31 -#define HIR_OPS(_) \
1.32 - _(Call) \
1.33 - _(Boolean) \
1.34 - _(Integer) \
1.35 - _(Float) \
1.36 - _(String) \
1.37 - _(Import) \
1.38 - _(Array) \
1.39 - _(Store) \
1.40 - _(ToRef) \
1.41 - _(NewDependentArray) \
1.42 - /* Special LValue types */ \
1.43 - _(Index) \
1.44 - _(Local) \
1.45 - _(Global) \
1.46 - _(Field) \
1.47 - /* End LValues */ \
1.48 - _(Unary) \
1.49 - _(Binary) \
1.50 - _(Convert) \
1.51 - _(PostIncDec)
1.52 -
1.53 -// Forward declarations.
1.54 -#define _(name) class H##name;
1.55 -HIR_OPS(_)
1.56 -#undef _
1.57 -
1.58 -class HIRVisitor;
1.59 -class AstNode;
1.60 -class HLValue;
1.61 -class Array;
1.62 -
1.63 -class HIR : public PoolObject
1.64 -{
1.65 - public:
1.66 - enum HOp {
1.67 -#define _(name) k##name,
1.68 - HIR_OPS(_)
1.69 -#undef _
1.70 - kTotalOps
1.71 - };
1.72 -
1.73 - public:
1.74 - HIR(AstNode *node, Type *type)
1.75 - : node_(node),
1.76 - type_(type)
1.77 - {
1.78 - }
1.79 -
1.80 - Handle<Type> type() {
1.81 - return type_;
1.82 - }
1.83 - AstNode *node() const {
1.84 - return node_;
1.85 - }
1.86 -
1.87 - virtual bool isLValue() const {
1.88 - return false;
1.89 - }
1.90 -
1.91 - virtual HOp op() const = 0;
1.92 - virtual void accept(HIRVisitor *visitor) = 0;
1.93 -
1.94 -#define _(name) \
1.95 - bool is##name() const { \
1.96 - return op() == k##name; \
1.97 - } \
1.98 - H##name *to##name() { \
1.99 - assert(is##name()); \
1.100 - return reinterpret_cast<H##name *>(this); \
1.101 - }
1.102 - HIR_OPS(_)
1.103 -#undef _
1.104 -
1.105 - HLValue *toLValue() {
1.106 - assert(isLValue());
1.107 - return reinterpret_cast<HLValue *>(this);
1.108 - }
1.109 -
1.110 - private:
1.111 - AstNode *node_;
1.112 - ScopedRoot<Type> type_;
1.113 -};
1.114 -
1.115 -class BytecodeEmitter;
1.116 -
1.117 -class HIRVisitor
1.118 -{
1.119 - public:
1.120 -#define _(name) \
1.121 - virtual void visit##name(H##name *hir) { \
1.122 - assert(false); \
1.123 - }
1.124 - HIR_OPS(_)
1.125 -#undef _
1.126 -};
1.127 -
1.128 -typedef PoolList<HIR *> HIRList;
1.129 -
1.130 -#define DEFINE_HIR(name) \
1.131 - virtual HOp op() const { \
1.132 - return k##name; \
1.133 - } \
1.134 - virtual void accept(HIRVisitor *visitor) { \
1.135 - visitor->visit##name(this); \
1.136 - }
1.137 -
1.138 -class HBoolean : public HIR
1.139 -{
1.140 - public:
1.141 - HBoolean(AstNode *node, Type *type, bool value)
1.142 - : HIR(node, type),
1.143 - value_(value)
1.144 - {
1.145 - }
1.146 -
1.147 - DEFINE_HIR(Boolean);
1.148 - bool value() const {
1.149 - return value_;
1.150 - }
1.151 -
1.152 - private:
1.153 - bool value_;
1.154 -};
1.155 -
1.156 -class HInteger : public HIR
1.157 -{
1.158 - public:
1.159 - HInteger(AstNode *node, Type *type, int value)
1.160 - : HIR(node, type),
1.161 - value_(value)
1.162 - {
1.163 - }
1.164 -
1.165 - DEFINE_HIR(Integer);
1.166 - int value() const {
1.167 - return value_;
1.168 - }
1.169 -
1.170 - private:
1.171 - int value_;
1.172 -};
1.173 -
1.174 -class HString : public HIR
1.175 -{
1.176 - public:
1.177 - HString(AstNode *node, Type *type, String *string)
1.178 - : HIR(node, type),
1.179 - string_(string)
1.180 - {
1.181 - }
1.182 -
1.183 - DEFINE_HIR(String);
1.184 - Handle<String> string() const {
1.185 - return string_;
1.186 - }
1.187 -
1.188 - private:
1.189 - ScopedRoot<String> string_;
1.190 -};
1.191 -
1.192 -class HImport : public HIR
1.193 -{
1.194 - public:
1.195 - HImport(AstNode *node, Type *type, unsigned index)
1.196 - : HIR(node, type),
1.197 - index_(index)
1.198 - {
1.199 - }
1.200 -
1.201 - DEFINE_HIR(Import);
1.202 - unsigned index() const {
1.203 - return index_;
1.204 - }
1.205 -
1.206 - private:
1.207 - unsigned index_;
1.208 -};
1.209 -
1.210 -class HArray : public HIR
1.211 -{
1.212 - public:
1.213 - HArray(AstNode *node, Type *type, Array *array, bool duplicate)
1.214 - : HIR(node, type),
1.215 - array_(array),
1.216 - duplicate_(duplicate)
1.217 - {
1.218 - }
1.219 -
1.220 - DEFINE_HIR(Array);
1.221 - Handle<Array> array() const {
1.222 - return array_;
1.223 - }
1.224 - bool duplicate() const {
1.225 - return duplicate_;
1.226 - }
1.227 -
1.228 - private:
1.229 - ScopedRoot<Array> array_;
1.230 - bool duplicate_;
1.231 -};
1.232 -
1.233 -class HConvert : public HIR
1.234 -{
1.235 - public:
1.236 - HConvert(AstNode *node, Type *type, Opcode op, HIR *in)
1.237 - : HIR(node, type),
1.238 - op_(op),
1.239 - in_(in)
1.240 - {
1.241 - }
1.242 -
1.243 - DEFINE_HIR(Convert);
1.244 - Opcode opcode() const {
1.245 - return op_;
1.246 - }
1.247 - HIR *in() const {
1.248 - return in_;
1.249 - }
1.250 -
1.251 - private:
1.252 - Opcode op_;
1.253 - HIR *in_;
1.254 -};
1.255 -
1.256 -class HLValue : public HIR
1.257 -{
1.258 - public:
1.259 - HLValue(AstNode *node, Type *type)
1.260 - : HIR(node, type)
1.261 - {
1.262 - }
1.263 -
1.264 - // Pushes a reference to the LValue on the stack.
1.265 - virtual void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_) = 0;
1.266 -
1.267 - // Duplicates a stack reference.
1.268 - virtual void hold(BytecodeEmitter &emitter_) = 0;
1.269 -
1.270 - // Reorders the stack for a post-increment operation:
1.271 - // REF VAL -> VAL REF VAL
1.272 - virtual void swapAndPick(BytecodeEmitter &emitter_) = 0;
1.273 -
1.274 - // Given a stack layout of the form:
1.275 - // [-1] value
1.276 - // [-2..n] ref
1.277 - //
1.278 - // Emits a store to the reference.
1.279 - virtual void store(BytecodeEmitter &emitter_) = 0;
1.280 - virtual void load(BytecodeEmitter &emitter_) = 0;
1.281 -
1.282 - // Try to make a direct reference, if semantics allow it. False if the
1.283 - // caller must allocate a reference to the stack.
1.284 - virtual bool ref(BytecodeEmitter &emitter_) = 0;
1.285 -
1.286 - bool isLValue() const {
1.287 - return true;
1.288 - }
1.289 -};
1.290 -
1.291 -class HLocal : public HLValue
1.292 -{
1.293 - public:
1.294 - HLocal(AstNode *node, VariableSymbol *sym);
1.295 -
1.296 - DEFINE_HIR(Local);
1.297 -
1.298 - // Pushes a reference to the LValue on the stack.
1.299 - void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
1.300 - void hold(BytecodeEmitter &emitter_);
1.301 - void swapAndPick(BytecodeEmitter &emitter_);
1.302 - void store(BytecodeEmitter &emitter_);
1.303 - void load(BytecodeEmitter &emitter_);
1.304 - bool ref(BytecodeEmitter &emitter_);
1.305 -
1.306 - VariableSymbol *sym() const {
1.307 - return sym_;
1.308 - }
1.309 -
1.310 - private:
1.311 - VariableSymbol *sym_;
1.312 -};
1.313 -
1.314 -class HIndex : public HLValue
1.315 -{
1.316 - public:
1.317 - HIndex(AstNode *node, Type *type, HIR *left, HIR *right)
1.318 - : HLValue(node, type),
1.319 - left_(left),
1.320 - right_(right)
1.321 - {
1.322 - }
1.323 -
1.324 - DEFINE_HIR(Index);
1.325 -
1.326 - void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
1.327 - void hold(BytecodeEmitter &emitter_);
1.328 - void swapAndPick(BytecodeEmitter &emitter_);
1.329 - void store(BytecodeEmitter &emitter_);
1.330 - void load(BytecodeEmitter &emitter_);
1.331 - bool ref(BytecodeEmitter &emitter_);
1.332 -
1.333 - HIR *base() const {
1.334 - return left_;
1.335 - }
1.336 - HIR *index() const {
1.337 - return right_;
1.338 - }
1.339 -
1.340 - private:
1.341 - HIR *left_;
1.342 - HIR *right_;
1.343 -};
1.344 -
1.345 -class HField : public HLValue
1.346 -{
1.347 - public:
1.348 - HField(AstNode *node, HIR *left, Type *type, unsigned index)
1.349 - : HLValue(node, type),
1.350 - base_(left),
1.351 - index_(index)
1.352 - {
1.353 - }
1.354 -
1.355 - DEFINE_HIR(Field);
1.356 -
1.357 - void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
1.358 - void hold(BytecodeEmitter &emitter_);
1.359 - void swapAndPick(BytecodeEmitter &emitter_);
1.360 - void store(BytecodeEmitter &emitter_);
1.361 - void load(BytecodeEmitter &emitter_);
1.362 - bool ref(BytecodeEmitter &emitter_);
1.363 -
1.364 - HIR *base() const {
1.365 - return base_;
1.366 - }
1.367 - unsigned index() const {
1.368 - return index_;
1.369 - }
1.370 -
1.371 - private:
1.372 - HIR *base_;
1.373 - unsigned index_;
1.374 -};
1.375 -
1.376 -class HGlobal : public HLValue
1.377 -{
1.378 - public:
1.379 - HGlobal(AstNode *node, Symbol *sym)
1.380 - : HLValue(node, sym->type()),
1.381 - sym_(sym)
1.382 - {
1.383 - }
1.384 -
1.385 - DEFINE_HIR(Global);
1.386 -
1.387 - void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
1.388 - void hold(BytecodeEmitter &emitter_);
1.389 - void swapAndPick(BytecodeEmitter &emitter_);
1.390 - void store(BytecodeEmitter &emitter_);
1.391 - void load(BytecodeEmitter &emitter_);
1.392 - bool ref(BytecodeEmitter &emitter_);
1.393 -
1.394 - Symbol *sym() const {
1.395 - return sym_;
1.396 - }
1.397 -
1.398 - private:
1.399 - Symbol *sym_;
1.400 -};
1.401 -
1.402 -class HBinary : public HIR
1.403 -{
1.404 - public:
1.405 - HBinary(AstNode *node, Type *type, TokenKind token, HIR *left, HIR *right)
1.406 - : HIR(node, type),
1.407 - token_(token),
1.408 - left_(left),
1.409 - right_(right)
1.410 - {
1.411 - }
1.412 -
1.413 - DEFINE_HIR(Binary);
1.414 - TokenKind token() const {
1.415 - return token_;
1.416 - }
1.417 - HIR *left() const {
1.418 - return left_;
1.419 - }
1.420 - HIR *right() const {
1.421 - return right_;
1.422 - }
1.423 -
1.424 - private:
1.425 - TokenKind token_;
1.426 - HIR *left_;
1.427 - HIR *right_;
1.428 -};
1.429 -
1.430 -class HFloat : public HIR
1.431 -{
1.432 - public:
1.433 - HFloat(AstNode *node, Type *type, float value)
1.434 - : HIR(node, type),
1.435 - value_(value)
1.436 - {
1.437 - }
1.438 -
1.439 - DEFINE_HIR(Float);
1.440 - float value() const {
1.441 - return value_;
1.442 - }
1.443 -
1.444 - private:
1.445 - float value_;
1.446 -};
1.447 -
1.448 -class HUnary : public HIR
1.449 -{
1.450 - public:
1.451 - HUnary(AstNode *node, Type *type, TokenKind tok, HIR *in)
1.452 - : HIR(node, type),
1.453 - in_(in),
1.454 - token_(tok)
1.455 - {
1.456 - }
1.457 -
1.458 - DEFINE_HIR(Unary);
1.459 - HIR *in() const {
1.460 - return in_;
1.461 - }
1.462 - TokenKind token() const {
1.463 - return token_;
1.464 - }
1.465 -
1.466 - private:
1.467 - HIR *in_;
1.468 - TokenKind token_;
1.469 -};
1.470 -
1.471 -class HStore : public HIR
1.472 -{
1.473 - public:
1.474 - HStore(AstNode *node, HLValue *lval, HIR *rval)
1.475 - : HIR(node, lval->type()),
1.476 - kind_(TOK_ASSIGN),
1.477 - lval_(lval),
1.478 - rval_(rval)
1.479 - {
1.480 - }
1.481 -
1.482 - HStore(AstNode *node, TokenKind kind, HLValue *lval, HIR *rval)
1.483 - : HIR(node, lval->type()),
1.484 - kind_(kind),
1.485 - lval_(lval),
1.486 - rval_(rval)
1.487 - {
1.488 - }
1.489 -
1.490 - DEFINE_HIR(Store);
1.491 -
1.492 - HLValue *lval() const {
1.493 - return lval_;
1.494 - }
1.495 - HIR *rval() const {
1.496 - return rval_;
1.497 - }
1.498 - TokenKind kind() const {
1.499 - return kind_;
1.500 - }
1.501 -
1.502 - private:
1.503 - TokenKind kind_;
1.504 - HLValue *lval_;
1.505 - HIR *rval_;
1.506 -};
1.507 -
1.508 -class HPostIncDec : public HIR
1.509 -{
1.510 - public:
1.511 - HPostIncDec(AstNode *node, TokenKind kind, HLValue *lval, HIR *rval)
1.512 - : HIR(node, lval->type()),
1.513 - kind_(kind),
1.514 - lval_(lval),
1.515 - rval_(rval)
1.516 - {
1.517 - }
1.518 -
1.519 - DEFINE_HIR(PostIncDec);
1.520 -
1.521 - HLValue *lval() const {
1.522 - return lval_;
1.523 - }
1.524 - HIR *rval() const {
1.525 - return rval_;
1.526 - }
1.527 - TokenKind kind() const {
1.528 - return kind_;
1.529 - }
1.530 -
1.531 - private:
1.532 - TokenKind kind_;
1.533 - HLValue *lval_;
1.534 - HIR *rval_;
1.535 -};
1.536 -
1.537 -class HCall : public HIR
1.538 -{
1.539 - public:
1.540 - HCall(AstNode *node, Type *type, HIR *callee, HIRList *args)
1.541 - : HIR(node, type),
1.542 - callee_(callee),
1.543 - args_(args)
1.544 - {
1.545 - }
1.546 -
1.547 - DEFINE_HIR(Call);
1.548 -
1.549 - HIR *callee() const {
1.550 - return callee_;
1.551 - }
1.552 - HIRList *args() const {
1.553 - return args_;
1.554 - }
1.555 -
1.556 - private:
1.557 - HIR *callee_;
1.558 - HIRList *args_;
1.559 -};
1.560 -
1.561 -class HToRef : public HIR
1.562 -{
1.563 - public:
1.564 - HToRef(AstNode *node, Type *type, HIR *in)
1.565 - : HIR(node, type),
1.566 - in_(in)
1.567 - {
1.568 - }
1.569 -
1.570 - DEFINE_HIR(ToRef);
1.571 -
1.572 - HIR *in() const {
1.573 - return in_;
1.574 - }
1.575 -
1.576 - private:
1.577 - HIR *in_;
1.578 -};
1.579 -
1.580 -class HNewDependentArray : public HIR
1.581 -{
1.582 - public:
1.583 - HNewDependentArray(AstNode *node, Type *type, HIR *base, HIR *index)
1.584 - : HIR(node, type),
1.585 - base_(base),
1.586 - index_(index)
1.587 - {
1.588 - }
1.589 -
1.590 - DEFINE_HIR(NewDependentArray);
1.591 -
1.592 - HIR *base() const {
1.593 - return base_;
1.594 - }
1.595 - HIR *index() const {
1.596 - return index_;
1.597 - }
1.598 -
1.599 - private:
1.600 - HIR *base_;
1.601 - HIR *index_;
1.602 -};
1.603 -
1.604 -#undef DEFINE_HIR
1.605 -
1.606 -void EmitHIR(Zone *zone, BytecodeEmitter &emitter, HIR *hir);
1.607 -
1.608 -}
1.609 -
1.610 -#endif // _include_sp2_hir_h_
1.611 +/*
1.612 + * Copyright (C) 2012 David Anderson
1.613 + *
1.614 + * This file is part of SourcePawn.
1.615 + *
1.616 + * SourcePawn is free software: you can redistribute it and/or modify it under
1.617 + * the terms of the GNU General Public License as published by the Free
1.618 + * Software Foundation, either version 3 of the License, or (at your option)
1.619 + * any later version.
1.620 + *
1.621 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
1.622 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.623 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
1.624 + *
1.625 + * You should have received a copy of the GNU General Public License along with
1.626 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
1.627 + */
1.628 +#ifndef _include_sp2_hir_h_
1.629 +#define _include_sp2_hir_h_
1.630 +
1.631 +#include "../Types.h"
1.632 +#include "../PoolAllocator.h"
1.633 +#include "../Opcodes.h"
1.634 +#include "Symbols.h"
1.635 +
1.636 +namespace ke {
1.637 +
1.638 +#define HIR_OPS(_) \
1.639 + _(Call) \
1.640 + _(Boolean) \
1.641 + _(Integer) \
1.642 + _(Float) \
1.643 + _(String) \
1.644 + _(Import) \
1.645 + _(Array) \
1.646 + _(Store) \
1.647 + _(ToRef) \
1.648 + _(NewDependentArray) \
1.649 + /* Special LValue types */ \
1.650 + _(Index) \
1.651 + _(Local) \
1.652 + _(Global) \
1.653 + _(Field) \
1.654 + /* End LValues */ \
1.655 + _(Unary) \
1.656 + _(Binary) \
1.657 + _(Convert) \
1.658 + _(PostIncDec)
1.659 +
1.660 +// Forward declarations.
1.661 +#define _(name) class H##name;
1.662 +HIR_OPS(_)
1.663 +#undef _
1.664 +
1.665 +class HIRVisitor;
1.666 +class AstNode;
1.667 +class HLValue;
1.668 +class Array;
1.669 +
1.670 +class HIR : public PoolObject
1.671 +{
1.672 + public:
1.673 + enum HOp {
1.674 +#define _(name) k##name,
1.675 + HIR_OPS(_)
1.676 +#undef _
1.677 + kTotalOps
1.678 + };
1.679 +
1.680 + public:
1.681 + HIR(AstNode *node, Type *type)
1.682 + : node_(node),
1.683 + type_(type)
1.684 + {
1.685 + }
1.686 +
1.687 + Handle<Type> type() {
1.688 + return type_;
1.689 + }
1.690 + AstNode *node() const {
1.691 + return node_;
1.692 + }
1.693 +
1.694 + virtual bool isLValue() const {
1.695 + return false;
1.696 + }
1.697 +
1.698 + virtual HOp op() const = 0;
1.699 + virtual void accept(HIRVisitor *visitor) = 0;
1.700 +
1.701 +#define _(name) \
1.702 + bool is##name() const { \
1.703 + return op() == k##name; \
1.704 + } \
1.705 + H##name *to##name() { \
1.706 + assert(is##name()); \
1.707 + return reinterpret_cast<H##name *>(this); \
1.708 + }
1.709 + HIR_OPS(_)
1.710 +#undef _
1.711 +
1.712 + HLValue *toLValue() {
1.713 + assert(isLValue());
1.714 + return reinterpret_cast<HLValue *>(this);
1.715 + }
1.716 +
1.717 + private:
1.718 + AstNode *node_;
1.719 + ScopedRoot<Type> type_;
1.720 +};
1.721 +
1.722 +class BytecodeEmitter;
1.723 +
1.724 +class HIRVisitor
1.725 +{
1.726 + public:
1.727 +#define _(name) \
1.728 + virtual void visit##name(H##name *hir) { \
1.729 + assert(false); \
1.730 + }
1.731 + HIR_OPS(_)
1.732 +#undef _
1.733 +};
1.734 +
1.735 +typedef PoolList<HIR *> HIRList;
1.736 +
1.737 +#define DEFINE_HIR(name) \
1.738 + virtual HOp op() const { \
1.739 + return k##name; \
1.740 + } \
1.741 + virtual void accept(HIRVisitor *visitor) { \
1.742 + visitor->visit##name(this); \
1.743 + }
1.744 +
1.745 +class HBoolean : public HIR
1.746 +{
1.747 + public:
1.748 + HBoolean(AstNode *node, Type *type, bool value)
1.749 + : HIR(node, type),
1.750 + value_(value)
1.751 + {
1.752 + }
1.753 +
1.754 + DEFINE_HIR(Boolean);
1.755 + bool value() const {
1.756 + return value_;
1.757 + }
1.758 +
1.759 + private:
1.760 + bool value_;
1.761 +};
1.762 +
1.763 +class HInteger : public HIR
1.764 +{
1.765 + public:
1.766 + HInteger(AstNode *node, Type *type, int value)
1.767 + : HIR(node, type),
1.768 + value_(value)
1.769 + {
1.770 + }
1.771 +
1.772 + DEFINE_HIR(Integer);
1.773 + int value() const {
1.774 + return value_;
1.775 + }
1.776 +
1.777 + private:
1.778 + int value_;
1.779 +};
1.780 +
1.781 +class HString : public HIR
1.782 +{
1.783 + public:
1.784 + HString(AstNode *node, Type *type, String *string)
1.785 + : HIR(node, type),
1.786 + string_(string)
1.787 + {
1.788 + }
1.789 +
1.790 + DEFINE_HIR(String);
1.791 + Handle<String> string() const {
1.792 + return string_;
1.793 + }
1.794 +
1.795 + private:
1.796 + ScopedRoot<String> string_;
1.797 +};
1.798 +
1.799 +class HImport : public HIR
1.800 +{
1.801 + public:
1.802 + HImport(AstNode *node, Type *type, unsigned index)
1.803 + : HIR(node, type),
1.804 + index_(index)
1.805 + {
1.806 + }
1.807 +
1.808 + DEFINE_HIR(Import);
1.809 + unsigned index() const {
1.810 + return index_;
1.811 + }
1.812 +
1.813 + private:
1.814 + unsigned index_;
1.815 +};
1.816 +
1.817 +class HArray : public HIR
1.818 +{
1.819 + public:
1.820 + HArray(AstNode *node, Type *type, Array *array, bool duplicate)
1.821 + : HIR(node, type),
1.822 + array_(array),
1.823 + duplicate_(duplicate)
1.824 + {
1.825 + }
1.826 +
1.827 + DEFINE_HIR(Array);
1.828 + Handle<Array> array() const {
1.829 + return array_;
1.830 + }
1.831 + bool duplicate() const {
1.832 + return duplicate_;
1.833 + }
1.834 +
1.835 + private:
1.836 + ScopedRoot<Array> array_;
1.837 + bool duplicate_;
1.838 +};
1.839 +
1.840 +class HConvert : public HIR
1.841 +{
1.842 + public:
1.843 + HConvert(AstNode *node, Type *type, Opcode op, HIR *in)
1.844 + : HIR(node, type),
1.845 + op_(op),
1.846 + in_(in)
1.847 + {
1.848 + }
1.849 +
1.850 + DEFINE_HIR(Convert);
1.851 + Opcode opcode() const {
1.852 + return op_;
1.853 + }
1.854 + HIR *in() const {
1.855 + return in_;
1.856 + }
1.857 +
1.858 + private:
1.859 + Opcode op_;
1.860 + HIR *in_;
1.861 +};
1.862 +
1.863 +class HLValue : public HIR
1.864 +{
1.865 + public:
1.866 + HLValue(AstNode *node, Type *type)
1.867 + : HIR(node, type)
1.868 + {
1.869 + }
1.870 +
1.871 + // Pushes a reference to the LValue on the stack.
1.872 + virtual void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_) = 0;
1.873 +
1.874 + // Duplicates a stack reference.
1.875 + virtual void hold(BytecodeEmitter &emitter_) = 0;
1.876 +
1.877 + // Reorders the stack for a post-increment operation:
1.878 + // REF VAL -> VAL REF VAL
1.879 + virtual void swapAndPick(BytecodeEmitter &emitter_) = 0;
1.880 +
1.881 + // Given a stack layout of the form:
1.882 + // [-1] value
1.883 + // [-2..n] ref
1.884 + //
1.885 + // Emits a store to the reference.
1.886 + virtual void store(BytecodeEmitter &emitter_) = 0;
1.887 + virtual void load(BytecodeEmitter &emitter_) = 0;
1.888 +
1.889 + // Try to make a direct reference, if semantics allow it. False if the
1.890 + // caller must allocate a reference to the stack.
1.891 + virtual bool ref(BytecodeEmitter &emitter_) = 0;
1.892 +
1.893 + bool isLValue() const {
1.894 + return true;
1.895 + }
1.896 +};
1.897 +
1.898 +class HLocal : public HLValue
1.899 +{
1.900 + public:
1.901 + HLocal(AstNode *node, VariableSymbol *sym);
1.902 +
1.903 + DEFINE_HIR(Local);
1.904 +
1.905 + // Pushes a reference to the LValue on the stack.
1.906 + void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
1.907 + void hold(BytecodeEmitter &emitter_);
1.908 + void swapAndPick(BytecodeEmitter &emitter_);
1.909 + void store(BytecodeEmitter &emitter_);
1.910 + void load(BytecodeEmitter &emitter_);
1.911 + bool ref(BytecodeEmitter &emitter_);
1.912 +
1.913 + VariableSymbol *sym() const {
1.914 + return sym_;
1.915 + }
1.916 +
1.917 + private:
1.918 + VariableSymbol *sym_;
1.919 +};
1.920 +
1.921 +class HIndex : public HLValue
1.922 +{
1.923 + public:
1.924 + HIndex(AstNode *node, Type *type, HIR *left, HIR *right)
1.925 + : HLValue(node, type),
1.926 + left_(left),
1.927 + right_(right)
1.928 + {
1.929 + }
1.930 +
1.931 + DEFINE_HIR(Index);
1.932 +
1.933 + void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
1.934 + void hold(BytecodeEmitter &emitter_);
1.935 + void swapAndPick(BytecodeEmitter &emitter_);
1.936 + void store(BytecodeEmitter &emitter_);
1.937 + void load(BytecodeEmitter &emitter_);
1.938 + bool ref(BytecodeEmitter &emitter_);
1.939 +
1.940 + HIR *base() const {
1.941 + return left_;
1.942 + }
1.943 + HIR *index() const {
1.944 + return right_;
1.945 + }
1.946 +
1.947 + private:
1.948 + HIR *left_;
1.949 + HIR *right_;
1.950 +};
1.951 +
1.952 +class HField : public HLValue
1.953 +{
1.954 + public:
1.955 + HField(AstNode *node, HIR *left, Type *type, unsigned index)
1.956 + : HLValue(node, type),
1.957 + base_(left),
1.958 + index_(index)
1.959 + {
1.960 + }
1.961 +
1.962 + DEFINE_HIR(Field);
1.963 +
1.964 + void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
1.965 + void hold(BytecodeEmitter &emitter_);
1.966 + void swapAndPick(BytecodeEmitter &emitter_);
1.967 + void store(BytecodeEmitter &emitter_);
1.968 + void load(BytecodeEmitter &emitter_);
1.969 + bool ref(BytecodeEmitter &emitter_);
1.970 +
1.971 + HIR *base() const {
1.972 + return base_;
1.973 + }
1.974 + unsigned index() const {
1.975 + return index_;
1.976 + }
1.977 +
1.978 + private:
1.979 + HIR *base_;
1.980 + unsigned index_;
1.981 +};
1.982 +
1.983 +class HGlobal : public HLValue
1.984 +{
1.985 + public:
1.986 + HGlobal(AstNode *node, Symbol *sym)
1.987 + : HLValue(node, sym->type()),
1.988 + sym_(sym)
1.989 + {
1.990 + }
1.991 +
1.992 + DEFINE_HIR(Global);
1.993 +
1.994 + void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
1.995 + void hold(BytecodeEmitter &emitter_);
1.996 + void swapAndPick(BytecodeEmitter &emitter_);
1.997 + void store(BytecodeEmitter &emitter_);
1.998 + void load(BytecodeEmitter &emitter_);
1.999 + bool ref(BytecodeEmitter &emitter_);
1.1000 +
1.1001 + Symbol *sym() const {
1.1002 + return sym_;
1.1003 + }
1.1004 +
1.1005 + private:
1.1006 + Symbol *sym_;
1.1007 +};
1.1008 +
1.1009 +class HBinary : public HIR
1.1010 +{
1.1011 + public:
1.1012 + HBinary(AstNode *node, Type *type, TokenKind token, HIR *left, HIR *right)
1.1013 + : HIR(node, type),
1.1014 + token_(token),
1.1015 + left_(left),
1.1016 + right_(right)
1.1017 + {
1.1018 + }
1.1019 +
1.1020 + DEFINE_HIR(Binary);
1.1021 + TokenKind token() const {
1.1022 + return token_;
1.1023 + }
1.1024 + HIR *left() const {
1.1025 + return left_;
1.1026 + }
1.1027 + HIR *right() const {
1.1028 + return right_;
1.1029 + }
1.1030 +
1.1031 + private:
1.1032 + TokenKind token_;
1.1033 + HIR *left_;
1.1034 + HIR *right_;
1.1035 +};
1.1036 +
1.1037 +class HFloat : public HIR
1.1038 +{
1.1039 + public:
1.1040 + HFloat(AstNode *node, Type *type, float value)
1.1041 + : HIR(node, type),
1.1042 + value_(value)
1.1043 + {
1.1044 + }
1.1045 +
1.1046 + DEFINE_HIR(Float);
1.1047 + float value() const {
1.1048 + return value_;
1.1049 + }
1.1050 +
1.1051 + private:
1.1052 + float value_;
1.1053 +};
1.1054 +
1.1055 +class HUnary : public HIR
1.1056 +{
1.1057 + public:
1.1058 + HUnary(AstNode *node, Type *type, TokenKind tok, HIR *in)
1.1059 + : HIR(node, type),
1.1060 + in_(in),
1.1061 + token_(tok)
1.1062 + {
1.1063 + }
1.1064 +
1.1065 + DEFINE_HIR(Unary);
1.1066 + HIR *in() const {
1.1067 + return in_;
1.1068 + }
1.1069 + TokenKind token() const {
1.1070 + return token_;
1.1071 + }
1.1072 +
1.1073 + private:
1.1074 + HIR *in_;
1.1075 + TokenKind token_;
1.1076 +};
1.1077 +
1.1078 +class HStore : public HIR
1.1079 +{
1.1080 + public:
1.1081 + HStore(AstNode *node, HLValue *lval, HIR *rval)
1.1082 + : HIR(node, lval->type()),
1.1083 + kind_(TOK_ASSIGN),
1.1084 + lval_(lval),
1.1085 + rval_(rval)
1.1086 + {
1.1087 + }
1.1088 +
1.1089 + HStore(AstNode *node, TokenKind kind, HLValue *lval, HIR *rval)
1.1090 + : HIR(node, lval->type()),
1.1091 + kind_(kind),
1.1092 + lval_(lval),
1.1093 + rval_(rval)
1.1094 + {
1.1095 + }
1.1096 +
1.1097 + DEFINE_HIR(Store);
1.1098 +
1.1099 + HLValue *lval() const {
1.1100 + return lval_;
1.1101 + }
1.1102 + HIR *rval() const {
1.1103 + return rval_;
1.1104 + }
1.1105 + TokenKind kind() const {
1.1106 + return kind_;
1.1107 + }
1.1108 +
1.1109 + private:
1.1110 + TokenKind kind_;
1.1111 + HLValue *lval_;
1.1112 + HIR *rval_;
1.1113 +};
1.1114 +
1.1115 +class HPostIncDec : public HIR
1.1116 +{
1.1117 + public:
1.1118 + HPostIncDec(AstNode *node, TokenKind kind, HLValue *lval, HIR *rval)
1.1119 + : HIR(node, lval->type()),
1.1120 + kind_(kind),
1.1121 + lval_(lval),
1.1122 + rval_(rval)
1.1123 + {
1.1124 + }
1.1125 +
1.1126 + DEFINE_HIR(PostIncDec);
1.1127 +
1.1128 + HLValue *lval() const {
1.1129 + return lval_;
1.1130 + }
1.1131 + HIR *rval() const {
1.1132 + return rval_;
1.1133 + }
1.1134 + TokenKind kind() const {
1.1135 + return kind_;
1.1136 + }
1.1137 +
1.1138 + private:
1.1139 + TokenKind kind_;
1.1140 + HLValue *lval_;
1.1141 + HIR *rval_;
1.1142 +};
1.1143 +
1.1144 +class HCall : public HIR
1.1145 +{
1.1146 + public:
1.1147 + HCall(AstNode *node, Type *type, HIR *callee, HIRList *args)
1.1148 + : HIR(node, type),
1.1149 + callee_(callee),
1.1150 + args_(args)
1.1151 + {
1.1152 + }
1.1153 +
1.1154 + DEFINE_HIR(Call);
1.1155 +
1.1156 + HIR *callee() const {
1.1157 + return callee_;
1.1158 + }
1.1159 + HIRList *args() const {
1.1160 + return args_;
1.1161 + }
1.1162 +
1.1163 + private:
1.1164 + HIR *callee_;
1.1165 + HIRList *args_;
1.1166 +};
1.1167 +
1.1168 +class HToRef : public HIR
1.1169 +{
1.1170 + public:
1.1171 + HToRef(AstNode *node, Type *type, HIR *in)
1.1172 + : HIR(node, type),
1.1173 + in_(in)
1.1174 + {
1.1175 + }
1.1176 +
1.1177 + DEFINE_HIR(ToRef);
1.1178 +
1.1179 + HIR *in() const {
1.1180 + return in_;
1.1181 + }
1.1182 +
1.1183 + private:
1.1184 + HIR *in_;
1.1185 +};
1.1186 +
1.1187 +class HNewDependentArray : public HIR
1.1188 +{
1.1189 + public:
1.1190 + HNewDependentArray(AstNode *node, Type *type, HIR *base, HIR *index)
1.1191 + : HIR(node, type),
1.1192 + base_(base),
1.1193 + index_(index)
1.1194 + {
1.1195 + }
1.1196 +
1.1197 + DEFINE_HIR(NewDependentArray);
1.1198 +
1.1199 + HIR *base() const {
1.1200 + return base_;
1.1201 + }
1.1202 + HIR *index() const {
1.1203 + return index_;
1.1204 + }
1.1205 +
1.1206 + private:
1.1207 + HIR *base_;
1.1208 + HIR *index_;
1.1209 +};
1.1210 +
1.1211 +#undef DEFINE_HIR
1.1212 +
1.1213 +void EmitHIR(Zone *zone, BytecodeEmitter &emitter, HIR *hir);
1.1214 +
1.1215 +}
1.1216 +
1.1217 +#endif // _include_sp2_hir_h_