@@ -89,6 +89,7 @@ C_SOURCES=\
CXX_SOURCES=runtime/pz_main.cpp \
runtime/pz.cpp \
runtime/pz_builtin.cpp \
runtime/pz_code.cpp \
runtime/pz_cxx_future.cpp \
runtime/pz_data.cpp \
runtime/pz_io.cpp \
@@ -19,6 +19,9 @@

namespace pz {

static void
static_trace_for_gc(PZ_Heap_Mark_State *marker, void *pz);

/*
* PZ Programs
*************/
@@ -36,7 +39,7 @@ bool
PZ::init()
{
assert(!heap_);
heap_ = pz_gc_init();
heap_ = pz_gc_init(static_trace_for_gc, this);

return heap_ != nullptr;
}
@@ -66,5 +69,22 @@ PZ::add_entry_module(Module *module)
entry_module_ = std::unique_ptr<pz::Module>(module);
}

static void
static_trace_for_gc(PZ_Heap_Mark_State *marker, void *pz)
{
((const PZ*)pz)->trace_for_gc(marker);
}

void
PZ::trace_for_gc(PZ_Heap_Mark_State *marker) const
{
for (auto m : modules) {
m.second->trace_for_gc(marker);
}
if (entry_module_) {
entry_module_->trace_for_gc(marker);
}
}

} // namespace pz

@@ -56,6 +56,8 @@ class PZ {

PZ(const PZ&) = delete;
void operator=(const PZ&) = delete;

void trace_for_gc(PZ_Heap_Mark_State *marker) const;
};

} // namespace pz
@@ -19,11 +19,13 @@ namespace pz {
static void
builtin_create(Module *module, const std::string &name,
unsigned (*func_make_instrs)(uint8_t *bytecode, void *data),
void *data);
void *data,
PZ_Heap *heap);

static void
builtin_create_c_code(Module *module, const char *name,
unsigned (*c_func)(void *stack, unsigned sp, PZ_Heap *));
unsigned (*c_func)(void *stack, unsigned sp, PZ_Heap *),
PZ_Heap *heap);

static unsigned
make_ccall_instr(uint8_t *bytecode, void *c_func);
@@ -170,56 +172,66 @@ builtin_unshift_value_instrs(uint8_t *bytecode, void *data)
}

Module *
setup_builtins(void)
setup_builtins(PZ_Heap *heap)
{
Module *module;

module = new Module();

builtin_create_c_code(module, "print", builtin_print_func);
builtin_create_c_code(module, "int_to_string", builtin_int_to_string_func);
builtin_create_c_code(module, "setenv", builtin_setenv_func);
builtin_create_c_code(module, "gettimeofday", builtin_gettimeofday_func);
builtin_create_c_code(module, "concat_string", builtin_concat_string_func);
builtin_create_c_code(module, "die", builtin_die_func);
builtin_create_c_code(module, "print",
builtin_print_func, heap);
builtin_create_c_code(module, "int_to_string",
builtin_int_to_string_func, heap);
builtin_create_c_code(module, "setenv",
builtin_setenv_func, heap);
builtin_create_c_code(module, "gettimeofday",
builtin_gettimeofday_func, heap);
builtin_create_c_code(module, "concat_string",
builtin_concat_string_func, heap);
builtin_create_c_code(module, "die",
builtin_die_func, heap);
builtin_create_c_code(module, "set_parameter",
builtin_set_parameter_func);

builtin_create(module, "make_tag", builtin_make_tag_instrs, NULL);
builtin_create(module, "shift_make_tag", builtin_shift_make_tag_instrs,
NULL);
builtin_create(module, "break_tag", builtin_break_tag_instrs, NULL);
builtin_create(module, "break_shift_tag", builtin_break_shift_tag_instrs,
NULL);
builtin_create(module, "unshift_value", builtin_unshift_value_instrs,
NULL);
builtin_set_parameter_func, heap);

builtin_create(module, "make_tag",
builtin_make_tag_instrs, NULL, heap);
builtin_create(module, "shift_make_tag",
builtin_shift_make_tag_instrs, NULL, heap);
builtin_create(module, "break_tag",
builtin_break_tag_instrs, NULL, heap);
builtin_create(module, "break_shift_tag",
builtin_break_shift_tag_instrs, NULL, heap);
builtin_create(module, "unshift_value",
builtin_unshift_value_instrs, NULL, heap);

return module;
}

static void
builtin_create(Module *module, const std::string &name,
unsigned (*func_make_instrs)(uint8_t *bytecode, void *data), void *data)
unsigned (*func_make_instrs)(uint8_t *bytecode, void *data), void *data,
PZ_Heap *heap)
{
PZ_Closure *closure;
Proc *proc;
unsigned size;

size = func_make_instrs(NULL, NULL);
proc = new Proc(size);
proc = new Proc(heap, size);
func_make_instrs(proc->code(), data);

closure = pz_init_closure(proc->code(), NULL);
closure = pz_init_closure(heap, proc->code(), NULL, NULL);

module->add_symbol(name, closure);
}

static void
builtin_create_c_code(Module *module, const char *name,
unsigned (*c_func)(void *stack, unsigned sp, PZ_Heap *heap))
unsigned (*c_func)(void *, unsigned, PZ_Heap *),
PZ_Heap *heap)
{
builtin_create(module, name, make_ccall_instr,
reinterpret_cast<void*>(c_func));
reinterpret_cast<void*>(c_func), heap);
}

static unsigned
@@ -10,14 +10,15 @@
#define PZ_BUILTIN_H

#include "pz.h"
#include "pz_gc.h"

#ifdef __cplusplus
extern "C" {
#endif

namespace pz {
Module *
setup_builtins(void);
setup_builtins(PZ_Heap *heap);
}

#ifdef __cplusplus
@@ -9,17 +9,16 @@
#ifndef PZ_CLOSURE_H
#define PZ_CLOSURE_H

#include "pz_gc.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct PZ_Closure_S PZ_Closure;

PZ_Closure *
pz_init_closure(uint8_t *code, void *data);

void
pz_closure_free(PZ_Closure *closure);
pz_init_closure(PZ_Heap *heap, uint8_t *code, void *data, void *top_of_stack);

#ifdef __cplusplus
} // extern "C"
@@ -0,0 +1,22 @@
/*
* Plasma bytecode code structures and functions
* vim: ts=4 sw=4 et
*
* Copyright (C) 2015-2016, 2018 Plasma Team
* Distributed under the terms of the MIT license, see ../LICENSE.code
*/

#include "pz_common.h"

#include "pz_code.h"

namespace pz {

Proc::Proc(PZ_Heap *heap, unsigned size) :
code_size(size)
{
code_ = (uint8_t*)pz_gc_alloc_bytes(heap, size, NULL);
}

} // namespace pz

@@ -23,11 +23,7 @@ class Proc {
unsigned code_size;

public:
Proc(unsigned size) : code_(new uint8_t[size]), code_size(size) {}
~Proc()
{
delete[] code_;
}
Proc(PZ_Heap *heap, unsigned size);

uint8_t * code() const { return code_; }
unsigned size() const { return code_size; }
@@ -46,23 +46,17 @@ Struct::calculate_layout()
**********/

void *
data_new_array_data(PZ_Width width, uint32_t num_elements)
data_new_array_data(PZ_Heap *heap, PZ_Width width, uint32_t num_elements)
{
return malloc(width_to_bytes(width) * num_elements);
return pz_gc_alloc_bytes(heap, width_to_bytes(width) * num_elements,
nullptr);
}

void *
data_new_struct_data(uintptr_t size)
data_new_struct_data(PZ_Heap *heap, uintptr_t size)
{
// TODO: Make this allocate via the GC, then use it during execution of
// PZT_ALLOC.
return malloc(size);
}

void
data_free(void *data)
{
free(data);
// TODO: Use this during execution of PZT_ALLOC.
return pz_gc_alloc_bytes(heap, size, nullptr);
}

/*
@@ -11,8 +11,9 @@

#include <vector>

#include "pz_format.h"
#include "pz_cxx_future.h"
#include "pz_format.h"
#include "pz_gc.h"

namespace pz {

@@ -84,19 +85,13 @@ width_to_bytes(PZ_Width w);
* references to other data, and each element should be machine word sized.
*/
void *
data_new_array_data(PZ_Width width, uint32_t num_elements);
data_new_array_data(PZ_Heap *heap, PZ_Width width, uint32_t num_elements);

/*
* Allocate space for struct data.
*/
void *
data_new_struct_data(uintptr_t size);

/*
* Free any of the above data entries.
*/
void
data_free(void *data);
data_new_struct_data(PZ_Heap *heap, uintptr_t size);

/*
* Functions for storing data in memory