projects: update some short descriptions
[nit.git] / lib / pnacl.nit
index 8f50fa1..89ff3cf 100644 (file)
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-#
-# Targets the PNaCl platform
+
+# Provides PNaCl support for Nit.
 #
 # To use this module and compile for PNaCl, you must install the
 # NaCl SDK (This file is based on Pepper 33).
 # If NACL_SDK_ROOT is not set in your PATH, you have to work in
 # 'nacl_sdk/pepper_your_pepper_version/getting_started/your_project_folder'.
-#
-# Provides PNaCl support for Nit.
 module pnacl is platform
-`{
-       #include <unistd.h>
-       #include <stddef.h>
-       #include <stdio.h>
-       #include <string.h>
-       #include <stdlib.h>
-       #include <pthread.h>
+
+import standard
+intrude import standard::stream
+
+in "C Header" `{
        #include "ppapi/c/pp_errors.h"
        #include "ppapi/c/ppp.h"
        #include "ppapi/c/ppp_instance.h"
@@ -39,6 +35,16 @@ module pnacl is platform
        #include "ppapi/c/ppp_messaging.h"
        #include "ppapi/c/ppb_var_dictionary.h"
        #include "ppapi/c/ppb_var_array.h"
+`}
+
+`{
+       #include <unistd.h>
+       #include <stddef.h>
+       #include <stdio.h>
+       #include <string.h>
+       #include <stdlib.h>
+       #include <pthread.h>
+       #include <poll.h>
 
        #define MAX_DICTIONARY_QUEUE_SIZE 200
        #define MAX_MESSAGE_QUEUE_SIZE 10
@@ -353,16 +359,16 @@ module pnacl is platform
        }
 
        /* Hack in order to avoid the problem with file. */
-       int poll(void *fds, int nfds, int timeout) { return 0; }
+       int poll(struct pollfd* fds, nfds_t nfds, int timeout) { return 0; }
 `}
 
 # Nit class representing a Pepper C API PP_Var typed as a Dictionary.
 extern class PepperDictionary `{ struct PP_Var* `}
 
        new `{
-               struct PP_Var* recv = malloc( sizeof( struct PP_Var ) );
-               *recv = g_varDictionaryInterface->Create();
-               return recv;
+               struct PP_Var* self = malloc( sizeof( struct PP_Var ) );
+               *self = g_varDictionaryInterface->Create();
+               return self;
        `}
 
        # Get fonction using PepperVars.
@@ -371,7 +377,7 @@ extern class PepperDictionary `{ struct PP_Var* `}
        # If 'key' is not a String typed PepperVar, or doesn't exist in the Dictionary, an undefined PepperVar is returned.
        fun native_get(key: PepperVar): PepperVar `{
                struct PP_Var* value = malloc( sizeof ( struct PP_Var ) );
-               *value = g_varDictionaryInterface->Get(*recv, *key);
+               *value = g_varDictionaryInterface->Get(*self, *key);
                return value;
        `}
 
@@ -395,7 +401,7 @@ extern class PepperDictionary `{ struct PP_Var* `}
        # Returns a Boolean indicating whether the operation succeeds.
        fun native_set(key: PepperVar, value: PepperVar): Bool `{
                PP_Bool b;
-               b = g_varDictionaryInterface->Set(*recv, *key, *value);
+               b = g_varDictionaryInterface->Set(*self, *key, *value);
                return b;
        `}
 
@@ -416,7 +422,7 @@ extern class PepperDictionary `{ struct PP_Var* `}
        #
        # Takes a String typed PepperVar.
        fun native_delete(key: PepperVar) `{
-               g_varDictionaryInterface->Delete(*recv, *key);
+               g_varDictionaryInterface->Delete(*self, *key);
        `}
        
        # Deletes the specified key and its associated value, if the key exists.
@@ -433,7 +439,7 @@ extern class PepperDictionary `{ struct PP_Var* `}
        # Takes a String typed PepperVar.
        fun native_has_key(key: PepperVar): Bool `{
                PP_Bool b;
-               b = g_varDictionaryInterface->HasKey(*recv, *key);
+               b = g_varDictionaryInterface->HasKey(*self, *key);
                return b;
        `}
 
@@ -451,7 +457,7 @@ extern class PepperDictionary `{ struct PP_Var* `}
        # Returns a PepperArray which contains all the keys of the Dictionary. The elements are string vars.
        fun get_keys: PepperArray `{
                struct PP_Var* array = malloc( sizeof( struct PP_Var ) );
-               *array = g_varDictionaryInterface->GetKeys(*recv);
+               *array = g_varDictionaryInterface->GetKeys(*self);
                return array;
        `}
 
@@ -459,7 +465,7 @@ extern class PepperDictionary `{ struct PP_Var* `}
        fun copy: PepperDictionary `{
                struct PP_Var* varDictionary = malloc( sizeof( struct PP_Var ) );
                *varDictionary = g_varDictionaryInterface->Create();
-               *varDictionary = *recv;
+               *varDictionary = *self;
                return varDictionary;
        `}
 end
@@ -468,9 +474,9 @@ end
 extern class PepperArray `{ struct PP_Var* `}
 
        new `{
-               struct PP_Var* recv = malloc( sizeof( struct PP_Var ) );
-               *recv = g_varArrayInterface->Create();
-               return recv;
+               struct PP_Var* self = malloc( sizeof( struct PP_Var ) );
+               *self = g_varArrayInterface->Create();
+               return self;
        `}
 
        # Returns the element at the specified position as a PepperVar.
@@ -478,7 +484,7 @@ extern class PepperArray `{ struct PP_Var* `}
        # If 'index' is larger than or equal to the array length, an undefined PepperVar is returned.
        fun native_get(index: Int): PepperVar `{
                struct PP_Var* value = malloc( sizeof( struct PP_Var ) );
-               *value = g_varArrayInterface->Get(*recv, index);
+               *value = g_varArrayInterface->Get(*self, index);
                return value;
        `}
 
@@ -493,7 +499,7 @@ extern class PepperArray `{ struct PP_Var* `}
 
        # Returns an int containing the length of the PepperArray.
        fun length: Int `{
-               int length = g_varArrayInterface->GetLength(*recv);
+               int length = g_varArrayInterface->GetLength(*self);
                return length;
        `}
 
@@ -505,7 +511,7 @@ extern class PepperArray `{ struct PP_Var* `}
        # Returns a Boolean indicating whether the operation succeeds.
        fun native_set(index: Int, value: PepperVar): Bool `{
                PP_Bool b;
-               b = g_varArrayInterface->Set(*recv, index, *value);
+               b = g_varArrayInterface->Set(*self, index, *value);
                return b;
        `}
 
@@ -528,7 +534,7 @@ extern class PepperArray `{ struct PP_Var* `}
        # Returns a Boolean indicating whether the operation succeeds.
        fun length=(length: Int): Bool `{
                PP_Bool b;
-               b = g_varArrayInterface->SetLength(*recv, length);
+               b = g_varArrayInterface->SetLength(*self, length);
                return b;
        `}
 end
@@ -555,19 +561,19 @@ extern class PepperVar `{ struct PP_Var* `}
                return null
        end
 
-       private fun isa_null: Bool `{ return recv->type == PP_VARTYPE_NULL; `}
-       private fun isa_bool: Bool `{ return recv->type == PP_VARTYPE_BOOL; `}
-       private fun isa_int: Bool `{ return recv->type == PP_VARTYPE_INT32; `}
-       private fun isa_float: Bool `{ return recv->type == PP_VARTYPE_DOUBLE; `}
-       private fun isa_string: Bool `{ return recv->type == PP_VARTYPE_STRING; `}
-       private fun is_undefined: Bool `{ return recv->type == PP_VARTYPE_UNDEFINED; `}
+       private fun isa_null: Bool `{ return self->type == PP_VARTYPE_NULL; `}
+       private fun isa_bool: Bool `{ return self->type == PP_VARTYPE_BOOL; `}
+       private fun isa_int: Bool `{ return self->type == PP_VARTYPE_INT32; `}
+       private fun isa_float: Bool `{ return self->type == PP_VARTYPE_DOUBLE; `}
+       private fun isa_string: Bool `{ return self->type == PP_VARTYPE_STRING; `}
+       private fun is_undefined: Bool `{ return self->type == PP_VARTYPE_UNDEFINED; `}
 
-       private fun as_bool: Bool `{ return recv->value.as_bool; `}
-       private fun as_int: Int `{ return recv->value.as_int; `}
-       private fun as_float: Float `{ return recv->value.as_double; `}
+       private fun as_bool: Bool `{ return self->value.as_bool; `}
+       private fun as_int: Int `{ return self->value.as_int; `}
+       private fun as_float: Float `{ return self->value.as_double; `}
        private fun as_string: String import NativeString.to_s_with_length `{
                uint32_t len;
-               char* str = (char*)g_varInterface->VarToUtf8(*recv, &len);
+               char* str = (char*)g_varInterface->VarToUtf8(*self, &len);
                return NativeString_to_s_with_length(str, len);
        `}
 end
@@ -583,7 +589,7 @@ redef class Int
        # Converts a Int into a PepperVar with Int type.
        redef fun to_pepper `{
                struct PP_Var* var = malloc( sizeof( struct PP_Var ) );
-               *var = PP_MakeInt32(recv);
+               *var = PP_MakeInt32(self);
                return var;
        `}
 end
@@ -594,7 +600,7 @@ redef class Float
        # Converts a Float into a PepperVar with Float type.
        redef fun to_pepper `{
                struct PP_Var* var = malloc( sizeof( struct PP_Var ) );
-               *var = PP_MakeDouble(recv);
+               *var = PP_MakeDouble(self);
                return var;
        `}
 end
@@ -605,7 +611,7 @@ redef class Bool
        # Converts a Bool into a PepperVar with Bool type.
        redef fun to_pepper `{
                struct PP_Var* var = malloc( sizeof( struct PP_Var ) );
-               *var = PP_MakeBool(recv);
+               *var = PP_MakeBool(self);
                return var;
        `}
 end
@@ -615,18 +621,18 @@ redef class String
 
        # Converts a String into a PepperVar with String type.
        redef fun to_pepper: PepperVar import String.to_cstring, String.length `{
-               char *str = String_to_cstring(recv);
+               char *str = String_to_cstring(self);
                struct PP_Var* var = malloc( sizeof( struct PP_Var ) );
-               *var = g_varInterface->VarFromUtf8(str, String_length(recv));
+               *var = g_varInterface->VarFromUtf8(str, String_length(self));
                return var;
        `}
 end
 
 # A stream for PNaCl, redefines basic input and output methods.
 class PnaclStream
-       super PollableIStream
-       super OStream
-       super BufferedIStream
+       super PollableReader
+       super Writer
+       super BufferedReader
 
        init do prepare_buffer(10)
 
@@ -647,9 +653,11 @@ class PnaclStream
        # fill_buffer now checks for a message in the message queue which is filled by user inputs.
        redef fun fill_buffer
        do
-               _buffer.clear
                _buffer_pos = 0
-               _buffer.append check_message.to_s
+               var nns = check_message
+               var nslen = nns.cstring_length
+               _buffer_length = nslen
+               nns.copy_to(buffer, nslen, 0, 0)
        end
 end
 
@@ -672,7 +680,7 @@ class PnaclApp
 
        # Sets everything up to work, need to be called at first.
        fun initialize import PnaclApp.handle_message, PnaclApp.handle_dictionary, NativeString.to_s_with_length `{
-               app = recv;
+               app = self;
        `}
 
        # Posts a message to JS.
@@ -712,9 +720,44 @@ class PnaclApp
 
        # Checks if there is a dictionary in the queue, and if so the dictionary is handled automatically.
        fun check_dictionary `{
-               while(1) {
-                       NitHandleDictionary();
-               }
+               NitHandleDictionary();
        `}
+
+       # Infinite loop on check_dictionary
+       fun run
+       do
+               loop
+                       check_dictionary
+               end
+       end
+end
+
+# Creates a new thread for Nit.
+#
+# This function launches the Nit main on a new thread.
+# Its purpose is to allow Nit to be still operational after an exit when needed,
+# because reloading the page may not be an option.
+#
+# Should only be used within the 'exit' before stopping the current thread
+# when the Nit execution causes a crash.
+#
+# REQUIRE: g_nit_thread and WrapperNitMain are set.
+fun create_thread `{
+       pthread_create(&g_nit_thread, NULL, &WrapperNitMain, NULL);
+`}
+
+# Calls 'pthread_exit on current thread.
+fun exit_thread(exit_value: Int) `{
+       pthread_exit((void*) exit_value);
+`}
+
+# Redef of exit in order to avoid the module to crash by terminating only the Nit thread.
+redef fun exit(exit_value: Int)
+do
+       var dictionary = new PepperDictionary
+       dictionary["exit"] = exit_value
+       app.post_dictionary dictionary
+       exit_thread exit_value
 end
+
 fun app: PnaclApp do return once new PnaclApp