AST.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047
  1. /*
  2. * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  19. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  21. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  22. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  23. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  24. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include <AK/Function.h>
  27. #include <AK/HashMap.h>
  28. #include <AK/StringBuilder.h>
  29. #include <LibJS/AST.h>
  30. #include <LibJS/Interpreter.h>
  31. #include <LibJS/Runtime/Array.h>
  32. #include <LibJS/Runtime/Error.h>
  33. #include <LibJS/Runtime/NativeFunction.h>
  34. #include <LibJS/Runtime/PrimitiveString.h>
  35. #include <LibJS/Runtime/ScriptFunction.h>
  36. #include <LibJS/Runtime/Value.h>
  37. #include <stdio.h>
  38. namespace JS {
  39. Value ScopeNode::execute(Interpreter& interpreter) const
  40. {
  41. return interpreter.run(*this);
  42. }
  43. Value FunctionDeclaration::execute(Interpreter& interpreter) const
  44. {
  45. auto* function = interpreter.heap().allocate<ScriptFunction>(body(), parameters());
  46. interpreter.set_variable(name(), function);
  47. return {};
  48. }
  49. Value FunctionExpression::execute(Interpreter& interpreter) const
  50. {
  51. return interpreter.heap().allocate<ScriptFunction>(body(), parameters());
  52. }
  53. Value ExpressionStatement::execute(Interpreter& interpreter) const
  54. {
  55. return m_expression->execute(interpreter);
  56. }
  57. CallExpression::ThisAndCallee CallExpression::compute_this_and_callee(Interpreter& interpreter) const
  58. {
  59. if (is_new_expression()) {
  60. // Computing |this| is irrelevant for "new" expression.
  61. return { {}, m_callee->execute(interpreter) };
  62. }
  63. if (m_callee->is_member_expression()) {
  64. auto& member_expression = static_cast<const MemberExpression&>(*m_callee);
  65. auto object_value = member_expression.object().execute(interpreter);
  66. if (interpreter.exception())
  67. return {};
  68. auto* this_value = object_value.to_object(interpreter.heap());
  69. if (interpreter.exception())
  70. return {};
  71. auto callee = this_value->get(member_expression.computed_property_name(interpreter)).value_or({});
  72. return { this_value, callee };
  73. }
  74. return { &interpreter.global_object(), m_callee->execute(interpreter) };
  75. }
  76. Value CallExpression::execute(Interpreter& interpreter) const
  77. {
  78. auto [this_value, callee] = compute_this_and_callee(interpreter);
  79. if (interpreter.exception())
  80. return {};
  81. if (is_new_expression()) {
  82. if (!callee.is_object()
  83. || !callee.as_object().is_function()
  84. || (callee.as_object().is_native_function()
  85. && !static_cast<NativeFunction&>(callee.as_object()).has_constructor()))
  86. return interpreter.throw_exception<Error>("TypeError", String::format("%s is not a constructor", callee.to_string().characters()));
  87. }
  88. if (!callee.is_object() || !callee.as_object().is_function())
  89. return interpreter.throw_exception<Error>("TypeError", String::format("%s is not a function", callee.to_string().characters()));
  90. auto& function = static_cast<Function&>(callee.as_object());
  91. Vector<Value> arguments;
  92. arguments.ensure_capacity(m_arguments.size());
  93. for (size_t i = 0; i < m_arguments.size(); ++i) {
  94. auto value = m_arguments[i].execute(interpreter);
  95. if (interpreter.exception())
  96. return {};
  97. arguments.append(value);
  98. if (interpreter.exception())
  99. return {};
  100. }
  101. auto& call_frame = interpreter.push_call_frame();
  102. call_frame.arguments = move(arguments);
  103. Object* new_object = nullptr;
  104. Value result;
  105. if (is_new_expression()) {
  106. new_object = interpreter.heap().allocate<Object>();
  107. auto prototype = function.get("prototype");
  108. if (prototype.has_value() && prototype.value().is_object())
  109. new_object->set_prototype(&prototype.value().as_object());
  110. call_frame.this_value = new_object;
  111. result = function.construct(interpreter);
  112. } else {
  113. call_frame.this_value = this_value;
  114. result = function.call(interpreter);
  115. }
  116. interpreter.pop_call_frame();
  117. if (is_new_expression()) {
  118. if (result.is_object())
  119. return result;
  120. return new_object;
  121. }
  122. return result;
  123. }
  124. Value ReturnStatement::execute(Interpreter& interpreter) const
  125. {
  126. auto value = argument() ? argument()->execute(interpreter) : js_undefined();
  127. if (interpreter.exception())
  128. return {};
  129. interpreter.unwind(ScopeType::Function);
  130. return value;
  131. }
  132. Value IfStatement::execute(Interpreter& interpreter) const
  133. {
  134. auto predicate_result = m_predicate->execute(interpreter);
  135. if (interpreter.exception())
  136. return {};
  137. if (predicate_result.to_boolean())
  138. return interpreter.run(*m_consequent);
  139. if (m_alternate)
  140. return interpreter.run(*m_alternate);
  141. return {};
  142. }
  143. Value WhileStatement::execute(Interpreter& interpreter) const
  144. {
  145. Value last_value = js_undefined();
  146. while (m_test->execute(interpreter).to_boolean()) {
  147. if (interpreter.exception())
  148. return {};
  149. last_value = interpreter.run(*m_body);
  150. if (interpreter.exception())
  151. return {};
  152. }
  153. return last_value;
  154. }
  155. Value DoWhileStatement::execute(Interpreter& interpreter) const
  156. {
  157. Value last_value = js_undefined();
  158. do {
  159. if (interpreter.exception())
  160. return {};
  161. last_value = interpreter.run(*m_body);
  162. if (interpreter.exception())
  163. return {};
  164. } while (m_test->execute(interpreter).to_boolean());
  165. return last_value;
  166. }
  167. Value ForStatement::execute(Interpreter& interpreter) const
  168. {
  169. RefPtr<BlockStatement> wrapper;
  170. if (m_init && m_init->is_variable_declaration() && static_cast<const VariableDeclaration*>(m_init.ptr())->declaration_type() != DeclarationType::Var) {
  171. wrapper = create_ast_node<BlockStatement>();
  172. interpreter.enter_scope(*wrapper, {}, ScopeType::Block);
  173. }
  174. Value last_value = js_undefined();
  175. if (m_init) {
  176. m_init->execute(interpreter);
  177. if (interpreter.exception())
  178. return {};
  179. }
  180. if (m_test) {
  181. while (m_test->execute(interpreter).to_boolean()) {
  182. if (interpreter.exception())
  183. return {};
  184. last_value = interpreter.run(*m_body);
  185. if (interpreter.exception())
  186. return {};
  187. if (m_update) {
  188. m_update->execute(interpreter);
  189. if (interpreter.exception())
  190. return {};
  191. }
  192. }
  193. } else {
  194. while (true) {
  195. last_value = interpreter.run(*m_body);
  196. if (interpreter.exception())
  197. return {};
  198. if (m_update) {
  199. m_update->execute(interpreter);
  200. if (interpreter.exception())
  201. return {};
  202. }
  203. }
  204. }
  205. if (wrapper)
  206. interpreter.exit_scope(*wrapper);
  207. return last_value;
  208. }
  209. Value BinaryExpression::execute(Interpreter& interpreter) const
  210. {
  211. auto lhs_result = m_lhs->execute(interpreter);
  212. if (interpreter.exception())
  213. return {};
  214. auto rhs_result = m_rhs->execute(interpreter);
  215. if (interpreter.exception())
  216. return {};
  217. switch (m_op) {
  218. case BinaryOp::Plus:
  219. return add(lhs_result, rhs_result);
  220. case BinaryOp::Minus:
  221. return sub(lhs_result, rhs_result);
  222. case BinaryOp::Asterisk:
  223. return mul(lhs_result, rhs_result);
  224. case BinaryOp::Slash:
  225. return div(lhs_result, rhs_result);
  226. case BinaryOp::Modulo:
  227. return mod(lhs_result, rhs_result);
  228. case BinaryOp::TypedEquals:
  229. return typed_eq(lhs_result, rhs_result);
  230. case BinaryOp::TypedInequals:
  231. return Value(!typed_eq(lhs_result, rhs_result).as_bool());
  232. case BinaryOp::AbstractEquals:
  233. return eq(lhs_result, rhs_result);
  234. case BinaryOp::AbstractInequals:
  235. return Value(!eq(lhs_result, rhs_result).as_bool());
  236. case BinaryOp::GreaterThan:
  237. return greater_than(lhs_result, rhs_result);
  238. case BinaryOp::GreaterThanEquals:
  239. return greater_than_equals(lhs_result, rhs_result);
  240. case BinaryOp::LessThan:
  241. return less_than(lhs_result, rhs_result);
  242. case BinaryOp::LessThanEquals:
  243. return less_than_equals(lhs_result, rhs_result);
  244. case BinaryOp::BitwiseAnd:
  245. return bitwise_and(lhs_result, rhs_result);
  246. case BinaryOp::BitwiseOr:
  247. return bitwise_or(lhs_result, rhs_result);
  248. case BinaryOp::BitwiseXor:
  249. return bitwise_xor(lhs_result, rhs_result);
  250. case BinaryOp::LeftShift:
  251. return left_shift(lhs_result, rhs_result);
  252. case BinaryOp::RightShift:
  253. return right_shift(lhs_result, rhs_result);
  254. case BinaryOp::InstanceOf:
  255. return instance_of(lhs_result, rhs_result);
  256. }
  257. ASSERT_NOT_REACHED();
  258. }
  259. Value LogicalExpression::execute(Interpreter& interpreter) const
  260. {
  261. auto lhs_result = m_lhs->execute(interpreter);
  262. if (interpreter.exception())
  263. return {};
  264. switch (m_op) {
  265. case LogicalOp::And:
  266. if (lhs_result.to_boolean()) {
  267. auto rhs_result = m_rhs->execute(interpreter);
  268. if (interpreter.exception())
  269. return {};
  270. return Value(rhs_result);
  271. }
  272. return Value(lhs_result);
  273. case LogicalOp::Or:
  274. if (lhs_result.to_boolean())
  275. return Value(lhs_result);
  276. auto rhs_result = m_rhs->execute(interpreter);
  277. if (interpreter.exception())
  278. return {};
  279. return Value(rhs_result);
  280. }
  281. ASSERT_NOT_REACHED();
  282. }
  283. Value UnaryExpression::execute(Interpreter& interpreter) const
  284. {
  285. auto lhs_result = m_lhs->execute(interpreter);
  286. switch (m_op) {
  287. case UnaryOp::BitwiseNot:
  288. return bitwise_not(lhs_result);
  289. case UnaryOp::Not:
  290. return Value(!lhs_result.to_boolean());
  291. case UnaryOp::Plus:
  292. return unary_plus(lhs_result);
  293. case UnaryOp::Minus:
  294. return unary_minus(lhs_result);
  295. case UnaryOp::Typeof:
  296. switch (lhs_result.type()) {
  297. case Value::Type::Undefined:
  298. return js_string(interpreter, "undefined");
  299. case Value::Type::Null:
  300. // yes, this is on purpose. yes, this is how javascript works.
  301. // yes, it's silly.
  302. return js_string(interpreter, "object");
  303. case Value::Type::Number:
  304. return js_string(interpreter, "number");
  305. case Value::Type::String:
  306. return js_string(interpreter, "string");
  307. case Value::Type::Object:
  308. if (lhs_result.as_object().is_function())
  309. return js_string(interpreter, "function");
  310. return js_string(interpreter, "object");
  311. case Value::Type::Boolean:
  312. return js_string(interpreter, "boolean");
  313. }
  314. }
  315. ASSERT_NOT_REACHED();
  316. }
  317. static void print_indent(int indent)
  318. {
  319. for (int i = 0; i < indent * 2; ++i)
  320. putchar(' ');
  321. }
  322. void ASTNode::dump(int indent) const
  323. {
  324. print_indent(indent);
  325. printf("%s\n", class_name());
  326. }
  327. void ScopeNode::dump(int indent) const
  328. {
  329. ASTNode::dump(indent);
  330. for (auto& child : children())
  331. child.dump(indent + 1);
  332. }
  333. void BinaryExpression::dump(int indent) const
  334. {
  335. const char* op_string = nullptr;
  336. switch (m_op) {
  337. case BinaryOp::Plus:
  338. op_string = "+";
  339. break;
  340. case BinaryOp::Minus:
  341. op_string = "-";
  342. break;
  343. case BinaryOp::Asterisk:
  344. op_string = "*";
  345. break;
  346. case BinaryOp::Slash:
  347. op_string = "/";
  348. break;
  349. case BinaryOp::Modulo:
  350. op_string = "%";
  351. break;
  352. case BinaryOp::TypedEquals:
  353. op_string = "===";
  354. break;
  355. case BinaryOp::TypedInequals:
  356. op_string = "!==";
  357. break;
  358. case BinaryOp::AbstractEquals:
  359. op_string = "==";
  360. break;
  361. case BinaryOp::AbstractInequals:
  362. op_string = "!=";
  363. break;
  364. case BinaryOp::GreaterThan:
  365. op_string = ">";
  366. break;
  367. case BinaryOp::GreaterThanEquals:
  368. op_string = ">=";
  369. break;
  370. case BinaryOp::LessThan:
  371. op_string = "<";
  372. break;
  373. case BinaryOp::LessThanEquals:
  374. op_string = "<=";
  375. break;
  376. case BinaryOp::BitwiseAnd:
  377. op_string = "&";
  378. break;
  379. case BinaryOp::BitwiseOr:
  380. op_string = "|";
  381. break;
  382. case BinaryOp::BitwiseXor:
  383. op_string = "^";
  384. break;
  385. case BinaryOp::LeftShift:
  386. op_string = "<<";
  387. break;
  388. case BinaryOp::RightShift:
  389. op_string = ">>";
  390. break;
  391. case BinaryOp::InstanceOf:
  392. op_string = "instanceof";
  393. break;
  394. }
  395. print_indent(indent);
  396. printf("%s\n", class_name());
  397. m_lhs->dump(indent + 1);
  398. print_indent(indent + 1);
  399. printf("%s\n", op_string);
  400. m_rhs->dump(indent + 1);
  401. }
  402. void LogicalExpression::dump(int indent) const
  403. {
  404. const char* op_string = nullptr;
  405. switch (m_op) {
  406. case LogicalOp::And:
  407. op_string = "&&";
  408. break;
  409. case LogicalOp::Or:
  410. op_string = "||";
  411. break;
  412. }
  413. print_indent(indent);
  414. printf("%s\n", class_name());
  415. m_lhs->dump(indent + 1);
  416. print_indent(indent + 1);
  417. printf("%s\n", op_string);
  418. m_rhs->dump(indent + 1);
  419. }
  420. void UnaryExpression::dump(int indent) const
  421. {
  422. const char* op_string = nullptr;
  423. switch (m_op) {
  424. case UnaryOp::BitwiseNot:
  425. op_string = "~";
  426. break;
  427. case UnaryOp::Not:
  428. op_string = "!";
  429. break;
  430. case UnaryOp::Plus:
  431. op_string = "+";
  432. break;
  433. case UnaryOp::Minus:
  434. op_string = "-";
  435. break;
  436. case UnaryOp::Typeof:
  437. op_string = "typeof ";
  438. break;
  439. }
  440. print_indent(indent);
  441. printf("%s\n", class_name());
  442. print_indent(indent + 1);
  443. printf("%s\n", op_string);
  444. m_lhs->dump(indent + 1);
  445. }
  446. void CallExpression::dump(int indent) const
  447. {
  448. ASTNode::dump(indent);
  449. m_callee->dump(indent + 1);
  450. for (auto& argument : m_arguments)
  451. argument.dump(indent + 1);
  452. }
  453. void StringLiteral::dump(int indent) const
  454. {
  455. print_indent(indent);
  456. printf("StringLiteral \"%s\"\n", m_value.characters());
  457. }
  458. void NumericLiteral::dump(int indent) const
  459. {
  460. print_indent(indent);
  461. printf("NumericLiteral %g\n", m_value);
  462. }
  463. void BooleanLiteral::dump(int indent) const
  464. {
  465. print_indent(indent);
  466. printf("BooleanLiteral %s\n", m_value ? "true" : "false");
  467. }
  468. void NullLiteral::dump(int indent) const
  469. {
  470. print_indent(indent);
  471. printf("null\n");
  472. }
  473. void FunctionNode::dump(int indent, const char* class_name) const
  474. {
  475. StringBuilder parameters_builder;
  476. parameters_builder.join(',', parameters());
  477. print_indent(indent);
  478. printf("%s '%s(%s)'\n", class_name, name().characters(), parameters_builder.build().characters());
  479. body().dump(indent + 1);
  480. }
  481. void FunctionDeclaration::dump(int indent) const
  482. {
  483. FunctionNode::dump(indent, class_name());
  484. }
  485. void FunctionExpression::dump(int indent) const
  486. {
  487. FunctionNode::dump(indent, class_name());
  488. }
  489. void ReturnStatement::dump(int indent) const
  490. {
  491. ASTNode::dump(indent);
  492. if (argument())
  493. argument()->dump(indent + 1);
  494. }
  495. void IfStatement::dump(int indent) const
  496. {
  497. ASTNode::dump(indent);
  498. print_indent(indent);
  499. printf("If\n");
  500. predicate().dump(indent + 1);
  501. consequent().dump(indent + 1);
  502. if (alternate()) {
  503. print_indent(indent);
  504. printf("Else\n");
  505. alternate()->dump(indent + 1);
  506. }
  507. }
  508. void WhileStatement::dump(int indent) const
  509. {
  510. ASTNode::dump(indent);
  511. print_indent(indent);
  512. printf("While\n");
  513. test().dump(indent + 1);
  514. body().dump(indent + 1);
  515. }
  516. void DoWhileStatement::dump(int indent) const
  517. {
  518. ASTNode::dump(indent);
  519. print_indent(indent);
  520. printf("DoWhile\n");
  521. test().dump(indent + 1);
  522. body().dump(indent + 1);
  523. }
  524. void ForStatement::dump(int indent) const
  525. {
  526. ASTNode::dump(indent);
  527. print_indent(indent);
  528. printf("For\n");
  529. if (init())
  530. init()->dump(indent + 1);
  531. if (test())
  532. test()->dump(indent + 1);
  533. if (update())
  534. update()->dump(indent + 1);
  535. body().dump(indent + 1);
  536. }
  537. Value Identifier::execute(Interpreter& interpreter) const
  538. {
  539. auto variable = interpreter.get_variable(string());
  540. if (!variable.has_value())
  541. return interpreter.throw_exception<Error>("ReferenceError", String::format("'%s' not known", string().characters()));
  542. return variable.value();
  543. }
  544. void Identifier::dump(int indent) const
  545. {
  546. print_indent(indent);
  547. printf("Identifier \"%s\"\n", m_string.characters());
  548. }
  549. Value AssignmentExpression::execute(Interpreter& interpreter) const
  550. {
  551. AK::Function<void(Value)> commit;
  552. if (m_lhs->is_identifier()) {
  553. commit = [&](Value value) {
  554. auto name = static_cast<const Identifier&>(*m_lhs).string();
  555. interpreter.set_variable(name, value);
  556. };
  557. } else if (m_lhs->is_member_expression()) {
  558. commit = [&](Value value) {
  559. if (auto* object = static_cast<const MemberExpression&>(*m_lhs).object().execute(interpreter).to_object(interpreter.heap())) {
  560. auto property_name = static_cast<const MemberExpression&>(*m_lhs).computed_property_name(interpreter);
  561. object->put(property_name, value);
  562. }
  563. };
  564. } else {
  565. ASSERT_NOT_REACHED();
  566. }
  567. auto rhs_result = m_rhs->execute(interpreter);
  568. if (interpreter.exception())
  569. return {};
  570. switch (m_op) {
  571. case AssignmentOp::Assignment:
  572. break;
  573. case AssignmentOp::AdditionAssignment:
  574. rhs_result = add(m_lhs->execute(interpreter), rhs_result);
  575. break;
  576. case AssignmentOp::SubtractionAssignment:
  577. rhs_result = sub(m_lhs->execute(interpreter), rhs_result);
  578. break;
  579. case AssignmentOp::MultiplicationAssignment:
  580. rhs_result = mul(m_lhs->execute(interpreter), rhs_result);
  581. break;
  582. case AssignmentOp::DivisionAssignment:
  583. rhs_result = div(m_lhs->execute(interpreter), rhs_result);
  584. break;
  585. }
  586. if (interpreter.exception())
  587. return {};
  588. commit(rhs_result);
  589. return rhs_result;
  590. }
  591. Value UpdateExpression::execute(Interpreter& interpreter) const
  592. {
  593. ASSERT(m_argument->is_identifier());
  594. auto name = static_cast<const Identifier&>(*m_argument).string();
  595. auto previous_variable = interpreter.get_variable(name);
  596. ASSERT(previous_variable.has_value());
  597. auto previous_value = previous_variable.value();
  598. ASSERT(previous_value.is_number());
  599. int op_result = 0;
  600. switch (m_op) {
  601. case UpdateOp::Increment:
  602. op_result = 1;
  603. break;
  604. case UpdateOp::Decrement:
  605. op_result = -1;
  606. break;
  607. }
  608. interpreter.set_variable(name, Value(previous_value.as_double() + op_result));
  609. if (m_prefixed)
  610. return JS::Value(previous_value.as_double() + op_result);
  611. return previous_value;
  612. }
  613. void AssignmentExpression::dump(int indent) const
  614. {
  615. const char* op_string = nullptr;
  616. switch (m_op) {
  617. case AssignmentOp::Assignment:
  618. op_string = "=";
  619. break;
  620. case AssignmentOp::AdditionAssignment:
  621. op_string = "+=";
  622. break;
  623. case AssignmentOp::SubtractionAssignment:
  624. op_string = "-=";
  625. break;
  626. case AssignmentOp::MultiplicationAssignment:
  627. op_string = "*=";
  628. break;
  629. case AssignmentOp::DivisionAssignment:
  630. op_string = "/=";
  631. break;
  632. }
  633. ASTNode::dump(indent);
  634. print_indent(indent + 1);
  635. printf("%s\n", op_string);
  636. m_lhs->dump(indent + 1);
  637. m_rhs->dump(indent + 1);
  638. }
  639. void UpdateExpression::dump(int indent) const
  640. {
  641. const char* op_string = nullptr;
  642. switch (m_op) {
  643. case UpdateOp::Increment:
  644. op_string = "++";
  645. break;
  646. case UpdateOp::Decrement:
  647. op_string = "--";
  648. break;
  649. }
  650. ASTNode::dump(indent);
  651. print_indent(indent + 1);
  652. if (m_prefixed)
  653. printf("%s\n", op_string);
  654. m_argument->dump(indent + 1);
  655. if (!m_prefixed) {
  656. print_indent(indent + 1);
  657. printf("%s\n", op_string);
  658. }
  659. }
  660. Value VariableDeclaration::execute(Interpreter& interpreter) const
  661. {
  662. interpreter.declare_variable(name().string(), m_declaration_type);
  663. if (m_initializer) {
  664. auto initalizer_result = m_initializer->execute(interpreter);
  665. if (interpreter.exception())
  666. return {};
  667. interpreter.set_variable(name().string(), initalizer_result, true);
  668. }
  669. return {};
  670. }
  671. void VariableDeclaration::dump(int indent) const
  672. {
  673. const char* declaration_type_string = nullptr;
  674. switch (m_declaration_type) {
  675. case DeclarationType::Let:
  676. declaration_type_string = "Let";
  677. break;
  678. case DeclarationType::Var:
  679. declaration_type_string = "Var";
  680. break;
  681. case DeclarationType::Const:
  682. declaration_type_string = "Const";
  683. break;
  684. }
  685. ASTNode::dump(indent);
  686. print_indent(indent + 1);
  687. printf("%s\n", declaration_type_string);
  688. m_name->dump(indent + 1);
  689. if (m_initializer)
  690. m_initializer->dump(indent + 1);
  691. }
  692. void ObjectExpression::dump(int indent) const
  693. {
  694. ASTNode::dump(indent);
  695. for (auto it : m_properties) {
  696. print_indent(indent + 1);
  697. printf("%s: ", it.key.characters());
  698. it.value->dump(0);
  699. }
  700. }
  701. void ExpressionStatement::dump(int indent) const
  702. {
  703. ASTNode::dump(indent);
  704. m_expression->dump(indent + 1);
  705. }
  706. Value ObjectExpression::execute(Interpreter& interpreter) const
  707. {
  708. auto object = interpreter.heap().allocate<Object>();
  709. for (auto it : m_properties) {
  710. auto value = it.value->execute(interpreter);
  711. if (interpreter.exception())
  712. return {};
  713. object->put(it.key, value);
  714. }
  715. return object;
  716. }
  717. void MemberExpression::dump(int indent) const
  718. {
  719. print_indent(indent);
  720. printf("%s (computed=%s)\n", class_name(), is_computed() ? "true" : "false");
  721. m_object->dump(indent + 1);
  722. m_property->dump(indent + 1);
  723. }
  724. FlyString MemberExpression::computed_property_name(Interpreter& interpreter) const
  725. {
  726. if (!is_computed()) {
  727. ASSERT(m_property->is_identifier());
  728. return static_cast<const Identifier&>(*m_property).string();
  729. }
  730. return m_property->execute(interpreter).to_string();
  731. }
  732. Value MemberExpression::execute(Interpreter& interpreter) const
  733. {
  734. auto* object_result = m_object->execute(interpreter).to_object(interpreter.heap());
  735. if (interpreter.exception())
  736. return {};
  737. auto result = object_result->get(computed_property_name(interpreter));
  738. return result.value_or({});
  739. }
  740. Value StringLiteral::execute(Interpreter& interpreter) const
  741. {
  742. return js_string(interpreter, m_value);
  743. }
  744. Value NumericLiteral::execute(Interpreter&) const
  745. {
  746. return Value(m_value);
  747. }
  748. Value BooleanLiteral::execute(Interpreter&) const
  749. {
  750. return Value(m_value);
  751. }
  752. Value NullLiteral::execute(Interpreter&) const
  753. {
  754. return js_null();
  755. }
  756. void ArrayExpression::dump(int indent) const
  757. {
  758. ASTNode::dump(indent);
  759. for (auto& element : m_elements) {
  760. element.dump(indent + 1);
  761. }
  762. }
  763. Value ArrayExpression::execute(Interpreter& interpreter) const
  764. {
  765. auto* array = interpreter.heap().allocate<Array>();
  766. for (auto& element : m_elements) {
  767. auto value = element.execute(interpreter);
  768. if (interpreter.exception())
  769. return {};
  770. array->push(value);
  771. }
  772. return array;
  773. }
  774. void TryStatement::dump(int indent) const
  775. {
  776. ASTNode::dump(indent);
  777. print_indent(indent);
  778. printf("(Block)\n");
  779. block().dump(indent + 1);
  780. if (handler()) {
  781. print_indent(indent);
  782. printf("(Handler)\n");
  783. handler()->dump(indent + 1);
  784. }
  785. if (finalizer()) {
  786. print_indent(indent);
  787. printf("(Finalizer)\n");
  788. finalizer()->dump(indent + 1);
  789. }
  790. }
  791. void CatchClause::dump(int indent) const
  792. {
  793. print_indent(indent);
  794. printf("CatchClause");
  795. if (!m_parameter.is_null())
  796. printf(" (%s)", m_parameter.characters());
  797. printf("\n");
  798. body().dump(indent + 1);
  799. }
  800. void ThrowStatement::dump(int indent) const
  801. {
  802. ASTNode::dump(indent);
  803. argument().dump(indent + 1);
  804. }
  805. Value TryStatement::execute(Interpreter& interpreter) const
  806. {
  807. interpreter.run(block(), {}, ScopeType::Try);
  808. if (auto* exception = interpreter.exception()) {
  809. if (m_handler) {
  810. interpreter.clear_exception();
  811. Vector<Argument> arguments { { m_handler->parameter(), exception->value() } };
  812. interpreter.run(m_handler->body(), move(arguments));
  813. }
  814. }
  815. if (m_finalizer)
  816. m_finalizer->execute(interpreter);
  817. return {};
  818. }
  819. Value CatchClause::execute(Interpreter&) const
  820. {
  821. // NOTE: CatchClause execution is handled by TryStatement.
  822. ASSERT_NOT_REACHED();
  823. return {};
  824. }
  825. Value ThrowStatement::execute(Interpreter& interpreter) const
  826. {
  827. auto value = m_argument->execute(interpreter);
  828. if (interpreter.exception())
  829. return {};
  830. return interpreter.throw_exception(value);
  831. }
  832. Value SwitchStatement::execute(Interpreter& interpreter) const
  833. {
  834. auto discriminant_result = m_discriminant->execute(interpreter);
  835. if (interpreter.exception())
  836. return {};
  837. bool falling_through = false;
  838. for (auto& switch_case : m_cases) {
  839. if (!falling_through && switch_case.test()) {
  840. auto test_result = switch_case.test()->execute(interpreter);
  841. if (interpreter.exception())
  842. return {};
  843. if (!eq(discriminant_result, test_result).to_boolean())
  844. continue;
  845. }
  846. falling_through = true;
  847. for (auto& statement : switch_case.consequent()) {
  848. statement.execute(interpreter);
  849. if (interpreter.exception())
  850. return {};
  851. if (interpreter.should_unwind())
  852. return {};
  853. }
  854. }
  855. return {};
  856. }
  857. Value SwitchCase::execute(Interpreter& interpreter) const
  858. {
  859. (void)interpreter;
  860. return {};
  861. }
  862. Value BreakStatement::execute(Interpreter& interpreter) const
  863. {
  864. interpreter.unwind(ScopeType::Breakable);
  865. return {};
  866. }
  867. void SwitchStatement::dump(int indent) const
  868. {
  869. ASTNode::dump(indent);
  870. m_discriminant->dump(indent + 1);
  871. for (auto& switch_case : m_cases) {
  872. switch_case.dump(indent + 1);
  873. }
  874. }
  875. void SwitchCase::dump(int indent) const
  876. {
  877. ASTNode::dump(indent);
  878. print_indent(indent);
  879. if (m_test) {
  880. printf("(Test)\n");
  881. m_test->dump(indent + 1);
  882. } else {
  883. printf("(Default)\n");
  884. }
  885. print_indent(indent);
  886. printf("(Consequent)\n");
  887. int i = 0;
  888. for (auto& statement : m_consequent) {
  889. print_indent(indent);
  890. printf("[%d]\n", i++);
  891. statement.dump(indent + 1);
  892. }
  893. }
  894. Value ConditionalExpression::execute(Interpreter& interpreter) const
  895. {
  896. auto test_result = m_test->execute(interpreter);
  897. if (interpreter.exception())
  898. return {};
  899. Value result;
  900. if (test_result.to_boolean()) {
  901. result = m_consequent->execute(interpreter);
  902. } else {
  903. result = m_alternate->execute(interpreter);
  904. }
  905. if (interpreter.exception())
  906. return {};
  907. return result;
  908. }
  909. void ConditionalExpression::dump(int indent) const
  910. {
  911. ASTNode::dump(indent);
  912. print_indent(indent);
  913. printf("(Test)\n");
  914. m_test->dump(indent + 1);
  915. print_indent(indent);
  916. printf("(Consequent)\n");
  917. m_test->dump(indent + 1);
  918. print_indent(indent);
  919. printf("(Alternate)\n");
  920. m_test->dump(indent + 1);
  921. }
  922. }