Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ addons:
apt:
packages:
- g++-multilib
- libgtest-dev
- linux-libc-dev:i386
- libreadline-dev:i386
- llvm-3.4-dev:i386
Expand Down
57 changes: 52 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,21 +1,65 @@
cmake_minimum_required(VERSION 2.8.4)

set (CMAKE_USER_MAKE_RULES_OVERRIDE "${CMAKE_SOURCE_DIR}/cmake/variables.cmake")
set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set (LLVM_PACKAGE_VERSION 3.4)

project(llst)

include(CheckCXXCompilerFlag)

list (APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

# message(STATUS "CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}")
# message(STATUS "CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}")
# message(STATUS "CMAKE_CXX_FLAGS_MINSIZEREL ${CMAKE_CXX_FLAGS_MINSIZEREL}")
# message(STATUS "CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}")
# message(STATUS "CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
# message(STATUS "CMAKE_CXX_FLAGS_COVERAGE ${CMAKE_CXX_FLAGS_COVERAGE}")

#set(CMAKE_CXX_STANDARD 11)

# C++ compiler.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -fexceptions -frtti")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb3 -O0")
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} ")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3")
set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} --coverage -fkeep-inline-functions")

if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
# This is a 64-bit OS
# LLST supports only 32-bit code
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
check_cxx_compiler_flag("-m32" CXX_HAS_32BIT_SUPPORT)
if (NOT CXX_HAS_32BIT_SUPPORT)
message(FATAL_ERROR "Your compiler does not support flag '-m32' to generate 32bit code")
endif()
endif()

#string(APPEND CMAKE_CXX_FLAGS " -fprofile-generate")
#string(APPEND CMAKE_CXX_FLAGS " -fprofile-use")

check_cxx_compiler_flag("-flto" CXX_HAS_LTO_SUPPORT)
if (CXX_HAS_LTO_SUPPORT)
#string(APPEND CMAKE_CXX_FLAGS " -flto")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
set(CMAKE_AR "gcc-ar") # TODO check existance
set(CMAKE_RANLIB "gcc-ranlib")
endif()

set (LLVM_PACKAGE_VERSION 3.4)

find_package(Threads REQUIRED QUIET)
find_package(READLINE)
find_package(LLVM ${LLVM_PACKAGE_VERSION} EXACT)
find_package(POD2MAN)
find_package(GZIP REQUIRED)
find_package(GMP REQUIRED)

option(USE_READLINE "Should we use the GNU readline and history libraries?" ON)
option(USE_LLVM "Should we use LLVM to build JIT?" OFF)
option(USE_POD2MAN "Should we use pod2man to build the documentation (we will create empty docs otherwise)?" ON)

include_directories(SYSTEM ${GMP_INCLUDE_DIRS})

if (USE_LLVM)
if (LLVM_FOUND)
message(STATUS "Using LLVM ${LLVM_VERSION}")
Expand Down Expand Up @@ -138,7 +182,10 @@ add_dependencies(llst image)
if (USE_LLVM)
target_link_libraries(llst jit trampoline ${LLVM_LIBS} ${LLVM_LD_FLAGS})
endif()
target_link_libraries(llst standard_set memory_managers stapi ${READLINE_LIBS_TO_LINK} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})
target_link_libraries(llst memory_managers standard_set stapi ${READLINE_LIBS_TO_LINK} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})

add_executable(llst_test src/test_main.cpp)
target_link_libraries(llst_test interpreter memory_managers standard_set ${GMP_LIBRARIES} ${READLINE_LIBS_TO_LINK})

set(changelog_compressed "${CMAKE_CURRENT_BINARY_DIR}/changelog.gz")
gzip_compress("compress_changelog" "${CMAKE_CURRENT_SOURCE_DIR}/ChangeLog" ${changelog_compressed})
Expand Down
14 changes: 14 additions & 0 deletions cmake/FindGMP.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Try to find the GNU Multiple Precision Arithmetic Library (GMP)
# See http://gmplib.org/

include(FindPackageHandleStandardArgs)

find_path(GMP_INCLUDE_DIRS NAMES gmp.h gmpxx.h)
find_library(GMP_LIBRARIES NAMES gmp gmpxx)

FIND_PACKAGE_HANDLE_STANDARD_ARGS(GMP
FOUND_VAR GMP_FOUND
REQUIRED_VARS
GMP_LIBRARIES
GMP_INCLUDE_DIRS
)
Binary file added image/LittleSmalltalk.image
Binary file not shown.
106 changes: 81 additions & 25 deletions image/imageSource.st
Original file line number Diff line number Diff line change
Expand Up @@ -1441,41 +1441,83 @@ printHierarchy: aClass | class |
[ class isNil ] whileFalse: [ class printNl. class <- class parent ]
!

CLASS Timer Object initValue
METHOD MetaTimer
get
<253>
CLASS TimeVal Object seconds microseconds

METHOD MetaTimeVal
new | instance |
instance <- super new.
self in: instance at: 1 put: 0.
self in: instance at: 2 put: 0.
^instance
!

METHOD MetaTimeVal
initWithNow: arg
(arg isMemberOf: TimeVal) ifFalse: [ self error: 'Incorrect argument' ].
<230 arg>.
self primitiveFailed
!

METHOD MetaTimeVal
now | instance |
instance <- self new.
self initWithNow: instance.
^instance
!

METHOD TimeVal
seconds
^seconds
!

METHOD TimeVal
seconds: value
seconds <- value
!

METHOD TimeVal
microseconds
^microseconds
!

METHOD TimeVal
microseconds: value
microseconds <- value
!

METHOD TimeVal
- arg |result|
(arg isMemberOf: TimeVal) ifFalse: [ self error: 'Incorrect argument' ].
result <- TimeVal new.
result seconds: (self seconds - arg seconds).
result microseconds: (self microseconds - arg microseconds).
(result microseconds < 0) ifTrue: [
result seconds: (result seconds - 1).
result microseconds: (result microseconds + 1000000).
].
^result
!

CLASS Timer Object initTimeVal

METHOD MetaTimer
new | instance |
instance <- super new.
self in: instance at: 1 put: self get.
self in: instance at: 1 put: TimeVal now.
^instance
!

METHOD MetaTimer
millisecondsToRun: aBlock | timer |
timer <- Timer new.
aBlock value.
^timer value.
!

METHOD Timer
millisecondsToRun: aBlock | time |
time <- self value.
aBlock value.
^self value - time.
^timer elapsedMilliseconds.
!

METHOD Timer
initValue
^initValue
!

METHOD Timer
value
^ self class get - initValue
elapsedMilliseconds |diff|
diff <- TimeVal now - initTimeVal.
^ (diff seconds * 1000) + (diff microseconds / 1000)
!

METHOD Undefined
Expand Down Expand Up @@ -2058,8 +2100,18 @@ run4: rounds | list indices tree |
METHOD Undefined
main | command data x |
Char initialize.
Class fillChildren.
System fixMethodClasses.

"Integer new: 200; factorial."

"(468468468468*2367123) printNl.
468468468 class printNl.
(468468468+468468468+468468468+468468468) class printNl."
"Timer millisecondsToRun: [ (Integer new: 150) factorial printNl. ] ; printNl."
"10 times: [ :x| nil benchmark: 10000 ]."
nil benchmark: 10000.

"Class fillChildren.
System fixMethodClasses."

"Jit do: [ nil runAllTests ].
Jit do: [ System rebuildImage ]."
Expand Down Expand Up @@ -3673,7 +3725,13 @@ negated
METHOD Number
factorial
self <= 1 ifTrue: [ ^ 1 ]
ifFalse: [ ^ (self - 1) factorial * self ]
ifFalse: [ ^ self * (self - 1) factorial ]
!
METHOD Number
fib
^ self < 2
ifTrue: [ 1 ]
ifFalse: [ (self - 2) fib + (self - 1) fib ]
!
METHOD Number
asDigit
Expand Down Expand Up @@ -3859,8 +3917,6 @@ bitShift: arg
COMMENT ---------- Integer ------------
METHOD MetaInteger
new: low
<32 low>
low <- low asSmallInt.
<32 low>.
self primitiveFailed
!
Expand Down
23 changes: 23 additions & 0 deletions include/interpreter/exceptions.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once

namespace Interpreter
{

class exception {
public:
exception() throw() {}
virtual ~exception() throw() {}
virtual const char* what() const throw() = 0;
};
class halt_execution : exception {
public:
halt_execution() {}
virtual const char* what() const throw() { return "You must stop execution of the current Process because of exceptions"; }
};
class out_of_memory : exception {
public:
out_of_memory() {}
virtual const char* what() const throw() { return "Memory manager failed to allocate memory"; }
};

}
46 changes: 46 additions & 0 deletions include/interpreter/interpreter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#pragma once

#include "runtime.hpp"
#include <map>

namespace st {
struct TSmalltalkInstruction;
}

namespace Interpreter
{

class Runtime;
class UsualOpcode;
class SpecialOpcode;
class PrimitiveOpcode;
class Interpreter
{
std::map<int, UsualOpcode*> m_usuals;
std::map<int, SpecialOpcode*> m_specials;
std::map<int, PrimitiveOpcode*> m_primitives;
Runtime m_runtime;
public:
enum TExecuteResult {
Failure = 2,
BadMethod = 3,
Success = 4,
TimeExpired = 5
};

explicit Interpreter(IMemoryManager* memoryManager) : m_usuals(), m_specials(), m_primitives(), m_runtime(*this, memoryManager) {}
explicit Interpreter(const Interpreter& interpreter):
m_usuals(interpreter.m_usuals),
m_specials(interpreter.m_specials),
m_primitives(interpreter.m_primitives),
m_runtime(*this, interpreter.m_runtime)
{}
Runtime& runtime();
void execute(const st::TSmalltalkInstruction& instruction);
TExecuteResult execute(TProcess* process, uint32_t ticks);
void installUsual(int opcode, UsualOpcode* f);
void installSpecial(int opcode, SpecialOpcode* f);
void installPrimitive(int opcode, PrimitiveOpcode* f);
};

} // namespace
28 changes: 28 additions & 0 deletions include/interpreter/opcodes.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma once

#include <stdint.h>

namespace Interpreter
{

class Runtime;

class UsualOpcode {
public:
virtual void execute(Runtime& runtime, const uint8_t arg, const uint16_t extra) = 0;
virtual ~UsualOpcode() {}
};

class SpecialOpcode {
public:
virtual void execute(Runtime& runtime, const uint16_t extra) = 0;
virtual ~SpecialOpcode() {}
};

class PrimitiveOpcode {
public:
virtual void execute(Runtime& runtime, const uint8_t arg) = 0;
virtual ~PrimitiveOpcode() {}
};

} // namespace
Loading