as2js: /home/snapwebsites/snapcpp/contrib/as2js/lib/optimizer_optimize.cpp Source File

as2js  0.1.14
AlexScript to JavaScript
optimizer_optimize.cpp
Go to the documentation of this file.
1 /* lib/optimizer_optimize.cpp
2 
3 Copyright (c) 2005-2019 Made to Order Software Corp. All Rights Reserved
4 
6 
7 Permission is hereby granted, free of charge, to any
8 person obtaining a copy of this software and
9 associated documentation files (the "Software"), to
10 deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify,
12 merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom
14 the Software is furnished to do so, subject to the
15 following conditions:
16 
17 The above copyright notice and this permission notice
18 shall be included in all copies or substantial
19 portions of the Software.
20 
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
22 ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
23 LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
24 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
25 EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
28 ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 SOFTWARE.
31 
32 */
33 
34 #include "optimizer_tables.h"
35 
36 #include "as2js/message.h"
37 #include "as2js/exceptions.h"
38 
39 #include <regex>
40 
41 
42 namespace as2js
43 {
44 namespace optimizer_details
45 {
46 
47 
56 namespace
57 {
58 
59 
77 {
78  uint32_t src1(optimize->f_indexes[0]),
79  src2(optimize->f_indexes[1]),
80  dst(optimize->f_indexes[2]);
81 
82  Node::node_t type1(node_array[src1]->get_type());
83  Node::node_t type2(node_array[src2]->get_type());
84 
85  // add the numbers together
86  if(type1 == Node::node_t::NODE_INT64 && type2 == Node::node_t::NODE_INT64)
87  {
88  // a + b when a and b are integers
89  Int64 i1(node_array[src1]->get_int64());
90  Int64 i2(node_array[src2]->get_int64());
91  // TODO: err on overflows?
92  i1.set(i1.get() + i2.get());
93  node_array[src1]->set_int64(i1);
94  }
95  else
96  {
97  // make sure a and b are floats, then do a + b as floats
98  // TODO: check for NaN and other fun things?
99  if(!node_array[src1]->to_float64()
100  || !node_array[src2]->to_float64())
101  {
102  throw exception_internal_error("optimizer used function to_float64() against a node that cannot be converted to a float64."); // LCOV_EXCL_LINE
103  }
104  Float64 f1(node_array[src1]->get_float64());
105  Float64 f2(node_array[src2]->get_float64());
106  // TODO: err on overflow?
107  f1.set(f1.get() + f2.get());
108  node_array[src1]->set_float64(f1);
109  }
110 
111  // save the result replacing the destination as specified
112  node_array[dst]->replace_with(node_array[src1]);
113  node_array[dst] = node_array[src1];
114 }
115 
116 
137 {
138  uint32_t src1(optimize->f_indexes[0]),
139  src2(optimize->f_indexes[1]),
140  dst(optimize->f_indexes[2]);
141 
142  if(!node_array[src1]->to_int64()
143  || !node_array[src2]->to_int64())
144  {
145  throw exception_internal_error("optimizer used function to_int64() against a node that cannot be converted to an int64."); // LCOV_EXCL_LINE
146  }
147 
148  // compute the result
149  // a & b
150  Int64 i1(node_array[src1]->get_int64());
151  Int64 i2(node_array[src2]->get_int64());
152  i1.set((i1.get() & i2.get()) & 0xFFFFFFFF);
153  node_array[src1]->set_int64(i1);
154 
155  // save the result replacing the destination as specified
156  node_array[dst]->replace_with(node_array[src1]);
157  node_array[dst] = node_array[src1];
158 }
159 
160 
181 {
182  uint32_t src(optimize->f_indexes[0]),
183  dst(optimize->f_indexes[1]);
184 
185  if(!node_array[src]->to_int64())
186  {
187  throw exception_internal_error("optimizer used function to_int64() against a node that cannot be converted to an int64."); // LCOV_EXCL_LINE
188  }
189 
190  // compute the result
191  // ~a
192  Int64 i1(node_array[src]->get_int64());
193  i1.set(~i1.get() & 0xFFFFFFFF);
194  node_array[src]->set_int64(i1);
195 
196  // save the result replacing the destination as specified
197  node_array[dst]->replace_with(node_array[src]);
198  node_array[dst] = node_array[src];
199 }
200 
201 
222 {
223  uint32_t src1(optimize->f_indexes[0]),
224  src2(optimize->f_indexes[1]),
225  dst(optimize->f_indexes[2]);
226 
227  if(!node_array[src1]->to_int64()
228  || !node_array[src2]->to_int64())
229  {
230  throw exception_internal_error("optimizer used function to_int64() against a node that cannot be converted to an int64."); // LCOV_EXCL_LINE
231  }
232 
233  // compute the result
234  // a | b
235  Int64 i1(node_array[src1]->get_int64());
236  Int64 i2(node_array[src2]->get_int64());
237  i1.set((i1.get() | i2.get()) & 0xFFFFFFFF);
238  node_array[src1]->set_int64(i1);
239 
240  // save the result replacing the destination as specified
241  node_array[dst]->replace_with(node_array[src1]);
242  node_array[dst] = node_array[src1];
243 }
244 
245 
266 {
267  uint32_t src1(optimize->f_indexes[0]),
268  src2(optimize->f_indexes[1]),
269  dst(optimize->f_indexes[2]);
270 
271  if(!node_array[src1]->to_int64()
272  || !node_array[src2]->to_int64())
273  {
274  throw exception_internal_error("optimizer used function to_int64() against a node that cannot be converted to an int64."); // LCOV_EXCL_LINE
275  }
276 
277  // compute the result
278  // a ^ b
279  Int64 i1(node_array[src1]->get_int64());
280  Int64 i2(node_array[src2]->get_int64());
281  i1.set((i1.get() ^ i2.get()) & 0xFFFFFFFF);
282  node_array[src1]->set_int64(i1);
283 
284  // save the result replacing the destination as specified
285  node_array[dst]->replace_with(node_array[src1]);
286  node_array[dst] = node_array[src1];
287 }
288 
289 
307 {
308  uint32_t src1(optimize->f_indexes[0]),
309  src2(optimize->f_indexes[1]),
310  dst(optimize->f_indexes[2]);
311  Node::pointer_t result;
312 
313  compare_t c(Node::compare(node_array[src1], node_array[src2], Node::compare_mode_t::COMPARE_LOOSE));
314  switch(c)
315  {
316  case compare_t::COMPARE_LESS: // -1
317  case compare_t::COMPARE_EQUAL: // 0
318  case compare_t::COMPARE_GREATER: // +1
319  result.reset(new Node(Node::node_t::NODE_INT64));
320  {
321  Int64 i;
322  i.set(static_cast<Int64::int64_type>(c));
323  result->set_int64(i);
324  }
325  break;
326 
330  // any invalid answer, included unordered becomes undefined
331  result.reset(new Node(Node::node_t::NODE_UNDEFINED));
332  break;
333 
334  }
335 
336  // save the result replacing the destination as specified
337  node_array[dst]->replace_with(result);
338  node_array[dst] = result;
339 }
340 
341 
360 {
361  uint32_t src1(optimize->f_indexes[0]),
362  src2(optimize->f_indexes[1]),
363  dst(optimize->f_indexes[2]);
364 
365  if(!node_array[src1]->to_string()
366  || !node_array[src2]->to_string())
367  {
368  throw exception_internal_error("a concatenate instruction can only be used with nodes that can be converted to strings."); // LCOV_EXCL_LINE
369  }
370 
371  String s1(node_array[src1]->get_string());
372  String s2(node_array[src2]->get_string());
373  node_array[src1]->set_string(s1 + s2);
374 
375  // save the result replacing the destination as specified
376  node_array[dst]->replace_with(node_array[src1]);
377  node_array[dst] = node_array[src1];
378 }
379 
380 
405 {
406  uint32_t src1(optimize->f_indexes[0]),
407  src2(optimize->f_indexes[1]),
408  dst(optimize->f_indexes[2]);
409 
410  // if both are integers, keep it as an integer
411  // (unless src2 is zero)
412  if(node_array[src1]->is_int64()
413  && node_array[src2]->is_int64())
414  {
415  Int64 i1(node_array[src1]->get_int64());
416  Int64 i2(node_array[src2]->get_int64());
417  if(i2.get() == 0)
418  {
419  // generate an warning about divisions by zero because it is not
420  // unlikely an error
422  msg << "division by zero of integers returning +Infinity or -Infinity.";
423 
424  // dividing by zero gives infinity
425  Float64 f;
426  f.set_infinity(); // +Infinity
427  if(i1.get() < 0)
428  {
429  // -Infinity
430  f.set(-f.get());
431  }
432  if(!node_array[src1]->to_float64())
433  {
434  throw exception_internal_error("optimizer used function to_float64() against a node that cannot be converted to a float64."); // LCOV_EXCL_LINE
435  }
436  node_array[src1]->set_float64(f);
437  }
438  else
439  {
440  // TBD: should this return a float?
441  i1.set(i1.get() / i2.get());
442  node_array[src1]->set_int64(i1);
443  }
444  }
445  else
446  {
447  if(!node_array[src1]->to_float64()
448  || !node_array[src2]->to_float64())
449  {
450  throw exception_internal_error("optimizer used function to_float64() against a node that cannot be converted to a float64."); // LCOV_EXCL_LINE
451  }
452  // make sure we keep NaN numbers as expected
453  Float64 f1(node_array[src1]->get_float64());
454  Float64 f2(node_array[src2]->get_float64());
455  if(f1.is_NaN()
456  || f2.is_NaN())
457  {
458  f1.set_NaN();
459  }
460  else
461  {
462  f1.set(f1.get() / f2.get());
463  }
464  node_array[src1]->set_float64(f1);
465  }
466 
467  // save the result replacing the destination as specified
468  node_array[dst]->replace_with(node_array[src1]);
469  node_array[dst] = node_array[src1];
470 }
471 
472 
487 {
488  uint32_t src1(optimize->f_indexes[0]),
489  src2(optimize->f_indexes[1]),
490  dst(optimize->f_indexes[2]);
491 
492  compare_t c(Node::compare(node_array[src1], node_array[src2], Node::compare_mode_t::COMPARE_LOOSE));
496 
497  // save the result replacing the destination as specified
498  node_array[dst]->replace_with(result);
499  node_array[dst] = result;
500 }
501 
502 
517 {
518  uint32_t src1(optimize->f_indexes[0]),
519  src2(optimize->f_indexes[1]),
520  dst(optimize->f_indexes[2]);
521 
522  compare_t c(Node::compare(node_array[src1], node_array[src2], Node::compare_mode_t::COMPARE_LOOSE));
526 
527  // save the result replacing the destination as specified
528  node_array[dst]->replace_with(result);
529  node_array[dst] = result;
530 }
531 
532 
547 {
548  uint32_t src1(optimize->f_indexes[0]),
549  src2(optimize->f_indexes[1]),
550  dst(optimize->f_indexes[2]);
551 
552  compare_t const c(Node::compare(node_array[src1], node_array[src2], Node::compare_mode_t::COMPARE_LOOSE));
557 
558  // save the result replacing the destination as specified
559  node_array[dst]->replace_with(result);
560  node_array[dst] = result;
561 }
562 
563 
584 {
585  uint32_t src(optimize->f_indexes[0]),
586  dst(optimize->f_indexes[1]);
587 
588  if(!node_array[src]->to_boolean())
589  {
590  throw exception_internal_error("optimizer used function to_boolean() against a node that cannot be converted to a Boolean."); // LCOV_EXCL_LINE
591  }
592  bool b(node_array[src]->get_boolean());
593  node_array[src]->set_boolean(!b);
594 
595  // save the result replacing the destination as specified
596  node_array[dst]->replace_with(node_array[src]);
597  node_array[dst] = node_array[src];
598 }
599 
600 
625 {
626  uint32_t src1(optimize->f_indexes[0]),
627  src2(optimize->f_indexes[1]),
628  dst(optimize->f_indexes[2]);
629 
630  Node::node_t n1(node_array[src1]->to_boolean_type_only());
631  Node::node_t n2(node_array[src2]->to_boolean_type_only());
634  {
635  throw exception_internal_error("optimizer used function to_boolean_type_only() against a node that cannot be converted to a Boolean."); // LCOV_EXCL_LINE
636  }
637  if(n1 == n2)
638  {
639  // if false, return the Boolean false
640  node_array[src1]->to_boolean();
641  node_array[src1]->set_boolean(false);
642  }
643  else
644  {
645  // if true, return the input as is
646  if(n1 == Node::node_t::NODE_FALSE)
647  {
648  // src2 is the result if src1 represents false
649  src1 = src2;
650  }
651  }
652 
653  // save the result replacing the destination as specified
654  node_array[dst]->replace_with(node_array[src1]);
655  node_array[dst] = node_array[src1];
656 }
657 
658 
680 {
681  uint32_t src1(optimize->f_indexes[0]),
682  src2(optimize->f_indexes[1]),
683  dst(optimize->f_indexes[2]);
684 
685  // if both are integers, keep it as an integer
686  // (unless src2 is zero)
687  if(node_array[src1]->is_int64()
688  && node_array[src2]->is_int64())
689  {
690  Int64 i1(node_array[src1]->get_int64());
691  Int64 i2(node_array[src2]->get_int64());
692  if(i2.get() == 0)
693  {
694  // generate an warning about divisions by zero because it is not
695  // unlikely an error
697  msg << "division by zero for a modulo of integers returning NaN.";
698 
699  // dividing by zero gives infinity
700  Float64 f;
701  f.set_NaN();
702  if(!node_array[src1]->to_float64())
703  {
704  throw exception_internal_error("optimizer used function to_float64() against a node that cannot be converted to a float64."); // LCOV_EXCL_LINE
705  }
706  node_array[src1]->set_float64(f);
707  }
708  else
709  {
710  // TBD: should this return a float?
711  i1.set(i1.get() % i2.get());
712  node_array[src1]->set_int64(i1);
713  }
714  }
715  else
716  {
717  if(!node_array[src1]->to_float64()
718  || !node_array[src2]->to_float64())
719  {
720  throw exception_internal_error("optimizer used function to_float64() against a node that cannot be converted to a float64."); // LCOV_EXCL_LINE
721  }
722  // make sure we keep NaN numbers as expected
723  Float64 f1(node_array[src1]->get_float64());
724  Float64 f2(node_array[src2]->get_float64());
725  if(f1.is_NaN()
726  || f2.is_NaN())
727  {
728  f1.set_NaN();
729  }
730  else
731  {
732  f1.set(fmod(f1.get(), f2.get()));
733  }
734  node_array[src1]->set_float64(f1);
735  }
736 
737  // save the result replacing the destination as specified
738  node_array[dst]->replace_with(node_array[src1]);
739  node_array[dst] = node_array[src1];
740 }
741 
742 
768 {
769  uint32_t src(optimize->f_indexes[0]),
770  dst(optimize->f_indexes[1]);
771 
772  // move the source in place of the destination
773  node_array[dst]->replace_with(node_array[src]);
774  node_array[dst] = node_array[src];
775 }
776 
777 
798 {
799  uint32_t src1(optimize->f_indexes[0]),
800  src2(optimize->f_indexes[1]),
801  dst(optimize->f_indexes[2]);
802 
803  // if both are integers, keep it as an integer
804  std::regex::flag_type regex_flags(std::regex_constants::ECMAScript | std::regex_constants::nosubs);
805  String regex(node_array[src2]->get_string());
806  if(regex[0] == '/')
807  {
808  String::size_type pos(regex.find_last_of('/'));
809  String flags(regex.substr(pos + 1));
810  regex = regex.substr(1, pos - 1); // remove the /.../
811  if(flags.find('i') != String::npos)
812  {
813  regex_flags |= std::regex_constants::icase;
814  }
815  }
816  // g++ implementation of regex is still quite limited in g++ 4.8.x
817  // if you have 4.9.0, the following should work nicely for you, otherwise
818  // it does nothing...
820  int match_result(-1);
821  try
822  {
823  std::basic_regex<as_char_t> js_regex(regex, regex_flags);
824  std::match_results<String::const_iterator> js_match;
825  std::regex_search(node_array[src1]->get_string(), js_match, js_regex);
826  match_result = js_match.empty() ? 1 : 0;
827  }
828  catch(std::regex_error const&)
829  {
830  }
831  catch(std::bad_cast const&)
832  {
833  }
834 
835  Node::pointer_t result;
836  if(match_result == -1)
837  {
838  // the regular expression is not valid, so we cannot optimize it
839  // to true or false, instead we generate an error now and transform
840  // the code to a throw
841  //
842  // throw new SyntaxError(errmsg, fileName, lineNumber);
843  //
844  // important note: any optimization has to do something or the
845  // optimizer tries again indefinitely...
846  //
847  result.reset(new Node(Node::node_t::NODE_THROW));
848  // TODO: we need to create a SyntaxError object
849 
851  result->append_child(call);
852 
854  syntax_error->set_string("SyntaxError");
855  call->append_child(syntax_error);
856 
858  call->append_child(params);
859 
861  String errmsg("regular expression \"");
862  errmsg += regex;
863  errmsg += "\" could not be compiled by std::regex.";
864  message->set_string(errmsg);
865  params->append_child(message);
866 
867  Position const& pos(node_array[src2]->get_position());
868 
870  filename->set_string(pos.get_filename());
871  params->append_child(filename);
872 
874  Int64 ln;
875  ln.set(pos.get_line());
876  line_number->set_int64(ln);
877  params->append_child(line_number);
878 
880  msg << errmsg;
881  }
882  else
883  {
884  result.reset(new Node(match_result == 0 ? Node::node_t::NODE_FALSE : Node::node_t::NODE_TRUE));
885  }
886 
887  // save the result replacing the destination as specified
888  node_array[dst]->replace_with(result);
889  node_array[dst] = result;
890 }
891 
892 
905 {
906  uint32_t src1(optimize->f_indexes[0]),
907  src2(optimize->f_indexes[1]),
908  dst(optimize->f_indexes[2]);
909 
910  Node::pointer_t result;
911 
912  Node::pointer_t n1(node_array[src1]);
913  Node::pointer_t n2(node_array[src2]);
914  if(n1->is_float64() && n1->get_float64().is_NaN())
915  {
916  result = n2;
917  }
918  else if(n2->is_float64() && n2->get_float64().is_NaN())
919  {
920  result = n1;
921  }
922  else
923  {
925  result = c == compare_t::COMPARE_GREATER ? n1 : n2;
926  }
927 
928  // save the result replacing the destination as specified
929  node_array[dst]->replace_with(result);
930  node_array[dst] = result;
931 }
932 
933 
946 {
947  uint32_t src1(optimize->f_indexes[0]),
948  src2(optimize->f_indexes[1]),
949  dst(optimize->f_indexes[2]);
950 
951  Node::pointer_t result;
952 
953  Node::pointer_t n1(node_array[src1]);
954  Node::pointer_t n2(node_array[src2]);
955  if(n1->is_float64() && n1->get_float64().is_NaN())
956  {
957  result = n2;
958  }
959  else if(n2->is_float64() && n2->get_float64().is_NaN())
960  {
961  result = n1;
962  }
963  else
964  {
966  result = c == compare_t::COMPARE_LESS ? n1 : n2;
967  }
968 
969  // save the result replacing the destination as specified
970  node_array[dst]->replace_with(result);
971  node_array[dst] = result;
972 }
973 
974 
994 {
995  uint32_t src1(optimize->f_indexes[0]),
996  src2(optimize->f_indexes[1]),
997  dst(optimize->f_indexes[2]);
998 
999  // if both are integers, keep it as an integer
1000  if(node_array[src1]->is_int64()
1001  && node_array[src2]->is_int64())
1002  {
1003  Int64 i1(node_array[src1]->get_int64());
1004  Int64 i2(node_array[src2]->get_int64());
1005  i1.set(i1.get() * i2.get());
1006  node_array[src1]->set_int64(i1);
1007  }
1008  else
1009  {
1010  if(!node_array[src1]->to_float64()
1011  || !node_array[src2]->to_float64())
1012  {
1013  throw exception_internal_error("optimizer used function to_float64() against a node that cannot be converted to a float64."); // LCOV_EXCL_LINE
1014  }
1015  // make sure we keep NaN numbers as expected
1016  Float64 f1(node_array[src1]->get_float64());
1017  Float64 f2(node_array[src2]->get_float64());
1018  if(f1.is_NaN()
1019  || f2.is_NaN())
1020  {
1021  f1.set_NaN();
1022  }
1023  else
1024  {
1025  f1.set(f1.get() * f2.get());
1026  }
1027  node_array[src1]->set_float64(f1);
1028  }
1029 
1030  // save the result replacing the destination as specified
1031  node_array[dst]->replace_with(node_array[src1]);
1032  node_array[dst] = node_array[src1];
1033 }
1034 
1035 
1052 {
1053  uint32_t src(optimize->f_indexes[0]),
1054  dst(optimize->f_indexes[1]);
1055 
1056  Node::node_t type(node_array[src]->get_type());
1057 
1058  // negate the integer or the float
1059  if(type == Node::node_t::NODE_INT64)
1060  {
1061  Int64 i(node_array[src]->get_int64());
1062  i.set(-i.get());
1063  node_array[src]->set_int64(i);
1064  }
1065  else
1066  {
1067  // make sure a and b are floats, then do a + b as floats
1068  // TODO: check for NaN and other fun things?
1069  if(!node_array[src]->to_float64())
1070  {
1071  throw exception_internal_error("optimizer used function to_float64() against a node that cannot be converted to a float64."); // LCOV_EXCL_LINE
1072  }
1073  Float64 f(node_array[src]->get_float64());
1074  f.set(-f.get());
1075  node_array[src]->set_float64(f);
1076  }
1077 
1078  // save the result replacing the destination as specified
1079  node_array[dst]->replace_with(node_array[src]);
1080  node_array[dst] = node_array[src];
1081 }
1082 
1083 
1103 {
1104  uint32_t src1(optimize->f_indexes[0]),
1105  src2(optimize->f_indexes[1]),
1106  dst(optimize->f_indexes[2]);
1107 
1108  // for powers, we always return a floating point
1109  // (think of negative numbers...)
1110  if(!node_array[src1]->to_float64()
1111  || !node_array[src2]->to_float64())
1112  {
1113  throw exception_internal_error("optimizer used function to_float64() against a node that cannot be converted to a float64."); // LCOV_EXCL_LINE
1114  }
1115 
1116  // make sure we keep NaN numbers as expected
1117  Float64 f1(node_array[src1]->get_float64());
1118  Float64 f2(node_array[src2]->get_float64());
1119  if(f1.is_NaN()
1120  || f2.is_NaN())
1121  {
1122  f1.set_NaN();
1123  }
1124  else
1125  {
1126  f1.set(pow(f1.get(), f2.get()));
1127  }
1128  node_array[src1]->set_float64(f1);
1129 
1130  // save the result replacing the destination as specified
1131  node_array[dst]->replace_with(node_array[src1]);
1132  node_array[dst] = node_array[src1];
1133 }
1134 
1135 
1157 {
1158  uint32_t src(optimize->f_indexes[0]);
1159 
1160  if(src == 0)
1161  {
1162  // ah... we cannot remove this one, instead mark it as unknown
1163  node_array[src]->to_unknown();
1164  }
1165  else
1166  {
1167  // simply remove from the parent, the smart pointers take care of the rest
1168  node_array[src]->set_parent(nullptr);
1169  }
1170 }
1171 
1172 
1195 {
1196  uint32_t src1(optimize->f_indexes[0]),
1197  src2(optimize->f_indexes[1]),
1198  dst(optimize->f_indexes[2]);
1199 
1200  if(!node_array[src1]->to_int64()
1201  || !node_array[src2]->to_int64())
1202  {
1203  throw exception_internal_error("optimizer used function to_int64() against a node that cannot be converted to an int64."); // LCOV_EXCL_LINE
1204  }
1205 
1206  // compute the result
1207  // a >% b
1208  Int64 i1(node_array[src1]->get_int64());
1209  Int64 i2(node_array[src2]->get_int64());
1210  Int64::int64_type v2(i2.get());
1211  Int64::int64_type v2_and(v2 & 0x1F);
1212  if(v2 < 0)
1213  {
1215  msg << "this static rotate amount is less than zero. " << v2_and << " will be used instead of " << v2 << ".";
1216  }
1217  else if(v2 >= 32)
1218  {
1220  msg << "this static rotate amount is larger than 31. " << v2_and << " will be used instead of " << v2 << ".";
1221  }
1222  // TODO: warn about v1 being larger than 32 bits?
1223  uint32_t v1(i1.get());
1224  if(v2_and != 0)
1225  {
1226  v1 = (v1 << v2_and) | (v1 >> (32 - v2_and));
1227  }
1228  i1.set(v1);
1229  node_array[src1]->set_int64(i1);
1230 
1231  // save the result replacing the destination as specified
1232  node_array[dst]->replace_with(node_array[src1]);
1233  node_array[dst] = node_array[src1];
1234 }
1235 
1236 
1259 {
1260  uint32_t src1(optimize->f_indexes[0]),
1261  src2(optimize->f_indexes[1]),
1262  dst(optimize->f_indexes[2]);
1263 
1264  if(!node_array[src1]->to_int64()
1265  || !node_array[src2]->to_int64())
1266  {
1267  throw exception_internal_error("optimizer used function to_int64() against a node that cannot be converted to an int64."); // LCOV_EXCL_LINE
1268  }
1269 
1270  // compute the result
1271  // a >% b
1272  Int64 i1(node_array[src1]->get_int64());
1273  Int64 i2(node_array[src2]->get_int64());
1274  Int64::int64_type v2(i2.get());
1275  Int64::int64_type v2_and(v2 & 0x1F);
1276  if(v2 < 0)
1277  {
1279  msg << "this static rotate amount is less than zero. " << v2_and << " will be used instead of " << v2 << ".";
1280  }
1281  else if(v2 >= 32)
1282  {
1284  msg << "this static rotate amount is larger than 31. " << v2_and << " will be used instead of " << v2 << ".";
1285  }
1286  // TODO: warn about v1 being larger than 32 bits?
1287  uint32_t v1(i1.get());
1288  if(v2_and != 0)
1289  {
1290  v1 = (v1 >> v2_and) | (v1 << (32 - v2_and));
1291  }
1292  i1.set(v1);
1293  node_array[src1]->set_int64(i1);
1294 
1295  // save the result replacing the destination as specified
1296  node_array[dst]->replace_with(node_array[src1]);
1297  node_array[dst] = node_array[src1];
1298 }
1299 
1300 
1302 // *
1303 // * This function sets the value of a float node. This is used when an
1304 // * optimization can determine the result of a numeric expression and
1305 // * a simple float can be set as the result.
1306 // *
1307 // * For example, a bitwise operation with NaN returns zero. This
1308 // * function can be used for that purpose.
1309 // *
1310 // * \li 0 -- node to be modified, it must be a NODE_FLOAT64
1311 // * \li 1 -- dividend (taken as a signed 16 bit value)
1312 // * \li 2 -- divisor (unsigned)
1313 // *
1314 // * The value is offset 1 divided by offset 2. Note however that
1315 // * both of those values are only 16 bits... If the divisor is zero
1316 // * then we use NaN as the value.
1317 // *
1318 // * \param[in] node_array The array of nodes being optimized.
1319 // * \param[in] optimize The optimization parameters.
1320 // */
1321 //void optimizer_func_SET_FLOAT(node_pointer_vector_t& node_array, optimization_optimize_t const *optimize)
1322 //{
1323 // uint32_t dst(optimize->f_indexes[0]),
1324 // divisor(optimize->f_indexes[2]);
1325 //
1326 // int32_t dividend(static_cast<int16_t>(optimize->f_indexes[1]));
1327 //
1328 // double value(divisor == 0 ? NAN : static_cast<double>(dividend) / static_cast<double>(divisor));
1329 //
1330 // Float64 v(node_array[dst]->get_float64());
1331 // v.set(value);
1332 // node_array[dst]->set_float64(v);
1333 //}
1334 
1335 
1354 {
1355  uint32_t dst(optimize->f_indexes[0]);
1356 
1357  int32_t value(static_cast<int16_t>(optimize->f_indexes[1]));
1358 
1359  Int64 v(node_array[dst]->get_int64());
1360  v.set(value);
1361  node_array[dst]->set_int64(v);
1362 }
1363 
1364 
1378 {
1379  Node::node_t node_type(static_cast<Node::node_t>(optimize->f_indexes[0]));
1380  uint32_t src(optimize->f_indexes[1]);
1381 
1382  Node::pointer_t node(new Node(node_type));
1383 
1384  Node::pointer_t to_replace(node_array[src]);
1385 
1386  size_t max_children(to_replace->get_children_size());
1387  for(size_t idx(0); idx < max_children; ++idx)
1388  {
1389  node->append_child(to_replace->get_child(0));
1390  }
1391  to_replace->replace_with(node);
1392  node_array[src] = node;
1393 }
1394 
1395 
1418 {
1419  uint32_t src1(optimize->f_indexes[0]),
1420  src2(optimize->f_indexes[1]),
1421  dst(optimize->f_indexes[2]);
1422 
1423  if(!node_array[src1]->to_int64()
1424  || !node_array[src2]->to_int64())
1425  {
1426  throw exception_internal_error("optimizer used function to_int64() against a node that cannot be converted to an int64."); // LCOV_EXCL_LINE
1427  }
1428 
1429  // compute the result
1430  // a << b
1431  Int64 i1(node_array[src1]->get_int64());
1432  Int64 i2(node_array[src2]->get_int64());
1433  // TODO: add a test to warn about 'b' being negative or larger than 31
1434  Int64::int64_type v2(i2.get());
1435  Int64::int64_type v2_and(v2 & 0x1F);
1436  if(v2 < 0)
1437  {
1439  msg << "this static shift amount is less than zero. " << v2_and << " will be used instead of " << v2 << ".";
1440  }
1441  else if(v2 >= 32)
1442  {
1444  msg << "this static shift amount is larger than 31. " << v2_and << " will be used instead of " << v2 << ".";
1445  }
1446  // TODO: warn about v1 being larger than 32 bits?
1447  i1.set((i1.get() << v2_and) & 0xFFFFFFFF);
1448  node_array[src1]->set_int64(i1);
1449 
1450  // save the result replacing the destination as specified
1451  node_array[dst]->replace_with(node_array[src1]);
1452  node_array[dst] = node_array[src1];
1453 }
1454 
1455 
1478 {
1479  uint32_t src1(optimize->f_indexes[0]),
1480  src2(optimize->f_indexes[1]),
1481  dst(optimize->f_indexes[2]);
1482 
1483  if(!node_array[src1]->to_int64()
1484  || !node_array[src2]->to_int64())
1485  {
1486  throw exception_internal_error("optimizer used function to_int64() against a node that cannot be converted to an int64."); // LCOV_EXCL_LINE
1487  }
1488 
1489  // compute the result
1490  // a >> b
1491  Int64 i1(node_array[src1]->get_int64());
1492  Int64 i2(node_array[src2]->get_int64());
1493  Int64::int64_type v2(i2.get());
1494  Int64::int64_type v2_and(v2 & 0x1F);
1495  if(v2 < 0)
1496  {
1498  msg << "this static shift amount is less than zero. " << v2_and << " will be used instead of " << v2 << ".";
1499  }
1500  else if(v2 >= 32)
1501  {
1503  msg << "this static shift amount is larger than 31. " << v2_and << " will be used instead of " << v2 << ".";
1504  }
1505  // TODO: warn about v1 being larger than 32 bits?
1506  int32_t v1(i1.get());
1507  v1 >>= v2_and;
1508  i1.set(v1);
1509  node_array[src1]->set_int64(i1);
1510 
1511  // save the result replacing the destination as specified
1512  node_array[dst]->replace_with(node_array[src1]);
1513  node_array[dst] = node_array[src1];
1514 }
1515 
1516 
1539 {
1540  uint32_t src1(optimize->f_indexes[0]),
1541  src2(optimize->f_indexes[1]),
1542  dst(optimize->f_indexes[2]);
1543 
1544  if(!node_array[src1]->to_int64()
1545  || !node_array[src2]->to_int64())
1546  {
1547  throw exception_internal_error("optimizer used function to_int64() against a node that cannot be converted to an int64."); // LCOV_EXCL_LINE
1548  }
1549 
1550  // compute the result
1551  // a >>> b
1552  Int64 i1(node_array[src1]->get_int64());
1553  Int64 i2(node_array[src2]->get_int64());
1554  Int64::int64_type v2(i2.get());
1555  Int64::int64_type v2_and(v2 & 0x1F);
1556  if(v2 < 0)
1557  {
1559  msg << "this static shift amount is less than zero. " << v2_and << " will be used instead of " << v2 << ".";
1560  }
1561  else if(v2 >= 32)
1562  {
1564  msg << "this static shift amount is larger than 31. " << v2_and << " will be used instead of " << v2 << ".";
1565  }
1566  // TODO: warn about v1 being larger than 32 bits?
1567  uint32_t v1(i1.get());
1568  v1 >>= v2_and;
1569  i1.set(v1);
1570  node_array[src1]->set_int64(i1);
1571 
1572  // save the result replacing the destination as specified
1573  node_array[dst]->replace_with(node_array[src1]);
1574  node_array[dst] = node_array[src1];
1575 }
1576 
1577 
1592 {
1593  uint32_t src1(optimize->f_indexes[0]),
1594  src2(optimize->f_indexes[1]),
1595  dst(optimize->f_indexes[2]);
1596 
1597  Node::pointer_t s1(node_array[src1]);
1598  Node::pointer_t s2(node_array[src2]);
1599 
1600  if(s1->get_type() == Node::node_t::NODE_STRING)
1601  {
1602  s1.reset(new Node(Node::node_t::NODE_STRING));
1603  s1->set_string(node_array[src1]->get_string().simplified());
1604  }
1605 
1606  if(s2->get_type() == Node::node_t::NODE_STRING)
1607  {
1608  s2.reset(new Node(Node::node_t::NODE_STRING));
1609  s2->set_string(node_array[src2]->get_string().simplified());
1610  }
1611 
1616 
1617  // save the result replacing the destination as specified
1618  node_array[dst]->replace_with(result);
1619  node_array[dst] = result;
1620 }
1621 
1622 
1637 {
1638  uint32_t src1(optimize->f_indexes[0]),
1639  src2(optimize->f_indexes[1]),
1640  dst(optimize->f_indexes[2]);
1641 
1642  compare_t const c(Node::compare(node_array[src1], node_array[src2], Node::compare_mode_t::COMPARE_STRICT));
1646 
1647  // save the result replacing the destination as specified
1648  node_array[dst]->replace_with(result);
1649  node_array[dst] = result;
1650 }
1651 
1652 
1670 {
1671  uint32_t src1(optimize->f_indexes[0]),
1672  src2(optimize->f_indexes[1]),
1673  dst(optimize->f_indexes[2]);
1674 
1675  Node::node_t type1(node_array[src1]->get_type());
1676  Node::node_t type2(node_array[src2]->get_type());
1677 
1678  // add the numbers together
1679  if(type1 == Node::node_t::NODE_INT64 && type2 == Node::node_t::NODE_INT64)
1680  {
1681  // a - b when a and b are integers
1682  Int64 i1(node_array[src1]->get_int64());
1683  Int64 i2(node_array[src2]->get_int64());
1684  // TODO: err on overflows?
1685  i1.set(i1.get() - i2.get());
1686  node_array[src1]->set_int64(i1);
1687  }
1688  else
1689  {
1690  // make sure a and b are floats, then do a - b as floats
1691  // TODO: check for NaN and other fun things?
1692  if(!node_array[src1]->to_float64()
1693  || !node_array[src2]->to_float64())
1694  {
1695  throw exception_internal_error("optimizer used function to_float64() against a node that cannot be converted to a float64."); // LCOV_EXCL_LINE
1696  }
1697  Float64 f1(node_array[src1]->get_float64());
1698  Float64 f2(node_array[src2]->get_float64());
1699  // TODO: err on overflow?
1700  f1.set(f1.get() - f2.get());
1701  node_array[src1]->set_float64(f1);
1702  }
1703 
1704  // save the result replacing the destination as specified
1705  node_array[dst]->replace_with(node_array[src1]);
1706  node_array[dst] = node_array[src1];
1707 }
1708 
1709 
1723 {
1724  uint32_t src1(optimize->f_indexes[0]),
1725  src2(optimize->f_indexes[1]);
1726 
1727  // get the existing pointers and offsets
1728  Node::pointer_t n1(node_array[src1]);
1729  Node::pointer_t n2(node_array[src2]);
1730 
1731  Node::pointer_t p1(n1->get_parent());
1732  Node::pointer_t p2(n2->get_parent());
1733 
1736 
1737  size_t o1(n1->get_offset());
1738  size_t o2(n2->get_offset());
1739 
1740  p1->set_child(o1, e1);
1741  p2->set_child(o2, e2);
1742 
1743  p1->set_child(o1, n2);
1744  p2->set_child(o2, n1);
1745 
1746  node_array[src1] = n2;
1747  node_array[src2] = n1;
1748 
1749  // WARNING: we do not use the replace_with() function because we would
1750  // otherwise lose the parent and offset information
1751 }
1752 
1753 
1772 {
1773  uint32_t src1(optimize->f_indexes[0]),
1774  src2(optimize->f_indexes[1]),
1775  src3(optimize->f_indexes[2]),
1776  dst(optimize->f_indexes[3]);
1777 
1779  conditional->append_child(node_array[src1]);
1780  conditional->append_child(node_array[src2]);
1781  conditional->append_child(node_array[src3]);
1782 
1783  // save the result replacing the specified destination
1784  node_array[dst]->replace_with(conditional);
1785  node_array[dst] = conditional;
1786 }
1787 
1788 
1790 // *
1791 // * This function transforms a node to a floating point number. The
1792 // * to_float64() HAS to work against that node or you will get an
1793 // * exception.
1794 // *
1795 // * \exception exception_internal_error
1796 // * The function attempts to convert the input to a floating point number.
1797 // * If that fails, this exception is raised. The Optimizer matching mechanism
1798 // * should, however, prevent all such problems.
1799 // *
1800 // * \param[in] node_array The array of nodes being optimized.
1801 // * \param[in] optimize The optimization parameters.
1802 // */
1803 //void optimizer_func_TO_FLOAT64(node_pointer_vector_t& node_array, optimization_optimize_t const *optimize)
1804 //{
1805 // if(!node_array[optimize->f_indexes[0]]->to_float64())
1806 // {
1807 // throw exception_internal_error("optimizer used function to_float64() against a node that cannot be converted to a floating point number."); // LCOV_EXCL_LINE
1808 // }
1809 //}
1810 
1811 
1827 {
1828  if(!node_array[optimize->f_indexes[0]]->to_int64())
1829  {
1830  throw exception_internal_error("optimizer used function to_int64() against a node that cannot be converted to an integer."); // LCOV_EXCL_LINE
1831  }
1832 }
1833 
1834 
1850 {
1851  if(!node_array[optimize->f_indexes[0]]->to_number())
1852  {
1853  throw exception_internal_error("optimizer used function to_number() against a node that cannot be converted to a number."); // LCOV_EXCL_LINE
1854  }
1855 }
1856 
1857 
1859 // *
1860 // * This function transforms a node to a string. The to_string() HAS to work
1861 // * against that node or you will get an exception.
1862 // *
1863 // * \exception exception_internal_error
1864 // * The function attempts to convert the input to a string.
1865 // * If that fails, this exception is raised. The Optimizer matching mechanism
1866 // * should, however, prevent all such problems.
1867 // *
1868 // * \param[in] node_array The array of nodes being optimized.
1869 // * \param[in] optimize The optimization parameters.
1870 // */
1871 //void optimizer_func_TO_STRING(node_pointer_vector_t& node_array, optimization_optimize_t const *optimize)
1872 //{
1873 // if(!node_array[optimize->f_indexes[0]]->to_string())
1874 // {
1875 // throw exception_internal_error("optimizer used function to_string() against a node that cannot be converted to a string."); // LCOV_EXCL_LINE
1876 // }
1877 //}
1878 
1879 
1889 {
1890  uint32_t src(optimize->f_indexes[0]),
1891  dst(optimize->f_indexes[1]);
1892 
1893  Node::pointer_t statements(node_array[src]);
1894  Node::pointer_t for_statement(new Node(Node::node_t::NODE_FOR));
1898 
1899  node_array[dst]->replace_with(for_statement);
1900  node_array[dst] = for_statement;
1901  for_statement->append_child(e1);
1902  for_statement->append_child(e2);
1903  for_statement->append_child(e3);
1904  for_statement->append_child(statements);
1905 }
1906 
1907 
1919 {
1920 #if defined(_DEBUG) || defined(DEBUG)
1921 
1932 #endif
1933 
1944  void (*f_func)(node_pointer_vector_t& node_array, optimization_optimize_t const *optimize);
1945 };
1946 
1947 
1948 #if defined(_DEBUG) || defined(DEBUG)
1949 #define OPTIMIZER_FUNC(name) { optimization_function_t::OPTIMIZATION_FUNCTION_##name, optimizer_func_##name }
1950 #else
1951 #define OPTIMIZER_FUNC(name) { optimizer_func_##name }
1952 #endif
1953 
1960 {
1961  /* OPTIMIZATION_FUNCTION_ADD */ OPTIMIZER_FUNC(ADD),
1962  /* OPTIMIZATION_FUNCTION_BITWISE_AND */ OPTIMIZER_FUNC(BITWISE_AND),
1963  /* OPTIMIZATION_FUNCTION_BITWISE_NOT */ OPTIMIZER_FUNC(BITWISE_NOT),
1964  /* OPTIMIZATION_FUNCTION_BITWISE_OR */ OPTIMIZER_FUNC(BITWISE_OR),
1965  /* OPTIMIZATION_FUNCTION_BITWISE_XOR */ OPTIMIZER_FUNC(BITWISE_XOR),
1966  /* OPTIMIZATION_FUNCTION_COMPARE */ OPTIMIZER_FUNC(COMPARE),
1967  /* OPTIMIZATION_FUNCTION_CONCATENATE */ OPTIMIZER_FUNC(CONCATENATE),
1968  /* OPTIMIZATION_FUNCTION_DIVIDE */ OPTIMIZER_FUNC(DIVIDE),
1969  /* OPTIMIZATION_FUNCTION_EQUAL */ OPTIMIZER_FUNC(EQUAL),
1970  /* OPTIMIZATION_FUNCTION_LESS */ OPTIMIZER_FUNC(LESS),
1971  /* OPTIMIZATION_FUNCTION_LESS_EQUAL */ OPTIMIZER_FUNC(LESS_EQUAL),
1972  /* OPTIMIZATION_FUNCTION_LOGICAL_NOT */ OPTIMIZER_FUNC(LOGICAL_NOT),
1973  /* OPTIMIZATION_FUNCTION_LOGICAL_XOR */ OPTIMIZER_FUNC(LOGICAL_XOR),
1974  /* OPTIMIZATION_FUNCTION_MATCH */ OPTIMIZER_FUNC(MATCH),
1975  /* OPTIMIZATION_FUNCTION_MAXIMUM */ OPTIMIZER_FUNC(MAXIMUM),
1976  /* OPTIMIZATION_FUNCTION_MINIMUM */ OPTIMIZER_FUNC(MINIMUM),
1977  /* OPTIMIZATION_FUNCTION_MODULO */ OPTIMIZER_FUNC(MODULO),
1978  /* OPTIMIZATION_FUNCTION_MOVE */ OPTIMIZER_FUNC(MOVE),
1979  /* OPTIMIZATION_FUNCTION_MULTIPLY */ OPTIMIZER_FUNC(MULTIPLY),
1980  /* OPTIMIZATION_FUNCTION_NEGATE */ OPTIMIZER_FUNC(NEGATE),
1981  /* OPTIMIZATION_FUNCTION_POWER */ OPTIMIZER_FUNC(POWER),
1982  /* OPTIMIZATION_FUNCTION_REMOVE */ OPTIMIZER_FUNC(REMOVE),
1983  /* OPTIMIZATION_FUNCTION_ROTATE_LEFT */ OPTIMIZER_FUNC(ROTATE_LEFT),
1984  /* OPTIMIZATION_FUNCTION_ROTATE_RIGHT */ OPTIMIZER_FUNC(ROTATE_RIGHT),
1985  /* OPTIMIZATION_FUNCTION_SET_INTEGER */ OPTIMIZER_FUNC(SET_INTEGER),
1987  /* OPTIMIZATION_FUNCTION_SET_NODE_TYPE */ OPTIMIZER_FUNC(SET_NODE_TYPE),
1988  /* OPTIMIZATION_FUNCTION_SHIFT_LEFT */ OPTIMIZER_FUNC(SHIFT_LEFT),
1989  /* OPTIMIZATION_FUNCTION_SHIFT_RIGHT */ OPTIMIZER_FUNC(SHIFT_RIGHT),
1990  /* OPTIMIZATION_FUNCTION_SHIFT_RIGHT_UNSIGNED */ OPTIMIZER_FUNC(SHIFT_RIGHT_UNSIGNED),
1991  /* OPTIMIZATION_FUNCTION_SMART_MATCH */ OPTIMIZER_FUNC(SMART_MATCH),
1992  /* OPTIMIZATION_FUNCTION_STRICTLY_EQUAL */ OPTIMIZER_FUNC(STRICTLY_EQUAL),
1993  /* OPTIMIZATION_FUNCTION_SUBTRACT */ OPTIMIZER_FUNC(SUBTRACT),
1994  /* OPTIMIZATION_FUNCTION_SWAP */ OPTIMIZER_FUNC(SWAP),
1995  /* OPTIMIZATION_FUNCTION_TO_CONDITIONAL */ OPTIMIZER_FUNC(TO_CONDITIONAL),
1997  /* OPTIMIZATION_FUNCTION_TO_INT64 */ OPTIMIZER_FUNC(TO_INT64),
1998  /* OPTIMIZATION_FUNCTION_TO_NUMBER */ OPTIMIZER_FUNC(TO_NUMBER),
2000  /* OPTIMIZATION_FUNCTION_WHILE_TRUE_TO_FOREVER */ OPTIMIZER_FUNC(WHILE_TRUE_TO_FOREVER)
2001 };
2002 
2010 size_t const g_optimizer_optimize_functions_size = sizeof(g_optimizer_optimize_functions) / sizeof(g_optimizer_optimize_functions[0]);
2011 
2012 
2025 {
2026 #if defined(_DEBUG) || defined(DEBUG)
2027  // this loop will not catch the last entries if missing, otherwise,
2028  // 'internal' functions are detected immediately, hence our other
2029  // test below
2030  for(size_t idx(0); idx < g_optimizer_optimize_functions_size; ++idx)
2031  {
2032  if(g_optimizer_optimize_functions[idx].f_func_index != static_cast<optimization_function_t>(idx))
2033  {
2034  std::cerr << "INTERNAL ERROR: function table index " << idx << " is not valid." // LCOV_EXCL_LINE
2035  << std::endl; // LCOV_EXCL_LINE
2036  throw exception_internal_error("INTERNAL ERROR: function table index is not valid (forgot to add a function to the table?)"); // LCOV_EXCL_LINE
2037  }
2038  }
2039  // make sure the function exists, otherwise we'd just crash (not good!)
2040  if(static_cast<size_t>(optimize->f_function) >= g_optimizer_optimize_functions_size)
2041  {
2042  std::cerr << "INTERNAL ERROR: f_function is too large " << static_cast<int>(optimize->f_function) << " > " // LCOV_EXCL_LINE
2043  << sizeof(g_optimizer_optimize_functions) / sizeof(g_optimizer_optimize_functions[0]) // LCOV_EXCL_LINE
2044  << std::endl; // LCOV_EXCL_LINE
2045  throw exception_internal_error("INTERNAL ERROR: f_function is out of range (forgot to add a function to the table?)"); // LCOV_EXCL_LINE
2046  }
2047 #endif
2048  g_optimizer_optimize_functions[static_cast<size_t>(optimize->f_function)].f_func(node_array, optimize);
2049 }
2050 
2051 
2052 }
2053 // noname namespace
2054 
2055 
2070 void apply_functions(node_pointer_vector_t& node_array, optimization_optimize_t const *optimize, size_t optimize_size)
2071 {
2072  for(; optimize_size > 0; --optimize_size, ++optimize)
2073  {
2074  apply_one_function(node_array, optimize);
2075  }
2076 }
2077 
2078 
2079 }
2080 // namespace optimizer_details
2081 }
2082 // namespace as2js
2083 
2084 // vim: ts=4 sw=4 et
float64_type get() const
Definition: float64.h:71
void optimizer_func_LOGICAL_XOR(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a LOGICAL_XOR function.
void optimizer_func_WHILE_TRUE_TO_FOREVER(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a TO_STRING function.
Definition of internal tables of the optimizer.
void set(float64_type const new_float)
Definition: float64.h:76
void optimizer_func_CONCATENATE(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a CONCATENATE function.
void optimizer_func_SHIFT_RIGHT_UNSIGNED(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply an SHIFT_RIGHT_UNSIGNED function.
void optimizer_func_SWAP(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a SWAP function.
void optimizer_func_MULTIPLY(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a MULTIPLY function.
void optimizer_func_ROTATE_LEFT(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply an ROTATE_LEFT function.
void optimizer_func_COMPARE(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a COMPARE function.
void optimizer_func_REMOVE(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a REMOVE function.
void set_NaN()
Definition: float64.h:81
void optimizer_func_MAXIMUM(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a MAXIMUM function.
void optimizer_func_SET_NODE_TYPE(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a SET_NODE_TYPE function.
void optimizer_func_SHIFT_RIGHT(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply an SHIFT_RIGHT function.
void apply_one_function(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply optimization functions to a node.
void optimizer_func_EQUAL(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply an EQUAL function.
std::vector< Node::pointer_t > node_pointer_vector_t
Definition: node.h:634
void optimizer_func_SET_INTEGER(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a SET_FLOAT function.
void optimizer_func_LOGICAL_NOT(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a LOGICAL_NOT function.
void optimizer_func_STRICTLY_EQUAL(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply an STRICTLY_EQUAL function.
void optimizer_func_BITWISE_XOR(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a BITWISE_XOR function.
#define OPTIMIZER_FUNC(name)
void optimizer_func_MODULO(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a MODULO function.
void set(int64_type const new_int)
Definition: int64.h:74
bool is_NaN() const
Definition: float64.h:91
counter_t get_line() const
Retrieve the current line counter.
Definition: position.cpp:214
static compare_t compare(Node::pointer_t const lhs, Node::pointer_t const rhs, compare_mode_t const mode)
Compare two nodes together.
int64_type get() const
Definition: int64.h:69
std::shared_ptr< Node > pointer_t
Definition: node.h:67
void apply_functions(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize, size_t optimize_size)
Apply all the optimization functions.
void optimizer_func_LESS_EQUAL(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a LESS_EQUAL function.
void set_infinity()
Definition: float64.h:86
void optimizer_func_BITWISE_AND(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a BITWISE_AND function.
void optimizer_func_DIVIDE(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a DIVIDE function.
size_t const g_optimizer_optimize_functions_size
The size of the optimizer list of optimization functions.
void optimizer_func_SMART_MATCH(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply an SMART_MATCH function.
void optimizer_func_TO_INT64(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a TO_FLOAT64 function.
void optimizer_func_SHIFT_LEFT(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply an SHIFT_LEFT function.
String get_filename() const
Retrieve the filename.
Definition: position.cpp:143
void optimizer_func_MINIMUM(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a MINIMUM function.
void optimizer_func_BITWISE_NOT(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a BITWISE_NOT function.
void optimizer_func_TO_CONDITIONAL(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply an TO_CONDITIONAL function.
void optimizer_func_MATCH(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a MATCH function.
The AlexScript to JavaScript namespace.
Definition: compiler.cpp:37
int optimize(Node::pointer_t &node)
The as2js optimizer.
Definition: optimizer.cpp:153
void optimizer_func_ADD(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply an ADD function.
optimizer_optimize_function_t g_optimizer_optimize_functions[]
List of optimization functions.
void optimizer_func_LESS(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a LESS function.
compare_t
Definition: compare.h:41
void optimizer_func_TO_NUMBER(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a TO_NUMBER function.
void optimizer_func_ROTATE_RIGHT(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply an ROTATE_RIGHT function.
void optimizer_func_NEGATE(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a NEGATE function.
void optimizer_func_BITWISE_OR(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a BITWISE_OR function.
void optimizer_func_SUBTRACT(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply an SUBTRACT function.
int64_t int64_type
Definition: int64.h:47
void optimizer_func_MOVE(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a MOVE function.
void optimizer_func_POWER(node_pointer_vector_t &node_array, optimization_optimize_t const *optimize)
Apply a POWER function.

This document is part of the Snap! Websites Project.

Copyright by Made to Order Software Corp.

Syndicate content

Snap! Websites
An Open Source CMS System in C++

Contact Us Directly