⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 js.c

📁 一个类似windows
💻 C
📖 第 1 页 / 共 3 页
字号:
			 (cls->num_methods + 1) * sizeof (JSMethodReg));
  if (nmethods == NULL)
    return 0;

  cls->methods = nmethods;

  /*
   * The names are interned to symbols when the class is defined to the
   * interpreter.
   */

  cls->methods[cls->num_methods].name = js_strdup (NULL, name);
  if (cls->methods[cls->num_methods].name == NULL)
    return 0;

  cls->methods[cls->num_methods].flags = flags;
  cls->methods[cls->num_methods].method = method;

  cls->num_methods++;

  return 1;
}


int
js_class_define_property (JSClassPtr cls, char *name, unsigned int flags,
			  JSPropertyProc property)
{
  JSPropertyReg *nprops;

  nprops = js_realloc (NULL, cls->properties,
		       (cls->num_properties + 1) * sizeof (JSPropertyReg));
  if (nprops == NULL)
    return 0;

  cls->properties = nprops;

  cls->properties[cls->num_properties].name = js_strdup (NULL, name);
  if (cls->properties[cls->num_properties].name == NULL)
    return 0;

  cls->properties[cls->num_properties].flags = flags;
  cls->properties[cls->num_properties].property = property;

  cls->num_properties++;

  return 1;
}


/* The stub functions for JSClass built-in objects. */

/* Method proc. */
static int
cls_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
	    void *instance_context, JSSymbol method, JSNode *result_return,
	    JSNode *args)
{
  JSClassPtr cls = builtin_info->obj_context;
  JSObjectInstanceCtx *ictx = instance_context;
  int i;
  JSMethodResult result;
  char msg[1024];

  /* Let's see if we know the method. */
  for (i = 0; i < cls->num_methods; i++)
    if (cls->methods[i].sym == method)
      {
	/* Found it. */

	/* Check flags. */
	if ((cls->methods[i].flags & JS_CF_STATIC) == 0
	    && instance_context == NULL)
	  /* An instance method called from the `main' class. */
	  break;

	result = (*cls->methods[i].method) (cls,
					    (ictx
					     ? ictx->instance_context
					     : NULL),
					    cls->interp, args[0].u.vinteger,
					    (JSType *) &args[1],
					    (JSType *) result_return,
					    msg);
	if (result == JS_ERROR)
	  {
	    sprintf (vm->error, "%s.%s(): %s", cls->name,
		     cls->methods[i].name, msg);
	    js_vm_error (vm);
	  }

	return JS_PROPERTY_FOUND;
      }

  return JS_PROPERTY_UNKNOWN;
}

/* Property proc. */
static int
cls_property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
	      void *instance_context, JSSymbol property, int set, JSNode *node)
{
  JSClassPtr cls = builtin_info->obj_context;
  JSObjectInstanceCtx *ictx = instance_context;
  JSMethodResult result;
  char msg[1024];
  int i;

  /* Find the property. */
  for (i = 0; i < cls->num_properties; i++)
    if (cls->properties[i].sym == property)
      {
	/* Found it. */

	/* Check flags. */

	if ((cls->properties[i].flags & JS_CF_STATIC) == 0
	    && instance_context == NULL)
	  break;

	if ((cls->properties[i].flags & JS_CF_IMMUTABLE) && set)
	  {
	    sprintf (vm->error, "%s.%s: immutable property",
		     cls->name, cls->properties[i].name);
	    js_vm_error (vm);
	  }

	result = (*cls->properties[i].property) (cls,
						 (ictx
						  ? ictx->instance_context
						  : NULL),
						 cls->interp, set,
						 (JSType *) node, msg);
	if (result == JS_ERROR)
	  {
	    sprintf (vm->error, "%s.%s: %s", cls->name,
		     cls->properties[i].name, msg);
	    js_vm_error (vm);
	  }

	return JS_PROPERTY_FOUND;
      }

  if (!set)
    node->type = JS_UNDEFINED;

  return JS_PROPERTY_UNKNOWN;
}

