001/* 002 * This file is part of OCaml-Java runtime. 003 * Copyright (C) 2007-2013 Xavier Clerc. 004 * 005 * OCaml-Java runtime is free software; you can redistribute it and/or modify 006 * it under the terms of the GNU Lesser General Public License as published by 007 * the Free Software Foundation; either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * OCaml-Java runtime is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.ocamljava.runtime.wrappers; 020 021import java.lang.invoke.MethodHandle; 022import java.lang.invoke.MethodHandles; 023import java.lang.invoke.MethodType; 024 025import org.ocamljava.runtime.values.Value; 026 027/** 028 * The {@code OCamlFunction7} class represent an OCaml function taking seven 029 * parameter. 030 * 031 * @author <a href="mailto:xclerc@ocamljava.org">Xavier Clerc</a> 032 * @version 2.0 033 * @since 2.0 034 */ 035public abstract class OCamlFunction7<T0 extends OCamlValue, 036 T1 extends OCamlValue, 037 T2 extends OCamlValue, 038 T3 extends OCamlValue, 039 T4 extends OCamlValue, 040 T5 extends OCamlValue, 041 T6 extends OCamlValue, 042 TR extends OCamlValue> extends OCamlValue { 043 044 /** Wrapper for first parameter. */ 045 protected final Wrapper<T0> wrapper0; 046 047 /** Wrapper for second parameter. */ 048 protected final Wrapper<T1> wrapper1; 049 050 /** Wrapper for third parameter. */ 051 protected final Wrapper<T2> wrapper2; 052 053 /** Wrapper for fourth parameter. */ 054 protected final Wrapper<T3> wrapper3; 055 056 /** Wrapper for fifth parameter. */ 057 protected final Wrapper<T4> wrapper4; 058 059 /** Wrapper for sixth parameter. */ 060 protected final Wrapper<T5> wrapper5; 061 062 /** Wrapper for seventh parameter. */ 063 protected final Wrapper<T6> wrapper6; 064 065 /** Wrapper for return value. */ 066 protected final Wrapper<TR> wrapperr; 067 068 /** Method handle for function actually called from the OCaml runtime. */ 069 private static final MethodHandle METHOD_HANDLE; 070 071 static { 072 MethodHandle mh; 073 try { 074 final MethodHandles.Lookup lookup = MethodHandles.lookup(); 075 final MethodType mt = MethodType.methodType(Value.class, 076 Value.class, 077 Value.class, 078 Value.class, 079 Value.class, 080 Value.class, 081 Value.class, 082 Value.class); 083 mh = lookup.findVirtual(OCamlFunction7Caller.class, "called", mt); 084 } catch (final NoSuchMethodException | IllegalAccessException e) { 085 assert false : "OCamlFunction7: unable to get method handle"; 086 mh = null; 087 } // end try/catch 088 METHOD_HANDLE = mh; 089 } // end static block 090 091 /** 092 * Constructs a new instance. <br/> 093 * To be used by Java implementations. 094 * @param w0 wrapper for first parameter - should not be {@code null} 095 * @param w1 wrapper for second parameter - should not be {@code null} 096 * @param w2 wrapper for third parameter - should not be {@code null} 097 * @param w3 wrapper for fourth parameter - should not be {@code null} 098 * @param w4 wrapper for fifth parameter - should not be {@code null} 099 * @param w5 wrapper for sixth parameter - should not be {@code null} 100 * @param w6 wrapper for seventh parameter - should not be {@code null} 101 * @param wr wrapper for result - should not be {@code null} 102 */ 103 public OCamlFunction7(final Wrapper<T0> w0, 104 final Wrapper<T1> w1, 105 final Wrapper<T2> w2, 106 final Wrapper<T3> w3, 107 final Wrapper<T4> w4, 108 final Wrapper<T5> w5, 109 final Wrapper<T6> w6, 110 final Wrapper<TR> wr) { 111 super(Value.UNIT); 112 assert w0 != null : "null w0"; 113 assert w1 != null : "null w1"; 114 assert w2 != null : "null w2"; 115 assert w3 != null : "null w3"; 116 assert w4 != null : "null w4"; 117 assert w5 != null : "null w5"; 118 assert w6 != null : "null w6"; 119 assert wr != null : "null wr"; 120 this.wrapper0 = w0; 121 this.wrapper1 = w1; 122 this.wrapper2 = w2; 123 this.wrapper3 = w3; 124 this.wrapper4 = w4; 125 this.wrapper5 = w5; 126 this.wrapper6 = w6; 127 this.wrapperr = wr; 128 } // end constructor(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<T6>, Wrapper<TR>) 129 130 /** 131 * Constructs a new instance. <br/> 132 * To be used by Java implementations. 133 */ 134 @SuppressWarnings("unchecked") 135 public OCamlFunction7() { 136 this((Wrapper<T0>) OCamlValue.WRAPPER, 137 (Wrapper<T1>) OCamlValue.WRAPPER, 138 (Wrapper<T2>) OCamlValue.WRAPPER, 139 (Wrapper<T3>) OCamlValue.WRAPPER, 140 (Wrapper<T4>) OCamlValue.WRAPPER, 141 (Wrapper<T5>) OCamlValue.WRAPPER, 142 (Wrapper<T6>) OCamlValue.WRAPPER, 143 (Wrapper<TR>) OCamlValue.WRAPPER); 144 } // end empty constructor 145 146 /** 147 * Constructs a new instance from a value. <br/> 148 * To be used by OCaml implementations. 149 * @param w0 wrapper for first parameter - should not be {@code null} 150 * @param w1 wrapper for second parameter - should not be {@code null} 151 * @param w2 wrapper for third parameter - should not be {@code null} 152 * @param w3 wrapper for fourth parameter - should not be {@code null} 153 * @param w4 wrapper for fifth parameter - should not be {@code null} 154 * @param w5 wrapper for fifth parameter - should not be {@code null} 155 * @param w6 wrapper for fifth parameter - should not be {@code null} 156 * @param wr wrapper for result - should not be {@code null} 157 */ 158 OCamlFunction7(final Value v, 159 final Wrapper<T0> w0, 160 final Wrapper<T1> w1, 161 final Wrapper<T2> w2, 162 final Wrapper<T3> w3, 163 final Wrapper<T4> w4, 164 final Wrapper<T5> w5, 165 final Wrapper<T6> w6, 166 final Wrapper<TR> wr) { 167 super(v); 168 assert w0 != null : "null w0"; 169 assert w1 != null : "null w1"; 170 assert w2 != null : "null w2"; 171 assert w3 != null : "null w3"; 172 assert w4 != null : "null w4"; 173 assert w5 != null : "null w5"; 174 assert w6 != null : "null w6"; 175 assert wr != null : "null wr"; 176 this.wrapper0 = w0; 177 this.wrapper1 = w1; 178 this.wrapper2 = w2; 179 this.wrapper3 = w3; 180 this.wrapper4 = w4; 181 this.wrapper5 = w5; 182 this.wrapper6 = w6; 183 this.wrapperr = wr; 184 } // end constructor(Value, Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<T6>, Wrapper<TR>) 185 186 /** 187 * {@inheritDoc} 188 */ 189 @Override 190 public final Wrapper<? extends OCamlFunction7<T0, T1, T2, T3, T4, T5, T6, TR>> getWrapper() { 191 return OCamlFunction7.wrapper(this.wrapper0, 192 this.wrapper1, 193 this.wrapper2, 194 this.wrapper3, 195 this.wrapper4, 196 this.wrapper5, 197 this.wrapper6, 198 this.wrapperr); 199 } // end method 'getWrapper()' 200 201 /** 202 * {@inheritDoc} 203 */ 204 @Override 205 public Wrapper<? extends OCamlValue> getWrapper(final int idx) { 206 switch (idx) { 207 case 0: return this.wrapper0; 208 case 1: return this.wrapper1; 209 case 2: return this.wrapper2; 210 case 3: return this.wrapper3; 211 case 4: return this.wrapper4; 212 case 5: return this.wrapper5; 213 case 6: return this.wrapper6; 214 case 7: return this.wrapperr; 215 default: return OCamlUnit.WRAPPER; 216 } // end switch 217 } // end method 'getWrapper(int)' 218 219 /** 220 * Returns the closure to be executed from the OCaml runtime. 221 * @param w0 wrapper for first parameter - should not be {@code null} 222 * @param w1 wrapper for second parameter - should not be {@code null} 223 * @param w2 wrapper for third parameter - should not be {@code null} 224 * @param w3 wrapper for fourth parameter - should not be {@code null} 225 * @param w4 wrapper for fifth parameter - should not be {@code null} 226 * @param w5 wrapper for sixth parameter - should not be {@code null} 227 * @param w6 wrapper for seventh parameter - should not be {@code null} 228 * @return the closure to be executed on the OCaml side 229 */ 230 public Value getClosure(final Wrapper<T0> w0, 231 final Wrapper<T1> w1, 232 final Wrapper<T2> w2, 233 final Wrapper<T3> w3, 234 final Wrapper<T4> w4, 235 final Wrapper<T5> w5, 236 final Wrapper<T6> w6) { 237 assert w0 != null : "null w0"; 238 assert w1 != null : "null w1"; 239 assert w2 != null : "null w2"; 240 assert w3 != null : "null w3"; 241 assert w4 != null : "null w4"; 242 assert w5 != null : "null w5"; 243 assert w6 != null : "null w6"; 244 final OCamlFunction7Caller<T0, T1, T2, T3, T4, T5, T6, TR> ofc = new OCamlFunction7Caller<>(w0, w1, w2, w3, w4, w5, w6, this); 245 return Value.createClosure(OCamlFunction7.METHOD_HANDLE.bindTo(ofc), 7); 246 } // end method 'getClosure(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<T6>)' 247 248 /** 249 * The actual implementation of the function 250 * @param p0 first parameter - should not be {@code null} 251 * @param p1 second parameter - should not be {@code null} 252 * @param p2 third parameter - should not be {@code null} 253 * @param p3 fourth parameter - should not be {@code null} 254 * @param p4 fifth parameter - should not be {@code null} 255 * @param p5 sixth parameter - should not be {@code null} 256 * @param p6 seventh parameter - should not be {@code null} 257 * @throws OCamlException if function fails 258 */ 259 public abstract TR execute(final T0 p0, 260 final T1 p1, 261 final T2 p2, 262 final T3 p3, 263 final T4 p4, 264 final T5 p5, 265 final T6 p6) 266 throws OCamlException; 267 268 /** 269 * {@inheritDoc} 270 */ 271 @Override 272 public final int hashCode() { 273 return super.hashCode(); 274 } // end method 'hashCode()' 275 276 /** 277 * {@inheritDoc} 278 */ 279 @Override 280 public final boolean equals(final Object obj) { 281 if (obj instanceof OCamlFunction7) { 282 final OCamlFunction7<?, ?, ?, ?, ?, ?, ?, ?> that = (OCamlFunction7) obj; 283 return this == that; 284 } else { 285 return false; 286 } // end if/else 287 } // end method 'equals(Object)' 288 289 /** 290 * {@inheritDoc} 291 */ 292 @Override 293 public final String toString() { 294 return "OCamlFunction7(...)"; 295 } // end method 'toString()' 296 297 /** 298 * Wraps the passed value. 299 * @param w0 wrapper for first parameter - should not be {@code null} 300 * @param w1 wrapper for second parameter - should not be {@code null} 301 * @param w2 wrapper for third parameter - should not be {@code null} 302 * @param w3 wrapper for fourth parameter - should not be {@code null} 303 * @param w4 wrapper for fifth parameter - should not be {@code null} 304 * @param w5 wrapper for sixth parameter - should not be {@code null} 305 * @param w6 wrapper for seventh parameter - should not be {@code null} 306 * @param wr wrapper for result - should not be {@code null} 307 * @param v value to wrap - should not be {@code null} 308 * @return a new {@code OCamlFunction7} instance wrapping the passed value 309 */ 310 public static <T0 extends OCamlValue, 311 T1 extends OCamlValue, 312 T2 extends OCamlValue, 313 T3 extends OCamlValue, 314 T4 extends OCamlValue, 315 T5 extends OCamlValue, 316 T6 extends OCamlValue, 317 TR extends OCamlValue> 318 OCamlFunction7<T0, T1, T2, T3, T4, T5, T6, TR> wrap(final Wrapper<T0> w0, 319 final Wrapper<T1> w1, 320 final Wrapper<T2> w2, 321 final Wrapper<T3> w3, 322 final Wrapper<T4> w4, 323 final Wrapper<T5> w5, 324 final Wrapper<T6> w6, 325 final Wrapper<TR> wr, 326 final Value v) { 327 assert w0 != null : "null w0"; 328 assert w1 != null : "null w1"; 329 assert w2 != null : "null w2"; 330 assert w3 != null : "null w3"; 331 assert w4 != null : "null w4"; 332 assert w5 != null : "null w5"; 333 assert w6 != null : "null w6"; 334 assert wr != null : "null wr"; 335 assert v != null : "null v"; 336 return new OCamlFunction7Impl<T0, T1, T2, T3, T4, T5, T6, TR>(w0, w1, w2, w3, w4, w5, w6, wr, v); 337 } // end method 'wrap(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<T6>, Wrapper<TR>, Value)' 338 339 /** 340 * Returns a wrapper for {@code OCamlFunction7} values. 341 * @param w0 wrapper for first parameter - should not be {@code null} 342 * @param w1 wrapper for second parameter - should not be {@code null} 343 * @param w2 wrapper for third parameter - should not be {@code null} 344 * @param w3 wrapper for fourth parameter - should not be {@code null} 345 * @param w4 wrapper for fifth parameter - should not be {@code null} 346 * @param w5 wrapper for sixth parameter - should not be {@code null} 347 * @param w6 wrapper for seventh parameter - should not be {@code null} 348 * @param wr wrapper for result - should not be {@code null} 349 * @return a wrapper for {@code OCamlFunction5} values 350 */ 351 @SuppressWarnings("unchecked") 352 public static <T0 extends OCamlValue, 353 T1 extends OCamlValue, 354 T2 extends OCamlValue, 355 T3 extends OCamlValue, 356 T4 extends OCamlValue, 357 T5 extends OCamlValue, 358 T6 extends OCamlValue, 359 TR extends OCamlValue> 360 Wrapper<? extends OCamlFunction7<T0, T1, T2, T3, T4, T5, T6, TR>> wrapper(final Wrapper<T0> w0, 361 final Wrapper<T1> w1, 362 final Wrapper<T2> w2, 363 final Wrapper<T3> w3, 364 final Wrapper<T4> w4, 365 final Wrapper<T5> w5, 366 final Wrapper<T6> w6, 367 final Wrapper<TR> wr) { 368 assert w0 != null : "null w0"; 369 assert w1 != null : "null w1"; 370 assert w2 != null : "null w2"; 371 assert w3 != null : "null w3"; 372 assert w4 != null : "null w4"; 373 assert w5 != null : "null w5"; 374 assert w6 != null : "null w6"; 375 assert wr != null : "null wr"; 376 return new ComposedWrapper<OCamlFunction7<T0, T1, T2, T3, T4, T5, T6, TR>>(w0, w1, w2, w3, w4, w5, w6, wr) { 377 /** 378 * {@inheritDoc} 379 */ 380 @Override 381 public OCamlFunction7<T0, T1, T2, T3, T4, T5, T6, TR> wrap(final Value v) { 382 return new OCamlFunction7Impl<T0, T1, T2, T3, T4, T5, T6, TR>(w0, w1, w2, w3, w4, w5, w6, wr, v); 383 } // end method 'wrap(Value)' 384 }; // end anonymous inner-class 385 } // end method 'wrapper(Wrapper<T0>, Wrapper<T1>, Wrapper<T2>, Wrapper<T3>, Wrapper<T4>, Wrapper<T5>, Wrapper<T6>, Wrapper<TR>)' 386 387} // end class 'OCamlFunction7'