Advertisement
Guest User

Untitled

a guest
Mar 21st, 2019
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.32 KB | None | 0 0
  1. diff -r c08a5e45d75b njs/njs_function.c
  2. --- a/njs/njs_function.c Mon Mar 18 14:09:40 2019 +0800
  3. +++ b/njs/njs_function.c Mon Mar 18 16:02:44 2019 +0800
  4. @@ -35,7 +35,7 @@ njs_function_alloc(njs_vm_t *vm, njs_fun
  5. goto fail;
  6. }
  7.  
  8. - function->ctor = 1;
  9. + function->ctor = lambda->arrow ? 0 : 1;
  10. function->args_offset = 1;
  11. function->u.lambda = lambda;
  12.  
  13. @@ -290,8 +290,8 @@ njs_function_lambda_frame(njs_vm_t *vm,
  14. nxt_bool_t ctor)
  15. {
  16. size_t size;
  17. - nxt_uint_t n, max_args, closures;
  18. - njs_value_t *value, *bound;
  19. + nxt_uint_t i, n, max_args, closures;
  20. + njs_value_t *value;
  21. njs_frame_t *frame;
  22. njs_native_frame_t *native_frame;
  23. njs_function_lambda_t *lambda;
  24. @@ -321,18 +321,17 @@ njs_function_lambda_frame(njs_vm_t *vm,
  25. njs_frame_size(closures));
  26. native_frame->arguments = value;
  27.  
  28. - bound = function->bound;
  29. -
  30. - if (bound == NULL) {
  31. + if (function->bound == NULL) {
  32. *value++ = *this;
  33.  
  34. } else {
  35. n = function->args_offset;
  36.  
  37. - do {
  38. - *value++ = *bound++;
  39. - n--;
  40. - } while (n != 0);
  41. + for (i = 0; i < n; i++) {
  42. + *value++ = function->bound[i];
  43. + }
  44. +
  45. + native_frame->nargs += (n - 1);
  46. }
  47.  
  48. vm->scopes[NJS_SCOPE_CALLEE_ARGUMENTS] = value;
  49. diff -r c08a5e45d75b njs/njs_function.h
  50. --- a/njs/njs_function.h Mon Mar 18 14:09:40 2019 +0800
  51. +++ b/njs/njs_function.h Mon Mar 18 16:02:44 2019 +0800
  52. @@ -30,6 +30,7 @@ struct njs_function_lambda_s {
  53. /* Function internal block closures levels. */
  54. uint8_t block_closures; /* 4 bits */
  55.  
  56. + uint8_t arrow; /* 1 bit */
  57. uint8_t rest_parameters; /* 1 bit */
  58.  
  59. /* Initial values of local scope. */
  60. diff -r c08a5e45d75b njs/njs_lexer.c
  61. --- a/njs/njs_lexer.c Mon Mar 18 14:09:40 2019 +0800
  62. +++ b/njs/njs_lexer.c Mon Mar 18 16:02:44 2019 +0800
  63. @@ -278,6 +278,7 @@ static const njs_lexer_multi_t njs_grea
  64.  
  65. static const njs_lexer_multi_t njs_assignment_token[] = {
  66. { '=', NJS_TOKEN_EQUAL, 1, njs_strict_equal_token },
  67. + { '>', NJS_TOKEN_ARROW, 0, NULL },
  68. };
  69.  
  70.  
  71. diff -r c08a5e45d75b njs/njs_lexer.h
  72. --- a/njs/njs_lexer.h Mon Mar 18 14:09:40 2019 +0800
  73. +++ b/njs/njs_lexer.h Mon Mar 18 16:02:44 2019 +0800
  74. @@ -36,6 +36,7 @@ typedef enum {
  75. NJS_TOKEN_CONDITIONAL,
  76.  
  77. NJS_TOKEN_ASSIGNMENT,
  78. + NJS_TOKEN_ARROW,
  79. NJS_TOKEN_ADDITION_ASSIGNMENT,
  80. NJS_TOKEN_SUBSTRACTION_ASSIGNMENT,
  81. NJS_TOKEN_MULTIPLICATION_ASSIGNMENT,
  82. diff -r c08a5e45d75b njs/njs_parser.c
  83. --- a/njs/njs_parser.c Mon Mar 18 14:09:40 2019 +0800
  84. +++ b/njs/njs_parser.c Mon Mar 18 16:02:44 2019 +0800
  85. @@ -1960,6 +1960,167 @@ njs_parser_property_token(njs_vm_t *vm,
  86. }
  87.  
  88.  
  89. +static nxt_int_t
  90. +njs_parser_match_arrow_expression(njs_vm_t *vm, njs_parser_t *parser,
  91. + njs_token_t token)
  92. +{
  93. + size_t offset;
  94. + nxt_bool_t rest_parameters;
  95. +
  96. + offset = 0;
  97. +
  98. + if (token == NJS_TOKEN_NAME) {
  99. + goto arrow;
  100. + }
  101. +
  102. + token = njs_parser_peek_token(vm, parser, &offset);
  103. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  104. + return NXT_DECLINED;
  105. + }
  106. +
  107. + rest_parameters = 0;
  108. +
  109. + while (token != NJS_TOKEN_CLOSE_PARENTHESIS) {
  110. +
  111. + if (rest_parameters) {
  112. + return NXT_DECLINED;
  113. + }
  114. +
  115. + if (nxt_slow_path(token == NJS_TOKEN_ELLIPSIS)) {
  116. + rest_parameters = 1;
  117. +
  118. + token = njs_parser_peek_token(vm, parser, &offset);
  119. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  120. + return NXT_DECLINED;
  121. + }
  122. + }
  123. +
  124. + if (nxt_slow_path(token != NJS_TOKEN_NAME)) {
  125. + return NXT_DECLINED;
  126. + }
  127. +
  128. + token = njs_parser_peek_token(vm, parser, &offset);
  129. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  130. + return token;
  131. + }
  132. +
  133. + if (token == NJS_TOKEN_COMMA) {
  134. + token = njs_parser_peek_token(vm, parser, &offset);
  135. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  136. + return NXT_DECLINED;
  137. + }
  138. + }
  139. + }
  140. +
  141. +arrow:
  142. +
  143. + token = njs_parser_peek_token(vm, parser, &offset);
  144. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  145. + return NXT_DECLINED;
  146. + }
  147. +
  148. + if (parser->lexer->prev_token == NJS_TOKEN_LINE_END) {
  149. + return NXT_DECLINED;
  150. + }
  151. +
  152. + if (nxt_slow_path(token != NJS_TOKEN_ARROW)) {
  153. + return NXT_DECLINED;
  154. + }
  155. +
  156. + return NXT_OK;
  157. +}
  158. +
  159. +
  160. +static njs_token_t
  161. +njs_parser_arrow_expression(njs_vm_t *vm, njs_parser_t *parser,
  162. + njs_token_t token)
  163. +{
  164. + njs_ret_t ret;
  165. + njs_index_t index;
  166. + njs_parser_node_t *node, *body, *parent;
  167. + njs_function_lambda_t *lambda;
  168. +
  169. + node = njs_parser_node_new(vm, parser, NJS_TOKEN_FUNCTION_EXPRESSION);
  170. + if (nxt_slow_path(node == NULL)) {
  171. + return NJS_TOKEN_ERROR;
  172. + }
  173. +
  174. + node->token_line = njs_parser_token_line(parser);
  175. + parser->node = node;
  176. +
  177. + lambda = nxt_mp_zalloc(vm->mem_pool, sizeof(njs_function_lambda_t));
  178. + if (nxt_slow_path(lambda == NULL)) {
  179. + return NJS_TOKEN_ERROR;
  180. + }
  181. +
  182. + lambda->arrow = 1;
  183. +
  184. + node->u.value.data.u.lambda = lambda;
  185. +
  186. + ret = njs_parser_scope_begin(vm, parser, NJS_SCOPE_FUNCTION);
  187. + if (nxt_slow_path(ret != NXT_OK)) {
  188. + return NJS_TOKEN_ERROR;
  189. + }
  190. +
  191. + index = NJS_SCOPE_ARGUMENTS;
  192. +
  193. + /* A "this" reservation. */
  194. + index += sizeof(njs_value_t);
  195. +
  196. + if (token == NJS_TOKEN_OPEN_PARENTHESIS) {
  197. + token = njs_parser_lambda_arguments(vm, parser, lambda, index, token);
  198. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  199. + return token;
  200. + }
  201. +
  202. + } else {
  203. + token = njs_parser_lambda_argument(vm, parser, index);
  204. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  205. + return token;
  206. + }
  207. +
  208. + lambda->nargs = 1;
  209. + }
  210. +
  211. + if (parser->lexer->prev_token == NJS_TOKEN_LINE_END) {
  212. + return NJS_TOKEN_ILLEGAL;
  213. + }
  214. +
  215. + token = njs_parser_match(vm, parser, token, NJS_TOKEN_ARROW);
  216. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  217. + return token;
  218. + }
  219. +
  220. + if (token == NJS_TOKEN_OPEN_BRACE) {
  221. + token = njs_parser_lambda_body(vm, parser, token);
  222. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  223. + return token;
  224. + }
  225. +
  226. + } else {
  227. + parent = parser->node;
  228. +
  229. + token = njs_parser_expression(vm, parser, token);
  230. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  231. + return token;
  232. + }
  233. +
  234. + body = njs_parser_return_set(vm, parser, parser->node);
  235. + if (nxt_slow_path(body == NULL)) {
  236. + return NJS_TOKEN_ERROR;
  237. + }
  238. +
  239. + parent->right = body;
  240. +
  241. + parser->node = parent;
  242. + }
  243. +
  244. + njs_parser_scope_end(vm, parser);
  245. +
  246. + return token;
  247. +}
  248. +
  249. +
  250. njs_token_t
  251. njs_parser_terminal(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token)
  252. {
  253. @@ -1967,6 +2128,12 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
  254. njs_ret_t ret;
  255. njs_parser_node_t *node;
  256.  
  257. + if (token == NJS_TOKEN_OPEN_PARENTHESIS || token == NJS_TOKEN_NAME) {
  258. + if (njs_parser_match_arrow_expression(vm, parser, token) == NXT_OK) {
  259. + return njs_parser_arrow_expression(vm, parser, token);
  260. + }
  261. + }
  262. +
  263. if (token == NJS_TOKEN_OPEN_PARENTHESIS) {
  264.  
  265. token = njs_parser_token(vm, parser);
  266. diff -r c08a5e45d75b njs/test/njs_unit_test.c
  267. --- a/njs/test/njs_unit_test.c Mon Mar 18 14:09:40 2019 +0800
  268. +++ b/njs/test/njs_unit_test.c Mon Mar 18 16:02:44 2019 +0800
  269. @@ -6503,6 +6503,86 @@ static njs_unit_test_t njs_test[] =
  270. "myFoo(1,2);" ),
  271. nxt_string("") },
  272.  
  273. + /* arrow functions. */
  274. +
  275. + { nxt_string("()"),
  276. + nxt_string("SyntaxError: Unexpected token \")\" in 1") },
  277. +
  278. + { nxt_string("() => "),
  279. + nxt_string("SyntaxError: Unexpected end of input in 1") },
  280. +
  281. + { nxt_string("() => {"),
  282. + nxt_string("SyntaxError: Unexpected end of input in 1") },
  283. +
  284. + { nxt_string("a\n => 1"),
  285. + nxt_string("SyntaxError: Unexpected token \"=>\" in 2") },
  286. +
  287. + { nxt_string("new (()=>1)"),
  288. + nxt_string("TypeError: function is not a constructor")},
  289. +
  290. + { nxt_string("(\n) => {}"),
  291. + nxt_string("[object Function]") },
  292. +
  293. + { nxt_string("a => 1"),
  294. + nxt_string("[object Function]") },
  295. +
  296. + { nxt_string("var f = f => {return 1;}; f()"),
  297. + nxt_string("1") },
  298. +
  299. + { nxt_string("var f = (f) => {return 1;}; f()"),
  300. + nxt_string("1") },
  301. +
  302. + { nxt_string("var f = (f, a, b) => {return 1;}; f()"),
  303. + nxt_string("1") },
  304. +
  305. + { nxt_string("var f = () => {return 1;}; f()"),
  306. + nxt_string("1") },
  307. +
  308. + { nxt_string("(f => {return 1;})()"),
  309. + nxt_string("1") },
  310. +
  311. + { nxt_string("((f) => {return 1;})()"),
  312. + nxt_string("1") },
  313. +
  314. + { nxt_string("(((f) => {return 1;}))()"),
  315. + nxt_string("1") },
  316. +
  317. + { nxt_string("var f = f => 1; f()"),
  318. + nxt_string("1") },
  319. +
  320. + { nxt_string("() => 1"),
  321. + nxt_string("[object Function]") },
  322. +
  323. + { nxt_string("var f = ()=>{}; f()"),
  324. + nxt_string("undefined") },
  325. +
  326. + { nxt_string("var f = ()=>({}); f()"),
  327. + nxt_string("[object Object]") },
  328. +
  329. + { nxt_string("var materials = ['Hydrogen', 'Helium', 'Lithium', 'Beryllium'];"
  330. + "materials.map(material => { return material.length; });"),
  331. + nxt_string("8,6,7,9") },
  332. +
  333. + { nxt_string("var materials = ['Hydrogen', 'Helium', 'Lithium', 'Beryllium'];"
  334. + "materials.map(material => material.length);"),
  335. + nxt_string("8,6,7,9") },
  336. +
  337. + { nxt_string("var materials = ['Hydrogen', 'Helium', 'Lithium', 'Beryllium'];"
  338. + "materials.map(material => { material.length });"),
  339. + nxt_string(",,,") },
  340. +
  341. + { nxt_string("function f(a, b, c) {a = 1; return () => { return arguments[1]; };};"
  342. + "f(1, 2, 3)('a', 'b');"),
  343. + nxt_string("2") },
  344. +
  345. + { nxt_string("var f = (...c) => { return (function() { return arguments.length; }).bind(null, c); };"
  346. + "var x = f(1,'a',false, {}); x()"),
  347. + nxt_string("1") },
  348. +
  349. + { nxt_string("var f = (...c) => { return (function() { return arguments.length; }).bind(null, c); };"
  350. + "var x = f(1,'a',false, {}); x(1,2,3)"),
  351. + nxt_string("4") },
  352. +
  353. /* Scopes. */
  354.  
  355. { nxt_string("function f(x) { a = x } var a; f(5); a"),
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement