Skip to content

Commit

Permalink
Eval (#6319)
Browse files Browse the repository at this point in the history
* add eval target (new interpreter)

* install findlib packages

* typo

* don't add trailing slashes if your name is remove_trailing_slash

* add rope and ptmap to merlin again

* fix timers

* support enum to expr conversion (#43)

* fix no-arg enum values (#44)

* make Md5 faster on `eval` (#45)

* implement Md5 natively

* add -D interp-times

* fix incr ops

* lose IO dependency

* ignore Japan (?)

* 64 bits

* implement FPHelper natively for more accuracy

* allow floats in place of int because apparently that happens sometimes

* print value kind in case of unexpected value

* make other interp's create functions compatible

* add more hxmls for mandelbrot benchmark

* optimize enum index access

* optimize enum construction

* return empty array for Reflect.fields(null) (#46)

* sort timers by time

* print parent % too

* add eval.vm.Gc

* deal with different OCaml versions

* optimize decrement ops

* avoid raising Return exceptions at the end of a function's control flow

* don't catch RunTimeException in two places

* Improve macro context api: add haxe.macro.Context.storeExpr (#47)

* optimize `while (a >= const)`

* use DynArray instead of Stack for environment stacks

* avoid Return exception wrapping if there's no nonfinal return

* don't record stack traces in non-debug mode, unless -D interp-stack

* throw "Unbound variable" instead of asserting

* keep a default environment and re-use it if possible

* specialize any calls

* fix closure jitting

* memoize proto functions on call

* avoid hitting the write barrier on envs so much

* show context of local functions for times (#48)

* avoid more write barrier by storing 3 ints instead of 1 pos

* make envs a bit smaller

* make constructor calls a bit less slow

* move env info creating to a function

* allow adding useless breakpoints because why not

* keep variable names around so we can print them

* move JitContext to its own file

* implement some parts of the hxcpp-debugger CLI

* detect uncaught exceptions when debugging

* make caught-type detection more accurate

* catch Not_found if a breakpoint file doesn't exist

* don't mess up blocks if we're debugging

* support captured variables

* use intermediate functions instead of print_endline so they can be modified

* restructure a bit

* rework debug representation to support up/down/frame

* adjust to vshaxe-debug requirements

* always print prompt

* match hxcpp-debugger output more accurately

* minor

* hook up names

* keep variable types around

* fix var info lookup

* fix breakpoint pattern parsing

* fixes

* support `print obj.field`

* automatically reset to real env instead of complaining about it

* print values in a way the debugger accepts it

* lose var type information

* more hxcpp-debugger sync

* quote string values

* unify set/print

* resolve idents to prototypes

* support more identifier resolution

* return real paths

* support column breakpoints

* readjust to picky debugger

* support socket connections via -D interp-debugger-socket=host:port

* actuall call recv

* asdfg

* output some json

* consistency

* send data length

* add value_to_json

* output breakpoint setting result as int

* sync breakpoint names

* thread debug experiment

* don't ctx.eval() so much

* keep main thread separate

* fix some threading

* remove Thread implementation, at lest for now

* branching is faster

* avoid unnecessary function call

* use macro call position if that's all we have

* rename interp- stuff to eval- stuff

* add test (closes #5155)

* add tests (closes #5160) (closes #6145)

* maybe fix timer accumulation

* fix call stack handling if record_stack is false

* small opt

* optimize null checks

* improve int equality check

* fix flag implications

* close env timers in case of exceptions

* remove check because bools don't trigger the write barrier

* guard against failing C#/php test

* fix timers, again

* make StringMap implementation faster

* emit breakpoint_stop event

* output some info about the exception

* command for getting scopes and vars within scope

* some hackery

* revert stack (so the frame with id=0 comes first), output response to move_frame commands

* don't skip, but mark artifical frames

* make "frame" accept ids returned by "w"

* can now use zero-based scope numbers

* wip on scope variable output

* add 'structured' flag for the var output

* wip

* flat var repr

* show object internals

* display arrays the same way as objects

* some value display improvements

* have instance_fields fields, next to object_fields

* more wip on var introspection

* support array access in expr_to_value

* improve enum printing, fix array printing order

* support enum value introspection

* output "access" field so we don't have to do the magic on the adapter side to know how to access subvars

* wip on setting vars

* use native crc32 implementation for Crc32.make

* skip empty scopes in "scopes" request

* swap argument order for jit_expr

* optimize method calls a little

* optimize calls to singly-implemented interface fields

* some minor cleanup

* don't make pointless vnull assignments when declaring variables without init

* use some `[@@inline]` to restructure call code

* don't mess up override calls

* check if 4.02.3 accepts this

* Revert "check if 4.02.3 accepts this"

This reverts commit e20311c.

* add position info to scope

* rename vars_scope to simply vars, rename vars_inner to structure

* remove `[@@inline]` for now

* ctrl s

* make fastCodeAt a bit faster

* don't use the default env if we want to record a stack

* Bring back VArray and VString (#49)

* bring back VString

* bring back VArray too

* change stack trace output

* reset ctx.curapi after call_path

* implement Haxe serialization algorithm and use it for Context.signature

* use full enum path (see #6273)

* set error state on eval context

* start separating connection from EvalDebug, since we want two different connection interfaces

* add EvalDebugSocket module which is the main goal to complete right now

* select connection based on whether there's a socket (do it the ugly way for now)

* rework EvalDebugSocket to a json-rpc protocol

* camelcase

* don't care about `id` structure, just return it as is

* conform to jsonrpc spec better by always supplying `id` for errors (should be null if there's no id)

* minor

* clean up EvalDebugCLI from the json socket stuff

* remove unused value_string

* add a method to replace all breakpoints within file

* make sure we actually compare the same enums (closes #6273)

* remove "created socket" print

* add eval.vm.Context.breakHere

* play it safe with compare/equals

* don't comment out what you want to test

* optimize int/enum switches

* get exception message _before_ resetting the context

* reset caught_types within catch blocks

* catch exception on recv

* re-work function argument handling

* add rev_file_hash

* [debug] don't stop at field access expressions

* let prototypes keep a reference to their own value

* rely on physical equality for equals

* [eval] initial vector implementation (#51)

* [eval] initial vector implementation

* [eval] add missing Vector key

* optimize Vector.get/set

* use native Vector.map

* optimize new Vector a bit

* improve Vector/Array.map

* [eval] vector should use ocaml implementations

* implement Vector.join natively and improve Array.join

* [eval] add special cases in jit to improve vector performance, add array access to eval.Vector to detect them, bugfixing

* fix Vector warnings

* remove unused eval.Vector.get/set

* compare prototypes by path (see #6308)

* check for uncaught haxe.macro.Error exceptions (closes #53)

* fix env_captures initialization

* always initialize vars

because nadako doesn't

* Revert "fix env_captures initialization"

This reverts commit cfc4fe2.

* [eval] add missing VVector handling in various places (#52)

* [eval] add missing VVector handling in various places

* [eval] handle vector.length like array.length, but don't support write access

* [eval] don't expose set and get of eval.Vector, we only handle array access

* add eval.vm.Context.loadPlugin

* expose decode_expr again

* expose encode_expr as well so we can do macros \o/

* expose encode_ctype

* add decode_type

* More work on cppiaast

* [lua] get rid of unused variable (and warning)

* Add cppiaast define to test unified cppia generation

* deal with `if (throw)` situations (closes #6315)

* Normalize class names in cppia-ast

* save locals in typing_timer

* subdate upmodule

* add back dynlink

* fix Uncompress
  • Loading branch information
Simn committed Jun 3, 2017
1 parent b10710e commit 614b588
Show file tree
Hide file tree
Showing 51 changed files with 10,603 additions and 13 deletions.
11 changes: 9 additions & 2 deletions Makefile
Expand Up @@ -27,9 +27,9 @@ STATICLINK?=0

# Configuration

HAXE_DIRECTORIES=compiler context generators generators/gencommon macro filters optimization syntax typing display
HAXE_DIRECTORIES=compiler context generators generators/gencommon macro filters macro/eval optimization syntax typing display
EXTLIB_LIBS=extlib-leftovers extc neko javalib swflib ttflib ilib objsize pcre ziplib
FINDLIB_LIBS=unix str threads sedlex xml-light extlib rope ptmap
FINDLIB_LIBS=unix str threads sedlex xml-light extlib rope ptmap dynlink

# Includes, packages and compiler

Expand Down Expand Up @@ -141,6 +141,13 @@ build_pass_3:
build_pass_4: $(MODULES:%=%.$(MODULE_EXT))
$(COMPILER) -safe-string -linkpkg -o $(OUTPUT) $(NATIVE_LIBS) $(NATIVE_LIB_FLAG) $(LFLAGS) $(FINDLIB_PACKAGES) $(EXTLIB_INCLUDES) $(EXTLIB_LIBS:=.$(LIB_EXT)) $(MODULES:%=%.$(MODULE_EXT))

plugin:
ifeq ($(BYTECODE),1)
$(CC_CMD) $(PLUGIN).ml
else
$(COMPILER) $(ALL_CFLAGS) -shared -o $(PLUGIN).cmxs $(PLUGIN).ml
endif

# Only use if you have only changed gencpp.ml
quickcpp: _build/src/generators/gencpp.ml build_pass_4 copy_haxetoolkit
_build/src/generators/gencpp.ml:src/generators/gencpp.ml
Expand Down
6 changes: 6 additions & 0 deletions src/context/common.ml
Expand Up @@ -474,6 +474,9 @@ module Define = struct
| DumpIgnoreVarIds
| DynamicInterfaceClosures
| EraseGenerics
| EvalDebugger
| EvalStack
| EvalTimes
| FastCast
| Fdb
| FileExtension
Expand Down Expand Up @@ -571,6 +574,9 @@ module Define = struct
| DumpIgnoreVarIds -> ("dump_ignore_var_ids","Remove variable IDs from non-pretty dumps (helps with diff)")
| DynamicInterfaceClosures -> ("dynamic_interface_closures","Use slow path for interface closures to save space")
| EraseGenerics -> ("erase_generics","Erase generic classes on C#")
| EvalDebugger -> ("eval_debugger","Support debugger in macro/interp mode. Allows host:port value to open a socket. Implies eval_stack.")
| EvalStack -> ("eval_stack","Record stack information in macro/interp mode")
| EvalTimes -> ("eval_times","Record per-method execution times in macro/interp mode. Implies eval_stack.")
| FastCast -> ("fast_cast","Enables an experimental casts cleanup on C# and Java")
| Fdb -> ("fdb","Enable full flash debug infos for FDB interactive debugging")
| FileExtension -> ("file_extension","Output filename extension for cpp source code")
Expand Down
188 changes: 188 additions & 0 deletions src/macro/eval/evalArray.ml
@@ -0,0 +1,188 @@
(*
The Haxe Compiler
Copyright (C) 2005-2017 Haxe Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*)

open Globals
open EvalValue

let create values = {
avalues = values;
alength = Array.length values;
}

let array_join a f sep =
let buf = Rope.Buffer.create 0 in
let last = Array.length a - 1 in
Array.iteri (fun i v ->
Rope.Buffer.add_rope buf (f v);
if i <> last then Rope.Buffer.add_rope buf sep;
) a;
Rope.Buffer.contents buf

let to_list a = Array.to_list (Array.sub a.avalues 0 a.alength)

let set_length a l =
a.alength <- l;
if a.alength > Array.length a.avalues then begin
let values' = Array.make (a.alength * 2) vnull in
Array.blit a.avalues 0 values' 0 (Array.length a.avalues);
a.avalues <- values'
end

let unsafe_get a i = a.avalues.(i)
let unsafe_set a i v = a.avalues.(i) <- v

let concat a a2 =
let values' = Array.make (a.alength + a2.alength) vnull in
Array.blit a.avalues 0 values' 0 a.alength;
let values2 = (Obj.magic a2.avalues) in
Array.blit values2 0 values' a.alength a2.alength;
create values'

let copy a =
create (Array.sub a.avalues 0 a.alength)

let filter a f =
create (ExtArray.Array.filter f (Array.sub a.avalues 0 a.alength))

let get a i =
if i < 0 || i >= a.alength then vnull
else Array.unsafe_get a.avalues i

let rec indexOf a equals x fromIndex =
if fromIndex >= a.alength then -1
else if equals x (Array.get a.avalues fromIndex) then fromIndex
else indexOf a equals x (fromIndex + 1)

let insert a pos x =
if a.alength + 1 >= Array.length a.avalues then begin
let values' = Array.make (Array.length a.avalues * 2 + 5) vnull in
Array.blit a.avalues 0 values' 0 a.alength;
a.avalues <- values'
end;
Array.blit a.avalues pos a.avalues (pos + 1) (a.alength - pos);
Array.set a.avalues pos x;
a.alength <- a.alength + 1

let iterator a =
let i = ref 0 in
let length = a.alength in
(fun () ->
!i < length
),
(fun () ->
let v = get a !i in
incr i;
v
)

let join a f sep =
array_join (Array.sub a.avalues 0 a.alength) f sep

let lastIndexOf a equals x fromIndex =
let rec loop i =
if i < 0 then -1
else if equals x (Array.get a.avalues i) then i
else loop (i - 1)
in
if a.alength = 0 then -1 else loop fromIndex

let map a f =
create (Array.map f (Array.sub a.avalues 0 a.alength))

let pop a =
if a.alength = 0 then
vnull
else begin
let v = get a (a.alength - 1) in
a.alength <- a.alength - 1;
v
end

let push a v =
if a.alength + 1 >= Array.length a.avalues then begin
let values' = Array.make (Array.length a.avalues * 2 + 5) vnull in
Array.blit a.avalues 0 values' 0 a.alength;
Array.set values' a.alength v;
a.avalues <- values'
end else begin
Array.set a.avalues a.alength v;
end;
a.alength <- a.alength + 1;
a.alength

let remove a equals x =
let i = indexOf a equals x 0 in
if i < 0 then
false
else begin
Array.blit a.avalues (i + 1) a.avalues i (a.alength - i - 1);
a.alength <- a.alength - 1;
true
end

let reverse a =
a.avalues <- ExtArray.Array.rev (Array.sub a.avalues 0 a.alength)

let set a i v =
if i >= a.alength then begin
if i >= Array.length a.avalues then begin
let values' = Array.make (i + 5) vnull in
Array.blit a.avalues 0 values' 0 a.alength;
a.avalues <- values';
end;
a.alength <- i + 1;
end;
Array.unsafe_set a.avalues i v

let shift a =
if a.alength = 0 then
vnull
else begin
let v = get a 0 in
a.alength <- a.alength - 1;
Array.blit a.avalues 1 a.avalues 0 a.alength;
v
end

let slice a pos end' =
if pos > a.alength || pos >= end' then
create [||]
else
create (Array.sub a.avalues pos (end' - pos))

let sort a f =
a.avalues <- Array.sub a.avalues 0 a.alength;
Array.sort f a.avalues

let splice a pos len end' =
let values' = Array.init len (fun i -> Array.get a.avalues (pos + i)) in
Array.blit a.avalues (pos + len) a.avalues pos (a.alength - end');
a.alength <- a.alength - len;
create values'

let unshift a v =
if a.alength + 1 >= Array.length a.avalues then begin
let values' = Array.make (Array.length a.avalues * 2 + 5) vnull in
Array.blit a.avalues 0 values' 1 a.alength;
a.avalues <- values'
end else begin
Array.blit a.avalues 0 a.avalues 1 a.alength;
end;
Array.set a.avalues 0 v;
a.alength <- a.alength + 1

0 comments on commit 614b588

Please sign in to comment.