]> git.saurik.com Git - cycript.git/commitdiff
Changed from a threaded pool to a thread-local pool, abstracted out token assignment...
authorJay Freeman (saurik) <saurik@saurik.com>
Thu, 8 Jul 2010 00:36:05 +0000 (00:36 +0000)
committerJay Freeman (saurik) <saurik@saurik.com>
Thu, 8 Jul 2010 00:36:05 +0000 (00:36 +0000)
13 files changed:
Console.cpp
Cycript.l.in
Cycript.yy.in
GNUmakefile.in
Library.cpp
Local.hpp [new file with mode: 0644]
ObjectiveC/Replace.mm
Output.cpp
Parser.cpp
Parser.hpp
Pooling.hpp
Replace.cpp
Replace.hpp

index 1afdb2fe93ef2c9d5f601b9458dc9ecf6c250c22..c9bce69c63178ea577fd490f8ed1635b98d93f25 100644 (file)
@@ -125,7 +125,7 @@ void Setup(CYDriver &driver, cy::parser &parser) {
 
 void Setup(CYOutput &out, CYDriver &driver, CYOptions &options) {
     out.pretty_ = pretty_;
-    CYContext context(driver.pool_, options);
+    CYContext context(options);
     driver.program_->Replace(context);
 }
 
@@ -216,12 +216,12 @@ int (*append_history$)(int, const char *);
 
 static std::string command_;
 
-static CYExpression *ParseExpression(CYPool &pool, CYUTF8String code) {
+static CYExpression *ParseExpression(CYUTF8String code) {
     std::ostringstream str;
     str << '(' << code << ')';
     std::string string(str.str());
 
-    CYDriver driver(pool);
+    CYDriver driver;
     driver.data_ = string.c_str();
     driver.size_ = string.size();
 
@@ -241,9 +241,8 @@ static int client_;
 static char **Complete(const char *word, int start, int end) {
     rl_attempted_completion_over = TRUE;
 
-    CYPool pool;
-
-    CYDriver driver(pool);
+    CYLocalPool pool;
+    CYDriver driver;
     cy::parser parser(driver);
     Setup(driver, parser);
 
@@ -264,7 +263,7 @@ static char **Complete(const char *word, int start, int end) {
     CYExpression *expression;
 
     CYOptions options;
-    CYContext context(driver.pool_, options);
+    CYContext context(options);
 
     std::ostringstream prefix;
 
@@ -294,7 +293,7 @@ static char **Complete(const char *word, int start, int end) {
 
     std::string begin(prefix.str());
 
-    driver.program_ = $ CYProgram($ CYExpress($C3(ParseExpression(pool,
+    driver.program_ = $ CYProgram($ CYExpress($C3(ParseExpression(
     "   function(object, prefix, word) {\n"
     "       var names = [];\n"
     "       var pattern = '^' + prefix + word;\n"
@@ -315,7 +314,7 @@ static char **Complete(const char *word, int start, int end) {
     std::string code(str.str());
     CYUTF8String json(Run(pool, client_, code));
 
-    CYExpression *result(ParseExpression(pool, json));
+    CYExpression *result(ParseExpression(json));
     CYArray *array(dynamic_cast<CYArray *>(result));
 
     if (array == NULL) {
@@ -388,7 +387,9 @@ static char **Complete(const char *word, int start, int end) {
 static char name_[] = "cycript";
 static char break_[] = " \t\n\"\\'`@$><=;|&{(" ")}" ".:[]";
 
-static void Console(apr_pool_t *pool, CYOptions &options) {
+static void Console(CYOptions &options) {
+    CYPool pool;
+
     passwd *passwd;
     if (const char *username = getenv("LOGNAME"))
         passwd = getpwnam(username);
@@ -488,6 +489,7 @@ static void Console(apr_pool_t *pool, CYOptions &options) {
         if (bypass)
             code = command_;
         else {
+            CYLocalPool pool;
             CYDriver driver;
             cy::parser parser(driver);
             Setup(driver, parser);
@@ -781,9 +783,10 @@ int Main(int argc, char const * const argv[], char const * const envp[]) {
 #endif
 
     if (script == NULL && tty)
-        Console(pool, options);
+        Console(options);
     else {
-        CYDriver driver(pool, script ?: "<stdin>");
+        CYLocalPool pool;
+        CYDriver driver(script ?: "<stdin>");
         cy::parser parser(driver);
         Setup(driver, parser);
 
index 352763a34a40ca82845b962b03e4aa4cec47da1a..7a5dbee795d05801182eaac4c183564a4d1627f7 100644 (file)
@@ -46,27 +46,34 @@ typedef cy::parser::token tk;
 
 #define YY_EXTRA_TYPE CYDriver *
 
+#define A new($pool)
+#define Y apr_pstrmemdup($pool, yytext, yyleng)
+
+#define I(type, Type, Name) do { \
+    yylval->type ## _ = A CY ## Type; \
+    return tk::Name; \
+} while (false)
+
 #define T yylval->newline_ = yyextra->state_ == CYNewLine; BEGIN(Div);
 #define C T yyextra->state_ = CYClear;
 #define R T yyextra->state_ = CYRestricted;
 
 #define E(prefix) L C { \
-    char *value(reinterpret_cast<char *>(apr_palloc(yyextra->pool_, yyleng + sizeof(prefix)))); \
+    char *value(A char[yyleng + sizeof(prefix)]); \
     memcpy(value, prefix, sizeof(prefix) - 1); \
     memcpy(value + sizeof(prefix) - 1, yytext, yyleng); \
     value[yyleng + sizeof(prefix) - 1] = '\0'; \
-    yylval->literal_ = new(yyextra->pool_) CYRegEx(value); \
-    return tk::RegularExpressionLiteral; \
+    I(literal, RegEx(value), RegularExpressionLiteral); \
 }
 
 #define N \
     if (yyextra->state_ != CYNewLine) { \
-        bool restricted(yyextra->state_ == CYRestricted); \
-        if (restricted) { \
+        if (yyextra->state_ != CYRestricted) \
+            yyextra->state_ = CYNewLine; \
+        else { \
             yyextra->state_ = CYClear; \
             return tk::NewLine; \
-        } else \
-            yyextra->state_ = CYNewLine; \
+        } \
     }
 
 #define V(more) { \
@@ -164,7 +171,7 @@ XMLName {XMLNameStart}{XMLNamePart}*
 
        /* http://ostermiller.org/findcomment.html */
        /* XXX: unify these two rules using !? */
-\/\*!([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/ V() C yylval->comment_ = new(yyextra->pool_) CYComment(apr_pstrmemdup(yyextra->pool_, yytext, yyleng)); return tk::Comment;
+\/\*!([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/ V() C I(comment, Comment(Y), Comment);
 \/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/ V(N)
 
 @begin E4X
@@ -180,10 +187,7 @@ XMLName {XMLNameStart}{XMLNamePart}*
 <XMLTag>"/>" L return tk::SlashRight;
 <XMLTag>"{"  L return tk::OpenBrace;
 
-<XMLTag>\"(\n|[^"])*\"|'(\n|[^'])*' V() {
-    return tk::XMLAttributeValue;
-}
-
+<XMLTag>\"(\n|[^"])*\"|'(\n|[^'])*' V() return tk::XMLAttributeValue;
 <XMLTag>{XMLName} L return tk::XMLName;
 <XMLTag>[ \t\r\n] V() return tk::XMLWhitespace;
 
@@ -267,92 +271,92 @@ XMLName {XMLNameStart}{XMLNamePart}*
 "@selector"       L C return tk::AtSelector;
 @end
 
-"false"        L C yylval->false_ = new(yyextra->pool_) CYFalse(); return tk::False;
-"null"         L C yylval->null_ = new(yyextra->pool_) CYNull(); return tk::Null;
-"true"         L C yylval->true_ = new(yyextra->pool_) CYTrue(); return tk::True;
-
-"break"        L R yylval->word_ = new(yyextra->pool_) CYWord("break"); return tk::Break;
-"case"         L C yylval->word_ = new(yyextra->pool_) CYWord("case"); return tk::Case;
-"catch"        L C yylval->word_ = new(yyextra->pool_) CYWord("catch"); return tk::Catch;
-"continue"     L R yylval->word_ = new(yyextra->pool_) CYWord("continue"); return tk::Continue;
-"default"      L C yylval->word_ = new(yyextra->pool_) CYWord("default"); return tk::Default;
-"delete"       L C yylval->word_ = new(yyextra->pool_) CYWord("delete"); return tk::Delete;
-"do"           L C yylval->word_ = new(yyextra->pool_) CYWord("do"); return tk::Do;
-"else"         L C yylval->word_ = new(yyextra->pool_) CYWord("else"); return tk::Else;
-"finally"      L C yylval->word_ = new(yyextra->pool_) CYWord("finally"); return tk::Finally;
-"for"          L C yylval->word_ = new(yyextra->pool_) CYWord("for"); return tk::For;
-"function"     L C yylval->word_ = new(yyextra->pool_) CYWord("function"); return tk::Function;
-"if"           L C yylval->word_ = new(yyextra->pool_) CYWord("if"); return tk::If;
-"in"           L C yylval->word_ = new(yyextra->pool_) CYWord("in"); return tk::In;
-"instanceof"   L C yylval->word_ = new(yyextra->pool_) CYWord("instanceof"); return tk::InstanceOf;
-"new"          L C yylval->word_ = new(yyextra->pool_) CYWord("new"); return tk::New;
-"return"       L R yylval->word_ = new(yyextra->pool_) CYWord("return"); return tk::Return;
-"switch"       L C yylval->word_ = new(yyextra->pool_) CYWord("switch"); return tk::Switch;
-"this"         L C yylval->this_ = new(yyextra->pool_) CYThis(); return tk::This;
-"throw"        L R yylval->word_ = new(yyextra->pool_) CYWord("throw"); return tk::Throw;
-"try"          L C yylval->word_ = new(yyextra->pool_) CYWord("try"); return tk::Try;
-"typeof"       L C yylval->word_ = new(yyextra->pool_) CYWord("typeof"); return tk::TypeOf;
-"var"          L C yylval->word_ = new(yyextra->pool_) CYWord("var"); return tk::Var;
-"void"         L C yylval->word_ = new(yyextra->pool_) CYWord("void"); return tk::Void;
-"while"        L C yylval->word_ = new(yyextra->pool_) CYWord("while"); return tk::While;
-"with"         L C yylval->word_ = new(yyextra->pool_) CYWord("with"); return tk::With;
-
-"debugger"     L C yylval->word_ = new(yyextra->pool_) CYWord("debugger"); return tk::Debugger;
-
-"const"        L C yylval->word_ = new(yyextra->pool_) CYWord("const"); return tk::Const;
-
-"class"        L C yylval->word_ = new(yyextra->pool_) CYWord("class"); return tk::Class;
-"enum"         L C yylval->word_ = new(yyextra->pool_) CYWord("enum"); return tk::Enum;
-"export"       L C yylval->word_ = new(yyextra->pool_) CYWord("export"); return tk::Export;
-"extends"      L C yylval->word_ = new(yyextra->pool_) CYWord("extends"); return tk::Extends;
-"import"       L C yylval->word_ = new(yyextra->pool_) CYWord("import"); return tk::Import;
-"super"        L C yylval->word_ = new(yyextra->pool_) CYWord("super"); return tk::Super;
-
-"implements"   L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("implements"); return tk::Implements;
-"interface"    L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("interface"); return tk::Interface;
-"package"      L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("package"); return tk::Package;
-"private"      L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("private"); return tk::Private;
-"protected"    L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("protected"); return tk::Protected;
-"public"       L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("public"); return tk::Public;
-"static"       L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("static"); return tk::Static;
-
-"abstract"     L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("abstract"); return tk::Abstract;
-"boolean"      L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("boolean"); return tk::Boolean;
-"byte"         L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("byte"); return tk::Byte;
-"char"         L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("char"); return tk::Char;
-"double"       L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("double"); return tk::Double;
-"final"        L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("final"); return tk::Final;
-"float"        L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("float"); return tk::Float;
-"goto"         L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("goto"); return tk::Goto;
-"int"          L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("int"); return tk::Int;
-"long"         L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("long"); return tk::Long;
-"native"       L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("native"); return tk::Native;
-"short"        L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("short"); return tk::Short;
-"synchronized" L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("synchronized"); return tk::Synchronized;
-"throws"       L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("throws"); return tk::Throws;
-"transient"    L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("transient"); return tk::Transient;
-"volatile"     L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("volatile"); return tk::Volatile;
-
-"let"          L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("let"); return tk::Let;
-"yield"        L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("yield"); return tk::Yield;
-
-"each"         L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("each"); return tk::Each;
+"false"        L C I(false, False(), False);
+"null"         L C I(null, Null(), Null);
+"true"         L C I(true, True(), True);
+
+"break"        L R I(word, Word("break"), Break);
+"case"         L C I(word, Word("case"), Case);
+"catch"        L C I(word, Word("catch"), Catch);
+"continue"     L R I(word, Word("continue"), Continue);
+"default"      L C I(word, Word("default"), Default);
+"delete"       L C I(word, Word("delete"), Delete);
+"do"           L C I(word, Word("do"), Do);
+"else"         L C I(word, Word("else"), Else);
+"finally"      L C I(word, Word("finally"), Finally);
+"for"          L C I(word, Word("for"), For);
+"function"     L C I(word, Word("function"), Function);
+"if"           L C I(word, Word("if"), If);
+"in"           L C I(word, Word("in"), In);
+"instanceof"   L C I(word, Word("instanceof"), InstanceOf);
+"new"          L C I(word, Word("new"), New);
+"return"       L R I(word, Word("return"), Return);
+"switch"       L C I(word, Word("switch"), Switch);
+"this"         L C I(this, This(), This);
+"throw"        L R I(word, Word("throw"), Throw);
+"try"          L C I(word, Word("try"), Try);
+"typeof"       L C I(word, Word("typeof"), TypeOf);
+"var"          L C I(word, Word("var"), Var);
+"void"         L C I(word, Word("void"), Void);
+"while"        L C I(word, Word("while"), While);
+"with"         L C I(word, Word("with"), With);
+
+"debugger"     L C I(word, Word("debugger"), Debugger);
+
+"const"        L C I(word, Word("const"), Const);
+
+"class"        L C I(word, Word("class"), Class);
+"enum"         L C I(word, Word("enum"), Enum);
+"export"       L C I(word, Word("export"), Export);
+"extends"      L C I(word, Word("extends"), Extends);
+"import"       L C I(word, Word("import"), Import);
+"super"        L C I(word, Word("super"), Super);
+
+"implements"   L C I(identifier, Identifier("implements"), Implements);
+"interface"    L C I(identifier, Identifier("interface"), Interface);
+"package"      L C I(identifier, Identifier("package"), Package);
+"private"      L C I(identifier, Identifier("private"), Private);
+"protected"    L C I(identifier, Identifier("protected"), Protected);
+"public"       L C I(identifier, Identifier("public"), Public);
+"static"       L C I(identifier, Identifier("static"), Static);
+
+"abstract"     L C I(identifier, Identifier("abstract"), Abstract);
+"boolean"      L C I(identifier, Identifier("boolean"), Boolean);
+"byte"         L C I(identifier, Identifier("byte"), Byte);
+"char"         L C I(identifier, Identifier("char"), Char);
+"double"       L C I(identifier, Identifier("double"), Double);
+"final"        L C I(identifier, Identifier("final"), Final);
+"float"        L C I(identifier, Identifier("float"), Float);
+"goto"         L C I(identifier, Identifier("goto"), Goto);
+"int"          L C I(identifier, Identifier("int"), Int);
+"long"         L C I(identifier, Identifier("long"), Long);
+"native"       L C I(identifier, Identifier("native"), Native);
+"short"        L C I(identifier, Identifier("short"), Short);
+"synchronized" L C I(identifier, Identifier("synchronized"), Synchronized);
+"throws"       L C I(identifier, Identifier("throws"), Throws);
+"transient"    L C I(identifier, Identifier("transient"), Transient);
+"volatile"     L C I(identifier, Identifier("volatile"), Volatile);
+
+"let"          L C I(identifier, Identifier("let"), Let);
+"yield"        L C I(identifier, Identifier("yield"), Yield);
+
+"each"         L C I(identifier, Identifier("each"), Each);
 
 @begin E4X
-"namespace"    L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("namespace"); return tk::Namespace;
-"xml"          L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier("xml"); return tk::XML;
+"namespace"    L C I(identifier, Identifier("namespace"), Namespace);
+"xml"          L C I(identifier, Identifier("xml"), XML);
 @end
 
-{IdentifierStart}{IdentifierPart}* L C yylval->identifier_ = new(yyextra->pool_) CYIdentifier(apr_pstrmemdup(yyextra->pool_, yytext, yyleng)); return tk::Identifier_;
+{IdentifierStart}{IdentifierPart}* L C I(identifier, Identifier(Y), Identifier_);
 
-(\.[0-9]+|(0|[1-9][0-9]*)(\.[0-9]*)?){Exponent}? L C yylval->number_ = new(yyextra->pool_) CYNumber(strtod(yytext, NULL)); return tk::NumericLiteral;
+(\.[0-9]+|(0|[1-9][0-9]*)(\.[0-9]*)?){Exponent}? L C I(number, Number(strtod(yytext, NULL)), NumericLiteral);
 
-0[xX][0-9a-fA-F]+ L C yylval->number_ = new(yyextra->pool_) CYNumber(strtoull(yytext + 2, NULL, 16)); return tk::NumericLiteral;
-0[0-7]+ L C yylval->number_ = new(yyextra->pool_) CYNumber(strtoull(yytext + 1, NULL, 8)); return tk::NumericLiteral;
-0[bB][0-1]+ L C yylval->number_ = new(yyextra->pool_) CYNumber(strtoull(yytext + 2, NULL, 2)); return tk::NumericLiteral;
+0[xX][0-9a-fA-F]+ L C I(number, Number(strtoull(yytext + 2, NULL, 16)), NumericLiteral);
+0[0-7]+ L C I(number, Number(strtoull(yytext + 1, NULL, 8)), NumericLiteral);
+0[bB][0-1]+ L C I(number, Number(strtoull(yytext + 2, NULL, 2)), NumericLiteral);
 
 \"([^"\\\n]|{Escape})*\"|'([^'\\\n]|{Escape})*' L C {
-    char *value(reinterpret_cast<char *>(apr_palloc(yyextra->pool_, yyleng)));
+    char *value(A char[yyleng]);
     char *local(value);
 
     for (yy_size_t i(1), e(yyleng - 1); i != e; ++i) {
@@ -382,8 +386,7 @@ XMLName {XMLNameStart}{XMLNamePart}*
     }
 
     *local = '\0';
-    yylval->string_ = new(yyextra->pool_) CYString(value, local - value);
-    return tk::StringLiteral;
+    I(string, String(value, local - value), StringLiteral);
 }
 
 \r?\n yylloc->end.lines(); yylloc->step(); N
index 7646e04e1690fb2ffdf4317906cc8912b9644b95..7cc9ef9d94ab481a03bb97fe85cdaf0764a40b4a 100644 (file)
@@ -47,6 +47,7 @@
 
 @if Bison24 %code requires {
 #include "Parser.hpp"
+#define CYNew new($pool)
 
 @begin ObjectiveC
 #include "ObjectiveC/Syntax.hpp"
@@ -739,7 +740,7 @@ PrimaryExpressionNoRE
 
 PrimaryExpressionNo
     : "this" { $$ = $1; }
-    | Identifier { $$ = new(driver.pool_) CYVariable($1); }
+    | Identifier { $$ = CYNew CYVariable($1); }
     | AutoComplete { driver.mode_ = CYDriver::AutoPrimary; YYACCEPT; }
     | Literal { $$ = $1; }
     | ArrayLiteral { $$ = $1; }
@@ -752,7 +753,7 @@ PrimaryExpressionBF
 /* }}} */
 /* 11.1.4 Array Initialiser {{{ */
 ArrayLiteral
-    : "[" ElementListOpt "]" { $$ = new(driver.pool_) CYArray($2); }
+    : "[" ElementListOpt "]" { $$ = CYNew CYArray($2); }
     ;
 
 Element
@@ -770,13 +771,13 @@ ElementListOpt
     ;
 
 ElementList
-    : ElementOpt "," ElementListOpt { $$ = new(driver.pool_) CYElement($1, $3); }
-    | Element { $$ = new(driver.pool_) CYElement($1, NULL); }
+    : ElementOpt "," ElementListOpt { $$ = CYNew CYElement($1, $3); }
+    | Element { $$ = CYNew CYElement($1, NULL); }
     ;
 /* }}} */
 /* 11.1.5 Object Initialiser {{{ */
 ObjectLiteral
-    : OpenBrace PropertyNameAndValueListOpt "}" { $$ = new(driver.pool_) CYObject($2); }
+    : OpenBrace PropertyNameAndValueListOpt "}" { $$ = CYNew CYObject($2); }
     ;
 
 PropertyNameAndValueList_
@@ -790,7 +791,7 @@ PropertyNameAndValueListOpt
     ;
 
 PropertyNameAndValueList
-    : PropertyName ":" AssignmentExpression PropertyNameAndValueList_ { $$ = new(driver.pool_) CYProperty($1, $3, $4); }
+    : PropertyName ":" AssignmentExpression PropertyNameAndValueList_ { $$ = CYNew CYProperty($1, $3, $4); }
     ;
 
 PropertyName_
@@ -806,12 +807,12 @@ PropertyName
 
 /* 11.2 Left-Hand-Side Expressions {{{ */
 MemberExpression_
-    : "new" MemberExpression Arguments { $$ = new(driver.pool_) CYNew($2, $3); }
+    : "new" MemberExpression Arguments { $$ = CYNew cy::Syntax::New($2, $3); }
     ;
 
 MemberAccess
-    : "[" Expression "]" { $$ = new(driver.pool_) CYDirectMember(NULL, $2); }
-    | "." Identifier { $$ = new(driver.pool_) CYDirectMember(NULL, new(driver.pool_) CYString($2)); }
+    : "[" Expression "]" { $$ = CYNew CYDirectMember(NULL, $2); }
+    | "." Identifier { $$ = CYNew CYDirectMember(NULL, CYNew CYString($2)); }
     | "." AutoComplete { driver.mode_ = CYDriver::AutoDirect; YYACCEPT; }
     ;
 
@@ -838,7 +839,7 @@ MemberExpressionNoRE
 @end
 
 NewExpression_
-    : "new" NewExpression { $$ = new(driver.pool_) CYNew($2, NULL); }
+    : "new" NewExpression { $$ = CYNew cy::Syntax::New($2, NULL); }
     ;
 
 NewExpression
@@ -859,21 +860,21 @@ NewExpressionNoRE
 @end
 
 CallExpression
-    : MemberExpression Arguments { $$ = new(driver.pool_) CYCall($1, $2); }
-    | CallExpression Arguments { $$ = new(driver.pool_) CYCall($1, $2); }
+    : MemberExpression Arguments { $$ = CYNew CYCall($1, $2); }
+    | CallExpression Arguments { $$ = CYNew CYCall($1, $2); }
     | CallExpression { driver.context_ = $1; } MemberAccess { $3->SetLeft($1); $$ = $3; }
     ;
 
 CallExpressionNoBF
-    : MemberExpressionNoBF Arguments { $$ = new(driver.pool_) CYCall($1, $2); }
-    | CallExpressionNoBF Arguments { $$ = new(driver.pool_) CYCall($1, $2); }
+    : MemberExpressionNoBF Arguments { $$ = CYNew CYCall($1, $2); }
+    | CallExpressionNoBF Arguments { $$ = CYNew CYCall($1, $2); }
     | CallExpressionNoBF { driver.context_ = $1; } MemberAccess { $3->SetLeft($1); $$ = $3; }
     ;
 
 @begin C
 CallExpressionNoRE
-    : MemberExpressionNoRE Arguments { $$ = new(driver.pool_) CYCall($1, $2); }
-    | CallExpressionNoRE Arguments { $$ = new(driver.pool_) CYCall($1, $2); }
+    : MemberExpressionNoRE Arguments { $$ = CYNew CYCall($1, $2); }
+    | CallExpressionNoRE Arguments { $$ = CYNew CYCall($1, $2); }
     | CallExpressionNoRE { driver.context_ = $1; } MemberAccess { $3->SetLeft($1); $$ = $3; }
     ;
 @end
@@ -889,7 +890,7 @@ ArgumentListOpt
     ;
 
 ArgumentList
-    : AssignmentExpression ArgumentList_ { $$ = new(driver.pool_) CYArgument(NULL, $1, $2); }
+    : AssignmentExpression ArgumentList_ { $$ = CYNew CYArgument(NULL, $1, $2); }
     ;
 
 Arguments
@@ -916,37 +917,37 @@ LeftHandSideExpressionNoRE
 /* 11.3 Postfix Expressions {{{ */
 PostfixExpression
     : AssigneeExpression { $$ = $1; }
-    | LeftHandSideExpression "++" { $$ = new(driver.pool_) CYPostIncrement($1); }
-    | LeftHandSideExpression "--" { $$ = new(driver.pool_) CYPostDecrement($1); }
+    | LeftHandSideExpression "++" { $$ = CYNew CYPostIncrement($1); }
+    | LeftHandSideExpression "--" { $$ = CYNew CYPostDecrement($1); }
     ;
 
 PostfixExpressionNoBF
     : AssigneeExpressionNoBF { $$ = $1; }
-    | LeftHandSideExpressionNoBF "++" { $$ = new(driver.pool_) CYPostIncrement($1); }
-    | LeftHandSideExpressionNoBF "--" { $$ = new(driver.pool_) CYPostDecrement($1); }
+    | LeftHandSideExpressionNoBF "++" { $$ = CYNew CYPostIncrement($1); }
+    | LeftHandSideExpressionNoBF "--" { $$ = CYNew CYPostDecrement($1); }
     ;
 
 @begin C
 PostfixExpressionNoRE
     : AssigneeExpressionNoRE { $$ = $1; }
-    | LeftHandSideExpressionNoRE "++" { $$ = new(driver.pool_) CYPostIncrement($1); }
-    | LeftHandSideExpressionNoRE "--" { $$ = new(driver.pool_) CYPostDecrement($1); }
+    | LeftHandSideExpressionNoRE "++" { $$ = CYNew CYPostIncrement($1); }
+    | LeftHandSideExpressionNoRE "--" { $$ = CYNew CYPostDecrement($1); }
     ;
 @end
 /* }}} */
 /* 11.4 Unary Operators {{{ */
 UnaryExpression_
-    : "delete" UnaryExpression { $$ = new(driver.pool_) CYDelete($2); }
-    | "void" UnaryExpression { $$ = new(driver.pool_) CYVoid($2); }
-    | "typeof" UnaryExpression { $$ = new(driver.pool_) CYTypeOf($2); }
-    | "++" UnaryExpression { $$ = new(driver.pool_) CYPreIncrement($2); }
-    | "\n++" UnaryExpression { $$ = new(driver.pool_) CYPreIncrement($2); }
-    | "--" UnaryExpression { $$ = new(driver.pool_) CYPreDecrement($2); }
-    | "\n--" UnaryExpression { $$ = new(driver.pool_) CYPreDecrement($2); }
-    | "+" UnaryExpression { $$ = new(driver.pool_) CYAffirm($2); }
-    | "-" UnaryExpression { $$ = new(driver.pool_) CYNegate($2); }
-    | "~" UnaryExpression { $$ = new(driver.pool_) CYBitwiseNot($2); }
-    | "!" UnaryExpression { $$ = new(driver.pool_) CYLogicalNot($2); }
+    : "delete" UnaryExpression { $$ = CYNew CYDelete($2); }
+    | "void" UnaryExpression { $$ = CYNew CYVoid($2); }
+    | "typeof" UnaryExpression { $$ = CYNew CYTypeOf($2); }
+    | "++" UnaryExpression { $$ = CYNew CYPreIncrement($2); }
+    | "\n++" UnaryExpression { $$ = CYNew CYPreIncrement($2); }
+    | "--" UnaryExpression { $$ = CYNew CYPreDecrement($2); }
+    | "\n--" UnaryExpression { $$ = CYNew CYPreDecrement($2); }
+    | "+" UnaryExpression { $$ = CYNew CYAffirm($2); }
+    | "-" UnaryExpression { $$ = CYNew CYNegate($2); }
+    | "~" UnaryExpression { $$ = CYNew CYBitwiseNot($2); }
+    | "!" UnaryExpression { $$ = CYNew CYLogicalNot($2); }
     ;
 
 UnaryExpression
@@ -969,58 +970,58 @@ UnaryExpressionNoRE
 /* 11.5 Multiplicative Operators {{{ */
 MultiplicativeExpression
     : UnaryExpression { $$ = $1; }
-    | MultiplicativeExpression "*" UnaryExpression { $$ = new(driver.pool_) CYMultiply($1, $3); }
-    | MultiplicativeExpression "/" UnaryExpression { $$ = new(driver.pool_) CYDivide($1, $3); }
-    | MultiplicativeExpression "%" UnaryExpression { $$ = new(driver.pool_) CYModulus($1, $3); }
+    | MultiplicativeExpression "*" UnaryExpression { $$ = CYNew CYMultiply($1, $3); }
+    | MultiplicativeExpression "/" UnaryExpression { $$ = CYNew CYDivide($1, $3); }
+    | MultiplicativeExpression "%" UnaryExpression { $$ = CYNew CYModulus($1, $3); }
     ;
 
 MultiplicativeExpressionNoBF
     : UnaryExpressionNoBF { $$ = $1; }
-    | MultiplicativeExpressionNoBF "*" UnaryExpression { $$ = new(driver.pool_) CYMultiply($1, $3); }
-    | MultiplicativeExpressionNoBF "/" UnaryExpression { $$ = new(driver.pool_) CYDivide($1, $3); }
-    | MultiplicativeExpressionNoBF "%" UnaryExpression { $$ = new(driver.pool_) CYModulus($1, $3); }
+    | MultiplicativeExpressionNoBF "*" UnaryExpression { $$ = CYNew CYMultiply($1, $3); }
+    | MultiplicativeExpressionNoBF "/" UnaryExpression { $$ = CYNew CYDivide($1, $3); }
+    | MultiplicativeExpressionNoBF "%" UnaryExpression { $$ = CYNew CYModulus($1, $3); }
     ;
 /* }}} */
 /* 11.6 Additive Operators {{{ */
 AdditiveExpression
     : MultiplicativeExpression { $$ = $1; }
-    | AdditiveExpression "+" MultiplicativeExpression { $$ = new(driver.pool_) CYAdd($1, $3); }
-    | AdditiveExpression "-" MultiplicativeExpression { $$ = new(driver.pool_) CYSubtract($1, $3); }
+    | AdditiveExpression "+" MultiplicativeExpression { $$ = CYNew CYAdd($1, $3); }
+    | AdditiveExpression "-" MultiplicativeExpression { $$ = CYNew CYSubtract($1, $3); }
     ;
 
 AdditiveExpressionNoBF
     : MultiplicativeExpressionNoBF { $$ = $1; }
-    | AdditiveExpressionNoBF "+" MultiplicativeExpression { $$ = new(driver.pool_) CYAdd($1, $3); }
-    | AdditiveExpressionNoBF "-" MultiplicativeExpression { $$ = new(driver.pool_) CYSubtract($1, $3); }
+    | AdditiveExpressionNoBF "+" MultiplicativeExpression { $$ = CYNew CYAdd($1, $3); }
+    | AdditiveExpressionNoBF "-" MultiplicativeExpression { $$ = CYNew CYSubtract($1, $3); }
     ;
 /* }}} */
 /* 11.7 Bitwise Shift Operators {{{ */
 ShiftExpression
     : AdditiveExpression { $$ = $1; }
-    | ShiftExpression "<<" AdditiveExpression { $$ = new(driver.pool_) CYShiftLeft($1, $3); }
-    | ShiftExpression ">>" AdditiveExpression { $$ = new(driver.pool_) CYShiftRightSigned($1, $3); }
-    | ShiftExpression ">>>" AdditiveExpression { $$ = new(driver.pool_) CYShiftRightUnsigned($1, $3); }
+    | ShiftExpression "<<" AdditiveExpression { $$ = CYNew CYShiftLeft($1, $3); }
+    | ShiftExpression ">>" AdditiveExpression { $$ = CYNew CYShiftRightSigned($1, $3); }
+    | ShiftExpression ">>>" AdditiveExpression { $$ = CYNew CYShiftRightUnsigned($1, $3); }
     ;
 
 ShiftExpressionNoBF
     : AdditiveExpressionNoBF { $$ = $1; }
-    | ShiftExpressionNoBF "<<" AdditiveExpression { $$ = new(driver.pool_) CYShiftLeft($1, $3); }
-    | ShiftExpressionNoBF ">>" AdditiveExpression { $$ = new(driver.pool_) CYShiftRightSigned($1, $3); }
-    | ShiftExpressionNoBF ">>>" AdditiveExpression { $$ = new(driver.pool_) CYShiftRightUnsigned($1, $3); }
+    | ShiftExpressionNoBF "<<" AdditiveExpression { $$ = CYNew CYShiftLeft($1, $3); }
+    | ShiftExpressionNoBF ">>" AdditiveExpression { $$ = CYNew CYShiftRightSigned($1, $3); }
+    | ShiftExpressionNoBF ">>>" AdditiveExpression { $$ = CYNew CYShiftRightUnsigned($1, $3); }
     ;
 /* }}} */
 /* 11.8 Relational Operators {{{ */
 RelationalExpressionNoIn_
-    : "<" ShiftExpression { $$ = new(driver.pool_) CYLess(NULL, $2); }
-    | ">" ShiftExpression { $$ = new(driver.pool_) CYGreater(NULL, $2); }
-    | "<=" ShiftExpression { $$ = new(driver.pool_) CYLessOrEqual(NULL, $2); }
-    | ">=" ShiftExpression { $$ = new(driver.pool_) CYGreaterOrEqual(NULL, $2); }
-    | "instanceof" ShiftExpression { $$ = new(driver.pool_) CYInstanceOf(NULL, $2); }
+    : "<" ShiftExpression { $$ = CYNew CYLess(NULL, $2); }
+    | ">" ShiftExpression { $$ = CYNew CYGreater(NULL, $2); }
+    | "<=" ShiftExpression { $$ = CYNew CYLessOrEqual(NULL, $2); }
+    | ">=" ShiftExpression { $$ = CYNew CYGreaterOrEqual(NULL, $2); }
+    | "instanceof" ShiftExpression { $$ = CYNew CYInstanceOf(NULL, $2); }
     ;
 
 RelationalExpression_
     : RelationalExpressionNoIn_ { $$ = $1; }
-    | "in" ShiftExpression { $$ = new(driver.pool_) CYIn(NULL, $2); }
+    | "in" ShiftExpression { $$ = CYNew CYIn(NULL, $2); }
     ;
 
 RelationalExpression
@@ -1041,135 +1042,135 @@ RelationalExpressionNoBF
 /* 11.9 Equality Operators {{{ */
 EqualityExpression
     : RelationalExpression { $$ = $1; }
-    | EqualityExpression "==" RelationalExpression { $$ = new(driver.pool_) CYEqual($1, $3); }
-    | EqualityExpression "!=" RelationalExpression { $$ = new(driver.pool_) CYNotEqual($1, $3); }
-    | EqualityExpression "===" RelationalExpression { $$ = new(driver.pool_) CYIdentical($1, $3); }
-    | EqualityExpression "!==" RelationalExpression { $$ = new(driver.pool_) CYNotIdentical($1, $3); }
+    | EqualityExpression "==" RelationalExpression { $$ = CYNew CYEqual($1, $3); }
+    | EqualityExpression "!=" RelationalExpression { $$ = CYNew CYNotEqual($1, $3); }
+    | EqualityExpression "===" RelationalExpression { $$ = CYNew CYIdentical($1, $3); }
+    | EqualityExpression "!==" RelationalExpression { $$ = CYNew CYNotIdentical($1, $3); }
     ;
 
 EqualityExpressionNoIn
     : RelationalExpressionNoIn { $$ = $1; }
-    | EqualityExpressionNoIn "==" RelationalExpressionNoIn { $$ = new(driver.pool_) CYEqual($1, $3); }
-    | EqualityExpressionNoIn "!=" RelationalExpressionNoIn { $$ = new(driver.pool_) CYNotEqual($1, $3); }
-    | EqualityExpressionNoIn "===" RelationalExpressionNoIn { $$ = new(driver.pool_) CYIdentical($1, $3); }
-    | EqualityExpressionNoIn "!==" RelationalExpressionNoIn { $$ = new(driver.pool_) CYNotIdentical($1, $3); }
+    | EqualityExpressionNoIn "==" RelationalExpressionNoIn { $$ = CYNew CYEqual($1, $3); }
+    | EqualityExpressionNoIn "!=" RelationalExpressionNoIn { $$ = CYNew CYNotEqual($1, $3); }
+    | EqualityExpressionNoIn "===" RelationalExpressionNoIn { $$ = CYNew CYIdentical($1, $3); }
+    | EqualityExpressionNoIn "!==" RelationalExpressionNoIn { $$ = CYNew CYNotIdentical($1, $3); }
     ;
 
 EqualityExpressionNoBF
     : RelationalExpressionNoBF { $$ = $1; }
-    | EqualityExpressionNoBF "==" RelationalExpression { $$ = new(driver.pool_) CYEqual($1, $3); }
-    | EqualityExpressionNoBF "!=" RelationalExpression { $$ = new(driver.pool_) CYNotEqual($1, $3); }
-    | EqualityExpressionNoBF "===" RelationalExpression { $$ = new(driver.pool_) CYIdentical($1, $3); }
-    | EqualityExpressionNoBF "!==" RelationalExpression { $$ = new(driver.pool_) CYNotIdentical($1, $3); }
+    | EqualityExpressionNoBF "==" RelationalExpression { $$ = CYNew CYEqual($1, $3); }
+    | EqualityExpressionNoBF "!=" RelationalExpression { $$ = CYNew CYNotEqual($1, $3); }
+    | EqualityExpressionNoBF "===" RelationalExpression { $$ = CYNew CYIdentical($1, $3); }
+    | EqualityExpressionNoBF "!==" RelationalExpression { $$ = CYNew CYNotIdentical($1, $3); }
     ;
 /* }}} */
 /* 11.10 Binary Bitwise Operators {{{ */
 BitwiseANDExpression
     : EqualityExpression { $$ = $1; }
-    | BitwiseANDExpression "&" EqualityExpression { $$ = new(driver.pool_) CYBitwiseAnd($1, $3); }
+    | BitwiseANDExpression "&" EqualityExpression { $$ = CYNew CYBitwiseAnd($1, $3); }
     ;
 
 BitwiseANDExpressionNoIn
     : EqualityExpressionNoIn { $$ = $1; }
-    | BitwiseANDExpressionNoIn "&" EqualityExpressionNoIn { $$ = new(driver.pool_) CYBitwiseAnd($1, $3); }
+    | BitwiseANDExpressionNoIn "&" EqualityExpressionNoIn { $$ = CYNew CYBitwiseAnd($1, $3); }
     ;
 
 BitwiseANDExpressionNoBF
     : EqualityExpressionNoBF { $$ = $1; }
-    | BitwiseANDExpressionNoBF "&" EqualityExpression { $$ = new(driver.pool_) CYBitwiseAnd($1, $3); }
+    | BitwiseANDExpressionNoBF "&" EqualityExpression { $$ = CYNew CYBitwiseAnd($1, $3); }
     ;
 
 BitwiseXORExpression
     : BitwiseANDExpression { $$ = $1; }
-    | BitwiseXORExpression "^" BitwiseANDExpression { $$ = new(driver.pool_) CYBitwiseXOr($1, $3); }
+    | BitwiseXORExpression "^" BitwiseANDExpression { $$ = CYNew CYBitwiseXOr($1, $3); }
     ;
 
 BitwiseXORExpressionNoIn
     : BitwiseANDExpressionNoIn { $$ = $1; }
-    | BitwiseXORExpressionNoIn "^" BitwiseANDExpressionNoIn { $$ = new(driver.pool_) CYBitwiseXOr($1, $3); }
+    | BitwiseXORExpressionNoIn "^" BitwiseANDExpressionNoIn { $$ = CYNew CYBitwiseXOr($1, $3); }
     ;
 
 BitwiseXORExpressionNoBF
     : BitwiseANDExpressionNoBF { $$ = $1; }
-    | BitwiseXORExpressionNoBF "^" BitwiseANDExpression { $$ = new(driver.pool_) CYBitwiseXOr($1, $3); }
+    | BitwiseXORExpressionNoBF "^" BitwiseANDExpression { $$ = CYNew CYBitwiseXOr($1, $3); }
     ;
 
 BitwiseORExpression
     : BitwiseXORExpression { $$ = $1; }
-    | BitwiseORExpression "|" BitwiseXORExpression { $$ = new(driver.pool_) CYBitwiseOr($1, $3); }
+    | BitwiseORExpression "|" BitwiseXORExpression { $$ = CYNew CYBitwiseOr($1, $3); }
     ;
 
 BitwiseORExpressionNoIn
     : BitwiseXORExpressionNoIn { $$ = $1; }
-    | BitwiseORExpressionNoIn "|" BitwiseXORExpressionNoIn { $$ = new(driver.pool_) CYBitwiseOr($1, $3); }
+    | BitwiseORExpressionNoIn "|" BitwiseXORExpressionNoIn { $$ = CYNew CYBitwiseOr($1, $3); }
     ;
 
 BitwiseORExpressionNoBF
     : BitwiseXORExpressionNoBF { $$ = $1; }
-    | BitwiseORExpressionNoBF "|" BitwiseXORExpression { $$ = new(driver.pool_) CYBitwiseOr($1, $3); }
+    | BitwiseORExpressionNoBF "|" BitwiseXORExpression { $$ = CYNew CYBitwiseOr($1, $3); }
     ;
 /* }}} */
 /* 11.11 Binary Logical Operators {{{ */
 LogicalANDExpression
     : BitwiseORExpression { $$ = $1; }
-    | LogicalANDExpression "&&" BitwiseORExpression { $$ = new(driver.pool_) CYLogicalAnd($1, $3); }
+    | LogicalANDExpression "&&" BitwiseORExpression { $$ = CYNew CYLogicalAnd($1, $3); }
     ;
 
 LogicalANDExpressionNoIn
     : BitwiseORExpressionNoIn { $$ = $1; }
-    | LogicalANDExpressionNoIn "&&" BitwiseORExpressionNoIn { $$ = new(driver.pool_) CYLogicalAnd($1, $3); }
+    | LogicalANDExpressionNoIn "&&" BitwiseORExpressionNoIn { $$ = CYNew CYLogicalAnd($1, $3); }
     ;
 
 LogicalANDExpressionNoBF
     : BitwiseORExpressionNoBF { $$ = $1; }
-    | LogicalANDExpressionNoBF "&&" BitwiseORExpression { $$ = new(driver.pool_) CYLogicalAnd($1, $3); }
+    | LogicalANDExpressionNoBF "&&" BitwiseORExpression { $$ = CYNew CYLogicalAnd($1, $3); }
     ;
 
 LogicalORExpression
     : LogicalANDExpression { $$ = $1; }
-    | LogicalORExpression "||" LogicalANDExpression { $$ = new(driver.pool_) CYLogicalOr($1, $3); }
+    | LogicalORExpression "||" LogicalANDExpression { $$ = CYNew CYLogicalOr($1, $3); }
     ;
 
 LogicalORExpressionNoIn
     : LogicalANDExpressionNoIn { $$ = $1; }
-    | LogicalORExpressionNoIn "||" LogicalANDExpressionNoIn { $$ = new(driver.pool_) CYLogicalOr($1, $3); }
+    | LogicalORExpressionNoIn "||" LogicalANDExpressionNoIn { $$ = CYNew CYLogicalOr($1, $3); }
     ;
 
 LogicalORExpressionNoBF
     : LogicalANDExpressionNoBF { $$ = $1; }
-    | LogicalORExpressionNoBF "||" LogicalANDExpression { $$ = new(driver.pool_) CYLogicalOr($1, $3); }
+    | LogicalORExpressionNoBF "||" LogicalANDExpression { $$ = CYNew CYLogicalOr($1, $3); }
     ;
 /* }}} */
 /* 11.12 Conditional Operator ( ? : ) {{{ */
 ConditionalExpression
     : LogicalORExpression { $$ = $1; }
-    | LogicalORExpression "?" AssignmentExpression ":" AssignmentExpression { $$ = new(driver.pool_) CYCondition($1, $3, $5); }
+    | LogicalORExpression "?" AssignmentExpression ":" AssignmentExpression { $$ = CYNew CYCondition($1, $3, $5); }
     ;
 
 ConditionalExpressionNoIn
     : LogicalORExpressionNoIn { $$ = $1; }
-    | LogicalORExpressionNoIn "?" AssignmentExpression ":" AssignmentExpressionNoIn { $$ = new(driver.pool_) CYCondition($1, $3, $5); }
+    | LogicalORExpressionNoIn "?" AssignmentExpression ":" AssignmentExpressionNoIn { $$ = CYNew CYCondition($1, $3, $5); }
     ;
 
 ConditionalExpressionNoBF
     : LogicalORExpressionNoBF { $$ = $1; }
-    | LogicalORExpressionNoBF "?" AssignmentExpression ":" AssignmentExpression { $$ = new(driver.pool_) CYCondition($1, $3, $5); }
+    | LogicalORExpressionNoBF "?" AssignmentExpression ":" AssignmentExpression { $$ = CYNew CYCondition($1, $3, $5); }
     ;
 /* }}} */
 /* 11.13 Assignment Operators {{{ */
 AssignmentExpression_
-    : "=" AssignmentExpression { $$ = new(driver.pool_) CYAssign(NULL, $2); }
-    | "*=" AssignmentExpression { $$ = new(driver.pool_) CYMultiplyAssign(NULL, $2); }
-    | "/=" AssignmentExpression { $$ = new(driver.pool_) CYDivideAssign(NULL, $2); }
-    | "%=" AssignmentExpression { $$ = new(driver.pool_) CYModulusAssign(NULL, $2); }
-    | "+=" AssignmentExpression { $$ = new(driver.pool_) CYAddAssign(NULL, $2); }
-    | "-=" AssignmentExpression { $$ = new(driver.pool_) CYSubtractAssign(NULL, $2); }
-    | "<<=" AssignmentExpression { $$ = new(driver.pool_) CYShiftLeftAssign(NULL, $2); }
-    | ">>=" AssignmentExpression { $$ = new(driver.pool_) CYShiftRightSignedAssign(NULL, $2); }
-    | ">>>=" AssignmentExpression { $$ = new(driver.pool_) CYShiftRightUnsignedAssign(NULL, $2); }
-    | "&=" AssignmentExpression { $$ = new(driver.pool_) CYBitwiseAndAssign(NULL, $2); }
-    | "^=" AssignmentExpression { $$ = new(driver.pool_) CYBitwiseXOrAssign(NULL, $2); }
-    | "|=" AssignmentExpression { $$ = new(driver.pool_) CYBitwiseOrAssign(NULL, $2); }
+    : "=" AssignmentExpression { $$ = CYNew CYAssign(NULL, $2); }
+    | "*=" AssignmentExpression { $$ = CYNew CYMultiplyAssign(NULL, $2); }
+    | "/=" AssignmentExpression { $$ = CYNew CYDivideAssign(NULL, $2); }
+    | "%=" AssignmentExpression { $$ = CYNew CYModulusAssign(NULL, $2); }
+    | "+=" AssignmentExpression { $$ = CYNew CYAddAssign(NULL, $2); }
+    | "-=" AssignmentExpression { $$ = CYNew CYSubtractAssign(NULL, $2); }
+    | "<<=" AssignmentExpression { $$ = CYNew CYShiftLeftAssign(NULL, $2); }
+    | ">>=" AssignmentExpression { $$ = CYNew CYShiftRightSignedAssign(NULL, $2); }
+    | ">>>=" AssignmentExpression { $$ = CYNew CYShiftRightUnsignedAssign(NULL, $2); }
+    | "&=" AssignmentExpression { $$ = CYNew CYBitwiseAndAssign(NULL, $2); }
+    | "^=" AssignmentExpression { $$ = CYNew CYBitwiseXOrAssign(NULL, $2); }
+    | "|=" AssignmentExpression { $$ = CYNew CYBitwiseOrAssign(NULL, $2); }
     ;
 
 AssigneeExpression
@@ -1200,18 +1201,18 @@ AssignmentExpression
 
 AssignmentExpressionNoIn
     : ConditionalExpressionNoIn { $$ = $1; }
-    | AssigneeExpression "=" AssignmentExpressionNoIn { $$ = new(driver.pool_) CYAssign($1, $3); }
-    | AssigneeExpression "*=" AssignmentExpressionNoIn { $$ = new(driver.pool_) CYMultiplyAssign($1, $3); }
-    | AssigneeExpression "/=" AssignmentExpressionNoIn { $$ = new(driver.pool_) CYDivideAssign($1, $3); }
-    | AssigneeExpression "%=" AssignmentExpressionNoIn { $$ = new(driver.pool_) CYModulusAssign($1, $3); }
-    | AssigneeExpression "+=" AssignmentExpressionNoIn { $$ = new(driver.pool_) CYAddAssign($1, $3); }
-    | AssigneeExpression "-=" AssignmentExpressionNoIn { $$ = new(driver.pool_) CYSubtractAssign($1, $3); }
-    | AssigneeExpression "<<=" AssignmentExpressionNoIn { $$ = new(driver.pool_) CYShiftLeftAssign($1, $3); }
-    | AssigneeExpression ">>=" AssignmentExpressionNoIn { $$ = new(driver.pool_) CYShiftRightSignedAssign($1, $3); }
-    | AssigneeExpression ">>>=" AssignmentExpressionNoIn { $$ = new(driver.pool_) CYShiftRightUnsignedAssign($1, $3); }
-    | AssigneeExpression "&=" AssignmentExpressionNoIn { $$ = new(driver.pool_) CYBitwiseAndAssign($1, $3); }
-    | AssigneeExpression "^=" AssignmentExpressionNoIn { $$ = new(driver.pool_) CYBitwiseXOrAssign($1, $3); }
-    | AssigneeExpression "|=" AssignmentExpressionNoIn { $$ = new(driver.pool_) CYBitwiseOrAssign($1, $3); }
+    | AssigneeExpression "=" AssignmentExpressionNoIn { $$ = CYNew CYAssign($1, $3); }
+    | AssigneeExpression "*=" AssignmentExpressionNoIn { $$ = CYNew CYMultiplyAssign($1, $3); }
+    | AssigneeExpression "/=" AssignmentExpressionNoIn { $$ = CYNew CYDivideAssign($1, $3); }
+    | AssigneeExpression "%=" AssignmentExpressionNoIn { $$ = CYNew CYModulusAssign($1, $3); }
+    | AssigneeExpression "+=" AssignmentExpressionNoIn { $$ = CYNew CYAddAssign($1, $3); }
+    | AssigneeExpression "-=" AssignmentExpressionNoIn { $$ = CYNew CYSubtractAssign($1, $3); }
+    | AssigneeExpression "<<=" AssignmentExpressionNoIn { $$ = CYNew CYShiftLeftAssign($1, $3); }
+    | AssigneeExpression ">>=" AssignmentExpressionNoIn { $$ = CYNew CYShiftRightSignedAssign($1, $3); }
+    | AssigneeExpression ">>>=" AssignmentExpressionNoIn { $$ = CYNew CYShiftRightUnsignedAssign($1, $3); }
+    | AssigneeExpression "&=" AssignmentExpressionNoIn { $$ = CYNew CYBitwiseAndAssign($1, $3); }
+    | AssigneeExpression "^=" AssignmentExpressionNoIn { $$ = CYNew CYBitwiseXOrAssign($1, $3); }
+    | AssigneeExpression "|=" AssignmentExpressionNoIn { $$ = CYNew CYBitwiseOrAssign($1, $3); }
     ;
 
 AssignmentExpressionNoBF
@@ -1221,12 +1222,12 @@ AssignmentExpressionNoBF
 /* }}} */
 /* 11.14 Comma Operator {{{ */
 Expression_
-    : "," Expression { $$ = new(driver.pool_) CYCompound($2); }
+    : "," Expression { $$ = CYNew CYCompound($2); }
     | { $$ = NULL; }
     ;
 
 ExpressionNoIn_
-    : "," ExpressionNoIn { $$ = new(driver.pool_) CYCompound($2); }
+    : "," ExpressionNoIn { $$ = CYNew CYCompound($2); }
     | { $$ = NULL; }
     ;
 
@@ -1281,7 +1282,7 @@ Block_
     ;
 
 Block
-    : Block_ { if ($1) $$ = new(driver.pool_) CYBlock($1); else $$ = new(driver.pool_) CYEmpty(); }
+    : Block_ { if ($1) $$ = CYNew CYBlock($1); else $$ = CYNew CYEmpty(); }
     ;
 
 StatementList
@@ -1295,7 +1296,7 @@ StatementListOpt
 /* }}} */
 /* 12.2 Variable Statement {{{ */
 VariableStatement
-    : "var" VariableDeclarationList Terminator { $$ = new(driver.pool_) CYVar($2); }
+    : "var" VariableDeclarationList Terminator { $$ = CYNew CYVar($2); }
     ;
 
 VariableDeclarationList_
@@ -1309,19 +1310,19 @@ VariableDeclarationListNoIn_
     ;
 
 VariableDeclarationList
-    : VariableDeclaration VariableDeclarationList_ { $$ = new(driver.pool_) CYDeclarations($1, $2); }
+    : VariableDeclaration VariableDeclarationList_ { $$ = CYNew CYDeclarations($1, $2); }
     ;
 
 VariableDeclarationListNoIn
-    : VariableDeclarationNoIn VariableDeclarationListNoIn_ { $$ = new(driver.pool_) CYDeclarations($1, $2); }
+    : VariableDeclarationNoIn VariableDeclarationListNoIn_ { $$ = CYNew CYDeclarations($1, $2); }
     ;
 
 VariableDeclaration
-    : Identifier InitialiserOpt { $$ = new(driver.pool_) CYDeclaration($1, $2); }
+    : Identifier InitialiserOpt { $$ = CYNew CYDeclaration($1, $2); }
     ;
 
 VariableDeclarationNoIn
-    : Identifier InitialiserNoInOpt { $$ = new(driver.pool_) CYDeclaration($1, $2); }
+    : Identifier InitialiserNoInOpt { $$ = CYNew CYDeclaration($1, $2); }
     ;
 
 InitialiserOpt
@@ -1344,12 +1345,12 @@ InitialiserNoIn
 /* }}} */
 /* 12.3 Empty Statement {{{ */
 EmptyStatement
-    : ";" { $$ = new(driver.pool_) CYEmpty(); }
+    : ";" { $$ = CYNew CYEmpty(); }
     ;
 /* }}} */
 /* 12.4 Expression Statement {{{ */
 ExpressionStatement
-    : ExpressionNoBF Terminator { $$ = new(driver.pool_) CYExpress($1); }
+    : ExpressionNoBF Terminator { $$ = CYNew CYExpress($1); }
     ;
 /* }}} */
 /* 12.5 The if Statement {{{ */
@@ -1359,7 +1360,7 @@ ElseStatementOpt
     ;
 
 IfStatement
-    : "if" "(" Expression ")" Statement ElseStatementOpt { $$ = new(driver.pool_) CYIf($3, $5, $6); }
+    : "if" "(" Expression ")" Statement ElseStatementOpt { $$ = CYNew CYIf($3, $5, $6); }
     ;
 /* }}} */
 
@@ -1373,17 +1374,17 @@ IterationStatement
 /* }}} */
 /* 12.6.1 The do-while Statement {{{ */
 DoWhileStatement
-    : "do" Statement "while" "(" Expression ")" TerminatorOpt { $$ = new(driver.pool_) CYDoWhile($5, $2); }
+    : "do" Statement "while" "(" Expression ")" TerminatorOpt { $$ = CYNew CYDoWhile($5, $2); }
     ;
 /* }}} */
 /* 12.6.2 The while Statement {{{ */
 WhileStatement
-    : "while" "(" Expression ")" Statement { $$ = new(driver.pool_) CYWhile($3, $5); }
+    : "while" "(" Expression ")" Statement { $$ = CYNew CYWhile($3, $5); }
     ;
 /* }}} */
 /* 12.6.3 The for Statement {{{ */
 ForStatement
-    : "for" "(" ForStatementInitialiser ";" ExpressionOpt ";" ExpressionOpt ")" Statement { $$ = new(driver.pool_) CYFor($3, $5, $7, $9); }
+    : "for" "(" ForStatementInitialiser ";" ExpressionOpt ";" ExpressionOpt ")" Statement { $$ = CYNew CYFor($3, $5, $7, $9); }
     ;
 
 ForStatementInitialiser
@@ -1393,7 +1394,7 @@ ForStatementInitialiser
 /* }}} */
 /* 12.6.4 The for-in Statement {{{ */
 ForInStatement
-    : "for" "(" ForInStatementInitialiser "in" Expression ")" Statement { $$ = new(driver.pool_) CYForIn($3, $5, $7); }
+    : "for" "(" ForInStatementInitialiser "in" Expression ")" Statement { $$ = CYNew CYForIn($3, $5, $7); }
     ;
 
 ForInStatementInitialiser
@@ -1404,28 +1405,28 @@ ForInStatementInitialiser
 
 /* 12.7 The continue Statement {{{ */
 ContinueStatement
-    : "continue" IdentifierOpt Terminator { $$ = new(driver.pool_) CYContinue($2); }
+    : "continue" IdentifierOpt Terminator { $$ = CYNew CYContinue($2); }
     ;
 /* }}} */
 /* 12.8 The break Statement {{{ */
 BreakStatement
-    : "break" IdentifierOpt Terminator { $$ = new(driver.pool_) CYBreak($2); }
+    : "break" IdentifierOpt Terminator { $$ = CYNew CYBreak($2); }
     ;
 /* }}} */
 /* 12.9 The return Statement {{{ */
 ReturnStatement
-    : "return" ExpressionOpt Terminator { $$ = new(driver.pool_) CYReturn($2); }
+    : "return" ExpressionOpt Terminator { $$ = CYNew CYReturn($2); }
     ;
 /* }}} */
 /* 12.10 The with Statement {{{ */
 WithStatement
-    : "with" "(" Expression ")" Statement { $$ = new(driver.pool_) CYWith($3, $5); }
+    : "with" "(" Expression ")" Statement { $$ = CYNew CYWith($3, $5); }
     ;
 /* }}} */
 
 /* 12.11 The switch Statement {{{ */
 SwitchStatement
-    : "switch" "(" Expression ")" CaseBlock { $$ = new(driver.pool_) CYSwitch($3, $5); }
+    : "switch" "(" Expression ")" CaseBlock { $$ = CYNew CYSwitch($3, $5); }
     ;
 
 CaseBlock
@@ -1439,46 +1440,46 @@ CaseClausesOpt
     ;
 
 CaseClause
-    : "case" Expression ":" StatementListOpt { $$ = new(driver.pool_) CYClause($2, $4); }
+    : "case" Expression ":" StatementListOpt { $$ = CYNew CYClause($2, $4); }
     ;
 
 DefaultClause
-    : "default" ":" StatementListOpt { $$ = new(driver.pool_) CYClause(NULL, $3); }
+    : "default" ":" StatementListOpt { $$ = CYNew CYClause(NULL, $3); }
     ;
 /* }}} */
 /* 12.12 Labelled Statements {{{ */
 LabelledStatement
-    : Identifier ":" Statement { $$ = new(driver.pool_) CYLabel($1, $3); }
+    : Identifier ":" Statement { $$ = CYNew CYLabel($1, $3); }
     ;
 /* }}} */
 /* 12.13 The throw Statement {{{ */
 ThrowStatement
-    : "throw" Expression Terminator { $$ = new(driver.pool_) cy::Syntax::Throw($2); }
+    : "throw" Expression Terminator { $$ = CYNew cy::Syntax::Throw($2); }
     ;
 /* }}} */
 /* 12.14 The try Statement {{{ */
 TryStatement
-    : "try" Block_ CatchOpt FinallyOpt { $$ = new(driver.pool_) cy::Syntax::Try($2, $3, $4); }
+    : "try" Block_ CatchOpt FinallyOpt { $$ = CYNew cy::Syntax::Try($2, $3, $4); }
     ;
 
 CatchOpt
-    : "catch" "(" Identifier ")" Block_ { $$ = new(driver.pool_) cy::Syntax::Catch($3, $5); }
+    : "catch" "(" Identifier ")" Block_ { $$ = CYNew cy::Syntax::Catch($3, $5); }
     | { $$ = NULL; }
     ;
 
 FinallyOpt
-    : "finally" Block_ { $$ = new(driver.pool_) CYFinally($2); }
+    : "finally" Block_ { $$ = CYNew CYFinally($2); }
     | { $$ = NULL; }
     ;
 /* }}} */
 
 /* 13 Function Definition {{{ */
 FunctionDeclaration
-    : "function" Identifier "(" FormalParameterList ")" Brace FunctionBody "}" { $$ = new(driver.pool_) CYFunctionStatement($2, $4, $7); }
+    : "function" Identifier "(" FormalParameterList ")" Brace FunctionBody "}" { $$ = CYNew CYFunctionStatement($2, $4, $7); }
     ;
 
 FunctionExpression
-    : "function" IdentifierOpt "(" FormalParameterList ")" Brace FunctionBody "}" { $$ = new(driver.pool_) CYFunctionExpression($2, $4, $7); }
+    : "function" IdentifierOpt "(" FormalParameterList ")" Brace FunctionBody "}" { $$ = CYNew CYFunctionExpression($2, $4, $7); }
     ;
 
 FormalParameterList_
@@ -1487,7 +1488,7 @@ FormalParameterList_
     ;
 
 FormalParameterList
-    : Identifier FormalParameterList_ { $$ = new(driver.pool_) CYFunctionParameter($1, $2); }
+    : Identifier FormalParameterList_ { $$ = CYNew CYFunctionParameter($1, $2); }
     | { $$ = NULL; }
     ;
 
@@ -1497,7 +1498,7 @@ FunctionBody
 /* }}} */
 /* 14 Program {{{ */
 Program
-    : SourceElements { driver.program_ = new(driver.pool_) CYProgram($1); }
+    : SourceElements { driver.program_ = CYNew CYProgram($1); }
     ;
 
 SourceElements
@@ -1548,7 +1549,7 @@ TypeOpt
     ;
 
 MessageParameter
-    : Word ":" TypeOpt Identifier { $$ = new(driver.pool_) CYMessageParameter($1, $3, $4); }
+    : Word ":" TypeOpt Identifier { $$ = CYNew CYMessageParameter($1, $3, $4); }
     ;
 
 MessageParameterListOpt
@@ -1562,11 +1563,11 @@ MessageParameterList
 
 MessageParameters
     : MessageParameterList { $$ = $1; }
-    | Word { $$ = new(driver.pool_) CYMessageParameter($1, NULL, NULL); }
+    | Word { $$ = CYNew CYMessageParameter($1, NULL, NULL); }
     ;
 
 ClassMessageDeclaration
-    : MessageScope TypeOpt MessageParameters Brace FunctionBody "}" { $$ = new(driver.pool_) CYMessage($1, $2, $3, $5); }
+    : MessageScope TypeOpt MessageParameters Brace FunctionBody "}" { $$ = CYNew CYMessage($1, $2, $3, $5); }
     ;
 
 ClassMessageDeclarationListOpt
@@ -1587,7 +1588,7 @@ ClassNameOpt
 
 // XXX: this should be AssignmentExpressionNoRight
 ClassProtocols
-    : ShiftExpression ClassProtocolsOpt { $$ = new(driver.pool_) CYProtocol($1, $2); }
+    : ShiftExpression ClassProtocolsOpt { $$ = CYNew CYProtocol($1, $2); }
     ;
 
 ClassProtocolsOpt
@@ -1601,11 +1602,11 @@ ClassProtocolListOpt
     ;
 
 ClassExpression
-    : "@implementation" ClassNameOpt ClassSuperOpt ClassProtocolListOpt ClassFieldList ClassMessageDeclarationListOpt "@end" { $$ = new(driver.pool_) CYClassExpression($2, $3, $4, $5, $6); }
+    : "@implementation" ClassNameOpt ClassSuperOpt ClassProtocolListOpt ClassFieldList ClassMessageDeclarationListOpt "@end" { $$ = CYNew CYClassExpression($2, $3, $4, $5, $6); }
     ;
 
 ClassStatement
-    : "@implementation" ClassName ClassSuperOpt ClassProtocolListOpt ClassFieldList ClassMessageDeclarationListOpt "@end" { $$ = new(driver.pool_) CYClassStatement($2, $3, $4, $5, $6); }
+    : "@implementation" ClassName ClassSuperOpt ClassProtocolListOpt ClassFieldList ClassMessageDeclarationListOpt "@end" { $$ = CYNew CYClassStatement($2, $3, $4, $5, $6); }
     ;
 
 CategoryName
@@ -1613,7 +1614,7 @@ CategoryName
     ;
 
 CategoryStatement
-    : "@implementation" ClassName CategoryName ClassMessageDeclarationListOpt "@end" { $$ = new(driver.pool_) CYCategory($2, $4); }
+    : "@implementation" ClassName CategoryName ClassMessageDeclarationListOpt "@end" { $$ = CYNew CYCategory($2, $4); }
     ;
 
 PrimaryExpressionBF
@@ -1627,7 +1628,7 @@ Statement_
 /* }}} */
 /* Cycript (Objective-C): Send Message {{{ */
 VariadicCall
-    : "," AssignmentExpression VariadicCall { $$ = new(driver.pool_) CYArgument(NULL, $2, $3); }
+    : "," AssignmentExpression VariadicCall { $$ = CYNew CYArgument(NULL, $2, $3); }
     | { $$ = NULL; }
     ;
 
@@ -1642,17 +1643,17 @@ SelectorWordOpt
     ;
 
 SelectorCall
-    : SelectorWordOpt ":" AssignmentExpression SelectorCall_ { $$ = new(driver.pool_) CYArgument($1 ?: new(driver.pool_) CYBlank(), $3, $4); }
+    : SelectorWordOpt ":" AssignmentExpression SelectorCall_ { $$ = CYNew CYArgument($1 ?: CYNew CYBlank(), $3, $4); }
     ;
 
 SelectorList
     : SelectorCall { $$ = $1; }
-    | Word { $$ = new(driver.pool_) CYArgument($1, NULL); }
+    | Word { $$ = CYNew CYArgument($1, NULL); }
     ;
 
 MessageExpression
-    : "[" AssignmentExpression { driver.contexts_.push_back($2); } SelectorList "]" { driver.contexts_.pop_back(); } { $$ = new(driver.pool_) CYSendDirect($2, $4); }
-    | "[" LexSetRegExp "super" { driver.context_ = NULL; } SelectorList "]" { $$ = new(driver.pool_) CYSendSuper($5); }
+    : "[" AssignmentExpression { driver.contexts_.push_back($2); } SelectorList "]" { driver.contexts_.pop_back(); } { $$ = CYNew CYSendDirect($2, $4); }
+    | "[" LexSetRegExp "super" { driver.context_ = NULL; } SelectorList "]" { $$ = CYNew CYSendSuper($5); }
     ;
 
 SelectorExpressionOpt
@@ -1661,17 +1662,17 @@ SelectorExpressionOpt
     ;
 
 SelectorExpression_
-    : WordOpt ":" SelectorExpressionOpt { $$ = new(driver.pool_) CYSelectorPart($1, true, $3); }
+    : WordOpt ":" SelectorExpressionOpt { $$ = CYNew CYSelectorPart($1, true, $3); }
     ;
 
 SelectorExpression
     : SelectorExpression_ { $$ = $1; }
-    | Word { $$ = new(driver.pool_) CYSelectorPart($1, false, NULL); }
+    | Word { $$ = CYNew CYSelectorPart($1, false, NULL); }
     ;
 
 PrimaryExpressionNo
     : MessageExpression { $$ = $1; }
-    | "@selector" "(" SelectorExpression ")" { $$ = new(driver.pool_) CYSelector($3); }
+    | "@selector" "(" SelectorExpression ")" { $$ = CYNew CYSelector($3); }
     ;
 /* }}} */
 /* Cycript (Objective-C): @import Directive {{{ */
@@ -1688,7 +1689,7 @@ ImportPath
     ;
 
 SourceElement_
-    : "@import" ImportPath { $$ = new(driver.pool_) CYImport(); }
+    : "@import" ImportPath { $$ = CYNew CYImport(); }
     ;
 /* }}} */
 @end
@@ -1696,16 +1697,16 @@ SourceElement_
 @begin C
 /* Cycript (C): Pointer Indirection/Addressing {{{ */
 UnaryAssigneeExpression
-    : "*" UnaryExpressionNoRE { $$ = new(driver.pool_) CYIndirect($2); }
+    : "*" UnaryExpressionNoRE { $$ = CYNew CYIndirect($2); }
     ;
 
 UnaryExpression_
-    : "&" UnaryExpression { $$ = new(driver.pool_) CYAddressOf($2); }
+    : "&" UnaryExpression { $$ = CYNew CYAddressOf($2); }
     ;
 
 MemberAccess
-    : "->" "[" Expression "]" { $$ = new(driver.pool_) CYIndirectMember(NULL, $3); }
-    | "->" Identifier { $$ = new(driver.pool_) CYIndirectMember(NULL, new(driver.pool_) CYString($2)); }
+    : "->" "[" Expression "]" { $$ = CYNew CYIndirectMember(NULL, $3); }
+    | "->" Identifier { $$ = CYNew CYIndirectMember(NULL, CYNew CYString($2)); }
     | "->" AutoComplete { driver.mode_ = CYDriver::AutoIndirect; YYACCEPT; }
     ;
 /* }}} */
@@ -1764,7 +1765,7 @@ XMLMarkup
 /* }}} */
 /* 11.1 Primary Expressions {{{ */
 PrimaryExpressionNo
-    : PropertyIdentifier { $$ = new(driver.pool_) CYPropertyVariable($1); }
+    : PropertyIdentifier { $$ = CYNew CYPropertyVariable($1); }
     | XMLInitialiser { $$ = $1; }
     | XMLListInitialiser { $$ = $1; }
     ;
@@ -1777,32 +1778,32 @@ PropertyIdentifier
 /* }}} */
 /* 11.1.1 Attribute Identifiers {{{ */
 AttributeIdentifier
-    : "@" QualifiedIdentifier_ { $$ = new(driver.pool_) CYAttribute($2); }
+    : "@" QualifiedIdentifier_ { $$ = CYNew CYAttribute($2); }
     ;
 
 PropertySelector_
     : PropertySelector { $$ = $1; }
-    | "[" Expression "]" { $$ = new(driver.pool_) CYSelector($2); }
+    | "[" Expression "]" { $$ = CYNew CYSelector($2); }
     ;
 
 PropertySelector
-    : Identifier { $$ = new(driver.pool_) CYSelector($1); }
+    : Identifier { $$ = CYNew CYSelector($1); }
     | WildcardIdentifier { $$ = $1; }
     ;
 /* }}} */
 /* 11.1.2 Qualified Identifiers {{{ */
 QualifiedIdentifier_
-    : PropertySelector_ { $$ = new(driver.pool_) CYQualified(NULL, $1); }
+    : PropertySelector_ { $$ = CYNew CYQualified(NULL, $1); }
     | QualifiedIdentifier { $$ = $1; }
     ;
 
 QualifiedIdentifier
-    : PropertySelector "::" PropertySelector_ { $$ = new(driver.pool_) CYQualified($1, $3); }
+    : PropertySelector "::" PropertySelector_ { $$ = CYNew CYQualified($1, $3); }
     ;
 /* }}} */
 /* 11.1.3 Wildcard Identifiers {{{ */
 WildcardIdentifier
-    : "*" { $$ = new(driver.pool_) CYWildcard(); }
+    : "*" { $$ = CYNew CYWildcard(); }
     ;
 /* }}} */
 /* 11.1.4 XML Initialiser {{{ */
@@ -1862,7 +1863,7 @@ XMLElementContentOpt
 /* }}} */
 /* 11.1.5 XMLList Initialiser {{{ */
 XMLListInitialiser
-    : "<>" LexPushXMLContent XMLElementContent "</>" LexPop { $$ = new(driver.pool_) CYXMLList($3); }
+    : "<>" LexPushXMLContent XMLElementContent "</>" LexPop { $$ = CYNew CYXMLList($3); }
     ;
 /* }}} */
 /* 11.2 Left-Hand-Side Expressions {{{ */
@@ -1872,14 +1873,14 @@ PropertyIdentifier_
     ;
 
 MemberAccess
-    : "." PropertyIdentifier { $$ = new(driver.pool_) CYPropertyMember(NULL, $2); }
-    | ".." PropertyIdentifier_ { $$ = new(driver.pool_) CYDescendantMember(NULL, $2); }
-    | "." "(" Expression ")" { $$ = new(driver.pool_) CYFilteringPredicate(NULL, $3); }
+    : "." PropertyIdentifier { $$ = CYNew CYPropertyMember(NULL, $2); }
+    | ".." PropertyIdentifier_ { $$ = CYNew CYDescendantMember(NULL, $2); }
+    | "." "(" Expression ")" { $$ = CYNew CYFilteringPredicate(NULL, $3); }
     ;
 /* }}} */
 /* 12.1 The default xml namespace Statement {{{ */
 /* XXX: DefaultXMLNamespaceStatement
-    : "default" "xml" "namespace" "=" Expression Terminator { $$ = new(driver.pool_) CYDefaultXMLNamespace($5); }
+    : "default" "xml" "namespace" "=" Expression Terminator { $$ = CYNew CYDefaultXMLNamespace($5); }
     ;
 
 Statement_
@@ -1896,12 +1897,12 @@ PropertyNameAndValueList_
 
 /* JavaScript 1.7: Array Comprehensions {{{ */
 IfComprehension
-    : "if" "(" Expression ")" { $$ = new(driver.pool_) CYIfComprehension($3); }
+    : "if" "(" Expression ")" { $$ = CYNew CYIfComprehension($3); }
     ;
 
 ForComprehension
-    : "for" "(" Identifier "in" Expression ")" { $$ = new(driver.pool_) CYForInComprehension($3, $5); }
-    | "for" "each" "(" Identifier "in" Expression ")" { $$ = new(driver.pool_) CYForEachInComprehension($4, $6); }
+    : "for" "(" Identifier "in" Expression ")" { $$ = CYNew CYForInComprehension($3, $5); }
+    | "for" "each" "(" Identifier "in" Expression ")" { $$ = CYNew CYForEachInComprehension($4, $6); }
     ;
 
 ComprehensionListOpt
@@ -1915,17 +1916,17 @@ ComprehensionList
     ;
 
 PrimaryExpressionNo
-    : "[" AssignmentExpression ComprehensionList "]" { $$ = new(driver.pool_) CYArrayComprehension($2, $3); }
+    : "[" AssignmentExpression ComprehensionList "]" { $$ = CYNew CYArrayComprehension($2, $3); }
     ;
 /* }}} */
 /* JavaScript 1.7: for each {{{ */
 ForInStatement
-    : "for" "each" "(" ForInStatementInitialiser "in" Expression ")" Statement { $$ = new(driver.pool_) CYForEachIn($4, $6, $8); }
+    : "for" "each" "(" ForInStatementInitialiser "in" Expression ")" Statement { $$ = CYNew CYForEachIn($4, $6, $8); }
     ;
 /* }}} */
 /* JavaScript 1.7: let Statements {{{ *//*
 LetStatement
-    : "let" "(" VariableDeclarationList ")" Block_ { $$ = new(driver.pool_) CYLet($3, $5); }
+    : "let" "(" VariableDeclarationList ")" Block_ { $$ = CYNew CYLet($3, $5); }
     ;
 
 Statement_
@@ -1940,7 +1941,7 @@ Statement
 /* }}} */
 /* JavaScript FTW: Optional Arguments {{{ */
 FormalParameterList
-    : Identifier "=" AssignmentExpression FormalParameterList_ { $$ = new(driver.pool_) CYOptionalFunctionParameter($1, $3, $4); }
+    : Identifier "=" AssignmentExpression FormalParameterList_ { $$ = CYNew CYOptionalFunctionParameter($1, $3, $4); }
     ;
 /* }}} */
 /* JavaScript FTW: Ruby Blocks {{{ */
@@ -1950,7 +1951,7 @@ RubyProcParameterList_
     ;
 
 RubyProcParameterList
-    : Identifier RubyProcParameterList_ { $$ = new(driver.pool_) CYFunctionParameter($1, $2); }
+    : Identifier RubyProcParameterList_ { $$ = CYNew CYFunctionParameter($1, $2); }
     | { $$ = NULL; }
     ;
 
@@ -1960,20 +1961,20 @@ RubyProcParametersOpt
     ;
 
 RubyProcExpression
-    : "{" RubyProcParametersOpt StatementListOpt "}" { $$ = new(driver.pool_) CYRubyProc($2, $3); }
+    : "{" RubyProcParametersOpt StatementListOpt "}" { $$ = CYNew CYRubyProc($2, $3); }
     ;
 
 LeftHandSideExpression
-    : LeftHandSideExpression RubyProcExpression { $$ = new(driver.pool_) CYRubyBlock($1, $2); }
+    : LeftHandSideExpression RubyProcExpression { $$ = CYNew CYRubyBlock($1, $2); }
     ;
 
 LeftHandSideExpressionNoBF
-    : LeftHandSideExpressionNoBF RubyProcExpression { $$ = new(driver.pool_) CYRubyBlock($1, $2); }
+    : LeftHandSideExpressionNoBF RubyProcExpression { $$ = CYNew CYRubyBlock($1, $2); }
     ;
 
 @begin C
 LeftHandSideExpressionNoRE
-    : LeftHandSideExpressionNoRE RubyProcExpression { $$ = new(driver.pool_) CYRubyBlock($1, $2); }
+    : LeftHandSideExpressionNoRE RubyProcExpression { $$ = CYNew CYRubyBlock($1, $2); }
     ;
 @end
 /* }}} */
index 5b390eaf68369822f5ca818bfbbd69d61fa43606..a99274702f3e41c42f54e1182ed1a1d1e021a97c 100644 (file)
@@ -85,7 +85,7 @@ all := cycript
 #arch := $(shell $(dpkg_architecture) -qDEB_HOST_ARCH 2>/dev/null)
 #endif
 
-header := Cycript.tab.hh Parser.hpp Pooling.hpp cycript.hpp Internal.hpp Error.hpp String.hpp Exception.hpp Standard.hpp
+header := Cycript.tab.hh Parser.hpp Pooling.hpp Local.hpp cycript.hpp Internal.hpp Error.hpp String.hpp Exception.hpp Standard.hpp
 
 code := 
 code += Replace.lo Output.lo
index d375d10769674ebe7032edb9a73f91c645705a11..48ad71f4e434d4e69c72c3b70227ff4dddbb7c81 100644 (file)
@@ -240,11 +240,13 @@ double CYCastDouble(const char *value) {
     return CYCastDouble(value, strlen(value));
 }
 
-extern "C" void CydgetPoolParse(apr_pool_t *pool, const uint16_t **data, size_t *size) {
+extern "C" void CydgetPoolParse(apr_pool_t *remote, const uint16_t **data, size_t *size) {
+    CYLocalPool local;
+
     CYDriver driver;
     cy::parser parser(driver);
 
-    CYUTF8String utf8(CYPoolUTF8String(pool, CYUTF16String(*data, *size)));
+    CYUTF8String utf8(CYPoolUTF8String(local, CYUTF16String(*data, *size)));
 
     driver.data_ = utf8.data;
     driver.size_ = utf8.size;
@@ -253,14 +255,14 @@ extern "C" void CydgetPoolParse(apr_pool_t *pool, const uint16_t **data, size_t
         return;
 
     CYOptions options;
-    CYContext context(driver.pool_, options);
+    CYContext context(options);
     driver.program_->Replace(context);
     std::ostringstream str;
     CYOutput out(str, options);
     out << *driver.program_;
     std::string code(str.str());
 
-    CYUTF16String utf16(CYPoolUTF16String(pool, CYUTF8String(code.c_str(), code.size())));
+    CYUTF16String utf16(CYPoolUTF16String(remote, CYUTF8String(code.c_str(), code.size())));
 
     *data = utf16.data;
     *size = utf16.size;
diff --git a/Local.hpp b/Local.hpp
new file mode 100644 (file)
index 0000000..c223792
--- /dev/null
+++ b/Local.hpp
@@ -0,0 +1,63 @@
+/* Cycript - Inlining/Optimizing JavaScript Compiler
+ * Copyright (C) 2009  Jay Freeman (saurik)
+*/
+
+/* Modified BSD License {{{ */
+/*
+ *        Redistribution and use in source and binary
+ * forms, with or without modification, are permitted
+ * provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the
+ *    above copyright notice, this list of conditions
+ *    and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions
+ *    and the following disclaimer in the documentation
+ *    and/or other materials provided with the
+ *    distribution.
+ * 3. The name of the author may not be used to endorse
+ *    or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/* }}} */
+
+#ifndef CYLOCAL_HPP
+#define CYLOCAL_HPP
+
+template <typename Type_>
+struct CYLocal {
+    Type_ last_;
+
+    CYLocal(Type_ next) {
+        Type_ &top(Top());
+        last_ = top;
+        top = next;
+    }
+
+    ~CYLocal() {
+        Top() = last_;
+    }
+
+    static Type_ &Top() {
+        static __thread Type_ top;
+        return top;
+    }
+};
+
+#endif/*CYLOCAL_HPP*/
index 34281868e11f467ab1ba8e2808075cb0b852ca00..4d0166af9fc06da81520a115241c71770c72528e 100644 (file)
@@ -144,7 +144,7 @@ CYString *CYSelectorPart::Replace(CYContext &context) {
         if (part->value_)
             str << ':';
     }
-    return $S(apr_pstrdup(context.pool_, str.str().c_str()));
+    return $S(apr_pstrdup($pool, str.str().c_str()));
 }
 
 CYExpression *CYSendDirect::Replace(CYContext &context) {
@@ -173,5 +173,5 @@ CYExpression *CYSendDirect::Replace(CYContext &context) {
 }
 
 CYExpression *CYSendSuper::Replace(CYContext &context) {
-    return $ CYSendDirect($V("$cyr"), arguments_);
+    return $ CYSendDirect($V("cyr"), arguments_);
 }
index c6686587eb87345dedb17cbca06b77f078a20863..67c9877a492d7d63ff92e3e20b8bc322f5be5315 100644 (file)
@@ -521,7 +521,10 @@ void CYLet::Output(CYOutput &out, CYFlags flags) const {
     out << "let" << ' ' << '(' << *declarations_ << ')' << ' ' << code_;
 }
 
-void CYNew::Output(CYOutput &out, CYFlags flags) const {
+namespace cy {
+namespace Syntax {
+
+void New::Output(CYOutput &out, CYFlags flags) const {
     out << "new" << ' ';
     CYFlags jacks(CYNoCall | CYCenter(flags));
     constructor_->Output(out, Precedence(), jacks);
@@ -529,6 +532,8 @@ void CYNew::Output(CYOutput &out, CYFlags flags) const {
         out << '(' << *arguments_ << ')';
 }
 
+} }
+
 void CYNull::Output(CYOutput &out, CYFlags flags) const {
     CYWord::Output(out);
 }
index 49f2d10ad3cf851ae34eb3e911de610a695314b9..7945299711069f6241d8267a1bf828caac24ea92 100644 (file)
@@ -44,8 +44,7 @@ CYRange DigitRange_    (0x3ff000000000000LLU, 0x000000000000000LLU); // 0-9
 CYRange WordStartRange_(0x000001000000000LLU, 0x7fffffe87fffffeLLU); // A-Za-z_$
 CYRange WordEndRange_  (0x3ff001000000000LLU, 0x7fffffe87fffffeLLU); // A-Za-z_$0-9
 
-CYDriver::CYDriver(apr_pool_t *pool, const std::string &filename) :
-    pool_(pool),
+CYDriver::CYDriver(const std::string &filename) :
     state_(CYClear),
     data_(NULL),
     size_(0),
index ceb4b6fd25785a9e803bb4d9d6b3b166d1e2eed1..8773619990066e94baba5a1afc36a4242a7ec830 100644 (file)
@@ -369,7 +369,6 @@ struct CYProgram :
 struct CYNonLocal;
 
 struct CYContext {
-    apr_pool_t *pool_;
     CYOptions &options_;
 
     CYScope *scope_;
@@ -379,8 +378,7 @@ struct CYContext {
     CYNonLocal *nextlocal_;
     unsigned unique_;
 
-    CYContext(apr_pool_t *pool, CYOptions &options) :
-        pool_(pool),
+    CYContext(CYOptions &options) :
         options_(options),
         scope_(NULL),
         nonlocal_(NULL),
@@ -460,8 +458,6 @@ enum CYState {
 
 class CYDriver {
   public:
-    CYPool pool_;
-
     CYState state_;
     void *scanner_;
 
@@ -522,7 +518,7 @@ class CYDriver {
     void ScannerDestroy();
 
   public:
-    CYDriver(apr_pool_t *pool = NULL, const std::string &filename = "");
+    CYDriver(const std::string &filename = "");
     ~CYDriver();
 
     Condition GetCondition();
@@ -972,6 +968,11 @@ struct CYVariable :
     {
     }
 
+    CYVariable(const char *name) :
+        name_(new($pool) CYIdentifier(name))
+    {
+    }
+
     CYPrecedence(0)
     CYRightHand(false)
 
@@ -1356,13 +1357,16 @@ struct CYIndirectMember :
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
-struct CYNew :
+namespace cy {
+namespace Syntax {
+
+struct New :
     CYExpression
 {
     CYExpression *constructor_;
     CYArgument *arguments_;
 
-    CYNew(CYExpression *constructor, CYArgument *arguments) :
+    New(CYExpression *constructor, CYArgument *arguments) :
         constructor_(constructor),
         arguments_(arguments)
     {
@@ -1380,6 +1384,8 @@ struct CYNew :
     virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
 };
 
+} }
+
 struct CYCall :
     CYExpression
 {
index d1ee2b7a0f537f018c4ee5d4b58473bff5b4b108..96b49326701e766e51834b457aa4e5b9ac718d55 100644 (file)
@@ -44,6 +44,7 @@
 #include <apr_strings.h>
 
 #include "Exception.hpp"
+#include "Local.hpp"
 #include "Standard.hpp"
 
 #include <cstdlib>
@@ -169,4 +170,21 @@ struct CYPoolAllocator {
     };
 };
 
+class CYLocalPool :
+    public CYPool
+{
+  private:
+    CYLocal<apr_pool_t *> local_;
+
+  public:
+    CYLocalPool() :
+        CYPool(),
+        local_(operator apr_pool_t *())
+    {
+    }
+};
+
+#define $pool \
+    CYLocal<apr_pool_t *>::Top()
+
 #endif/*CYPOOLING_HPP*/
index 3fd02aac8ec811aca5092a7678f529244c44431a..db438b20b5baf546363e9bb2e82acc9db3a086ea 100644 (file)
@@ -204,8 +204,7 @@ void CYContext::NonLocal(CYStatement *&statements) {
 }
 
 CYIdentifier *CYContext::Unique() {
-    CYContext &context(*this);
-    return $ CYIdentifier(apr_psprintf(pool_, "$cy%u", unique_++));
+    return $ CYIdentifier(apr_psprintf($pool, "$cy%u", unique_++));
 }
 
 CYStatement *CYContinue::Replace(CYContext &context) {
@@ -351,11 +350,11 @@ CYStatement *CYForInComprehension::Replace(CYContext &context, CYStatement *stat
 }
 
 CYStatement *CYForEachIn::Replace(CYContext &context) {
-    CYVariable *cys($V("$cys")), *cyt($V("$cyt"));
+    CYIdentifier *cys($I("$cys")), *cyt($I("$cyt"));
 
-    return $ CYLet($L2($L($I("$cys"), set_), $L($I("$cyt"))), $$->*
-        $ CYForIn(cyt, cys, $ CYBlock($$->*
-            $E($ CYAssign(initialiser_->ForEachIn(context), $M(cys, cyt)))->*
+    return $ CYLet($L2($L(cys, set_), $L(cyt)), $$->*
+        $ CYForIn($V(cyt), $V(cys), $ CYBlock($$->*
+            $E($ CYAssign(initialiser_->ForEachIn(context), $M($V(cys), $V(cyt))))->*
             code_
         ))
     );
@@ -366,12 +365,12 @@ CYFunctionParameter *CYForEachInComprehension::Parameter(CYContext &context) con
 }
 
 CYStatement *CYForEachInComprehension::Replace(CYContext &context, CYStatement *statement) const {
-    CYVariable *cys($V("$cys")), *name($ CYVariable(name_));
+    CYIdentifier *cys($I("cys"));
 
     return $E($C0($F(NULL, $P1("$cys"), $$->*
-        $E($ CYAssign(cys, set_))->*
-        $ CYForIn(name, cys, $ CYBlock($$->*
-            $E($ CYAssign(name, $M(cys, name)))->*
+        $E($ CYAssign($V(cys), set_))->*
+        $ CYForIn($V(name_), $V(cys), $ CYBlock($$->*
+            $E($ CYAssign($V(name_), $M($V(cys), $V(name_))))->*
             CYComprehension::Replace(context, statement)
         ))
     )));
@@ -488,7 +487,10 @@ void CYMember::Replace_(CYContext &context) {
     context.Replace(property_);
 }
 
-CYExpression *CYNew::AddArgument(CYContext &context, CYExpression *value) {
+namespace cy {
+namespace Syntax {
+
+CYExpression *New::AddArgument(CYContext &context, CYExpression *value) {
     CYArgument **argument(&arguments_);
     while (*argument != NULL)
         argument = &(*argument)->next_;
@@ -496,12 +498,14 @@ CYExpression *CYNew::AddArgument(CYContext &context, CYExpression *value) {
     return this;
 }
 
-CYExpression *CYNew::Replace(CYContext &context) {
+CYExpression *New::Replace(CYContext &context) {
     context.Replace(constructor_);
     arguments_->Replace(context);
     return this;
 }
 
+} }
+
 CYNumber *CYNull::Number(CYContext &context) {
     return $D(0);
 }
@@ -516,7 +520,7 @@ CYNumber *CYNumber::Number(CYContext &context) {
 
 CYString *CYNumber::String(CYContext &context) {
     // XXX: there is a precise algorithm for this
-    return $S(apr_psprintf(context.pool_, "%.17g", Value()));
+    return $S(apr_psprintf($pool, "%.17g", Value()));
 }
 
 CYExpression *CYObject::Replace(CYContext &context) {
@@ -593,7 +597,7 @@ void CYProgram::Replace(CYContext &context) {
         const char *name;
 
         if (context.options_.verbose_)
-            name = apr_psprintf(context.pool_, "$%"APR_SIZE_T_FMT"", offset);
+            name = apr_psprintf($pool, "$%"APR_SIZE_T_FMT"", offset);
         else {
             char id[8];
             id[7] = '\0';
@@ -612,7 +616,7 @@ void CYProgram::Replace(CYContext &context) {
                 goto id;
             }
 
-            name = apr_pstrmemdup(context.pool_, id + position, 7 - position);
+            name = apr_pstrmemdup($pool, id + position, 7 - position);
             // XXX: at some point, this could become a keyword
         }
 
@@ -781,7 +785,7 @@ CYStatement *CYStatement::ReplaceAll(CYContext &context) { $T(NULL)
 
 CYString *CYString::Concat(CYContext &context, CYString *rhs) const {
     size_t size(size_ + rhs->size_);
-    char *value(new(context.pool_) char[size + 1]);
+    char *value($ char[size + 1]);
     memcpy(value, value_, size_);
     memcpy(value + size_, rhs->value_, rhs->size_);
     value[size] = '\0';
index 3c4a6b799c15392696e4a9817b74f07dfe620d7e..3074fce77d3ff6fd52553de133acbbd988508d4e 100644 (file)
@@ -42,8 +42,7 @@
 
 #include "Parser.hpp"
 
-#define $ \
-    new(context.pool_)
+#define $ new($pool)
 
 #define $D(args...) \
     ($ CYNumber(args))
@@ -60,9 +59,9 @@
 #define $S(args...) \
     ($ CYString(args))
 #define $U \
-    $V("undefined")
+    $V($I("undefined"))
 #define $V(name) \
-    ($ CYVariable($I(name)))
+    ($ CYVariable(name))
 
 #define $T(value) \
     if (this == NULL) \
@@ -88,7 +87,7 @@
 #define $C_(args...) \
     ($ CYArgument(args))
 #define $N(args...) \
-    ($ CYNew(args))
+    ($ cy::Syntax::New(args))
 
 #define $C1_(arg0, args...) \
     $C_(arg0, ##args)