Added 'create_thread' function to enable thread creation after a exit.
Pull-Request: #519
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>
Reviewed-by: Jean Privat <jean@pryen.org>
Clement de Figueiredo <clement.defigueiredo@gmail.com>
Christophe Gigax <christophe.gigax@viacesi.fr>
+
+Julien Pagès <julien.projet@gmail.com>
--- /dev/null
+#!/bin/bash
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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.
+
+# Common functions for all the bench scripts
+
+# Run a single command multiple time and store the execution times
+# in the current $res file.
+#
+# $1: title of the command
+# $2: long desription of the command
+# rest: the command to execute
+function bench_command()
+{
+ if [ "$dry_run" = "true" ]; then return; fi
+ local title="$1"
+ local desc="$2"
+ shift
+ shift
+ if test "$verbose" = true; then outputopts="/dev/stdout"; else outputopts="/dev/null"; fi
+ timeout="time.out"
+ echo "$title" > "$timeout"
+ echo "# $desc" >> "$timeout"
+ echo "\$ $@" >> "$timeout"
+ echo
+ echo "** [$title] $desc **"
+ echo " $ $@"
+
+ # Execute the commands $count times
+ for i in `seq 1 "$count"`; do
+ /usr/bin/time -f "%U" -o "$timeout" -a "$@" > $outputopts 2>&1 || die "$1: failed"
+ echo -n "$i. "
+ tail -n 1 "$timeout"
+ done
+
+ line=`compute_stats "$timeout"`
+ echo "$line ($res)"
+ echo $line >> "$res"
+}
+
+# Run a simble command witout storing the execution time
+# Used to display command on verbose and skip long executions when dry_run is given
+# $@ command to execute
+function run_command()
+{
+ if [ "$dry_run" = "true" ]; then return; fi
+ echo " $ $@"
+ "$@" || die "$@: failed"
+}
+
+# Check if the test should be skiped according to its name
+# $1: name of the test
+# $2: description of the test
+# $NOTSKIPED: arguments
+function skip_test()
+{
+ if test -z "$NOTSKIPED"; then
+ echo "* $1"
+ return 0
+ fi
+ if test "$NOTSKIPED" = "all"; then
+ : # Execute anyway
+ elif echo "$1" | egrep "$NOTSKIPED" >/dev/null 2>&1; then
+ : # Found one to execute
+ else
+ return 0
+ fi
+ if test -n "$html"; then
+ echo >>"$html" "<h2>$1</h2>"
+ fi
+ echo "*"
+ echo "* $1 *****"
+ echo "*"
+ return 1
+}
+
# TODO: cleanup and libify the helper-parts
+source ./bench_common.sh
source ./bench_plot.sh
## CONFIGURATION OPTIONS ##
died=1
}
-# Run a single command multiple time and store the execution times
-# in the current $res file.
-#
-# $1: title of the command
-# $2: long desription of the command
-# rest: the command to execute
-function bench_command()
-{
- if [ "$dry_run" = "true" ]; then return; fi
- local title="$1"
- local desc="$2"
- shift
- shift
- if test "$verbose" = true; then outputopts="/dev/stdout"; else outputopts="/dev/null"; fi
- timeout="time.out"
- echo "$title" > "$timeout"
- echo "# $desc" >> "$timeout"
- echo "\$ $@" >> "$timeout"
- echo
- echo "** [$title] $desc **"
- echo " $ $@"
-
- # Execute the commands $count times
- for i in `seq 1 "$count"`; do
- /usr/bin/time -f "%U" -o "$timeout" -a "$@" > $outputopts 2>&1 || die "$1: failed"
- echo -n "$i. "
- tail -n 1 "$timeout"
- done
-
- line=`compute_stats "$timeout"`
- echo "$line ($res)"
- echo $line >> "$res"
-}
-
-# Run a simble command witout storing the execution time
-# Used to display command on verbose and skip long executions when dry_run is given
-# $@ command to execute
-function run_command()
-{
- if [ "$dry_run" = "true" ]; then return; fi
- echo " $ $@"
- "$@" || die "$@: failed"
-}
-
-# Check if the test should be skiped according to its name
-# $1: name of the test
-# $2: description of the test
-# $NOTSKIPED: arguments
-function skip_test()
-{
- if test -z "$NOTSKIPED"; then
- echo "* $1"
- return 0
- fi
- if test "$NOTSKIPED" = "all"; then
- : # Execute anyway
- elif echo "$1" | egrep "$NOTSKIPED" >/dev/null 2>&1; then
- : # Found one to execute
- else
- return 0
- fi
- if test -n "$html"; then
- echo >>"$html" "<h2>$1</h2>"
- fi
- echo "*"
- echo "* $1 *****"
- echo "*"
- return 1
-}
-
# HELPER FOR NIT #
# Run standards benchs on a compiler command
# TODO: cleanup and libify the helper-parts
+source ./bench_common.sh
source ./bench_plot.sh
## CONFIGURATION OPTIONS ##
died=1
}
-# Run a single command multiple time and store the execution times
-# in the current $res file.
-#
-# $1: title of the command
-# $2: long desription of the command
-# rest: the command to execute
-function bench_command()
-{
- if [ "$dry_run" = "true" ]; then return; fi
- local title="$1"
- local desc="$2"
- shift
- shift
- if test "$verbose" = true; then outputopts="/dev/stdout"; else outputopts="/dev/null"; fi
- timeout="time.out"
- echo "$title" > "$timeout"
- echo "# $desc" >> "$timeout"
- echo "\$ $@" >> "$timeout"
- echo
- echo "** [$title] $desc **"
- echo " $ $@"
-
- # Execute the commands $count times
- for i in `seq 1 "$count"`; do
- (ulimit -t 300; /usr/bin/time -f "%U" -o "$timeout" -a "$@") > $outputopts 2>&1 || die "$1: failed"
- echo -n "$i. "
- tail -n 1 "$timeout"
- done
-
- line=`compute_stats "$timeout"`
- echo "$line ($res)"
- echo $line >> "$res"
- rm $timeout
-}
-
-# Run a simple command witout storing the execution time
-# Used to display command on verbose and skip long executions when dry_run is given
-# $@ command to execute
-function run_command()
-{
- if [ "$dry_run" = "true" ]; then return; fi
- echo " $ $@"
- (ulimit -t 180; "$@") || die "$@: failed"
-}
-
-# Check if the test should be skiped according to its name
-# $1: name of the test
-# $2: description of the test
-# $NOTSKIPED: arguments
-function skip_test()
-{
- if test -z "$NOTSKIPED"; then
- echo "* $1"
- return 0
- fi
- if test "$NOTSKIPED" = "all"; then
- : # Execute anyway
- elif echo "$1" | egrep "$NOTSKIPED" >/dev/null 2>&1; then
- : # Found one to execute
- else
- return 0
- fi
- echo "*"
- echo "* $1 *****"
- echo "*"
- return 1
-}
-
## HANDLE OPTIONS ##
function usage()
CC = ccache cc
-CFLAGS = -g -O2
+CFLAGS = -g -O2 -Wno-unused-value -Wno-switch
CINCL = -I "clib"
LDFLAGS ?=
-LDLIBS ?= -lm -lgc -lunwind
+LDLIBS ?= -lm -lgc
+
+NEED_LIBUNWIND := YesPlease
+uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
+ifeq ($(uname_S),Darwin)
+ NEED_LIBUNWIND :=
+endif
+
+clang_check := $(shell sh -c '$(CC) -v 2>&1 | grep -q clang; echo $$?')
+ifeq ($(clang_check), 0)
+ CFLAGS += -Qunused-arguments
+endif
+ifdef NEED_LIBUNWIND
+ LDLIBS += -lunwind
+endif
all: nitg
# The class can also be specialized to provide more specific behavior.
class OrderedTree[E: Object]
super Streamable
+ super Collection[E]
# Sequence
var roots = new Array[E]
#
# Subclasses should redefine this method to provide a specific output
fun display(e: E): String do return e.to_s
+
+ # Get an array of the contained elements
+ # Order is preserved
+ #
+ # var tree = new OrderedTree[Int]
+ # tree.add(null, 1)
+ # tree.add(1, 11)
+ # tree.add(11, 111)
+ # tree.add(11, 112)
+ # tree.add(1, 12)
+ # tree.add(12, 121)
+ # tree.add(12, 122)
+ # tree.add(null, 2)
+ # tree.add(2, 21)
+ # tree.add(2, 22)
+ # assert tree.to_a == [1, 11, 111, 112, 12, 121, 122, 2, 21, 22]
+ redef fun to_a: Array[E] do
+ var res = new Array[E]
+ for r in roots do sub_to_a(r, res)
+ return res
+ end
+
+ private fun sub_to_a(e: E, res: Array[E]) do
+ res.add e
+ if sub.has_key(e) then for e2 in sub[e] do sub_to_a(e2, res)
+ end
+
+ # var tree = new OrderedTree[Int]
+ # assert tree.is_empty
+ # tree.add(null, 1)
+ # assert not tree.is_empty
+ redef fun is_empty: Bool do return roots.is_empty
+
+ # var tree = new OrderedTree[Int]
+ # tree.add(null, 1)
+ # tree.add(1, 11)
+ # assert tree.first == 1
+ redef fun first do return roots.first
+
+ # var tree = new OrderedTree[Int]
+ # tree.add(null, 1)
+ # tree.add(1, 11)
+ # tree.add(11, 111)
+ # tree.add(11, 112)
+ # tree.add(1, 12)
+ # tree.add(12, 121)
+ # tree.add(12, 122)
+ # tree.add(null, 2)
+ # tree.add(2, 21)
+ # tree.add(2, 22)
+ # var order = [1, 11, 111, 112, 12, 121, 122, 2, 21, 22]
+ # var res = new Array[Int]
+ # for i in tree do res.add(i)
+ # assert res == order
+ redef fun iterator do return new OrderedTreeIterator[E](self)
+end
+
+# An Iterator over an OrderedTree
+private class OrderedTreeIterator[E: Object]
+ super Iterator[E]
+
+ var tree: OrderedTree[E]
+
+ var iterators = new Array[Iterator[E]]
+
+ init(tree: OrderedTree[E]) do
+ self.tree = tree
+
+ if not tree.is_empty then
+ iterators.add tree.roots.iterator
+ end
+ end
+
+ redef fun is_ok do return not iterators.is_empty
+
+ redef fun item do
+ assert is_ok
+ return iterators.last.item
+ end
+
+ redef fun next do
+ assert is_ok
+ if tree.sub.has_key(item) then
+ iterators.add tree.sub[item].iterator
+ else
+ iterators.last.next
+ while is_ok and not iterators.last.is_ok do
+ iterators.pop
+ if is_ok and iterators.last.is_ok then
+ iterators.last.next
+ end
+ end
+ end
+ end
+
+ redef fun iterator do return new OrderedTreeIterator[E](tree)
end
end
end
+redef class FlatText
+ fun to_dot(s: String): String is abstract
+end
+
redef class FlatString
- fun to_dot(s: String): String
+ redef fun to_dot(s: String): String
do
return s + "n{object_id} [label=\"FlatString\\nindex_from = {index_from}\\nindex_to = {index_to}\\nNativeString = {items.to_s_with_length(items.cstring_length)}\"];\n"
end
end
+redef class FlatBuffer
+ redef fun to_dot(s: String): String
+ do
+ return s + "n{object_id} [label=\"FlatBuffer\\length = {length}\\ncapacity = {capacity}\\nitems = {items.to_s_with_length(items.cstring_length)}\"];\n"
+ end
+end
+
redef class RopeString
redef fun to_dot(filepath: String)
do
private abstract class RopeNode
# Length of the node
var length = 0
+
+ # Transforms the current node to a Leaf.
+ # This might be costly to invoke since this produces a FlatString concatenation.
+ # Can be used internally to limit the growth of the Rope when working with small leaves.
+ fun to_leaf: Leaf is abstract
end
# Node that represents a concatenation between two nodes (of any RopeNode type)
super RopeNode
# Left child of the node
- var _left: nullable RopeNode = null
+ var left: nullable RopeNode
# Right child of the node
- var _right: nullable RopeNode = null
-
- fun left: nullable RopeNode do return _left
- fun right: nullable RopeNode do return _right
+ var right: nullable RopeNode
- fun left=(l: RopeNode)
+ init(l: nullable RopeNode, r: nullable RopeNode)
do
- _left = l
- length = l.length
- if _right != null then length += _right.length
+ left = l
+ right = r
+ if l != null then length += l.length
+ if r != null then length += r.length
end
- fun right=(r: RopeNode)
+ redef fun to_leaf
do
- _right = r
- length = r.length
- if _left != null then length += _left.length
+ if left == null then
+ if right == null then return new StringLeaf("".as(FlatString))
+ return right.to_leaf
+ end
+ if right == null then return left.as(not null).to_leaf
+ return new StringLeaf((left.to_leaf.str.as(FlatString) + right.to_leaf.str.as(FlatString)).as(FlatString))
end
end
# Leaf of a Rope, contains a FlatString
-private class Leaf
+private abstract class Leaf
super RopeNode
# Encapsulated FlatString in the leaf node
- var str: FlatString
+ var str: FlatText
+
+end
+
+private class StringLeaf
+ super Leaf
init(val: FlatString) do
self.str = val
length = str.length
end
+ redef fun to_leaf do return self
end
# Basic structure, binary tree with a root node.
# Creates a new Rope with `s` as root
init from(s: String) do
- if s isa RopeString then root = s.root else root = new Leaf(s.as(FlatString))
+ if s isa RopeString then root = s.root else root = new StringLeaf(s.as(FlatString))
end
private init from_root(r: RopeNode)
var path = node_at(pos)
- var last_concat = new Concat
+ var last_concat: Concat
if path.offset == 0 then
- last_concat.right = path.leaf
- if str isa FlatString then last_concat.left = new Leaf(str) else last_concat.left = str.as(RopeString).root
+ if str isa FlatString then
+ last_concat = new Concat(new StringLeaf(str), path.leaf)
+ else
+ last_concat = new Concat(str.as(RopeString).root, path.leaf)
+ end
else if path.offset == path.leaf.length then
- if str isa FlatString then last_concat.right = new Leaf(str) else last_concat.right = str.as(RopeString).root
- last_concat.left = path.leaf
+ if str isa FlatString then
+ last_concat = new Concat(path.leaf, new StringLeaf(str))
+ else
+ last_concat = new Concat(path.leaf, str.as(RopeString).root)
+ end
else
var s = path.leaf.str
var l_half = s.substring(0, s.length - path.offset)
var r_half = s.substring_from(s.length - path.offset)
- var cct = new Concat
- cct.right = new Leaf(r_half.as(FlatString))
- last_concat.left = new Leaf(l_half.as(FlatString))
- if str isa FlatString then last_concat.right = new Leaf(str) else last_concat.right = str.as(RopeString).root
- cct.left = last_concat
- last_concat = cct
+ var cct: Concat
+ var ll = new StringLeaf(l_half.as(FlatString))
+ if str isa FlatString then
+ cct = new Concat(ll, new StringLeaf(str))
+ else
+ cct = new Concat(ll, str.as(RopeString).root)
+ end
+ last_concat = new Concat(cct, new StringLeaf(r_half.as(FlatString)))
end
for i in path.stack.reverse_iterator do
- var nod = new Concat
if i.left then
- nod.right = i.node.right.as(not null)
- nod.left = last_concat
+ last_concat = new Concat(last_concat, i.node.right)
else
- nod.left = i.node.left.as(not null)
- nod.right = last_concat
+ last_concat = new Concat(i.node.left, last_concat)
end
- last_concat = nod
end
return new RopeString.from_root(last_concat)
# Builds a new path from root to the rightmost node with s appended
private fun append_to_path(node: RopeNode, s: String): RopeNode
do
- var cct = new Concat
+ var cct: Concat
if node isa Leaf then
- cct.left = node
- if s isa FlatString then cct.right = new Leaf(s) else cct.right = s.as(RopeString).root
- else if node isa Concat then
- var right = node.right
- if node.left != null then cct.left = node.left.as(not null)
+ if s isa FlatString then
+ cct = new Concat(node, new StringLeaf(s))
+ else
+ cct = new Concat(node, s.as(RopeString).root)
+ end
+ else
+ var n = node.as(Concat)
+ var right = n.right
+ var lft = n.left.as(not null)
if right == null then
- if s isa FlatString then cct.right = new Leaf(s) else cct.right = s.as(RopeString).root
+ if s isa FlatString then
+ cct = new Concat(lft, new StringLeaf(s))
+ else
+ cct = new Concat(lft, s.as(RopeString).root)
+ end
else
- cct.right = append_to_path(right, s)
+ cct = new Concat(lft, append_to_path(right, s))
end
end
return cct
var lf = path.leaf
var offset = path.offset
- if path.leaf.str.length - offset > len then lf = new Leaf(lf.str.substring(offset,len).as(FlatString)) else lf = new Leaf(lf.str.substring_from(offset).as(FlatString))
+ if path.leaf.str.length - offset > len then lf = new StringLeaf(lf.str.substring(offset,len).as(FlatString)) else lf = new StringLeaf(lf.str.substring_from(offset).as(FlatString))
var nod: RopeNode = lf
for i in path.stack.reverse_iterator do
if i.right then continue
- var tmp = new Concat
- tmp.left = nod
- var r = i.node.right
- if r != null then tmp.right = r
- nod = tmp
+ nod = new Concat(nod, i.node.right)
end
var ret = new RopeString
path = ret.node_at(len-1)
offset = path.offset
- nod = new Leaf(path.leaf.str.substring(0, offset+1).as(FlatString))
+ nod = new StringLeaf(path.leaf.str.substring(0, offset+1).as(FlatString))
for i in path.stack.reverse_iterator do
if i.left then continue
- var tmp = new Concat
- tmp.right = nod
- var l = i.node.left
- if l != null then tmp.left = l
- nod = tmp
+ nod = new Concat(i.node.left, nod)
end
ret.root = nod
# limitations under the License.
NITCOPT=
+OLDNITCOPT= --no-stacktrace
all: ../bin/nitdoc ../bin/nitmetrics ../bin/nitg ../bin/nit ../bin/nitx ../bin/nitunit ../bin/nitlight ../bin/nitls ../bin/nitdbg_client
@echo '* Compile nitg_0 from NIT source files *'
@echo '***************************************************************'
./git-gen-version.sh
- ../c_src/nitg ${NITCOPT} -o nitg_0 -v nitg.nit
+ ../c_src/nitg ${OLDNITCOPT} -o nitg_0 -v nitg.nit
../bin/nitg: nitg_0 parser/parser.nit
@echo '***************************************************************'
if libs != null then linker_options.add_all(libs)
end
+ makefile.write("CC = ccache cc\nCFLAGS = -g -O2 -Wno-unused-value -Wno-switch\nCINCL = {cc_includes}\nLDFLAGS ?= \nLDLIBS ?= -lm -lgc {linker_options.join(" ")}\n\n")
+
var ost = toolcontext.opt_stacktrace.value
- if ost == "libunwind" or ost == "nitstack" then linker_options.add("-lunwind")
+ if ost == "libunwind" or ost == "nitstack" then makefile.write("NEED_LIBUNWIND := YesPlease\n")
+
+ # Dynamic adaptations
+ # While `platform` enable complex toolchains, they are statically applied
+ # For a dynamic adaptsation of the compilation, the generated Makefile should check and adapt things itself
+
+ # Check and adapt the targeted system
+ makefile.write("uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')\n")
+ makefile.write("ifeq ($(uname_S),Darwin)\n")
+ # remove -lunwind since it is already included on macosx
+ makefile.write("\tNEED_LIBUNWIND :=\n")
+ makefile.write("endif\n\n")
+
+ # Check and adapt for the compiler used
+ # clang need an additionnal `-Qunused-arguments`
+ makefile.write("clang_check := $(shell sh -c '$(CC) -v 2>&1 | grep -q clang; echo $$?')\nifeq ($(clang_check), 0)\n\tCFLAGS += -Qunused-arguments\nendif\n")
+
+ makefile.write("ifdef NEED_LIBUNWIND\n\tLDLIBS += -lunwind\nendif\n")
- makefile.write("CC = ccache cc\nCFLAGS = -g -O2\nCINCL = {cc_includes}\nLDFLAGS ?= \nLDLIBS ?= -lm -lgc {linker_options.join(" ")}\n\n")
makefile.write("all: {outpath}\n\n")
var ofiles = new Array[String]
intrude import local_var_init
intrude import scope
intrude import toolcontext
-import websocket
redef class Model
# Cleans the model to remove a module and what it defines when semantic analysis fails on injected code
# -c
var opt_debugger_autorun: OptionBool = new OptionBool("Launches the target program with the interpreter, such as when the program fails, the debugging prompt is summoned", "-c")
- # --socket
- var opt_socket_mode = new OptionBool("Launches the target program with raw output on the network via sockets", "--socket")
-
- # --websocket
- var opt_websocket_mode = new OptionBool("Launches the target program with output on the network via websockets", "--websocket")
-
- # --port
- var opt_debug_port: OptionInt = new OptionInt("Sets the debug port (Defaults to 22125) - Must be contained between 0 and 65535", 22125, "--port")
-
redef init
do
super
self.option_context.add_option(self.opt_debugger_mode)
self.option_context.add_option(self.opt_debugger_autorun)
- self.option_context.add_option(self.opt_socket_mode)
- self.option_context.add_option(self.opt_websocket_mode)
- self.option_context.add_option(self.opt_debug_port)
end
end
var interpreter = new Debugger(self, mainmodule, arguments)
- set_stdstreams
-
init_naive_interpreter(interpreter, mainmodule)
- close_stdstreams
-
var time1 = get_time
self.toolcontext.info("*** END INTERPRETING: {time1-time0} ***", 2)
end
var interpreter = new Debugger(self, mainmodule, arguments)
interpreter.autocontinue = true
- set_stdstreams
-
init_naive_interpreter(interpreter, mainmodule)
- close_stdstreams
-
var time1 = get_time
self.toolcontext.info("*** END INTERPRETING: {time1-time0} ***", 2)
end
-
- redef fun run_naive_interpreter(mmod, args)
- do
- set_stdstreams
- super
- end
-
- fun set_stdstreams
- do
- if self.toolcontext.opt_socket_mode.value then
- var sock = new Socket.server(toolcontext.opt_debug_port.value, 1)
- var ns = sock.accept
- sock.close
- sys.set_io(ns,ns,ns)
- else if self.toolcontext.opt_websocket_mode.value then
- var websock = new WebSocket(toolcontext.opt_debug_port.value, 1)
- websock.accept
- sys.set_io(websock,websock,websock)
- end
- end
-
- fun close_stdstreams
- do
- if sys.stdin isa WebSocket or sys.stdin isa Socket then
- sys.stdin.close
- sys.stdout.close
- sys.stderr.close
- end
- end
-end
-
-redef class Sys
- private fun set_io(istream: PollableIStream, ostream: OStream, errstream: OStream)
- do
- self.stdin = istream
- self.stdout = ostream
- self.stderr = ostream
- end
end
# The class extending `NaiveInterpreter` by adding debugging methods
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2014 Johan Kayser <kayser.johan@gmail.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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.
+
+# Debugging of a nit program using sockets.
+module debugger_socket
+
+intrude import debugger
+import websocket
+
+redef class ToolContext
+ # --socket
+ var opt_socket_mode = new OptionBool("Launches the target program with raw output on the network via sockets", "--socket")
+
+ # --websocket
+ var opt_websocket_mode = new OptionBool("Launches the target program with output on the network via websockets", "--websocket")
+
+ # --port
+ var opt_debug_port: OptionInt = new OptionInt("Sets the debug port (Defaults to 22125) - Must be contained between 0 and 65535", 22125, "--port")
+
+ redef init
+ do
+ super
+ self.option_context.add_option(self.opt_socket_mode)
+ self.option_context.add_option(self.opt_websocket_mode)
+ self.option_context.add_option(self.opt_debug_port)
+ end
+end
+
+redef class ModelBuilder
+ # Execute the program from the entry point (Sys::main) of the `mainmodule`
+ # `arguments` are the command-line arguments in order
+ # REQUIRE that:
+ # 1. the AST is fully loaded.
+ # 2. the model is fully built.
+ # 3. the instructions are fully analysed.
+ redef fun run_debugger(mainmodule: MModule, arguments: Array[String])
+ do
+ var time0 = get_time
+ self.toolcontext.info("*** START INTERPRETING ***", 1)
+
+ var interpreter = new Debugger(self, mainmodule, arguments)
+
+ set_stdstreams
+
+ init_naive_interpreter(interpreter, mainmodule)
+
+ close_stdstreams
+
+ var time1 = get_time
+ self.toolcontext.info("*** END INTERPRETING: {time1-time0} ***", 2)
+ end
+
+ redef fun run_debugger_autorun(mainmodule: MModule, arguments: Array[String])
+ do
+ var time0 = get_time
+ self.toolcontext.info("*** START INTERPRETING ***", 1)
+
+ var interpreter = new Debugger(self, mainmodule, arguments)
+ interpreter.autocontinue = true
+
+ set_stdstreams
+
+ init_naive_interpreter(interpreter, mainmodule)
+
+ close_stdstreams
+
+ var time1 = get_time
+ self.toolcontext.info("*** END INTERPRETING: {time1-time0} ***", 2)
+ end
+
+ redef fun run_naive_interpreter(mmod, args)
+ do
+ set_stdstreams
+ super
+ end
+
+ fun set_stdstreams
+ do
+ if self.toolcontext.opt_socket_mode.value then
+ var sock = new Socket.server(toolcontext.opt_debug_port.value, 1)
+ var ns = sock.accept
+ sock.close
+ sys.set_io(ns,ns,ns)
+ else if self.toolcontext.opt_websocket_mode.value then
+ var websock = new WebSocket(toolcontext.opt_debug_port.value, 1)
+ websock.accept
+ sys.set_io(websock,websock,websock)
+ end
+ end
+
+ fun close_stdstreams
+ do
+ if sys.stdin isa WebSocket or sys.stdin isa Socket then
+ sys.stdin.close
+ sys.stdout.close
+ sys.stderr.close
+ end
+ end
+end
+
+redef class Sys
+ private fun set_io(istream: PollableIStream, ostream: OStream, errstream: OStream)
+ do
+ self.stdin = istream
+ self.stdout = ostream
+ self.stderr = ostream
+ end
+end
private var ctx: NitdocContext
private var model: Model
+ private var name_sorter = new MEntityNameSorter
init(ctx: NitdocContext) do
self.ctx = ctx
if mmodule.name == "<main>" then continue
sorted.add mmodule
end
- var sorter = new MModuleNameSorter
- sorter.sort(sorted)
+ name_sorter.sort(sorted)
return sorted
end
if mclass.visibility < ctx.min_visibility then continue
sorted.add mclass
end
- var sorter = new MClassNameSorter
- sorter.sort(sorted)
+ name_sorter.sort(sorted)
return sorted
end
if mproperty isa MAttribute then continue
sorted.add mproperty
end
- var sorter = new MPropertyNameSorter
- sorter.sort(sorted)
+ name_sorter.sort(sorted)
return sorted
end
end
if clients.length > 10 then clients = mmodule.in_importation.direct_smallers
# Display lists
- var sorter = new MModuleNameSorter
var section = new TplSection.with_title("inheritance", "Inheritance")
# Graph
# nested modules
if not nested.is_empty then
var lst = nested.to_a
- sorter.sort lst
+ name_sorter.sort lst
section.add_child tpl_list("nesting", "Nested modules", lst)
end
lst.add(dep)
end
if not lst.is_empty then
- sorter.sort lst
+ name_sorter.sort lst
section.add_child tpl_list("imports", "Imports", lst)
end
lst.add(dep)
end
if not lst.is_empty then
- sorter.sort lst
+ name_sorter.sort lst
section.add_child tpl_list("clients", "Clients", lst)
end
end
private fun tpl_mclasses(parent: TplSection) do
- var sorter = new MClassNameSorter
var mclassdefs = new HashSet[MClassDef]
mclassdefs.add_all mmodule.in_nesting_intro_mclassdefs(ctx.min_visibility)
mclassdefs.add_all mmodule.in_nesting_redef_mclassdefs(ctx.min_visibility)
var mclasses2mdefs = sort_by_mclass(mclassdefs)
var sorted_mclasses = mclasses2mdefs.keys.to_a
- sorter.sort sorted_mclasses
+ name_sorter.sort sorted_mclasses
# intros
var section = new TplSection.with_title("intros", "Introductions")
var intros = mmodule.in_nesting_intro_mclasses(ctx.min_visibility)
var sorted_intros = intros.to_a
- sorter.sort(sorted_intros)
+ name_sorter.sort(sorted_intros)
for mclass in sorted_intros do
if not mclasses2mdefs.has_key(mclass) then continue
section.add_child tpl_mclass_article(mclass, mclasses2mdefs[mclass].to_a)
# redefs
section = new TplSection.with_title("redefs", "Refinements")
var redefs = mmodule.in_nesting_redef_mclasses(ctx.min_visibility).to_a
- sorter.sort(redefs)
+ name_sorter.sort(redefs)
for mclass in redefs do
if intros.has(mclass) then continue
if not mclasses2mdefs.has_key(mclass) then continue
tpl_sidebar.boxes.add new TplSideBox.with_content("All properties", summary)
end
- var mprop_sorter = new MPropertyNameSorter
-
private fun tpl_sidebar_list(name: String, mprops: Array[MProperty], summary: TplList) do
if mprops.is_empty then return
- mprop_sorter.sort(mprops)
+ name_sorter.sort(mprops)
var entry = new TplListItem.with_content(name)
var list = new TplList.with_classes(["list-unstyled", "list-labeled"])
for mprop in mprops do
if not owners.is_empty then
var article = new TplArticle.with_title("concerns", "Concerns")
- var module_sorter = new MModuleNameSorter
- module_sorter.sort owners
+ name_sorter.sort owners
var list = new TplList.with_classes(["list-unstyled", "list-definition"])
for owner in owners do
var li = new Template
var smmodules = owner_map[owner].to_a
#if not smmodules.length >= 1 then
var slist = new TplList.with_classes(["list-unstyled", "list-definition"])
- module_sorter.sort smmodules
+ name_sorter.sort smmodules
for mmodule in smmodules do
if mmodule == owner then continue
var sli = new Template
end
# Display lists
- var sorter = new MClassNameSorter
var section = new TplSection.with_title("inheritance", "Inheritance")
# Graph
# parents
if not hparents.is_empty then
var lst = hparents.to_a
- sorter.sort lst
+ name_sorter.sort lst
section.add_child tpl_list("parents", "Parents", lst)
end
# ancestors
if not hancestors.is_empty then
var lst = hancestors.to_a
- sorter.sort lst
+ name_sorter.sort lst
section.add_child tpl_list("ancestors", "Ancestors", lst)
end
# children
if not hchildren.is_empty and hchildren.length < 15 then
var lst = hchildren.to_a
- sorter.sort lst
+ name_sorter.sort lst
section.add_child tpl_list("children", "Children", lst)
end
# descendants
if not hdescendants.is_empty and hchildren.length < 15 then
var lst = hdescendants.to_a
- sorter.sort lst
+ name_sorter.sort lst
section.add_child tpl_list("descendants", "Descendants", lst)
end
for mmodule in owner_map[owner] do
# properties
var mprops = mod_map[mmodule]
- var sorter = new MPropertyNameSorter
var kind_map = sort_by_kind(mprops)
# virtual types
var elts = kind_map["type"].to_a
- sorter.sort(elts)
+ name_sorter.sort(elts)
for elt in elts do
var defs = mprops2mdefs[elt].to_a
section.add_child tpl_mprop_article(elt, defs)
# constructors
elts = kind_map["init"].to_a
- sorter.sort(elts)
+ name_sorter.sort(elts)
for elt in elts do
var defs = mprops2mdefs[elt].to_a
section.add_child tpl_mprop_article(elt, defs)
# methods
elts = kind_map["fun"].to_a
- sorter.sort(elts)
+ name_sorter.sort(elts)
for elt in elts do
var defs = mprops2mdefs[elt].to_a
section.add_child tpl_mprop_article(elt, defs)
# Compile class names (for the class_name and output_class_name methods)
protected fun compile_class_names do
var v = new_visitor
- self.header.add_decl("extern const char const * class_names[];")
- v.add("const char const * class_names[] = \{")
+ self.header.add_decl("extern const char *class_names[];")
+ v.add("const char *class_names[] = \{")
for t in self.runtime_type_analysis.live_types do
v.add("\"{t}\", /* {self.classid(t)} */")
end
perl -i -npe 's#"\.\./.*?([^/]*.h)"#"\1"#' "$out"/*.[ch]
perl -i -npe 's#\S*/([^/]*.[ch])#\1#' "$out/Makefile"
perl -i -npe 's#\.\./clib#.#' "$out/Makefile"
+
+# Remove old compilation flags
+sed -i -e 's/OLDNITCOPT=.*/OLDNITCOPT=/' src/Makefile
# A Nit module is usually associated with a Nit source file.
class MModule
- super MEntity
+ super MConcern
# The model considered
var model: Model
var mgroup: nullable MGroup
# The short name of the module
- var name: String
+ redef var name: String
# The origin of the definition
var location: Location
abort
end
end
+
+ redef fun parent_concern do return mgroup
end
import location
import mmodule
import mdoc
+import ordered_tree
private import more_collections
redef class Model
# The only null type
var null_type: MNullType = new MNullType(self)
+
+ # Build an ordered tree with from `concerns`
+ fun concerns_tree(mconcerns: Collection[MConcern]): ConcernsTree do
+ var seen = new HashSet[MConcern]
+ var res = new ConcernsTree
+
+ var todo = new Array[MConcern]
+ todo.add_all mconcerns
+
+ while not todo.is_empty do
+ var c = todo.pop
+ if seen.has(c) then continue
+ var pc = c.parent_concern
+ if pc == null then
+ res.add(null, c)
+ else
+ res.add(pc, c)
+ todo.add(pc)
+ end
+ seen.add(c)
+ end
+
+ return res
+ end
+end
+
+# An OrderedTree that can be easily refined for display purposes
+class ConcernsTree
+ super OrderedTree[MConcern]
end
redef class MModule
# The short name of the class
# In Nit, the name of a class cannot evolve in refinements
- var name: String
+ redef var name: String
# The canonical name of the class
# Example: `"owner::module::MyClass"`
self.to_s = "{mmodule}#{mclass}"
end
+ # Actually the name of the `mclass`
+ redef fun name do return mclass.name
+
# All declared super-types
# FIXME: quite ugly but not better idea yet
var supertypes: Array[MClassType] = new Array[MClassType]
var intro_mclassdef: MClassDef
# The (short) name of the property
- var name: String
+ redef var name: String
# The canonical name of the property
# Example: "owner::my_module::MyClass::my_method"
self.to_s = "{mclassdef}#{mproperty}"
end
+ # Actually the name of the `mproperty`
+ redef fun name do return mproperty.name
+
# Internal name combining the module, the class and the property
# Example: "mymodule#MyClass#mymethod"
redef var to_s: String
# A named and possibly documented entity in the model.
# This class is usefull to generalize presentation of entities to the human.
abstract class MEntity
+ # The short (unqualified) name of this model entity
+ fun name: String is abstract
+end
+
+# Something that represents a concern
+abstract class MConcern
+ super MEntity
+ # The concern that contains `self` or null if `self` is the root of the concern hierarchy
+ fun parent_concern: nullable MConcern is abstract
end
# A visibility (for modules, class and properties)
# A Nit project, thas encompass a product
class MProject
- super MEntity
+ super MConcern
# The name of the project
- var name: String
+ redef var name: String
# The model of the project
var model: Model
model.mprojects.add(self)
model.mproject_by_name.add_one(name, self)
end
+
+ # MProject are always roots of the concerns hierarchy
+ redef fun parent_concern do return null
end
# A group of modules in a project
class MGroup
- super MEntity
+ super MConcern
# The name of the group
# empty name for a default group in a single-module project
- var name: String
+ redef var name: String
# The englobing project
var mproject: MProject
# nesting group (see `parent`) is bigger
var in_nesting: POSetElement[MGroup]
+ # Is `self` the root of its project?
+ fun is_root: Bool do return mproject.root == self
+
# The filepath (usualy a directory) of the group, if any
var filepath: nullable String writable
end
end
+ redef fun parent_concern do
+ if not is_root then return parent
+ return mproject
+ end
+
redef fun to_s do return name
end
import modelbuilder
+redef class MGroup
+ fun in_nesting_intro_mclasses(min_visibility: MVisibility): Set[MClass] do
+ var res = new HashSet[MClass]
+ var lst = in_nesting.direct_smallers
+ for mmodule in mmodules do res.add_all mmodule.filter_intro_mclasses(min_visibility)
+ for mgrp in lst do res.add_all mgrp.in_nesting_intro_mclasses(min_visibility)
+ return res
+ end
+
+ fun in_nesting_redef_mclasses(min_visibility: MVisibility): Set[MClass] do
+ var res = new HashSet[MClass]
+ var lst = in_nesting.direct_smallers
+ for mmodule in mmodules do res.add_all mmodule.filter_redef_mclasses(min_visibility)
+ for mgrp in lst do res.add_all mgrp.in_nesting_redef_mclasses(min_visibility)
+ return res
+ end
+
+ fun in_nesting_intro_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do
+ var res = new HashSet[MClassDef]
+ var lst = in_nesting.direct_smallers
+ for mmodule in mmodules do res.add_all mmodule.intro_mclassdefs(min_visibility)
+ for mgrp in lst do res.add_all mgrp.in_nesting_intro_mclassdefs(min_visibility)
+ return res
+ end
+
+ fun in_nesting_redef_mclassdefs(min_visibility: MVisibility): Set[MClassDef] do
+ var res = new HashSet[MClassDef]
+ var lst = in_nesting.direct_smallers
+ for mmodule in mmodules do res.add_all mmodule.redef_mclassdefs(min_visibility)
+ for mgrp in lst do res.add_all mgrp.in_nesting_redef_mclassdefs(min_visibility)
+ return res
+ end
+
+ # Collect nested modules
+ fun collect_mmodules: Set[MModule] do
+ var res = new HashSet[MModule]
+ res.add_all mmodules
+ for mgroup in in_nesting.direct_smallers do
+ res.add_all mgroup.collect_mmodules
+ end
+ return res
+ end
+end
+
redef class MModule
# The list of intro mclassdef in the module.
return res
end
+ # The list of intro mclass in the module.
+ # with visibility >= to min_visibility
+ fun filter_intro_mclasses(min_visibility: MVisibility): Set[MClass] do
+ var res = new HashSet[MClass]
+ for mclass in intro_mclasses do
+ if mclass.visibility < min_visibility then continue
+ res.add mclass
+ end
+ return res
+ end
+
# Get the list of mclasses refined in 'self'.
fun redef_mclasses: Set[MClass] do
var mclasses = new HashSet[MClass]
return mclasses
end
+ # Get the list of mclasses refined in 'self'.
+ fun filter_redef_mclasses(min_visibility: MVisibility): Set[MClass] do
+ var mclasses = new HashSet[MClass]
+ for c in mclassdefs do
+ if c.mclass.visibility < min_visibility then continue
+ if not c.is_intro then mclasses.add(c.mclass)
+ end
+ return mclasses
+ end
+
# Get the list of all mclasses imported by 'self'.
fun imported_mclasses: Set[MClass] do
var mclasses = new HashSet[MClass]
fun in_nesting_intro_mclasses(min_visibility: MVisibility): Set[MClass] do
var res = new HashSet[MClass]
for mmodule in in_nesting.greaters do
- for mclass in mmodule.intro_mclasses do
+ for mclass in mmodule.filter_intro_mclasses(min_visibility) do
if mclass.visibility < min_visibility then continue
res.add mclass
end
fun in_nesting_redef_mclasses(min_visibility: MVisibility): Set[MClass] do
var res = new HashSet[MClass]
for mmodule in self.in_nesting.greaters do
- for mclass in mmodule.redef_mclasses do
+ for mclass in mmodule.filter_redef_mclasses(min_visibility) do
if mclass.visibility < min_visibility then continue
res.add mclass
end
# Sorters
-# Sort mmodules by their name
-class MModuleNameSorter
- super AbstractSorter[MModule]
+# Sort mentities by their name
+class MEntityNameSorter
+ super AbstractSorter[MEntity]
redef fun compare(a, b) do return a.name <=> b.name
init do end
end
-# Sort mclasses by their name
-class MClassNameSorter
- super AbstractSorter[MClass]
- redef fun compare(a, b) do return a.name <=> b.name
- init do end
-end
-
-# Sort mclassdefs by their name
-class MClassDefNameSorter
- super AbstractSorter[MClassDef]
- redef fun compare(a, b) do return a.mclass.name <=> b.mclass.name
- init do end
-end
-
-# Sort mproperties by their name
-class MPropertyNameSorter
- super AbstractSorter[MProperty]
- redef fun compare(a, b) do return a.name <=> b.name
- init do end
-end
-
-# Sort mpropdefs by their name
-class MPropDefNameSorter
- super AbstractSorter[MPropDef]
- redef fun compare(a, b) do return a.mproperty.name <=> b.mproperty.name
- init do end
-end
import naive_interpreter
import debugger
+import debugger_socket
# Create a tool context to handle options and paths
var toolcontext = new ToolContext
print "Loaded modules:"
var mmodules = new Array[MModule]
mmodules.add_all(model.mmodules)
- var sorter = new MModuleNameSorter
+ var sorter = new MEntityNameSorter
sorter.sort(mmodules)
for m in mmodules do
print "\t{m.name}"
cats[key].add(mprop)
end
#sort groups
- var sorter = new MModuleNameSorter
+ var sorter = new MEntityNameSorter
var sorted = new Array[MModule]
sorted.add_all(cats.keys)
sorter.sort(sorted)
for mmodule in sorted do
var mprops = cats[mmodule]
pager.add("# matches in module {mmodule.namespace.bold}")
- var sorterp = new MPropertyNameSorter
- sorterp.sort(mprops)
+ sorter.sort(mprops)
for mprop in mprops do
end
pager.add(prototype)
pager.add("{namespace}".bold.gray + " (lines {location.lines})".gray)
pager.indent = pager.indent + 1
- var sorter = new MModuleNameSorter
+ var sorter = new MEntityNameSorter
# imported modules
var imports = new Array[MModule]
for mmodule in in_importation.direct_greaters.to_a do
pager.indent = pager.indent - 1
end
# mclassdefs
- var csorter = new MClassDefNameSorter
var intros = new Array[MClassDef]
var redefs = new Array[MClassDef]
for mclassdef in mclassdefs do
end
# introductions
if not intros.is_empty then
- csorter.sort(intros)
+ sorter.sort(intros)
pager.add("")
pager.add("== introduced classes".bold)
pager.indent = pager.indent + 1
end
# refinements
if not redefs.is_empty then
- csorter.sort(redefs)
+ sorter.sort(redefs)
pager.add("")
pager.add("== refined classes".bold)
pager.indent = pager.indent + 1
redef fun content(index, pager) do
# intro comment
+ var sorter = new MEntityNameSorter
var mdoc = intro.mdoc
if mdoc != null then
for comment in mdoc.content do pager.add(comment.green)
# parents
var supers = self.in_hierarchy(index.mainmodule).direct_greaters.to_a
if not supers.is_empty then
- var csorter = new MClassNameSorter
- csorter.sort(supers)
+ sorter.sort(supers)
pager.add("")
pager.add("== supers".bold)
pager.indent = pager.indent + 1
pager.indent = pager.indent - 1
end
# intro mproperties
- var psorter = new MPropDefNameSorter
var mpropdefs = intro.mpropdefs
index.mainmodule.linearize_mpropdefs(mpropdefs)
for cat in intro.cats2mpropdefs.keys do
var defs = intro.cats2mpropdefs[cat].to_a
if defs.is_empty then continue
- psorter.sort(defs)
+ sorter.sort(defs)
pager.add("")
pager.add("== {cat}".bold)
pager.indent = pager.indent + 1
pager.add("{namespace}".bold.gray + " (lines {location.lines})".gray)
pager.indent = pager.indent + 1
var mpropdefs = self.mpropdefs
- var psorter = new MPropDefNameSorter
+ var sorter = new MEntityNameSorter
index.mainmodule.linearize_mpropdefs(mpropdefs)
for cat in cats2mpropdefs.keys do
var defs = cats2mpropdefs[cat].to_a
- psorter.sort(defs)
+ sorter.sort(defs)
if defs.is_empty then continue
pager.add("")
pager.add("== {cat}".bold)
--- /dev/null
+init_inherit
+init_linext
--- /dev/null
+import emscripten
+redef class IFStream
+ redef fun fill_buffer
+ do
+ print "NOT YET IMPLEMENTED"
+ abort
+ end
+ redef init open(f)
+ do
+ print "NOT YET IMPLEMENTED"
+ abort
+ end
+end
--- /dev/null
+Not executable (platform?)
-Caught signal : Segmentation fault
+UNDEFINED
-Caught signal : Segmentation fault
+UNDEFINED
--- /dev/null
+1
+11
+111
+112
+12
+121
+122
+2
+21
+22
+--
+22
+21
+2
+122
+121
+12
+112
+111
+11
+1
--- /dev/null
+1
+|--11
+| |--111
+| `--112
+`--12
+ |--121
+ `--122
+2
+|--21
+`--22
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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.
+
+import ordered_tree
+
+var tree = new OrderedTree[Int]
+tree.add(null, 1)
+tree.add(1, 11)
+tree.add(11, 111)
+tree.add(11, 112)
+tree.add(1, 12)
+tree.add(12, 121)
+tree.add(12, 122)
+tree.add(null, 2)
+tree.add(2, 21)
+tree.add(2, 22)
+
+for i in tree do print i
+print "--"
+for i in tree.to_a.reversed do print i
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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.
+
+import ordered_tree
+
+var tree = new OrderedTree[Int]
+tree.add(null, 1)
+tree.add(1, 11)
+tree.add(11, 111)
+tree.add(11, 112)
+tree.add(1, 12)
+tree.add(12, 121)
+tree.add(12, 122)
+tree.add(null, 2)
+tree.add(2, 21)
+tree.add(2, 22)
+
+tree.write_to(stdout)
# Set lang do default to avoid failed tests because of locale
export LANG=C
+export LC_ALL=C
export NIT_TESTING=true
unset NIT_DIR
niti)
enginebinname=nit
;;
+ emscripten)
+ enginebinname=nitg
+ OPT="-m emscripten_nodejs.nit --semi-global $OPT"
+ savdirs="sav/nitg-sg/"
+ ;;
nitc)
echo "disabled engine $engine"
exit 0
inputs=/dev/null
fi
+ ffout="$ff.bin"
+ if [ "$engine" = "emscripten" ]; then
+ ffout="$ff.bin.js"
+ fi
+
if [ "$engine" = "niti" ]; then
cat > "./$ff.bin" <<END
exec $NITC --no-color $OPT "$i" $includes -- "\$@"
# Compile
if [ "x$verbose" = "xtrue" ]; then
echo ""
- echo $NITC --no-color $OPT -o "$ff.bin" "$i" "$includes" $nocc
+ echo $NITC --no-color $OPT -o "$ffout" "$i" "$includes" $nocc
fi
NIT_NO_STACK=1 JNI_LIB_PATH=$JNI_LIB_PATH JAVA_HOME=$JAVA_HOME \
- $TIMEOUT $NITC --no-color $OPT -o "$ff.bin" "$i" $includes $nocc 2> "$ff.cmp.err" > "$ff.compile.log"
+ $TIMEOUT $NITC --no-color $OPT -o "$ffout" "$i" $includes $nocc 2> "$ff.cmp.err" > "$ff.compile.log"
ERR=$?
if [ "x$verbose" = "xtrue" ]; then
cat "$ff.compile.log"
cat >&2 "$ff.cmp.err"
fi
fi
+ if [ "$engine" = "emscripten" ]; then
+ echo > "./$ff.bin" "nodejs $ffout \"\$@\""
+ chmod +x "$ff.bin"
+ if grep "Fatal Error: more than one primitive class" "$ff.compile.log" > /dev/null; then
+ echo " [skip] do no not imports kernel"
+ echo >>$xml "<testcase classname='$pack' name='$bf'><skipped/></testcase>"
+ continue
+ fi
+ fi
if [ "$ERR" != 0 ]; then
echo -n "! "
cat "$ff.compile.log" "$ff.cmp.err" > "$ff.res"