1package goja 2 3import ( 4 "math" 5) 6 7func (r *Runtime) math_abs(call FunctionCall) Value { 8 return floatToValue(math.Abs(call.Argument(0).ToFloat())) 9} 10 11func (r *Runtime) math_acos(call FunctionCall) Value { 12 return floatToValue(math.Acos(call.Argument(0).ToFloat())) 13} 14 15func (r *Runtime) math_asin(call FunctionCall) Value { 16 return floatToValue(math.Asin(call.Argument(0).ToFloat())) 17} 18 19func (r *Runtime) math_atan(call FunctionCall) Value { 20 return floatToValue(math.Atan(call.Argument(0).ToFloat())) 21} 22 23func (r *Runtime) math_atan2(call FunctionCall) Value { 24 y := call.Argument(0).ToFloat() 25 x := call.Argument(1).ToFloat() 26 27 return floatToValue(math.Atan2(y, x)) 28} 29 30func (r *Runtime) math_ceil(call FunctionCall) Value { 31 return floatToValue(math.Ceil(call.Argument(0).ToFloat())) 32} 33 34func (r *Runtime) math_cos(call FunctionCall) Value { 35 return floatToValue(math.Cos(call.Argument(0).ToFloat())) 36} 37 38func (r *Runtime) math_exp(call FunctionCall) Value { 39 return floatToValue(math.Exp(call.Argument(0).ToFloat())) 40} 41 42func (r *Runtime) math_floor(call FunctionCall) Value { 43 return floatToValue(math.Floor(call.Argument(0).ToFloat())) 44} 45 46func (r *Runtime) math_log(call FunctionCall) Value { 47 return floatToValue(math.Log(call.Argument(0).ToFloat())) 48} 49 50func (r *Runtime) math_max(call FunctionCall) Value { 51 if len(call.Arguments) == 0 { 52 return _negativeInf 53 } 54 55 result := call.Arguments[0].ToFloat() 56 if math.IsNaN(result) { 57 return _NaN 58 } 59 for _, arg := range call.Arguments[1:] { 60 f := arg.ToFloat() 61 if math.IsNaN(f) { 62 return _NaN 63 } 64 result = math.Max(result, f) 65 } 66 return floatToValue(result) 67} 68 69func (r *Runtime) math_min(call FunctionCall) Value { 70 if len(call.Arguments) == 0 { 71 return _positiveInf 72 } 73 74 result := call.Arguments[0].ToFloat() 75 if math.IsNaN(result) { 76 return _NaN 77 } 78 for _, arg := range call.Arguments[1:] { 79 f := arg.ToFloat() 80 if math.IsNaN(f) { 81 return _NaN 82 } 83 result = math.Min(result, f) 84 } 85 return floatToValue(result) 86} 87 88func (r *Runtime) math_pow(call FunctionCall) Value { 89 x := call.Argument(0) 90 y := call.Argument(1) 91 if x, ok := x.assertInt(); ok { 92 if y, ok := y.assertInt(); ok && y >= 0 && y < 64 { 93 if y == 0 { 94 return intToValue(1) 95 } 96 if x == 0 { 97 return intToValue(0) 98 } 99 ip := ipow(x, y) 100 if ip != 0 { 101 return intToValue(ip) 102 } 103 } 104 } 105 106 return floatToValue(math.Pow(x.ToFloat(), y.ToFloat())) 107} 108 109func (r *Runtime) math_random(call FunctionCall) Value { 110 return floatToValue(r.rand()) 111} 112 113func (r *Runtime) math_round(call FunctionCall) Value { 114 f := call.Argument(0).ToFloat() 115 if math.IsNaN(f) { 116 return _NaN 117 } 118 119 if f == 0 && math.Signbit(f) { 120 return _negativeZero 121 } 122 123 t := math.Trunc(f) 124 125 if f >= 0 { 126 if f-t >= 0.5 { 127 return floatToValue(t + 1) 128 } 129 } else { 130 if t-f > 0.5 { 131 return floatToValue(t - 1) 132 } 133 } 134 135 return floatToValue(t) 136} 137 138func (r *Runtime) math_sin(call FunctionCall) Value { 139 return floatToValue(math.Sin(call.Argument(0).ToFloat())) 140} 141 142func (r *Runtime) math_sqrt(call FunctionCall) Value { 143 return floatToValue(math.Sqrt(call.Argument(0).ToFloat())) 144} 145 146func (r *Runtime) math_tan(call FunctionCall) Value { 147 return floatToValue(math.Tan(call.Argument(0).ToFloat())) 148} 149 150func (r *Runtime) createMath(val *Object) objectImpl { 151 m := &baseObject{ 152 class: "Math", 153 val: val, 154 extensible: true, 155 prototype: r.global.ObjectPrototype, 156 } 157 m.init() 158 159 m._putProp("E", valueFloat(math.E), false, false, false) 160 m._putProp("LN10", valueFloat(math.Ln10), false, false, false) 161 m._putProp("LN2", valueFloat(math.Ln2), false, false, false) 162 m._putProp("LOG2E", valueFloat(math.Log2E), false, false, false) 163 m._putProp("LOG10E", valueFloat(math.Log10E), false, false, false) 164 m._putProp("PI", valueFloat(math.Pi), false, false, false) 165 m._putProp("SQRT1_2", valueFloat(sqrt1_2), false, false, false) 166 m._putProp("SQRT2", valueFloat(math.Sqrt2), false, false, false) 167 168 m._putProp("abs", r.newNativeFunc(r.math_abs, nil, "abs", nil, 1), true, false, true) 169 m._putProp("acos", r.newNativeFunc(r.math_acos, nil, "acos", nil, 1), true, false, true) 170 m._putProp("asin", r.newNativeFunc(r.math_asin, nil, "asin", nil, 1), true, false, true) 171 m._putProp("atan", r.newNativeFunc(r.math_atan, nil, "atan", nil, 1), true, false, true) 172 m._putProp("atan2", r.newNativeFunc(r.math_atan2, nil, "atan2", nil, 2), true, false, true) 173 m._putProp("ceil", r.newNativeFunc(r.math_ceil, nil, "ceil", nil, 1), true, false, true) 174 m._putProp("cos", r.newNativeFunc(r.math_cos, nil, "cos", nil, 1), true, false, true) 175 m._putProp("exp", r.newNativeFunc(r.math_exp, nil, "exp", nil, 1), true, false, true) 176 m._putProp("floor", r.newNativeFunc(r.math_floor, nil, "floor", nil, 1), true, false, true) 177 m._putProp("log", r.newNativeFunc(r.math_log, nil, "log", nil, 1), true, false, true) 178 m._putProp("max", r.newNativeFunc(r.math_max, nil, "max", nil, 2), true, false, true) 179 m._putProp("min", r.newNativeFunc(r.math_min, nil, "min", nil, 2), true, false, true) 180 m._putProp("pow", r.newNativeFunc(r.math_pow, nil, "pow", nil, 2), true, false, true) 181 m._putProp("random", r.newNativeFunc(r.math_random, nil, "random", nil, 0), true, false, true) 182 m._putProp("round", r.newNativeFunc(r.math_round, nil, "round", nil, 1), true, false, true) 183 m._putProp("sin", r.newNativeFunc(r.math_sin, nil, "sin", nil, 1), true, false, true) 184 m._putProp("sqrt", r.newNativeFunc(r.math_sqrt, nil, "sqrt", nil, 1), true, false, true) 185 m._putProp("tan", r.newNativeFunc(r.math_tan, nil, "tan", nil, 1), true, false, true) 186 187 return m 188} 189 190func (r *Runtime) initMath() { 191 r.addToGlobal("Math", r.newLazyObject(r.createMath)) 192} 193