/* New proc. */
static void
cls_new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args,
	      JSNode *result_return)
{
  JSClassPtr cls = builtin_info->obj_context;
  JSMethodResult result;
  char msg[1024];
  void *instance_context;
  JSFreeProc instance_context_destructor;
  JSObjectInstanceCtx *ictx;

  result = (*cls->constructor) (cls, cls->interp, args[0].u.vinteger,
				(JSType *) &args[1], &instance_context,
				&instance_context_destructor,
				msg);
  if (result == JS_ERROR)
    {
      sprintf (vm->error, "new %s(): %s", cls->name, msg);
      js_vm_error (vm);
    }

  ictx = js_calloc (vm, 1, sizeof (*ictx));
  ictx->instance_context = instance_context;
  ictx->instance_context_destructor = instance_context_destructor;

  js_vm_builtin_create (vm, result_return, builtin_info, ictx);
}


/* Delete proc. */
static void
cls_delete_proc (JSBuiltinInfo *builtin_info, void *instance_context)
{
  JSObjectInstanceCtx *ictx = instance_context;

  if (ictx)
    {
      if (ictx->instance_context_destructor)
	(*ictx->instance_context_destructor) (ictx->instance_context);

      js_free (ictx);
    }
}

/*
 * This is called to destroy the class handle, when there are no more
 * references to it.
 */
static void
js_class_destructor (void *context)
{
  JSClassPtr cls = context;

  if (cls->no_auto_destroy)
    return;

  js_class_destroy (cls);
}


static void
intern_symbols (JSVirtualMachine *vm, JSClassPtr cls)
{
  int i;

  for (i = 0; i < cls->num_methods; i++)
    cls->methods[i].sym = js_vm_intern (vm, cls->methods[i].name);

  for (i = 0; i < cls->num_properties; i++)
    cls->properties[i].sym = js_vm_intern (vm, cls->properties[i].name);

  cls->interned = 1;
}


static JSBuiltinInfo *
one_builtin_info_please (JSVirtualMachine *vm, JSClassPtr cls)
{
  JSBuiltinInfo *info;

  info = js_vm_builtin_info_create (vm);

  info->method_proc		= cls_method;
  info->property_proc		= cls_property;

  if (cls->constructor)
    {
      info->new_proc 		= cls_new_proc;
      info->delete_proc		= cls_delete_proc;
    }

  info->obj_context		= cls;
  info->obj_context_delete	= js_class_destructor;

  return info;
}


int
js_define_class (JSInterpPtr interp, JSClassPtr cls, char *name)
{
  JSNode *n;
  JSVirtualMachine *vm = interp->vm;
  JSBuiltinInfo *info;

  /* XXX We need a top-level here */

  cls->name = js_strdup (vm, name);
  cls->interp = interp;

  if (!cls->interned)
    /* Intern the symbols and properties. */
    intern_symbols (interp->vm, cls);

  /* Define it to the interpreter. */

  info = one_builtin_info_please (vm, cls);

  n = &vm->globals[js_vm_intern (vm, name)];
  js_vm_builtin_create (vm, n, info, NULL);

  return 1;
}


int
js_instantiate_class (JSInterpPtr interp, JSClassPtr cls, void *ictx,
		      JSFreeProc ictx_destructor, JSType *result_return)
{
  JSObjectInstanceCtx *instance;
  JSVirtualMachine *vm = interp->vm;
  JSBuiltinInfo *info;

  if (!cls->interned)
    /* Intern the symbols and properties. */
    intern_symbols (vm, cls);

  /* Create an instance. */
  instance = js_calloc (vm, 1, sizeof (*instance));
  instance->instance_context = ictx;
  instance->instance_context_destructor = ictx_destructor;

  /* Create a fresh builtin info. */
  info = one_builtin_info_please (vm, cls);

  /* And create it.  */
  js_vm_builtin_create (vm, (JSNode *) result_return, info, instance);

  return 1;
}


JSClassPtr
js_lookup_class (JSInterpPtr interp, char *name)
{
  JSNode *n;
  JSVirtualMachine *vm = interp->vm;

  n = &vm->globals[js_vm_intern (vm, name)];
  if (n->type != JS_BUILTIN)
    return NULL;

  if (n->u.vbuiltin->info->method_proc != cls_method)
    /* This is a wrong built-in. */
    return NULL;

  return (JSClassPtr) n->u.vbuiltin->info->obj_context;
}


