package org.perl6.rakudo;

import org.perl6.nqp.runtime.*;
import org.perl6.nqp.sixmodel.*;

/**
 * Contains implementation of nqp:: ops specific to Rakudo Perl 6.
 */
public final class Ops {
    private static SixModelObject Code;
    private static SixModelObject Signature;
    public static SixModelObject Parameter;
    private static SixModelObject False;
    private static SixModelObject True;
    private static boolean initialized = false;
    
    /* Parameter hints for fast lookups. */
    private static final int HINT_CODE_DO = 0;
    private static final int HINT_CODE_SIG = 1;
    private static final int HINT_SIG_PARAMS = 0;
    
    public static SixModelObject p6init(ThreadContext tc) {
        if (!initialized) {
            tc.gc.contConfigs.put("rakudo_scalar", new RakudoContainerConfigurer());
            initialized = true;
        }
        return null;
    }
    
    public static SixModelObject p6settypes(SixModelObject conf, ThreadContext tc) {
        Code = conf.at_key_boxed(tc, "Code");
        Signature = conf.at_key_boxed(tc, "Signature");
        Parameter = conf.at_key_boxed(tc, "Parameter");
        False = conf.at_key_boxed(tc, "False");
        True = conf.at_key_boxed(tc, "True");
        return conf;
    }
    
    public static SixModelObject booleanize(int x) {
        return x == 0 ? False : True;
    }
    
    public static CallSiteDescriptor p6bindsig(ThreadContext tc, CallSiteDescriptor csd, Object[] args) {
        /* Do any flattening before processing begins. */
        CallFrame cf = tc.curFrame;
        if (csd.hasFlattening) {
            csd = csd.explodeFlattening(cf, args);
            args = tc.flatArgs;
        }
        else {
            tc.flatArgs = args;
        }
        
        /* Look up parameters to bind. */
        SixModelObject sig = cf.codeRef.codeObject
            .get_attribute_boxed(tc, Code, "$!signature", HINT_CODE_SIG);
        SixModelObject params = sig
            .get_attribute_boxed(tc, Signature, "$!params", HINT_SIG_PARAMS);
        
        /* Run binder, and handle any errors. */
        switch (Binder.bind(tc, cf, params, csd, args, false, true)) {
            case Binder.BIND_RESULT_FAIL:
                throw ExceptionHandling.dieInternal(tc, Binder.lastError(tc));
            case Binder.BIND_RESULT_JUNCTION:
                throw ExceptionHandling.dieInternal(tc, "Junction re-dispatch NYI");
        }
        
        return csd;
    }
}

@@ -186,16 +186,58 @@
 s Ops %7B%0A
+    private static SixModelObject Parcel;%0A
     priv
@@ -268,16 +268,16 @@
 t Code;%0A
-
     priv
@@ -531,24 +531,78 @@
 lookups. */%0A
+    private static final int HINT_PARCEL_STORAGE = 0;%0A
     private 
@@ -1063,32 +1063,82 @@
 adContext tc) %7B%0A
+        Parcel = conf.at_key_boxed(tc, %22Parcel%22);%0A
         Code = c
@@ -2572,32 +2572,32 @@
      %7D%0A        %0A
-
         return c
@@ -2606,10 +2606,595 @@
 ;%0A    %7D%0A
+    %0A    public static SixModelObject p6parcel(SixModelObject array, SixModelObject fill, ThreadContext tc) %7B%0A        SixModelObject parcel = Parcel.st.REPR.allocate(tc, Parcel.st);%0A        parcel.initialize(tc);%0A        parcel.bind_attribute_boxed(tc, Parcel, %22$!storage%22, HINT_PARCEL_STORAGE, array);%0A%0A        if (fill != null) %7B%0A            long elems = array.elems(tc);%0A            for (long i = 0; i %3C elems; i++) %7B%0A                if (array.at_pos_boxed(tc, i) == null)%0A                    array.bind_pos_boxed(tc, i, fill);%0A            %7D%0A        %7D%0A%0A        return parcel;%0A    %7D%0A
 %7D%0A

Implement nqp::p6parcel on JVM.