// Executes a method declaration on the given fragment. static value_t apply_method_declaration(value_t ambience, value_t decl, value_t fragment) { CHECK_FAMILY(ofMethodDeclarationAst, decl); CHECK_FAMILY(ofModuleFragment, fragment); runtime_t *runtime = get_ambience_runtime(ambience); // Look for the :builtin annotation on this method. value_t annots = get_method_declaration_ast_annotations(decl); value_t builtin_name = new_not_found_condition(); for (size_t i = 0; i < get_array_length(annots); i++) { value_t annot = get_array_at(annots, i); TRY_DEF(value, run_expression_until_condition(ambience, fragment, annot)); if (in_family(ofBuiltinMarker, value)) builtin_name = get_builtin_marker_name(value); } // Compile the method whether it's a builtin or not. This way we can reuse // the compilation code for both cases and just patch up the result after // the fact if it's a builtin. value_t method_ast = get_method_declaration_ast_method(decl); TRY_DEF(method, compile_method_ast_to_method(runtime, method_ast, fragment)); if (!in_condition_cause(ccNotFound, builtin_name)) { // This is a builtin so patch the method with the builtin implementation. TRY_DEF(impl, runtime_get_builtin_implementation(runtime, builtin_name)); value_t impl_code = get_builtin_implementation_code(impl); TRY(validate_builtin_method_binding(method, impl)); set_method_code(method, impl_code); value_t impl_flags = get_builtin_implementation_method_flags(impl); set_method_flags(method, impl_flags); } value_t methodspace = get_module_fragment_methodspace(fragment); TRY(add_methodspace_method(runtime, methodspace, method)); return success(); }
static value_t new_instance_of_string(runtime_t *runtime, value_t type) { value_t factories = ROOT(runtime, plankton_factories); value_t factory = get_id_hash_map_at(factories, type); if (in_family(ofFactory, factory)) { value_t new_instance_wrapper = get_factory_new_instance(factory); void *new_instance_ptr = get_void_p_value(new_instance_wrapper); factory_new_instance_t *new_instance = (factory_new_instance_t*) (intptr_t) new_instance_ptr; return new_instance(runtime); } else { return new_heap_seed(runtime, type, nothing()); } }
static value_t set_heap_object_contents_with_utf8_type(runtime_t *runtime, value_t object, value_t header, value_t payload) { value_t factories = ROOT(runtime, plankton_factories); value_t factory = get_id_hash_map_at(factories, header); if (in_family(ofFactory, factory)) { value_t set_contents_wrapper = get_factory_set_contents(factory); void *set_contents_ptr = get_void_p_value(set_contents_wrapper); factory_set_contents_t *set_contents = (factory_set_contents_t*) (intptr_t) set_contents_ptr; return set_contents(object, runtime, payload); } else { set_seed_payload(object, payload); return success(); } }
// Reads a library from the given library path and adds the modules to this // loaders set of available modules. static value_t module_loader_read_library(runtime_t *runtime, value_t self, value_t library_path) { // Read the library from the file. string_t library_path_str; get_string_contents(library_path, &library_path_str); TRY_DEF(data, read_file_to_blob(runtime, &library_path_str)); TRY_DEF(library, runtime_plankton_deserialize(runtime, data)); if (!in_family(ofLibrary, library)) return new_invalid_input_condition(); set_library_display_name(library, library_path); // Load all the modules from the library into this module loader. id_hash_map_iter_t iter; id_hash_map_iter_init(&iter, get_library_modules(library)); while (id_hash_map_iter_advance(&iter)) { value_t key; value_t value; id_hash_map_iter_get_current(&iter, &key, &value); TRY(set_id_hash_map_at(runtime, get_module_loader_modules(self), key, value)); } return success(); }