{"action":"created","comment":{"url":"https://api.github.com/repos/livecode/livecode/pulls/comments/68744338","id":68744338,"diff_hunk":"@@ -0,0 +1,871 @@\n+/* Copyright (C) 2003-2016 LiveCode Ltd.\n+ \n+ This file is part of LiveCode.\n+ \n+ LiveCode is free software; you can redistribute it and/or modify it under\n+ the terms of the GNU General Public License v3 as published by the Free\n+ Software Foundation.\n+ \n+ LiveCode is distributed in the hope that it will be useful, but WITHOUT ANY\n+ WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n+ for more details.\n+ \n+ You should have received a copy of the GNU General Public License\n+ along with LiveCode.  If not see <http://www.gnu.org/licenses/>.  */\n+\n+#include <libscript/script.h>\n+\n+#include \"script-private.h\"\n+\n+#include \"script-validate.hpp\"\n+#include \"script-execute.hpp\"\n+\n+/*\n+struct MCScriptBytecodeOp_Noop\n+{\n+\t// The code used to specify the operation\n+\tstatic const MCScriptBytecodeOpcode kCode = kMCScriptBytecodeOpcodeNoop;\n+ \n+\t// The name of the operation, as used in bytecode blocks\n+\tstatic const char *kName = \"noop\";\n+ \n+\t// The parameter description of the operation:\n+\t//   l - label\n+\t//   r - register (param, local or temp)\n+\t//   c - constant pool index\n+\t//   d - fetchable definition (variable, constant, handler)\n+\t//   h - handler definition\n+\t//   v - variable definition\n+\t// The final char of the description string can be one of:\n+\t//   ? - the final parameter is optional\n+\t//   * - the final parameter type is expected 0-n times\n+\t//   % - the final parameter type is expected 0-2n times\n+\t//\n+\tstatic const char *kFormat = \"\";\n+\t\n+\t// Validate is performed when a module is loaded to ensure that the\n+\t// operation is well-formed in terms of its argument.\n+\tstatic bool Validate(MCScriptValidateContext& ctxt)\n+\t{\n+\t\treturn true;\n+\t}\n+\t\n+\t// Execute is performed during execution to actually run the given\n+\t// operation.\n+\tstatic bool Execute(MCScriptExecuteContext& ctxt)\n+\t{\n+\t\treturn true;\n+\t}\n+};\n+*/\n+\n+#define MC_SCRIPT_DEFINE_BYTECODE(NameM, LabelM, FormatM) \\\n+\tstatic MCScriptBytecodeOp Code(void) { return kMCScriptBytecodeOp##NameM; } \\\n+\tstatic const char *Name(void) {return LabelM; } \\\n+\tstatic const char *Format(void) {return FormatM; }\n+\n+struct MCScriptBytecodeOp_Jump\n+{\n+\t// jump <offset>\n+\t//\n+\t// Jump <offset> bytes in the bytecode relative to the jump opcode's\n+\t// address.\n+\t\n+\tMC_SCRIPT_DEFINE_BYTECODE(Jump, \"jump\", \"l\")\n+\t\n+\tstatic void Validate(MCScriptValidateContext& ctxt)\n+\t{\n+\t\tctxt.CheckArity(1);\n+\t\tctxt.CheckAddress(ctxt.GetAddress() +\n+\t\t\t\t\t\t  ctxt.GetSignedArgument(0));\n+\t}\n+\t\n+\tstatic void Execute(MCScriptExecuteContext& ctxt)\n+\t{\n+\t\tctxt.Jump(ctxt.GetSignedArgument(0));\n+\t}\n+};\n+\n+template<bool IfTrue>\n+struct MCScriptBytecodeOp_JumpIf\n+{\n+\t// jump_if* <cond-reg>, <offset>\n+\t//\n+\t// Test <cond-reg> is a bool, and if so jump <offset> bytes in the bytecode\n+\t// relative to the jump_if*'s opcode's address if the value in <cond-reg>\n+\t// is IfTrue.\n+\t\n+\tstatic bool Validate(MCScriptValidateContext& ctxt)\n+\t{\n+\t\tctxt.CheckArity(2);\n+\t\tctxt.CheckRegister(ctxt.GetArgument(0));\n+\t\tctxt.CheckAddress(ctxt.GetAddress() +\n+\t\t\t\t\t\t  ctxt.GetSignedArgument(0));\n+\t}\n+\t\n+\tstatic void Execute(MCScriptExecuteContext& ctxt)\n+\t{\n+\t\tif (IfTrue != ctxt.CheckedFetchRegisterAsBool(ctxt.GetArgument(0)))\n+\t\t\treturn;\n+\t\t\n+\t\tctxt.Jump(ctxt.GetSignedArgument(1));\n+\t}\n+};\n+\n+struct MCScriptBytecodeOp_JumpIfFalse: public MCScriptBytecodeOp_JumpIf<false>\n+{\n+\tMC_SCRIPT_DEFINE_BYTECODE(JumpIfFalse, \"jump_if_false\", \"rl\")\n+};\n+\n+struct MCScriptBytecodeOp_JumpIfTrue: public MCScriptBytecodeOp_JumpIf<true>\n+{\n+\tMC_SCRIPT_DEFINE_BYTECODE(JumpIfTrue, \"jump_if_true\", \"rl\")\n+};\n+\n+struct MCScriptBytecodeOp_AssignConstant\n+{\n+\t// assign_constant <dst-reg>, <constant-idx>\n+\t//\n+\t// Fetch the constant pool value at <constant-idx> and store into\n+\t// <dst-reg>. The constant must conform to the type of register.\n+\t\n+\tMC_SCRIPT_DEFINE_BYTECODE(AssignConstant, \"assign_constant\", \"rc\")\n+\t\n+\tstatic void Validate(MCScriptValidateContext& ctxt)\n+\t{\n+\t\tctxt.CheckArity(2);\n+\t\tctxt.CheckRegister(ctxt.GetArgument(0));\n+\t\tctxt.CheckValue(ctxt.GetArgument(1));\n+\t}\n+\t\n+\tstatic void Execute(MCScriptExecuteContext& ctxt)\n+\t{\n+\t\tctxt.CheckedStoreRegister(ctxt.GetArgument(0),\n+\t\t\t\t\t\t\t\t  ctxt.FetchValue(ctxt.GetArgument(1)));\n+\t}\n+};\n+\n+struct MCScriptBytecodeOp_Assign\n+{\n+\t// assign <dst-reg>, <src-reg>\n+\t//\n+\t// Fetch the value from <src-reg> and store it into <dst-reg>. The value\n+\t// being stored must conform to the type of the register.\n+\t\n+\tMC_SCRIPT_DEFINE_BYTECODE(AssignConstant, \"assign\", \"rr\")\n+\t\n+\tstatic void Validate(MCScriptValidateContext& ctxt)\n+\t{\n+\t\tctxt.CheckArity(2);\n+\t\tctxt.CheckRegister(ctxt.GetArgument(0));\n+\t\tctxt.CheckRegister(ctxt.GetArgument(1));\n+\t}\n+\t\n+\tstatic void Execute(MCScriptExecuteContext& ctxt)\n+\t{\n+\t\tctxt.CheckedStoreRegister(ctxt.GetArgument(0),\n+\t\t\t\t\t\t\t\t  ctxt.CheckedFetchRegister(ctxt.GetArgument(1)));\n+\t}\n+};\n+\n+struct MCScriptBytecodeOp_Return\n+{\n+\t// return [ <result-reg> ]\n+\t//\n+\t// Return from the current frame, setting the normal return value to the\n+\t// contents of <result-reg> if specified, and nothing if not. The return\n+\t// value must conform to the type of the handler's return value.\n+\t\n+\tMC_SCRIPT_DEFINE_BYTECODE(AssignConstant, \"return\", \"r?\")\n+\t\n+\tstatic void Validate(MCScriptValidateContext& ctxt)\n+\t{\n+\t\tif (ctxt.GetArity() == 0)\n+\t\t{\n+\t\t\t// Nothing to check\n+\t\t}\n+\t\telse if (ctxt.GetArity() == 1)\n+\t\t{\n+\t\t\tctxt.CheckRegister(ctxt.GetArgument(0));\n+\t\t}\n+\t\telse\n+\t\t{\n+\t\t\tctxt.ReportInvalidArity();\n+\t\t}\n+\t}\n+\t\n+\tstatic void Execute(MCScriptExecuteContext& ctxt)\n+\t{\n+\t\tMCValueRef t_return_value = nil;\n+\t\tif (ctxt.GetArgumentCount() == 0)\n+\t\t\tt_return_value = kMCNull;\n+\t\telse\n+\t\t\tt_return_value = ctxt.CheckedFetchRegister(ctxt.GetArgument(0));\n+\t\t\n+\t\tctxt.PopFrame(t_return_value);\n+\t}\n+};\n+\n+struct MCScriptBytecodeOp_Invoke\n+{\n+\t// invoke <handler-idx>, <result-reg>, <arg_1-reg>, ..., <arg_n-reg>\n+\t//\n+\t// Invoke the given handler (which can be a normal handler, foreign handler\n+\t// or a handler group), returning the value into result-reg and using the\n+\t// arg_i-reg's as the in, out and inout parameters.\n+\t\n+\tMC_SCRIPT_DEFINE_BYTECODE(Invoke, \"invoke\", \"hrr*\")\n+\t\n+\tstatic void Validate(MCScriptValidateContext& ctxt)\n+\t{\n+\t\tif (ctxt.GetArity() < 2)\n+\t\t\tctxt.ReportInvalidArity();\n+\t\t\n+\t\tctxt.CheckHandler(ctxt.GetArgument(0));\n+\t\t\n+\t\tfor(uindex_t i = 1; i < ctxt.GetArity(); i++)\n+\t\t\tctxt.CheckRegister(ctxt.GetArgument(i));\n+\t}\n+\t\n+\tstatic void Execute(MCScriptExecuteContext& ctxt)\n+\t{\n+\t\t// Resolve the import definition chain for the specified definition.\n+\t\tMCScriptInstanceRef t_instance = nil;\n+\t\tMCScriptDefinition *t_definition = nil;\n+\t\tctxt.ResolveDefinition(ctxt.GetArgument(0),\n+\t\t\t\t\t\t\t   t_instance,\n+\t\t\t\t\t\t\t   t_definition);\n+\t\t\n+\t\t// The result register is the second argument.\n+\t\tuindex_t t_result_reg;\n+\t\tt_result_reg = ctxt.GetArgument(1);\n+\t\t\n+\t\t// The argument list starts at the third argument.\n+\t\tuindex_t *t_argument_regs;\n+\t\tuindex_t t_argument_count;\n+\t\tt_argument_regs = ctxt.GetArgumentList() + 2;\n+\t\tt_argument_count = ctxt.GetArgumentCount() - 2;\n+\t\t\n+\t\t\n+\t\t// If the definition kind is a group, then we must select which handler\n+\t\t// in the group is appropriate based on the in-mode argument types.\n+\t\tif (t_definition -> kind == kMCScriptDefinitionKindDefinitionGroup)\n+\t\t{\n+\t\t\tSelectDefinitionFromGroup(ctxt,\n+\t\t\t\t\t\t\t\t\t  t_instance,\n+\t\t\t\t\t\t\t\t\t  static_cast<MCScriptDefinitionGroupDefinition *>(t_definition),\n+\t\t\t\t\t\t\t\t\t  t_argument_regs,\n+\t\t\t\t\t\t\t\t\t  t_argument_count,\n+\t\t\t\t\t\t\t\t\t  t_instance,\n+\t\t\t\t\t\t\t\t\t  t_definition);\n+\t\t}\n+\t\t\n+\t\t// If we have no definition (due to failure), we return,\n+\t\tif (t_definition == nil)\n+\t\t\treturn;\n+\t\t\n+\t\tif (t_definition -> kind == kMCScriptDefinitionKindHandler)\n+\t\t{\n+\t\t\tctxt.PushFrame(t_instance,\n+\t\t\t\t\t\t   static_cast<MCScriptHandlerDefinition *>(t_definition),\n+\t\t\t\t\t\t   t_result_reg,\n+\t\t\t\t\t\t   t_argument_regs,\n+\t\t\t\t\t\t   t_argument_count);\n+\t\t}\n+\t\telse if (t_definition -> kind == kMCScriptDefinitionKindForeignHandler)\n+\t\t{\n+\t\t\tctxt.InvokeForeign(t_instance,\n+\t\t\t\t\t\t\t   static_cast<MCScriptForeignHandlerDefinition *>(t_definition),\n+\t\t\t\t\t\t\t   t_result_reg,\n+\t\t\t\t\t\t\t   t_argument_regs,\n+\t\t\t\t\t\t\t   t_argument_count);\n+\t\t}\n+\t\telse\n+\t\t{\n+\t\t\t__MCScriptUnreachable__(\"invalid definition kind in invoke\");\n+\t\t}\n+\t}\n+\t\n+private:\n+\tstatic void SelectDefinitionFromGroup(MCScriptExecuteContext& ctxt,\n+\t\t\t\t\t\t\t\t\t\t  MCScriptInstanceRef p_instance,\n+\t\t\t\t\t\t\t\t\t\t  MCScriptDefinitionGroupDefinition *p_group,\n+\t\t\t\t\t\t\t\t\t\t  uindex_t *p_arguments,\n+\t\t\t\t\t\t\t\t\t\t  uindex_t p_argument_count,\n+\t\t\t\t\t\t\t\t\t\t  MCScriptInstanceRef& r_selected_instance,\n+\t\t\t\t\t\t\t\t\t\t  MCScriptDefinition*& r_selected_definition)\n+\t{\n+\t\t// We use a simple scoring mechanism to determine which method to use. If\n+\t\t// input type for an argument is equal to expected type, then this is a\n+\t\t// score of zero. If input type for an argument conforms to expected type, then\n+\t\t// this is a score of 1. The method with the lowest score is chosen, with\n+\t\t// priority given to the first in the list in the case of a tie.\n+\t\t\n+\t\tuindex_t t_min_score = UINDEX_MAX;\n+\t\tMCScriptDefinition *t_min_score_definition = nil;\n+\t\tMCScriptInstanceRef t_min_score_instance = nil;\n+\t\tfor(uindex_t t_handler_idx = 0; t_handler_idx < p_group -> handler_count; t_handler_idx++)\n+\t\t{\n+\t\t\tMCScriptInstanceRef t_current_instance;\n+\t\t\tMCScriptDefinition *t_current_definition;\n+\t\t\tctxt.ResolveDefinition(p_group -> handlers[t_handler_idx],\n+\t\t\t\t\t\t\t\t   t_current_instance,\n+\t\t\t\t\t\t\t\t   t_current_definition);\n+\t\t\t\n+\t\t\tMCScriptCommonHandlerDefinition *t_current_handler;\n+\t\t\tt_current_handler = static_cast<MCScriptCommonHandlerDefinition *>(t_current_definition);\n+\t\t\t\n+\t\t\t// The signature of handler definitions is always a handler typeinfo.\n+\t\t\tMCTypeInfoRef t_current_signature;\n+\t\t\tt_current_signature = t_current_instance -> module -> types[t_current_handler -> type] -> typeinfo;\n+\t\t\t\n+\t\t\tif (MCHandlerTypeInfoGetParameterCount(t_current_signature) != p_argument_count)\n+\t\t\t\tcontinue;\n+\t\t\t\n+\t\t\tuindex_t t_current_score = 0;\n+\t\t\tfor(uindex_t t_arg_idx = 0; t_arg_idx < p_argument_count; t_arg_idx++)\n+\t\t\t{\n+\t\t\t\t// We can't compare types of out arguments as they have no value\n+\t\t\t\t// (yet).\n+\t\t\t\tif (MCHandlerTypeInfoGetParameterMode(t_current_signature,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  t_arg_idx) == kMCHandlerTypeFieldModeOut)\n+\t\t\t\t\tcontinue;\n+\t\t\t\t\n+\t\t\t\t// Fetch the value in the register.\n+\t\t\t\tMCValueRef t_arg_value;\n+\t\t\t\tt_arg_value = ctxt.CheckedFetchRegister(p_arguments[t_arg_idx]);\n+\t\t\t\t\n+\t\t\t\t// If the fetch failed, there was an error.\n+\t\t\t\tif (t_arg_value == nil)\n+\t\t\t\t\treturn;\n+\t\t\t\t\n+\t\t\t\tMCTypeInfoRef t_arg_type, t_param_type;\n+\t\t\t\tt_arg_type = MCValueGetTypeInfo(t_arg_value);\n+\t\t\t\tt_param_type = MCHandlerTypeInfoGetParameterType(t_current_signature,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t t_arg_idx);\n+\t\t\t\t\n+\t\t\t\t// If the typeinfo's are the same, short-circuit to a score of 0\n+\t\t\t\tif (t_arg_type == t_param_type)\n+\t\t\t\t\tcontinue;\n+\t\t\t\t\n+\t\t\t\t// Resolve both the source and target types.\n+\t\t\t\tMCResolvedTypeInfo t_resolved_arg_type, t_resolved_param_type;\n+\t\t\t\tif (!ctxt.ResolveType(t_arg_type,\n+\t\t\t\t\t\t\t\t\t  t_resolved_arg_type))\n+\t\t\t\t\treturn;\n+\t\t\t\t\n+\t\t\t\tif (!ctxt.ResolveType(t_param_type,\n+\t\t\t\t\t\t\t\t\t  t_resolved_param_type))\n+\t\t\t\t\treturn;\n+\t\t\t\t\n+\t\t\t\t// If the resolved types are the same, then this argument matches.\n+\t\t\t\tif (t_resolved_arg_type . type == t_resolved_param_type . type)\n+\t\t\t\t\tcontinue;\n+\t\t\t\t\n+\t\t\t\t// If the types don't conform, then this method is no good.\n+\t\t\t\tif (!MCResolvedTypeInfoConforms(t_resolved_arg_type,\n+\t\t\t\t\t\t\t\t\t\t\t\tt_resolved_param_type))\n+\t\t\t\t{\n+\t\t\t\t\tt_current_score = UINDEX_MAX;\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t\t\n+\t\t\t\t// Otherwise we have a score of 1\n+\t\t\t\tt_current_score += 1;\n+\t\t\t}\n+\n+\t\t\tif (t_current_score < t_min_score)\n+\t\t\t{\n+\t\t\t\tt_min_score = t_current_score;\n+\t\t\t\tt_min_score_definition = t_current_definition;\n+\t\t\t\tt_min_score_instance = t_current_instance;\n+\t\t\t}\n+\t\t}\n+\t\tif (t_min_score_definition == NULL)\n+\t\t{\n+\t\t\tctxt.ThrowUnableToResolveMultiInvoke(p_group, p_arguments, p_argument_count);\n+\t\t\treturn;\n+\t\t}\n+\t\t\n+\t\tr_selected_instance = t_min_score_instance;\n+\t\tr_selected_definition = t_min_score_definition;\n+\t}\n+};\n+\n+struct MCScriptBytecodeOp_InvokeIndirect\n+{\n+\t// invoke_indirect <handler-reg>, <result-reg>, <arg_1-reg>, ..., <arg_n-reg>\n+\t//\n+\t// Invoke the handler value in handler-reg, returning the value into\n+\t// result-reg and using the arg_i-reg's as the in, out and inout parameters.\n+\t\n+\tMC_SCRIPT_DEFINE_BYTECODE(InvokeIndirect, \"invoke_indirect\", \"rrr*\")\n+\t\n+\tstatic void Validate(MCScriptValidateContext& ctxt)\n+\t{\n+\t\tif (ctxt.GetArity() < 2)\n+\t\t{\n+\t\t\tctxt.ReportInvalidArity();\n+\t\t\treturn;\n+\t\t}\n+\t\t\t\n+\t\tctxt.CheckRegister(ctxt.GetArgument(0));\n+\t\t\n+\t\tfor(uindex_t i = 1; i < ctxt.GetArity(); i++)\n+\t\t\tctxt.CheckRegister(ctxt.GetArgument(i));\n+\t}\n+\t\n+\tstatic void Execute(MCScriptExecuteContext& ctxt)\n+\t{\n+\t\t// The result register is the second argument.\n+\t\tuindex_t t_result_reg;\n+\t\tt_result_reg = ctxt.GetArgument(1);\n+\t\t\n+\t\t// The argument list starts at the third argument.\n+\t\tuindex_t *t_argument_regs;\n+\t\tuindex_t t_argument_count;\n+\t\tt_argument_regs = ctxt.GetArgumentList() + 2;\n+\t\tt_argument_count = ctxt.GetArgumentCount() - 2;\n+\t\t\n+\t\tMCValueRef t_handler;\n+\t\tt_handler = ctxt.CheckedFetchRegister(ctxt.GetArgument(0));\n+\t\tif (t_handler == nil)\n+\t\t\treturn;\n+\t\t\n+\t\tif (MCValueGetTypeCode(t_handler) != kMCValueTypeCodeHandler)\n+\t\t{\n+\t\t\tctxt.ThrowNotAHandlerValue(t_handler);\n+\t\t\treturn;\n+\t\t}\n+\t\t\n+\t\t// If the handler-ref is of 'internal' kind (i.e. a instance/definition\n+\t\t// pair) then we can invoke directly; otherwise the handler-ref must\n+\t\t// be wrapping some other sort of invokable handler and thus we must\n+\t\t// use the MCHandlerRef API.\n+\t\tif (ctxt.IsInternalHandler((MCHandlerRef)t_handler))\n+\t\t{\n+\t\t\tInternalInvoke(ctxt,\n+\t\t\t\t\t\t   (MCHandlerRef)t_handler,\n+\t\t\t\t\t\t   t_result_reg,\n+\t\t\t\t\t\t   t_argument_regs,\n+\t\t\t\t\t\t   t_argument_count);\n+\t\t}\n+\t\telse\n+\t\t{\n+\t\t\tExternalInvoke(ctxt,\n+\t\t\t\t\t\t   (MCHandlerRef)t_handler,\n+\t\t\t\t\t\t   t_result_reg,\n+\t\t\t\t\t\t   t_argument_regs,\n+\t\t\t\t\t\t   t_argument_count);\n+\t\t}\n+\t}\n+\t\n+private:\n+\tstatic void InternalInvoke(MCScriptExecuteContext& ctxt,\n+\t\t\t\t\t\t\t   MCHandlerRef p_handler,\n+\t\t\t\t\t\t\t   uindex_t p_result_reg,\n+\t\t\t\t\t\t\t   uindex_t *p_argument_regs,\n+\t\t\t\t\t\t\t   uindex_t p_argument_count)\n+\t{\n+\t\t// An 'internal' handler-ref is nothing more than an instance/definition\n+\t\t// pair, so we can execute directly inside this execution context. This\n+\t\t// avoids packing/unpacking the argument list as MCValueRefs and we can\n+\t\t// use the register file directly.\n+\t\t\n+\t\tMCScriptExecuteContext::InternalHandlerContext *t_context;\n+\t\tt_context = (MCScriptExecuteContext::InternalHandlerContext *)MCHandlerGetContext((MCHandlerRef)p_handler);\n+\t\t\n+\t\tif (t_context -> definition -> kind == kMCScriptDefinitionKindHandler)\n+\t\t{\n+\t\t\tctxt.PushFrame(t_context -> instance,\n+\t\t\t\t\t\t   static_cast<MCScriptHandlerDefinition *>(t_context -> definition),\n+\t\t\t\t\t\t   p_result_reg,\n+\t\t\t\t\t\t   p_argument_regs,\n+\t\t\t\t\t\t   p_argument_count);\n+\t\t}\n+\t\telse if (t_context -> definition -> kind == kMCScriptDefinitionKindForeignHandler)\n+\t\t{\n+\t\t\tctxt.InvokeForeign(t_context -> instance,\n+\t\t\t\t\t\t\t   static_cast<MCScriptForeignHandlerDefinition *>(t_context -> definition),\n+\t\t\t\t\t\t\t   p_result_reg,\n+\t\t\t\t\t\t\t   p_argument_regs,\n+\t\t\t\t\t\t\t   p_argument_count);\n+\t\t}\n+\t\telse\n+\t\t{\n+\t\t\t__MCScriptUnreachable__(\"invalid definition kind in internal handler-ref\");\n+\t\t}","path":"libscript/src/script-bytecode.hpp","position":498,"original_position":498,"commit_id":"51dcc6d54987d59753f292413ed5f5e51cd86c16","original_commit_id":"51dcc6d54987d59753f292413ed5f5e51cd86c16","user":{"login":"peter-b","id":47528,"avatar_url":"https://avatars.githubusercontent.com/u/47528?v=3","gravatar_id":"","url":"https://api.github.com/users/peter-b","html_url":"https://github.com/peter-b","followers_url":"https://api.github.com/users/peter-b/followers","following_url":"https://api.github.com/users/peter-b/following{/other_user}","gists_url":"https://api.github.com/users/peter-b/gists{/gist_id}","starred_url":"https://api.github.com/users/peter-b/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/peter-b/subscriptions","organizations_url":"https://api.github.com/users/peter-b/orgs","repos_url":"https://api.github.com/users/peter-b/repos","events_url":"https://api.github.com/users/peter-b/events{/privacy}","received_events_url":"https://api.github.com/users/peter-b/received_events","type":"User","site_admin":false},"body":"This looks like a `switch (t_context->definition->kind)`","created_at":"2016-06-28T12:11:48Z","updated_at":"2016-06-28T12:11:48Z","html_url":"https://github.com/livecode/livecode/pull/4190#discussion_r68744338","pull_request_url":"https://api.github.com/repos/livecode/livecode/pulls/4190","_links":{"self":{"href":"https://api.github.com/repos/livecode/livecode/pulls/comments/68744338"},"html":{"href":"https://github.com/livecode/livecode/pull/4190#discussion_r68744338"},"pull_request":{"href":"https://api.github.com/repos/livecode/livecode/pulls/4190"}}},"pull_request":{"url":"https://api.github.com/repos/livecode/livecode/pulls/4190","id":74824205,"html_url":"https://github.com/livecode/livecode/pull/4190","diff_url":"https://github.com/livecode/livecode/pull/4190.diff","patch_url":"https://github.com/livecode/livecode/pull/4190.patch","issue_url":"https://api.github.com/repos/livecode/livecode/issues/4190","number":4190,"state":"open","locked":false,"title":"[[ UntangleVM ]] Work on restructuring core VM bytecode implementation.","user":{"login":"runrevmark","id":3985298,"avatar_url":"https://avatars.githubusercontent.com/u/3985298?v=3","gravatar_id":"","url":"https://api.github.com/users/runrevmark","html_url":"https://github.com/runrevmark","followers_url":"https://api.github.com/users/runrevmark/followers","following_url":"https://api.github.com/users/runrevmark/following{/other_user}","gists_url":"https://api.github.com/users/runrevmark/gists{/gist_id}","starred_url":"https://api.github.com/users/runrevmark/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/runrevmark/subscriptions","organizations_url":"https://api.github.com/users/runrevmark/orgs","repos_url":"https://api.github.com/users/runrevmark/repos","events_url":"https://api.github.com/users/runrevmark/events{/privacy}","received_events_url":"https://api.github.com/users/runrevmark/received_events","type":"User","site_admin":false},"body":"Work-in-progress on restructuring the bytecode loops in the VM.\r\n\r\nBytecodes are in individual classes (as a set of static methods) and break down their operations into more primitive ones executing on a Validate or Execute context.","created_at":"2016-06-22T17:25:53Z","updated_at":"2016-06-28T12:11:48Z","closed_at":null,"merged_at":null,"merge_commit_sha":"da8a5992801df40f2997b4c6000814bce82c1362","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/livecode/livecode/pulls/4190/commits","review_comments_url":"https://api.github.com/repos/livecode/livecode/pulls/4190/comments","review_comment_url":"https://api.github.com/repos/livecode/livecode/pulls/comments{/number}","comments_url":"https://api.github.com/repos/livecode/livecode/issues/4190/comments","statuses_url":"https://api.github.com/repos/livecode/livecode/statuses/51dcc6d54987d59753f292413ed5f5e51cd86c16","head":{"label":"runrevmark:lcb-untangle_vm","ref":"lcb-untangle_vm","sha":"51dcc6d54987d59753f292413ed5f5e51cd86c16","user":{"login":"runrevmark","id":3985298,"avatar_url":"https://avatars.githubusercontent.com/u/3985298?v=3","gravatar_id":"","url":"https://api.github.com/users/runrevmark","html_url":"https://github.com/runrevmark","followers_url":"https://api.github.com/users/runrevmark/followers","following_url":"https://api.github.com/users/runrevmark/following{/other_user}","gists_url":"https://api.github.com/users/runrevmark/gists{/gist_id}","starred_url":"https://api.github.com/users/runrevmark/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/runrevmark/subscriptions","organizations_url":"https://api.github.com/users/runrevmark/orgs","repos_url":"https://api.github.com/users/runrevmark/repos","events_url":"https://api.github.com/users/runrevmark/events{/privacy}","received_events_url":"https://api.github.com/users/runrevmark/received_events","type":"User","site_admin":false},"repo":{"id":9373954,"name":"livecode","full_name":"runrevmark/livecode","owner":{"login":"runrevmark","id":3985298,"avatar_url":"https://avatars.githubusercontent.com/u/3985298?v=3","gravatar_id":"","url":"https://api.github.com/users/runrevmark","html_url":"https://github.com/runrevmark","followers_url":"https://api.github.com/users/runrevmark/followers","following_url":"https://api.github.com/users/runrevmark/following{/other_user}","gists_url":"https://api.github.com/users/runrevmark/gists{/gist_id}","starred_url":"https://api.github.com/users/runrevmark/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/runrevmark/subscriptions","organizations_url":"https://api.github.com/users/runrevmark/orgs","repos_url":"https://api.github.com/users/runrevmark/repos","events_url":"https://api.github.com/users/runrevmark/events{/privacy}","received_events_url":"https://api.github.com/users/runrevmark/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/runrevmark/livecode","description":"","fork":true,"url":"https://api.github.com/repos/runrevmark/livecode","forks_url":"https://api.github.com/repos/runrevmark/livecode/forks","keys_url":"https://api.github.com/repos/runrevmark/livecode/keys{/key_id}","collaborators_url":"https://api.github.com/repos/runrevmark/livecode/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/runrevmark/livecode/teams","hooks_url":"https://api.github.com/repos/runrevmark/livecode/hooks","issue_events_url":"https://api.github.com/repos/runrevmark/livecode/issues/events{/number}","events_url":"https://api.github.com/repos/runrevmark/livecode/events","assignees_url":"https://api.github.com/repos/runrevmark/livecode/assignees{/user}","branches_url":"https://api.github.com/repos/runrevmark/livecode/branches{/branch}","tags_url":"https://api.github.com/repos/runrevmark/livecode/tags","blobs_url":"https://api.github.com/repos/runrevmark/livecode/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/runrevmark/livecode/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/runrevmark/livecode/git/refs{/sha}","trees_url":"https://api.github.com/repos/runrevmark/livecode/git/trees{/sha}","statuses_url":"https://api.github.com/repos/runrevmark/livecode/statuses/{sha}","languages_url":"https://api.github.com/repos/runrevmark/livecode/languages","stargazers_url":"https://api.github.com/repos/runrevmark/livecode/stargazers","contributors_url":"https://api.github.com/repos/runrevmark/livecode/contributors","subscribers_url":"https://api.github.com/repos/runrevmark/livecode/subscribers","subscription_url":"https://api.github.com/repos/runrevmark/livecode/subscription","commits_url":"https://api.github.com/repos/runrevmark/livecode/commits{/sha}","git_commits_url":"https://api.github.com/repos/runrevmark/livecode/git/commits{/sha}","comments_url":"https://api.github.com/repos/runrevmark/livecode/comments{/number}","issue_comment_url":"https://api.github.com/repos/runrevmark/livecode/issues/comments{/number}","contents_url":"https://api.github.com/repos/runrevmark/livecode/contents/{+path}","compare_url":"https://api.github.com/repos/runrevmark/livecode/compare/{base}...{head}","merges_url":"https://api.github.com/repos/runrevmark/livecode/merges","archive_url":"https://api.github.com/repos/runrevmark/livecode/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/runrevmark/livecode/downloads","issues_url":"https://api.github.com/repos/runrevmark/livecode/issues{/number}","pulls_url":"https://api.github.com/repos/runrevmark/livecode/pulls{/number}","milestones_url":"https://api.github.com/repos/runrevmark/livecode/milestones{/number}","notifications_url":"https://api.github.com/repos/runrevmark/livecode/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/runrevmark/livecode/labels{/name}","releases_url":"https://api.github.com/repos/runrevmark/livecode/releases{/id}","deployments_url":"https://api.github.com/repos/runrevmark/livecode/deployments","created_at":"2013-04-11T15:43:35Z","updated_at":"2015-05-23T15:45:42Z","pushed_at":"2016-06-28T11:32:48Z","git_url":"git://github.com/runrevmark/livecode.git","ssh_url":"git@github.com:runrevmark/livecode.git","clone_url":"https://github.com/runrevmark/livecode.git","svn_url":"https://github.com/runrevmark/livecode","homepage":null,"size":116724,"stargazers_count":1,"watchers_count":1,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":1,"default_branch":"master"}},"base":{"label":"livecode:develop","ref":"develop","sha":"80de4f3300eec5a22fea6f2b61b7042a32c5b269","user":{"login":"livecode","id":3985749,"avatar_url":"https://avatars.githubusercontent.com/u/3985749?v=3","gravatar_id":"","url":"https://api.github.com/users/livecode","html_url":"https://github.com/livecode","followers_url":"https://api.github.com/users/livecode/followers","following_url":"https://api.github.com/users/livecode/following{/other_user}","gists_url":"https://api.github.com/users/livecode/gists{/gist_id}","starred_url":"https://api.github.com/users/livecode/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/livecode/subscriptions","organizations_url":"https://api.github.com/users/livecode/orgs","repos_url":"https://api.github.com/users/livecode/repos","events_url":"https://api.github.com/users/livecode/events{/privacy}","received_events_url":"https://api.github.com/users/livecode/received_events","type":"Organization","site_admin":false},"repo":{"id":9334445,"name":"livecode","full_name":"livecode/livecode","owner":{"login":"livecode","id":3985749,"avatar_url":"https://avatars.githubusercontent.com/u/3985749?v=3","gravatar_id":"","url":"https://api.github.com/users/livecode","html_url":"https://github.com/livecode","followers_url":"https://api.github.com/users/livecode/followers","following_url":"https://api.github.com/users/livecode/following{/other_user}","gists_url":"https://api.github.com/users/livecode/gists{/gist_id}","starred_url":"https://api.github.com/users/livecode/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/livecode/subscriptions","organizations_url":"https://api.github.com/users/livecode/orgs","repos_url":"https://api.github.com/users/livecode/repos","events_url":"https://api.github.com/users/livecode/events{/privacy}","received_events_url":"https://api.github.com/users/livecode/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/livecode/livecode","description":"LiveCode cross-platform development environment (engine)","fork":false,"url":"https://api.github.com/repos/livecode/livecode","forks_url":"https://api.github.com/repos/livecode/livecode/forks","keys_url":"https://api.github.com/repos/livecode/livecode/keys{/key_id}","collaborators_url":"https://api.github.com/repos/livecode/livecode/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/livecode/livecode/teams","hooks_url":"https://api.github.com/repos/livecode/livecode/hooks","issue_events_url":"https://api.github.com/repos/livecode/livecode/issues/events{/number}","events_url":"https://api.github.com/repos/livecode/livecode/events","assignees_url":"https://api.github.com/repos/livecode/livecode/assignees{/user}","branches_url":"https://api.github.com/repos/livecode/livecode/branches{/branch}","tags_url":"https://api.github.com/repos/livecode/livecode/tags","blobs_url":"https://api.github.com/repos/livecode/livecode/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/livecode/livecode/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/livecode/livecode/git/refs{/sha}","trees_url":"https://api.github.com/repos/livecode/livecode/git/trees{/sha}","statuses_url":"https://api.github.com/repos/livecode/livecode/statuses/{sha}","languages_url":"https://api.github.com/repos/livecode/livecode/languages","stargazers_url":"https://api.github.com/repos/livecode/livecode/stargazers","contributors_url":"https://api.github.com/repos/livecode/livecode/contributors","subscribers_url":"https://api.github.com/repos/livecode/livecode/subscribers","subscription_url":"https://api.github.com/repos/livecode/livecode/subscription","commits_url":"https://api.github.com/repos/livecode/livecode/commits{/sha}","git_commits_url":"https://api.github.com/repos/livecode/livecode/git/commits{/sha}","comments_url":"https://api.github.com/repos/livecode/livecode/comments{/number}","issue_comment_url":"https://api.github.com/repos/livecode/livecode/issues/comments{/number}","contents_url":"https://api.github.com/repos/livecode/livecode/contents/{+path}","compare_url":"https://api.github.com/repos/livecode/livecode/compare/{base}...{head}","merges_url":"https://api.github.com/repos/livecode/livecode/merges","archive_url":"https://api.github.com/repos/livecode/livecode/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/livecode/livecode/downloads","issues_url":"https://api.github.com/repos/livecode/livecode/issues{/number}","pulls_url":"https://api.github.com/repos/livecode/livecode/pulls{/number}","milestones_url":"https://api.github.com/repos/livecode/livecode/milestones{/number}","notifications_url":"https://api.github.com/repos/livecode/livecode/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/livecode/livecode/labels{/name}","releases_url":"https://api.github.com/repos/livecode/livecode/releases{/id}","deployments_url":"https://api.github.com/repos/livecode/livecode/deployments","created_at":"2013-04-10T00:15:57Z","updated_at":"2016-06-21T09:02:12Z","pushed_at":"2016-06-28T11:32:49Z","git_url":"git://github.com/livecode/livecode.git","ssh_url":"git@github.com:livecode/livecode.git","clone_url":"https://github.com/livecode/livecode.git","svn_url":"https://github.com/livecode/livecode","homepage":"https://livecode.com/","size":176757,"stargazers_count":130,"watchers_count":130,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":103,"mirror_url":null,"open_issues_count":49,"forks":103,"open_issues":49,"watchers":130,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/livecode/livecode/pulls/4190"},"html":{"href":"https://github.com/livecode/livecode/pull/4190"},"issue":{"href":"https://api.github.com/repos/livecode/livecode/issues/4190"},"comments":{"href":"https://api.github.com/repos/livecode/livecode/issues/4190/comments"},"review_comments":{"href":"https://api.github.com/repos/livecode/livecode/pulls/4190/comments"},"review_comment":{"href":"https://api.github.com/repos/livecode/livecode/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/livecode/livecode/pulls/4190/commits"},"statuses":{"href":"https://api.github.com/repos/livecode/livecode/statuses/51dcc6d54987d59753f292413ed5f5e51cd86c16"}}}}
{"actor":{"display_login":"peter-b"}}