int
js_isa (JSInterpPtr interp, JSType *object, JSClassPtr cls,
	void **instance_context_return)
{
  JSNode *n = (JSNode *) object;
  JSObjectInstanceCtx *instance;

  if (n->type != JS_BUILTIN || n->u.vbuiltin->info->obj_context != cls
      || n->u.vbuiltin->instance_context == NULL)
    return 0;

  if (instance_context_return)
    {
      instance = (JSObjectInstanceCtx *) n->u.vbuiltin->instance_context;
      *instance_context_return = instance->instance_context;
    }

  return 1;
}



/* Type functions. */

void
js_type_make_string (JSInterpPtr interp, JSType *type, unsigned char *data,
		     unsigned int length)
{
  JSNode *n = (JSNode *) type;

  js_vm_make_string (interp->vm, n, (char*)data, length);
}


void
js_type_make_array (JSInterpPtr interp, JSType *type, unsigned int length)
{
  JSNode *n = (JSNode *) type;

  js_vm_make_array (interp->vm, n, length);
}


void
js_set_var (JSInterpPtr interp, char *name, JSType *value)
{
  JSNode *n = &interp->vm->globals[js_vm_intern (interp->vm, name)];
  JS_COPY (n, (JSNode *) value);
}


void
js_get_var (JSInterpPtr interp, char *name, JSType *value)
{
  JSNode *n = &interp->vm->globals[js_vm_intern (interp->vm, name)];
  JS_COPY ((JSNode *) value, n);
}


void
js_get_options (JSInterpPtr interp, JSInterpOptions *options)
{
  memcpy (options, &interp->options, sizeof (*options));
}


void
js_set_options (JSInterpPtr interp, JSInterpOptions *options)
{
  memcpy (&interp->options, options, sizeof (*options));

  /* User can change the security options, */

  if (interp->options.secure_builtin_file)
    interp->vm->security |= JS_VM_SECURE_FILE;
  else
    interp->vm->security &= ~JS_VM_SECURE_FILE;

  if (interp->options.secure_builtin_system)
    interp->vm->security |= JS_VM_SECURE_SYSTEM;
  else
    interp->vm->security &= ~JS_VM_SECURE_SYSTEM;

  /* and the event hook. */
  interp->vm->hook			 = options->hook;
  interp->vm->hook_context		 = options->hook_context;
  interp->vm->hook_operand_count_trigger = options->hook_operand_count_trigger;
}


int
js_create_global_method (JSInterpPtr interp, char *name,
			 JSGlobalMethodProc proc, void *context,
			 JSFreeProc context_free_proc)
{
  JSNode *n = &interp->vm->globals[js_vm_intern (interp->vm, name)];
  JSVirtualMachine *vm = interp->vm;
  int result = 1;

  /* Need one toplevel here. */
  {
    JSErrorHandlerFrame handler;

    /* We must create the toplevel ourself. */
    memset (&handler, 0, sizeof (handler));
    handler.next = vm->error_handler;
    vm->error_handler = &handler;

    if (setjmp (vm->error_handler->error_jmp))
      /* An error occurred. */
      result = 0;
    else
      {
	JSBuiltinInfo *info;
	JSGlobalMethodContext *ctx;

	/* Context. */
	ctx = js_calloc (vm, 1, sizeof (*ctx));

	ctx->proc = proc;
	ctx->context = context;
	ctx->free_proc = context_free_proc;
	ctx->interp = interp;

	/* Info. */
	info = js_vm_builtin_info_create (vm);
	info->global_method_proc = js_global_method_stub;
	info->delete_proc = js_global_method_delete;

	/* Create the builtin. */
	js_vm_builtin_create (interp->vm, n, info, ctx);
      }

    /* Pop the error handler. */
    vm->error_handler = vm->error_handler->next;
  }

  return result;
}


int
js_define_module (JSInterpPtr interp, JSModuleInitProc init_proc)
{
  JSErrorHandlerFrame handler;
  JSVirtualMachine *vm = interp->vm;
  int result = 1;

  /* Just call the init proc in a toplevel. */

  memset (&handler, 0, sizeof (handler));
  handler.next = vm->error_handler;
  vm->error_handler = &handler;

  if (setjmp (vm->error_handler->error_jmp))
    /* An error occurred. */
    result = 0;
  else
    /* Call the module init proc. */
    (*init_proc) (interp);

  /* Pop the error handler. */
  vm->error_handler = vm->error_handler->next;

  return result;
}



/*
 * Static functions.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -