ReflectParse.cpp (127625B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /* JS reflection package. */ 8 9 #include "mozilla/DebugOnly.h" 10 11 #include <utility> 12 13 #include "jspubtd.h" 14 15 #include "builtin/Array.h" 16 #include "frontend/CompilationStencil.h" 17 #include "frontend/FrontendContext.h" // AutoReportFrontendContext 18 #include "frontend/ModuleSharedContext.h" 19 #include "frontend/ParseNode.h" 20 #include "frontend/Parser.h" 21 #include "js/ColumnNumber.h" // JS::LimitedColumnNumberOneOrigin 22 #include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_* 23 #include "js/friend/StackLimits.h" // js::AutoCheckRecursionLimit 24 #include "js/PropertyAndElement.h" // JS_DefineFunction 25 #include "js/StableStringChars.h" 26 #include "vm/FunctionFlags.h" // js::FunctionFlags 27 #include "vm/Interpreter.h" 28 #include "vm/JSAtomUtils.h" // Atomize, AtomizeUTF8Chars 29 #include "vm/JSObject.h" 30 #include "vm/ModuleBuilder.h" // js::ModuleBuilder 31 #include "vm/PlainObject.h" // js::PlainObject 32 #include "vm/RegExpObject.h" 33 34 #include "vm/JSContext-inl.h" 35 #include "vm/JSObject-inl.h" 36 #include "vm/ObjectOperations-inl.h" 37 38 using namespace js; 39 using namespace js::frontend; 40 41 using JS::AutoStableStringChars; 42 using JS::CompileOptions; 43 using JS::RootedValueArray; 44 using mozilla::DebugOnly; 45 46 enum ASTType { 47 AST_ERROR = -1, 48 #define ASTDEF(ast, str) ast, 49 #include "jsast.tbl" 50 #undef ASTDEF 51 AST_LIMIT 52 }; 53 54 enum AssignmentOperator { 55 AOP_ERR = -1, 56 57 /* assign */ 58 AOP_ASSIGN = 0, 59 /* operator-assign */ 60 AOP_PLUS, 61 AOP_MINUS, 62 AOP_STAR, 63 AOP_DIV, 64 AOP_MOD, 65 AOP_POW, 66 /* shift-assign */ 67 AOP_LSH, 68 AOP_RSH, 69 AOP_URSH, 70 /* binary */ 71 AOP_BITOR, 72 AOP_BITXOR, 73 AOP_BITAND, 74 /* short-circuit */ 75 AOP_COALESCE, 76 AOP_OR, 77 AOP_AND, 78 79 AOP_LIMIT 80 }; 81 82 enum BinaryOperator { 83 BINOP_ERR = -1, 84 85 /* eq */ 86 BINOP_EQ = 0, 87 BINOP_NE, 88 BINOP_STRICTEQ, 89 BINOP_STRICTNE, 90 /* rel */ 91 BINOP_LT, 92 BINOP_LE, 93 BINOP_GT, 94 BINOP_GE, 95 /* shift */ 96 BINOP_LSH, 97 BINOP_RSH, 98 BINOP_URSH, 99 /* arithmetic */ 100 BINOP_ADD, 101 BINOP_SUB, 102 BINOP_STAR, 103 BINOP_DIV, 104 BINOP_MOD, 105 BINOP_POW, 106 /* binary */ 107 BINOP_BITOR, 108 BINOP_BITXOR, 109 BINOP_BITAND, 110 /* misc */ 111 BINOP_IN, 112 BINOP_INSTANCEOF, 113 BINOP_COALESCE, 114 115 BINOP_LIMIT 116 }; 117 118 enum UnaryOperator { 119 UNOP_ERR = -1, 120 121 UNOP_DELETE = 0, 122 UNOP_NEG, 123 UNOP_POS, 124 UNOP_NOT, 125 UNOP_BITNOT, 126 UNOP_TYPEOF, 127 UNOP_VOID, 128 UNOP_AWAIT, 129 130 UNOP_LIMIT 131 }; 132 133 enum VarDeclKind { 134 VARDECL_ERR = -1, 135 VARDECL_VAR = 0, 136 VARDECL_CONST, 137 VARDECL_LET, 138 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT 139 VARDECL_USING, 140 VARDECL_AWAIT_USING, 141 #endif 142 VARDECL_LIMIT 143 }; 144 145 enum PropKind { 146 PROP_ERR = -1, 147 PROP_INIT = 0, 148 PROP_GETTER, 149 PROP_SETTER, 150 PROP_MUTATEPROTO, 151 PROP_LIMIT 152 }; 153 154 static const char* const aopNames[] = { 155 "=", /* AOP_ASSIGN */ 156 "+=", /* AOP_PLUS */ 157 "-=", /* AOP_MINUS */ 158 "*=", /* AOP_STAR */ 159 "/=", /* AOP_DIV */ 160 "%=", /* AOP_MOD */ 161 "**=", /* AOP_POW */ 162 "<<=", /* AOP_LSH */ 163 ">>=", /* AOP_RSH */ 164 ">>>=", /* AOP_URSH */ 165 "|=", /* AOP_BITOR */ 166 "^=", /* AOP_BITXOR */ 167 "&=", /* AOP_BITAND */ 168 "\?\?=", /* AOP_COALESCE */ 169 "||=", /* AOP_OR */ 170 "&&=", /* AOP_AND */ 171 }; 172 173 static const char* const binopNames[] = { 174 "==", /* BINOP_EQ */ 175 "!=", /* BINOP_NE */ 176 "===", /* BINOP_STRICTEQ */ 177 "!==", /* BINOP_STRICTNE */ 178 "<", /* BINOP_LT */ 179 "<=", /* BINOP_LE */ 180 ">", /* BINOP_GT */ 181 ">=", /* BINOP_GE */ 182 "<<", /* BINOP_LSH */ 183 ">>", /* BINOP_RSH */ 184 ">>>", /* BINOP_URSH */ 185 "+", /* BINOP_PLUS */ 186 "-", /* BINOP_MINUS */ 187 "*", /* BINOP_STAR */ 188 "/", /* BINOP_DIV */ 189 "%", /* BINOP_MOD */ 190 "**", /* BINOP_POW */ 191 "|", /* BINOP_BITOR */ 192 "^", /* BINOP_BITXOR */ 193 "&", /* BINOP_BITAND */ 194 "in", /* BINOP_IN */ 195 "instanceof", /* BINOP_INSTANCEOF */ 196 "??", /* BINOP_COALESCE */ 197 }; 198 199 static const char* const unopNames[] = { 200 "delete", /* UNOP_DELETE */ 201 "-", /* UNOP_NEG */ 202 "+", /* UNOP_POS */ 203 "!", /* UNOP_NOT */ 204 "~", /* UNOP_BITNOT */ 205 "typeof", /* UNOP_TYPEOF */ 206 "void", /* UNOP_VOID */ 207 "await", /* UNOP_AWAIT */ 208 }; 209 210 static const char* const nodeTypeNames[] = { 211 #define ASTDEF(ast, str) str, 212 #include "jsast.tbl" 213 #undef ASTDEF 214 nullptr}; 215 216 enum YieldKind { Delegating, NotDelegating }; 217 218 using NodeVector = RootedValueVector; 219 220 /* 221 * ParseNode is a somewhat intricate data structure, and its invariants have 222 * evolved, making it more likely that there could be a disconnect between the 223 * parser and the AST serializer. We use these macros to check invariants on a 224 * parse node and raise a dynamic error on failure. 225 */ 226 #define LOCAL_ASSERT(expr) \ 227 JS_BEGIN_MACRO \ 228 MOZ_ASSERT(expr); \ 229 if (!(expr)) { \ 230 JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, \ 231 JSMSG_BAD_PARSE_NODE); \ 232 return false; \ 233 } \ 234 JS_END_MACRO 235 236 #define LOCAL_NOT_REACHED(expr) \ 237 JS_BEGIN_MACRO \ 238 MOZ_ASSERT(false); \ 239 JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, \ 240 JSMSG_BAD_PARSE_NODE); \ 241 return false; \ 242 JS_END_MACRO 243 244 namespace { 245 246 /* Set 'result' to obj[id] if any such property exists, else defaultValue. */ 247 static bool GetPropertyDefault(JSContext* cx, HandleObject obj, HandleId id, 248 HandleValue defaultValue, 249 MutableHandleValue result) { 250 bool found; 251 if (!HasProperty(cx, obj, id, &found)) { 252 return false; 253 } 254 if (!found) { 255 result.set(defaultValue); 256 return true; 257 } 258 return GetProperty(cx, obj, obj, id, result); 259 } 260 261 enum class GeneratorStyle { None, ES6 }; 262 263 /* 264 * Builder class that constructs JavaScript AST node objects. 265 */ 266 class NodeBuilder { 267 using CallbackArray = RootedValueArray<AST_LIMIT>; 268 269 JSContext* cx; 270 FrontendContext* fc; 271 frontend::Parser<frontend::FullParseHandler, char16_t>* parser; 272 bool saveLoc; /* save source location information? */ 273 char const* src; /* UTF-8 encoded source filename or null */ 274 RootedValue srcval; /* source filename JS value or null */ 275 276 public: 277 NodeBuilder(JSContext* c, FrontendContext* f, bool l, char const* s) 278 : cx(c), fc(f), parser(nullptr), saveLoc(l), src(s), srcval(c) {} 279 280 [[nodiscard]] bool init() { 281 if (src) { 282 if (!atomValueUtf8(src, &srcval)) { 283 return false; 284 } 285 } else { 286 srcval.setNull(); 287 } 288 289 return true; 290 } 291 292 void setParser(frontend::Parser<frontend::FullParseHandler, char16_t>* p) { 293 parser = p; 294 } 295 296 private: 297 [[nodiscard]] bool atomValue(const char* s, MutableHandleValue dst) { 298 MOZ_ASSERT(JS::StringIsASCII(s)); 299 300 /* 301 * Bug 575416: instead of Atomize, lookup constant atoms in tbl file 302 */ 303 Rooted<JSAtom*> atom(cx, Atomize(cx, s, strlen(s))); 304 if (!atom) { 305 return false; 306 } 307 308 dst.setString(atom); 309 return true; 310 } 311 312 [[nodiscard]] bool atomValueUtf8(const char* s, MutableHandleValue dst) { 313 Rooted<JSAtom*> atom(cx, AtomizeUTF8Chars(cx, s, strlen(s))); 314 if (!atom) { 315 return false; 316 } 317 318 dst.setString(atom); 319 return true; 320 } 321 322 [[nodiscard]] bool newObject(MutableHandleObject dst) { 323 Rooted<PlainObject*> nobj(cx, NewPlainObject(cx)); 324 if (!nobj) { 325 return false; 326 } 327 328 dst.set(nobj); 329 return true; 330 } 331 332 [[nodiscard]] bool newArray(NodeVector& elts, MutableHandleValue dst); 333 334 [[nodiscard]] bool createNode(ASTType type, TokenPos* pos, 335 MutableHandleObject dst); 336 337 [[nodiscard]] bool newNodeHelper(HandleObject obj, MutableHandleValue dst) { 338 // The end of the implementation of newNode(). 339 MOZ_ASSERT(obj); 340 dst.setObject(*obj); 341 return true; 342 } 343 344 template <typename... Arguments> 345 [[nodiscard]] bool newNodeHelper(HandleObject obj, const char* name, 346 HandleValue value, Arguments&&... rest) { 347 // Recursive loop to define properties. Note that the newNodeHelper() 348 // call below passes two fewer arguments than we received, as we omit 349 // `name` and `value`. This eventually bottoms out in a call to the 350 // non-template newNodeHelper() above. 351 return defineProperty(obj, name, value) && 352 newNodeHelper(obj, std::forward<Arguments>(rest)...); 353 } 354 355 // Create a node object with "type" and "loc" properties, as well as zero 356 // or more properties passed in as arguments. The signature is really more 357 // like: 358 // 359 // bool newNode(ASTType type, TokenPos* pos, 360 // {const char *name0, HandleValue value0,}... 361 // MutableHandleValue dst); 362 template <typename... Arguments> 363 [[nodiscard]] bool newNode(ASTType type, TokenPos* pos, Arguments&&... args) { 364 RootedObject node(cx); 365 return createNode(type, pos, &node) && 366 newNodeHelper(node, std::forward<Arguments>(args)...); 367 } 368 369 [[nodiscard]] bool listNode(ASTType type, const char* propName, 370 NodeVector& elts, TokenPos* pos, 371 MutableHandleValue dst) { 372 RootedValue array(cx); 373 if (!newArray(elts, &array)) { 374 return false; 375 } 376 377 return newNode(type, pos, propName, array, dst); 378 } 379 380 [[nodiscard]] bool defineProperty(HandleObject obj, const char* name, 381 HandleValue val) { 382 MOZ_ASSERT_IF(val.isMagic(), val.whyMagic() == JS_SERIALIZE_NO_NODE); 383 384 /* 385 * Bug 575416: instead of Atomize, lookup constant atoms in tbl file 386 */ 387 Rooted<JSAtom*> atom(cx, Atomize(cx, name, strlen(name))); 388 if (!atom) { 389 return false; 390 } 391 392 // Represent "no node" as null and ensure users are not exposed to magic 393 // values. 394 RootedValue optVal(cx, 395 val.isMagic(JS_SERIALIZE_NO_NODE) ? NullValue() : val); 396 return DefineDataProperty(cx, obj, atom->asPropertyName(), optVal); 397 } 398 399 [[nodiscard]] bool newNodeLoc(TokenPos* pos, MutableHandleValue dst); 400 401 [[nodiscard]] bool setNodeLoc(HandleObject node, TokenPos* pos); 402 403 public: 404 /* 405 * All of the public builder methods take as their last two 406 * arguments a nullable token position and a non-nullable, rooted 407 * outparam. 408 * 409 * Any Value arguments representing optional subnodes may be a 410 * JS_SERIALIZE_NO_NODE magic value. 411 */ 412 413 /* 414 * misc nodes 415 */ 416 417 [[nodiscard]] bool program(NodeVector& elts, TokenPos* pos, 418 MutableHandleValue dst); 419 420 [[nodiscard]] bool literal(HandleValue val, TokenPos* pos, 421 MutableHandleValue dst); 422 423 [[nodiscard]] bool identifier(HandleValue name, TokenPos* pos, 424 MutableHandleValue dst); 425 426 [[nodiscard]] bool function(ASTType type, TokenPos* pos, HandleValue id, 427 NodeVector& args, NodeVector& defaults, 428 HandleValue body, HandleValue rest, 429 GeneratorStyle generatorStyle, bool isAsync, 430 bool isExpression, MutableHandleValue dst); 431 432 [[nodiscard]] bool variableDeclarator(HandleValue id, HandleValue init, 433 TokenPos* pos, MutableHandleValue dst); 434 435 [[nodiscard]] bool switchCase(HandleValue expr, NodeVector& elts, 436 TokenPos* pos, MutableHandleValue dst); 437 438 [[nodiscard]] bool catchClause(HandleValue var, HandleValue body, 439 TokenPos* pos, MutableHandleValue dst); 440 441 [[nodiscard]] bool prototypeMutation(HandleValue val, TokenPos* pos, 442 MutableHandleValue dst); 443 [[nodiscard]] bool propertyInitializer(HandleValue key, HandleValue val, 444 PropKind kind, bool isShorthand, 445 bool isMethod, TokenPos* pos, 446 MutableHandleValue dst); 447 448 /* 449 * statements 450 */ 451 452 [[nodiscard]] bool blockStatement(NodeVector& elts, TokenPos* pos, 453 MutableHandleValue dst); 454 455 [[nodiscard]] bool expressionStatement(HandleValue expr, TokenPos* pos, 456 MutableHandleValue dst); 457 458 [[nodiscard]] bool emptyStatement(TokenPos* pos, MutableHandleValue dst); 459 460 [[nodiscard]] bool ifStatement(HandleValue test, HandleValue cons, 461 HandleValue alt, TokenPos* pos, 462 MutableHandleValue dst); 463 464 [[nodiscard]] bool breakStatement(HandleValue label, TokenPos* pos, 465 MutableHandleValue dst); 466 467 [[nodiscard]] bool continueStatement(HandleValue label, TokenPos* pos, 468 MutableHandleValue dst); 469 470 [[nodiscard]] bool labeledStatement(HandleValue label, HandleValue stmt, 471 TokenPos* pos, MutableHandleValue dst); 472 473 [[nodiscard]] bool throwStatement(HandleValue arg, TokenPos* pos, 474 MutableHandleValue dst); 475 476 [[nodiscard]] bool returnStatement(HandleValue arg, TokenPos* pos, 477 MutableHandleValue dst); 478 479 [[nodiscard]] bool forStatement(HandleValue init, HandleValue test, 480 HandleValue update, HandleValue stmt, 481 TokenPos* pos, MutableHandleValue dst); 482 483 [[nodiscard]] bool forInStatement(HandleValue var, HandleValue expr, 484 HandleValue stmt, TokenPos* pos, 485 MutableHandleValue dst); 486 487 [[nodiscard]] bool forOfStatement(HandleValue var, HandleValue expr, 488 HandleValue stmt, TokenPos* pos, 489 MutableHandleValue dst); 490 491 [[nodiscard]] bool withStatement(HandleValue expr, HandleValue stmt, 492 TokenPos* pos, MutableHandleValue dst); 493 494 [[nodiscard]] bool whileStatement(HandleValue test, HandleValue stmt, 495 TokenPos* pos, MutableHandleValue dst); 496 497 [[nodiscard]] bool doWhileStatement(HandleValue stmt, HandleValue test, 498 TokenPos* pos, MutableHandleValue dst); 499 500 [[nodiscard]] bool switchStatement(HandleValue disc, NodeVector& elts, 501 bool lexical, TokenPos* pos, 502 MutableHandleValue dst); 503 504 [[nodiscard]] bool tryStatement(HandleValue body, HandleValue handler, 505 HandleValue finally, TokenPos* pos, 506 MutableHandleValue dst); 507 508 [[nodiscard]] bool debuggerStatement(TokenPos* pos, MutableHandleValue dst); 509 510 [[nodiscard]] bool moduleRequest(HandleValue moduleSpec, 511 NodeVector& attributes, TokenPos* pos, 512 MutableHandleValue dst); 513 514 [[nodiscard]] bool importAttribute(HandleValue key, HandleValue value, 515 TokenPos* pos, MutableHandleValue dst); 516 517 [[nodiscard]] bool importDeclaration(NodeVector& elts, HandleValue moduleSpec, 518 TokenPos* pos, MutableHandleValue dst); 519 520 [[nodiscard]] bool importSpecifier(HandleValue importName, 521 HandleValue bindingName, TokenPos* pos, 522 MutableHandleValue dst); 523 524 [[nodiscard]] bool importNamespaceSpecifier(HandleValue bindingName, 525 TokenPos* pos, 526 MutableHandleValue dst); 527 528 [[nodiscard]] bool exportDeclaration(HandleValue decl, NodeVector& elts, 529 HandleValue moduleSpec, 530 HandleValue isDefault, TokenPos* pos, 531 MutableHandleValue dst); 532 533 [[nodiscard]] bool exportSpecifier(HandleValue bindingName, 534 HandleValue exportName, TokenPos* pos, 535 MutableHandleValue dst); 536 537 [[nodiscard]] bool exportNamespaceSpecifier(HandleValue exportName, 538 TokenPos* pos, 539 MutableHandleValue dst); 540 541 [[nodiscard]] bool exportBatchSpecifier(TokenPos* pos, 542 MutableHandleValue dst); 543 544 [[nodiscard]] bool classDefinition(bool expr, HandleValue name, 545 HandleValue heritage, HandleValue block, 546 #ifdef ENABLE_DECORATORS 547 HandleValue decorators, 548 #endif 549 TokenPos* pos, MutableHandleValue dst); 550 [[nodiscard]] bool classMembers(NodeVector& members, MutableHandleValue dst); 551 [[nodiscard]] bool classMethod(HandleValue name, HandleValue body, 552 #ifdef ENABLE_DECORATORS 553 HandleValue decorators, 554 #endif 555 PropKind kind, bool isStatic, TokenPos* pos, 556 MutableHandleValue dst); 557 [[nodiscard]] bool classField(HandleValue name, HandleValue initializer, 558 #ifdef ENABLE_DECORATORS 559 HandleValue decorators, 560 #endif 561 TokenPos* pos, MutableHandleValue dst); 562 [[nodiscard]] bool staticClassBlock(HandleValue body, TokenPos* pos, 563 MutableHandleValue dst); 564 565 /* 566 * expressions 567 */ 568 569 [[nodiscard]] bool binaryExpression(BinaryOperator op, HandleValue left, 570 HandleValue right, TokenPos* pos, 571 MutableHandleValue dst); 572 573 [[nodiscard]] bool unaryExpression(UnaryOperator op, HandleValue expr, 574 TokenPos* pos, MutableHandleValue dst); 575 576 [[nodiscard]] bool assignmentExpression(AssignmentOperator op, 577 HandleValue lhs, HandleValue rhs, 578 TokenPos* pos, 579 MutableHandleValue dst); 580 581 [[nodiscard]] bool updateExpression(HandleValue expr, bool incr, bool prefix, 582 TokenPos* pos, MutableHandleValue dst); 583 584 [[nodiscard]] bool logicalExpression(ParseNodeKind pnk, HandleValue left, 585 HandleValue right, TokenPos* pos, 586 MutableHandleValue dst); 587 588 [[nodiscard]] bool conditionalExpression(HandleValue test, HandleValue cons, 589 HandleValue alt, TokenPos* pos, 590 MutableHandleValue dst); 591 592 [[nodiscard]] bool sequenceExpression(NodeVector& elts, TokenPos* pos, 593 MutableHandleValue dst); 594 595 [[nodiscard]] bool newExpression(HandleValue callee, NodeVector& args, 596 TokenPos* pos, MutableHandleValue dst); 597 598 [[nodiscard]] bool callExpression(HandleValue callee, NodeVector& args, 599 TokenPos* pos, MutableHandleValue dst, 600 bool isOptional = false); 601 602 [[nodiscard]] bool memberExpression(bool computed, HandleValue expr, 603 HandleValue member, TokenPos* pos, 604 MutableHandleValue dst, 605 bool isOptional = false); 606 607 [[nodiscard]] bool arrayExpression(NodeVector& elts, TokenPos* pos, 608 MutableHandleValue dst); 609 610 [[nodiscard]] bool templateLiteral(NodeVector& elts, TokenPos* pos, 611 MutableHandleValue dst); 612 613 [[nodiscard]] bool taggedTemplate(HandleValue callee, NodeVector& args, 614 TokenPos* pos, MutableHandleValue dst); 615 616 [[nodiscard]] bool callSiteObj(NodeVector& raw, NodeVector& cooked, 617 TokenPos* pos, MutableHandleValue dst); 618 619 [[nodiscard]] bool spreadExpression(HandleValue expr, TokenPos* pos, 620 MutableHandleValue dst); 621 622 [[nodiscard]] bool optionalExpression(HandleValue expr, TokenPos* pos, 623 MutableHandleValue dst); 624 625 [[nodiscard]] bool deleteOptionalExpression(HandleValue expr, TokenPos* pos, 626 MutableHandleValue dst); 627 628 [[nodiscard]] bool computedName(HandleValue name, TokenPos* pos, 629 MutableHandleValue dst); 630 631 [[nodiscard]] bool objectExpression(NodeVector& elts, TokenPos* pos, 632 MutableHandleValue dst); 633 634 [[nodiscard]] bool thisExpression(TokenPos* pos, MutableHandleValue dst); 635 636 [[nodiscard]] bool yieldExpression(HandleValue arg, YieldKind kind, 637 TokenPos* pos, MutableHandleValue dst); 638 639 [[nodiscard]] bool metaProperty(HandleValue meta, HandleValue property, 640 TokenPos* pos, MutableHandleValue dst); 641 642 [[nodiscard]] bool callImportExpression(HandleValue ident, NodeVector& args, 643 TokenPos* pos, 644 MutableHandleValue dst); 645 646 [[nodiscard]] bool super(TokenPos* pos, MutableHandleValue dst); 647 648 /* 649 * declarations 650 */ 651 652 [[nodiscard]] bool variableDeclaration(NodeVector& elts, VarDeclKind kind, 653 TokenPos* pos, MutableHandleValue dst); 654 655 /* 656 * patterns 657 */ 658 659 [[nodiscard]] bool arrayPattern(NodeVector& elts, TokenPos* pos, 660 MutableHandleValue dst); 661 662 [[nodiscard]] bool objectPattern(NodeVector& elts, TokenPos* pos, 663 MutableHandleValue dst); 664 665 [[nodiscard]] bool propertyPattern(HandleValue key, HandleValue patt, 666 bool isShorthand, TokenPos* pos, 667 MutableHandleValue dst); 668 }; 669 670 } /* anonymous namespace */ 671 672 bool NodeBuilder::createNode(ASTType type, TokenPos* pos, 673 MutableHandleObject dst) { 674 MOZ_ASSERT(type > AST_ERROR && type < AST_LIMIT); 675 676 RootedValue tv(cx); 677 Rooted<PlainObject*> node(cx, NewPlainObject(cx)); 678 if (!node || !setNodeLoc(node, pos) || !atomValue(nodeTypeNames[type], &tv) || 679 !defineProperty(node, "type", tv)) { 680 return false; 681 } 682 683 dst.set(node); 684 return true; 685 } 686 687 bool NodeBuilder::newArray(NodeVector& elts, MutableHandleValue dst) { 688 const size_t len = elts.length(); 689 if (len > UINT32_MAX) { 690 ReportAllocationOverflow(fc); 691 return false; 692 } 693 RootedObject array(cx, NewDenseFullyAllocatedArray(cx, uint32_t(len))); 694 if (!array) { 695 return false; 696 } 697 698 for (size_t i = 0; i < len; i++) { 699 RootedValue val(cx, elts[i]); 700 701 MOZ_ASSERT_IF(val.isMagic(), val.whyMagic() == JS_SERIALIZE_NO_NODE); 702 703 /* Represent "no node" as an array hole by not adding the value. */ 704 if (val.isMagic(JS_SERIALIZE_NO_NODE)) { 705 continue; 706 } 707 708 if (!DefineDataElement(cx, array, i, val)) { 709 return false; 710 } 711 } 712 713 dst.setObject(*array); 714 return true; 715 } 716 717 bool NodeBuilder::newNodeLoc(TokenPos* pos, MutableHandleValue dst) { 718 if (!pos) { 719 dst.setNull(); 720 return true; 721 } 722 723 RootedObject loc(cx); 724 RootedObject to(cx); 725 RootedValue val(cx); 726 727 if (!newObject(&loc)) { 728 return false; 729 } 730 731 dst.setObject(*loc); 732 733 uint32_t startLineNum, endLineNum; 734 JS::LimitedColumnNumberOneOrigin startColumnIndex, endColumnIndex; 735 parser->tokenStream.computeLineAndColumn(pos->begin, &startLineNum, 736 &startColumnIndex); 737 parser->tokenStream.computeLineAndColumn(pos->end, &endLineNum, 738 &endColumnIndex); 739 740 if (!newObject(&to)) { 741 return false; 742 } 743 val.setObject(*to); 744 if (!defineProperty(loc, "start", val)) { 745 return false; 746 } 747 val.setNumber(startLineNum); 748 if (!defineProperty(to, "line", val)) { 749 return false; 750 } 751 val.setNumber(startColumnIndex.oneOriginValue()); 752 if (!defineProperty(to, "column", val)) { 753 return false; 754 } 755 756 if (!newObject(&to)) { 757 return false; 758 } 759 val.setObject(*to); 760 if (!defineProperty(loc, "end", val)) { 761 return false; 762 } 763 val.setNumber(endLineNum); 764 if (!defineProperty(to, "line", val)) { 765 return false; 766 } 767 val.setNumber(endColumnIndex.oneOriginValue()); 768 if (!defineProperty(to, "column", val)) { 769 return false; 770 } 771 772 if (!defineProperty(loc, "source", srcval)) { 773 return false; 774 } 775 776 return true; 777 } 778 779 bool NodeBuilder::setNodeLoc(HandleObject node, TokenPos* pos) { 780 if (!saveLoc) { 781 return true; 782 } 783 784 RootedValue loc(cx); 785 return newNodeLoc(pos, &loc) && defineProperty(node, "loc", loc); 786 } 787 788 bool NodeBuilder::program(NodeVector& elts, TokenPos* pos, 789 MutableHandleValue dst) { 790 return listNode(AST_PROGRAM, "body", elts, pos, dst); 791 } 792 793 bool NodeBuilder::blockStatement(NodeVector& elts, TokenPos* pos, 794 MutableHandleValue dst) { 795 return listNode(AST_BLOCK_STMT, "body", elts, pos, dst); 796 } 797 798 bool NodeBuilder::expressionStatement(HandleValue expr, TokenPos* pos, 799 MutableHandleValue dst) { 800 return newNode(AST_EXPR_STMT, pos, "expression", expr, dst); 801 } 802 803 bool NodeBuilder::emptyStatement(TokenPos* pos, MutableHandleValue dst) { 804 return newNode(AST_EMPTY_STMT, pos, dst); 805 } 806 807 bool NodeBuilder::ifStatement(HandleValue test, HandleValue cons, 808 HandleValue alt, TokenPos* pos, 809 MutableHandleValue dst) { 810 return newNode(AST_IF_STMT, pos, "test", test, "consequent", cons, 811 "alternate", alt, dst); 812 } 813 814 bool NodeBuilder::breakStatement(HandleValue label, TokenPos* pos, 815 MutableHandleValue dst) { 816 return newNode(AST_BREAK_STMT, pos, "label", label, dst); 817 } 818 819 bool NodeBuilder::continueStatement(HandleValue label, TokenPos* pos, 820 MutableHandleValue dst) { 821 return newNode(AST_CONTINUE_STMT, pos, "label", label, dst); 822 } 823 824 bool NodeBuilder::labeledStatement(HandleValue label, HandleValue stmt, 825 TokenPos* pos, MutableHandleValue dst) { 826 return newNode(AST_LAB_STMT, pos, "label", label, "body", stmt, dst); 827 } 828 829 bool NodeBuilder::throwStatement(HandleValue arg, TokenPos* pos, 830 MutableHandleValue dst) { 831 return newNode(AST_THROW_STMT, pos, "argument", arg, dst); 832 } 833 834 bool NodeBuilder::returnStatement(HandleValue arg, TokenPos* pos, 835 MutableHandleValue dst) { 836 return newNode(AST_RETURN_STMT, pos, "argument", arg, dst); 837 } 838 839 bool NodeBuilder::forStatement(HandleValue init, HandleValue test, 840 HandleValue update, HandleValue stmt, 841 TokenPos* pos, MutableHandleValue dst) { 842 return newNode(AST_FOR_STMT, pos, "init", init, "test", test, "update", 843 update, "body", stmt, dst); 844 } 845 846 bool NodeBuilder::forInStatement(HandleValue var, HandleValue expr, 847 HandleValue stmt, TokenPos* pos, 848 MutableHandleValue dst) { 849 return newNode(AST_FOR_IN_STMT, pos, "left", var, "right", expr, "body", stmt, 850 dst); 851 } 852 853 bool NodeBuilder::forOfStatement(HandleValue var, HandleValue expr, 854 HandleValue stmt, TokenPos* pos, 855 MutableHandleValue dst) { 856 return newNode(AST_FOR_OF_STMT, pos, "left", var, "right", expr, "body", stmt, 857 dst); 858 } 859 860 bool NodeBuilder::withStatement(HandleValue expr, HandleValue stmt, 861 TokenPos* pos, MutableHandleValue dst) { 862 return newNode(AST_WITH_STMT, pos, "object", expr, "body", stmt, dst); 863 } 864 865 bool NodeBuilder::whileStatement(HandleValue test, HandleValue stmt, 866 TokenPos* pos, MutableHandleValue dst) { 867 return newNode(AST_WHILE_STMT, pos, "test", test, "body", stmt, dst); 868 } 869 870 bool NodeBuilder::doWhileStatement(HandleValue stmt, HandleValue test, 871 TokenPos* pos, MutableHandleValue dst) { 872 return newNode(AST_DO_STMT, pos, "body", stmt, "test", test, dst); 873 } 874 875 bool NodeBuilder::switchStatement(HandleValue disc, NodeVector& elts, 876 bool lexical, TokenPos* pos, 877 MutableHandleValue dst) { 878 RootedValue array(cx); 879 if (!newArray(elts, &array)) { 880 return false; 881 } 882 883 RootedValue lexicalVal(cx, BooleanValue(lexical)); 884 return newNode(AST_SWITCH_STMT, pos, "discriminant", disc, "cases", array, 885 "lexical", lexicalVal, dst); 886 } 887 888 bool NodeBuilder::tryStatement(HandleValue body, HandleValue handler, 889 HandleValue finally, TokenPos* pos, 890 MutableHandleValue dst) { 891 return newNode(AST_TRY_STMT, pos, "block", body, "handler", handler, 892 "finalizer", finally, dst); 893 } 894 895 bool NodeBuilder::debuggerStatement(TokenPos* pos, MutableHandleValue dst) { 896 return newNode(AST_DEBUGGER_STMT, pos, dst); 897 } 898 899 bool NodeBuilder::binaryExpression(BinaryOperator op, HandleValue left, 900 HandleValue right, TokenPos* pos, 901 MutableHandleValue dst) { 902 MOZ_ASSERT(op > BINOP_ERR && op < BINOP_LIMIT); 903 904 RootedValue opName(cx); 905 if (!atomValue(binopNames[op], &opName)) { 906 return false; 907 } 908 909 return newNode(AST_BINARY_EXPR, pos, "operator", opName, "left", left, 910 "right", right, dst); 911 } 912 913 bool NodeBuilder::unaryExpression(UnaryOperator unop, HandleValue expr, 914 TokenPos* pos, MutableHandleValue dst) { 915 MOZ_ASSERT(unop > UNOP_ERR && unop < UNOP_LIMIT); 916 917 RootedValue opName(cx); 918 if (!atomValue(unopNames[unop], &opName)) { 919 return false; 920 } 921 922 RootedValue trueVal(cx, BooleanValue(true)); 923 return newNode(AST_UNARY_EXPR, pos, "operator", opName, "argument", expr, 924 "prefix", trueVal, dst); 925 } 926 927 bool NodeBuilder::assignmentExpression(AssignmentOperator aop, HandleValue lhs, 928 HandleValue rhs, TokenPos* pos, 929 MutableHandleValue dst) { 930 MOZ_ASSERT(aop > AOP_ERR && aop < AOP_LIMIT); 931 932 RootedValue opName(cx); 933 if (!atomValue(aopNames[aop], &opName)) { 934 return false; 935 } 936 937 return newNode(AST_ASSIGN_EXPR, pos, "operator", opName, "left", lhs, "right", 938 rhs, dst); 939 } 940 941 bool NodeBuilder::updateExpression(HandleValue expr, bool incr, bool prefix, 942 TokenPos* pos, MutableHandleValue dst) { 943 RootedValue opName(cx); 944 if (!atomValue(incr ? "++" : "--", &opName)) { 945 return false; 946 } 947 948 RootedValue prefixVal(cx, BooleanValue(prefix)); 949 950 return newNode(AST_UPDATE_EXPR, pos, "operator", opName, "argument", expr, 951 "prefix", prefixVal, dst); 952 } 953 954 bool NodeBuilder::logicalExpression(ParseNodeKind pnk, HandleValue left, 955 HandleValue right, TokenPos* pos, 956 MutableHandleValue dst) { 957 RootedValue opName(cx); 958 switch (pnk) { 959 case ParseNodeKind::OrExpr: 960 if (!atomValue("||", &opName)) { 961 return false; 962 } 963 break; 964 case ParseNodeKind::CoalesceExpr: 965 if (!atomValue("??", &opName)) { 966 return false; 967 } 968 break; 969 case ParseNodeKind::AndExpr: 970 if (!atomValue("&&", &opName)) { 971 return false; 972 } 973 break; 974 default: 975 MOZ_CRASH("Unexpected ParseNodeKind: Must be `Or`, `And`, or `Coalesce`"); 976 } 977 978 return newNode(AST_LOGICAL_EXPR, pos, "operator", opName, "left", left, 979 "right", right, dst); 980 } 981 982 bool NodeBuilder::conditionalExpression(HandleValue test, HandleValue cons, 983 HandleValue alt, TokenPos* pos, 984 MutableHandleValue dst) { 985 return newNode(AST_COND_EXPR, pos, "test", test, "consequent", cons, 986 "alternate", alt, dst); 987 } 988 989 bool NodeBuilder::sequenceExpression(NodeVector& elts, TokenPos* pos, 990 MutableHandleValue dst) { 991 return listNode(AST_LIST_EXPR, "expressions", elts, pos, dst); 992 } 993 994 bool NodeBuilder::callExpression(HandleValue callee, NodeVector& args, 995 TokenPos* pos, MutableHandleValue dst, 996 bool isOptional) { 997 RootedValue array(cx); 998 if (!newArray(args, &array)) { 999 return false; 1000 } 1001 1002 return newNode(isOptional ? AST_OPT_CALL_EXPR : AST_CALL_EXPR, pos, "callee", 1003 callee, "arguments", array, dst); 1004 } 1005 1006 bool NodeBuilder::newExpression(HandleValue callee, NodeVector& args, 1007 TokenPos* pos, MutableHandleValue dst) { 1008 RootedValue array(cx); 1009 if (!newArray(args, &array)) { 1010 return false; 1011 } 1012 1013 return newNode(AST_NEW_EXPR, pos, "callee", callee, "arguments", array, dst); 1014 } 1015 1016 bool NodeBuilder::memberExpression(bool computed, HandleValue expr, 1017 HandleValue member, TokenPos* pos, 1018 MutableHandleValue dst, 1019 bool isOptional /* = false */) { 1020 RootedValue computedVal(cx, BooleanValue(computed)); 1021 1022 return newNode(isOptional ? AST_OPT_MEMBER_EXPR : AST_MEMBER_EXPR, pos, 1023 "object", expr, "property", member, "computed", computedVal, 1024 dst); 1025 } 1026 1027 bool NodeBuilder::arrayExpression(NodeVector& elts, TokenPos* pos, 1028 MutableHandleValue dst) { 1029 return listNode(AST_ARRAY_EXPR, "elements", elts, pos, dst); 1030 } 1031 1032 bool NodeBuilder::callSiteObj(NodeVector& raw, NodeVector& cooked, 1033 TokenPos* pos, MutableHandleValue dst) { 1034 RootedValue rawVal(cx); 1035 if (!newArray(raw, &rawVal)) { 1036 return false; 1037 } 1038 1039 RootedValue cookedVal(cx); 1040 if (!newArray(cooked, &cookedVal)) { 1041 return false; 1042 } 1043 1044 return newNode(AST_CALL_SITE_OBJ, pos, "raw", rawVal, "cooked", cookedVal, 1045 dst); 1046 } 1047 1048 bool NodeBuilder::taggedTemplate(HandleValue callee, NodeVector& args, 1049 TokenPos* pos, MutableHandleValue dst) { 1050 RootedValue array(cx); 1051 if (!newArray(args, &array)) { 1052 return false; 1053 } 1054 1055 return newNode(AST_TAGGED_TEMPLATE, pos, "callee", callee, "arguments", array, 1056 dst); 1057 } 1058 1059 bool NodeBuilder::templateLiteral(NodeVector& elts, TokenPos* pos, 1060 MutableHandleValue dst) { 1061 return listNode(AST_TEMPLATE_LITERAL, "elements", elts, pos, dst); 1062 } 1063 1064 bool NodeBuilder::computedName(HandleValue name, TokenPos* pos, 1065 MutableHandleValue dst) { 1066 return newNode(AST_COMPUTED_NAME, pos, "name", name, dst); 1067 } 1068 1069 bool NodeBuilder::spreadExpression(HandleValue expr, TokenPos* pos, 1070 MutableHandleValue dst) { 1071 return newNode(AST_SPREAD_EXPR, pos, "expression", expr, dst); 1072 } 1073 1074 bool NodeBuilder::optionalExpression(HandleValue expr, TokenPos* pos, 1075 MutableHandleValue dst) { 1076 return newNode(AST_OPTIONAL_EXPR, pos, "expression", expr, dst); 1077 } 1078 1079 bool NodeBuilder::deleteOptionalExpression(HandleValue expr, TokenPos* pos, 1080 MutableHandleValue dst) { 1081 return newNode(AST_DELETE_OPTIONAL_EXPR, pos, "expression", expr, dst); 1082 } 1083 1084 bool NodeBuilder::propertyPattern(HandleValue key, HandleValue patt, 1085 bool isShorthand, TokenPos* pos, 1086 MutableHandleValue dst) { 1087 RootedValue kindName(cx); 1088 if (!atomValue("init", &kindName)) { 1089 return false; 1090 } 1091 1092 RootedValue isShorthandVal(cx, BooleanValue(isShorthand)); 1093 1094 return newNode(AST_PROP_PATT, pos, "key", key, "value", patt, "kind", 1095 kindName, "shorthand", isShorthandVal, dst); 1096 } 1097 1098 bool NodeBuilder::prototypeMutation(HandleValue val, TokenPos* pos, 1099 MutableHandleValue dst) { 1100 return newNode(AST_PROTOTYPEMUTATION, pos, "value", val, dst); 1101 } 1102 1103 bool NodeBuilder::propertyInitializer(HandleValue key, HandleValue val, 1104 PropKind kind, bool isShorthand, 1105 bool isMethod, TokenPos* pos, 1106 MutableHandleValue dst) { 1107 RootedValue kindName(cx); 1108 if (!atomValue(kind == PROP_INIT ? "init" 1109 : kind == PROP_GETTER ? "get" 1110 : "set", 1111 &kindName)) { 1112 return false; 1113 } 1114 1115 RootedValue isShorthandVal(cx, BooleanValue(isShorthand)); 1116 RootedValue isMethodVal(cx, BooleanValue(isMethod)); 1117 1118 return newNode(AST_PROPERTY, pos, "key", key, "value", val, "kind", kindName, 1119 "method", isMethodVal, "shorthand", isShorthandVal, dst); 1120 } 1121 1122 bool NodeBuilder::objectExpression(NodeVector& elts, TokenPos* pos, 1123 MutableHandleValue dst) { 1124 return listNode(AST_OBJECT_EXPR, "properties", elts, pos, dst); 1125 } 1126 1127 bool NodeBuilder::thisExpression(TokenPos* pos, MutableHandleValue dst) { 1128 return newNode(AST_THIS_EXPR, pos, dst); 1129 } 1130 1131 bool NodeBuilder::yieldExpression(HandleValue arg, YieldKind kind, 1132 TokenPos* pos, MutableHandleValue dst) { 1133 RootedValue delegateVal(cx); 1134 switch (kind) { 1135 case Delegating: 1136 delegateVal = BooleanValue(true); 1137 break; 1138 case NotDelegating: 1139 delegateVal = BooleanValue(false); 1140 break; 1141 } 1142 return newNode(AST_YIELD_EXPR, pos, "argument", arg, "delegate", delegateVal, 1143 dst); 1144 } 1145 1146 bool NodeBuilder::moduleRequest(HandleValue moduleSpec, NodeVector& attributes, 1147 TokenPos* pos, MutableHandleValue dst) { 1148 RootedValue array(cx); 1149 if (!newArray(attributes, &array)) { 1150 return false; 1151 } 1152 1153 return newNode(AST_MODULE_REQUEST, pos, "source", moduleSpec, "attributes", 1154 array, dst); 1155 } 1156 1157 bool NodeBuilder::importAttribute(HandleValue key, HandleValue value, 1158 TokenPos* pos, MutableHandleValue dst) { 1159 return newNode(AST_IMPORT_ATTRIBUTE, pos, "key", key, "value", value, dst); 1160 } 1161 1162 bool NodeBuilder::importDeclaration(NodeVector& elts, HandleValue moduleRequest, 1163 TokenPos* pos, MutableHandleValue dst) { 1164 RootedValue array(cx); 1165 if (!newArray(elts, &array)) { 1166 return false; 1167 } 1168 1169 return newNode(AST_IMPORT_DECL, pos, "specifiers", array, "moduleRequest", 1170 moduleRequest, dst); 1171 } 1172 1173 bool NodeBuilder::importSpecifier(HandleValue importName, 1174 HandleValue bindingName, TokenPos* pos, 1175 MutableHandleValue dst) { 1176 return newNode(AST_IMPORT_SPEC, pos, "id", importName, "name", bindingName, 1177 dst); 1178 } 1179 1180 bool NodeBuilder::importNamespaceSpecifier(HandleValue bindingName, 1181 TokenPos* pos, 1182 MutableHandleValue dst) { 1183 return newNode(AST_IMPORT_NAMESPACE_SPEC, pos, "name", bindingName, dst); 1184 } 1185 1186 bool NodeBuilder::exportDeclaration(HandleValue decl, NodeVector& elts, 1187 HandleValue moduleRequest, 1188 HandleValue isDefault, TokenPos* pos, 1189 MutableHandleValue dst) { 1190 RootedValue array(cx, NullValue()); 1191 if (decl.isNull() && !newArray(elts, &array)) { 1192 return false; 1193 } 1194 1195 return newNode(AST_EXPORT_DECL, pos, "declaration", decl, "specifiers", array, 1196 "moduleRequest", moduleRequest, "isDefault", isDefault, dst); 1197 } 1198 1199 bool NodeBuilder::exportSpecifier(HandleValue bindingName, 1200 HandleValue exportName, TokenPos* pos, 1201 MutableHandleValue dst) { 1202 return newNode(AST_EXPORT_SPEC, pos, "id", bindingName, "name", exportName, 1203 dst); 1204 } 1205 1206 bool NodeBuilder::exportNamespaceSpecifier(HandleValue exportName, 1207 TokenPos* pos, 1208 MutableHandleValue dst) { 1209 return newNode(AST_EXPORT_NAMESPACE_SPEC, pos, "name", exportName, dst); 1210 } 1211 1212 bool NodeBuilder::exportBatchSpecifier(TokenPos* pos, MutableHandleValue dst) { 1213 return newNode(AST_EXPORT_BATCH_SPEC, pos, dst); 1214 } 1215 1216 bool NodeBuilder::variableDeclaration(NodeVector& elts, VarDeclKind kind, 1217 TokenPos* pos, MutableHandleValue dst) { 1218 MOZ_ASSERT(kind > VARDECL_ERR && kind < VARDECL_LIMIT); 1219 1220 RootedValue array(cx), kindName(cx); 1221 const char* s; 1222 switch (kind) { 1223 case VARDECL_CONST: 1224 s = "const"; 1225 break; 1226 case VARDECL_LET: 1227 s = "let"; 1228 break; 1229 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT 1230 case VARDECL_USING: 1231 s = "using"; 1232 break; 1233 case VARDECL_AWAIT_USING: 1234 s = "await using"; 1235 break; 1236 #endif 1237 default: 1238 s = "var"; 1239 } 1240 if (!newArray(elts, &array) || !atomValue(s, &kindName)) { 1241 return false; 1242 } 1243 1244 return newNode(AST_VAR_DECL, pos, "kind", kindName, "declarations", array, 1245 dst); 1246 } 1247 1248 bool NodeBuilder::variableDeclarator(HandleValue id, HandleValue init, 1249 TokenPos* pos, MutableHandleValue dst) { 1250 return newNode(AST_VAR_DTOR, pos, "id", id, "init", init, dst); 1251 } 1252 1253 bool NodeBuilder::switchCase(HandleValue expr, NodeVector& elts, TokenPos* pos, 1254 MutableHandleValue dst) { 1255 RootedValue array(cx); 1256 if (!newArray(elts, &array)) { 1257 return false; 1258 } 1259 1260 return newNode(AST_CASE, pos, "test", expr, "consequent", array, dst); 1261 } 1262 1263 bool NodeBuilder::catchClause(HandleValue var, HandleValue body, TokenPos* pos, 1264 MutableHandleValue dst) { 1265 return newNode(AST_CATCH, pos, "param", var, "body", body, dst); 1266 } 1267 1268 bool NodeBuilder::literal(HandleValue val, TokenPos* pos, 1269 MutableHandleValue dst) { 1270 return newNode(AST_LITERAL, pos, "value", val, dst); 1271 } 1272 1273 bool NodeBuilder::identifier(HandleValue name, TokenPos* pos, 1274 MutableHandleValue dst) { 1275 return newNode(AST_IDENTIFIER, pos, "name", name, dst); 1276 } 1277 1278 bool NodeBuilder::objectPattern(NodeVector& elts, TokenPos* pos, 1279 MutableHandleValue dst) { 1280 return listNode(AST_OBJECT_PATT, "properties", elts, pos, dst); 1281 } 1282 1283 bool NodeBuilder::arrayPattern(NodeVector& elts, TokenPos* pos, 1284 MutableHandleValue dst) { 1285 return listNode(AST_ARRAY_PATT, "elements", elts, pos, dst); 1286 } 1287 1288 bool NodeBuilder::function(ASTType type, TokenPos* pos, HandleValue id, 1289 NodeVector& args, NodeVector& defaults, 1290 HandleValue body, HandleValue rest, 1291 GeneratorStyle generatorStyle, bool isAsync, 1292 bool isExpression, MutableHandleValue dst) { 1293 RootedValue array(cx), defarray(cx); 1294 if (!newArray(args, &array)) { 1295 return false; 1296 } 1297 if (!newArray(defaults, &defarray)) { 1298 return false; 1299 } 1300 1301 bool isGenerator = generatorStyle != GeneratorStyle::None; 1302 RootedValue isGeneratorVal(cx, BooleanValue(isGenerator)); 1303 RootedValue isAsyncVal(cx, BooleanValue(isAsync)); 1304 RootedValue isExpressionVal(cx, BooleanValue(isExpression)); 1305 1306 if (isGenerator) { 1307 MOZ_ASSERT(generatorStyle == GeneratorStyle::ES6); 1308 JSAtom* styleStr = Atomize(cx, "es6", 3); 1309 if (!styleStr) { 1310 return false; 1311 } 1312 RootedValue styleVal(cx, StringValue(styleStr)); 1313 return newNode(type, pos, "id", id, "params", array, "defaults", defarray, 1314 "body", body, "rest", rest, "generator", isGeneratorVal, 1315 "async", isAsyncVal, "style", styleVal, "expression", 1316 isExpressionVal, dst); 1317 } 1318 1319 return newNode(type, pos, "id", id, "params", array, "defaults", defarray, 1320 "body", body, "rest", rest, "generator", isGeneratorVal, 1321 "async", isAsyncVal, "expression", isExpressionVal, dst); 1322 } 1323 1324 bool NodeBuilder::classMethod(HandleValue name, HandleValue body, 1325 #ifdef ENABLE_DECORATORS 1326 HandleValue decorators, 1327 #endif 1328 PropKind kind, bool isStatic, TokenPos* pos, 1329 MutableHandleValue dst) { 1330 RootedValue kindName(cx); 1331 if (!atomValue(kind == PROP_INIT ? "method" 1332 : kind == PROP_GETTER ? "get" 1333 : "set", 1334 &kindName)) { 1335 return false; 1336 } 1337 1338 RootedValue isStaticVal(cx, BooleanValue(isStatic)); 1339 return newNode(AST_CLASS_METHOD, pos, "name", name, "body", body, "kind", 1340 kindName, "static", isStaticVal, 1341 #ifdef ENABLE_DECORATORS 1342 "decorators", decorators, 1343 #endif 1344 dst); 1345 } 1346 1347 bool NodeBuilder::classField(HandleValue name, HandleValue initializer, 1348 #ifdef ENABLE_DECORATORS 1349 HandleValue decorators, 1350 #endif 1351 TokenPos* pos, MutableHandleValue dst) { 1352 return newNode(AST_CLASS_FIELD, pos, "name", name, "init", initializer, 1353 #ifdef ENABLE_DECORATORS 1354 "decorators", decorators, 1355 #endif 1356 dst); 1357 } 1358 1359 bool NodeBuilder::staticClassBlock(HandleValue body, TokenPos* pos, 1360 MutableHandleValue dst) { 1361 return newNode(AST_STATIC_CLASS_BLOCK, pos, "body", body, dst); 1362 } 1363 1364 bool NodeBuilder::classMembers(NodeVector& members, MutableHandleValue dst) { 1365 return newArray(members, dst); 1366 } 1367 1368 bool NodeBuilder::classDefinition(bool expr, HandleValue name, 1369 HandleValue heritage, HandleValue block, 1370 #ifdef ENABLE_DECORATORS 1371 HandleValue decorators, 1372 #endif 1373 TokenPos* pos, MutableHandleValue dst) { 1374 ASTType type = expr ? AST_CLASS_EXPR : AST_CLASS_STMT; 1375 return newNode(type, pos, "id", name, "superClass", heritage, "body", block, 1376 #ifdef ENABLE_DECORATORS 1377 "decorators", decorators, 1378 #endif 1379 dst); 1380 } 1381 1382 bool NodeBuilder::metaProperty(HandleValue meta, HandleValue property, 1383 TokenPos* pos, MutableHandleValue dst) { 1384 return newNode(AST_METAPROPERTY, pos, "meta", meta, "property", property, 1385 dst); 1386 } 1387 1388 bool NodeBuilder::callImportExpression(HandleValue ident, NodeVector& args, 1389 TokenPos* pos, MutableHandleValue dst) { 1390 RootedValue array(cx); 1391 if (!newArray(args, &array)) { 1392 return false; 1393 } 1394 1395 return newNode(AST_CALL_IMPORT, pos, "ident", ident, "arguments", array, dst); 1396 } 1397 1398 bool NodeBuilder::super(TokenPos* pos, MutableHandleValue dst) { 1399 return newNode(AST_SUPER, pos, dst); 1400 } 1401 1402 namespace { 1403 1404 /* 1405 * Serialization of parse nodes to JavaScript objects. 1406 * 1407 * All serialization methods take a non-nullable ParseNode pointer. 1408 */ 1409 class ASTSerializer { 1410 JSContext* cx; 1411 FrontendContext* fc; 1412 Parser<FullParseHandler, char16_t>* parser; 1413 NodeBuilder builder; 1414 DebugOnly<uint32_t> lineno; 1415 1416 Value unrootedAtomContents(JSAtom* atom) { 1417 return StringValue(atom ? atom : cx->names().empty_); 1418 } 1419 1420 BinaryOperator binop(ParseNodeKind kind); 1421 UnaryOperator unop(ParseNodeKind kind); 1422 AssignmentOperator aop(ParseNodeKind kind); 1423 1424 bool statements(ListNode* stmtList, NodeVector& elts); 1425 bool expressions(ListNode* exprList, NodeVector& elts); 1426 bool leftAssociate(ListNode* node, MutableHandleValue dst); 1427 bool rightAssociate(ListNode* node, MutableHandleValue dst); 1428 bool functionArgs(ParamsBodyNode* pn, NodeVector& args, NodeVector& defaults, 1429 MutableHandleValue rest); 1430 1431 bool sourceElement(ParseNode* pn, MutableHandleValue dst); 1432 1433 bool declaration(ParseNode* pn, MutableHandleValue dst); 1434 bool variableDeclaration(ListNode* declList, bool lexical, 1435 MutableHandleValue dst); 1436 bool variableDeclarator(ParseNode* pn, MutableHandleValue dst); 1437 bool importDeclaration(BinaryNode* importNode, MutableHandleValue dst); 1438 bool importSpecifier(BinaryNode* importSpec, MutableHandleValue dst); 1439 bool importNamespaceSpecifier(UnaryNode* importSpec, MutableHandleValue dst); 1440 bool exportDeclaration(ParseNode* exportNode, MutableHandleValue dst); 1441 bool exportSpecifier(BinaryNode* exportSpec, MutableHandleValue dst); 1442 bool exportNamespaceSpecifier(UnaryNode* exportSpec, MutableHandleValue dst); 1443 bool classDefinition(ClassNode* pn, bool expr, MutableHandleValue dst); 1444 bool importAttributes(ListNode* attributeList, NodeVector& attributes); 1445 1446 bool optStatement(ParseNode* pn, MutableHandleValue dst) { 1447 if (!pn) { 1448 dst.setMagic(JS_SERIALIZE_NO_NODE); 1449 return true; 1450 } 1451 return statement(pn, dst); 1452 } 1453 1454 bool forInit(ParseNode* pn, MutableHandleValue dst); 1455 bool forIn(ForNode* loop, ParseNode* iterExpr, HandleValue var, 1456 HandleValue stmt, MutableHandleValue dst); 1457 bool forOf(ForNode* loop, ParseNode* iterExpr, HandleValue var, 1458 HandleValue stmt, MutableHandleValue dst); 1459 bool statement(ParseNode* pn, MutableHandleValue dst); 1460 bool blockStatement(ListNode* node, MutableHandleValue dst); 1461 bool switchStatement(SwitchStatement* switchStmt, MutableHandleValue dst); 1462 bool switchCase(CaseClause* caseClause, MutableHandleValue dst); 1463 bool tryStatement(TryNode* tryNode, MutableHandleValue dst); 1464 bool catchClause(BinaryNode* catchClause, MutableHandleValue dst); 1465 1466 bool optExpression(ParseNode* pn, MutableHandleValue dst) { 1467 if (!pn) { 1468 dst.setMagic(JS_SERIALIZE_NO_NODE); 1469 return true; 1470 } 1471 return expression(pn, dst); 1472 } 1473 1474 bool expression(ParseNode* pn, MutableHandleValue dst); 1475 1476 bool propertyName(ParseNode* key, MutableHandleValue dst); 1477 bool property(ParseNode* pn, MutableHandleValue dst); 1478 1479 bool classMethod(ClassMethod* classMethod, MutableHandleValue dst); 1480 bool classField(ClassField* classField, MutableHandleValue dst); 1481 bool staticClassBlock(StaticClassBlock* staticClassBlock, 1482 MutableHandleValue dst); 1483 1484 bool optIdentifier(Handle<JSAtom*> atom, TokenPos* pos, 1485 MutableHandleValue dst) { 1486 if (!atom) { 1487 dst.setMagic(JS_SERIALIZE_NO_NODE); 1488 return true; 1489 } 1490 return identifier(atom, pos, dst); 1491 } 1492 1493 bool identifier(Handle<JSAtom*> atom, TokenPos* pos, MutableHandleValue dst); 1494 bool identifier(NameNode* id, MutableHandleValue dst); 1495 bool identifierOrLiteral(ParseNode* id, MutableHandleValue dst); 1496 bool literal(ParseNode* pn, MutableHandleValue dst); 1497 1498 bool optPattern(ParseNode* pn, MutableHandleValue dst) { 1499 if (!pn) { 1500 dst.setMagic(JS_SERIALIZE_NO_NODE); 1501 return true; 1502 } 1503 return pattern(pn, dst); 1504 } 1505 1506 bool pattern(ParseNode* pn, MutableHandleValue dst); 1507 bool arrayPattern(ListNode* array, MutableHandleValue dst); 1508 bool objectPattern(ListNode* obj, MutableHandleValue dst); 1509 1510 bool function(FunctionNode* funNode, ASTType type, MutableHandleValue dst); 1511 bool functionArgsAndBody(ParamsBodyNode* pn, NodeVector& args, 1512 NodeVector& defaults, bool isAsync, 1513 bool isExpression, MutableHandleValue body, 1514 MutableHandleValue rest); 1515 bool functionBody(ParseNode* pn, TokenPos* pos, MutableHandleValue dst); 1516 1517 public: 1518 ASTSerializer(JSContext* c, FrontendContext* f, bool l, char const* src, 1519 uint32_t ln) 1520 : cx(c), 1521 fc(f), 1522 parser(nullptr), 1523 builder(c, f, l, src) 1524 #ifdef DEBUG 1525 , 1526 lineno(ln) 1527 #endif 1528 { 1529 } 1530 1531 bool init() { return builder.init(); } 1532 1533 void setParser(frontend::Parser<frontend::FullParseHandler, char16_t>* p) { 1534 parser = p; 1535 builder.setParser(p); 1536 } 1537 1538 bool program(ListNode* node, MutableHandleValue dst); 1539 }; 1540 1541 } /* anonymous namespace */ 1542 1543 AssignmentOperator ASTSerializer::aop(ParseNodeKind kind) { 1544 switch (kind) { 1545 case ParseNodeKind::AssignExpr: 1546 return AOP_ASSIGN; 1547 case ParseNodeKind::AddAssignExpr: 1548 return AOP_PLUS; 1549 case ParseNodeKind::SubAssignExpr: 1550 return AOP_MINUS; 1551 case ParseNodeKind::MulAssignExpr: 1552 return AOP_STAR; 1553 case ParseNodeKind::DivAssignExpr: 1554 return AOP_DIV; 1555 case ParseNodeKind::ModAssignExpr: 1556 return AOP_MOD; 1557 case ParseNodeKind::PowAssignExpr: 1558 return AOP_POW; 1559 case ParseNodeKind::LshAssignExpr: 1560 return AOP_LSH; 1561 case ParseNodeKind::RshAssignExpr: 1562 return AOP_RSH; 1563 case ParseNodeKind::UrshAssignExpr: 1564 return AOP_URSH; 1565 case ParseNodeKind::BitOrAssignExpr: 1566 return AOP_BITOR; 1567 case ParseNodeKind::BitXorAssignExpr: 1568 return AOP_BITXOR; 1569 case ParseNodeKind::BitAndAssignExpr: 1570 return AOP_BITAND; 1571 case ParseNodeKind::CoalesceAssignExpr: 1572 return AOP_COALESCE; 1573 case ParseNodeKind::OrAssignExpr: 1574 return AOP_OR; 1575 case ParseNodeKind::AndAssignExpr: 1576 return AOP_AND; 1577 default: 1578 return AOP_ERR; 1579 } 1580 } 1581 1582 UnaryOperator ASTSerializer::unop(ParseNodeKind kind) { 1583 if (IsDeleteKind(kind)) { 1584 return UNOP_DELETE; 1585 } 1586 1587 if (IsTypeofKind(kind)) { 1588 return UNOP_TYPEOF; 1589 } 1590 1591 switch (kind) { 1592 case ParseNodeKind::AwaitExpr: 1593 return UNOP_AWAIT; 1594 case ParseNodeKind::NegExpr: 1595 return UNOP_NEG; 1596 case ParseNodeKind::PosExpr: 1597 return UNOP_POS; 1598 case ParseNodeKind::NotExpr: 1599 return UNOP_NOT; 1600 case ParseNodeKind::BitNotExpr: 1601 return UNOP_BITNOT; 1602 case ParseNodeKind::VoidExpr: 1603 return UNOP_VOID; 1604 default: 1605 return UNOP_ERR; 1606 } 1607 } 1608 1609 BinaryOperator ASTSerializer::binop(ParseNodeKind kind) { 1610 switch (kind) { 1611 case ParseNodeKind::LshExpr: 1612 return BINOP_LSH; 1613 case ParseNodeKind::RshExpr: 1614 return BINOP_RSH; 1615 case ParseNodeKind::UrshExpr: 1616 return BINOP_URSH; 1617 case ParseNodeKind::LtExpr: 1618 return BINOP_LT; 1619 case ParseNodeKind::LeExpr: 1620 return BINOP_LE; 1621 case ParseNodeKind::GtExpr: 1622 return BINOP_GT; 1623 case ParseNodeKind::GeExpr: 1624 return BINOP_GE; 1625 case ParseNodeKind::EqExpr: 1626 return BINOP_EQ; 1627 case ParseNodeKind::NeExpr: 1628 return BINOP_NE; 1629 case ParseNodeKind::StrictEqExpr: 1630 return BINOP_STRICTEQ; 1631 case ParseNodeKind::StrictNeExpr: 1632 return BINOP_STRICTNE; 1633 case ParseNodeKind::AddExpr: 1634 return BINOP_ADD; 1635 case ParseNodeKind::SubExpr: 1636 return BINOP_SUB; 1637 case ParseNodeKind::MulExpr: 1638 return BINOP_STAR; 1639 case ParseNodeKind::DivExpr: 1640 return BINOP_DIV; 1641 case ParseNodeKind::ModExpr: 1642 return BINOP_MOD; 1643 case ParseNodeKind::PowExpr: 1644 return BINOP_POW; 1645 case ParseNodeKind::BitOrExpr: 1646 return BINOP_BITOR; 1647 case ParseNodeKind::BitXorExpr: 1648 return BINOP_BITXOR; 1649 case ParseNodeKind::BitAndExpr: 1650 return BINOP_BITAND; 1651 case ParseNodeKind::InExpr: 1652 case ParseNodeKind::PrivateInExpr: 1653 return BINOP_IN; 1654 case ParseNodeKind::InstanceOfExpr: 1655 return BINOP_INSTANCEOF; 1656 case ParseNodeKind::CoalesceExpr: 1657 return BINOP_COALESCE; 1658 default: 1659 return BINOP_ERR; 1660 } 1661 } 1662 1663 bool ASTSerializer::statements(ListNode* stmtList, NodeVector& elts) { 1664 MOZ_ASSERT(stmtList->isKind(ParseNodeKind::StatementList)); 1665 1666 if (!elts.reserve(stmtList->count())) { 1667 return false; 1668 } 1669 1670 for (ParseNode* stmt : stmtList->contents()) { 1671 MOZ_ASSERT(stmtList->pn_pos.encloses(stmt->pn_pos)); 1672 1673 RootedValue elt(cx); 1674 if (!sourceElement(stmt, &elt)) { 1675 return false; 1676 } 1677 elts.infallibleAppend(elt); 1678 } 1679 1680 return true; 1681 } 1682 1683 bool ASTSerializer::expressions(ListNode* exprList, NodeVector& elts) { 1684 if (!elts.reserve(exprList->count())) { 1685 return false; 1686 } 1687 1688 for (ParseNode* expr : exprList->contents()) { 1689 MOZ_ASSERT(exprList->pn_pos.encloses(expr->pn_pos)); 1690 1691 RootedValue elt(cx); 1692 if (!expression(expr, &elt)) { 1693 return false; 1694 } 1695 elts.infallibleAppend(elt); 1696 } 1697 1698 return true; 1699 } 1700 1701 bool ASTSerializer::blockStatement(ListNode* node, MutableHandleValue dst) { 1702 MOZ_ASSERT(node->isKind(ParseNodeKind::StatementList)); 1703 1704 NodeVector stmts(cx); 1705 return statements(node, stmts) && 1706 builder.blockStatement(stmts, &node->pn_pos, dst); 1707 } 1708 1709 bool ASTSerializer::program(ListNode* node, MutableHandleValue dst) { 1710 #ifdef DEBUG 1711 { 1712 const TokenStreamAnyChars& anyChars = parser->anyChars; 1713 auto lineToken = anyChars.lineToken(node->pn_pos.begin); 1714 MOZ_ASSERT(anyChars.lineNumber(lineToken) == lineno); 1715 } 1716 #endif 1717 1718 NodeVector stmts(cx); 1719 return statements(node, stmts) && builder.program(stmts, &node->pn_pos, dst); 1720 } 1721 1722 bool ASTSerializer::sourceElement(ParseNode* pn, MutableHandleValue dst) { 1723 /* SpiderMonkey allows declarations even in pure statement contexts. */ 1724 return statement(pn, dst); 1725 } 1726 1727 bool ASTSerializer::declaration(ParseNode* pn, MutableHandleValue dst) { 1728 MOZ_ASSERT(pn->isKind(ParseNodeKind::Function) || 1729 pn->isKind(ParseNodeKind::VarStmt) || 1730 pn->isKind(ParseNodeKind::LetDecl) || 1731 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT 1732 pn->isKind(ParseNodeKind::UsingDecl) || 1733 pn->isKind(ParseNodeKind::AwaitUsingDecl) || 1734 #endif 1735 pn->isKind(ParseNodeKind::ConstDecl)); 1736 1737 switch (pn->getKind()) { 1738 case ParseNodeKind::Function: 1739 return function(&pn->as<FunctionNode>(), AST_FUNC_DECL, dst); 1740 1741 case ParseNodeKind::VarStmt: 1742 return variableDeclaration(&pn->as<ListNode>(), false, dst); 1743 1744 default: 1745 MOZ_ASSERT(pn->isKind(ParseNodeKind::LetDecl) || 1746 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT 1747 pn->isKind(ParseNodeKind::UsingDecl) || 1748 pn->isKind(ParseNodeKind::AwaitUsingDecl) || 1749 #endif 1750 pn->isKind(ParseNodeKind::ConstDecl)); 1751 return variableDeclaration(&pn->as<ListNode>(), true, dst); 1752 } 1753 } 1754 1755 bool ASTSerializer::variableDeclaration(ListNode* declList, bool lexical, 1756 MutableHandleValue dst) { 1757 MOZ_ASSERT_IF(lexical, declList->isKind(ParseNodeKind::LetDecl) || 1758 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT 1759 declList->isKind(ParseNodeKind::UsingDecl) || 1760 declList->isKind(ParseNodeKind::AwaitUsingDecl) || 1761 #endif 1762 declList->isKind(ParseNodeKind::ConstDecl)); 1763 MOZ_ASSERT_IF(!lexical, declList->isKind(ParseNodeKind::VarStmt)); 1764 1765 VarDeclKind kind = VARDECL_ERR; 1766 // Treat both the toplevel const binding (secretly var-like) and the lexical 1767 // const the same way 1768 if (lexical) { 1769 if (declList->isKind(ParseNodeKind::LetDecl)) { 1770 kind = VARDECL_LET; 1771 } 1772 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT 1773 else if (declList->isKind(ParseNodeKind::UsingDecl)) { 1774 kind = VARDECL_USING; 1775 } else if (declList->isKind(ParseNodeKind::AwaitUsingDecl)) { 1776 kind = VARDECL_AWAIT_USING; 1777 } 1778 #endif 1779 else { 1780 kind = VARDECL_CONST; 1781 } 1782 } else { 1783 kind = 1784 declList->isKind(ParseNodeKind::VarStmt) ? VARDECL_VAR : VARDECL_CONST; 1785 } 1786 1787 NodeVector dtors(cx); 1788 if (!dtors.reserve(declList->count())) { 1789 return false; 1790 } 1791 for (ParseNode* decl : declList->contents()) { 1792 RootedValue child(cx); 1793 if (!variableDeclarator(decl, &child)) { 1794 return false; 1795 } 1796 dtors.infallibleAppend(child); 1797 } 1798 return builder.variableDeclaration(dtors, kind, &declList->pn_pos, dst); 1799 } 1800 1801 bool ASTSerializer::variableDeclarator(ParseNode* pn, MutableHandleValue dst) { 1802 ParseNode* patternNode; 1803 ParseNode* initNode; 1804 1805 if (pn->isKind(ParseNodeKind::Name)) { 1806 patternNode = pn; 1807 initNode = nullptr; 1808 } else if (pn->isKind(ParseNodeKind::AssignExpr)) { 1809 AssignmentNode* assignNode = &pn->as<AssignmentNode>(); 1810 patternNode = assignNode->left(); 1811 initNode = assignNode->right(); 1812 MOZ_ASSERT(pn->pn_pos.encloses(patternNode->pn_pos)); 1813 MOZ_ASSERT(pn->pn_pos.encloses(initNode->pn_pos)); 1814 } else { 1815 /* This happens for a destructuring declarator in a for-in/of loop. */ 1816 patternNode = pn; 1817 initNode = nullptr; 1818 } 1819 1820 RootedValue patternVal(cx), init(cx); 1821 return pattern(patternNode, &patternVal) && optExpression(initNode, &init) && 1822 builder.variableDeclarator(patternVal, init, &pn->pn_pos, dst); 1823 } 1824 1825 bool ASTSerializer::importDeclaration(BinaryNode* importNode, 1826 MutableHandleValue dst) { 1827 MOZ_ASSERT(importNode->isKind(ParseNodeKind::ImportDecl)); 1828 1829 ListNode* specList = &importNode->left()->as<ListNode>(); 1830 MOZ_ASSERT(specList->isKind(ParseNodeKind::ImportSpecList)); 1831 1832 auto* moduleRequest = &importNode->right()->as<BinaryNode>(); 1833 MOZ_ASSERT(moduleRequest->isKind(ParseNodeKind::ImportModuleRequest)); 1834 1835 ParseNode* moduleSpecNode = moduleRequest->left(); 1836 MOZ_ASSERT(moduleSpecNode->isKind(ParseNodeKind::StringExpr)); 1837 1838 auto* attributeList = &moduleRequest->right()->as<ListNode>(); 1839 MOZ_ASSERT(attributeList->isKind(ParseNodeKind::ImportAttributeList)); 1840 1841 NodeVector elts(cx); 1842 if (!elts.reserve(specList->count())) { 1843 return false; 1844 } 1845 1846 for (ParseNode* item : specList->contents()) { 1847 RootedValue elt(cx); 1848 if (item->is<UnaryNode>()) { 1849 auto* spec = &item->as<UnaryNode>(); 1850 if (!importNamespaceSpecifier(spec, &elt)) { 1851 return false; 1852 } 1853 } else { 1854 auto* spec = &item->as<BinaryNode>(); 1855 if (!importSpecifier(spec, &elt)) { 1856 return false; 1857 } 1858 } 1859 elts.infallibleAppend(elt); 1860 } 1861 1862 RootedValue moduleSpec(cx); 1863 if (!literal(moduleSpecNode, &moduleSpec)) { 1864 return false; 1865 } 1866 1867 NodeVector attributes(cx); 1868 if (!importAttributes(attributeList, attributes)) { 1869 return false; 1870 } 1871 1872 RootedValue moduleRequestValue(cx); 1873 if (!builder.moduleRequest(moduleSpec, attributes, &importNode->pn_pos, 1874 &moduleRequestValue)) { 1875 return false; 1876 } 1877 1878 return builder.importDeclaration(elts, moduleRequestValue, 1879 &importNode->pn_pos, dst); 1880 } 1881 1882 bool ASTSerializer::importSpecifier(BinaryNode* importSpec, 1883 MutableHandleValue dst) { 1884 MOZ_ASSERT(importSpec->isKind(ParseNodeKind::ImportSpec)); 1885 NameNode* importNameNode = &importSpec->left()->as<NameNode>(); 1886 NameNode* bindingNameNode = &importSpec->right()->as<NameNode>(); 1887 1888 RootedValue importName(cx); 1889 RootedValue bindingName(cx); 1890 return identifierOrLiteral(importNameNode, &importName) && 1891 identifier(bindingNameNode, &bindingName) && 1892 builder.importSpecifier(importName, bindingName, &importSpec->pn_pos, 1893 dst); 1894 } 1895 1896 bool ASTSerializer::importNamespaceSpecifier(UnaryNode* importSpec, 1897 MutableHandleValue dst) { 1898 MOZ_ASSERT(importSpec->isKind(ParseNodeKind::ImportNamespaceSpec)); 1899 NameNode* bindingNameNode = &importSpec->kid()->as<NameNode>(); 1900 1901 RootedValue bindingName(cx); 1902 return identifier(bindingNameNode, &bindingName) && 1903 builder.importNamespaceSpecifier(bindingName, &importSpec->pn_pos, 1904 dst); 1905 } 1906 1907 bool ASTSerializer::exportDeclaration(ParseNode* exportNode, 1908 MutableHandleValue dst) { 1909 MOZ_ASSERT(exportNode->isKind(ParseNodeKind::ExportStmt) || 1910 exportNode->isKind(ParseNodeKind::ExportFromStmt) || 1911 exportNode->isKind(ParseNodeKind::ExportDefaultStmt)); 1912 MOZ_ASSERT_IF(exportNode->isKind(ParseNodeKind::ExportStmt), 1913 exportNode->is<UnaryNode>()); 1914 MOZ_ASSERT_IF(exportNode->isKind(ParseNodeKind::ExportFromStmt), 1915 exportNode->as<BinaryNode>().right()->isKind( 1916 ParseNodeKind::ImportModuleRequest)); 1917 1918 RootedValue decl(cx, NullValue()); 1919 NodeVector elts(cx); 1920 1921 ParseNode* kid = exportNode->isKind(ParseNodeKind::ExportStmt) 1922 ? exportNode->as<UnaryNode>().kid() 1923 : exportNode->as<BinaryNode>().left(); 1924 switch (ParseNodeKind kind = kid->getKind()) { 1925 case ParseNodeKind::ExportSpecList: { 1926 ListNode* specList = &kid->as<ListNode>(); 1927 if (!elts.reserve(specList->count())) { 1928 return false; 1929 } 1930 1931 for (ParseNode* spec : specList->contents()) { 1932 RootedValue elt(cx); 1933 if (spec->isKind(ParseNodeKind::ExportSpec)) { 1934 if (!exportSpecifier(&spec->as<BinaryNode>(), &elt)) { 1935 return false; 1936 } 1937 } else if (spec->isKind(ParseNodeKind::ExportNamespaceSpec)) { 1938 if (!exportNamespaceSpecifier(&spec->as<UnaryNode>(), &elt)) { 1939 return false; 1940 } 1941 } else { 1942 MOZ_ASSERT(spec->isKind(ParseNodeKind::ExportBatchSpecStmt)); 1943 if (!builder.exportBatchSpecifier(&exportNode->pn_pos, &elt)) { 1944 return false; 1945 } 1946 } 1947 elts.infallibleAppend(elt); 1948 } 1949 break; 1950 } 1951 1952 case ParseNodeKind::Function: 1953 if (!function(&kid->as<FunctionNode>(), AST_FUNC_DECL, &decl)) { 1954 return false; 1955 } 1956 break; 1957 1958 case ParseNodeKind::ClassDecl: 1959 if (!classDefinition(&kid->as<ClassNode>(), false, &decl)) { 1960 return false; 1961 } 1962 break; 1963 1964 case ParseNodeKind::VarStmt: 1965 case ParseNodeKind::ConstDecl: 1966 case ParseNodeKind::LetDecl: 1967 if (!variableDeclaration(&kid->as<ListNode>(), 1968 kind != ParseNodeKind::VarStmt, &decl)) { 1969 return false; 1970 } 1971 break; 1972 1973 default: 1974 if (!expression(kid, &decl)) { 1975 return false; 1976 } 1977 break; 1978 } 1979 1980 RootedValue moduleSpec(cx, NullValue()); 1981 RootedValue moduleRequestValue(cx, NullValue()); 1982 if (exportNode->isKind(ParseNodeKind::ExportFromStmt)) { 1983 ParseNode* moduleRequest = exportNode->as<BinaryNode>().right(); 1984 if (!literal(moduleRequest->as<BinaryNode>().left(), &moduleSpec)) { 1985 return false; 1986 } 1987 1988 auto* attributeList = 1989 &moduleRequest->as<BinaryNode>().right()->as<ListNode>(); 1990 MOZ_ASSERT(attributeList->isKind(ParseNodeKind::ImportAttributeList)); 1991 1992 NodeVector attributes(cx); 1993 if (!importAttributes(attributeList, attributes)) { 1994 return false; 1995 } 1996 1997 if (!builder.moduleRequest(moduleSpec, attributes, &exportNode->pn_pos, 1998 &moduleRequestValue)) { 1999 return false; 2000 } 2001 } 2002 2003 RootedValue isDefault(cx, BooleanValue(false)); 2004 if (exportNode->isKind(ParseNodeKind::ExportDefaultStmt)) { 2005 isDefault.setBoolean(true); 2006 } 2007 2008 return builder.exportDeclaration(decl, elts, moduleRequestValue, isDefault, 2009 &exportNode->pn_pos, dst); 2010 } 2011 2012 bool ASTSerializer::exportSpecifier(BinaryNode* exportSpec, 2013 MutableHandleValue dst) { 2014 MOZ_ASSERT(exportSpec->isKind(ParseNodeKind::ExportSpec)); 2015 NameNode* bindingNameNode = &exportSpec->left()->as<NameNode>(); 2016 NameNode* exportNameNode = &exportSpec->right()->as<NameNode>(); 2017 2018 RootedValue bindingName(cx); 2019 RootedValue exportName(cx); 2020 return identifierOrLiteral(bindingNameNode, &bindingName) && 2021 identifierOrLiteral(exportNameNode, &exportName) && 2022 builder.exportSpecifier(bindingName, exportName, &exportSpec->pn_pos, 2023 dst); 2024 } 2025 2026 bool ASTSerializer::exportNamespaceSpecifier(UnaryNode* exportSpec, 2027 MutableHandleValue dst) { 2028 MOZ_ASSERT(exportSpec->isKind(ParseNodeKind::ExportNamespaceSpec)); 2029 NameNode* exportNameNode = &exportSpec->kid()->as<NameNode>(); 2030 2031 RootedValue exportName(cx); 2032 return identifierOrLiteral(exportNameNode, &exportName) && 2033 builder.exportNamespaceSpecifier(exportName, &exportSpec->pn_pos, dst); 2034 } 2035 2036 bool ASTSerializer::importAttributes(ListNode* attributeList, 2037 NodeVector& attributes) { 2038 for (ParseNode* attributeItem : attributeList->contents()) { 2039 BinaryNode* attributeNode = &attributeItem->as<BinaryNode>(); 2040 MOZ_ASSERT(attributeNode->isKind(ParseNodeKind::ImportAttribute)); 2041 2042 NameNode* keyNameNode = &attributeNode->left()->as<NameNode>(); 2043 NameNode* valueNameNode = &attributeNode->right()->as<NameNode>(); 2044 2045 RootedValue key(cx); 2046 if (!identifierOrLiteral(keyNameNode, &key)) { 2047 return false; 2048 } 2049 2050 RootedValue value(cx); 2051 if (!literal(valueNameNode, &value)) { 2052 return false; 2053 } 2054 2055 RootedValue attribute(cx); 2056 if (!builder.importAttribute(key, value, &attributeNode->pn_pos, 2057 &attribute)) { 2058 return false; 2059 } 2060 2061 if (!attributes.append(attribute)) { 2062 return false; 2063 } 2064 } 2065 2066 return true; 2067 } 2068 2069 bool ASTSerializer::switchCase(CaseClause* caseClause, MutableHandleValue dst) { 2070 MOZ_ASSERT_IF( 2071 caseClause->caseExpression(), 2072 caseClause->pn_pos.encloses(caseClause->caseExpression()->pn_pos)); 2073 MOZ_ASSERT(caseClause->pn_pos.encloses(caseClause->statementList()->pn_pos)); 2074 2075 NodeVector stmts(cx); 2076 RootedValue expr(cx); 2077 return optExpression(caseClause->caseExpression(), &expr) && 2078 statements(caseClause->statementList(), stmts) && 2079 builder.switchCase(expr, stmts, &caseClause->pn_pos, dst); 2080 } 2081 2082 bool ASTSerializer::switchStatement(SwitchStatement* switchStmt, 2083 MutableHandleValue dst) { 2084 MOZ_ASSERT(switchStmt->pn_pos.encloses(switchStmt->discriminant().pn_pos)); 2085 MOZ_ASSERT( 2086 switchStmt->pn_pos.encloses(switchStmt->lexicalForCaseList().pn_pos)); 2087 2088 RootedValue disc(cx); 2089 if (!expression(&switchStmt->discriminant(), &disc)) { 2090 return false; 2091 } 2092 2093 ListNode* caseList = 2094 &switchStmt->lexicalForCaseList().scopeBody()->as<ListNode>(); 2095 2096 NodeVector cases(cx); 2097 if (!cases.reserve(caseList->count())) { 2098 return false; 2099 } 2100 2101 for (ParseNode* item : caseList->contents()) { 2102 CaseClause* caseClause = &item->as<CaseClause>(); 2103 RootedValue child(cx); 2104 if (!switchCase(caseClause, &child)) { 2105 return false; 2106 } 2107 cases.infallibleAppend(child); 2108 } 2109 2110 // `lexical` field is always true. 2111 return builder.switchStatement(disc, cases, true, &switchStmt->pn_pos, dst); 2112 } 2113 2114 bool ASTSerializer::catchClause(BinaryNode* catchClause, 2115 MutableHandleValue dst) { 2116 MOZ_ASSERT(catchClause->isKind(ParseNodeKind::Catch)); 2117 2118 ParseNode* varNode = catchClause->left(); 2119 MOZ_ASSERT_IF(varNode, catchClause->pn_pos.encloses(varNode->pn_pos)); 2120 2121 ParseNode* bodyNode = catchClause->right(); 2122 MOZ_ASSERT(catchClause->pn_pos.encloses(bodyNode->pn_pos)); 2123 2124 RootedValue var(cx), body(cx); 2125 if (!optPattern(varNode, &var)) { 2126 return false; 2127 } 2128 2129 return statement(bodyNode, &body) && 2130 builder.catchClause(var, body, &catchClause->pn_pos, dst); 2131 } 2132 2133 bool ASTSerializer::tryStatement(TryNode* tryNode, MutableHandleValue dst) { 2134 ParseNode* bodyNode = tryNode->body(); 2135 MOZ_ASSERT(tryNode->pn_pos.encloses(bodyNode->pn_pos)); 2136 2137 LexicalScopeNode* catchNode = tryNode->catchScope(); 2138 MOZ_ASSERT_IF(catchNode, tryNode->pn_pos.encloses(catchNode->pn_pos)); 2139 2140 ParseNode* finallyNode = tryNode->finallyBlock(); 2141 MOZ_ASSERT_IF(finallyNode, tryNode->pn_pos.encloses(finallyNode->pn_pos)); 2142 2143 RootedValue body(cx); 2144 if (!statement(bodyNode, &body)) { 2145 return false; 2146 } 2147 2148 RootedValue handler(cx, NullValue()); 2149 if (catchNode) { 2150 LexicalScopeNode* catchScope = &catchNode->as<LexicalScopeNode>(); 2151 if (!catchClause(&catchScope->scopeBody()->as<BinaryNode>(), &handler)) { 2152 return false; 2153 } 2154 } 2155 2156 RootedValue finally(cx); 2157 return optStatement(finallyNode, &finally) && 2158 builder.tryStatement(body, handler, finally, &tryNode->pn_pos, dst); 2159 } 2160 2161 bool ASTSerializer::forInit(ParseNode* pn, MutableHandleValue dst) { 2162 if (!pn) { 2163 dst.setMagic(JS_SERIALIZE_NO_NODE); 2164 return true; 2165 } 2166 2167 bool lexical = pn->isKind(ParseNodeKind::LetDecl) || 2168 pn->isKind(ParseNodeKind::ConstDecl) 2169 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT 2170 || pn->isKind(ParseNodeKind::UsingDecl) || 2171 pn->isKind(ParseNodeKind::AwaitUsingDecl) 2172 #endif 2173 ; 2174 return (lexical || pn->isKind(ParseNodeKind::VarStmt)) 2175 ? variableDeclaration(&pn->as<ListNode>(), lexical, dst) 2176 : expression(pn, dst); 2177 } 2178 2179 bool ASTSerializer::forOf(ForNode* loop, ParseNode* iterExpr, HandleValue var, 2180 HandleValue stmt, MutableHandleValue dst) { 2181 RootedValue expr(cx); 2182 2183 return expression(iterExpr, &expr) && 2184 builder.forOfStatement(var, expr, stmt, &loop->pn_pos, dst); 2185 } 2186 2187 bool ASTSerializer::forIn(ForNode* loop, ParseNode* iterExpr, HandleValue var, 2188 HandleValue stmt, MutableHandleValue dst) { 2189 RootedValue expr(cx); 2190 2191 return expression(iterExpr, &expr) && 2192 builder.forInStatement(var, expr, stmt, &loop->pn_pos, dst); 2193 } 2194 2195 bool ASTSerializer::classDefinition(ClassNode* pn, bool expr, 2196 MutableHandleValue dst) { 2197 RootedValue className(cx, MagicValue(JS_SERIALIZE_NO_NODE)); 2198 RootedValue heritage(cx); 2199 RootedValue classBody(cx); 2200 #ifdef ENABLE_DECORATORS 2201 NodeVector classDecorators(cx); 2202 RootedValue classDecoratorsArray(cx); 2203 TokenPos decoratorPos; 2204 bool decoratorsParsed = true; 2205 if (pn->decorators()) { 2206 decoratorPos.begin = pn->decorators()->head()->pn_pos.begin; 2207 decoratorPos.end = pn->decorators()->last()->pn_pos.end; 2208 decoratorsParsed = 2209 expressions(pn->decorators(), classDecorators) && 2210 builder.sequenceExpression(classDecorators, &decoratorPos, 2211 &classDecoratorsArray); 2212 } else { 2213 classDecoratorsArray.setMagic(JS_SERIALIZE_NO_NODE); 2214 } 2215 #endif 2216 2217 if (ClassNames* names = pn->names()) { 2218 if (!identifier(names->innerBinding(), &className)) { 2219 return false; 2220 } 2221 } 2222 2223 return optExpression(pn->heritage(), &heritage) && 2224 statement(pn->memberList(), &classBody) && 2225 #ifdef ENABLE_DECORATORS 2226 decoratorsParsed && 2227 #endif 2228 builder.classDefinition(expr, className, heritage, classBody, 2229 #ifdef ENABLE_DECORATORS 2230 classDecoratorsArray, 2231 #endif 2232 &pn->pn_pos, dst); 2233 } 2234 2235 bool ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst) { 2236 AutoCheckRecursionLimit recursion(cx); 2237 if (!recursion.check(cx)) { 2238 return false; 2239 } 2240 2241 switch (pn->getKind()) { 2242 case ParseNodeKind::Function: 2243 case ParseNodeKind::VarStmt: 2244 return declaration(pn, dst); 2245 2246 case ParseNodeKind::LetDecl: 2247 case ParseNodeKind::ConstDecl: 2248 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT 2249 case ParseNodeKind::UsingDecl: 2250 case ParseNodeKind::AwaitUsingDecl: 2251 #endif 2252 return declaration(pn, dst); 2253 2254 case ParseNodeKind::ImportDecl: 2255 return importDeclaration(&pn->as<BinaryNode>(), dst); 2256 2257 case ParseNodeKind::ExportStmt: 2258 case ParseNodeKind::ExportDefaultStmt: 2259 case ParseNodeKind::ExportFromStmt: 2260 return exportDeclaration(pn, dst); 2261 2262 case ParseNodeKind::EmptyStmt: 2263 return builder.emptyStatement(&pn->pn_pos, dst); 2264 2265 case ParseNodeKind::ExpressionStmt: { 2266 RootedValue expr(cx); 2267 return expression(pn->as<UnaryNode>().kid(), &expr) && 2268 builder.expressionStatement(expr, &pn->pn_pos, dst); 2269 } 2270 2271 case ParseNodeKind::LexicalScope: 2272 pn = pn->as<LexicalScopeNode>().scopeBody(); 2273 if (!pn->isKind(ParseNodeKind::StatementList)) { 2274 return statement(pn, dst); 2275 } 2276 [[fallthrough]]; 2277 2278 case ParseNodeKind::StatementList: 2279 return blockStatement(&pn->as<ListNode>(), dst); 2280 2281 case ParseNodeKind::IfStmt: { 2282 TernaryNode* ifNode = &pn->as<TernaryNode>(); 2283 2284 ParseNode* testNode = ifNode->kid1(); 2285 MOZ_ASSERT(ifNode->pn_pos.encloses(testNode->pn_pos)); 2286 2287 ParseNode* consNode = ifNode->kid2(); 2288 MOZ_ASSERT(ifNode->pn_pos.encloses(consNode->pn_pos)); 2289 2290 ParseNode* altNode = ifNode->kid3(); 2291 MOZ_ASSERT_IF(altNode, ifNode->pn_pos.encloses(altNode->pn_pos)); 2292 2293 RootedValue test(cx), cons(cx), alt(cx); 2294 2295 return expression(testNode, &test) && statement(consNode, &cons) && 2296 optStatement(altNode, &alt) && 2297 builder.ifStatement(test, cons, alt, &ifNode->pn_pos, dst); 2298 } 2299 2300 case ParseNodeKind::SwitchStmt: 2301 return switchStatement(&pn->as<SwitchStatement>(), dst); 2302 2303 case ParseNodeKind::TryStmt: 2304 return tryStatement(&pn->as<TryNode>(), dst); 2305 2306 case ParseNodeKind::WithStmt: 2307 case ParseNodeKind::WhileStmt: { 2308 BinaryNode* node = &pn->as<BinaryNode>(); 2309 2310 ParseNode* exprNode = node->left(); 2311 MOZ_ASSERT(node->pn_pos.encloses(exprNode->pn_pos)); 2312 2313 ParseNode* stmtNode = node->right(); 2314 MOZ_ASSERT(node->pn_pos.encloses(stmtNode->pn_pos)); 2315 2316 RootedValue expr(cx), stmt(cx); 2317 2318 return expression(exprNode, &expr) && statement(stmtNode, &stmt) && 2319 (node->isKind(ParseNodeKind::WithStmt) 2320 ? builder.withStatement(expr, stmt, &node->pn_pos, dst) 2321 : builder.whileStatement(expr, stmt, &node->pn_pos, dst)); 2322 } 2323 2324 case ParseNodeKind::DoWhileStmt: { 2325 BinaryNode* node = &pn->as<BinaryNode>(); 2326 2327 ParseNode* stmtNode = node->left(); 2328 MOZ_ASSERT(node->pn_pos.encloses(stmtNode->pn_pos)); 2329 2330 ParseNode* testNode = node->right(); 2331 MOZ_ASSERT(node->pn_pos.encloses(testNode->pn_pos)); 2332 2333 RootedValue stmt(cx), test(cx); 2334 2335 return statement(stmtNode, &stmt) && expression(testNode, &test) && 2336 builder.doWhileStatement(stmt, test, &node->pn_pos, dst); 2337 } 2338 2339 case ParseNodeKind::ForStmt: { 2340 ForNode* forNode = &pn->as<ForNode>(); 2341 2342 TernaryNode* head = forNode->head(); 2343 MOZ_ASSERT(forNode->pn_pos.encloses(head->pn_pos)); 2344 2345 ParseNode* stmtNode = forNode->right(); 2346 MOZ_ASSERT(forNode->pn_pos.encloses(stmtNode->pn_pos)); 2347 2348 ParseNode* initNode = head->kid1(); 2349 MOZ_ASSERT_IF(initNode, head->pn_pos.encloses(initNode->pn_pos)); 2350 2351 ParseNode* maybeTest = head->kid2(); 2352 MOZ_ASSERT_IF(maybeTest, head->pn_pos.encloses(maybeTest->pn_pos)); 2353 2354 ParseNode* updateOrIter = head->kid3(); 2355 MOZ_ASSERT_IF(updateOrIter, head->pn_pos.encloses(updateOrIter->pn_pos)); 2356 2357 RootedValue stmt(cx); 2358 if (!statement(stmtNode, &stmt)) { 2359 return false; 2360 } 2361 2362 if (head->isKind(ParseNodeKind::ForIn) || 2363 head->isKind(ParseNodeKind::ForOf)) { 2364 RootedValue var(cx); 2365 if (initNode->is<LexicalScopeNode>()) { 2366 LexicalScopeNode* scopeNode = &initNode->as<LexicalScopeNode>(); 2367 if (!variableDeclaration(&scopeNode->scopeBody()->as<ListNode>(), 2368 true, &var)) { 2369 return false; 2370 } 2371 } else if (!initNode->isKind(ParseNodeKind::VarStmt) && 2372 !initNode->isKind(ParseNodeKind::LetDecl) && 2373 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT 2374 !initNode->isKind(ParseNodeKind::UsingDecl) && 2375 !initNode->isKind(ParseNodeKind::AwaitUsingDecl) && 2376 #endif 2377 !initNode->isKind(ParseNodeKind::ConstDecl)) { 2378 if (!pattern(initNode, &var)) { 2379 return false; 2380 } 2381 } else { 2382 if (!variableDeclaration( 2383 &initNode->as<ListNode>(), 2384 initNode->isKind(ParseNodeKind::LetDecl) || 2385 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT 2386 initNode->isKind(ParseNodeKind::UsingDecl) || 2387 initNode->isKind(ParseNodeKind::AwaitUsingDecl) || 2388 #endif 2389 initNode->isKind(ParseNodeKind::ConstDecl), 2390 &var)) { 2391 return false; 2392 } 2393 } 2394 if (head->isKind(ParseNodeKind::ForIn)) { 2395 return forIn(forNode, updateOrIter, var, stmt, dst); 2396 } 2397 return forOf(forNode, updateOrIter, var, stmt, dst); 2398 } 2399 2400 RootedValue init(cx), test(cx), update(cx); 2401 2402 return forInit(initNode, &init) && optExpression(maybeTest, &test) && 2403 optExpression(updateOrIter, &update) && 2404 builder.forStatement(init, test, update, stmt, &forNode->pn_pos, 2405 dst); 2406 } 2407 2408 case ParseNodeKind::BreakStmt: 2409 case ParseNodeKind::ContinueStmt: { 2410 LoopControlStatement* node = &pn->as<LoopControlStatement>(); 2411 RootedValue label(cx); 2412 Rooted<JSAtom*> pnAtom(cx); 2413 if (node->label()) { 2414 pnAtom.set(parser->liftParserAtomToJSAtom(node->label())); 2415 if (!pnAtom) { 2416 return false; 2417 } 2418 } 2419 return optIdentifier(pnAtom, nullptr, &label) && 2420 (node->isKind(ParseNodeKind::BreakStmt) 2421 ? builder.breakStatement(label, &node->pn_pos, dst) 2422 : builder.continueStatement(label, &node->pn_pos, dst)); 2423 } 2424 2425 case ParseNodeKind::LabelStmt: { 2426 LabeledStatement* labelNode = &pn->as<LabeledStatement>(); 2427 ParseNode* stmtNode = labelNode->statement(); 2428 MOZ_ASSERT(labelNode->pn_pos.encloses(stmtNode->pn_pos)); 2429 2430 RootedValue label(cx), stmt(cx); 2431 Rooted<JSAtom*> pnAtom( 2432 cx, parser->liftParserAtomToJSAtom(labelNode->label())); 2433 if (!pnAtom.get()) { 2434 return false; 2435 } 2436 return identifier(pnAtom, nullptr, &label) && 2437 statement(stmtNode, &stmt) && 2438 builder.labeledStatement(label, stmt, &labelNode->pn_pos, dst); 2439 } 2440 2441 case ParseNodeKind::ThrowStmt: { 2442 UnaryNode* throwNode = &pn->as<UnaryNode>(); 2443 ParseNode* operand = throwNode->kid(); 2444 MOZ_ASSERT(throwNode->pn_pos.encloses(operand->pn_pos)); 2445 2446 RootedValue arg(cx); 2447 2448 return expression(operand, &arg) && 2449 builder.throwStatement(arg, &throwNode->pn_pos, dst); 2450 } 2451 2452 case ParseNodeKind::ReturnStmt: { 2453 UnaryNode* returnNode = &pn->as<UnaryNode>(); 2454 ParseNode* operand = returnNode->kid(); 2455 MOZ_ASSERT_IF(operand, returnNode->pn_pos.encloses(operand->pn_pos)); 2456 2457 RootedValue arg(cx); 2458 2459 return optExpression(operand, &arg) && 2460 builder.returnStatement(arg, &returnNode->pn_pos, dst); 2461 } 2462 2463 case ParseNodeKind::DebuggerStmt: 2464 return builder.debuggerStatement(&pn->pn_pos, dst); 2465 2466 case ParseNodeKind::ClassDecl: 2467 return classDefinition(&pn->as<ClassNode>(), false, dst); 2468 2469 case ParseNodeKind::ClassMemberList: { 2470 ListNode* memberList = &pn->as<ListNode>(); 2471 NodeVector members(cx); 2472 if (!members.reserve(memberList->count())) { 2473 return false; 2474 } 2475 2476 for (ParseNode* item : memberList->contents()) { 2477 if (item->is<LexicalScopeNode>()) { 2478 item = item->as<LexicalScopeNode>().scopeBody(); 2479 } 2480 if (item->is<ClassField>()) { 2481 ClassField* field = &item->as<ClassField>(); 2482 MOZ_ASSERT(memberList->pn_pos.encloses(field->pn_pos)); 2483 2484 RootedValue prop(cx); 2485 if (!classField(field, &prop)) { 2486 return false; 2487 } 2488 members.infallibleAppend(prop); 2489 } else if (item->is<StaticClassBlock>()) { 2490 // StaticClassBlock* block = &item->as<StaticClassBlock>(); 2491 StaticClassBlock* scb = &item->as<StaticClassBlock>(); 2492 MOZ_ASSERT(memberList->pn_pos.encloses(scb->pn_pos)); 2493 RootedValue prop(cx); 2494 if (!staticClassBlock(scb, &prop)) { 2495 return false; 2496 } 2497 members.infallibleAppend(prop); 2498 } else if (!item->isKind(ParseNodeKind::DefaultConstructor)) { 2499 ClassMethod* method = &item->as<ClassMethod>(); 2500 MOZ_ASSERT(memberList->pn_pos.encloses(method->pn_pos)); 2501 2502 RootedValue prop(cx); 2503 if (!classMethod(method, &prop)) { 2504 return false; 2505 } 2506 members.infallibleAppend(prop); 2507 } 2508 } 2509 2510 return builder.classMembers(members, dst); 2511 } 2512 2513 default: 2514 LOCAL_NOT_REACHED("unexpected statement type"); 2515 } 2516 } 2517 2518 bool ASTSerializer::classMethod(ClassMethod* classMethod, 2519 MutableHandleValue dst) { 2520 PropKind kind; 2521 switch (classMethod->accessorType()) { 2522 case AccessorType::None: 2523 kind = PROP_INIT; 2524 break; 2525 2526 case AccessorType::Getter: 2527 kind = PROP_GETTER; 2528 break; 2529 2530 case AccessorType::Setter: 2531 kind = PROP_SETTER; 2532 break; 2533 2534 default: 2535 LOCAL_NOT_REACHED("unexpected object-literal property"); 2536 } 2537 #ifdef ENABLE_DECORATORS 2538 NodeVector methodDecorators(cx); 2539 RootedValue methodDecoratorsArray(cx); 2540 TokenPos decoratorPos; 2541 bool decoratorsParsed = true; 2542 if (classMethod->decorators()) { 2543 decoratorPos.begin = classMethod->decorators()->head()->pn_pos.begin; 2544 decoratorPos.end = classMethod->decorators()->last()->pn_pos.end; 2545 decoratorsParsed = 2546 expressions(classMethod->decorators(), methodDecorators) && 2547 builder.sequenceExpression(methodDecorators, &decoratorPos, 2548 &methodDecoratorsArray); 2549 } else { 2550 methodDecoratorsArray.setMagic(JS_SERIALIZE_NO_NODE); 2551 } 2552 #endif 2553 2554 RootedValue key(cx), val(cx); 2555 bool isStatic = classMethod->isStatic(); 2556 return propertyName(&classMethod->name(), &key) && 2557 expression(&classMethod->method(), &val) && 2558 #ifdef ENABLE_DECORATORS 2559 decoratorsParsed && 2560 #endif 2561 builder.classMethod(key, val, 2562 #ifdef ENABLE_DECORATORS 2563 methodDecoratorsArray, 2564 #endif 2565 kind, isStatic, &classMethod->pn_pos, dst); 2566 } 2567 2568 bool ASTSerializer::classField(ClassField* classField, MutableHandleValue dst) { 2569 RootedValue key(cx), val(cx); 2570 // Dig through the lambda and get to the actual expression 2571 ParseNode* value = classField->initializer() 2572 ->body() 2573 ->body() 2574 ->scopeBody() 2575 ->as<ListNode>() 2576 .head() 2577 ->as<UnaryNode>() 2578 .kid() 2579 ->as<BinaryNode>() 2580 .right(); 2581 #ifdef ENABLE_DECORATORS 2582 NodeVector fieldDecorators(cx); 2583 RootedValue fieldDecoratorsArray(cx); 2584 TokenPos decoratorPos; 2585 bool decoratorsParsed = true; 2586 if (classField->decorators()) { 2587 decoratorPos.begin = classField->decorators()->head()->pn_pos.begin; 2588 decoratorPos.end = classField->decorators()->last()->pn_pos.end; 2589 decoratorsParsed = 2590 expressions(classField->decorators(), fieldDecorators) && 2591 builder.sequenceExpression(fieldDecorators, &decoratorPos, 2592 &fieldDecoratorsArray); 2593 } else { 2594 fieldDecoratorsArray.setMagic(JS_SERIALIZE_NO_NODE); 2595 } 2596 #endif 2597 // RawUndefinedExpr is the node we use for "there is no initializer". If one 2598 // writes, literally, `x = undefined;`, it will not be a RawUndefinedExpr 2599 // node, but rather a variable reference. 2600 // Behavior for "there is no initializer" should be { ..., "init": null } 2601 if (value->getKind() != ParseNodeKind::RawUndefinedExpr) { 2602 if (!expression(value, &val)) { 2603 return false; 2604 } 2605 } else { 2606 val.setNull(); 2607 } 2608 return propertyName(&classField->name(), &key) && 2609 #ifdef ENABLE_DECORATORS 2610 decoratorsParsed && 2611 #endif 2612 builder.classField(key, val, 2613 #ifdef ENABLE_DECORATORS 2614 fieldDecoratorsArray, 2615 #endif 2616 &classField->pn_pos, dst); 2617 } 2618 2619 bool ASTSerializer::staticClassBlock(StaticClassBlock* staticClassBlock, 2620 MutableHandleValue dst) { 2621 FunctionNode* fun = staticClassBlock->function(); 2622 2623 NodeVector args(cx); 2624 NodeVector defaults(cx); 2625 2626 RootedValue body(cx), rest(cx); 2627 rest.setNull(); 2628 return functionArgsAndBody(fun->body(), args, defaults, false, false, &body, 2629 &rest) && 2630 builder.staticClassBlock(body, &staticClassBlock->pn_pos, dst); 2631 } 2632 2633 bool ASTSerializer::leftAssociate(ListNode* node, MutableHandleValue dst) { 2634 MOZ_ASSERT(!node->empty()); 2635 2636 ParseNodeKind pnk = node->getKind(); 2637 bool lor = pnk == ParseNodeKind::OrExpr; 2638 bool coalesce = pnk == ParseNodeKind::CoalesceExpr; 2639 bool logop = lor || coalesce || pnk == ParseNodeKind::AndExpr; 2640 2641 ParseNode* head = node->head(); 2642 RootedValue left(cx); 2643 if (!expression(head, &left)) { 2644 return false; 2645 } 2646 for (ParseNode* next : node->contentsFrom(head->pn_next)) { 2647 RootedValue right(cx); 2648 if (!expression(next, &right)) { 2649 return false; 2650 } 2651 2652 TokenPos subpos(node->pn_pos.begin, next->pn_pos.end); 2653 2654 if (logop) { 2655 if (!builder.logicalExpression(pnk, left, right, &subpos, &left)) { 2656 return false; 2657 } 2658 } else { 2659 BinaryOperator op = binop(node->getKind()); 2660 LOCAL_ASSERT(op > BINOP_ERR && op < BINOP_LIMIT); 2661 2662 if (!builder.binaryExpression(op, left, right, &subpos, &left)) { 2663 return false; 2664 } 2665 } 2666 } 2667 2668 dst.set(left); 2669 return true; 2670 } 2671 2672 bool ASTSerializer::rightAssociate(ListNode* node, MutableHandleValue dst) { 2673 MOZ_ASSERT(!node->empty()); 2674 2675 // First, we need to reverse the list, so that we can traverse it in the right 2676 // order. It's OK to destructively reverse the list, because there are no 2677 // other consumers. 2678 2679 ParseNode* head = node->head(); 2680 ParseNode* prev = nullptr; 2681 ParseNode* current = head; 2682 ParseNode* next; 2683 while (current != nullptr) { 2684 next = current->pn_next; 2685 current->pn_next = prev; 2686 prev = current; 2687 current = next; 2688 } 2689 2690 head = prev; 2691 2692 RootedValue right(cx); 2693 if (!expression(head, &right)) { 2694 return false; 2695 } 2696 for (ParseNode* next = head->pn_next; next; next = next->pn_next) { 2697 RootedValue left(cx); 2698 if (!expression(next, &left)) { 2699 return false; 2700 } 2701 2702 TokenPos subpos(node->pn_pos.begin, next->pn_pos.end); 2703 2704 BinaryOperator op = binop(node->getKind()); 2705 LOCAL_ASSERT(op > BINOP_ERR && op < BINOP_LIMIT); 2706 2707 if (!builder.binaryExpression(op, left, right, &subpos, &right)) { 2708 return false; 2709 } 2710 } 2711 2712 dst.set(right); 2713 return true; 2714 } 2715 2716 bool ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst) { 2717 AutoCheckRecursionLimit recursion(cx); 2718 if (!recursion.check(cx)) { 2719 return false; 2720 } 2721 2722 switch (pn->getKind()) { 2723 case ParseNodeKind::Function: { 2724 FunctionNode* funNode = &pn->as<FunctionNode>(); 2725 ASTType type = 2726 funNode->funbox()->isArrow() ? AST_ARROW_EXPR : AST_FUNC_EXPR; 2727 return function(funNode, type, dst); 2728 } 2729 2730 case ParseNodeKind::CommaExpr: { 2731 NodeVector exprs(cx); 2732 return expressions(&pn->as<ListNode>(), exprs) && 2733 builder.sequenceExpression(exprs, &pn->pn_pos, dst); 2734 } 2735 2736 case ParseNodeKind::ConditionalExpr: { 2737 ConditionalExpression* condNode = &pn->as<ConditionalExpression>(); 2738 ParseNode* testNode = condNode->kid1(); 2739 ParseNode* consNode = condNode->kid2(); 2740 ParseNode* altNode = condNode->kid3(); 2741 MOZ_ASSERT(condNode->pn_pos.encloses(testNode->pn_pos)); 2742 MOZ_ASSERT(condNode->pn_pos.encloses(consNode->pn_pos)); 2743 MOZ_ASSERT(condNode->pn_pos.encloses(altNode->pn_pos)); 2744 2745 RootedValue test(cx), cons(cx), alt(cx); 2746 2747 return expression(testNode, &test) && expression(consNode, &cons) && 2748 expression(altNode, &alt) && 2749 builder.conditionalExpression(test, cons, alt, &condNode->pn_pos, 2750 dst); 2751 } 2752 2753 case ParseNodeKind::CoalesceExpr: 2754 case ParseNodeKind::OrExpr: 2755 case ParseNodeKind::AndExpr: 2756 return leftAssociate(&pn->as<ListNode>(), dst); 2757 2758 case ParseNodeKind::PreIncrementExpr: 2759 case ParseNodeKind::PreDecrementExpr: { 2760 UnaryNode* incDec = &pn->as<UnaryNode>(); 2761 ParseNode* operand = incDec->kid(); 2762 MOZ_ASSERT(incDec->pn_pos.encloses(operand->pn_pos)); 2763 2764 bool inc = incDec->isKind(ParseNodeKind::PreIncrementExpr); 2765 RootedValue expr(cx); 2766 return expression(operand, &expr) && 2767 builder.updateExpression(expr, inc, true, &incDec->pn_pos, dst); 2768 } 2769 2770 case ParseNodeKind::PostIncrementExpr: 2771 case ParseNodeKind::PostDecrementExpr: { 2772 UnaryNode* incDec = &pn->as<UnaryNode>(); 2773 ParseNode* operand = incDec->kid(); 2774 MOZ_ASSERT(incDec->pn_pos.encloses(operand->pn_pos)); 2775 2776 bool inc = incDec->isKind(ParseNodeKind::PostIncrementExpr); 2777 RootedValue expr(cx); 2778 return expression(operand, &expr) && 2779 builder.updateExpression(expr, inc, false, &incDec->pn_pos, dst); 2780 } 2781 2782 case ParseNodeKind::AssignExpr: 2783 case ParseNodeKind::AddAssignExpr: 2784 case ParseNodeKind::SubAssignExpr: 2785 case ParseNodeKind::CoalesceAssignExpr: 2786 case ParseNodeKind::OrAssignExpr: 2787 case ParseNodeKind::AndAssignExpr: 2788 case ParseNodeKind::BitOrAssignExpr: 2789 case ParseNodeKind::BitXorAssignExpr: 2790 case ParseNodeKind::BitAndAssignExpr: 2791 case ParseNodeKind::LshAssignExpr: 2792 case ParseNodeKind::RshAssignExpr: 2793 case ParseNodeKind::UrshAssignExpr: 2794 case ParseNodeKind::MulAssignExpr: 2795 case ParseNodeKind::DivAssignExpr: 2796 case ParseNodeKind::ModAssignExpr: 2797 case ParseNodeKind::PowAssignExpr: { 2798 AssignmentNode* assignNode = &pn->as<AssignmentNode>(); 2799 ParseNode* lhsNode = assignNode->left(); 2800 ParseNode* rhsNode = assignNode->right(); 2801 MOZ_ASSERT(assignNode->pn_pos.encloses(lhsNode->pn_pos)); 2802 MOZ_ASSERT(assignNode->pn_pos.encloses(rhsNode->pn_pos)); 2803 2804 AssignmentOperator op = aop(assignNode->getKind()); 2805 LOCAL_ASSERT(op > AOP_ERR && op < AOP_LIMIT); 2806 2807 RootedValue lhs(cx), rhs(cx); 2808 return pattern(lhsNode, &lhs) && expression(rhsNode, &rhs) && 2809 builder.assignmentExpression(op, lhs, rhs, &assignNode->pn_pos, 2810 dst); 2811 } 2812 2813 case ParseNodeKind::AddExpr: 2814 case ParseNodeKind::SubExpr: 2815 case ParseNodeKind::StrictEqExpr: 2816 case ParseNodeKind::EqExpr: 2817 case ParseNodeKind::StrictNeExpr: 2818 case ParseNodeKind::NeExpr: 2819 case ParseNodeKind::LtExpr: 2820 case ParseNodeKind::LeExpr: 2821 case ParseNodeKind::GtExpr: 2822 case ParseNodeKind::GeExpr: 2823 case ParseNodeKind::LshExpr: 2824 case ParseNodeKind::RshExpr: 2825 case ParseNodeKind::UrshExpr: 2826 case ParseNodeKind::MulExpr: 2827 case ParseNodeKind::DivExpr: 2828 case ParseNodeKind::ModExpr: 2829 case ParseNodeKind::BitOrExpr: 2830 case ParseNodeKind::BitXorExpr: 2831 case ParseNodeKind::BitAndExpr: 2832 case ParseNodeKind::InExpr: 2833 case ParseNodeKind::PrivateInExpr: 2834 case ParseNodeKind::InstanceOfExpr: 2835 return leftAssociate(&pn->as<ListNode>(), dst); 2836 2837 case ParseNodeKind::PowExpr: 2838 return rightAssociate(&pn->as<ListNode>(), dst); 2839 2840 case ParseNodeKind::DeleteNameExpr: 2841 case ParseNodeKind::DeletePropExpr: 2842 case ParseNodeKind::DeleteElemExpr: 2843 case ParseNodeKind::DeleteExpr: 2844 case ParseNodeKind::TypeOfNameExpr: 2845 case ParseNodeKind::TypeOfExpr: 2846 case ParseNodeKind::VoidExpr: 2847 case ParseNodeKind::NotExpr: 2848 case ParseNodeKind::BitNotExpr: 2849 case ParseNodeKind::PosExpr: 2850 case ParseNodeKind::AwaitExpr: 2851 case ParseNodeKind::NegExpr: { 2852 UnaryNode* unaryNode = &pn->as<UnaryNode>(); 2853 ParseNode* operand = unaryNode->kid(); 2854 MOZ_ASSERT(unaryNode->pn_pos.encloses(operand->pn_pos)); 2855 2856 UnaryOperator op = unop(unaryNode->getKind()); 2857 LOCAL_ASSERT(op > UNOP_ERR && op < UNOP_LIMIT); 2858 2859 RootedValue expr(cx); 2860 return expression(operand, &expr) && 2861 builder.unaryExpression(op, expr, &unaryNode->pn_pos, dst); 2862 } 2863 2864 case ParseNodeKind::DeleteOptionalChainExpr: { 2865 RootedValue expr(cx); 2866 return expression(pn->as<UnaryNode>().kid(), &expr) && 2867 builder.deleteOptionalExpression(expr, &pn->pn_pos, dst); 2868 } 2869 2870 case ParseNodeKind::OptionalChain: { 2871 RootedValue expr(cx); 2872 return expression(pn->as<UnaryNode>().kid(), &expr) && 2873 builder.optionalExpression(expr, &pn->pn_pos, dst); 2874 } 2875 2876 case ParseNodeKind::NewExpr: 2877 case ParseNodeKind::TaggedTemplateExpr: 2878 case ParseNodeKind::CallExpr: 2879 case ParseNodeKind::OptionalCallExpr: 2880 case ParseNodeKind::SuperCallExpr: { 2881 BinaryNode* node = &pn->as<BinaryNode>(); 2882 ParseNode* calleeNode = node->left(); 2883 ListNode* argsList = &node->right()->as<ListNode>(); 2884 MOZ_ASSERT(node->pn_pos.encloses(calleeNode->pn_pos)); 2885 2886 RootedValue callee(cx); 2887 if (node->isKind(ParseNodeKind::SuperCallExpr)) { 2888 MOZ_ASSERT(calleeNode->isKind(ParseNodeKind::SuperBase)); 2889 if (!builder.super(&calleeNode->pn_pos, &callee)) { 2890 return false; 2891 } 2892 } else { 2893 if (!expression(calleeNode, &callee)) { 2894 return false; 2895 } 2896 } 2897 2898 NodeVector args(cx); 2899 if (!args.reserve(argsList->count())) { 2900 return false; 2901 } 2902 2903 for (ParseNode* argNode : argsList->contents()) { 2904 MOZ_ASSERT(node->pn_pos.encloses(argNode->pn_pos)); 2905 2906 RootedValue arg(cx); 2907 if (!expression(argNode, &arg)) { 2908 return false; 2909 } 2910 args.infallibleAppend(arg); 2911 } 2912 2913 if (node->getKind() == ParseNodeKind::TaggedTemplateExpr) { 2914 return builder.taggedTemplate(callee, args, &node->pn_pos, dst); 2915 } 2916 2917 bool isOptional = node->isKind(ParseNodeKind::OptionalCallExpr); 2918 2919 // SUPERCALL is Call(super, args) 2920 return node->isKind(ParseNodeKind::NewExpr) 2921 ? builder.newExpression(callee, args, &node->pn_pos, dst) 2922 : builder.callExpression(callee, args, &node->pn_pos, dst, 2923 isOptional); 2924 } 2925 2926 case ParseNodeKind::DotExpr: 2927 case ParseNodeKind::OptionalDotExpr: 2928 case ParseNodeKind::ArgumentsLength: { 2929 PropertyAccessBase* prop = &pn->as<PropertyAccessBase>(); 2930 MOZ_ASSERT(prop->pn_pos.encloses(prop->expression().pn_pos)); 2931 2932 bool isSuper = 2933 prop->is<PropertyAccess>() && prop->as<PropertyAccess>().isSuper(); 2934 2935 RootedValue expr(cx); 2936 RootedValue propname(cx); 2937 Rooted<JSAtom*> pnAtom( 2938 cx, parser->liftParserAtomToJSAtom(prop->key().atom())); 2939 if (!pnAtom.get()) { 2940 return false; 2941 } 2942 2943 if (isSuper) { 2944 if (!builder.super(&prop->expression().pn_pos, &expr)) { 2945 return false; 2946 } 2947 } else { 2948 if (!expression(&prop->expression(), &expr)) { 2949 return false; 2950 } 2951 } 2952 2953 bool isOptional = prop->isKind(ParseNodeKind::OptionalDotExpr); 2954 2955 return identifier(pnAtom, nullptr, &propname) && 2956 builder.memberExpression(false, expr, propname, &prop->pn_pos, dst, 2957 isOptional); 2958 } 2959 2960 case ParseNodeKind::ElemExpr: 2961 case ParseNodeKind::OptionalElemExpr: { 2962 PropertyByValueBase* elem = &pn->as<PropertyByValueBase>(); 2963 MOZ_ASSERT(elem->pn_pos.encloses(elem->expression().pn_pos)); 2964 MOZ_ASSERT(elem->pn_pos.encloses(elem->key().pn_pos)); 2965 2966 bool isSuper = 2967 elem->is<PropertyByValue>() && elem->as<PropertyByValue>().isSuper(); 2968 2969 RootedValue expr(cx), key(cx); 2970 2971 if (isSuper) { 2972 if (!builder.super(&elem->expression().pn_pos, &expr)) { 2973 return false; 2974 } 2975 } else { 2976 if (!expression(&elem->expression(), &expr)) { 2977 return false; 2978 } 2979 } 2980 2981 bool isOptional = elem->isKind(ParseNodeKind::OptionalElemExpr); 2982 2983 return expression(&elem->key(), &key) && 2984 builder.memberExpression(true, expr, key, &elem->pn_pos, dst, 2985 isOptional); 2986 } 2987 2988 case ParseNodeKind::PrivateMemberExpr: 2989 case ParseNodeKind::OptionalPrivateMemberExpr: { 2990 PrivateMemberAccessBase* privateExpr = &pn->as<PrivateMemberAccessBase>(); 2991 MOZ_ASSERT( 2992 privateExpr->pn_pos.encloses(privateExpr->expression().pn_pos)); 2993 MOZ_ASSERT( 2994 privateExpr->pn_pos.encloses(privateExpr->privateName().pn_pos)); 2995 2996 RootedValue expr(cx), key(cx); 2997 2998 if (!expression(&privateExpr->expression(), &expr)) { 2999 return false; 3000 } 3001 3002 bool isOptional = 3003 privateExpr->isKind(ParseNodeKind::OptionalPrivateMemberExpr); 3004 3005 return expression(&privateExpr->privateName(), &key) && 3006 builder.memberExpression(true, expr, key, &privateExpr->pn_pos, 3007 dst, isOptional); 3008 } 3009 3010 case ParseNodeKind::CallSiteObj: { 3011 CallSiteNode* callSiteObj = &pn->as<CallSiteNode>(); 3012 ListNode* rawNodes = callSiteObj->rawNodes(); 3013 NodeVector raw(cx); 3014 if (!raw.reserve(rawNodes->count())) { 3015 return false; 3016 } 3017 for (ParseNode* item : rawNodes->contents()) { 3018 NameNode* rawItem = &item->as<NameNode>(); 3019 MOZ_ASSERT(callSiteObj->pn_pos.encloses(rawItem->pn_pos)); 3020 3021 JSAtom* exprAtom = parser->liftParserAtomToJSAtom(rawItem->atom()); 3022 if (!exprAtom) { 3023 return false; 3024 } 3025 RootedValue expr(cx, StringValue(exprAtom)); 3026 raw.infallibleAppend(expr); 3027 } 3028 3029 NodeVector cooked(cx); 3030 if (!cooked.reserve(callSiteObj->count() - 1)) { 3031 return false; 3032 } 3033 3034 for (ParseNode* cookedItem : 3035 callSiteObj->contentsFrom(rawNodes->pn_next)) { 3036 MOZ_ASSERT(callSiteObj->pn_pos.encloses(cookedItem->pn_pos)); 3037 3038 RootedValue expr(cx); 3039 if (cookedItem->isKind(ParseNodeKind::RawUndefinedExpr)) { 3040 expr.setUndefined(); 3041 } else { 3042 MOZ_ASSERT(cookedItem->isKind(ParseNodeKind::TemplateStringExpr)); 3043 JSAtom* exprAtom = 3044 parser->liftParserAtomToJSAtom(cookedItem->as<NameNode>().atom()); 3045 if (!exprAtom) { 3046 return false; 3047 } 3048 expr.setString(exprAtom); 3049 } 3050 cooked.infallibleAppend(expr); 3051 } 3052 3053 return builder.callSiteObj(raw, cooked, &callSiteObj->pn_pos, dst); 3054 } 3055 3056 case ParseNodeKind::ArrayExpr: { 3057 ListNode* array = &pn->as<ListNode>(); 3058 NodeVector elts(cx); 3059 if (!elts.reserve(array->count())) { 3060 return false; 3061 } 3062 3063 for (ParseNode* item : array->contents()) { 3064 MOZ_ASSERT(array->pn_pos.encloses(item->pn_pos)); 3065 3066 if (item->isKind(ParseNodeKind::Elision)) { 3067 elts.infallibleAppend(NullValue()); 3068 } else { 3069 RootedValue expr(cx); 3070 if (!expression(item, &expr)) { 3071 return false; 3072 } 3073 elts.infallibleAppend(expr); 3074 } 3075 } 3076 3077 return builder.arrayExpression(elts, &array->pn_pos, dst); 3078 } 3079 3080 case ParseNodeKind::Spread: { 3081 RootedValue expr(cx); 3082 return expression(pn->as<UnaryNode>().kid(), &expr) && 3083 builder.spreadExpression(expr, &pn->pn_pos, dst); 3084 } 3085 3086 case ParseNodeKind::ComputedName: { 3087 if (pn->as<UnaryNode>().isSyntheticComputedName()) { 3088 return literal(pn->as<UnaryNode>().kid(), dst); 3089 } 3090 RootedValue name(cx); 3091 return expression(pn->as<UnaryNode>().kid(), &name) && 3092 builder.computedName(name, &pn->pn_pos, dst); 3093 } 3094 3095 case ParseNodeKind::ObjectExpr: { 3096 ListNode* obj = &pn->as<ListNode>(); 3097 NodeVector elts(cx); 3098 if (!elts.reserve(obj->count())) { 3099 return false; 3100 } 3101 3102 for (ParseNode* item : obj->contents()) { 3103 MOZ_ASSERT(obj->pn_pos.encloses(item->pn_pos)); 3104 3105 RootedValue prop(cx); 3106 if (!property(item, &prop)) { 3107 return false; 3108 } 3109 elts.infallibleAppend(prop); 3110 } 3111 3112 return builder.objectExpression(elts, &obj->pn_pos, dst); 3113 } 3114 3115 case ParseNodeKind::PrivateName: 3116 case ParseNodeKind::Name: 3117 return identifier(&pn->as<NameNode>(), dst); 3118 3119 case ParseNodeKind::ThisExpr: 3120 return builder.thisExpression(&pn->pn_pos, dst); 3121 3122 case ParseNodeKind::TemplateStringListExpr: { 3123 ListNode* list = &pn->as<ListNode>(); 3124 NodeVector elts(cx); 3125 if (!elts.reserve(list->count())) { 3126 return false; 3127 } 3128 3129 for (ParseNode* item : list->contents()) { 3130 MOZ_ASSERT(list->pn_pos.encloses(item->pn_pos)); 3131 3132 RootedValue expr(cx); 3133 if (!expression(item, &expr)) { 3134 return false; 3135 } 3136 elts.infallibleAppend(expr); 3137 } 3138 3139 return builder.templateLiteral(elts, &list->pn_pos, dst); 3140 } 3141 3142 case ParseNodeKind::TemplateStringExpr: 3143 case ParseNodeKind::StringExpr: 3144 case ParseNodeKind::RegExpExpr: 3145 case ParseNodeKind::NumberExpr: 3146 case ParseNodeKind::BigIntExpr: 3147 case ParseNodeKind::TrueExpr: 3148 case ParseNodeKind::FalseExpr: 3149 case ParseNodeKind::NullExpr: 3150 case ParseNodeKind::RawUndefinedExpr: 3151 return literal(pn, dst); 3152 3153 case ParseNodeKind::YieldStarExpr: { 3154 UnaryNode* yieldNode = &pn->as<UnaryNode>(); 3155 ParseNode* operand = yieldNode->kid(); 3156 MOZ_ASSERT(yieldNode->pn_pos.encloses(operand->pn_pos)); 3157 3158 RootedValue arg(cx); 3159 return expression(operand, &arg) && 3160 builder.yieldExpression(arg, Delegating, &yieldNode->pn_pos, dst); 3161 } 3162 3163 case ParseNodeKind::YieldExpr: { 3164 UnaryNode* yieldNode = &pn->as<UnaryNode>(); 3165 ParseNode* operand = yieldNode->kid(); 3166 MOZ_ASSERT_IF(operand, yieldNode->pn_pos.encloses(operand->pn_pos)); 3167 3168 RootedValue arg(cx); 3169 return optExpression(operand, &arg) && 3170 builder.yieldExpression(arg, NotDelegating, &yieldNode->pn_pos, 3171 dst); 3172 } 3173 3174 case ParseNodeKind::ClassDecl: 3175 return classDefinition(&pn->as<ClassNode>(), true, dst); 3176 3177 case ParseNodeKind::NewTargetExpr: { 3178 auto* node = &pn->as<NewTargetNode>(); 3179 ParseNode* firstNode = node->newHolder(); 3180 MOZ_ASSERT(firstNode->isKind(ParseNodeKind::PosHolder)); 3181 MOZ_ASSERT(node->pn_pos.encloses(firstNode->pn_pos)); 3182 3183 ParseNode* secondNode = node->targetHolder(); 3184 MOZ_ASSERT(secondNode->isKind(ParseNodeKind::PosHolder)); 3185 MOZ_ASSERT(node->pn_pos.encloses(secondNode->pn_pos)); 3186 3187 RootedValue firstIdent(cx); 3188 RootedValue secondIdent(cx); 3189 3190 Rooted<JSAtom*> firstStr(cx, cx->names().new_); 3191 Rooted<JSAtom*> secondStr(cx, cx->names().target); 3192 3193 return identifier(firstStr, &firstNode->pn_pos, &firstIdent) && 3194 identifier(secondStr, &secondNode->pn_pos, &secondIdent) && 3195 builder.metaProperty(firstIdent, secondIdent, &node->pn_pos, dst); 3196 } 3197 3198 case ParseNodeKind::ImportMetaExpr: { 3199 BinaryNode* node = &pn->as<BinaryNode>(); 3200 ParseNode* firstNode = node->left(); 3201 MOZ_ASSERT(firstNode->isKind(ParseNodeKind::PosHolder)); 3202 MOZ_ASSERT(node->pn_pos.encloses(firstNode->pn_pos)); 3203 3204 ParseNode* secondNode = node->right(); 3205 MOZ_ASSERT(secondNode->isKind(ParseNodeKind::PosHolder)); 3206 MOZ_ASSERT(node->pn_pos.encloses(secondNode->pn_pos)); 3207 3208 RootedValue firstIdent(cx); 3209 RootedValue secondIdent(cx); 3210 3211 Rooted<JSAtom*> firstStr(cx, cx->names().import); 3212 Rooted<JSAtom*> secondStr(cx, cx->names().meta); 3213 3214 return identifier(firstStr, &firstNode->pn_pos, &firstIdent) && 3215 identifier(secondStr, &secondNode->pn_pos, &secondIdent) && 3216 builder.metaProperty(firstIdent, secondIdent, &node->pn_pos, dst); 3217 } 3218 3219 case ParseNodeKind::CallImportExpr: { 3220 BinaryNode* node = &pn->as<BinaryNode>(); 3221 ParseNode* identNode = node->left(); 3222 MOZ_ASSERT(identNode->isKind(ParseNodeKind::PosHolder)); 3223 MOZ_ASSERT(identNode->pn_pos.encloses(identNode->pn_pos)); 3224 3225 ParseNode* specNode = node->right(); 3226 MOZ_ASSERT(specNode->is<BinaryNode>()); 3227 MOZ_ASSERT(specNode->isKind(ParseNodeKind::CallImportSpec)); 3228 3229 ParseNode* argNode = specNode->as<BinaryNode>().left(); 3230 MOZ_ASSERT(node->pn_pos.encloses(argNode->pn_pos)); 3231 3232 ParseNode* optionsArgNode = specNode->as<BinaryNode>().right(); 3233 MOZ_ASSERT(node->pn_pos.encloses(optionsArgNode->pn_pos)); 3234 3235 RootedValue ident(cx); 3236 Handle<PropertyName*> name = cx->names().import; 3237 if (!identifier(name, &identNode->pn_pos, &ident)) { 3238 return false; 3239 } 3240 3241 NodeVector args(cx); 3242 3243 RootedValue arg(cx); 3244 if (!expression(argNode, &arg)) { 3245 return false; 3246 } 3247 if (!args.append(arg)) { 3248 return false; 3249 } 3250 3251 if (!optionsArgNode->isKind(ParseNodeKind::PosHolder)) { 3252 RootedValue optionsArg(cx); 3253 if (!expression(optionsArgNode, &optionsArg)) { 3254 return false; 3255 } 3256 if (!args.append(optionsArg)) { 3257 return false; 3258 } 3259 } 3260 3261 return builder.callImportExpression(ident, args, &pn->pn_pos, dst); 3262 } 3263 3264 case ParseNodeKind::SetThis: { 3265 // SETTHIS is used to assign the result of a super() call to |this|. 3266 // It's not part of the original AST, so just forward to the call. 3267 BinaryNode* node = &pn->as<BinaryNode>(); 3268 MOZ_ASSERT(node->left()->isKind(ParseNodeKind::Name)); 3269 return expression(node->right(), dst); 3270 } 3271 3272 default: 3273 LOCAL_NOT_REACHED("unexpected expression type"); 3274 } 3275 } 3276 3277 bool ASTSerializer::propertyName(ParseNode* key, MutableHandleValue dst) { 3278 if (key->isKind(ParseNodeKind::ComputedName)) { 3279 return expression(key, dst); 3280 } 3281 if (key->isKind(ParseNodeKind::ObjectPropertyName) || 3282 key->isKind(ParseNodeKind::PrivateName)) { 3283 return identifier(&key->as<NameNode>(), dst); 3284 } 3285 3286 LOCAL_ASSERT(key->isKind(ParseNodeKind::StringExpr) || 3287 key->isKind(ParseNodeKind::NumberExpr) || 3288 key->isKind(ParseNodeKind::BigIntExpr)); 3289 3290 return literal(key, dst); 3291 } 3292 3293 bool ASTSerializer::property(ParseNode* pn, MutableHandleValue dst) { 3294 if (pn->isKind(ParseNodeKind::MutateProto)) { 3295 RootedValue val(cx); 3296 return expression(pn->as<UnaryNode>().kid(), &val) && 3297 builder.prototypeMutation(val, &pn->pn_pos, dst); 3298 } 3299 if (pn->isKind(ParseNodeKind::Spread)) { 3300 return expression(pn, dst); 3301 } 3302 3303 PropKind kind; 3304 if (pn->is<PropertyDefinition>()) { 3305 switch (pn->as<PropertyDefinition>().accessorType()) { 3306 case AccessorType::None: 3307 kind = PROP_INIT; 3308 break; 3309 3310 case AccessorType::Getter: 3311 kind = PROP_GETTER; 3312 break; 3313 3314 case AccessorType::Setter: 3315 kind = PROP_SETTER; 3316 break; 3317 3318 default: 3319 LOCAL_NOT_REACHED("unexpected object-literal property"); 3320 } 3321 } else { 3322 MOZ_ASSERT(pn->isKind(ParseNodeKind::Shorthand)); 3323 kind = PROP_INIT; 3324 } 3325 3326 BinaryNode* node = &pn->as<BinaryNode>(); 3327 ParseNode* keyNode = node->left(); 3328 ParseNode* valNode = node->right(); 3329 3330 bool isShorthand = node->isKind(ParseNodeKind::Shorthand); 3331 bool isMethod = 3332 valNode->is<FunctionNode>() && 3333 valNode->as<FunctionNode>().funbox()->kind() == FunctionFlags::Method; 3334 RootedValue key(cx), val(cx); 3335 return propertyName(keyNode, &key) && expression(valNode, &val) && 3336 builder.propertyInitializer(key, val, kind, isShorthand, isMethod, 3337 &node->pn_pos, dst); 3338 } 3339 3340 bool ASTSerializer::literal(ParseNode* pn, MutableHandleValue dst) { 3341 RootedValue val(cx); 3342 switch (pn->getKind()) { 3343 case ParseNodeKind::TemplateStringExpr: 3344 case ParseNodeKind::StringExpr: { 3345 JSAtom* exprAtom = 3346 parser->liftParserAtomToJSAtom(pn->as<NameNode>().atom()); 3347 if (!exprAtom) { 3348 return false; 3349 } 3350 val.setString(exprAtom); 3351 break; 3352 } 3353 3354 case ParseNodeKind::RegExpExpr: { 3355 RegExpObject* re = pn->as<RegExpLiteral>().create( 3356 cx, fc, parser->parserAtoms(), 3357 parser->getCompilationState().input.atomCache, 3358 parser->getCompilationState()); 3359 if (!re) { 3360 return false; 3361 } 3362 3363 val.setObject(*re); 3364 break; 3365 } 3366 3367 case ParseNodeKind::NumberExpr: 3368 val.setNumber(pn->as<NumericLiteral>().value()); 3369 break; 3370 3371 case ParseNodeKind::BigIntExpr: { 3372 auto index = pn->as<BigIntLiteral>().index(); 3373 BigInt* x = parser->compilationState_.bigIntData[index].createBigInt(cx); 3374 if (!x) { 3375 return false; 3376 } 3377 cx->check(x); 3378 val.setBigInt(x); 3379 break; 3380 } 3381 3382 case ParseNodeKind::NullExpr: 3383 val.setNull(); 3384 break; 3385 3386 case ParseNodeKind::RawUndefinedExpr: 3387 val.setUndefined(); 3388 break; 3389 3390 case ParseNodeKind::TrueExpr: 3391 val.setBoolean(true); 3392 break; 3393 3394 case ParseNodeKind::FalseExpr: 3395 val.setBoolean(false); 3396 break; 3397 3398 default: 3399 LOCAL_NOT_REACHED("unexpected literal type"); 3400 } 3401 3402 return builder.literal(val, &pn->pn_pos, dst); 3403 } 3404 3405 bool ASTSerializer::arrayPattern(ListNode* array, MutableHandleValue dst) { 3406 MOZ_ASSERT(array->isKind(ParseNodeKind::ArrayExpr)); 3407 3408 NodeVector elts(cx); 3409 if (!elts.reserve(array->count())) { 3410 return false; 3411 } 3412 3413 for (ParseNode* item : array->contents()) { 3414 if (item->isKind(ParseNodeKind::Elision)) { 3415 elts.infallibleAppend(NullValue()); 3416 } else if (item->isKind(ParseNodeKind::Spread)) { 3417 RootedValue target(cx); 3418 RootedValue spread(cx); 3419 if (!pattern(item->as<UnaryNode>().kid(), &target)) { 3420 return false; 3421 } 3422 if (!builder.spreadExpression(target, &item->pn_pos, &spread)) 3423 return false; 3424 elts.infallibleAppend(spread); 3425 } else { 3426 RootedValue patt(cx); 3427 if (!pattern(item, &patt)) { 3428 return false; 3429 } 3430 elts.infallibleAppend(patt); 3431 } 3432 } 3433 3434 return builder.arrayPattern(elts, &array->pn_pos, dst); 3435 } 3436 3437 bool ASTSerializer::objectPattern(ListNode* obj, MutableHandleValue dst) { 3438 MOZ_ASSERT(obj->isKind(ParseNodeKind::ObjectExpr)); 3439 3440 NodeVector elts(cx); 3441 if (!elts.reserve(obj->count())) { 3442 return false; 3443 } 3444 3445 for (ParseNode* propdef : obj->contents()) { 3446 if (propdef->isKind(ParseNodeKind::Spread)) { 3447 RootedValue target(cx); 3448 RootedValue spread(cx); 3449 if (!pattern(propdef->as<UnaryNode>().kid(), &target)) { 3450 return false; 3451 } 3452 if (!builder.spreadExpression(target, &propdef->pn_pos, &spread)) 3453 return false; 3454 elts.infallibleAppend(spread); 3455 continue; 3456 } 3457 // Patterns can't have getters/setters. 3458 LOCAL_ASSERT(!propdef->is<PropertyDefinition>() || 3459 propdef->as<PropertyDefinition>().accessorType() == 3460 AccessorType::None); 3461 3462 RootedValue key(cx); 3463 ParseNode* target; 3464 if (propdef->isKind(ParseNodeKind::MutateProto)) { 3465 RootedValue pname(cx, StringValue(cx->names().proto_)); 3466 if (!builder.literal(pname, &propdef->pn_pos, &key)) { 3467 return false; 3468 } 3469 target = propdef->as<UnaryNode>().kid(); 3470 } else { 3471 BinaryNode* prop = &propdef->as<BinaryNode>(); 3472 if (!propertyName(prop->left(), &key)) { 3473 return false; 3474 } 3475 target = prop->right(); 3476 } 3477 3478 RootedValue patt(cx), prop(cx); 3479 if (!pattern(target, &patt) || 3480 !builder.propertyPattern(key, patt, 3481 propdef->isKind(ParseNodeKind::Shorthand), 3482 &propdef->pn_pos, &prop)) { 3483 return false; 3484 } 3485 3486 elts.infallibleAppend(prop); 3487 } 3488 3489 return builder.objectPattern(elts, &obj->pn_pos, dst); 3490 } 3491 3492 bool ASTSerializer::pattern(ParseNode* pn, MutableHandleValue dst) { 3493 AutoCheckRecursionLimit recursion(cx); 3494 if (!recursion.check(cx)) { 3495 return false; 3496 } 3497 3498 switch (pn->getKind()) { 3499 case ParseNodeKind::ObjectExpr: 3500 return objectPattern(&pn->as<ListNode>(), dst); 3501 3502 case ParseNodeKind::ArrayExpr: 3503 return arrayPattern(&pn->as<ListNode>(), dst); 3504 3505 default: 3506 return expression(pn, dst); 3507 } 3508 } 3509 3510 bool ASTSerializer::identifier(Handle<JSAtom*> atom, TokenPos* pos, 3511 MutableHandleValue dst) { 3512 RootedValue atomContentsVal(cx, unrootedAtomContents(atom)); 3513 return builder.identifier(atomContentsVal, pos, dst); 3514 } 3515 3516 bool ASTSerializer::identifier(NameNode* id, MutableHandleValue dst) { 3517 LOCAL_ASSERT(id->atom()); 3518 3519 Rooted<JSAtom*> pnAtom(cx, parser->liftParserAtomToJSAtom(id->atom())); 3520 if (!pnAtom.get()) { 3521 return false; 3522 } 3523 return identifier(pnAtom, &id->pn_pos, dst); 3524 } 3525 3526 bool ASTSerializer::identifierOrLiteral(ParseNode* id, MutableHandleValue dst) { 3527 if (id->getKind() == ParseNodeKind::Name) { 3528 return identifier(&id->as<NameNode>(), dst); 3529 } 3530 return literal(id, dst); 3531 } 3532 3533 bool ASTSerializer::function(FunctionNode* funNode, ASTType type, 3534 MutableHandleValue dst) { 3535 FunctionBox* funbox = funNode->funbox(); 3536 3537 GeneratorStyle generatorStyle = 3538 funbox->isGenerator() ? GeneratorStyle::ES6 : GeneratorStyle::None; 3539 3540 bool isAsync = funbox->isAsync(); 3541 bool isExpression = funbox->hasExprBody(); 3542 3543 RootedValue id(cx); 3544 Rooted<JSAtom*> funcAtom(cx); 3545 if (funbox->explicitName()) { 3546 funcAtom.set(parser->liftParserAtomToJSAtom(funbox->explicitName())); 3547 if (!funcAtom) { 3548 return false; 3549 } 3550 } 3551 if (!optIdentifier(funcAtom, nullptr, &id)) { 3552 return false; 3553 } 3554 3555 NodeVector args(cx); 3556 NodeVector defaults(cx); 3557 3558 RootedValue body(cx), rest(cx); 3559 if (funbox->hasRest()) { 3560 rest.setUndefined(); 3561 } else { 3562 rest.setNull(); 3563 } 3564 return functionArgsAndBody(funNode->body(), args, defaults, isAsync, 3565 isExpression, &body, &rest) && 3566 builder.function(type, &funNode->pn_pos, id, args, defaults, body, 3567 rest, generatorStyle, isAsync, isExpression, dst); 3568 } 3569 3570 bool ASTSerializer::functionArgsAndBody(ParamsBodyNode* pn, NodeVector& args, 3571 NodeVector& defaults, bool isAsync, 3572 bool isExpression, 3573 MutableHandleValue body, 3574 MutableHandleValue rest) { 3575 // Serialize the arguments. 3576 if (!functionArgs(pn, args, defaults, rest)) { 3577 return false; 3578 } 3579 3580 // Skip the enclosing lexical scope. 3581 ParseNode* bodyNode = pn->body()->scopeBody(); 3582 3583 // Serialize the body. 3584 switch (bodyNode->getKind()) { 3585 // Arrow function with expression body. 3586 case ParseNodeKind::ReturnStmt: 3587 MOZ_ASSERT(isExpression); 3588 return expression(bodyNode->as<UnaryNode>().kid(), body); 3589 3590 // Function with statement body. 3591 case ParseNodeKind::StatementList: { 3592 ParseNode* firstNode = bodyNode->as<ListNode>().head(); 3593 3594 // Skip over initial yield in generator. 3595 if (firstNode && firstNode->isKind(ParseNodeKind::InitialYield)) { 3596 firstNode = firstNode->pn_next; 3597 } 3598 3599 // Async arrow with expression body is converted into STATEMENTLIST 3600 // to insert initial yield. 3601 if (isAsync && isExpression) { 3602 MOZ_ASSERT(firstNode->getKind() == ParseNodeKind::ReturnStmt); 3603 return expression(firstNode->as<UnaryNode>().kid(), body); 3604 } 3605 3606 return functionBody(firstNode, &bodyNode->pn_pos, body); 3607 } 3608 3609 default: 3610 LOCAL_NOT_REACHED("unexpected function contents"); 3611 } 3612 } 3613 3614 bool ASTSerializer::functionArgs(ParamsBodyNode* pn, NodeVector& args, 3615 NodeVector& defaults, 3616 MutableHandleValue rest) { 3617 RootedValue node(cx); 3618 bool defaultsNull = true; 3619 MOZ_ASSERT(defaults.empty(), 3620 "must be initially empty for it to be proper to clear this " 3621 "when there are no defaults"); 3622 3623 MOZ_ASSERT(rest.isNullOrUndefined(), 3624 "rest is set to |undefined| when a rest argument is present, " 3625 "otherwise rest is set to |null|"); 3626 3627 for (ParseNode* arg : pn->parameters()) { 3628 ParseNode* pat; 3629 ParseNode* defNode; 3630 if (arg->isKind(ParseNodeKind::Name) || 3631 arg->isKind(ParseNodeKind::ArrayExpr) || 3632 arg->isKind(ParseNodeKind::ObjectExpr)) { 3633 pat = arg; 3634 defNode = nullptr; 3635 } else { 3636 MOZ_ASSERT(arg->isKind(ParseNodeKind::AssignExpr)); 3637 AssignmentNode* assignNode = &arg->as<AssignmentNode>(); 3638 pat = assignNode->left(); 3639 defNode = assignNode->right(); 3640 } 3641 3642 // Process the name or pattern. 3643 MOZ_ASSERT(pat->isKind(ParseNodeKind::Name) || 3644 pat->isKind(ParseNodeKind::ArrayExpr) || 3645 pat->isKind(ParseNodeKind::ObjectExpr)); 3646 if (!pattern(pat, &node)) { 3647 return false; 3648 } 3649 if (rest.isUndefined() && arg->pn_next == *std::end(pn->parameters())) { 3650 rest.setObject(node.toObject()); 3651 } else { 3652 if (!args.append(node)) { 3653 return false; 3654 } 3655 } 3656 3657 // Process its default (or lack thereof). 3658 if (defNode) { 3659 defaultsNull = false; 3660 RootedValue def(cx); 3661 if (!expression(defNode, &def) || !defaults.append(def)) { 3662 return false; 3663 } 3664 } else { 3665 if (!defaults.append(NullValue())) { 3666 return false; 3667 } 3668 } 3669 } 3670 MOZ_ASSERT(!rest.isUndefined(), 3671 "if a rest argument was present (signified by " 3672 "|rest.isUndefined()| initially), the rest node was properly " 3673 "recorded"); 3674 3675 if (defaultsNull) { 3676 defaults.clear(); 3677 } 3678 3679 return true; 3680 } 3681 3682 bool ASTSerializer::functionBody(ParseNode* pn, TokenPos* pos, 3683 MutableHandleValue dst) { 3684 NodeVector elts(cx); 3685 3686 // We aren't sure how many elements there are up front, so we'll check each 3687 // append. 3688 for (ParseNode* next = pn; next; next = next->pn_next) { 3689 RootedValue child(cx); 3690 if (!sourceElement(next, &child) || !elts.append(child)) { 3691 return false; 3692 } 3693 } 3694 3695 return builder.blockStatement(elts, pos, dst); 3696 } 3697 3698 static bool reflect_parse(JSContext* cx, uint32_t argc, Value* vp) { 3699 CallArgs args = CallArgsFromVp(argc, vp); 3700 3701 if (!args.requireAtLeast(cx, "Reflect.parse", 1)) { 3702 return false; 3703 } 3704 3705 RootedString src(cx, ToString<CanGC>(cx, args[0])); 3706 if (!src) { 3707 return false; 3708 } 3709 3710 UniqueChars filename; 3711 uint32_t lineno = 1; 3712 bool loc = true; 3713 ParseGoal target = ParseGoal::Script; 3714 3715 RootedValue arg(cx, args.get(1)); 3716 3717 if (!arg.isNullOrUndefined()) { 3718 if (!arg.isObject()) { 3719 ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, arg, 3720 nullptr, "not an object"); 3721 return false; 3722 } 3723 3724 RootedObject config(cx, &arg.toObject()); 3725 3726 RootedValue prop(cx); 3727 3728 /* config.loc */ 3729 RootedId locId(cx, NameToId(cx->names().loc)); 3730 RootedValue trueVal(cx, BooleanValue(true)); 3731 if (!GetPropertyDefault(cx, config, locId, trueVal, &prop)) { 3732 return false; 3733 } 3734 3735 loc = ToBoolean(prop); 3736 3737 if (loc) { 3738 /* config.source */ 3739 RootedId sourceId(cx, NameToId(cx->names().source)); 3740 RootedValue nullVal(cx, NullValue()); 3741 if (!GetPropertyDefault(cx, config, sourceId, nullVal, &prop)) { 3742 return false; 3743 } 3744 3745 if (!prop.isNullOrUndefined()) { 3746 RootedString str(cx, ToString<CanGC>(cx, prop)); 3747 if (!str) { 3748 return false; 3749 } 3750 3751 filename = StringToNewUTF8CharsZ(cx, *str); 3752 if (!filename) { 3753 return false; 3754 } 3755 } 3756 3757 /* config.line */ 3758 RootedId lineId(cx, NameToId(cx->names().line)); 3759 RootedValue oneValue(cx, Int32Value(1)); 3760 if (!GetPropertyDefault(cx, config, lineId, oneValue, &prop) || 3761 !ToUint32(cx, prop, &lineno)) { 3762 return false; 3763 } 3764 } 3765 3766 /* config.target */ 3767 RootedId targetId(cx, NameToId(cx->names().target)); 3768 RootedValue scriptVal(cx, StringValue(cx->names().script)); 3769 if (!GetPropertyDefault(cx, config, targetId, scriptVal, &prop)) { 3770 return false; 3771 } 3772 3773 if (!prop.isString()) { 3774 ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, prop, 3775 nullptr, "not 'script' or 'module'"); 3776 return false; 3777 } 3778 3779 RootedString stringProp(cx, prop.toString()); 3780 bool isScript = false; 3781 bool isModule = false; 3782 if (!EqualStrings(cx, stringProp, cx->names().script, &isScript)) { 3783 return false; 3784 } 3785 3786 if (!EqualStrings(cx, stringProp, cx->names().module, &isModule)) { 3787 return false; 3788 } 3789 3790 if (isScript) { 3791 target = ParseGoal::Script; 3792 } else if (isModule) { 3793 target = ParseGoal::Module; 3794 } else { 3795 JS_ReportErrorASCII(cx, 3796 "Bad target value, expected 'script' or 'module'"); 3797 return false; 3798 } 3799 } 3800 3801 AutoReportFrontendContext fc(cx); 3802 ASTSerializer serialize(cx, &fc, loc, filename.get(), lineno); 3803 if (!serialize.init()) { 3804 return false; 3805 } 3806 3807 JSLinearString* linear = src->ensureLinear(cx); 3808 if (!linear) { 3809 return false; 3810 } 3811 3812 AutoStableStringChars linearChars(cx); 3813 if (!linearChars.initTwoByte(cx, linear)) { 3814 return false; 3815 } 3816 3817 CompileOptions options(cx); 3818 options.setFileAndLine(filename.get(), lineno); 3819 options.setForceFullParse(); 3820 options.allowHTMLComments = target == ParseGoal::Script; 3821 mozilla::Range<const char16_t> chars = linearChars.twoByteRange(); 3822 3823 Rooted<CompilationInput> input(cx, CompilationInput(options)); 3824 if (target == ParseGoal::Script) { 3825 if (!input.get().initForGlobal(&fc)) { 3826 return false; 3827 } 3828 } else { 3829 if (!input.get().initForModule(&fc)) { 3830 return false; 3831 } 3832 } 3833 3834 LifoAllocScope allocScope(&cx->tempLifoAlloc()); 3835 frontend::NoScopeBindingCache scopeCache; 3836 frontend::CompilationState compilationState(&fc, allocScope, input.get()); 3837 if (!compilationState.init(&fc, &scopeCache)) { 3838 return false; 3839 } 3840 3841 Parser<FullParseHandler, char16_t> parser(&fc, options, chars.begin().get(), 3842 chars.length(), compilationState, 3843 /* syntaxParser = */ nullptr); 3844 if (!parser.checkOptions()) { 3845 return false; 3846 } 3847 3848 serialize.setParser(&parser); 3849 3850 ParseNode* pn; 3851 if (target == ParseGoal::Script) { 3852 pn = parser.parse().unwrapOr(nullptr); 3853 if (!pn) { 3854 return false; 3855 } 3856 } else { 3857 ModuleBuilder builder(&fc, &parser); 3858 3859 uint32_t len = chars.length(); 3860 SourceExtent extent = SourceExtent::makeGlobalExtent( 3861 len, options.lineno, 3862 JS::LimitedColumnNumberOneOrigin::fromUnlimited( 3863 JS::ColumnNumberOneOrigin(options.column))); 3864 ModuleSharedContext modulesc(&fc, options, builder, extent); 3865 pn = parser.moduleBody(&modulesc).unwrapOr(nullptr); 3866 if (!pn) { 3867 return false; 3868 } 3869 3870 pn = pn->as<ModuleNode>().body(); 3871 } 3872 3873 RootedValue val(cx); 3874 if (!serialize.program(&pn->as<ListNode>(), &val)) { 3875 args.rval().setNull(); 3876 return false; 3877 } 3878 3879 args.rval().set(val); 3880 return true; 3881 } 3882 3883 JS_PUBLIC_API bool JS_InitReflectParse(JSContext* cx, HandleObject global) { 3884 RootedValue reflectVal(cx); 3885 if (!GetProperty(cx, global, global, cx->names().Reflect, &reflectVal)) { 3886 return false; 3887 } 3888 if (!reflectVal.isObject()) { 3889 JS_ReportErrorASCII( 3890 cx, "JS_InitReflectParse must be called during global initialization"); 3891 return false; 3892 } 3893 3894 RootedObject reflectObj(cx, &reflectVal.toObject()); 3895 return JS_DefineFunction(cx, reflectObj, "parse", reflect_parse, 1, 0); 3896 }