@hew-lang/sandbox-vm 0.10.0-rc1 → 0.11.0-rc3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -61,6 +61,23 @@ A `sandbox_rejected` result includes rejection entries with `category`, `code`,
61
61
  checked traps, VM failures and step-budget exhaustion have distinct statuses.
62
62
  Consumers can offer explicit remote execution for native capabilities.
63
63
 
64
+ ## Crash details
65
+
66
+ Actor callers and crash hooks receive the same originating `CrashInfo`, with
67
+ owned kind, trap, message, site and trace fields. The VM captures up to 48 real
68
+ Hew activations before unwind and folds consecutive identical functions into
69
+ `StackFrame.repeat`. Distinct instruction sites remain separate. Diagnostic
70
+ messages are bounded to 4096 UTF-8 bytes, including an explicit ` [truncated]`
71
+ suffix when needed; oversized function names are omitted. Capture is always enabled; there is no VM trace-control
72
+ option. Frames describe the failing execution rather than its observer.
73
+
74
+ Current bytecode carries function names and byte-offset spans, but no source
75
+ file and line table. `CrashInfo.site` and each frame's `site` are therefore
76
+ `None`. A failure outside an executing Hew activation also has no trace.
77
+ Diagnostic materialization respects the receiving actor's managed heap budget:
78
+ it omits the trace first, then uses an empty message if necessary, preserving
79
+ the original kind and trap when diagnostic storage cannot fit.
80
+
64
81
  ## Validation
65
82
 
66
83
  From the repository root:
@@ -54,8 +54,10 @@ var SandboxExitCode;
54
54
  SandboxExitCode[SandboxExitCode["HeapExceeded"] = 200] = "HeapExceeded";
55
55
  SandboxExitCode[SandboxExitCode["IntegerOverflow"] = 201] = "IntegerOverflow";
56
56
  SandboxExitCode[SandboxExitCode["DivideByZero"] = 202] = "DivideByZero";
57
+ SandboxExitCode[SandboxExitCode["SignedMinDivNegOne"] = 203] = "SignedMinDivNegOne";
57
58
  SandboxExitCode[SandboxExitCode["ShiftOutOfRange"] = 204] = "ShiftOutOfRange";
58
59
  SandboxExitCode[SandboxExitCode["IndexOutOfBounds"] = 205] = "IndexOutOfBounds";
60
+ SandboxExitCode[SandboxExitCode["StackOverflow"] = 215] = "StackOverflow";
59
61
  SandboxExitCode[SandboxExitCode["ActorSendFailed"] = 206] = "ActorSendFailed";
60
62
  SandboxExitCode[SandboxExitCode["MachineDispatchUnreachable"] = 207] = "MachineDispatchUnreachable";
61
63
  SandboxExitCode[SandboxExitCode["ExhaustivenessFallthrough"] = 208] = "ExhaustivenessFallthrough";
@@ -66,6 +68,8 @@ const TRAP_EXIT_CODES = {
66
68
  integer_overflow: SandboxExitCode.IntegerOverflow,
67
69
  shift_out_of_range: SandboxExitCode.ShiftOutOfRange,
68
70
  divide_by_zero: SandboxExitCode.DivideByZero,
71
+ signed_min_div_neg_one: SandboxExitCode.SignedMinDivNegOne,
72
+ stack_overflow: SandboxExitCode.StackOverflow,
69
73
  invalid_local: SandboxExitCode.InternalError,
70
74
  invalid_block: SandboxExitCode.InternalError,
71
75
  invalid_call: SandboxExitCode.InternalError,
@@ -2,7 +2,7 @@ export type JsonValue = null | boolean | number | string | JsonValue[] | {
2
2
  [key: string]: JsonValue;
3
3
  };
4
4
  export type SandboxBytecodePackage = import("./v1/package.js").PackageV1;
5
- export type TrapKind = "heap_exceeded" | "actor_refused" | "integer_overflow" | "shift_out_of_range" | "divide_by_zero" | "invalid_local" | "invalid_block" | "invalid_call" | "invalid_enum_tag" | "invalid_record_field" | "vector_bounds" | "string_bounds" | "regex_compile" | "capability_missing" | "budget_exhausted" | "panic" | "unsupported_instruction" | "internal_error";
5
+ export type TrapKind = import("./v1/package.js").TrapName | "invalid_local" | "invalid_block" | "invalid_call" | "invalid_enum_tag" | "invalid_record_field" | "string_bounds" | "regex_compile" | "capability_missing" | "budget_exhausted" | "panic" | "unsupported_instruction" | "internal_error";
6
6
  export type RuntimeStatus = "ok" | "compile_error" | "sandbox_rejected" | "runtime_failure" | "budget_exhausted" | "panic" | "trap";
7
7
  export interface RuntimeFailure {
8
8
  kind: "panic" | "trap" | "budget_exhausted" | "unsupported" | "internal_error";
@@ -1,4 +1,4 @@
1
- import { UNIT } from "../values.js";
1
+ import { vectorItems, UNIT } from "../values.js";
2
2
  export const DIRECTORY_OPERATIONS = {
3
3
  hew_dir_open_read: {
4
4
  release: "hew_dir_read_close",
@@ -250,7 +250,7 @@ export class BrowserDirectories {
250
250
  const data = args[1];
251
251
  if (data?.kind !== "vector")
252
252
  throw new Error("file write requires bytes");
253
- const bytes = Uint8Array.from(data.items, (value) => {
253
+ const bytes = Uint8Array.from(vectorItems(data), (value) => {
254
254
  if (value.kind !== "i64")
255
255
  throw new Error("file write requires byte elements");
256
256
  return Number(value.value);
@@ -1,4 +1,4 @@
1
- import { UNIT, stringValue } from "../values.js";
1
+ import { vectorItems, UNIT, stringValue } from "../values.js";
2
2
  import { runtimeTag } from "./package.js";
3
3
  import { collectionOperation } from "./value-operations.js";
4
4
  class DecodeFailure extends Error {
@@ -19,7 +19,7 @@ function fields(value) {
19
19
  if (value.kind === "record")
20
20
  return value.fields;
21
21
  if (value.kind === "vector")
22
- return value.items;
22
+ return vectorItems(value);
23
23
  throw new Error(`codec aggregate received ${value.kind}`);
24
24
  }
25
25
  function toBridge(pkg, shape, id, value) {