+ if (C->enums) {
+ size_t i = 0;
+ struct psi_decl_enum *e;
+
+ while (psi_plist_get(C->enums, i++, &e)) {
+ size_t j = 0;
+ struct psi_decl_enum_item *item;
+
+ while (psi_plist_get(e->items, j++, &item)) {
+ zend_string *name;
+
+ if (psi_decl_type_is_anon(e->name, "enum")) {
+ name = strpprintf(0, "psi\\%s", item->name);
+ } else {
+ name = strpprintf(0, "psi\\%s\\%s", e->name, item->name);
+ }
+
+ if (zend_get_constant(name)) {
+ zend_string_release(name);
+ continue;
+ }
+
+ zc.name = zend_string_dup(name, 1);
+ ZVAL_LONG(&zc.value, psi_num_exp_get_long(item->num, NULL, NULL));
+ zend_register_constant(&zc);
+ zend_string_release(name);
+ }
+ }
+ }
+
+ return C->closures = C->ops->compile(C);
+}
+
+
+ZEND_RESULT_CODE psi_context_call(struct psi_context *C, zend_execute_data *execute_data, zval *return_value, struct psi_impl *impl)
+{
+ struct psi_call_frame *frame;
+
+ frame = psi_call_frame_init(C, impl->decl, impl);
+
+ if (SUCCESS != psi_call_frame_parse_args(frame, execute_data)) {
+ psi_call_frame_free(frame);
+
+ return FAILURE;
+ }
+
+ psi_call_frame_enter(frame);
+
+ if (SUCCESS != psi_call_frame_do_let(frame)) {
+ psi_call_frame_do_return(frame, return_value);
+ psi_call_frame_free(frame);
+
+ return FAILURE;
+ }
+
+ if (SUCCESS != psi_call_frame_do_assert(frame, PSI_ASSERT_PRE)) {
+ psi_call_frame_do_return(frame, return_value);
+ psi_call_frame_free(frame);
+
+ return FAILURE;
+ }